pax_global_header00006660000000000000000000000064121571320150014507gustar00rootroot0000000000000052 comment=aecc31b92a3ea5c855f7bc90136e6cd6d5abe723 skycat-3.1.2-starlink-1b/000077500000000000000000000000001215713201500151355ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/.gitignore000066400000000000000000000005341215713201500171270ustar00rootroot00000000000000*.a *.o *.so *~ Makefile astrotclConfig.sh autom4te.cache catConfig.sh cat_version.tcl config.* configure.lineno pkgIndex.tcl rtd/rtd rtdClient rtdConfig.sh rtdCubeDisplay rtdServer rtd_version.tcl skycat-star skycat/linux/skycat.spec skycatConfig.sh skycat_version.tcl tRtd tclIndex tclutil.sh tclutilConfig.sh tclutil_version.tcl *.dSYM *.dylib skycat-3.1.2-starlink-1b/CHANGES000066400000000000000000001404651215713201500161420ustar00rootroot00000000000000CHANGES to Skycat Release ------------------------- This file contains a list of overall changes to the Skycat software and user interface. The latest changes are at the top. See also the CHANGES files in the tclutil, astrotcl, rtd, cat and skycat directories for changes specific to those packages. --------------- 17.10.08 released skycat-3.1.1 ----------------- * Fixed: HDU images display for VISTA data --------------- 17.10.08 released skycat-3.1.0 ----------------- * Updated cfitsio and wcstools packages (astrotcl) to newer versions. * Added support for ZPN projection. * Added support for tiled-image compressed files. * Added support for data types double and long long int. * Fixes for gcc version 4.2.4. --------------- 10.09.07 released skycat-3.0.2 ----------------- * Increased maximum number of views of an image from 8 to 64 --------------- 26.03.06 released skycat-3.0.1 ----------------- * Added patches from Sergio Gelato : Replaced calls to free() with Tcl_Free() for Tcl lists accessed from C code, as well as other minor bugs that showed up under Debian GNU/Linux 3.1. --------------- 03.02.06 released skycat-3.0 ------------------- * Rewrote makefiles and configure scripts using the Tcl TEA standard, Simplified source directory structure (There is now only one Makefile per package) * Rewrote skycat and rtd start scripts to be relocatable and set the correct environment variables on each platform. * All Tcl packages are now dynamically loaded (There is no skycat binary: just standard wish8.4 and a script that does a "package require Skycat") * Updated cfitsio and wcstools packages (astrotcl) to the latest versions * Merged in changes made by Peter Biereichel and Carlos Guirao at ESO * Removed dependency on the Tix package, replaced with BLT widgets and tkimg * Added tkimg (Img1.3) package (by request, also used for displaying some images) * Added Mac OS X support and a Skycat.dmg binary package * Binary versions are now available for Solaris9 (sparc), HP-UX, Redhat9, Fedora3, Fedora4, SuSE-10, Mac OS X. (Source RPMs can be used to make RPMs for other Linux versions) * Single binary (TclPro) version is no longer supported. Instead, RPMs and tar files are provided. (TclKit would not work as a replacement for TclPro, due to BLT package/linking issues.) * Added fix from awicenec@eso.org for WorldCoords.dispos() (calculates distance between two WCS positions) --------------- 04.04.05 released skycat-2.7.4 ----------------- * Merged in RTD changes from Peter Biereichel * Minor bug fixes and testing with latest compilers --------------- 20.01.03 released skycat-2.7.3 ----------------- * Ported to gcc-3.2.1 and Tcl-8.4.1: Changed the syntax for standard #include files from: to (for C++) and for C. For example: changed to and change to . The Standard C++ Header files are: algorithm bitset complex deque exception fstream functional iomanip ios iosfwd iostream istream iterator limits list locale map memory new numeric ostream queue set sstream stack stdexcept streambuf typeinfo utility valarray vector The Standard C Header files are: assert ctype errno float iso646 limits locale math setjmp signal stdarg stddef stdio stdlib string time * Added std:: namespace prefix to all standard C++ names. (For example: std::iostream, std::string, std::list, std::endl). --------------- 27.02.02 released skycat-2.7.2 ----------------- * Fixed problem with temporary downloaded image files being deleted too soon. (Now they are only deleted after they are loaded, so that the OS can delete them later on.) --------------- 13.12.01 released skycat-2.7.1 ----------------- * Enabled WCS coordinate conversion outside of the image area (by request). * fixed problem with equinox syntax reported by David Terrett. --------------- 27.08.01 released skycat-2.7 ----------------- * Merged in rtd and catalog changes from Peter Biereichel. * Fixed the -float_panel and -panel_orient options as well as the show/hide control panel menu item. * Included IWidgets in the skycat single binary version (used by the new FITS header viewer). --------------- 22.08.01 released skycat-2.6.10 ----------------- * Fixed a bug that caused skycat to access data outside the image array for some (very small) images, which could cause the application to crash or display incorrect values. --------------- 30.07.01 released skycat-2.6.9 ----------------- * Fixed problem with X shared memory, ssh and X11 forwarding: (X shm areas are not freed, so don't use them in this case) --------------- 20.06.01 released skycat-2.6.8 ----------------- * Fixed problem selecting catalog symbols in tk8.3.x --------------- 18.05.01 released skycat-2.6.7 ----------------- * Ported to tcl8.3.3 (still compatible with earlier versions). --------------- 11.05.01 released skycat-2.6.6 ----------------- * Fix for displaying multi-extension FITS images (see rtd/CHANGES) --------------- 17.02.01 released skycat-2.6.5 ----------------- * Fixed a bug converting coordinates between deg and wcs using the rtd tcl subcommand "convert". * Fixed a minor bug that occurred when a catalog config entry had a copyright field but no x,y or ra,dec columns defined. --------------- 09.11.00 released skycat-2.6.4 ----------------- * Fixed a bug that occurred when attempting to load an image file that was a relative path to a relative symbolic link. (For example: skycat ../x.fits, where x.fits is a link to y.fits). --------------- 20.09.00 released skycat-2.6.3 ----------------- * Fixed a bug in the display of galactic and ecliptic coordinates: RA was being displayed in hours and the equinox was displayed as 2000. Now RA is displayed in degrees in those cases and the equinox field displays "GALACTIC" or "ECLIPTIC". * Upgraded the WCS library to wcssubs-2.8.3. --------------- 25.05.00 released skycat-2.6.2 ----------------- * Added the procedure "display_catalog {catalogName}" to the SkyCat itcl class, for use via the remote interface. Now you can send this command to open a catalog window to display a catalog (name from the skycat config file) or a local catalog file (path name). * Note: the Solaris and HP single binary versions are now built with the same gcc compiler used to build the VLT software (There were previously some subtle incompatibilities). * Removed an error message that caused problems when the image header and data were in separate files. * Minor layout changes. --------------- 21.03.00 released skycat-2.6.1 ----------------- * Tested compiling with Sun-CC 4.2 and fixed a number of incompatibilities. --------------- 02.03.00 released skycat-2.6 ----------------- * Added support for displaying WFI type images, which contain multiple image extensions, as a single image, based on the CRPIX values in the extensions. The default bahavoir is as before, except that there is a new button in the HDU window "Display as one Image". * Added a new button in the HDU window: "Use Settings from Main Image" that sets the colormap, color scaling options and cut levels for the preview images from the main image. This is needed, since the preview images often appear black when they have not been not prescaled. * Merged the Skycat and RTD versions of the HDU window. Now the Skycat version is a subclass of the RTD version. * Tested Skycat build with Tcl8.2/Tk8.2 and Scriptics TclPro-1.3 and made minor changes in the Skycat configure script to support this. See ./INSTALL for details. * Added a new Skycat/RTD option: -panel_orient horizontal|vertical and added code to support having the main info panel on the left with a vertical orientation. The default for RTD is horizontal, as before. * Changed the default layout of the Skycat main panel to be on the left instead of the top (use "skycat -panel_orient horizontal" to get the old behavior). * Added code to check for valid command line options (The previous version sometimes crashed when passed invalid options). --------------- 27.12.99 released skycat-2.5.3 ----------------- * Minor bug fixes for the pick object window (to handle transformations correctly). --------------- 15.12.99 released skycat-2.5.2 ----------------- * Merged in RTD changes made by Peter Biereichel (see rtd/CHANGES) * Fixed minor bug in pick object window (rectangle was not being displayed in the center of the image). --------------- 02.11.99 released skycat-2.5.1 ----------------- * Fixed a bug dealing with leading zeros in formatting the seconds of RA (Could lead to incorrect plots and/or displayed values for RA). --------------- 25.10.99 released skycat-2.5 -------------------- * Merged in changes made by Peter Biereichel --------------- 09.9.99 released skycat-2.4.7 ------------------- * Fixed a bug in the formatting/printing of RA values (sometimes the fractional part of the seconds was incorrect). * Updated for egcs/gcc-2.95 (This compiler version is stricter for C++ code and even fails the solaris X11 header files, unless told to ignore the errors...). --------------- 22.7.99 released skycat-2.4.6 ------------------- * TCS catalogs: fixed a bug dealing with TCS catalogs (error message was "empty TCS result"). * Fixed problem with catalog directory hierarchies. Previously, catalog names had to be unique in the entire catalog hierarchy. Now, the interface has been changed slightly to fix this (see cat/CHANGES). --------------- 14.7.99 released skycat-2.4.5 ------------------- * Fixed a bug in the FITS I/O that caused problems under HP-UX when loading FITS tables. * TCS catalogs: fixed a bug dealing with TCS catalogs (error message was "empty TCS result"). --------------- 21.6.99 released skycat-2.4.4 ------------------- * catalogs: allow empty RA and DEC columns in query results where ra_col and dec_col are defined (previously an error mesage was generated: "error in RA value, expected HH:MM:SS"). * Fixed problem with double-click in FileSelect widget. --------------- 16.15.99 released skycat-2.4.3 ------------------- * HDU Display: Reversed the row order for displaying image extensions when sorting by CRPIX values (The order was previously incorrect). * Fits I/O: For image files with multiple image extensions: Now each header is merged with the primary HDU header when checking for WCS keywords. Keywords in the extension header override the same keywords in the primary header. * Fixed a number of RTD related bugs (see rtd/CHANGES). --------------- 02.04.99 released skycat-2.4.2 ------------------- * Added changes from Peter Biereichel: new rtdimage subcommand 'biasimage' and widget 'RtdImageBias' for on-the-fly bias image subtraction. The widget can be called from the real-time menu (See rtd/CHANGES). * Fixed from HP-UX related bugs dealing with dynamic loading (see tclutil/CHANGES). --------------- 25.03.99 released skycat-2.4.1 ------------------- * Added a check when saving catalog data to a compressed image, since this is not implemented. * Fixed the Exit menu item to really exit and not just close the window, in the case where there is more than one main window. * Fixed bug in startup when creating history catalog. * In the skycatgaia binary release, there was a problem with the ardmask binary (The release contained an older version). * Fixed problems with BLT graphs and zooming. --------------- 22.03.99 released skycat-2.4 --------------------- * Tested with SuSE-Linux-6.0 (gnulibc), TclPro-1.2, tcl8.0.5, the egcs-1.1.1 compiler and fixed a number of bugs that turned up there. * The single binary skycat release is now created using Scriptics TclPro-1.2 (tcl8.0.5). You can still create Tcl7.6 versions using the older "ET" utility. The ET version does not work with tcl8.x. * Changed the GAIA binary release to use Scriptics TclPro to generate a binary including all of the necessary scripts and extensions. Now "skycatgaia" is just a large binary. The release also includes a large number of STARLINK and PPM binaries that are used to convert between various image formats. (Note: skycatgaia is released as a separate package: see the skycat ftp site: ftp://ftp.archive.eso.org/pub/skycat/README.html). * Added scrollbars to the catalog entry widget. * RTD remote interface: Fixed socket error check in rtdrmt/src/rtdRemote.c. * Rtd: Coordinates/Zoom window: Fixed an "off by one" bug that caused the wrong coordinates to be displayed for pixels when the image was rotated and/or flipped at zoom 1. * Merged in changes from Peter W. Draper (Starlink) to support 16 and 24 bit color. Skycat now supports 16 and 24 bit color displays! Thanks to Peter Draper (P.W.Draper@durham.ac.uk) for providing the necessary changes! * Fixed a bug in the handling of local catalogs and "mmap" that could cause a core dump in certain cases. * Added a work around to Tk's limit on canvas coordinates to short range. Now the canvas (and image) coordinates do not have to be clipped to short range. This limit previously caused problems when zooming in large images. --------------- 4.02.99 released skycat-2.3.2 ---------------------- * Ported the GAIA plugin to tcl8.0.3 and changed the release structure to make it easier to install and start. Now you can just unpack the tar file in a directory and start the script "skycatgaia". * Removed redundant calls to Rtd_Init and Cat_Init in the skycat tkAppInit.C file. --------------- 14.01.99 released skycat-2.3.1 --------------------- * Upgraded the cfitsio sources to version cfitsio2027 (includes ESO HIERARCH keyword support). --------------- 29.12.98 released skycat-2.3 ----------------------- * The Skycat Tcl package and shared library now "contains" the Rtd and Cat packages. Previously it was dependent on them. This means that you should no longer load and/or link the Rtd and Cat libraries. Only the Skycat library is now required. This change was necessary, to avoid problems with static variables in shared libraries, since both the Cat and Rtd libraries contain some of the same object files (For backward compatibility reasons, both the Rtd and Cat libraries contain the contents of the Astrotcl and Tclutil packages). --------------- 28.12.98 released skycat-2.2.2 ----------------------- * Removed dialog asking if you want to save a temporary image, for example from an image server, since it sometimes caused problems. Now, if you save the temporary image, it will be added to the history catalog and menu. otherwise not. * Fixed a bug in opening the image server window (error complains about the "Add to..." menu item not being found). * Tested with Sunpro CC-2.4 and Solaris-2.6 and fixed minor compilation and linking problems. * HDU window: Allow different NAXIS[12] values and try to determine correct row,col indexes anyway. If images overlap, the display order will be the oder of the HDUs as they are found in the file. * HDU window: Show the selected HDU. The line in the table is now highlighted and the selected image HDU is displayed with a sunken relief. --------------- 03.12.98 released skycat-2.2.1 ----------------------- * Added a new item to the catalog window File menu: "Save with image", for saving catalogs as FITS binary tables and reloading them again. Now you can save local catalogs with the image, including plot symbol information. Catalog configuration information is stored in the CATINFO table, which contains one row for each FITS table created from a catalog. * Added a menu item to the Graphics menu: "Save graphics with image". Selecting this item adds a FITS table to the current image containing descriptions of all of the line graphics objects in the image. When you load the image again later, the graphics are restored automatically. The name of the FITS table is based on the name (EXTNAME) of the current FITS image extension, so you can save different graphics with each image extension. * Changed the "-remote" option to use the RTD remote socket interface, if "Tk send" does not work. "Tk send" only works when you use X-Auth style X security. --------------- 16.11.98 released skycat-2.2 ----------------------- * Added support for multiple FITS HDUs. Now, when you open a FITS file with multiple HDUs, a window is displayed where you can choose which parts to display. FITS tables are displayed as local catalogs. Small versions of the images are displayed in a table, in the correct orientation, if posible, using the values of the CRPIX* keywords. Clicking on an image displays it in the main window. * Modified the CFITSIO sources files to handle ESO HIERARCH keywords. * Ported Skycat to tcl8.0.3/BLT2.4f/Scriptics TclPro (But still compatible with tcl7.6/tk4.2/BLT2.1) - Updated namespace syntax - Updated BLT references where needed (for BLT-2.1 or 2.4f) - Added a "tclpro" directory that replaces the "et" directory when building a single binary version for Tcl8. The Et code doesn't work with Tcl8, so the Tclpro product from Scripts is used instead, if it is available (and in your shell $PATH). * SkySearch.tcl: Fixed a problem linking catalog objects to line numbers when sorting was turned on. * SkyCat.tcl: force full path names by -catalog option for local catalogs, to avoid confusion over local catalog names. * Catalog window: Fixed a problem linking catalog objects to line numbers when sorting was turned on. --------------- 30.9.98 released skycat-2.1.3 ----------------------- * Upgraded wcslib to (Doug Mink's) wcssubs-2.5b, which fixes some problems with COE projections and includes other bug fixes. * Changed the release structure of the rtd, cat and astrotcl packages to include the necessary utility packages. Now the rtd and cat tarfiles also contain the astrotcl and tclutil packages. The top level Makefile and configure script automatically determine which packages to make. This does not affect the skycat release itself, since it always included the other packages. * Rtd: Fixed a bug in the "Save region..." implementation, where FITS keywords were not updated correctly in some cases. * Skycat, Catlib: fixed a bug in the handling of temporary image files (from image servers or when decompressing). * Added an image history feature, for quick access to previously loaded images. This includes a "Go" menu, for quick access, and a "History" catalog menu item under Data-Servers. Images from image servers need to be saved to a file in order to be put in the history (see below). The history catalog is also used to save information about each file, such as the colormap and cut level settings. * Added a dialog to ask the user if an image from an image server should be saved to a file before loading another image, so that file can be put in the image history list. * Skycat now automatically saves and restores the main window size and position between sessions. --------------- 23.8.98 released skycat-2.1.2 ----------------------- * Catlib: image servers: Fixed a bug introduced in the previous version that caused problems when displaying images from an image server. * Also made a number of minor bug fixes. --------------- 7.8.98 released skycat-2.1.1 ------------------------ * Skycat command line options: Changed -remote option to reuse the same image window and interpret only image and catalog arguments. This makes it easier to use skycat as a netscape application, for example: "skycat -remote 1 %s". For catalogs, you can also do: "skycat -remote 1 -catalog %s". * Catalogs: The "Select Area" button no longer pops up a message window telling you to drag out a region. It simply sets the mouse cursor (for convenience). * Fixed a bug dealing with catalog name servers (SIMBAD, NED) introduced in the previous version. * Removed default for limit on number of rows returned from a catalog query (%n in URL). * Merged the image server interfaces with the catalog interfaces. The AstroImage and TclAstroImage classes, and the astroimage Tcl command are still available for backward compatibility, but are now obsolete and should no longer be used. The AstroCatalog and TclAstroCat classes, and the astrocat Tcl command now handle image servers as well as catalogs. The "getimage" methods/subcommands are now part of the catalog classes. The merge was made to avoid duplicating large chunks of code, since there are many similarities in the two interfaces. * Now it is possible to generate image server windows with custom search labels and without the default search widgets (name, ra, dec, radius). This was previously only supported for catalogs. In both cases, if you don't want the default search widgets, add these lines to the config entry: ra_col: -1 dec_col: -1 x_col: -1 y_col: -1 For catalogs, this means that there are no searchable ra,dec or x,y columns. For image servers, it means that you can't search by these values, so they are not displayed. * Catalog config file: Allow search columns with only one value (previously only min and max values were allowed). This feature is enabled if the second label is missing in the "search_cols: " keyword in the catalog config file. For example, in an image server: search_cols: patch Patch will display a "Patch:" label and entry in the user interface. In the URL for the image server, "%cond" will then be replaced by "patch=22", if the user typed in 22. * Fixed the handling of the "maxRows" field for searching catalogs, so that, if it is left blank or zero, there is no limit (previous versions had a default limit). * Updated to wcssubs-2.4 (Doug Mink's wcslib, on which the SAOWCS C++ class is based). This fixes some bugs in the handling of world coordinates rotation. --------------- 5.8.98 released skycat-2.1 -------------------------- * Added a top level configure script that runs configure in the subdirectories. This way you can just run "configure..." in place of "make World...". A "Makefile.in" was also added. A top level Makefile is still included in the release for backward compatibility. * Changed the name of the top level directory in the source release tar files to include the version number (for example: skycat-2.0.19/). This is more standard and avoids problems updating old directories. * Image previews, image servers: Added code to check the the HTTP Content-Encoding of image files (instead of only the Content-type), to help recognize compression types. * Added HTTP password authorization suport. If an HTTP server returns the error "Authorization Required", skycat now opens a dialog box and asks for the username and password. The information is cached for later use. * Added support for backup URLs for image servers (was previously only supported for catalogs). This is activated by using the "backup1" and "backup2" keywords in the catalog config file. * "Reload Config File" now works recursively and reloads the information in any remote catalog directories that were open. Previously, only the top level catalogs were reloaded. * Added the X11 library directory to shared lib path in startup script. * catlib: Fixed a bug where the "id" column was still assumed to be always 0 (The id column index is now always taken from catalog config file). * catlib: Changed the way that rows are inserted into local catalogs. They were previously appended to the end of the file after removing duplicates. Now the original row position is kept and the row is updated if it already exists (same id) and appended otherwise. * Color scaling: Added new command line option "-color_scale" to set the color scaling on startup. The option takes a value: one of linear, log, sqrt, histeq. Also made changes so that the color scaling setting is remembered between images and reapplied. * Coordinates: Added new coordinate type: "chip", for detector chip or CCD coordinates, that takes into account the origin of the chip and binning. X,Y coordinates in the user interface are now displayed in chip coordinates, which are the same as image coordinates, unless the FITS keywords "HIERARCH ESO DET WIN STRX" and "...STRY" are defined or special fields in the real-time image event struct are set. Also added two new fields to the RTD real-time image event struct in rtdImageEvent.h: startX and startY, with the same meaning as the FITS keywords above. * RTD now reads cut level values from the real-time image events and sets the image cut levels, unless the user set them already by hand. User values override real-time event cut level values. * Implemented "histogram equalization" color scaling and added it to the list of choices in the Rtd "Colors" popup window (based on saoimage source code). * Added code to handle NAN values for image pixels. They are now treated as blank pixels. * Updated to wcssubs-2.3.2 (Doug Mink's wcslib, on which the SAOWCS C++ class is based). This fixes a number of bugs in the handling of world coordinates. * Error and info dialogs: Added code to truncate messages with too many lines to be displayed and also made the dialog windows wider. * Top level windows: Fixed minor bug that prevented the code from remembering the locations of top level widgets. Now, if you place a window somewhere, it comes up there the next time the window is created in that session. * The catalog and image server windows were using up too many file descriptors. Now the files are only opened as needed and then closed again immediately. --------------- 07.7.98 released skycat-2.0.18 -------------------------- * catlib: allow local catalog search without ra,dec columns, fixed handling of default column positions for ra and dec, to allow catalogs with no ra,dec or x,y columns. * Image I/O: Changed location of the temp file used when compressing or decompressing an image from "file.tmp" to /tmp/fitsioXXXXXX, since the directory that file is in may not be writable or might be on a CD. * class HTTP: added suport for HTTP POST: new methods: HTTP::post(url, data) and HTTP::post(url, data, ostream). * Other minor changes (see */CHANGES files). --------------- 26.6.98 released skycat-2.0.17 -------------------------- * Skycat, single binary version: Added check for correct prolog.ps file in ~/.skycat dir (many users have an outdated version of this file in the ~/.skycat dir, created by an earlier skycat release). * Rtd: Changed footers in postscript output to include object name, file name and center position. * Tested compiling with egcs-1.0.3 (based on gcc-2.8.x) and fixed minor errors and warnings that were reported by the new compiler. * Added support for HTTP proxy servers (thanks to Peter Draper for implementing this). * Catalog window: added a menu (under Options) and dialog window for setting a proxy server for HTTP catalog access from behind a firewall. --------------- 19.6.98 released skycat-2.0.16 -------------------------- * Catalog window: Minor change in the way query coordinates are interpreted. If the RA value is an integer, it is assumed to be in hours (as before), but if it is a decimal number (3.2, for example), it is assumed to be in degrees. * Catalog window: fixed bug in the handling of the MORE URL (mostly used for HST catalogs). The "M=" part before the URL was not being recognized. * Rtd: Printing Images now outputs better postscript, since it no longer does a screen dump, but generates postscript directly from the image and graphics information (see also rtd/CHANGES). * Rtd: changed focus policy to fix problems with mouse pointer warping (moving mouse with arrow keys). The previous version included some code to avoid obscure problems with the CDE window manager, with the "click to focus" setting. If anyone has problems with the new version, please let me know. --------------- 28.5.98 released skycat-2.0.15 -------------------------- * Added support for HTTP redirect "Location: ..." to HTTP class * Catalogs: MORE and PREVIEW fields can now be commands. No special check is made for "http://" or "file://" as before. For PREVIEW data, the stdout of the command is assumed to be a FITS file, if it starts with "SIMPLE", and otherwise catalog data to plot. * FitsIO::blankImage(...), Changed generated blank images to use the normal colormap colors instead of all blank pixels, so that you can change the background color of a generated image by manipulating the colormap. * Catalog window: "Data-Servers/Local catalogs" menu: Added check for local catalogs, to see if the file exists. If not, you are asked if you want to specify a new name or remove the catalog from the menu. * Image Server window: added "Select Area..." button to to select the * area of the image to fetch (as with the catalog window). --------------- 13.5.98 released skycat-2.0.14 -------------------------- * Catalogs: Added a "help" field to the catalog config file, which may optionally contain a URL pointing to information about the catalog. If the "help" URL is specified, a "Help" button appears in the user interface, which displays the URL in netscape (using the remote interface, if netscape is already running). * Catalogs: Fixed problem with "Preview" images that was caused by using the same temporary file to hold the image each time (now uses a new file each time and deletes the old one). * SkyCat.tcl: remote interface proc: pick_object: fixed a minor bug that reported an unknown Tcl variable. --------------- 4.5.98 released skycat-2.0.13 ----------------------------- * Fixed a recently introduced bug in coordinate conversion that caused problems plotting catalog symbols for images with equinox != 2000. * Catalog window: Fixed "Reload Config File" menu item to remove "dead" catalog entries (entries that were removed from the config file since the last time it was read). * Other minor changes. --------------- 28.4.98 released skycat-2.0.12 ----------------------------- * Pick Object window: Merged in Peter Biereichel's changes, which include using a "zoom window" for the image. This lets you zoom in and out to get the correct resolution. Also changed the default layout of the window to save space. You can get the old layout by specifying the command line option "-pickobjectorient horizontal". * The single binary version of skycat is now linked with the shared X libraries. This is necessary in order to be able to dynamically load shared libraries for skycat plugins at runtime. If this causes any problems, check out ftp://ftp.archive.eso.org/pub/skycat/, where we will provide tar files with the necessary libraries. * Various minor bug fixes. --------------- 15.4.98 released skycat-2.0.11 ------------------------------ * Allow additional suffixes for automatic compression and decompression of FITS files: ".gz" for gzip, ".Z" for UNIX compression (i.e.: file.fits.Z, file.fits.gz). * Added "public", "private", and "protected" keywords in the Itcl source as well as some comments to help identify the public interface, for use by skycat plugins and extensions. * Updated the man pages for all of the Itcl classes to include the Itk components and standard options used. * Minor changes in configure script and top level makefile for shared libraries * Fixed a bug in image pixel coordinate conversion that caused the world coordinates to be slightly shifted in images created with the "File => Save region as..." menu item. * Various minor bug fixes. --------------- 31.03.98 released skycat 2.0.10 ----------------------- * Updated man pages and documentation * Fixed the -shm_data and -shm_header options, which were no longer working after earlier changes. --------------- 25.03.98 released skycat 2.0.9 ----------------------- * This release contains a number of minor changes to make it easier for plugins and subclasses to override the default behavior. See the */CHANGES files for details. * Added "clone" number to window headers, to help identify related windows when there is more than one main window. * Change keyboard accelerators for menu items to use instead of , since is used in Tk for popping up a menu with the keyboard (see -underline option in menubutton(n)). * Added -float_panel option to allow info panel to be in a popup window (default is off, no change), usage: rtd ... -float_panel 1, to enable. * Added -panel_layout option to allow changing the order of the zoom and pan windows in the layout (default is the same as before, no change). Usage: rtd ... -panel_layout $value, where value is one of {saoimage reverse default}, for an saoimage type layout, reverse or default. * Compress: Upgraded to new "press" library routines to fix bug found in H-compress code (Bug was only in decompression). --------------- 05.03.98 released skycat 2.0.8 ----------------------- * Added a -remote option to skycat: usage: "skycat -remote 1 file ..." When "-remote 1" is specified and a skycat application is already running on the same display, the existing skycat application opens a new main window to display the image. In this way, you only need to have one skycat application running at a time, which saves memory and colors in the colormap. Note that this feature uses "Tcl send", which has a special X security check and so won't work if you use the "XHOST" style X security. Unless X security is disabled in the binary, you need to use XAUTH style security. See the "Tcl/Tk Tools" book for a good explanation of this. * For backward compatibility: Removed dependence on the Tix package (now part of tclutil package). * For backward compatibility: Removed application dependence on the tclutil and astrotcl packages by merging these into the rtd and cat libraries in the installation (i.e.: the object files from astrotcl and tclutil are included in the master rtd and cat libraries and the include files are copied to the rtd and cat include dirs. * Implemented rotation for canvas graphics. Since Tk doesn't support this directly, it is done now in Tcl code. Polygons are now used in place of rectangles, to make it posible to rotate a rectangle. (The appearance and funtionality is the same). You still can't rotate ovals, but you can rotate a smooth rectangle, which is similar (see below). * Added a "Smooth" option in the graphics window (CanvasDraw), so you can make smooth (rounded) rectangles, polygons or polylines. * Made it possible to "select" a catalog symbol in the image, even if it is hidden by another symbol on top of it. If one symbol is hidden behind another, just click again to select it. You can "cycle" through a stack of symbols by clicking multiple times. Use -1 to toggle the selection of a symbol. * Added a "Filter" button to the catalog display widget to filter out objects that are not visible in the query result list. This is needed because the query is circular, while the image is rectangular, leaving some objects in the listing that can not be plotted in the image. * Added a new command line option: "-catalog $catalogName". Now you can have a catalog window (local or other) opened automatically when skycat starts. i.e.: "skycat file.fits -catalog file.cat". * Plugins: The SKYCAT_PLUGIN environment variable may now contain a colon separated list of plugin files or directories. For directories, teh default file name for a skycat plugin is SkyCat_plugin.tcl, which defines the Tcl proc SkyCat_plugin. --------------- 13.2.98 released skycat 2.0.7 ----------------------- * Moved the catalog symbol plotting code from Tcl to C++ to improve the performace of plotting 1000's of objects on large images. (In one test, the time required to plot a large catalog was reduced from about 60 secs to about 3 seconds). * Removed the "unexec" directories (replaced by "et" - Embedded Tk). The "unexec" code was previously used to create a single binary and has been replaced by "et" now. --------------- 9.2.98 released skycat 2.0.6 -------------------------------- * Fixed problems with floating point precision when converting world coordinates (raised from default of 6 digits to max 17 digits.) * Fixed bug in introduced in the last version that could cause a core dump when setting the cut levels. --------------- 3.2.98 released skycat 2.0.5 -------------------------------- * Added a selection mechanism to select a region of the image or canvas. The graphics toolbox now contains a "region" item that can be used to select a region of the image. Also added binding as a shortcut to select a region. * Improved selection of catalog plot symbols in the image and listbox. Plot symbols are now selected in the image with mouse button 1. If the shift or control key are also down, multiple objects may be selected. Objects may be selected in either the image window or the table listing, with the same effect. The selected objects may be added to a local catalog, etc... * Added a menu item to the "Real-Time ==> Rapid Frame menu": "Delete Rapid Frame", to delete the current rapid frame. * Added a new rtdimage subcommand: "mmap", which has a similar syntax to the "shm" subcommand. The rtd "shm" subcommand is used to manipulate sysV shared memory areas containing the image and header data. The rtd "mmap" subcommand does the same, but with "mmap" memory, which is the default, since rtd uses mmap to read image files. * Rtd now checks the value of the FITS "BLANK" or "BADPIXEL" keywords and ignores these pixels when setting cutlevels or doing any calculations. The blank pixels are displayed black by default. --------------- 26.1.98 released skycat 2.0.4 ------------------------------- * Added support for Tcl plugins for all top level widget classes and added documentation and examples in the Skycat documentation (see ftp://ftp.archive.eso.org/pub/skycat/doc/skycat.ps.gz) * Updated comments in Itcl sources for automatic generation of man pages. (There are now man pages for all Itcl classes). * Added postscript (framemaker) documentation for all packages (tclutil, astritcl, rtd, cat, skycat), see: ftp://ftp.archive.eso.org/pub/skycat/doc * Add menu accelerators (keyboard shortcuts) in Skycat, Rtd and Cat menus * Split the "top level" AstroCat class into different "frame" classes, by request. Now the AstroCat class is made up of an AstroQuery class (defines the panel with the search entries) and the QueryResult class (defines the table for displaying the query results). None of these classes knows about images. For image support, see the Skycat package, which contains classes that are derived from these and add image support. --------------- released skycat 2.0.2 ------------------------------- * Compilied sources with the SunPRO C++ compiler and fixed problems that showed up there and not with gcc. * Replaced "unexec" package with "ET" (Embedded Tk), for creating a single binary of skycat, including Tcl sources and colormaps, etc. (The unexec version is still included, but not used by default). * Reorganized sources to include 2 new packages: The "Tclutil" package was created by gathering "generic" Tcl and C++ code from various applications into a single generic Tcl package. The "Astrotcl" package was created by gathering general astronomy related Tcl and C++ code from other packages into a single, reusable package. Note: if you were using the Rtd or Cat packages in another application, there are some minor changes to be made to the initialization code to initialize the new packages. * Moved catalog widgets to the Cat package. * changes in skycat user interface: - There is a new catalog menu layout. - added support for a hierarchy of catalog directories. There is a new type of catalog called "directory" that has a URL that points to other catalog config files, possibly on other hosts. - Added a new popup window for displaying and browsing the catalog directory tree. You can select catalogs from various catalog servers and save them in your own personal config file. The changes appear immediately in the catalog menu. - Added a menu item to reload the catalog config file after you have edited it by hand. - The layout of the catalog window is now dependent on the information in the catalog config file (search columns). - Added support for editing the catalog config file. There are now menu items for setting the sort columns and sort order, search columns, column display order, columns to show or hide, plot symbol info (see the "Options" menu - changes are automatically saved in ~/.skycat/skycat.cfg) - Added more support for plot symbols: Now you can configure the color, shape, angle, size and units of the symbols to be displayed in the image for a star or other object. There is a window interface for editing the settings (see the Options menu). --------------- 17 Jun 97 released skycat 1.1 ------------------------ * Rtd, Skycat, Catlib: added support for shared libraries, itcl2.2, tk4.2, tcl7.6. blt-2.1, loadable modules, packages. Use: "configure --enable-shared ..." (see INSTALL file). * The Rtd configure script now gets information from the Tcl/Tk config files (tclConfig.sh, tkConfig.sh, etc...) and generates its own rtdConfig.sh file, which is used by the catlib and skycat configure scripts. This makes running configure faster and hopefully more portable. * added a make target "release_bin" that generates a binary/interpreted release of skycat. This can be used in place of the single binary "unexec" version on systems where that doesn't work. * various bug fixes in rtd and catlib (see rtd/CHANGES and cat/CHANGES) --------------- 13 Feb 97 released skycat 1.0.6 --------------------- * various bug fixes (see rtd/CHANGES, cat/CHANGES) --------------- 30 Jan 97 released skycat 1.0.5 --------------------- * (Catlib) added support for backup catalog servers and local catalog config files. * Skycat catalog windows: The default catalog/archive/image server is now taken as the first one in the config file and no longer hard coded to names such as "Guide Star Catalog at ESO". * Added World Coordinates support to the real-time image events by extending the structure used to pass images to the RTD via the rtdServer. *** (NOTE: incompatible change: clients must at least be recompiled!) --------------- 21 Nov 96 released skycat 1.0.3 --------------------- * Fixed byte-swap problems in FITS files and made Linux compatible. Skycat should now work on machines that have a byte order that is different from network byte-order (such as PCs). Thanks to Sidik Isani for supplying the patches for this. * The "Pick Object" feature (View Menu) now also works for images that do not support world coordinates. * (Rtd) Local file URLs are now supported, i.e., file:/path/name... Now you can specify the URL for the catalog config file using file:/... * (Catlib) It is now possible to search GSC by Id. --------------- 14 Nov 96 released skycat 1.0.2 --------------------- * Changed configure scripts and makefiles so that skycat can be used as a separate package, assuming the correct Rtd and Catlib versions have already been installed. --------------- 8 Nov 96 released skycat 1.0.1 ---------------------- * (Rtd) Fixed compass to display East correctly (was reversed...) * (Skycat, Catlib) Added copyright field to catalog config file and added item to the user interface to display the copyright info for the current catalog or image server. --------------- 7 Nov 96 released skycat 1.0 ---------------------- * (WCS lib) Major improvements in the World Coordinates handling. The WCS information for HST images should be handled correctly now, so you can plot guide stars, etc. This previously worked correctly only for some images (such as those from DSS). Many thanks to Doug Mink (dmink@cfa.harvard.edu) for supplying the WCS library and bug fixes. * (Rtd) added a new "Grid" feature (see View menu) that displays a world coordinates based grid over the image. You can also control the grid size (distance in arcsecs between grid lines) in a new entry in the main panel. * (Rtd) The compass widget (N-E display in panel) was removed and replaced with a more correct display in the Pan window. The Pan window now displays 2 arrows indicating the real north and east for the image, based on the world coordinate information. * (Rtd) fixed bug in "measure band" display that caused incorrect distances to be displayed for the width and height lines (the diagonal was ok). * (Rtd) Added bindings to measure band so that arrow keys can be used to position it. --------------- 23 Oct 96 released skycat 1.0b16 ---------------------- * (skycat) fixed the single binary problem related to the tclEnv patch (see below), since the original fix did not work. The tclEnv patch is still the same. --------------- 22 Oct 96 released skycat 1.0b15 ---------------------- * (skycat) fixed a problem that only showed up in the single binary version of skycat: under certain circumstances, skycat would crash immediately on start up. I had to patch a a Tcl source file (tclEnv.c) to fix this (see skycat/CHANGES and patches/tclEnv.patch). * (Rtd) fixed bug setting cut levels (was a result of changing the way the min/max pixel value is set). * (catlib) Fixed bug when saving local catalogs for images that are not J2000. (The catalog was saved as B1950, for example and later treated as J2000 when loaded). Now all local catalogs are saved (the ra,dec columns) in equinox J2000 and are expected to be in J2000 when opened. * (Rtd) changed the bindings on the "measure band" so that it acts more like a menu or the line graphics: it will stay up if you click <3>, release and then drag. Clicking <3> again makes it go away. now makes it "freeze" so you can keep it where it is. (or ) displays just the single line mband. * (Rtd) Changed the way image cut levels are set by default. In the previous version, cut levels were not changed at all when a new image was loaded, which meant that you usually had to press the "Auto Set Cut Levels" button to make the image visible. Now this has been changed as follows: If you set the cut levels explicitly by typing in a number or moving a slider bar, etc., they will not be changed, even if a new image is loaded. However, if you have the cut levels calculated automatically by pressing the "Auto Set Cut Levels" button or the "Median Filter" button, etc., then it is assumed that new cut levels can be set automatically when a new image is loaded. (We would be interested to hear any comments on this. Maybe we should make this behavior optional ny adding a checkbutton somewhere...) * (Rtd) Made a number of changes designed to improve performance on very large images (got test image from Kim Gillies: 170 MB, 8192 x 5464 floats): * the zoom window is no longer updated from the pan window, since that can cause a lot of disk activity on large images (the mouse easily crosses the entire pan image, which would have to be displayed in the zoom window). * auto set cut levels, median filter, finding min/max pixel, etc. now are only calculated for the visible part of the image and (for speed) don't examine all image pixels. * (skycat) added confirmation dialogs for entering, updating and deleting local catalog entries. * (catlib) The catalog config file entry is now written to local catalogs (in the header) so that the same plot symbol is used when the file is reloaded. --------------- 1 Oct 96 released skycat 1.0b12 ---------------------- * added new View menu item: "WCS Info" for setting/displaying basic world coordinate information. --------------- 20 Sep 96 released skycat 1.0b11 ------------------ * loading of very large images should be faster now, since "mmap(2)" is used to map files to memory rather than reading them. Also, the alogorithm used to get the min and max pixel values has been changed to not look at every pixel (see rtd/CHANGES). * now using new SAO wcs library (wcssubs-1.0). * made improvements to the colormap handling code to avoid color flashing when using a private colormap (see rtd/CHANGES). * split the "./cat" directory into "./cat" (catalog libraries only) and "./skycat" (skycat application, interpreted and single binary versions), by request. ---- see also: rtd/CHANGES, cat/CHANGES, skycat/CHANGES ------------------- skycat-3.1.2-starlink-1b/CHANGES_DOUBLE000066400000000000000000000011231215713201500171570ustar00rootroot00000000000000Double precision image support. ------------------------------- I modified the following files to add a double precision image type (bitpix -64): --- astrotcl/imageio/include/ImageIO.h astrotcl/imageio/src/FitsIO.C rtd/rtdimg/src/RtdCamera.C rtd/rtdimg/src/RtdImage.C rtd/rtilib/include/NativeImageData.h rtd/rtilib/src/ImageData.C rtd/rtilib/src/ImageTemplates.C rtd/rtilib/src/Makefile.in rtd/rtilib/src/NativeImageData.C --- and created the following files: --- rtd/rtilib/include/DoubleImageData.h rtd/rtilib/src/DoubleImageData.C Peter W. Draper (p.w.draper@durham.ac.uk) 31st May 2001. skycat-3.1.2-starlink-1b/COPYING000066400000000000000000000023611215713201500161720ustar00rootroot00000000000000Copyright (C) 1995-2001, European Southern Observatory (E.S.O.) Karl-Schwarzschild-Str.2, 85748 GARCHING, GERMANY Skycat is a copyright protected software product of the European Southern Observatory, and provides a general tool for image display and astronomical catalog access. Skycat is available under the GNU General Public License. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU General Public License text is included in the file GNU_PUBLIC_LICENSE in this directory. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. Correspondance concerning VLT-RTD should be addressed as follows: Internet e-mail: pbiereic@eso.org Postal address: European Southern Observatory VLT Software Group Karl-Schwarzschild-Strasse 2 D-85748 Garching near Munich GERMANY skycat-3.1.2-starlink-1b/INSTALL000066400000000000000000000075261215713201500162000ustar00rootroot00000000000000Installing the Skycat Software ------------------------------ Binary Installation ------------------- Precompiled versions of Skycat are available from the Skycat ftp site: ftp://ftp.eso.org/pub/archive/skycat Due to technical reasons, there is no longer a single binary version of Skycat. Instead, the installation method depends on the OS: Mac OS X -------- The skycat ftp site contains a disk image that you can download and mount in the usual way. Just click on the image and drag the skycat icon to your desktop or Applications folder. Make sure you have the optional X11 package installed. The skycat start script will try to start X11, if it is not already running. This version was compiled on a Powerbook running Mac OS X 10.4.4. All of the required Tcl/Tk extensions are included in the Skycat application directory (neither Fink nor DarwinPorts had all of the ones we need). Linux ----- RPM Install ----------- For Linux (Redhat9, Fedora3, Fedora4, Scientific Linux 4.1, SuSE-10), install the RPMs for tcl, tk, (tcl-devel, tk-devel), itcl, tclx, BLT, tkimg, and skycat. For example, first install the standard tcl/tk packages for the system in the usual way, using yum (Fedora), or yast (SuSE): yum install tcl yum install tk yum install itcl ... Only SuSE-10 comes with all of the required Tcl extensions, however you can get the missing rpms (for itcl, BLT, tclx, tkimg) from the skycat ftp site and install them with: rpm -i ... Tarball Install ---------------- If you don't have the root password for the machine, you won't be able to install the RPMs. In that case, you can download a tar file containing the skycat and tcltk installation directory compiled for the given OS. You can put this directory anywhere and include the $skycat/bin dir in your shell path. Then you can start skycat with the command "skycat&". Solaris9 and HP-UX10 -------------------- You can download a tar file from the skycat ftp site that contains the complete skycat/tcltk installation in a relocatable directory. Just untar the file somewhere and include the bin directory in your shell path. Building Skycat from the Sources -------------------------------- Requirements ------------ The following Tcl environment should be installed: Tcl8.4.* - Tcl Shell (8.4.11, earlier versions may also work) Tk8.4.* - Tk Toolkit (8.4.11, earlier versions may also work) itcl3.3 - [Incr Tcl] object system BLT2.4z - BLT toolkit, graphs and other widgets tclX8.4 - Extended Tcl (8.3 should also work) TkImg1.3 - Tk Image extensions You can download a tar file containing the sources for all of the above packages from: ftp://ftp.eso.org/pub/archive/skycat/tcltk-8.4.tar.gz You can also build skycat against the Linux system Tcl libraries (installed under /usr/lib). The only system I know of that comes with all of the required packages is SuSE-10, however I recompiled the missing rpms for Redhat9, Fedora3, Fedora4, and ScientificLinux-4.1 and put them under ftp://ftp.eso.org/pub/archive/skycat. Building the Software --------------------- To build the software, run these commands: % configure --prefix=$INSTALLDIR % make all install There are a number of options you can pass to configure: --with-tcl directory containing tcl configuration (tclConfig.sh) --with-tk directory containing tk configuration (tkConfig.sh) --with-blt=DIR link with BLT library installed in DIR --enable-merge merge the contents of compile-time dependent packages into master rtd, cat and skycat libraries (for backward compatibility) "configure --help" prints a list of available options. As an alternative to specifying --with-tcl, you can also set the TCLTK_ROOT environment variable to point to the top of the Tcl/Tk installation. -- Please report any problems to me: Allan Brighton abrighto@eso.org skycat-3.1.2-starlink-1b/Makefile.in000066400000000000000000000040241215713201500172020ustar00rootroot00000000000000# Makefile # change these to the install prefix and exec-prefix values prefix = @prefix@ exec_prefix = @exec_prefix@ # directories in which to run make subdirs = tclutil astrotcl rtd cat skycat # Note: add --enable-merge if you want to merge object files into the # skycat, rtd and cat shared libraries (for backward compatibility) CONFIGURE = configure --prefix=$(prefix) --exec_prefix=$(exec_prefix) all install clean: FORCE @set -x; for i in $(subdirs); do (cd $$i && $(MAKE) $@ || exit 1) done # Run "configure" and "make all install" in the subdirectories All: $(subdirs) release: FORCE (cd skycat; $(MAKE) release) distclean: FORCE @set -x; for i in $(subdirs) ; do (cd $$i && $(MAKE) distclean) ; done rm -rf autom4te.cache config.status config.log configure */configure Makefile # run configure and make in individual dirs tclutil: tclutil/configure FORCE (cd tclutil && $(CONFIGURE) && $(MAKE) && $(MAKE) install) astrotcl: astrotcl/configure FORCE (cd astrotcl && $(CONFIGURE) && $(MAKE) && $(MAKE) install) cat: cat/configure FORCE (cd cat && $(CONFIGURE) && $(MAKE) && $(MAKE) install) rtd: rtd/configure FORCE (cd rtd && $(CONFIGURE) && $(MAKE) && $(MAKE) install) skycat: skycat/configure FORCE (cd skycat && $(CONFIGURE) && $(MAKE) && $(MAKE) install) # run autoconf autoconf: configure tclutil/configure astrotcl/configure rtd/configure cat/configure skycat/configure # run autoconf and configure config: configure tclutil/configure astrotcl/configure rtd/configure cat/configure skycat/configure $(CONFIGURE) configure: configure.in autoconf tclutil/configure: tclutil/configure.in tclutil/aclocal.m4 tclconfig/tcl.m4 (cd tclutil; autoconf) astrotcl/configure: astrotcl/configure.in astrotcl/aclocal.m4 tclconfig/tcl.m4 (cd astrotcl; autoconf) rtd/configure: rtd/configure.in rtd/aclocal.m4 tclconfig/tcl.m4 (cd rtd; autoconf) cat/configure: cat/configure.in cat/aclocal.m4 tclconfig/tcl.m4 (cd cat; autoconf) skycat/configure: skycat/configure.in skycat/aclocal.m4 tclconfig/tcl.m4 (cd skycat; autoconf) FORCE: skycat-3.1.2-starlink-1b/README000066400000000000000000000033311215713201500160150ustar00rootroot00000000000000 Skycat Source Distribution -------------------------- Skycat is a tool that combines visualization of images with access to catalogs and archive data for astronomy. It is based on the Real Time Display (rtd) and catalog library (cat), which may also be used separately. The following URLs may also be of interest: Skycat home page: http://archive.eso.org/skycat/ Sources and binaries: ftp://ftp.eso.org/pub/archive/skycat/ (see README.html) Postscript, PDF, and FrameMaker Documentation: ftp://ftp.eso.org/pub/archive/skycat/doc HTML Docs: http://archive.eso.org/skycat/docs/skycat-man.html Installation ------------ For installation instructions, see the file INSTALL in this directory. See the CHANGES files in this directory and in the subdirectories for a list of recent changes. The Skycat application is based on the following packages: * Tclutil - Tcl and C++ Utilities * Astrotcl - Astronomical Tcl and C++ Utilities * Rtd - Real-Time Display * Cat - Catalog library * Skycat - The ESO Skycat Tool In addition, the Astrotcl package includes the sources for these C libraries: * Cfitsio - C routines for reading and writing FITS files (cfitsio-3.0.0.4: William D. Pence, HEASARC, NASA/GSFC) * Libwcs - C routines for handling world coordinates (wcstools-3.6.2, Doug Mink, Smithsonian Astrophysical Observatory) See the documentation for the above packages for more information. ------------------------------------------------------------------ Contact: Allan Brighton (abrighto@eso.org) Andreas Wicenec (awicenec@eso.org) Peter Biereichel (pbiereic@eso.org) (RTD issues) ESO - European Southern Observatory ------------------------------------------------------------------ skycat-3.1.2-starlink-1b/README.Starlink000066400000000000000000000005561215713201500176110ustar00rootroot00000000000000This is the ESO Skycat distribution imported into the ESO thirdparty vendor branch. Note none of the build mechanism is used at this level, see the directory above. Also note that this is not Skycat official and various small-level changes have been made that support GAIA, if you want the official Skycat go to the ESO download site. Peter W. Draper 25-APR-2007. skycat-3.1.2-starlink-1b/VERSION000066400000000000000000000000151215713201500162010ustar00rootroot00000000000000skycat-3.1.1 skycat-3.1.2-starlink-1b/astrotcl/000077500000000000000000000000001215713201500167705ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/astrotcl/CHANGES000066400000000000000000000314251215713201500177700ustar00rootroot00000000000000CHANGES to Astrotcl ------------------- This file contains a list of changes to the Astrotcl software. The latest changes are at the top. --------------- 16.10.08 released astrotcl-2.1.0 ---------------- * Upgraded to cfitsio version 3.0.4 (32-bit signed integer, BITPIX=32). * Upgraded to wcslib version 4.3.0 (July 25, 2007). Needed for ZPN projection. * Added support for data types double and long long int. * Added support for tiled-image compressed files. --------------- 03.02.06 released astrtcl-2.0 ------------------- * Major update: see top level CHANGES file. * Added fix from awicenec@eso.org for WorldCoords.dispos() (calculates distance between two WCS positions) * Increased NIOBUF in fitsio2.h from 25 to 128 for OmegaCam --------------- 04.04.05 released astrotcl-1.4.9 ----------------- * Generally 'using namespace std' instead of specifying ::std * Fixed compiler warning in wcs.c --------------- 20.01.03 released astrotcl-1.4.8 ----------------- * Ported to gcc-3.2.1 and Tcl-8.4.1 * Fixed bug in wcslib/src/hget.c, routine ksearch, that could cause skycat to core dump on some FITS files. (The routine called strlen() on the FITS header, which was mmap'ed and might not contain a null char). --------------- 13.12.01 released astrotcl-1.4.7 ----------------- * Enabled WCS coordinate conversion outside of the image area (by request). --------------- 27.08.01 released astrotcl-1.4.6 ----------------- * Merged in minor changes from Peter Biereichel (added some #include files). --------------- 23.08.01 released astrotcl-1.4.5 ----------------- * Fixed problem with boolean declaration in press.c (caused problems with latest linux/gcc version). --------------- 20.09.00 released astrotcl-1.4.4 ----------------- * Removed outdated wcslib source files from astrotcl/wcslib (fitsio.[ch], imhio.[ch]). --------------- 20.09.00 released astrotcl-1.4.3 ----------------- * SAOWCS.C: Fixed a bug in the display of galactic coordinates: RA was being displayed in hours and the equinox was displayed as 2000. Now RA is displayed in degrees and the equinox is displayed as "GALACTIC". * Upgraded the WCS library to wcssubs-2.8.3. * Made changes to class WorldCoords to support non-equatorial coordinates, such as GALACTIC and ECLIPTIC. Now, instead of an equinox value, you can pass in an equinox string, which may be a number (2000, 1950, etc.) or a name ("J2000", "B1950", "FK5", "FK4", "ECLIPTIC", "GALACTIC", ...). The case is not important and abbreviations are allowed (based on the wcscon routine in the wcssubs package). --------------- 02.03.00 released astrotcl-1.4.2 ----------------- * Added a check for a null coordinate string in HMS.C. --------------- 15.12.99 released astrotcl-1.4.1 ----------------- * Merged in changes made by Peter Biereichel (classes WCS, SAOWCS). --------------- 02.11.99 released astrotcl-1.4 -------------------- * Fixed a bug in HMS.C dealing with leading zeros in formatting the seconds of RA (The previous fix was incorrect). --------------- 25.10.99 released astrotcl-1.3 -------------------- * Merged in changes made by Peter Biereichel --------------- 09.09.99 released astrotcl-1.2.8 ------------------------- * Updated for egcs/gcc-2.95 --------------- 27.07.99 released astrotcl-1.2.7 ------------------------- * wcs.c, wcspix(): added "int wcsset()" declaration * wcs.c, wcsxinit(): temporary fix * wcslib/src/Makefile.in: use of 'trigod' --------------- 14.07.99 released astrotcl-1.2.7 ------------------------- * Fixed a bug in FitsIO.C that caused problems under HP-UX when loading FITS tables (was bad null value parameter for a cfitsio routine). --------------- 21.06.99 released astrotcl-1.2.6 ------------------------- * WorldCoords.C: removed error message generated when null ra or dec is passed to constructor. Now only the status is set (to avoid unwanted error messages when the ra or dec field is blank). --------------- 16.05.99 released astrotcl-1.2.5 ------------------------- * FitsIO: Merge primary header with extension header when checking for WCS keywords. --------------- 22.03.99 released astrotcl-1.2.4 ------------------------- * Replaced itclsh2.2 with itclsh@ITCL_VERSION@ in Makefile.in. * compress: Moved some global declarations from gzip.h to gzip.c to avoid linker warnings. --------------- 14.01.99 released astrotcl-1.2.3 ------------------------- * Upgraded the cfitsio sources to version cfitsio2027 (includes ESO HIERARCH keyword support). --------------- 29.12.98 released astrotcl-1.2.2 ------------------------- * FitsIO.C: bug fix: set fits_ member variable in flush(). --------------- 28.12.98 released astrotcl-1.2.1 ------------------------- * Rebuild tclIndex file whenever configure is run, since Tcl8 version is not compatible with tcl7 version (see makelinks script). * wcslib/src/iraf2fits.c: fixed undefined ref: calloc_errchk() * imageio/src/FitsIO.h: added #include "fitsio.h" to avoid sunpro compiler error message. * Removed -Xc option from configure.in (should not have been there). --------------- 03.12.98 released astrotcl-1.2 ------------------------- * Made some corrections to the "ESO HIERARCH" changes in the cfitsio sources (removed the 29 char keyword limit). * Changed cfitsio to allow lower case letters in FITS keywords (since we had some files that contained these). * Added a number of new FitsIO methods for working with HDUs and FITS tables. * Added a "realloc" method for use with cfitsio that extends the size of an image file when needed for inserting a new FITS block. --------------- 16.11.98 released astrotcl-1.1 ------------------------- * The FitsIO C++ class is now based on the CFITSIO package (URL: http://legacy.gsfc.nasa.gov/docs/software/fitsio). The public interface is backward compatible. A number of new methods are now available for accessing multiple HDUs and FITS tables. The only incompatible change is that some invalid FITS files that were previously allowed may cause an error message now (For example when keywords contain illegal characters). * Modified the CFITSIO sources files fitscore.c and getkey.c to handle ESO HIERARCH keywords. Also added "static" to some global variables in compress.c to avoid name conflicts. * Ported to Tcl8.0.3 (minor namespace changes, still compatible with Tcl7.6/Tk4.2/itcl2.2). * Changed the names of 2 global variables in the compress/gzip code, since the same code is being used by both cfitsio and tclpro, in variously hacked versions. See gzip.h for details. --------------- 30.9.98 released astrotcl-1.0.16 ------------------------- * Fixed some bugs in FitsIO.C and hput.c dealing with FITS keyword insertion. * Upgraded wcslib to (Doug Mink's) wcssubs-2.5b, which fixes some problems with COE projections and includes other bug fixes. * Changed the release structure of the astrotcl package to include the tclutil package. The top level Makefile and configure script automatically determine which packages to make. --------------- 7.9.98 released astrotcl-1.0.15 ------------------------- * HMS.C: Fixed a bug in the formatting/printing of RA values (sometimes the fractional part of the seconds was incorrect). * Updated to wcssubs-2.4 (Doug Mink's wcslib, on which the SAOWCS C++ class is based). This fixes some bugs in the handling of world coordinates rotation. --------------- 5.8.98 released astrotcl-1.0.14 ------------------------- * Added the X11 library directory to shared lib path in startup script. * Updated to wcssubs-2.3.2 (Doug Mink's wcslib, on which the SAOWCS C++ class is based). This fixes a number of bugs in the handling of world coordinates. The FitsIO class was also updated, since it uses the FITS header routines in hget.c and hput.c. * Added COE projection to wcssubs (in worldpos.c), based on previous patches from Andreas Wicenec. --------------- 07.07.98 released astrotcl-1.0.13 ------------------------- * Increased buf size for print method in util/src/HMS.C to avoid potential overflow when given bad data. * FitsIO.[Ch]: added new static method: "FitsIO::check_compress" (was not a member before) so that it can be used from outside the class. * FitsIO.C: Changed location of the temp file used when compressing or decompressing an image from "file.tmp" to /tmp/fitsioXXXXXX, since the directory that file is in may not be writable or might be on a CD. --------------- 19.6.98 released astrotcl-1.0.12 ------------------------- * HMS.C: When interpreting the RA value for world coordinates, assume decimal numbers to be in degrees and integer values to be hours. --------------- 28.5.98 released astrotcl-1.0.11 ------------------------- * FitsIO::blankImage(...), Changed generated blank images to use the normal colormap colors instead of all blank pixels, so that you can change the background color of a generated image by manipulating the colormap. * ImageIO: added methods: byteSwapData() and isclear(). --------------- 4.5.98 released astrotcl-1.0.10 ------------------------- * HMS.C: print 3 digits after the decimal point for seconds for RA values. --------------- 28.4.98 released astrotcl-1.0.9 ------------------------- * HMS.C (used by class WorldCoords): changed printing of seconds to always include leading zero i.e.: (42::12:03.51 instead of 42:12:3.51 as before). --------------- 15.4.98 released astrotcl-1.0.8 ------------------------- * FitsIO.C: Added additional suffixes for automatic compression and decompression: ".gz" for gzip, ".Z" for UNIX compression (i.e.: file.fits.Z, file.fits.gz). * Minor changes in configure script and top level makefile for shared libraries * Fixed possible bug in reference counted classes (WCS, ImageIO, Mem) by adding check for null rep_ pointer. The pointer can be null in some cases (WCS, for example, when there is no WCS information). --------------- 31.03.98 released astrotcl-1.0.7 ------------------------- * Updated man pages and documentation --------------- 25.03.98 released astrotcl-1.0.6 ------------------------- * The following changes were made to make it easier to add new image types and new WCS functionality in derived classes and should not cause any change in the external interfaces: * Class ImageIO: removed direct dependency on FitsIO class to make it possible to define new image types (by deriving a subclass of class ImageIORep). * Added a WCS object to the ImageIORep class. This can be used to optionally add world coordinates support to an image. Since WCS is a reference counted class, it is possible to replace the WCS implementation with a new one by defining a subclass of WCSRep (the internal class) that has the required interface (see below). * Renamed the WCSRep class to SAOWCS. The new WCSRep class is now an abstract base class, of which SAOWCS is a subclass. The external interfaces are the same. The change just makes it possible to add new WCS implementations in subclasses. * Compress: Upgraded to new "press" library routines to fix bug found in H-compress code (Bug was only in decompression). --------------- 05.03.98 released astrotcl-1.0.5 ------------------------- * Added static method: "set_options" to class Compress, so that you can specify scale and smoothing options for H_COMPRESS. --------------- 13.2.98 released astrotcl-1.0.4 ------------------------- * Minor changes/fixes in wcslib. --------------- 9.2.98 released astrotcl-1.0.3 ------------------------- * Fixed accuracy problems converting pixel to wcs distance. * Fixed problems with floating point precision when converting world coordinates (raised from default of 6 digits to max 17 digits.) --------------- 3.2.98 released astrotcl-1.0.2 -------------------------- * added "long int" versions of the ImageIO and FitsIO class "get" and "put" methods for reading and writing keywords. * added option to Tcl wcs command to support converting a single hh:mm:ss value to floating point and back (previous version required ra and dec, new version will also convert a single value, so that it can more easily be used in expressions). --------------- 26.01.98 released astrotcl-1.0.1 ------------------------ * WCS: There was a problem converting a WCS distance to a pixel distance on certain images (HST, for example), since the CDELT1 and CDELT2 keywords were not always defined. This has been changed now to use wcsWidth/pixWidth, which is known. --------------- released astrotcl-1.0 ----------------------------------- * Compress: Fixed bug in h_comp.h (H_COMPRESS), so that it now works on Linux (inserted calls to htonl and ntohl where needed to make it portable). * Created new package "Astrotcl" by gathering general astronomy related Tcl and C++ code from other packages into a single, reusable package. ----------- Nov 21, 1997: begin change log for Astrotcl ---------------- skycat-3.1.2-starlink-1b/astrotcl/Makefile.in000077500000000000000000000372411215713201500210470ustar00rootroot00000000000000# Makefile.in -- # # This file is a Makefile for Sample TEA Extension. If it has the name # "Makefile.in" then it is a template for a Makefile; to generate the # actual Makefile, run "./configure", which is a configuration script # generated by the "autoconf" program (constructs like "@foo@" will get # replaced in the actual Makefile). # # Copyright (c) 1999 Scriptics Corporation. # Copyright (c) 2002-2005 ActiveState Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: Makefile.in,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ #======================================================================== # Add additional lines to handle any additional AC_SUBST cases that # have been added in a customized configure script. #======================================================================== #SAMPLE_NEW_VAR = @SAMPLE_NEW_VAR@ TEST_APPS = tCompress tFitsIO tHMS tImageCoords tWorldCoords tWorldOrImageCoords TEST_LIBS = @astrotcl_LIB_SPEC@ @tclutil_LIB_SPEC@ @TCL_LIB_SPEC@ @TK_LIB_SPEC@ #======================================================================== # Nothing of the variables below this line should need to be changed. # Please check the TARGETS section below to make sure the make targets # are correct. #======================================================================== #======================================================================== # The names of the source files is defined in the configure script. # The object files are used for linking into the final library. # This will be used when a dist target is added to the Makefile. # It is not important to specify the directory, as long as it is the # $(srcdir) or in the generic, win or unix subdirectory. #======================================================================== PKG_SOURCES = @PKG_SOURCES@ PKG_OBJECTS = @PKG_OBJECTS@ PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ #======================================================================== # PKG_TCL_SOURCES identifies Tcl runtime files that are associated with # this package that need to be installed, if any. #======================================================================== PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ #======================================================================== # This is a list of public header files to be installed, if any. #======================================================================== PKG_HEADERS = @PKG_HEADERS@ #======================================================================== # "PKG_LIB_FILE" refers to the library (dynamic or static as per # configuration options) composed of the named objects. #======================================================================== PKG_LIB_FILE = @PKG_LIB_FILE@ PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ PKG_BIN_FILE = bin_BINARIES = $(PKG_BIN_FILE) lib_BINARIES = $(PKG_LIB_FILE) BINARIES = $(lib_BINARIES) $(bin_BINARIES) SHELL = @SHELL@ srcdir = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ libdir = @libdir@ datadir = @datadir@ mandir = @mandir@ includedir = @includedir@ DESTDIR = PKG_DIR = $(PACKAGE_NAME)$(PACKAGE_VERSION) pkgdatadir = $(datadir)/$(PKG_DIR) pkglibdir = $(libdir)/$(PKG_DIR) pkgincludedir = $(includedir)/$(PACKAGE_NAME) top_builddir = . INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ CC = @CC@ CXX = @CXX@ CFLAGS_DEFAULT = @CFLAGS_DEFAULT@ #CFLAGS_WARNING = @CFLAGS_WARNING@ CLEANFILES = @CLEANFILES@ $(TEST_APPS) *.result test.fits* tmp.fits *.tmp *.o tests/*.o EXEEXT = @EXEEXT@ LDFLAGS_DEFAULT = @LDFLAGS_DEFAULT@ MAKE_LIB = @MAKE_LIB@ MAKE_SHARED_LIB = @MAKE_SHARED_LIB@ MAKE_STATIC_LIB = @MAKE_STATIC_LIB@ MAKE_STUB_LIB = @MAKE_STUB_LIB@ OBJEXT = @OBJEXT@ RANLIB = @RANLIB@ RANLIB_STUB = @RANLIB_STUB@ SHLIB_CFLAGS = @SHLIB_CFLAGS@ SHLIB_LD = @SHLIB_LD@ SHLIB_LD_LIBS = @PKG_LIBS@ @SHLIB_LD_LIBS@ @SHLIB_LD_CXX_LIBS@ STLIB_LD = @STLIB_LD@ #TCL_DEFS = @TCL_DEFS@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_SRC_DIR = @TCL_SRC_DIR@ #TK_BIN_DIR = @TK_BIN_DIR@ #TK_SRC_DIR = @TK_SRC_DIR@ # Not used, but retained for reference of what libs Tcl required #TCL_LIBS = @TCL_LIBS@ #======================================================================== # TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our # package without installing. The other environment variables allow us # to test against an uninstalled Tcl. Add special env vars that you # require for testing here (like TCLX_LIBRARY). #======================================================================== EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR) #EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR) TCLLIBPATH = $(top_builddir) TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \ @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \ PATH="$(EXTRA_PATH):$(PATH)" \ TCLLIBPATH="$(TCLLIBPATH)" # TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library` TCLSH_PROG = @TCLSH_PROG@ TCLSH = $(TCLSH_ENV) $(TCLSH_PROG) #WISH_PROG = @WISH_PROG@ #WISH = $(TCLSH_ENV) $(WISH_PROG) SHARED_BUILD = @SHARED_BUILD@ #INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@ PKG_CFLAGS = @PKG_CFLAGS@ # TCL_DEFS is not strictly need here, but if you remove it, then you # must make sure that configure.in checks for the necessary components # that your library may use. TCL_DEFS can actually be a problem if # you do not compile with a similar machine setup as the Tcl core was # compiled with. #DEFS = $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS) DEFS = @DEFS@ $(PKG_CFLAGS) CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl ${PACKAGE_NAME}Config.sh ${PACKAGE_NAME}.sh ${PACKAGE_NAME}_version.tcl CPPFLAGS = @CPPFLAGS@ LIBS = @PKG_LIBS@ @LIBS@ AR = @AR@ CFLAGS = @CFLAGS@ CXXFLAGS = @CXXFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(CXXFLAGS) #======================================================================== # Start of user-definable TARGETS section #======================================================================== #======================================================================== # TEA TARGETS. Please note that the "libraries:" target refers to platform # independent files, and the "binaries:" target inclues executable programs and # platform-dependent libraries. Modify these targets so that they install # the various pieces of your package. The make and install rules # for the BINARIES that you specified above have already been done. #======================================================================== all: binaries libraries doc tclIndex #======================================================================== # The binaries target builds executable programs, Windows .dll's, unix # shared/static libraries, and any other platform-dependent files. # The list of targets to build for "binaries:" is specified at the top # of the Makefile, in the "BINARIES" variable. #======================================================================== binaries: $(BINARIES) libraries: tclIndex: (cd $(srcdir)/library; $(TCLSH_PROG) mkIndex.tcl) #======================================================================== # Your doc target should differentiate from doc builds (by the developer) # and doc installs (see install-doc), which just install the docs on the # end user machine when building from source. #======================================================================== doc: # generate man pages for itcl classes gendoc: (cd $(srcdir)/library; $(TCLSH) itcldoc [A-Z]*.tcl) # remove generated man pages cleandoc: rm -f $(srcdir)/man/[A-Z]*.mann install: all install-binaries install-libraries install-doc install-binaries: binaries install-lib-binaries install-bin-binaries #======================================================================== # This rule installs platform-independent files, such as header files. # The list=...; for p in $$list handles the empty list case x-platform. #======================================================================== install-libraries: libraries @test -d $(DESTDIR)$(pkgincludedir) || mkdir -p $(DESTDIR)$(pkgincludedir) @echo "Installing header files in $(DESTDIR)$(pkgincludedir)" @list='$(PKG_HEADERS)'; for i in $$list; do \ echo "Installing $(srcdir)/$$i" ; \ $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(pkgincludedir) ; \ done; #======================================================================== # Install documentation. Unix manpages should go in the $(mandir) # directory. #======================================================================== install-doc: #install-doc: doc # @mkdir -p $(DESTDIR)$(mandir)/mann # @echo "Installing documentation in $(DESTDIR)$(mandir)" # @list='$(srcdir)/doc/*.n'; for i in $$list; do \ # echo "Installing $$i"; \ # rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \ # $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \ # done shell: binaries libraries @$(TCLSH) $(SCRIPT) gdb: $(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT) depend: #======================================================================== # $(PKG_LIB_FILE) should be listed as part of the BINARIES variable # mentioned above. That will ensure that this target is built when you # run "make binaries". # # The $(PKG_OBJECTS) objects are created and linked into the final # library. In most cases these object files will correspond to the # source files above. #======================================================================== $(PKG_LIB_FILE): $(PKG_OBJECTS) -rm -f $(PKG_LIB_FILE) ${MAKE_LIB} $(RANLIB) $(PKG_LIB_FILE) #$(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS) # -rm -f $(PKG_STUB_LIB_FILE) # ${MAKE_STUB_LIB} # $(RANLIB_STUB) $(PKG_STUB_LIB_FILE) #======================================================================== # We need to enumerate the list of .c to .o lines here. # # In the following lines, $(srcdir) refers to the toplevel directory # containing your extension. If your sources are in a subdirectory, # you will have to modify the paths to reflect this: # # sample.$(OBJEXT): $(srcdir)/generic/sample.c # $(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@ # # Setting the VPATH variable to a list of paths will cause the makefile # to look into these paths when resolving .c to .obj dependencies. # As necessary, add $(srcdir):$(srcdir)/compat:.... #======================================================================== VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/press:$(srcdir)/libwcs .c.@OBJEXT@: $(COMPILE) -c `@CYGPATH@ $<` -o $@ .C.@OBJEXT@: $(CXXCOMPILE) -c `@CYGPATH@ $<` -o $@ #======================================================================== # End of user-definable section #======================================================================== #======================================================================== # Don't modify the file to clean here. Instead, set the "CLEANFILES" # variable in configure.in #======================================================================== clean: -test -z "$(BINARIES)" || rm -f $(BINARIES) -rm -f *.$(OBJEXT) core *.core -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean: clean -rm -f *.tab.c -rm -f $(CONFIG_CLEAN_FILES) -rm -rf config.cache config.log config.status autom4te.cache #======================================================================== # Install binary object libraries. On Windows this includes both .dll and # .lib files. Because the .lib files are not explicitly listed anywhere, # we need to deduce their existence from the .dll file of the same name. # Library files go into the lib directory. # In addition, this will generate the pkgIndex.tcl # file in the install location (assuming it can find a usable tclsh shell) # # You should not have to modify this target. #======================================================================== install-lib-binaries: binaries @test -d $(DESTDIR)$(pkglibdir) || mkdir -p $(DESTDIR)$(pkglibdir) @list='$(lib_BINARIES)'; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libdir)/$$p"; \ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libdir)/$$p; \ stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \ if test "x$$stub" = "xstub"; then \ echo " $(RANLIB_STUB) $(DESTDIR)$(libdir)/$$p"; \ $(RANLIB_STUB) $(DESTDIR)$(libdir)/$$p; \ else \ echo " $(RANLIB) $(DESTDIR)$(libdir)/$$p"; \ $(RANLIB) $(DESTDIR)$(libdir)/$$p; \ fi; \ ext=`echo $$p|sed -e "s/.*\.//"`; \ if test "x$$ext" = "xdll"; then \ lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \ if test -f $$lib; then \ echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(libdir)/$$lib"; \ $(INSTALL_DATA) $$lib $(DESTDIR)$(libdir)/$$lib; \ fi; \ fi; \ fi; \ done @echo " Install $(PACKAGE_NAME)Config.sh $(DESTDIR)$(libdir)" @$(INSTALL_DATA) $(PACKAGE_NAME)Config.sh $(DESTDIR)$(libdir); @list='$(PKG_TCL_SOURCES) library/tclIndex'; for p in $$list; do \ if test -f $(srcdir)/$$p; then \ destp=`basename $$p`; \ echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \ fi; \ done @if test "x$(SHARED_BUILD)" = "x1"; then \ echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \ $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \ fi #======================================================================== # Install binary executables (e.g. .exe files and dependent .dll files) # This is for files that must go in the bin directory (located next to # wish and tclsh), like dependent .dll files on Windows. # # You should not have to modify this target, except to define bin_BINARIES # above if necessary. #======================================================================== install-bin-binaries: binaries @test -d $(DESTDIR)$(bindir) || mkdir -p $(DESTDIR)$(bindir) @list='$(bin_BINARIES)'; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \ fi; \ done .SUFFIXES: .c .$(OBJEXT) .C Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status uninstall-binaries: list='$(lib_BINARIES)'; for p in $$list; do \ rm -f $(DESTDIR)$(pkglibdir)/$$p; \ done list='$(PKG_TCL_SOURCES)'; for p in $$list; do \ p=`basename $$p`; \ rm -f $(DESTDIR)$(pkglibdir)/$$p; \ done list='$(bin_BINARIES)'; for p in $$list; do \ rm -f $(DESTDIR)$(bindir)/$$p; \ done .PHONY: all binaries clean depend distclean doc install libraries test # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: #======================================================================== # Run C++ Test cases #======================================================================== test: binaries libraries $(TEST_APPS) $(TEST_APPS): FORCE $(CXXCOMPILE) -o $@ $(srcdir)/tests/$@.C $(TEST_LIBS) cp $(srcdir)/tests/test.fits . -@@LD_LIBRARY_PATH_VAR@=@exec_prefix@/lib; export @LD_LIBRARY_PATH_VAR@ ;\ $@ > $@.result 2>&1 ;\ if cmp $@.result $(srcdir)/tests/$@.ok ;\ then echo "$@: PASSED" ; \ else echo "*** $@: TEST FAILED: see $@.result" ; \ fi rm test.fits #======================================================================== # Run Tcl test cases #======================================================================== #tcltest: binaries libraries # (cd tests; sh all.tcl) FORCE: skycat-3.1.2-starlink-1b/astrotcl/README000066400000000000000000000016501215713201500176520ustar00rootroot00000000000000 Astrotcl, C++ Library and Tcl Package for Astronomical Software --------------------------------------------------------------- The Astrotcl package contains a collection of C, C++ and Tcl utilities related to astronomical software. It contains support for manipulating World Coordinates and images in FITS format, and image compression and decompression. The library may be loaded dynamically as a Tcl package with the Tcl command: package require Astrotcl For installation instructions, see the file INSTALL in the parent directory. See the CHANGES file in this directory for a list of recent changes. The following URLs may also be of interest: Skycat home page: http://archive.eso.org/skycat/ Sources and binaries: ftp://ftp.eso.org/pub/archive/skycat/README.html Postscript, PDF, and FrameMaker Documentation: ftp://ftp.eso.org/pub/archive/skycat/doc HTML Docs: http://archive.eso.org/skycat/docs/skycat-man.html skycat-3.1.2-starlink-1b/astrotcl/VERSION000066400000000000000000000000171215713201500200360ustar00rootroot00000000000000astrotcl-2.1.0 skycat-3.1.2-starlink-1b/astrotcl/aclocal.m4000066400000000000000000000140161215713201500206320ustar00rootroot00000000000000builtin(include,../tclconfig/tcl.m4) AC_DEFUN(ASTROTCL_CONFIG, [ # Load the Tclutil definitions cf=../tclutil/tclutilConfig.sh if test -f $cf ; then . $cf AC_SUBST(tclutil_VERSION) AC_SUBST(tclutil_LIB_FILE) AC_SUBST(tclutil_BUILD_LIB_SPEC) AC_SUBST(tclutil_LIB_SPEC) AC_SUBST(BLT_LIB_SPEC) AC_SUBST(tclutil_SRC_DIR) AC_SUBST(CFITSIO_LIB_SPEC) else AC_MSG_ERROR([$cf doesn't exist]) fi AC_CHECK_HEADERS(sys/filio.h) # Check if we need (or can use) the socklen_t type. AC_CHECK_TYPES([socklen_t],,,[#include ]) AC_DEFINE(USE_COMPAT_CONST, 1, [For compatibility between tcl8.4 and previous tcl releases]) #-------------------------------------------------------------------- # From the cfitsio configure script #-------------------------------------------------------------------- AC_CHECK_HEADERS(stdlib.h string.h math.h limits.h ,ANSI_HEADER=yes,ANSI_HEADER=no)dnl # ================= test for the unix ftruncate function ================ AC_MSG_CHECKING("whether ftruncate works") AC_TRY_LINK([#include ], [ ftruncate(0, 0); ], [ AC_DEFINE(HAVE_FTRUNCATE) AC_MSG_RESULT("yes") ], AC_MSG_RESULT("no") ) # --------------------------------------------------------- # some systems define long long for 64-bit ints # --------------------------------------------------------- AC_MSG_CHECKING("whether long long is defined") AC_TRY_COMPILE([#include ], [ long long filler; ], [ AC_DEFINE(HAVE_LONGLONG) AC_MSG_RESULT("yes") ], AC_MSG_RESULT("no") ) # ------------------------------------------------------------------------- # check is System V IPC is supported on this machine # ------------------------------------------------------------------------- AC_MSG_CHECKING("whether system V style IPC services are supported") AC_TRY_LINK([#include #include #include ], [ shmat(0, 0, 0); shmdt(0); shmget(0, 0, 0); semget(0, 0, 0); ], [ AC_DEFINE(HAVE_SHMEM_SERVICES) my_shmem=\${SOURCES_SHMEM} AC_MSG_RESULT("yes") ], AC_MSG_RESULT("no") ) AC_SUBST(my_shmem) # ------------------------------------------------------------------------- # some systems define flock_t, for others we have to define it ourselves # ------------------------------------------------------------------------- AC_MSG_CHECKING("do we have flock_t defined in sys/fcntl.h") AC_TRY_COMPILE([#include ], [ flock_t filler; ], [ AC_DEFINE(HAVE_FLOCK_T) AC_MSG_RESULT("yes") ], AC_MSG_RESULT("no") ) if test "$HAVE_FLOCK_T" != 1; then AC_MSG_CHECKING("do we have flock_t defined in sys/flock.h") AC_TRY_COMPILE([#include ], [ flock_t filler; ], [ AC_DEFINE(HAVE_FLOCK_T) AC_MSG_RESULT("yes") ], AC_MSG_RESULT("no") ) fi # ------------------------------------------------------------------------- # there are some idiosyncrasies with semun defs (used in semxxx). Solaris # does not define it at all # ------------------------------------------------------------------------- AC_MSG_CHECKING("do we have union semun defined") AC_TRY_COMPILE( [#include #include #include #include ], [ union semun filler; ], [ AC_DEFINE(HAVE_UNION_SEMUN) AC_MSG_RESULT("yes") ], AC_MSG_RESULT("no") ) AC_DEFINE(HAVE_NET_SERVICES) # ==================== END OF cfitsio SECTION ================ #------------------------------------------------------------------------ # ASTROTCL_PATH_CFITSIO -- # # Locate the CFITSIO library # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-cfitsio=... # # Defines the following vars: # CFITSIO_LIB_SPEC String to add to link the CFITSIO lib (-L... -lBLT) # CFITSIO_LIB_DIR Directory containing libcfitsio.so #------------------------------------------------------------------------ AC_DEFUN(ASTROTCL_PATH_CFITSIO, [ AC_MSG_CHECKING(for CFITSIO library) AC_ARG_WITH(cfitsio, [AC_HELP_STRING([--with-cfitsio=DIR],[link with CFITSIO library installed in DIR])], CFITSIO_LIB_DIR=$withval) CFITSIO_LIBNAME=libcfitsio${SHLIB_SUFFIX} CFITSIO_LIBFLAG=-lcfitsio if test -z "$CFITSIO_LIB_DIR" ; then # If --with-cfitsio=dir was not specified, try the exec-prefix/lib dir places="\ $exec_prefix/lib \ $prefix/lib \ " for i in $places ; do if test -f $i/$CFITSIO_LIBNAME then CFITSIO_LIB_DIR=$i break fi done if test -z "$CFITSIO_LIB_DIR" ; then echo AC_MSG_ERROR([could not find $CFITSIO_LIBNAME: Please use the --with-cfitsio=DIR option.]) fi else # Just assume the given value will work. This may not be true if # CFITSIO itself isn't built yet, so allow the flexibility. CFITSIO_LIB_DIR=$CFITSIO_LIB_DIR/lib fi CFITSIO_LIB_SPEC="-L$CFITSIO_LIB_DIR $CFITSIO_LIBFLAG" AC_MSG_RESULT($CFITSIO_LIB_DIR) AC_SUBST(CFITSIO_LIB_DIR) AC_SUBST(CFITSIO_LIB_SPEC) ]) #------------------------------------------------------------------------ # Check if we require additional libraries to support C++ shareable # libraries. system=`uname -s`-`uname -r` SHLIB_LD_CXX_LIBS="" export SHLIB_LD_CXX_LIBS case $system in SunOS-5*) SHLIB_LD_CXX_LIBS="-lCrun -lCstd" ;; OSF*) SHLIB_LD_CXX_LIBS="-lcxx -lcxxstd" ;; esac AC_SUBST(SHLIB_LD_CXX_LIBS) #------------------------------------------------------------------------- # The cxx C++ compiler under Tru64 UNIX needs the special # CXXFLAGS "-std gnu -D__USE_STD_IOSTREAM=1". These allow the standard # library streams headers to work and to generate templates that do # not require special handling throughout skycat directories (normally # template object files are created in various cxx_repository subdirectories, # this way the object files are kept embedded the usual object files, see # the cxx man page for details). #------------------------------------------------------------------------- export CXXFLAGS case $system in OSF*) case "x$CXX" in xcxx*) CXXFLAGS="$CXXFLAGS -g3 -std gnu -D__USE_STD_IOSTREAM=1" ;; esac ;; esac ]) skycat-3.1.2-starlink-1b/astrotcl/astrotclConfig.sh.in000066400000000000000000000037111215713201500227140ustar00rootroot00000000000000# E.S.O. - VLT project # $Id: astrotclConfig.sh.in,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # astrotclConfig.sh -- # # This shell script (for sh) is generated automatically by Astrotcl's # configure script. It will create shell variables for most of # the configuration options discovered by the configure script. # This script is intended to be included by the configure scripts # for Astrotcl extensions so that they don't have to figure this all # out for themselves. This file does not duplicate information # already provided by tclConfig.sh, so you may need to use that # file in addition to this one. # # The information in this file is specific to a single platform. # Astrotcl's version number. astrotcl_VERSION='@PACKAGE_VERSION@' # The name of the Astrotcl library: astrotcl_LIB_FILE=@astrotcl_LIB_FILE@ # Astrotcl build directory. astrotcl_BUILD_DIR='@astrotcl_BUILD_DIR@' # String to pass to linker to pick up the Astrotcl library from its # build directory. astrotcl_BUILD_LIB_SPEC='@astrotcl_BUILD_LIB_SPEC@' # String to pass to linker to pick up the Astrotcl library from its # installed directory. astrotcl_LIB_SPEC='@astrotcl_LIB_SPEC@' # Location of the top-level source directories from which Astrotcl # was built. This is the directory that contains generic, unix, etc. # If Astrotcl was compiled in a different place than the directory # containing the source files, this points to the location of the sources, # not the location where Astrotcl was compiled. astrotcl_SRC_DIR='@astrotcl_SRC_DIR@' # List of object files used to build the library (for merging packages). astrotcl_PKG_OBJECTS='@astrotcl_PKG_OBJECTS@' # List of header filesinstalled for this library (for merging packages). astrotcl_PKG_HEADERS='@astrotcl_PKG_HEADERS@' # String to pass to linker to pick up the CFITSIO library from its # installed directory. CFITSIO_LIB_SPEC='@CFITSIO_LIB_SPEC@' # Directory containing the CFITSIO shared library CFITSIO_LIB_DIR='@CFITSIO_LIB_DIR@' skycat-3.1.2-starlink-1b/astrotcl/cfitsio/000077500000000000000000000000001215713201500204305ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/astrotcl/cfitsio/README000066400000000000000000000143241215713201500213140ustar00rootroot00000000000000 CFITSIO Interface Library CFITSIO is a library of ANSI C routines for reading and writing FITS format data files. A set of Fortran-callable wrapper routines are also included for the convenience of Fortran programmers. This README file gives a brief summary of how to build and test CFITSIO, but the CFITSIO User's Guide, found in the files cfitsio.doc (plain text), cfitsio.tex (LaTeX source file), or cfitsio.ps (postscript format), should be referenced for the latest and most complete information. BUILDING CFITSIO ---------------- The CFITSIO code is contained in about 40 *.c source files and several *.h header files. The CFITSIO library is built on Unix systems by typing: > ./configure [--prefix=/target/installation/path] > make (or 'make shared') > make install (this step is optional) at the operating system prompt. The configure command customizes the Makefile for the particular system, then the `make' command compiles the source files and builds the library. Type `./configure' and not simply `configure' to ensure that the configure script in the current directory is run and not some other system-wide configure script. The optional 'prefix' argument to configure gives the path to the directory where the CFITSIO library and include files should be installed via the later 'make install' command. For example, > ./configure --prefix=/usr1/local will cause the 'make install' command to copy the CFITSIO libcfitsio file to /usr1/local/lib and the necessary include files to /usr1/local/include (assuming of course that the process has permission to write to these directories). On VAX/VMS and ALPHA/VMS systems the make.com command file may be used to build the cfitsio.olb object library using the default G-floating point option for double variables. The make\_dfloat.com and make\_ieee.com files may be used instead to build the library with the other floating point options. A precompiled DLL version of CFITSIO is available for IBM-PC users of the Borland or Microsoft Visual C++ compilers in the files cfitsiodll_2xxx_borland.zip and cfitsiodll_2xxx_vcc.zip, where '2xxx' represents the current release number. These zip archives also contains other files and instructions on how to use the CFITSIO DLL library. The CFITSIO library may also be built from the source code using the makefile.bc or makefile.vcc files. Finally, the makepc.bat file gives an example of building CFITSIO with the Borland C++ v4.5 compiler using simpler DOS commands. On OS/2 systems, CFITSIO can be built using the supplied makefile by typing 'make -f makefile.os2'. This makefile requires the GCC compiler and EMX library, which are available from many Internet sites containing OS/2 software, such as ftp-os2.nmsu.edu/pub/os2/dev/emx/v0.9c and ftp.leo.org/pub/comp/os/os2/leo/devtools/emx+gcc. When building on Mac OS-X, users should follow the Unix instructions, above. Previous MacOS versions of the cfitsio library can be built by (1) un binhex and unstuff cfitsio_mac.sit.hqx, (2) put CFitsioPPC.mcp in the cfitsio directory, and (3) load CFitsioPPC.mcp into CodeWarrior Pro 5 and make. This builds the cfitsio library for PPC. There are also targets for both the test program and the speed test program. To use the MacOS port you can add Cfitsio PPC.lib to your Codewarrior Pro 5 project. Note that this only has been tested for the PPC and probably won't work on 68k macs. TESTING CFITSIO --------------- The CFITSIO library should be tested by building and running the testprog.c program that is included with the release. On Unix systems, type: - % make testprog % testprog > testprog.lis % diff testprog.lis testprog.out % cmp testprog.fit testprog.std - On VMS systems, (assuming cc is the name of the C compiler command), type: - $ cc testprog.c $ link testprog, cfitsio/lib $ run testprog - The testprog program should produce a FITS file called `testprog.fit' that is identical to the testprog.std FITS file included in this release. The diagnostic messages (which were piped to the file testprog.lis in the Unix example) should be identical to the listing contained in the file testprog.out. The 'diff' and 'cmp' commands shown above should not report any differences in the files. USING CFITSIO ------------- The CFITSIO User's Guide, contained in the files cfitsio.doc (plain text file) and cfitsio.ps (postscript file), provides detailed documentation about how to build and use the CFITSIO library. It contains a description of every user-callable routine in the CFITSIO interface. The cookbook.c file provides some sample routines for performing common operations on various types of FITS files. Programmers are urged to examine these routines for recommended programming practices when using CFITSIO. Users are free to copy or modify these routines for their own purposes. SUPPORTED PLATFORMS ------------------- CFITSIO has currently been tested on the following platforms: Operating System Compiler ---------------- -------- OPERATING SYSTEM COMPILER Sun OS gcc and cc (3.0.1) Sun Solaris gcc and cc Silicon Graphics IRIX gcc and cc Silicon Graphics IRIX64 MIPS Dec Alpha OSF/1 gcc and cc DECstation Ultrix gcc Dec Alpha OpenVMS cc DEC VAX/VMS gcc and cc HP-UX gcc IBM AIX gcc Linux gcc MkLinux DR3 Windows 95/98/NT Borland C++ V4.5 Windows 95/98/NT/ME/XP Microsoft/Compaq Visual C++ v5.0, v6.0 Windows 95/98/NT Cygwin gcc OS/2 gcc + EMX Mac OS 7.1 or greater Metrowerks 10.+ Mac OS-X 10.1 or greater cc (gcc) CFITSIO will probably run on most other Unix platforms without modification. Cray supercomputers and IBM mainframe computers are currently not supported. Reports of any success or failure to run CFITSIO on other platforms would be appreciated. Any problem reports or suggestions for improvements are also welcome and should be sent to the primary author. ------------------------------------------------------------------------- William D. Pence pence@tetra.gsfc.nasa.gov HEASARC, NASA/GSFC skycat-3.1.2-starlink-1b/astrotcl/cfitsio/VERSION000066400000000000000000000000161215713201500214750ustar00rootroot00000000000000cfitsio-3.0.4 skycat-3.1.2-starlink-1b/astrotcl/cfitsio/buffers.c000066400000000000000000001521171215713201500222370ustar00rootroot00000000000000/* This file, buffers.c, contains the core set of FITSIO routines */ /* that use or manage the internal set of IO buffers. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" static char iobuffer[NIOBUF][IOBUFLEN]; /* initialize to zero by default */ static FITSfile *bufptr[NIOBUF]; /* initialize to zero by default */ static long bufrecnum[NIOBUF]; /* initialize to zero by default */ static int dirty[NIOBUF], ageindex[NIOBUF]; /* ages get initialized in ffwhbf */ /*--------------------------------------------------------------------------*/ int ffmbyt(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG bytepos, /* I - byte position in file to move to */ int err_mode, /* I - 1=ignore error, 0 = return error */ int *status) /* IO - error status */ { /* Move to the input byte location in the file. When writing to a file, a move may sometimes be made to a position beyond the current EOF. The err_mode parameter determines whether such conditions should be returned as an error or simply ignored. */ long record; if (*status > 0) return(*status); if (bytepos < 0) return(*status = NEG_FILE_POS); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); record = (long) (bytepos / IOBUFLEN); /* zero-indexed record number */ /* if this is not the current record, then load it */ if ( ((fptr->Fptr)->curbuf < 0) || (record != bufrecnum[(fptr->Fptr)->curbuf])) ffldrc(fptr, record, err_mode, status); if (*status <= 0) (fptr->Fptr)->bytepos = bytepos; /* save new file position */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpbyt(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG nbytes, /* I - number of bytes to write */ void *buffer, /* I - buffer containing the bytes to write */ int *status) /* IO - error status */ /* put (write) the buffer of bytes to the output FITS file, starting at the current file position. Write large blocks of data directly to disk; write smaller segments to intermediate IO buffers to improve efficiency. */ { int ii, nbuff; LONGLONG filepos; long recstart, recend; long ntodo, bufpos, nspace, nwrite; char *cptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); cptr = (char *)buffer; ntodo = (long) nbytes; if ((fptr->Fptr)->curbuf < 0) /* no current data buffer for this file */ { /* so reload the last one that was used */ ffldrc(fptr, (long) (((fptr->Fptr)->bytepos) / IOBUFLEN), REPORT_EOF, status); } if (nbytes >= MINDIRECT) { /* write large blocks of data directly to disk instead of via buffers */ /* first, fill up the current IO buffer before flushing it to disk */ nbuff = (fptr->Fptr)->curbuf; /* current IO buffer number */ filepos = (fptr->Fptr)->bytepos; /* save the write starting position */ recstart = bufrecnum[nbuff]; /* starting record */ recend = (long) ((filepos + nbytes - 1) / IOBUFLEN); /* ending record */ /* bufpos is the starting position within the IO buffer */ bufpos = (long) (filepos - ((LONGLONG)recstart * IOBUFLEN)); nspace = IOBUFLEN - bufpos; /* amount of space left in the buffer */ if (nspace) { /* fill up the IO buffer */ memcpy(iobuffer[nbuff] + bufpos, cptr, nspace); ntodo -= nspace; /* decrement remaining number of bytes */ cptr += nspace; /* increment user buffer pointer */ filepos += nspace; /* increment file position pointer */ dirty[nbuff] = TRUE; /* mark record as having been modified */ } for (ii = 0; ii < NIOBUF; ii++) /* flush any affected buffers to disk */ { if (bufptr[ii] == fptr->Fptr && bufrecnum[ii] >= recstart && bufrecnum[ii] <= recend ) { if (dirty[ii]) /* flush modified buffer to disk */ ffbfwt(ii, status); bufptr[ii] = NULL; /* disassociate buffer from the file */ } } /* move to the correct write position */ if ((fptr->Fptr)->io_pos != filepos) ffseek(fptr->Fptr, filepos); nwrite = ((ntodo - 1) / IOBUFLEN) * IOBUFLEN; /* don't write last buff */ ffwrite(fptr->Fptr, nwrite, cptr, status); /* write the data */ ntodo -= nwrite; /* decrement remaining number of bytes */ cptr += nwrite; /* increment user buffer pointer */ (fptr->Fptr)->io_pos = filepos + nwrite; /* update the file position */ if ((fptr->Fptr)->io_pos >= (fptr->Fptr)->filesize) /* at the EOF? */ { (fptr->Fptr)->filesize = (fptr->Fptr)->io_pos; /* increment file size */ /* initialize the current buffer with the correct fill value */ if ((fptr->Fptr)->hdutype == ASCII_TBL) memset(iobuffer[nbuff], 32, IOBUFLEN); /* blank fill */ else memset(iobuffer[nbuff], 0, IOBUFLEN); /* zero fill */ } else { /* read next record */ ffread(fptr->Fptr, IOBUFLEN, iobuffer[nbuff], status); (fptr->Fptr)->io_pos += IOBUFLEN; } /* copy remaining bytes from user buffer into current IO buffer */ memcpy(iobuffer[nbuff], cptr, ntodo); dirty[nbuff] = TRUE; /* mark record as having been modified */ bufrecnum[nbuff] = recend; /* record number */ bufptr[nbuff] = fptr->Fptr; /* file pointer associated with IO buffer */ (fptr->Fptr)->logfilesize = maxvalue((fptr->Fptr)->logfilesize, (LONGLONG)(recend + 1) * IOBUFLEN); (fptr->Fptr)->bytepos = filepos + nwrite + ntodo; } else { /* bufpos is the starting position in IO buffer */ bufpos = (long) ((fptr->Fptr)->bytepos - ((LONGLONG)bufrecnum[(fptr->Fptr)->curbuf] * IOBUFLEN)); nspace = IOBUFLEN - bufpos; /* amount of space left in the buffer */ while (ntodo) { nwrite = minvalue(ntodo, nspace); /* copy bytes from user's buffer to the IO buffer */ memcpy(iobuffer[(fptr->Fptr)->curbuf] + bufpos, cptr, nwrite); ntodo -= nwrite; /* decrement remaining number of bytes */ cptr += nwrite; (fptr->Fptr)->bytepos += nwrite; /* increment file position pointer */ dirty[(fptr->Fptr)->curbuf] = TRUE; /* mark record as modified */ if (ntodo) /* load next record into a buffer */ { ffldrc(fptr, (long) ((fptr->Fptr)->bytepos / IOBUFLEN), IGNORE_EOF, status); bufpos = 0; nspace = IOBUFLEN; } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffpbytoff(fitsfile *fptr, /* I - FITS file pointer */ long gsize, /* I - size of each group of bytes */ long ngroups, /* I - number of groups to write */ long offset, /* I - size of gap between groups */ void *buffer, /* I - buffer to be written */ int *status) /* IO - error status */ /* put (write) the buffer of bytes to the output FITS file, with an offset between each group of bytes. This function combines ffmbyt and ffpbyt for increased efficiency. */ { int bcurrent; long ii, bufpos, nspace, nwrite, record; char *cptr, *ioptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ((fptr->Fptr)->curbuf < 0) /* no current data buffer for this file */ { /* so reload the last one that was used */ ffldrc(fptr, (long) (((fptr->Fptr)->bytepos) / IOBUFLEN), REPORT_EOF, status); } cptr = (char *)buffer; bcurrent = (fptr->Fptr)->curbuf; /* number of the current IO buffer */ record = bufrecnum[bcurrent]; /* zero-indexed record number */ bufpos = (long) ((fptr->Fptr)->bytepos - ((LONGLONG)record * IOBUFLEN)); /* start pos */ nspace = IOBUFLEN - bufpos; /* amount of space left in buffer */ ioptr = iobuffer[bcurrent] + bufpos; for (ii = 1; ii < ngroups; ii++) /* write all but the last group */ { /* copy bytes from user's buffer to the IO buffer */ nwrite = minvalue(gsize, nspace); memcpy(ioptr, cptr, nwrite); cptr += nwrite; /* increment buffer pointer */ if (nwrite < gsize) /* entire group did not fit */ { dirty[bcurrent] = TRUE; /* mark record as having been modified */ record++; ffldrc(fptr, record, IGNORE_EOF, status); /* load next record */ bcurrent = (fptr->Fptr)->curbuf; ioptr = iobuffer[bcurrent]; nwrite = gsize - nwrite; memcpy(ioptr, cptr, nwrite); cptr += nwrite; /* increment buffer pointer */ ioptr += (offset + nwrite); /* increment IO buffer pointer */ nspace = IOBUFLEN - offset - nwrite; /* amount of space left */ } else { ioptr += (offset + nwrite); /* increment IO bufer pointer */ nspace -= (offset + nwrite); } if (nspace <= 0) /* beyond current record? */ { dirty[bcurrent] = TRUE; record += ((IOBUFLEN - nspace) / IOBUFLEN); /* new record number */ ffldrc(fptr, record, IGNORE_EOF, status); bcurrent = (fptr->Fptr)->curbuf; bufpos = (-nspace) % IOBUFLEN; /* starting buffer pos */ nspace = IOBUFLEN - bufpos; ioptr = iobuffer[bcurrent] + bufpos; } } /* now write the last group */ nwrite = minvalue(gsize, nspace); memcpy(ioptr, cptr, nwrite); cptr += nwrite; /* increment buffer pointer */ if (nwrite < gsize) /* entire group did not fit */ { dirty[bcurrent] = TRUE; /* mark record as having been modified */ record++; ffldrc(fptr, record, IGNORE_EOF, status); /* load next record */ bcurrent = (fptr->Fptr)->curbuf; ioptr = iobuffer[bcurrent]; nwrite = gsize - nwrite; memcpy(ioptr, cptr, nwrite); } dirty[bcurrent] = TRUE; /* mark record as having been modified */ (fptr->Fptr)->bytepos = (fptr->Fptr)->bytepos + (ngroups * gsize) + (ngroups - 1) * offset; return(*status); } /*--------------------------------------------------------------------------*/ int ffgbyt(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG nbytes, /* I - number of bytes to read */ void *buffer, /* O - buffer to read into */ int *status) /* IO - error status */ /* get (read) the requested number of bytes from the file, starting at the current file position. Read large blocks of data directly from disk; read smaller segments via intermediate IO buffers to improve efficiency. */ { int ii; LONGLONG filepos; long recstart, recend, ntodo, bufpos, nspace, nread; char *cptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); cptr = (char *)buffer; if (nbytes >= MINDIRECT) { /* read large blocks of data directly from disk instead of via buffers */ filepos = (fptr->Fptr)->bytepos; /* save the read starting position */ /* note that in this case, ffmbyt has not been called, and so */ /* bufrecnum[(fptr->Fptr)->curbuf] does not point to the intended */ /* output buffer */ recstart = (long) (filepos / IOBUFLEN); /* starting record */ recend = (long) ((filepos + nbytes - 1) / IOBUFLEN); /* ending record */ for (ii = 0; ii < NIOBUF; ii++) /* flush any affected buffers to disk */ { if (dirty[ii] && bufptr[ii] == fptr->Fptr && bufrecnum[ii] >= recstart && bufrecnum[ii] <= recend) { ffbfwt(ii, status); /* flush modified buffer to disk */ } } /* move to the correct read position */ if ((fptr->Fptr)->io_pos != filepos) ffseek(fptr->Fptr, filepos); ffread(fptr->Fptr, (long) nbytes, cptr, status); /* read the data */ (fptr->Fptr)->io_pos = filepos + nbytes; /* update the file position */ } else { /* read small chucks of data using the IO buffers for efficiency */ if ((fptr->Fptr)->curbuf < 0) /* no current data buffer for this file */ { /* so reload the last one that was used */ ffldrc(fptr, (long) (((fptr->Fptr)->bytepos) / IOBUFLEN), REPORT_EOF, status); } /* bufpos is the starting position in IO buffer */ bufpos = (long) ((fptr->Fptr)->bytepos - ((LONGLONG)bufrecnum[(fptr->Fptr)->curbuf] * IOBUFLEN)); nspace = IOBUFLEN - bufpos; /* amount of space left in the buffer */ ntodo = (long) nbytes; while (ntodo) { nread = minvalue(ntodo, nspace); /* copy bytes from IO buffer to user's buffer */ memcpy(cptr, iobuffer[(fptr->Fptr)->curbuf] + bufpos, nread); ntodo -= nread; /* decrement remaining number of bytes */ cptr += nread; (fptr->Fptr)->bytepos += nread; /* increment file position pointer */ if (ntodo) /* load next record into a buffer */ { ffldrc(fptr, (long) ((fptr->Fptr)->bytepos / IOBUFLEN), REPORT_EOF, status); bufpos = 0; nspace = IOBUFLEN; } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgbytoff(fitsfile *fptr, /* I - FITS file pointer */ long gsize, /* I - size of each group of bytes */ long ngroups, /* I - number of groups to read */ long offset, /* I - size of gap between groups (may be < 0) */ void *buffer, /* I - buffer to be filled */ int *status) /* IO - error status */ /* get (read) the requested number of bytes from the file, starting at the current file position. This function combines ffmbyt and ffgbyt for increased efficiency. */ { int bcurrent; long ii, bufpos, nspace, nread, record; char *cptr, *ioptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ((fptr->Fptr)->curbuf < 0) /* no current data buffer for this file */ { /* so reload the last one that was used */ ffldrc(fptr, (long) (((fptr->Fptr)->bytepos) / IOBUFLEN), REPORT_EOF, status); } cptr = (char *)buffer; bcurrent = (fptr->Fptr)->curbuf; /* number of the current IO buffer */ record = bufrecnum[bcurrent]; /* zero-indexed record number */ bufpos = (long) ((fptr->Fptr)->bytepos - ((LONGLONG)record * IOBUFLEN)); /* start pos */ nspace = IOBUFLEN - bufpos; /* amount of space left in buffer */ ioptr = iobuffer[bcurrent] + bufpos; for (ii = 1; ii < ngroups; ii++) /* read all but the last group */ { /* copy bytes from IO buffer to the user's buffer */ nread = minvalue(gsize, nspace); memcpy(cptr, ioptr, nread); cptr += nread; /* increment buffer pointer */ if (nread < gsize) /* entire group did not fit */ { record++; ffldrc(fptr, record, REPORT_EOF, status); /* load next record */ bcurrent = (fptr->Fptr)->curbuf; ioptr = iobuffer[bcurrent]; nread = gsize - nread; memcpy(cptr, ioptr, nread); cptr += nread; /* increment buffer pointer */ ioptr += (offset + nread); /* increment IO buffer pointer */ nspace = IOBUFLEN - offset - nread; /* amount of space left */ } else { ioptr += (offset + nread); /* increment IO bufer pointer */ nspace -= (offset + nread); } if (nspace <= 0 || nspace > IOBUFLEN) /* beyond current record? */ { if (nspace <= 0) { record += ((IOBUFLEN - nspace) / IOBUFLEN); /* new record number */ bufpos = (-nspace) % IOBUFLEN; /* starting buffer pos */ } else { record -= ((nspace - 1 ) / IOBUFLEN); /* new record number */ bufpos = IOBUFLEN - (nspace % IOBUFLEN); /* starting buffer pos */ } ffldrc(fptr, record, REPORT_EOF, status); bcurrent = (fptr->Fptr)->curbuf; nspace = IOBUFLEN - bufpos; ioptr = iobuffer[bcurrent] + bufpos; } } /* now read the last group */ nread = minvalue(gsize, nspace); memcpy(cptr, ioptr, nread); cptr += nread; /* increment buffer pointer */ if (nread < gsize) /* entire group did not fit */ { record++; ffldrc(fptr, record, REPORT_EOF, status); /* load next record */ bcurrent = (fptr->Fptr)->curbuf; ioptr = iobuffer[bcurrent]; nread = gsize - nread; memcpy(cptr, ioptr, nread); } (fptr->Fptr)->bytepos = (fptr->Fptr)->bytepos + (ngroups * gsize) + (ngroups - 1) * offset; return(*status); } /*--------------------------------------------------------------------------*/ int ffldrc(fitsfile *fptr, /* I - FITS file pointer */ long record, /* I - record number to be loaded */ int err_mode, /* I - 1=ignore EOF, 0 = return EOF error */ int *status) /* IO - error status */ { /* low-level routine to load a specified record from a file into a physical buffer, if it is not already loaded. Reset all pointers to make this the new current record for that file. Update ages of all the physical buffers. */ int ibuff, nbuff; LONGLONG rstart; /* check if record is already loaded in one of the buffers */ /* search from youngest to oldest buffer for efficiency */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); for (ibuff = NIOBUF - 1; ibuff >= 0; ibuff--) { nbuff = ageindex[ibuff]; if (bufptr[nbuff] == fptr->Fptr && record == bufrecnum[nbuff]) goto updatebuf; /* use 'goto' for efficiency */ } /* record is not already loaded */ rstart = (LONGLONG)record * IOBUFLEN; if ( !err_mode && (rstart >= (fptr->Fptr)->logfilesize) ) /* EOF? */ return(*status = END_OF_FILE); if (ffwhbf(fptr, &nbuff) < 0) /* which buffer should we reuse? */ return(*status = TOO_MANY_FILES); if (dirty[nbuff]) ffbfwt(nbuff, status); /* write dirty buffer to disk */ if (rstart >= (fptr->Fptr)->filesize) /* EOF? */ { /* initialize an empty buffer with the correct fill value */ if ((fptr->Fptr)->hdutype == ASCII_TBL) memset(iobuffer[nbuff], 32, IOBUFLEN); /* blank fill */ else memset(iobuffer[nbuff], 0, IOBUFLEN); /* zero fill */ (fptr->Fptr)->logfilesize = maxvalue((fptr->Fptr)->logfilesize, rstart + IOBUFLEN); dirty[nbuff] = TRUE; /* mark record as having been modified */ } else /* not EOF, so read record from disk */ { if ((fptr->Fptr)->io_pos != rstart) ffseek(fptr->Fptr, rstart); ffread(fptr->Fptr, IOBUFLEN, iobuffer[nbuff], status); (fptr->Fptr)->io_pos = rstart + IOBUFLEN; /* set new IO position */ } bufptr[nbuff] = fptr->Fptr; /* file pointer for this buffer */ bufrecnum[nbuff] = record; /* record number contained in buffer */ updatebuf: (fptr->Fptr)->curbuf = nbuff; /* this is the current buffer for this file */ if (ibuff < 0) { /* find the current position of the buffer in the age index */ for (ibuff = 0; ibuff < NIOBUF; ibuff++) if (ageindex[ibuff] == nbuff) break; } /* increment the age of all the buffers that were younger than it */ for (ibuff++; ibuff < NIOBUF; ibuff++) ageindex[ibuff - 1] = ageindex[ibuff]; ageindex[NIOBUF - 1] = nbuff; /* this is now the youngest buffer */ return(*status); } /*--------------------------------------------------------------------------*/ int ffwhbf(fitsfile *fptr, /* I - FITS file pointer */ int *nbuff) /* O - which buffer to use */ { /* decide which buffer to (re)use to hold a new file record */ int ii, ibuff; static int ageinit = 0; if (!ageinit) /* first time thru, initialize default age of buffers */ { for (ii = 0; ii < NIOBUF; ii++) ageindex[ii] = ii; ageinit = 1; } for (ii = 0; ii < NIOBUF; ii++) { ibuff = ageindex[ii]; /* search from the oldest to youngest buffer */ if (bufptr[ibuff] == NULL || /* if buffer is empty, or */ bufptr[ibuff]->curbuf != ibuff) /* is not the current buffer */ return(*nbuff = ibuff); /* then choose this buffer */ } /* all the buffers are locked, so we have to reuse the current one */ /* If there is no current buffer (e.g., file has just been opened) */ /* then use the oldest buffer. */ if ((fptr->Fptr)->curbuf < 0) { bufptr[ageindex[0]]->curbuf = -1; /* this buffer no longer contains */ /* the current buffer of another file */ return(*nbuff = ageindex[0]); /* return oldest buffer */ } else { return(*nbuff = (fptr->Fptr)->curbuf); /* return current buffer */ } } /*--------------------------------------------------------------------------*/ int ffflus(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Flush all the data in the current FITS file to disk. This ensures that if the program subsequently dies, the disk FITS file will be closed correctly. */ { int hdunum, hdutype; if (*status > 0) return(*status); ffghdn(fptr, &hdunum); /* get the current HDU number */ if (ffchdu(fptr,status) > 0) /* close out the current HDU */ ffpmsg("ffflus could not close the current HDU."); ffflsh(fptr, FALSE, status); /* flush any modified IO buffers to disk */ if (ffgext(fptr, hdunum - 1, &hdutype, status) > 0) /* reopen HDU */ ffpmsg("ffflus could not reopen the current HDU."); return(*status); } /*--------------------------------------------------------------------------*/ int ffflsh(fitsfile *fptr, /* I - FITS file pointer */ int clearbuf, /* I - also clear buffer contents? */ int *status) /* IO - error status */ { /* flush all dirty IO buffers associated with the file to disk */ int ii; /* no need to move to a different HDU if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); */ for (ii = 0; ii < NIOBUF; ii++) { if (bufptr[ii] == fptr->Fptr) { if (dirty[ii]) /* flush modified buffer to disk */ ffbfwt(ii, status); if (clearbuf) bufptr[ii] = NULL; /* set contents of buffer as undefined */ } } if (*status != READONLY_FILE) ffflushx(fptr->Fptr); /* flush system buffers to disk */ return(*status); } /*--------------------------------------------------------------------------*/ int ffbfeof(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ { /* clear any buffers beyond the end of file */ int ii; for (ii = 0; ii < NIOBUF; ii++) { if (bufptr[ii] == fptr->Fptr) { if ( (LONGLONG) bufrecnum[ii] * IOBUFLEN >= fptr->Fptr->filesize) { bufptr[ii] = NULL; /* set contents of buffer as undefined */ } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffbfwt(int nbuff, /* I - which buffer to write */ int *status) /* IO - error status */ { /* write contents of buffer to file; If the position of the buffer is beyond the current EOF, then the file may need to be extended with fill values, and/or with the contents of some of the other i/o buffers. */ FITSfile *Fptr; int ii,ibuff; long jj, irec, minrec, nloop; LONGLONG filepos; static char zeros[IOBUFLEN]; /* initialized to zero by default */ Fptr = bufptr[nbuff]; if (!(Fptr->writemode) ) { ffpmsg("Error: trying to write to READONLY file."); dirty[nbuff] = FALSE; /* reset buffer status to prevent later probs */ *status = READONLY_FILE; return(*status); } filepos = (LONGLONG)bufrecnum[nbuff] * IOBUFLEN; if (filepos <= Fptr->filesize) { /* record is located within current file, so just write it */ /* move to the correct write position */ if (Fptr->io_pos != filepos) ffseek(Fptr, filepos); ffwrite(Fptr, IOBUFLEN, iobuffer[nbuff], status); Fptr->io_pos = filepos + IOBUFLEN; if (filepos == Fptr->filesize) /* appended new record? */ Fptr->filesize += IOBUFLEN; /* increment the file size */ dirty[nbuff] = FALSE; } else /* if record is beyond the EOF, append any other records */ /* and/or insert fill values if necessary */ { /* move to EOF */ if (Fptr->io_pos != Fptr->filesize) ffseek(Fptr, Fptr->filesize); ibuff = NIOBUF; /* initialize to impossible value */ while(ibuff != nbuff) /* repeat until requested buffer is written */ { minrec = (long) (Fptr->filesize / IOBUFLEN); /* write lowest record beyond the EOF first */ irec = bufrecnum[nbuff]; /* initially point to the requested buffer */ ibuff = nbuff; for (ii = 0; ii < NIOBUF; ii++) { if (bufptr[ii] == Fptr && bufrecnum[ii] >= minrec && bufrecnum[ii] < irec) { irec = bufrecnum[ii]; /* found a lower record */ ibuff = ii; } } filepos = (LONGLONG)irec * IOBUFLEN; /* byte offset of record in file */ /* append 1 or more fill records if necessary */ if (filepos > Fptr->filesize) { nloop = (long) ((filepos - (Fptr->filesize)) / IOBUFLEN); for (jj = 0; jj < nloop && !(*status); jj++) ffwrite(Fptr, IOBUFLEN, zeros, status); /* ffseek(Fptr, filepos); */ Fptr->filesize = filepos; /* increment the file size */ } /* write the buffer itself */ ffwrite(Fptr, IOBUFLEN, iobuffer[ibuff], status); dirty[ibuff] = FALSE; Fptr->filesize += IOBUFLEN; /* increment the file size */ } /* loop back if more buffers need to be written */ Fptr->io_pos = Fptr->filesize; /* currently positioned at EOF */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffgrsz( fitsfile *fptr, /* I - FITS file pionter */ long *ndata, /* O - optimal amount of data to access */ int *status) /* IO - error status */ /* Returns an optimal value for the number of rows in a binary table or the number of pixels in an image that should be read or written at one time for maximum efficiency. Accessing more data than this may cause excessive flushing and rereading of buffers to/from disk. */ { int nfiles, typecode, bytesperpixel; long repeat, width; /* There are NIOBUF internal buffers available each IOBUFLEN bytes long. */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header to get hdu struct */ return(*status); /* determine how many different FITS files are currently open */ nfiles = fits_get_num_files(); /* one buffer (at least) is always allocated to each open file */ if ((fptr->Fptr)->hdutype == IMAGE_HDU ) /* calc pixels per buffer size */ { /* image pixels are in column 2 of the 'table' */ ffgtcl(fptr, 2, &typecode, &repeat, &width, status); bytesperpixel = typecode / 10; *ndata = ((NIOBUF - nfiles) * IOBUFLEN) / bytesperpixel; } else /* calc number of rows that fit in buffers */ { *ndata = (long) (((NIOBUF - nfiles) * IOBUFLEN) / maxvalue(1, (fptr->Fptr)->rowlength)); *ndata = maxvalue(1, *ndata); } return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_num_files(void) /* Returns the number of FITS files currently opened in CFITSIO */ { int ii, jj, unique, nfiles; /* determine how many different FITS files are currently open */ nfiles = 0; for (ii = 0; ii < NIOBUF; ii++) { if (bufptr[ii]) { unique = TRUE; for (jj = 0; jj < ii; jj++) { if (bufptr[ii] == bufptr[jj]) { unique = FALSE; break; } } if (unique) nfiles++; } } return(nfiles); } /*--------------------------------------------------------------------------*/ int ffgtbb(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG firstrow, /* I - starting row (1 = first row) */ LONGLONG firstchar, /* I - starting byte in row (1=first) */ LONGLONG nchars, /* I - number of bytes to read */ unsigned char *values, /* I - array of bytes to read */ int *status) /* IO - error status */ /* read a consecutive string of bytes from an ascii or binary table. This will span multiple rows of the table if nchars + firstchar is greater than the length of a row. */ { LONGLONG bytepos, endrow; if (*status > 0 || nchars <= 0) return(*status); else if (firstrow < 1) return(*status=BAD_ROW_NUM); else if (firstchar < 1) return(*status=BAD_ELEM_NUM); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* check that we do not exceed number of rows in the table */ endrow = ((firstchar + nchars - 2) / (fptr->Fptr)->rowlength) + firstrow; if (endrow > (fptr->Fptr)->numrows) { ffpmsg("attempt to read past end of table (ffgtbb)"); return(*status=BAD_ROW_NUM); } /* move the i/o pointer to the start of the sequence of characters */ bytepos = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * (firstrow - 1)) + firstchar - 1; ffmbyt(fptr, bytepos, REPORT_EOF, status); ffgbyt(fptr, nchars, values, status); /* read the bytes */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgi1b(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG byteloc, /* I - position within file to start reading */ long nvals, /* I - number of pixels to read */ long incre, /* I - byte increment between pixels */ unsigned char *values, /* O - returned array of values */ int *status) /* IO - error status */ /* get (read) the array of values from the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { LONGLONG postemp; if (incre == 1) /* read all the values at once (contiguous bytes) */ { if (nvals < MINDIRECT) /* read normally via IO buffers */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbyt(fptr, nvals, values, status); } else /* read directly from disk, bypassing IO buffers */ { postemp = (fptr->Fptr)->bytepos; /* store current file position */ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */ ffgbyt(fptr, nvals, values, status); (fptr->Fptr)->bytepos = postemp; /* reset to original position */ } } else /* have to read each value individually (not contiguous ) */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbytoff(fptr, 1, nvals, incre - 1, values, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgi2b(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG byteloc, /* I - position within file to start reading */ long nvals, /* I - number of pixels to read */ long incre, /* I - byte increment between pixels */ short *values, /* O - returned array of values */ int *status) /* IO - error status */ /* get (read) the array of values from the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { LONGLONG postemp; if (incre == 2) /* read all the values at once (contiguous bytes) */ { if (nvals * 2 < MINDIRECT) /* read normally via IO buffers */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbyt(fptr, nvals * 2, values, status); } else /* read directly from disk, bypassing IO buffers */ { postemp = (fptr->Fptr)->bytepos; /* store current file position */ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */ ffgbyt(fptr, nvals * 2, values, status); (fptr->Fptr)->bytepos = postemp; /* reset to original position */ } } else /* have to read each value individually (not contiguous ) */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbytoff(fptr, 2, nvals, incre - 2, values, status); } #if BYTESWAPPED ffswap2(values, nvals); /* reverse order of bytes in each value */ #endif return(*status); } /*--------------------------------------------------------------------------*/ int ffgi4b(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG byteloc, /* I - position within file to start reading */ long nvals, /* I - number of pixels to read */ long incre, /* I - byte increment between pixels */ INT32BIT *values, /* O - returned array of values */ int *status) /* IO - error status */ /* get (read) the array of values from the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { LONGLONG postemp; if (incre == 4) /* read all the values at once (contiguous bytes) */ { if (nvals * 4 < MINDIRECT) /* read normally via IO buffers */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbyt(fptr, nvals * 4, values, status); } else /* read directly from disk, bypassing IO buffers */ { postemp = (fptr->Fptr)->bytepos; /* store current file position */ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */ ffgbyt(fptr, nvals * 4, values, status); (fptr->Fptr)->bytepos = postemp; /* reset to original position */ } } else /* have to read each value individually (not contiguous ) */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbytoff(fptr, 4, nvals, incre - 4, values, status); } #if BYTESWAPPED ffswap4(values, nvals); /* reverse order of bytes in each value */ #endif return(*status); } /*--------------------------------------------------------------------------*/ int ffgi8b(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG byteloc, /* I - position within file to start reading */ long nvals, /* I - number of pixels to read */ long incre, /* I - byte increment between pixels */ long *values, /* O - returned array of values */ int *status) /* IO - error status */ /* get (read) the array of values from the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! This routine reads 'nvals' 8-byte integers into 'values'. This works both on platforms that have sizeof(long) = 64, and 32, as long as 'values' has been allocated to large enough to hold 8 * nvals bytes of data. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ { LONGLONG postemp; if (incre == 8) /* read all the values at once (contiguous bytes) */ { if (nvals * 8 < MINDIRECT) /* read normally via IO buffers */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbyt(fptr, nvals * 8, values, status); } else /* read directly from disk, bypassing IO buffers */ { postemp = (fptr->Fptr)->bytepos; /* store current file position */ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */ ffgbyt(fptr, nvals * 8, values, status); (fptr->Fptr)->bytepos = postemp; /* reset to original position */ } } else /* have to read each value individually (not contiguous ) */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbytoff(fptr, 8, nvals, incre - 8, values, status); } #if BYTESWAPPED ffswap8((double *) values, nvals); /* reverse bytes in each value */ #endif return(*status); } /*--------------------------------------------------------------------------*/ int ffgr4b(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG byteloc, /* I - position within file to start reading */ long nvals, /* I - number of pixels to read */ long incre, /* I - byte increment between pixels */ float *values, /* O - returned array of values */ int *status) /* IO - error status */ /* get (read) the array of values from the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { LONGLONG postemp; #if MACHINE == VAXVMS long ii; #elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT) short *sptr; long ii; #endif if (incre == 4) /* read all the values at once (contiguous bytes) */ { if (nvals * 4 < MINDIRECT) /* read normally via IO buffers */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbyt(fptr, nvals * 4, values, status); } else /* read directly from disk, bypassing IO buffers */ { postemp = (fptr->Fptr)->bytepos; /* store current file position */ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */ ffgbyt(fptr, nvals * 4, values, status); (fptr->Fptr)->bytepos = postemp; /* reset to original position */ } } else /* have to read each value individually (not contiguous ) */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbytoff(fptr, 4, nvals, incre - 4, values, status); } #if MACHINE == VAXVMS ii = nvals; /* call VAX macro routine to convert */ ieevur(values, values, &ii); /* from IEEE float -> F float */ #elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT) ffswap2( (short *) values, nvals * 2); /* swap pairs of bytes */ /* convert from IEEE float format to VMS GFLOAT float format */ sptr = (short *) values; for (ii = 0; ii < nvals; ii++, sptr += 2) { if (!fnan(*sptr) ) /* test for NaN or underflow */ values[ii] *= 4.0; } #elif BYTESWAPPED ffswap4((INT32BIT *)values, nvals); /* reverse order of bytes in values */ #endif return(*status); } /*--------------------------------------------------------------------------*/ int ffgr8b(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG byteloc, /* I - position within file to start reading */ long nvals, /* I - number of pixels to read */ long incre, /* I - byte increment between pixels */ double *values, /* O - returned array of values */ int *status) /* IO - error status */ /* get (read) the array of values from the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { LONGLONG postemp; #if MACHINE == VAXVMS long ii; #elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT) short *sptr; long ii; #endif if (incre == 8) /* read all the values at once (contiguous bytes) */ { if (nvals * 8 < MINDIRECT) /* read normally via IO buffers */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbyt(fptr, nvals * 8, values, status); } else /* read directly from disk, bypassing IO buffers */ { postemp = (fptr->Fptr)->bytepos; /* store current file position */ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */ ffgbyt(fptr, nvals * 8, values, status); (fptr->Fptr)->bytepos = postemp; /* reset to original position */ } } else /* have to read each value individually (not contiguous ) */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbytoff(fptr, 8, nvals, incre - 8, values, status); } #if MACHINE == VAXVMS ii = nvals; /* call VAX macro routine to convert */ ieevud(values, values, &ii); /* from IEEE float -> D float */ #elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT) ffswap2( (short *) values, nvals * 4); /* swap pairs of bytes */ /* convert from IEEE float format to VMS GFLOAT float format */ sptr = (short *) values; for (ii = 0; ii < nvals; ii++, sptr += 4) { if (!dnan(*sptr) ) /* test for NaN or underflow */ values[ii] *= 4.0; } #elif BYTESWAPPED ffswap8(values, nvals); /* reverse order of bytes in each value */ #endif return(*status); } /*--------------------------------------------------------------------------*/ int ffptbb(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG firstrow, /* I - starting row (1 = first row) */ LONGLONG firstchar, /* I - starting byte in row (1=first) */ LONGLONG nchars, /* I - number of bytes to write */ unsigned char *values, /* I - array of bytes to write */ int *status) /* IO - error status */ /* write a consecutive string of bytes to an ascii or binary table. This will span multiple rows of the table if nchars + firstchar is greater than the length of a row. */ { LONGLONG bytepos, endrow, nrows; char message[81]; if (*status > 0 || nchars <= 0) return(*status); else if (firstrow < 1) return(*status=BAD_ROW_NUM); else if (firstchar < 1) return(*status=BAD_ELEM_NUM); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart < 0) /* rescan header if data undefined */ ffrdef(fptr, status); endrow = ((firstchar + nchars - 2) / (fptr->Fptr)->rowlength) + firstrow; /* check if we are writing beyond the current end of table */ if (endrow > (fptr->Fptr)->numrows) { /* if there are more HDUs following the current one, or */ /* if there is a data heap, then we must insert space */ /* for the new rows. */ if ( !((fptr->Fptr)->lasthdu) || (fptr->Fptr)->heapsize > 0) { nrows = endrow - ((fptr->Fptr)->numrows); /* ffirow also updates the heap address and numrows */ if (ffirow(fptr, (fptr->Fptr)->numrows, nrows, status) > 0) { sprintf(message, "ffptbb failed to add space for %.0f new rows in table.", (double) nrows); ffpmsg(message); return(*status); } } else { /* manally update heap starting address */ (fptr->Fptr)->heapstart += ((LONGLONG)(endrow - (fptr->Fptr)->numrows) * (fptr->Fptr)->rowlength ); (fptr->Fptr)->numrows = endrow; /* update number of rows */ } } /* move the i/o pointer to the start of the sequence of characters */ bytepos = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * (firstrow - 1)) + firstchar - 1; ffmbyt(fptr, bytepos, IGNORE_EOF, status); ffpbyt(fptr, nchars, values, status); /* write the bytes */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpi1b(fitsfile *fptr, /* I - FITS file pointer */ long nvals, /* I - number of pixels in the values array */ long incre, /* I - byte increment between pixels */ unsigned char *values, /* I - array of values to write */ int *status) /* IO - error status */ /* put (write) the array of values to the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { if (incre == 1) /* write all the values at once (contiguous bytes) */ ffpbyt(fptr, nvals, values, status); else /* have to write each value individually (not contiguous ) */ ffpbytoff(fptr, 1, nvals, incre - 1, values, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpi2b(fitsfile *fptr, /* I - FITS file pointer */ long nvals, /* I - number of pixels in the values array */ long incre, /* I - byte increment between pixels */ short *values, /* I - array of values to write */ int *status) /* IO - error status */ /* put (write) the array of values to the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { #if BYTESWAPPED ffswap2(values, nvals); /* reverse order of bytes in each value */ #endif if (incre == 2) /* write all the values at once (contiguous bytes) */ ffpbyt(fptr, nvals * 2, values, status); else /* have to write each value individually (not contiguous ) */ ffpbytoff(fptr, 2, nvals, incre - 2, values, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpi4b(fitsfile *fptr, /* I - FITS file pointer */ long nvals, /* I - number of pixels in the values array */ long incre, /* I - byte increment between pixels */ INT32BIT *values, /* I - array of values to write */ int *status) /* IO - error status */ /* put (write) the array of values to the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { #if BYTESWAPPED ffswap4(values, nvals); /* reverse order of bytes in each value */ #endif if (incre == 4) /* write all the values at once (contiguous bytes) */ ffpbyt(fptr, nvals * 4, values, status); else /* have to write each value individually (not contiguous ) */ ffpbytoff(fptr, 4, nvals, incre - 4, values, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpi8b(fitsfile *fptr, /* I - FITS file pointer */ long nvals, /* I - number of pixels in the values array */ long incre, /* I - byte increment between pixels */ long *values, /* I - array of values to write */ int *status) /* IO - error status */ /* put (write) the array of values to the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! This routine writes 'nvals' 8-byte integers from 'values'. This works both on platforms that have sizeof(long) = 64, and 32, as long as 'values' has been allocated to large enough to hold 8 * nvals bytes of data. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ { #if BYTESWAPPED ffswap8((double *) values, nvals); /* reverse bytes in each value */ #endif if (incre == 8) /* write all the values at once (contiguous bytes) */ ffpbyt(fptr, nvals * 8, values, status); else /* have to write each value individually (not contiguous ) */ ffpbytoff(fptr, 8, nvals, incre - 8, values, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpr4b(fitsfile *fptr, /* I - FITS file pointer */ long nvals, /* I - number of pixels in the values array */ long incre, /* I - byte increment between pixels */ float *values, /* I - array of values to write */ int *status) /* IO - error status */ /* put (write) the array of values to the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { #if MACHINE == VAXVMS long ii; ii = nvals; /* call VAX macro routine to convert */ ieevpr(values, values, &ii); /* from F float -> IEEE float */ #elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT) long ii; /* convert from VMS FFLOAT float format to IEEE float format */ for (ii = 0; ii < nvals; ii++) values[ii] *= 0.25; ffswap2( (short *) values, nvals * 2); /* swap pairs of bytes */ #elif BYTESWAPPED ffswap4((INT32BIT *) values, nvals); /* reverse order of bytes in values */ #endif if (incre == 4) /* write all the values at once (contiguous bytes) */ ffpbyt(fptr, nvals * 4, values, status); else /* have to write each value individually (not contiguous ) */ ffpbytoff(fptr, 4, nvals, incre - 4, values, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpr8b(fitsfile *fptr, /* I - FITS file pointer */ long nvals, /* I - number of pixels in the values array */ long incre, /* I - byte increment between pixels */ double *values, /* I - array of values to write */ int *status) /* IO - error status */ /* put (write) the array of values to the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { #if MACHINE == VAXVMS long ii; ii = nvals; /* call VAX macro routine to convert */ ieevpd(values, values, &ii); /* from D float -> IEEE float */ #elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT) long ii; /* convert from VMS GFLOAT float format to IEEE float format */ for (ii = 0; ii < nvals; ii++) values[ii] *= 0.25; ffswap2( (short *) values, nvals * 4); /* swap pairs of bytes */ #elif BYTESWAPPED ffswap8(values, nvals); /* reverse order of bytes in each value */ #endif if (incre == 8) /* write all the values at once (contiguous bytes) */ ffpbyt(fptr, nvals * 8, values, status); else /* have to write each value individually (not contiguous ) */ ffpbytoff(fptr, 8, nvals, incre - 8, values, status); return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/cfileio.c000066400000000000000000006346211215713201500222220ustar00rootroot00000000000000/* This file, cfileio.c, contains the low-level file access routines. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include #include /* apparently needed to define size_t */ #include "fitsio2.h" #include "group.h" #define MAX_PREFIX_LEN 20 /* max length of file type prefix (e.g. 'http://') */ #define MAX_DRIVERS 23 /* max number of file I/O drivers */ typedef struct /* structure containing pointers to I/O driver functions */ { char prefix[MAX_PREFIX_LEN]; int (*init)(void); int (*shutdown)(void); int (*setoptions)(int option); int (*getoptions)(int *options); int (*getversion)(int *version); int (*checkfile)(char *urltype, char *infile, char *outfile); int (*open)(char *filename, int rwmode, int *driverhandle); int (*create)(char *filename, int *drivehandle); int (*truncate)(int drivehandle, LONGLONG size); int (*close)(int drivehandle); int (*remove)(char *filename); int (*size)(int drivehandle, LONGLONG *size); int (*flush)(int drivehandle); int (*seek)(int drivehandle, LONGLONG offset); int (*read)(int drivehandle, void *buffer, long nbytes); int (*write)(int drivehandle, void *buffer, long nbytes); } fitsdriver; fitsdriver driverTable[MAX_DRIVERS]; /* allocate driver tables */ FITSfile *FptrTable[NMAXFILES]; /* this table of Fptr pointers is */ /* used by fits_already_open */ int need_to_initialize = 1; /* true if CFITSIO has not been initialized */ int no_of_drivers = 0; /* number of currently defined I/O drivers */ static int pixel_filter_helper(fitsfile **fptr, char *outfile, char *expr, int *status); /*--------------------------------------------------------------------------*/ int ffomem(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ void **buffptr, /* I - address of memory pointer */ size_t *buffsize, /* I - size of buffer, in bytes */ size_t deltasize, /* I - increment for future realloc's */ void *(*mem_realloc)(void *p, size_t newsize), /* function */ int *status) /* IO - error status */ /* Open an existing FITS file in core memory. This is a specialized version of ffopen. */ { int driver, handle, hdutyp, slen, movetotype, extvers, extnum; char extname[FLEN_VALUE]; LONGLONG filesize; char urltype[MAX_PREFIX_LEN], infile[FLEN_FILENAME], outfile[FLEN_FILENAME]; char extspec[FLEN_FILENAME], rowfilter[FLEN_FILENAME]; char binspec[FLEN_FILENAME], colspec[FLEN_FILENAME]; char imagecolname[FLEN_VALUE], rowexpress[FLEN_FILENAME]; char *url, errmsg[FLEN_ERRMSG]; char *hdtype[3] = {"IMAGE", "TABLE", "BINTABLE"}; if (*status > 0) return(*status); *fptr = 0; /* initialize null file pointer */ if (need_to_initialize) /* this is called only once */ { if (need_to_initialize != 1) { /* This is bad. looks like memory has been corrupted. */ ffpmsg("Vital CFITSIO parameters held in memory have been corrupted!!"); ffpmsg("Fatal condition detected in ffomem."); *status = FILE_NOT_OPENED; return(*status); } *status = fits_init_cfitsio(); if (*status > 0) return(*status); } url = (char *) name; while (*url == ' ') /* ignore leading spaces in the file spec */ url++; /* parse the input file specification */ ffiurl(url, urltype, infile, outfile, extspec, rowfilter, binspec, colspec, status); strcpy(urltype, "memkeep://"); /* URL type for pre-existing memory file */ *status = urltype2driver(urltype, &driver); if (*status > 0) { ffpmsg("could not find driver for pre-existing memory file: (ffomem)"); return(*status); } /* call driver routine to open the memory file */ *status = mem_openmem( buffptr, buffsize,deltasize, mem_realloc, &handle); if (*status > 0) { ffpmsg("failed to open pre-existing memory file: (ffomem)"); return(*status); } /* get initial file size */ *status = (*driverTable[driver].size)(handle, &filesize); if (*status > 0) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed get the size of the memory file: (ffomem)"); return(*status); } /* allocate fitsfile structure and initialize = 0 */ *fptr = (fitsfile *) calloc(1, sizeof(fitsfile)); if (!(*fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for following file: (ffomem)"); ffpmsg(url); return(*status = MEMORY_ALLOCATION); } /* allocate FITSfile structure and initialize = 0 */ (*fptr)->Fptr = (FITSfile *) calloc(1, sizeof(FITSfile)); if (!((*fptr)->Fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for following file: (ffomem)"); ffpmsg(url); free(*fptr); *fptr = 0; return(*status = MEMORY_ALLOCATION); } slen = strlen(url) + 1; slen = maxvalue(slen, 32); /* reserve at least 32 chars */ ((*fptr)->Fptr)->filename = (char *) malloc(slen); /* mem for file name */ if ( !(((*fptr)->Fptr)->filename) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for filename: (ffomem)"); ffpmsg(url); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* mem for headstart array */ ((*fptr)->Fptr)->headstart = (LONGLONG *) calloc(1001, sizeof(LONGLONG)); if ( !(((*fptr)->Fptr)->headstart) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for headstart array: (ffomem)"); ffpmsg(url); free( ((*fptr)->Fptr)->filename); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* store the parameters describing the file */ ((*fptr)->Fptr)->MAXHDU = 1000; /* initial size of headstart */ ((*fptr)->Fptr)->filehandle = handle; /* file handle */ ((*fptr)->Fptr)->driver = driver; /* driver number */ strcpy(((*fptr)->Fptr)->filename, url); /* full input filename */ ((*fptr)->Fptr)->filesize = filesize; /* physical file size */ ((*fptr)->Fptr)->logfilesize = filesize; /* logical file size */ ((*fptr)->Fptr)->writemode = mode; /* read-write mode */ ((*fptr)->Fptr)->datastart = DATA_UNDEFINED; /* unknown start of data */ ((*fptr)->Fptr)->curbuf = -1; /* undefined current IO buffer */ ((*fptr)->Fptr)->open_count = 1; /* structure is currently used once */ ((*fptr)->Fptr)->validcode = VALIDSTRUC; /* flag denoting valid structure */ ffldrc(*fptr, 0, REPORT_EOF, status); /* load first record */ fits_store_Fptr( (*fptr)->Fptr, status); /* store Fptr address */ if (ffrhdu(*fptr, &hdutyp, status) > 0) /* determine HDU structure */ { ffpmsg( "ffomem could not interpret primary array header of file: (ffomem)"); ffpmsg(url); if (*status == UNKNOWN_REC) ffpmsg("This does not look like a FITS file."); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ } /* ---------------------------------------------------------- */ /* move to desired extension, if specified as part of the URL */ /* ---------------------------------------------------------- */ imagecolname[0] = '\0'; rowexpress[0] = '\0'; if (*extspec) { /* parse the extension specifier into individual parameters */ ffexts(extspec, &extnum, extname, &extvers, &movetotype, imagecolname, rowexpress, status); if (*status > 0) return(*status); if (extnum) { ffmahd(*fptr, extnum + 1, &hdutyp, status); } else if (*extname) /* move to named extension, if specified */ { ffmnhd(*fptr, movetotype, extname, extvers, status); } if (*status > 0) { ffpmsg("ffomem could not move to the specified extension:"); if (extnum > 0) { sprintf(errmsg, " extension number %d doesn't exist or couldn't be opened.",extnum); ffpmsg(errmsg); } else { sprintf(errmsg, " extension with EXTNAME = %s,", extname); ffpmsg(errmsg); if (extvers) { sprintf(errmsg, " and with EXTVERS = %d,", extvers); ffpmsg(errmsg); } if (movetotype != ANY_HDU) { sprintf(errmsg, " and with XTENSION = %s,", hdtype[movetotype]); ffpmsg(errmsg); } ffpmsg(" doesn't exist or couldn't be opened."); } return(*status); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffdkopn(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - full name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ int *status) /* IO - error status */ /* Open an existing FITS file on magnetic disk with either readonly or read/write access. The routine does not support CFITSIO's extended filename syntax and simply uses the entire input 'name' string as the name of the file. */ { if (*status > 0) return(*status); *status = OPEN_DISK_FILE; ffopen(fptr, name, mode, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffdopn(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - full name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ int *status) /* IO - error status */ /* Open an existing FITS file with either readonly or read/write access. and move to the first HDU that contains 'interesting' data, if the primary array contains a null image (i.e., NAXIS = 0). */ { if (*status > 0) return(*status); *status = SKIP_NULL_PRIMARY; ffopen(fptr, name, mode, status); return(*status); } /*--------------------------------------------------------------------------*/ int fftopn(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - full name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ int *status) /* IO - error status */ /* Open an existing FITS file with either readonly or read/write access. and move to the first HDU that contains 'interesting' table (not an image). */ { int hdutype; if (*status > 0) return(*status); *status = SKIP_IMAGE; ffopen(fptr, name, mode, status); if (ffghdt(*fptr, &hdutype, status) <= 0) { if (hdutype == IMAGE_HDU) *status = NOT_TABLE; } return(*status); } /*--------------------------------------------------------------------------*/ int ffiopn(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - full name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ int *status) /* IO - error status */ /* Open an existing FITS file with either readonly or read/write access. and move to the first HDU that contains 'interesting' image (not an table). */ { int hdutype; if (*status > 0) return(*status); *status = SKIP_TABLE; ffopen(fptr, name, mode, status); if (ffghdt(*fptr, &hdutype, status) <= 0) { if (hdutype != IMAGE_HDU) *status = NOT_IMAGE; } return(*status); } /*--------------------------------------------------------------------------*/ int ffopentest(double version, /* I - CFITSIO version number, from the */ /* application program (fitsio.h file) */ fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - full name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ int *status) /* IO - error status */ /* Open an existing FITS file with either readonly or read/write access. First test that the version of fitsio.h used to build the CFITSIO library is the same as the version used in building the application program that links to the library. */ { if (version != CFITSIO_VERSION) { printf("ERROR: Mismatch in the version of the fitsio.h include file used to build\n"); printf("the CFITSIO library, and the version included by the application program:\n"); printf(" Version used to build the CFITSIO library = %f\n",CFITSIO_VERSION); printf(" Version included by the application program = %f\n",version); *status = FILE_NOT_OPENED; return(*status); } /* now call the normal file open routine */ ffopen(fptr, name, mode, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffopen(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - full name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ int *status) /* IO - error status */ /* Open an existing FITS file with either readonly or read/write access. */ { fitsfile *newptr; int driver, hdutyp, hdunum, slen, writecopy, isopen; LONGLONG filesize; long rownum, nrows, goodrows; int extnum, extvers, handle, movetotype, tstatus = 0; char urltype[MAX_PREFIX_LEN], infile[FLEN_FILENAME], outfile[FLEN_FILENAME]; char origurltype[MAX_PREFIX_LEN], extspec[FLEN_FILENAME]; char extname[FLEN_VALUE], rowfilter[FLEN_FILENAME], tblname[FLEN_VALUE]; char imagecolname[FLEN_VALUE], rowexpress[FLEN_FILENAME]; char binspec[FLEN_FILENAME], colspec[FLEN_FILENAME], pixfilter[FLEN_FILENAME]; char histfilename[FLEN_FILENAME]; char filtfilename[FLEN_FILENAME]; char wtcol[FLEN_VALUE]; char minname[4][FLEN_VALUE], maxname[4][FLEN_VALUE]; char binname[4][FLEN_VALUE]; char *url; double minin[4], maxin[4], binsizein[4], weight; int imagetype, naxis = 1, haxis, recip; int skip_null = 0, skip_image = 0, skip_table = 0, open_disk_file = 0; char colname[4][FLEN_VALUE]; char errmsg[FLEN_ERRMSG]; char *hdtype[3] = {"IMAGE", "TABLE", "BINTABLE"}; char *rowselect = 0; if (*status > 0) return(*status); if (*status == SKIP_NULL_PRIMARY) { /* this special status value is used as a flag by ffdopn to tell */ /* ffopen to skip over a null primary array when opening the file. */ skip_null = 1; *status = 0; } else if (*status == SKIP_IMAGE) { /* this special status value is used as a flag by fftopn to tell */ /* ffopen to move to 1st significant table when opening the file. */ skip_image = 1; *status = 0; } else if (*status == SKIP_TABLE) { /* this special status value is used as a flag by ffiopn to tell */ /* ffopen to move to 1st significant image when opening the file. */ skip_table = 1; *status = 0; } else if (*status == OPEN_DISK_FILE) { /* this special status value is used as a flag by ffdkopn to tell */ /* ffopen to not interpret the input filename using CFITSIO's */ /* extended filename syntax, and simply open the specified disk file */ open_disk_file = 1; *status = 0; } *fptr = 0; /* initialize null file pointer */ writecopy = 0; /* have we made a write-able copy of the input file? */ if (need_to_initialize) { /* this is called only once */ if (need_to_initialize != 1) { /* This is bad. looks like memory has been corrupted. */ ffpmsg("Vital CFITSIO parameters held in memory have been corrupted!!"); ffpmsg("Fatal condition detected in ffopen."); *status = FILE_NOT_OPENED; return(*status); } *status = fits_init_cfitsio(); } if (*status > 0) return(*status); url = (char *) name; while (*url == ' ') /* ignore leading spaces in the filename */ url++; if (*url == '\0') { ffpmsg("Name of file to open is blank. (ffopen)"); return(*status = FILE_NOT_OPENED); } if (open_disk_file) { /* treat the input URL literally as the name of the file to open */ /* and don't try to parse the URL using the extended filename syntax */ strcpy(infile,url); strcpy(urltype, "file://"); outfile[0] = '\0'; extspec[0] = '\0'; binspec[0] = '\0'; colspec[0] = '\0'; rowfilter[0] = '\0'; pixfilter[0] = '\0'; } else { /* parse the input file specification */ fits_parse_input_filename(url, urltype, infile, outfile, extspec, rowfilter, binspec, colspec, pixfilter, status); } if (*status > 0) { ffpmsg("could not parse the input filename: (ffopen)"); ffpmsg(url); return(*status); } imagecolname[0] = '\0'; rowexpress[0] = '\0'; if (*extspec) { /* parse the extension specifier into individual parameters */ ffexts(extspec, &extnum, extname, &extvers, &movetotype, imagecolname, rowexpress, status); if (*status > 0) return(*status); } /*-------------------------------------------------------------------*/ /* special cases: */ /*-------------------------------------------------------------------*/ histfilename[0] = '\0'; filtfilename[0] = '\0'; if (*outfile && (*binspec || *imagecolname || *pixfilter)) { /* if binspec or imagecolumn are specified, then the */ /* output file name is intended for the final image, */ /* and not a copy of the input file. */ strcpy(histfilename, outfile); outfile[0] = '\0'; } else if (*outfile && (*rowfilter || *colspec)) { /* if rowfilter or colspece are specified, then the */ /* output file name is intended for the filtered file */ /* and not a copy of the input file. */ strcpy(filtfilename, outfile); outfile[0] = '\0'; } /*-------------------------------------------------------------------*/ /* check if this same file is already open, and if so, attach to it */ /*-------------------------------------------------------------------*/ if (fits_already_open(fptr, url, urltype, infile, extspec, rowfilter, binspec, colspec, mode, &isopen, status) > 0) { return(*status); } if (isopen) goto move2hdu; /* get the driver number corresponding to this urltype */ *status = urltype2driver(urltype, &driver); if (*status > 0) { ffpmsg("could not find driver for this file: (ffopen)"); ffpmsg(urltype); ffpmsg(url); return(*status); } /*------------------------------------------------------------------- deal with all those messy special cases which may require that a different driver be used: - is disk file compressed? - are ftp:, gsiftp:, or http: files compressed? - has user requested that a local copy be made of the ftp or http file? -------------------------------------------------------------------*/ if (driverTable[driver].checkfile) { strcpy(origurltype,urltype); /* Save the urltype */ /* 'checkfile' may modify the urltype, infile and outfile strings */ *status = (*driverTable[driver].checkfile)(urltype, infile, outfile); if (*status) { ffpmsg("checkfile failed for this file: (ffopen)"); ffpmsg(url); return(*status); } if (strcmp(origurltype, urltype)) /* did driver changed on us? */ { *status = urltype2driver(urltype, &driver); if (*status > 0) { ffpmsg("could not change driver for this file: (ffopen)"); ffpmsg(url); ffpmsg(urltype); return(*status); } } } /* call appropriate driver to open the file */ if (driverTable[driver].open) { *status = (*driverTable[driver].open)(infile, mode, &handle); if (*status > 0) { ffpmsg("failed to find or open the following file: (ffopen)"); ffpmsg(url); return(*status); } } else { ffpmsg("cannot open an existing file of this type: (ffopen)"); ffpmsg(url); return(*status = FILE_NOT_OPENED); } /* get initial file size */ *status = (*driverTable[driver].size)(handle, &filesize); if (*status > 0) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed get the size of the following file: (ffopen)"); ffpmsg(url); return(*status); } /* allocate fitsfile structure and initialize = 0 */ *fptr = (fitsfile *) calloc(1, sizeof(fitsfile)); if (!(*fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for following file: (ffopen)"); ffpmsg(url); return(*status = MEMORY_ALLOCATION); } /* allocate FITSfile structure and initialize = 0 */ (*fptr)->Fptr = (FITSfile *) calloc(1, sizeof(FITSfile)); if (!((*fptr)->Fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for following file: (ffopen)"); ffpmsg(url); free(*fptr); *fptr = 0; return(*status = MEMORY_ALLOCATION); } slen = strlen(url) + 1; slen = maxvalue(slen, 32); /* reserve at least 32 chars */ ((*fptr)->Fptr)->filename = (char *) malloc(slen); /* mem for file name */ if ( !(((*fptr)->Fptr)->filename) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for filename: (ffopen)"); ffpmsg(url); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* mem for headstart array */ ((*fptr)->Fptr)->headstart = (LONGLONG *) calloc(1001, sizeof(LONGLONG)); if ( !(((*fptr)->Fptr)->headstart) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for headstart array: (ffopen)"); ffpmsg(url); free( ((*fptr)->Fptr)->filename); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* store the parameters describing the file */ ((*fptr)->Fptr)->MAXHDU = 1000; /* initial size of headstart */ ((*fptr)->Fptr)->filehandle = handle; /* file handle */ ((*fptr)->Fptr)->driver = driver; /* driver number */ strcpy(((*fptr)->Fptr)->filename, url); /* full input filename */ ((*fptr)->Fptr)->filesize = filesize; /* physical file size */ ((*fptr)->Fptr)->logfilesize = filesize; /* logical file size */ ((*fptr)->Fptr)->writemode = mode; /* read-write mode */ ((*fptr)->Fptr)->datastart = DATA_UNDEFINED; /* unknown start of data */ ((*fptr)->Fptr)->curbuf = -1; /* undefined current IO buffer */ ((*fptr)->Fptr)->open_count = 1; /* structure is currently used once */ ((*fptr)->Fptr)->validcode = VALIDSTRUC; /* flag denoting valid structure */ ffldrc(*fptr, 0, REPORT_EOF, status); /* load first record */ fits_store_Fptr( (*fptr)->Fptr, status); /* store Fptr address */ if (ffrhdu(*fptr, &hdutyp, status) > 0) /* determine HDU structure */ { ffpmsg( "ffopen could not interpret primary array header of file: "); ffpmsg(url); if (*status == UNKNOWN_REC) ffpmsg("This does not look like a FITS file."); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } /* ------------------------------------------------------------- */ /* At this point, the input file has been opened. If outfile was */ /* specified, then we have opened a copy of the file, not the */ /* original file so it is safe to modify it if necessary */ /* ------------------------------------------------------------- */ if (*outfile) writecopy = 1; move2hdu: /* ---------------------------------------------------------- */ /* move to desired extension, if specified as part of the URL */ /* ---------------------------------------------------------- */ if (*extspec) { if (extnum) /* extension number was specified */ { ffmahd(*fptr, extnum + 1, &hdutyp, status); } else if (*extname) /* move to named extension, if specified */ { ffmnhd(*fptr, movetotype, extname, extvers, status); } if (*status > 0) /* clean up after error */ { ffpmsg("ffopen could not move to the specified extension:"); if (extnum > 0) { sprintf(errmsg, " extension number %d doesn't exist or couldn't be opened.",extnum); ffpmsg(errmsg); } else { sprintf(errmsg, " extension with EXTNAME = %s,", extname); ffpmsg(errmsg); if (extvers) { sprintf(errmsg, " and with EXTVERS = %d,", extvers); ffpmsg(errmsg); } if (movetotype != ANY_HDU) { sprintf(errmsg, " and with XTENSION = %s,", hdtype[movetotype]); ffpmsg(errmsg); } ffpmsg(" doesn't exist or couldn't be opened."); } ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } } else if (skip_null || skip_image || skip_table || (*imagecolname || *colspec || *rowfilter || *binspec)) { /* ------------------------------------------------------------------ If no explicit extension specifier is given as part of the file name, and, if a) skip_null is true (set if ffopen is called by ffdopn) or b) skip_image or skip_table is true (set if ffopen is called by fftopn or ffdopn) or c) other file filters are specified, then CFITSIO will attempt to move to the first 'interesting' HDU after opening an existing FITS file (or to first interesting table HDU if skip_image is true); An 'interesting' HDU is defined to be either an image with NAXIS > 0 (i.e., not a null array) or a table which has an EXTNAME value which does not contain any of the following strings: 'GTI' - Good Time Interval extension 'OBSTABLE' - used in Beppo SAX data files The main purpose for this is to allow CFITSIO to skip over a null primary and other non-interesting HDUs when opening an existing file, and move directly to the first extension that contains significant data. ------------------------------------------------------------------ */ fits_get_hdu_num(*fptr, &hdunum); if (hdunum == 1) { fits_get_img_dim(*fptr, &naxis, status); if (naxis == 0 || skip_image) /* skip primary array */ { while(1) { /* see if the next HDU is 'interesting' */ if (fits_movrel_hdu(*fptr, 1, &hdutyp, status)) { if (*status == END_OF_FILE) *status = 0; /* reset expected error */ /* didn't find an interesting HDU so move back to beginning */ fits_movabs_hdu(*fptr, 1, &hdutyp, status); break; } if (hdutyp == IMAGE_HDU && skip_image) { continue; /* skip images */ } else if (hdutyp != IMAGE_HDU && skip_table) { continue; /* skip tables */ } else if (hdutyp == IMAGE_HDU) { fits_get_img_dim(*fptr, &naxis, status); if (naxis > 0) break; /* found a non-null image */ } else { tstatus = 0; tblname[0] = '\0'; fits_read_key(*fptr, TSTRING, "EXTNAME", tblname, NULL,&tstatus); if ( (!strstr(tblname, "GTI") && !strstr(tblname, "gti")) && strncasecmp(tblname, "OBSTABLE", 8) ) break; /* found an interesting table */ } } /* end while */ } } /* end if (hdunum==1) */ } if (*imagecolname) { /* ----------------------------------------------------------------- */ /* we need to open an image contained in a single table cell */ /* First, determine which row of the table to use. */ /* ----------------------------------------------------------------- */ if (isdigit((int) *rowexpress)) /* is the row specification a number? */ { sscanf(rowexpress, "%ld", &rownum); if (rownum < 1) { ffpmsg("illegal rownum for image cell:"); ffpmsg(rowexpress); ffpmsg("Could not open the following image in a table cell:"); ffpmsg(extspec); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status = BAD_ROW_NUM); } } else if (fits_find_first_row(*fptr, rowexpress, &rownum, status) > 0) { ffpmsg("Failed to find row matching this expression:"); ffpmsg(rowexpress); ffpmsg("Could not open the following image in a table cell:"); ffpmsg(extspec); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } if (rownum == 0) { ffpmsg("row statisfying this expression doesn't exist::"); ffpmsg(rowexpress); ffpmsg("Could not open the following image in a table cell:"); ffpmsg(extspec); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status = BAD_ROW_NUM); } /* determine the name of the new file to contain copy of the image */ if (*histfilename && !(*pixfilter) ) strcpy(outfile, histfilename); /* the original outfile name */ else strcpy(outfile, "mem://_1"); /* create image file in memory */ /* Copy the image into new primary array and open it as the current */ /* fptr. This will close the table that contains the original image. */ /* create new empty file to hold copy of the image */ if (ffinit(&newptr, outfile, status) > 0) { ffpmsg("failed to create file for copy of image in table cell:"); ffpmsg(outfile); return(*status); } if (fits_copy_cell2image(*fptr, newptr, imagecolname, rownum, status) > 0) { ffpmsg("Failed to copy table cell to new primary array:"); ffpmsg(extspec); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } /* close the original file and set fptr to the new image */ ffclos(*fptr, status); *fptr = newptr; /* reset the pointer to the new table */ writecopy = 1; /* we are now dealing with a copy of the original file */ /* add some HISTORY; fits_copy_image_cell also wrote HISTORY keywords */ /* disable this; leave it up to calling routine to write any HISTORY keywords if (*extname) sprintf(card,"HISTORY in HDU '%.16s' of file '%.36s'",extname,infile); else sprintf(card,"HISTORY in HDU %d of file '%.45s'", extnum, infile); ffprec(*fptr, card, status); */ } /* --------------------------------------------------------------------- */ /* edit columns (and/or keywords) in the table, if specified in the URL */ /* --------------------------------------------------------------------- */ if (*colspec) { /* the column specifier will modify the file, so make sure */ /* we are already dealing with a copy, or else make a new copy */ if (!writecopy) /* Is the current file already a copy? */ writecopy = fits_is_this_a_copy(urltype); if (!writecopy) { if (*filtfilename && *outfile == '\0') strcpy(outfile, filtfilename); /* the original outfile name */ else strcpy(outfile, "mem://_1"); /* will create copy in memory */ writecopy = 1; } else { ((*fptr)->Fptr)->writemode = READWRITE; /* we have write access */ outfile[0] = '\0'; } if (ffedit_columns(fptr, outfile, colspec, status) > 0) { ffpmsg("editing columns in input table failed (ffopen)"); ffpmsg(" while trying to perform the following operation:"); ffpmsg(colspec); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } } /* ------------------------------------------------------------------- */ /* select rows from the table, if specified in the URL */ /* or select a subimage (if this is an image HDU and not a table) */ /* ------------------------------------------------------------------- */ if (*rowfilter) { fits_get_hdu_type(*fptr, &hdutyp, status); /* get type of HDU */ if (hdutyp == IMAGE_HDU) { /* this is an image so 'rowfilter' is an image section specification */ if (*filtfilename && *outfile == '\0') strcpy(outfile, filtfilename); /* the original outfile name */ else if (*outfile == '\0') /* output file name not already defined? */ strcpy(outfile, "mem://_2"); /* will create file in memory */ /* create new file containing the image section, plus a copy of */ /* any other HDUs that exist in the input file. This routine */ /* will close the original image file and return a pointer */ /* to the new file. */ if (fits_select_image_section(fptr, outfile, rowfilter, status) > 0) { ffpmsg("on-the-fly selection of image section failed (ffopen)"); ffpmsg(" while trying to use the following section filter:"); ffpmsg(rowfilter); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } writecopy = 1; } else { /* this is a table HDU, so the rowfilter is really a row filter */ if (*binspec) { /* since we are going to make a histogram of the selected rows, */ /* it would be a waste of time and memory to make a whole copy of */ /* the selected rows. Instead, just construct an array of TRUE */ /* or FALSE values that indicate which rows are to be included */ /* in the histogram and pass that to the histogram generating */ /* routine */ fits_get_num_rows(*fptr, &nrows, status); /* get no. of rows */ rowselect = (char *) calloc(nrows, 1); if (!rowselect) { ffpmsg( "failed to allocate memory for selected columns array (ffopen)"); ffpmsg(" while trying to select rows with the following filter:"); ffpmsg(rowfilter); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } if (fits_find_rows(*fptr, rowfilter, 1L, nrows, &goodrows, rowselect, status) > 0) { ffpmsg("selection of rows in input table failed (ffopen)"); ffpmsg(" while trying to select rows with the following filter:"); ffpmsg(rowfilter); free(rowselect); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } } else { if (!writecopy) /* Is the current file already a copy? */ writecopy = fits_is_this_a_copy(urltype); if (!writecopy) { if (*filtfilename && *outfile == '\0') strcpy(outfile, filtfilename); /* the original outfile name */ else if (*outfile == '\0') /* output filename not already defined? */ strcpy(outfile, "mem://_2"); /* will create copy in memory */ } else { ((*fptr)->Fptr)->writemode = READWRITE; /* we have write access */ outfile[0] = '\0'; } /* select rows in the table. If a copy of the input file has */ /* not already been made, then this routine will make a copy */ /* and then close the input file, so that the modifications will */ /* only be made on the copy, not the original */ if (ffselect_table(fptr, outfile, rowfilter, status) > 0) { ffpmsg("on-the-fly selection of rows in input table failed (ffopen)"); ffpmsg(" while trying to select rows with the following filter:"); ffpmsg(rowfilter); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } /* write history records */ ffphis(*fptr, "CFITSIO used the following filtering expression to create this table:", status); ffphis(*fptr, name, status); } /* end of no binspec case */ } /* end of table HDU case */ } /* end of rowfilter exists case */ /* ------------------------------------------------------------------- */ /* make an image histogram by binning columns, if specified in the URL */ /* ------------------------------------------------------------------- */ if (*binspec) { if (*histfilename && !(*pixfilter) ) strcpy(outfile, histfilename); /* the original outfile name */ else strcpy(outfile, "mem://_3"); /* create histogram in memory */ /* if not already copied the file */ /* parse the binning specifier into individual parameters */ ffbins(binspec, &imagetype, &haxis, colname, minin, maxin, binsizein, minname, maxname, binname, &weight, wtcol, &recip, status); /* Create the histogram primary array and open it as the current fptr */ /* This will close the table that was used to create the histogram. */ ffhist(fptr, outfile, imagetype, haxis, colname, minin, maxin, binsizein, minname, maxname, binname, weight, wtcol, recip, rowselect, status); if (rowselect) free(rowselect); if (*status > 0) { ffpmsg("on-the-fly histogramming of input table failed (ffopen)"); ffpmsg(" while trying to execute the following histogram specification:"); ffpmsg(binspec); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } /* write history records */ ffphis(*fptr, "CFITSIO used the following expression to create this histogram:", status); ffphis(*fptr, name, status); } if (*pixfilter) { if (*histfilename) strcpy(outfile, histfilename); /* the original outfile name */ else strcpy(outfile, "mem://_4"); /* create in memory */ /* if not already copied the file */ /* Ensure type of HDU is consistent with pixel filtering */ fits_get_hdu_type(*fptr, &hdutyp, status); /* get type of HDU */ if (hdutyp == IMAGE_HDU) { pixel_filter_helper(fptr, outfile, pixfilter, status); if (*status > 0) { ffpmsg("pixel filtering of input image failed (ffopen)"); ffpmsg(" while trying to execute the following:"); ffpmsg(pixfilter); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } /* write history records */ ffphis(*fptr, "CFITSIO used the following expression to create this image:", status); ffphis(*fptr, name, status); return *status; } else { ffpmsg("cannot use pixel filter on non-IMAGE HDU"); ffpmsg(pixfilter); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ *status = NOT_IMAGE; return(*status); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffreopen(fitsfile *openfptr, /* I - FITS file pointer to open file */ fitsfile **newfptr, /* O - pointer to new re opened file */ int *status) /* IO - error status */ /* Reopen an existing FITS file with either readonly or read/write access. The reopened file shares the same FITSfile structure but may point to a different HDU within the file. */ { if (*status > 0) return(*status); /* check that the open file pointer is valid */ if (!openfptr) return(*status = NULL_INPUT_PTR); else if ((openfptr->Fptr)->validcode != VALIDSTRUC) /* check magic value */ return(*status = BAD_FILEPTR); /* allocate fitsfile structure and initialize = 0 */ *newfptr = (fitsfile *) calloc(1, sizeof(fitsfile)); (*newfptr)->Fptr = openfptr->Fptr; /* both point to the same structure */ (*newfptr)->HDUposition = 0; /* set initial position to primary array */ (((*newfptr)->Fptr)->open_count)++; /* increment the file usage counter */ return(*status); } /*--------------------------------------------------------------------------*/ int fits_store_Fptr(FITSfile *Fptr, /* O - FITS file pointer */ int *status) /* IO - error status */ /* store the new Fptr address for future use by fits_already_open */ { int ii; if (*status > 0) return(*status); for (ii = 0; ii < NMAXFILES; ii++) { if (FptrTable[ii] == 0) { FptrTable[ii] = Fptr; break; } } return(*status); } /*--------------------------------------------------------------------------*/ int fits_clear_Fptr(FITSfile *Fptr, /* O - FITS file pointer */ int *status) /* IO - error status */ /* clear the Fptr address from the Fptr Table */ { int ii; for (ii = 0; ii < NMAXFILES; ii++) { if (FptrTable[ii] == Fptr) { FptrTable[ii] = 0; break; } } return(*status); } /*--------------------------------------------------------------------------*/ int fits_already_open(fitsfile **fptr, /* I/O - FITS file pointer */ char *url, char *urltype, char *infile, char *extspec, char *rowfilter, char *binspec, char *colspec, int mode, /* I - 0 = open readonly; 1 = read/write */ int *isopen, /* O - 1 = file is already open */ int *status) /* IO - error status */ /* Check if the file to be opened is already open. If so, then attach to it. */ /* this function was changed so that for files of access method FILE:// the file paths are compared using standard URL syntax and absolute paths (as opposed to relative paths). This eliminates some instances where a file is already opened but it is not realized because it was opened with another file path. For instance, if the CWD is /a/b/c and I open /a/b/c/foo.fits then open ./foo.fits the previous version of this function would not have reconized that the two files were the same. This version does recognize that the two files are the same. */ { FITSfile *oldFptr; int ii; char oldurltype[MAX_PREFIX_LEN], oldinfile[FLEN_FILENAME]; char oldextspec[FLEN_FILENAME], oldoutfile[FLEN_FILENAME]; char oldrowfilter[FLEN_FILENAME]; char oldbinspec[FLEN_FILENAME], oldcolspec[FLEN_FILENAME]; char cwd[FLEN_FILENAME]; char tmpStr[FLEN_FILENAME]; char tmpinfile[FLEN_FILENAME]; *isopen = 0; if(strcasecmp(urltype,"FILE://") == 0) { fits_path2url(infile,tmpinfile,status); if(tmpinfile[0] != '/') { fits_get_cwd(cwd,status); strcat(cwd,"/"); strcat(cwd,tmpinfile); fits_clean_url(cwd,tmpinfile,status); } } else strcpy(tmpinfile,infile); for (ii = 0; ii < NMAXFILES; ii++) /* check every buffer */ { if (FptrTable[ii] != 0) { oldFptr = FptrTable[ii]; ffiurl(oldFptr->filename, oldurltype, oldinfile, oldoutfile, oldextspec, oldrowfilter, oldbinspec, oldcolspec, status); if (*status > 0) { ffpmsg("could not parse the previously opened filename: (ffopen)"); ffpmsg(oldFptr->filename); return(*status); } if(strcasecmp(oldurltype,"FILE://") == 0) { fits_path2url(oldinfile,tmpStr,status); if(tmpStr[0] != '/') { fits_get_cwd(cwd,status); strcat(cwd,"/"); strcat(cwd,tmpStr); fits_clean_url(cwd,tmpStr,status); } strcpy(oldinfile,tmpStr); } if (!strcmp(urltype, oldurltype) && !strcmp(tmpinfile, oldinfile) ) { /* identical type of file and root file name */ if ( (!rowfilter[0] && !oldrowfilter[0] && !binspec[0] && !oldbinspec[0] && !colspec[0] && !oldcolspec[0]) /* no filtering or binning specs for either file, so */ /* this is a case where the same file is being reopened. */ /* It doesn't matter if the extensions are different */ || /* or */ (!strcmp(rowfilter, oldrowfilter) && !strcmp(binspec, oldbinspec) && !strcmp(colspec, oldcolspec) && !strcmp(extspec, oldextspec) ) ) /* filtering specs are given and are identical, and */ /* the same extension is specified */ { if (mode == READWRITE && oldFptr->writemode == READONLY) { /* cannot assume that a file previously opened with READONLY can now be written to (e.g., files on CDROM, or over the the network, or STDIN), so return with an error. */ ffpmsg( "cannot reopen file READWRITE when previously opened READONLY"); ffpmsg(url); return(*status = FILE_NOT_OPENED); } *fptr = (fitsfile *) calloc(1, sizeof(fitsfile)); if (!(*fptr)) { ffpmsg( "failed to allocate structure for following file: (ffopen)"); ffpmsg(url); return(*status = MEMORY_ALLOCATION); } (*fptr)->Fptr = oldFptr; /* point to the structure */ (*fptr)->HDUposition = 0; /* set initial position */ (((*fptr)->Fptr)->open_count)++; /* increment usage counter */ if (binspec[0]) /* if binning specified, don't move */ extspec[0] = '\0'; /* all the filtering has already been applied, so ignore */ rowfilter[0] = '\0'; binspec[0] = '\0'; colspec[0] = '\0'; *isopen = 1; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fits_is_this_a_copy(char *urltype) /* I - type of file */ /* specialized routine that returns 1 if the file is known to be a temporary copy of the originally opened file. Otherwise it returns 0. */ { int iscopy; if (!strncmp(urltype, "mem", 3) ) iscopy = 1; /* file copy is in memory */ else if (!strncmp(urltype, "compress", 8) ) iscopy = 1; /* compressed diskfile that is uncompressed in memory */ else if (!strncmp(urltype, "http", 4) ) iscopy = 1; /* copied file using http protocol */ else if (!strncmp(urltype, "ftp", 3) ) iscopy = 1; /* copied file using ftp protocol */ else if (!strncmp(urltype, "gsiftp", 6) ) iscopy = 1; /* copied file using gsiftp protocol */ else if (!strncpy(urltype, "stdin", 5) ) iscopy = 1; /* piped stdin has been copied to memory */ else iscopy = 0; /* file is not known to be a copy */ return(iscopy); } /*--------------------------------------------------------------------------*/ int ffedit_columns( fitsfile **fptr, /* IO - pointer to input table; on output it */ /* points to the new selected rows table */ char *outfile, /* I - name for output file */ char *expr, /* I - column edit expression */ int *status) /* modify columns in a table and/or header keywords in the HDU */ { fitsfile *newptr; int ii, hdunum, slen, colnum = -1, testnum, deletecol = 0, savecol = 0; int numcols = 0, *colindex = 0, tstatus = 0; char *cptr, *cptr2, *cptr3, clause[FLEN_FILENAME], keyname[FLEN_KEYWORD]; char colname[FLEN_VALUE], oldname[FLEN_VALUE], colformat[FLEN_VALUE]; char *file_expr = NULL, testname[FLEN_VALUE], card[FLEN_CARD]; if (*outfile) { /* create new empty file in to hold the selected rows */ if (ffinit(&newptr, outfile, status) > 0) { ffpmsg("failed to create file for copy (ffedit_columns)"); return(*status); } fits_get_hdu_num(*fptr, &hdunum); /* current HDU number in input file */ /* copy all HDUs to the output copy */ for (ii = 1; 1; ii++) { if (fits_movabs_hdu(*fptr, ii, NULL, status) > 0) break; fits_copy_hdu(*fptr, newptr, 0, status); } if (*status == END_OF_FILE) { *status = 0; /* got the expected EOF error; reset = 0 */ } else if (*status > 0) { ffclos(newptr, status); ffpmsg("failed to copy all HDUs from input file (ffedit_columns)"); return(*status); } /* close the original file and return ptr to the new image */ ffclos(*fptr, status); *fptr = newptr; /* reset the pointer to the new table */ /* move back to the selected table HDU */ if (fits_movabs_hdu(*fptr, hdunum, NULL, status) > 0) { ffpmsg("failed to copy the input file (ffedit_columns)"); return(*status); } } /* remove the "col " from the beginning of the column edit expression */ cptr = expr + 4; while (*cptr == ' ') cptr++; /* skip leading white space */ /* Check if need to import expression from a file */ if( *cptr=='@' ) { if( ffimport_file( cptr+1, &file_expr, status ) ) return(*status); cptr = file_expr; while (*cptr == ' ') cptr++; /* skip leading white space... again */ } tstatus = 0; ffgncl(*fptr, &numcols, &tstatus); /* get initial # of cols */ /* parse expression and get first clause, if more than 1 */ while ((slen = fits_get_token(&cptr, ";", clause, NULL)) > 0 ) { if( *cptr==';' ) cptr++; clause[slen] = '\0'; if (clause[0] == '!' || clause[0] == '-') { /* ===================================== */ /* Case I. delete this column or keyword */ /* ===================================== */ if (ffgcno(*fptr, CASEINSEN, &clause[1], &colnum, status) <= 0) { /* a column with this name exists, so try to delete it */ if (ffdcol(*fptr, colnum, status) > 0) { ffpmsg("failed to delete column in input file:"); ffpmsg(clause); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); return(*status); } deletecol = 1; /* set flag that at least one col was deleted */ numcols--; colnum = -1; } else { ffcmsg(); /* clear previous error message from ffgcno */ /* try deleting a keyword with this name */ *status = 0; if (ffdkey(*fptr, &clause[1], status) > 0) { ffpmsg("column or keyword to be deleted does not exist:"); ffpmsg(clause); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); return(*status); } } } else { /* ===================================================== */ /* Case II: this is either a column name, (case 1) or a new column name followed by double = ("==") followed by the old name which is to be renamed. (case 2A) or a column or keyword name followed by a single "=" and a calculation expression (case 2B) */ /* ===================================================== */ cptr2 = clause; slen = fits_get_token(&cptr2, "( =", colname, NULL); if (slen == 0) { ffpmsg("error: column or keyword name is blank:"); ffpmsg(clause); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); return(*status= URL_PARSE_ERROR); } /* If this is a keyword of the form #KEYWORD# then transform to the form #KEYWORDn where n is the previously used column number */ if (colname[0] == '#' && strstr(colname+1, "#") == (colname + strlen(colname) - 1)) { if (colnum <= 0) { ffpmsg("The keyword name:"); ffpmsg(colname); ffpmsg("is invalid unless a column has been previously"); ffpmsg("created or editted by a calculator command"); return(*status = URL_PARSE_ERROR); } colname[strlen(colname)-1] = '\0'; /* Make keyword name and put it in oldname */ ffkeyn(colname+1, colnum, oldname, status); if (*status) return (*status); /* Re-copy back into colname */ strcpy(colname+1,oldname); } else if (strstr(colname, "#") == (colname + strlen(colname) - 1)) { /* colname is of the form "NAME#"; if a) colnum is defined, and b) a column with literal name "NAME#" does not exist, and c) a keyword with name "NAMEn" (where n=colnum) exists, then transfrom the colname string to "NAMEn", otherwise do nothing. */ if (colnum > 0) { /* colnum must be defined */ tstatus = 0; ffgcno(*fptr, CASEINSEN, colname, &testnum, &tstatus); if (tstatus != 0 && tstatus != COL_NOT_UNIQUE) { /* OK, column doesn't exist, now see if keyword exists */ ffcmsg(); /* clear previous error message from ffgcno */ strcpy(testname, colname); testname[strlen(testname)-1] = '\0'; /* Make keyword name and put it in oldname */ ffkeyn(testname, colnum, oldname, status); if (*status) return (*status); tstatus = 0; if (!fits_read_card(*fptr, oldname, card, &tstatus)) { /* Keyword does exist; copy real name back into colname */ strcpy(colname,oldname); } } } } /* if we encountered an opening parenthesis, then we need to */ /* find the closing parenthesis, and concatinate the 2 strings */ /* This supports expressions like: [col #EXTNAME(Extension name)="GTI"] */ if (*cptr2 == '(') { fits_get_token(&cptr2, ")", oldname, NULL); strcat(colname, oldname); strcat(colname, ")"); cptr2++; } while (*cptr2 == ' ') cptr2++; /* skip white space */ if (*cptr2 != '=') { /* ------------------------------------ */ /* case 1 - simply the name of a column */ /* ------------------------------------ */ /* look for matching column */ ffgcno(*fptr, CASEINSEN, colname, &testnum, status); while (*status == COL_NOT_UNIQUE) { /* the column name contained wild cards, and it */ /* matches more than one column in the table. */ colnum = testnum; /* keep this column in the output file */ savecol = 1; if (!colindex) colindex = (int *) calloc(999, sizeof(int)); colindex[colnum - 1] = 1; /* flag this column number */ /* look for other matching column names */ ffgcno(*fptr, CASEINSEN, colname, &testnum, status); if (*status == COL_NOT_FOUND) *status = 999; /* temporary status flag value */ } if (*status <= 0) { colnum = testnum; /* keep this column in the output file */ savecol = 1; if (!colindex) colindex = (int *) calloc(999, sizeof(int)); colindex[colnum - 1] = 1; /* flag this column number */ } else if (*status == 999) { /* this special flag value does not represent an error */ *status = 0; } else { ffpmsg("Syntax error in columns specifier in input URL:"); ffpmsg(cptr2); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); return(*status = URL_PARSE_ERROR); } } else { /* ----------------------------------------------- */ /* case 2 where the token ends with an equals sign */ /* ----------------------------------------------- */ cptr2++; /* skip over the first '=' */ if (*cptr2 == '=') { /*................................................. */ /* Case A: rename a column or keyword; syntax is "new_name == old_name" */ /*................................................. */ cptr2++; /* skip the 2nd '=' */ while (*cptr2 == ' ') cptr2++; /* skip white space */ fits_get_token(&cptr2, " ", oldname, NULL); /* get column number of the existing column */ if (ffgcno(*fptr, CASEINSEN, oldname, &colnum, status) <= 0) { /* modify the TTYPEn keyword value with the new name */ ffkeyn("TTYPE", colnum, keyname, status); if (ffmkys(*fptr, keyname, colname, NULL, status) > 0) { ffpmsg("failed to rename column in input file"); ffpmsg(" oldname ="); ffpmsg(oldname); ffpmsg(" newname ="); ffpmsg(colname); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); return(*status); } /* keep this column in the output file */ savecol = 1; if (!colindex) colindex = (int *) calloc(999, sizeof(int)); colindex[colnum - 1] = 1; /* flag this column number */ } else { /* try renaming a keyword */ ffcmsg(); /* clear error message stack */ *status = 0; if (ffmnam(*fptr, oldname, colname, status) > 0) { ffpmsg("column or keyword to be renamed does not exist:"); ffpmsg(clause); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); return(*status); } } } else { /*...................................................... */ /* Case B: */ /* this must be a general column/keyword calc expression */ /* "name = expression" or "colname(TFORM) = expression" */ /*...................................................... */ /* parse the name and TFORM values, if present */ colformat[0] = '\0'; cptr3 = colname; fits_get_token(&cptr3, "(", oldname, NULL); if (cptr3[0] == '(' ) { cptr3++; /* skip the '(' */ fits_get_token(&cptr3, ")", colformat, NULL); } /* calculate values for the column or keyword */ /* cptr2 = the expression to be calculated */ /* oldname = name of the column or keyword */ /* colformat = column format, or keyword comment string */ if (fits_calculator(*fptr, cptr2, *fptr, oldname, colformat, status) > 0) { ffpmsg("Unable to calculate expression"); return(*status); } /* test if this is a column and not a keyword */ tstatus = 0; ffgcno(*fptr, CASEINSEN, oldname, &testnum, &tstatus); if (tstatus == 0) { /* keep this column in the output file */ colnum = testnum; savecol = 1; if (!colindex) colindex = (int *) calloc(999, sizeof(int)); colindex[colnum - 1] = 1; if (colnum > numcols)numcols++; } else { ffcmsg(); /* clear the error message stack */ } } } } } if (savecol && !deletecol) { /* need to delete all but the specified columns */ for (ii = numcols; ii > 0; ii--) { if (!colindex[ii-1]) /* delete this column */ { if (ffdcol(*fptr, ii, status) > 0) { ffpmsg("failed to delete column in input file:"); ffpmsg(clause); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); return(*status); } } } } if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); return(*status); } /*--------------------------------------------------------------------------*/ int fits_copy_cell2image( fitsfile *fptr, /* I - point to input table */ fitsfile *newptr, /* O - existing output file; new image HDU will be appended to it */ char *colname, /* I - column name / number containing the image*/ long rownum, /* I - number of the row containing the image */ int *status) /* IO - error status */ /* Copy a table cell of a given row and column into an image extension. The output file must already have been created. A new image extension will be created in that file. This routine was written by Craig Markwardt, GSFC */ { unsigned char buffer[30000]; int hdutype, colnum, typecode, bitpix, naxis, maxelem, tstatus; LONGLONG naxes[9], nbytes, firstbyte, ntodo; LONGLONG repeat, startpos, elemnum, rowlen, tnull; long twidth, incre; double scale, zero; char tform[20]; char card[FLEN_CARD]; char templt[FLEN_CARD] = ""; /* Table-to-image keyword translation table */ /* INPUT OUTPUT */ /* 01234567 01234567 */ char *patterns[][2] = {{"TSCALn", "BSCALE" }, /* Standard FITS keywords */ {"TZEROn", "BZERO" }, {"TUNITn", "BUNIT" }, {"TNULLn", "BLANK" }, {"TDMINn", "DATAMIN" }, {"TDMAXn", "DATAMAX" }, {"iCTYPn", "CTYPEi" }, /* Coordinate labels */ {"iCTYna", "CTYPEia" }, {"iCUNIn", "CUNITi" }, /* Coordinate units */ {"iCUNna", "CUNITia" }, {"iCRVLn", "CRVALi" }, /* WCS keywords */ {"iCRVna", "CRVALia" }, {"iCDLTn", "CDELTi" }, {"iCDEna", "CDELTia" }, {"iCRPXn", "CRPIXi" }, {"iCRPna", "CRPIXia" }, {"ijPCna", "PCi_ja" }, {"ijCDna", "CDi_ja" }, {"iVn_ma", "PVi_ma" }, {"iSn_ma", "PSi_ma" }, {"iCRDna", "CRDERia" }, {"iCSYna", "CSYERia" }, {"iCROTn", "CROTAi" }, {"WCAXna", "WCSAXESa"}, {"WCSNna", "WCSNAMEa"}, {"LONPna", "LONPOLEa"}, {"LATPna", "LATPOLEa"}, {"EQUIna", "EQUINOXa"}, {"MJDOBn", "MJD-OBS" }, {"MJDAn", "MJD-AVG" }, {"RADEna", "RADESYSa"}, {"iCNAna", "CNAMEia" }, {"DAVGn", "DATE-AVG"}, /* Delete table keywords related to other columns */ {"T????#a", "-" }, {"TC??#a", "-" }, {"TWCS#a", "-" }, {"TDIM#", "-" }, {"iCTYPm", "-" }, {"iCUNIm", "-" }, {"iCRVLm", "-" }, {"iCDLTm", "-" }, {"iCRPXm", "-" }, {"iCTYma", "-" }, {"iCUNma", "-" }, {"iCRVma", "-" }, {"iCDEma", "-" }, {"iCRPma", "-" }, {"ijPCma", "-" }, {"ijCDma", "-" }, {"iVm_ma", "-" }, {"iSm_ma", "-" }, {"iCRDma", "-" }, {"iCSYma", "-" }, {"iCROTm", "-" }, {"WCAXma", "-" }, {"WCSNma", "-" }, {"LONPma", "-" }, {"LATPma", "-" }, {"EQUIma", "-" }, {"MJDOBm", "-" }, {"MJDAm", "-" }, {"RADEma", "-" }, {"iCNAma", "-" }, {"DAVGm", "-" }, {"EXTNAME", "-" }, /* Remove structural keywords*/ {"EXTVER", "-" }, {"EXTLEVEL","-" }, {"CHECKSUM","-" }, {"DATASUM", "-" }, {"*", "+" }}; /* copy all other keywords */ int npat; if (*status > 0) return(*status); /* get column number */ if (ffgcno(fptr, CASEINSEN, colname, &colnum, status) > 0) { ffpmsg("column containing image in table cell does not exist:"); ffpmsg(colname); return(*status); } /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if ( ffgcprll(fptr, colnum, rownum, 1L, 1L, 0, &scale, &zero, tform, &twidth, &typecode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, (char *) buffer, status) > 0 ) return(*status); /* get the actual column name, in case a column number was given */ ffkeyn("", colnum, templt, &tstatus); ffgcnn(fptr, CASEINSEN, templt, colname, &colnum, &tstatus); if (hdutype != BINARY_TBL) { ffpmsg("This extension is not a binary table."); ffpmsg(" Cannot open the image in a binary table cell."); return(*status = NOT_BTABLE); } if (typecode < 0) { /* variable length array */ typecode *= -1; /* variable length arrays are 1-dimensional by default */ naxis = 1; naxes[0] = repeat; } else { /* get the dimensions of the image */ ffgtdmll(fptr, colnum, 9, &naxis, naxes, status); } if (*status > 0) { ffpmsg("Error getting the dimensions of the image"); return(*status); } /* determine BITPIX value for the image */ if (typecode == TBYTE) { bitpix = BYTE_IMG; nbytes = repeat; } else if (typecode == TSHORT) { bitpix = SHORT_IMG; nbytes = repeat * 2; } else if (typecode == TLONG) { bitpix = LONG_IMG; nbytes = repeat * 4; } else if (typecode == TFLOAT) { bitpix = FLOAT_IMG; nbytes = repeat * 4; } else if (typecode == TDOUBLE) { bitpix = DOUBLE_IMG; nbytes = repeat * 8; } else if (typecode == TLONGLONG) { bitpix = LONGLONG_IMG; nbytes = repeat * 8; } else if (typecode == TLOGICAL) { bitpix = BYTE_IMG; nbytes = repeat; } else { ffpmsg("Error: the following image column has invalid datatype:"); ffpmsg(colname); ffpmsg(tform); ffpmsg("Cannot open an image in a single row of this column."); return(*status = BAD_TFORM); } /* create new image in output file */ if (ffcrimll(newptr, bitpix, naxis, naxes, status) > 0) { ffpmsg("failed to write required primary array keywords in the output file"); return(*status); } npat = sizeof(patterns)/sizeof(patterns[0][0])/2; /* skip over the first 8 keywords, starting just after TFIELDS */ fits_translate_keywords(fptr, newptr, 9, patterns, npat, colnum, 0, 0, status); /* add some HISTORY */ sprintf(card,"HISTORY This image was copied from row %ld of column '%s',", rownum, colname); /* disable this; leave it up to the caller to write history if needed. ffprec(newptr, card, status); */ /* the use of ffread routine, below, requires that any 'dirty' */ /* buffers in memory be flushed back to the file first */ ffflsh(fptr, FALSE, status); /* finally, copy the data, one buffer size at a time */ ffmbyt(fptr, startpos, TRUE, status); firstbyte = 1; /* the upper limit on the number of bytes must match the declaration */ /* read up to the first 30000 bytes in the normal way with ffgbyt */ ntodo = minvalue(30000, nbytes); ffgbyt(fptr, ntodo, buffer, status); ffptbb(newptr, 1, firstbyte, ntodo, buffer, status); nbytes -= ntodo; firstbyte += ntodo; /* read any additional bytes with low-level ffread routine, for speed */ while (nbytes && (*status <= 0) ) { ntodo = minvalue(30000, nbytes); ffread((fptr)->Fptr, (long) ntodo, buffer, status); ffptbb(newptr, 1, firstbyte, ntodo, buffer, status); nbytes -= ntodo; firstbyte += ntodo; } /* Re-scan the header so that CFITSIO knows about all the new keywords */ ffrdef(newptr,status); return(*status); } /*--------------------------------------------------------------------------*/ int fits_copy_image2cell( fitsfile *fptr, /* I - pointer to input image extension */ fitsfile *newptr, /* I - pointer to output table */ char *colname, /* I - name of column containing the image */ long rownum, /* I - number of the row containing the image */ int copykeyflag, /* I - controls which keywords to copy */ int *status) /* IO - error status */ /* Copy an image extension into a table cell at a given row and column. The table must have already been created. If the "colname" column exists, it will be used, otherwise a new column will be created in the table. The "copykeyflag" parameter controls which keywords to copy from the input image to the output table header (with any appropriate translation). copykeyflag = 0 -- no keywords will be copied copykeyflag = 1 -- essentially all keywords will be copied copykeyflag = 2 -- copy only the WCS related keywords This routine was written by Craig Markwardt, GSFC */ { tcolumn *colptr; unsigned char buffer[30000]; int ii, hdutype, colnum, typecode, bitpix, naxis, ncols, hdunum; char tformchar, tform[20], card[FLEN_CARD]; LONGLONG imgstart, naxes[9], nbytes, repeat, ntodo,firstbyte; char filename[FLEN_FILENAME+20]; int npat; int naxis1; LONGLONG naxes1[9] = {0,0,0,0,0,0,0,0,0}, repeat1, width1; int typecode1; unsigned char dummy = 0; LONGLONG headstart, datastart, dataend; /* Image-to-table keyword translation table */ /* INPUT OUTPUT */ /* 01234567 01234567 */ char *patterns[][2] = {{"BSCALE", "TSCALn" }, /* Standard FITS keywords */ {"BZERO", "TZEROn" }, {"BUNIT", "TUNITn" }, {"BLANK", "TNULLn" }, {"DATAMIN", "TDMINn" }, {"DATAMAX", "TDMAXn" }, {"CTYPEi", "iCTYPn" }, /* Coordinate labels */ {"CTYPEia", "iCTYna" }, {"CUNITi", "iCUNIn" }, /* Coordinate units */ {"CUNITia", "iCUNna" }, {"CRVALi", "iCRVLn" }, /* WCS keywords */ {"CRVALia", "iCRVna" }, {"CDELTi", "iCDLTn" }, {"CDELTia", "iCDEna" }, {"CRPIXj", "jCRPXn" }, {"CRPIXja", "jCRPna" }, {"PCi_ja", "ijPCna" }, {"CDi_ja", "ijCDna" }, {"PVi_ma", "iVn_ma" }, {"PSi_ma", "iSn_ma" }, {"WCSAXESa","WCAXna" }, {"WCSNAMEa","WCSNna" }, {"CRDERia", "iCRDna" }, {"CSYERia", "iCSYna" }, {"CROTAi", "iCROTn" }, {"LONPOLEa","LONPna"}, {"LATPOLEa","LATPna"}, {"EQUINOXa","EQUIna"}, {"MJD-OBS", "MJDOBn" }, {"MJD-AVG", "MJDAn" }, {"RADESYSa","RADEna"}, {"CNAMEia", "iCNAna" }, {"DATE-AVG","DAVGn"}, {"NAXISi", "-" }, /* Remove structural keywords*/ {"PCOUNT", "-" }, {"GCOUNT", "-" }, {"EXTEND", "-" }, {"EXTNAME", "-" }, {"EXTVER", "-" }, {"EXTLEVEL","-" }, {"CHECKSUM","-" }, {"DATASUM", "-" }, {"*", "+" }}; /* copy all other keywords */ if (*status > 0) return(*status); if (fptr == 0 || newptr == 0) return (*status = NULL_INPUT_PTR); if (ffghdt(fptr, &hdutype, status) > 0) { ffpmsg("could not get input HDU type"); return (*status); } if (hdutype != IMAGE_HDU) { ffpmsg("The input extension is not an image."); ffpmsg(" Cannot open the image."); return(*status = NOT_IMAGE); } if (ffghdt(newptr, &hdutype, status) > 0) { ffpmsg("could not get output HDU type"); return (*status); } if (hdutype != BINARY_TBL) { ffpmsg("The output extension is not a table."); return(*status = NOT_BTABLE); } if (ffgiprll(fptr, 9, &bitpix, &naxis, naxes, status) > 0) { ffpmsg("Could not read image parameters."); return (*status); } /* Determine total number of pixels in the image */ repeat = 1; for (ii = 0; ii < naxis; ii++) repeat *= naxes[ii]; /* Determine the TFORM value for the table cell */ if (bitpix == BYTE_IMG) { typecode = TBYTE; tformchar = 'B'; nbytes = repeat; } else if (bitpix == SHORT_IMG) { typecode = TSHORT; tformchar = 'I'; nbytes = repeat*2; } else if (bitpix == LONG_IMG) { typecode = TLONG; tformchar = 'J'; nbytes = repeat*4; } else if (bitpix == FLOAT_IMG) { typecode = TFLOAT; tformchar = 'E'; nbytes = repeat*4; } else if (bitpix == DOUBLE_IMG) { typecode = TDOUBLE; tformchar = 'D'; nbytes = repeat*8; } else if (bitpix == LONGLONG_IMG) { typecode = TLONGLONG; tformchar = 'K'; nbytes = repeat*8; } else { ffpmsg("Error: the image has an invalid datatype."); return (*status = BAD_BITPIX); } /* get column number */ ffpmrk(); ffgcno(newptr, CASEINSEN, colname, &colnum, status); ffcmrk(); /* Column does not exist; create it */ if (*status) { *status = 0; sprintf(tform, "%.0f%c", (double) repeat, tformchar); ffgncl(newptr, &ncols, status); colnum = ncols+1; fficol(newptr, colnum, colname, tform, status); ffptdmll(newptr, colnum, naxis, naxes, status); if (*status) { ffpmsg("Could not insert new column into output table."); return *status; } } else { ffgtdmll(newptr, colnum, 9, &naxis1, naxes1, status); if (*status > 0 || naxis != naxis1) { ffpmsg("Input image dimensions and output table cell dimensions do not match."); return (*status = BAD_DIMEN); } for (ii=0; ii 0) || (typecode1 != typecode) || (repeat1 != repeat)) { ffpmsg("Input image data type does not match output table cell type."); return (*status = BAD_TFORM); } } /* copy keywords from input image to output table, if required */ if (copykeyflag) { npat = sizeof(patterns)/sizeof(patterns[0][0])/2; if (copykeyflag == 2) { /* copy only the WCS-related keywords */ patterns[npat-1][1] = "-"; } /* The 3rd parameter value = 5 means skip the first 4 keywords in the image */ fits_translate_keywords(fptr, newptr, 5, patterns, npat, colnum, 0, 0, status); } /* Here is all the code to compute offsets: * * byte offset from start of row to column (dest table) * * byte offset from start of file to image data (source image) */ /* Force the writing of the row of the table by writing the last byte of the array, which grows the table, and/or shifts following extensions */ ffpcl(newptr, TBYTE, colnum, rownum, repeat, 1, &dummy, status); /* byte offset within the row to the start of the image column */ colptr = (newptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ firstbyte = colptr->tbcol + 1; /* get starting address of input image to be read */ ffghadll(fptr, &headstart, &datastart, &dataend, status); imgstart = datastart; sprintf(card, "HISTORY Table column '%s' row %ld copied from image", colname, rownum); /* Don't automatically write History keywords; leave this up to the caller. ffprec(newptr, card, status); */ /* write HISTORY keyword with the file name (this is now disabled)*/ filename[0] = '\0'; hdunum = 0; strcpy(filename, "HISTORY "); ffflnm(fptr, filename+strlen(filename), status); ffghdn(fptr, &hdunum); sprintf(filename+strlen(filename),"[%d]", hdunum-1); /* ffprec(newptr, filename, status); */ /* the use of ffread routine, below, requires that any 'dirty' */ /* buffers in memory be flushed back to the file first */ ffflsh(fptr, FALSE, status); /* move to the first byte of the input image */ ffmbyt(fptr, imgstart, TRUE, status); ntodo = minvalue(30000L, nbytes); ffgbyt(fptr, ntodo, buffer, status); /* read input image */ ffptbb(newptr, rownum, firstbyte, ntodo, buffer, status); /* write to table */ nbytes -= ntodo; firstbyte += ntodo; /* read any additional bytes with low-level ffread routine, for speed */ while (nbytes && (*status <= 0) ) { ntodo = minvalue(30000L, nbytes); ffread(fptr->Fptr, (long) ntodo, buffer, status); ffptbb(newptr, rownum, firstbyte, ntodo, buffer, status); nbytes -= ntodo; firstbyte += ntodo; } /* Re-scan the header so that CFITSIO knows about all the new keywords */ ffrdef(newptr,status); return(*status); } /*--------------------------------------------------------------------------*/ int fits_select_image_section( fitsfile **fptr, /* IO - pointer to input image; on output it */ /* points to the new subimage */ char *outfile, /* I - name for output file */ char *expr, /* I - Image section expression */ int *status) { /* copies an image section from the input file to a new output file. Any HDUs preceding or following the image are also copied to the output file. */ fitsfile *newptr; int ii, hdunum; /* create new empty file to hold the image section */ if (ffinit(&newptr, outfile, status) > 0) { ffpmsg( "failed to create output file for image section:"); ffpmsg(outfile); return(*status); } fits_get_hdu_num(*fptr, &hdunum); /* current HDU number in input file */ /* copy all preceding extensions to the output file */ for (ii = 1; ii < hdunum; ii++) { fits_movabs_hdu(*fptr, ii, NULL, status); if (fits_copy_hdu(*fptr, newptr, 0, status) > 0) { ffclos(newptr, status); return(*status); } } /* move back to the original HDU position */ fits_movabs_hdu(*fptr, hdunum, NULL, status); if (fits_copy_image_section(*fptr, newptr, expr, status) > 0) { ffclos(newptr, status); return(*status); } /* copy any remaining HDUs to the output file */ for (ii = hdunum + 1; 1; ii++) { if (fits_movabs_hdu(*fptr, ii, NULL, status) > 0) break; fits_copy_hdu(*fptr, newptr, 0, status); } if (*status == END_OF_FILE) *status = 0; /* got the expected EOF error; reset = 0 */ else if (*status > 0) { ffclos(newptr, status); return(*status); } /* close the original file and return ptr to the new image */ ffclos(*fptr, status); *fptr = newptr; /* reset the pointer to the new table */ /* move back to the image subsection */ if (ii - 1 != hdunum) fits_movabs_hdu(*fptr, hdunum, NULL, status); else { /* may have to reset BSCALE and BZERO pixel scaling, */ /* since the keywords were previously turned off */ if (ffrdef(*fptr, status) > 0) { ffclos(*fptr, status); return(*status); } } return(*status); } /*--------------------------------------------------------------------------*/ int fits_copy_image_section( 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 */ int bitpix, naxis, numkeys, nkey; long naxes[9], smin, smax, sinc, fpixels[9], lpixels[9], incs[9]; char *cptr, keyname[FLEN_KEYWORD], card[FLEN_CARD]; int ii, tstatus, anynull; int klen, kk, jj; long outnaxes[9], outsize, buffsize, dummy[2]; double *buffer = 0, crpix, cdelt; if (*status > 0) return(*status); /* get the size of the input image */ fits_get_img_type(fptr, &bitpix, status); fits_get_img_dim(fptr, &naxis, status); if (fits_get_img_size(fptr, naxis, naxes, status) > 0) return(*status); if (naxis < 1 || naxis > 9) { ffpmsg( "Input image either had NAXIS = 0 (NULL image) or has > 9 dimensions"); return(*status = BAD_NAXIS); } /* create output image with same size and type as the input image */ /* Will update the size later */ fits_create_img(newptr, bitpix, naxis, naxes, status); /* copy all other non-structural keywords from the input to output file */ fits_get_hdrspace(fptr, &numkeys, NULL, status); for (nkey = 4; nkey <= numkeys; nkey++) /* skip the first few keywords */ { fits_read_record(fptr, nkey, card, status); if (fits_get_keyclass(card) > TYP_CMPRS_KEY) { /* write the record to the output file */ fits_write_record(newptr, card, status); } } if (*status > 0) { ffpmsg("error copying header from input image to output image"); return(*status); } /* parse the section specifier to get min, max, and inc for each axis */ /* and the size of each output image axis */ outsize = 1; cptr = expr; for (ii=0; ii < naxis; ii++) { if (fits_get_section_range(&cptr, &smin, &smax, &sinc, status) > 0) { ffpmsg("error parsing the following image section specifier:"); ffpmsg(expr); return(*status); } if (smax == 0) smax = naxes[ii]; /* use whole axis by default */ else if (smin == 0) smin = naxes[ii]; /* use inverted whole axis */ if (smin > naxes[ii] || smax > naxes[ii]) { ffpmsg("image section exceeds dimensions of input image:"); ffpmsg(expr); return(*status = BAD_NAXIS); } fpixels[ii] = smin; lpixels[ii] = smax; incs[ii] = sinc; if (smin <= smax) outnaxes[ii] = (smax - smin + sinc) / sinc; else outnaxes[ii] = (smin - smax + sinc) / sinc; outsize = outsize * outnaxes[ii]; /* modify the NAXISn keyword */ fits_make_keyn("NAXIS", ii + 1, keyname, status); fits_modify_key_lng(newptr, keyname, outnaxes[ii], NULL, status); /* modify the WCS keywords if necessary */ if (fpixels[ii] != 1 || incs[ii] != 1) { for (kk=-1;kk<26; kk++) /* modify any alternate WCS keywords */ { /* read the CRPIXn keyword if it exists in the input file */ fits_make_keyn("CRPIX", ii + 1, keyname, status); if (kk != -1) { klen = strlen(keyname); keyname[klen]='A' + kk; keyname[klen + 1] = '\0'; } tstatus = 0; if (fits_read_key(fptr, TDOUBLE, keyname, &crpix, NULL, &tstatus) == 0) { /* calculate the new CRPIXn value */ if (fpixels[ii] <= lpixels[ii]) crpix = (crpix - (fpixels[ii] - 1.0) - .5) / incs[ii] + 0.5; else crpix = (fpixels[ii] - (crpix - 1.0) - .5) / incs[ii] + 0.5; /* modify the value in the output file */ fits_modify_key_dbl(newptr, keyname, crpix, 15, NULL, status); if (incs[ii] != 1 || fpixels[ii] > lpixels[ii]) { /* read the CDELTn keyword if it exists in the input file */ fits_make_keyn("CDELT", ii + 1, keyname, status); if (kk != -1) { klen = strlen(keyname); keyname[klen]='A' + kk; keyname[klen + 1] = '\0'; } tstatus = 0; if (fits_read_key(fptr, TDOUBLE, keyname, &cdelt, NULL, &tstatus) == 0) { /* calculate the new CDELTn value */ if (fpixels[ii] <= lpixels[ii]) cdelt = cdelt * incs[ii]; else cdelt = cdelt * (-incs[ii]); /* modify the value in the output file */ fits_modify_key_dbl(newptr, keyname, cdelt, 15, NULL, status); } /* modify the CDi_j keywords if they exist in the input file */ fits_make_keyn("CD1_", ii + 1, keyname, status); if (kk != -1) { klen = strlen(keyname); keyname[klen]='A' + kk; keyname[klen + 1] = '\0'; } for (jj=0; jj < 9; jj++) /* look for up to 9 dimensions */ { keyname[2] = '1' + jj; tstatus = 0; if (fits_read_key(fptr, TDOUBLE, keyname, &cdelt, NULL, &tstatus) == 0) { /* calculate the new CDi_j value */ if (fpixels[ii] <= lpixels[ii]) cdelt = cdelt * incs[ii]; else cdelt = cdelt * (-incs[ii]); /* modify the value in the output file */ fits_modify_key_dbl(newptr, keyname, cdelt, 15, NULL, status); } } } /* end of if (incs[ii]... loop */ } /* end of fits_read_key loop */ } /* end of for (kk loop */ } } /* end of main NAXIS loop */ if (ffrdef(newptr, status) > 0) /* force the header to be scanned */ { return(*status); } /* write a dummy value to the last pixel in the output section */ /* This will force memory to be allocated for the FITS files if it */ /* is being written in memory, before we allocate some more memory */ /* below. Hopefully this leads to better memory management and */ /* reduces the probability that the memory for the FITS file will have */ /* to be reallocated to a new location later. */ /* turn off any scaling of the pixel values */ fits_set_bscale(fptr, 1.0, 0.0, status); fits_set_bscale(newptr, 1.0, 0.0, status); dummy[0] = 0; if (fits_write_img(newptr, TLONG, outsize, 1, dummy, status) > 0) { ffpmsg("fits_copy_image_section: error writing to the last image pixel"); return(*status); } /* allocate memory for the entire image section */ buffsize = (abs(bitpix) / 8) * outsize; buffer = (double *) malloc(buffsize); if (!buffer) { ffpmsg("fits_copy_image_section: no memory for image section"); return(*status = MEMORY_ALLOCATION); } /* read the image section then write it to the output file */ if (bitpix == 8) { ffgsvb(fptr, 1, naxis, naxes, fpixels, lpixels, incs, 0, (unsigned char *) buffer, &anynull, status); ffpprb(newptr, 1, 1, outsize, (unsigned char *) buffer, status); } else if (bitpix == 16) { ffgsvi(fptr, 1, naxis, naxes, fpixels, lpixels, incs, 0, (short *) buffer, &anynull, status); ffppri(newptr, 1, 1, outsize, (short *) buffer, status); } else if (bitpix == 32) { ffgsvk(fptr, 1, naxis, naxes, fpixels, lpixels, incs, 0, (int *) buffer, &anynull, status); ffpprk(newptr, 1, 1, outsize, (int *) buffer, status); } else if (bitpix == -32) { ffgsve(fptr, 1, naxis, naxes, fpixels, lpixels, incs, FLOATNULLVALUE, (float *) buffer, &anynull, status); ffppne(newptr, 1, 1, outsize, (float *) buffer, FLOATNULLVALUE, status); } else if (bitpix == -64) { ffgsvd(fptr, 1, naxis, naxes, fpixels, lpixels, incs, DOUBLENULLVALUE, buffer, &anynull, status); ffppnd(newptr, 1, 1, outsize, buffer, DOUBLENULLVALUE, status); } else if (bitpix == 64) { ffgsvjj(fptr, 1, naxis, naxes, fpixels, lpixels, incs, 0, (LONGLONG *) buffer, &anynull, status); ffpprjj(newptr, 1, 1, outsize, (LONGLONG *) buffer, status); } free(buffer); /* finished with the memory */ if (*status > 0) { ffpmsg("fits_copy_image_section: error copying image section"); return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_section_range(char **ptr, long *secmin, long *secmax, long *incre, int *status) /* Parse the input image section specification string, returning the min, max and increment values. Typical string = "1:512:2" or "1:512" */ { int slen, isanumber; char token[FLEN_VALUE]; if (*status > 0) return(*status); slen = fits_get_token(ptr, " ,:", token, &isanumber); /* get 1st token */ if (*token == '*') /* wild card means to use the whole range */ { *secmin = 1; *secmax = 0; } else if (*token == '-' && *(token+1) == '*' ) /* invert the whole range */ { *secmin = 0; *secmax = 1; } else { if (slen == 0 || !isanumber || **ptr != ':') return(*status = URL_PARSE_ERROR); /* the token contains the min value */ *secmin = atol(token); (*ptr)++; /* skip the colon between the min and max values */ slen = fits_get_token(ptr, " ,:", token, &isanumber); /* get token */ if (slen == 0 || !isanumber) return(*status = URL_PARSE_ERROR); /* the token contains the max value */ *secmax = atol(token); } if (**ptr == ':') { (*ptr)++; /* skip the colon between the max and incre values */ slen = fits_get_token(ptr, " ,", token, &isanumber); /* get token */ if (slen == 0 || !isanumber) return(*status = URL_PARSE_ERROR); *incre = atol(token); } else *incre = 1; /* default increment if none is supplied */ if (**ptr == ',') (*ptr)++; while (**ptr == ' ') /* skip any trailing blanks */ (*ptr)++; if (*secmin < 0 || *secmax < 0 || *incre < 1) *status = URL_PARSE_ERROR; return(*status); } /*--------------------------------------------------------------------------*/ int ffselect_table( fitsfile **fptr, /* IO - pointer to input table; on output it */ /* points to the new selected rows table */ char *outfile, /* I - name for output file */ char *expr, /* I - Boolean expression */ int *status) { fitsfile *newptr; int ii, hdunum; if (*outfile) { /* create new empty file in to hold the selected rows */ if (ffinit(&newptr, outfile, status) > 0) { ffpmsg( "failed to create file for selected rows from input table"); ffpmsg(outfile); return(*status); } fits_get_hdu_num(*fptr, &hdunum); /* current HDU number in input file */ /* copy all preceding extensions to the output file */ for (ii = 1; ii < hdunum; ii++) { fits_movabs_hdu(*fptr, ii, NULL, status); if (fits_copy_hdu(*fptr, newptr, 0, status) > 0) { ffclos(newptr, status); return(*status); } } /* copy all the header keywords from the input to output file */ fits_movabs_hdu(*fptr, hdunum, NULL, status); if (fits_copy_header(*fptr, newptr, status) > 0) { ffclos(newptr, status); return(*status); } /* set number of rows = 0 */ fits_modify_key_lng(newptr, "NAXIS2", 0, NULL,status); (newptr->Fptr)->numrows = 0; (newptr->Fptr)->origrows = 0; if (ffrdef(newptr, status) > 0) /* force the header to be scanned */ { ffclos(newptr, status); return(*status); } } else newptr = *fptr; /* will delete rows in place in the table */ /* copy rows which satisfy the selection expression to the output table */ /* or delete the nonqualifying rows if *fptr = newptr. */ if (fits_select_rows(*fptr, newptr, expr, status) > 0) { if (*outfile) ffclos(newptr, status); return(*status); } if (*outfile) { /* copy any remaining HDUs to the output copy */ for (ii = hdunum + 1; 1; ii++) { if (fits_movabs_hdu(*fptr, ii, NULL, status) > 0) break; fits_copy_hdu(*fptr, newptr, 0, status); } if (*status == END_OF_FILE) *status = 0; /* got the expected EOF error; reset = 0 */ else if (*status > 0) { ffclos(newptr, status); return(*status); } /* close the original file and return ptr to the new image */ ffclos(*fptr, status); *fptr = newptr; /* reset the pointer to the new table */ /* move back to the selected table HDU */ fits_movabs_hdu(*fptr, hdunum, NULL, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffparsecompspec(fitsfile *fptr, /* I - FITS file pointer */ char *compspec, /* I - image compression specification */ int *status) /* IO - error status */ /* Parse the image compression specification that was give in square brackets following the output FITS file name, as in these examples: myfile.fits[compress] - default Rice compression, row by row myfile.fits[compress TYPE] - the first letter of TYPE defines the compression algorithm: R = Rice G = GZIP H = HCOMPRESS P = PLIO myfile.fits[compress TYPE 100,100] - the numbers give the dimensions of the compression tiles. Default is NAXIS1, 1, 1, ... myfile.fits[compress; 5] The number following the semicolon mufile.fits[compress TYPE; 5] gives the value of the noisebits myfile.fits[compress TYPE 100,100; 5] parameter that is used when quantizing floating point images. The compression parameters are saved in the fptr->Fptr structure for use when writing FITS images. */ { char *ptr1; /* initialize with default values */ int ii, compresstype = RICE_1, noisebits = 4, smooth = 0, scale = 1, intval; long tilesize[9] = {0,1,1,1,1,1,1,1,1}; ptr1 = compspec; while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; if (strncmp(ptr1, "compress", 8) && strncmp(ptr1, "COMPRESS", 8) ) { /* apparently this string does not specify compression parameters */ return(*status = URL_PARSE_ERROR); } ptr1 += 8; while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; /* ========================= */ /* look for compression type */ /* ========================= */ if (*ptr1 == 'r' || *ptr1 == 'R') { compresstype = RICE_1; while (*ptr1 != ' ' && *ptr1 != ';' && *ptr1 != '\0') ptr1++; } else if (*ptr1 == 'g' || *ptr1 == 'G') { compresstype = GZIP_1; while (*ptr1 != ' ' && *ptr1 != ';' && *ptr1 != '\0') ptr1++; } else if (*ptr1 == 'p' || *ptr1 == 'P') { compresstype = PLIO_1; while (*ptr1 != ' ' && *ptr1 != ';' && *ptr1 != '\0') ptr1++; } else if (*ptr1 == 'h' || *ptr1 == 'H') { compresstype = HCOMPRESS_1; while (*ptr1 != ' ' && *ptr1 != ';' && *ptr1 != '\0') ptr1++; } /* ======================== */ /* look for tile dimensions */ /* ======================== */ while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; ii = 0; while (isdigit( (int) *ptr1) && ii < 9) { tilesize[ii] = atol(ptr1); /* read the integer value */ ii++; while (isdigit((int) *ptr1)) /* skip over the integer */ ptr1++; if (*ptr1 == ',') ptr1++; /* skip over the comma */ while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; } /* ========================================================= */ /* look for other parameters */ /* ========================================================= */ if (*ptr1 == ';') { ptr1++; while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; /* get first integer parameter */ if (!isdigit((int) *ptr1) ) return(*status = URL_PARSE_ERROR); intval = atol(ptr1); /* read the integer value */ if (compresstype == HCOMPRESS_1) scale = intval; else noisebits = intval; while (isdigit((int) *ptr1)) /* skip over the integer */ ptr1++; if (*ptr1 == ',') { ptr1++; /* skip over the comma */ while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; /* get 2nd integer parameter */ if (!isdigit((int) *ptr1) ) return(*status = URL_PARSE_ERROR); intval = atol(ptr1); /* read the integer value */ if (compresstype == HCOMPRESS_1) smooth = intval; else return(*status = URL_PARSE_ERROR); while (isdigit((int) *ptr1)) /* skip over the integer */ ptr1++; } } while (*ptr1 == ' ') /* ignore blanks */ ptr1++; if (*ptr1 != 0) /* remaining junk in the string?? */ return(*status = URL_PARSE_ERROR); /* ================================= */ /* finished parsing; save the values */ /* ================================= */ (fptr->Fptr)->request_compress_type = compresstype; for (ii = 0; ii < 9; ii++) (fptr->Fptr)->request_tilesize[ii] = tilesize[ii]; if (compresstype == HCOMPRESS_1) { (fptr->Fptr)->request_hcomp_scale = scale; (fptr->Fptr)->request_hcomp_smooth = smooth; } else { (fptr->Fptr)->request_noise_nbits = noisebits; } return(*status); } /*--------------------------------------------------------------------------*/ int ffdkinit(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - name of file to create */ int *status) /* IO - error status */ /* Create and initialize a new FITS file on disk. This routine differs from ffinit in that the input 'name' is literally taken as the name of the disk file to be created, and it does not support CFITSIO's extended filename syntax. */ { if (*status > 0) return(*status); *status = CREATE_DISK_FILE; ffinit(fptr, name,status); return(*status); } /*--------------------------------------------------------------------------*/ int ffinit(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - name of file to create */ int *status) /* IO - error status */ /* Create and initialize a new FITS file. */ { int driver, slen, clobber = 0; char *url; char urltype[MAX_PREFIX_LEN], outfile[FLEN_FILENAME]; char tmplfile[FLEN_FILENAME], compspec[80]; int handle, create_disk_file = 0; if (*status > 0) return(*status); if (*status == CREATE_DISK_FILE) { create_disk_file = 1; *status = 0; } *fptr = 0; /* initialize null file pointer */ if (need_to_initialize) { /* this is called only once */ if (need_to_initialize != 1) { /* This is bad. looks like memory has been corrupted. */ ffpmsg("Vital CFITSIO parameters held in memory have been corrupted!!"); ffpmsg("Fatal condition detected in ffinit."); *status = FILE_NOT_CREATED; return(*status); } *status = fits_init_cfitsio(); } if (*status > 0) return(*status); url = (char *) name; while (*url == ' ') /* ignore leading spaces in the filename */ url++; if (*url == '\0') { ffpmsg("Name of file to create is blank. (ffinit)"); return(*status = FILE_NOT_CREATED); } if (create_disk_file) { strcpy(outfile, url); strcpy(urltype, "file://"); tmplfile[0] = '\0'; compspec[0] = '\0'; } else { /* check for clobber symbol, i.e, overwrite existing file */ if (*url == '!') { clobber = TRUE; url++; } else clobber = FALSE; /* parse the output file specification */ ffourl(url, urltype, outfile, tmplfile, compspec, status); if (*status > 0) { ffpmsg("could not parse the output filename: (ffinit)"); ffpmsg(url); return(*status); } } /* find which driver corresponds to the urltype */ *status = urltype2driver(urltype, &driver); if (*status) { ffpmsg("could not find driver for this file: (ffinit)"); ffpmsg(url); return(*status); } /* delete pre-existing file, if asked to do so */ if (clobber) { if (driverTable[driver].remove) (*driverTable[driver].remove)(outfile); } /* call appropriate driver to create the file */ if (driverTable[driver].create) { *status = (*driverTable[driver].create)(outfile, &handle); if (*status) { ffpmsg("failed to create new file (already exists?):"); ffpmsg(url); return(*status); } } else { ffpmsg("cannot create a new file of this type: (ffinit)"); ffpmsg(url); return(*status = FILE_NOT_CREATED); } /* allocate fitsfile structure and initialize = 0 */ *fptr = (fitsfile *) calloc(1, sizeof(fitsfile)); if (!(*fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for following file: (ffopen)"); ffpmsg(url); return(*status = MEMORY_ALLOCATION); } /* allocate FITSfile structure and initialize = 0 */ (*fptr)->Fptr = (FITSfile *) calloc(1, sizeof(FITSfile)); if (!((*fptr)->Fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for following file: (ffopen)"); ffpmsg(url); free(*fptr); *fptr = 0; return(*status = MEMORY_ALLOCATION); } slen = strlen(url) + 1; slen = maxvalue(slen, 32); /* reserve at least 32 chars */ ((*fptr)->Fptr)->filename = (char *) malloc(slen); /* mem for file name */ if ( !(((*fptr)->Fptr)->filename) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for filename: (ffinit)"); ffpmsg(url); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = FILE_NOT_CREATED); } /* mem for headstart array */ ((*fptr)->Fptr)->headstart = (LONGLONG *) calloc(1001, sizeof(LONGLONG)); if ( !(((*fptr)->Fptr)->headstart) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for headstart array: (ffinit)"); ffpmsg(url); free( ((*fptr)->Fptr)->filename); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* store the parameters describing the file */ ((*fptr)->Fptr)->MAXHDU = 1000; /* initial size of headstart */ ((*fptr)->Fptr)->filehandle = handle; /* store the file pointer */ ((*fptr)->Fptr)->driver = driver; /* driver number */ strcpy(((*fptr)->Fptr)->filename, url); /* full input filename */ ((*fptr)->Fptr)->filesize = 0; /* physical file size */ ((*fptr)->Fptr)->logfilesize = 0; /* logical file size */ ((*fptr)->Fptr)->writemode = 1; /* read-write mode */ ((*fptr)->Fptr)->datastart = DATA_UNDEFINED; /* unknown start of data */ ((*fptr)->Fptr)->curbuf = -1; /* undefined current IO buffer */ ((*fptr)->Fptr)->open_count = 1; /* structure is currently used once */ ((*fptr)->Fptr)->validcode = VALIDSTRUC; /* flag denoting valid structure */ ffldrc(*fptr, 0, IGNORE_EOF, status); /* initialize first record */ fits_store_Fptr( (*fptr)->Fptr, status); /* store Fptr address */ /* if template file was given, use it to define structure of new file */ if (tmplfile[0]) ffoptplt(*fptr, tmplfile, status); /* parse and save image compression specification, if given */ if (compspec[0]) ffparsecompspec(*fptr, compspec, status); return(*status); /* successful return */ } /*--------------------------------------------------------------------------*/ /* ffimem == fits_create_memfile */ int ffimem(fitsfile **fptr, /* O - FITS file pointer */ void **buffptr, /* I - address of memory pointer */ size_t *buffsize, /* I - size of buffer, in bytes */ size_t deltasize, /* I - increment for future realloc's */ void *(*mem_realloc)(void *p, size_t newsize), /* function */ int *status) /* IO - error status */ /* Create and initialize a new FITS file in memory */ { int driver, slen; char urltype[MAX_PREFIX_LEN]; int handle; if (*status > 0) return(*status); *fptr = 0; /* initialize null file pointer */ if (need_to_initialize) { /* this is called only once */ if (need_to_initialize != 1) { /* This is bad. looks like memory has been corrupted. */ ffpmsg("Vital CFITSIO parameters held in memory have been corrupted!!"); ffpmsg("Fatal condition detected in ffimem."); *status = FILE_NOT_CREATED; return(*status); } *status = fits_init_cfitsio(); } if (*status > 0) return(*status); strcpy(urltype, "memkeep://"); /* URL type for pre-existing memory file */ *status = urltype2driver(urltype, &driver); if (*status > 0) { ffpmsg("could not find driver for pre-existing memory file: (ffimem)"); return(*status); } /* call driver routine to "open" the memory file */ *status = mem_openmem( buffptr, buffsize, deltasize, mem_realloc, &handle); if (*status > 0) { ffpmsg("failed to open pre-existing memory file: (ffimem)"); return(*status); } /* allocate fitsfile structure and initialize = 0 */ *fptr = (fitsfile *) calloc(1, sizeof(fitsfile)); if (!(*fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for memory file: (ffimem)"); return(*status = MEMORY_ALLOCATION); } /* allocate FITSfile structure and initialize = 0 */ (*fptr)->Fptr = (FITSfile *) calloc(1, sizeof(FITSfile)); if (!((*fptr)->Fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for memory file: (ffimem)"); free(*fptr); *fptr = 0; return(*status = MEMORY_ALLOCATION); } slen = 32; /* reserve at least 32 chars */ ((*fptr)->Fptr)->filename = (char *) malloc(slen); /* mem for file name */ if ( !(((*fptr)->Fptr)->filename) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for filename: (ffimem)"); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* mem for headstart array */ ((*fptr)->Fptr)->headstart = (LONGLONG *) calloc(1001, sizeof(LONGLONG)); if ( !(((*fptr)->Fptr)->headstart) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for headstart array: (ffinit)"); free( ((*fptr)->Fptr)->filename); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* store the parameters describing the file */ ((*fptr)->Fptr)->MAXHDU = 1000; /* initial size of headstart */ ((*fptr)->Fptr)->filehandle = handle; /* file handle */ ((*fptr)->Fptr)->driver = driver; /* driver number */ strcpy(((*fptr)->Fptr)->filename, "memfile"); /* dummy filename */ ((*fptr)->Fptr)->filesize = *buffsize; /* physical file size */ ((*fptr)->Fptr)->logfilesize = *buffsize; /* logical file size */ ((*fptr)->Fptr)->writemode = 1; /* read-write mode */ ((*fptr)->Fptr)->datastart = DATA_UNDEFINED; /* unknown start of data */ ((*fptr)->Fptr)->curbuf = -1; /* undefined current IO buffer */ ((*fptr)->Fptr)->open_count = 1; /* structure is currently used once */ ((*fptr)->Fptr)->validcode = VALIDSTRUC; /* flag denoting valid structure */ ffldrc(*fptr, 0, IGNORE_EOF, status); /* initialize first record */ fits_store_Fptr( (*fptr)->Fptr, status); /* store Fptr address */ return(*status); } /*--------------------------------------------------------------------------*/ int fits_init_cfitsio(void) /* initialize anything that is required before using the CFITSIO routines */ { int status; union u_tag { short ival; char cval[2]; } u; need_to_initialize = 0; /* test for correct byteswapping. */ u.ival = 1; if ((BYTESWAPPED && u.cval[0] != 1) || (BYTESWAPPED == FALSE && u.cval[1] != 1) ) { printf ("\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); printf(" Byteswapping is not being done correctly on this system.\n"); printf(" Check the MACHINE and BYTESWAPPED definitions in fitsio2.h\n"); printf(" Please report this problem to the author at\n"); printf(" pence@tetra.gsfc.nasa.gov\n"); printf( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); return(1); } /* test that LONGLONG is an 8 byte integer */ if (sizeof(LONGLONG) != 8) { printf ("\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); printf(" CFITSIO did not find an 8-byte long integer data type.\n"); printf(" sizeof(LONGLONG) = %d\n",(int)sizeof(LONGLONG)); printf(" Please report this problem to the author at\n"); printf(" pence@tetra.gsfc.nasa.gov\n"); printf( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); return(1); } /* register the standard I/O drivers that are always available */ /* 1--------------------disk file driver-----------------------*/ status = fits_register_driver("file://", file_init, file_shutdown, file_setoptions, file_getoptions, file_getversion, file_checkfile, file_open, file_create, #ifdef HAVE_FTRUNCATE file_truncate, #else NULL, /* no file truncate function */ #endif file_close, file_remove, file_size, file_flush, file_seek, file_read, file_write); if (status) { ffpmsg("failed to register the file:// driver (init_cfitsio)"); return(status); } /* 2------------ output temporary memory file driver ----------------*/ status = fits_register_driver("mem://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ NULL, /* open function not allowed */ mem_create, mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the mem:// driver (init_cfitsio)"); return(status); } /* 3--------------input pre-existing memory file driver----------------*/ status = fits_register_driver("memkeep://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ NULL, /* file open driver function is not used */ NULL, /* create function not allowed */ mem_truncate, mem_close_keep, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the memkeep:// driver (init_cfitsio)"); return(status); } /* 4-------------------stdin stream driver----------------------*/ /* the stdin stream is copied to memory then opened in memory */ status = fits_register_driver("stdin://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, stdin_checkfile, stdin_open, NULL, /* create function not allowed */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the stdin:// driver (init_cfitsio)"); return(status); } /* 5-------------------stdin file stream driver----------------------*/ /* the stdin stream is copied to a disk file then the disk file is opened */ status = fits_register_driver("stdinfile://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ stdin_open, NULL, /* create function not allowed */ #ifdef HAVE_FTRUNCATE file_truncate, #else NULL, /* no file truncate function */ #endif file_close, file_remove, file_size, file_flush, file_seek, file_read, file_write); if (status) { ffpmsg("failed to register the stdinfile:// driver (init_cfitsio)"); return(status); } /* 6-----------------------stdout stream driver------------------*/ status = fits_register_driver("stdout://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ NULL, /* open function not required */ mem_create, mem_truncate, stdout_close, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the stdout:// driver (init_cfitsio)"); return(status); } /* 7------------------iraf disk file to memory driver -----------*/ status = fits_register_driver("irafmem://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ mem_iraf_open, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the irafmem:// driver (init_cfitsio)"); return(status); } /* 8------------------raw binary file to memory driver -----------*/ status = fits_register_driver("rawfile://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ mem_rawfile_open, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the rawfile:// driver (init_cfitsio)"); return(status); } /* 9------------------compressed disk file to memory driver -----------*/ status = fits_register_driver("compress://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ mem_compress_open, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the compress:// driver (init_cfitsio)"); return(status); } /* 10------------------compressed disk file to memory driver -----------*/ /* Identical to compress://, except it allows READWRITE access */ status = fits_register_driver("compressmem://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ mem_compress_openrw, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the compressmem:// driver (init_cfitsio)"); return(status); } /* 11------------------compressed disk file to disk file driver -------*/ status = fits_register_driver("compressfile://", file_init, file_shutdown, file_setoptions, file_getoptions, file_getversion, NULL, /* checkfile not needed */ file_compress_open, file_create, #ifdef HAVE_FTRUNCATE file_truncate, #else NULL, /* no file truncate function */ #endif file_close, file_remove, file_size, file_flush, file_seek, file_read, file_write); if (status) { ffpmsg("failed to register the compressfile:// driver (init_cfitsio)"); return(status); } /* 12---create file in memory, then compress it to disk file on close--*/ status = fits_register_driver("compressoutfile://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ NULL, /* open function not allowed */ mem_create_comp, mem_truncate, mem_close_comp, file_remove, /* delete existing compressed disk file */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg( "failed to register the compressoutfile:// driver (init_cfitsio)"); return(status); } /* Register Optional drivers */ #ifdef HAVE_NET_SERVICES /* 13--------------------root driver-----------------------*/ status = fits_register_driver("root://", root_init, root_shutdown, root_setoptions, root_getoptions, root_getversion, NULL, /* checkfile not needed */ root_open, root_create, NULL, /* No truncate possible */ root_close, NULL, /* No remove possible */ root_size, /* no size possible */ root_flush, root_seek, /* Though will always succeed */ root_read, root_write); if (status) { ffpmsg("failed to register the root:// driver (init_cfitsio)"); return(status); } /* 14--------------------http driver-----------------------*/ status = fits_register_driver("http://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, http_checkfile, http_open, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the http:// driver (init_cfitsio)"); return(status); } /* 15--------------------http file driver-----------------------*/ status = fits_register_driver("httpfile://", file_init, file_shutdown, file_setoptions, file_getoptions, file_getversion, NULL, /* checkfile not needed */ http_file_open, file_create, #ifdef HAVE_FTRUNCATE file_truncate, #else NULL, /* no file truncate function */ #endif file_close, file_remove, file_size, file_flush, file_seek, file_read, file_write); if (status) { ffpmsg("failed to register the httpfile:// driver (init_cfitsio)"); return(status); } /* 16--------------------http memory driver-----------------------*/ /* same as http:// driver, except memory file can be opened READWRITE */ status = fits_register_driver("httpmem://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, http_checkfile, http_file_open, /* this will simply call http_open */ NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the httpmem:// driver (init_cfitsio)"); return(status); } /* 17--------------------httpcompress file driver-----------------------*/ status = fits_register_driver("httpcompress://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ http_compress_open, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the httpcompress:// driver (init_cfitsio)"); return(status); } /* 18--------------------ftp driver-----------------------*/ status = fits_register_driver("ftp://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, ftp_checkfile, ftp_open, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the ftp:// driver (init_cfitsio)"); return(status); } /* 19--------------------ftp file driver-----------------------*/ status = fits_register_driver("ftpfile://", file_init, file_shutdown, file_setoptions, file_getoptions, file_getversion, NULL, /* checkfile not needed */ ftp_file_open, file_create, #ifdef HAVE_FTRUNCATE file_truncate, #else NULL, /* no file truncate function */ #endif file_close, file_remove, file_size, file_flush, file_seek, file_read, file_write); if (status) { ffpmsg("failed to register the ftpfile:// driver (init_cfitsio)"); return(status); } /* 20--------------------ftp mem driver-----------------------*/ /* same as ftp:// driver, except memory file can be opened READWRITE */ status = fits_register_driver("ftpmem://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, ftp_checkfile, ftp_file_open, /* this will simply call ftp_open */ NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the ftpmem:// driver (init_cfitsio)"); return(status); } /* 21--------------------ftp compressed file driver------------------*/ status = fits_register_driver("ftpcompress://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ ftp_compress_open, 0, /* create function not required */ mem_truncate, mem_close_free, 0, /* remove function not required */ mem_size, 0, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the ftpcompress:// driver (init_cfitsio)"); return(status); } /* === End of net drivers section === */ #endif /* ==================== SHARED MEMORY DRIVER SECTION ======================= */ #ifdef HAVE_SHMEM_SERVICES /* 22--------------------shared memory driver-----------------------*/ status = fits_register_driver("shmem://", smem_init, smem_shutdown, smem_setoptions, smem_getoptions, smem_getversion, NULL, /* checkfile not needed */ smem_open, smem_create, NULL, /* truncate file not supported yet */ smem_close, smem_remove, smem_size, smem_flush, smem_seek, smem_read, smem_write ); if (status) { /** * XXX This flag seem to get raised on Solaris for no * discernable reason (perhaps the lock file is cleared?). The * error isn't fatal so ignore). */ return( 0 ); ffpmsg("failed to register the shmem:// driver (init_cfitsio)"); return(status); } #endif /* ==================== END OF SHARED MEMORY DRIVER SECTION ================ */ #ifdef HAVE_GSIFTP /* 23--------------------gsiftp driver-----------------------*/ status = fits_register_driver("gsiftp://", gsiftp_init, gsiftp_shutdown, gsiftp_setoptions, gsiftp_getoptions, gsiftp_getversion, gsiftp_checkfile, gsiftp_open, gsiftp_create, #ifdef HAVE_FTRUNCATE gsiftp_truncate, #else NULL, #endif gsiftp_close, NULL, /* remove function not yet implemented */ gsiftp_size, gsiftp_flush, gsiftp_seek, gsiftp_read, gsiftp_write); if (status) { ffpmsg("failed to register the gsiftp:// driver (init_cfitsio)"); return(status); } #endif return(status); } /*--------------------------------------------------------------------------*/ int fits_register_driver(char *prefix, int (*init)(void), int (*shutdown)(void), int (*setoptions)(int option), int (*getoptions)(int *options), int (*getversion)(int *version), int (*checkfile) (char *urltype, char *infile, char *outfile), int (*open)(char *filename, int rwmode, int *driverhandle), int (*create)(char *filename, int *driverhandle), int (*truncate)(int driverhandle, LONGLONG filesize), int (*close)(int driverhandle), int (*fremove)(char *filename), int (*size)(int driverhandle, LONGLONG *size), int (*flush)(int driverhandle), int (*seek)(int driverhandle, LONGLONG offset), int (*read) (int driverhandle, void *buffer, long nbytes), int (*write)(int driverhandle, void *buffer, long nbytes) ) /* register all the functions needed to support an I/O driver */ { int status; if (no_of_drivers < 0 ) { /* This is bad. looks like memory has been corrupted. */ ffpmsg("Vital CFITSIO parameters held in memory have been corrupted!!"); ffpmsg("Fatal condition detected in fits_register_driver."); return(TOO_MANY_DRIVERS); } if (no_of_drivers + 1 > MAX_DRIVERS) return(TOO_MANY_DRIVERS); if (prefix == NULL) return(BAD_URL_PREFIX); if (init != NULL) { status = (*init)(); if (status) return(status); } /* fill in data in table */ strncpy(driverTable[no_of_drivers].prefix, prefix, MAX_PREFIX_LEN); driverTable[no_of_drivers].prefix[MAX_PREFIX_LEN - 1] = 0; driverTable[no_of_drivers].init = init; driverTable[no_of_drivers].shutdown = shutdown; driverTable[no_of_drivers].setoptions = setoptions; driverTable[no_of_drivers].getoptions = getoptions; driverTable[no_of_drivers].getversion = getversion; driverTable[no_of_drivers].checkfile = checkfile; driverTable[no_of_drivers].open = open; driverTable[no_of_drivers].create = create; driverTable[no_of_drivers].truncate = truncate; driverTable[no_of_drivers].close = close; driverTable[no_of_drivers].remove = fremove; driverTable[no_of_drivers].size = size; driverTable[no_of_drivers].flush = flush; driverTable[no_of_drivers].seek = seek; driverTable[no_of_drivers].read = read; driverTable[no_of_drivers].write = write; no_of_drivers++; /* increment the number of drivers */ return(0); } /*--------------------------------------------------------------------------*/ int ffiurl(char *url, /* input filename */ char *urltype, /* e.g., 'file://', 'http://', 'mem://' */ char *infilex, /* root filename (may be complete path) */ char *outfile, /* optional output file name */ char *extspec, /* extension spec: +n or [extname, extver] */ char *rowfilterx, /* boolean row filter expression */ char *binspec, /* histogram binning specifier */ char *colspec, /* column or keyword modifier expression */ int *status) /* parse the input URL into its basic components. This routine is big and ugly and should be redesigned someday! */ { return fits_parse_input_filename(url, urltype, infilex, outfile, extspec, rowfilterx, binspec, colspec, 0, status); } /*--------------------------------------------------------------------------*/ int ffifile(char *url, /* input filename */ char *urltype, /* e.g., 'file://', 'http://', 'mem://' */ char *infilex, /* root filename (may be complete path) */ char *outfile, /* optional output file name */ char *extspec, /* extension spec: +n or [extname, extver] */ char *rowfilterx, /* boolean row filter expression */ char *binspec, /* histogram binning specifier */ char *colspec, /* column or keyword modifier expression */ char *pixfilter, /* pixel filter expression */ int *status) /* fits_parse_input_filename parse the input URL into its basic components. This routine is big and ugly and should be redesigned someday! */ { int ii, jj, slen, infilelen, plus_ext = 0, collen; char *ptr1, *ptr2, *ptr3, *tmptr; int hasAt, hasDot, hasOper, followingOper, spaceTerm, rowFilter; int colStart, binStart, pixStart; /* must have temporary variable for these, in case inputs are NULL */ char *infile; char *rowfilter; char *tmpstr; if (*status > 0) return(*status); /* Initialize null strings */ if (infilex) *infilex = '\0'; if (urltype) *urltype = '\0'; if (outfile) *outfile = '\0'; if (extspec) *extspec = '\0'; if (binspec) *binspec = '\0'; if (colspec) *colspec = '\0'; if (rowfilterx) *rowfilterx = '\0'; if (pixfilter) *pixfilter = '\0'; slen = strlen(url); if (slen == 0) /* blank filename ?? */ return(*status); /* allocate memory for 3 strings, each as long as the input url */ infile = (char *) calloc(3, slen + 1); if (!infile) return(*status = MEMORY_ALLOCATION); rowfilter = &infile[slen + 1]; tmpstr = &rowfilter[slen + 1]; ptr1 = url; /* -------------------------------------------------------- */ /* get urltype (e.g., file://, ftp://, http://, etc.) */ /* --------------------------------------------------------- */ if (*ptr1 == '-' && ( *(ptr1 +1) == 0 || *(ptr1 +1) == ' ' || *(ptr1 +1) == '[' || *(ptr1 +1) == '(' ) ) { /* "-" means read file from stdin. Also support "- ", */ /* "-[extname]" and '-(outfile.fits)" but exclude disk file */ /* names that begin with a minus sign, e.g., "-55d33m.fits" */ if (urltype) strcat(urltype, "stdin://"); ptr1++; } else if (!strncasecmp(ptr1, "stdin", 5)) { if (urltype) strcat(urltype, "stdin://"); ptr1 = ptr1 + 5; } else { ptr2 = strstr(ptr1, "://"); ptr3 = strstr(ptr1, "(" ); if (ptr3 && (ptr3 < ptr2) ) { /* the urltype follows a '(' character, so it must apply */ /* to the output file, and is not the urltype of the input file */ ptr2 = 0; /* so reset pointer to zero */ } if (ptr2) /* copy the explicit urltype string */ { if (urltype) strncat(urltype, ptr1, ptr2 - ptr1 + 3); ptr1 = ptr2 + 3; } else if (!strncmp(ptr1, "ftp:", 4) ) { /* the 2 //'s are optional */ if (urltype) strcat(urltype, "ftp://"); ptr1 += 4; } else if (!strncmp(ptr1, "gsiftp:", 7) ) { /* the 2 //'s are optional */ if (urltype) strcat(urltype, "gsiftp://"); ptr1 += 7; } else if (!strncmp(ptr1, "http:", 5) ) { /* the 2 //'s are optional */ if (urltype) strcat(urltype, "http://"); ptr1 += 5; } else if (!strncmp(ptr1, "mem:", 4) ) { /* the 2 //'s are optional */ if (urltype) strcat(urltype, "mem://"); ptr1 += 4; } else if (!strncmp(ptr1, "shmem:", 6) ) { /* the 2 //'s are optional */ if (urltype) strcat(urltype, "shmem://"); ptr1 += 6; } else if (!strncmp(ptr1, "file:", 5) ) { /* the 2 //'s are optional */ if (urltype) strcat(urltype, "file://"); ptr1 += 5; } else /* assume file driver */ { if (urltype) strcat(urltype, "file://"); } } /* ---------------------------------------------------------- If this is a http:// type file, then the cgi file name could include the '[' character, which should not be interpreted as part of CFITSIO's Extended File Name Syntax. Test for this case by seeing if the last character is a ']' or ')'. If it is not, then just treat the whole input string as the file name and do not attempt to interprete the name using the extended filename syntax. ----------------------------------------------------------- */ if (urltype && !strncmp(urltype, "http://", 7) ) { /* test for opening parenthesis or bracket in the file name */ if( strchr(ptr1, '(' ) || strchr(ptr1, '[' ) ) { slen = strlen(ptr1); ptr3 = ptr1 + slen - 1; while (*ptr3 == ' ') /* ignore trailing blanks */ ptr3--; if (*ptr3 != ']' && *ptr3 != ')' ) { /* name doesn't end with a ']' or ')' so don't try */ /* to parse this unusual string (may be cgi string) */ if (infilex) strcpy(infilex, ptr1); free(infile); return(*status); } } } /* ---------------------------------------------------------- Look for VMS style filenames like: disk:[directory.subdirectory]filename.ext, or [directory.subdirectory]filename.ext Check if the first character is a '[' and urltype != stdin or if there is a ':[' string in the remaining url string. If so, then need to move past this bracket character before search for the opening bracket of a filter specification. ----------------------------------------------------------- */ tmptr = ptr1; if (*ptr1 == '[') { if (*url != '-') tmptr = ptr1 + 1; /* this bracket encloses a VMS directory name */ } else { tmptr = strstr(ptr1, ":["); if (tmptr) /* these 2 chars are part of the VMS disk and directory */ tmptr += 2; else tmptr = ptr1; } /* ------------------------ */ /* get the input file name */ /* ------------------------ */ ptr2 = strchr(tmptr, '('); /* search for opening parenthesis ( */ ptr3 = strchr(tmptr, '['); /* search for opening bracket [ */ if (ptr2 == ptr3) /* simple case: no [ or ( in the file name */ { strcat(infile, ptr1); } else if (!ptr3 || /* no bracket, so () enclose output file name */ (ptr2 && (ptr2 < ptr3)) ) /* () enclose output name before bracket */ { strncat(infile, ptr1, ptr2 - ptr1); ptr2++; ptr1 = strchr(ptr2, ')' ); /* search for closing ) */ if (!ptr1) { free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ) */ } if (outfile) strncat(outfile, ptr2, ptr1 - ptr2); /* the opening [ could have been part of output name, */ /* e.g., file(out[compress])[3][#row > 5] */ /* so search again for opening bracket following the closing ) */ ptr3 = strchr(ptr1, '['); } else /* bracket comes first, so there is no output name */ { strncat(infile, ptr1, ptr3 - ptr1); } /* strip off any trailing blanks in the names */ slen = strlen(infile); while ( (--slen) > 0 && infile[slen] == ' ') infile[slen] = '\0'; if (outfile) { slen = strlen(outfile); while ( (--slen) > 0 && outfile[slen] == ' ') outfile[slen] = '\0'; } /* --------------------------------------------- */ /* check if this is an IRAF file (.imh extension */ /* --------------------------------------------- */ if (strstr(infile, ".imh")) { if (urltype) strcpy(urltype, "irafmem://"); } /* --------------------------------------------- */ /* check if the 'filename+n' convention has been */ /* used to specifiy which HDU number to open */ /* --------------------------------------------- */ jj = strlen(infile); for (ii = jj - 1; ii >= 0; ii--) { if (infile[ii] == '+') /* search backwards for '+' sign */ break; } if (ii > 0 && (jj - ii) < 7) /* limit extension numbers to 5 digits */ { infilelen = ii; ii++; ptr1 = infile+ii; /* pointer to start of sequence */ for (; ii < jj; ii++) { if (!isdigit((int) infile[ii] ) ) /* are all the chars digits? */ break; } if (ii == jj) { /* yes, the '+n' convention was used. Copy */ /* the digits to the output extspec string. */ plus_ext = 1; if (extspec) strncpy(extspec, ptr1, jj - infilelen); infile[infilelen] = '\0'; /* delete the extension number */ } } /* -------------------------------------------------------------------- */ /* if '*' was given for the output name expand it to the root file name */ /* -------------------------------------------------------------------- */ if (outfile && outfile[0] == '*') { /* scan input name backwards to the first '/' character */ for (ii = jj - 1; ii >= 0; ii--) { if (infile[ii] == '/' || ii == 0) { strcpy(outfile, &infile[ii + 1]); break; } } } /* ------------------------------------------ */ /* copy strings from local copy to the output */ /* ------------------------------------------ */ if (infilex) strcpy(infilex, infile); /* ---------------------------------------------------------- */ /* if no '[' character in the input string, then we are done. */ /* ---------------------------------------------------------- */ if (!ptr3) { free(infile); return(*status); } /* ------------------------------------------- */ /* see if [ extension specification ] is given */ /* ------------------------------------------- */ if (!plus_ext) /* extension no. not already specified? Then */ /* first brackets must enclose extension name or # */ /* or it encloses a image subsection specification */ /* or a raw binary image specifier */ /* Or, the extension specification may have been */ /* omitted and we have to guess what the user intended */ { ptr1 = ptr3 + 1; /* pointer to first char after the [ */ ptr2 = strchr(ptr1, ']' ); /* search for closing ] */ if (!ptr2) { ffpmsg("input file URL is missing closing bracket ']'"); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } /* ---------------------------------------------- */ /* First, test if this is a rawfile specifier */ /* which looks something like: '[ib512,512:2880]' */ /* Test if first character is b,i,j,d,r,f, or u, */ /* and optional second character is b or l, */ /* followed by one or more digits, */ /* finally followed by a ',', ':', or ']' */ /* ---------------------------------------------- */ if (*ptr1 == 'b' || *ptr1 == 'B' || *ptr1 == 'i' || *ptr1 == 'I' || *ptr1 == 'j' || *ptr1 == 'J' || *ptr1 == 'd' || *ptr1 == 'D' || *ptr1 == 'r' || *ptr1 == 'R' || *ptr1 == 'f' || *ptr1 == 'F' || *ptr1 == 'u' || *ptr1 == 'U') { /* next optional character may be a b or l (for Big or Little) */ ptr1++; if (*ptr1 == 'b' || *ptr1 == 'B' || *ptr1 == 'l' || *ptr1 == 'L') ptr1++; if (isdigit((int) *ptr1)) /* must have at least 1 digit */ { while (isdigit((int) *ptr1)) ptr1++; /* skip over digits */ if (*ptr1 == ',' || *ptr1 == ':' || *ptr1 == ']' ) { /* OK, this looks like a rawfile specifier */ if (urltype) { if (strstr(urltype, "stdin") ) strcpy(urltype, "rawstdin://"); else strcpy(urltype, "rawfile://"); } /* append the raw array specifier to infilex */ if (infilex) { strcat(infilex, ptr3); ptr1 = strchr(infilex, ']'); /* find the closing ] char */ if (ptr1) *(ptr1 + 1) = '\0'; /* terminate string after the ] */ } if (extspec) strcpy(extspec, "0"); /* the 0 ext number is implicit */ tmptr = strchr(ptr2 + 1, '[' ); /* search for another [ char */ /* copy any remaining characters into rowfilterx */ if (tmptr && rowfilterx) { strcat(rowfilterx, tmptr + 1); tmptr = strchr(rowfilterx, ']' ); /* search for closing ] */ if (tmptr) *tmptr = '\0'; /* overwrite the ] with null terminator */ } free(infile); /* finished parsing, so return */ return(*status); } } } /* end of rawfile specifier test */ /* -------------------------------------------------------- */ /* Not a rawfile, so next, test if this is an image section */ /* i.e., an integer followed by a ':' or a '*' or '-*' */ /* -------------------------------------------------------- */ ptr1 = ptr3 + 1; /* reset pointer to first char after the [ */ tmptr = ptr1; while (*tmptr == ' ') tmptr++; /* skip leading blanks */ while (isdigit((int) *tmptr)) tmptr++; /* skip over leading digits */ if (*tmptr == ':' || *tmptr == '*' || *tmptr == '-') { /* this is an image section specifier */ strcat(rowfilter, ptr3); /* don't want to assume 0 extension any more; may imply an image extension. if (extspec) strcpy(extspec, "0"); */ } else { /* ----------------------------------------------------------------- Not an image section or rawfile spec so may be an extension spec. Examples of valid extension specifiers: [3] - 3rd extension; 0 = primary array [events] - events extension [events, 2] - events extension, with EXTVER = 2 [events,2] - spaces are optional [events, 3, b] - same as above, plus XTENSION = 'BINTABLE' [PICS; colName(12)] - an image in row 12 of the colName column in the PICS table extension [PICS; colName(exposure > 1000)] - as above, but find image in first row with with exposure column value > 1000. [Rate Table] - extension name can contain spaces! [Rate Table;colName(exposure>1000)] Examples of other types of specifiers (Not extension specifiers) [bin] !!! this is ambiguous, and can't be distinguished from a valid extension specifier [bini X=1:512:16] (also binb, binj, binr, and bind are allowed) [binr (X,Y) = 5] [bin @binfilter.txt] [col Time;rate] [col PI=PHA * 1.1] [col -Time; status] [X > 5] [X>5] [@filter.txt] [StatusCol] !!! this is ambiguous, and can't be distinguished from a valid extension specifier [StatusCol==0] [StatusCol || x>6] [gtifilter()] [regfilter("region.reg")] There will always be some ambiguity between an extension name and a boolean row filtering expression, (as in a couple of the above examples). If there is any doubt, the expression should be treated as an extension specification; The user can always add an explicit expression specifier to override this interpretation. The following decision logic will be used: 1) locate the first token, terminated with a space, comma, semi-colon, or closing bracket. 2) the token is not part of an extension specifier if any of the following is true: - if the token begins with '@' and contains a '.' - if the token contains an operator: = > < || && - if the token begins with "gtifilter(" or "regfilter(" - if the token is terminated by a space and is followed by additional characters (not a ']') AND any of the following: - the token is 'col' - the token is 3 or 4 chars long and begins with 'bin' - the second token begins with an operator: ! = < > | & + - * / % 3) otherwise, the string is assumed to be an extension specifier ----------------------------------------------------------------- */ tmptr = ptr1; while(*tmptr == ' ') tmptr++; hasAt = 0; hasDot = 0; hasOper = 0; followingOper = 0; spaceTerm = 0; rowFilter = 0; colStart = 0; binStart = 0; pixStart = 0; if (*tmptr == '@') /* test for leading @ symbol */ hasAt = 1; if ( !strncasecmp(tmptr, "col ", 4) ) colStart = 1; if ( !strncasecmp(tmptr, "bin", 3) ) binStart = 1; if ( !strncasecmp(tmptr, "pix", 3) ) pixStart = 1; if ( !strncasecmp(tmptr, "gtifilter(", 10) || !strncasecmp(tmptr, "regfilter(", 10) ) { rowFilter = 1; } else { /* parse the first token of the expression */ for (ii = 0; ii < ptr2 - ptr1 + 1; ii++, tmptr++) { if (*tmptr == '.') hasDot = 1; else if (*tmptr == '=' || *tmptr == '>' || *tmptr == '<' || (*tmptr == '|' && *(tmptr+1) == '|') || (*tmptr == '&' && *(tmptr+1) == '&') ) hasOper = 1; else if (*tmptr == ',' || *tmptr == ';' || *tmptr == ']') { break; } else if (*tmptr == ' ') /* a space char? */ { while(*tmptr == ' ') /* skip spaces */ tmptr++; if (*tmptr == ']') /* is this the end? */ break; spaceTerm = 1; /* 1st token is terminated by space */ /* test if this is a column or binning specifier */ if (colStart || (ii <= 4 && (binStart || pixStart)) ) rowFilter = 1; else { /* check if next character is an operator */ if (*tmptr == '=' || *tmptr == '>' || *tmptr == '<' || *tmptr == '|' || *tmptr == '&' || *tmptr == '!' || *tmptr == '+' || *tmptr == '-' || *tmptr == '*' || *tmptr == '/' || *tmptr == '%') followingOper = 1; } break; } } } /* test if this is NOT an extension specifier */ if ( rowFilter || (pixStart && spaceTerm) || (hasAt && hasDot) || hasOper || (spaceTerm && followingOper) ) { /* this is (probably) not an extension specifier */ /* so copy all chars to filter spec string */ strcat(rowfilter, ptr3); } else { /* this appears to be a legit extension specifier */ /* copy the extension specification */ if (extspec) strncat(extspec, ptr1, ptr2 - ptr1); /* copy any remaining chars to filter spec string */ strcat(rowfilter, ptr2 + 1); } } } /* end of if (!plus_ext) */ else { /* ------------------------------------------------------------------ */ /* already have extension, so this must be a filter spec of some sort */ /* ------------------------------------------------------------------ */ strcat(rowfilter, ptr3); } /* strip off any trailing blanks from filter */ slen = strlen(rowfilter); while ( (--slen) >= 0 && rowfilter[slen] == ' ') rowfilter[slen] = '\0'; if (!rowfilter[0]) { free(infile); return(*status); /* nothing left to parse */ } /* ------------------------------------------------ */ /* does the filter contain a binning specification? */ /* ------------------------------------------------ */ ptr1 = strstr(rowfilter, "[bin"); /* search for "[bin" */ if (!ptr1) ptr1 = strstr(rowfilter, "[BIN"); /* search for "[BIN" */ if (!ptr1) ptr1 = strstr(rowfilter, "[Bin"); /* search for "[Bin" */ if (ptr1) { ptr2 = ptr1 + 4; /* end of the '[bin' string */ if (*ptr2 == 'b' || *ptr2 == 'i' || *ptr2 == 'j' || *ptr2 == 'r' || *ptr2 == 'd') ptr2++; /* skip the datatype code letter */ if ( *ptr2 != ' ' && *ptr2 != ']') ptr1 = NULL; /* bin string must be followed by space or ] */ } if (ptr1) { /* found the binning string */ if (binspec) { strcpy(binspec, ptr1 + 1); ptr2 = strchr(binspec, ']'); if (ptr2) /* terminate the binning filter */ { *ptr2 = '\0'; if ( *(--ptr2) == ' ') /* delete trailing spaces */ *ptr2 = '\0'; } else { ffpmsg("input file URL is missing closing bracket ']'"); ffpmsg(rowfilter); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } } /* delete the binning spec from the row filter string */ ptr2 = strchr(ptr1, ']'); strcpy(tmpstr, ptr2+1); /* copy any chars after the binspec */ strcpy(ptr1, tmpstr); /* overwrite binspec */ } /* --------------------------------------------------------- */ /* does the filter contain a column selection specification? */ /* --------------------------------------------------------- */ ptr1 = strstr(rowfilter, "[col "); if (!ptr1) { ptr1 = strstr(rowfilter, "[COL "); if (!ptr1) ptr1 = strstr(rowfilter, "[Col "); } if (ptr1) { /* find the end of the column specifier */ ptr2 = ptr1 + 5; while (*ptr2 != ']') { if (*ptr2 == '\0') { ffpmsg("input file URL is missing closing bracket ']'"); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } if (*ptr2 == '\'') /* start of a literal string */ { ptr2 = strchr(ptr2 + 1, '\''); /* find closing quote */ if (!ptr2) { ffpmsg ("literal string in input file URL is missing closing single quote"); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } } if (*ptr2 == '[') /* set of nested square brackets */ { ptr2 = strchr(ptr2 + 1, ']'); /* find closing bracket */ if (!ptr2) { ffpmsg ("nested brackets in input file URL is missing closing bracket"); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } } ptr2++; /* continue search for the closing bracket character */ } collen = ptr2 - ptr1 - 1; if (colspec) /* copy the column specifier to output string */ { strncpy(colspec, ptr1 + 1, collen); colspec[collen] = '\0'; while (colspec[--collen] == ' ') colspec[collen] = '\0'; /* strip trailing blanks */ } /* delete the column selection spec from the row filter string */ strcpy(tmpstr, ptr2 + 1); /* copy any chars after the colspec */ strcpy(ptr1, tmpstr); /* overwrite binspec */ } /* --------------------------------------------------------- */ /* does the filter contain a pixel filter specification? */ /* --------------------------------------------------------- */ ptr1 = strstr(rowfilter, "[pix"); if (!ptr1) { ptr1 = strstr(rowfilter, "[PIX"); if (!ptr1) ptr1 = strstr(rowfilter, "[Pix"); } if (ptr1) { ptr2 = ptr1 + 4; /* end of the '[pix' string */ if (*ptr2 == 'b' || *ptr2 == 'i' || *ptr2 == 'j' || *ptr2 == 'B' || *ptr2 == 'I' || *ptr2 == 'J' || *ptr2 == 'r' || *ptr2 == 'd' || *ptr2 == 'R' || *ptr2 == 'D') ptr2++; /* skip the datatype code letter */ if (*ptr2 == '1') ptr2++; /* skip the single HDU indicator */ if ( *ptr2 != ' ') ptr1 = NULL; /* pix string must be followed by space */ } if (ptr1) { /* find the end of the pixel filter */ while (*ptr2 != ']') { if (*ptr2 == '\0') { ffpmsg("input file URL is missing closing bracket ']'"); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } if (*ptr2 == '\'') /* start of a literal string */ { ptr2 = strchr(ptr2 + 1, '\''); /* find closing quote */ if (!ptr2) { ffpmsg ("literal string in input file URL is missing closing single quote"); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } } if (*ptr2 == '[') /* set of nested square brackets */ { ptr2 = strchr(ptr2 + 1, ']'); /* find closing bracket */ if (!ptr2) { ffpmsg ("nested brackets in input file URL is missing closing bracket"); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } } ptr2++; /* continue search for the closing bracket character */ } collen = ptr2 - ptr1 - 1; if (pixfilter) /* copy the column specifier to output string */ { strncpy(pixfilter, ptr1 + 1, collen); pixfilter[collen] = '\0'; while (pixfilter[--collen] == ' ') pixfilter[collen] = '\0'; /* strip trailing blanks */ } /* delete the pixel filter from the row filter string */ strcpy(tmpstr, ptr2 + 1); /* copy any chars after the pixel filter */ strcpy(ptr1, tmpstr); /* overwrite binspec */ } /* copy the remaining string to the rowfilter output... should only */ /* contain a rowfilter expression of the form "[expr]" */ if (rowfilterx && rowfilter[0]) { ptr2 = rowfilter + strlen(rowfilter) - 1; if( rowfilter[0]=='[' && *ptr2==']' ) { *ptr2 = '\0'; strcpy(rowfilterx, rowfilter+1); } else { ffpmsg("input file URL lacks valid row filter expression"); *status = URL_PARSE_ERROR; } } free(infile); return(*status); } /*--------------------------------------------------------------------------*/ int ffexist(const char *infile, /* I - input filename or URL */ int *exists, /* O - 2 = a compressed version of file exists */ /* 1 = yes, disk file exists */ /* 0 = no, disk file could not be found */ /* -1 = infile is not a disk file (could */ /* be a http, ftp, gsiftp, smem, or stdin file) */ int *status) /* I/O status */ /* test if the input file specifier is an existing file on disk If the specified file can't be found, it then searches for a compressed version of the file. */ { FILE *diskfile; char rootname[FLEN_FILENAME]; char *ptr1; if (*status > 0) return(*status); /* strip off any extname or filters from the name */ ffrtnm( (char *)infile, rootname, status); ptr1 = strstr(rootname, "://"); if (ptr1 || *rootname == '-') { if (!strncmp(rootname, "file", 4) ) { ptr1 = ptr1 + 3; /* pointer to start of the disk file name */ } else { *exists = -1; /* this is not a disk file */ return (*status); } } else { ptr1 = rootname; } /* see if the disk file exists */ if (file_openfile(ptr1, 0, &diskfile)) { /* no, couldn't open file, so see if there is a compressed version */ if (file_is_compressed(ptr1) ) { *exists = 2; /* a compressed version of the file exists */ } else { *exists = 0; /* neither file nor compressed version exist */ } } else { /* yes, file exists */ *exists = 1; fclose(diskfile); } return(*status); } /*--------------------------------------------------------------------------*/ int ffrtnm(char *url, char *rootname, int *status) /* parse the input URL, returning the root name (filetype://basename). */ { int ii, jj, slen, infilelen; char *ptr1, *ptr2, *ptr3; char urltype[MAX_PREFIX_LEN]; char infile[FLEN_FILENAME]; if (*status > 0) return(*status); ptr1 = url; *rootname = '\0'; *urltype = '\0'; *infile = '\0'; /* get urltype (e.g., file://, ftp://, http://, etc.) */ if (*ptr1 == '-') /* "-" means read file from stdin */ { strcat(urltype, "-"); ptr1++; } else if (!strncmp(ptr1, "stdin", 5) || !strncmp(ptr1, "STDIN", 5)) { strcat(urltype, "-"); ptr1 = ptr1 + 5; } else { ptr2 = strstr(ptr1, "://"); ptr3 = strstr(ptr1, "(" ); if (ptr3 && (ptr3 < ptr2) ) { /* the urltype follows a '(' character, so it must apply */ /* to the output file, and is not the urltype of the input file */ ptr2 = 0; /* so reset pointer to zero */ } if (ptr2) /* copy the explicit urltype string */ { strncat(urltype, ptr1, ptr2 - ptr1 + 3); ptr1 = ptr2 + 3; } else if (!strncmp(ptr1, "ftp:", 4) ) { /* the 2 //'s are optional */ strcat(urltype, "ftp://"); ptr1 += 4; } else if (!strncmp(ptr1, "gsiftp:", 7) ) { /* the 2 //'s are optional */ strcat(urltype, "gsiftp://"); ptr1 += 7; } else if (!strncmp(ptr1, "http:", 5) ) { /* the 2 //'s are optional */ strcat(urltype, "http://"); ptr1 += 5; } else if (!strncmp(ptr1, "mem:", 4) ) { /* the 2 //'s are optional */ strcat(urltype, "mem://"); ptr1 += 4; } else if (!strncmp(ptr1, "shmem:", 6) ) { /* the 2 //'s are optional */ strcat(urltype, "shmem://"); ptr1 += 6; } else if (!strncmp(ptr1, "file:", 5) ) { /* the 2 //'s are optional */ ptr1 += 5; } /* else assume file driver */ } /* get the input file name */ ptr2 = strchr(ptr1, '('); /* search for opening parenthesis ( */ ptr3 = strchr(ptr1, '['); /* search for opening bracket [ */ if (ptr2 == ptr3) /* simple case: no [ or ( in the file name */ { strcat(infile, ptr1); } else if (!ptr3) /* no bracket, so () enclose output file name */ { strncat(infile, ptr1, ptr2 - ptr1); ptr2++; ptr1 = strchr(ptr2, ')' ); /* search for closing ) */ if (!ptr1) return(*status = URL_PARSE_ERROR); /* error, no closing ) */ } else if (ptr2 && (ptr2 < ptr3)) /* () enclose output name before bracket */ { strncat(infile, ptr1, ptr2 - ptr1); ptr2++; ptr1 = strchr(ptr2, ')' ); /* search for closing ) */ if (!ptr1) return(*status = URL_PARSE_ERROR); /* error, no closing ) */ } else /* bracket comes first, so there is no output name */ { strncat(infile, ptr1, ptr3 - ptr1); } /* strip off any trailing blanks in the names */ slen = strlen(infile); for (ii = slen - 1; ii > 0; ii--) { if (infile[ii] == ' ') infile[ii] = '\0'; else break; } /* --------------------------------------------- */ /* check if the 'filename+n' convention has been */ /* used to specifiy which HDU number to open */ /* --------------------------------------------- */ jj = strlen(infile); for (ii = jj - 1; ii >= 0; ii--) { if (infile[ii] == '+') /* search backwards for '+' sign */ break; } if (ii > 0 && (jj - ii) < 5) /* limit extension numbers to 4 digits */ { infilelen = ii; ii++; for (; ii < jj; ii++) { if (!isdigit((int) infile[ii] ) ) /* are all the chars digits? */ break; } if (ii == jj) { /* yes, the '+n' convention was used. */ infile[infilelen] = '\0'; /* delete the extension number */ } } strcat(rootname, urltype); /* construct the root name */ strcat(rootname, infile); return(*status); } /*--------------------------------------------------------------------------*/ int ffourl(char *url, /* I - full input URL */ char *urltype, /* O - url type */ char *outfile, /* O - base file name */ char *tpltfile, /* O - template file name, if any */ char *compspec, /* O - compression specification, if any */ int *status) /* parse the output URL into its basic components. */ { char *ptr1, *ptr2, *ptr3; if (*status > 0) return(*status); if (urltype) *urltype = '\0'; if (outfile) *outfile = '\0'; if (tpltfile) *tpltfile = '\0'; if (compspec) *compspec = '\0'; ptr1 = url; while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; if ( ( (*ptr1 == '-') && ( *(ptr1 +1) == 0 || *(ptr1 +1) == ' ' ) ) || !strcmp(ptr1, "stdout") || !strcmp(ptr1, "STDOUT")) /* "-" means write to stdout; also support "- " */ /* but exclude disk file names that begin with a minus sign */ /* e.g., "-55d33m.fits" */ { if (urltype) strcpy(urltype, "stdout://"); } else { /* not writing to stdout */ /* get urltype (e.g., file://, ftp://, http://, etc.) */ ptr2 = strstr(ptr1, "://"); if (ptr2) /* copy the explicit urltype string */ { if (urltype) strncat(urltype, ptr1, ptr2 - ptr1 + 3); ptr1 = ptr2 + 3; } else /* assume file driver */ { if (urltype) strcat(urltype, "file://"); } /* look for template file name, enclosed in parenthesis */ ptr2 = strchr(ptr1, '('); /* look for image compression parameters, enclosed in sq. brackets */ ptr3 = strchr(ptr1, '['); if (outfile) { if (ptr2) /* template file was specified */ strncat(outfile, ptr1, ptr2 - ptr1); else if (ptr3) /* compression was specified */ strncat(outfile, ptr1, ptr3 - ptr1); else /* no template file or compression */ strcpy(outfile, ptr1); } if (ptr2) /* template file was specified */ { ptr2++; ptr1 = strchr(ptr2, ')' ); /* search for closing ) */ if (!ptr1) { return(*status = URL_PARSE_ERROR); /* error, no closing ) */ } if (tpltfile) strncat(tpltfile, ptr2, ptr1 - ptr2); } if (ptr3) /* compression was specified */ { ptr3++; ptr1 = strchr(ptr3, ']' ); /* search for closing ] */ if (!ptr1) { return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } if (compspec) strncat(compspec, ptr3, ptr1 - ptr3); } /* check if a .gz compressed output file is to be created */ /* by seeing if the filename ends in '.gz' */ if (urltype && outfile) { if (!strcmp(urltype, "file://") ) { ptr1 = strstr(outfile, ".gz"); if (ptr1) { /* make sure the ".gz" is at the end of the file name */ ptr1 += 3; if (*ptr1 == 0 || *ptr1 == ' ' ) strcpy(urltype, "compressoutfile://"); } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffexts(char *extspec, int *extnum, char *extname, int *extvers, int *hdutype, char *imagecolname, char *rowexpress, int *status) { /* Parse the input extension specification string, returning either the extension number or the values of the EXTNAME, EXTVERS, and XTENSION keywords in desired extension. Also return the name of the column containing an image, and an expression to be used to determine which row to use, if present. */ char *ptr1, *ptr2; int slen, nvals; int notint = 1; /* initially assume specified extname is not an integer */ char tmpname[FLEN_VALUE], *loc; *extnum = 0; *extname = '\0'; *extvers = 0; *hdutype = ANY_HDU; *imagecolname = '\0'; *rowexpress = '\0'; if (*status > 0) return(*status); ptr1 = extspec; /* pointer to first char */ while (*ptr1 == ' ') /* skip over any leading blanks */ ptr1++; if (isdigit((int) *ptr1)) /* is the extension specification a number? */ { notint = 0; /* looks like extname may actually be the ext. number */ *extnum = strtol(ptr1, &loc, 10); /* read the string as an integer */ while (*loc == ' ') /* skip over trailing blanks */ loc++; /* check for read error, or junk following the integer */ if ((*loc != '\0' && *loc != ';' ) || (errno == ERANGE) ) { *extnum = 0; notint = 1; /* no, extname was not a simple integer after all */ } if ( *extnum < 0 || *extnum > 99999) { *extnum = 0; /* this is not a reasonable extension number */ ffpmsg("specified extension number is out of range:"); ffpmsg(extspec); return(*status = URL_PARSE_ERROR); } } /* This logic was too simple, and failed on extnames like '1000TEMP' where it would try to move to the 1000th extension if (isdigit((int) *ptr1)) { sscanf(ptr1, "%d", extnum); if (*extnum < 0 || *extnum > 9999) { *extnum = 0; ffpmsg("specified extension number is out of range:"); ffpmsg(extspec); return(*status = URL_PARSE_ERROR); } } */ if (notint) { /* not a number, so EXTNAME must be specified, followed by */ /* optional EXTVERS and XTENSION values */ /* don't use space char as end indicator, because there */ /* may be imbedded spaces in the EXTNAME value */ slen = strcspn(ptr1, ",:;"); /* length of EXTNAME */ strncat(extname, ptr1, slen); /* EXTNAME value */ /* now remove any trailing blanks */ while (slen > 0 && *(extname + slen -1) == ' ') { *(extname + slen -1) = '\0'; slen--; } ptr1 += slen; slen = strspn(ptr1, " ,:"); /* skip delimiter characters */ ptr1 += slen; slen = strcspn(ptr1, " ,:;"); /* length of EXTVERS */ if (slen) { nvals = sscanf(ptr1, "%d", extvers); /* EXTVERS value */ if (nvals != 1) { ffpmsg("illegal EXTVER value in input URL:"); ffpmsg(extspec); return(*status = URL_PARSE_ERROR); } ptr1 += slen; slen = strspn(ptr1, " ,:"); /* skip delimiter characters */ ptr1 += slen; slen = strcspn(ptr1, ";"); /* length of HDUTYPE */ if (slen) { if (*ptr1 == 'b' || *ptr1 == 'B') *hdutype = BINARY_TBL; else if (*ptr1 == 't' || *ptr1 == 'T' || *ptr1 == 'a' || *ptr1 == 'A') *hdutype = ASCII_TBL; else if (*ptr1 == 'i' || *ptr1 == 'I') *hdutype = IMAGE_HDU; else { ffpmsg("unknown type of HDU in input URL:"); ffpmsg(extspec); return(*status = URL_PARSE_ERROR); } } } else { strcpy(tmpname, extname); ffupch(tmpname); if (!strcmp(tmpname, "PRIMARY") || !strcmp(tmpname, "P") ) *extname = '\0'; /* return extnum = 0 */ } } ptr1 = strchr(ptr1, ';'); if (ptr1) { /* an image is to be opened; the image is contained in a single */ /* cell of a binary table. A column name and an expression to */ /* determine which row to use has been entered. */ ptr1++; /* skip over the ';' delimiter */ while (*ptr1 == ' ') /* skip over any leading blanks */ ptr1++; ptr2 = strchr(ptr1, '('); if (!ptr2) { ffpmsg("illegal specification of image in table cell in input URL:"); ffpmsg(" did not find a row expression enclosed in ( )"); ffpmsg(extspec); return(*status = URL_PARSE_ERROR); } strncat(imagecolname, ptr1, ptr2 - ptr1); /* copy column name */ ptr2++; /* skip over the '(' delimiter */ while (*ptr2 == ' ') /* skip over any leading blanks */ ptr2++; ptr1 = strchr(ptr2, ')'); if (!ptr2) { ffpmsg("illegal specification of image in table cell in input URL:"); ffpmsg(" missing closing ')' character in row expression"); ffpmsg(extspec); return(*status = URL_PARSE_ERROR); } strncat(rowexpress, ptr2, ptr1 - ptr2); /* row expression */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffextn(char *url, /* I - input filename/URL */ int *extension_num, /* O - returned extension number */ int *status) { /* Parse the input url string and return the number of the extension that CFITSIO would automatically move to if CFITSIO were to open this input URL. The extension numbers are one's based, so 1 = the primary array, 2 = the first extension, etc. The extension number that gets returned is determined by the following algorithm: 1. If the input URL includes a binning specification (e.g. 'myfile.fits[3][bin X,Y]') then the returned extension number will always = 1, since CFITSIO would create a temporary primary image on the fly in this case. The same is true if an image within a single cell of a binary table is opened. 2. Else if the input URL specifies an extension number (e.g., 'myfile.fits[3]' or 'myfile.fits+3') then the specified extension number (+ 1) is returned. 3. Else if the extension name is specified in brackets (e.g., this 'myfile.fits[EVENTS]') then the file will be opened and searched for the extension number. If the input URL is '-' (reading from the stdin file stream) this is not possible and an error will be returned. 4. Else if the URL does not specify an extension (e.g. 'myfile.fits') then a special extension number = -99 will be returned to signal that no extension was specified. This feature is mainly for compatibility with existing FTOOLS software. CFITSIO would open the primary array by default (extension_num = 1) in this case. */ fitsfile *fptr; char urltype[20]; char infile[FLEN_FILENAME]; char outfile[FLEN_FILENAME]; char extspec[FLEN_FILENAME]; char extname[FLEN_FILENAME]; char rowfilter[FLEN_FILENAME]; char binspec[FLEN_FILENAME]; char colspec[FLEN_FILENAME]; char imagecolname[FLEN_VALUE], rowexpress[FLEN_FILENAME]; char *cptr; int extnum, extvers, hdutype, tstatus = 0; if (*status > 0) return(*status); /* parse the input URL into its basic components */ ffiurl(url, urltype, infile, outfile, extspec, rowfilter,binspec, colspec, status); if (*status > 0) return(*status); if (*binspec) /* is there a binning specification? */ { *extension_num = 1; /* a temporary primary array image is created */ return(*status); } if (*extspec) /* is an extension specified? */ { ffexts(extspec, &extnum, extname, &extvers, &hdutype, imagecolname, rowexpress, status); if (*status > 0) return(*status); if (*imagecolname) /* is an image within a table cell being opened? */ { *extension_num = 1; /* a temporary primary array image is created */ return(*status); } if (*extname) { /* have to open the file to search for the extension name (curses!) */ if (!strcmp(urltype, "stdin://")) /* opening stdin would destroying it! */ return(*status = URL_PARSE_ERROR); /* First, strip off any filtering specification */ strcpy(infile, url); cptr = strchr(infile, ']'); /* locate the closing bracket */ if (!cptr) { return(*status = URL_PARSE_ERROR); } else { cptr++; *cptr = '\0'; /* terminate URl after the extension spec */ } if (ffopen(&fptr, infile, READONLY, status) > 0) /* open the file */ { ffclos(fptr, &tstatus); return(*status); } ffghdn(fptr, &extnum); /* where am I in the file? */ *extension_num = extnum; ffclos(fptr, status); return(*status); } else { *extension_num = extnum + 1; /* return the specified number (+ 1) */ return(*status); } } else { *extension_num = -99; /* no specific extension was specified */ /* defaults to primary array */ return(*status); } } /*--------------------------------------------------------------------------*/ int ffurlt(fitsfile *fptr, char *urlType, int *status) /* return the prefix string associated with the driver in use by the fitsfile pointer fptr */ { strcpy(urlType, driverTable[fptr->Fptr->driver].prefix); return(*status); } /*--------------------------------------------------------------------------*/ int ffimport_file( char *filename, /* Text file to read */ char **contents, /* Pointer to pointer to hold file */ int *status ) /* CFITSIO error code */ /* Read and concatenate all the lines from the given text file. User must free the pointer returned in contents. Pointer is guaranteed to hold 2 characters more than the length of the text... allows the calling routine to append (or prepend) a newline (or quotes?) without reallocating memory. */ { int allocLen, totalLen, llen, eoline; char *lines,line[256]; FILE *aFile; if( *status > 0 ) return( *status ); totalLen = 0; allocLen = 1024; lines = (char *)malloc( allocLen * sizeof(char) ); if( !lines ) { ffpmsg("Couldn't allocate memory to hold ASCII file contents."); return(*status = MEMORY_ALLOCATION ); } lines[0] = '\0'; if( (aFile = fopen( filename, "r" ))==NULL ) { sprintf(line,"Could not open ASCII file %s.",filename); ffpmsg(line); free( lines ); return(*status = FILE_NOT_OPENED); } while( fgets(line,256,aFile)!=NULL ) { llen = strlen(line); if ((llen > 1) && (line[0] == '/' && line[1] == '/')) continue; /* skip comment lines begging with // */ eoline = 0; /* replace CR and newline chars at end of line with nulls */ if ((llen > 0) && (line[llen-1]=='\n' || line[llen-1] == '\r')) { line[--llen] = '\0'; eoline = 1; /* found an end of line character */ if ((llen > 0) && (line[llen-1]=='\n' || line[llen-1] == '\r')) { line[--llen] = '\0'; } } if( totalLen + llen + 3 >= allocLen ) { allocLen += 256; lines = (char *)realloc(lines, allocLen * sizeof(char) ); if( ! lines ) { ffpmsg("Couldn't allocate memory to hold ASCII file contents."); *status = MEMORY_ALLOCATION; break; } } strcpy( lines+totalLen, line ); totalLen += llen; if (eoline) { strcpy( lines+totalLen, " "); /* add a space between lines */ totalLen += 1; } } fclose(aFile); *contents = lines; return( *status ); } /*--------------------------------------------------------------------------*/ int fits_get_token(char **ptr, char *delimiter, char *token, int *isanumber) /* O - is this token a number? */ /* parse off the next token, delimited by a character in 'delimiter', from the input ptr string; increment *ptr to the end of the token. Returns the length of the token, not including the delimiter char; */ { int slen, ii; *token = '\0'; while (**ptr == ' ') /* skip over leading blanks */ (*ptr)++; slen = strcspn(*ptr, delimiter); /* length of next token */ if (slen) { strncat(token, *ptr, slen); /* copy token */ (*ptr) += slen; /* skip over the token */ if (isanumber) { *isanumber = 1; for (ii = 0; ii < slen; ii++) { if ( !isdigit((int) token[ii]) && token[ii] != '.' && token[ii] != '-' && token[ii] != '+' && token[ii] != 'E' && token[ii] != 'e') { *isanumber = 0; break; } } } } return(slen); } /*---------------------------------------------------------------------------*/ char *fits_split_names( char *list) /* I - input list of names */ { /* A sequence of calls to fits_split_names will split the input string into name tokens. The string typically contains a list of file or column names. The names must be delimited by a comma and/or spaces. This routine ignores spaces and commas that occur within parentheses, brackets, or curly brackets. It also strips any leading and trailing blanks from the returned name. This routine is similar to the ANSI C 'strtok' function: The first call to fits_split_names has a non-null input string. It finds the first name in the string and terminates it by overwriting the next character of the string with a '\0' and returns a pointer to the name. Each subsequent call, indicated by a NULL value of the input string, returns the next name, searching from just past the end of the previous name. It returns NULL when no further names are found. The following line illustrates how a string would be split into 3 names: myfile[1][bin (x,y)=4], file2.fits file3.fits ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^ 1st name 2nd name 3rd name */ int depth = 0; char *start; static char *ptr; if (list) /* reset ptr if a string is given */ ptr = list; while (*ptr == ' ')ptr++; /* skip leading white space */ if (*ptr == '\0')return(0); /* no remaining file names */ start = ptr; while (*ptr != '\0') { if ((*ptr == '[') || (*ptr == '(') || (*ptr == '{')) depth ++; else if ((*ptr == '}') || (*ptr == ')') || (*ptr == ']')) depth --; else if ((depth == 0) && (*ptr == ',' || *ptr == ' ')) { *ptr = '\0'; /* terminate the filename here */ ptr++; /* save pointer to start of next filename */ break; } ptr++; } return(start); } /*--------------------------------------------------------------------------*/ int urltype2driver(char *urltype, int *driver) /* compare input URL with list of known drivers, returning the matching driver numberL. */ { int ii; /* find matching driver; search most recent drivers first */ for (ii=no_of_drivers - 1; ii >= 0; ii--) { if (0 == strcmp(driverTable[ii].prefix, urltype)) { *driver = ii; return(0); } } return(NO_MATCHING_DRIVER); } /*--------------------------------------------------------------------------*/ int ffclos(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* close the FITS file by completing the current HDU, flushing it to disk, then calling the system dependent routine to physically close the FITS file */ { int tstatus = NO_CLOSE_ERROR, zerostatus = 0; if (!fptr) return(*status = NULL_INPUT_PTR); else if ((fptr->Fptr)->validcode != VALIDSTRUC) /* check for magic value */ return(*status = BAD_FILEPTR); /* close and flush the current HDU */ if (*status > 0) ffchdu(fptr, &tstatus); /* turn off the error message from ffchdu */ else ffchdu(fptr, status); ((fptr->Fptr)->open_count)--; /* decrement usage counter */ if ((fptr->Fptr)->open_count == 0) /* if no other files use structure */ { ffflsh(fptr, TRUE, status); /* flush and disassociate IO buffers */ /* call driver function to actually close the file */ if ( (*driverTable[(fptr->Fptr)->driver].close)((fptr->Fptr)->filehandle) ) { if (*status <= 0) { *status = FILE_NOT_CLOSED; /* report if no previous error */ ffpmsg("failed to close the following file: (ffclos)"); ffpmsg((fptr->Fptr)->filename); } } fits_clear_Fptr( fptr->Fptr, status); /* clear Fptr address */ free((fptr->Fptr)->headstart); /* free memory for headstart array */ free((fptr->Fptr)->filename); /* free memory for the filename */ (fptr->Fptr)->filename = 0; (fptr->Fptr)->validcode = 0; /* magic value to indicate invalid fptr */ free(fptr->Fptr); /* free memory for the FITS file structure */ free(fptr); /* free memory for the FITS file structure */ } else { /* to minimize the fallout from any previous error (e.g., trying to open a non-existent extension in a already opened file), always call ffflsh with status = 0. */ /* just flush the buffers, don't disassociate them */ if (*status > 0) ffflsh(fptr, FALSE, &zerostatus); else ffflsh(fptr, FALSE, status); free(fptr); /* free memory for the FITS file structure */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffdelt(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* close and DELETE the FITS file. */ { char *basename; int slen, tstatus = 0; if (!fptr) return(*status = NULL_INPUT_PTR); else if ((fptr->Fptr)->validcode != VALIDSTRUC) /* check for magic value */ return(*status = BAD_FILEPTR); ffchdu(fptr, status); /* close the current HDU, ignore any errors */ ffflsh(fptr, TRUE, status); /* flush and disassociate IO buffers */ /* call driver function to actually close the file */ if ( (*driverTable[(fptr->Fptr)->driver].close)((fptr->Fptr)->filehandle) ) { if (*status <= 0) { *status = FILE_NOT_CLOSED; /* report error if no previous error */ ffpmsg("failed to close the following file: (ffdelt)"); ffpmsg((fptr->Fptr)->filename); } } /* call driver function to actually delete the file */ if ( (driverTable[(fptr->Fptr)->driver].remove) ) { /* parse the input URL to get the base filename */ slen = strlen((fptr->Fptr)->filename); basename = (char *) malloc(slen +1); if (!basename) return(*status = MEMORY_ALLOCATION); ffiurl((fptr->Fptr)->filename, NULL, basename, NULL, NULL, NULL, NULL, NULL, &tstatus); if ((*driverTable[(fptr->Fptr)->driver].remove)(basename)) { ffpmsg("failed to delete the following file: (ffdelt)"); ffpmsg((fptr->Fptr)->filename); if (!(*status)) *status = FILE_NOT_CLOSED; } free(basename); } fits_clear_Fptr( fptr->Fptr, status); /* clear Fptr address */ free((fptr->Fptr)->headstart); /* free memory for headstart array */ free((fptr->Fptr)->filename); /* free memory for the filename */ (fptr->Fptr)->filename = 0; (fptr->Fptr)->validcode = 0; /* magic value to indicate invalid fptr */ free(fptr->Fptr); /* free memory for the FITS file structure */ free(fptr); /* free memory for the FITS file structure */ return(*status); } /*--------------------------------------------------------------------------*/ int fftrun( fitsfile *fptr, /* I - FITS file pointer */ LONGLONG filesize, /* I - size to truncate the file */ int *status) /* O - error status */ /* low level routine to truncate a file to a new smaller size. */ { if (driverTable[(fptr->Fptr)->driver].truncate) { ffflsh(fptr, FALSE, status); /* flush all the buffers first */ (fptr->Fptr)->filesize = filesize; (fptr->Fptr)->logfilesize = filesize; (fptr->Fptr)->bytepos = filesize; ffbfeof(fptr, status); /* eliminate any buffers beyond current EOF */ return (*status = (*driverTable[(fptr->Fptr)->driver].truncate)((fptr->Fptr)->filehandle, filesize) ); } else return(*status); } /*--------------------------------------------------------------------------*/ int ffflushx( FITSfile *fptr) /* I - FITS file pointer */ /* low level routine to flush internal file buffers to the file. */ { if (driverTable[fptr->driver].flush) return ( (*driverTable[fptr->driver].flush)(fptr->filehandle) ); else return(0); /* no flush function defined for this driver */ } /*--------------------------------------------------------------------------*/ int ffseek( FITSfile *fptr, /* I - FITS file pointer */ LONGLONG position) /* I - byte position to seek to */ /* low level routine to seek to a position in a file. */ { return( (*driverTable[fptr->driver].seek)(fptr->filehandle, position) ); } /*--------------------------------------------------------------------------*/ int ffwrite( FITSfile *fptr, /* I - FITS file pointer */ long nbytes, /* I - number of bytes to write */ void *buffer, /* I - buffer to write */ int *status) /* O - error status */ /* low level routine to write bytes to a file. */ { if ( (*driverTable[fptr->driver].write)(fptr->filehandle, buffer, nbytes) ) { ffpmsg("Error writing data buffer to file:"); ffpmsg(fptr->filename); *status = WRITE_ERROR; } return(*status); } /*--------------------------------------------------------------------------*/ int ffread( FITSfile *fptr, /* I - FITS file pointer */ long nbytes, /* I - number of bytes to read */ void *buffer, /* O - buffer to read into */ int *status) /* O - error status */ /* low level routine to read bytes from a file. */ { int readstatus; readstatus = (*driverTable[fptr->driver].read)(fptr->filehandle, buffer, nbytes); if (readstatus == END_OF_FILE) *status = END_OF_FILE; else if (readstatus > 0) { ffpmsg("Error reading data buffer from file:"); ffpmsg(fptr->filename); *status = READ_ERROR; } return(*status); } /*--------------------------------------------------------------------------*/ int fftplt(fitsfile **fptr, /* O - FITS file pointer */ const char *filename, /* I - name of file to create */ const char *tempname, /* I - name of template file */ int *status) /* IO - error status */ /* Create and initialize a new FITS file based on a template file. Uses C fopen and fgets functions. */ { if (*status > 0) return(*status); if ( ffinit(fptr, filename, status) ) /* create empty file */ return(*status); ffoptplt(*fptr, tempname, status); /* open and use template */ return(*status); } /*--------------------------------------------------------------------------*/ int ffoptplt(fitsfile *fptr, /* O - FITS file pointer */ const char *tempname, /* I - name of template file */ int *status) /* IO - error status */ /* open template file and use it to create new file */ { fitsfile *tptr; int tstatus = 0, nkeys, nadd, ii; char card[FLEN_CARD]; if (*status > 0) return(*status); if (tempname == NULL || *tempname == '\0') /* no template file? */ return(*status); /* try opening template */ ffopen(&tptr, (char *) tempname, READONLY, &tstatus); if (tstatus) /* not a FITS file, so treat it as an ASCII template */ { ffxmsg(2, card); /* clear the error message */ fits_execute_template(fptr, (char *) tempname, status); ffmahd(fptr, 1, 0, status); /* move back to the primary array */ return(*status); } else /* template is a valid FITS file */ { ffmahd(tptr, 1, NULL, status); /* make sure we are at the beginning */ while (*status <= 0) { ffghsp(tptr, &nkeys, &nadd, status); /* get no. of keywords */ for (ii = 1; ii <= nkeys; ii++) /* copy keywords */ { ffgrec(tptr, ii, card, status); ffprec(fptr, card, status); } ffmrhd(tptr, 1, 0, status); /* move to next HDU until error */ ffcrhd(fptr, status); /* create empty new HDU in output file */ } if (*status == END_OF_FILE) { *status = 0; /* expected error condition */ } ffclos(tptr, status); /* close the template file */ } ffmahd(fptr, 1, 0, status); /* move to the primary array */ return(*status); } /*--------------------------------------------------------------------------*/ void ffrprt( FILE *stream, int status) /* Print out report of cfitsio error status and messages on the error stack. Uses C FILE stream. */ { char status_str[FLEN_STATUS], errmsg[FLEN_ERRMSG]; if (status) { fits_get_errstatus(status, status_str); /* get the error description */ fprintf(stream, "\nFITSIO status = %d: %s\n", status, status_str); while ( fits_read_errmsg(errmsg) ) /* get error stack messages */ fprintf(stream, "%s\n", errmsg); } return; } /*--------------------------------------------------------------------------*/ int pixel_filter_helper( fitsfile **fptr, /* IO - pointer to input image; on output it */ /* points to the new image */ char *outfile, /* I - name for output file */ char *expr, /* I - Image filter expression */ int *status) { PixelFilter filter = { 0 }; char * DEFAULT_TAG = "X"; int ii, hdunum; int singleHDU = 0; filter.count = 1; filter.ifptr = fptr; filter.tag = &DEFAULT_TAG; /* create new empty file for result */ if (ffinit(&filter.ofptr, outfile, status) > 0) { ffpmsg("failed to create output file for pixel filter:"); ffpmsg(outfile); return(*status); } fits_get_hdu_num(*fptr, &hdunum); /* current HDU number in input file */ expr += 3; /* skip 'pix' */ switch (expr[0]) { case 'b': case 'B': filter.bitpix = BYTE_IMG; break; case 'i': case 'I': filter.bitpix = SHORT_IMG; break; case 'j': case 'J': filter.bitpix = LONG_IMG; break; case 'r': case 'R': filter.bitpix = FLOAT_IMG; break; case 'd': case 'D': filter.bitpix = DOUBLE_IMG; break; } if (filter.bitpix) /* skip bitpix indicator */ ++expr; if (*expr == '1') { ++expr; singleHDU = 1; } if (*expr != ' ') { ffpmsg("pixel filtering expression not space separated:"); ffpmsg(expr); } while (*expr == ' ') ++expr; /* copy all preceding extensions to the output file */ for (ii = 1; !singleHDU && ii < hdunum; ii++) { fits_movabs_hdu(*fptr, ii, NULL, status); if (fits_copy_hdu(*fptr, filter.ofptr, 0, status) > 0) { ffclos(filter.ofptr, status); return(*status); } } /* move back to the original HDU position */ fits_movabs_hdu(*fptr, hdunum, NULL, status); filter.expression = expr; if (fits_pixel_filter(&filter, status)) { ffpmsg("failed to execute image filter:"); ffpmsg(expr); ffclos(filter.ofptr, status); return(*status); } /* copy any remaining HDUs to the output file */ for (ii = hdunum + 1; !singleHDU; ii++) { if (fits_movabs_hdu(*fptr, ii, NULL, status) > 0) break; fits_copy_hdu(*fptr, filter.ofptr, 0, status); } if (*status == END_OF_FILE) *status = 0; /* got the expected EOF error; reset = 0 */ else if (*status > 0) { ffclos(filter.ofptr, status); return(*status); } /* close the original file and return ptr to the new image */ ffclos(*fptr, status); *fptr = filter.ofptr; /* reset the pointer to the new table */ /* move back to the image subsection */ if (ii - 1 != hdunum) fits_movabs_hdu(*fptr, hdunum, NULL, status); return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/cfortran.h000066400000000000000000004067261215713201500224360ustar00rootroot00000000000000/* cfortran.h 4.4 */ /* http://www-zeus.desy.de/~burow/cfortran/ */ /* Burkhard Burow burow@desy.de 1990 - 2002. */ #ifndef __CFORTRAN_LOADED #define __CFORTRAN_LOADED /* THIS FILE IS PROPERTY OF BURKHARD BUROW. IF YOU ARE USING THIS FILE YOU SHOULD ALSO HAVE ACCESS TO CFORTRAN.DOC WHICH PROVIDES TERMS FOR USING, MODIFYING, COPYING AND DISTRIBUTING THE CFORTRAN.H PACKAGE. */ /* The following modifications were made by the authors of CFITSIO or by me. * They are flagged below with CFITSIO, the author's initials, or KMCCARTY. * PDW = Peter Wilson * DM = Doug Mink * LEB = Lee E Brotzman * MR = Martin Reinecke * WDP = William D Pence * -- Kevin McCarty, for Debian (19 Dec. 2005) */ /******* Modifications: Oct 1997: Changed symbol name extname to appendus (PDW/HSTX) (Conflicted with a common variable name in FTOOLS) Nov 1997: If g77Fortran defined, also define f2cFortran (PDW/HSTX) Feb 1998: Let VMS see the NUM_ELEMS code. Lets programs treat single strings as vectors with single elements Nov 1999: If macintoxh defined, also define f2cfortran (for Mac OS-X) Apr 2000: If WIN32 defined, also define PowerStationFortran and VISUAL_CPLUSPLUS (Visual C++) Jun 2000: If __GNUC__ and linux defined, also define f2cFortran (linux/gcc environment detection) Apr 2002: If __CYGWIN__ is defined, also define f2cFortran Nov 2002: If __APPLE__ defined, also define f2cfortran (for Mac OS-X) Nov 2003: If __INTEL_COMPILER or INTEL_COMPILER defined, also define f2cFortran (KMCCARTY) Dec 2005: If f2cFortran is defined, enforce REAL functions in FORTRAN returning "double" in C. This was one of the items on Burkhard's TODO list. (KMCCARTY) Dec 2005: Modifications to support 8-byte integers. (MR) USE AT YOUR OWN RISK! Feb 2006 Added logic to typedef the symbol 'LONGLONG' to an appropriate intrinsic 8-byte integer datatype (WDP) Apr 2006: Modifications to support gfortran (and g77 with -fno-f2c flag) since by default it returns "float" for FORTRAN REAL function. (KMCCARTY) *******/ /* Avoid symbols already used by compilers and system *.h: __ - OSF1 zukal06 V3.0 347 alpha, cc -c -std1 cfortest.c */ /* Determine what 8-byte integer data type is available. 'long long' is now supported by most compilers, but older MS Visual C++ compilers before V7.0 use '__int64' instead. (WDP) */ #ifndef LONGLONG_TYPE /* this may have been previously defined */ #if defined(_MSC_VER) /* Microsoft Visual C++ */ #if (_MSC_VER < 1300) /* versions earlier than V7.0 do not have 'long long' */ typedef __int64 LONGLONG; #else /* newer versions do support 'long long' */ typedef long long LONGLONG; #endif #else typedef long long LONGLONG; #endif #define LONGLONG_TYPE #endif /* First prepare for the C compiler. */ #ifndef ANSI_C_preprocessor /* i.e. user can override. */ #ifdef __CF__KnR #define ANSI_C_preprocessor 0 #else #ifdef __STDC__ #define ANSI_C_preprocessor 1 #else #define _cfleft 1 #define _cfright #define _cfleft_cfright 0 #define ANSI_C_preprocessor _cfleft/**/_cfright #endif #endif #endif #if ANSI_C_preprocessor #define _0(A,B) A##B #define _(A,B) _0(A,B) /* see cat,xcat of K&R ANSI C p. 231 */ #define _2(A,B) A##B /* K&R ANSI C p.230: .. identifier is not replaced */ #define _3(A,B,C) _(A,_(B,C)) #else /* if it turns up again during rescanning. */ #define _(A,B) A/**/B #define _2(A,B) A/**/B #define _3(A,B,C) A/**/B/**/C #endif #if (defined(vax)&&defined(unix)) || (defined(__vax__)&&defined(__unix__)) #define VAXUltrix #endif #include /* NULL [in all machines stdio.h] */ #include /* strlen, memset, memcpy, memchr. */ #if !( defined(VAXUltrix) || defined(sun) || (defined(apollo)&&!defined(__STDCPP__)) ) #include /* malloc,free */ #else #include /* Had to be removed for DomainOS h105 10.4 sys5.3 425t*/ #ifdef apollo #define __CF__APOLLO67 /* __STDCPP__ is in Apollo 6.8 (i.e. ANSI) and onwards */ #endif #endif #if !defined(__GNUC__) && !defined(__sun) && (defined(sun)||defined(VAXUltrix)||defined(lynx)) #define __CF__KnR /* Sun, LynxOS and VAX Ultrix cc only supports K&R. */ /* Manually define __CF__KnR for HP if desired/required.*/ #endif /* i.e. We will generate Kernighan and Ritchie C. */ /* Note that you may define __CF__KnR before #include cfortran.h, in order to generate K&R C instead of the default ANSI C. The differences are mainly in the function prototypes and declarations. All machines, except the Apollo, work with either style. The Apollo's argument promotion rules require ANSI or use of the obsolete std_$call which we have not implemented here. Hence on the Apollo, only C calling FORTRAN subroutines will work using K&R style.*/ /* Remainder of cfortran.h depends on the Fortran compiler. */ /* 11/29/2003 (KMCCARTY): add *INTEL_COMPILER symbols here */ /* 04/05/2006 (KMCCARTY): add gFortran symbol here */ #if defined(CLIPPERFortran) || defined(pgiFortran) || defined(__INTEL_COMPILER) || defined(INTEL_COMPILER) || defined(gFortran) #define f2cFortran #endif /* VAX/VMS does not let us \-split long #if lines. */ /* Split #if into 2 because some HP-UX can't handle long #if */ #if !(defined(NAGf90Fortran)||defined(f2cFortran)||defined(hpuxFortran)||defined(apolloFortran)||defined(sunFortran)||defined(IBMR2Fortran)||defined(CRAYFortran)) #if !(defined(mipsFortran)||defined(DECFortran)||defined(vmsFortran)||defined(CONVEXFortran)||defined(PowerStationFortran)||defined(AbsoftUNIXFortran)||defined(AbsoftProFortran)||defined(SXFortran)) /* If no Fortran compiler is given, we choose one for the machines we know. */ #if defined(lynx) || defined(VAXUltrix) #define f2cFortran /* Lynx: Only support f2c at the moment. VAXUltrix: f77 behaves like f2c. Support f2c or f77 with gcc, vcc with f2c. f77 with vcc works, missing link magic for f77 I/O.*/ #endif /* 04/13/00 DM (CFITSIO): Add these lines for NT */ /* with PowerStationFortran and and Visual C++ */ #if defined(WIN32) && !defined(__CYGWIN__) #define PowerStationFortran #define VISUAL_CPLUSPLUS #endif #if defined(g77Fortran) /* 11/03/97 PDW (CFITSIO) */ #define f2cFortran #endif #if defined(__CYGWIN__) /* 04/11/02 LEB (CFITSIO) */ #define f2cFortran #endif #if defined(__GNUC__) && defined(linux) /* 06/21/00 PDW (CFITSIO) */ #define f2cFortran #endif #if defined(macintosh) /* 11/1999 (CFITSIO) */ #define f2cFortran #endif #if defined(__APPLE__) /* 11/2002 (CFITSIO) */ #define f2cFortran #endif #if defined(__hpux) /* 921107: Use __hpux instead of __hp9000s300 */ #define hpuxFortran /* Should also allow hp9000s7/800 use.*/ #endif #if defined(apollo) #define apolloFortran /* __CF__APOLLO67 also defines some behavior. */ #endif #if defined(sun) || defined(__sun) #define sunFortran #endif #if defined(_IBMR2) #define IBMR2Fortran #endif #if defined(_CRAY) #define CRAYFortran /* _CRAYT3E also defines some behavior. */ #endif #if defined(_SX) #define SXFortran #endif #if defined(mips) || defined(__mips) #define mipsFortran #endif #if defined(vms) || defined(__vms) #define vmsFortran #endif #if defined(__alpha) && defined(__unix__) #define DECFortran #endif #if defined(__convex__) #define CONVEXFortran #endif #if defined(VISUAL_CPLUSPLUS) #define PowerStationFortran #endif #endif /* ...Fortran */ #endif /* ...Fortran */ /* Split #if into 2 because some HP-UX can't handle long #if */ #if !(defined(NAGf90Fortran)||defined(f2cFortran)||defined(hpuxFortran)||defined(apolloFortran)||defined(sunFortran)||defined(IBMR2Fortran)||defined(CRAYFortran)) #if !(defined(mipsFortran)||defined(DECFortran)||defined(vmsFortran)||defined(CONVEXFortran)||defined(PowerStationFortran)||defined(AbsoftUNIXFortran)||defined(AbsoftProFortran)||defined(SXFortran)) /* If your compiler barfs on ' #error', replace # with the trigraph for # */ #error "cfortran.h: Can't find your environment among:\ - GNU gcc (g77) on Linux. \ - MIPS cc and f77 2.0. (e.g. Silicon Graphics, DECstations, ...) \ - IBM AIX XL C and FORTRAN Compiler/6000 Version 01.01.0000.0000 \ - VAX VMS CC 3.1 and FORTRAN 5.4. \ - Alpha VMS DEC C 1.3 and DEC FORTRAN 6.0. \ - Alpha OSF DEC C and DEC Fortran for OSF/1 AXP Version 1.2 \ - Apollo DomainOS 10.2 (sys5.3) with f77 10.7 and cc 6.7. \ - CRAY \ - NEC SX-4 SUPER-UX \ - CONVEX \ - Sun \ - PowerStation Fortran with Visual C++ \ - HP9000s300/s700/s800 Latest test with: HP-UX A.08.07 A 9000/730 \ - LynxOS: cc or gcc with f2c. \ - VAXUltrix: vcc,cc or gcc with f2c. gcc or cc with f77. \ - f77 with vcc works; but missing link magic for f77 I/O. \ - NO fort. None of gcc, cc or vcc generate required names.\ - f2c/g77: Use #define f2cFortran, or cc -Df2cFortran \ - gfortran: Use #define gFortran, or cc -DgFortran \ (also necessary for g77 with -fno-f2c option) \ - NAG f90: Use #define NAGf90Fortran, or cc -DNAGf90Fortran \ - Absoft UNIX F77: Use #define AbsoftUNIXFortran or cc -DAbsoftUNIXFortran \ - Absoft Pro Fortran: Use #define AbsoftProFortran \ - Portland Group Fortran: Use #define pgiFortran \ - Intel Fortran: Use #define INTEL_COMPILER" /* Compiler must throw us out at this point! */ #endif #endif #if defined(VAXC) && !defined(__VAXC) #define OLD_VAXC #pragma nostandard /* Prevent %CC-I-PARAMNOTUSED. */ #endif /* Throughout cfortran.h we use: UN = Uppercase Name. LN = Lowercase Name. */ /* "extname" changed to "appendus" below (CFITSIO) */ #if defined(f2cFortran) || defined(NAGf90Fortran) || defined(DECFortran) || defined(mipsFortran) || defined(apolloFortran) || defined(sunFortran) || defined(CONVEXFortran) || defined(SXFortran) || defined(appendus) #define CFC_(UN,LN) _(LN,_) /* Lowercase FORTRAN symbols. */ #define orig_fcallsc(UN,LN) CFC_(UN,LN) #else #if defined(CRAYFortran) || defined(PowerStationFortran) || defined(AbsoftProFortran) #ifdef _CRAY /* (UN), not UN, circumvents CRAY preprocessor bug. */ #define CFC_(UN,LN) (UN) /* Uppercase FORTRAN symbols. */ #else /* At least VISUAL_CPLUSPLUS barfs on (UN), so need UN. */ #define CFC_(UN,LN) UN /* Uppercase FORTRAN symbols. */ #endif #define orig_fcallsc(UN,LN) CFC_(UN,LN) /* CRAY insists on arg.'s here. */ #else /* For following machines one may wish to change the fcallsc default. */ #define CF_SAME_NAMESPACE #ifdef vmsFortran #define CFC_(UN,LN) LN /* Either case FORTRAN symbols. */ /* BUT we usually use UN for C macro to FORTRAN routines, so use LN here,*/ /* because VAX/VMS doesn't do recursive macros. */ #define orig_fcallsc(UN,LN) UN #else /* HP-UX without +ppu or IBMR2 without -qextname. NOT reccomended. */ #define CFC_(UN,LN) LN /* Lowercase FORTRAN symbols. */ #define orig_fcallsc(UN,LN) CFC_(UN,LN) #endif /* vmsFortran */ #endif /* CRAYFortran PowerStationFortran */ #endif /* ....Fortran */ #define fcallsc(UN,LN) orig_fcallsc(UN,LN) #define preface_fcallsc(P,p,UN,LN) CFC_(_(P,UN),_(p,LN)) #define append_fcallsc(P,p,UN,LN) CFC_(_(UN,P),_(LN,p)) #define C_FUNCTION(UN,LN) fcallsc(UN,LN) #define FORTRAN_FUNCTION(UN,LN) CFC_(UN,LN) #ifndef COMMON_BLOCK #ifndef CONVEXFortran #ifndef CLIPPERFortran #if !(defined(AbsoftUNIXFortran)||defined(AbsoftProFortran)) #define COMMON_BLOCK(UN,LN) CFC_(UN,LN) #else #define COMMON_BLOCK(UN,LN) _(_C,LN) #endif /* AbsoftUNIXFortran or AbsoftProFortran */ #else #define COMMON_BLOCK(UN,LN) _(LN,__) #endif /* CLIPPERFortran */ #else #define COMMON_BLOCK(UN,LN) _3(_,LN,_) #endif /* CONVEXFortran */ #endif /* COMMON_BLOCK */ #ifndef DOUBLE_PRECISION #if defined(CRAYFortran) && !defined(_CRAYT3E) #define DOUBLE_PRECISION long double #else #define DOUBLE_PRECISION double #endif #endif #ifndef FORTRAN_REAL #if defined(CRAYFortran) && defined(_CRAYT3E) #define FORTRAN_REAL double #else #define FORTRAN_REAL float #endif #endif #ifdef CRAYFortran #ifdef _CRAY #include #else #include "fortran.h" /* i.e. if crosscompiling assume user has file. */ #endif #define FLOATVVVVVVV_cfPP (FORTRAN_REAL *) /* Used for C calls FORTRAN. */ /* CRAY's double==float but CRAY says pointers to doubles and floats are diff.*/ #define VOIDP (void *) /* When FORTRAN calls C, we don't know if C routine arg.'s have been declared float *, or double *. */ #else #define FLOATVVVVVVV_cfPP #define VOIDP #endif #ifdef vmsFortran #if defined(vms) || defined(__vms) #include #else #include "descrip.h" /* i.e. if crosscompiling assume user has file. */ #endif #endif #ifdef sunFortran #if defined(sun) || defined(__sun) #include /* Sun's FLOATFUNCTIONTYPE, ASSIGNFLOAT, RETURNFLOAT. */ #else #include "math.h" /* i.e. if crosscompiling assume user has file. */ #endif /* At least starting with the default C compiler SC3.0.1 of SunOS 5.3, * FLOATFUNCTIONTYPE, ASSIGNFLOAT, RETURNFLOAT are not required and not in * , since sun C no longer promotes C float return values to doubles. * Therefore, only use them if defined. * Even if gcc is being used, assume that it exhibits the Sun C compiler * behavior in order to be able to use *.o from the Sun C compiler. * i.e. If FLOATFUNCTIONTYPE, etc. are in math.h, they required by gcc. */ #endif #ifndef apolloFortran /* "extern" removed (CFITSIO) */ #define COMMON_BLOCK_DEF(DEFINITION, NAME) /* extern */ DEFINITION NAME #define CF_NULL_PROTO #else /* HP doesn't understand #elif. */ /* Without ANSI prototyping, Apollo promotes float functions to double. */ /* Note that VAX/VMS, IBM, Mips choke on 'type function(...);' prototypes. */ #define CF_NULL_PROTO ... #ifndef __CF__APOLLO67 #define COMMON_BLOCK_DEF(DEFINITION, NAME) \ DEFINITION NAME __attribute((__section(NAME))) #else #define COMMON_BLOCK_DEF(DEFINITION, NAME) \ DEFINITION NAME #attribute[section(NAME)] #endif #endif #ifdef __cplusplus #undef CF_NULL_PROTO #define CF_NULL_PROTO ... #endif #ifndef USE_NEW_DELETE #ifdef __cplusplus #define USE_NEW_DELETE 1 #else #define USE_NEW_DELETE 0 #endif #endif #if USE_NEW_DELETE #define _cf_malloc(N) new char[N] #define _cf_free(P) delete[] P #else #define _cf_malloc(N) (char *)malloc(N) #define _cf_free(P) free(P) #endif #ifdef mipsFortran #define CF_DECLARE_GETARG int f77argc; char **f77argv #define CF_SET_GETARG(ARGC,ARGV) f77argc = ARGC; f77argv = ARGV #else #define CF_DECLARE_GETARG #define CF_SET_GETARG(ARGC,ARGV) #endif #ifdef OLD_VAXC /* Allow %CC-I-PARAMNOTUSED. */ #pragma standard #endif #define AcfCOMMA , #define AcfCOLON ; /*-------------------------------------------------------------------------*/ /* UTILITIES USED WITHIN CFORTRAN.H */ #define _cfMIN(A,B) (As) { /* Need this to handle NULL string.*/ while (e>s && *--e==t); /* Don't follow t's past beginning. */ e[*e==t?0:1] = '\0'; /* Handle s[0]=t correctly. */ } return s; } /* kill_trailingn(s,t,e) will kill the trailing t's in string s. e normally points to the terminating '\0' of s, but may actually point to anywhere in s. s's new '\0' will be placed at e or earlier in order to remove any trailing t's. If es) { /* Watch out for neg. length string.*/ while (e>s && *--e==t); /* Don't follow t's past beginning. */ e[*e==t?0:1] = '\0'; /* Handle s[0]=t correctly. */ } return s; } /* Note the following assumes that any element which has t's to be chopped off, does indeed fill the entire element. */ #ifndef __CF__KnR static char *vkill_trailing(char* cstr, int elem_len, int sizeofcstr, char t) #else static char *vkill_trailing( cstr, elem_len, sizeofcstr, t) char* cstr; int elem_len; int sizeofcstr; char t; #endif { int i; for (i=0; i= 4.3 gives message: zow35> cc -c -DDECFortran cfortest.c cfe: Fatal: Out of memory: cfortest.c zow35> Old __hpux had the problem, but new 'HP-UX A.09.03 A 9000/735' is fine if using -Aa, otherwise we have a problem. */ #ifndef MAX_PREPRO_ARGS #if !defined(__GNUC__) && (defined(VAXUltrix) || defined(__CF__APOLLO67) || (defined(sun)&&!defined(__sun)) || defined(_CRAY) || defined(__ultrix__) || (defined(__hpux)&&defined(__CF__KnR))) #define MAX_PREPRO_ARGS 31 #else #define MAX_PREPRO_ARGS 99 #endif #endif #if defined(AbsoftUNIXFortran) || defined(AbsoftProFortran) /* In addition to explicit Absoft stuff, only Absoft requires: - DEFAULT coming from _cfSTR. DEFAULT could have been called e.g. INT, but keep it for clarity. - M term in CFARGT14 and CFARGT14FS. */ #define ABSOFT_cf1(T0) _(T0,_cfSTR)(0,ABSOFT1,0,0,0,0,0) #define ABSOFT_cf2(T0) _(T0,_cfSTR)(0,ABSOFT2,0,0,0,0,0) #define ABSOFT_cf3(T0) _(T0,_cfSTR)(0,ABSOFT3,0,0,0,0,0) #define DEFAULT_cfABSOFT1 #define LOGICAL_cfABSOFT1 #define STRING_cfABSOFT1 ,MAX_LEN_FORTRAN_FUNCTION_STRING #define DEFAULT_cfABSOFT2 #define LOGICAL_cfABSOFT2 #define STRING_cfABSOFT2 ,unsigned D0 #define DEFAULT_cfABSOFT3 #define LOGICAL_cfABSOFT3 #define STRING_cfABSOFT3 ,D0 #else #define ABSOFT_cf1(T0) #define ABSOFT_cf2(T0) #define ABSOFT_cf3(T0) #endif /* _Z introduced to cicumvent IBM and HP silly preprocessor warning. e.g. "Macro CFARGT14 invoked with a null argument." */ #define _Z #define CFARGT14S(S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \ S(T1,1) S(T2,2) S(T3,3) S(T4,4) S(T5,5) S(T6,6) S(T7,7) \ S(T8,8) S(T9,9) S(TA,10) S(TB,11) S(TC,12) S(TD,13) S(TE,14) #define CFARGT27S(S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \ S(T1,1) S(T2,2) S(T3,3) S(T4,4) S(T5,5) S(T6,6) S(T7,7) \ S(T8,8) S(T9,9) S(TA,10) S(TB,11) S(TC,12) S(TD,13) S(TE,14) \ S(TF,15) S(TG,16) S(TH,17) S(TI,18) S(TJ,19) S(TK,20) S(TL,21) \ S(TM,22) S(TN,23) S(TO,24) S(TP,25) S(TQ,26) S(TR,27) #define CFARGT14FS(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \ F(T1,1,0) F(T2,2,1) F(T3,3,1) F(T4,4,1) F(T5,5,1) F(T6,6,1) F(T7,7,1) \ F(T8,8,1) F(T9,9,1) F(TA,10,1) F(TB,11,1) F(TC,12,1) F(TD,13,1) F(TE,14,1) \ M CFARGT14S(S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) #define CFARGT27FS(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \ F(T1,1,0) F(T2,2,1) F(T3,3,1) F(T4,4,1) F(T5,5,1) F(T6,6,1) F(T7,7,1) \ F(T8,8,1) F(T9,9,1) F(TA,10,1) F(TB,11,1) F(TC,12,1) F(TD,13,1) F(TE,14,1) \ F(TF,15,1) F(TG,16,1) F(TH,17,1) F(TI,18,1) F(TJ,19,1) F(TK,20,1) F(TL,21,1) \ F(TM,22,1) F(TN,23,1) F(TO,24,1) F(TP,25,1) F(TQ,26,1) F(TR,27,1) \ M CFARGT27S(S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) #if !(defined(PowerStationFortran)||defined(hpuxFortran800)) /* Old CFARGT14 -> CFARGT14FS as seen below, for Absoft cross-compile yields: SunOS> cc -c -Xa -DAbsoftUNIXFortran c.c "c.c", line 406: warning: argument mismatch Haven't checked if this is ANSI C or a SunOS bug. SunOS -Xs works ok. Behavior is most clearly seen in example: #define A 1 , 2 #define C(X,Y,Z) x=X. y=Y. z=Z. #define D(X,Y,Z) C(X,Y,Z) D(x,A,z) Output from preprocessor is: x = x . y = 1 . z = 2 . #define CFARGT14(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \ CFARGT14FS(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) */ #define CFARGT14(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \ F(T1,1,0) F(T2,2,1) F(T3,3,1) F(T4,4,1) F(T5,5,1) F(T6,6,1) F(T7,7,1) \ F(T8,8,1) F(T9,9,1) F(TA,10,1) F(TB,11,1) F(TC,12,1) F(TD,13,1) F(TE,14,1) \ M CFARGT14S(S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) #define CFARGT27(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \ F(T1,1,0) F(T2,2,1) F(T3,3,1) F(T4,4,1) F(T5,5,1) F(T6,6,1) F(T7,7,1) \ F(T8,8,1) F(T9,9,1) F(TA,10,1) F(TB,11,1) F(TC,12,1) F(TD,13,1) F(TE,14,1) \ F(TF,15,1) F(TG,16,1) F(TH,17,1) F(TI,18,1) F(TJ,19,1) F(TK,20,1) F(TL,21,1) \ F(TM,22,1) F(TN,23,1) F(TO,24,1) F(TP,25,1) F(TQ,26,1) F(TR,27,1) \ M CFARGT27S(S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) #define CFARGT20(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) \ F(T1,1,0) F(T2,2,1) F(T3,3,1) F(T4,4,1) F(T5,5,1) F(T6,6,1) F(T7,7,1) \ F(T8,8,1) F(T9,9,1) F(TA,10,1) F(TB,11,1) F(TC,12,1) F(TD,13,1) F(TE,14,1) \ F(TF,15,1) F(TG,16,1) F(TH,17,1) F(TI,18,1) F(TJ,19,1) F(TK,20,1) \ S(T1,1) S(T2,2) S(T3,3) S(T4,4) S(T5,5) S(T6,6) S(T7,7) \ S(T8,8) S(T9,9) S(TA,10) S(TB,11) S(TC,12) S(TD,13) S(TE,14) \ S(TF,15) S(TG,16) S(TH,17) S(TI,18) S(TJ,19) S(TK,20) #define CFARGTA14(F,S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE) \ F(T1,A1,1,0) F(T2,A2,2,1) F(T3,A3,3,1) F(T4,A4,4,1) F(T5,A5,5,1) F(T6,A6,6,1) \ F(T7,A7,7,1) F(T8,A8,8,1) F(T9,A9,9,1) F(TA,AA,10,1) F(TB,AB,11,1) F(TC,AC,12,1) \ F(TD,AD,13,1) F(TE,AE,14,1) S(T1,1) S(T2,2) S(T3,3) S(T4,4) \ S(T5,5) S(T6,6) S(T7,7) S(T8,8) S(T9,9) S(TA,10) \ S(TB,11) S(TC,12) S(TD,13) S(TE,14) #if MAX_PREPRO_ARGS>31 #define CFARGTA20(F,S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK) \ F(T1,A1,1,0) F(T2,A2,2,1) F(T3,A3,3,1) F(T4,A4,4,1) F(T5,A5,5,1) F(T6,A6,6,1) \ F(T7,A7,7,1) F(T8,A8,8,1) F(T9,A9,9,1) F(TA,AA,10,1) F(TB,AB,11,1) F(TC,AC,12,1) \ F(TD,AD,13,1) F(TE,AE,14,1) F(TF,AF,15,1) F(TG,AG,16,1) F(TH,AH,17,1) F(TI,AI,18,1) \ F(TJ,AJ,19,1) F(TK,AK,20,1) S(T1,1) S(T2,2) S(T3,3) S(T4,4) \ S(T5,5) S(T6,6) S(T7,7) S(T8,8) S(T9,9) S(TA,10) \ S(TB,11) S(TC,12) S(TD,13) S(TE,14) S(TF,15) S(TG,16) \ S(TH,17) S(TI,18) S(TJ,19) S(TK,20) #define CFARGTA27(F,S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR) \ F(T1,A1,1,0) F(T2,A2,2,1) F(T3,A3,3,1) F(T4,A4,4,1) F(T5,A5,5,1) F(T6,A6,6,1) \ F(T7,A7,7,1) F(T8,A8,8,1) F(T9,A9,9,1) F(TA,AA,10,1) F(TB,AB,11,1) F(TC,AC,12,1) \ F(TD,AD,13,1) F(TE,AE,14,1) F(TF,AF,15,1) F(TG,AG,16,1) F(TH,AH,17,1) F(TI,AI,18,1) \ F(TJ,AJ,19,1) F(TK,AK,20,1) F(TL,AL,21,1) F(TM,AM,22,1) F(TN,AN,23,1) F(TO,AO,24,1) \ F(TP,AP,25,1) F(TQ,AQ,26,1) F(TR,AR,27,1) S(T1,1) S(T2,2) S(T3,3) \ S(T4,4) S(T5,5) S(T6,6) S(T7,7) S(T8,8) S(T9,9) \ S(TA,10) S(TB,11) S(TC,12) S(TD,13) S(TE,14) S(TF,15) \ S(TG,16) S(TH,17) S(TI,18) S(TJ,19) S(TK,20) S(TL,21) \ S(TM,22) S(TN,23) S(TO,24) S(TP,25) S(TQ,26) S(TR,27) #endif #else #define CFARGT14(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \ F(T1,1,0) S(T1,1) F(T2,2,1) S(T2,2) F(T3,3,1) S(T3,3) F(T4,4,1) S(T4,4) \ F(T5,5,1) S(T5,5) F(T6,6,1) S(T6,6) F(T7,7,1) S(T7,7) F(T8,8,1) S(T8,8) \ F(T9,9,1) S(T9,9) F(TA,10,1) S(TA,10) F(TB,11,1) S(TB,11) F(TC,12,1) S(TC,12) \ F(TD,13,1) S(TD,13) F(TE,14,1) S(TE,14) #define CFARGT27(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \ F(T1,1,0) S(T1,1) F(T2,2,1) S(T2,2) F(T3,3,1) S(T3,3) F(T4,4,1) S(T4,4) \ F(T5,5,1) S(T5,5) F(T6,6,1) S(T6,6) F(T7,7,1) S(T7,7) F(T8,8,1) S(T8,8) \ F(T9,9,1) S(T9,9) F(TA,10,1) S(TA,10) F(TB,11,1) S(TB,11) F(TC,12,1) S(TC,12) \ F(TD,13,1) S(TD,13) F(TE,14,1) S(TE,14) F(TF,15,1) S(TF,15) F(TG,16,1) S(TG,16) \ F(TH,17,1) S(TH,17) F(TI,18,1) S(TI,18) F(TJ,19,1) S(TJ,19) F(TK,20,1) S(TK,20) \ F(TL,21,1) S(TL,21) F(TM,22,1) S(TM,22) F(TN,23,1) S(TN,23) F(TO,24,1) S(TO,24) \ F(TP,25,1) S(TP,25) F(TQ,26,1) S(TQ,26) F(TR,27,1) S(TR,27) #define CFARGT20(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) \ F(T1,1,0) S(T1,1) F(T2,2,1) S(T2,2) F(T3,3,1) S(T3,3) F(T4,4,1) S(T4,4) \ F(T5,5,1) S(T5,5) F(T6,6,1) S(T6,6) F(T7,7,1) S(T7,7) F(T8,8,1) S(T8,8) \ F(T9,9,1) S(T9,9) F(TA,10,1) S(TA,10) F(TB,11,1) S(TB,11) F(TC,12,1) S(TC,12) \ F(TD,13,1) S(TD,13) F(TE,14,1) S(TE,14) F(TF,15,1) S(TF,15) F(TG,16,1) S(TG,16) \ F(TH,17,1) S(TH,17) F(TI,18,1) S(TI,18) F(TJ,19,1) S(TJ,19) F(TK,20,1) S(TK,20) #define CFARGTA14(F,S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE) \ F(T1,A1,1,0) S(T1,1) F(T2,A2,2,1) S(T2,2) F(T3,A3,3,1) S(T3,3) \ F(T4,A4,4,1) S(T4,4) F(T5,A5,5,1) S(T5,5) F(T6,A6,6,1) S(T6,6) \ F(T7,A7,7,1) S(T7,7) F(T8,A8,8,1) S(T8,8) F(T9,A9,9,1) S(T9,9) \ F(TA,AA,10,1) S(TA,10) F(TB,AB,11,1) S(TB,11) F(TC,AC,12,1) S(TC,12) \ F(TD,AD,13,1) S(TD,13) F(TE,AE,14,1) S(TE,14) #if MAX_PREPRO_ARGS>31 #define CFARGTA20(F,S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK) \ F(T1,A1,1,0) S(T1,1) F(T2,A2,2,1) S(T2,2) F(T3,A3,3,1) S(T3,3) \ F(T4,A4,4,1) S(T4,4) F(T5,A5,5,1) S(T5,5) F(T6,A6,6,1) S(T6,6) \ F(T7,A7,7,1) S(T7,7) F(T8,A8,8,1) S(T8,8) F(T9,A9,9,1) S(T9,9) \ F(TA,AA,10,1) S(TA,10) F(TB,AB,11,1) S(TB,11) F(TC,AC,12,1) S(TC,12) \ F(TD,AD,13,1) S(TD,13) F(TE,AE,14,1) S(TE,14) F(TF,AF,15,1) S(TF,15) \ F(TG,AG,16,1) S(TG,16) F(TH,AH,17,1) S(TH,17) F(TI,AI,18,1) S(TI,18) \ F(TJ,AJ,19,1) S(TJ,19) F(TK,AK,20,1) S(TK,20) #define CFARGTA27(F,S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR) \ F(T1,A1,1,0) S(T1,1) F(T2,A2,2,1) S(T2,2) F(T3,A3,3,1) S(T3,3) \ F(T4,A4,4,1) S(T4,4) F(T5,A5,5,1) S(T5,5) F(T6,A6,6,1) S(T6,6) \ F(T7,A7,7,1) S(T7,7) F(T8,A8,8,1) S(T8,8) F(T9,A9,9,1) S(T9,9) \ F(TA,AA,10,1) S(TA,10) F(TB,AB,11,1) S(TB,11) F(TC,AC,12,1) S(TC,12) \ F(TD,AD,13,1) S(TD,13) F(TE,AE,14,1) S(TE,14) F(TF,AF,15,1) S(TF,15) \ F(TG,AG,16,1) S(TG,16) F(TH,AH,17,1) S(TH,17) F(TI,AI,18,1) S(TI,18) \ F(TJ,AJ,19,1) S(TJ,19) F(TK,AK,20,1) S(TK,20) F(TL,AL,21,1) S(TL,21) \ F(TM,AM,22,1) S(TM,22) F(TN,AN,23,1) S(TN,23) F(TO,AO,24,1) S(TO,24) \ F(TP,AP,25,1) S(TP,25) F(TQ,AQ,26,1) S(TQ,26) F(TR,AR,27,1) S(TR,27) #endif #endif #define PROTOCCALLSFSUB1( UN,LN,T1) \ PROTOCCALLSFSUB14(UN,LN,T1,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0) #define PROTOCCALLSFSUB2( UN,LN,T1,T2) \ PROTOCCALLSFSUB14(UN,LN,T1,T2,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0) #define PROTOCCALLSFSUB3( UN,LN,T1,T2,T3) \ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0) #define PROTOCCALLSFSUB4( UN,LN,T1,T2,T3,T4) \ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0) #define PROTOCCALLSFSUB5( UN,LN,T1,T2,T3,T4,T5) \ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0) #define PROTOCCALLSFSUB6( UN,LN,T1,T2,T3,T4,T5,T6) \ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0) #define PROTOCCALLSFSUB7( UN,LN,T1,T2,T3,T4,T5,T6,T7) \ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0) #define PROTOCCALLSFSUB8( UN,LN,T1,T2,T3,T4,T5,T6,T7,T8) \ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0) #define PROTOCCALLSFSUB9( UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9) \ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,CF_0,CF_0,CF_0,CF_0,CF_0) #define PROTOCCALLSFSUB10(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA) \ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,CF_0,CF_0,CF_0,CF_0) #define PROTOCCALLSFSUB11(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB) \ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,CF_0,CF_0,CF_0) #define PROTOCCALLSFSUB12(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC) \ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,CF_0,CF_0) #define PROTOCCALLSFSUB13(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD) \ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,CF_0) #define PROTOCCALLSFSUB15(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF) \ PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,CF_0,CF_0,CF_0,CF_0,CF_0) #define PROTOCCALLSFSUB16(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG) \ PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,CF_0,CF_0,CF_0,CF_0) #define PROTOCCALLSFSUB17(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH) \ PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,CF_0,CF_0,CF_0) #define PROTOCCALLSFSUB18(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI) \ PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,CF_0,CF_0) #define PROTOCCALLSFSUB19(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ) \ PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,CF_0) #define PROTOCCALLSFSUB21(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL) \ PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0) #define PROTOCCALLSFSUB22(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM) \ PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,CF_0,CF_0,CF_0,CF_0,CF_0) #define PROTOCCALLSFSUB23(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN) \ PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,CF_0,CF_0,CF_0,CF_0) #define PROTOCCALLSFSUB24(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO) \ PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,CF_0,CF_0,CF_0) #define PROTOCCALLSFSUB25(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP) \ PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,CF_0,CF_0) #define PROTOCCALLSFSUB26(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ) \ PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,CF_0) #ifndef FCALLSC_QUALIFIER #ifdef VISUAL_CPLUSPLUS #define FCALLSC_QUALIFIER __stdcall #else #define FCALLSC_QUALIFIER #endif #endif #ifdef __cplusplus #define CFextern extern "C" #else #define CFextern extern #endif #ifdef CFSUBASFUN #define PROTOCCALLSFSUB0(UN,LN) \ PROTOCCALLSFFUN0( VOID,UN,LN) #define PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \ PROTOCCALLSFFUN14(VOID,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) #define PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK)\ PROTOCCALLSFFUN20(VOID,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) #define PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR)\ PROTOCCALLSFFUN27(VOID,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) #else /* Note: Prevent compiler warnings, null #define PROTOCCALLSFSUB14/20 after #include-ing cfortran.h if calling the FORTRAN wrapper within the same source code where the wrapper is created. */ #define PROTOCCALLSFSUB0(UN,LN) _(VOID,_cfPU)(CFC_(UN,LN))(); #ifndef __CF__KnR #define PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \ _(VOID,_cfPU)(CFC_(UN,LN))( CFARGT14(NCF,KCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) ); #define PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK)\ _(VOID,_cfPU)(CFC_(UN,LN))( CFARGT20(NCF,KCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) ); #define PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR)\ _(VOID,_cfPU)(CFC_(UN,LN))( CFARGT27(NCF,KCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) ); #else #define PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \ PROTOCCALLSFSUB0(UN,LN) #define PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) \ PROTOCCALLSFSUB0(UN,LN) #define PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \ PROTOCCALLSFSUB0(UN,LN) #endif #endif #ifdef OLD_VAXC /* Allow %CC-I-PARAMNOTUSED. */ #pragma standard #endif #define CCALLSFSUB1( UN,LN,T1, A1) \ CCALLSFSUB5 (UN,LN,T1,CF_0,CF_0,CF_0,CF_0,A1,0,0,0,0) #define CCALLSFSUB2( UN,LN,T1,T2, A1,A2) \ CCALLSFSUB5 (UN,LN,T1,T2,CF_0,CF_0,CF_0,A1,A2,0,0,0) #define CCALLSFSUB3( UN,LN,T1,T2,T3, A1,A2,A3) \ CCALLSFSUB5 (UN,LN,T1,T2,T3,CF_0,CF_0,A1,A2,A3,0,0) #define CCALLSFSUB4( UN,LN,T1,T2,T3,T4, A1,A2,A3,A4)\ CCALLSFSUB5 (UN,LN,T1,T2,T3,T4,CF_0,A1,A2,A3,A4,0) #define CCALLSFSUB5( UN,LN,T1,T2,T3,T4,T5, A1,A2,A3,A4,A5) \ CCALLSFSUB10(UN,LN,T1,T2,T3,T4,T5,CF_0,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,0,0,0,0,0) #define CCALLSFSUB6( UN,LN,T1,T2,T3,T4,T5,T6, A1,A2,A3,A4,A5,A6) \ CCALLSFSUB10(UN,LN,T1,T2,T3,T4,T5,T6,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,0,0,0,0) #define CCALLSFSUB7( UN,LN,T1,T2,T3,T4,T5,T6,T7, A1,A2,A3,A4,A5,A6,A7) \ CCALLSFSUB10(UN,LN,T1,T2,T3,T4,T5,T6,T7,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,0,0,0) #define CCALLSFSUB8( UN,LN,T1,T2,T3,T4,T5,T6,T7,T8, A1,A2,A3,A4,A5,A6,A7,A8) \ CCALLSFSUB10(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,0,0) #define CCALLSFSUB9( UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,A1,A2,A3,A4,A5,A6,A7,A8,A9)\ CCALLSFSUB10(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,0) #define CCALLSFSUB10(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA)\ CCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,0,0,0,0) #define CCALLSFSUB11(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB)\ CCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,0,0,0) #define CCALLSFSUB12(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC)\ CCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,0,0) #define CCALLSFSUB13(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD)\ CCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,0) #ifdef __cplusplus #define CPPPROTOCLSFSUB0( UN,LN) #define CPPPROTOCLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) #define CPPPROTOCLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) #define CPPPROTOCLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) #else #define CPPPROTOCLSFSUB0(UN,LN) \ PROTOCCALLSFSUB0(UN,LN) #define CPPPROTOCLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) #define CPPPROTOCLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) \ PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) #define CPPPROTOCLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \ PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) #endif #ifdef CFSUBASFUN #define CCALLSFSUB0(UN,LN) CCALLSFFUN0(UN,LN) #define CCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE)\ CCALLSFFUN14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE) #else /* do{...}while(0) allows if(a==b) FORT(); else BORT(); */ #define CCALLSFSUB0( UN,LN) do{CPPPROTOCLSFSUB0(UN,LN) CFC_(UN,LN)();}while(0) #define CCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE)\ do{VVCF(T1,A1,B1) VVCF(T2,A2,B2) VVCF(T3,A3,B3) VVCF(T4,A4,B4) VVCF(T5,A5,B5) \ VVCF(T6,A6,B6) VVCF(T7,A7,B7) VVCF(T8,A8,B8) VVCF(T9,A9,B9) VVCF(TA,AA,B10) \ VVCF(TB,AB,B11) VVCF(TC,AC,B12) VVCF(TD,AD,B13) VVCF(TE,AE,B14) \ CPPPROTOCLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \ ACF(LN,T1,A1,1) ACF(LN,T2,A2,2) ACF(LN,T3,A3,3) \ ACF(LN,T4,A4,4) ACF(LN,T5,A5,5) ACF(LN,T6,A6,6) ACF(LN,T7,A7,7) \ ACF(LN,T8,A8,8) ACF(LN,T9,A9,9) ACF(LN,TA,AA,10) ACF(LN,TB,AB,11) \ ACF(LN,TC,AC,12) ACF(LN,TD,AD,13) ACF(LN,TE,AE,14) \ CFC_(UN,LN)( CFARGTA14(AACF,JCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE) );\ WCF(T1,A1,1) WCF(T2,A2,2) WCF(T3,A3,3) WCF(T4,A4,4) WCF(T5,A5,5) \ WCF(T6,A6,6) WCF(T7,A7,7) WCF(T8,A8,8) WCF(T9,A9,9) WCF(TA,AA,10) \ WCF(TB,AB,11) WCF(TC,AC,12) WCF(TD,AD,13) WCF(TE,AE,14) }while(0) #endif #if MAX_PREPRO_ARGS>31 #define CCALLSFSUB15(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF)\ CCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,CF_0,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,0,0,0,0,0) #define CCALLSFSUB16(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG)\ CCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,0,0,0,0) #define CCALLSFSUB17(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH)\ CCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,0,0,0) #define CCALLSFSUB18(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI)\ CCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,0,0) #define CCALLSFSUB19(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ)\ CCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,0) #ifdef CFSUBASFUN #define CCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH, \ TI,TJ,TK, A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK) \ CCALLSFFUN20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH, \ TI,TJ,TK, A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK) #else #define CCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH, \ TI,TJ,TK, A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK) \ do{VVCF(T1,A1,B1) VVCF(T2,A2,B2) VVCF(T3,A3,B3) VVCF(T4,A4,B4) VVCF(T5,A5,B5) \ VVCF(T6,A6,B6) VVCF(T7,A7,B7) VVCF(T8,A8,B8) VVCF(T9,A9,B9) VVCF(TA,AA,B10) \ VVCF(TB,AB,B11) VVCF(TC,AC,B12) VVCF(TD,AD,B13) VVCF(TE,AE,B14) VVCF(TF,AF,B15) \ VVCF(TG,AG,B16) VVCF(TH,AH,B17) VVCF(TI,AI,B18) VVCF(TJ,AJ,B19) VVCF(TK,AK,B20) \ CPPPROTOCLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) \ ACF(LN,T1,A1,1) ACF(LN,T2,A2,2) ACF(LN,T3,A3,3) ACF(LN,T4,A4,4) \ ACF(LN,T5,A5,5) ACF(LN,T6,A6,6) ACF(LN,T7,A7,7) ACF(LN,T8,A8,8) \ ACF(LN,T9,A9,9) ACF(LN,TA,AA,10) ACF(LN,TB,AB,11) ACF(LN,TC,AC,12) \ ACF(LN,TD,AD,13) ACF(LN,TE,AE,14) ACF(LN,TF,AF,15) ACF(LN,TG,AG,16) \ ACF(LN,TH,AH,17) ACF(LN,TI,AI,18) ACF(LN,TJ,AJ,19) ACF(LN,TK,AK,20) \ CFC_(UN,LN)( CFARGTA20(AACF,JCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK) ); \ WCF(T1,A1,1) WCF(T2,A2,2) WCF(T3,A3,3) WCF(T4,A4,4) WCF(T5,A5,5) WCF(T6,A6,6) \ WCF(T7,A7,7) WCF(T8,A8,8) WCF(T9,A9,9) WCF(TA,AA,10) WCF(TB,AB,11) WCF(TC,AC,12) \ WCF(TD,AD,13) WCF(TE,AE,14) WCF(TF,AF,15) WCF(TG,AG,16) WCF(TH,AH,17) WCF(TI,AI,18) \ WCF(TJ,AJ,19) WCF(TK,AK,20) }while(0) #endif #endif /* MAX_PREPRO_ARGS */ #if MAX_PREPRO_ARGS>31 #define CCALLSFSUB21(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL)\ CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,0,0,0,0,0,0) #define CCALLSFSUB22(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM)\ CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,CF_0,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,0,0,0,0,0) #define CCALLSFSUB23(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN)\ CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,0,0,0,0) #define CCALLSFSUB24(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO)\ CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,0,0,0) #define CCALLSFSUB25(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP)\ CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,0,0) #define CCALLSFSUB26(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ)\ CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,0) #ifdef CFSUBASFUN #define CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR, \ A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR) \ CCALLSFFUN27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR, \ A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR) #else #define CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR, \ A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR) \ do{VVCF(T1,A1,B1) VVCF(T2,A2,B2) VVCF(T3,A3,B3) VVCF(T4,A4,B4) VVCF(T5,A5,B5) \ VVCF(T6,A6,B6) VVCF(T7,A7,B7) VVCF(T8,A8,B8) VVCF(T9,A9,B9) VVCF(TA,AA,B10) \ VVCF(TB,AB,B11) VVCF(TC,AC,B12) VVCF(TD,AD,B13) VVCF(TE,AE,B14) VVCF(TF,AF,B15) \ VVCF(TG,AG,B16) VVCF(TH,AH,B17) VVCF(TI,AI,B18) VVCF(TJ,AJ,B19) VVCF(TK,AK,B20) \ VVCF(TL,AL,B21) VVCF(TM,AM,B22) VVCF(TN,AN,B23) VVCF(TO,AO,B24) VVCF(TP,AP,B25) \ VVCF(TQ,AQ,B26) VVCF(TR,AR,B27) \ CPPPROTOCLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \ ACF(LN,T1,A1,1) ACF(LN,T2,A2,2) ACF(LN,T3,A3,3) ACF(LN,T4,A4,4) \ ACF(LN,T5,A5,5) ACF(LN,T6,A6,6) ACF(LN,T7,A7,7) ACF(LN,T8,A8,8) \ ACF(LN,T9,A9,9) ACF(LN,TA,AA,10) ACF(LN,TB,AB,11) ACF(LN,TC,AC,12) \ ACF(LN,TD,AD,13) ACF(LN,TE,AE,14) ACF(LN,TF,AF,15) ACF(LN,TG,AG,16) \ ACF(LN,TH,AH,17) ACF(LN,TI,AI,18) ACF(LN,TJ,AJ,19) ACF(LN,TK,AK,20) \ ACF(LN,TL,AL,21) ACF(LN,TM,AM,22) ACF(LN,TN,AN,23) ACF(LN,TO,AO,24) \ ACF(LN,TP,AP,25) ACF(LN,TQ,AQ,26) ACF(LN,TR,AR,27) \ CFC_(UN,LN)( CFARGTA27(AACF,JCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR,\ A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR) ); \ WCF(T1,A1,1) WCF(T2,A2,2) WCF(T3,A3,3) WCF(T4,A4,4) WCF(T5,A5,5) WCF(T6,A6,6) \ WCF(T7,A7,7) WCF(T8,A8,8) WCF(T9,A9,9) WCF(TA,AA,10) WCF(TB,AB,11) WCF(TC,AC,12) \ WCF(TD,AD,13) WCF(TE,AE,14) WCF(TF,AF,15) WCF(TG,AG,16) WCF(TH,AH,17) WCF(TI,AI,18) \ WCF(TJ,AJ,19) WCF(TK,AK,20) WCF(TL,AL,21) WCF(TM,AM,22) WCF(TN,AN,23) WCF(TO,AO,24) \ WCF(TP,AP,25) WCF(TQ,AQ,26) WCF(TR,AR,27) }while(0) #endif #endif /* MAX_PREPRO_ARGS */ /*-------------------------------------------------------------------------*/ /* UTILITIES FOR C TO CALL FORTRAN FUNCTIONS */ /*N.B. PROTOCCALLSFFUNn(..) generates code, whether or not the FORTRAN function is called. Therefore, especially for creator's of C header files for large FORTRAN libraries which include many functions, to reduce compile time and object code size, it may be desirable to create preprocessor directives to allow users to create code for only those functions which they use. */ /* The following defines the maximum length string that a function can return. Of course it may be undefine-d and re-define-d before individual PROTOCCALLSFFUNn(..) as required. It would also be nice to have this derived from the individual machines' limits. */ #define MAX_LEN_FORTRAN_FUNCTION_STRING 0x4FE /* The following defines a character used by CFORTRAN.H to flag the end of a string coming out of a FORTRAN routine. */ #define CFORTRAN_NON_CHAR 0x7F #ifdef OLD_VAXC /* Prevent %CC-I-PARAMNOTUSED. */ #pragma nostandard #endif #define _SEP_(TN,C,cfCOMMA) _(__SEP_,C)(TN,cfCOMMA) #define __SEP_0(TN,cfCOMMA) #define __SEP_1(TN,cfCOMMA) _Icf(2,SEP,TN,cfCOMMA,0) #define INT_cfSEP(T,B) _(A,B) #define INTV_cfSEP(T,B) INT_cfSEP(T,B) #define INTVV_cfSEP(T,B) INT_cfSEP(T,B) #define INTVVV_cfSEP(T,B) INT_cfSEP(T,B) #define INTVVVV_cfSEP(T,B) INT_cfSEP(T,B) #define INTVVVVV_cfSEP(T,B) INT_cfSEP(T,B) #define INTVVVVVV_cfSEP(T,B) INT_cfSEP(T,B) #define INTVVVVVVV_cfSEP(T,B) INT_cfSEP(T,B) #define PINT_cfSEP(T,B) INT_cfSEP(T,B) #define PVOID_cfSEP(T,B) INT_cfSEP(T,B) #define ROUTINE_cfSEP(T,B) INT_cfSEP(T,B) #define SIMPLE_cfSEP(T,B) INT_cfSEP(T,B) #define VOID_cfSEP(T,B) INT_cfSEP(T,B) /* For FORTRAN calls C subr.s.*/ #define STRING_cfSEP(T,B) INT_cfSEP(T,B) #define STRINGV_cfSEP(T,B) INT_cfSEP(T,B) #define PSTRING_cfSEP(T,B) INT_cfSEP(T,B) #define PSTRINGV_cfSEP(T,B) INT_cfSEP(T,B) #define PNSTRING_cfSEP(T,B) INT_cfSEP(T,B) #define PPSTRING_cfSEP(T,B) INT_cfSEP(T,B) #define ZTRINGV_cfSEP(T,B) INT_cfSEP(T,B) #define PZTRINGV_cfSEP(T,B) INT_cfSEP(T,B) #if defined(SIGNED_BYTE) || !defined(UNSIGNED_BYTE) #ifdef OLD_VAXC #define INTEGER_BYTE char /* Old VAXC barfs on 'signed char' */ #else #define INTEGER_BYTE signed char /* default */ #endif #else #define INTEGER_BYTE unsigned char #endif #define BYTEVVVVVVV_cfTYPE INTEGER_BYTE #define DOUBLEVVVVVVV_cfTYPE DOUBLE_PRECISION #define FLOATVVVVVVV_cfTYPE FORTRAN_REAL #define INTVVVVVVV_cfTYPE int #define LOGICALVVVVVVV_cfTYPE int #define LONGVVVVVVV_cfTYPE long #define LONGLONGVVVVVVV_cfTYPE LONGLONG /* added by MR December 2005 */ #define SHORTVVVVVVV_cfTYPE short #define PBYTE_cfTYPE INTEGER_BYTE #define PDOUBLE_cfTYPE DOUBLE_PRECISION #define PFLOAT_cfTYPE FORTRAN_REAL #define PINT_cfTYPE int #define PLOGICAL_cfTYPE int #define PLONG_cfTYPE long #define PLONGLONG_cfTYPE LONGLONG /* added by MR December 2005 */ #define PSHORT_cfTYPE short #define CFARGS0(A,T,V,W,X,Y,Z) _3(T,_cf,A) #define CFARGS1(A,T,V,W,X,Y,Z) _3(T,_cf,A)(V) #define CFARGS2(A,T,V,W,X,Y,Z) _3(T,_cf,A)(V,W) #define CFARGS3(A,T,V,W,X,Y,Z) _3(T,_cf,A)(V,W,X) #define CFARGS4(A,T,V,W,X,Y,Z) _3(T,_cf,A)(V,W,X,Y) #define CFARGS5(A,T,V,W,X,Y,Z) _3(T,_cf,A)(V,W,X,Y,Z) #define _Icf(N,T,I,X,Y) _(I,_cfINT)(N,T,I,X,Y,0) #define _Icf4(N,T,I,X,Y,Z) _(I,_cfINT)(N,T,I,X,Y,Z) #define BYTE_cfINT(N,A,B,X,Y,Z) DOUBLE_cfINT(N,A,B,X,Y,Z) #define DOUBLE_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INT,B,X,Y,Z,0) #define FLOAT_cfINT(N,A,B,X,Y,Z) DOUBLE_cfINT(N,A,B,X,Y,Z) #define INT_cfINT(N,A,B,X,Y,Z) DOUBLE_cfINT(N,A,B,X,Y,Z) #define LOGICAL_cfINT(N,A,B,X,Y,Z) DOUBLE_cfINT(N,A,B,X,Y,Z) #define LONG_cfINT(N,A,B,X,Y,Z) DOUBLE_cfINT(N,A,B,X,Y,Z) #define LONGLONG_cfINT(N,A,B,X,Y,Z) DOUBLE_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */ #define SHORT_cfINT(N,A,B,X,Y,Z) DOUBLE_cfINT(N,A,B,X,Y,Z) #define PBYTE_cfINT(N,A,B,X,Y,Z) PDOUBLE_cfINT(N,A,B,X,Y,Z) #define PDOUBLE_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,PINT,B,X,Y,Z,0) #define PFLOAT_cfINT(N,A,B,X,Y,Z) PDOUBLE_cfINT(N,A,B,X,Y,Z) #define PINT_cfINT(N,A,B,X,Y,Z) PDOUBLE_cfINT(N,A,B,X,Y,Z) #define PLOGICAL_cfINT(N,A,B,X,Y,Z) PDOUBLE_cfINT(N,A,B,X,Y,Z) #define PLONG_cfINT(N,A,B,X,Y,Z) PDOUBLE_cfINT(N,A,B,X,Y,Z) #define PLONGLONG_cfINT(N,A,B,X,Y,Z) PDOUBLE_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */ #define PSHORT_cfINT(N,A,B,X,Y,Z) PDOUBLE_cfINT(N,A,B,X,Y,Z) #define BYTEV_cfINT(N,A,B,X,Y,Z) DOUBLEV_cfINT(N,A,B,X,Y,Z) #define BYTEVV_cfINT(N,A,B,X,Y,Z) DOUBLEVV_cfINT(N,A,B,X,Y,Z) #define BYTEVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVV_cfINT(N,A,B,X,Y,Z) #define BYTEVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVV_cfINT(N,A,B,X,Y,Z) #define BYTEVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z) #define BYTEVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z) #define BYTEVVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z) #define DOUBLEV_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INTV,B,X,Y,Z,0) #define DOUBLEVV_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INTVV,B,X,Y,Z,0) #define DOUBLEVVV_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INTVVV,B,X,Y,Z,0) #define DOUBLEVVVV_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INTVVVV,B,X,Y,Z,0) #define DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INTVVVVV,B,X,Y,Z,0) #define DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INTVVVVVV,B,X,Y,Z,0) #define DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INTVVVVVVV,B,X,Y,Z,0) #define FLOATV_cfINT(N,A,B,X,Y,Z) DOUBLEV_cfINT(N,A,B,X,Y,Z) #define FLOATVV_cfINT(N,A,B,X,Y,Z) DOUBLEVV_cfINT(N,A,B,X,Y,Z) #define FLOATVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVV_cfINT(N,A,B,X,Y,Z) #define FLOATVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVV_cfINT(N,A,B,X,Y,Z) #define FLOATVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z) #define FLOATVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z) #define FLOATVVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z) #define INTV_cfINT(N,A,B,X,Y,Z) DOUBLEV_cfINT(N,A,B,X,Y,Z) #define INTVV_cfINT(N,A,B,X,Y,Z) DOUBLEVV_cfINT(N,A,B,X,Y,Z) #define INTVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVV_cfINT(N,A,B,X,Y,Z) #define INTVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVV_cfINT(N,A,B,X,Y,Z) #define INTVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z) #define INTVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z) #define INTVVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z) #define LOGICALV_cfINT(N,A,B,X,Y,Z) DOUBLEV_cfINT(N,A,B,X,Y,Z) #define LOGICALVV_cfINT(N,A,B,X,Y,Z) DOUBLEVV_cfINT(N,A,B,X,Y,Z) #define LOGICALVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVV_cfINT(N,A,B,X,Y,Z) #define LOGICALVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVV_cfINT(N,A,B,X,Y,Z) #define LOGICALVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z) #define LOGICALVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z) #define LOGICALVVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z) #define LONGV_cfINT(N,A,B,X,Y,Z) DOUBLEV_cfINT(N,A,B,X,Y,Z) #define LONGVV_cfINT(N,A,B,X,Y,Z) DOUBLEVV_cfINT(N,A,B,X,Y,Z) #define LONGVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVV_cfINT(N,A,B,X,Y,Z) #define LONGVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVV_cfINT(N,A,B,X,Y,Z) #define LONGVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z) #define LONGVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z) #define LONGVVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z) #define LONGLONGV_cfINT(N,A,B,X,Y,Z) DOUBLEV_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */ #define LONGLONGVV_cfINT(N,A,B,X,Y,Z) DOUBLEVV_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */ #define LONGLONGVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVV_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */ #define LONGLONGVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVV_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */ #define LONGLONGVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */ #define LONGLONGVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */ #define LONGLONGVVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */ #define SHORTV_cfINT(N,A,B,X,Y,Z) DOUBLEV_cfINT(N,A,B,X,Y,Z) #define SHORTVV_cfINT(N,A,B,X,Y,Z) DOUBLEVV_cfINT(N,A,B,X,Y,Z) #define SHORTVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVV_cfINT(N,A,B,X,Y,Z) #define SHORTVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVV_cfINT(N,A,B,X,Y,Z) #define SHORTVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z) #define SHORTVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z) #define SHORTVVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z) #define PVOID_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,B,B,X,Y,Z,0) #define ROUTINE_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z) /*CRAY coughs on the first, i.e. the usual trouble of not being able to define macros to macros with arguments. New ultrix is worse, it coughs on all such uses. */ /*#define SIMPLE_cfINT PVOID_cfINT*/ #define SIMPLE_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z) #define VOID_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z) #define STRING_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z) #define STRINGV_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z) #define PSTRING_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z) #define PSTRINGV_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z) #define PNSTRING_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z) #define PPSTRING_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z) #define ZTRINGV_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z) #define PZTRINGV_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z) #define CF_0_cfINT(N,A,B,X,Y,Z) #define UCF(TN,I,C) _SEP_(TN,C,cfCOMMA) _Icf(2,U,TN,_(A,I),0) #define UUCF(TN,I,C) _SEP_(TN,C,cfCOMMA) _SEP_(TN,1,I) #define UUUCF(TN,I,C) _SEP_(TN,C,cfCOLON) _Icf(2,U,TN,_(A,I),0) #define INT_cfU(T,A) _(T,VVVVVVV_cfTYPE) A #define INTV_cfU(T,A) _(T,VVVVVV_cfTYPE) * A #define INTVV_cfU(T,A) _(T,VVVVV_cfTYPE) * A #define INTVVV_cfU(T,A) _(T,VVVV_cfTYPE) * A #define INTVVVV_cfU(T,A) _(T,VVV_cfTYPE) * A #define INTVVVVV_cfU(T,A) _(T,VV_cfTYPE) * A #define INTVVVVVV_cfU(T,A) _(T,V_cfTYPE) * A #define INTVVVVVVV_cfU(T,A) _(T,_cfTYPE) * A #define PINT_cfU(T,A) _(T,_cfTYPE) * A #define PVOID_cfU(T,A) void *A #define ROUTINE_cfU(T,A) void (*A)(CF_NULL_PROTO) #define VOID_cfU(T,A) void A /* Needed for C calls FORTRAN sub.s. */ #define STRING_cfU(T,A) char *A /* via VOID and wrapper. */ #define STRINGV_cfU(T,A) char *A #define PSTRING_cfU(T,A) char *A #define PSTRINGV_cfU(T,A) char *A #define ZTRINGV_cfU(T,A) char *A #define PZTRINGV_cfU(T,A) char *A /* VOID breaks U into U and UU. */ #define INT_cfUU(T,A) _(T,VVVVVVV_cfTYPE) A #define VOID_cfUU(T,A) /* Needed for FORTRAN calls C sub.s. */ #define STRING_cfUU(T,A) char *A #define BYTE_cfPU(A) CFextern INTEGER_BYTE FCALLSC_QUALIFIER A #define DOUBLE_cfPU(A) CFextern DOUBLE_PRECISION FCALLSC_QUALIFIER A #if ! (defined(FLOATFUNCTIONTYPE)&&defined(ASSIGNFLOAT)&&defined(RETURNFLOAT)) #if defined (f2cFortran) && ! defined (gFortran) /* f2c/g77 return double from FORTRAN REAL functions. (KMCCARTY, 2005/12/09) */ #define FLOAT_cfPU(A) CFextern DOUBLE_PRECISION FCALLSC_QUALIFIER A #else #define FLOAT_cfPU(A) CFextern FORTRAN_REAL FCALLSC_QUALIFIER A #endif #else #define FLOAT_cfPU(A) CFextern FLOATFUNCTIONTYPE FCALLSC_QUALIFIER A #endif #define INT_cfPU(A) CFextern int FCALLSC_QUALIFIER A #define LOGICAL_cfPU(A) CFextern int FCALLSC_QUALIFIER A #define LONG_cfPU(A) CFextern long FCALLSC_QUALIFIER A #define SHORT_cfPU(A) CFextern short FCALLSC_QUALIFIER A #define STRING_cfPU(A) CFextern void FCALLSC_QUALIFIER A #define VOID_cfPU(A) CFextern void FCALLSC_QUALIFIER A #define BYTE_cfE INTEGER_BYTE A0; #define DOUBLE_cfE DOUBLE_PRECISION A0; #if ! (defined(FLOATFUNCTIONTYPE)&&defined(ASSIGNFLOAT)&&defined(RETURNFLOAT)) #define FLOAT_cfE FORTRAN_REAL A0; #else #define FLOAT_cfE FORTRAN_REAL AA0; FLOATFUNCTIONTYPE A0; #endif #define INT_cfE int A0; #define LOGICAL_cfE int A0; #define LONG_cfE long A0; #define SHORT_cfE short A0; #define VOID_cfE #ifdef vmsFortran #define STRING_cfE static char AA0[1+MAX_LEN_FORTRAN_FUNCTION_STRING]; \ static fstring A0 = \ {MAX_LEN_FORTRAN_FUNCTION_STRING,DSC$K_DTYPE_T,DSC$K_CLASS_S,AA0};\ memset(AA0, CFORTRAN_NON_CHAR, MAX_LEN_FORTRAN_FUNCTION_STRING);\ *(AA0+MAX_LEN_FORTRAN_FUNCTION_STRING)='\0'; #else #ifdef CRAYFortran #define STRING_cfE static char AA0[1+MAX_LEN_FORTRAN_FUNCTION_STRING]; \ static _fcd A0; *(AA0+MAX_LEN_FORTRAN_FUNCTION_STRING)='\0';\ memset(AA0,CFORTRAN_NON_CHAR, MAX_LEN_FORTRAN_FUNCTION_STRING);\ A0 = _cptofcd(AA0,MAX_LEN_FORTRAN_FUNCTION_STRING); #else /* 'cc: SC3.0.1 13 Jul 1994' barfs on char A0[0x4FE+1]; * char A0[0x4FE +1]; char A0[1+0x4FE]; are both OK. */ #define STRING_cfE static char A0[1+MAX_LEN_FORTRAN_FUNCTION_STRING]; \ memset(A0, CFORTRAN_NON_CHAR, \ MAX_LEN_FORTRAN_FUNCTION_STRING); \ *(A0+MAX_LEN_FORTRAN_FUNCTION_STRING)='\0'; #endif #endif /* ESTRING must use static char. array which is guaranteed to exist after function returns. */ /* N.B.i) The diff. for 0 (Zero) and >=1 arguments. ii)That the following create an unmatched bracket, i.e. '(', which must of course be matched in the call. iii)Commas must be handled very carefully */ #define INT_cfGZ(T,UN,LN) A0=CFC_(UN,LN)( #define VOID_cfGZ(T,UN,LN) CFC_(UN,LN)( #ifdef vmsFortran #define STRING_cfGZ(T,UN,LN) CFC_(UN,LN)(&A0 #else #if defined(CRAYFortran) || defined(AbsoftUNIXFortran) || defined(AbsoftProFortran) #define STRING_cfGZ(T,UN,LN) CFC_(UN,LN)( A0 #else #define STRING_cfGZ(T,UN,LN) CFC_(UN,LN)( A0,MAX_LEN_FORTRAN_FUNCTION_STRING #endif #endif #define INT_cfG(T,UN,LN) INT_cfGZ(T,UN,LN) #define VOID_cfG(T,UN,LN) VOID_cfGZ(T,UN,LN) #define STRING_cfG(T,UN,LN) STRING_cfGZ(T,UN,LN), /*, is only diff. from _cfG*/ #define BYTEVVVVVVV_cfPP #define INTVVVVVVV_cfPP /* These complement FLOATVVVVVVV_cfPP. */ #define DOUBLEVVVVVVV_cfPP #define LOGICALVVVVVVV_cfPP #define LONGVVVVVVV_cfPP #define SHORTVVVVVVV_cfPP #define PBYTE_cfPP #define PINT_cfPP #define PDOUBLE_cfPP #define PLOGICAL_cfPP #define PLONG_cfPP #define PSHORT_cfPP #define PFLOAT_cfPP FLOATVVVVVVV_cfPP #define BCF(TN,AN,C) _SEP_(TN,C,cfCOMMA) _Icf(2,B,TN,AN,0) #define INT_cfB(T,A) (_(T,VVVVVVV_cfTYPE)) A #define INTV_cfB(T,A) A #define INTVV_cfB(T,A) (A)[0] #define INTVVV_cfB(T,A) (A)[0][0] #define INTVVVV_cfB(T,A) (A)[0][0][0] #define INTVVVVV_cfB(T,A) (A)[0][0][0][0] #define INTVVVVVV_cfB(T,A) (A)[0][0][0][0][0] #define INTVVVVVVV_cfB(T,A) (A)[0][0][0][0][0][0] #define PINT_cfB(T,A) _(T,_cfPP)&A #define STRING_cfB(T,A) (char *) A #define STRINGV_cfB(T,A) (char *) A #define PSTRING_cfB(T,A) (char *) A #define PSTRINGV_cfB(T,A) (char *) A #define PVOID_cfB(T,A) (void *) A #define ROUTINE_cfB(T,A) (cfCAST_FUNCTION)A #define ZTRINGV_cfB(T,A) (char *) A #define PZTRINGV_cfB(T,A) (char *) A #define SCF(TN,NAME,I,A) _(TN,_cfSTR)(3,S,NAME,I,A,0,0) #define DEFAULT_cfS(M,I,A) #define LOGICAL_cfS(M,I,A) #define PLOGICAL_cfS(M,I,A) #define STRING_cfS(M,I,A) ,sizeof(A) #define STRINGV_cfS(M,I,A) ,( (unsigned)0xFFFF*firstindexlength(A) \ +secondindexlength(A)) #define PSTRING_cfS(M,I,A) ,sizeof(A) #define PSTRINGV_cfS(M,I,A) STRINGV_cfS(M,I,A) #define ZTRINGV_cfS(M,I,A) #define PZTRINGV_cfS(M,I,A) #define HCF(TN,I) _(TN,_cfSTR)(3,H,cfCOMMA, H,_(C,I),0,0) #define HHCF(TN,I) _(TN,_cfSTR)(3,H,cfCOMMA,HH,_(C,I),0,0) #define HHHCF(TN,I) _(TN,_cfSTR)(3,H,cfCOLON, H,_(C,I),0,0) #define H_CF_SPECIAL unsigned #define HH_CF_SPECIAL #define DEFAULT_cfH(M,I,A) #define LOGICAL_cfH(S,U,B) #define PLOGICAL_cfH(S,U,B) #define STRING_cfH(S,U,B) _(A,S) _(U,_CF_SPECIAL) B #define STRINGV_cfH(S,U,B) STRING_cfH(S,U,B) #define PSTRING_cfH(S,U,B) STRING_cfH(S,U,B) #define PSTRINGV_cfH(S,U,B) STRING_cfH(S,U,B) #define PNSTRING_cfH(S,U,B) STRING_cfH(S,U,B) #define PPSTRING_cfH(S,U,B) STRING_cfH(S,U,B) #define ZTRINGV_cfH(S,U,B) #define PZTRINGV_cfH(S,U,B) /* Need VOID_cfSTR because Absoft forced function types go through _cfSTR. */ /* No spaces inside expansion. They screws up macro catenation kludge. */ #define VOID_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define BYTE_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define DOUBLE_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define FLOAT_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define INT_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define LOGICAL_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,LOGICAL,A,B,C,D,E) #define LONG_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define LONGLONG_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */ #define SHORT_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define BYTEV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define BYTEVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define BYTEVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define BYTEVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define BYTEVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define BYTEVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define BYTEVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define DOUBLEV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define DOUBLEVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define DOUBLEVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define DOUBLEVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define DOUBLEVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define DOUBLEVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define DOUBLEVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define FLOATV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define FLOATVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define FLOATVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define FLOATVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define FLOATVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define FLOATVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define FLOATVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define INTV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define INTVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define INTVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define INTVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define INTVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define INTVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define INTVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define LOGICALV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define LOGICALVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define LOGICALVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define LOGICALVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define LOGICALVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define LOGICALVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define LOGICALVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define LONGV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define LONGVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define LONGVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define LONGVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define LONGVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define LONGVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define LONGVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define LONGLONGV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */ #define LONGLONGVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */ #define LONGLONGVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */ #define LONGLONGVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */ #define LONGLONGVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */ #define LONGLONGVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */ #define LONGLONGVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */ #define SHORTV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define SHORTVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define SHORTVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define SHORTVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define SHORTVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define SHORTVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define SHORTVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define PBYTE_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define PDOUBLE_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define PFLOAT_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define PINT_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define PLOGICAL_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,PLOGICAL,A,B,C,D,E) #define PLONG_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define PLONGLONG_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */ #define PSHORT_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define STRING_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,STRING,A,B,C,D,E) #define PSTRING_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,PSTRING,A,B,C,D,E) #define STRINGV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,STRINGV,A,B,C,D,E) #define PSTRINGV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,PSTRINGV,A,B,C,D,E) #define PNSTRING_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,PNSTRING,A,B,C,D,E) #define PPSTRING_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,PPSTRING,A,B,C,D,E) #define PVOID_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define ROUTINE_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define SIMPLE_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) #define ZTRINGV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,ZTRINGV,A,B,C,D,E) #define PZTRINGV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,PZTRINGV,A,B,C,D,E) #define CF_0_cfSTR(N,T,A,B,C,D,E) /* See ACF table comments, which explain why CCF was split into two. */ #define CCF(NAME,TN,I) _(TN,_cfSTR)(5,C,NAME,I,_(A,I),_(B,I),_(C,I)) #define DEFAULT_cfC(M,I,A,B,C) #define LOGICAL_cfC(M,I,A,B,C) A=C2FLOGICAL( A); #define PLOGICAL_cfC(M,I,A,B,C) *A=C2FLOGICAL(*A); #ifdef vmsFortran #define STRING_cfC(M,I,A,B,C) (B.clen=strlen(A),B.f.dsc$a_pointer=A, \ C==sizeof(char*)||C==(unsigned)(B.clen+1)?B.f.dsc$w_length=B.clen: \ (memset((A)+B.clen,' ',C-B.clen-1),A[B.f.dsc$w_length=C-1]='\0')); /* PSTRING_cfC to beware of array A which does not contain any \0. */ #define PSTRING_cfC(M,I,A,B,C) (B.dsc$a_pointer=A, C==sizeof(char*) ? \ B.dsc$w_length=strlen(A): (A[C-1]='\0',B.dsc$w_length=strlen(A), \ memset((A)+B.dsc$w_length,' ',C-B.dsc$w_length-1), B.dsc$w_length=C-1)); #else #define STRING_cfC(M,I,A,B,C) (B.nombre=A,B.clen=strlen(A), \ C==sizeof(char*)||C==(unsigned)(B.clen+1)?B.flen=B.clen: \ (memset(B.nombre+B.clen,' ',C-B.clen-1),B.nombre[B.flen=C-1]='\0')); #define PSTRING_cfC(M,I,A,B,C) (C==sizeof(char*)? B=strlen(A): \ (A[C-1]='\0',B=strlen(A),memset((A)+B,' ',C-B-1),B=C-1)); #endif /* For CRAYFortran for (P)STRINGV_cfC, B.fs is set, but irrelevant. */ #define STRINGV_cfC(M,I,A,B,C) \ AATRINGV_cfA( A,B,(C/0xFFFF)*(C%0xFFFF),C/0xFFFF,C%0xFFFF) #define PSTRINGV_cfC(M,I,A,B,C) \ APATRINGV_cfA( A,B,(C/0xFFFF)*(C%0xFFFF),C/0xFFFF,C%0xFFFF) #define ZTRINGV_cfC(M,I,A,B,C) \ AATRINGV_cfA( A,B, (_3(M,_ELEMS_,I))*((_3(M,_ELEMLEN_,I))+1), \ (_3(M,_ELEMS_,I)), (_3(M,_ELEMLEN_,I))+1 ) #define PZTRINGV_cfC(M,I,A,B,C) \ APATRINGV_cfA( A,B, (_3(M,_ELEMS_,I))*((_3(M,_ELEMLEN_,I))+1), \ (_3(M,_ELEMS_,I)), (_3(M,_ELEMLEN_,I))+1 ) #define BYTE_cfCCC(A,B) &A #define DOUBLE_cfCCC(A,B) &A #if !defined(__CF__KnR) #define FLOAT_cfCCC(A,B) &A /* Although the VAX doesn't, at least the */ #else /* HP and K&R mips promote float arg.'s of */ #define FLOAT_cfCCC(A,B) &B /* unprototyped functions to double. Cannot */ #endif /* use A here to pass the argument to FORTRAN. */ #define INT_cfCCC(A,B) &A #define LOGICAL_cfCCC(A,B) &A #define LONG_cfCCC(A,B) &A #define SHORT_cfCCC(A,B) &A #define PBYTE_cfCCC(A,B) A #define PDOUBLE_cfCCC(A,B) A #define PFLOAT_cfCCC(A,B) A #define PINT_cfCCC(A,B) A #define PLOGICAL_cfCCC(A,B) B=A /* B used to keep a common W table. */ #define PLONG_cfCCC(A,B) A #define PSHORT_cfCCC(A,B) A #define CCCF(TN,I,M) _SEP_(TN,M,cfCOMMA) _Icf(3,CC,TN,_(A,I),_(B,I)) #define INT_cfCC(T,A,B) _(T,_cfCCC)(A,B) #define INTV_cfCC(T,A,B) A #define INTVV_cfCC(T,A,B) A #define INTVVV_cfCC(T,A,B) A #define INTVVVV_cfCC(T,A,B) A #define INTVVVVV_cfCC(T,A,B) A #define INTVVVVVV_cfCC(T,A,B) A #define INTVVVVVVV_cfCC(T,A,B) A #define PINT_cfCC(T,A,B) _(T,_cfCCC)(A,B) #define PVOID_cfCC(T,A,B) A #if defined(apolloFortran) || defined(hpuxFortran800) || defined(AbsoftUNIXFortran) #define ROUTINE_cfCC(T,A,B) &A #else #define ROUTINE_cfCC(T,A,B) A #endif #define SIMPLE_cfCC(T,A,B) A #ifdef vmsFortran #define STRING_cfCC(T,A,B) &B.f #define STRINGV_cfCC(T,A,B) &B #define PSTRING_cfCC(T,A,B) &B #define PSTRINGV_cfCC(T,A,B) &B #else #ifdef CRAYFortran #define STRING_cfCC(T,A,B) _cptofcd(A,B.flen) #define STRINGV_cfCC(T,A,B) _cptofcd(B.s,B.flen) #define PSTRING_cfCC(T,A,B) _cptofcd(A,B) #define PSTRINGV_cfCC(T,A,B) _cptofcd(A,B.flen) #else #define STRING_cfCC(T,A,B) A #define STRINGV_cfCC(T,A,B) B.fs #define PSTRING_cfCC(T,A,B) A #define PSTRINGV_cfCC(T,A,B) B.fs #endif #endif #define ZTRINGV_cfCC(T,A,B) STRINGV_cfCC(T,A,B) #define PZTRINGV_cfCC(T,A,B) PSTRINGV_cfCC(T,A,B) #define BYTE_cfX return A0; #define DOUBLE_cfX return A0; #if ! (defined(FLOATFUNCTIONTYPE)&&defined(ASSIGNFLOAT)&&defined(RETURNFLOAT)) #define FLOAT_cfX return A0; #else #define FLOAT_cfX ASSIGNFLOAT(AA0,A0); return AA0; #endif #define INT_cfX return A0; #define LOGICAL_cfX return F2CLOGICAL(A0); #define LONG_cfX return A0; #define SHORT_cfX return A0; #define VOID_cfX return ; #if defined(vmsFortran) || defined(CRAYFortran) #define STRING_cfX return kill_trailing( \ kill_trailing(AA0,CFORTRAN_NON_CHAR),' '); #else #define STRING_cfX return kill_trailing( \ kill_trailing( A0,CFORTRAN_NON_CHAR),' '); #endif #define CFFUN(NAME) _(__cf__,NAME) /* Note that we don't use LN here, but we keep it for consistency. */ #define CCALLSFFUN0(UN,LN) CFFUN(UN)() #ifdef OLD_VAXC /* Allow %CC-I-PARAMNOTUSED. */ #pragma standard #endif #define CCALLSFFUN1( UN,LN,T1, A1) \ CCALLSFFUN5 (UN,LN,T1,CF_0,CF_0,CF_0,CF_0,A1,0,0,0,0) #define CCALLSFFUN2( UN,LN,T1,T2, A1,A2) \ CCALLSFFUN5 (UN,LN,T1,T2,CF_0,CF_0,CF_0,A1,A2,0,0,0) #define CCALLSFFUN3( UN,LN,T1,T2,T3, A1,A2,A3) \ CCALLSFFUN5 (UN,LN,T1,T2,T3,CF_0,CF_0,A1,A2,A3,0,0) #define CCALLSFFUN4( UN,LN,T1,T2,T3,T4, A1,A2,A3,A4)\ CCALLSFFUN5 (UN,LN,T1,T2,T3,T4,CF_0,A1,A2,A3,A4,0) #define CCALLSFFUN5( UN,LN,T1,T2,T3,T4,T5, A1,A2,A3,A4,A5) \ CCALLSFFUN10(UN,LN,T1,T2,T3,T4,T5,CF_0,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,0,0,0,0,0) #define CCALLSFFUN6( UN,LN,T1,T2,T3,T4,T5,T6, A1,A2,A3,A4,A5,A6) \ CCALLSFFUN10(UN,LN,T1,T2,T3,T4,T5,T6,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,0,0,0,0) #define CCALLSFFUN7( UN,LN,T1,T2,T3,T4,T5,T6,T7, A1,A2,A3,A4,A5,A6,A7) \ CCALLSFFUN10(UN,LN,T1,T2,T3,T4,T5,T6,T7,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,0,0,0) #define CCALLSFFUN8( UN,LN,T1,T2,T3,T4,T5,T6,T7,T8, A1,A2,A3,A4,A5,A6,A7,A8) \ CCALLSFFUN10(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,0,0) #define CCALLSFFUN9( UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,A1,A2,A3,A4,A5,A6,A7,A8,A9)\ CCALLSFFUN10(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,0) #define CCALLSFFUN10(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA)\ CCALLSFFUN14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,0,0,0,0) #define CCALLSFFUN11(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB)\ CCALLSFFUN14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,0,0,0) #define CCALLSFFUN12(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC)\ CCALLSFFUN14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,0,0) #define CCALLSFFUN13(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD)\ CCALLSFFUN14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,0) #define CCALLSFFUN14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE)\ ((CFFUN(UN)( BCF(T1,A1,0) BCF(T2,A2,1) BCF(T3,A3,1) BCF(T4,A4,1) BCF(T5,A5,1) \ BCF(T6,A6,1) BCF(T7,A7,1) BCF(T8,A8,1) BCF(T9,A9,1) BCF(TA,AA,1) \ BCF(TB,AB,1) BCF(TC,AC,1) BCF(TD,AD,1) BCF(TE,AE,1) \ SCF(T1,LN,1,A1) SCF(T2,LN,2,A2) SCF(T3,LN,3,A3) SCF(T4,LN,4,A4) \ SCF(T5,LN,5,A5) SCF(T6,LN,6,A6) SCF(T7,LN,7,A7) SCF(T8,LN,8,A8) \ SCF(T9,LN,9,A9) SCF(TA,LN,10,AA) SCF(TB,LN,11,AB) SCF(TC,LN,12,AC) \ SCF(TD,LN,13,AD) SCF(TE,LN,14,AE)))) /* N.B. Create a separate function instead of using (call function, function value here) because in order to create the variables needed for the input arg.'s which may be const.'s one has to do the creation within {}, but these can never be placed within ()'s. Therefore one must create wrapper functions. gcc, on the other hand may be able to avoid the wrapper functions. */ /* Prototypes are needed to correctly handle the value returned correctly. N.B. Can only have prototype arg.'s with difficulty, a la G... table since FORTRAN functions returning strings have extra arg.'s. Don't bother, since this only causes a compiler warning to come up when one uses FCALLSCFUNn and CCALLSFFUNn for the same function in the same source code. Something done by the experts in debugging only.*/ #define PROTOCCALLSFFUN0(F,UN,LN) \ _(F,_cfPU)( CFC_(UN,LN))(CF_NULL_PROTO); \ static _Icf(2,U,F,CFFUN(UN),0)() {_(F,_cfE) _Icf(3,GZ,F,UN,LN) ABSOFT_cf1(F));_(F,_cfX)} #define PROTOCCALLSFFUN1( T0,UN,LN,T1) \ PROTOCCALLSFFUN5 (T0,UN,LN,T1,CF_0,CF_0,CF_0,CF_0) #define PROTOCCALLSFFUN2( T0,UN,LN,T1,T2) \ PROTOCCALLSFFUN5 (T0,UN,LN,T1,T2,CF_0,CF_0,CF_0) #define PROTOCCALLSFFUN3( T0,UN,LN,T1,T2,T3) \ PROTOCCALLSFFUN5 (T0,UN,LN,T1,T2,T3,CF_0,CF_0) #define PROTOCCALLSFFUN4( T0,UN,LN,T1,T2,T3,T4) \ PROTOCCALLSFFUN5 (T0,UN,LN,T1,T2,T3,T4,CF_0) #define PROTOCCALLSFFUN5( T0,UN,LN,T1,T2,T3,T4,T5) \ PROTOCCALLSFFUN10(T0,UN,LN,T1,T2,T3,T4,T5,CF_0,CF_0,CF_0,CF_0,CF_0) #define PROTOCCALLSFFUN6( T0,UN,LN,T1,T2,T3,T4,T5,T6) \ PROTOCCALLSFFUN10(T0,UN,LN,T1,T2,T3,T4,T5,T6,CF_0,CF_0,CF_0,CF_0) #define PROTOCCALLSFFUN7( T0,UN,LN,T1,T2,T3,T4,T5,T6,T7) \ PROTOCCALLSFFUN10(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,CF_0,CF_0,CF_0) #define PROTOCCALLSFFUN8( T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8) \ PROTOCCALLSFFUN10(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,CF_0,CF_0) #define PROTOCCALLSFFUN9( T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9) \ PROTOCCALLSFFUN10(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,CF_0) #define PROTOCCALLSFFUN10(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA) \ PROTOCCALLSFFUN14(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,CF_0,CF_0,CF_0,CF_0) #define PROTOCCALLSFFUN11(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB) \ PROTOCCALLSFFUN14(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,CF_0,CF_0,CF_0) #define PROTOCCALLSFFUN12(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC) \ PROTOCCALLSFFUN14(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,CF_0,CF_0) #define PROTOCCALLSFFUN13(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD) \ PROTOCCALLSFFUN14(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,CF_0) /* HP/UX 9.01 cc requires the blank between '_Icf(3,G,T0,UN,LN) CCCF(T1,1,0)' */ #ifndef __CF__KnR #define PROTOCCALLSFFUN14(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \ _(T0,_cfPU)(CFC_(UN,LN))(CF_NULL_PROTO); static _Icf(2,U,T0,CFFUN(UN),0)( \ CFARGT14FS(UCF,HCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) ) \ { CFARGT14S(VCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) _(T0,_cfE) \ CCF(LN,T1,1) CCF(LN,T2,2) CCF(LN,T3,3) CCF(LN,T4,4) CCF(LN,T5,5) \ CCF(LN,T6,6) CCF(LN,T7,7) CCF(LN,T8,8) CCF(LN,T9,9) CCF(LN,TA,10) \ CCF(LN,TB,11) CCF(LN,TC,12) CCF(LN,TD,13) CCF(LN,TE,14) _Icf(3,G,T0,UN,LN) \ CFARGT14(CCCF,JCF,ABSOFT_cf1(T0),T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)); \ WCF(T1,A1,1) WCF(T2,A2,2) WCF(T3,A3,3) WCF(T4,A4,4) WCF(T5,A5,5) \ WCF(T6,A6,6) WCF(T7,A7,7) WCF(T8,A8,8) WCF(T9,A9,9) WCF(TA,A10,10) \ WCF(TB,A11,11) WCF(TC,A12,12) WCF(TD,A13,13) WCF(TE,A14,14) _(T0,_cfX)} #else #define PROTOCCALLSFFUN14(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \ _(T0,_cfPU)(CFC_(UN,LN))(CF_NULL_PROTO); static _Icf(2,U,T0,CFFUN(UN),0)( \ CFARGT14FS(UUCF,HHCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) ) \ CFARGT14FS(UUUCF,HHHCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) ; \ { CFARGT14S(VCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) _(T0,_cfE) \ CCF(LN,T1,1) CCF(LN,T2,2) CCF(LN,T3,3) CCF(LN,T4,4) CCF(LN,T5,5) \ CCF(LN,T6,6) CCF(LN,T7,7) CCF(LN,T8,8) CCF(LN,T9,9) CCF(LN,TA,10) \ CCF(LN,TB,11) CCF(LN,TC,12) CCF(LN,TD,13) CCF(LN,TE,14) _Icf(3,G,T0,UN,LN) \ CFARGT14(CCCF,JCF,ABSOFT_cf1(T0),T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)); \ WCF(T1,A1,1) WCF(T2,A2,2) WCF(T3,A3,3) WCF(T4,A4,4) WCF(T5,A5,5) \ WCF(T6,A6,6) WCF(T7,A7,7) WCF(T8,A8,8) WCF(T9,A9,9) WCF(TA,A10,10) \ WCF(TB,A11,11) WCF(TC,A12,12) WCF(TD,A13,13) WCF(TE,A14,14) _(T0,_cfX)} #endif /*-------------------------------------------------------------------------*/ /* UTILITIES FOR FORTRAN TO CALL C ROUTINES */ #ifdef OLD_VAXC /* Prevent %CC-I-PARAMNOTUSED. */ #pragma nostandard #endif #if defined(vmsFortran) || defined(CRAYFortran) #define DCF(TN,I) #define DDCF(TN,I) #define DDDCF(TN,I) #else #define DCF(TN,I) HCF(TN,I) #define DDCF(TN,I) HHCF(TN,I) #define DDDCF(TN,I) HHHCF(TN,I) #endif #define QCF(TN,I) _(TN,_cfSTR)(1,Q,_(B,I), 0,0,0,0) #define DEFAULT_cfQ(B) #define LOGICAL_cfQ(B) #define PLOGICAL_cfQ(B) #define STRINGV_cfQ(B) char *B; unsigned int _(B,N); #define STRING_cfQ(B) char *B=NULL; #define PSTRING_cfQ(B) char *B=NULL; #define PSTRINGV_cfQ(B) STRINGV_cfQ(B) #define PNSTRING_cfQ(B) char *B=NULL; #define PPSTRING_cfQ(B) #ifdef __sgi /* Else SGI gives warning 182 contrary to its C LRM A.17.7 */ #define ROUTINE_orig *(void**)& #else #define ROUTINE_orig (void *) #endif #define ROUTINE_1 ROUTINE_orig #define ROUTINE_2 ROUTINE_orig #define ROUTINE_3 ROUTINE_orig #define ROUTINE_4 ROUTINE_orig #define ROUTINE_5 ROUTINE_orig #define ROUTINE_6 ROUTINE_orig #define ROUTINE_7 ROUTINE_orig #define ROUTINE_8 ROUTINE_orig #define ROUTINE_9 ROUTINE_orig #define ROUTINE_10 ROUTINE_orig #define ROUTINE_11 ROUTINE_orig #define ROUTINE_12 ROUTINE_orig #define ROUTINE_13 ROUTINE_orig #define ROUTINE_14 ROUTINE_orig #define ROUTINE_15 ROUTINE_orig #define ROUTINE_16 ROUTINE_orig #define ROUTINE_17 ROUTINE_orig #define ROUTINE_18 ROUTINE_orig #define ROUTINE_19 ROUTINE_orig #define ROUTINE_20 ROUTINE_orig #define ROUTINE_21 ROUTINE_orig #define ROUTINE_22 ROUTINE_orig #define ROUTINE_23 ROUTINE_orig #define ROUTINE_24 ROUTINE_orig #define ROUTINE_25 ROUTINE_orig #define ROUTINE_26 ROUTINE_orig #define ROUTINE_27 ROUTINE_orig #define TCF(NAME,TN,I,M) _SEP_(TN,M,cfCOMMA) _(TN,_cfT)(NAME,I,_(A,I),_(B,I),_(C,I)) #define BYTE_cfT(M,I,A,B,D) *A #define DOUBLE_cfT(M,I,A,B,D) *A #define FLOAT_cfT(M,I,A,B,D) *A #define INT_cfT(M,I,A,B,D) *A #define LOGICAL_cfT(M,I,A,B,D) F2CLOGICAL(*A) #define LONG_cfT(M,I,A,B,D) *A #define LONGLONG_cfT(M,I,A,B,D) *A /* added by MR December 2005 */ #define SHORT_cfT(M,I,A,B,D) *A #define BYTEV_cfT(M,I,A,B,D) A #define DOUBLEV_cfT(M,I,A,B,D) A #define FLOATV_cfT(M,I,A,B,D) VOIDP A #define INTV_cfT(M,I,A,B,D) A #define LOGICALV_cfT(M,I,A,B,D) A #define LONGV_cfT(M,I,A,B,D) A #define LONGLONGV_cfT(M,I,A,B,D) A /* added by MR December 2005 */ #define SHORTV_cfT(M,I,A,B,D) A #define BYTEVV_cfT(M,I,A,B,D) (void *)A /* We have to cast to void *,*/ #define BYTEVVV_cfT(M,I,A,B,D) (void *)A /* since we don't know the */ #define BYTEVVVV_cfT(M,I,A,B,D) (void *)A /* dimensions of the array. */ #define BYTEVVVVV_cfT(M,I,A,B,D) (void *)A /* i.e. Unfortunately, can't */ #define BYTEVVVVVV_cfT(M,I,A,B,D) (void *)A /* check that the type */ #define BYTEVVVVVVV_cfT(M,I,A,B,D) (void *)A /* matches the prototype. */ #define DOUBLEVV_cfT(M,I,A,B,D) (void *)A #define DOUBLEVVV_cfT(M,I,A,B,D) (void *)A #define DOUBLEVVVV_cfT(M,I,A,B,D) (void *)A #define DOUBLEVVVVV_cfT(M,I,A,B,D) (void *)A #define DOUBLEVVVVVV_cfT(M,I,A,B,D) (void *)A #define DOUBLEVVVVVVV_cfT(M,I,A,B,D) (void *)A #define FLOATVV_cfT(M,I,A,B,D) (void *)A #define FLOATVVV_cfT(M,I,A,B,D) (void *)A #define FLOATVVVV_cfT(M,I,A,B,D) (void *)A #define FLOATVVVVV_cfT(M,I,A,B,D) (void *)A #define FLOATVVVVVV_cfT(M,I,A,B,D) (void *)A #define FLOATVVVVVVV_cfT(M,I,A,B,D) (void *)A #define INTVV_cfT(M,I,A,B,D) (void *)A #define INTVVV_cfT(M,I,A,B,D) (void *)A #define INTVVVV_cfT(M,I,A,B,D) (void *)A #define INTVVVVV_cfT(M,I,A,B,D) (void *)A #define INTVVVVVV_cfT(M,I,A,B,D) (void *)A #define INTVVVVVVV_cfT(M,I,A,B,D) (void *)A #define LOGICALVV_cfT(M,I,A,B,D) (void *)A #define LOGICALVVV_cfT(M,I,A,B,D) (void *)A #define LOGICALVVVV_cfT(M,I,A,B,D) (void *)A #define LOGICALVVVVV_cfT(M,I,A,B,D) (void *)A #define LOGICALVVVVVV_cfT(M,I,A,B,D) (void *)A #define LOGICALVVVVVVV_cfT(M,I,A,B,D) (void *)A #define LONGVV_cfT(M,I,A,B,D) (void *)A #define LONGVVV_cfT(M,I,A,B,D) (void *)A #define LONGVVVV_cfT(M,I,A,B,D) (void *)A #define LONGVVVVV_cfT(M,I,A,B,D) (void *)A #define LONGVVVVVV_cfT(M,I,A,B,D) (void *)A #define LONGVVVVVVV_cfT(M,I,A,B,D) (void *)A #define LONGLONGVV_cfT(M,I,A,B,D) (void *)A /* added by MR December 2005 */ #define LONGLONGVVV_cfT(M,I,A,B,D) (void *)A /* added by MR December 2005 */ #define LONGLONGVVVV_cfT(M,I,A,B,D) (void *)A /* added by MR December 2005 */ #define LONGLONGVVVVV_cfT(M,I,A,B,D) (void *)A /* added by MR December 2005 */ #define LONGLONGVVVVVV_cfT(M,I,A,B,D) (void *)A /* added by MR December 2005 */ #define LONGLONGVVVVVVV_cfT(M,I,A,B,D) (void *)A /* added by MR December 2005 */ #define SHORTVV_cfT(M,I,A,B,D) (void *)A #define SHORTVVV_cfT(M,I,A,B,D) (void *)A #define SHORTVVVV_cfT(M,I,A,B,D) (void *)A #define SHORTVVVVV_cfT(M,I,A,B,D) (void *)A #define SHORTVVVVVV_cfT(M,I,A,B,D) (void *)A #define SHORTVVVVVVV_cfT(M,I,A,B,D) (void *)A #define PBYTE_cfT(M,I,A,B,D) A #define PDOUBLE_cfT(M,I,A,B,D) A #define PFLOAT_cfT(M,I,A,B,D) VOIDP A #define PINT_cfT(M,I,A,B,D) A #define PLOGICAL_cfT(M,I,A,B,D) ((*A=F2CLOGICAL(*A)),A) #define PLONG_cfT(M,I,A,B,D) A #define PLONGLONG_cfT(M,I,A,B,D) A /* added by MR December 2005 */ #define PSHORT_cfT(M,I,A,B,D) A #define PVOID_cfT(M,I,A,B,D) A #if defined(apolloFortran) || defined(hpuxFortran800) || defined(AbsoftUNIXFortran) #define ROUTINE_cfT(M,I,A,B,D) _(ROUTINE_,I) (*A) #else #define ROUTINE_cfT(M,I,A,B,D) _(ROUTINE_,I) A #endif /* A == pointer to the characters D == length of the string, or of an element in an array of strings E == number of elements in an array of strings */ #define TTSTR( A,B,D) \ ((B=_cf_malloc(D+1))[D]='\0', memcpy(B,A,D), kill_trailing(B,' ')) #define TTTTSTR( A,B,D) (!(D<4||A[0]||A[1]||A[2]||A[3]))?NULL: \ memchr(A,'\0',D) ?A : TTSTR(A,B,D) #define TTTTSTRV( A,B,D,E) (_(B,N)=E,B=_cf_malloc(_(B,N)*(D+1)), (void *) \ vkill_trailing(f2cstrv(A,B,D+1, _(B,N)*(D+1)), D+1,_(B,N)*(D+1),' ')) #ifdef vmsFortran #define STRING_cfT(M,I,A,B,D) TTTTSTR( A->dsc$a_pointer,B,A->dsc$w_length) #define STRINGV_cfT(M,I,A,B,D) TTTTSTRV(A->dsc$a_pointer, B, \ A->dsc$w_length , A->dsc$l_m[0]) #define PSTRING_cfT(M,I,A,B,D) TTSTR( A->dsc$a_pointer,B,A->dsc$w_length) #define PPSTRING_cfT(M,I,A,B,D) A->dsc$a_pointer #else #ifdef CRAYFortran #define STRING_cfT(M,I,A,B,D) TTTTSTR( _fcdtocp(A),B,_fcdlen(A)) #define STRINGV_cfT(M,I,A,B,D) TTTTSTRV(_fcdtocp(A),B,_fcdlen(A), \ num_elem(_fcdtocp(A),_fcdlen(A),_3(M,_STRV_A,I))) #define PSTRING_cfT(M,I,A,B,D) TTSTR( _fcdtocp(A),B,_fcdlen(A)) #define PPSTRING_cfT(M,I,A,B,D) _fcdtocp(A) #else #define STRING_cfT(M,I,A,B,D) TTTTSTR( A,B,D) #define STRINGV_cfT(M,I,A,B,D) TTTTSTRV(A,B,D, num_elem(A,D,_3(M,_STRV_A,I))) #define PSTRING_cfT(M,I,A,B,D) TTSTR( A,B,D) #define PPSTRING_cfT(M,I,A,B,D) A #endif #endif #define PNSTRING_cfT(M,I,A,B,D) STRING_cfT(M,I,A,B,D) #define PSTRINGV_cfT(M,I,A,B,D) STRINGV_cfT(M,I,A,B,D) #define CF_0_cfT(M,I,A,B,D) #define RCF(TN,I) _(TN,_cfSTR)(3,R,_(A,I),_(B,I),_(C,I),0,0) #define DEFAULT_cfR(A,B,D) #define LOGICAL_cfR(A,B,D) #define PLOGICAL_cfR(A,B,D) *A=C2FLOGICAL(*A); #define STRING_cfR(A,B,D) if (B) _cf_free(B); #define STRINGV_cfR(A,B,D) _cf_free(B); /* A and D as defined above for TSTRING(V) */ #define RRRRPSTR( A,B,D) if (B) memcpy(A,B, _cfMIN(strlen(B),D)), \ (D>strlen(B)?memset(A+strlen(B),' ', D-strlen(B)):0), _cf_free(B); #define RRRRPSTRV(A,B,D) c2fstrv(B,A,D+1,(D+1)*_(B,N)), _cf_free(B); #ifdef vmsFortran #define PSTRING_cfR(A,B,D) RRRRPSTR( A->dsc$a_pointer,B,A->dsc$w_length) #define PSTRINGV_cfR(A,B,D) RRRRPSTRV(A->dsc$a_pointer,B,A->dsc$w_length) #else #ifdef CRAYFortran #define PSTRING_cfR(A,B,D) RRRRPSTR( _fcdtocp(A),B,_fcdlen(A)) #define PSTRINGV_cfR(A,B,D) RRRRPSTRV(_fcdtocp(A),B,_fcdlen(A)) #else #define PSTRING_cfR(A,B,D) RRRRPSTR( A,B,D) #define PSTRINGV_cfR(A,B,D) RRRRPSTRV(A,B,D) #endif #endif #define PNSTRING_cfR(A,B,D) PSTRING_cfR(A,B,D) #define PPSTRING_cfR(A,B,D) #define BYTE_cfFZ(UN,LN) INTEGER_BYTE FCALLSC_QUALIFIER fcallsc(UN,LN)( #define DOUBLE_cfFZ(UN,LN) DOUBLE_PRECISION FCALLSC_QUALIFIER fcallsc(UN,LN)( #define INT_cfFZ(UN,LN) int FCALLSC_QUALIFIER fcallsc(UN,LN)( #define LOGICAL_cfFZ(UN,LN) int FCALLSC_QUALIFIER fcallsc(UN,LN)( #define LONG_cfFZ(UN,LN) long FCALLSC_QUALIFIER fcallsc(UN,LN)( #define LONGLONG_cfFZ(UN,LN) LONGLONG FCALLSC_QUALIFIER fcallsc(UN,LN)( /* added by MR December 2005 */ #define SHORT_cfFZ(UN,LN) short FCALLSC_QUALIFIER fcallsc(UN,LN)( #define VOID_cfFZ(UN,LN) void FCALLSC_QUALIFIER fcallsc(UN,LN)( #ifndef __CF__KnR /* The void is req'd by the Apollo, to make this an ANSI function declaration. The Apollo promotes K&R float functions to double. */ #if defined (f2cFortran) && ! defined (gFortran) /* f2c/g77 return double from FORTRAN REAL functions. (KMCCARTY, 2005/12/09) */ #define FLOAT_cfFZ(UN,LN) DOUBLE_PRECISION FCALLSC_QUALIFIER fcallsc(UN,LN)(void #else #define FLOAT_cfFZ(UN,LN) FORTRAN_REAL FCALLSC_QUALIFIER fcallsc(UN,LN)(void #endif #ifdef vmsFortran #define STRING_cfFZ(UN,LN) void FCALLSC_QUALIFIER fcallsc(UN,LN)(fstring *AS #else #ifdef CRAYFortran #define STRING_cfFZ(UN,LN) void FCALLSC_QUALIFIER fcallsc(UN,LN)(_fcd AS #else #if defined(AbsoftUNIXFortran) || defined(AbsoftProFortran) #define STRING_cfFZ(UN,LN) void FCALLSC_QUALIFIER fcallsc(UN,LN)(char *AS #else #define STRING_cfFZ(UN,LN) void FCALLSC_QUALIFIER fcallsc(UN,LN)(char *AS, unsigned D0 #endif #endif #endif #else #if ! (defined(FLOATFUNCTIONTYPE)&&defined(ASSIGNFLOAT)&&defined(RETURNFLOAT)) #if defined (f2cFortran) && ! defined (gFortran) /* f2c/g77 return double from FORTRAN REAL functions. (KMCCARTY, 2005/12/09) */ #define FLOAT_cfFZ(UN,LN) DOUBLE_PRECISION FCALLSC_QUALIFIER fcallsc(UN,LN)( #else #define FLOAT_cfFZ(UN,LN) FORTRAN_REAL FCALLSC_QUALIFIER fcallsc(UN,LN)( #endif #else #define FLOAT_cfFZ(UN,LN) FLOATFUNCTIONTYPE FCALLSC_QUALIFIER fcallsc(UN,LN)( #endif #if defined(vmsFortran) || defined(CRAYFortran) || defined(AbsoftUNIXFortran) #define STRING_cfFZ(UN,LN) void FCALLSC_QUALIFIER fcallsc(UN,LN)(AS #else #define STRING_cfFZ(UN,LN) void FCALLSC_QUALIFIER fcallsc(UN,LN)(AS, D0 #endif #endif #define BYTE_cfF(UN,LN) BYTE_cfFZ(UN,LN) #define DOUBLE_cfF(UN,LN) DOUBLE_cfFZ(UN,LN) #ifndef __CF_KnR #if defined (f2cFortran) && ! defined (gFortran) /* f2c/g77 return double from FORTRAN REAL functions. (KMCCARTY, 2005/12/09) */ #define FLOAT_cfF(UN,LN) DOUBLE_PRECISION FCALLSC_QUALIFIER fcallsc(UN,LN)( #else #define FLOAT_cfF(UN,LN) FORTRAN_REAL FCALLSC_QUALIFIER fcallsc(UN,LN)( #endif #else #define FLOAT_cfF(UN,LN) FLOAT_cfFZ(UN,LN) #endif #define INT_cfF(UN,LN) INT_cfFZ(UN,LN) #define LOGICAL_cfF(UN,LN) LOGICAL_cfFZ(UN,LN) #define LONG_cfF(UN,LN) LONG_cfFZ(UN,LN) #define LONGLONG_cfF(UN,LN) LONGLONG_cfFZ(UN,LN) /* added by MR December 2005 */ #define SHORT_cfF(UN,LN) SHORT_cfFZ(UN,LN) #define VOID_cfF(UN,LN) VOID_cfFZ(UN,LN) #define STRING_cfF(UN,LN) STRING_cfFZ(UN,LN), #define INT_cfFF #define VOID_cfFF #ifdef vmsFortran #define STRING_cfFF fstring *AS; #else #ifdef CRAYFortran #define STRING_cfFF _fcd AS; #else #define STRING_cfFF char *AS; unsigned D0; #endif #endif #define INT_cfL A0= #define STRING_cfL A0= #define VOID_cfL #define INT_cfK #define VOID_cfK /* KSTRING copies the string into the position provided by the caller. */ #ifdef vmsFortran #define STRING_cfK \ memcpy(AS->dsc$a_pointer,A0,_cfMIN(AS->dsc$w_length,(A0==NULL?0:strlen(A0))));\ AS->dsc$w_length>(A0==NULL?0:strlen(A0))? \ memset(AS->dsc$a_pointer+(A0==NULL?0:strlen(A0)),' ', \ AS->dsc$w_length-(A0==NULL?0:strlen(A0))):0; #else #ifdef CRAYFortran #define STRING_cfK \ memcpy(_fcdtocp(AS),A0, _cfMIN(_fcdlen(AS),(A0==NULL?0:strlen(A0))) ); \ _fcdlen(AS)>(A0==NULL?0:strlen(A0))? \ memset(_fcdtocp(AS)+(A0==NULL?0:strlen(A0)),' ', \ _fcdlen(AS)-(A0==NULL?0:strlen(A0))):0; #else #define STRING_cfK memcpy(AS,A0, _cfMIN(D0,(A0==NULL?0:strlen(A0))) ); \ D0>(A0==NULL?0:strlen(A0))?memset(AS+(A0==NULL?0:strlen(A0)), \ ' ', D0-(A0==NULL?0:strlen(A0))):0; #endif #endif /* Note that K.. and I.. can't be combined since K.. has to access data before R.., in order for functions returning strings which are also passed in as arguments to work correctly. Note that R.. frees and hence may corrupt the string. */ #define BYTE_cfI return A0; #define DOUBLE_cfI return A0; #if ! (defined(FLOATFUNCTIONTYPE)&&defined(ASSIGNFLOAT)&&defined(RETURNFLOAT)) #define FLOAT_cfI return A0; #else #define FLOAT_cfI RETURNFLOAT(A0); #endif #define INT_cfI return A0; #ifdef hpuxFortran800 /* Incredibly, functions must return true as 1, elsewhere .true.==0x01000000. */ #define LOGICAL_cfI return ((A0)?1:0); #else #define LOGICAL_cfI return C2FLOGICAL(A0); #endif #define LONG_cfI return A0; #define LONGLONG_cfI return A0; /* added by MR December 2005 */ #define SHORT_cfI return A0; #define STRING_cfI return ; #define VOID_cfI return ; #ifdef OLD_VAXC /* Allow %CC-I-PARAMNOTUSED. */ #pragma standard #endif #define FCALLSCSUB0( CN,UN,LN) FCALLSCFUN0(VOID,CN,UN,LN) #define FCALLSCSUB1( CN,UN,LN,T1) FCALLSCFUN1(VOID,CN,UN,LN,T1) #define FCALLSCSUB2( CN,UN,LN,T1,T2) FCALLSCFUN2(VOID,CN,UN,LN,T1,T2) #define FCALLSCSUB3( CN,UN,LN,T1,T2,T3) FCALLSCFUN3(VOID,CN,UN,LN,T1,T2,T3) #define FCALLSCSUB4( CN,UN,LN,T1,T2,T3,T4) \ FCALLSCFUN4(VOID,CN,UN,LN,T1,T2,T3,T4) #define FCALLSCSUB5( CN,UN,LN,T1,T2,T3,T4,T5) \ FCALLSCFUN5(VOID,CN,UN,LN,T1,T2,T3,T4,T5) #define FCALLSCSUB6( CN,UN,LN,T1,T2,T3,T4,T5,T6) \ FCALLSCFUN6(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6) #define FCALLSCSUB7( CN,UN,LN,T1,T2,T3,T4,T5,T6,T7) \ FCALLSCFUN7(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7) #define FCALLSCSUB8( CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8) \ FCALLSCFUN8(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8) #define FCALLSCSUB9( CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9) \ FCALLSCFUN9(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9) #define FCALLSCSUB10(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA) \ FCALLSCFUN10(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA) #define FCALLSCSUB11(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB) \ FCALLSCFUN11(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB) #define FCALLSCSUB12(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC) \ FCALLSCFUN12(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC) #define FCALLSCSUB13(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD) \ FCALLSCFUN13(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD) #define FCALLSCSUB14(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \ FCALLSCFUN14(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) #define FCALLSCSUB15(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF) \ FCALLSCFUN15(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF) #define FCALLSCSUB16(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG) \ FCALLSCFUN16(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG) #define FCALLSCSUB17(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH) \ FCALLSCFUN17(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH) #define FCALLSCSUB18(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI) \ FCALLSCFUN18(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI) #define FCALLSCSUB19(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ) \ FCALLSCFUN19(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ) #define FCALLSCSUB20(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) \ FCALLSCFUN20(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) #define FCALLSCSUB21(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL) \ FCALLSCFUN21(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL) #define FCALLSCSUB22(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM) \ FCALLSCFUN22(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM) #define FCALLSCSUB23(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN) \ FCALLSCFUN23(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN) #define FCALLSCSUB24(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO) \ FCALLSCFUN24(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO) #define FCALLSCSUB25(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP) \ FCALLSCFUN25(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP) #define FCALLSCSUB26(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ) \ FCALLSCFUN26(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ) #define FCALLSCSUB27(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \ FCALLSCFUN27(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) #define FCALLSCFUN1( T0,CN,UN,LN,T1) \ FCALLSCFUN5 (T0,CN,UN,LN,T1,CF_0,CF_0,CF_0,CF_0) #define FCALLSCFUN2( T0,CN,UN,LN,T1,T2) \ FCALLSCFUN5 (T0,CN,UN,LN,T1,T2,CF_0,CF_0,CF_0) #define FCALLSCFUN3( T0,CN,UN,LN,T1,T2,T3) \ FCALLSCFUN5 (T0,CN,UN,LN,T1,T2,T3,CF_0,CF_0) #define FCALLSCFUN4( T0,CN,UN,LN,T1,T2,T3,T4) \ FCALLSCFUN5 (T0,CN,UN,LN,T1,T2,T3,T4,CF_0) #define FCALLSCFUN5( T0,CN,UN,LN,T1,T2,T3,T4,T5) \ FCALLSCFUN10(T0,CN,UN,LN,T1,T2,T3,T4,T5,CF_0,CF_0,CF_0,CF_0,CF_0) #define FCALLSCFUN6( T0,CN,UN,LN,T1,T2,T3,T4,T5,T6) \ FCALLSCFUN10(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,CF_0,CF_0,CF_0,CF_0) #define FCALLSCFUN7( T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7) \ FCALLSCFUN10(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,CF_0,CF_0,CF_0) #define FCALLSCFUN8( T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8) \ FCALLSCFUN10(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,CF_0,CF_0) #define FCALLSCFUN9( T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9) \ FCALLSCFUN10(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,CF_0) #define FCALLSCFUN10(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA) \ FCALLSCFUN14(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,CF_0,CF_0,CF_0,CF_0) #define FCALLSCFUN11(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB) \ FCALLSCFUN14(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,CF_0,CF_0,CF_0) #define FCALLSCFUN12(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC) \ FCALLSCFUN14(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,CF_0,CF_0) #define FCALLSCFUN13(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD) \ FCALLSCFUN14(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,CF_0) #define FCALLSCFUN15(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF) \ FCALLSCFUN20(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,CF_0,CF_0,CF_0,CF_0,CF_0) #define FCALLSCFUN16(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG) \ FCALLSCFUN20(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,CF_0,CF_0,CF_0,CF_0) #define FCALLSCFUN17(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH) \ FCALLSCFUN20(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,CF_0,CF_0,CF_0) #define FCALLSCFUN18(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI) \ FCALLSCFUN20(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,CF_0,CF_0) #define FCALLSCFUN19(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ) \ FCALLSCFUN20(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,CF_0) #define FCALLSCFUN20(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) \ FCALLSCFUN27(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0) #define FCALLSCFUN21(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL) \ FCALLSCFUN27(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0) #define FCALLSCFUN22(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM) \ FCALLSCFUN27(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,CF_0,CF_0,CF_0,CF_0,CF_0) #define FCALLSCFUN23(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN) \ FCALLSCFUN27(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,CF_0,CF_0,CF_0,CF_0) #define FCALLSCFUN24(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO) \ FCALLSCFUN27(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,CF_0,CF_0,CF_0) #define FCALLSCFUN25(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP) \ FCALLSCFUN27(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,CF_0,CF_0) #define FCALLSCFUN26(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ) \ FCALLSCFUN27(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,CF_0) #ifndef __CF__KnR #define FCALLSCFUN0(T0,CN,UN,LN) CFextern _(T0,_cfFZ)(UN,LN) ABSOFT_cf2(T0)) \ {_Icf(2,UU,T0,A0,0); _Icf(0,L,T0,0,0) CN(); _Icf(0,K,T0,0,0) _(T0,_cfI)} #define FCALLSCFUN14(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \ CFextern _(T0,_cfF)(UN,LN) \ CFARGT14(NCF,DCF,ABSOFT_cf2(T0),T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) ) \ { CFARGT14S(QCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \ _Icf(2,UU,T0,A0,0); _Icf(0,L,T0,0,0) CN( TCF(LN,T1,1,0) TCF(LN,T2,2,1) \ TCF(LN,T3,3,1) TCF(LN,T4,4,1) TCF(LN,T5,5,1) TCF(LN,T6,6,1) TCF(LN,T7,7,1) \ TCF(LN,T8,8,1) TCF(LN,T9,9,1) TCF(LN,TA,10,1) TCF(LN,TB,11,1) TCF(LN,TC,12,1) \ TCF(LN,TD,13,1) TCF(LN,TE,14,1) ); _Icf(0,K,T0,0,0) \ CFARGT14S(RCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) _(T0,_cfI) } #define FCALLSCFUN27(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \ CFextern _(T0,_cfF)(UN,LN) \ CFARGT27(NCF,DCF,ABSOFT_cf2(T0),T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) ) \ { CFARGT27S(QCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \ _Icf(2,UU,T0,A0,0); _Icf(0,L,T0,0,0) CN( TCF(LN,T1,1,0) TCF(LN,T2,2,1) \ TCF(LN,T3,3,1) TCF(LN,T4,4,1) TCF(LN,T5,5,1) TCF(LN,T6,6,1) TCF(LN,T7,7,1) \ TCF(LN,T8,8,1) TCF(LN,T9,9,1) TCF(LN,TA,10,1) TCF(LN,TB,11,1) TCF(LN,TC,12,1) \ TCF(LN,TD,13,1) TCF(LN,TE,14,1) TCF(LN,TF,15,1) TCF(LN,TG,16,1) TCF(LN,TH,17,1) \ TCF(LN,TI,18,1) TCF(LN,TJ,19,1) TCF(LN,TK,20,1) TCF(LN,TL,21,1) TCF(LN,TM,22,1) \ TCF(LN,TN,23,1) TCF(LN,TO,24,1) TCF(LN,TP,25,1) TCF(LN,TQ,26,1) TCF(LN,TR,27,1) ); _Icf(0,K,T0,0,0) \ CFARGT27S(RCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) _(T0,_cfI) } #else #define FCALLSCFUN0(T0,CN,UN,LN) CFextern _(T0,_cfFZ)(UN,LN) ABSOFT_cf3(T0)) _Icf(0,FF,T0,0,0)\ {_Icf(2,UU,T0,A0,0); _Icf(0,L,T0,0,0) CN(); _Icf(0,K,T0,0,0) _(T0,_cfI)} #define FCALLSCFUN14(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \ CFextern _(T0,_cfF)(UN,LN) \ CFARGT14(NNCF,DDCF,ABSOFT_cf3(T0),T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)) _Icf(0,FF,T0,0,0) \ CFARGT14FS(NNNCF,DDDCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE); \ { CFARGT14S(QCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \ _Icf(2,UU,T0,A0,0); _Icf(0,L,T0,0,0) CN( TCF(LN,T1,1,0) TCF(LN,T2,2,1) \ TCF(LN,T3,3,1) TCF(LN,T4,4,1) TCF(LN,T5,5,1) TCF(LN,T6,6,1) TCF(LN,T7,7,1) \ TCF(LN,T8,8,1) TCF(LN,T9,9,1) TCF(LN,TA,10,1) TCF(LN,TB,11,1) TCF(LN,TC,12,1) \ TCF(LN,TD,13,1) TCF(LN,TE,14,1) ); _Icf(0,K,T0,0,0) \ CFARGT14S(RCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) _(T0,_cfI)} #define FCALLSCFUN27(T0,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \ CFextern _(T0,_cfF)(UN,LN) \ CFARGT27(NNCF,DDCF,ABSOFT_cf3(T0),T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR)) _Icf(0,FF,T0,0,0) \ CFARGT27FS(NNNCF,DDDCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR); \ { CFARGT27S(QCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \ _Icf(2,UU,T0,A0,0); _Icf(0,L,T0,0,0) CN( TCF(LN,T1,1,0) TCF(LN,T2,2,1) \ TCF(LN,T3,3,1) TCF(LN,T4,4,1) TCF(LN,T5,5,1) TCF(LN,T6,6,1) TCF(LN,T7,7,1) \ TCF(LN,T8,8,1) TCF(LN,T9,9,1) TCF(LN,TA,10,1) TCF(LN,TB,11,1) TCF(LN,TC,12,1) \ TCF(LN,TD,13,1) TCF(LN,TE,14,1) TCF(LN,TF,15,1) TCF(LN,TG,16,1) TCF(LN,TH,17,1) \ TCF(LN,TI,18,1) TCF(LN,TJ,19,1) TCF(LN,TK,20,1) TCF(LN,TL,21,1) TCF(LN,TM,22,1) \ TCF(LN,TN,23,1) TCF(LN,TO,24,1) TCF(LN,TP,25,1) TCF(LN,TQ,26,1) TCF(LN,TR,27,1) ); _Icf(0,K,T0,0,0) \ CFARGT27S(RCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) _(T0,_cfI)} #endif #endif /* __CFORTRAN_LOADED */ skycat-3.1.2-starlink-1b/astrotcl/cfitsio/checksum.c000066400000000000000000000422641215713201500224060ustar00rootroot00000000000000/* This file, checksum.c, contains the checksum-related routines in the */ /* FITSIO library. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" /*------------------------------------------------------------------------*/ int ffcsum(fitsfile *fptr, /* I - FITS file pointer */ long nrec, /* I - number of 2880-byte blocks to sum */ unsigned long *sum, /* IO - accumulated checksum */ int *status) /* IO - error status */ /* Calculate a 32-bit 1's complement checksum of the FITS 2880-byte blocks. This routine is based on the C algorithm developed by Rob Seaman at NOAO that was presented at the 1994 ADASS conference, published in the Astronomical Society of the Pacific Conference Series. This uses a 32-bit 1's complement checksum in which the overflow bits are permuted back into the sum and therefore all bit positions are sampled evenly. */ { long ii, jj; unsigned short sbuf[1440]; unsigned long hi, lo, hicarry, locarry; if (*status > 0) return(*status); /* Sum the specified number of FITS 2880-byte records. This assumes that the FITSIO file pointer points to the start of the records to be summed. Read each FITS block as 1440 short values (do byte swapping if needed). */ for (jj = 0; jj < nrec; jj++) { ffgbyt(fptr, 2880, sbuf, status); #if BYTESWAPPED ffswap2( (short *)sbuf, 1440); /* reverse order of bytes in each value */ #endif hi = (*sum >> 16); lo = *sum & 0xFFFF; for (ii = 0; ii < 1440; ii += 2) { hi += sbuf[ii]; lo += sbuf[ii+1]; } hicarry = hi >> 16; /* fold carry bits in */ locarry = lo >> 16; while (hicarry | locarry) { hi = (hi & 0xFFFF) + locarry; lo = (lo & 0xFFFF) + hicarry; hicarry = hi >> 16; locarry = lo >> 16; } *sum = (hi << 16) + lo; } return(*status); } /*-------------------------------------------------------------------------*/ void ffesum(unsigned long sum, /* I - accumulated checksum */ int complm, /* I - = 1 to encode complement of the sum */ char *ascii) /* O - 16-char ASCII encoded checksum */ /* encode the 32 bit checksum by converting every 2 bits of each byte into an ASCII character (32 bit word encoded as 16 character string). Only ASCII letters and digits are used to encode the values (no ASCII punctuation characters). If complm=TRUE, then the complement of the sum will be encoded. This routine is based on the C algorithm developed by Rob Seaman at NOAO that was presented at the 1994 ADASS conference, published in the Astronomical Society of the Pacific Conference Series. */ { unsigned int exclude[13] = { 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60 }; unsigned long mask[4] = { 0xff000000, 0xff0000, 0xff00, 0xff }; int offset = 0x30; /* ASCII 0 (zero) */ unsigned long value; int byte, quotient, remainder, ch[4], check, ii, jj, kk; char asc[32]; if (complm) value = 0xFFFFFFFF - sum; /* complement each bit of the value */ else value = sum; for (ii = 0; ii < 4; ii++) { byte = (value & mask[ii]) >> (24 - (8 * ii)); quotient = byte / 4 + offset; remainder = byte % 4; for (jj = 0; jj < 4; jj++) ch[jj] = quotient; ch[0] += remainder; for (check = 1; check;) /* avoid ASCII punctuation */ for (check = 0, kk = 0; kk < 13; kk++) for (jj = 0; jj < 4; jj += 2) if ((unsigned char) ch[jj] == exclude[kk] || (unsigned char) ch[jj+1] == exclude[kk]) { ch[jj]++; ch[jj+1]--; check++; } for (jj = 0; jj < 4; jj++) /* assign the bytes */ asc[4*jj+ii] = ch[jj]; } for (ii = 0; ii < 16; ii++) /* shift the bytes 1 to the right */ ascii[ii] = asc[(ii+15)%16]; ascii[16] = '\0'; } /*-------------------------------------------------------------------------*/ unsigned long ffdsum(char *ascii, /* I - 16-char ASCII encoded checksum */ int complm, /* I - =1 to decode complement of the */ unsigned long *sum) /* O - 32-bit checksum */ /* decode the 16-char ASCII encoded checksum into an unsigned 32-bit long. If complm=TRUE, then the complement of the sum will be decoded. This routine is based on the C algorithm developed by Rob Seaman at NOAO that was presented at the 1994 ADASS conference, published in the Astronomical Society of the Pacific Conference Series. */ { char cbuf[16]; unsigned long hi = 0, lo = 0, hicarry, locarry; int ii; /* remove the permuted FITS byte alignment and the ASCII 0 offset */ for (ii = 0; ii < 16; ii++) { cbuf[ii] = ascii[(ii+1)%16]; cbuf[ii] -= 0x30; } for (ii = 0; ii < 16; ii += 4) { hi += (cbuf[ii] << 8) + cbuf[ii+1]; lo += (cbuf[ii+2] << 8) + cbuf[ii+3]; } hicarry = hi >> 16; locarry = lo >> 16; while (hicarry || locarry) { hi = (hi & 0xFFFF) + locarry; lo = (lo & 0xFFFF) + hicarry; hicarry = hi >> 16; locarry = lo >> 16; } *sum = (hi << 16) + lo; if (complm) *sum = 0xFFFFFFFF - *sum; /* complement each bit of the value */ return(*sum); } /*------------------------------------------------------------------------*/ int ffpcks(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Create or update the checksum keywords in the CHDU. These keywords provide a checksum verification of the FITS HDU based on the ASCII coded 1's complement checksum algorithm developed by Rob Seaman at NOAO. */ { char datestr[20], checksum[FLEN_VALUE], datasum[FLEN_VALUE]; char comm[FLEN_COMMENT], chkcomm[FLEN_COMMENT], datacomm[FLEN_COMMENT]; int tstatus; long nrec; LONGLONG headstart, datastart, dataend; unsigned long dsum, olddsum, sum; double tdouble; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* generate current date string and construct the keyword comments */ ffgstm(datestr, NULL, status); strcpy(chkcomm, "HDU checksum updated "); strcat(chkcomm, datestr); strcpy(datacomm, "data unit checksum updated "); strcat(datacomm, datestr); /* write the CHECKSUM keyword if it does not exist */ tstatus = *status; if (ffgkys(fptr, "CHECKSUM", checksum, comm, status) == KEY_NO_EXIST) { *status = tstatus; strcpy(checksum, "0000000000000000"); ffpkys(fptr, "CHECKSUM", checksum, chkcomm, status); } /* write the DATASUM keyword if it does not exist */ tstatus = *status; if (ffgkys(fptr, "DATASUM", datasum, comm, status) == KEY_NO_EXIST) { *status = tstatus; olddsum = 0; ffpkys(fptr, "DATASUM", " 0", datacomm, status); /* set the CHECKSUM keyword as undefined, if it isn't already */ if (strcmp(checksum, "0000000000000000") ) { strcpy(checksum, "0000000000000000"); ffmkys(fptr, "CHECKSUM", checksum, chkcomm, status); } } else { /* decode the datasum into an unsigned long variable */ /* olddsum = strtoul(datasum, 0, 10); doesn't work on SUN OS */ tdouble = atof(datasum); olddsum = (unsigned long) tdouble; } /* close header: rewrite END keyword and following blank fill */ /* and re-read the required keywords to determine the structure */ if (ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->heapsize > 0) ffuptf(fptr, status); /* update the variable length TFORM values */ /* write the correct data fill values, if they are not already correct */ if (ffpdfl(fptr, status) > 0) return(*status); /* calc size of data unit, in FITS 2880-byte blocks */ if (ffghadll(fptr, &headstart, &datastart, &dataend, status) > 0) return(*status); nrec = (long) ((dataend - datastart) / 2880); dsum = 0; if (nrec > 0) { /* accumulate the 32-bit 1's complement checksum */ ffmbyt(fptr, datastart, REPORT_EOF, status); if (ffcsum(fptr, nrec, &dsum, status) > 0) return(*status); } if (dsum != olddsum) { /* update the DATASUM keyword with the correct value */ sprintf(datasum, "%lu", dsum); ffmkys(fptr, "DATASUM", datasum, datacomm, status); /* set the CHECKSUM keyword as undefined, if it isn't already */ if (strcmp(checksum, "0000000000000000") ) { strcpy(checksum, "0000000000000000"); ffmkys(fptr, "CHECKSUM", checksum, chkcomm, status); } } if (strcmp(checksum, "0000000000000000") ) { /* check if CHECKSUM is still OK; move to the start of the header */ ffmbyt(fptr, headstart, REPORT_EOF, status); /* accumulate the header checksum into the previous data checksum */ nrec = (long) ((datastart - headstart) / 2880); sum = dsum; if (ffcsum(fptr, nrec, &sum, status) > 0) return(*status); if (sum == 0 || sum == 0xFFFFFFFF) return(*status); /* CHECKSUM is correct */ /* Zero the CHECKSUM and recompute the new value */ ffmkys(fptr, "CHECKSUM", "0000000000000000", chkcomm, status); } /* move to the start of the header */ ffmbyt(fptr, headstart, REPORT_EOF, status); /* accumulate the header checksum into the previous data checksum */ nrec = (long) ((datastart - headstart) / 2880); sum = dsum; if (ffcsum(fptr, nrec, &sum, status) > 0) return(*status); /* encode the COMPLEMENT of the checksum into a 16-character string */ ffesum(sum, TRUE, checksum); /* update the CHECKSUM keyword value with the new string */ ffmkys(fptr, "CHECKSUM", checksum, "&", status); return(*status); } /*------------------------------------------------------------------------*/ int ffupck(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Update the CHECKSUM keyword value. This assumes that the DATASUM keyword exists and has the correct value. */ { char datestr[20], chkcomm[FLEN_COMMENT], comm[FLEN_COMMENT]; char checksum[FLEN_VALUE], datasum[FLEN_VALUE]; int tstatus; long nrec; LONGLONG headstart, datastart, dataend; unsigned long sum, dsum; double tdouble; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* generate current date string and construct the keyword comments */ ffgstm(datestr, NULL, status); strcpy(chkcomm, "HDU checksum updated "); strcat(chkcomm, datestr); /* get the DATASUM keyword and convert it to a unsigned long */ if (ffgkys(fptr, "DATASUM", datasum, comm, status) == KEY_NO_EXIST) { ffpmsg("DATASUM keyword not found (ffupck"); return(*status); } tdouble = atof(datasum); /* read as a double as a workaround */ dsum = (unsigned long) tdouble; /* get size of the HDU */ if (ffghadll(fptr, &headstart, &datastart, &dataend, status) > 0) return(*status); /* get the checksum keyword, if it exists */ tstatus = *status; if (ffgkys(fptr, "CHECKSUM", checksum, comm, status) == KEY_NO_EXIST) { *status = tstatus; strcpy(checksum, "0000000000000000"); ffpkys(fptr, "CHECKSUM", checksum, chkcomm, status); } else { /* check if CHECKSUM is still OK */ /* rewrite END keyword and following blank fill */ if (ffwend(fptr, status) > 0) return(*status); /* move to the start of the header */ ffmbyt(fptr, headstart, REPORT_EOF, status); /* accumulate the header checksum into the previous data checksum */ nrec = (long) ((datastart - headstart) / 2880); sum = dsum; if (ffcsum(fptr, nrec, &sum, status) > 0) return(*status); if (sum == 0 || sum == 0xFFFFFFFF) return(*status); /* CHECKSUM is already correct */ /* Zero the CHECKSUM and recompute the new value */ ffmkys(fptr, "CHECKSUM", "0000000000000000", chkcomm, status); } /* move to the start of the header */ ffmbyt(fptr, headstart, REPORT_EOF, status); /* accumulate the header checksum into the previous data checksum */ nrec = (long) ((datastart - headstart) / 2880); sum = dsum; if (ffcsum(fptr, nrec, &sum, status) > 0) return(*status); /* encode the COMPLEMENT of the checksum into a 16-character string */ ffesum(sum, TRUE, checksum); /* update the CHECKSUM keyword value with the new string */ ffmkys(fptr, "CHECKSUM", checksum, "&", status); return(*status); } /*------------------------------------------------------------------------*/ int ffvcks(fitsfile *fptr, /* I - FITS file pointer */ int *datastatus, /* O - data checksum status */ int *hdustatus, /* O - hdu checksum status */ /* 1 verification is correct */ /* 0 checksum keyword is not present */ /* -1 verification not correct */ int *status) /* IO - error status */ /* Verify the HDU by comparing the value of the computed checksums against the values of the DATASUM and CHECKSUM keywords if they are present. */ { int tstatus; double tdouble; unsigned long datasum, hdusum, olddatasum; char chksum[FLEN_VALUE], comm[FLEN_COMMENT]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); *datastatus = -1; *hdustatus = -1; tstatus = *status; if (ffgkys(fptr, "CHECKSUM", chksum, comm, status) == KEY_NO_EXIST) { *hdustatus = 0; /* CHECKSUM keyword does not exist */ *status = tstatus; } if (chksum[0] == '\0') *hdustatus = 0; /* all blank checksum means it is undefined */ if (ffgkys(fptr, "DATASUM", chksum, comm, status) == KEY_NO_EXIST) { *datastatus = 0; /* DATASUM keyword does not exist */ *status = tstatus; } if (chksum[0] == '\0') *datastatus = 0; /* all blank checksum means it is undefined */ if ( *status > 0 || (!(*hdustatus) && !(*datastatus)) ) return(*status); /* return if neither keywords exist */ /* convert string to unsigned long */ /* olddatasum = strtoul(chksum, 0, 10); doesn't work w/ gcc on SUN OS */ /* sscanf(chksum, "%u", &olddatasum); doesn't work w/ cc on VAX/VMS */ tdouble = atof(chksum); /* read as a double as a workaround */ olddatasum = (unsigned long) tdouble; /* calculate the data checksum and the HDU checksum */ if (ffgcks(fptr, &datasum, &hdusum, status) > 0) return(*status); if (*datastatus) if (datasum == olddatasum) *datastatus = 1; if (*hdustatus) if (hdusum == 0 || hdusum == 0xFFFFFFFF) *hdustatus = 1; return(*status); } /*------------------------------------------------------------------------*/ int ffgcks(fitsfile *fptr, /* I - FITS file pointer */ unsigned long *datasum, /* O - data checksum */ unsigned long *hdusum, /* O - hdu checksum */ int *status) /* IO - error status */ /* calculate the checksums of the data unit and the total HDU */ { long nrec; LONGLONG headstart, datastart, dataend; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* get size of the HDU */ if (ffghadll(fptr, &headstart, &datastart, &dataend, status) > 0) return(*status); nrec = (long) ((dataend - datastart) / 2880); *datasum = 0; if (nrec > 0) { /* accumulate the 32-bit 1's complement checksum */ ffmbyt(fptr, datastart, REPORT_EOF, status); if (ffcsum(fptr, nrec, datasum, status) > 0) return(*status); } /* move to the start of the header and calc. size of header */ ffmbyt(fptr, headstart, REPORT_EOF, status); nrec = (long) ((datastart - headstart) / 2880); /* accumulate the header checksum into the previous data checksum */ *hdusum = *datasum; ffcsum(fptr, nrec, hdusum, status); return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/compress.c000066400000000000000000005400701215713201500224350ustar00rootroot00000000000000#include "compress.h" local void error OF((char *m)); /* ====================================================================== This file contains source code that was copied and modified from the original gzip-1.2.4 program, which contained the following copyright and warranty notices: "gzip is free software, you can redistribute it and/or modify it under the terms of the GNU General Public License, a copy of which is provided below. The latest version of gzip are always available by ftp in prep.ai.mit.edu:/pub/gnu, or in any of the prep mirror sites." * gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface * Copyright (C) 1992-1993 Jean-loup Gailly * The unzip code was written and put in the public domain by Mark Adler. * Portions of the lzw code are derived from the public domain 'compress' * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies, * Ken Turkowski, Dave Mack and Peter Jannesen. * * See the license_msg below and the file COPYING for the software license. * See the file algorithm.doc for the compression algorithms and file formats. * unlzh.c -- decompress files in SCO compress -H (LZH) format. * The code in this file is directly derived from the public domain 'ar002' * written by Haruhiko Okumura. ---------- Beginning of GNU GENERAL PUBLIC LICENSE ---------------- GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS ------------- End of GNU GENERAL PUBLIC LICENSE ---------------- =========================================================================== */ /* global buffers */ static DECLARE(uch, inbuf, INBUFSIZ +INBUF_EXTRA); static DECLARE(uch, outbuf, OUTBUFSIZ+OUTBUF_EXTRA); static DECLARE(ush, d_buf, DIST_BUFSIZE); static DECLARE(uch, window, 2L*WSIZE); #ifndef MAXSEG_64K static DECLARE(ush, tab_prefix, 1L< 0) return(*status); /* save input parameters into global variables */ strcpy(ifname, filename); ifd = diskfile; memptr = (void **) buffptr; memsize = buffsize; realloc_fn = mem_realloc; in_memptr = NULL; /* signal that we are reading from file, not memory */ /* clear input and output buffers */ outcnt = 0; insize = inptr = 0; bytes_in = bytes_out = 0L; part_nb = 0; method = get_method(ifd); if (method < 0) { return(*status = 414); /* error message already emitted */ } /* Actually do the compression/decompression. Loop over zipped members. */ for (;;) { if ((*work)(ifd, ofd) != OK) { method = -1; /* force cleanup */ *status = 414; /* report some sort of decompression error */ break; } if (last_member || inptr == insize) break; /* end of file */ method = get_method(ifd); if (method < 0) break; /* error message already emitted */ bytes_out = 0; /* required for length check */ } /* *buffptr = *memptr; *buffsize = *memsize; */ *filesize = bytes_out; return(*status); } /*--------------------------------------------------------------------------*/ int uncompress2mem_from_mem( char *inmemptr, /* I - memory pointer to compressed bytes */ size_t inmemsize, /* I - size of input compressed file */ char **buffptr, /* IO - memory pointer */ size_t *buffsize, /* IO - size of buffer, in bytes */ void *(*mem_realloc)(void *p, size_t newsize), /* function */ size_t *filesize, /* O - size of file, in bytes */ int *status) /* IO - error status */ /* Uncompress the file into memory. Fill whatever amount of memory has already been allocated, then realloc more memory, using the supplied input function, if necessary. */ { if (*status > 0) return(*status); /* save input parameters into global variables */ in_memptr = inmemptr; in_memsize = inmemsize; memptr = (void **) buffptr; memsize = buffsize; realloc_fn = mem_realloc; /* clear input and output buffers */ outcnt = 0; insize = inptr = 0; bytes_in = bytes_out = 0L; part_nb = 0; method = get_method(ifd); if (method < 0) { return(*status = 414); /* error message already emitted */ } /* Actually do the compression/decompression. Loop over zipped members. */ for (;;) { if ((*work)(ifd, ofd) != OK) { method = -1; /* force cleanup */ *status = 414; /* report some sort of decompression error */ break; } if (last_member || inptr == insize) break; /* end of file */ method = get_method(ifd); if (method < 0) break; /* error message already emitted */ bytes_out = 0; /* required for length check */ } /* *buffptr = *memptr; *buffsize = *memsize; */ *filesize = bytes_out; return(*status); } /*--------------------------------------------------------------------------*/ int uncompress2file(char *filename, /* name of input file */ FILE *indiskfile, /* I - input file pointer */ FILE *outdiskfile, /* I - output file pointer */ int *status) /* IO - error status */ /* Uncompress the file into file. */ { if (*status > 0) return(*status); /* save input parameters into global variables */ strcpy(ifname, filename); ifd = indiskfile; ofd = outdiskfile; realloc_fn = NULL; /* a null reallocation fn signals that the file is */ /* to be uncompressed to a file on disk, not memory */ in_memptr = NULL; /* signal that we are reading from file, not memory */ /* clear input and output buffers */ outcnt = 0; insize = inptr = 0; bytes_in = bytes_out = 0L; part_nb = 0; method = get_method(ifd); if (method < 0) { return(*status = 1); /* error message already emitted */ } /* Actually do the compression/decompression. Loop over zipped members. */ for (;;) { if ((*work)(ifd, ofd) != OK) { method = -1; /* force cleanup */ break; } if (last_member || inptr == insize) break; /* end of file */ method = get_method(ifd); if (method < 0) break; /* error message already emitted */ bytes_out = 0; /* required for length check */ } return(*status); } /*--------------------------------------------------------------------------*/ int compress2mem_from_mem( char *inmemptr, /* I - memory pointer to uncompressed bytes */ size_t inmemsize, /* I - size of input uncompressed file */ char **buffptr, /* IO - memory pointer for compressed file */ size_t *buffsize, /* IO - size of buffer, in bytes */ void *(*mem_realloc)(void *p, size_t newsize), /* function */ size_t *filesize, /* O - size of file, in bytes */ int *status) /* IO - error status */ /* Compress the file into memory. Fill whatever amount of memory has already been allocated, then realloc more memory, using the supplied input function, if necessary. */ { uch flags = 0; /* general purpose bit flags */ ush attr = 0; /* ascii/binary flag */ ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */ if (*status > 0) return(*status); /* save input parameters into global variables */ in_memptr = inmemptr; in_memsize = inmemsize; memptr = (void **) buffptr; memsize = buffsize; realloc_fn = mem_realloc; /* clear input and output buffers */ outcnt = 0; insize = inptr = 0; bytes_in = bytes_out = 0L; part_nb = 0; method = DEFLATED; /* write gzip header bytes */ put_byte(GZIP_MAGIC[0]); /* magic header */ put_byte(GZIP_MAGIC[1]); put_byte(DEFLATED); /* compression method */ put_byte(flags); /* just write zero as dummy value for the timestamp put_long(time_stamp); */ put_long(0); /* dummy time stamp */ /* Write deflated file to zip file */ crc_value = updcrc(0, 0); bi_init(NO_FILE); ct_init(&attr, &method); lm_init(level, &deflate_flags); put_byte((uch)deflate_flags); /* extra flags */ put_byte(0); /* OS identifier; 0 = default */ header_bytes = (long)outcnt; (void)deflate(); /* Write the crc and uncompressed size */ put_long(crc_value); put_long(isize); header_bytes += 2*sizeof(long); flush_outbuf(); *buffptr = *memptr; *buffsize = *memsize; *filesize = bytes_out; return(*status); } /*--------------------------------------------------------------------------*/ int compress2file_from_mem( char *inmemptr, /* I - memory pointer to uncompressed bytes */ size_t inmemsize, /* I - size of input uncompressed file */ FILE *outdiskfile, size_t *filesize, /* O - size of file, in bytes */ int *status) /* Compress the memory file into disk file. */ { uch flags = 0; /* general purpose bit flags */ ush attr = 0; /* ascii/binary flag */ ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */ if (*status > 0) return(*status); /* save input parameters into global variables */ in_memptr = inmemptr; in_memsize = inmemsize; ofd = outdiskfile; realloc_fn = NULL; /* a null reallocation fn signals that the file is */ /* to be compressed to a file on disk, not memory */ /* clear input and output buffers */ outcnt = 0; insize = inptr = 0; bytes_in = bytes_out = 0L; part_nb = 0; method = DEFLATED; /* write gzip header bytes */ put_byte(GZIP_MAGIC[0]); /* magic header */ put_byte(GZIP_MAGIC[1]); put_byte(DEFLATED); /* compression method */ put_byte(flags); /* just write zero as dummy value for the timestamp put_long(time_stamp); */ put_long(0); /* dummy time stamp */ /* Write deflated file to zip file */ crc_value = updcrc(0, 0); bi_init(NO_FILE); ct_init(&attr, &method); lm_init(level, &deflate_flags); put_byte((uch)deflate_flags); /* extra flags */ put_byte(0); /* OS identifier; 0 = default */ header_bytes = (long)outcnt; (void)deflate(); /* Write the crc and uncompressed size */ put_long(crc_value); put_long(isize); header_bytes += 2*sizeof(long); flush_outbuf(); *filesize = bytes_out; return(*status); } /*--------------------------------------------------------------------------*/ /* ****************************** */ /* The following came from gzip.c */ /* ****************************** */ /* ======================================================================== * Check the magic number of the input file and update ofname if an * original name was given and to_stdout is not set. * Return the compression method, -1 for error, -2 for warning. * Set inptr to the offset of the next byte to be processed. * Updates time_stamp if there is one and --no-time is not used. * This function may be called repeatedly for an input file consisting * of several contiguous gzip'ed members. * IN assertions: there is at least one remaining compressed member. * If the member is a zip file, it must be the only one. */ local int get_method(in) FILE *in; /* input file descriptor */ { uch flags; /* compression flags */ char magic[2]; /* magic header */ magic[0] = (char)get_byte(); magic[1] = (char)get_byte(); method = -1; /* unknown yet */ part_nb++; /* number of parts in gzip file */ header_bytes = 0; last_member = RECORD_IO; /* assume multiple members in gzip file except for record oriented I/O */ if (memcmp(magic, GZIP_MAGIC, 2) == 0 || memcmp(magic, OLD_GZIP_MAGIC, 2) == 0) { method = (int)get_byte(); if (method != DEFLATED) { error("unknown compression method -- get newer version of gzip"); exit_code = ERROR; return -1; } work = unzip; flags = (uch)get_byte(); if ((flags & ENCRYPTED) != 0) { error("input file is encrypted -- get newer version of gzip"); exit_code = ERROR; return -1; } if ((flags & CONTINUATION) != 0) { error( "file is a a multi-part gzip file -- get newer version of gzip"); exit_code = ERROR; if (force <= 1) return -1; } if ((flags & RESERVED) != 0) { error("file has flags 0x%x -- get newer version of gzip"); exit_code = ERROR; if (force <= 1) return -1; } (void)get_byte(); /* Ignore time stamp */ (void)get_byte(); (void)get_byte(); (void)get_byte(); (void)get_byte(); /* Ignore extra flags for the moment */ (void)get_byte(); /* Ignore OS type for the moment */ if ((flags & CONTINUATION) != 0) { (void)get_byte(); (void)get_byte(); } if ((flags & EXTRA_FIELD) != 0) { unsigned len = (unsigned)get_byte(); len |= ((unsigned)get_byte())<<8; while (len--) (void)get_byte(); } /* Get original file name if it was truncated */ if ((flags & ORIG_NAME) != 0) { /* Discard the old name */ char c; /* dummy used for NeXTstep 3.0 cc optimizer bug */ do {c=get_byte();} while (c != 0); } /* ORIG_NAME */ /* Discard file comment if any */ if ((flags & COMMENT) != 0) { while (get_char() != 0) /* null */ ; } if (part_nb == 1) { header_bytes = inptr + 2*sizeof(long); /* include crc and size */ } } else if (memcmp(magic, PKZIP_MAGIC, 2) == 0 && inptr == 2 && memcmp((char*)inbuf, PKZIP_MAGIC, 4) == 0) { /* To simplify the code, we support a zip file when alone only. * We are thus guaranteed that the entire local header fits in inbuf. */ inptr = 0; work = unzip; if (check_zipfile(in) != OK) return -1; /* check_zipfile may get ofname from the local header */ last_member = 1; } else if (memcmp(magic, PACK_MAGIC, 2) == 0) { work = unpack; method = PACKED; } else if (memcmp(magic, LZW_MAGIC, 2) == 0) { work = unlzw; method = COMPRESSED; last_member = 1; } else if (memcmp(magic, LZH_MAGIC, 2) == 0) { work = unlzh; method = LZHED; last_member = 1; } if (method >= 0) return method; if (part_nb == 1) { error("file not in gzip format:"); exit_code = ERROR; return -1; } else { /* decompression OK, trailing garbage ignored */ return -2; } } /* ========================================================================*/ /* this marks the start of the code that was originally in the */ /* gzip source file called 'util.c' */ /* util.c -- utility functions for gzip support * Copyright (C) 1992-1993 Jean-loup Gailly * This is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, see the file COPYING. */ extern ulg crc_32_tab[]; /* crc table, defined below */ /* =========================================================================== * Run a set of bytes through the crc shift register. If s is a NULL * pointer, then initialize the crc shift register contents instead. * Return the current crc in either case. */ local ulg updcrc(s, n) uch *s; /* pointer to bytes to pump through */ unsigned n; /* number of bytes in s[] */ { register ulg c; /* temporary variable */ static ulg crc = (ulg)0xffffffffL; /* shift register contents */ if (s == NULL) { c = 0xffffffffUL; } else { c = crc; if (n) do { c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8); } while (--n); } crc = c; return c ^ 0xffffffffUL; /* (instead of ~c for 64-bit machines) */ } /* =========================================================================== * Fill the input buffer. This is called only when the buffer is empty. */ local int fill_inbuf(eof_ok) int eof_ok; /* set if EOF acceptable as a result */ { int len; if (in_memptr) { /* read from memory, not from a file */ if (in_memsize < INBUFSIZ) insize = in_memsize; else insize = INBUFSIZ; memcpy( (char*)inbuf, in_memptr, insize); in_memptr += insize; in_memsize -= insize; } else { /* Read as much as possible from file */ insize = 0; do { /* len = read(ifd, (char*)inbuf+insize, INBUFSIZ-insize); */ len = fread((char*)inbuf+insize, 1, INBUFSIZ-insize, ifd); if (len == 0 || len == EOF) break; insize += len; } while (insize < INBUFSIZ); } if (insize == 0) { if (eof_ok) return EOF; error("unexpected end of file"); exit_code = ERROR; return ERROR; } bytes_in += (ulg)insize; inptr = 1; return inbuf[0]; } /* =========================================================================== * Read a new buffer from the current input file, perform end-of-line * translation, and update the crc and input file size. * IN assertion: size >= 2 (for end-of-line translation) (this routine came from zip.c, and was modified to read and write from/to memory) */ int file_read(buf, size) char *buf; unsigned size; { unsigned len; Assert(insize == 0, "inbuf not empty"); len = in_memsize - isize; /* number of bytes left to compress */ if (size < len) len = size; /* only copy the requested number of bytes */ memcpy(buf, in_memptr + isize, len); /* len = read(ifd, buf, size); if (len == (unsigned)(-1) || len == 0) return (int)len; */ crc_value = updcrc((uch*)buf, len); isize += (ulg)len; return (int)len; } /* =========================================================================== * Write the output buffer outbuf[0..outcnt-1] and update bytes_out. * (used for the compressed data only) */ local void flush_outbuf() { if (outcnt == 0) return; write_buf((char *)outbuf, outcnt); bytes_out += (ulg)outcnt; outcnt = 0; } /* =========================================================================== * Write the output window window[0..outcnt-1] and update crc and bytes_out. * (Used for the decompressed data only.) */ local void flush_window() { if (exit_code != OK) return; if (outcnt == 0) return; updcrc(window, outcnt); write_buf((char *)window, outcnt); bytes_out += (ulg)outcnt; outcnt = 0; } /* =========================================================================== * copy buffer into memory; allocate more memory if required */ local void write_buf(buf, cnt) voidp buf; unsigned cnt; { if (!realloc_fn) { /* append buffer to file */ /* added 'unsigned' to get rid of compiler warning (WDP 1/1/99) */ if ((unsigned long) fwrite(buf, 1, cnt, ofd) != cnt) { error ("failed to write buffer to uncompressed output file (write_buf)"); exit_code = ERROR; return; } } else { /* copy/append buffer into memory */ /* get more memory if current buffer is too small */ if (bytes_out + cnt > *memsize) { *memptr = realloc_fn(*memptr, bytes_out + cnt); *memsize = bytes_out + cnt; /* new memory buffer size */ } if (!(*memptr)) { error("malloc failed while uncompressing (write_buf)"); exit_code = ERROR; return; } /* copy into memory buffer */ memcpy((char *) *memptr + bytes_out, (char *) buf, cnt); } } /* ======================================================================== * Error handlers. */ local void error(m) char *m; { ffpmsg(ifname); ffpmsg(m); } /* ======================================================================== * Table of CRC-32's of all single-byte values (made by makecrc.c) */ ulg crc_32_tab[] = { 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL }; /* ******************************************** */ /* ** the following code came from unlzh.c **** */ /* ******************************************** */ #define DICBIT 13 /* 12(-lh4-) or 13(-lh5-) */ #define DICSIZ ((unsigned) 1 << DICBIT) #ifndef CHAR_BIT # define CHAR_BIT 8 #endif #ifndef UCHAR_MAX # define UCHAR_MAX 255 #endif #define BITBUFSIZ (CHAR_BIT * 2 * sizeof(char)) /* Do not use CHAR_BIT * sizeof(bitbuf), does not work on machines * for which short is not on 16 bits (Cray). */ /* encode.c and decode.c */ #define MAXMATCH 256 /* formerly F (not more than UCHAR_MAX + 1) */ #define THRESHOLD 3 /* choose optimal value */ /* huf.c */ #define NC (UCHAR_MAX + MAXMATCH + 2 - THRESHOLD) /* alphabet = {0, 1, 2, ..., NC - 1} */ #define CBIT 9 /* $\lfloor \log_2 NC \rfloor + 1$ */ #define CODE_BIT 16 /* codeword length */ #define NP (DICBIT + 1) #define NT (CODE_BIT + 3) #define PBIT 4 /* smallest integer such that (1U << PBIT) > NP */ #define TBIT 5 /* smallest integer such that (1U << TBIT) > NT */ #if NT > NP # define NPT NT #else # define NPT NP #endif /* local ush left[2 * NC - 1]; */ /* local ush right[2 * NC - 1]; */ #define left prev #define right head #if NC > (1<<(BITS-2)) error cannot overlay left+right and prev #endif /* local uch c_len[NC]; */ #define c_len outbuf #if NC > OUTBUFSIZ error cannot overlay c_len and outbuf #endif local uch pt_len[NPT]; local unsigned blocksize; local ush pt_table[256]; /* local ush c_table[4096]; */ #define c_table d_buf #if (DIST_BUFSIZE-1) < 4095 error cannot overlay c_table and d_buf #endif /*********************************************************** io.c -- input/output ***********************************************************/ local ush bitbuf; local unsigned subbitbuf; local int bitcount; local void fillbuf(n) /* Shift bitbuf n bits left, read n bits */ int n; { bitbuf <<= n; while (n > bitcount) { bitbuf |= subbitbuf << (n -= bitcount); subbitbuf = (unsigned)try_byte(); if ((int)subbitbuf == EOF) subbitbuf = 0; bitcount = CHAR_BIT; } bitbuf |= subbitbuf >> (bitcount -= n); } local unsigned getbits(n) int n; { unsigned x; x = bitbuf >> (BITBUFSIZ - n); fillbuf(n); return x; } local void init_getbits() { bitbuf = 0; subbitbuf = 0; bitcount = 0; fillbuf(BITBUFSIZ); } /*********************************************************** maketbl.c -- make table for decoding ***********************************************************/ local void make_table(nchar, bitlen, tablebits, table) int nchar; uch bitlen[]; int tablebits; ush table[]; { ush count[17], weight[17], start[18], *p; unsigned i, k, len, ch, jutbits, avail, nextcode, mask; for (i = 1; i <= 16; i++) count[i] = 0; /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) for (i = 0; i < (unsigned)nchar; i++) count[bitlen[i]]++; */ for (i = 0; i < (unsigned)nchar; i++) { if (bitlen[i] > 16) error("Bad table (case a)\n"); else count[bitlen[i]]++; } start[1] = 0; for (i = 1; i <= 16; i++) start[i + 1] = start[i] + (count[i] << (16 - i)); /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) if ((start[17] & 0xffff) != 0) { error("Bad table\n"); */ if ((start[17] & 0xffff) != 0 || tablebits > 16) /* 16 for weight below */ { error("Bad table (case b)\n"); exit_code = ERROR; return; } jutbits = 16 - tablebits; for (i = 1; i <= (unsigned)tablebits; i++) { start[i] >>= jutbits; weight[i] = (unsigned) 1 << (tablebits - i); } while (i <= 16) { weight[i] = (unsigned) 1 << (16 - i); i++; } i = start[tablebits + 1] >> jutbits; if (i != 0) { /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) k = 1 << tablebits; while (i != k) table[i++] = 0; */ k = MINZIP(1 << tablebits, DIST_BUFSIZE); while (i < k) table[i++] = 0; } avail = nchar; mask = (unsigned) 1 << (15 - tablebits); for (ch = 0; ch < (unsigned)nchar; ch++) { if ((len = bitlen[ch]) == 0) continue; /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) nextcode = start[len] + weight[len]; */ nextcode = MINZIP(start[len] + weight[len], DIST_BUFSIZE); if (len <= (unsigned)tablebits) { for (i = start[len]; i < nextcode; i++) table[i] = ch; } else { k = start[len]; p = &table[k >> jutbits]; i = len - tablebits; while (i != 0) { if (*p == 0) { right[avail] = left[avail] = 0; *p = avail++; } if (k & mask) p = &right[*p]; else p = &left[*p]; k <<= 1; i--; } *p = ch; } start[len] = nextcode; } } /*********************************************************** huf.c -- static Huffman ***********************************************************/ local void read_pt_len(nn, nbit, i_special) int nn; int nbit; int i_special; { int i, c, n; unsigned mask; n = getbits(nbit); if (n == 0) { c = getbits(nbit); for (i = 0; i < nn; i++) pt_len[i] = 0; for (i = 0; i < 256; i++) pt_table[i] = c; } else { i = 0; /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) while (i < n) { */ while (i < MINZIP(n,NPT)) { c = bitbuf >> (BITBUFSIZ - 3); if (c == 7) { mask = (unsigned) 1 << (BITBUFSIZ - 1 - 3); while (mask & bitbuf) { mask >>= 1; c++; } } fillbuf((c < 7) ? 3 : c - 3); pt_len[i++] = c; if (i == i_special) { c = getbits(2); /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) while (--c >= 0) pt_len[i++] = 0; */ while (--c >= 0 && i < NPT) pt_len[i++] = 0; } } while (i < nn) pt_len[i++] = 0; make_table(nn, pt_len, 8, pt_table); } } local void read_c_len() { int i, c, n; unsigned mask; n = getbits(CBIT); if (n == 0) { c = getbits(CBIT); for (i = 0; i < NC; i++) c_len[i] = 0; for (i = 0; i < 4096; i++) c_table[i] = c; } else { i = 0; /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) while (i < n) { */ while (i < MINZIP(n,NC)) { c = pt_table[bitbuf >> (BITBUFSIZ - 8)]; if (c >= NT) { mask = (unsigned) 1 << (BITBUFSIZ - 1 - 8); do { if (bitbuf & mask) c = right[c]; else c = left [c]; mask >>= 1; /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) } while (c >= NT); */ } while (c >= NT && (mask || c != left[c])); } fillbuf((int) pt_len[c]); if (c <= 2) { if (c == 0) c = 1; else if (c == 1) c = getbits(4) + 3; else c = getbits(CBIT) + 20; /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) while (--c >= 0) c_len[i++] = 0; */ while (--c >= 0 && i < NC) c_len[i++] = 0; } else c_len[i++] = c - 2; } while (i < NC) c_len[i++] = 0; make_table(NC, c_len, 12, c_table); } } local unsigned decode_c() { unsigned j = 0, mask; if (blocksize == 0) { blocksize = getbits(16); if (blocksize == 0) { return NC; /* end of file */ } read_pt_len(NT, TBIT, 3); if (exit_code != OK) return j; read_c_len(); if (exit_code != OK) return j; read_pt_len(NP, PBIT, -1); if (exit_code != OK) return j; } blocksize--; j = c_table[bitbuf >> (BITBUFSIZ - 12)]; if (j >= NC) { mask = (unsigned) 1 << (BITBUFSIZ - 1 - 12); do { if (bitbuf & mask) j = right[j]; else j = left [j]; mask >>= 1; /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) } while (j >= NC); */ } while (j >= NC && (mask || j != left[j])); } fillbuf((int) c_len[j]); return j; } local unsigned decode_p() { unsigned j, mask; j = pt_table[bitbuf >> (BITBUFSIZ - 8)]; if (j >= NP) { mask = (unsigned) 1 << (BITBUFSIZ - 1 - 8); do { if (bitbuf & mask) j = right[j]; else j = left [j]; mask >>= 1; /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) } while (j >= NP); */ } while (j >= NP && (mask || j != left[j])); } fillbuf((int) pt_len[j]); if (j != 0) j = ((unsigned) 1 << (j - 1)) + getbits((int) (j - 1)); return j; } local void huf_decode_start() { init_getbits(); blocksize = 0; } /*********************************************************** decode.c ***********************************************************/ /* changed 'j' to 'jj1' to avoid conflicts - WDP 1/1/99) */ local int jj1; /* remaining bytes to copy */ local int done; /* set at end of input */ local void decode_start() { huf_decode_start(); jj1 = 0; done = 0; } /* Decode the input and return the number of decoded bytes put in buffer */ local unsigned decode(count, buffer) unsigned count; uch buffer[]; /* The calling function must keep the number of bytes to be processed. This function decodes either 'count' bytes or 'DICSIZ' bytes, whichever is smaller, into the array 'buffer[]' of size 'DICSIZ' or more. Call decode_start() once for each new file before calling this function. */ { local unsigned i; unsigned r, c; r = 0; while (--jj1 >= 0) { buffer[r] = buffer[i]; i = (i + 1) & (DICSIZ - 1); /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) if (++r == count) return r; */ if (++r >= count) return r; } for ( ; ; ) { c = decode_c(); if (exit_code != OK) return r; if (c == NC) { done = 1; return r; } if (c <= UCHAR_MAX) { buffer[r] = c; /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) if (++r == count) return r; */ if (++r >= count) return r; } else { jj1 = c - (UCHAR_MAX + 1 - THRESHOLD); i = (r - decode_p() - 1) & (DICSIZ - 1); while (--jj1 >= 0) { buffer[r] = buffer[i]; i = (i + 1) & (DICSIZ - 1); /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) if (++r == count) return r; */ if (++r >= count) return r; } } } } /* =========================================================================== * Unlzh in to out. Return OK or ERROR. */ local int unlzh(in, out) FILE *in; FILE *out; { unsigned n; ifd = in; ofd = out; decode_start(); while (!done) { n = decode((unsigned) DICSIZ, window); if (exit_code != OK) return ERROR; if (n > 0) { write_buf((char*)window, n); } } return OK; } /*=========================================================================*/ /* this marks the begining of the original file 'unlzw.c' */ /*=========================================================================*/ /* unlzw.c -- decompress files in LZW format. * The code in this file is directly derived from the public domain 'compress' * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies, * Ken Turkowski, Dave Mack and Peter Jannesen. * * This is a temporary version which will be rewritten in some future version * to accommodate in-memory decompression. */ typedef unsigned char char_type; typedef long code_int; typedef unsigned long count_int; typedef unsigned short count_short; typedef unsigned long cmp_code_int; #define MAXCODE(n) (1L << (n)) #ifndef REGISTERS # define REGISTERS 2 #endif #define REG1 #define REG2 #define REG3 #define REG4 #define REG5 #define REG6 #define REG7 #define REG8 #define REG9 #define REG10 #define REG11 #define REG12 #define REG13 #define REG14 #define REG15 #define REG16 #if REGISTERS >= 1 # undef REG1 # define REG1 register #endif #if REGISTERS >= 2 # undef REG2 # define REG2 register #endif #if REGISTERS >= 3 # undef REG3 # define REG3 register #endif #if REGISTERS >= 4 # undef REG4 # define REG4 register #endif #if REGISTERS >= 5 # undef REG5 # define REG5 register #endif #if REGISTERS >= 6 # undef REG6 # define REG6 register #endif #if REGISTERS >= 7 # undef REG7 # define REG7 register #endif #if REGISTERS >= 8 # undef REG8 # define REG8 register #endif #if REGISTERS >= 9 # undef REG9 # define REG9 register #endif #if REGISTERS >= 10 # undef REG10 # define REG10 register #endif #if REGISTERS >= 11 # undef REG11 # define REG11 register #endif #if REGISTERS >= 12 # undef REG12 # define REG12 register #endif #if REGISTERS >= 13 # undef REG13 # define REG13 register #endif #if REGISTERS >= 14 # undef REG14 # define REG14 register #endif #if REGISTERS >= 15 # undef REG15 # define REG15 register #endif #if REGISTERS >= 16 # undef REG16 # define REG16 register #endif #ifndef BYTEORDER # define BYTEORDER 0000 #endif #ifndef NOALLIGN # define NOALLIGN 0 #endif union bytes { long word; struct { #if BYTEORDER == 4321 char_type b1; char_type b2; char_type b3; char_type b4; #else #if BYTEORDER == 1234 char_type b4; char_type b3; char_type b2; char_type b1; #else # undef BYTEORDER int dummy; #endif #endif } bytes; }; #if BYTEORDER == 4321 && NOALLIGN == 1 # define input(b,o,c,n,m){ \ (c) = (*(long *)(&(b)[(o)>>3])>>((o)&0x7))&(m); \ (o) += (n); \ } #else # define input(b,o,c,n,m){ \ REG1 char_type *p = &(b)[(o)>>3]; \ (c) = ((((long)(p[0]))|((long)(p[1])<<8)| \ ((long)(p[2])<<16))>>((o)&0x7))&(m); \ (o) += (n); \ } #endif #ifndef MAXSEG_64K /* DECLARE(ush, tab_prefix, (1<>1] # define clear_tab_prefixof() \ memzero(tab_prefix0, 128), \ memzero(tab_prefix1, 128); #endif #define de_stack ((char_type *)(&d_buf[DIST_BUFSIZE-1])) #define tab_suffixof(i) tab_suffix[i] int block_mode = BLOCK_MODE; /* block compress mode -C compatible with 2.0 */ /* ============================================================================ * Decompress in to out. This routine adapts to the codes in the * file building the "string" table on-the-fly; requiring no table to * be stored in the compressed file. * IN assertions: the buffer inbuf contains already the beginning of * the compressed data, from offsets iptr to insize-1 included. * The magic header has already been checked and skipped. * bytes_in and bytes_out have been initialized. */ local int unlzw(in, out) FILE *in, *out; /* input and output file descriptors */ { REG2 char_type *stackp; REG3 code_int code; REG4 int finchar; REG5 code_int oldcode; REG6 code_int incode; REG7 long inbits; REG8 long posbits; REG9 int outpos; /* REG10 int insize; (global) */ REG11 unsigned bitmask; REG12 code_int free_ent; REG13 code_int maxcode; REG14 code_int maxmaxcode; REG15 int n_bits; REG16 int rsize; ofd = out; #ifdef MAXSEG_64K tab_prefix[0] = tab_prefix0; tab_prefix[1] = tab_prefix1; #endif maxbits = get_byte(); block_mode = maxbits & BLOCK_MODE; if ((maxbits & LZW_RESERVED) != 0) { error( "warning, unknown flags in unlzw decompression"); } maxbits &= BIT_MASK; maxmaxcode = MAXCODE(maxbits); if (maxbits > BITS) { error("compressed with too many bits; cannot handle file"); exit_code = ERROR; return ERROR; } rsize = insize; maxcode = MAXCODE(n_bits = INIT_BITS)-1; bitmask = (1<= 0 ; --code) { tab_suffixof(code) = (char_type)code; } do { REG1 int i; int e; int o; resetbuf: e = insize-(o = (posbits>>3)); for (i = 0 ; i < e ; ++i) { inbuf[i] = inbuf[i+o]; } insize = e; posbits = 0; if (insize < INBUF_EXTRA) { /* modified to use fread instead of read - WDP 10/22/97 */ /* if ((rsize = read(in, (char*)inbuf+insize, INBUFSIZ)) == EOF) { */ if ((rsize = fread((char*)inbuf+insize, 1, INBUFSIZ, in)) == EOF) { error("unexpected end of file"); exit_code = ERROR; return ERROR; } insize += rsize; bytes_in += (ulg)rsize; } inbits = ((rsize != 0) ? ((long)insize - insize%n_bits)<<3 : ((long)insize<<3)-(n_bits-1)); while (inbits > posbits) { if (free_ent > maxcode) { posbits = ((posbits-1) + ((n_bits<<3)-(posbits-1+(n_bits<<3))%(n_bits<<3))); ++n_bits; if (n_bits == maxbits) { maxcode = maxmaxcode; } else { maxcode = MAXCODE(n_bits)-1; } bitmask = (1<= 256) { error("corrupt input."); exit_code = ERROR; return ERROR; } outbuf[outpos++] = (char_type)(finchar = (int)(oldcode=code)); continue; } if (code == CLEAR && block_mode) { clear_tab_prefixof(); free_ent = FIRST - 1; posbits = ((posbits-1) + ((n_bits<<3)-(posbits-1+(n_bits<<3))%(n_bits<<3))); maxcode = MAXCODE(n_bits = INIT_BITS)-1; bitmask = (1<= free_ent) { /* Special case for KwKwK string. */ if (code > free_ent) { if (outpos > 0) { write_buf((char*)outbuf, outpos); bytes_out += (ulg)outpos; } error("corrupt input."); exit_code = ERROR; return ERROR; } *--stackp = (char_type)finchar; code = oldcode; } while ((cmp_code_int)code >= (cmp_code_int)256) { /* Generate output characters in reverse order */ *--stackp = tab_suffixof(code); code = tab_prefixof(code); } *--stackp = (char_type)(finchar = tab_suffixof(code)); /* And put them out in forward order */ { /* REG1 int i; already defined above (WDP) */ if (outpos+(i = (de_stack-stackp)) >= OUTBUFSIZ) { do { if (i > OUTBUFSIZ-outpos) i = OUTBUFSIZ-outpos; if (i > 0) { memcpy(outbuf+outpos, stackp, i); outpos += i; } if (outpos >= OUTBUFSIZ) { write_buf((char*)outbuf, outpos); bytes_out += (ulg)outpos; outpos = 0; } stackp+= i; } while ((i = (de_stack-stackp)) > 0); } else { memcpy(outbuf+outpos, stackp, i); outpos += i; } } if ((code = free_ent) < maxmaxcode) { /* Generate the new entry. */ tab_prefixof(code) = (unsigned short)oldcode; tab_suffixof(code) = (char_type)finchar; free_ent = code+1; } oldcode = incode; /* Remember previous code. */ } } while (rsize != 0); if (outpos > 0) { write_buf((char*)outbuf, outpos); bytes_out += (ulg)outpos; } return OK; } /*=========================================================================*/ /* This marks the beginning of the original file 'unpack.c' */ /*=========================================================================*/ /* unpack.c -- decompress files in pack format. * Copyright (C) 1992-1993 Jean-loup Gailly * This is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, see the file COPYING. */ #define MIN(a,b) ((a) <= (b) ? (a) : (b)) /* The arguments must not have side effects. */ #define MAX_BITLEN 25 /* Maximum length of Huffman codes. (Minor modifications to the code * would be needed to support 32 bits codes, but pack never generates * more than 24 bits anyway.) */ #define LITERALS 256 /* Number of literals, excluding the End of Block (EOB) code */ #define MAX_PEEK 12 /* Maximum number of 'peek' bits used to optimize traversal of the * Huffman tree. */ local ulg orig_len; /* original uncompressed length */ local int max_len; /* maximum bit length of Huffman codes */ local uch literal[LITERALS]; /* The literal bytes present in the Huffman tree. The EOB code is not * represented. */ local int lit_base[MAX_BITLEN+1]; /* All literals of a given bit length are contiguous in literal[] and * have contiguous codes. literal[code+lit_base[len]] is the literal * for a code of len bits. */ local int leaves [MAX_BITLEN+1]; /* Number of leaves for each bit length */ local int parents[MAX_BITLEN+1]; /* Number of parents for each bit length */ local int peek_bits; /* Number of peek bits currently used */ /* local uch prefix_len[1 << MAX_PEEK]; */ #define prefix_len outbuf /* For each bit pattern b of peek_bits bits, prefix_len[b] is the length * of the Huffman code starting with a prefix of b (upper bits), or 0 * if all codes of prefix b have more than peek_bits bits. It is not * necessary to have a huge table (large MAX_PEEK) because most of the * codes encountered in the input stream are short codes (by construction). * So for most codes a single lookup will be necessary. */ #if (1< OUTBUFSIZ error cannot overlay prefix_len and outbuf #endif local ulg bitbufulg; /* Bits are added on the low part of bitbufulg and read from the high part. */ local int valid; /* number of valid bits in bitbufulg */ /* all bits above the last valid bit are always zero */ /* Set code to the next 'bits' input bits without skipping them. code * must be the name of a simple variable and bits must not have side effects. * IN assertions: bits <= 25 (so that we still have room for an extra byte * when valid is only 24), and mask = (1<> (valid-(bits))) & (mask); \ } /* Skip the given number of bits (after having peeked at them): */ #define skip_bits(bits) (valid -= (bits)) #define clear_bitbuf() (valid = 0, bitbufulg = 0) /* =========================================================================== * Read the Huffman tree. */ local void read_tree() { int len; /* bit length */ int base; /* base offset for a sequence of leaves */ int n; /* Read the original input size, MSB first */ orig_len = 0; for (n = 1; n <= 4; n++) orig_len = (orig_len << 8) | (ulg)get_byte(); max_len = (int)get_byte(); /* maximum bit length of Huffman codes */ if (max_len > MAX_BITLEN) { error("invalid compressed data -- Huffman code > 32 bits"); } /* Get the number of leaves at each bit length */ n = 0; for (len = 1; len <= max_len; len++) { leaves[len] = (int)get_byte(); n += leaves[len]; } if (n > LITERALS) { error("too many leaves in Huffman tree"); } Trace((stderr, "orig_len %ld, max_len %d, leaves %d\n", orig_len, max_len, n)); /* There are at least 2 and at most 256 leaves of length max_len. * (Pack arbitrarily rejects empty files and files consisting of * a single byte even repeated.) To fit the last leaf count in a * byte, it is offset by 2. However, the last literal is the EOB * code, and is not transmitted explicitly in the tree, so we must * adjust here by one only. */ leaves[max_len]++; /* Now read the leaves themselves */ base = 0; for (len = 1; len <= max_len; len++) { /* Remember where the literals of this length start in literal[] : */ lit_base[len] = base; /* And read the literals: */ /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) for (n = leaves[len]; n > 0; n--) { */ for (n = leaves[len]; n > 0 && base < LITERALS; n--) { literal[base++] = (uch)get_byte(); } } leaves[max_len]++; /* Now include the EOB code in the Huffman tree */ } /* =========================================================================== * Build the Huffman tree and the prefix table. */ local void build_tree_unpack() { int nodes = 0; /* number of nodes (parents+leaves) at current bit length */ int len; /* current bit length */ uch *prefixp; /* pointer in prefix_len */ for (len = max_len; len >= 1; len--) { /* The number of parent nodes at this level is half the total * number of nodes at parent level: */ nodes >>= 1; parents[len] = nodes; /* Update lit_base by the appropriate bias to skip the parent nodes * (which are not represented in the literal array): */ lit_base[len] -= nodes; /* Restore nodes to be parents+leaves: */ nodes += leaves[len]; } /* Construct the prefix table, from shortest leaves to longest ones. * The shortest code is all ones, so we start at the end of the table. */ peek_bits = MIN(max_len, MAX_PEEK); prefixp = &prefix_len[1< prefix_len) *--prefixp = (uch)len; } /* The length of all other codes is unknown: */ while (prefixp > prefix_len) *--prefixp = 0; } /* =========================================================================== * Unpack in to out. This routine does not support the old pack format * with magic header \037\037. * * IN assertions: the buffer inbuf contains already the beginning of * the compressed data, from offsets inptr to insize-1 included. * The magic header has already been checked. The output buffer is cleared. */ local int unpack(in, out) FILE *in, *out; /* input and output file descriptors */ { int len; /* Bit length of current code */ unsigned eob; /* End Of Block code */ register unsigned peek; /* lookahead bits */ unsigned peek_mask; /* Mask for peek_bits bits */ ifd = in; ofd = out; read_tree(); /* Read the Huffman tree */ build_tree_unpack(); /* Build the prefix table */ clear_bitbuf(); /* Initialize bit input */ peek_mask = (1< 0) { peek >>= peek_bits - len; /* discard the extra bits */ } else { /* Code of more than peek_bits bits, we must traverse the tree */ ulg mask = peek_mask; len = peek_bits; do { len++, mask = (mask<<1)+1; look_bits(peek, len, mask); } while (peek < (unsigned)parents[len]); /* loop as long as peek is a parent node */ } /* At this point, peek is the next complete code, of len bits */ if (peek == eob && len == max_len) break; /* end of file? */ put_ubyte(literal[peek+lit_base[len]]); Tracev((stderr,"%02d %04x %c\n", len, peek, literal[peek+lit_base[len]])); skip_bits(len); } /* for (;;) */ flush_window(); Trace((stderr, "bytes_out %ld\n", bytes_out)); if (orig_len != (ulg)bytes_out) { error("invalid compressed data--length error"); return ERROR; } return OK; } /*=======================================================================*/ /* This marks the beginning of the original file 'unzip.c' */ /*=======================================================================*/ /* unzip.c -- decompress files in gzip or pkzip format. * Copyright (C) 1992-1993 Jean-loup Gailly * This is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, see the file COPYING. * * The code in this file is derived from the file funzip.c written * and put in the public domain by Mark Adler. */ /* This version can extract files in gzip or pkzip format. For the latter, only the first entry is extracted, and it has to be either deflated or stored. */ /* PKZIP header definitions */ #define LOCSIG 0x04034b50L /* four-byte lead-in (lsb first) */ #define LOCFLG 6 /* offset of bit flag */ #define CRPFLG 1 /* bit for encrypted entry */ #define EXTFLG 8 /* bit for extended local header */ #define LOCHOW 8 /* offset of compression method */ #define LOCTIM 10 /* file mod time (for decryption) */ #define LOCCRC 14 /* offset of crc */ #define LOCSIZ 18 /* offset of compressed size */ #define LOCLEN 22 /* offset of uncompressed length */ #define LOCFIL 26 /* offset of file name field length */ #define LOCEXT 28 /* offset of extra field length */ #define LOCHDR 30 /* size of local header, including sig */ #define EXTHDR 16 /* size of extended local header, inc sig */ /* Globals */ /* added 'static' to the following 4 lines - WDP (1/1/99) */ static int decrypt; /* flag to turn on decryption */ /* static char *key; */ /* not used--needed to link crypt.c */ static int pkzip = 0; /* set for a pkzip file */ static int ext_header = 0; /* set if extended local header */ /* =========================================================================== * Check zip file and advance inptr to the start of the compressed data. * Get ofname from the local header if necessary. */ local int check_zipfile(in) FILE *in; /* input file descriptors */ { uch *h = inbuf + inptr; /* first local header */ ifd = in; /* Check validity of local header, and skip name and extra fields */ inptr += LOCHDR + SH(h + LOCFIL) + SH(h + LOCEXT); if (inptr > insize || LG(h) != LOCSIG) { error("not a valid zip file"); exit_code = ERROR; return ERROR; } method = h[LOCHOW]; if (method != STORED && method != DEFLATED) { error("first entry not deflated or stored -- use unzip"); exit_code = ERROR; return ERROR; } /* If entry encrypted, decrypt and validate encryption header */ if ((decrypt = h[LOCFLG] & CRPFLG) != 0) { error("encrypted file -- use unzip"); exit_code = ERROR; return ERROR; } /* Save flags for unzip() */ ext_header = (h[LOCFLG] & EXTFLG) != 0; pkzip = 1; /* Get ofname and time stamp from local header (to be done) */ return OK; } /* =========================================================================== * Unzip in to out. This routine works on both gzip and pkzip files. * * IN assertions: the buffer inbuf contains already the beginning of * the compressed data, from offsets inptr to insize-1 included. * The magic header has already been checked. The output buffer is cleared. */ local int unzip(in, out) FILE *in, *out; /* input and output file descriptors */ { ulg orig_crc = 0; /* original crc */ /* orig_len has already been defined statically before */ /* ulg orig_len = 0; */ /* original uncompressed length */ int n; uch buf[EXTHDR]; /* extended local header */ ifd = in; ofd = out; updcrc(NULL, 0); /* initialize crc */ if (pkzip && !ext_header) { /* crc and length at the end otherwise */ orig_crc = LG(inbuf + LOCCRC); orig_len = LG(inbuf + LOCLEN); } /* Decompress */ if (method == DEFLATED) { int res = inflate(); if (res == 3) { error("out of memory"); return ERROR; } else if (res != 0) { error("invalid compressed data--format violated"); return ERROR; } } else if (pkzip && method == STORED) { /* 'nn' here was originally declared 'n' which conflicts with the */ /* previous local declaration of 'n'. It was changed to 'nn' on 1/4/99 */ register ulg nn = LG(inbuf + LOCLEN); if (nn != LG(inbuf + LOCSIZ) - (decrypt ? 12 : 0)) { error("invalid compressed data--length mismatch"); return ERROR; } while (nn--) { uch c = (uch)get_byte(); #ifdef CRYPT if (decrypt) zdecode(c); #endif put_ubyte(c); } flush_window(); } else { error("internal error, invalid method"); return ERROR; } /* Get the crc and original length */ if (!pkzip) { /* crc32 (see algorithm.doc) * uncompressed input size modulo 2^32 */ for (n = 0; n < 8; n++) { buf[n] = (uch)get_byte(); /* may cause an error if EOF */ } orig_crc = LG(buf); orig_len = LG(buf+4); } else if (ext_header) { /* If extended header, check it */ /* signature - 4bytes: 0x50 0x4b 0x07 0x08 * CRC-32 value * compressed size 4-bytes * uncompressed size 4-bytes */ for (n = 0; n < EXTHDR; n++) { buf[n] = (uch)get_byte(); /* may cause an error if EOF */ } orig_crc = LG(buf+4); orig_len = LG(buf+12); } /* Validate decompression */ if (orig_crc != updcrc(outbuf, 0)) { error("invalid compressed data--crc error"); return ERROR; } if (orig_len != (ulg)bytes_out) { error("invalid compressed data--length error"); return ERROR; } /* Check if there are more entries in a pkzip file */ if (pkzip && inptr + 4 < insize && LG(inbuf+inptr) == LOCSIG) { /* Don't destroy the input zip file */ error("file has more than one entry -- unchanged"); exit_code = ERROR; ext_header = pkzip = 0; return ERROR; } ext_header = pkzip = 0; /* for next file */ return OK; } /*======================================================================*/ /* This marks the start of the code originally in the file 'inflate.c' */ /*======================================================================*/ /* inflate.c -- Not copyrighted 1992 by Mark Adler version c10p1, 10 January 1993 */ /* You can do whatever you like with this source file, though I would prefer that if you modify it and redistribute it that you include comments to that effect with your name and the date. Thank you. [The history has been moved to the file ChangeLog.] */ /* Inflate deflated (PKZIP's method 8 compressed) data. The compression method searches for as much of the current string of bytes (up to a length of 258) in the previous 32K bytes. If it doesn't find any matches (of at least length 3), it codes the next byte. Otherwise, it codes the length of the matched string and its distance backwards from the current position. There is a single Huffman code that codes both single bytes (called "literals") and match lengths. A second Huffman code codes the distance information, which follows a length code. Each length or distance code actually represents a base value and a number of "extra" (sometimes zero) bits to get to add to the base value. At the end of each deflated block is a special end-of-block (EOB) literal/ length code. The decoding process is basically: get a literal/length code; if EOB then done; if a literal, emit the decoded byte; if a length then get the distance and emit the referred-to bytes from the sliding window of previously emitted data. There are (currently) three kinds of inflate blocks: stored, fixed, and dynamic. The compressor deals with some chunk of data at a time, and decides which method to use on a chunk-by-chunk basis. A chunk might typically be 32K or 64K. If the chunk is uncompressible, then the "stored" method is used. In this case, the bytes are simply stored as is, eight bits per byte, with none of the above coding. The bytes are preceded by a count, since there is no longer an EOB code. If the data is compressible, then either the fixed or dynamic methods are used. In the dynamic method, the compressed data is preceded by an encoding of the literal/length and distance Huffman codes that are to be used to decode this block. The representation is itself Huffman coded, and so is preceded by a description of that code. These code descriptions take up a little space, and so for small blocks, there is a predefined set of codes, called the fixed codes. The fixed method is used if the block codes up smaller that way (usually for quite small chunks), otherwise the dynamic method is used. In the latter case, the codes are customized to the probabilities in the current block, and so can code it much better than the pre-determined fixed codes. The Huffman codes themselves are decoded using a mutli-level table lookup, in order to maximize the speed of decoding plus the speed of building the decoding tables. See the comments below that precede the lbits and dbits tuning parameters. */ #define slide window /* Huffman code lookup table entry--this entry is four bytes for machines that have 16-bit pointers (e.g. PC's in the small or medium model). Valid extra bits are 0..13. e == 15 is EOB (end of block), e == 16 means that v is a literal, 16 < e < 32 means that v is a pointer to the next table, which codes e - 16 bits, and lastly e == 99 indicates an unused code. If a code with e == 99 is looked up, this implies an error in the data. */ /* The inflate algorithm uses a sliding 32K byte window on the uncompressed stream to find repeated byte strings. This is implemented here as a circular buffer. The index is updated simply by incrementing and then and'ing with 0x7fff (32K-1). */ /* It is left to other modules to supply the 32K area. It is assumed to be usable as if it were declared "uch slide[32768];" or as just "uch *slide;" and then malloc'ed in the latter case. The definition must be in unzip.h, included above. */ /* unsigned wp; current position in slide */ #define wp outcnt #define flush_output(w) (wp=(w),flush_window()) /* Tables for deflate from PKZIP's appnote.txt. */ static unsigned border[] = { /* Order of the bit length code lengths */ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; static ush cplens[] = { /* Copy lengths for literal codes 257..285 */ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; /* note: see note #13 above about the 258 in this list. */ static ush cplext[] = { /* Extra bits for literal codes 257..285 */ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */ static ush cpdist[] = { /* Copy offsets for distance codes 0..29 */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; static ush cpdext[] = { /* Extra bits for distance codes */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; /* Macros for inflate() bit peeking and grabbing. The usage is: NEEDBITS(j) x = b & mask_bits[j]; DUMPBITS(j) where NEEDBITS makes sure that b has at least j bits in it, and DUMPBITS removes the bits from b. The macros use the variable k for the number of bits in b. Normally, b and k are register variables for speed, and are initialized at the beginning of a routine that uses these macros from a global bit buffer and count. If we assume that EOB will be the longest code, then we will never ask for bits with NEEDBITS that are beyond the end of the stream. So, NEEDBITS should not read any more bytes than are needed to meet the request. Then no bytes need to be "returned" to the buffer at the end of the last block. However, this assumption is not true for fixed blocks--the EOB code is 7 bits, but the other literal/length codes can be 8 or 9 bits. (The EOB code is shorter than other codes because fixed blocks are generally short. So, while a block always has an EOB, many other literal/length codes have a significantly lower probability of showing up at all.) However, by making the first table have a lookup of seven bits, the EOB code will be found in that first lookup, and so will not require that too many bits be pulled from the stream. */ static ulg bb; /* bit buffer */ static unsigned bk; /* bits in bit buffer */ static ush mask_bits[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff }; #ifdef CRYPT uch cc; # define NEXTBYTE() \ (decrypt ? (cc = get_byte(), zdecode(cc), cc) : get_byte()) #else # define NEXTBYTE() (uch)get_byte() #endif #define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<>=(n);k-=(n);} /* Huffman code decoding is performed using a multi-level table lookup. The fastest way to decode is to simply build a lookup table whose size is determined by the longest code. However, the time it takes to build this table can also be a factor if the data being decoded is not very long. The most common codes are necessarily the shortest codes, so those codes dominate the decoding time, and hence the speed. The idea is you can have a shorter table that decodes the shorter, more probable codes, and then point to subsidiary tables for the longer codes. The time it costs to decode the longer codes is then traded against the time it takes to make longer tables. This results of this trade are in the variables lbits and dbits below. lbits is the number of bits the first level table for literal/ length codes can decode in one step, and dbits is the same thing for the distance codes. Subsequent tables are also less than or equal to those sizes. These values may be adjusted either when all of the codes are shorter than that, in which case the longest code length in bits is used, or when the shortest code is *longer* than the requested table size, in which case the length of the shortest code in bits is used. There are two different values for the two tables, since they code a different number of possibilities each. The literal/length table codes 286 possible values, or in a flat code, a little over eight bits. The distance table codes 30 possible values, or a little less than five bits, flat. The optimum values for speed end up being about one bit more than those, so lbits is 8+1 and dbits is 5+1. The optimum values may differ though from machine to machine, and possibly even between compilers. Your mileage may vary. */ static int lbits = 9; /* bits in base literal/length lookup table */ static int dbits = 6; /* bits in base distance lookup table */ /* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ #define BMAX 16 /* maximum bit length of any code (16 for explode) */ #define N_MAX 288 /* maximum number of codes in any set */ static unsigned hufts; /* track memory usage */ local int huft_build(b, n, s, d, e, t, m) unsigned *b; /* code lengths in bits (all assumed <= BMAX) */ unsigned n; /* number of codes (assumed <= N_MAX) */ unsigned s; /* number of simple-valued codes (0..s-1) */ ush *d; /* list of base values for non-simple codes */ ush *e; /* list of extra bits for non-simple codes */ struct huft **t; /* result: starting table */ int *m; /* maximum lookup bits, returns actual */ /* Given a list of code lengths and a maximum table size, make a set of tables to decode that set of codes. Return zero on success, one if the given code set is incomplete (the tables are still built in this case), two if the input is invalid (all zero length codes or an oversubscribed set of lengths), and three if not enough memory. */ { unsigned a; /* counter for codes of length k */ unsigned c[BMAX+1]; /* bit length count table */ unsigned f; /* i repeats in table every f entries */ int g; /* maximum code length */ int h; /* table level */ register unsigned i; /* counter, current code */ register unsigned j; /* counter */ register int k; /* number of bits in current code */ int l; /* bits per table (returned in m) */ register unsigned *p; /* pointer into c[], b[], or v[] */ register struct huft *q; /* points to current table */ struct huft r; /* table entry for structure assignment */ struct huft *u[BMAX]; /* table stack */ unsigned v[N_MAX]; /* values in order of bit length */ register int w; /* bits before this table == (l * h) */ unsigned x[BMAX+1]; /* bit offsets, then code stack */ unsigned *xp; /* pointer into x */ int y; /* number of dummy codes added */ unsigned z; /* number of entries in current table */ /* Generate counts for each bit length */ memzero(c, sizeof(c)); p = b; i = n; do { Tracecv(*p, (stderr, (n-i >= ' ' && n-i <= '~' ? "%c %d\n" : "0x%x %d\n"), n-i, *p)); c[*p]++; /* assume all entries <= BMAX */ p++; /* Can't combine with above line (Solaris bug) */ } while (--i); if (c[0] == n) /* null input--all zero length codes */ { *t = (struct huft *)NULL; *m = 0; /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) return 0; */ return 2; } /* Find minimum and maximum length, bound *m by those */ l = *m; for (j = 1; j <= BMAX; j++) if (c[j]) break; k = j; /* minimum code length */ if ((unsigned)l < j) l = j; for (i = BMAX; i; i--) if (c[i]) break; g = i; /* maximum code length */ if ((unsigned)l > i) l = i; *m = l; /* Adjust last length count to fill out codes, if needed */ for (y = 1 << j; j < i; j++, y <<= 1) if ((y -= c[j]) < 0) return 2; /* bad input: more codes than bits */ if ((y -= c[i]) < 0) return 2; c[i] += y; /* Generate starting offsets into the value table for each length */ x[1] = j = 0; p = c + 1; xp = x + 2; while (--i) { /* note that i == g from above */ *xp++ = (j += *p++); } /* Make a table of values in order of bit lengths */ p = b; i = 0; do { if ((j = *p++) != 0) v[x[j]++] = i; } while (++i < n); /* Generate the Huffman codes and for each, make the table entries */ x[0] = i = 0; /* first Huffman code is zero */ p = v; /* grab values in bit order */ h = -1; /* no tables yet--level -1 */ w = -l; /* bits decoded == (l * h) */ u[0] = (struct huft *)NULL; /* just to keep compilers happy */ q = (struct huft *)NULL; /* ditto */ z = 0; /* ditto */ /* go through the bit lengths (k already is bits in shortest code) */ for (; k <= g; k++) { a = c[k]; while (a--) { /* here i is the Huffman code of length k bits for value *p */ /* make tables up to required level */ while (k > w + l) { h++; w += l; /* previous table always l bits */ /* compute minimum size table less than or equal to l bits */ z = (z = g - w) > (unsigned)l ? l : z; /* upper limit on table size */ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ { /* too few codes for k-w bit table */ f -= a + 1; /* deduct codes from patterns left */ xp = c + k; while (++j < z) /* try smaller tables up to z bits */ { if ((f <<= 1) <= *++xp) break; /* enough codes to use up j bits */ f -= *xp; /* else deduct codes from patterns */ } } z = 1 << j; /* table entries for j-bit table */ /* allocate and link in new table */ if ((q = (struct huft *)malloc((z + 1)*sizeof(struct huft))) == (struct huft *)NULL) { if (h) huft_free(u[0]); return 3; /* not enough memory */ } hufts += z + 1; /* track memory usage */ *t = q + 1; /* link to list for huft_free() */ *(t = &(q->v.t)) = (struct huft *)NULL; u[h] = ++q; /* table starts after link */ /* connect to last table, if there is one */ if (h) { x[h] = i; /* save pattern for backing up */ r.b = (uch)l; /* bits to dump before this table */ r.e = (uch)(16 + j); /* bits in this table */ r.v.t = q; /* pointer to this table */ j = i >> (w - l); /* (get around Turbo C bug) */ u[h-1][j] = r; /* connect to last table */ } } /* set up table entry in r */ r.b = (uch)(k - w); if (p >= v + n) { r.e = 99; /* out of values--invalid code */ } else if (*p < s) { r.e = (uch)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */ r.v.n = (ush)(*p); /* simple code is just the value */ p++; /* one compiler does not like *p++ */ } else { /* WDP added this to prevent seg fault reading a particular currupted .gz file */ if (*p > 1000000)return 4; r.e = (uch)e[*p - s]; /* non-simple--look up in lists */ r.v.n = d[*p++ - s]; } /* fill code-like entries with r */ f = 1 << (k - w); for (j = i >> w; j < z; j += f) q[j] = r; /* backwards increment the k-bit code i */ for (j = 1 << (k - 1); i & j; j >>= 1) i ^= j; i ^= j; /* backup over finished tables */ while ((i & ((1 << w) - 1)) != x[h]) { h--; /* don't need to update q */ w -= l; } } } /* Return true (1) if we were given an incomplete table */ return y != 0 && g != 1; } local int huft_free(t) struct huft *t; /* table to free */ /* Free the malloc'ed tables built by huft_build(), which makes a linked list of the tables it made, with the links in a dummy first entry of each table. */ { register struct huft *p, *q; /* Go through linked list, freeing from the malloced (t[-1]) address. */ p = t; while (p != (struct huft *)NULL) { q = (--p)->v.t; free((char*)p); p = q; } return 0; } local int inflate_codes(tl, td, bl, bd) struct huft *tl, *td; /* literal/length and distance decoder tables */ int bl, bd; /* number of bits decoded by tl[] and td[] */ /* inflate (decompress) the codes in a deflated (compressed) block. Return an error code or zero if it all goes ok. */ { register unsigned e; /* table entry flag/number of extra bits */ unsigned n, d; /* length and index for copy */ unsigned w; /* current window position */ struct huft *t; /* pointer to table entry */ unsigned ml, md; /* masks for bl and bd bits */ register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ register int nloop = 0; /* make local copies of globals */ b = bb; /* initialize bit buffer */ k = bk; w = wp; /* initialize window position */ /* inflate the coded data */ ml = mask_bits[bl]; /* precompute masks for speed */ md = mask_bits[bd]; for (;;) /* do until end of block */ { /* The NEEDBITS macro (which calls NEXTBYTE, which calls get_byte, which finally calls fill_inbuf) has no way to return an error in the case of unexpected EOF. The original gunzip program simply exits in this case, but that is not acceptable for CFITSIO. Therefore, we will check how many times this loop is executed and if it looks like it is in an infinite loop then we will return with an error. WDP - Nov 1999. */ nloop++; if (nloop > 500000) { error("'inflate_codes' is in infinite loop; corrupt compressed file??"); return(1); } NEEDBITS((unsigned)bl) if ((e = (t = tl + ((unsigned)b & ml))->e) > 16) do { if (e == 99) return 1; DUMPBITS(t->b) e -= 16; NEEDBITS(e) } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16); DUMPBITS(t->b) if (e == 16) /* then it's a literal */ { slide[w++] = (uch)t->v.n; Tracevv((stderr, "%c", slide[w-1])); if (w == WSIZE) { flush_output(w); w = 0; } } else /* it's an EOB or a length */ { /* exit if end of block */ if (e == 15) break; /* get length of block to copy */ NEEDBITS(e) n = t->v.n + ((unsigned)b & mask_bits[e]); DUMPBITS(e); /* decode distance of block to copy */ NEEDBITS((unsigned)bd) if ((e = (t = td + ((unsigned)b & md))->e) > 16) do { if (e == 99) return 1; DUMPBITS(t->b) e -= 16; NEEDBITS(e) } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16); DUMPBITS(t->b) NEEDBITS(e) d = w - t->v.n - ((unsigned)b & mask_bits[e]); DUMPBITS(e) Tracevv((stderr,"\\[%d,%d]", w-d, n)); /* do the copy */ do { n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); #if !defined(NOMEMCPY) && !defined(DEBUG) if (w - d >= e) /* (this test assumes unsigned comparison) */ { memcpy(slide + w, slide + d, e); w += e; d += e; } else /* do it slow to avoid memcpy() overlap */ #endif /* !NOMEMCPY */ do { slide[w++] = slide[d++]; Tracevv((stderr, "%c", slide[w-1])); } while (--e); if (w == WSIZE) { flush_output(w); w = 0; } } while (n); } } /* restore the globals from the locals */ wp = w; /* restore global window pointer */ bb = b; /* restore global bit buffer */ bk = k; /* done */ return 0; } local int inflate_stored() /* "decompress" an inflated type 0 (stored) block. */ { unsigned n; /* number of bytes in block */ unsigned w; /* current window position */ register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ /* make local copies of globals */ b = bb; /* initialize bit buffer */ k = bk; w = wp; /* initialize window position */ /* go to byte boundary */ n = k & 7; DUMPBITS(n); /* get the length and its complement */ NEEDBITS(16) n = ((unsigned)b & 0xffff); DUMPBITS(16) NEEDBITS(16) if (n != (unsigned)((~b) & 0xffff)) return 1; /* error in compressed data */ DUMPBITS(16) /* read and output the compressed data */ while (n--) { NEEDBITS(8) slide[w++] = (uch)b; if (w == WSIZE) { flush_output(w); w = 0; } DUMPBITS(8) } /* restore the globals from the locals */ wp = w; /* restore global window pointer */ bb = b; /* restore global bit buffer */ bk = k; return 0; } local int inflate_fixed() /* decompress an inflated type 1 (fixed Huffman codes) block. We should either replace this with a custom decoder, or at least precompute the Huffman tables. */ { int i; /* temporary variable */ struct huft *tl; /* literal/length code table */ struct huft *td; /* distance code table */ int bl; /* lookup bits for tl */ int bd; /* lookup bits for td */ unsigned l[288]; /* length list for huft_build */ /* set up literal table */ for (i = 0; i < 144; i++) l[i] = 8; for (; i < 256; i++) l[i] = 9; for (; i < 280; i++) l[i] = 7; for (; i < 288; i++) /* make a complete, but wrong code set */ l[i] = 8; bl = 7; if ((i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl)) != 0) return i; /* set up distance table */ for (i = 0; i < 30; i++) /* make an incomplete code set */ l[i] = 5; bd = 5; if ((i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd)) > 1) { huft_free(tl); return i; } /* decompress until an end-of-block code */ if (inflate_codes(tl, td, bl, bd)) return 1; /* free the decoding tables, return */ huft_free(tl); huft_free(td); return 0; } local int inflate_dynamic() /* decompress an inflated type 2 (dynamic Huffman codes) block. */ { int i; /* temporary variables */ unsigned j; unsigned l; /* last length */ unsigned m; /* mask for bit lengths table */ unsigned n; /* number of lengths to get */ struct huft *tl; /* literal/length code table */ struct huft *td; /* distance code table */ int bl; /* lookup bits for tl */ int bd; /* lookup bits for td */ unsigned nb; /* number of bit length codes */ unsigned nl; /* number of literal/length codes */ unsigned nd; /* number of distance codes */ #ifdef PKZIP_BUG_WORKAROUND unsigned ll[288+32]; /* literal/length and distance code lengths */ #else unsigned ll[286+30]; /* literal/length and distance code lengths */ #endif register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ /* make local bit buffer */ b = bb; k = bk; /* read in table lengths */ NEEDBITS(5) nl = 257 + ((unsigned)b & 0x1f); /* number of literal/length codes */ DUMPBITS(5) NEEDBITS(5) nd = 1 + ((unsigned)b & 0x1f); /* number of distance codes */ DUMPBITS(5) NEEDBITS(4) nb = 4 + ((unsigned)b & 0xf); /* number of bit length codes */ DUMPBITS(4) #ifdef PKZIP_BUG_WORKAROUND if (nl > 288 || nd > 32) #else if (nl > 286 || nd > 30) #endif return 1; /* bad lengths */ /* read in bit-length-code lengths */ for (j = 0; j < nb; j++) { NEEDBITS(3) ll[border[j]] = (unsigned)b & 7; DUMPBITS(3) } for (; j < 19; j++) ll[border[j]] = 0; /* build decoding table for trees--single level, 7 bit lookup */ bl = 7; if ((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl)) != 0) { if (i == 1) huft_free(tl); return i; /* incomplete code set */ } /* read in literal and distance code lengths */ n = nl + nd; m = mask_bits[bl]; i = l = 0; while ((unsigned)i < n) { NEEDBITS((unsigned)bl) j = (td = tl + ((unsigned)b & m))->b; DUMPBITS(j) j = td->v.n; if (j < 16) /* length of code in bits (0..15) */ ll[i++] = l = j; /* save last length in l */ else if (j == 16) /* repeat last length 3 to 6 times */ { NEEDBITS(2) j = 3 + ((unsigned)b & 3); DUMPBITS(2) if ((unsigned)i + j > n) return 1; while (j--) ll[i++] = l; } else if (j == 17) /* 3 to 10 zero length codes */ { NEEDBITS(3) j = 3 + ((unsigned)b & 7); DUMPBITS(3) if ((unsigned)i + j > n) return 1; while (j--) ll[i++] = 0; l = 0; } else /* j == 18: 11 to 138 zero length codes */ { NEEDBITS(7) j = 11 + ((unsigned)b & 0x7f); DUMPBITS(7) if ((unsigned)i + j > n) return 1; while (j--) ll[i++] = 0; l = 0; } } /* free decoding table for trees */ huft_free(tl); /* restore the global bit buffer */ bb = b; bk = k; /* build the decoding tables for literal/length and distance codes */ bl = lbits; if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0) { if (i == 1) { error(" incomplete literal tree in inflate_dynamic"); huft_free(tl); } return i; /* incomplete code set */ } bd = dbits; if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0) { if (i == 1) { error(" incomplete distance tree in inflate_dynamic"); #ifdef PKZIP_BUG_WORKAROUND i = 0; } #else huft_free(td); } huft_free(tl); return i; /* incomplete code set */ #endif } /* decompress until an end-of-block code */ if (inflate_codes(tl, td, bl, bd)) return 1; /* free the decoding tables, return */ huft_free(tl); huft_free(td); return 0; } local int inflate_block(e) int *e; /* last block flag */ /* decompress an inflated block */ { unsigned t; /* block type */ register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ /* make local bit buffer */ b = bb; k = bk; /* read in last block bit */ NEEDBITS(1) *e = (int)b & 1; DUMPBITS(1) /* read in block type */ NEEDBITS(2) t = (unsigned)b & 3; DUMPBITS(2) /* restore the global bit buffer */ bb = b; bk = k; /* inflate that block type */ if (t == 2) return inflate_dynamic(); if (t == 0) return inflate_stored(); if (t == 1) return inflate_fixed(); /* bad block type */ return 2; } local int inflate() /* decompress an inflated entry */ { int e; /* last block flag */ int r; /* result code */ unsigned h; /* maximum struct huft's malloc'ed */ /* initialize window, bit buffer */ wp = 0; bk = 0; bb = 0; /* decompress until the last block */ h = 0; do { hufts = 0; if ((r = inflate_block(&e)) != 0) return r; if (hufts > h) h = hufts; } while (!e); /* Undo too much lookahead. The next read will be byte aligned so we * can discard unused bits in the last meaningful byte. */ while (bk >= 8) { bk -= 8; inptr--; } /* flush out slide */ flush_output(wp); return 0; } /* *********************** */ /* start of file deflate.c */ /* *********************** */ /* deflate.c -- compress data using the deflation algorithm * Copyright (C) 1992-1993 Jean-loup Gailly * This is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, see the file COPYING. */ /* * PURPOSE * * Identify new text as repetitions of old text within a fixed- * length sliding window trailing behind the new text. * * DISCUSSION * * The "deflation" process depends on being able to identify portions * of the input text which are identical to earlier input (within a * sliding window trailing behind the input currently being processed). * * The most straightforward technique turns out to be the fastest for * most input files: try all possible matches and select the longest. * The key feature of this algorithm is that insertions into the string * dictionary are very simple and thus fast, and deletions are avoided * completely. Insertions are performed at each input character, whereas * string matches are performed only when the previous match ends. So it * is preferable to spend more time in matches to allow very fast string * insertions and avoid deletions. The matching algorithm for small * strings is inspired from that of Rabin & Karp. A brute force approach * is used to find longer strings when a small match has been found. * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze * (by Leonid Broukhis). * A previous version of this file used a more sophisticated algorithm * (by Fiala and Greene) which is guaranteed to run in linear amortized * time, but has a larger average cost, uses more memory and is patented. * However the F&G algorithm may be faster for some highly redundant * files if the parameter max_chain_length (described below) is too large. * * ACKNOWLEDGEMENTS * * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and * I found it in 'freeze' written by Leonid Broukhis. * Thanks to many info-zippers for bug reports and testing. * * REFERENCES * * APPNOTE.TXT documentation file in PKZIP 1.93a distribution. * * A description of the Rabin and Karp algorithm is given in the book * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. * * Fiala,E.R., and Greene,D.H. * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 * * INTERFACE * * void lm_init (int pack_level, ush *flags) * Initialize the "longest match" routines for a new file * * ulg deflate (void) * Processes a new input file and return its compressed length. Sets * the compressed length, crc, deflate flags and internal file * attributes. */ /* =========================================================================== * Configuration parameters */ /* Compile with MEDIUM_MEM to reduce the memory requirements or * with SMALL_MEM to use as little memory as possible. Use BIG_MEM if the * entire input file can be held in memory (not possible on 16 bit systems). * Warning: defining these symbols affects HASH_BITS (see below) and thus * affects the compression ratio. The compressed output * is still correct, and might even be smaller in some cases. */ #ifdef SMALL_MEM # define HASH_BITS 13 /* Number of bits used to hash strings */ #endif #ifdef MEDIUM_MEM # define HASH_BITS 14 #endif #ifndef HASH_BITS # define HASH_BITS 15 /* For portability to 16 bit machines, do not use values above 15. */ #endif /* To save space (see unlzw.c), we overlay prev+head with tab_prefix and * window with tab_suffix. Check that we can do this: */ #if (WSIZE<<1) > (1< BITS-1 error: cannot overlay head with tab_prefix1 #endif #define HASH_SIZE (unsigned)(1<= HASH_BITS */ unsigned int near prev_length; /* Length of the best match at previous step. Matches not greater than this * are discarded. This is used in the lazy match evaluation. */ unsigned near strstart; /* start of string to insert */ unsigned near match_start; /* start of matching string */ local int eofile; /* flag set at end of input file */ local unsigned lookahead; /* number of valid bytes ahead in window */ unsigned near max_chain_length; /* To speed up deflation, hash chains are never searched beyond this length. * A higher limit improves compression ratio but degrades the speed. */ local unsigned int max_lazy_match; /* Attempt to find a better match only when the current match is strictly * smaller than this value. This mechanism is used only for compression * levels >= 4. */ #define max_insert_length max_lazy_match /* Insert new strings in the hash table only if the match length * is not greater than this length. This saves time but degrades compression. * max_insert_length is used only for compression levels <= 3. */ local int compr_level; /* compression level (1..9) */ unsigned near good_match; /* Use a faster search when the previous match is longer than this */ /* Values for max_lazy_match, good_match and max_chain_length, depending on * the desired pack level (0..9). The values given below have been tuned to * exclude worst case performance for pathological files. Better values may be * found for specific files. */ typedef struct config { ush good_length; /* reduce lazy search above this match length */ ush max_lazy; /* do not perform lazy search above this match length */ ush nice_length; /* quit search above this match length */ ush max_chain; } config; #ifdef FULL_SEARCH # define nice_match MAX_MATCH #else int near nice_match; /* Stop searching when current match exceeds this */ #endif local config configuration_table[10] = { /* good lazy nice chain */ /* 0 */ {0, 0, 0, 0}, /* store only */ /* 1 */ {4, 4, 8, 4}, /* maximum speed, no lazy matches */ /* 2 */ {4, 5, 16, 8}, /* 3 */ {4, 6, 32, 32}, /* 4 */ {4, 4, 16, 16}, /* lazy matches */ /* 5 */ {8, 16, 32, 32}, /* 6 */ {8, 16, 128, 128}, /* 7 */ {8, 32, 128, 256}, /* 8 */ {32, 128, 258, 1024}, /* 9 */ {32, 258, 258, 4096}}; /* maximum compression */ /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 * For deflate_fast() (levels <= 3) good is ignored and lazy has a different * meaning. */ #define EQUAL 0 /* result of memcmp for equal strings */ /* =========================================================================== * Prototypes for local functions. */ local void fill_window OF((void)); local ulg deflate_fast OF((void)); int longest_match OF((IPos cur_match)); #ifdef ASMV void match_init OF((void)); /* asm code initialization */ #endif #ifdef DEBUG local void check_match OF((IPos start, IPos match, int length)); #endif /* =========================================================================== * Update a hash value with the given input byte * IN assertion: all calls to to UPDATE_HASH are made with consecutive * input characters, so that a running hash key can be computed from the * previous key instead of complete recalculation each time. */ #define UPDATE_HASH(h,c) (h = (((h)< 9) error("bad pack level"); compr_level = pack_level; /* Initialize the hash table. */ #if defined(MAXSEG_64K) && HASH_BITS == 15 for (j = 0; j < HASH_SIZE; j++) head[j] = NIL; #else memzero((char*)head, HASH_SIZE*sizeof(*head)); #endif /* prev will be initialized on the fly */ /* Set the default configuration parameters: */ max_lazy_match = configuration_table[pack_level].max_lazy; good_match = configuration_table[pack_level].good_length; #ifndef FULL_SEARCH nice_match = configuration_table[pack_level].nice_length; #endif max_chain_length = configuration_table[pack_level].max_chain; if (pack_level == 1) { *flags |= FAST; } else if (pack_level == 9) { *flags |= SLOW; } /* ??? reduce max_chain_length for binary files */ strstart = 0; block_start = 0L; #ifdef ASMV match_init(); /* initialize the asm code */ #endif lookahead = read_buf((char*)window, sizeof(int) <= 2 ? (unsigned)WSIZE : 2*WSIZE); if (lookahead == 0 || lookahead == (unsigned)EOF) { eofile = 1, lookahead = 0; return; } eofile = 0; /* Make sure that we always have enough lookahead. This is important * if input comes from a device such as a tty. */ while (lookahead < MIN_LOOKAHEAD && !eofile) fill_window(); ins_h = 0; for (j=0; j= 1 */ #ifndef ASMV /* For MSDOS, OS/2 and 386 Unix, an optimized version is in match.asm or * match.s. The code is functionally equivalent, so you can use the C version * if desired. */ int longest_match(cur_match) IPos cur_match; /* current match */ { unsigned chain_length = max_chain_length; /* max hash chain length */ register uch *scan = window + strstart; /* current string */ register uch *match; /* matched string */ register int len; /* length of current match */ int best_len = prev_length; /* best match length so far */ IPos limit = strstart > (IPos)MAX_DIST ? strstart - (IPos)MAX_DIST : NIL; /* Stop when cur_match becomes <= limit. To simplify the code, * we prevent matches with the string of window index 0. */ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. * It is easy to get rid of this optimization if necessary. */ #if HASH_BITS < 8 || MAX_MATCH != 258 error: Code too clever #endif #ifdef UNALIGNED_OK /* Compare two bytes at a time. Note: this is not always beneficial. * Try with and without -DUNALIGNED_OK to check. */ register uch *strend = window + strstart + MAX_MATCH - 1; register ush scan_start = *(ush*)scan; register ush scan_end = *(ush*)(scan+best_len-1); #else register uch *strend = window + strstart + MAX_MATCH; register uch scan_end1 = scan[best_len-1]; register uch scan_end = scan[best_len]; #endif /* Do not waste too much time if we already have a good match: */ if (prev_length >= good_match) { chain_length >>= 2; } Assert(strstart <= window_size-MIN_LOOKAHEAD, "insufficient lookahead"); do { Assert(cur_match < strstart, "no future"); match = window + cur_match; /* Skip to next match if the match length cannot increase * or if the match length is less than 2: */ #if (defined(UNALIGNED_OK) && MAX_MATCH == 258) /* This code assumes sizeof(unsigned short) == 2. Do not use * UNALIGNED_OK if your compiler uses a different size. */ if (*(ush*)(match+best_len-1) != scan_end || *(ush*)match != scan_start) continue; /* It is not necessary to compare scan[2] and match[2] since they are * always equal when the other bytes match, given that the hash keys * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at * strstart+3, +5, ... up to strstart+257. We check for insufficient * lookahead only every 4th comparison; the 128th check will be made * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is * necessary to put more guard bytes at the end of the window, or * to check more often for insufficient lookahead. */ scan++, match++; do { } while (*(ush*)(scan+=2) == *(ush*)(match+=2) && *(ush*)(scan+=2) == *(ush*)(match+=2) && *(ush*)(scan+=2) == *(ush*)(match+=2) && *(ush*)(scan+=2) == *(ush*)(match+=2) && scan < strend); /* The funny "do {}" generates better code on most compilers */ /* Here, scan <= window+strstart+257 */ Assert(scan <= window+(unsigned)(window_size-1), "wild scan"); if (*scan == *match) scan++; len = (MAX_MATCH - 1) - (int)(strend-scan); scan = strend - (MAX_MATCH-1); #else /* UNALIGNED_OK */ if (match[best_len] != scan_end || match[best_len-1] != scan_end1 || *match != *scan || *++match != scan[1]) continue; /* The check at best_len-1 can be removed because it will be made * again later. (This heuristic is not always a win.) * It is not necessary to compare scan[2] and match[2] since they * are always equal when the other bytes match, given that * the hash keys are equal and that HASH_BITS >= 8. */ scan += 2, match++; /* We check for insufficient lookahead only every 8th comparison; * the 256th check will be made at strstart+258. */ do { } while (*++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && scan < strend); len = MAX_MATCH - (int)(strend - scan); scan = strend - MAX_MATCH; #endif /* UNALIGNED_OK */ if (len > best_len) { match_start = cur_match; best_len = len; if (len >= nice_match) break; #ifdef UNALIGNED_OK scan_end = *(ush*)(scan+best_len-1); #else scan_end1 = scan[best_len-1]; scan_end = scan[best_len]; #endif } } while ((cur_match = prev[cur_match & WMASK]) > limit && --chain_length != 0); return best_len; } #endif /* ASMV */ #ifdef DEBUG /* =========================================================================== * Check that the match at match_start is indeed a match. */ local void check_match(start, match, length) IPos start, match; int length; { /* check that the match is indeed a match */ if (memcmp((char*)window + match, (char*)window + start, length) != EQUAL) { fprintf(stderr, " start %d, match %d, length %d\n", start, match, length); error("invalid match"); } if (verbose > 1) { fprintf(stderr,"\\[%d,%d]", start-match, length); do { putc(window[start++], stderr); } while (--length != 0); } } #else # define check_match(start, match, length) #endif /* =========================================================================== * Fill the window when the lookahead becomes insufficient. * Updates strstart and lookahead, and sets eofile if end of input file. * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0 * OUT assertions: at least one byte has been read, or eofile is set; * file reads are performed for at least two bytes (required for the * translate_eol option). */ local void fill_window() { register unsigned n, m; unsigned more = (unsigned)(window_size - (ulg)lookahead - (ulg)strstart); /* Amount of free space at the end of the window. */ /* If the window is almost full and there is insufficient lookahead, * move the upper half to the lower one to make room in the upper half. */ if (more == (unsigned)EOF) { /* Very unlikely, but possible on 16 bit machine if strstart == 0 * and lookahead == 1 (input done one byte at time) */ more--; } else if (strstart >= WSIZE+MAX_DIST) { /* By the IN assertion, the window is not empty so we can't confuse * more == 0 with more == 64K on a 16 bit machine. */ Assert(window_size == (ulg)2*WSIZE, "no sliding with BIG_MEM"); memcpy((char*)window, (char*)window+WSIZE, (unsigned)WSIZE); match_start -= WSIZE; strstart -= WSIZE; /* we now have strstart >= MAX_DIST: */ block_start -= (long) WSIZE; for (n = 0; n < HASH_SIZE; n++) { m = head[n]; head[n] = (Pos)(m >= WSIZE ? m-WSIZE : NIL); } for (n = 0; n < WSIZE; n++) { m = prev[n]; prev[n] = (Pos)(m >= WSIZE ? m-WSIZE : NIL); /* If n is not on any hash chain, prev[n] is garbage but * its value will never be used. */ } more += WSIZE; } /* At this point, more >= 2 */ if (!eofile) { n = read_buf((char*)window+strstart+lookahead, more); if (n == 0 || n == (unsigned)EOF) { eofile = 1; } else { lookahead += n; } } } /* =========================================================================== * Flush the current block, with given end-of-file flag. * IN assertion: strstart is set to the end of the current match. */ #define FLUSH_BLOCK(eof) \ flush_block(block_start >= 0L ? (char*)&window[(unsigned)block_start] : \ (char*)NULL, (long)strstart - block_start, (eof)) /* =========================================================================== * Processes a new input file and return its compressed length. This * function does not perform lazy evaluationof matches and inserts * new strings in the dictionary only for unmatched strings or for short * matches. It is used only for the fast compression options. */ local ulg deflate_fast() { IPos hash_head; /* head of the hash chain */ int flush; /* set if current block must be flushed */ unsigned match_length = 0; /* length of best match */ prev_length = MIN_MATCH-1; while (lookahead != 0) { /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ INSERT_STRING(strstart, hash_head); /* Find the longest match, discarding those <= prev_length. * At this point we have always match_length < MIN_MATCH */ if (hash_head != NIL && strstart - hash_head <= MAX_DIST) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ match_length = longest_match (hash_head); /* longest_match() sets match_start */ if (match_length > lookahead) match_length = lookahead; } if (match_length >= MIN_MATCH) { check_match(strstart, match_start, match_length); flush = ct_tally(strstart-match_start, match_length - MIN_MATCH); lookahead -= match_length; /* Insert new strings in the hash table only if the match length * is not too large. This saves time but degrades compression. */ if (match_length <= max_insert_length) { match_length--; /* string at strstart already in hash table */ do { strstart++; INSERT_STRING(strstart, hash_head); /* strstart never exceeds WSIZE-MAX_MATCH, so there are * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH * these bytes are garbage, but it does not matter since * the next lookahead bytes will be emitted as literals. */ } while (--match_length != 0); strstart++; } else { strstart += match_length; match_length = 0; ins_h = window[strstart]; UPDATE_HASH(ins_h, window[strstart+1]); #if MIN_MATCH != 3 Call UPDATE_HASH() MIN_MATCH-3 more times #endif } } else { /* No match, output a literal byte */ Tracevv((stderr,"%c",window[strstart])); flush = ct_tally (0, window[strstart]); lookahead--; strstart++; } if (flush) FLUSH_BLOCK(0), block_start = strstart; /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ while (lookahead < MIN_LOOKAHEAD && !eofile) fill_window(); } return FLUSH_BLOCK(1); /* eof */ } /* =========================================================================== * Same as above, but achieves better compression. We use a lazy * evaluation for matches: a match is finally adopted only if there is * no better match at the next window position. */ ulg deflate() { IPos hash_head; /* head of hash chain */ IPos prev_match; /* previous match */ int flush; /* set if current block must be flushed */ int match_available = 0; /* set if previous match exists */ register unsigned match_length = MIN_MATCH-1; /* length of best match */ #ifdef DEBUG extern long isize; /* byte length of input file, for debug only */ #endif if (compr_level <= 3) return deflate_fast(); /* optimized for speed */ /* Process the input block. */ while (lookahead != 0) { /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ INSERT_STRING(strstart, hash_head); /* Find the longest match, discarding those <= prev_length. */ prev_length = match_length, prev_match = match_start; match_length = MIN_MATCH-1; if (hash_head != NIL && prev_length < max_lazy_match && strstart - hash_head <= MAX_DIST) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ match_length = longest_match (hash_head); /* longest_match() sets match_start */ if (match_length > lookahead) match_length = lookahead; /* Ignore a length 3 match if it is too distant: */ if (match_length == MIN_MATCH && strstart-match_start > TOO_FAR){ /* If prev_match is also MIN_MATCH, match_start is garbage * but we will ignore the current match anyway. */ match_length--; } } /* If there was a match at the previous step and the current * match is not better, output the previous match: */ if (prev_length >= MIN_MATCH && match_length <= prev_length) { check_match(strstart-1, prev_match, prev_length); flush = ct_tally(strstart-1-prev_match, prev_length - MIN_MATCH); /* Insert in hash table all strings up to the end of the match. * strstart-1 and strstart are already inserted. */ lookahead -= prev_length-1; prev_length -= 2; do { strstart++; INSERT_STRING(strstart, hash_head); /* strstart never exceeds WSIZE-MAX_MATCH, so there are * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH * these bytes are garbage, but it does not matter since the * next lookahead bytes will always be emitted as literals. */ } while (--prev_length != 0); match_available = 0; match_length = MIN_MATCH-1; strstart++; if (flush) FLUSH_BLOCK(0), block_start = strstart; } else if (match_available) { /* If there was no match at the previous position, output a * single literal. If there was a match but the current match * is longer, truncate the previous match to a single literal. */ Tracevv((stderr,"%c",window[strstart-1])); if (ct_tally (0, window[strstart-1])) { FLUSH_BLOCK(0), block_start = strstart; } strstart++; lookahead--; } else { /* There is no previous match to compare with, wait for * the next step to decide. */ match_available = 1; strstart++; lookahead--; } Assert (strstart <= isize && lookahead <= isize, "a bit too far"); /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ while (lookahead < MIN_LOOKAHEAD && !eofile) fill_window(); } if (match_available) ct_tally (0, window[strstart-1]); return FLUSH_BLOCK(1); /* eof */ } /* ********************** */ /* start of file trees.c */ /* ********************** */ /* trees.c -- output deflated data using Huffman coding * Copyright (C) 1992-1993 Jean-loup Gailly * This is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, see the file COPYING. */ /* * PURPOSE * * Encode various sets of source values using variable-length * binary code trees. * * DISCUSSION * * The PKZIP "deflation" process uses several Huffman trees. The more * common source values are represented by shorter bit sequences. * * Each code tree is stored in the ZIP file in a compressed form * which is itself a Huffman encoding of the lengths of * all the code strings (in ascending order by source values). * The actual code strings are reconstructed from the lengths in * the UNZIP process, as described in the "application note" * (APPNOTE.TXT) distributed as part of PKWARE's PKZIP program. * * REFERENCES * * Lynch, Thomas J. * Data Compression: Techniques and Applications, pp. 53-55. * Lifetime Learning Publications, 1985. ISBN 0-534-03418-7. * * Storer, James A. * Data Compression: Methods and Theory, pp. 49-50. * Computer Science Press, 1988. ISBN 0-7167-8156-5. * * Sedgewick, R. * Algorithms, p290. * Addison-Wesley, 1983. ISBN 0-201-06672-6. * * INTERFACE * * void ct_init (ush *attr, int *methodp) * Allocate the match buffer, initialize the various tables and save * the location of the internal file attribute (ascii/binary) and * method (DEFLATE/STORE) * * void ct_tally (int dist, int lc); * Save the match info and tally the frequency counts. * * long flush_block (char *buf, ulg stored_len, int eof) * Determine the best encoding for the current block: dynamic trees, * static trees or store, and output the encoded block to the zip * file. Returns the total compressed length for the file so far. * */ /* =========================================================================== * Constants */ #define MAX_BITS 15 /* All codes must not exceed MAX_BITS bits */ #define MAX_BL_BITS 7 /* Bit length codes must not exceed MAX_BL_BITS bits */ #define LENGTH_CODES 29 /* number of length codes, not counting the special END_BLOCK code */ #define LITERALS 256 /* number of literal bytes 0..255 */ #define END_BLOCK 256 /* end of block literal code */ #define L_CODES (LITERALS+1+LENGTH_CODES) /* number of Literal or Length codes, including the END_BLOCK code */ #define D_CODES 30 /* number of distance codes */ #define BL_CODES 19 /* number of codes used to transfer the bit lengths */ local int near extra_lbits[LENGTH_CODES] /* extra bits for each length code */ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; local int near extra_dbits[D_CODES] /* extra bits for each distance code */ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; local int near extra_blbits[BL_CODES]/* extra bits for each bit length code */ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; #define STORED_BLOCK 0 #define STATIC_TREES 1 #define DYN_TREES 2 /* The three kinds of block type */ #ifndef LIT_BUFSIZE # ifdef SMALL_MEM # define LIT_BUFSIZE 0x2000 # else # ifdef MEDIUM_MEM # define LIT_BUFSIZE 0x4000 # else # define LIT_BUFSIZE 0x8000 # endif # endif #endif #ifndef DIST_BUFSIZE # define DIST_BUFSIZE LIT_BUFSIZE #endif /* Sizes of match buffers for literals/lengths and distances. There are * 4 reasons for limiting LIT_BUFSIZE to 64K: * - frequencies can be kept in 16 bit counters * - if compression is not successful for the first block, all input data is * still in the window so we can still emit a stored block even when input * comes from standard input. (This can also be done for all blocks if * LIT_BUFSIZE is not greater than 32K.) * - if compression is not successful for a file smaller than 64K, we can * even emit a stored file instead of a stored block (saving 5 bytes). * - creating new Huffman trees less frequently may not provide fast * adaptation to changes in the input data statistics. (Take for * example a binary file with poorly compressible code followed by * a highly compressible string table.) Smaller buffer sizes give * fast adaptation but have of course the overhead of transmitting trees * more frequently. * - I can't count above 4 * The current code is general and allows DIST_BUFSIZE < LIT_BUFSIZE (to save * memory at the expense of compression). Some optimizations would be possible * if we rely on DIST_BUFSIZE == LIT_BUFSIZE. */ #if LIT_BUFSIZE > INBUFSIZ error cannot overlay l_buf and inbuf #endif #define REP_3_6 16 /* repeat previous bit length 3-6 times (2 bits of repeat count) */ #define REPZ_3_10 17 /* repeat a zero length 3-10 times (3 bits of repeat count) */ #define REPZ_11_138 18 /* repeat a zero length 11-138 times (7 bits of repeat count) */ /* =========================================================================== * Local data */ /* Data structure describing a single value and its code string. */ typedef struct ct_data { union { ush freq; /* frequency count */ ush code; /* bit string */ } fc; union { ush dad; /* father node in Huffman tree */ ush len; /* length of bit string */ } dl; } ct_data; #define Freq fc.freq #define Code fc.code #define Dad dl.dad #define Len dl.len #define HEAP_SIZE (2*L_CODES+1) /* maximum heap size */ local ct_data near dyn_ltree[HEAP_SIZE]; /* literal and length tree */ local ct_data near dyn_dtree[2*D_CODES+1]; /* distance tree */ local ct_data near static_ltree[L_CODES+2]; /* The static literal tree. Since the bit lengths are imposed, there is no * need for the L_CODES extra codes used during heap construction. However * The codes 286 and 287 are needed to build a canonical tree (see ct_init * below). */ local ct_data near static_dtree[D_CODES]; /* The static distance tree. (Actually a trivial tree since all codes use * 5 bits.) */ local ct_data near bl_tree[2*BL_CODES+1]; /* Huffman tree for the bit lengths */ typedef struct tree_desc { ct_data near *dyn_tree; /* the dynamic tree */ ct_data near *static_tree; /* corresponding static tree or NULL */ int near *extra_bits; /* extra bits for each code or NULL */ int extra_base; /* base index for extra_bits */ int elems; /* max number of elements in the tree */ int max_length; /* max bit length for the codes */ int max_code; /* largest code with non zero frequency */ } tree_desc; local tree_desc near l_desc = {dyn_ltree, static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS, 0}; local tree_desc near d_desc = {dyn_dtree, static_dtree, extra_dbits, 0, D_CODES, MAX_BITS, 0}; local tree_desc near bl_desc = {bl_tree, (ct_data near *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS, 0}; local ush near bl_count[MAX_BITS+1]; /* number of codes at each bit length for an optimal tree */ local uch near bl_order[BL_CODES] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; /* The lengths of the bit length codes are sent in order of decreasing * probability, to avoid transmitting the lengths for unused bit length codes. */ local int near heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ local int heap_len; /* number of elements in the heap */ local int heap_max; /* element of largest frequency */ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. * The same heap array is used to build all trees. */ local uch near depth[2*L_CODES+1]; /* Depth of each subtree used as tie breaker for trees of equal frequency */ local uch length_code[MAX_MATCH-MIN_MATCH+1]; /* length code for each normalized match length (0 == MIN_MATCH) */ local uch dist_code[512]; /* distance codes. The first 256 values correspond to the distances * 3 .. 258, the last 256 values correspond to the top 8 bits of * the 15 bit distances. */ local int near base_length[LENGTH_CODES]; /* First normalized length for each code (0 = MIN_MATCH) */ local int near base_dist[D_CODES]; /* First normalized distance for each code (0 = distance of 1) */ #define l_buf inbuf /* DECLARE(uch, l_buf, LIT_BUFSIZE); buffer for literals or lengths */ /* DECLARE(ush, d_buf, DIST_BUFSIZE); buffer for distances */ local uch near flag_buf[(LIT_BUFSIZE/8)]; /* flag_buf is a bit array distinguishing literals from lengths in * l_buf, thus indicating the presence or absence of a distance. */ local unsigned last_lit; /* running index in l_buf */ local unsigned last_dist; /* running index in d_buf */ local unsigned last_flags; /* running index in flag_buf */ local uch flags; /* current flags not yet saved in flag_buf */ local uch flag_bit; /* current bit used in flags */ /* bits are filled in flags starting at bit 0 (least significant). * Note: these flags are overkill in the current code since we don't * take advantage of DIST_BUFSIZE == LIT_BUFSIZE. */ local ulg opt_len; /* bit length of current block with optimal trees */ local ulg static_len; /* bit length of current block with static trees */ local ulg compressed_len; /* total bit length of compressed file */ local ulg input_len; /* total byte length of input file */ /* input_len is for debugging only since we can get it by other means. */ int *file_method; /* pointer to DEFLATE or STORE */ #ifdef DEBUG extern ulg bits_sent; /* bit length of the compressed data */ extern long isize; /* byte length of input file */ #endif extern long block_start; /* window offset of current block */ extern unsigned near strstart; /* window offset of current string */ /* =========================================================================== * Local (static) routines in this file. */ local void init_block OF((void)); local void pqdownheap OF((ct_data near *tree, int k)); local void gen_bitlen OF((tree_desc near *desc)); local void gen_codes OF((ct_data near *tree, int max_code)); local void build_tree OF((tree_desc near *desc)); local void scan_tree OF((ct_data near *tree, int max_code)); local void send_tree OF((ct_data near *tree, int max_code)); local int build_bl_tree OF((void)); local void send_all_trees OF((int lcodes, int dcodes, int blcodes)); local void compress_block OF((ct_data near *ltree, ct_data near *dtree)); # define send_code(c, tree) send_bits(tree[c].Code, tree[c].Len) /* Send a code of the given tree. c and tree must not have side effects */ #define d_code(dist) \ ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)]) /* Mapping from a distance to a distance code. dist is the distance - 1 and * must not have side effects. dist_code[256] and dist_code[257] are never * used. */ #define MAX(a,b) (a >= b ? a : b) /* the arguments must not have side effects */ /* =========================================================================== * Allocate the match buffer, initialize the various tables and save the * location of the internal file attribute (ascii/binary) and method * (DEFLATE/STORE). */ void ct_init(attr, methodp) ush *attr; /* pointer to internal file attribute */ int *methodp; /* pointer to compression method */ { int n; /* iterates over tree elements */ int bits; /* bit counter */ int length; /* length value */ int code; /* code value */ int dist; /* distance index */ file_method = methodp; compressed_len = input_len = 0L; if (static_dtree[0].Len != 0) return; /* ct_init already called */ /* Initialize the mapping length (0..255) -> length code (0..28) */ length = 0; for (code = 0; code < LENGTH_CODES-1; code++) { base_length[code] = length; for (n = 0; n < (1< dist code (0..29) */ dist = 0; for (code = 0 ; code < 16; code++) { base_dist[code] = dist; for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ for ( ; code < D_CODES; code++) { base_dist[code] = dist << 7; for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { dist_code[256 + dist++] = (uch)code; } } Assert (dist == 256, "ct_init: 256+dist != 512"); /* Construct the codes of the static literal tree */ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; n = 0; while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; /* Codes 286 and 287 do not exist, but we must include them in the * tree construction to get a canonical Huffman tree (longest code * all ones) */ gen_codes((ct_data near *)static_ltree, L_CODES+1); /* The static distance tree is trivial: */ for (n = 0; n < D_CODES; n++) { static_dtree[n].Len = 5; static_dtree[n].Code = bi_reverse(n, 5); } /* Initialize the first block of the first file: */ init_block(); } /* =========================================================================== * Initialize a new block. */ local void init_block() { int n; /* iterates over tree elements */ /* Initialize the trees. */ for (n = 0; n < L_CODES; n++) dyn_ltree[n].Freq = 0; for (n = 0; n < D_CODES; n++) dyn_dtree[n].Freq = 0; for (n = 0; n < BL_CODES; n++) bl_tree[n].Freq = 0; dyn_ltree[END_BLOCK].Freq = 1; opt_len = static_len = 0L; last_lit = last_dist = last_flags = 0; flags = 0; flag_bit = 1; } #define SMALLEST 1 /* Index within the heap array of least frequent node in the Huffman tree */ /* =========================================================================== * Remove the smallest element from the heap and recreate the heap with * one less element. Updates heap and heap_len. */ #define pqremove(tree, top) \ {\ top = heap[SMALLEST]; \ heap[SMALLEST] = heap[heap_len--]; \ pqdownheap(tree, SMALLEST); \ } /* =========================================================================== * Compares to subtrees, using the tree depth as tie breaker when * the subtrees have equal frequency. This minimizes the worst case length. */ #define smaller(tree, n, m) \ (tree[n].Freq < tree[m].Freq || \ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) /* =========================================================================== * Restore the heap property by moving down the tree starting at node k, * exchanging a node with the smallest of its two sons if necessary, stopping * when the heap property is re-established (each father smaller than its * two sons). */ local void pqdownheap(tree, k) ct_data near *tree; /* the tree to restore */ int k; /* node to move down */ { int v = heap[k]; int j = k << 1; /* left son of k */ while (j <= heap_len) { /* Set j to the smallest of the two sons: */ if (j < heap_len && smaller(tree, heap[j+1], heap[j])) j++; /* Exit if v is smaller than both sons */ if (smaller(tree, v, heap[j])) break; /* Exchange v with the smallest son */ heap[k] = heap[j]; k = j; /* And continue down the tree, setting j to the left son of k */ j <<= 1; } heap[k] = v; } /* =========================================================================== * Compute the optimal bit lengths for a tree and update the total bit length * for the current block. * IN assertion: the fields freq and dad are set, heap[heap_max] and * above are the tree nodes sorted by increasing frequency. * OUT assertions: the field len is set to the optimal bit length, the * array bl_count contains the frequencies for each bit length. * The length opt_len is updated; static_len is also updated if stree is * not null. */ local void gen_bitlen(desc) tree_desc near *desc; /* the tree descriptor */ { ct_data near *tree = desc->dyn_tree; int near *extra = desc->extra_bits; int base = desc->extra_base; int max_code = desc->max_code; int max_length = desc->max_length; ct_data near *stree = desc->static_tree; int h; /* heap index */ int n, m; /* iterate over the tree elements */ int bits; /* bit length */ int xbits; /* extra bits */ ush f; /* frequency */ int overflow = 0; /* number of elements with bit length too large */ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; /* In a first pass, compute the optimal bit lengths (which may * overflow in the case of the bit length tree). */ tree[heap[heap_max]].Len = 0; /* root of the heap */ for (h = heap_max+1; h < HEAP_SIZE; h++) { n = heap[h]; bits = tree[tree[n].Dad].Len + 1; if (bits > max_length) bits = max_length, overflow++; tree[n].Len = (ush)bits; /* We overwrite tree[n].Dad which is no longer needed */ if (n > max_code) continue; /* not a leaf node */ bl_count[bits]++; xbits = 0; if (n >= base) xbits = extra[n-base]; f = tree[n].Freq; opt_len += (ulg)f * (bits + xbits); if (stree) static_len += (ulg)f * (stree[n].Len + xbits); } if (overflow == 0) return; Trace((stderr,"\nbit length overflow\n")); /* This happens for example on obj2 and pic of the Calgary corpus */ /* Find the first bit length which could increase: */ do { bits = max_length-1; while (bl_count[bits] == 0) bits--; bl_count[bits]--; /* move one leaf down the tree */ bl_count[bits+1] += 2; /* move one overflow item as its brother */ bl_count[max_length]--; /* The brother of the overflow item also moves one step up, * but this does not affect bl_count[max_length] */ overflow -= 2; } while (overflow > 0); /* Now recompute all bit lengths, scanning in increasing frequency. * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all * lengths instead of fixing only the wrong ones. This idea is taken * from 'ar' written by Haruhiko Okumura.) */ for (bits = max_length; bits != 0; bits--) { n = bl_count[bits]; while (n != 0) { m = heap[--h]; if (m > max_code) continue; if (tree[m].Len != (unsigned) bits) { Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); opt_len += ((long)bits-(long)tree[m].Len)*(long)tree[m].Freq; tree[m].Len = (ush)bits; } n--; } } } /* =========================================================================== * Generate the codes for a given tree and bit counts (which need not be * optimal). * IN assertion: the array bl_count contains the bit length statistics for * the given tree and the field len is set for all tree elements. * OUT assertion: the field code is set for all tree elements of non * zero code length. */ local void gen_codes (tree, max_code) ct_data near *tree; /* the tree to decorate */ int max_code; /* largest code with non zero frequency */ { ush next_code[MAX_BITS+1]; /* next code value for each bit length */ ush code = 0; /* running code value */ int bits; /* bit index */ int n; /* code index */ /* The distribution counts are first used to generate the code values * without bit reversal. */ for (bits = 1; bits <= MAX_BITS; bits++) { next_code[bits] = code = (code + bl_count[bits-1]) << 1; } /* Check that the bit counts in bl_count are consistent. The last code * must be all ones. */ Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; ct_data near *stree = desc->static_tree; int elems = desc->elems; int n, m; /* iterate over heap elements */ int max_code = -1; /* largest code with non zero frequency */ int node = elems; /* next internal node of the tree */ int new; /* WDP added this, instead of declaring it below */ /* Construct the initial heap, with least frequent element in * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. * heap[0] is not used. */ heap_len = 0, heap_max = HEAP_SIZE; for (n = 0; n < elems; n++) { if (tree[n].Freq != 0) { heap[++heap_len] = max_code = n; depth[n] = 0; } else { tree[n].Len = 0; } } /* The pkzip format requires that at least one distance code exists, * and that at least one bit should be sent even if there is only one * possible code. So to avoid special checks later on we force at least * two codes of non zero frequency. */ while (heap_len < 2) { /* int new = heap[++heap_len] = (max_code < 2 ? ++max_code : 0); */ new = heap[++heap_len] = (max_code < 2 ? ++max_code : 0); tree[new].Freq = 1; depth[new] = 0; opt_len--; if (stree) static_len -= stree[new].Len; /* new is 0 or 1 so it does not have extra bits */ } desc->max_code = max_code; /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, * establish sub-heaps of increasing lengths: */ for (n = heap_len/2; n >= 1; n--) pqdownheap(tree, n); /* Construct the Huffman tree by repeatedly combining the least two * frequent nodes. */ do { pqremove(tree, n); /* n = node of least frequency */ m = heap[SMALLEST]; /* m = node of next least frequency */ heap[--heap_max] = n; /* keep the nodes sorted by frequency */ heap[--heap_max] = m; /* Create a new node father of n and m */ tree[node].Freq = tree[n].Freq + tree[m].Freq; depth[node] = (uch) (MAX(depth[n], depth[m]) + 1); tree[n].Dad = tree[m].Dad = (ush)node; #ifdef DUMP_BL_TREE if (tree == bl_tree) { fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); } #endif /* and insert the new node in the heap */ heap[SMALLEST] = node++; pqdownheap(tree, SMALLEST); } while (heap_len >= 2); heap[--heap_max] = heap[SMALLEST]; /* At this point, the fields freq and dad are set. We can now * generate the bit lengths. */ gen_bitlen((tree_desc near *)desc); /* The field len is now set, we can generate the bit codes */ gen_codes ((ct_data near *)tree, max_code); } /* =========================================================================== * Scan a literal or distance tree to determine the frequencies of the codes * in the bit length tree. Updates opt_len to take into account the repeat * counts. (The contribution of the bit length codes will be added later * during the construction of bl_tree.) */ local void scan_tree (tree, max_code) ct_data near *tree; /* the tree to be scanned */ int max_code; /* and its largest code of non zero frequency */ { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ int nextlen = tree[0].Len; /* length of next code */ int count = 0; /* repeat count of the current code */ int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ if (nextlen == 0) max_count = 138, min_count = 3; tree[max_code+1].Len = (ush)0xffff; /* guard */ for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[n+1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { bl_tree[curlen].Freq += count; } else if (curlen != 0) { if (curlen != prevlen) bl_tree[curlen].Freq++; bl_tree[REP_3_6].Freq++; } else if (count <= 10) { bl_tree[REPZ_3_10].Freq++; } else { bl_tree[REPZ_11_138].Freq++; } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138, min_count = 3; } else if (curlen == nextlen) { max_count = 6, min_count = 3; } else { max_count = 7, min_count = 4; } } } /* =========================================================================== * Send a literal or distance tree in compressed form, using the codes in * bl_tree. */ local void send_tree (tree, max_code) ct_data near *tree; /* the tree to be scanned */ int max_code; /* and its largest code of non zero frequency */ { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ int nextlen = tree[0].Len; /* length of next code */ int count = 0; /* repeat count of the current code */ int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ /* tree[max_code+1].Len = -1; */ /* guard already set */ if (nextlen == 0) max_count = 138, min_count = 3; for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[n+1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { do { send_code(curlen, bl_tree); } while (--count != 0); } else if (curlen != 0) { if (curlen != prevlen) { send_code(curlen, bl_tree); count--; } Assert(count >= 3 && count <= 6, " 3_6?"); send_code(REP_3_6, bl_tree); send_bits(count-3, 2); } else if (count <= 10) { send_code(REPZ_3_10, bl_tree); send_bits(count-3, 3); } else { send_code(REPZ_11_138, bl_tree); send_bits(count-11, 7); } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138, min_count = 3; } else if (curlen == nextlen) { max_count = 6, min_count = 3; } else { max_count = 7, min_count = 4; } } } /* =========================================================================== * Construct the Huffman tree for the bit lengths and return the index in * bl_order of the last bit length code to send. */ local int build_bl_tree() { int max_blindex; /* index of last bit length code of non zero freq */ /* Determine the bit length frequencies for literal and distance trees */ scan_tree((ct_data near *)dyn_ltree, l_desc.max_code); scan_tree((ct_data near *)dyn_dtree, d_desc.max_code); /* Build the bit length tree: */ build_tree((tree_desc near *)(&bl_desc)); /* opt_len now includes the length of the tree representations, except * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. */ /* Determine the number of bit length codes to send. The pkzip format * requires that at least 4 bit length codes be sent. (appnote.txt says * 3 but the actual value used is 4.) */ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { if (bl_tree[bl_order[max_blindex]].Len != 0) break; } /* Update opt_len to include the bit length tree and counts */ opt_len += 3*(max_blindex+1) + 5+5+4; Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", opt_len, static_len)); return max_blindex; } /* =========================================================================== * Send the header for a block using dynamic Huffman trees: the counts, the * lengths of the bit length codes, the literal tree and the distance tree. * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. */ local void send_all_trees(lcodes, dcodes, blcodes) int lcodes, dcodes, blcodes; /* number of codes for each tree */ { int rank; /* index in bl_order */ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, "too many codes"); Tracev((stderr, "\nbl counts: ")); send_bits(lcodes-257, 5); /* not +255 as stated in appnote.txt */ send_bits(dcodes-1, 5); send_bits(blcodes-4, 4); /* not -3 as stated in appnote.txt */ for (rank = 0; rank < blcodes; rank++) { Tracev((stderr, "\nbl code %2d ", bl_order[rank])); send_bits(bl_tree[bl_order[rank]].Len, 3); } Tracev((stderr, "\nbl tree: sent %ld", bits_sent)); send_tree((ct_data near *)dyn_ltree, lcodes-1); /* send the literal tree */ Tracev((stderr, "\nlit tree: sent %ld", bits_sent)); send_tree((ct_data near *)dyn_dtree, dcodes-1); /* send the distance tree */ Tracev((stderr, "\ndist tree: sent %ld", bits_sent)); } /* =========================================================================== * Determine the best encoding for the current block: dynamic trees, static * trees or store, and output the encoded block to the zip file. This function * returns the total compressed length for the file so far. */ ulg flush_block(buf, stored_len, eof) char *buf; /* input block, or NULL if too old */ ulg stored_len; /* length of input block */ int eof; /* true if this is the last block for a file */ { ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ int max_blindex; /* index of last bit length code of non zero freq */ flag_buf[last_flags] = flags; /* Save the flags for the last 8 items */ /* Construct the literal and distance trees */ build_tree((tree_desc near *)(&l_desc)); Tracev((stderr, "\nlit data: dyn %ld, stat %ld", opt_len, static_len)); build_tree((tree_desc near *)(&d_desc)); Tracev((stderr, "\ndist data: dyn %ld, stat %ld", opt_len, static_len)); /* At this point, opt_len and static_len are the total bit lengths of * the compressed block data, excluding the tree representations. */ /* Build the bit length tree for the above two trees, and get the index * in bl_order of the last bit length code to send. */ max_blindex = build_bl_tree(); /* Determine the best encoding. Compute first the block length in bytes */ opt_lenb = (opt_len+3+7)>>3; static_lenb = (static_len+3+7)>>3; input_len += stored_len; /* for debugging only */ Trace((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ", opt_lenb, opt_len, static_lenb, static_len, stored_len, last_lit, last_dist)); if (static_lenb <= opt_lenb) opt_lenb = static_lenb; /* If compression failed and this is the first and last block, * and if the zip file can be seeked (to rewrite the local header), * the whole file is transformed into a stored file: */ #ifdef FORCE_METHOD if (level == 1 && eof && compressed_len == 0L) { /* force stored file */ #else if (stored_len <= opt_lenb && eof && compressed_len == 0L && seekable()) { #endif /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */ if (buf == (char*)0) error ("block vanished"); copy_block(buf, (unsigned)stored_len, 0); /* without header */ compressed_len = stored_len << 3; *file_method = STORED; #ifdef FORCE_METHOD } else if (level == 2 && buf != (char*)0) { /* force stored block */ #else } else if (stored_len+4 <= opt_lenb && buf != (char*)0) { /* 4: two words for the lengths */ #endif /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. * Otherwise we can't have processed more than WSIZE input bytes since * the last block flush, because compression would have been * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to * transform a block into a stored block. */ send_bits((STORED_BLOCK<<1)+eof, 3); /* send block type */ compressed_len = (compressed_len + 3 + 7) & ~7L; compressed_len += (stored_len + 4) << 3; copy_block(buf, (unsigned)stored_len, 1); /* with header */ #ifdef FORCE_METHOD } else if (level == 3) { /* force static trees */ #else } else if (static_lenb == opt_lenb) { #endif send_bits((STATIC_TREES<<1)+eof, 3); compress_block((ct_data near *)static_ltree, (ct_data near *)static_dtree); compressed_len += 3 + static_len; } else { send_bits((DYN_TREES<<1)+eof, 3); send_all_trees(l_desc.max_code+1, d_desc.max_code+1, max_blindex+1); compress_block((ct_data near *)dyn_ltree, (ct_data near *)dyn_dtree); compressed_len += 3 + opt_len; } Assert (compressed_len == bits_sent, "bad compressed size"); init_block(); if (eof) { Assert (input_len == isize, "bad input size"); bi_windup(); compressed_len += 7; /* align on byte boundary */ } Tracev((stderr,"\ncomprlen %lu(%lu) ", compressed_len>>3, compressed_len-7*eof)); return compressed_len >> 3; } /* =========================================================================== * Save the match info and tally the frequency counts. Return true if * the current block must be flushed. */ int ct_tally (dist, lc) int dist; /* distance of matched string */ int lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ { l_buf[last_lit++] = (uch)lc; if (dist == 0) { /* lc is the unmatched char */ dyn_ltree[lc].Freq++; } else { /* Here, lc is the match length - MIN_MATCH */ dist--; /* dist = match distance - 1 */ Assert((ush)dist < (ush)MAX_DIST && (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && (ush)d_code(dist) < (ush)D_CODES, "ct_tally: bad match"); dyn_ltree[length_code[lc]+LITERALS+1].Freq++; dyn_dtree[d_code(dist)].Freq++; d_buf[last_dist++] = (ush)dist; flags |= flag_bit; } flag_bit <<= 1; /* Output the flags if they fill a byte: */ if ((last_lit & 7) == 0) { flag_buf[last_flags++] = flags; flags = 0, flag_bit = 1; } /* Try to guess if it is profitable to stop the current block here */ if (level > 2 && (last_lit & 0xfff) == 0) { /* Compute an upper bound for the compressed length */ ulg out_length = (ulg)last_lit*8L; ulg in_length = (ulg)strstart-block_start; int dcode; for (dcode = 0; dcode < D_CODES; dcode++) { out_length += (ulg)dyn_dtree[dcode].Freq*(5L+extra_dbits[dcode]); } out_length >>= 3; Trace((stderr,"\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ", last_lit, last_dist, in_length, out_length, 100L - out_length*100L/in_length)); if (last_dist < last_lit/2 && out_length < in_length/2) return 1; } return (last_lit == LIT_BUFSIZE-1 || last_dist == DIST_BUFSIZE); /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K * on 16 bit machines and because stored blocks are restricted to * 64K-1 bytes. */ } /* =========================================================================== * Send the block data compressed using the given Huffman trees */ local void compress_block(ltree, dtree) ct_data near *ltree; /* literal tree */ ct_data near *dtree; /* distance tree */ { unsigned dist; /* distance of matched string */ int lc; /* match length or unmatched char (if dist == 0) */ unsigned lx = 0; /* running index in l_buf */ unsigned dx = 0; /* running index in d_buf */ unsigned fx = 0; /* running index in flag_buf */ uch flag = 0; /* current flags */ unsigned code; /* the code to send */ int extra; /* number of extra bits to send */ if (last_lit != 0) do { if ((lx & 7) == 0) flag = flag_buf[fx++]; lc = l_buf[lx++]; if ((flag & 1) == 0) { send_code(lc, ltree); /* send a literal byte */ Tracecv(isgraph(lc), (stderr," '%c' ", lc)); } else { /* Here, lc is the match length - MIN_MATCH */ code = length_code[lc]; send_code(code+LITERALS+1, ltree); /* send the length code */ extra = extra_lbits[code]; if (extra != 0) { lc -= base_length[code]; send_bits(lc, extra); /* send the extra length bits */ } dist = d_buf[dx++]; /* Here, dist is the match distance - 1 */ code = d_code(dist); Assert (code < D_CODES, "bad d_code"); send_code(code, dtree); /* send the distance code */ extra = extra_dbits[code]; if (extra != 0) { dist -= base_dist[code]; send_bits(dist, extra); /* send the extra distance bits */ } } /* literal or match pair ? */ flag >>= 1; } while (lx < last_lit); send_code(END_BLOCK, ltree); } /* ********************** */ /* start of file bits.c */ /* ********************** */ /* bits.c -- output variable-length bit strings * Copyright (C) 1992-1993 Jean-loup Gailly * This is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, see the file COPYING. */ /* * PURPOSE * * Output variable-length bit strings. Compression can be done * to a file or to memory. (The latter is not supported in this version.) * * DISCUSSION * * The PKZIP "deflate" file format interprets compressed file data * as a sequence of bits. Multi-bit strings in the file may cross * byte boundaries without restriction. * * The first bit of each byte is the low-order bit. * * The routines in this file allow a variable-length bit value to * be output right-to-left (useful for literal values). For * left-to-right output (useful for code strings from the tree routines), * the bits must have been reversed first with bi_reverse(). * * For in-memory compression, the compressed bit stream goes directly * into the requested output buffer. The input data is read in blocks * by the mem_read() function. The buffer is limited to 64K on 16 bit * machines. * * INTERFACE * * void bi_init (FILE *zipfile) * Initialize the bit string routines. * * void send_bits (int value, int length) * Write out a bit string, taking the source bits right to * left. * * int bi_reverse (int value, int length) * Reverse the bits of a bit string, taking the source bits left to * right and emitting them right to left. * * void bi_windup (void) * Write out any remaining bits in an incomplete byte. * * void copy_block(char *buf, unsigned len, int header) * Copy a stored block to the zip file, storing first the length and * its one's complement if requested. * */ /* #include "tailor.h" */ /* #include "gzip.h" */ /* #include "crypt.h" */ /* =========================================================================== * Local data used by the "bit string" routines. */ local file_t zfile; /* output gzip file */ local unsigned short bi_buf; /* Output buffer. bits are inserted starting at the bottom (least significant * bits). */ #define Buf_size (8 * 2*sizeof(char)) /* Number of bits used within bi_buf. (bi_buf might be implemented on * more than 16 bits on some systems.) */ local int bi_valid; /* Number of valid bits in bi_buf. All bits above the last valid bit * are always zero. */ /* int (*read_buf) OF((char *buf, unsigned size)); */ /* Current input function. Set to mem_read for in-memory compression */ #ifdef DEBUG ulg bits_sent; /* bit length of the compressed data */ #endif /* =========================================================================== * Initialize the bit string routines. */ void bi_init (zipfile) file_t zipfile; /* output zip file, NO_FILE for in-memory compression */ { zfile = zipfile; bi_buf = 0; bi_valid = 0; #ifdef DEBUG bits_sent = 0L; #endif /* Set the defaults for file compression. They are set by memcompress * for in-memory compression. */ read_buf = file_read; /* if (zfile != NO_FILE) { read_buf = file_read; } */ } /* =========================================================================== * Send a value on a given number of bits. * IN assertion: length <= 16 and value fits in length bits. */ void send_bits(value, length) int value; /* value to send */ int length; /* number of bits */ { #ifdef DEBUG Tracev((stderr," l %2d v %4x ", length, value)); Assert(length > 0 && length <= 15, "invalid length"); bits_sent += (ulg)length; #endif /* If not enough room in bi_buf, use (valid) bits from bi_buf and * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) * unused bits in value. */ if (bi_valid > (int)Buf_size - length) { bi_buf |= (value << bi_valid); put_short(bi_buf); bi_buf = (ush)value >> (Buf_size - bi_valid); bi_valid += length - Buf_size; } else { bi_buf |= value << bi_valid; bi_valid += length; } } /* =========================================================================== * Reverse the first len bits of a code, using straightforward code (a faster * method would use a table) * IN assertion: 1 <= len <= 15 */ unsigned bi_reverse(code, len) unsigned code; /* the value to invert */ int len; /* its bit length */ { register unsigned res = 0; do { res |= code & 1; code >>= 1, res <<= 1; } while (--len > 0); return res >> 1; } /* =========================================================================== * Write out any remaining bits in an incomplete byte. */ void bi_windup() { if (bi_valid > 8) { put_short(bi_buf); } else if (bi_valid > 0) { put_byte(bi_buf); } bi_buf = 0; bi_valid = 0; #ifdef DEBUG bits_sent = (bits_sent+7) & ~7; #endif } /* =========================================================================== * Copy a stored block to the zip file, storing first the length and its * one's complement if requested. */ void copy_block(buf, len, header) char *buf; /* the input data */ unsigned len; /* its length */ int header; /* true if block header must be written */ { bi_windup(); /* align on byte boundary */ if (header) { put_short((ush)len); put_short((ush)~len); #ifdef DEBUG bits_sent += 2*16; #endif } #ifdef DEBUG bits_sent += (ulg)len<<3; #endif while (len--) { #ifdef CRYPT int t; if (key) zencode(*buf, t); #endif put_byte(*buf++); } } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/compress.h000066400000000000000000000157041215713201500224430ustar00rootroot00000000000000/* compress.h -- definitions for the decompression routines used in CFITSIO */ /* Blatantly copied and modified from the original gzip-1.2.4 source code. */ #include #include #include #include /* 'near' is only relevant for 16-bit PC with small memory model */ # define near #if defined(VAXC) || defined(VMS) # define RECORD_IO 1 #else # define RECORD_IO 0 #endif #define get_char() get_byte() /* gzip.h -- common declarations for all gzip modules */ #define OF(args) args typedef void *voidp; #define memzero(s, n) memset ((voidp)(s), 0, (n)) typedef unsigned char uch; typedef unsigned short ush; typedef unsigned long ulg; /* private version of MIN function */ #define MINZIP(a,b) ((a) <= (b) ? (a) : (b)) /* Return codes from gzip */ #define OK 0 #define ERROR 1 #define WARNING 2 /* Compression methods (see algorithm.doc) */ #define STORED 0 #define COMPRESSED 1 #define PACKED 2 #define LZHED 3 /* methods 4 to 7 reserved */ #define DEFLATED 8 #define MAX_METHODS 9 #define INBUFSIZ 0x8000 /* input buffer size */ #define INBUF_EXTRA 64 /* required by unlzw() */ #define OUTBUFSIZ 16384 /* output buffer size */ #define OUTBUF_EXTRA 2048 /* required by unlzw() */ #define DIST_BUFSIZE 0x8000 /* buffer for distances, see trees.c */ #define WSIZE 0x8000 /* window size--must be a power of two, and */ #define DECLARE(type, array, size) type array[size] #define tab_suffix window #define tab_prefix prev /* hash link (see deflate.c) */ #define head (prev+WSIZE) /* hash head (see deflate.c) */ #define PACK_MAGIC "\037\036" /* Magic header for packed files */ #define GZIP_MAGIC "\037\213" /* Magic header for gzip files, 1F 8B */ #define OLD_GZIP_MAGIC "\037\236" /* Magic header for gzip 0.5 = freeze 1.x */ #define LZH_MAGIC "\037\240" /* Magic header for SCO LZH Compress files*/ #define LZW_MAGIC "\037\235" /* Magic header for lzw files, 1F 9D */ #define PKZIP_MAGIC "\120\113\003\004" /* Magic header for pkzip files */ /* gzip flag byte */ #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ #define COMMENT 0x10 /* bit 4 set: file comment present */ #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ #define RESERVED 0xC0 /* bit 6,7: reserved */ #define MIN_MATCH 3 #define MAX_MATCH 258 #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) #define MAX_DIST (WSIZE-MIN_LOOKAHEAD) #define translate_eol 0 /* no option -a yet */ #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf(0)) #define try_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf(1)) #define put_ubyte(c) {window[outcnt++]=(uch)(c); if (outcnt==WSIZE)\ flush_window();} /* Macros for getting two-byte and four-byte header values */ #define SH(p) ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8)) #define LG(p) ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16)) /* Diagnostic functions */ # define Assert(cond,msg) # define Trace(x) # define Tracev(x) # define Tracevv(x) # define Tracec(c,x) # define Tracecv(c,x) /* lzw.h -- define the lzw functions. */ #ifndef BITS # define BITS 16 #endif #define INIT_BITS 9 /* Initial number of bits per code */ #define BIT_MASK 0x1f /* Mask for 'number of compression bits' */ #define BLOCK_MODE 0x80 #define LZW_RESERVED 0x60 /* reserved bits */ #define CLEAR 256 /* flush the dictionary */ #define FIRST (CLEAR+1) /* first free entry */ /* prototypes */ #define local static void ffpmsg(const char *err_message); local int get_method OF((FILE *in)); local ulg updcrc OF((uch *s, unsigned n)); local int fill_inbuf OF((int eof_ok)); local void flush_outbuf OF((void)); local void flush_window OF((void)); local void write_buf OF((voidp buf, unsigned cnt)); local void error OF((char *m)); local ulg flush_block OF((char *buf, ulg stored_len, int eof)); typedef int file_t; /* Do not use stdio */ #define NO_FILE (-1) /* in memory compression */ local int file_read OF((char *buf, unsigned size)); local void send_bits OF((int value, int length)); local unsigned bi_reverse OF((unsigned value, int length)); local void bi_windup OF((void)); local void copy_block OF((char *buf, unsigned len, int header)); local int (*read_buf) OF((char *buf, unsigned size)); local void lm_init OF((int pack_level, ush *flags)); local ulg deflate OF((void)); local void ct_init OF((ush *attr, int *method)); local int ct_tally OF((int dist, int lc)); local void bi_init OF((file_t zipfile)); #define put_byte(c) {outbuf[outcnt++]=(uch)(c); if (outcnt==OUTBUFSIZ)\ flush_outbuf();} /* Output a 16 bit value, lsb first */ #define put_short(w) \ { if (outcnt < OUTBUFSIZ-2) { \ outbuf[outcnt++] = (uch) ((w) & 0xff); \ outbuf[outcnt++] = (uch) ((ush)(w) >> 8); \ } else { \ put_byte((uch)((w) & 0xff)); \ put_byte((uch)((ush)(w) >> 8)); \ } \ } /* Output a 32 bit value to the bit stream, lsb first */ #define put_long(n) { \ put_short((n) & 0xffff); \ put_short(((ulg)(n)) >> 16); \ } #define seekable() 0 /* force sequential output */ /* io.c */ local void fillbuf OF((int n)); local unsigned getbits OF((int n)); local void init_getbits OF((void)); /* maketbl.c */ local void make_table OF((int nchar, uch bitlen[], int tablebits, ush table[])); /* huf.c */ local void read_pt_len OF((int nn, int nbit, int i_special)); local void read_c_len OF((void)); local unsigned decode_c OF((void)); local unsigned decode_p OF((void)); local void huf_decode_start OF((void)); /* decode.c */ local void decode_start OF((void)); local unsigned decode OF((unsigned count, uch buffer[])); local int unlzh OF((FILE *in, FILE *out)); local int unlzw OF((FILE *in, FILE *out)); local void read_tree OF((void)); local void build_tree_unpack OF((void)); local int unpack OF((FILE *in, FILE *out)); local int check_zipfile OF((FILE *in)); local int unzip OF((FILE *in, FILE *out)); int (*work) OF((FILE *infile, FILE *outfile)) = unzip; /* function to call */ /* inflate.c */ struct huft { uch e; /* number of extra bits or operation */ uch b; /* number of bits in this code or subcode */ union { ush n; /* literal, length base, or distance base */ struct huft *t; /* pointer to next level of table */ } v; }; local int huft_build OF((unsigned *, unsigned, unsigned, ush *, ush *, struct huft **, int *)); local int huft_free OF((struct huft *)); local int inflate_codes OF((struct huft *, struct huft *, int, int)); local int inflate_stored OF((void)); local int inflate_fixed OF((void)); local int inflate_dynamic OF((void)); local int inflate_block OF((int *)); local int inflate OF((void)); /* end of compress.h include file */ skycat-3.1.2-starlink-1b/astrotcl/cfitsio/drvrfile.c000066400000000000000000000507341215713201500224220ustar00rootroot00000000000000/* This file, drvrfile.c contains driver routines for disk files. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" #if defined(unix) || defined(__unix__) || defined(__unix) #include /* needed in file_openfile */ #ifdef REPLACE_LINKS #include #include #endif #endif #ifdef HAVE_FTRUNCATE #if defined(unix) || defined(__unix__) || defined(__unix) #include /* needed for getcwd prototype on unix machines */ #endif #endif #define IO_SEEK 0 /* last file I/O operation was a seek */ #define IO_READ 1 /* last file I/O operation was a read */ #define IO_WRITE 2 /* last file I/O operation was a write */ static char file_outfile[FLEN_FILENAME]; typedef struct /* structure containing disk file structure */ { FILE *fileptr; LONGLONG currentpos; int last_io_op; } diskdriver; static diskdriver handleTable[NMAXFILES]; /* allocate diskfile handle tables */ /*--------------------------------------------------------------------------*/ int file_init(void) { int ii; for (ii = 0; ii < NMAXFILES; ii++) /* initialize all empty slots in table */ { handleTable[ii].fileptr = 0; } return(0); } /*--------------------------------------------------------------------------*/ int file_setoptions(int options) { /* do something with the options argument, to stop compiler warning */ options = 0; return(options); } /*--------------------------------------------------------------------------*/ int file_getoptions(int *options) { *options = 0; return(0); } /*--------------------------------------------------------------------------*/ int file_getversion(int *version) { *version = 10; return(0); } /*--------------------------------------------------------------------------*/ int file_shutdown(void) { return(0); } /*--------------------------------------------------------------------------*/ int file_open(char *filename, int rwmode, int *handle) { FILE *diskfile; int copyhandle, ii, status; char recbuf[2880]; size_t nread; /* if an output filename has been specified as part of the input file, as in "inputfile.fits(outputfile.fit)" then we have to create the output file, copy the input to it, then reopen the the new copy. */ if (*file_outfile) { /* open the original file, with readonly access */ status = file_openfile(filename, READONLY, &diskfile); if (status) { file_outfile[0] = '\0'; return(status); } /* create the output file */ status = file_create(file_outfile,handle); if (status) { ffpmsg("Unable to create output file for copy of input file:"); ffpmsg(file_outfile); file_outfile[0] = '\0'; return(status); } /* copy the file from input to output */ while(0 != (nread = fread(recbuf,1,2880, diskfile))) { status = file_write(*handle, recbuf, nread); if (status) { file_outfile[0] = '\0'; return(status); } } /* close both files */ fclose(diskfile); copyhandle = *handle; file_close(*handle); *handle = copyhandle; /* reuse the old file handle */ /* reopen the new copy, with correct rwmode */ status = file_openfile(file_outfile, rwmode, &diskfile); file_outfile[0] = '\0'; } else { *handle = -1; for (ii = 0; ii < NMAXFILES; ii++) /* find empty slot in table */ { if (handleTable[ii].fileptr == 0) { *handle = ii; break; } } if (*handle == -1) return(TOO_MANY_FILES); /* too many files opened */ /*open the file */ status = file_openfile(filename, rwmode, &diskfile); } handleTable[*handle].fileptr = diskfile; handleTable[*handle].currentpos = 0; handleTable[*handle].last_io_op = IO_SEEK; return(status); } /*--------------------------------------------------------------------------*/ int file_openfile(char *filename, int rwmode, FILE **diskfile) /* lowest level routine to physically open a disk file */ { char mode[4]; #if defined(unix) || defined(__unix__) || defined(__unix) char tempname[512], *cptr, user[80]; struct passwd *pwd; int ii = 0; #if defined(REPLACE_LINKS) struct stat stbuf; int success = 0; size_t n; FILE *f1, *f2; char buf[BUFSIZ]; #endif #endif if (rwmode == READWRITE) { strcpy(mode, "r+b"); /* open existing file with read-write */ } else { strcpy(mode, "rb"); /* open existing file readonly */ } #if MACHINE == ALPHAVMS || MACHINE == VAXVMS /* specify VMS record structure: fixed format, 2880 byte records */ /* but force stream mode access to enable random I/O access */ *diskfile = fopen(filename, mode, "rfm=fix", "mrs=2880", "ctx=stm"); #elif defined(unix) || defined(__unix__) || defined(__unix) /* support the ~user/file.fits or ~/file.fits filenames in UNIX */ if (*filename == '~') { if (filename[1] == '/') { cptr = getenv("HOME"); if (cptr) { strcpy(tempname, cptr); strcat(tempname, filename+1); } else { strcpy(tempname, filename); } } else { /* copy user name */ cptr = filename+1; while (*cptr && (*cptr != '/')) { user[ii] = *cptr; cptr++; ii++; } user[ii] = '\0'; /* get structure that includes name of user's home directory */ pwd = getpwnam(user); /* copy user's home directory */ strcpy(tempname, pwd->pw_dir); strcat(tempname, cptr); } *diskfile = fopen(tempname, mode); } else { /* don't need to expand the input file name */ *diskfile = fopen(filename, mode); #if defined(REPLACE_LINKS) if (!(*diskfile) && (rwmode == READWRITE)) { /* failed to open file with READWRITE privilege. Test if */ /* the file we are trying to open is a soft link to a file that */ /* doesn't have write privilege. */ lstat(filename, &stbuf); if ((stbuf.st_mode & S_IFMT) == S_IFLNK) /* is this a soft link? */ { if ((f1 = fopen(filename, "rb")) != 0) /* try opening READONLY */ { strcpy(tempname, filename); strcat(tempname, ".TmxFil"); if ((f2 = fopen(tempname, "wb")) != 0) /* create temp file */ { success = 1; while ((n = fread(buf, 1, BUFSIZ, f1)) > 0) { /* copy linked file to local temporary file */ if (fwrite(buf, 1, n, f2) != n) { success = 0; break; } } fclose(f2); } fclose(f1); if (success) { /* delete link and rename temp file to previous link name */ remove(filename); rename(tempname, filename); /* try once again to open the file with write access */ *diskfile = fopen(filename, mode); } else remove(tempname); /* clean up the failed copy */ } } } #endif } #else /* other non-UNIX machines */ *diskfile = fopen(filename, mode); #endif if (!(*diskfile)) /* couldn't open file */ { return(FILE_NOT_OPENED); } return(0); } /*--------------------------------------------------------------------------*/ int file_create(char *filename, int *handle) { FILE *diskfile; int ii; char mode[4]; *handle = -1; for (ii = 0; ii < NMAXFILES; ii++) /* find empty slot in table */ { if (handleTable[ii].fileptr == 0) { *handle = ii; break; } } if (*handle == -1) return(TOO_MANY_FILES); /* too many files opened */ strcpy(mode, "w+b"); /* create new file with read-write */ diskfile = fopen(filename, "r"); /* does file already exist? */ if (diskfile) { fclose(diskfile); /* close file and exit with error */ return(FILE_NOT_CREATED); } #if MACHINE == ALPHAVMS || MACHINE == VAXVMS /* specify VMS record structure: fixed format, 2880 byte records */ /* but force stream mode access to enable random I/O access */ diskfile = fopen(filename, mode, "rfm=fix", "mrs=2880", "ctx=stm"); #else diskfile = fopen(filename, mode); #endif if (!(diskfile)) /* couldn't create file */ { return(FILE_NOT_CREATED); } handleTable[ii].fileptr = diskfile; handleTable[ii].currentpos = 0; handleTable[ii].last_io_op = IO_SEEK; return(0); } /*--------------------------------------------------------------------------*/ int file_truncate(int handle, LONGLONG filesize) /* truncate the diskfile to a new smaller size */ { #ifdef HAVE_FTRUNCATE int fdesc; fdesc = fileno(handleTable[handle].fileptr); ftruncate(fdesc, (OFF_T) filesize); handleTable[handle].currentpos = filesize; handleTable[handle].last_io_op = IO_WRITE; #endif return(0); } /*--------------------------------------------------------------------------*/ int file_size(int handle, LONGLONG *filesize) /* return the size of the file in bytes */ { OFF_T position1,position2; FILE *diskfile; diskfile = handleTable[handle].fileptr; #if _FILE_OFFSET_BITS - 0 == 64 /* call the newer ftello and fseeko routines , which support */ /* Large Files (> 2GB) if they are supported. */ position1 = ftello(diskfile); /* save current postion */ if (position1 < 0) return(SEEK_ERROR); if (fseeko(diskfile, 0, 2) != 0) /* seek to end of file */ return(SEEK_ERROR); position2 = ftello(diskfile); /* get file size */ if (position2 < 0) return(SEEK_ERROR); if (fseeko(diskfile, position1, 0) != 0) /* seek back to original pos */ return(SEEK_ERROR); #else position1 = ftell(diskfile); /* save current postion */ if (position1 < 0) return(SEEK_ERROR); if (fseek(diskfile, 0, 2) != 0) /* seek to end of file */ return(SEEK_ERROR); position2 = ftell(diskfile); /* get file size */ if (position2 < 0) return(SEEK_ERROR); if (fseek(diskfile, position1, 0) != 0) /* seek back to original pos */ return(SEEK_ERROR); #endif *filesize = (LONGLONG) position2; return(0); } /*--------------------------------------------------------------------------*/ int file_close(int handle) /* close the file */ { if (fclose(handleTable[handle].fileptr) ) return(FILE_NOT_CLOSED); handleTable[handle].fileptr = 0; return(0); } /*--------------------------------------------------------------------------*/ int file_remove(char *filename) /* delete the file from disk */ { remove(filename); return(0); } /*--------------------------------------------------------------------------*/ int file_flush(int handle) /* flush the file */ { if (fflush(handleTable[handle].fileptr) ) return(WRITE_ERROR); /* The flush operation is not supposed to move the internal */ /* file pointer, but it does on some Windows-95 compilers and */ /* perhaps others, so seek to original position to be sure. */ /* This seek will do no harm on other systems. */ #if MACHINE == IBMPC if (file_seek(handle, handleTable[handle].currentpos)) return(SEEK_ERROR); #endif return(0); } /*--------------------------------------------------------------------------*/ int file_seek(int handle, LONGLONG offset) /* seek to position relative to start of the file */ { #if _FILE_OFFSET_BITS - 0 == 64 if (fseeko(handleTable[handle].fileptr, (OFF_T) offset, 0) != 0) return(SEEK_ERROR); #else if (fseek(handleTable[handle].fileptr, (OFF_T) offset, 0) != 0) return(SEEK_ERROR); #endif handleTable[handle].currentpos = offset; return(0); } /*--------------------------------------------------------------------------*/ int file_read(int hdl, void *buffer, long nbytes) /* read bytes from the current position in the file */ { long nread; char *cptr; if (handleTable[hdl].last_io_op == IO_WRITE) { if (file_seek(hdl, handleTable[hdl].currentpos)) return(SEEK_ERROR); } nread = (long) fread(buffer, 1, nbytes, handleTable[hdl].fileptr); if (nread == 1) { cptr = (char *) buffer; /* some editors will add a single end-of-file character to a file */ /* Ignore it if the character is a zero, 10, or 32 */ if (*cptr == 0 || *cptr == 10 || *cptr == 32) return(END_OF_FILE); else return(READ_ERROR); } else if (nread != nbytes) { return(READ_ERROR); } handleTable[hdl].currentpos += nbytes; handleTable[hdl].last_io_op = IO_READ; return(0); } /*--------------------------------------------------------------------------*/ int file_write(int hdl, void *buffer, long nbytes) /* write bytes at the current position in the file */ { if (handleTable[hdl].last_io_op == IO_READ) { if (file_seek(hdl, handleTable[hdl].currentpos)) return(SEEK_ERROR); } if((long) fwrite(buffer, 1, nbytes, handleTable[hdl].fileptr) != nbytes) return(WRITE_ERROR); handleTable[hdl].currentpos += nbytes; handleTable[hdl].last_io_op = IO_WRITE; return(0); } /*--------------------------------------------------------------------------*/ int file_compress_open(char *filename, int rwmode, int *hdl) /* This routine opens the compressed diskfile by creating a new uncompressed file then opening it. The input file name (the name of the compressed file) gets replaced with the name of the uncompressed file, which is initially stored in the global file_outfile string. file_outfile then gets set to a null string. */ { FILE *indiskfile, *outdiskfile; int status, clobber = 0; char *cptr; /* open the compressed disk file */ status = file_openfile(filename, READONLY, &indiskfile); if (status) { ffpmsg("failed to open compressed disk file (file_compress_open)"); ffpmsg(filename); return(status); } /* name of the output uncompressed file is stored in the */ /* global variable called 'file_outfile'. */ cptr = file_outfile; if (*cptr == '!') { /* clobber any existing file with the same name */ clobber = 1; cptr++; remove(cptr); } else { outdiskfile = fopen(file_outfile, "r"); /* does file already exist? */ if (outdiskfile) { ffpmsg("uncompressed file already exists: (file_compress_open)"); ffpmsg(file_outfile); fclose(outdiskfile); /* close file and exit with error */ file_outfile[0] = '\0'; return(FILE_NOT_CREATED); } } outdiskfile = fopen(cptr, "w+b"); /* create new file */ if (!outdiskfile) { ffpmsg("could not create uncompressed file: (file_compress_open)"); ffpmsg(file_outfile); file_outfile[0] = '\0'; return(FILE_NOT_CREATED); } /* uncompress file into another file */ uncompress2file(filename, indiskfile, outdiskfile, &status); fclose(indiskfile); fclose(outdiskfile); if (status) { ffpmsg("error in file_compress_open: failed to uncompressed file:"); ffpmsg(filename); ffpmsg(" into new output file:"); ffpmsg(file_outfile); file_outfile[0] = '\0'; return(status); } strcpy(filename, cptr); /* switch the names */ file_outfile[0] = '\0'; status = file_open(filename, rwmode, hdl); return(status); } /*--------------------------------------------------------------------------*/ int file_is_compressed(char *filename) /* I - FITS file name */ /* Test if the disk file is compressed. Returns 1 if compressed, 0 if not. This may modify the filename string by appending a compression suffex. */ { FILE *diskfile; unsigned char buffer[2]; char tmpfilename[FLEN_FILENAME]; /* Open file. Try various suffix combinations */ if (file_openfile(filename, 0, &diskfile)) { strcpy(tmpfilename,filename); strcat(filename,".gz"); if (file_openfile(filename, 0, &diskfile)) { strcpy(filename, tmpfilename); strcat(filename,".Z"); if (file_openfile(filename, 0, &diskfile)) { strcpy(filename, tmpfilename); strcat(filename,".z"); /* it's often lower case on CDROMs */ if (file_openfile(filename, 0, &diskfile)) { strcpy(filename, tmpfilename); strcat(filename,".zip"); if (file_openfile(filename, 0, &diskfile)) { strcpy(filename, tmpfilename); strcat(filename,"-z"); /* VMS suffix */ if (file_openfile(filename, 0, &diskfile)) { strcpy(filename, tmpfilename); strcat(filename,"-gz"); /* VMS suffix */ if (file_openfile(filename, 0, &diskfile)) { strcpy(filename,tmpfilename); /* restore original name */ return(0); /* file not found */ } } } } } } } if (fread(buffer, 1, 2, diskfile) != 2) /* read 2 bytes */ { fclose(diskfile); /* error reading file so just return */ return(0); } fclose(diskfile); /* see if the 2 bytes have the magic values for a compressed file */ if ( (memcmp(buffer, "\037\213", 2) == 0) || /* GZIP */ (memcmp(buffer, "\120\113", 2) == 0) || /* PKZIP */ (memcmp(buffer, "\037\036", 2) == 0) || /* PACK */ (memcmp(buffer, "\037\235", 2) == 0) || /* LZW */ (memcmp(buffer, "\037\240", 2) == 0) ) /* LZH */ { return(1); /* this is a compressed file */ } else { return(0); /* not a compressed file */ } } /*--------------------------------------------------------------------------*/ int file_checkfile (char *urltype, char *infile, char *outfile) { /* special case: if file:// driver, check if the file is compressed */ if ( file_is_compressed(infile) ) { /* if output file has been specified, save the name for future use: */ /* This is the name of the uncompressed file to be created on disk. */ if (strlen(outfile)) { if (!strncmp(outfile, "mem:", 4) ) { /* uncompress the file in memory, with READ and WRITE access */ strcpy(urltype, "compressmem://"); /* use special driver */ *file_outfile = '\0'; } else { strcpy(urltype, "compressfile://"); /* use special driver */ /* don't copy the "file://" prefix, if present. */ if (!strncmp(outfile, "file://", 7) ) strcpy(file_outfile,outfile+7); else strcpy(file_outfile,outfile); } } else { /* uncompress the file in memory */ strcpy(urltype, "compress://"); /* use special driver */ *file_outfile = '\0'; /* no output file was specified */ } } else /* an ordinary, uncompressed FITS file on disk */ { /* save the output file name for later use when opening the file. */ /* In this case, the file to be opened will be opened READONLY, */ /* and copied to this newly created output file. The original file */ /* will be closed, and the copy will be opened by CFITSIO for */ /* subsequent processing (possibly with READWRITE access). */ if (strlen(outfile)) strcpy(file_outfile,outfile); } return 0; } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/drvrmem.c000066400000000000000000001031451215713201500222540ustar00rootroot00000000000000/* This file, drvrmem.c, contains driver routines for memory files. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include /* apparently needed to define size_t */ #include "fitsio2.h" #define RECBUFLEN 1000 static char stdin_outfile[FLEN_FILENAME]; typedef struct /* structure containing mem file structure */ { char **memaddrptr; /* Pointer to memory address pointer; */ /* This may or may not point to memaddr. */ char *memaddr; /* Pointer to starting memory address; may */ /* not always be used, so use *memaddrptr instead */ size_t *memsizeptr; /* Pointer to the size of the memory allocation. */ /* This may or may not point to memsize. */ size_t memsize; /* Size of the memory allocation; this may not */ /* always be used, so use *memsizeptr instead. */ size_t deltasize; /* Suggested increment for reallocating memory */ void *(*mem_realloc)(void *p, size_t newsize); /* realloc function */ LONGLONG currentpos; /* current file position, relative to start */ LONGLONG fitsfilesize; /* size of the FITS file (always <= *memsizeptr) */ FILE *fileptr; /* pointer to compressed output disk file */ } memdriver; static memdriver memTable[NMAXFILES]; /* allocate mem file handle tables */ /*--------------------------------------------------------------------------*/ int mem_init(void) { int ii; for (ii = 0; ii < NMAXFILES; ii++) /* initialize all empty slots in table */ { memTable[ii].memaddrptr = 0; memTable[ii].memaddr = 0; } return(0); } /*--------------------------------------------------------------------------*/ int mem_setoptions(int options) { /* do something with the options argument, to stop compiler warning */ options = 0; return(options); } /*--------------------------------------------------------------------------*/ int mem_getoptions(int *options) { *options = 0; return(0); } /*--------------------------------------------------------------------------*/ int mem_getversion(int *version) { *version = 10; return(0); } /*--------------------------------------------------------------------------*/ int mem_shutdown(void) { return(0); } /*--------------------------------------------------------------------------*/ int mem_create(char *filename, int *handle) /* Create a new empty memory file for subsequent writes. The file name is ignored in this case. */ { int status; /* initially allocate 1 FITS block = 2880 bytes */ status = mem_createmem(2880L, handle); if (status) { ffpmsg("failed to create empty memory file (mem_create)"); return(status); } return(0); } /*--------------------------------------------------------------------------*/ int mem_create_comp(char *filename, int *handle) /* Create a new empty memory file for subsequent writes. Also create an empty compressed .gz file. The memory file will be compressed and written to the disk file when the file is closed. */ { FILE *diskfile; char mode[4]; int status; /* first, create disk file for the compressed output */ if ( !strcmp(filename, "-.gz") || !strcmp(filename, "stdout.gz") || !strcmp(filename, "STDOUT.gz") ) { /* special case: create uncompressed FITS file in memory, then compress it an write it out to 'stdout' when it is closed. */ diskfile = stdout; } else { /* normal case: create disk file for the compressed output */ strcpy(mode, "w+b"); /* create file with read-write */ diskfile = fopen(filename, "r"); /* does file already exist? */ if (diskfile) { fclose(diskfile); /* close file and exit with error */ return(FILE_NOT_CREATED); } #if MACHINE == ALPHAVMS || MACHINE == VAXVMS /* specify VMS record structure: fixed format, 2880 byte records */ /* but force stream mode access to enable random I/O access */ diskfile = fopen(filename, mode, "rfm=fix", "mrs=2880", "ctx=stm"); #else diskfile = fopen(filename, mode); #endif if (!(diskfile)) /* couldn't create file */ { return(FILE_NOT_CREATED); } } /* now create temporary memory file */ /* initially allocate 1 FITS block = 2880 bytes */ status = mem_createmem(2880L, handle); if (status) { ffpmsg("failed to create empty memory file (mem_create_comp)"); return(status); } memTable[*handle].fileptr = diskfile; return(0); } /*--------------------------------------------------------------------------*/ int mem_openmem(void **buffptr, /* I - address of memory pointer */ size_t *buffsize, /* I - size of buffer, in bytes */ size_t deltasize, /* I - increment for future realloc's */ void *(*memrealloc)(void *p, size_t newsize), /* function */ int *handle) /* lowest level routine to open a pre-existing memory file. */ { int ii; *handle = -1; for (ii = 0; ii < NMAXFILES; ii++) /* find empty slot in handle table */ { if (memTable[ii].memaddrptr == 0) { *handle = ii; break; } } if (*handle == -1) return(TOO_MANY_FILES); /* too many files opened */ memTable[ii].memaddrptr = (char **) buffptr; /* pointer to start addres */ memTable[ii].memsizeptr = buffsize; /* allocated size of memory */ memTable[ii].deltasize = deltasize; /* suggested realloc increment */ memTable[ii].fitsfilesize = *buffsize; /* size of FITS file (upper limit) */ memTable[ii].currentpos = 0; /* at beginning of the file */ memTable[ii].mem_realloc = memrealloc; /* memory realloc function */ return(0); } /*--------------------------------------------------------------------------*/ int mem_createmem(size_t msize, int *handle) /* lowest level routine to allocate a memory file. */ { int ii; *handle = -1; for (ii = 0; ii < NMAXFILES; ii++) /* find empty slot in handle table */ { if (memTable[ii].memaddrptr == 0) { *handle = ii; break; } } if (*handle == -1) return(TOO_MANY_FILES); /* too many files opened */ /* use the internally allocated memaddr and memsize variables */ memTable[ii].memaddrptr = &memTable[ii].memaddr; memTable[ii].memsizeptr = &memTable[ii].memsize; /* allocate initial block of memory for the file */ if (msize > 0) { memTable[ii].memaddr = (char *) malloc(msize); if ( !(memTable[ii].memaddr) ) { ffpmsg("malloc of initial memory failed (mem_createmem)"); return(FILE_NOT_OPENED); } } /* set initial state of the file */ memTable[ii].memsize = msize; memTable[ii].deltasize = 2880; memTable[ii].fitsfilesize = 0; memTable[ii].currentpos = 0; memTable[ii].mem_realloc = realloc; return(0); } /*--------------------------------------------------------------------------*/ int mem_truncate(int handle, LONGLONG filesize) /* truncate the file to a new size */ { char *ptr; /* call the memory reallocation function, if defined */ if ( memTable[handle].mem_realloc ) { /* explicit LONGLONG->size_t cast */ ptr = (memTable[handle].mem_realloc)( *(memTable[handle].memaddrptr), (size_t) filesize); if (!ptr) { ffpmsg("Failed to reallocate memory (mem_truncate)"); return(MEMORY_ALLOCATION); } /* if allocated more memory, initialize it to zero */ if ( filesize > *(memTable[handle].memsizeptr) ) { memset(ptr + *(memTable[handle].memsizeptr), 0, ((size_t) filesize) - *(memTable[handle].memsizeptr) ); } *(memTable[handle].memaddrptr) = ptr; *(memTable[handle].memsizeptr) = (size_t) (filesize); } memTable[handle].fitsfilesize = filesize; return(0); } /*--------------------------------------------------------------------------*/ int stdin_checkfile(char *urltype, char *infile, char *outfile) /* do any special case checking when opening a file on the stdin stream */ { if (strlen(outfile)) { strcpy(stdin_outfile,outfile); /* an output file is specified */ strcpy(urltype,"stdinfile://"); } else *stdin_outfile = '\0'; /* no output file was specified */ return(0); } /*--------------------------------------------------------------------------*/ int stdin_open(char *filename, int rwmode, int *handle) /* open a FITS file from the stdin file stream by copying it into memory The file name is ignored in this case. */ { int status = 0; char cbuff; if (*stdin_outfile) { /* copy the stdin stream to the specified disk file then open the file */ /* Create the output file */ status = file_create(stdin_outfile,handle); if (status) { ffpmsg("Unable to create output file to copy stdin (stdin_open):"); ffpmsg(stdin_outfile); return(status); } /* copy the whole stdin stream to the file */ status = stdin2file(*handle); file_close(*handle); if (status) { ffpmsg("failed to copy stdin to file (stdin_open)"); ffpmsg(stdin_outfile); return(status); } /* reopen file with proper rwmode attribute */ status = file_open(stdin_outfile, rwmode, handle); } else { /* get the first character, then put it back */ cbuff = fgetc(stdin); ungetc(cbuff, stdin); /* compressed files begin with 037 or 'P' */ if (cbuff == 31 || cbuff == 75) { /* looks like the input stream is compressed */ status = mem_compress_stdin_open(filename, rwmode, handle); } else { /* copy the stdin stream into memory then open file in memory */ if (rwmode != READONLY) { ffpmsg("cannot open stdin with WRITE access"); return(READONLY_FILE); } status = mem_createmem(2880L, handle); if (status) { ffpmsg("failed to create empty memory file (stdin_open)"); return(status); } /* copy the whole stdin stream into memory */ status = stdin2mem(*handle); if (status) { ffpmsg("failed to copy stdin into memory (stdin_open)"); free(memTable[*handle].memaddr); } } } return(status); } /*--------------------------------------------------------------------------*/ int stdin2mem(int hd) /* handle number */ /* Copy the stdin stream into memory. Fill whatever amount of memory has already been allocated, then realloc more memory if necessary. */ { size_t nread, memsize, delta; LONGLONG filesize; char *memptr; char simple[] = "SIMPLE"; int c, ii, jj; memptr = *memTable[hd].memaddrptr; memsize = *memTable[hd].memsizeptr; delta = memTable[hd].deltasize; filesize = 0; ii = 0; for(jj = 0; (c = fgetc(stdin)) != EOF && jj < 2000; jj++) { /* Skip over any garbage at the beginning of the stdin stream by */ /* reading 1 char at a time, looking for 'S', 'I', 'M', 'P', 'L', 'E' */ /* Give up if not found in the first 2000 characters */ if (c == simple[ii]) { ii++; if (ii == 6) /* found the complete string? */ { memcpy(memptr, simple, 6); /* copy "SIMPLE" to buffer */ filesize = 6; break; } } else ii = 0; /* reset search to beginning of the string */ } if (filesize == 0) { ffpmsg("Couldn't find the string 'SIMPLE' in the stdin stream."); ffpmsg("This does not look like a FITS file."); return(FILE_NOT_OPENED); } /* fill up the remainder of the initial memory allocation */ nread = fread(memptr + 6, 1, memsize - 6, stdin); nread += 6; /* add in the 6 characters in 'SIMPLE' */ if (nread < memsize) /* reached the end? */ { memTable[hd].fitsfilesize = nread; return(0); } filesize = nread; while (1) { /* allocate memory for another FITS block */ memptr = realloc(memptr, memsize + delta); if (!memptr) { ffpmsg("realloc failed while copying stdin (stdin2mem)"); return(MEMORY_ALLOCATION); } memsize += delta; /* read another FITS block */ nread = fread(memptr + filesize, 1, delta, stdin); filesize += nread; if (nread < delta) /* reached the end? */ break; } memTable[hd].fitsfilesize = filesize; *memTable[hd].memaddrptr = memptr; *memTable[hd].memsizeptr = memsize; return(0); } /*--------------------------------------------------------------------------*/ int stdin2file(int handle) /* handle number */ /* Copy the stdin stream to a file. . */ { size_t nread = 0; char simple[] = "SIMPLE"; int c, ii, jj, status = 0; char recbuf[RECBUFLEN]; ii = 0; for(jj = 0; (c = fgetc(stdin)) != EOF && jj < 2000; jj++) { /* Skip over any garbage at the beginning of the stdin stream by */ /* reading 1 char at a time, looking for 'S', 'I', 'M', 'P', 'L', 'E' */ /* Give up if not found in the first 2000 characters */ if (c == simple[ii]) { ii++; if (ii == 6) /* found the complete string? */ { memcpy(recbuf, simple, 6); /* copy "SIMPLE" to buffer */ break; } } else ii = 0; /* reset search to beginning of the string */ } if (ii != 6) { ffpmsg("Couldn't find the string 'SIMPLE' in the stdin stream"); return(FILE_NOT_OPENED); } /* fill up the remainder of the buffer */ nread = fread(recbuf + 6, 1, RECBUFLEN - 6, stdin); nread += 6; /* add in the 6 characters in 'SIMPLE' */ status = file_write(handle, recbuf, nread); if (status) return(status); /* copy the rest of stdin stream */ while(0 != (nread = fread(recbuf,1,RECBUFLEN, stdin))) { status = file_write(handle, recbuf, nread); if (status) return(status); } return(status); } /*--------------------------------------------------------------------------*/ int stdout_close(int handle) /* copy the memory file to stdout, then free the memory */ { int status = 0; /* copy from memory to standard out. explicit LONGLONG->size_t cast */ if(fwrite(memTable[handle].memaddr, 1, ((size_t) memTable[handle].fitsfilesize), stdout) != (size_t) memTable[handle].fitsfilesize ) { ffpmsg("failed to copy memory file to stdout (stdout_close)"); status = WRITE_ERROR; } free( memTable[handle].memaddr ); /* free the memory */ memTable[handle].memaddrptr = 0; memTable[handle].memaddr = 0; return(status); } /*--------------------------------------------------------------------------*/ int mem_compress_openrw(char *filename, int rwmode, int *hdl) /* This routine opens the compressed diskfile and creates an empty memory buffer with an appropriate size, then calls mem_uncompress2mem. It allows the memory 'file' to be opened with READWRITE access. */ { return(mem_compress_open(filename, READONLY, hdl)); } /*--------------------------------------------------------------------------*/ int mem_compress_open(char *filename, int rwmode, int *hdl) /* This routine opens the compressed diskfile and creates an empty memory buffer with an appropriate size, then calls mem_uncompress2mem. */ { FILE *diskfile; int status, estimated = 1; unsigned char buffer[4]; size_t finalsize; char *ptr; if (rwmode != READONLY) { ffpmsg( "cannot open compressed file with WRITE access (mem_compress_open)"); ffpmsg(filename); return(READONLY_FILE); } /* open the compressed disk file */ status = file_openfile(filename, READONLY, &diskfile); if (status) { ffpmsg("failed to open compressed disk file (compress_open)"); ffpmsg(filename); return(status); } if (fread(buffer, 1, 2, diskfile) != 2) /* read 2 bytes */ { fclose(diskfile); return(READ_ERROR); } if (memcmp(buffer, "\037\213", 2) == 0) /* GZIP */ { /* the uncompressed file size is give at the end of the file */ fseek(diskfile, 0, 2); /* move to end of file */ fseek(diskfile, -4L, 1); /* move back 4 bytes */ fread(buffer, 1, 4L, diskfile); /* read 4 bytes */ /* have to worry about integer byte order */ finalsize = buffer[0]; finalsize |= buffer[1] << 8; finalsize |= buffer[2] << 16; finalsize |= buffer[3] << 24; estimated = 0; /* file size is known, not estimated */ } else if (memcmp(buffer, "\120\113", 2) == 0) /* PKZIP */ { /* the uncompressed file size is give at byte 22 the file */ fseek(diskfile, 22L, 0); /* move to byte 22 */ fread(buffer, 1, 4L, diskfile); /* read 4 bytes */ /* have to worry about integer byte order */ finalsize = buffer[0]; finalsize |= buffer[1] << 8; finalsize |= buffer[2] << 16; finalsize |= buffer[3] << 24; estimated = 0; /* file size is known, not estimated */ } else if (memcmp(buffer, "\037\036", 2) == 0) /* PACK */ finalsize = 0; /* for most methods we can't determine final size */ else if (memcmp(buffer, "\037\235", 2) == 0) /* LZW */ finalsize = 0; /* for most methods we can't determine final size */ else if (memcmp(buffer, "\037\240", 2) == 0) /* LZH */ finalsize = 0; /* for most methods we can't determine final size */ else { /* not a compressed file; this should never happen */ fclose(diskfile); return(1); } if (finalsize == 0) /* estimate uncompressed file size */ { fseek(diskfile, 0, 2); /* move to end of the compressed file */ finalsize = ftell(diskfile); /* position = size of file */ finalsize = finalsize * 3; /* assume factor of 3 compression */ } fseek(diskfile, 0, 0); /* move back to beginning of file */ /* create a memory file big enough (hopefully) for the uncompressed file */ status = mem_createmem(finalsize, hdl); if (status && estimated) { /* memory allocation failed, so try a smaller estimated size */ finalsize = finalsize / 3; status = mem_createmem(finalsize, hdl); } if (status) { fclose(diskfile); ffpmsg("failed to create empty memory file (compress_open)"); return(status); } /* uncompress file into memory */ status = mem_uncompress2mem(filename, diskfile, *hdl); fclose(diskfile); if (status) { mem_close_free(*hdl); /* free up the memory */ ffpmsg("failed to uncompress file into memory (compress_open)"); return(status); } /* if we allocated too much memory initially, then free it */ if (*(memTable[*hdl].memsizeptr) > (( (size_t) memTable[*hdl].fitsfilesize) + 256L) ) { ptr = realloc(*(memTable[*hdl].memaddrptr), ((size_t) memTable[*hdl].fitsfilesize) ); if (!ptr) { ffpmsg("Failed to reduce size of allocated memory (compress_open)"); return(MEMORY_ALLOCATION); } *(memTable[*hdl].memaddrptr) = ptr; *(memTable[*hdl].memsizeptr) = (size_t) (memTable[*hdl].fitsfilesize); } return(0); } /*--------------------------------------------------------------------------*/ int mem_compress_stdin_open(char *filename, int rwmode, int *hdl) /* This routine reads the compressed input stream and creates an empty memory buffer, then calls mem_uncompress2mem. */ { int status; char *ptr; if (rwmode != READONLY) { ffpmsg( "cannot open compressed input stream with WRITE access (mem_compress_stdin_open)"); return(READONLY_FILE); } /* create a memory file for the uncompressed file */ status = mem_createmem(28800, hdl); if (status) { ffpmsg("failed to create empty memory file (compress_stdin_open)"); return(status); } /* uncompress file into memory */ status = mem_uncompress2mem(filename, stdin, *hdl); if (status) { mem_close_free(*hdl); /* free up the memory */ ffpmsg("failed to uncompress stdin into memory (compress_stdin_open)"); return(status); } /* if we allocated too much memory initially, then free it */ if (*(memTable[*hdl].memsizeptr) > (( (size_t) memTable[*hdl].fitsfilesize) + 256L) ) { ptr = realloc(*(memTable[*hdl].memaddrptr), ((size_t) memTable[*hdl].fitsfilesize) ); if (!ptr) { ffpmsg("Failed to reduce size of allocated memory (compress_stdin_open)"); return(MEMORY_ALLOCATION); } *(memTable[*hdl].memaddrptr) = ptr; *(memTable[*hdl].memsizeptr) = (size_t) (memTable[*hdl].fitsfilesize); } return(0); } /*--------------------------------------------------------------------------*/ int mem_iraf_open(char *filename, int rwmode, int *hdl) /* This routine creates an empty memory buffer, then calls iraf2mem to open the IRAF disk file and convert it to a FITS file in memeory. */ { int status; size_t filesize = 0; /* create a memory file with size = 0 for the FITS converted IRAF file */ status = mem_createmem(filesize, hdl); if (status) { ffpmsg("failed to create empty memory file (mem_iraf_open)"); return(status); } /* convert the iraf file into a FITS file in memory */ status = iraf2mem(filename, memTable[*hdl].memaddrptr, memTable[*hdl].memsizeptr, &filesize, &status); if (status) { mem_close_free(*hdl); /* free up the memory */ ffpmsg("failed to convert IRAF file into memory (mem_iraf_open)"); return(status); } memTable[*hdl].currentpos = 0; /* save starting position */ memTable[*hdl].fitsfilesize=filesize; /* and initial file size */ return(0); } /*--------------------------------------------------------------------------*/ int mem_rawfile_open(char *filename, int rwmode, int *hdl) /* This routine creates an empty memory buffer, writes a minimal image header, then copies the image data from the raw file into memory. It will byteswap the pixel values if the raw array is in little endian byte order. */ { FILE *diskfile; fitsfile *fptr; short *sptr; int status, endian, datatype, bytePerPix, naxis; long dim[5] = {1,1,1,1,1}, ii, nvals, offset = 0; size_t filesize = 0, datasize; char rootfile[FLEN_FILENAME], *cptr = 0, *cptr2 = 0; void *ptr; if (rwmode != READONLY) { ffpmsg( "cannot open raw binary file with WRITE access (mem_rawfile_open)"); ffpmsg(filename); return(READONLY_FILE); } cptr = strchr(filename, '['); /* search for opening bracket [ */ if (!cptr) { ffpmsg("binary file name missing '[' character (mem_rawfile_open)"); ffpmsg(filename); return(URL_PARSE_ERROR); } *rootfile = '\0'; strncat(rootfile, filename, cptr - filename); /* store the rootname */ cptr++; while (*cptr == ' ') cptr++; /* skip leading blanks */ /* Get the Data Type of the Image */ if (*cptr == 'b' || *cptr == 'B') { datatype = BYTE_IMG; bytePerPix = 1; } else if (*cptr == 'i' || *cptr == 'I') { datatype = SHORT_IMG; bytePerPix = 2; } else if (*cptr == 'u' || *cptr == 'U') { datatype = USHORT_IMG; bytePerPix = 2; } else if (*cptr == 'j' || *cptr == 'J') { datatype = LONG_IMG; bytePerPix = 4; } else if (*cptr == 'r' || *cptr == 'R' || *cptr == 'f' || *cptr == 'F') { datatype = FLOAT_IMG; bytePerPix = 4; } else if (*cptr == 'd' || *cptr == 'D') { datatype = DOUBLE_IMG; bytePerPix = 8; } else { ffpmsg("error in raw binary file datatype (mem_rawfile_open)"); ffpmsg(filename); return(URL_PARSE_ERROR); } cptr++; /* get Endian: Big or Little; default is same as the local machine */ if (*cptr == 'b' || *cptr == 'B') { endian = 0; cptr++; } else if (*cptr == 'l' || *cptr == 'L') { endian = 1; cptr++; } else endian = BYTESWAPPED; /* byteswapped machines are little endian */ /* read each dimension (up to 5) */ naxis = 1; dim[0] = strtol(cptr, &cptr2, 10); if (cptr2 && *cptr2 == ',') { naxis = 2; dim[1] = strtol(cptr2+1, &cptr, 10); if (cptr && *cptr == ',') { naxis = 3; dim[2] = strtol(cptr+1, &cptr2, 10); if (cptr2 && *cptr2 == ',') { naxis = 4; dim[3] = strtol(cptr2+1, &cptr, 10); if (cptr && *cptr == ',') naxis = 5; dim[4] = strtol(cptr+1, &cptr2, 10); } } } cptr = maxvalue(cptr, cptr2); if (*cptr == ':') /* read starting offset value */ offset = strtol(cptr+1, 0, 10); nvals = dim[0] * dim[1] * dim[2] * dim[3] * dim[4]; datasize = nvals * bytePerPix; filesize = nvals * bytePerPix + 2880; filesize = ((filesize - 1) / 2880 + 1) * 2880; /* open the raw binary disk file */ status = file_openfile(rootfile, READONLY, &diskfile); if (status) { ffpmsg("failed to open raw binary file (mem_rawfile_open)"); ffpmsg(rootfile); return(status); } /* create a memory file with corrct size for the FITS converted raw file */ status = mem_createmem(filesize, hdl); if (status) { ffpmsg("failed to create memory file (mem_rawfile_open)"); fclose(diskfile); return(status); } /* open this piece of memory as a new FITS file */ ffimem(&fptr, (void **) memTable[*hdl].memaddrptr, &filesize, 0, 0, &status); /* write the required header keywords */ ffcrim(fptr, datatype, naxis, dim, &status); /* close the FITS file, but keep the memory allocated */ ffclos(fptr, &status); if (status > 0) { ffpmsg("failed to write basic image header (mem_rawfile_open)"); fclose(diskfile); mem_close_free(*hdl); /* free up the memory */ return(status); } if (offset > 0) fseek(diskfile, offset, 0); /* offset to start of the data */ /* read the raw data into memory */ ptr = *memTable[*hdl].memaddrptr + 2880; if (fread((char *) ptr, 1, datasize, diskfile) != datasize) status = READ_ERROR; fclose(diskfile); /* close the raw binary disk file */ if (status) { mem_close_free(*hdl); /* free up the memory */ ffpmsg("failed to copy raw file data into memory (mem_rawfile_open)"); return(status); } if (datatype == USHORT_IMG) /* have to subtract 32768 from each unsigned */ { /* value to conform to FITS convention. More */ /* efficient way to do this is to just flip */ /* the most significant bit. */ sptr = (short *) ptr; if (endian == BYTESWAPPED) /* working with native format */ { for (ii = 0; ii < nvals; ii++, sptr++) { *sptr = ( *sptr ) ^ 0x8000; } } else /* pixels are byteswapped WRT the native format */ { for (ii = 0; ii < nvals; ii++, sptr++) { *sptr = ( *sptr ) ^ 0x80; } } } if (endian) /* swap the bytes if array is in little endian byte order */ { if (datatype == SHORT_IMG || datatype == USHORT_IMG) { ffswap2( (short *) ptr, nvals); } else if (datatype == LONG_IMG || datatype == FLOAT_IMG) { ffswap4( (INT32BIT *) ptr, nvals); } else if (datatype == DOUBLE_IMG) { ffswap8( (double *) ptr, nvals); } } memTable[*hdl].currentpos = 0; /* save starting position */ memTable[*hdl].fitsfilesize=filesize; /* and initial file size */ return(0); } /*--------------------------------------------------------------------------*/ int mem_uncompress2mem(char *filename, FILE *diskfile, int hdl) { /* lower level routine to uncompress a file into memory. The file has already been opened and the memory buffer has been allocated. */ size_t finalsize; int status; /* uncompress file into memory */ status = 0; uncompress2mem(filename, diskfile, memTable[hdl].memaddrptr, /* pointer to memory address */ memTable[hdl].memsizeptr, /* pointer to size of memory */ realloc, /* reallocation function */ &finalsize, &status); /* returned file size nd status*/ memTable[hdl].currentpos = 0; /* save starting position */ memTable[hdl].fitsfilesize=finalsize; /* and initial file size */ return status; } /*--------------------------------------------------------------------------*/ int mem_size(int handle, LONGLONG *filesize) /* return the size of the file; only called when the file is first opened */ { *filesize = memTable[handle].fitsfilesize; return(0); } /*--------------------------------------------------------------------------*/ int mem_close_free(int handle) /* close the file and free the memory. */ { free( *(memTable[handle].memaddrptr) ); memTable[handle].memaddrptr = 0; memTable[handle].memaddr = 0; return(0); } /*--------------------------------------------------------------------------*/ int mem_close_keep(int handle) /* close the memory file but do not free the memory. */ { memTable[handle].memaddrptr = 0; memTable[handle].memaddr = 0; return(0); } /*--------------------------------------------------------------------------*/ int mem_close_comp(int handle) /* compress the memory file, writing it out to the fileptr (which might be stdout) */ { int status = 0; size_t compsize; /* compress file in memory to a .gz disk file */ if(compress2file_from_mem(memTable[handle].memaddr, (size_t) (memTable[handle].fitsfilesize), memTable[handle].fileptr, &compsize, &status ) ) { ffpmsg("failed to copy memory file to file (mem_close_comp)"); status = WRITE_ERROR; } free( memTable[handle].memaddr ); /* free the memory */ memTable[handle].memaddrptr = 0; memTable[handle].memaddr = 0; /* close the compressed disk file (except if it is 'stdout' */ if (memTable[handle].fileptr != stdout) fclose(memTable[handle].fileptr); return(status); } /*--------------------------------------------------------------------------*/ int mem_seek(int handle, LONGLONG offset) /* seek to position relative to start of the file. */ { if (offset > memTable[handle].fitsfilesize ) return(END_OF_FILE); memTable[handle].currentpos = offset; return(0); } /*--------------------------------------------------------------------------*/ int mem_read(int hdl, void *buffer, long nbytes) /* read bytes from the current position in the file */ { if (memTable[hdl].currentpos + nbytes > memTable[hdl].fitsfilesize) return(END_OF_FILE); memcpy(buffer, *(memTable[hdl].memaddrptr) + memTable[hdl].currentpos, nbytes); memTable[hdl].currentpos += nbytes; return(0); } /*--------------------------------------------------------------------------*/ int mem_write(int hdl, void *buffer, long nbytes) /* write bytes at the current position in the file */ { size_t newsize; char *ptr; if ((size_t) (memTable[hdl].currentpos + nbytes) > *(memTable[hdl].memsizeptr) ) { if (!(memTable[hdl].mem_realloc)) { ffpmsg("realloc function not defined (mem_write)"); return(WRITE_ERROR); } /* Attempt to reallocate additional memory: the memory buffer size is incremented by the larger of: 1 FITS block (2880 bytes) or the defined 'deltasize' parameter */ newsize = maxvalue( (size_t) (((memTable[hdl].currentpos + nbytes - 1) / 2880) + 1) * 2880, *(memTable[hdl].memsizeptr) + memTable[hdl].deltasize); /* call the realloc function */ ptr = (memTable[hdl].mem_realloc)( *(memTable[hdl].memaddrptr), newsize); if (!ptr) { ffpmsg("Failed to reallocate memory (mem_write)"); return(MEMORY_ALLOCATION); } *(memTable[hdl].memaddrptr) = ptr; *(memTable[hdl].memsizeptr) = newsize; } /* now copy the bytes from the buffer into memory */ memcpy( *(memTable[hdl].memaddrptr) + memTable[hdl].currentpos, buffer, nbytes); memTable[hdl].currentpos += nbytes; memTable[hdl].fitsfilesize = maxvalue(memTable[hdl].fitsfilesize, memTable[hdl].currentpos); return(0); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/drvrnet.c000066400000000000000000002075131215713201500222700ustar00rootroot00000000000000/* This file, drvrhttp.c contains driver routines for http, ftp and root files. */ /* This file was written by Bruce O'Neel at the ISDC, Switzerland */ /* The FITSIO software is maintained by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ /* Notes on the drivers: The ftp driver uses passive mode exclusivly. If your remote system can't deal with passive mode then it'll fail. Since Netscape Navigator uses passive mode as well there shouldn't be too many ftp servers which have problems. The http driver works properly with 301 and 302 redirects. For many more gory details see http://www.w3c.org/Protocols/rfc2068/rfc2068. The only catch to the 301/302 redirects is that they have to redirect to another http:// url. If not, things would have to change a lot in cfitsio and this was thought to be too difficult. Redirects look like 301 Moved Permanently

Moved Permanently

The document has moved here.

This redirect was from apache 1.2.5 but most of the other servers produce something very similiar. The parser for the redirects finds the first anchor tag in the body and goes there. If that wasn't what was intended by the remote system then hopefully the error stack, which includes notes about the redirect will help the user fix the problem. Root protocal doesn't have any real docs, so, the emperical docs are as follows. First, you must use a slightly modified rootd server. The modifications include implimentation of the stat command which returns the size of the remote file. Without that it's impossible for cfitsio to work properly since fitsfiles don't include any information about the size of the files in the headers. The rootd server closes the connections on any errors, including reading beyond the end of the file or seeking beyond the end of the file. The rootd:// driver doesn't reopen a closed connection, if the connection is closed you're pretty much done. The messages are of the form All binary information is transfered in network format, so use htonl and ntohl to convert back and forth. :== 4 byte length, in network format, the len doesn't include the length of :== one of the message opcodes below, 4 bytes, network format :== depends on opcode The response is of the same form with the same opcode sent. Success is indicated by being 0. Root is a NFSish protocol where each read/write includes the byte offset to read or write to. As a result, seeks will always succeed in the driver even if they would cause a fatal error when you try to read because you're beyond the end of the file. There is file locking on the host such that you need to possibly create /usr/tmp/rootdtab on the host system. There is one file per socket connection, though the rootd daemon can support multiple files open at once. The messages are sent in the following order: ROOTD_USER - user name, is the user name, trailing null is sent though it's not required it seems. A ROOTD_AUTH message is returned with any sort of error meaning that the user name is wrong. ROOTD_PASS - password, ones complemented, stored in . Once again the trailing null is sent. Once again a ROOTD_AUTH message is returned ROOTD_OPEN - includes filename and one of {create|update|read} as the file mode. ~ seems to be dealt with as the username's login directory. A ROOTD_OPEN message is returned. Once the file is opened any of the following can be sent: ROOTD_STAT - file status and size returns a message where is the file length in bytes ROOTD_FLUSH - flushes the file, not sure this has any real effect on the daemon since the daemon uses open/read/write/close rather than the buffered fopen/fread/fwrite/fclose. ROOTD_GET - on send includes a text message of offset and length to get. Return is a status message first with a status value, then, the raw bytes for the length that you requested. It's an error to seek or read past the end of the file, and, the rootd daemon exits and won't respond anymore. Ie, don't do this. ROOTD_PUT - on send includes a text message of offset and length to put. Then send the raw bytes you want to write. Then recieve a status message When you are finished then you send the message: ROOTD_CLOSE - closes the file Once the file is closed then the socket is closed. $Id: drvrnet.c,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ $Log: drvrnet.c,v $ Revision 1.1.1.1 2009/03/31 14:11:53 cguirao skycat-3.1.1 Revision 3.45 2005/12/21 18:18:01 pence New beta 3.005 release. Contains new cfortran.h to support integer*8 parameters when calling cfitsio from Fortran tasks. Also has modified fitsio.h file that now assumes that the 'long long' data type is supported by the C compiler (which may not be the case for older compilers). Revision 1.56 2000/01/04 11:58:31 oneel Updates so that compressed network files are dealt with regardless of their file names and/or mime types. Revision 1.55 2000/01/04 10:52:40 oneel cfitsio 2.034 Revision 1.51 1999/08/10 12:13:40 oneel Make the http code a bit less picky about the types of files it uncompresses. Now it also uncompresses files which end in .Z or .gz. Revision 1.50 1999/08/04 12:38:46 oneel Don's 2.0.32 patch with dal 1.3 Revision 1.39 1998/12/02 15:31:33 oneel Updates to drvrnet.c so that less compiler warnings would be generated. Fixes the signal handling. Revision 1.38 1998/11/23 10:03:24 oneel Added in a useragent string, as suggested by: Tim Kimball · Data Systems Division ¦ kimball@stsci.edu · 410-338-4417 Space Telescope Science Institute ¦ http://www.stsci.edu/~kimball/ 3700 San Martin Drive ¦ http://archive.stsci.edu/ Baltimore MD 21218 USA ¦ http://faxafloi.stsci.edu:4547/ */ #ifdef HAVE_NET_SERVICES #include #include #include #include #include #include #include #include #include #include #include #if defined(unix) || defined(__unix__) || defined(__unix) #include #endif #include #include #include "fitsio2.h" static jmp_buf env; /* holds the jump buffer for setjmp/longjmp pairs */ static void signal_handler(int sig); /* Network routine error codes */ #define NET_OK 0 #define NOT_INET_ADDRESS -1000 #define UNKNOWN_INET_HOST -1001 #define CONNECTION_ERROR -1002 /* Network routine constants */ #define NET_DEFAULT 0 #define NET_OOB 1 #define NET_PEEK 2 #define NETTIMEOUT 180 /* in secs */ /* local defines and variables */ #define MAXLEN 1200 #define SHORTLEN 100 static char netoutfile[MAXLEN]; #define ROOTD_USER 2000 /*user id follows */ #define ROOTD_PASS 2001 /*passwd follows */ #define ROOTD_AUTH 2002 /*authorization status (to client) */ #define ROOTD_FSTAT 2003 /*filename follows */ #define ROOTD_OPEN 2004 /*filename follows + mode */ #define ROOTD_PUT 2005 /*offset, number of bytes and buffer */ #define ROOTD_GET 2006 /*offset, number of bytes */ #define ROOTD_FLUSH 2007 /*flush file */ #define ROOTD_CLOSE 2008 /*close file */ #define ROOTD_STAT 2009 /*return rootd statistics */ #define ROOTD_ACK 2010 /*acknowledgement (all OK) */ #define ROOTD_ERR 2011 /*error code and message follow */ typedef struct /* structure containing disk file structure */ { int sock; LONGLONG currentpos; } rootdriver; static rootdriver handleTable[NMAXFILES]; /* allocate diskfile handle tables */ /* static prototypes */ static int NET_TcpConnect(char *hostname, int port); static int NET_SendRaw(int sock, const void *buf, int length, int opt); static int NET_RecvRaw(int sock, void *buffer, int length); static int NET_ParseUrl(const char *url, char *proto, char *host, int *port, char *fn); static int CreateSocketAddress(struct sockaddr_in *sockaddrPtr, char *host,int port); static int ftp_status(FILE *ftp, char *statusstr); static int http_open_network(char *url, FILE **httpfile, char *contentencoding, int *contentlength); static int ftp_open_network(char *url, FILE **ftpfile, FILE **command, int *sock); static int root_send_buffer(int sock, int op, char *buffer, int buflen); static int root_recv_buffer(int sock, int *op, char *buffer,int buflen); static int root_openfile(char *filename, char *rwmode, int *sock); /***************************/ /* Static variables */ static int closehttpfile; static int closememfile; static int closefdiskfile; static int closediskfile; static int closefile; static int closeoutfile; static int closecommandfile; static int closeftpfile; static FILE *diskfile; static FILE *outfile; /*--------------------------------------------------------------------------*/ /* This creates a memory file handle with a copy of the URL in filename. The file is uncompressed if necessary */ int http_open(char *filename, int rwmode, int *handle) { FILE *httpfile; char contentencoding[SHORTLEN]; char newfilename[MAXLEN]; char errorstr[MAXLEN]; char recbuf[MAXLEN]; long len; int contentlength; int status; char firstchar; closehttpfile = 0; closememfile = 0; /* don't do r/w files */ if (rwmode != 0) { ffpmsg("Can't open http:// type file with READWRITE access"); ffpmsg(" Specify an outfile for r/w access (http_open)"); goto error; } /* do the signal handler bits */ if (setjmp(env) != 0) { /* feels like the second time */ /* this means something bad happened */ ffpmsg("Timeout (http_open)"); goto error; } (void) signal(SIGALRM, signal_handler); /* Open the network connection */ /* Does the file have a .Z or .gz in it */ /* Also, if file has a '?' in it (probably cgi script) */ if (strstr(filename,".Z") || strstr(filename,".gz") || strstr(filename,"?")) { alarm(NETTIMEOUT); if (http_open_network(filename,&httpfile,contentencoding, &contentlength)) { alarm(0); ffpmsg("Unable to open http file (http_open):"); ffpmsg(filename); goto error; } } else { alarm(NETTIMEOUT); /* Try the .gz one */ strcpy(newfilename,filename); strcat(newfilename,".gz"); if (http_open_network(newfilename,&httpfile,contentencoding, &contentlength)) { alarm(0); /* Now the .Z one */ strcpy(newfilename,filename); strcat(newfilename,".Z"); alarm(NETTIMEOUT); if (http_open_network(newfilename,&httpfile,contentencoding, &contentlength)) { alarm(0); alarm(NETTIMEOUT); if (http_open_network(filename,&httpfile,contentencoding, &contentlength)) { alarm(0); ffpmsg("Unable to open http file (http_open)"); ffpmsg(filename); goto error; } } } } closehttpfile++; /* Create the memory file */ if ((status = mem_create(filename,handle))) { ffpmsg("Unable to create memory file (http_open)"); goto error; } closememfile++; /* Now, what do we do with the file */ /* Check to see what the first character is */ firstchar = fgetc(httpfile); ungetc(firstchar,httpfile); if (!strcmp(contentencoding,"x-gzip") || !strcmp(contentencoding,"x-compress") || strstr(filename,".gz") || strstr(filename,".Z") || ('\037' == firstchar)) { /* do the compress dance, which is the same as the gzip dance */ /* Using the cfitsio routine */ status = 0; /* Ok, this is a tough case, let's be arbritary and say 10*NETTIMEOUT, Given the choices for nettimeout above they'll probaby ^C before, but it's always worth a shot*/ alarm(NETTIMEOUT*10); status = mem_uncompress2mem(filename, httpfile, *handle); alarm(0); if (status) { ffpmsg("Error writing compressed memory file (http_open)"); ffpmsg(filename); goto error; } } else { /* It's not compressed, bad choice, but we'll copy it anyway */ if (contentlength % 2880) { sprintf(errorstr,"Content-Length not a multiple of 2880 (http_open) %d", contentlength); ffpmsg(errorstr); } /* write a memory file */ alarm(NETTIMEOUT); while(0 != (len = fread(recbuf,1,MAXLEN,httpfile))) { alarm(0); /* cancel alarm */ status = mem_write(*handle,recbuf,len); if (status) { ffpmsg("Error copying http file into memory (http_open)"); ffpmsg(filename); goto error; } alarm(NETTIMEOUT); /* rearm the alarm */ } } fclose(httpfile); signal(SIGALRM, SIG_DFL); alarm(0); return mem_seek(*handle,0); error: alarm(0); /* clear it */ if (closehttpfile) { fclose(httpfile); } if (closememfile) { mem_close_free(*handle); } signal(SIGALRM, SIG_DFL); return (FILE_NOT_OPENED); } /*--------------------------------------------------------------------------*/ /* This creates a memory file handle with a copy of the URL in filename. The file must be compressed and is copied (still compressed) to disk first. The compressed disk file is then uncompressed into memory (READONLY). */ int http_compress_open(char *url, int rwmode, int *handle) { FILE *httpfile; char contentencoding[SHORTLEN]; char recbuf[MAXLEN]; long len; int contentlength; int ii, flen, status; char firstchar; closehttpfile = 0; closediskfile = 0; closefdiskfile = 0; closememfile = 0; /* cfileio made a mistake, should set the netoufile first otherwise we don't know where to write the output file */ flen = strlen(netoutfile); if (!flen) { ffpmsg ("Output file not set, shouldn't have happened (http_compress_open)"); goto error; } if (rwmode != 0) { ffpmsg("Can't open compressed http:// type file with READWRITE access"); ffpmsg(" Specify an UNCOMPRESSED outfile (http_compress_open)"); goto error; } /* do the signal handler bits */ if (setjmp(env) != 0) { /* feels like the second time */ /* this means something bad happened */ ffpmsg("Timeout (http_open)"); goto error; } signal(SIGALRM, signal_handler); /* Open the http connectin */ alarm(NETTIMEOUT); if ((status = http_open_network(url,&httpfile,contentencoding, &contentlength))) { alarm(0); ffpmsg("Unable to open http file (http_compress_open)"); ffpmsg(url); goto error; } closehttpfile++; /* Better be compressed */ firstchar = fgetc(httpfile); ungetc(firstchar,httpfile); if (!strcmp(contentencoding,"x-gzip") || !strcmp(contentencoding,"x-compress") || ('\037' == firstchar)) { if (*netoutfile == '!') { /* user wants to clobber file, if it already exists */ for (ii = 0; ii < flen; ii++) netoutfile[ii] = netoutfile[ii + 1]; /* remove '!' */ status = file_remove(netoutfile); } /* Create the new file */ if ((status = file_create(netoutfile,handle))) { ffpmsg("Unable to create output disk file (http_compress_open):"); ffpmsg(netoutfile); goto error; } closediskfile++; /* write a file */ alarm(NETTIMEOUT); while(0 != (len = fread(recbuf,1,MAXLEN,httpfile))) { alarm(0); status = file_write(*handle,recbuf,len); if (status) { ffpmsg("Error writing disk file (http_compres_open)"); ffpmsg(netoutfile); goto error; } alarm(NETTIMEOUT); } file_close(*handle); fclose(httpfile); closehttpfile--; closediskfile--; /* File is on disk, let's uncompress it into memory */ if (NULL == (diskfile = fopen(netoutfile,"r"))) { ffpmsg("Unable to reopen disk file (http_compress_open)"); ffpmsg(netoutfile); goto error; } closefdiskfile++; /* Create the memory handle to hold it */ if ((status = mem_create(url,handle))) { ffpmsg("Unable to create memory file (http_compress_open)"); goto error; } closememfile++; /* Uncompress it */ status = 0; status = mem_uncompress2mem(url,diskfile,*handle); fclose(diskfile); closefdiskfile--; if (status) { ffpmsg("Error uncompressing disk file to memory (http_compress_open)"); ffpmsg(netoutfile); goto error; } } else { /* Opps, this should not have happened */ ffpmsg("Can only have compressed files here (http_compress_open)"); goto error; } signal(SIGALRM, SIG_DFL); alarm(0); return mem_seek(*handle,0); error: alarm(0); /* clear it */ if (closehttpfile) { fclose(httpfile); } if (closefdiskfile) { fclose(diskfile); } if (closememfile) { mem_close_free(*handle); } if (closediskfile) { file_close(*handle); } signal(SIGALRM, SIG_DFL); return (FILE_NOT_OPENED); } /*--------------------------------------------------------------------------*/ /* This creates a file handle with a copy of the URL in filename. The http file is copied to disk first. If it's compressed then it is uncompressed when copying to the disk */ int http_file_open(char *url, int rwmode, int *handle) { FILE *httpfile; char contentencoding[SHORTLEN]; char errorstr[MAXLEN]; char recbuf[MAXLEN]; long len; int contentlength; int ii, flen, status; char firstchar; /* Check if output file is actually a memory file */ if (!strncmp(netoutfile, "mem:", 4) ) { /* allow the memory file to be opened with write access */ return( http_open(url, READONLY, handle) ); } closehttpfile = 0; closefile = 0; closeoutfile = 0; /* cfileio made a mistake, we need to know where to write the file */ flen = strlen(netoutfile); if (!flen) { ffpmsg("Output file not set, shouldn't have happened (http_file_open)"); return (FILE_NOT_OPENED); } /* do the signal handler bits */ if (setjmp(env) != 0) { /* feels like the second time */ /* this means something bad happened */ ffpmsg("Timeout (http_open)"); goto error; } signal(SIGALRM, signal_handler); /* Open the network connection */ alarm(NETTIMEOUT); if ((status = http_open_network(url,&httpfile,contentencoding, &contentlength))) { alarm(0); ffpmsg("Unable to open http file (http_file_open)"); ffpmsg(url); goto error; } closehttpfile++; if (*netoutfile == '!') { /* user wants to clobber disk file, if it already exists */ for (ii = 0; ii < flen; ii++) netoutfile[ii] = netoutfile[ii + 1]; /* remove '!' */ status = file_remove(netoutfile); } firstchar = fgetc(httpfile); ungetc(firstchar,httpfile); if (!strcmp(contentencoding,"x-gzip") || !strcmp(contentencoding,"x-compress") || ('\037' == firstchar)) { /* to make this more cfitsioish we use the file driver calls to create the disk file */ /* Create the output file */ if ((status = file_create(netoutfile,handle))) { ffpmsg("Unable to create output file (http_file_open)"); ffpmsg(netoutfile); goto error; } file_close(*handle); if (NULL == (outfile = fopen(netoutfile,"w"))) { ffpmsg("Unable to reopen the output file (http_file_open)"); ffpmsg(netoutfile); goto error; } closeoutfile++; status = 0; /* Ok, this is a tough case, let's be arbritary and say 10*NETTIMEOUT, Given the choices for nettimeout above they'll probaby ^C before, but it's always worth a shot*/ alarm(NETTIMEOUT*10); status = uncompress2file(url,httpfile,outfile,&status); alarm(0); if (status) { ffpmsg("Error uncompressing http file to disk file (http_file_open)"); ffpmsg(url); ffpmsg(netoutfile); goto error; } fclose(outfile); closeoutfile--; } else { /* Create the output file */ if ((status = file_create(netoutfile,handle))) { ffpmsg("Unable to create output file (http_file_open)"); ffpmsg(netoutfile); goto error; } /* Give a warning message. This could just be bad padding at the end so don't treat it like an error. */ closefile++; if (contentlength % 2880) { sprintf(errorstr, "Content-Length not a multiple of 2880 (http_file_open) %d", contentlength); ffpmsg(errorstr); } /* write a file */ alarm(NETTIMEOUT); while(0 != (len = fread(recbuf,1,MAXLEN,httpfile))) { alarm(0); status = file_write(*handle,recbuf,len); if (status) { ffpmsg("Error copying http file to disk file (http_file_open)"); ffpmsg(url); ffpmsg(netoutfile); goto error; } } file_close(*handle); closefile--; } fclose(httpfile); closehttpfile--; signal(SIGALRM, SIG_DFL); alarm(0); return file_open(netoutfile,rwmode,handle); error: alarm(0); /* clear it */ if (closehttpfile) { fclose(httpfile); } if (closeoutfile) { fclose(outfile); } if (closefile) { file_close(*handle); } signal(SIGALRM, SIG_DFL); return (FILE_NOT_OPENED); } /*--------------------------------------------------------------------------*/ /* This is the guts of the code to get a file via http. url is the input url httpfile is set to be the file connected to the socket which you can read the file from contentencoding is the mime type of the file, returned if the http server returns it contentlength is the lenght of the file, returned if the http server returns it */ static int http_open_network(char *url, FILE **httpfile, char *contentencoding, int *contentlength) { int status; int sock; int tmpint; char recbuf[MAXLEN]; char tmpstr[MAXLEN]; char tmpstr1[SHORTLEN]; char errorstr[MAXLEN]; char proto[SHORTLEN]; char host[SHORTLEN]; char fn[MAXLEN]; char turl[MAXLEN]; char *scratchstr; int port; float version; char pproto[SHORTLEN]; char phost[SHORTLEN]; /* address of the proxy server */ int pport; /* port number of the proxy server */ char pfn[MAXLEN]; char *proxy; /* URL of the proxy server */ /* Parse the URL apart again */ strcpy(turl,"http://"); strcat(turl,url); if (NET_ParseUrl(turl,proto,host,&port,fn)) { sprintf(errorstr,"URL Parse Error (http_open) %s",url); ffpmsg(errorstr); return (FILE_NOT_OPENED); } /* Ph. Prugniel 2003/04/03 Are we using a proxy? We use a proxy if the environment variable "http_proxy" is set to an address, eg. http://wwwcache.nottingham.ac.uk:3128 ("http_proxy" is also used by wget) */ proxy = getenv("http_proxy"); /* Connect to the remote host */ if (proxy) { if (NET_ParseUrl(proxy,pproto,phost,&pport,pfn)) { sprintf(errorstr,"URL Parse Error (http_open) %s",proxy); ffpmsg(errorstr); return (FILE_NOT_OPENED); } sock = NET_TcpConnect(phost,pport); } else sock = NET_TcpConnect(host,port); if (sock < 0) { if (proxy) { ffpmsg("Couldn't connect to host via proxy server (http_open_network)"); ffpmsg(proxy); } return (FILE_NOT_OPENED); } /* Make the socket a stdio file */ if (NULL == (*httpfile = fdopen(sock,"r"))) { ffpmsg ("fdopen failed to convert socket to file (http_open_network)"); close(sock); return (FILE_NOT_OPENED); } /* Send the GET request to the remote server */ /* Ph. Prugniel 2003/04/03 One must add the Host: command because of HTTP 1.1 servers (ie. virtual hosts) */ if (proxy) sprintf(tmpstr,"GET http://%s:%-d%s HTTP/1.0\r\n",host,port,fn); else sprintf(tmpstr,"GET %s HTTP/1.0\r\n",fn); sprintf(tmpstr1,"User-Agent: HEASARC/CFITSIO/%-8.3f\r\n",ffvers(&version)); strcat(tmpstr,tmpstr1); /* HTTP 1.1 servers require the following 'Host: ' string */ sprintf(tmpstr1,"Host: %s:%-d\r\n\r\n",host,port); strcat(tmpstr,tmpstr1); status = NET_SendRaw(sock,tmpstr,strlen(tmpstr),NET_DEFAULT); /* read the header */ if (!(fgets(recbuf,MAXLEN,*httpfile))) { sprintf (errorstr,"http header short (http_open_network) %s",recbuf); ffpmsg(errorstr); fclose(*httpfile); return (FILE_NOT_OPENED); } *contentlength = 0; contentencoding[0] = '\0'; /* Our choices are 200, ok, 301, temporary redirect, or 302 perm redirect */ sscanf(recbuf,"%s %d",tmpstr,&status); if (status != 200){ if (status == 301 || status == 302) { /* got a redirect */ if (status == 301) { ffpmsg("Note: Web server replied with a temporary redirect from"); } else { ffpmsg("Note: Web server replied with a redirect from"); } ffpmsg(turl); /* now, let's not write the most sophisticated parser here */ while (fgets(recbuf,MAXLEN,*httpfile)) { scratchstr = strstr(recbuf," 3) { recbuf[strlen(recbuf)-1] = '\0'; recbuf[strlen(recbuf)-1] = '\0'; } sscanf(recbuf,"%s %d",tmpstr,&tmpint); /* Did we get a content-length header ? */ if (!strcmp(tmpstr,"Content-Length:")) { *contentlength = tmpint; } /* Did we get the content-encoding header ? */ if (!strcmp(tmpstr,"Content-Encoding:")) { if (NULL != (scratchstr = strstr(recbuf,":"))) { /* Found the : */ scratchstr++; /* skip the : */ scratchstr++; /* skip the extra space */ strcpy(contentencoding,scratchstr); } } } /* we're done, so return */ return 0; } /*--------------------------------------------------------------------------*/ /* This creates a memory file handle with a copy of the URL in filename. The file is uncompressed if necessary */ int ftp_open(char *filename, int rwmode, int *handle) { FILE *ftpfile; FILE *command; int sock; char newfilename[MAXLEN]; char recbuf[MAXLEN]; long len; int status; char firstchar; closememfile = 0; closecommandfile = 0; closeftpfile = 0; /* don't do r/w files */ if (rwmode != 0) { ffpmsg("Can't open ftp:// type file with READWRITE access"); ffpmsg("Specify an outfile for r/w access (ftp_open)"); return (FILE_NOT_OPENED); } /* do the signal handler bits */ if (setjmp(env) != 0) { /* feels like the second time */ /* this means something bad happened */ ffpmsg("Timeout (http_open)"); goto error; } signal(SIGALRM, signal_handler); /* Open the ftp connetion. ftpfile is connected to the file port, command is connected to port 21. sock is the socket on port 21 */ alarm(NETTIMEOUT); strcpy(newfilename,filename); /* Does the file have a .Z or .gz in it */ if (strstr(newfilename,".Z") || strstr(newfilename,".gz")) { alarm(NETTIMEOUT); if (ftp_open_network(filename,&ftpfile,&command,&sock)) { alarm(0); ffpmsg("Unable to open ftp file (ftp_open)"); ffpmsg(filename); goto error; } } else { /* Try the .gz one */ strcpy(newfilename,filename); strcat(newfilename,".gz"); alarm(NETTIMEOUT); if (ftp_open_network(newfilename,&ftpfile,&command,&sock)) { alarm(0); strcpy(newfilename,filename); strcat(newfilename,".Z"); alarm(NETTIMEOUT); if (ftp_open_network(newfilename,&ftpfile,&command,&sock)) { /* Now as given */ alarm(0); strcpy(newfilename,filename); alarm(NETTIMEOUT); if (ftp_open_network(newfilename,&ftpfile,&command,&sock)) { alarm(0); ffpmsg("Unable to open ftp file (ftp_open)"); ffpmsg(newfilename); goto error; } } } } closeftpfile++; closecommandfile++; /* create the memory file */ if ((status = mem_create(filename,handle))) { ffpmsg ("Could not create memory file to passive port (ftp_open)"); ffpmsg(filename); goto error; } closememfile++; /* This isn't quite right, it'll fail if the file has .gzabc at the end for instance */ /* Decide if the file is compressed */ firstchar = fgetc(ftpfile); ungetc(firstchar,ftpfile); if (strstr(newfilename,".gz") || strstr(newfilename,".Z") || ('\037' == firstchar)) { status = 0; /* A bit arbritary really, the user will probably hit ^C */ alarm(NETTIMEOUT*10); status = mem_uncompress2mem(filename, ftpfile, *handle); alarm(0); if (status) { ffpmsg("Error writing compressed memory file (ftp_open)"); ffpmsg(filename); goto error; } } else { /* write a memory file */ alarm(NETTIMEOUT); while(0 != (len = fread(recbuf,1,MAXLEN,ftpfile))) { alarm(0); status = mem_write(*handle,recbuf,len); if (status) { ffpmsg("Error writing memory file (http_open)"); ffpmsg(filename); goto error; } alarm(NETTIMEOUT); } } /* close and clean up */ fclose(ftpfile); closeftpfile--; NET_SendRaw(sock,"QUIT\n",5,NET_DEFAULT); fclose(command); closecommandfile--; signal(SIGALRM, SIG_DFL); alarm(0); return mem_seek(*handle,0); error: alarm(0); /* clear it */ if (closecommandfile) { fclose(command); } if (closeftpfile) { fclose(ftpfile); } if (closememfile) { mem_close_free(*handle); } signal(SIGALRM, SIG_DFL); return (FILE_NOT_OPENED); } /*--------------------------------------------------------------------------*/ /* This creates a file handle with a copy of the URL in filename. The file must be uncompressed and is copied to disk first */ int ftp_file_open(char *url, int rwmode, int *handle) { FILE *ftpfile; FILE *command; char recbuf[MAXLEN]; long len; int sock; int ii, flen, status; char firstchar; /* Check if output file is actually a memory file */ if (!strncmp(netoutfile, "mem:", 4) ) { /* allow the memory file to be opened with write access */ return( ftp_open(url, READONLY, handle) ); } closeftpfile = 0; closecommandfile = 0; closefile = 0; closeoutfile = 0; /* cfileio made a mistake, need to know where to write the output file */ flen = strlen(netoutfile); if (!flen) { ffpmsg("Output file not set, shouldn't have happened (ftp_file_open)"); return (FILE_NOT_OPENED); } /* do the signal handler bits */ if (setjmp(env) != 0) { /* feels like the second time */ /* this means something bad happened */ ffpmsg("Timeout (http_open)"); goto error; } signal(SIGALRM, signal_handler); /* open the network connection to url. ftpfile holds the connection to the input file, command holds the connection to port 21, and sock is the socket connected to port 21 */ alarm(NETTIMEOUT); if ((status = ftp_open_network(url,&ftpfile,&command,&sock))) { alarm(0); ffpmsg("Unable to open http file (ftp_file_open)"); ffpmsg(url); goto error; } closeftpfile++; closecommandfile++; if (*netoutfile == '!') { /* user wants to clobber file, if it already exists */ for (ii = 0; ii < flen; ii++) netoutfile[ii] = netoutfile[ii + 1]; /* remove '!' */ status = file_remove(netoutfile); } /* Now, what do we do with the file */ firstchar = fgetc(ftpfile); ungetc(firstchar,ftpfile); if (strstr(url,".gz") || strstr(url,".Z") || ('\037' == firstchar)) { /* to make this more cfitsioish we use the file driver calls to create the file */ /* Create the output file */ if ((status = file_create(netoutfile,handle))) { ffpmsg("Unable to create output file (ftp_file_open)"); ffpmsg(netoutfile); goto error; } file_close(*handle); if (NULL == (outfile = fopen(netoutfile,"w"))) { ffpmsg("Unable to reopen the output file (ftp_file_open)"); ffpmsg(netoutfile); goto error; } closeoutfile++; status = 0; /* Ok, this is a tough case, let's be arbritary and say 10*NETTIMEOUT, Given the choices for nettimeout above they'll probaby ^C before, but it's always worth a shot*/ alarm(NETTIMEOUT*10); status = uncompress2file(url,ftpfile,outfile,&status); alarm(0); if (status) { ffpmsg("Unable to uncompress the output file (ftp_file_open)"); ffpmsg(url); ffpmsg(netoutfile); goto error; } fclose(outfile); closeoutfile--; } else { /* Create the output file */ if ((status = file_create(netoutfile,handle))) { ffpmsg("Unable to create output file (ftp_file_open)"); ffpmsg(netoutfile); goto error; } closefile++; /* write a file */ alarm(NETTIMEOUT); while(0 != (len = fread(recbuf,1,MAXLEN,ftpfile))) { alarm(0); status = file_write(*handle,recbuf,len); if (status) { ffpmsg("Error writing file (ftp_file_open)"); ffpmsg(url); ffpmsg(netoutfile); goto error; } alarm(NETTIMEOUT); } file_close(*handle); } fclose(ftpfile); closeftpfile--; NET_SendRaw(sock,"QUIT\n",5,NET_DEFAULT); fclose(command); closecommandfile--; signal(SIGALRM, SIG_DFL); alarm(0); return file_open(netoutfile,rwmode,handle); error: alarm(0); /* clear it */ if (closeftpfile) { fclose(ftpfile); } if (closecommandfile) { fclose(command); } if (closeoutfile) { fclose(outfile); } if (closefile) { file_close(*handle); } signal(SIGALRM, SIG_DFL); return (FILE_NOT_OPENED); } /*--------------------------------------------------------------------------*/ /* This creates a memory handle with a copy of the URL in filename. The file must be compressed and is copied to disk first */ int ftp_compress_open(char *url, int rwmode, int *handle) { FILE *ftpfile; FILE *command; char recbuf[MAXLEN]; long len; int ii, flen, status; int sock; char firstchar; closeftpfile = 0; closecommandfile = 0; closememfile = 0; closefdiskfile = 0; closediskfile = 0; /* don't do r/w files */ if (rwmode != 0) { ffpmsg("Compressed files must be r/o"); return (FILE_NOT_OPENED); } /* Need to know where to write the output file */ flen = strlen(netoutfile); if (!flen) { ffpmsg( "Output file not set, shouldn't have happened (ftp_compress_open)"); return (FILE_NOT_OPENED); } /* do the signal handler bits */ if (setjmp(env) != 0) { /* feels like the second time */ /* this means something bad happened */ ffpmsg("Timeout (http_open)"); goto error; } signal(SIGALRM, signal_handler); /* Open the network connection to url, ftpfile is connected to the file port, command is connected to port 21. sock is for writing to port 21 */ alarm(NETTIMEOUT); if ((status = ftp_open_network(url,&ftpfile,&command,&sock))) { alarm(0); ffpmsg("Unable to open ftp file (ftp_compress_open)"); ffpmsg(url); goto error; } closeftpfile++; closecommandfile++; /* Now, what do we do with the file */ firstchar = fgetc(ftpfile); ungetc(firstchar,ftpfile); if (strstr(url,".gz") || strstr(url,".Z") || ('\037' == firstchar)) { if (*netoutfile == '!') { /* user wants to clobber file, if it already exists */ for (ii = 0; ii < flen; ii++) netoutfile[ii] = netoutfile[ii + 1]; /* remove '!' */ status = file_remove(netoutfile); } /* Create the output file */ if ((status = file_create(netoutfile,handle))) { ffpmsg("Unable to create output file (ftp_compress_open)"); ffpmsg(netoutfile); goto error; } closediskfile++; /* write a file */ alarm(NETTIMEOUT); while(0 != (len = fread(recbuf,1,MAXLEN,ftpfile))) { alarm(0); status = file_write(*handle,recbuf,len); if (status) { ffpmsg("Error writing file (ftp_compres_open)"); ffpmsg(url); ffpmsg(netoutfile); goto error; } alarm(NETTIMEOUT); } file_close(*handle); closediskfile--; fclose(ftpfile); closeftpfile--; /* Close down the ftp connection */ NET_SendRaw(sock,"QUIT\n",5,NET_DEFAULT); fclose(command); closecommandfile--; /* File is on disk, let's uncompress it into memory */ if (NULL == (diskfile = fopen(netoutfile,"r"))) { ffpmsg("Unable to reopen disk file (ftp_compress_open)"); ffpmsg(netoutfile); return (FILE_NOT_OPENED); } closefdiskfile++; if ((status = mem_create(url,handle))) { ffpmsg("Unable to create memory file (ftp_compress_open)"); ffpmsg(url); goto error; } closememfile++; status = 0; status = mem_uncompress2mem(url,diskfile,*handle); fclose(diskfile); closefdiskfile--; if (status) { ffpmsg("Error writing compressed memory file (ftp_compress_open)"); goto error; } } else { /* Opps, this should not have happened */ ffpmsg("Can only compressed files here (ftp_compress_open)"); goto error; } signal(SIGALRM, SIG_DFL); alarm(0); return mem_seek(*handle,0); error: alarm(0); /* clear it */ if (closeftpfile) { fclose(ftpfile); } if (closecommandfile) { fclose(command); } if (closefdiskfile) { fclose(diskfile); } if (closememfile) { mem_close_free(*handle); } if (closediskfile) { file_close(*handle); } signal(SIGALRM, SIG_DFL); return (FILE_NOT_OPENED); } /*--------------------------------------------------------------------------*/ /* Open a ftp connection to filename (really a URL), return ftpfile set to the file connection, and command set to the control connection, with sock also set to the control connection */ int ftp_open_network(char *filename, FILE **ftpfile, FILE **command, int *sock) { int status; int sock1; int tmpint; char recbuf[MAXLEN]; char errorstr[MAXLEN]; char tmpstr[MAXLEN]; char proto[SHORTLEN]; char host[SHORTLEN]; char *newhost; char *username; char *password; char fn[MAXLEN]; char *newfn; char *passive; char *tstr; char ip[SHORTLEN]; char turl[MAXLEN]; int port; /* parse the URL */ strcpy(turl,"ftp://"); strcat(turl,filename); if (NET_ParseUrl(turl,proto,host,&port,fn)) { sprintf(errorstr,"URL Parse Error (ftp_open) %s",filename); ffpmsg(errorstr); return (FILE_NOT_OPENED); } #ifdef DEBUG printf ("proto, %s, host, %s, port %d, fn %s\n",proto,host,port,fn); #endif port = 21; /* we might have a user name */ username = "anonymous"; password = "user@host.com"; /* is there an @ sign */ if (NULL != (newhost = strrchr(host,'@'))) { *newhost = '\0'; /* make it a null, */ newhost++; /* Now newhost points to the host name and host points to the user name, password combo */ username = host; /* is there a : for a password */ if (NULL != strchr(username,':')) { password = strchr(username,':'); *password = '\0'; password++; } } else { newhost = host; } #ifdef DEBUG printf("User %s pass %s\n",username,password); #endif /* Connect to the host on the required port */ *sock = NET_TcpConnect(newhost,port); /* convert it to a stdio file */ if (NULL == (*command = fdopen(*sock,"r"))) { ffpmsg ("fdopen failed to convert socket to stdio file (ftp_open)"); return (FILE_NOT_OPENED); } /* Wait for the 220 response */ if (ftp_status(*command,"220 ")) { ffpmsg ("error connecting to remote server, no 220 seen (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } /* Send the user name and wait for the right response */ sprintf(tmpstr,"USER %s\n",username); status = NET_SendRaw(*sock,tmpstr,strlen(tmpstr),NET_DEFAULT); if (ftp_status(*command,"331 ")) { ffpmsg ("USER error no 331 seen (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } /* Send the password and wait for the right response */ sprintf(tmpstr,"PASS %s\n",password); status = NET_SendRaw(*sock,tmpstr,strlen(tmpstr),NET_DEFAULT); if (ftp_status(*command,"230 ")) { ffpmsg ("PASS error, no 230 seen (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } /* now do the cwd command */ newfn = strrchr(fn,'/'); if (newfn == NULL) { strcpy(tmpstr,"CWD /\n"); newfn = fn; } else { *newfn = '\0'; newfn++; if (strlen(fn) == 0) { strcpy(tmpstr,"CWD /\n"); } else { /* remove the leading slash */ if (fn[0] == '/') { sprintf(tmpstr,"CWD %s\n",&fn[1]); } else { sprintf(tmpstr,"CWD %s\n",fn); } } } #ifdef DEBUG printf("CWD command is %s\n",tmpstr); #endif status = NET_SendRaw(*sock,tmpstr,strlen(tmpstr),NET_DEFAULT); if (ftp_status(*command,"250 ")) { ffpmsg ("CWD error, no 250 seen (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } if (!strlen(newfn)) { ffpmsg("Null file name (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } /* Always use binary mode */ sprintf(tmpstr,"TYPE I\n"); status = NET_SendRaw(*sock,tmpstr,strlen(tmpstr),NET_DEFAULT); if (ftp_status(*command,"200 ")) { ffpmsg ("TYPE I error, 200 not seen (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } status = NET_SendRaw(*sock,"PASV\n",5,NET_DEFAULT); if (!(fgets(recbuf,MAXLEN,*command))) { ffpmsg ("PASV error (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } /* Passive mode response looks like 227 Entering Passive Mode (129,194,67,8,210,80) */ if (recbuf[0] == '2' && recbuf[1] == '2' && recbuf[2] == '7') { /* got a good passive mode response, find the opening ( */ if (!(passive = strchr(recbuf,'('))) { ffpmsg ("PASV error (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } *passive = '\0'; passive++; ip[0] = '\0'; /* Messy parsing of response from PASV *command */ if (!(tstr = strtok(passive,",)"))) { ffpmsg ("PASV error (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } strcpy(ip,tstr); strcat(ip,"."); if (!(tstr = strtok(NULL,",)"))) { ffpmsg ("PASV error (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } strcat(ip,tstr); strcat(ip,"."); if (!(tstr = strtok(NULL,",)"))) { ffpmsg ("PASV error (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } strcat(ip,tstr); strcat(ip,"."); if (!(tstr = strtok(NULL,",)"))) { ffpmsg ("PASV error (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } strcat(ip,tstr); /* Done the ip number, now do the port # */ if (!(tstr = strtok(NULL,",)"))) { ffpmsg ("PASV error (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } sscanf(tstr,"%d",&port); port *= 256; if (!(tstr = strtok(NULL,",)"))) { ffpmsg ("PASV error (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } sscanf(tstr,"%d",&tmpint); port += tmpint; if (!strlen(newfn)) { ffpmsg("Null file name (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } #ifdef DEBUG puts("connection to passive port"); #endif /* COnnect to the data port */ sock1 = NET_TcpConnect(ip,port); if (NULL == (*ftpfile = fdopen(sock1,"r"))) { ffpmsg ("Could not connect to passive port (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } /* now we return */ /* Send the retrieve command */ sprintf(tmpstr,"RETR %s\n",newfn); status = NET_SendRaw(*sock,tmpstr,strlen(tmpstr),NET_DEFAULT); #ifdef DEBUG puts("Sent RETR command"); #endif if (ftp_status(*command,"150 ")) { ffpmsg ("RETR error, most likely file is not there (ftp_open)"); fclose(*command); #ifdef DEBUG puts("File not there"); #endif return (FILE_NOT_OPENED); } return 0; } /* no passive mode */ NET_SendRaw(*sock,"QUIT\n",5,NET_DEFAULT); fclose(*command); return (FILE_NOT_OPENED); } /*--------------------------------------------------------------------------*/ /* return a socket which results from connection to hostname on port port */ static int NET_TcpConnect(char *hostname, int port) { /* Connect to hostname on port */ struct sockaddr_in sockaddr; int sock; int stat; int val = 1; CreateSocketAddress(&sockaddr,hostname,port); /* Create socket */ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { ffpmsg("Can't create socket"); return CONNECTION_ERROR; } if ((stat = connect(sock, (struct sockaddr*) &sockaddr, sizeof(sockaddr))) < 0) { close(sock); /* perror("NET_Tcpconnect - Connection error"); ffpmsg("Can't connect to host, connection error"); */ return CONNECTION_ERROR; } setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&val, sizeof(val)); val = 65536; setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&val, sizeof(val)); setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&val, sizeof(val)); return sock; } /*--------------------------------------------------------------------------*/ /* Write len bytes from buffer to socket sock */ static int NET_SendRaw(int sock, const void *buffer, int length, int opt) { char * buf = (char *) buffer; int flag; int n, nsent = 0; switch (opt) { case NET_DEFAULT: flag = 0; break; case NET_OOB: flag = MSG_OOB; break; case NET_PEEK: default: flag = 0; break; } if (sock < 0) return -1; for (n = 0; n < length; n += nsent) { if ((nsent = send(sock, buf+n, length-n, flag)) <= 0) { return nsent; } #ifdef DEBUG printf ("send raw, sent %d bytes\n",nsent); #endif } #ifdef DEBUG printf ("send raw end, sent %d bytes\n",n); #endif return n; } /*--------------------------------------------------------------------------*/ static int NET_RecvRaw(int sock, void *buffer, int length) { /* Receive exactly length bytes into buffer. Returns number of bytes */ /* received. Returns -1 in case of error. */ int nrecv, n; char *buf = (char *)buffer; if (sock < 0) return -1; for (n = 0; n < length; n += nrecv) { while ((nrecv = recv(sock, buf+n, length-n, 0)) == -1 && errno == EINTR) errno = 0; /* probably a SIGCLD that was caught */ if (nrecv < 0) return nrecv; else if (nrecv == 0) break; /*/ EOF */ } return n; } /*--------------------------------------------------------------------------*/ /* Yet Another URL Parser url - input url proto - input protocol host - output host port - output port fn - output filename */ static int NET_ParseUrl(const char *url, char *proto, char *host, int *port, char *fn) { /* parses urls into their bits */ /* returns 1 if error, else 0 */ char *urlcopy, *urlcopyorig; char *ptrstr; char *thost; int isftp = 0; /* figure out if there is a http: or ftp: */ urlcopyorig = urlcopy = (char *) malloc(strlen(url)+1); strcpy(urlcopy,url); /* set some defaults */ *port = 80; strcpy(proto,"http:"); strcpy(host,"localhost"); strcpy(fn,"/"); ptrstr = strstr(urlcopy,"http:"); if (ptrstr == NULL) { /* Nope, not http: */ ptrstr = strstr(urlcopy,"root:"); if (ptrstr == NULL) { /* Nope, not root either */ ptrstr = strstr(urlcopy,"ftp:"); if (ptrstr != NULL) { if (ptrstr == urlcopy) { strcpy(proto,"ftp:"); *port = 21; isftp++; urlcopy += 4; /* move past ftp: */ } else { /* not at the beginning, bad url */ free(urlcopyorig); return 1; } } } else { if (ptrstr == urlcopy) { urlcopy += 5; /* move past root: */ } else { /* not at the beginning, bad url */ free(urlcopyorig); return 1; } } } else { if (ptrstr == urlcopy) { urlcopy += 5; /* move past http: */ } else { free(urlcopyorig); return 1; } } /* got the protocol */ /* get the hostname */ if (urlcopy[0] == '/' && urlcopy[1] == '/') { /* we have a hostname */ urlcopy += 2; /* move past the // */ } /* do this only if http */ if (!strcmp(proto,"http:")) { strcpy(host,urlcopy); thost = host; while (*urlcopy != '/' && *urlcopy != ':' && *urlcopy) { thost++; urlcopy++; } /* we should either be at the end of the string, have a /, or have a : */ *thost = '\0'; if (*urlcopy == ':') { /* follows a port number */ urlcopy++; sscanf(urlcopy,"%d",port); while (*urlcopy != '/' && *urlcopy) urlcopy++; /* step to the */ } } else { /* do this for ftp */ strcpy(host,urlcopy); thost = host; while (*urlcopy != '/' && *urlcopy) { thost++; urlcopy++; } *thost = '\0'; /* Now, we should either be at the end of the string, or have a / */ } /* Now the rest is a fn */ if (*urlcopy) { strcpy(fn,urlcopy); } free(urlcopyorig); return 0; } /*--------------------------------------------------------------------------*/ /* Small helper functions to set the netoutfile static string */ /* Called by cfileio after parsing the output file off of the input file url */ int http_checkfile (char *urltype, char *infile, char *outfile1) { char newinfile[MAXLEN]; FILE *httpfile; char contentencoding[MAXLEN]; int contentlength; /* default to http:// if there is no output file */ strcpy(urltype,"http://"); if (strlen(outfile1)) { /* there is an output file */ /* don't copy the "file://" prefix, if present. */ if (!strncmp(outfile1, "file://", 7) ) strcpy(netoutfile,outfile1+7); else strcpy(netoutfile,outfile1); if (!strncmp(outfile1, "mem:", 4) ) { /* copy the file to memory, with READ and WRITE access In this case, it makes no difference whether the http file and or the output file are compressed or not. */ strcpy(urltype, "httpmem://"); /* use special driver */ return 0; } if (strstr(infile, "?")) { /* file name contains a '?' so probably a cgi string; don't open it */ strcpy(urltype,"httpfile://"); return 0; } if (!http_open_network(infile,&httpfile,contentencoding,&contentlength)) { fclose(httpfile); /* It's there, we're happy */ if (strstr(infile,".gz") || (strstr(infile,".Z"))) { /* It's compressed */ if (strstr(outfile1,".gz") || (strstr(outfile1,".Z"))) { strcpy(urltype,"httpcompress://"); } else { strcpy(urltype,"httpfile://"); } } else { strcpy(urltype,"httpfile://"); } return 0; } /* Ok, let's try the .gz one */ strcpy(newinfile,infile); strcat(newinfile,".gz"); if (!http_open_network(newinfile,&httpfile,contentencoding, &contentlength)) { fclose(httpfile); strcpy(infile,newinfile); /* It's there, we're happy, and, it's compressed */ /* It's compressed */ if (strstr(outfile1,".gz") || (strstr(outfile1,".Z"))) { strcpy(urltype,"httpcompress://"); } else { strcpy(urltype,"httpfile://"); } return 0; } /* Ok, let's try the .Z one */ strcpy(newinfile,infile); strcat(newinfile,".Z"); if (!http_open_network(newinfile,&httpfile,contentencoding, &contentlength)) { fclose(httpfile); strcpy(infile,newinfile); /* It's there, we're happy, and, it's compressed */ if (strstr(outfile1,".gz") || (strstr(outfile1,".Z"))) { strcpy(urltype,"httpcompress://"); } else { strcpy(urltype,"httpfile://"); } return 0; } } return 0; } /*--------------------------------------------------------------------------*/ int ftp_checkfile (char *urltype, char *infile, char *outfile1) { char newinfile[MAXLEN]; FILE *ftpfile; FILE *command; int sock; /* default to ftp:// */ strcpy(urltype,"ftp://"); if (strlen(outfile1)) { /* there is an output file */ /* don't copy the "file://" prefix, if present. */ if (!strncmp(outfile1, "file://", 7) ) strcpy(netoutfile,outfile1+7); else strcpy(netoutfile,outfile1); if (!strncmp(outfile1, "mem:", 4) ) { /* copy the file to memory, with READ and WRITE access In this case, it makes no difference whether the ftp file and or the output file are compressed or not. */ strcpy(urltype, "ftpmem://"); /* use special driver */ return 0; } if (!ftp_open_network(infile,&ftpfile,&command,&sock)) { fclose(ftpfile); fclose(command); /* It's there, we're happy */ if (strstr(infile,".gz") || (strstr(infile,".Z"))) { /* It's compressed */ if (strstr(outfile1,".gz") || (strstr(outfile1,".Z"))) { strcpy(urltype,"ftpcompress://"); } else { strcpy(urltype,"ftpfile://"); } } else { strcpy(urltype,"ftpfile://"); } return 0; } /* Ok, let's try the .gz one */ strcpy(newinfile,infile); strcat(newinfile,".gz"); if (!ftp_open_network(newinfile,&ftpfile,&command,&sock)) { fclose(ftpfile); fclose(command); strcpy(infile,newinfile); /* It's there, we're happy, and, it's compressed */ if (strstr(outfile1,".gz") || (strstr(outfile1,".Z"))) { strcpy(urltype,"ftpcompress://"); } else { strcpy(urltype,"ftpfile://"); } return 0; } /* Ok, let's try the .Z one */ strcpy(newinfile,infile); strcat(newinfile,".Z"); if (!ftp_open_network(newinfile,&ftpfile,&command,&sock)) { fclose(ftpfile); fclose(command); strcpy(infile,newinfile); if (strstr(outfile1,".gz") || (strstr(outfile1,".Z"))) { strcpy(urltype,"ftpcompress://"); } else { strcpy(urltype,"ftpfile://"); } return 0; } } return 0; } /*--------------------------------------------------------------------------*/ /* A small helper function to wait for a particular status on the ftp connectino */ static int ftp_status(FILE *ftp, char *statusstr) { /* read through until we find a string beginning with statusstr */ /* This needs a timeout */ char recbuf[MAXLEN]; int len; len = strlen(statusstr); while (1) { if (!(fgets(recbuf,MAXLEN,ftp))) { #ifdef DEBUG puts("error reading response in ftp_status"); #endif return 1; /* error reading */ } #ifdef DEBUG printf("ftp_status, return string was %s\n",recbuf); #endif recbuf[len] = '\0'; /* make it short */ if (!strcmp(recbuf,statusstr)) { return 0; /* we're ok */ } if (recbuf[0] > '3') { /* oh well, some sort of error */ return 1; } } } /* *---------------------------------------------------------------------- * * CreateSocketAddress -- * * This function initializes a sockaddr structure for a host and port. * * Results: * 1 if the host was valid, 0 if the host could not be converted to * an IP address. * * Side effects: * Fills in the *sockaddrPtr structure. * *---------------------------------------------------------------------- */ static int CreateSocketAddress( struct sockaddr_in *sockaddrPtr, /* Socket address */ char *host, /* Host. NULL implies INADDR_ANY */ int port) /* Port number */ { struct hostent *hostent; /* Host database entry */ struct in_addr addr; /* For 64/32 bit madness */ char localhost[MAXLEN]; strcpy(localhost,host); memset((void *) sockaddrPtr, '\0', sizeof(struct sockaddr_in)); sockaddrPtr->sin_family = AF_INET; sockaddrPtr->sin_port = htons((unsigned short) (port & 0xFFFF)); if (host == NULL) { addr.s_addr = INADDR_ANY; } else { addr.s_addr = inet_addr(localhost); if (addr.s_addr == 0xFFFFFFFF) { hostent = gethostbyname(localhost); if (hostent != NULL) { memcpy((void *) &addr, (void *) hostent->h_addr_list[0], (size_t) hostent->h_length); } else { #ifdef EHOSTUNREACH errno = EHOSTUNREACH; #else #ifdef ENXIO errno = ENXIO; #endif #endif return 0; /* error */ } } } /* * NOTE: On 64 bit machines the assignment below is rumored to not * do the right thing. Please report errors related to this if you * observe incorrect behavior on 64 bit machines such as DEC Alphas. * Should we modify this code to do an explicit memcpy? */ sockaddrPtr->sin_addr.s_addr = addr.s_addr; return 1; /* Success. */ } /* Signal handler for timeouts */ static void signal_handler(int sig) { switch (sig) { case SIGALRM: /* process for alarm */ longjmp(env,sig); default: { /* Hmm, shouldn't have happend */ exit(sig); } } } /**************************************************************/ /* Root driver */ /*--------------------------------------------------------------------------*/ int root_init(void) { int ii; for (ii = 0; ii < NMAXFILES; ii++) /* initialize all empty slots in table */ { handleTable[ii].sock = 0; handleTable[ii].currentpos = 0; } return(0); } /*--------------------------------------------------------------------------*/ int root_setoptions(int options) { /* do something with the options argument, to stop compiler warning */ options = 0; return(options); } /*--------------------------------------------------------------------------*/ int root_getoptions(int *options) { *options = 0; return(0); } /*--------------------------------------------------------------------------*/ int root_getversion(int *version) { *version = 10; return(0); } /*--------------------------------------------------------------------------*/ int root_shutdown(void) { return(0); } /*--------------------------------------------------------------------------*/ int root_open(char *url, int rwmode, int *handle) { int ii, status; int sock; *handle = -1; for (ii = 0; ii < NMAXFILES; ii++) /* find empty slot in table */ { if (handleTable[ii].sock == 0) { *handle = ii; break; } } if (*handle == -1) return(TOO_MANY_FILES); /* too many files opened */ /*open the file */ if (rwmode) { status = root_openfile(url, "update", &sock); } else { status = root_openfile(url, "read", &sock); } if (status) return(status); handleTable[ii].sock = sock; handleTable[ii].currentpos = 0; return(0); } /*--------------------------------------------------------------------------*/ int root_create(char *filename, int *handle) { int ii, status; int sock; *handle = -1; for (ii = 0; ii < NMAXFILES; ii++) /* find empty slot in table */ { if (handleTable[ii].sock == 0) { *handle = ii; break; } } if (*handle == -1) return(TOO_MANY_FILES); /* too many files opened */ /*open the file */ status = root_openfile(filename, "create", &sock); if (status) { ffpmsg("Unable to create file"); return(status); } handleTable[ii].sock = sock; handleTable[ii].currentpos = 0; return(0); } /*--------------------------------------------------------------------------*/ int root_size(int handle, LONGLONG *filesize) /* return the size of the file in bytes */ { int sock; int offset; int status; int op; sock = handleTable[handle].sock; status = root_send_buffer(sock,ROOTD_STAT,NULL,0); status = root_recv_buffer(sock,&op,(char *)&offset, 4); *filesize = (LONGLONG) ntohl(offset); return(0); } /*--------------------------------------------------------------------------*/ int root_close(int handle) /* close the file */ { int status; int sock; sock = handleTable[handle].sock; status = root_send_buffer(sock,ROOTD_CLOSE,NULL,0); close(sock); handleTable[handle].sock = 0; return(0); } /*--------------------------------------------------------------------------*/ int root_flush(int handle) /* flush the file */ { int status; int sock; sock = handleTable[handle].sock; status = root_send_buffer(sock,ROOTD_FLUSH,NULL,0); return(0); } /*--------------------------------------------------------------------------*/ int root_seek(int handle, LONGLONG offset) /* seek to position relative to start of the file */ { handleTable[handle].currentpos = offset; return(0); } /*--------------------------------------------------------------------------*/ int root_read(int hdl, void *buffer, long nbytes) /* read bytes from the current position in the file */ { char msg[SHORTLEN]; int op; int status; int astat; /* we presume here that the file position will never be > 2**31 = 2.1GB */ sprintf(msg,"%ld %ld ",(long) handleTable[hdl].currentpos,nbytes); status = root_send_buffer(handleTable[hdl].sock,ROOTD_GET,msg,strlen(msg)); if ((unsigned) status != strlen(msg)) { return (READ_ERROR); } astat = 0; status = root_recv_buffer(handleTable[hdl].sock,&op,(char *) &astat,4); if (astat != 0) { return (READ_ERROR); } #ifdef DEBUG printf("root_read, op %d astat %d\n",op,astat); #endif status = NET_RecvRaw(handleTable[hdl].sock,buffer,nbytes); if (status != nbytes) { return (READ_ERROR); } handleTable[hdl].currentpos += nbytes; return(0); } /*--------------------------------------------------------------------------*/ int root_write(int hdl, void *buffer, long nbytes) /* write bytes at the current position in the file */ { char msg[SHORTLEN]; int len; int sock; int status; int astat; int op; sock = handleTable[hdl].sock; /* we presume here that the file position will never be > 2**31 = 2.1GB */ sprintf(msg,"%ld %ld ",(long) handleTable[hdl].currentpos,nbytes); len = strlen(msg); status = root_send_buffer(sock,ROOTD_PUT,msg,len+1); if (status != len+1) { return (WRITE_ERROR); } status = NET_SendRaw(sock,buffer,nbytes,NET_DEFAULT); if (status != nbytes) { return (WRITE_ERROR); } astat = 0; status = root_recv_buffer(handleTable[hdl].sock,&op,(char *) &astat,4); #ifdef DEBUG printf("root_read, op %d astat %d\n",op,astat); #endif if (astat != 0) { return (WRITE_ERROR); } handleTable[hdl].currentpos += nbytes; return(0); } /*--------------------------------------------------------------------------*/ int root_openfile(char *url, char *rwmode, int *sock) /* lowest level routine to physically open a root file */ { int status; char recbuf[MAXLEN]; char errorstr[MAXLEN]; char proto[SHORTLEN]; char host[SHORTLEN]; char fn[MAXLEN]; char turl[MAXLEN]; int port; int op; int ii; int authstat; /* Parse the URL apart again */ strcpy(turl,"root://"); strcat(turl,url); if (NET_ParseUrl(turl,proto,host,&port,fn)) { sprintf(errorstr,"URL Parse Error (root_open) %s",url); ffpmsg(errorstr); return (FILE_NOT_OPENED); } #ifdef DEBUG printf("Connecting to %s on port %d\n",host,port); #endif /* Connect to the remote host */ *sock = NET_TcpConnect(host,port); if (*sock < 0) { ffpmsg("Couldn't connect to host (http_open_network)"); return (FILE_NOT_OPENED); } /* get the username */ if (NULL != getenv("ROOTUSERNAME")) { strcpy(recbuf,getenv("ROOTUSERNAME")); } else { printf("Username: "); fgets(recbuf,MAXLEN,stdin); recbuf[strlen(recbuf)-1] = '\0'; } status = root_send_buffer(*sock, ROOTD_USER, recbuf,strlen(recbuf)); if (status < 0) { ffpmsg("error talking to remote system on username "); return (FILE_NOT_OPENED); } status = root_recv_buffer(*sock,&op,(char *)&authstat,4); if (!status) { ffpmsg("error talking to remote system on username"); return (FILE_NOT_OPENED); } #ifdef DEBUG printf("op is %d and authstat is %d\n",op,authstat); #endif if (op != ROOTD_AUTH) { ffpmsg("ERROR on ROOTD_USER"); ffpmsg(recbuf); return (FILE_NOT_OPENED); } /* now the password */ if (NULL != getenv("ROOTPASSWORD")) { strcpy(recbuf,getenv("ROOTPASSWORD")); } else { printf("Password: "); fgets(recbuf,MAXLEN,stdin); recbuf[strlen(recbuf)-1] = '\0'; } /* ones complement the password */ for (ii=0;(unsigned) ii includes the 4 bytes for the op, the length bytes (4) are implicit if buffer is null don't send it, not everything needs something sent */ int len; int status; int hdr[2]; len = 4; if (buffer != NULL) { len += buflen; } hdr[0] = htonl(len); #ifdef DEBUG printf("len sent is %x\n",hdr[0]); #endif hdr[1] = htonl(op); #ifdef DEBUG printf("op sent is %x\n",hdr[1]); #endif #ifdef DEBUG printf("Sending op %d and length of %d\n",op,len); #endif status = NET_SendRaw(sock,hdr,sizeof(hdr),NET_DEFAULT); if (status < 0) { return status; } if (buffer != NULL) { status = NET_SendRaw(sock,buffer,buflen,NET_DEFAULT); } return status; } static int root_recv_buffer(int sock, int *op, char *buffer, int buflen) { /* recv a buffer, the form is */ int recv1 = 0; int len; int status; char recbuf[MAXLEN]; status = NET_RecvRaw(sock,&len,4); #ifdef DEBUG printf("Recv: status from rec is %d\n",status); #endif if (status < 0) { return status; } recv1 += status; len = ntohl(len); #ifdef DEBUG printf ("Recv: length is %d\n",len); #endif /* ok, have the length, recive the operation */ len -= 4; status = NET_RecvRaw(sock,op,4); if (status < 0) { return status; } recv1 += status; *op = ntohl(*op); #ifdef DEBUG printf ("Recv: Operation is %d\n",*op); #endif if (len > MAXLEN) { len = MAXLEN; } if (len > 0) { /* Get the rest of the message */ status = NET_RecvRaw(sock,recbuf,len); if (len > buflen) { len = buflen; } memcpy(buffer,recbuf,len); if (status < 0) { return status; } } recv1 += status; return recv1; } #endif skycat-3.1.2-starlink-1b/astrotcl/cfitsio/drvrsmem.c000066400000000000000000001130661215713201500224420ustar00rootroot00000000000000/* S H A R E D M E M O R Y D R I V E R ======================================= by Jerzy.Borkowski@obs.unige.ch 09-Mar-98 : initial version 1.0 released 23-Mar-98 : shared_malloc now accepts new handle as an argument 23-Mar-98 : shmem://0, shmem://1, etc changed to shmem://h0, etc due to bug in url parser. 10-Apr-98 : code cleanup 13-May-99 : delayed initialization added, global table deleted on exit when no shmem segments remain, and last process terminates */ #ifdef HAVE_SHMEM_SERVICES #include "fitsio2.h" /* drvrsmem.h is included by it */ #include #include #include #include #include #include #include #if defined(unix) || defined(__unix__) || defined(__unix) #include #endif static int shared_kbase = 0; /* base for shared memory handles */ static int shared_maxseg = 0; /* max number of shared memory blocks */ static int shared_range = 0; /* max number of tried entries */ static int shared_fd = SHARED_INVALID; /* handle of global access lock file */ static int shared_gt_h = SHARED_INVALID; /* handle of global table segment */ static SHARED_LTAB *shared_lt = NULL; /* local table pointer */ static SHARED_GTAB *shared_gt = NULL; /* global table pointer */ static int shared_create_mode = 0666; /* permission flags for created objects */ static int shared_debug = 1; /* simple debugging tool, set to 0 to disable messages */ static int shared_init_called = 0; /* flag whether shared_init() has been called, used for delayed init */ /* static support routines prototypes */ static int shared_clear_entry(int idx); /* unconditionally clear entry */ static int shared_destroy_entry(int idx); /* unconditionally destroy sema & shseg and clear entry */ static int shared_mux(int idx, int mode); /* obtain exclusive access to specified segment */ static int shared_demux(int idx, int mode); /* free exclusive access to specified segment */ static int shared_process_count(int sem); /* valid only for time of invocation */ static int shared_delta_process(int sem, int delta); /* change number of processes hanging on segment */ static int shared_attach_process(int sem); static int shared_detach_process(int sem); static int shared_get_free_entry(int newhandle); /* get free entry in shared_key, or -1, entry is set rw locked */ static int shared_get_hash(long size, int idx);/* return hash value for malloc */ static long shared_adjust_size(long size); /* size must be >= 0 !!! */ static int shared_check_locked_index(int idx); /* verify that given idx is valid */ static int shared_map(int idx); /* map all tables for given idx, check for validity */ static int shared_validate(int idx, int mode); /* use intrnally inside crit.sect !!! */ /* support routines - initialization */ static int shared_clear_entry(int idx) /* unconditionally clear entry */ { if ((idx < 0) || (idx >= shared_maxseg)) return(SHARED_BADARG); shared_gt[idx].key = SHARED_INVALID; /* clear entries in global table */ shared_gt[idx].handle = SHARED_INVALID; shared_gt[idx].sem = SHARED_INVALID; shared_gt[idx].semkey = SHARED_INVALID; shared_gt[idx].nprocdebug = 0; shared_gt[idx].size = 0; shared_gt[idx].attr = 0; return(SHARED_OK); } static int shared_destroy_entry(int idx) /* unconditionally destroy sema & shseg and clear entry */ { int r, r2; union semun filler; if ((idx < 0) || (idx >= shared_maxseg)) return(SHARED_BADARG); r2 = r = SHARED_OK; filler.val = 0; /* this is to make cc happy (warning otherwise) */ if (SHARED_INVALID != shared_gt[idx].sem) r = semctl(shared_gt[idx].sem, 0, IPC_RMID, filler); /* destroy semaphore */ if (SHARED_INVALID != shared_gt[idx].handle) r2 = shmctl(shared_gt[idx].handle, IPC_RMID, 0); /* destroy shared memory segment */ if (SHARED_OK == r) r = r2; /* accumulate error code in r, free r2 */ r2 = shared_clear_entry(idx); return((SHARED_OK == r) ? r2 : r); } void shared_cleanup(void) /* this must (should) be called during exit/abort */ { int i, j, r, oktodelete, filelocked, segmentspresent; flock_t flk; struct shmid_ds ds; if (shared_debug) printf("shared_cleanup:"); if (NULL != shared_lt) { if (shared_debug) printf(" deleting segments:"); for (i=0; i>\n"); return; } int shared_init(int debug_msgs) /* initialize shared memory stuff, you have to call this routine once */ { int i; char buf[1000], *p; mode_t oldumask; shared_init_called = 1; /* tell everybody no need to call us for the 2nd time */ shared_debug = debug_msgs; /* set required debug mode */ if (shared_debug) printf("shared_init:"); shared_kbase = 0; /* adapt to current env. settings */ if (NULL != (p = getenv(SHARED_ENV_KEYBASE))) shared_kbase = atoi(p); if (0 == shared_kbase) shared_kbase = SHARED_KEYBASE; if (shared_debug) printf(" keybase=%d", shared_kbase); shared_maxseg = 0; if (NULL != (p = getenv(SHARED_ENV_MAXSEG))) shared_maxseg = atoi(p); if (0 == shared_maxseg) shared_maxseg = SHARED_MAXSEG; if (shared_debug) printf(" maxseg=%d", shared_maxseg); shared_range = 3 * shared_maxseg; if (SHARED_INVALID == shared_fd) /* create rw locking file (this file is never deleted) */ { if (shared_debug) printf(" lockfileinit="); sprintf(buf, "%s.%d.%d", SHARED_FDNAME, shared_kbase, shared_maxseg); oldumask = umask(0); shared_fd = open(buf, O_TRUNC | O_EXCL | O_CREAT | O_RDWR, shared_create_mode); umask(oldumask); if (SHARED_INVALID == shared_fd) /* or just open rw locking file, in case it already exists */ { shared_fd = open(buf, O_TRUNC | O_RDWR, shared_create_mode); if (SHARED_INVALID == shared_fd) return(SHARED_NOFILE); if (shared_debug) printf("slave"); } else { if (shared_debug) printf("master"); } } if (SHARED_INVALID == shared_gt_h) /* global table not attached, try to create it in shared memory */ { if (shared_debug) printf(" globalsharedtableinit="); shared_gt_h = shmget(shared_kbase, shared_maxseg * sizeof(SHARED_GTAB), IPC_CREAT | IPC_EXCL | shared_create_mode); /* try open as a master */ if (SHARED_INVALID == shared_gt_h) /* if failed, try to open as a slave */ { shared_gt_h = shmget(shared_kbase, shared_maxseg * sizeof(SHARED_GTAB), shared_create_mode); if (SHARED_INVALID == shared_gt_h) return(SHARED_IPCERR); /* means deleted ID residing in system, shared mem unusable ... */ shared_gt = (SHARED_GTAB *)shmat(shared_gt_h, 0, 0); /* attach segment */ if (((SHARED_GTAB *)SHARED_INVALID) == shared_gt) return(SHARED_IPCERR); if (shared_debug) printf("slave"); } else { shared_gt = (SHARED_GTAB *)shmat(shared_gt_h, 0, 0); /* attach segment */ if (((SHARED_GTAB *)SHARED_INVALID) == shared_gt) return(SHARED_IPCERR); for (i=0; i>\n"); return(SHARED_OK); } int shared_recover(int id) /* try to recover dormant segments after applic crash */ { int i, r, r2; if (NULL == shared_gt) return(SHARED_NOTINIT); /* not initialized */ if (NULL == shared_lt) return(SHARED_NOTINIT); /* not initialized */ r = SHARED_OK; for (i=0; i r2) || (0 == r2)) { if (shared_debug) printf("Bogus handle=%d nproc=%d sema=%d:", i, shared_gt[i].nprocdebug, r2); r = shared_destroy_entry(i); if (shared_debug) { printf("%s", r ? "error couldn't clear handle" : "handle cleared"); } } shared_demux(i, SHARED_RDWRITE); } return(r); /* table full */ } /* API routines - mutexes and locking */ static int shared_mux(int idx, int mode) /* obtain exclusive access to specified segment */ { flock_t flk; int r; if (0 == shared_init_called) /* delayed initialization */ { if (SHARED_OK != (r = shared_init(0))) return(r); } if (SHARED_INVALID == shared_fd) return(SHARED_NOTINIT); if ((idx < 0) || (idx >= shared_maxseg)) return(SHARED_BADARG); flk.l_type = ((mode & SHARED_RDWRITE) ? F_WRLCK : F_RDLCK); flk.l_whence = 0; flk.l_start = idx; flk.l_len = 1; if (shared_debug) printf(" [mux (%d): ", idx); if (-1 == fcntl(shared_fd, ((mode & SHARED_NOWAIT) ? F_SETLK : F_SETLKW), &flk)) { switch (errno) { case EAGAIN: ; case EACCES: if (shared_debug) printf("again]"); return(SHARED_AGAIN); default: if (shared_debug) printf("err]"); return(SHARED_IPCERR); } } if (shared_debug) printf("ok]"); return(SHARED_OK); } static int shared_demux(int idx, int mode) /* free exclusive access to specified segment */ { flock_t flk; if (SHARED_INVALID == shared_fd) return(SHARED_NOTINIT); if ((idx < 0) || (idx >= shared_maxseg)) return(SHARED_BADARG); flk.l_type = F_UNLCK; flk.l_whence = 0; flk.l_start = idx; flk.l_len = 1; if (shared_debug) printf(" [demux (%d): ", idx); if (-1 == fcntl(shared_fd, F_SETLKW, &flk)) { switch (errno) { case EAGAIN: ; case EACCES: if (shared_debug) printf("again]"); return(SHARED_AGAIN); default: if (shared_debug) printf("err]"); return(SHARED_IPCERR); } } if (shared_debug) printf("mode=%d ok]", mode); return(SHARED_OK); } static int shared_process_count(int sem) /* valid only for time of invocation */ { union semun su; su.val = 0; /* to force compiler not to give warning messages */ return(semctl(sem, 0, GETVAL, su)); /* su is unused here */ } static int shared_delta_process(int sem, int delta) /* change number of processes hanging on segment */ { struct sembuf sb; if (SHARED_INVALID == sem) return(SHARED_BADARG); /* semaphore not attached */ sb.sem_num = 0; sb.sem_op = delta; sb.sem_flg = SEM_UNDO; return((-1 == semop(sem, &sb, 1)) ? SHARED_IPCERR : SHARED_OK); } static int shared_attach_process(int sem) { if (shared_debug) printf(" [attach process]"); return(shared_delta_process(sem, 1)); } static int shared_detach_process(int sem) { if (shared_debug) printf(" [detach process]"); return(shared_delta_process(sem, -1)); } /* API routines - hashing and searching */ static int shared_get_free_entry(int newhandle) /* get newhandle, or -1, entry is set rw locked */ { if (NULL == shared_gt) return(-1); /* not initialized */ if (NULL == shared_lt) return(-1); /* not initialized */ if (newhandle < 0) return(-1); if (newhandle >= shared_maxseg) return(-1); if (shared_lt[newhandle].tcnt) return(-1); /* somebody (we) is using it */ if (shared_mux(newhandle, SHARED_NOWAIT | SHARED_RDWRITE)) return(-1); /* used by others */ if (SHARED_INVALID == shared_gt[newhandle].key) return(newhandle); /* we have found free slot, lock it and return index */ shared_demux(newhandle, SHARED_RDWRITE); if (shared_debug) printf("[free_entry - ERROR - entry unusable]"); return(-1); /* table full */ } static int shared_get_hash(long size, int idx) /* return hash value for malloc */ { static int counter = 0; int hash; hash = (counter + size * idx) % shared_range; counter = (counter + 1) % shared_range; return(hash); } static long shared_adjust_size(long size) /* size must be >= 0 !!! */ { return(((size + sizeof(BLKHEAD) + SHARED_GRANUL - 1) / SHARED_GRANUL) * SHARED_GRANUL); } /* API routines - core : malloc/realloc/free/attach/detach/lock/unlock */ int shared_malloc(long size, int mode, int newhandle) /* return idx or SHARED_INVALID */ { int h, i, r, idx, key; union semun filler; BLKHEAD *bp; if (0 == shared_init_called) /* delayed initialization */ { if (SHARED_OK != (r = shared_init(0))) return(r); } if (shared_debug) printf("malloc (size = %ld, mode = %d):", size, mode); if (size < 0) return(SHARED_INVALID); if (-1 == (idx = shared_get_free_entry(newhandle))) return(SHARED_INVALID); if (shared_debug) printf(" idx=%d", idx); for (i = 0; ; i++) { if (i >= shared_range) /* table full, signal error & exit */ { shared_demux(idx, SHARED_RDWRITE); return(SHARED_INVALID); } key = shared_kbase + ((i + shared_get_hash(size, idx)) % shared_range); if (shared_debug) printf(" key=%d", key); h = shmget(key, shared_adjust_size(size), IPC_CREAT | IPC_EXCL | shared_create_mode); if (shared_debug) printf(" handle=%d", h); if (SHARED_INVALID == h) continue; /* segment already accupied */ bp = (BLKHEAD *)shmat(h, 0, 0); /* try attach */ if (shared_debug) printf(" p=%p", bp); if (((BLKHEAD *)SHARED_INVALID) == bp) /* cannot attach, delete segment, try with another key */ { shmctl(h, IPC_RMID, 0); continue; } /* now create semaphor counting number of processes attached */ if (SHARED_INVALID == (shared_gt[idx].sem = semget(key, 1, IPC_CREAT | IPC_EXCL | shared_create_mode))) { shmdt((void *)bp); /* cannot create segment, delete everything */ shmctl(h, IPC_RMID, 0); continue; /* try with another key */ } if (shared_debug) printf(" sem=%d", shared_gt[idx].sem); if (shared_attach_process(shared_gt[idx].sem)) /* try attach process */ { semctl(shared_gt[idx].sem, 0, IPC_RMID, filler); /* destroy semaphore */ shmdt((char *)bp); /* detach shared mem segment */ shmctl(h, IPC_RMID, 0); /* destroy shared mem segment */ continue; /* try with another key */ } bp->s.tflag = BLOCK_SHARED; /* fill in data in segment's header (this is really not necessary) */ bp->s.ID[0] = SHARED_ID_0; bp->s.ID[1] = SHARED_ID_1; bp->s.handle = idx; /* used in yorick */ if (mode & SHARED_RESIZE) { if (shmdt((char *)bp)) r = SHARED_IPCERR; /* if segment is resizable, then detach segment */ shared_lt[idx].p = NULL; } else { shared_lt[idx].p = bp; } shared_lt[idx].tcnt = 1; /* one thread using segment */ shared_lt[idx].lkcnt = 0; /* no locks at the moment */ shared_lt[idx].seekpos = 0L; /* r/w pointer positioned at beg of block */ shared_gt[idx].handle = h; /* fill in data in global table */ shared_gt[idx].size = size; shared_gt[idx].attr = mode; shared_gt[idx].semkey = key; shared_gt[idx].key = key; shared_gt[idx].nprocdebug = 0; break; } shared_demux(idx, SHARED_RDWRITE); /* hope this will not fail */ return(idx); } int shared_attach(int idx) { int r, r2; if (SHARED_OK != (r = shared_mux(idx, SHARED_RDWRITE | SHARED_WAIT))) return(r); if (SHARED_OK != (r = shared_map(idx))) { shared_demux(idx, SHARED_RDWRITE); return(r); } if (shared_attach_process(shared_gt[idx].sem)) /* try attach process */ { shmdt((char *)(shared_lt[idx].p)); /* cannot attach process, detach everything */ shared_lt[idx].p = NULL; shared_demux(idx, SHARED_RDWRITE); return(SHARED_BADARG); } shared_lt[idx].tcnt++; /* one more thread is using segment */ if (shared_gt[idx].attr & SHARED_RESIZE) /* if resizeable, detach and return special pointer */ { if (shmdt((char *)(shared_lt[idx].p))) r = SHARED_IPCERR; /* if segment is resizable, then detach segment */ shared_lt[idx].p = NULL; } shared_lt[idx].seekpos = 0L; /* r/w pointer positioned at beg of block */ r2 = shared_demux(idx, SHARED_RDWRITE); return(r ? r : r2); } static int shared_check_locked_index(int idx) /* verify that given idx is valid */ { int r; if (0 == shared_init_called) /* delayed initialization */ { if (SHARED_OK != (r = shared_init(0))) return(r); } if ((idx < 0) || (idx >= shared_maxseg)) return(SHARED_BADARG); if (NULL == shared_lt[idx].p) return(SHARED_BADARG); /* NULL pointer, not attached ?? */ if (0 == shared_lt[idx].lkcnt) return(SHARED_BADARG); /* not locked ?? */ if ((SHARED_ID_0 != (shared_lt[idx].p)->s.ID[0]) || (SHARED_ID_1 != (shared_lt[idx].p)->s.ID[1]) || (BLOCK_SHARED != (shared_lt[idx].p)->s.tflag)) /* invalid data in segment */ return(SHARED_BADARG); return(SHARED_OK); } static int shared_map(int idx) /* map all tables for given idx, check for validity */ { int h; /* have to obtain excl. access before calling shared_map */ BLKHEAD *bp; if ((idx < 0) || (idx >= shared_maxseg)) return(SHARED_BADARG); if (SHARED_INVALID == shared_gt[idx].key) return(SHARED_BADARG); if (SHARED_INVALID == (h = shmget(shared_gt[idx].key, 1, shared_create_mode))) return(SHARED_BADARG); if (((BLKHEAD *)SHARED_INVALID) == (bp = (BLKHEAD *)shmat(h, 0, 0))) return(SHARED_BADARG); if ((SHARED_ID_0 != bp->s.ID[0]) || (SHARED_ID_1 != bp->s.ID[1]) || (BLOCK_SHARED != bp->s.tflag) || (h != shared_gt[idx].handle)) { shmdt((char *)bp); /* invalid segment, detach everything */ return(SHARED_BADARG); } if (shared_gt[idx].sem != semget(shared_gt[idx].semkey, 1, shared_create_mode)) /* check if sema is still there */ { shmdt((char *)bp); /* cannot attach semaphore, detach everything */ return(SHARED_BADARG); } shared_lt[idx].p = bp; /* store pointer to shmem data */ return(SHARED_OK); } static int shared_validate(int idx, int mode) /* use intrnally inside crit.sect !!! */ { int r; if (SHARED_OK != (r = shared_mux(idx, mode))) return(r); /* idx checked by shared_mux */ if (NULL == shared_lt[idx].p) if (SHARED_OK != (r = shared_map(idx))) { shared_demux(idx, mode); return(r); } if ((SHARED_ID_0 != (shared_lt[idx].p)->s.ID[0]) || (SHARED_ID_1 != (shared_lt[idx].p)->s.ID[1]) || (BLOCK_SHARED != (shared_lt[idx].p)->s.tflag)) { shared_demux(idx, mode); return(r); } return(SHARED_OK); } SHARED_P shared_realloc(int idx, long newsize) /* realloc shared memory segment */ { int h, key, i, r; BLKHEAD *bp; long transfersize; r = SHARED_OK; if (newsize < 0) return(NULL); if (shared_check_locked_index(idx)) return(NULL); if (0 == (shared_gt[idx].attr & SHARED_RESIZE)) return(NULL); if (-1 != shared_lt[idx].lkcnt) return(NULL); /* check for RW lock */ if (shared_adjust_size(shared_gt[idx].size) == shared_adjust_size(newsize)) { shared_gt[idx].size = newsize; return((SHARED_P)((shared_lt[idx].p) + 1)); } for (i = 0; ; i++) { if (i >= shared_range) return(NULL); /* table full, signal error & exit */ key = shared_kbase + ((i + shared_get_hash(newsize, idx)) % shared_range); h = shmget(key, shared_adjust_size(newsize), IPC_CREAT | IPC_EXCL | shared_create_mode); if (SHARED_INVALID == h) continue; /* segment already accupied */ bp = (BLKHEAD *)shmat(h, 0, 0); /* try attach */ if (((BLKHEAD *)SHARED_INVALID) == bp) /* cannot attach, delete segment, try with another key */ { shmctl(h, IPC_RMID, 0); continue; } *bp = *(shared_lt[idx].p); /* copy header, then data */ transfersize = ((newsize < shared_gt[idx].size) ? newsize : shared_gt[idx].size); if (transfersize > 0) memcpy((void *)(bp + 1), (void *)((shared_lt[idx].p) + 1), transfersize); if (shmdt((char *)(shared_lt[idx].p))) r = SHARED_IPCERR; /* try to detach old segment */ if (shmctl(shared_gt[idx].handle, IPC_RMID, 0)) if (SHARED_OK == r) r = SHARED_IPCERR; /* destroy old shared memory segment */ shared_gt[idx].size = newsize; /* signal new size */ shared_gt[idx].handle = h; /* signal new handle */ shared_gt[idx].key = key; /* signal new key */ shared_lt[idx].p = bp; break; } return((SHARED_P)(bp + 1)); } int shared_free(int idx) /* detach segment, if last process & !PERSIST, destroy segment */ { int cnt, r, r2; if (SHARED_OK != (r = shared_validate(idx, SHARED_RDWRITE | SHARED_WAIT))) return(r); if (SHARED_OK != (r = shared_detach_process(shared_gt[idx].sem))) /* update number of processes using segment */ { shared_demux(idx, SHARED_RDWRITE); return(r); } shared_lt[idx].tcnt--; /* update number of threads using segment */ if (shared_lt[idx].tcnt > 0) return(shared_demux(idx, SHARED_RDWRITE)); /* if more threads are using segment we are done */ if (shmdt((char *)(shared_lt[idx].p))) /* if, we are the last thread, try to detach segment */ { shared_demux(idx, SHARED_RDWRITE); return(SHARED_IPCERR); } shared_lt[idx].p = NULL; /* clear entry in local table */ shared_lt[idx].seekpos = 0L; /* r/w pointer positioned at beg of block */ if (-1 == (cnt = shared_process_count(shared_gt[idx].sem))) /* get number of processes hanging on segment */ { shared_demux(idx, SHARED_RDWRITE); return(SHARED_IPCERR); } if ((0 == cnt) && (0 == (shared_gt[idx].attr & SHARED_PERSIST))) r = shared_destroy_entry(idx); /* no procs on seg, destroy it */ r2 = shared_demux(idx, SHARED_RDWRITE); return(r ? r : r2); } SHARED_P shared_lock(int idx, int mode) /* lock given segment for exclusive access */ { int r; if (shared_mux(idx, mode)) return(NULL); /* idx checked by shared_mux */ if (0 != shared_lt[idx].lkcnt) /* are we already locked ?? */ if (SHARED_OK != (r = shared_map(idx))) { shared_demux(idx, mode); return(NULL); } if (NULL == shared_lt[idx].p) /* stupid pointer ?? */ if (SHARED_OK != (r = shared_map(idx))) { shared_demux(idx, mode); return(NULL); } if ((SHARED_ID_0 != (shared_lt[idx].p)->s.ID[0]) || (SHARED_ID_1 != (shared_lt[idx].p)->s.ID[1]) || (BLOCK_SHARED != (shared_lt[idx].p)->s.tflag)) { shared_demux(idx, mode); return(NULL); } if (mode & SHARED_RDWRITE) { shared_lt[idx].lkcnt = -1; shared_gt[idx].nprocdebug++; } else shared_lt[idx].lkcnt++; shared_lt[idx].seekpos = 0L; /* r/w pointer positioned at beg of block */ return((SHARED_P)((shared_lt[idx].p) + 1)); } int shared_unlock(int idx) /* unlock given segment, assumes seg is locked !! */ { int r, r2, mode; if (SHARED_OK != (r = shared_check_locked_index(idx))) return(r); if (shared_lt[idx].lkcnt > 0) { shared_lt[idx].lkcnt--; /* unlock read lock */ mode = SHARED_RDONLY; } else { shared_lt[idx].lkcnt = 0; /* unlock write lock */ shared_gt[idx].nprocdebug--; mode = SHARED_RDWRITE; } if (0 == shared_lt[idx].lkcnt) if (shared_gt[idx].attr & SHARED_RESIZE) { if (shmdt((char *)(shared_lt[idx].p))) r = SHARED_IPCERR; /* segment is resizable, then detach segment */ shared_lt[idx].p = NULL; /* signal detachment in local table */ } r2 = shared_demux(idx, mode); /* unlock segment, rest is only parameter checking */ return(r ? r : r2); } /* API routines - support and info routines */ int shared_attr(int idx) /* get the attributes of the shared memory segment */ { int r; if (shared_check_locked_index(idx)) return(SHARED_INVALID); r = shared_gt[idx].attr; return(r); } int shared_set_attr(int idx, int newattr) /* get the attributes of the shared memory segment */ { int r; if (shared_check_locked_index(idx)) return(SHARED_INVALID); if (-1 != shared_lt[idx].lkcnt) return(SHARED_INVALID); /* ADDED - check for RW lock */ r = shared_gt[idx].attr; shared_gt[idx].attr = newattr; return(r); } int shared_set_debug(int mode) /* set/reset debug mode */ { int r = shared_debug; shared_debug = mode; return(r); } int shared_set_createmode(int mode) /* set/reset debug mode */ { int r = shared_create_mode; shared_create_mode = mode; return(r); } int shared_list(int id) { int i, r; if (NULL == shared_gt) return(SHARED_NOTINIT); /* not initialized */ if (NULL == shared_lt) return(SHARED_NOTINIT); /* not initialized */ if (shared_debug) printf("shared_list:"); r = SHARED_OK; printf(" Idx Key Nproc Size Flags\n"); printf("==============================================\n"); for (i=0; i= SHARED_ERRBASE) { printf(" cannot clear PERSIST attribute"); } if (shared_free(i)) { printf(" delete failed\n"); } else { printf(" deleted\n"); } } if (shared_debug) printf(" done\n"); return(r); /* table full */ } /************************* CFITSIO DRIVER FUNCTIONS ***************************/ int smem_init(void) { return(0); } int smem_shutdown(void) { if (shared_init_called) shared_cleanup(); return(0); } int smem_setoptions(int option) { option = 0; return(0); } int smem_getoptions(int *options) { if (NULL == options) return(SHARED_NULPTR); *options = 0; return(0); } int smem_getversion(int *version) { if (NULL == version) return(SHARED_NULPTR); *version = 10; return(0); } int smem_open(char *filename, int rwmode, int *driverhandle) { int h, nitems, r; DAL_SHM_SEGHEAD *sp; if (NULL == filename) return(SHARED_NULPTR); if (NULL == driverhandle) return(SHARED_NULPTR); nitems = sscanf(filename, "h%d", &h); if (1 != nitems) return(SHARED_BADARG); if (SHARED_OK != (r = shared_attach(h))) return(r); if (NULL == (sp = (DAL_SHM_SEGHEAD *)shared_lock(h, ((READWRITE == rwmode) ? SHARED_RDWRITE : SHARED_RDONLY)))) { shared_free(h); return(SHARED_BADARG); } if ((h != sp->h) || (DAL_SHM_SEGHEAD_ID != sp->ID)) { shared_unlock(h); shared_free(h); return(SHARED_BADARG); } *driverhandle = h; return(0); } int smem_create(char *filename, int *driverhandle) { DAL_SHM_SEGHEAD *sp; int h, sz, nitems; if (NULL == filename) return(SHARED_NULPTR); /* currently ignored */ if (NULL == driverhandle) return(SHARED_NULPTR); nitems = sscanf(filename, "h%d", &h); if (1 != nitems) return(SHARED_BADARG); if (SHARED_INVALID == (h = shared_malloc(sz = 2880 + sizeof(DAL_SHM_SEGHEAD), SHARED_RESIZE | SHARED_PERSIST, h))) return(SHARED_NOMEM); if (NULL == (sp = (DAL_SHM_SEGHEAD *)shared_lock(h, SHARED_RDWRITE))) { shared_free(h); return(SHARED_BADARG); } sp->ID = DAL_SHM_SEGHEAD_ID; sp->h = h; sp->size = sz; sp->nodeidx = -1; *driverhandle = h; return(0); } int smem_close(int driverhandle) { int r; if (SHARED_OK != (r = shared_unlock(driverhandle))) return(r); return(shared_free(driverhandle)); } int smem_remove(char *filename) { int nitems, h, r; if (NULL == filename) return(SHARED_NULPTR); nitems = sscanf(filename, "h%d", &h); if (1 != nitems) return(SHARED_BADARG); if (0 == shared_check_locked_index(h)) /* are we locked ? */ { if (-1 != shared_lt[h].lkcnt) /* are we locked RO ? */ { if (SHARED_OK != (r = shared_unlock(h))) return(r); /* yes, so relock in RW */ if (NULL == shared_lock(h, SHARED_RDWRITE)) return(SHARED_BADARG); } } else /* not locked */ { if (SHARED_OK != (r = smem_open(filename, READWRITE, &h))) return(r); /* so open in RW mode */ } shared_set_attr(h, SHARED_RESIZE); /* delete PERSIST attribute */ return(smem_close(h)); /* detach segment (this will delete it) */ } int smem_size(int driverhandle, LONGLONG *size) { if (NULL == size) return(SHARED_NULPTR); if (shared_check_locked_index(driverhandle)) return(SHARED_INVALID); *size = (LONGLONG) (shared_gt[driverhandle].size - sizeof(DAL_SHM_SEGHEAD)); return(0); } int smem_flush(int driverhandle) { if (shared_check_locked_index(driverhandle)) return(SHARED_INVALID); return(0); } int smem_seek(int driverhandle, LONGLONG offset) { if (offset < 0) return(SHARED_BADARG); if (shared_check_locked_index(driverhandle)) return(SHARED_INVALID); shared_lt[driverhandle].seekpos = offset; return(0); } int smem_read(int driverhandle, void *buffer, long nbytes) { if (NULL == buffer) return(SHARED_NULPTR); if (shared_check_locked_index(driverhandle)) return(SHARED_INVALID); if (nbytes < 0) return(SHARED_BADARG); if ((shared_lt[driverhandle].seekpos + nbytes) > shared_gt[driverhandle].size) return(SHARED_BADARG); /* read beyond EOF */ memcpy(buffer, ((char *)(((DAL_SHM_SEGHEAD *)(shared_lt[driverhandle].p + 1)) + 1)) + shared_lt[driverhandle].seekpos, nbytes); shared_lt[driverhandle].seekpos += nbytes; return(0); } int smem_write(int driverhandle, void *buffer, long nbytes) { if (NULL == buffer) return(SHARED_NULPTR); if (shared_check_locked_index(driverhandle)) return(SHARED_INVALID); if (-1 != shared_lt[driverhandle].lkcnt) return(SHARED_INVALID); /* are we locked RW ? */ if (nbytes < 0) return(SHARED_BADARG); if ((unsigned long)(shared_lt[driverhandle].seekpos + nbytes) > (unsigned long)(shared_gt[driverhandle].size - sizeof(DAL_SHM_SEGHEAD))) { /* need to realloc shmem */ if (NULL == shared_realloc(driverhandle, shared_lt[driverhandle].seekpos + nbytes + sizeof(DAL_SHM_SEGHEAD))) return(SHARED_NOMEM); } memcpy(((char *)(((DAL_SHM_SEGHEAD *)(shared_lt[driverhandle].p + 1)) + 1)) + shared_lt[driverhandle].seekpos, buffer, nbytes); shared_lt[driverhandle].seekpos += nbytes; return(0); } #endif skycat-3.1.2-starlink-1b/astrotcl/cfitsio/drvrsmem.h000066400000000000000000000146101215713201500224420ustar00rootroot00000000000000/* S H A R E D M E M O R Y D R I V E R ======================================= by Jerzy.Borkowski@obs.unige.ch 09-Mar-98 : initial version 1.0 released 23-Mar-98 : shared_malloc now accepts new handle as an argument */ #include /* this is necessary for Solaris/Linux */ #include #include #ifdef _AIX #include #else #include #endif /* configuration parameters */ #define SHARED_MAXSEG (16) /* maximum number of shared memory blocks */ #define SHARED_KEYBASE (14011963) /* base for shared memory keys, may be overriden by getenv */ #define SHARED_FDNAME ("/tmp/.shmem-lockfile") /* template for lock file name */ #define SHARED_ENV_KEYBASE ("SHMEM_LIB_KEYBASE") /* name of environment variable */ #define SHARED_ENV_MAXSEG ("SHMEM_LIB_MAXSEG") /* name of environment variable */ /* useful constants */ #define SHARED_RDONLY (0) /* flag for shared_(un)lock, lock for read */ #define SHARED_RDWRITE (1) /* flag for shared_(un)lock, lock for write */ #define SHARED_WAIT (0) /* flag for shared_lock, block if cannot lock immediate */ #define SHARED_NOWAIT (2) /* flag for shared_lock, fail if cannot lock immediate */ #define SHARED_NOLOCK (0x100) /* flag for shared_validate function */ #define SHARED_RESIZE (4) /* flag for shared_malloc, object is resizeable */ #define SHARED_PERSIST (8) /* flag for shared_malloc, object is not deleted after last proc detaches */ #define SHARED_INVALID (-1) /* invalid handle for semaphore/shared memory */ #define SHARED_EMPTY (0) /* entries for shared_used table */ #define SHARED_USED (1) #define SHARED_GRANUL (16384) /* granularity of shared_malloc allocation = phys page size, system dependent */ /* checkpoints in shared memory segments - might be omitted */ #define SHARED_ID_0 ('J') /* first byte of identifier in BLKHEAD */ #define SHARED_ID_1 ('B') /* second byte of identifier in BLKHEAD */ #define BLOCK_REG (0) /* value for tflag member of BLKHEAD */ #define BLOCK_SHARED (1) /* value for tflag member of BLKHEAD */ /* generic error codes */ #define SHARED_OK (0) #define SHARED_ERR_MIN_IDX SHARED_BADARG #define SHARED_ERR_MAX_IDX SHARED_NORESIZE #define DAL_SHM_FREE (0) #define DAL_SHM_USED (1) #define DAL_SHM_ID0 ('D') #define DAL_SHM_ID1 ('S') #define DAL_SHM_ID2 ('M') #define DAL_SHM_SEGHEAD_ID (0x19630114) /* data types */ /* BLKHEAD object is placed at the beginning of every memory segment (both shared and regular) to allow automatic recognition of segments type */ typedef union { struct BLKHEADstruct { char ID[2]; /* ID = 'JB', just as a checkpoint */ char tflag; /* is it shared memory or regular one ? */ int handle; /* this is not necessary, used only for non-resizeable objects via ptr */ } s; double d; /* for proper alignment on every machine */ } BLKHEAD; typedef void *SHARED_P; /* generic type of shared memory pointer */ typedef struct SHARED_GTABstruct /* data type used in global table */ { int sem; /* access semaphore (1 field): process count */ int semkey; /* key value used to generate semaphore handle */ int key; /* key value used to generate shared memory handle (realloc changes it) */ int handle; /* handle of shared memory segment */ int size; /* size of shared memory segment */ int nprocdebug; /* attached proc counter, helps remove zombie segments */ char attr; /* attributes of shared memory object */ } SHARED_GTAB; typedef struct SHARED_LTABstruct /* data type used in local table */ { BLKHEAD *p; /* pointer to segment (may be null) */ int tcnt; /* number of threads in this process attached to segment */ int lkcnt; /* >=0 <- number of read locks, -1 - write lock */ long seekpos; /* current pointer position, read/write/seek operations change it */ } SHARED_LTAB; /* system dependent definitions */ #ifndef HAVE_FLOCK_T typedef struct flock flock_t; #define HAVE_FLOCK_T #endif #ifndef HAVE_UNION_SEMUN union semun { int val; struct semid_ds *buf; unsigned short *array; }; #define HAVE_UNION_SEMUN #endif typedef struct DAL_SHM_SEGHEAD_STRUCT DAL_SHM_SEGHEAD; struct DAL_SHM_SEGHEAD_STRUCT { int ID; /* ID for debugging */ int h; /* handle of sh. mem */ int size; /* size of data area */ int nodeidx; /* offset of root object (node struct typically) */ }; /* API routines */ #ifdef __cplusplus extern "C" { #endif void shared_cleanup(void); /* must be called at exit/abort */ int shared_init(int debug_msgs); /* must be called before any other shared memory routine */ int shared_recover(int id); /* try to recover dormant segment(s) after applic crash */ int shared_malloc(long size, int mode, int newhandle); /* allocate n-bytes of shared memory */ int shared_attach(int idx); /* attach to segment given index to table */ int shared_free(int idx); /* release shared memory */ SHARED_P shared_lock(int idx, int mode); /* lock segment for reading */ SHARED_P shared_realloc(int idx, long newsize); /* reallocate n-bytes of shared memory (ON LOCKED SEGMENT ONLY) */ int shared_size(int idx); /* get size of attached shared memory segment (ON LOCKED SEGMENT ONLY) */ int shared_attr(int idx); /* get attributes of attached shared memory segment (ON LOCKED SEGMENT ONLY) */ int shared_set_attr(int idx, int newattr); /* set attributes of attached shared memory segment (ON LOCKED SEGMENT ONLY) */ int shared_unlock(int idx); /* unlock segment (ON LOCKED SEGMENT ONLY) */ int shared_set_debug(int debug_msgs); /* set/reset debug mode */ int shared_set_createmode(int mode); /* set/reset debug mode */ int shared_list(int id); /* list segment(s) */ int shared_uncond_delete(int id); /* uncondintionally delete (NOWAIT operation) segment(s) */ int shared_getaddr(int id, char **address); /* get starting address of FITS file in segment */ int smem_init(void); int smem_shutdown(void); int smem_setoptions(int options); int smem_getoptions(int *options); int smem_getversion(int *version); int smem_open(char *filename, int rwmode, int *driverhandle); int smem_create(char *filename, int *driverhandle); int smem_close(int driverhandle); int smem_remove(char *filename); int smem_size(int driverhandle, LONGLONG *size); int smem_flush(int driverhandle); int smem_seek(int driverhandle, LONGLONG offset); int smem_read(int driverhandle, void *buffer, long nbytes); int smem_write(int driverhandle, void *buffer, long nbytes); #ifdef __cplusplus } #endif skycat-3.1.2-starlink-1b/astrotcl/cfitsio/editcol.c000066400000000000000000002371241215713201500222300ustar00rootroot00000000000000/* This file, editcol.c, contains the set of FITSIO routines that */ /* insert or delete rows or columns in a table or resize an image */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffrsim(fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - bits per pixel */ int naxis, /* I - number of axes in the array */ long *naxes, /* I - size of each axis */ int *status) /* IO - error status */ /* resize an existing primary array or IMAGE extension. */ { LONGLONG tnaxes[99]; int ii; if (*status > 0) return(*status); for (ii = 0; (ii < naxis) && (ii < 99); ii++) tnaxes[ii] = naxes[ii]; ffrsimll(fptr, bitpix, naxis, tnaxes, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffrsimll(fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - bits per pixel */ int naxis, /* I - number of axes in the array */ LONGLONG *naxes, /* I - size of each axis */ int *status) /* IO - error status */ /* resize an existing primary array or IMAGE extension. */ { int ii, simple, obitpix, onaxis, extend, nmodify; long nblocks, longval; long pcount, gcount, longbitpix; LONGLONG onaxes[99], newsize, oldsize; char comment[FLEN_COMMENT], keyname[FLEN_KEYWORD], message[FLEN_ERRMSG]; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); /* get current image size parameters */ if (ffghprll(fptr, 99, &simple, &obitpix, &onaxis, onaxes, &pcount, &gcount, &extend, status) > 0) return(*status); longbitpix = bitpix; /* test for the 2 special cases that represent unsigned integers */ if (longbitpix == USHORT_IMG) longbitpix = SHORT_IMG; else if (longbitpix == ULONG_IMG) longbitpix = LONG_IMG; /* test that the new values are legal */ if (longbitpix != BYTE_IMG && longbitpix != SHORT_IMG && longbitpix != LONG_IMG && longbitpix != LONGLONG_IMG && longbitpix != FLOAT_IMG && longbitpix != DOUBLE_IMG) { sprintf(message, "Illegal value for BITPIX keyword: %d", bitpix); ffpmsg(message); return(*status = BAD_BITPIX); } if (naxis < 0 || naxis > 999) { sprintf(message, "Illegal value for NAXIS keyword: %d", naxis); ffpmsg(message); return(*status = BAD_NAXIS); } if (naxis == 0) newsize = 0; else newsize = 1; for (ii = 0; ii < naxis; ii++) { if (naxes[ii] < 0) { sprintf(message, "Illegal value for NAXIS%d keyword: %.0f", ii + 1, (double) (naxes[ii])); ffpmsg(message); return(*status = BAD_NAXES); } newsize *= naxes[ii]; /* compute new image size, in pixels */ } /* compute size of old image, in bytes */ if (onaxis == 0) oldsize = 0; else { oldsize = 1; for (ii = 0; ii < onaxis; ii++) oldsize *= onaxes[ii]; oldsize = (oldsize + pcount) * gcount * (abs(obitpix) / 8); } oldsize = (oldsize + 2879) / 2880; /* old size, in blocks */ newsize = (newsize + pcount) * gcount * (abs(longbitpix) / 8); newsize = (newsize + 2879) / 2880; /* new size, in blocks */ if (newsize > oldsize) /* have to insert new blocks for image */ { nblocks = (long) (newsize - oldsize); if (ffiblk(fptr, nblocks, 1, status) > 0) return(*status); } else if (oldsize > newsize) /* have to delete blocks from image */ { nblocks = (long) (oldsize - newsize); if (ffdblk(fptr, nblocks, status) > 0) return(*status); } /* now update the header keywords */ strcpy(comment,"&"); /* special value to leave comments unchanged */ if (longbitpix != obitpix) { /* update BITPIX value */ ffmkyj(fptr, "BITPIX", longbitpix, comment, status); } if (naxis != onaxis) { /* update NAXIS value */ longval = naxis; ffmkyj(fptr, "NAXIS", longval, comment, status); } /* modify the existing NAXISn keywords */ nmodify = minvalue(naxis, onaxis); for (ii = 0; ii < nmodify; ii++) { ffkeyn("NAXIS", ii+1, keyname, status); ffmkyj(fptr, keyname, naxes[ii], comment, status); } if (naxis > onaxis) /* insert additional NAXISn keywords */ { strcpy(comment,"length of data axis"); for (ii = onaxis; ii < naxis; ii++) { ffkeyn("NAXIS", ii+1, keyname, status); ffikyj(fptr, keyname, naxes[ii], comment, status); } } else if (onaxis > naxis) /* delete old NAXISn keywords */ { for (ii = naxis; ii < onaxis; ii++) { ffkeyn("NAXIS", ii+1, keyname, status); ffdkey(fptr, keyname, status); } } /* Update the BSCALE and BZERO keywords, if an unsigned integer image */ if (bitpix == USHORT_IMG) { strcpy(comment, "offset data range to that of unsigned short"); ffukyg(fptr, "BZERO", 32768., 0, comment, status); strcpy(comment, "default scaling factor"); ffukyg(fptr, "BSCALE", 1.0, 0, comment, status); } else if (bitpix == ULONG_IMG) { strcpy(comment, "offset data range to that of unsigned long"); ffukyg(fptr, "BZERO", 2147483648., 0, comment, status); strcpy(comment, "default scaling factor"); ffukyg(fptr, "BSCALE", 1.0, 0, comment, status); } /* re-read the header, to make sure structures are updated */ ffrdef(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffirow(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG firstrow, /* I - insert space AFTER this row */ /* 0 = insert space at beginning of table */ LONGLONG nrows, /* I - number of rows to insert */ int *status) /* IO - error status */ /* insert NROWS blank rows immediated after row firstrow (1 = first row). Set firstrow = 0 to insert space at the beginning of the table. */ { int tstatus; LONGLONG naxis1, naxis2; LONGLONG datasize, firstbyte, nshift, nbytes; LONGLONG freespace; long nblock; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg("Can only add rows to TABLE or BINTABLE extension (ffirow)"); return(*status = NOT_TABLE); } if (nrows < 0 ) return(*status = NEG_BYTES); else if (nrows == 0) return(*status); /* no op, so just return */ /* get the current size of the table */ /* use internal structure since NAXIS2 keyword may not be up to date */ naxis1 = (fptr->Fptr)->rowlength; naxis2 = (fptr->Fptr)->numrows; if (firstrow > naxis2) { ffpmsg( "Insert position greater than the number of rows in the table (ffirow)"); return(*status = BAD_ROW_NUM); } else if (firstrow < 0) { ffpmsg("Insert position is less than 0 (ffirow)"); return(*status = BAD_ROW_NUM); } /* current data size */ datasize = (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; freespace = ( ( (datasize + 2879) / 2880) * 2880) - datasize; nshift = naxis1 * nrows; /* no. of bytes to add to table */ if ( (freespace - nshift) < 0) /* not enough existing space? */ { nblock = (long) ((nshift - freespace + 2879) / 2880); /* number of blocks */ ffiblk(fptr, nblock, 1, status); /* insert the blocks */ } firstbyte = naxis1 * firstrow; /* relative insert position */ nbytes = datasize - firstbyte; /* no. of bytes to shift down */ firstbyte += ((fptr->Fptr)->datastart); /* absolute insert position */ ffshft(fptr, firstbyte, nbytes, nshift, status); /* shift rows and heap */ /* update the heap starting address */ (fptr->Fptr)->heapstart += nshift; /* update the THEAP keyword if it exists */ tstatus = 0; ffmkyj(fptr, "THEAP", (fptr->Fptr)->heapstart, "&", &tstatus); /* update the NAXIS2 keyword */ ffmkyj(fptr, "NAXIS2", naxis2 + nrows, "&", status); ((fptr->Fptr)->numrows) += nrows; ((fptr->Fptr)->origrows) += nrows; return(*status); } /*--------------------------------------------------------------------------*/ int ffdrow(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG firstrow, /* I - first row to delete (1 = first) */ LONGLONG nrows, /* I - number of rows to delete */ int *status) /* IO - error status */ /* delete NROWS rows from table starting with firstrow (1 = first row of table). */ { int tstatus; LONGLONG naxis1, naxis2; LONGLONG datasize, firstbyte, nbytes, nshift; LONGLONG freespace; long nblock; char comm[FLEN_COMMENT]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg("Can only delete rows in TABLE or BINTABLE extension (ffdrow)"); return(*status = NOT_TABLE); } if (nrows < 0 ) return(*status = NEG_BYTES); else if (nrows == 0) return(*status); /* no op, so just return */ ffgkyjj(fptr, "NAXIS1", &naxis1, comm, status); /* get the current */ /* ffgkyj(fptr, "NAXIS2", &naxis2, comm, status);*/ /* size of the table */ /* the NAXIS2 keyword may not be up to date, so use the structure value */ naxis2 = (fptr->Fptr)->numrows; if (firstrow > naxis2) { ffpmsg( "Delete position greater than the number of rows in the table (ffdrow)"); return(*status = BAD_ROW_NUM); } else if (firstrow < 1) { ffpmsg("Delete position is less than 1 (ffdrow)"); return(*status = BAD_ROW_NUM); } else if (firstrow + nrows - 1 > naxis2) { ffpmsg("No. of rows to delete exceeds size of table (ffdrow)"); return(*status = BAD_ROW_NUM); } nshift = naxis1 * nrows; /* no. of bytes to delete from table */ /* cur size of data */ datasize = (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; firstbyte = naxis1 * (firstrow + nrows - 1); /* relative del pos */ nbytes = datasize - firstbyte; /* no. of bytes to shift up */ firstbyte += ((fptr->Fptr)->datastart); /* absolute delete position */ ffshft(fptr, firstbyte, nbytes, nshift * (-1), status); /* shift data */ freespace = ( ( (datasize + 2879) / 2880) * 2880) - datasize; nblock = (long) ((nshift + freespace) / 2880); /* number of blocks */ /* delete integral number blocks */ if (nblock > 0) ffdblk(fptr, nblock, status); /* update the heap starting address */ (fptr->Fptr)->heapstart -= nshift; /* update the THEAP keyword if it exists */ tstatus = 0; ffmkyj(fptr, "THEAP", (long)(fptr->Fptr)->heapstart, "&", &tstatus); /* update the NAXIS2 keyword */ ffmkyj(fptr, "NAXIS2", naxis2 - nrows, "&", status); ((fptr->Fptr)->numrows) -= nrows; ((fptr->Fptr)->origrows) -= nrows; /* Update the heap data, if any. This will remove any orphaned data */ /* that was only pointed to by the rows that have been deleted */ ffcmph(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffdrrg(fitsfile *fptr, /* I - FITS file pointer to table */ char *ranges, /* I - ranges of rows to delete (1 = first) */ int *status) /* IO - error status */ /* delete the ranges of rows from the table (1 = first row of table). The 'ranges' parameter typically looks like: '10-20, 30 - 40, 55' or '50-' and gives a list of rows or row ranges separated by commas. */ { char *cptr; int nranges, nranges2, ii; long *minrow, *maxrow, nrows, *rowarray, jj, kk; LONGLONG naxis2; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg("Can only delete rows in TABLE or BINTABLE extension (ffdrrg)"); return(*status = NOT_TABLE); } /* the NAXIS2 keyword may not be up to date, so use the structure value */ naxis2 = (fptr->Fptr)->numrows; /* find how many ranges were specified ( = no. of commas in string + 1) */ cptr = ranges; for (nranges = 1; (cptr = strchr(cptr, ',')); nranges++) cptr++; minrow = calloc(nranges, sizeof(long)); maxrow = calloc(nranges, sizeof(long)); if (!minrow || !maxrow) { *status = MEMORY_ALLOCATION; ffpmsg("failed to allocate memory for row ranges (ffdrrg)"); if (maxrow) free(maxrow); if (minrow) free(minrow); return(*status); } /* parse range list into array of range min and max values */ ffrwrg(ranges, naxis2, nranges, &nranges2, minrow, maxrow, status); if (*status > 0 || nranges2 == 0) { free(maxrow); free(minrow); return(*status); } /* determine total number or rows to delete */ nrows = 0; for (ii = 0; ii < nranges2; ii++) { nrows = nrows + maxrow[ii] - minrow[ii] + 1; } rowarray = calloc(nrows, sizeof(long)); if (!rowarray) { *status = MEMORY_ALLOCATION; ffpmsg("failed to allocate memory for row array (ffdrrg)"); return(*status); } for (kk = 0, ii = 0; ii < nranges2; ii++) { for (jj = minrow[ii]; jj <= maxrow[ii]; jj++) { rowarray[kk] = jj; kk++; } } /* delete the rows */ ffdrws(fptr, rowarray, nrows, status); free(rowarray); free(maxrow); free(minrow); return(*status); } /*--------------------------------------------------------------------------*/ int ffdrws(fitsfile *fptr, /* I - FITS file pointer */ long *rownum, /* I - list of rows to delete (1 = first) */ long nrows, /* I - number of rows to delete */ int *status) /* IO - error status */ /* delete the list of rows from the table (1 = first row of table). */ { LONGLONG naxis1, naxis2, insertpos, nextrowpos; long ii, nextrow; char comm[FLEN_COMMENT]; unsigned char *buffer; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg("Can only delete rows in TABLE or BINTABLE extension (ffdrws)"); return(*status = NOT_TABLE); } if (nrows < 0 ) return(*status = NEG_BYTES); else if (nrows == 0) return(*status); /* no op, so just return */ ffgkyjj(fptr, "NAXIS1", &naxis1, comm, status); /* row width */ ffgkyjj(fptr, "NAXIS2", &naxis2, comm, status); /* number of rows */ /* check that input row list is in ascending order */ for (ii = 1; ii < nrows; ii++) { if (rownum[ii - 1] >= rownum[ii]) { ffpmsg("row numbers are not in increasing order (ffdrws)"); return(*status = BAD_ROW_NUM); } } if (rownum[0] < 1) { ffpmsg("first row to delete is less than 1 (ffdrws)"); return(*status = BAD_ROW_NUM); } else if (rownum[nrows - 1] > naxis2) { ffpmsg("last row to delete exceeds size of table (ffdrws)"); return(*status = BAD_ROW_NUM); } buffer = (unsigned char *) malloc( (size_t) naxis1); /* buffer for one row */ if (!buffer) { ffpmsg("malloc failed (ffdrws)"); return(*status = MEMORY_ALLOCATION); } /* byte location to start of first row to delete, and the next row */ insertpos = (fptr->Fptr)->datastart + ((rownum[0] - 1) * naxis1); nextrowpos = insertpos + naxis1; nextrow = rownum[0] + 1; /* work through the list of rows to delete */ for (ii = 1; ii < nrows; nextrow++, nextrowpos += naxis1) { if (nextrow < rownum[ii]) { /* keep this row, so copy it to the new position */ ffmbyt(fptr, nextrowpos, REPORT_EOF, status); ffgbyt(fptr, naxis1, buffer, status); /* read the bytes */ ffmbyt(fptr, insertpos, IGNORE_EOF, status); ffpbyt(fptr, naxis1, buffer, status); /* write the bytes */ if (*status > 0) { ffpmsg("error while copying good rows in table (ffdrws)"); free(buffer); return(*status); } insertpos += naxis1; } else { /* skip over this row since it is in the list */ ii++; } } /* finished with all the rows to delete; copy remaining rows */ while(nextrow <= naxis2) { ffmbyt(fptr, nextrowpos, REPORT_EOF, status); ffgbyt(fptr, naxis1, buffer, status); /* read the bytes */ ffmbyt(fptr, insertpos, IGNORE_EOF, status); ffpbyt(fptr, naxis1, buffer, status); /* write the bytes */ if (*status > 0) { ffpmsg("failed to copy remaining rows in table (ffdrws)"); free(buffer); return(*status); } insertpos += naxis1; nextrowpos += naxis1; nextrow++; } free(buffer); /* now delete the empty rows at the end of the table */ ffdrow(fptr, naxis2 - nrows + 1, nrows, status); /* Update the heap data, if any. This will remove any orphaned data */ /* that was only pointed to by the rows that have been deleted */ ffcmph(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffdrwsll(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG *rownum, /* I - list of rows to delete (1 = first) */ LONGLONG nrows, /* I - number of rows to delete */ int *status) /* IO - error status */ /* delete the list of rows from the table (1 = first row of table). */ { LONGLONG insertpos, nextrowpos; LONGLONG naxis1, naxis2, ii, nextrow; char comm[FLEN_COMMENT]; unsigned char *buffer; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg("Can only delete rows in TABLE or BINTABLE extension (ffdrws)"); return(*status = NOT_TABLE); } if (nrows < 0 ) return(*status = NEG_BYTES); else if (nrows == 0) return(*status); /* no op, so just return */ ffgkyjj(fptr, "NAXIS1", &naxis1, comm, status); /* row width */ ffgkyjj(fptr, "NAXIS2", &naxis2, comm, status); /* number of rows */ /* check that input row list is in ascending order */ for (ii = 1; ii < nrows; ii++) { if (rownum[ii - 1] >= rownum[ii]) { ffpmsg("row numbers are not in increasing order (ffdrws)"); return(*status = BAD_ROW_NUM); } } if (rownum[0] < 1) { ffpmsg("first row to delete is less than 1 (ffdrws)"); return(*status = BAD_ROW_NUM); } else if (rownum[nrows - 1] > naxis2) { ffpmsg("last row to delete exceeds size of table (ffdrws)"); return(*status = BAD_ROW_NUM); } buffer = (unsigned char *) malloc( (size_t) naxis1); /* buffer for one row */ if (!buffer) { ffpmsg("malloc failed (ffdrwsll)"); return(*status = MEMORY_ALLOCATION); } /* byte location to start of first row to delete, and the next row */ insertpos = (fptr->Fptr)->datastart + ((rownum[0] - 1) * naxis1); nextrowpos = insertpos + naxis1; nextrow = rownum[0] + 1; /* work through the list of rows to delete */ for (ii = 1; ii < nrows; nextrow++, nextrowpos += naxis1) { if (nextrow < rownum[ii]) { /* keep this row, so copy it to the new position */ ffmbyt(fptr, nextrowpos, REPORT_EOF, status); ffgbyt(fptr, naxis1, buffer, status); /* read the bytes */ ffmbyt(fptr, insertpos, IGNORE_EOF, status); ffpbyt(fptr, naxis1, buffer, status); /* write the bytes */ if (*status > 0) { ffpmsg("error while copying good rows in table (ffdrws)"); free(buffer); return(*status); } insertpos += naxis1; } else { /* skip over this row since it is in the list */ ii++; } } /* finished with all the rows to delete; copy remaining rows */ while(nextrow <= naxis2) { ffmbyt(fptr, nextrowpos, REPORT_EOF, status); ffgbyt(fptr, naxis1, buffer, status); /* read the bytes */ ffmbyt(fptr, insertpos, IGNORE_EOF, status); ffpbyt(fptr, naxis1, buffer, status); /* write the bytes */ if (*status > 0) { ffpmsg("failed to copy remaining rows in table (ffdrws)"); free(buffer); return(*status); } insertpos += naxis1; nextrowpos += naxis1; nextrow++; } free(buffer); /* now delete the empty rows at the end of the table */ ffdrow(fptr, naxis2 - nrows + 1, nrows, status); /* Update the heap data, if any. This will remove any orphaned data */ /* that was only pointed to by the rows that have been deleted */ ffcmph(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffrwrg( char *rowlist, /* I - list of rows and row ranges */ LONGLONG maxrows, /* I - number of rows in the table */ int maxranges, /* I - max number of ranges to be returned */ int *numranges, /* O - number ranges returned */ long *minrow, /* O - first row in each range */ long *maxrow, /* O - last row in each range */ int *status) /* IO - status value */ { /* parse the input list of row ranges, returning the number of ranges, and the min and max row value in each range. The only characters allowed in the input rowlist are decimal digits, minus sign, and comma (and non-significant spaces) Example: list = "10-20, 30-35,50" would return numranges = 3, minrow[] = {10, 30, 50}, maxrow[] = {20, 35, 50} error is returned if min value of range is > max value of range or if the ranges are not monotonically increasing. */ char *next; long minval, maxval; if (*status > 0) return(*status); if (maxrows <= 0 ) { *status = RANGE_PARSE_ERROR; ffpmsg("Input maximum range value is <= 0 (fits_parse_ranges)"); return(*status); } next = rowlist; *numranges = 0; while (*next == ' ')next++; /* skip spaces */ while (*next != '\0') { /* find min value of next range; *next must be '-' or a digit */ if (*next == '-') { minval = 1; /* implied minrow value = 1 */ } else if ( isdigit((int) *next) ) { minval = strtol(next, &next, 10); } else { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list:"); ffpmsg(rowlist); return(*status); } while (*next == ' ')next++; /* skip spaces */ /* find max value of next range; *next must be '-', or ',' */ if (*next == '-') { next++; while (*next == ' ')next++; /* skip spaces */ if ( isdigit((int) *next) ) { maxval = strtol(next, &next, 10); } else if (*next == ',' || *next == '\0') { maxval = (long) maxrows; /* implied max value */ } else { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list:"); ffpmsg(rowlist); return(*status); } } else if (*next == ',' || *next == '\0') { maxval = minval; /* only a single integer in this range */ } else { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list:"); ffpmsg(rowlist); return(*status); } if (*numranges + 1 > maxranges) { *status = RANGE_PARSE_ERROR; ffpmsg("Overflowed maximum number of ranges (fits_parse_ranges)"); return(*status); } if (minval < 1 ) { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list: row number < 1"); ffpmsg(rowlist); return(*status); } if (maxval < minval) { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list: min > max"); ffpmsg(rowlist); return(*status); } if (*numranges > 0) { if (minval <= maxrow[(*numranges) - 1]) { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list. Range minimum is"); ffpmsg(" less than or equal to previous range maximum"); ffpmsg(rowlist); return(*status); } } if (minval <= maxrows) { /* ignore range if greater than maxrows */ if (maxval > maxrows) maxval = (long) maxrows; minrow[*numranges] = minval; maxrow[*numranges] = maxval; (*numranges)++; } while (*next == ' ')next++; /* skip spaces */ if (*next == ',') { next++; while (*next == ' ')next++; /* skip more spaces */ } } if (*numranges == 0) { /* a null string was entered */ minrow[0] = 1; maxrow[0] = (long) maxrows; *numranges = 1; } return(*status); } /*--------------------------------------------------------------------------*/ int ffrwrgll( char *rowlist, /* I - list of rows and row ranges */ LONGLONG maxrows, /* I - number of rows in the list */ int maxranges, /* I - max number of ranges to be returned */ int *numranges, /* O - number ranges returned */ LONGLONG *minrow, /* O - first row in each range */ LONGLONG *maxrow, /* O - last row in each range */ int *status) /* IO - status value */ { /* parse the input list of row ranges, returning the number of ranges, and the min and max row value in each range. The only characters allowed in the input rowlist are decimal digits, minus sign, and comma (and non-significant spaces) Example: list = "10-20, 30-35,50" would return numranges = 3, minrow[] = {10, 30, 50}, maxrow[] = {20, 35, 50} error is returned if min value of range is > max value of range or if the ranges are not monotonically increasing. */ char *next; LONGLONG minval, maxval; double dvalue; if (*status > 0) return(*status); if (maxrows <= 0 ) { *status = RANGE_PARSE_ERROR; ffpmsg("Input maximum range value is <= 0 (fits_parse_ranges)"); return(*status); } next = rowlist; *numranges = 0; while (*next == ' ')next++; /* skip spaces */ while (*next != '\0') { /* find min value of next range; *next must be '-' or a digit */ if (*next == '-') { minval = 1; /* implied minrow value = 1 */ } else if ( isdigit((int) *next) ) { /* read as a double, because the string to LONGLONG function */ /* is platform dependent (strtoll, strtol, _atoI64) */ dvalue = strtod(next, &next); minval = (LONGLONG) (dvalue + 0.1); } else { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list:"); ffpmsg(rowlist); return(*status); } while (*next == ' ')next++; /* skip spaces */ /* find max value of next range; *next must be '-', or ',' */ if (*next == '-') { next++; while (*next == ' ')next++; /* skip spaces */ if ( isdigit((int) *next) ) { /* read as a double, because the string to LONGLONG function */ /* is platform dependent (strtoll, strtol, _atoI64) */ dvalue = strtod(next, &next); maxval = (LONGLONG) (dvalue + 0.1); } else if (*next == ',' || *next == '\0') { maxval = maxrows; /* implied max value */ } else { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list:"); ffpmsg(rowlist); return(*status); } } else if (*next == ',' || *next == '\0') { maxval = minval; /* only a single integer in this range */ } else { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list:"); ffpmsg(rowlist); return(*status); } if (*numranges + 1 > maxranges) { *status = RANGE_PARSE_ERROR; ffpmsg("Overflowed maximum number of ranges (fits_parse_ranges)"); return(*status); } if (minval < 1 ) { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list: row number < 1"); ffpmsg(rowlist); return(*status); } if (maxval < minval) { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list: min > max"); ffpmsg(rowlist); return(*status); } if (*numranges > 0) { if (minval <= maxrow[(*numranges) - 1]) { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list. Range minimum is"); ffpmsg(" less than or equal to previous range maximum"); ffpmsg(rowlist); return(*status); } } if (minval <= maxrows) { /* ignore range if greater than maxrows */ if (maxval > maxrows) maxval = maxrows; minrow[*numranges] = minval; maxrow[*numranges] = maxval; (*numranges)++; } while (*next == ' ')next++; /* skip spaces */ if (*next == ',') { next++; while (*next == ' ')next++; /* skip more spaces */ } } if (*numranges == 0) { /* a null string was entered */ minrow[0] = 1; maxrow[0] = maxrows; *numranges = 1; } return(*status); } /*--------------------------------------------------------------------------*/ int fficol(fitsfile *fptr, /* I - FITS file pointer */ int numcol, /* I - position for new col. (1 = 1st) */ char *ttype, /* I - name of column (TTYPE keyword) */ char *tform, /* I - format of column (TFORM keyword) */ int *status) /* IO - error status */ /* Insert a new column into an existing table at position numcol. If numcol is greater than the number of existing columns in the table then the new column will be appended as the last column in the table. */ { char *name, *format; name = ttype; format = tform; fficls(fptr, numcol, 1, &name, &format, status); return(*status); } /*--------------------------------------------------------------------------*/ int fficls(fitsfile *fptr, /* I - FITS file pointer */ int fstcol, /* I - position for first new col. (1 = 1st) */ int ncols, /* I - number of columns to insert */ char **ttype, /* I - array of column names(TTYPE keywords) */ char **tform, /* I - array of formats of column (TFORM) */ int *status) /* IO - error status */ /* Insert 1 or more new columns into an existing table at position numcol. If fstcol is greater than the number of existing columns in the table then the new column will be appended as the last column in the table. */ { int colnum, datacode, decims, tfields, tstatus, ii; LONGLONG datasize, firstbyte, nbytes, nadd, naxis1, naxis2, freespace; LONGLONG tbcol, firstcol, delbyte; long nblock, width, repeat; char tfm[FLEN_VALUE], keyname[FLEN_KEYWORD], comm[FLEN_COMMENT], *cptr; tcolumn *colptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg("Can only add columns to TABLE or BINTABLE extension (fficol)"); return(*status = NOT_TABLE); } /* is the column number valid? */ tfields = (fptr->Fptr)->tfield; if (fstcol < 1 ) return(*status = BAD_COL_NUM); else if (fstcol > tfields) colnum = tfields + 1; /* append as last column */ else colnum = fstcol; /* parse the tform value and calc number of bytes to add to each row */ delbyte = 0; for (ii = 0; ii < ncols; ii++) { strcpy(tfm, tform[ii]); ffupch(tfm); /* make sure format is in upper case */ if ((fptr->Fptr)->hdutype == ASCII_TBL) { ffasfm(tfm, &datacode, &width, &decims, status); delbyte += width + 1; /* add one space between the columns */ } else { ffbnfm(tfm, &datacode, &repeat, &width, status); if (datacode < 0) /* variable length array column */ delbyte += 8; else if (datacode == 1) /* bit column; round up */ delbyte += (repeat + 7) / 8; /* to multiple of 8 bits */ else if (datacode == 16) /* ASCII string column */ delbyte += repeat; else /* numerical data type */ delbyte += (datacode / 10) * repeat; } } if (*status > 0) return(*status); /* get the current size of the table */ /* use internal structure since NAXIS2 keyword may not be up to date */ naxis1 = (fptr->Fptr)->rowlength; naxis2 = (fptr->Fptr)->numrows; /* current size of data */ datasize = (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; freespace = ( ( (datasize + 2879) / 2880) * 2880) - datasize; nadd = delbyte * naxis2; /* no. of bytes to add to table */ if ( (freespace - nadd) < 0) /* not enough existing space? */ { nblock = (long) ((nadd - freespace + 2879) / 2880); /* number of blocks */ if (ffiblk(fptr, nblock, 1, status) > 0) /* insert the blocks */ return(*status); } /* shift heap down (if it exists) */ if ((fptr->Fptr)->heapsize > 0) { nbytes = (fptr->Fptr)->heapsize; /* no. of bytes to shift down */ /* absolute heap pos */ firstbyte = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart; if (ffshft(fptr, firstbyte, nbytes, nadd, status) > 0) /* move heap */ return(*status); } /* update the heap starting address */ (fptr->Fptr)->heapstart += nadd; /* update the THEAP keyword if it exists */ tstatus = 0; ffmkyj(fptr, "THEAP", (fptr->Fptr)->heapstart, "&", &tstatus); /* calculate byte position in the row where to insert the new column */ if (colnum > tfields) firstcol = naxis1; else { colptr = (fptr->Fptr)->tableptr; colptr += (colnum - 1); firstcol = colptr->tbcol; } /* insert delbyte bytes in every row, at byte position firstcol */ ffcins(fptr, naxis1, naxis2, delbyte, firstcol, status); if ((fptr->Fptr)->hdutype == ASCII_TBL) { /* adjust the TBCOL values of the existing columns */ for(ii = 0; ii < tfields; ii++) { ffkeyn("TBCOL", ii + 1, keyname, status); ffgkyjj(fptr, keyname, &tbcol, comm, status); if (tbcol > firstcol) { tbcol += delbyte; ffmkyj(fptr, keyname, tbcol, "&", status); } } } /* update the mandatory keywords */ ffmkyj(fptr, "TFIELDS", tfields + ncols, "&", status); ffmkyj(fptr, "NAXIS1", naxis1 + delbyte, "&", status); /* increment the index value on any existing column keywords */ if(colnum <= tfields) ffkshf(fptr, colnum, tfields, ncols, status); /* add the required keywords for the new columns */ for (ii = 0; ii < ncols; ii++, colnum++) { strcpy(comm, "label for field"); ffkeyn("TTYPE", colnum, keyname, status); ffpkys(fptr, keyname, ttype[ii], comm, status); strcpy(comm, "format of field"); strcpy(tfm, tform[ii]); ffupch(tfm); /* make sure format is in upper case */ ffkeyn("TFORM", colnum, keyname, status); if (abs(datacode) == TSBYTE) { /* Replace the 'S' with an 'B' in the TFORMn code */ cptr = tfm; while (*cptr != 'S') cptr++; *cptr = 'B'; ffpkys(fptr, keyname, tfm, comm, status); /* write the TZEROn and TSCALn keywords */ ffkeyn("TZERO", colnum, keyname, status); strcpy(comm, "offset for signed bytes"); ffpkyg(fptr, keyname, -128., 0, comm, status); ffkeyn("TSCAL", colnum, keyname, status); strcpy(comm, "data are not scaled"); ffpkyg(fptr, keyname, 1., 0, comm, status); } else if (abs(datacode) == TUSHORT) { /* Replace the 'U' with an 'I' in the TFORMn code */ cptr = tfm; while (*cptr != 'U') cptr++; *cptr = 'I'; ffpkys(fptr, keyname, tfm, comm, status); /* write the TZEROn and TSCALn keywords */ ffkeyn("TZERO", colnum, keyname, status); strcpy(comm, "offset for unsigned integers"); ffpkyg(fptr, keyname, 32768., 0, comm, status); ffkeyn("TSCAL", colnum, keyname, status); strcpy(comm, "data are not scaled"); ffpkyg(fptr, keyname, 1., 0, comm, status); } else if (abs(datacode) == TULONG) { /* Replace the 'V' with an 'J' in the TFORMn code */ cptr = tfm; while (*cptr != 'V') cptr++; *cptr = 'J'; ffpkys(fptr, keyname, tfm, comm, status); /* write the TZEROn and TSCALn keywords */ ffkeyn("TZERO", colnum, keyname, status); strcpy(comm, "offset for unsigned integers"); ffpkyg(fptr, keyname, 2147483648., 0, comm, status); ffkeyn("TSCAL", colnum, keyname, status); strcpy(comm, "data are not scaled"); ffpkyg(fptr, keyname, 1., 0, comm, status); } else { ffpkys(fptr, keyname, tfm, comm, status); } if ((fptr->Fptr)->hdutype == ASCII_TBL) /* write the TBCOL keyword */ { if (colnum == tfields + 1) tbcol = firstcol + 2; /* allow space between preceding col */ else tbcol = firstcol + 1; strcpy(comm, "beginning column of field"); ffkeyn("TBCOL", colnum, keyname, status); ffpkyj(fptr, keyname, tbcol, comm, status); /* increment the column starting position for the next column */ ffasfm(tfm, &datacode, &width, &decims, status); firstcol += width + 1; /* add one space between the columns */ } } ffrdef(fptr, status); /* initialize the new table structure */ return(*status); } /*--------------------------------------------------------------------------*/ int ffmvec(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - position of col to be modified */ LONGLONG newveclen, /* I - new vector length of column (TFORM) */ int *status) /* IO - error status */ /* Modify the vector length of a column in a binary table, larger or smaller. E.g., change a column from TFORMn = '1E' to '20E'. */ { int datacode, tfields, tstatus; LONGLONG datasize, size, firstbyte, nbytes, nadd, ndelete; LONGLONG naxis1, naxis2, firstcol, freespace; LONGLONG width, delbyte, repeat; long nblock; char tfm[FLEN_VALUE], keyname[FLEN_KEYWORD], tcode[2]; tcolumn *colptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype != BINARY_TBL) { ffpmsg( "Can only change vector length of a column in BINTABLE extension (ffmvec)"); return(*status = NOT_TABLE); } /* is the column number valid? */ tfields = (fptr->Fptr)->tfield; if (colnum < 1 || colnum > tfields) return(*status = BAD_COL_NUM); /* look up the current vector length and element width */ colptr = (fptr->Fptr)->tableptr; colptr += (colnum - 1); datacode = colptr->tdatatype; /* datatype of the column */ repeat = colptr->trepeat; /* field repeat count */ width = colptr->twidth; /* width of a single element in chars */ if (datacode < 0) { ffpmsg( "Can't modify vector length of variable length column (ffmvec)"); return(*status = BAD_TFORM); } if (repeat == newveclen) return(*status); /* column already has the desired vector length */ if (datacode == TSTRING) width = 1; /* width was equal to width of unit string */ naxis1 = (fptr->Fptr)->rowlength; /* current width of the table */ naxis2 = (fptr->Fptr)->numrows; delbyte = (newveclen - repeat) * width; /* no. of bytes to insert */ if (datacode == TBIT) /* BIT column is a special case */ delbyte = ((newveclen + 1) / 8) - ((repeat + 1) / 8); if (delbyte > 0) /* insert space for more elements */ { /* current size of data */ datasize = (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; freespace = ( ( (datasize + 2879) / 2880) * 2880) - datasize; nadd = (LONGLONG)delbyte * naxis2; /* no. of bytes to add to table */ if ( (freespace - nadd) < 0) /* not enough existing space? */ { nblock = (long) ((nadd - freespace + 2879) / 2880); /* number of blocks */ if (ffiblk(fptr, nblock, 1, status) > 0) /* insert the blocks */ return(*status); } /* shift heap down (if it exists) */ if ((fptr->Fptr)->heapsize > 0) { nbytes = (fptr->Fptr)->heapsize; /* no. of bytes to shift down */ /* absolute heap pos */ firstbyte = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart; if (ffshft(fptr, firstbyte, nbytes, nadd, status) > 0) /* move heap */ return(*status); } /* update the heap starting address */ (fptr->Fptr)->heapstart += nadd; /* update the THEAP keyword if it exists */ tstatus = 0; ffmkyj(fptr, "THEAP", (fptr->Fptr)->heapstart, "&", &tstatus); firstcol = colptr->tbcol + (repeat * width); /* insert position */ /* insert delbyte bytes in every row, at byte position firstcol */ ffcins(fptr, naxis1, naxis2, delbyte, firstcol, status); } else if (delbyte < 0) { /* current size of table */ size = (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; freespace = ((size + 2879) / 2880) * 2880 - size - ((LONGLONG)delbyte * naxis2); nblock = (long) (freespace / 2880); /* number of empty blocks to delete */ firstcol = colptr->tbcol + (newveclen * width); /* delete position */ /* delete elements from the vector */ ffcdel(fptr, naxis1, naxis2, -delbyte, firstcol, status); /* abs heap pos */ firstbyte = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart; ndelete = (LONGLONG)delbyte * naxis2; /* size of shift (negative) */ /* shift heap up (if it exists) */ if ((fptr->Fptr)->heapsize > 0) { nbytes = (fptr->Fptr)->heapsize; /* no. of bytes to shift up */ if (ffshft(fptr, firstbyte, nbytes, ndelete, status) > 0) return(*status); } /* delete the empty blocks at the end of the HDU */ if (nblock > 0) ffdblk(fptr, nblock, status); /* update the heap starting address */ (fptr->Fptr)->heapstart += ndelete; /* ndelete is negative */ /* update the THEAP keyword if it exists */ tstatus = 0; ffmkyj(fptr, "THEAP", (fptr->Fptr)->heapstart, "&", &tstatus); } /* construct the new TFORM keyword for the column */ if (datacode == TBIT) strcpy(tcode,"X"); else if (datacode == TBYTE) strcpy(tcode,"B"); else if (datacode == TLOGICAL) strcpy(tcode,"L"); else if (datacode == TSTRING) strcpy(tcode,"A"); else if (datacode == TSHORT) strcpy(tcode,"I"); else if (datacode == TLONG) strcpy(tcode,"J"); else if (datacode == TLONGLONG) strcpy(tcode,"K"); else if (datacode == TFLOAT) strcpy(tcode,"E"); else if (datacode == TDOUBLE) strcpy(tcode,"D"); else if (datacode == TCOMPLEX) strcpy(tcode,"C"); else if (datacode == TDBLCOMPLEX) strcpy(tcode,"M"); /* write as a double value because the LONGLONG conversion */ /* character in sprintf is platform dependent ( %lld, %ld, %I64d ) */ sprintf(tfm,"%.0f%s",(double) newveclen, tcode); ffkeyn("TFORM", colnum, keyname, status); /* Keyword name */ ffmkys(fptr, keyname, tfm, "&", status); /* modify TFORM keyword */ ffmkyj(fptr, "NAXIS1", naxis1 + delbyte, "&", status); /* modify NAXIS1 */ ffrdef(fptr, status); /* reinitialize the new table structure */ return(*status); } /*--------------------------------------------------------------------------*/ int ffcpcl(fitsfile *infptr, /* I - FITS file pointer to input file */ fitsfile *outfptr, /* I - FITS file pointer to output file */ int incol, /* I - number of input column */ int outcol, /* I - number for output column */ int create_col, /* I - create new col if TRUE, else overwrite */ int *status) /* IO - error status */ /* copy a column from infptr and insert it in the outfptr table. */ { int tstatus, colnum, typecode, anynull; long tfields, repeat, width, nrows, outrows; long inloop, outloop, maxloop, ndone, ntodo, npixels; long firstrow, firstelem, ii; char keyname[FLEN_KEYWORD], ttype[FLEN_VALUE], tform[FLEN_VALUE]; char ttype_comm[FLEN_COMMENT],tform_comm[FLEN_COMMENT]; char *lvalues = 0, nullflag, **strarray = 0; char nulstr[] = {'\5', '\0'}; /* unique null string value */ double dnull = 0.l, *dvalues = 0; float fnull = 0., *fvalues = 0; if (*status > 0) return(*status); if (infptr->HDUposition != (infptr->Fptr)->curhdu) { ffmahd(infptr, (infptr->HDUposition) + 1, NULL, status); } else if ((infptr->Fptr)->datastart == DATA_UNDEFINED) ffrdef(infptr, status); /* rescan header */ if (outfptr->HDUposition != (outfptr->Fptr)->curhdu) { ffmahd(outfptr, (outfptr->HDUposition) + 1, NULL, status); } else if ((outfptr->Fptr)->datastart == DATA_UNDEFINED) ffrdef(outfptr, status); /* rescan header */ if (*status > 0) return(*status); if ((infptr->Fptr)->hdutype == IMAGE_HDU || (outfptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg ("Can not copy columns to or from IMAGE HDUs (ffcpcl)"); return(*status = NOT_TABLE); } if ( (infptr->Fptr)->hdutype == BINARY_TBL && (outfptr->Fptr)->hdutype == ASCII_TBL) { ffpmsg ("Copying from Binary table to ASCII table is not supported (ffcpcl)"); return(*status = NOT_BTABLE); } /* get the datatype and vector repeat length of the column */ ffgtcl(infptr, incol, &typecode, &repeat, &width, status); if (typecode < 0) { ffpmsg("Variable-length columns are not supported (ffcpcl)"); return(*status = BAD_TFORM); } if (create_col) /* insert new column in output table? */ { tstatus = 0; ffkeyn("TTYPE", incol, keyname, &tstatus); ffgkys(infptr, keyname, ttype, ttype_comm, &tstatus); ffkeyn("TFORM", incol, keyname, &tstatus); if (ffgkys(infptr, keyname, tform, tform_comm, &tstatus) ) { ffpmsg ("Could not find TTYPE and TFORM keywords in input table (ffcpcl)"); return(*status = NO_TFORM); } if ((infptr->Fptr)->hdutype == ASCII_TBL && (outfptr->Fptr)->hdutype == BINARY_TBL) { /* convert from ASCII table to BINARY table format string */ if (typecode == TSTRING) ffnkey(width, "A", tform, status); else if (typecode == TLONG) strcpy(tform, "1J"); else if (typecode == TSHORT) strcpy(tform, "1I"); else if (typecode == TFLOAT) strcpy(tform,"1E"); else if (typecode == TDOUBLE) strcpy(tform,"1D"); } if (ffgkyj(outfptr, "TFIELDS", &tfields, 0, &tstatus)) { ffpmsg ("Could not read TFIELDS keyword in output table (ffcpcl)"); return(*status = NO_TFIELDS); } colnum = minvalue((int) tfields + 1, outcol); /* output col. number */ /* create the empty column */ if (fficol(outfptr, colnum, ttype, tform, status) > 0) { ffpmsg ("Could not append new column to output file (ffcpcl)"); return(*status); } /* copy the comment strings from the input file for TTYPE and TFORM */ tstatus = 0; ffkeyn("TTYPE", colnum, keyname, &tstatus); ffmcom(outfptr, keyname, ttype_comm, &tstatus); ffkeyn("TFORM", colnum, keyname, &tstatus); ffmcom(outfptr, keyname, tform_comm, &tstatus); /* copy other column-related keywords if they exist */ ffcpky(infptr, outfptr, incol, colnum, "TUNIT", status); ffcpky(infptr, outfptr, incol, colnum, "TSCAL", status); ffcpky(infptr, outfptr, incol, colnum, "TZERO", status); ffcpky(infptr, outfptr, incol, colnum, "TDISP", status); ffcpky(infptr, outfptr, incol, colnum, "TLMIN", status); ffcpky(infptr, outfptr, incol, colnum, "TLMAX", status); ffcpky(infptr, outfptr, incol, colnum, "TDIM", status); /* WCS keywords */ ffcpky(infptr, outfptr, incol, colnum, "TCTYP", status); ffcpky(infptr, outfptr, incol, colnum, "TCUNI", status); ffcpky(infptr, outfptr, incol, colnum, "TCRVL", status); ffcpky(infptr, outfptr, incol, colnum, "TCRPX", status); ffcpky(infptr, outfptr, incol, colnum, "TCDLT", status); ffcpky(infptr, outfptr, incol, colnum, "TCROT", status); if ((infptr->Fptr)->hdutype == ASCII_TBL && (outfptr->Fptr)->hdutype == BINARY_TBL) { /* binary tables only have TNULLn keyword for integer columns */ if (typecode == TLONG || typecode == TSHORT) { /* check if null string is defined; replace with integer */ ffkeyn("TNULL", incol, keyname, &tstatus); if (ffgkys(infptr, keyname, ttype, 0, &tstatus) <= 0) { ffkeyn("TNULL", colnum, keyname, &tstatus); if (typecode == TLONG) ffpkyj(outfptr, keyname, -9999999L, "Null value", status); else ffpkyj(outfptr, keyname, -32768L, "Null value", status); } } } else { ffcpky(infptr, outfptr, incol, colnum, "TNULL", status); } /* rescan header to recognize the new keywords */ if (ffrdef(outfptr, status) ) return(*status); } else { colnum = outcol; } ffgkyj(infptr, "NAXIS2", &nrows, 0, status); /* no. of input rows */ ffgkyj(outfptr, "NAXIS2", &outrows, 0, status); /* no. of output rows */ nrows = minvalue(nrows, outrows); if (typecode == TBIT) repeat = (repeat - 1) / 8 + 1; /* convert from bits to bytes */ else if (typecode == TSTRING && (infptr->Fptr)->hdutype == BINARY_TBL) repeat = repeat / width; /* convert from chars to unit strings */ /* get optimum number of rows to copy at one time */ ffgrsz(infptr, &inloop, status); ffgrsz(outfptr, &outloop, status); /* adjust optimum number, since 2 tables are open at once */ maxloop = minvalue(inloop, outloop); /* smallest of the 2 tables */ maxloop = maxvalue(1, maxloop / 2); /* at least 1 row */ maxloop = minvalue(maxloop, nrows); /* max = nrows to be copied */ maxloop *= repeat; /* mult by no of elements in a row */ /* allocate memory for arrays */ if (typecode == TLOGICAL) { lvalues = (char *) calloc(maxloop, sizeof(char) ); if (!lvalues) { ffpmsg ("malloc failed to get memory for logicals (ffcpcl)"); return(*status = ARRAY_TOO_BIG); } } else if (typecode == TSTRING) { /* allocate array of pointers */ strarray = (char **) calloc(maxloop, sizeof(strarray)); /* allocate space for each string */ for (ii = 0; ii < maxloop; ii++) strarray[ii] = (char *) calloc(width+1, sizeof(char)); } else if (typecode == TCOMPLEX) { fvalues = (float *) calloc(maxloop * 2, sizeof(float) ); if (!fvalues) { ffpmsg ("malloc failed to get memory for complex (ffcpcl)"); return(*status = ARRAY_TOO_BIG); } fnull = 0.; } else if (typecode == TDBLCOMPLEX) { dvalues = (double *) calloc(maxloop * 2, sizeof(double) ); if (!dvalues) { ffpmsg ("malloc failed to get memory for dbl complex (ffcpcl)"); return(*status = ARRAY_TOO_BIG); } dnull = 0.; } else /* numerical datatype; read them all as doubles */ { dvalues = (double *) calloc(maxloop, sizeof(double) ); if (!dvalues) { ffpmsg ("malloc failed to get memory for doubles (ffcpcl)"); return(*status = ARRAY_TOO_BIG); } dnull = -9.99991999E31; /* use an unlikely value for nulls */ } npixels = nrows * repeat; /* total no. of pixels to copy */ ntodo = minvalue(npixels, maxloop); /* no. to copy per iteration */ ndone = 0; /* total no. of pixels that have been copied */ while (ntodo) /* iterate through the table */ { firstrow = ndone / repeat + 1; firstelem = ndone - ((firstrow - 1) * repeat) + 1; /* read from input table */ if (typecode == TLOGICAL) ffgcl(infptr, incol, firstrow, firstelem, ntodo, lvalues, status); else if (typecode == TSTRING) ffgcvs(infptr, incol, firstrow, firstelem, ntodo, nulstr, strarray, &anynull, status); else if (typecode == TCOMPLEX) ffgcvc(infptr, incol, firstrow, firstelem, ntodo, fnull, fvalues, &anynull, status); else if (typecode == TDBLCOMPLEX) ffgcvm(infptr, incol, firstrow, firstelem, ntodo, dnull, dvalues, &anynull, status); else /* all numerical types */ ffgcvd(infptr, incol, firstrow, firstelem, ntodo, dnull, dvalues, &anynull, status); if (*status > 0) { ffpmsg("Error reading input copy of column (ffcpcl)"); break; } /* write to output table */ if (typecode == TLOGICAL) { nullflag = 2; ffpcnl(outfptr, colnum, firstrow, firstelem, ntodo, lvalues, nullflag, status); } else if (typecode == TSTRING) { if (anynull) ffpcns(outfptr, colnum, firstrow, firstelem, ntodo, strarray, nulstr, status); else ffpcls(outfptr, colnum, firstrow, firstelem, ntodo, strarray, status); } else if (typecode == TCOMPLEX) { /* doesn't support writing nulls */ ffpclc(outfptr, colnum, firstrow, firstelem, ntodo, fvalues, status); } else if (typecode == TDBLCOMPLEX) { /* doesn't support writing nulls */ ffpclm(outfptr, colnum, firstrow, firstelem, ntodo, dvalues, status); } else /* all other numerical types */ { if (anynull) ffpcnd(outfptr, colnum, firstrow, firstelem, ntodo, dvalues, dnull, status); else ffpcld(outfptr, colnum, firstrow, firstelem, ntodo, dvalues, status); } if (*status > 0) { ffpmsg("Error writing output copy of column (ffcpcl)"); break; } npixels -= ntodo; ndone += ntodo; ntodo = minvalue(npixels, maxloop); } /* free the previously allocated memory */ if (typecode == TLOGICAL) { free(lvalues); } else if (typecode == TSTRING) { for (ii = 0; ii < maxloop; ii++) free(strarray[ii]); free(strarray); } else { free(dvalues); } return(*status); } /*--------------------------------------------------------------------------*/ int ffcpky(fitsfile *infptr, /* I - FITS file pointer to input file */ fitsfile *outfptr, /* I - FITS file pointer to output file */ int incol, /* I - input index number */ int outcol, /* I - output index number */ char *rootname, /* I - root name of the keyword to be copied */ int *status) /* IO - error status */ /* copy an indexed keyword from infptr to outfptr. */ { int tstatus = 0; char keyname[FLEN_KEYWORD]; char value[FLEN_VALUE], comment[FLEN_COMMENT], card[FLEN_CARD]; ffkeyn(rootname, incol, keyname, &tstatus); if (ffgkey(infptr, keyname, value, comment, &tstatus) <= 0) { ffkeyn(rootname, outcol, keyname, &tstatus); ffmkky(keyname, value, comment, card, status); ffprec(outfptr, card, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffdcol(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column to delete (1 = 1st) */ int *status) /* IO - error status */ /* Delete a column from a table. */ { int ii, tstatus; LONGLONG firstbyte, size, ndelete, nbytes, naxis1, naxis2, firstcol, delbyte, freespace; LONGLONG tbcol; long nblock, nspace; char keyname[FLEN_KEYWORD], comm[FLEN_COMMENT]; tcolumn *colptr, *nextcol; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg ("Can only delete column from TABLE or BINTABLE extension (ffdcol)"); return(*status = NOT_TABLE); } if (colnum < 1 || colnum > (fptr->Fptr)->tfield ) return(*status = BAD_COL_NUM); colptr = (fptr->Fptr)->tableptr; colptr += (colnum - 1); firstcol = colptr->tbcol; /* starting byte position of the column */ /* use column width to determine how many bytes to delete in each row */ if ((fptr->Fptr)->hdutype == ASCII_TBL) { delbyte = colptr->twidth; /* width of ASCII column */ if (colnum < (fptr->Fptr)->tfield) /* check for space between next column */ { nextcol = colptr + 1; nspace = (long) ((nextcol->tbcol) - (colptr->tbcol) - delbyte); if (nspace > 0) delbyte++; } else if (colnum > 1) /* check for space between last 2 columns */ { nextcol = colptr - 1; nspace = (long) ((colptr->tbcol) - (nextcol->tbcol) - (nextcol->twidth)); if (nspace > 0) { delbyte++; firstcol--; /* delete the leading space */ } } } else /* a binary table */ { if (colnum < (fptr->Fptr)->tfield) { nextcol = colptr + 1; delbyte = (nextcol->tbcol) - (colptr->tbcol); } else { delbyte = ((fptr->Fptr)->rowlength) - (colptr->tbcol); } } naxis1 = (fptr->Fptr)->rowlength; /* current width of the table */ naxis2 = (fptr->Fptr)->numrows; /* current size of table */ size = (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; freespace = ((LONGLONG)delbyte * naxis2) + ((size + 2879) / 2880) * 2880 - size; nblock = (long) (freespace / 2880); /* number of empty blocks to delete */ ffcdel(fptr, naxis1, naxis2, delbyte, firstcol, status); /* delete col */ /* absolute heap position */ firstbyte = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart; ndelete = (LONGLONG)delbyte * naxis2; /* size of shift */ /* shift heap up (if it exists) */ if ((fptr->Fptr)->heapsize > 0) { nbytes = (fptr->Fptr)->heapsize; /* no. of bytes to shift up */ if (ffshft(fptr, firstbyte, nbytes, -ndelete, status) > 0) /* mv heap */ return(*status); } /* delete the empty blocks at the end of the HDU */ if (nblock > 0) ffdblk(fptr, nblock, status); /* update the heap starting address */ (fptr->Fptr)->heapstart -= ndelete; /* update the THEAP keyword if it exists */ tstatus = 0; ffmkyj(fptr, "THEAP", (long)(fptr->Fptr)->heapstart, "&", &tstatus); if ((fptr->Fptr)->hdutype == ASCII_TBL) { /* adjust the TBCOL values of the remaining columns */ for (ii = 1; ii <= (fptr->Fptr)->tfield; ii++) { ffkeyn("TBCOL", ii, keyname, status); ffgkyjj(fptr, keyname, &tbcol, comm, status); if (tbcol > firstcol) { tbcol = tbcol - delbyte; ffmkyj(fptr, keyname, tbcol, "&", status); } } } /* update the mandatory keywords */ ffmkyj(fptr, "TFIELDS", ((fptr->Fptr)->tfield) - 1, "&", status); ffmkyj(fptr, "NAXIS1", naxis1 - delbyte, "&", status); /* delete the index keywords starting with 'T' associated with the deleted column and subtract 1 from index of all higher keywords */ ffkshf(fptr, colnum, (fptr->Fptr)->tfield, -1, status); ffrdef(fptr, status); /* initialize the new table structure */ return(*status); } /*--------------------------------------------------------------------------*/ int ffcins(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG naxis1, /* I - width of the table, in bytes */ LONGLONG naxis2, /* I - number of rows in the table */ LONGLONG ninsert, /* I - number of bytes to insert in each row */ LONGLONG bytepos, /* I - rel. position in row to insert bytes */ int *status) /* IO - error status */ /* Insert 'ninsert' bytes into each row of the table at position 'bytepos'. */ { unsigned char buffer[10000], cfill; LONGLONG newlen, fbyte, nbytes, irow, nseg, ii; if (*status > 0) return(*status); if (naxis2 == 0) return(*status); /* just return if there are 0 rows in the table */ /* select appropriate fill value */ if ((fptr->Fptr)->hdutype == ASCII_TBL) cfill = 32; /* ASCII tables use blank fill */ else cfill = 0; /* primary array and binary tables use zero fill */ newlen = naxis1 + ninsert; if (newlen <= 10000) { /******************************************************************* CASE #1: optimal case where whole new row fits in the work buffer *******************************************************************/ for (ii = 0; ii < ninsert; ii++) buffer[ii] = cfill; /* initialize buffer with fill value */ /* first move the trailing bytes (if any) in the last row */ fbyte = bytepos + 1; nbytes = naxis1 - bytepos; ffgtbb(fptr, naxis2, fbyte, nbytes, &buffer[ninsert], status); (fptr->Fptr)->rowlength = newlen; /* new row length */ /* write the row (with leading fill bytes) in the new place */ nbytes += ninsert; ffptbb(fptr, naxis2, fbyte, nbytes, buffer, status); (fptr->Fptr)->rowlength = naxis1; /* reset to orig. value */ /* now move the rest of the rows */ for (irow = naxis2 - 1; irow > 0; irow--) { /* read the row to be shifted (work backwards thru the table) */ ffgtbb(fptr, irow, fbyte, naxis1, &buffer[ninsert], status); (fptr->Fptr)->rowlength = newlen; /* new row length */ /* write the row (with the leading fill bytes) in the new place */ ffptbb(fptr, irow, fbyte, newlen, buffer, status); (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ } } else { /***************************************************************** CASE #2: whole row doesn't fit in work buffer; move row in pieces ****************************************************************** first copy the data, then go back and write fill into the new column start by copying the trailing bytes (if any) in the last row. */ nbytes = naxis1 - bytepos; nseg = (nbytes + 9999) / 10000; fbyte = (nseg - 1) * 10000 + bytepos + 1; nbytes = naxis1 - fbyte + 1; for (ii = 0; ii < nseg; ii++) { ffgtbb(fptr, naxis2, fbyte, nbytes, buffer, status); (fptr->Fptr)->rowlength = newlen; /* new row length */ ffptbb(fptr, naxis2, fbyte + ninsert, nbytes, buffer, status); (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ fbyte -= 10000; nbytes = 10000; } /* now move the rest of the rows */ nseg = (naxis1 + 9999) / 10000; for (irow = naxis2 - 1; irow > 0; irow--) { fbyte = (nseg - 1) * 10000 + bytepos + 1; nbytes = naxis1 - (nseg - 1) * 10000; for (ii = 0; ii < nseg; ii++) { /* read the row to be shifted (work backwards thru the table) */ ffgtbb(fptr, irow, fbyte, nbytes, buffer, status); (fptr->Fptr)->rowlength = newlen; /* new row length */ /* write the row in the new place */ ffptbb(fptr, irow, fbyte + ninsert, nbytes, buffer, status); (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ fbyte -= 10000; nbytes = 10000; } } /* now write the fill values into the new column */ nbytes = minvalue(ninsert, 10000); memset(buffer, cfill, (size_t) nbytes); /* initialize with fill value */ nseg = (ninsert + 9999) / 10000; (fptr->Fptr)->rowlength = newlen; /* new row length */ for (irow = 1; irow <= naxis2; irow++) { fbyte = bytepos + 1; nbytes = ninsert - ((nseg - 1) * 10000); for (ii = 0; ii < nseg; ii++) { ffptbb(fptr, irow, fbyte, nbytes, buffer, status); fbyte += nbytes; nbytes = 10000; } } (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffcdel(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG naxis1, /* I - width of the table, in bytes */ LONGLONG naxis2, /* I - number of rows in the table */ LONGLONG ndelete, /* I - number of bytes to delete in each row */ LONGLONG bytepos, /* I - rel. position in row to delete bytes */ int *status) /* IO - error status */ /* delete 'ndelete' bytes from each row of the table at position 'bytepos'. */ { unsigned char buffer[10000]; LONGLONG i1, i2, ii, irow, nseg; LONGLONG newlen, remain, nbytes; if (*status > 0) return(*status); if (naxis2 == 0) return(*status); /* just return if there are 0 rows in the table */ newlen = naxis1 - ndelete; if (newlen <= 10000) { /******************************************************************* CASE #1: optimal case where whole new row fits in the work buffer *******************************************************************/ i1 = bytepos + 1; i2 = i1 + ndelete; for (irow = 1; irow < naxis2; irow++) { ffgtbb(fptr, irow, i2, newlen, buffer, status); /* read row */ (fptr->Fptr)->rowlength = newlen; /* new row length */ ffptbb(fptr, irow, i1, newlen, buffer, status); /* write row */ (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ } /* now do the last row */ remain = naxis1 - (bytepos + ndelete); if (remain > 0) { ffgtbb(fptr, naxis2, i2, remain, buffer, status); /* read row */ (fptr->Fptr)->rowlength = newlen; /* new row length */ ffptbb(fptr, naxis2, i1, remain, buffer, status); /* write row */ (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ } } else { /***************************************************************** CASE #2: whole row doesn't fit in work buffer; move row in pieces ******************************************************************/ nseg = (newlen + 9999) / 10000; for (irow = 1; irow < naxis2; irow++) { i1 = bytepos + 1; i2 = i1 + ndelete; nbytes = newlen - (nseg - 1) * 10000; for (ii = 0; ii < nseg; ii++) { ffgtbb(fptr, irow, i2, nbytes, buffer, status); /* read bytes */ (fptr->Fptr)->rowlength = newlen; /* new row length */ ffptbb(fptr, irow, i1, nbytes, buffer, status); /* rewrite bytes */ (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ i1 += nbytes; i2 += nbytes; nbytes = 10000; } } /* now do the last row */ remain = naxis1 - (bytepos + ndelete); if (remain > 0) { nseg = (remain + 9999) / 10000; i1 = bytepos + 1; i2 = i1 + ndelete; nbytes = remain - (nseg - 1) * 10000; for (ii = 0; ii < nseg; ii++) { ffgtbb(fptr, naxis2, i2, nbytes, buffer, status); (fptr->Fptr)->rowlength = newlen; /* new row length */ ffptbb(fptr, naxis2, i1, nbytes, buffer, status); /* write row */ (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ i1 += nbytes; i2 += nbytes; nbytes = 10000; } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffkshf(fitsfile *fptr, /* I - FITS file pointer */ int colmin, /* I - starting col. to be incremented; 1 = 1st */ int colmax, /* I - last column to be incremented */ int incre, /* I - shift index number by this amount */ int *status) /* IO - error status */ /* shift the index value on any existing column keywords This routine will modify the name of any keyword that begins with 'T' and has an index number in the range COLMIN - COLMAX, inclusive. if incre is positive, then the index values will be incremented. if incre is negative, then the kewords with index = COLMIN will be deleted and the index of higher numbered keywords will be decremented. */ { int nkeys, nmore, nrec, tstatus, i1; long ivalue; char rec[FLEN_CARD], q[FLEN_KEYWORD], newkey[FLEN_KEYWORD]; ffghsp(fptr, &nkeys, &nmore, status); /* get number of keywords */ /* go thru header starting with the 9th keyword looking for 'TxxxxNNN' */ for (nrec = 9; nrec <= nkeys; nrec++) { ffgrec(fptr, nrec, rec, status); if (rec[0] == 'T') { i1 = 0; strncpy(q, &rec[1], 4); if (!strncmp(q, "BCOL", 4) || !strncmp(q, "FORM", 4) || !strncmp(q, "TYPE", 4) || !strncmp(q, "SCAL", 4) || !strncmp(q, "UNIT", 4) || !strncmp(q, "NULL", 4) || !strncmp(q, "ZERO", 4) || !strncmp(q, "DISP", 4) || !strncmp(q, "LMIN", 4) || !strncmp(q, "LMAX", 4) || !strncmp(q, "DMIN", 4) || !strncmp(q, "DMAX", 4) || !strncmp(q, "CTYP", 4) || !strncmp(q, "CRPX", 4) || !strncmp(q, "CRVL", 4) || !strncmp(q, "CDLT", 4) || !strncmp(q, "CROT", 4) || !strncmp(q, "CUNI", 4) ) i1 = 5; else if (!strncmp(rec, "TDIM", 4) ) i1 = 4; if (i1) { /* try reading the index number suffix */ q[0] = '\0'; strncat(q, &rec[i1], 8 - i1); tstatus = 0; ffc2ii(q, &ivalue, &tstatus); if (tstatus == 0 && ivalue >= colmin && ivalue <= colmax) { if (incre <= 0 && ivalue == colmin) { ffdrec(fptr, nrec, status); /* delete keyword */ nkeys = nkeys - 1; nrec = nrec - 1; } else { ivalue = ivalue + incre; q[0] = '\0'; strncat(q, rec, i1); ffkeyn(q, ivalue, newkey, status); strncpy(rec, " ", 8); /* erase old keyword name */ i1 = strlen(newkey); strncpy(rec, newkey, i1); /* overwrite new keyword name */ ffmrec(fptr, nrec, rec, status); /* modify the record */ } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffshft(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG firstbyte, /* I - position of first byte in block to shift */ LONGLONG nbytes, /* I - size of block of bytes to shift */ LONGLONG nshift, /* I - size of shift in bytes (+ or -) */ int *status) /* IO - error status */ /* Shift block of bytes by nshift bytes (positive or negative). A positive nshift value moves the block down further in the file, while a negative value shifts the block towards the beginning of the file. */ { #define shftbuffsize 100000 long ntomov; LONGLONG ptr, ntodo; char buffer[shftbuffsize]; if (*status > 0) return(*status); ntodo = nbytes; /* total number of bytes to shift */ if (nshift > 0) /* start at the end of the block and work backwards */ ptr = firstbyte + nbytes; else /* start at the beginning of the block working forwards */ ptr = firstbyte; while (ntodo) { /* number of bytes to move at one time */ ntomov = (long) (minvalue(ntodo, shftbuffsize)); if (nshift > 0) /* if moving block down ... */ ptr -= ntomov; /* move to position and read the bytes to be moved */ ffmbyt(fptr, ptr, REPORT_EOF, status); ffgbyt(fptr, ntomov, buffer, status); /* move by shift amount and write the bytes */ ffmbyt(fptr, ptr + nshift, IGNORE_EOF, status); if (ffpbyt(fptr, ntomov, buffer, status) > 0) { ffpmsg("Error while shifting block (ffshft)"); return(*status); } ntodo -= ntomov; if (nshift < 0) /* if moving block up ... */ ptr += ntomov; } /* now overwrite the old data with fill */ if ((fptr->Fptr)->hdutype == ASCII_TBL) memset(buffer, 32, shftbuffsize); /* fill ASCII tables with spaces */ else memset(buffer, 0, shftbuffsize); /* fill other HDUs with zeros */ if (nshift < 0) { ntodo = -nshift; /* point to the end of the shifted block */ ptr = firstbyte + nbytes + nshift; } else { ntodo = nshift; /* point to original beginning of the block */ ptr = firstbyte; } ffmbyt(fptr, ptr, REPORT_EOF, status); while (ntodo) { ntomov = (long) (minvalue(ntodo, shftbuffsize)); ffpbyt(fptr, ntomov, buffer, status); ntodo -= ntomov; } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/edithdu.c000066400000000000000000000731361215713201500222340ustar00rootroot00000000000000/* This file, edithdu.c, contains the FITSIO routines related to */ /* copying, inserting, or deleting HDUs in a FITS file */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffcopy(fitsfile *infptr, /* I - FITS file pointer to input file */ fitsfile *outfptr, /* I - FITS file pointer to output file */ int morekeys, /* I - reserve space in output header */ int *status) /* IO - error status */ /* copy the CHDU from infptr to the CHDU of outfptr. This will also allocate space in the output header for MOREKY keywords */ { if (*status > 0) return(*status); if (infptr == outfptr) return(*status = SAME_FILE); if (ffcphd(infptr, outfptr, status) ) /* copy the header keywords */ return(*status); if (morekeys > 0) ffhdef(outfptr, morekeys, status); /* reserve space for more keywords */ ffcpdt(infptr, outfptr, status); /* now copy the data unit */ return(*status); } /*--------------------------------------------------------------------------*/ int ffcpfl(fitsfile *infptr, /* I - FITS file pointer to input file */ fitsfile *outfptr, /* I - FITS file pointer to output file */ int previous, /* I - copy any previous HDUs? */ int current, /* I - copy the current HDU? */ int following, /* I - copy any following HDUs? */ int *status) /* IO - error status */ /* copy all or part of the input file to the output file. */ { int hdunum, ii; if (*status > 0) return(*status); if (infptr == outfptr) return(*status = SAME_FILE); ffghdn(infptr, &hdunum); if (previous) { /* copy any previous HDUs */ for (ii=1; ii < hdunum; ii++) { ffmahd(infptr, ii, NULL, status); ffcopy(infptr, outfptr, 0, status); } } if (current && (*status <= 0) ) { /* copy current HDU */ ffmahd(infptr, hdunum, NULL, status); ffcopy(infptr, outfptr, 0, status); } if (following && (*status <= 0) ) { /* copy any remaining HDUs */ ii = hdunum + 1; while (1) { if (ffmahd(infptr, ii, NULL, status) ) { /* reset expected end of file status */ if (*status == END_OF_FILE) *status = 0; break; } if (ffcopy(infptr, outfptr, 0, status)) break; /* quit on unexpected error */ ii++; } } ffmahd(infptr, hdunum, NULL, status); /* restore initial position */ return(*status); } /*--------------------------------------------------------------------------*/ int ffcphd(fitsfile *infptr, /* I - FITS file pointer to input file */ fitsfile *outfptr, /* I - FITS file pointer to output file */ int *status) /* IO - error status */ /* copy the header keywords from infptr to outfptr. */ { int nkeys, ii, inPrim = 0, outPrim = 0; long naxis, naxes[1]; char *card, comm[FLEN_COMMENT]; char *tmpbuff = NULL; if (*status > 0) return(*status); if (infptr == outfptr) return(*status = SAME_FILE); /* set the input pointer to the correct HDU */ if (infptr->HDUposition != (infptr->Fptr)->curhdu) ffmahd(infptr, (infptr->HDUposition) + 1, NULL, status); if (ffghsp(infptr, &nkeys, NULL, status) > 0) /* get no. of keywords */ return(*status); /* create a memory buffer to hold the header records */ tmpbuff = (char*) malloc(nkeys*FLEN_CARD*sizeof(char)); if (!tmpbuff) return(*status = MEMORY_ALLOCATION); /* read all of the header records in the input HDU */ for (ii = 0; ii < nkeys; ii++) ffgrec(infptr, ii+1, tmpbuff + (ii * FLEN_CARD), status); if (infptr->HDUposition == 0) /* set flag if this is the Primary HDU */ inPrim = 1; /* if input is an image hdu, get the number of axes */ naxis = -1; /* negative if HDU is a table */ if ((infptr->Fptr)->hdutype == IMAGE_HDU) ffgkyj(infptr, "NAXIS", &naxis, NULL, status); /* set the output pointer to the correct HDU */ if (outfptr->HDUposition != (outfptr->Fptr)->curhdu) ffmahd(outfptr, (outfptr->HDUposition) + 1, NULL, status); /* check if output header is empty; if not create new empty HDU */ if ((outfptr->Fptr)->headend != (outfptr->Fptr)->headstart[(outfptr->Fptr)->curhdu] ) ffcrhd(outfptr, status); if (outfptr->HDUposition == 0) { if (naxis < 0) { /* the input HDU is a table, so we have to create */ /* a dummy Primary array before copying it to the output */ ffcrim(outfptr, 8, 0, naxes, status); ffcrhd(outfptr, status); /* create new empty HDU */ } else { /* set flag that this is the Primary HDU */ outPrim = 1; } } if (*status > 0) /* check for errors before proceeding */ { free(tmpbuff); return(*status); } if ( inPrim == 1 && outPrim == 0 ) { /* copying from primary array to image extension */ strcpy(comm, "IMAGE extension"); ffpkys(outfptr, "XTENSION", "IMAGE", comm, status); /* copy BITPIX through NAXISn keywords */ for (ii = 1; ii < 3 + naxis; ii++) { card = tmpbuff + (ii * FLEN_CARD); ffprec(outfptr, card, status); } strcpy(comm, "number of random group parameters"); ffpkyj(outfptr, "PCOUNT", 0, comm, status); strcpy(comm, "number of random groups"); ffpkyj(outfptr, "GCOUNT", 1, comm, status); /* copy remaining keywords, excluding EXTEND, and reference COMMENT keywords */ for (ii = 3 + naxis ; ii < nkeys; ii++) { card = tmpbuff+(ii * FLEN_CARD); if (FSTRNCMP(card, "EXTEND ", 8) && FSTRNCMP(card, "COMMENT FITS (Flexible Image Transport System) format is", 58) && FSTRNCMP(card, "COMMENT and Astrophysics', volume 376, page 3", 47) ) { ffprec(outfptr, card, status); } } } else if ( inPrim == 0 && outPrim == 1 ) { /* copying between image extension and primary array */ strcpy(comm, "file does conform to FITS standard"); ffpkyl(outfptr, "SIMPLE", TRUE, comm, status); /* copy BITPIX through NAXISn keywords */ for (ii = 1; ii < 3 + naxis; ii++) { card = tmpbuff + (ii * FLEN_CARD); ffprec(outfptr, card, status); } /* add the EXTEND keyword */ strcpy(comm, "FITS dataset may contain extensions"); ffpkyl(outfptr, "EXTEND", TRUE, comm, status); /* write standard block of self-documentating comments */ ffprec(outfptr, "COMMENT FITS (Flexible Image Transport System) format is defined in 'Astronomy", status); ffprec(outfptr, "COMMENT and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H", status); /* copy remaining keywords, excluding pcount, gcount */ for (ii = 3 + naxis; ii < nkeys; ii++) { card = tmpbuff+(ii * FLEN_CARD); if (FSTRNCMP(card, "PCOUNT ", 8) && FSTRNCMP(card, "GCOUNT ", 8)) { ffprec(outfptr, card, status); } } } else { /* input and output HDUs are same type; simply copy all keywords */ for (ii = 0; ii < nkeys; ii++) { card = tmpbuff+(ii * FLEN_CARD); ffprec(outfptr, card, status); } } free(tmpbuff); return(*status); } /*--------------------------------------------------------------------------*/ int ffcpdt(fitsfile *infptr, /* I - FITS file pointer to input file */ fitsfile *outfptr, /* I - FITS file pointer to output file */ int *status) /* IO - error status */ { /* copy the data unit from the CHDU of infptr to the CHDU of outfptr. This will overwrite any data already in the outfptr CHDU. */ long nb, ii; LONGLONG indatastart, indataend, outdatastart; char buffer[2880]; if (*status > 0) return(*status); if (infptr == outfptr) return(*status = SAME_FILE); ffghadll(infptr, NULL, &indatastart, &indataend, status); ffghadll(outfptr, NULL, &outdatastart, NULL, status); /* Calculate the number of blocks to be copied */ nb = (long) ((indataend - indatastart) / 2880); if (nb > 0) { if (infptr->Fptr == outfptr->Fptr) { /* copying between 2 HDUs in the SAME file */ for (ii = 0; ii < nb; ii++) { ffmbyt(infptr, indatastart, REPORT_EOF, status); ffgbyt(infptr, 2880L, buffer, status); /* read input block */ ffmbyt(outfptr, outdatastart, IGNORE_EOF, status); ffpbyt(outfptr, 2880L, buffer, status); /* write output block */ indatastart += 2880; /* move address */ outdatastart += 2880; /* move address */ } } else { /* copying between HDUs in separate files */ /* move to the initial copy position in each of the files */ ffmbyt(infptr, indatastart, REPORT_EOF, status); ffmbyt(outfptr, outdatastart, IGNORE_EOF, status); for (ii = 0; ii < nb; ii++) { ffgbyt(infptr, 2880L, buffer, status); /* read input block */ ffpbyt(outfptr, 2880L, buffer, status); /* write output block */ } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffwrhdu(fitsfile *infptr, /* I - FITS file pointer to input file */ FILE *outstream, /* I - stream to write HDU to */ int *status) /* IO - error status */ { /* write the data unit from the CHDU of infptr to the output file stream */ long nb, ii; LONGLONG hdustart, hduend; char buffer[2880]; if (*status > 0) return(*status); ffghadll(infptr, &hdustart, NULL, &hduend, status); nb = (long) ((hduend - hdustart) / 2880); /* number of blocks to copy */ if (nb > 0) { /* move to the start of the HDU */ ffmbyt(infptr, hdustart, REPORT_EOF, status); for (ii = 0; ii < nb; ii++) { ffgbyt(infptr, 2880L, buffer, status); /* read input block */ fwrite(buffer, 1, 2880, outstream ); /* write to output stream */ } } return(*status); } /*--------------------------------------------------------------------------*/ int ffiimg(fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - bits per pixel */ int naxis, /* I - number of axes in the array */ long *naxes, /* I - size of each axis */ int *status) /* IO - error status */ /* insert an IMAGE extension following the current HDU */ { LONGLONG tnaxes[99]; int ii; if (*status > 0) return(*status); if (naxis > 99) { ffpmsg("NAXIS value is too large (>99) (ffiimg)"); return(*status = 212); } for (ii = 0; (ii < naxis); ii++) tnaxes[ii] = naxes[ii]; ffiimgll(fptr, bitpix, naxis, tnaxes, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffiimgll(fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - bits per pixel */ int naxis, /* I - number of axes in the array */ LONGLONG *naxes, /* I - size of each axis */ int *status) /* IO - error status */ /* insert an IMAGE extension following the current HDU */ { int bytlen, nexthdu, maxhdu, ii, onaxis; long nblocks; LONGLONG npixels, newstart, datasize; char errmsg[FLEN_ERRMSG], card[FLEN_CARD], naxiskey[FLEN_KEYWORD]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); maxhdu = (fptr->Fptr)->maxhdu; if (*status != PREPEND_PRIMARY) { /* if the current header is completely empty ... */ if (( (fptr->Fptr)->headend == (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]) /* or, if we are at the end of the file, ... */ || ( (((fptr->Fptr)->curhdu) == maxhdu ) && ((fptr->Fptr)->headstart[maxhdu + 1] >= (fptr->Fptr)->logfilesize ) ) ) { /* then simply append new image extension */ ffcrimll(fptr, bitpix, naxis, naxes, status); return(*status); } } if (bitpix == 8) bytlen = 1; else if (bitpix == 16) bytlen = 2; else if (bitpix == 32 || bitpix == -32) bytlen = 4; else if (bitpix == 64 || bitpix == -64) bytlen = 8; else { sprintf(errmsg, "Illegal value for BITPIX keyword: %d", bitpix); ffpmsg(errmsg); return(*status = BAD_BITPIX); /* illegal bitpix value */ } if (naxis < 0 || naxis > 999) { sprintf(errmsg, "Illegal value for NAXIS keyword: %d", naxis); ffpmsg(errmsg); return(*status = BAD_NAXIS); } for (ii = 0; ii < naxis; ii++) { if (naxes[ii] < 0) { sprintf(errmsg, "Illegal value for NAXIS%d keyword: %ld", ii + 1, (long) naxes[ii]); ffpmsg(errmsg); return(*status = BAD_NAXES); } } /* calculate number of pixels in the image */ if (naxis == 0) npixels = 0; else npixels = naxes[0]; for (ii = 1; ii < naxis; ii++) npixels = npixels * naxes[ii]; datasize = npixels * bytlen; /* size of image in bytes */ nblocks = (long) (((datasize + 2879) / 2880) + 1); /* +1 for the header */ if ((fptr->Fptr)->writemode == READWRITE) /* must have write access */ { /* close the CHDU */ ffrdef(fptr, status); /* scan header to redefine structure */ ffpdfl(fptr, status); /* insure correct data file values */ } else return(*status = READONLY_FILE); if (*status == PREPEND_PRIMARY) { /* inserting a new primary array; the current primary */ /* array must be transformed into an image extension. */ *status = 0; ffmahd(fptr, 1, NULL, status); /* move to the primary array */ ffgidm(fptr, &onaxis, status); if (onaxis > 0) ffkeyn("NAXIS",onaxis, naxiskey, status); else strcpy(naxiskey, "NAXIS"); ffgcrd(fptr, naxiskey, card, status); /* read last NAXIS keyword */ ffikyj(fptr, "PCOUNT", 0, "required keyword", status); /* add PCOUNT and */ ffikyj(fptr, "GCOUNT", 1, "required keyword", status); /* GCOUNT keywords */ if (*status > 0) return(*status); if (ffdkey(fptr, "EXTEND", status) ) /* delete the EXTEND keyword */ *status = 0; /* redefine internal structure for this HDU */ ffrdef(fptr, status); /* insert space for the primary array */ if (ffiblk(fptr, nblocks, -1, status) > 0) /* insert the blocks */ return(*status); nexthdu = 0; /* number of the new hdu */ newstart = 0; /* starting addr of HDU */ } else { nexthdu = ((fptr->Fptr)->curhdu) + 1; /* number of the next (new) hdu */ newstart = (fptr->Fptr)->headstart[nexthdu]; /* save starting addr of HDU */ (fptr->Fptr)->hdutype = IMAGE_HDU; /* so that correct fill value is used */ /* ffiblk also increments headstart for all following HDUs */ if (ffiblk(fptr, nblocks, 1, status) > 0) /* insert the blocks */ return(*status); } ((fptr->Fptr)->maxhdu)++; /* increment known number of HDUs in the file */ for (ii = (fptr->Fptr)->maxhdu; ii > (fptr->Fptr)->curhdu; ii--) (fptr->Fptr)->headstart[ii + 1] = (fptr->Fptr)->headstart[ii]; /* incre start addr */ if (nexthdu == 0) (fptr->Fptr)->headstart[1] = nblocks * 2880; /* start of the old Primary array */ (fptr->Fptr)->headstart[nexthdu] = newstart; /* set starting addr of HDU */ /* set default parameters for this new empty HDU */ (fptr->Fptr)->curhdu = nexthdu; /* we are now located at the next HDU */ fptr->HDUposition = nexthdu; /* we are now located at the next HDU */ (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[nexthdu]; (fptr->Fptr)->headend = (fptr->Fptr)->headstart[nexthdu]; (fptr->Fptr)->datastart = ((fptr->Fptr)->headstart[nexthdu]) + 2880; (fptr->Fptr)->hdutype = IMAGE_HDU; /* might need to be reset... */ /* write the required header keywords */ ffphprll(fptr, TRUE, bitpix, naxis, naxes, 0, 1, TRUE, status); /* redefine internal structure for this HDU */ ffrdef(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffitab(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG naxis1, /* I - width of row in the table */ LONGLONG naxis2, /* I - number of rows in the table */ int tfields, /* I - number of columns in the table */ char **ttype, /* I - name of each column */ long *tbcol, /* I - byte offset in row to each column */ char **tform, /* I - value of TFORMn keyword for each column */ char **tunit, /* I - value of TUNITn keyword for each column */ char *extnm, /* I - value of EXTNAME keyword, if any */ int *status) /* IO - error status */ /* insert an ASCII table extension following the current HDU */ { int nexthdu, maxhdu, ii, nunit, nhead, ncols, gotmem = 0; long nblocks, rowlen; LONGLONG datasize, newstart; char errmsg[81]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); maxhdu = (fptr->Fptr)->maxhdu; /* if the current header is completely empty ... */ if (( (fptr->Fptr)->headend == (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) /* or, if we are at the end of the file, ... */ || ( (((fptr->Fptr)->curhdu) == maxhdu ) && ((fptr->Fptr)->headstart[maxhdu + 1] >= (fptr->Fptr)->logfilesize ) ) ) { /* then simply append new image extension */ ffcrtb(fptr, ASCII_TBL, naxis2, tfields, ttype, tform, tunit, extnm, status); return(*status); } if (naxis1 < 0) return(*status = NEG_WIDTH); else if (naxis2 < 0) return(*status = NEG_ROWS); else if (tfields < 0 || tfields > 999) { sprintf(errmsg, "Illegal value for TFIELDS keyword: %d", tfields); ffpmsg(errmsg); return(*status = BAD_TFIELDS); } /* count number of optional TUNIT keywords to be written */ nunit = 0; for (ii = 0; ii < tfields; ii++) { if (tunit && *tunit && *tunit[ii]) nunit++; } if (extnm && *extnm) nunit++; /* add one for the EXTNAME keyword */ rowlen = (long) naxis1; if (!tbcol || !tbcol[0] || (!naxis1 && tfields)) /* spacing not defined? */ { /* allocate mem for tbcol; malloc may have problems allocating small */ /* arrays, so allocate at least 20 bytes */ ncols = maxvalue(5, tfields); tbcol = (long *) calloc(ncols, sizeof(long)); if (tbcol) { gotmem = 1; /* calculate width of a row and starting position of each column. */ /* Each column will be separated by 1 blank space */ ffgabc(tfields, tform, 1, &rowlen, tbcol, status); } } nhead = (9 + (3 * tfields) + nunit + 35) / 36; /* no. of header blocks */ datasize = (LONGLONG)rowlen * naxis2; /* size of table in bytes */ nblocks = (long) (((datasize + 2879) / 2880) + nhead); /* size of HDU */ if ((fptr->Fptr)->writemode == READWRITE) /* must have write access */ { /* close the CHDU */ ffrdef(fptr, status); /* scan header to redefine structure */ ffpdfl(fptr, status); /* insure correct data file values */ } else return(*status = READONLY_FILE); nexthdu = ((fptr->Fptr)->curhdu) + 1; /* number of the next (new) hdu */ newstart = (fptr->Fptr)->headstart[nexthdu]; /* save starting addr of HDU */ (fptr->Fptr)->hdutype = ASCII_TBL; /* so that correct fill value is used */ /* ffiblk also increments headstart for all following HDUs */ if (ffiblk(fptr, nblocks, 1, status) > 0) /* insert the blocks */ { if (gotmem) free(tbcol); return(*status); } ((fptr->Fptr)->maxhdu)++; /* increment known number of HDUs in the file */ for (ii = (fptr->Fptr)->maxhdu; ii > (fptr->Fptr)->curhdu; ii--) (fptr->Fptr)->headstart[ii + 1] = (fptr->Fptr)->headstart[ii]; /* incre start addr */ (fptr->Fptr)->headstart[nexthdu] = newstart; /* set starting addr of HDU */ /* set default parameters for this new empty HDU */ (fptr->Fptr)->curhdu = nexthdu; /* we are now located at the next HDU */ fptr->HDUposition = nexthdu; /* we are now located at the next HDU */ (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[nexthdu]; (fptr->Fptr)->headend = (fptr->Fptr)->headstart[nexthdu]; (fptr->Fptr)->datastart = ((fptr->Fptr)->headstart[nexthdu]) + (nhead * 2880); (fptr->Fptr)->hdutype = ASCII_TBL; /* might need to be reset... */ /* write the required header keywords */ ffphtb(fptr, rowlen, naxis2, tfields, ttype, tbcol, tform, tunit, extnm, status); if (gotmem) free(tbcol); /* redefine internal structure for this HDU */ ffrdef(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffibin(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG naxis2, /* I - number of rows in the table */ int tfields, /* I - number of columns in the table */ char **ttype, /* I - name of each column */ char **tform, /* I - value of TFORMn keyword for each column */ char **tunit, /* I - value of TUNITn keyword for each column */ char *extnm, /* I - value of EXTNAME keyword, if any */ LONGLONG pcount, /* I - size of special data area (heap) */ int *status) /* IO - error status */ /* insert a Binary table extension following the current HDU */ { int nexthdu, maxhdu, ii, nunit, nhead, datacode; LONGLONG naxis1; long nblocks, repeat, width; LONGLONG datasize, newstart; char errmsg[81]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); maxhdu = (fptr->Fptr)->maxhdu; /* if the current header is completely empty ... */ if (( (fptr->Fptr)->headend == (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) /* or, if we are at the end of the file, ... */ || ( (((fptr->Fptr)->curhdu) == maxhdu ) && ((fptr->Fptr)->headstart[maxhdu + 1] >= (fptr->Fptr)->logfilesize ) ) ) { /* then simply append new image extension */ ffcrtb(fptr, BINARY_TBL, naxis2, tfields, ttype, tform, tunit, extnm, status); return(*status); } if (naxis2 < 0) return(*status = NEG_ROWS); else if (tfields < 0 || tfields > 999) { sprintf(errmsg, "Illegal value for TFIELDS keyword: %d", tfields); ffpmsg(errmsg); return(*status = BAD_TFIELDS); } /* count number of optional TUNIT keywords to be written */ nunit = 0; for (ii = 0; ii < tfields; ii++) { if (tunit && *tunit && *tunit[ii]) nunit++; } if (extnm && *extnm) nunit++; /* add one for the EXTNAME keyword */ nhead = (9 + (2 * tfields) + nunit + 35) / 36; /* no. of header blocks */ /* calculate total width of the table */ naxis1 = 0; for (ii = 0; ii < tfields; ii++) { ffbnfm(tform[ii], &datacode, &repeat, &width, status); if (datacode == TBIT) naxis1 = naxis1 + ((repeat + 7) / 8); else if (datacode == TSTRING) naxis1 += repeat; else naxis1 = naxis1 + (repeat * width); } datasize = ((LONGLONG)naxis1 * naxis2) + pcount; /* size of table in bytes */ nblocks = (long) ((datasize + 2879) / 2880) + nhead; /* size of HDU */ if ((fptr->Fptr)->writemode == READWRITE) /* must have write access */ { /* close the CHDU */ ffrdef(fptr, status); /* scan header to redefine structure */ ffpdfl(fptr, status); /* insure correct data file values */ } else return(*status = READONLY_FILE); nexthdu = ((fptr->Fptr)->curhdu) + 1; /* number of the next (new) hdu */ newstart = (fptr->Fptr)->headstart[nexthdu]; /* save starting addr of HDU */ (fptr->Fptr)->hdutype = BINARY_TBL; /* so that correct fill value is used */ /* ffiblk also increments headstart for all following HDUs */ if (ffiblk(fptr, nblocks, 1, status) > 0) /* insert the blocks */ return(*status); ((fptr->Fptr)->maxhdu)++; /* increment known number of HDUs in the file */ for (ii = (fptr->Fptr)->maxhdu; ii > (fptr->Fptr)->curhdu; ii--) (fptr->Fptr)->headstart[ii + 1] = (fptr->Fptr)->headstart[ii]; /* incre start addr */ (fptr->Fptr)->headstart[nexthdu] = newstart; /* set starting addr of HDU */ /* set default parameters for this new empty HDU */ (fptr->Fptr)->curhdu = nexthdu; /* we are now located at the next HDU */ fptr->HDUposition = nexthdu; /* we are now located at the next HDU */ (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[nexthdu]; (fptr->Fptr)->headend = (fptr->Fptr)->headstart[nexthdu]; (fptr->Fptr)->datastart = ((fptr->Fptr)->headstart[nexthdu]) + (nhead * 2880); (fptr->Fptr)->hdutype = BINARY_TBL; /* might need to be reset... */ /* write the required header keywords. This will write PCOUNT = 0 */ /* so that the variable length data will be written at the right place */ ffphbn(fptr, naxis2, tfields, ttype, tform, tunit, extnm, pcount, status); /* redefine internal structure for this HDU (with PCOUNT = 0) */ ffrdef(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffdhdu(fitsfile *fptr, /* I - FITS file pointer */ int *hdutype, /* O - type of the new CHDU after deletion */ int *status) /* IO - error status */ /* Delete the CHDU. If the CHDU is the primary array, then replace the HDU with an empty primary array with no data. Return the type of the new CHDU after the old CHDU is deleted. */ { int tmptype = 0; long nblocks, ii, naxes[1]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ((fptr->Fptr)->curhdu == 0) /* replace primary array with null image */ { /* ignore any existing keywords */ (fptr->Fptr)->headend = 0; (fptr->Fptr)->nextkey = 0; /* write default primary array header */ ffphpr(fptr,1,8,0,naxes,0,1,1,status); /* calc number of blocks to delete (leave just 1 block) */ nblocks = (long) (( (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu + 1] - 2880 ) / 2880); /* ffdblk also updates the starting address of all following HDUs */ if (nblocks > 0) { if (ffdblk(fptr, nblocks, status) > 0) /* delete the HDU */ return(*status); } /* this might not be necessary, but is doesn't hurt */ (fptr->Fptr)->datastart = DATA_UNDEFINED; ffrdef(fptr, status); /* reinitialize the primary array */ } else { /* calc number of blocks to delete */ nblocks = (long) (( (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu + 1] - (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) / 2880); /* ffdblk also updates the starting address of all following HDUs */ if (ffdblk(fptr, nblocks, status) > 0) /* delete the HDU */ return(*status); /* delete the CHDU from the list of HDUs */ for (ii = (fptr->Fptr)->curhdu + 1; ii <= (fptr->Fptr)->maxhdu; ii++) (fptr->Fptr)->headstart[ii] = (fptr->Fptr)->headstart[ii + 1]; (fptr->Fptr)->headstart[(fptr->Fptr)->maxhdu + 1] = 0; ((fptr->Fptr)->maxhdu)--; /* decrement the known number of HDUs */ if (ffrhdu(fptr, &tmptype, status) > 0) /* initialize next HDU */ { /* failed (end of file?), so move back one HDU */ *status = 0; ffcmsg(); /* clear extraneous error messages */ ffgext(fptr, ((fptr->Fptr)->curhdu) - 1, &tmptype, status); } } if (hdutype) *hdutype = tmptype; return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/eval_defs.h000066400000000000000000000101041215713201500225250ustar00rootroot00000000000000#include #include #include #include #if defined(__sgi) || defined(__hpux) #include #endif #ifdef sparc #include #endif #include "fitsio2.h" #ifndef FFBISON #include "eval_tab.h" #endif #define MAXDIMS 5 #define MAXSUBS 10 #define MAXVARNAME 80 #define CONST_OP -1000 #define pERROR -1 typedef struct { char name[MAXVARNAME+1]; int type; long nelem; int naxis; long naxes[MAXDIMS]; char *undef; void *data; } DataInfo; typedef struct { long nelem; int naxis; long naxes[MAXDIMS]; char *undef; union { double dbl; long lng; char log; char str[256]; double *dblptr; long *lngptr; char *logptr; char **strptr; void *ptr; } data; } lval; typedef struct Node { int operation; void (*DoOp)(struct Node *this); int nSubNodes; int SubNodes[MAXSUBS]; int type; lval value; } Node; typedef struct { fitsfile *def_fptr; int (*getData)( char *dataName, void *dataValue ); int (*loadData)( int varNum, long fRow, long nRows, void *data, char *undef ); int compressed; int timeCol; int parCol; int valCol; char *expr; int index; int is_eobuf; Node *Nodes; int nNodes; int nNodesAlloc; int resultNode; long firstRow; long nRows; int nCols; iteratorCol *colData; DataInfo *varData; PixelFilter *pixFilter; long firstDataRow; long nDataRows; long totalRows; int datatype; int hdutype; int status; } ParseData; typedef enum { rnd_fct = 1001, sum_fct, nelem_fct, sin_fct, cos_fct, tan_fct, asin_fct, acos_fct, atan_fct, sinh_fct, cosh_fct, tanh_fct, exp_fct, log_fct, log10_fct, sqrt_fct, abs_fct, atan2_fct, ceil_fct, floor_fct, round_fct, min1_fct, min2_fct, max1_fct, max2_fct, near_fct, circle_fct, box_fct, elps_fct, isnull_fct, defnull_fct, gtifilt_fct, regfilt_fct, ifthenelse_fct, row_fct, null_fct, median_fct, average_fct, stddev_fct, nonnull_fct, angsep_fct, gasrnd_fct, poirnd_fct } funcOp; extern ParseData gParse; #ifdef __cplusplus extern "C" { #endif int ffparse(void); int fflex(void); void ffrestart(FILE*); void Evaluate_Parser( long firstRow, long nRows ); #ifdef __cplusplus } #endif skycat-3.1.2-starlink-1b/astrotcl/cfitsio/eval_f.c000066400000000000000000002761021215713201500220400ustar00rootroot00000000000000/************************************************************************/ /* */ /* CFITSIO Lexical Parser */ /* */ /* This file is one of 3 files containing code which parses an */ /* arithmetic expression and evaluates it in the context of an input */ /* FITS file table extension. The CFITSIO lexical parser is divided */ /* into the following 3 parts/files: the CFITSIO "front-end", */ /* eval_f.c, contains the interface between the user/CFITSIO and the */ /* real core of the parser; the FLEX interpreter, eval_l.c, takes the */ /* input string and parses it into tokens and identifies the FITS */ /* information required to evaluate the expression (ie, keywords and */ /* columns); and, the BISON grammar and evaluation routines, eval_y.c, */ /* receives the FLEX output and determines and performs the actual */ /* operations. The files eval_l.c and eval_y.c are produced from */ /* running flex and bison on the files eval.l and eval.y, respectively. */ /* (flex and bison are available from any GNU archive: see www.gnu.org) */ /* */ /* The grammar rules, rather than evaluating the expression in situ, */ /* builds a tree, or Nodal, structure mapping out the order of */ /* operations and expression dependencies. This "compilation" process */ /* allows for much faster processing of multiple rows. This technique */ /* was developed by Uwe Lammers of the XMM Science Analysis System, */ /* although the CFITSIO implementation is entirely code original. */ /* */ /* */ /* Modification History: */ /* */ /* Kent Blackburn c1992 Original parser code developed for the */ /* FTOOLS software package, in particular, */ /* the fselect task. */ /* Kent Blackburn c1995 BIT column support added */ /* Peter D Wilson Feb 1998 Vector column support added */ /* Peter D Wilson May 1998 Ported to CFITSIO library. User */ /* interface routines written, in essence */ /* making fselect, fcalc, and maketime */ /* capabilities available to all tools */ /* via single function calls. */ /* Peter D Wilson Jun 1998 Major rewrite of parser core, so as to */ /* create a run-time evaluation tree, */ /* inspired by the work of Uwe Lammers, */ /* resulting in a speed increase of */ /* 10-100 times. */ /* Peter D Wilson Jul 1998 gtifilter(a,b,c,d) function added */ /* Peter D Wilson Aug 1998 regfilter(a,b,c,d) function added */ /* Peter D Wilson Jul 1999 Make parser fitsfile-independent, */ /* allowing a purely vector-based usage */ /* Peter D Wilson Aug 1999 Add row-offset capability */ /* Peter D Wilson Sep 1999 Add row-range capability to ffcalc_rng */ /* */ /************************************************************************/ #include #include #include "eval_defs.h" #include "region.h" typedef struct { int datatype; /* Data type to cast parse results into for user */ void *dataPtr; /* Pointer to array of results, NULL if to use iterCol */ void *nullPtr; /* Pointer to nulval, use zero if NULL */ long maxRows; /* Max No. of rows to process, -1=all, 0=1 iteration */ int anyNull; /* Flag indicating at least 1 undef value encountered */ } parseInfo; /* Internal routines needed to allow the evaluator to operate on FITS data */ static void Setup_DataArrays( int nCols, iteratorCol *cols, long fRow, long nRows ); static int find_column( char *colName, void *itslval ); static int find_keywd ( char *key, void *itslval ); static int allocateCol( int nCol, int *status ); static int load_column( int varNum, long fRow, long nRows, void *data, char *undef ); static int DEBUG_PIXFILTER; #define FREE(x) { if (x) free(x); else printf("invalid free(" #x ") at %s:%d\n", __FILE__, __LINE__); } /*---------------------------------------------------------------------------*/ int fffrow( fitsfile *fptr, /* I - Input FITS file */ char *expr, /* I - Boolean expression */ long firstrow, /* I - First row of table to eval */ long nrows, /* I - Number of rows to evaluate */ long *n_good_rows, /* O - Number of rows eval to True */ char *row_status, /* O - Array of boolean results */ int *status ) /* O - Error status */ /* */ /* Evaluate a boolean expression using the indicated rows, returning an */ /* array of flags indicating which rows evaluated to TRUE/FALSE */ /*---------------------------------------------------------------------------*/ { parseInfo Info; int naxis, constant; long nelem, naxes[MAXDIMS], elem; char result; if( *status ) return( *status ); if( ffiprs( fptr, 0, expr, MAXDIMS, &Info.datatype, &nelem, &naxis, naxes, status ) ) { ffcprs(); return( *status ); } if( nelem<0 ) { constant = 1; nelem = -nelem; } else constant = 0; if( Info.datatype!=TLOGICAL || nelem!=1 ) { ffcprs(); ffpmsg("Expression does not evaluate to a logical scalar."); return( *status = PARSE_BAD_TYPE ); } if( constant ) { /* No need to call parser... have result from ffiprs */ result = gParse.Nodes[gParse.resultNode].value.data.log; *n_good_rows = nrows; for( elem=0; elem1 ? firstrow : 1); Info.dataPtr = row_status; Info.nullPtr = NULL; Info.maxRows = nrows; if( ffiter( gParse.nCols, gParse.colData, firstrow-1, 0, parse_data, (void*)&Info, status ) == -1 ) *status = 0; /* -1 indicates exitted without error before end... OK */ if( *status ) { /***********************/ /* Error... Do nothing */ /***********************/ } else { /***********************************/ /* Count number of good rows found */ /***********************************/ *n_good_rows = 0L; for( elem=0; elemHDUposition != (infptr->Fptr)->curhdu ) ffmahd( infptr, (infptr->HDUposition) + 1, NULL, status ); if( *status ) { ffcprs(); return( *status ); } inExt.rowLength = (long) (infptr->Fptr)->rowlength; inExt.numRows = (infptr->Fptr)->numrows; inExt.heapSize = (infptr->Fptr)->heapsize; if( inExt.numRows == 0 ) { /* Nothing to copy */ ffcprs(); return( *status ); } if( outfptr->HDUposition != (outfptr->Fptr)->curhdu ) ffmahd( outfptr, (outfptr->HDUposition) + 1, NULL, status ); if( (outfptr->Fptr)->datastart < 0 ) ffrdef( outfptr, status ); if( *status ) { ffcprs(); return( *status ); } outExt.rowLength = (long) (outfptr->Fptr)->rowlength; outExt.numRows = (outfptr->Fptr)->numrows; if( !outExt.numRows ) (outfptr->Fptr)->heapsize = 0L; outExt.heapSize = (outfptr->Fptr)->heapsize; if( inExt.rowLength != outExt.rowLength ) { ffpmsg("Output table has different row length from input"); ffcprs(); return( *status = PARSE_BAD_OUTPUT ); } /***********************************/ /* Fill out Info data for parser */ /***********************************/ Info.dataPtr = (char *)malloc( (size_t) ((inExt.numRows + 1) * sizeof(char)) ); Info.nullPtr = NULL; Info.maxRows = (long) inExt.numRows; if( !Info.dataPtr ) { ffpmsg("Unable to allocate memory for row selection"); ffcprs(); return( *status = MEMORY_ALLOCATION ); } /* make sure array is zero terminated */ ((char*)Info.dataPtr)[inExt.numRows] = 0; if( constant ) { /* Set all rows to the same value from constant result */ result = gParse.Nodes[gParse.resultNode].value.data.log; for( ntodo = 0; ntodo 1) ffirow( outfptr, outExt.numRows, nGood, status ); } do { if( ((char*)Info.dataPtr)[inloc-1] ) { ffgtbb( infptr, inloc, 1L, rdlen, buffer+rdlen*nbuff, status ); nbuff++; if( nbuff==maxrows ) { ffptbb( outfptr, outloc, 1L, rdlen*nbuff, buffer, status ); outloc += nbuff; nbuff = 0; } } inloc++; } while( !*status && inloc<=inExt.numRows ); if( nbuff ) { ffptbb( outfptr, outloc, 1L, rdlen*nbuff, buffer, status ); outloc += nbuff; } if( infptr==outfptr ) { if( outloc<=inExt.numRows ) ffdrow( infptr, outloc, inExt.numRows-outloc+1, status ); } else if( inExt.heapSize && nGood ) { /* Copy heap, if it exists and at least one row copied */ /********************************************************/ /* Get location information from the output extension */ /********************************************************/ if( outfptr->HDUposition != (outfptr->Fptr)->curhdu ) ffmahd( outfptr, (outfptr->HDUposition) + 1, NULL, status ); outExt.dataStart = (outfptr->Fptr)->datastart; outExt.heapStart = (outfptr->Fptr)->heapstart; /*************************************************/ /* Insert more space into outfptr if necessary */ /*************************************************/ hsize = outExt.heapStart + outExt.heapSize; freespace = (long) (( ( (hsize + 2879) / 2880) * 2880) - hsize); ntodo = inExt.heapSize; if ( (freespace - ntodo) < 0) { /* not enough existing space? */ ntodo = (ntodo - freespace + 2879) / 2880; /* number of blocks */ ffiblk(outfptr, (long) ntodo, 1, status); /* insert the blocks */ } ffukyj( outfptr, "PCOUNT", inExt.heapSize+outExt.heapSize, NULL, status ); /*******************************************************/ /* Get location information from the input extension */ /*******************************************************/ if( infptr->HDUposition != (infptr->Fptr)->curhdu ) ffmahd( infptr, (infptr->HDUposition) + 1, NULL, status ); inExt.dataStart = (infptr->Fptr)->datastart; inExt.heapStart = (infptr->Fptr)->heapstart; /**********************************/ /* Finally copy heap to outfptr */ /**********************************/ ntodo = inExt.heapSize; inbyteloc = inExt.heapStart + inExt.dataStart; outbyteloc = outExt.heapStart + outExt.dataStart + outExt.heapSize; while ( ntodo && !*status ) { rdlen = (long) minvalue(ntodo,500000); ffmbyt( infptr, inbyteloc, REPORT_EOF, status ); ffgbyt( infptr, rdlen, buffer, status ); ffmbyt( outfptr, outbyteloc, IGNORE_EOF, status ); ffpbyt( outfptr, rdlen, buffer, status ); inbyteloc += rdlen; outbyteloc += rdlen; ntodo -= rdlen; } /***********************************************************/ /* But must update DES if data is being appended to a */ /* pre-existing heap space. Edit each new entry in file */ /***********************************************************/ if( outExt.heapSize ) { LONGLONG repeat, offset, j; int i; for( i=1; i<=(outfptr->Fptr)->tfield; i++ ) { if( (outfptr->Fptr)->tableptr[i-1].tdatatype<0 ) { for( j=outExt.numRows+1; j<=outExt.numRows+nGood; j++ ) { ffgdesll( outfptr, i, j, &repeat, &offset, status ); offset += outExt.heapSize; ffpdes( outfptr, i, j, repeat, offset, status ); } } } } } /* End of HEAP copy */ FREE(buffer); } FREE(Info.dataPtr); ffcprs(); ffcmph(outfptr, status); /* compress heap, deleting any orphaned data */ return(*status); } /*---------------------------------------------------------------------------*/ int ffcrow( fitsfile *fptr, /* I - Input FITS file */ int datatype, /* I - Datatype to return results as */ char *expr, /* I - Arithmetic expression */ long firstrow, /* I - First row to evaluate */ long nelements, /* I - Number of elements to return */ void *nulval, /* I - Ptr to value to use as UNDEF */ void *array, /* O - Array of results */ int *anynul, /* O - Were any UNDEFs encountered? */ int *status ) /* O - Error status */ /* */ /* Calculate an expression for the indicated rows of a table, returning */ /* the results, cast as datatype (TSHORT, TDOUBLE, etc), in array. If */ /* nulval==NULL, UNDEFs will be zeroed out. For vector results, the number */ /* of elements returned may be less than nelements if nelements is not an */ /* even multiple of the result dimension. Call fftexp to obtain the */ /* dimensions of the results. */ /*---------------------------------------------------------------------------*/ { parseInfo Info; int naxis; long nelem1, naxes[MAXDIMS]; if( *status ) return( *status ); if( ffiprs( fptr, 0, expr, MAXDIMS, &Info.datatype, &nelem1, &naxis, naxes, status ) ) { ffcprs(); return( *status ); } if( nelem1<0 ) nelem1 = - nelem1; if( nelements1 ? firstrow : 1); if( datatype ) Info.datatype = datatype; Info.dataPtr = array; Info.nullPtr = nulval; Info.maxRows = nelements / nelem1; if( ffiter( gParse.nCols, gParse.colData, firstrow-1, 0, parse_data, (void*)&Info, status ) == -1 ) *status=0; /* -1 indicates exitted without error before end... OK */ *anynul = Info.anyNull; ffcprs(); return( *status ); } /*--------------------------------------------------------------------------*/ int ffcalc( fitsfile *infptr, /* I - Input FITS file */ char *expr, /* I - Arithmetic expression */ fitsfile *outfptr, /* I - Output fits file */ char *parName, /* I - Name of output parameter */ char *parInfo, /* I - Extra information on parameter */ int *status ) /* O - Error status */ /* */ /* Evaluate an expression for all rows of a table. Call ffcalc_rng with */ /* a row range of 1-MAX. */ { long start=1, end=LONG_MAX; return ffcalc_rng( infptr, expr, outfptr, parName, parInfo, 1, &start, &end, status ); } /*--------------------------------------------------------------------------*/ int ffcalc_rng( fitsfile *infptr, /* I - Input FITS file */ char *expr, /* I - Arithmetic expression */ fitsfile *outfptr, /* I - Output fits file */ char *parName, /* I - Name of output parameter */ char *parInfo, /* I - Extra information on parameter */ int nRngs, /* I - Row range info */ long *start, /* I - Row range info */ long *end, /* I - Row range info */ int *status ) /* O - Error status */ /* */ /* Evaluate an expression using the data in the input FITS file and place */ /* the results into either a column or keyword in the output fits file, */ /* depending on the value of parName (keywords normally prefixed with '#') */ /* and whether the expression evaluates to a constant or a table column. */ /* The logic is as follows: */ /* (1) If a column exists with name, parName, put results there. */ /* (2) If parName starts with '#', as in #NAXIS, put result there, */ /* with parInfo used as the comment. If expression does not evaluate */ /* to a constant, flag an error. */ /* (3) If a keyword exists with name, parName, and expression is a */ /* constant, put result there, using parInfo as the new comment. */ /* (4) Else, create a new column with name parName and TFORM parInfo. */ /* If parInfo is NULL, use a default data type for the column. */ /*--------------------------------------------------------------------------*/ { parseInfo Info; int naxis, constant, typecode, newNullKwd=0; long nelem, naxes[MAXDIMS], repeat, width; int col_cnt, colNo; Node *result; char card[81], tform[16], nullKwd[9], tdimKwd[9]; if( *status ) return( *status ); if( ffiprs( infptr, 0, expr, MAXDIMS, &Info.datatype, &nelem, &naxis, naxes, status ) ) { ffcprs(); return( *status ); } if( nelem<0 ) { constant = 1; nelem = -nelem; } else constant = 0; /* Case (1): If column exists put it there */ colNo = 0; if( ffgcno( outfptr, CASEINSEN, parName, &colNo, status )==COL_NOT_FOUND ) { /* Output column doesn't exist. Test for keyword. */ /* Case (2): Does parName indicate result should be put into keyword */ *status = 0; if( parName[0]=='#' ) { if( ! constant ) { ffcprs(); ffpmsg( "Cannot put tabular result into keyword (ffcalc)" ); return( *status = PARSE_BAD_TYPE ); } parName++; } else if( constant ) { /* Case (3): Does a keyword named parName already exist */ if( ffgcrd( outfptr, parName, card, status )==KEY_NO_EXIST ) { colNo = -1; } else if( *status ) { ffcprs(); return( *status ); } } else colNo = -1; if( colNo<0 ) { /* Case (4): Create new column */ *status = 0; ffgncl( outfptr, &colNo, status ); colNo++; if( parInfo==NULL || *parInfo=='\0' ) { /* Figure out best default column type */ if( gParse.hdutype==BINARY_TBL ) { sprintf(tform,"%ld",nelem); switch( Info.datatype ) { case TLOGICAL: strcat(tform,"L"); break; case TLONG: strcat(tform,"J"); break; case TDOUBLE: strcat(tform,"D"); break; case TSTRING: strcat(tform,"A"); break; case TBIT: strcat(tform,"X"); break; case TLONGLONG: strcat(tform,"K"); break; } } else { switch( Info.datatype ) { case TLOGICAL: ffcprs(); ffpmsg("Cannot create LOGICAL column in ASCII table"); return( *status = NOT_BTABLE ); break; case TLONG: strcpy(tform,"I11"); break; case TDOUBLE: strcpy(tform,"D23.15"); break; case TSTRING: case TBIT: sprintf(tform,"A%ld",nelem); break; } } parInfo = tform; } else if( !(isdigit((int) *parInfo)) && gParse.hdutype==BINARY_TBL ) { if( Info.datatype==TBIT && *parInfo=='B' ) nelem = (nelem+7)/8; sprintf(tform,"%ld%s",nelem,parInfo); parInfo = tform; } fficol( outfptr, colNo, parName, parInfo, status ); if( naxis>1 ) ffptdm( outfptr, colNo, naxis, naxes, status ); /* Setup TNULLn keyword in case NULLs are encountered */ ffkeyn("TNULL", colNo, nullKwd, status); if( ffgcrd( outfptr, nullKwd, card, status )==KEY_NO_EXIST ) { *status = 0; if( gParse.hdutype==BINARY_TBL ) { LONGLONG nullVal=0; fits_binary_tform( parInfo, &typecode, &repeat, &width, status ); if( typecode==TBYTE ) nullVal = UCHAR_MAX; else if( typecode==TSHORT ) nullVal = SHRT_MIN; else if( typecode==TINT ) nullVal = INT_MIN; else if( typecode==TLONG ) nullVal = LONG_MIN; else if( typecode==TLONGLONG ) nullVal = LONGLONG_MIN; if( nullVal ) { ffpkyj( outfptr, nullKwd, nullVal, "Null value", status ); fits_set_btblnull( outfptr, colNo, nullVal, status ); newNullKwd = 1; } } else if( gParse.hdutype==ASCII_TBL ) { ffpkys( outfptr, nullKwd, "NULL", "Null value string", status ); fits_set_atblnull( outfptr, colNo, "NULL", status ); newNullKwd = 1; } } } } else if( *status ) { ffcprs(); return( *status ); } else { /********************************************************/ /* Check if a TDIM keyword should be written/updated. */ /********************************************************/ ffkeyn("TDIM", colNo, tdimKwd, status); ffgcrd( outfptr, tdimKwd, card, status ); if( *status==0 ) { /* TDIM exists, so update it with result's dimension */ ffptdm( outfptr, colNo, naxis, naxes, status ); } else if( *status==KEY_NO_EXIST ) { /* TDIM does not exist, so clear error stack and */ /* write a TDIM only if result is multi-dimensional */ *status = 0; ffcmsg(); if( naxis>1 ) ffptdm( outfptr, colNo, naxis, naxes, status ); } if( *status ) { /* Either some other error happened in ffgcrd */ /* or one happened in ffptdm */ ffcprs(); return( *status ); } } if( colNo>0 ) { /* Output column exists (now)... put results into it */ int anyNull = 0; int nPerLp, i; long totaln; ffgkyj(infptr, "NAXIS2", &totaln, 0, status); /*************************************/ /* Create new iterator Output Column */ /*************************************/ col_cnt = gParse.nCols; if( allocateCol( col_cnt, status ) ) { ffcprs(); return( *status ); } fits_iter_set_by_num( gParse.colData+col_cnt, outfptr, colNo, 0, OutputCol ); gParse.nCols++; for( i=0; i= 10) && (nRngs == 1) && (start[0] == 1) && (end[0] == totaln)) nPerLp = 0; else nPerLp = Info.maxRows; if( ffiter( gParse.nCols, gParse.colData, start[i]-1, nPerLp, parse_data, (void*)&Info, status ) == -1 ) *status = 0; else if( *status ) { ffcprs(); return( *status ); } if( Info.anyNull ) anyNull = 1; } if( newNullKwd && !anyNull ) { ffdkey( outfptr, nullKwd, status ); } } else { /* Put constant result into keyword */ result = gParse.Nodes + gParse.resultNode; switch( Info.datatype ) { case TDOUBLE: ffukyd( outfptr, parName, result->value.data.dbl, 15, parInfo, status ); break; case TLONG: ffukyj( outfptr, parName, result->value.data.lng, parInfo, status ); break; case TLOGICAL: ffukyl( outfptr, parName, result->value.data.log, parInfo, status ); break; case TBIT: case TSTRING: ffukys( outfptr, parName, result->value.data.str, parInfo, status ); break; } } ffcprs(); return( *status ); } /*--------------------------------------------------------------------------*/ int fftexp( fitsfile *fptr, /* I - Input FITS file */ char *expr, /* I - Arithmetic expression */ int maxdim, /* I - Max Dimension of naxes */ int *datatype, /* O - Data type of result */ long *nelem, /* O - Vector length of result */ int *naxis, /* O - # of dimensions of result */ long *naxes, /* O - Size of each dimension */ int *status ) /* O - Error status */ /* */ /* Evaluate the given expression and return information on the result. */ /*--------------------------------------------------------------------------*/ { ffiprs( fptr, 0, expr, maxdim, datatype, nelem, naxis, naxes, status ); ffcprs(); return( *status ); } /*--------------------------------------------------------------------------*/ int ffiprs( fitsfile *fptr, /* I - Input FITS file */ int compressed, /* I - Is FITS file hkunexpanded? */ char *expr, /* I - Arithmetic expression */ int maxdim, /* I - Max Dimension of naxes */ int *datatype, /* O - Data type of result */ long *nelem, /* O - Vector length of result */ int *naxis, /* O - # of dimensions of result */ long *naxes, /* O - Size of each dimension */ int *status ) /* O - Error status */ /* */ /* Initialize the parser and determine what type of result the expression */ /* produces. */ /*--------------------------------------------------------------------------*/ { Node *result; int i,lexpr, tstatus = 0; int xaxis, bitpix; long xaxes[9]; static iteratorCol dmyCol; if( *status ) return( *status ); /* make sure all internal structures for this HDU are current */ if ( ffrdef(fptr, status) ) return(*status); /* Initialize the Parser structure */ gParse.def_fptr = fptr; gParse.compressed = compressed; gParse.nCols = 0; gParse.colData = NULL; gParse.varData = NULL; gParse.getData = find_column; gParse.loadData = load_column; gParse.Nodes = NULL; gParse.nNodesAlloc= 0; gParse.nNodes = 0; gParse.hdutype = 0; gParse.status = 0; fits_get_hdu_type(fptr, &gParse.hdutype, status ); if (gParse.hdutype == IMAGE_HDU) { fits_get_img_param(fptr, 9, &bitpix, &xaxis, xaxes, status); if (*status) { ffpmsg("ffiprs: unable to get image dimensions"); return( *status ); } gParse.totalRows = xaxis > 0 ? 1 : 0; for (i = 0; i < xaxis; ++i) gParse.totalRows *= xaxes[i]; if (DEBUG_PIXFILTER) printf("naxis=%d, gParse.totalRows=%ld\n", xaxis, gParse.totalRows); } else if( ffgkyj(fptr, "NAXIS2", &gParse.totalRows, 0, &tstatus) ) { /* this might be a 1D or null image with no NAXIS2 keyword */ gParse.totalRows = 0; } /* Copy expression into parser... read from file if necessary */ if( expr[0]=='@' ) { if( ffimport_file( expr+1, &gParse.expr, status ) ) return( *status ); lexpr = strlen(gParse.expr); } else { lexpr = strlen(expr); gParse.expr = (char*)malloc( (2+lexpr)*sizeof(char)); strcpy(gParse.expr,expr); } strcat(gParse.expr + lexpr,"\n"); gParse.index = 0; gParse.is_eobuf = 0; /* Parse the expression, building the Nodes and determing */ /* which columns are needed and what data type is returned */ ffrestart(NULL); if( ffparse() ) { return( *status = PARSE_SYNTAX_ERR ); } /* Check results */ *status = gParse.status; if( *status ) return(*status); if( !gParse.nNodes ) { ffpmsg("Blank expression"); return( *status = PARSE_SYNTAX_ERR ); } if( !gParse.nCols ) { dmyCol.fptr = fptr; /* This allows iterator to know value of */ gParse.colData = &dmyCol; /* fptr when no columns are referenced */ } result = gParse.Nodes + gParse.resultNode; *naxis = result->value.naxis; *nelem = result->value.nelem; for( i=0; i<*naxis && ivalue.naxes[i]; switch( result->type ) { case BOOLEAN: *datatype = TLOGICAL; break; case LONG: *datatype = TLONG; break; case DOUBLE: *datatype = TDOUBLE; break; case BITSTR: *datatype = TBIT; break; case STRING: *datatype = TSTRING; break; default: *datatype = 0; ffpmsg("Bad return data type"); *status = gParse.status = PARSE_BAD_TYPE; break; } gParse.datatype = *datatype; FREE(gParse.expr); if( result->operation==CONST_OP ) *nelem = - *nelem; return(*status); } /*--------------------------------------------------------------------------*/ void ffcprs( void ) /* No parameters */ /* */ /* Clear the parser, making it ready to accept a new expression. */ /*--------------------------------------------------------------------------*/ { int col, node, i; if( gParse.nCols > 0 ) { FREE( gParse.colData ); for( col=0; col 0 ) { node = gParse.nNodes; while( node-- ) { if( gParse.Nodes[node].operation==gtifilt_fct ) { i = gParse.Nodes[node].SubNodes[0]; FREE( gParse.Nodes[ i ].value.data.ptr ); } else if( gParse.Nodes[node].operation==regfilt_fct ) { i = gParse.Nodes[node].SubNodes[0]; fits_free_region( (SAORegion *)gParse.Nodes[ i ].value.data.ptr ); } } gParse.nNodes = 0; } if( gParse.Nodes ) free( gParse.Nodes ); gParse.Nodes = NULL; gParse.hdutype = ANY_HDU; gParse.pixFilter = 0; } /*---------------------------------------------------------------------------*/ int parse_data( long totalrows, /* I - Total rows to be processed */ long offset, /* I - Number of rows skipped at start*/ long firstrow, /* I - First row of this iteration */ long nrows, /* I - Number of rows in this iter */ int nCols, /* I - Number of columns in use */ iteratorCol *colData, /* IO- Column information/data */ void *userPtr ) /* I - Data handling instructions */ /* */ /* Iterator work function which calls the parser and copies the results */ /* into either an OutputCol or a data pointer supplied in the userPtr */ /* structure. */ /*---------------------------------------------------------------------------*/ { int status, constant=0, anyNullThisTime=0; long jj, kk, idx, remain, ntodo; Node *result; iteratorCol * outcol; /* declare variables static to preserve their values between calls */ static void *Data, *Null; static int datasize; static long lastRow, repeat, resDataSize; LONGLONG jnull; static parseInfo *userInfo; static long zeros[4] = {0,0,0,0}; if (DEBUG_PIXFILTER) printf("parse_data(total=%ld, offset=%ld, first=%ld, rows=%ld, cols=%d)\n", totalrows, offset, firstrow, nrows, nCols); /*--------------------------------------------------------*/ /* Initialization procedures: execute on the first call */ /*--------------------------------------------------------*/ outcol = colData + (nCols - 1); if (firstrow == offset+1) { userInfo = (parseInfo*)userPtr; userInfo->anyNull = 0; if( userInfo->maxRows>0 ) userInfo->maxRows = minvalue(totalrows,userInfo->maxRows); else if( userInfo->maxRows<0 ) userInfo->maxRows = totalrows; else userInfo->maxRows = nrows; lastRow = firstrow + userInfo->maxRows - 1; if( userInfo->dataPtr==NULL ) { if( outcol->iotype == InputCol ) { ffpmsg("Output column for parser results not found!"); return( PARSE_NO_OUTPUT ); } /* Data gets set later */ Null = outcol->array; userInfo->datatype = outcol->datatype; /* Check for a TNULL/BLANK keyword for output column/image */ status = 0; jnull = 0; if (gParse.hdutype == IMAGE_HDU) { if (gParse.pixFilter->blank) jnull = (LONGLONG) gParse.pixFilter->blank; } else { ffgknjj( outcol->fptr, "TNULL", outcol->colnum, 1, &jnull, (int*)&jj, &status ); if( status==BAD_INTKEY ) { /* Probably ASCII table with text TNULL keyword */ switch( userInfo->datatype ) { case TSHORT: jnull = (LONGLONG) SHRT_MIN; break; case TINT: jnull = (LONGLONG) INT_MIN; break; case TLONG: jnull = (LONGLONG) LONG_MIN; break; } } } repeat = outcol->repeat; if (DEBUG_PIXFILTER) printf("using null value %ld\n", jnull); } else { Data = userInfo->dataPtr; Null = (userInfo->nullPtr ? userInfo->nullPtr : zeros); repeat = gParse.Nodes[gParse.resultNode].value.nelem; } /* Determine the size of each element of the returned result */ switch( userInfo->datatype ) { case TBIT: /* Fall through to TBYTE */ case TLOGICAL: /* Fall through to TBYTE */ case TBYTE: datasize = sizeof(char); break; case TSHORT: datasize = sizeof(short); break; case TINT: datasize = sizeof(int); break; case TLONG: datasize = sizeof(long); break; case TLONGLONG: datasize = sizeof(LONGLONG); break; case TFLOAT: datasize = sizeof(float); break; case TDOUBLE: datasize = sizeof(double); break; case TSTRING: datasize = sizeof(char*); break; } /* Determine the size of each element of the calculated result */ /* (only matters for numeric/logical data) */ switch( gParse.Nodes[gParse.resultNode].type ) { case BOOLEAN: resDataSize = sizeof(char); break; case LONG: resDataSize = sizeof(long); break; case DOUBLE: resDataSize = sizeof(double); break; } } /*-------------------------------------------*/ /* Main loop: process all the rows of data */ /*-------------------------------------------*/ /* If writing to output column, set first element to appropriate */ /* null value. If no NULLs encounter, zero out before returning. */ if( userInfo->dataPtr == NULL ) { /* First, reset Data pointer to start of output array */ Data = (char*) outcol->array + datasize; switch( userInfo->datatype ) { case TLOGICAL: *(char *)Null = 'U'; break; case TBYTE: *(char *)Null = (char )jnull; break; case TSHORT: *(short *)Null = (short)jnull; break; case TINT: *(int *)Null = (int )jnull; break; case TLONG: *(long *)Null = (long )jnull; break; case TLONGLONG: *(LONGLONG *)Null = (LONGLONG )jnull; break; case TFLOAT: *(float *)Null = FLOATNULLVALUE; break; case TDOUBLE: *(double*)Null = DOUBLENULLVALUE; break; case TSTRING: (*(char **)Null)[0] = '\1'; (*(char **)Null)[1] = '\0'; break; } } /* Alter nrows in case calling routine didn't want to do all rows */ nrows = minvalue(nrows,lastRow-firstrow+1); Setup_DataArrays( nCols, colData, firstrow, nrows ); /* Parser allocates arrays for each column and calculation it performs. */ /* Limit number of rows processed during each pass to reduce memory */ /* requirements... In most cases, iterator will limit rows to less */ /* than 2500 rows per iteration, so this is really only relevant for */ /* hk-compressed files which must be decompressed in memory and sent */ /* whole to parse_data in a single iteration. */ remain = nrows; while( remain ) { ntodo = minvalue(remain,2500); Evaluate_Parser ( firstrow, ntodo ); if( gParse.status ) break; firstrow += ntodo; remain -= ntodo; /* Copy results into data array */ result = gParse.Nodes + gParse.resultNode; if( result->operation==CONST_OP ) constant = 1; switch( result->type ) { case BOOLEAN: case LONG: case DOUBLE: if( constant ) { char undef=0; for( kk=0; kkvalue.data), &undef, result->value.nelem /* 1 */, userInfo->datatype, Null, (char*)Data + (kk*repeat+jj)*datasize, &anyNullThisTime, &gParse.status ); } else { if ( repeat == result->value.nelem ) { ffcvtn( gParse.datatype, result->value.data.ptr, result->value.undef, result->value.nelem*ntodo, userInfo->datatype, Null, Data, &anyNullThisTime, &gParse.status ); } else if( result->value.nelem == 1 ) { for( kk=0; kkvalue.data.ptr + kk*resDataSize, (char*)result->value.undef + kk, 1, userInfo->datatype, Null, (char*)Data + (kk*repeat+jj)*datasize, &anyNullThisTime, &gParse.status ); } } else { int nCopy; nCopy = minvalue( repeat, result->value.nelem ); for( kk=0; kkvalue.data.ptr + kk*result->value.nelem*resDataSize, (char*)result->value.undef + kk*result->value.nelem, nCopy, userInfo->datatype, Null, (char*)Data + (kk*repeat)*datasize, &anyNullThisTime, &gParse.status ); if( nCopy < repeat ) { memset( (char*)Data + (kk*repeat+nCopy)*datasize, 0, (repeat-nCopy)*datasize); } } } if( result->operation>0 ) { FREE( result->value.data.ptr ); } } if( gParse.status==OVERFLOW_ERR ) { gParse.status = NUM_OVERFLOW; ffpmsg("Numerical overflow while converting expression to necessary datatype"); } break; case BITSTR: switch( userInfo->datatype ) { case TBYTE: idx = -1; for( kk=0; kkvalue.nelem; jj++ ) { if( jj%8 == 0 ) ((char*)Data)[++idx] = 0; if( constant ) { if( result->value.data.str[jj]=='1' ) ((char*)Data)[idx] |= 128>>(jj%8); } else { if( result->value.data.strptr[kk][jj]=='1' ) ((char*)Data)[idx] |= 128>>(jj%8); } } } break; case TBIT: case TLOGICAL: if( constant ) { for( kk=0; kkvalue.nelem; jj++ ) { ((char*)Data)[ jj+kk*result->value.nelem ] = ( result->value.data.str[jj]=='1' ); } } else { for( kk=0; kkvalue.nelem; jj++ ) { ((char*)Data)[ jj+kk*result->value.nelem ] = ( result->value.data.strptr[kk][jj]=='1' ); } } break; case TSTRING: if( constant ) { for( jj=0; jjvalue.data.str ); } } else { for( jj=0; jjvalue.data.strptr[jj] ); } } break; default: ffpmsg("Cannot convert bit expression to desired type."); gParse.status = PARSE_BAD_TYPE; break; } if( result->operation>0 ) { FREE( result->value.data.strptr[0] ); FREE( result->value.data.strptr ); } break; case STRING: if( userInfo->datatype==TSTRING ) { if( constant ) { for( jj=0; jjvalue.data.str ); } else { for( jj=0; jjvalue.undef[jj] ) { anyNullThisTime = 1; strcpy( ((char**)Data)[jj], *(char **)Null ); } else { strcpy( ((char**)Data)[jj], result->value.data.strptr[jj] ); } } } else { ffpmsg("Cannot convert string expression to desired type."); gParse.status = PARSE_BAD_TYPE; } if( result->operation>0 ) { FREE( result->value.data.strptr[0] ); FREE( result->value.data.strptr ); } break; } if( gParse.status ) break; /* Increment Data to point to where the next block should go */ if( result->type==BITSTR && userInfo->datatype==TBYTE ) Data = (char*)Data + datasize * ( (result->value.nelem+7)/8 ) * ntodo; else if( result->type==STRING ) Data = (char*)Data + datasize * ntodo; else Data = (char*)Data + datasize * ntodo * repeat; } /* If no NULLs encountered during this pass, set Null value to */ /* zero to make the writing of the output column data faster */ if( anyNullThisTime ) userInfo->anyNull = 1; else if( userInfo->dataPtr == NULL ) { if( userInfo->datatype == TSTRING ) memcpy( *(char **)Null, zeros, 2 ); else memcpy( Null, zeros, datasize ); } /*-------------------------------------------------------*/ /* Clean up procedures: after processing all the rows */ /*-------------------------------------------------------*/ /* if the calling routine specified that only a limited number */ /* of rows in the table should be processed, return a value of -1 */ /* once all the rows have been done, if no other error occurred. */ if (gParse.hdutype != IMAGE_HDU && firstrow - 1 == lastRow) { if (!gParse.status && userInfo->maxRowsiotype == OutputCol ) continue; nelem = varData->nelem; len = nelem * nRows; switch ( varData->type ) { case BITSTR: /* No need for UNDEF array, but must make string DATA array */ len = (nelem+1)*nRows; /* Count '\0' */ bitStrs = (char**)varData->data; if( bitStrs ) FREE( bitStrs[0] ); free( bitStrs ); bitStrs = (char**)malloc( nRows*sizeof(char*) ); if( bitStrs==NULL ) { varData->data = varData->undef = NULL; gParse.status = MEMORY_ALLOCATION; break; } bitStrs[0] = (char*)malloc( len*sizeof(char) ); if( bitStrs[0]==NULL ) { free( bitStrs ); varData->data = varData->undef = NULL; gParse.status = MEMORY_ALLOCATION; break; } for( row=0; rowarray)[idx] & (1<<(7-len%8)) ) bitStrs[row][len] = '1'; else bitStrs[row][len] = '0'; if( len%8==7 ) idx++; } bitStrs[row][len] = '\0'; } varData->undef = (char*)bitStrs; varData->data = (char*)bitStrs; break; case STRING: sptr = (char**)icol->array; if (varData->undef) free( varData->undef ); varData->undef = (char*)malloc( nRows*sizeof(char) ); if( varData->undef==NULL ) { gParse.status = MEMORY_ALLOCATION; break; } row = nRows; while( row-- ) varData->undef[row] = ( **sptr != '\0' && FSTRCMP( sptr[0], sptr[row+1] )==0 ); varData->data = sptr + 1; break; case BOOLEAN: barray = (char*)icol->array; if (varData->undef) free( varData->undef ); varData->undef = (char*)malloc( len*sizeof(char) ); if( varData->undef==NULL ) { gParse.status = MEMORY_ALLOCATION; break; } while( len-- ) { varData->undef[len] = ( barray[0]!=0 && barray[0]==barray[len+1] ); } varData->data = barray + 1; break; case LONG: iarray = (long*)icol->array; if (varData->undef) free( varData->undef ); varData->undef = (char*)malloc( len*sizeof(char) ); if( varData->undef==NULL ) { gParse.status = MEMORY_ALLOCATION; break; } while( len-- ) { varData->undef[len] = ( iarray[0]!=0L && iarray[0]==iarray[len+1] ); } varData->data = iarray + 1; break; case DOUBLE: rarray = (double*)icol->array; if (varData->undef) free( varData->undef ); varData->undef = (char*)malloc( len*sizeof(char) ); if( varData->undef==NULL ) { gParse.status = MEMORY_ALLOCATION; break; } while( len-- ) { varData->undef[len] = ( rarray[0]!=0.0 && rarray[0]==rarray[len+1]); } varData->data = rarray + 1; break; default: sprintf(msg, "SetupDataArrays, unhandled type %d\n", varData->type); ffpmsg(msg); } if( gParse.status ) { /* Deallocate NULL arrays of previous columns */ while( i-- ) { varData = gParse.varData + i; if( varData->type==BITSTR ) FREE( ((char**)varData->data)[0] ); FREE( varData->undef ); varData->undef = NULL; } return; } } } /*--------------------------------------------------------------------------*/ int ffcvtn( int inputType, /* I - Data type of input array */ void *input, /* I - Input array of type inputType */ char *undef, /* I - Array of flags indicating UNDEF elems */ long ntodo, /* I - Number of elements to process */ int outputType, /* I - Data type of output array */ void *nulval, /* I - Ptr to value to use for UNDEF elements */ void *output, /* O - Output array of type outputType */ int *anynull, /* O - Any nulls flagged? */ int *status ) /* O - Error status */ /* */ /* Convert an array of any input data type to an array of any output */ /* data type, using an array of UNDEF flags to assign nulvals to */ /*--------------------------------------------------------------------------*/ { long i; switch( outputType ) { case TLOGICAL: switch( inputType ) { case TLOGICAL: case TBYTE: for( i=0; i UCHAR_MAX ) { *status = OVERFLOW_ERR; ((unsigned char*)output)[i] = UCHAR_MAX; } else ((unsigned char*)output)[i] = (unsigned char) ((long*)input)[i]; } } return( *status ); break; case TFLOAT: fffr4i1((float*)input,ntodo,1.,0.,0,0,NULL,NULL, (unsigned char*)output,status); break; case TDOUBLE: fffr8i1((double*)input,ntodo,1.,0.,0,0,NULL,NULL, (unsigned char*)output,status); break; default: *status = BAD_DATATYPE; break; } for(i=0;i SHRT_MAX ) { *status = OVERFLOW_ERR; ((short*)output)[i] = SHRT_MAX; } else ((short*)output)[i] = (short) ((long*)input)[i]; } } return( *status ); break; case TFLOAT: fffr4i2((float*)input,ntodo,1.,0.,0,0,NULL,NULL, (short*)output,status); break; case TDOUBLE: fffr8i2((double*)input,ntodo,1.,0.,0,0,NULL,NULL, (short*)output,status); break; default: *status = BAD_DATATYPE; break; } for(i=0;i=0 ) { found[parNo] = 1; /* Flag this parameter as found */ switch( gParse.colData[parNo].datatype ) { case TLONG: ffgcvj( fptr, gParse.valCol, row, 1L, 1L, ((long*)gParse.colData[parNo].array)[0], ((long*)gParse.colData[parNo].array)+currelem, &anynul, status ); break; case TDOUBLE: ffgcvd( fptr, gParse.valCol, row, 1L, 1L, ((double*)gParse.colData[parNo].array)[0], ((double*)gParse.colData[parNo].array)+currelem, &anynul, status ); break; case TSTRING: ffgcvs( fptr, gParse.valCol, row, 1L, 1L, ((char**)gParse.colData[parNo].array)[0], ((char**)gParse.colData[parNo].array)+currelem, &anynul, status ); break; } if( *status ) return( *status ); } } if( currelemoperation==CONST_OP ) { if( result->value.data.log ) { *(long*)userPtr = firstrow; return( -1 ); } } else { for( idx=0; idxvalue.data.logptr[idx] && !result->value.undef[idx] ) { *(long*)userPtr = firstrow + idx; return( -1 ); } } } return( gParse.status ); } static int set_image_col_types (fitsfile * fptr, const char * name, int bitpix, DataInfo * varInfo, iteratorCol *colIter) { int istatus; double tscale, tzero; char temp[80]; switch (bitpix) { case BYTE_IMG: case SHORT_IMG: case LONG_IMG: istatus = 0; if (fits_read_key(fptr, TDOUBLE, "BZERO", &tzero, NULL, &istatus)) tzero = 0.0; istatus = 0; if (fits_read_key(fptr, TDOUBLE, "BSCALE", &tscale, NULL, &istatus)) tscale = 1.0; if (tscale == 1.0 && (tzero == 0.0 || tzero == 32768.0 )) { varInfo->type = LONG; colIter->datatype = TLONG; } else { varInfo->type = DOUBLE; colIter->datatype = TDOUBLE; if (DEBUG_PIXFILTER) printf("use DOUBLE for %s with BSCALE=%g/BZERO=%g\n", name, tscale, tzero); } break; case LONGLONG_IMG: case FLOAT_IMG: case DOUBLE_IMG: varInfo->type = DOUBLE; colIter->datatype = TDOUBLE; break; default: sprintf(temp, "set_image_col_types: unrecognized image bitpix [%d]\n", bitpix); ffpmsg(temp); return gParse.status = PARSE_BAD_TYPE; } return 0; } /************************************************************************* Functions used by the evaluator to access FITS data (find_column, find_keywd, allocateCol, load_column) *************************************************************************/ static int find_column( char *colName, void *itslval ) { FFSTYPE *thelval = (FFSTYPE*)itslval; int col_cnt, status; int colnum, typecode, type; long repeat, width; fitsfile *fptr; char temp[80]; double tzero,tscale; int istatus; DataInfo *varInfo; iteratorCol *colIter; if (DEBUG_PIXFILTER) printf("find_column(%s)\n", colName); if( *colName == '#' ) return( find_keywd( colName + 1, itslval ) ); fptr = gParse.def_fptr; status = 0; col_cnt = gParse.nCols; if (gParse.hdutype == IMAGE_HDU) { int i; if (!gParse.pixFilter) { gParse.status = COL_NOT_FOUND; ffpmsg("find_column: IMAGE_HDU but no PixelFilter"); return pERROR; } colnum = -1; for (i = 0; i < gParse.pixFilter->count; ++i) { if (!strcasecmp(colName, gParse.pixFilter->tag[i])) colnum = i; } if (colnum < 0) { sprintf(temp, "find_column: PixelFilter tag %s not found", colName); ffpmsg(temp); gParse.status = COL_NOT_FOUND; return pERROR; } if( allocateCol( col_cnt, &gParse.status ) ) return pERROR; varInfo = gParse.varData + col_cnt; colIter = gParse.colData + col_cnt; fptr = gParse.pixFilter->ifptr[colnum]; fits_get_img_param(fptr, MAXDIMS, &typecode, /* actually bitpix */ &varInfo->naxis, &varInfo->naxes[0], &status); varInfo->nelem = 1; type = COLUMN; if (set_image_col_types(fptr, colName, typecode, varInfo, colIter)) return pERROR; colIter->fptr = fptr; colIter->iotype = InputCol; } else { /* HDU holds a table */ if( gParse.compressed ) colnum = gParse.valCol; else if( fits_get_colnum( fptr, CASEINSEN, colName, &colnum, &status ) ) { if( status == COL_NOT_FOUND ) { type = find_keywd( colName, itslval ); if( type != pERROR ) ffcmsg(); return( type ); } gParse.status = status; return pERROR; } if( fits_get_coltype( fptr, colnum, &typecode, &repeat, &width, &status ) ) { gParse.status = status; return pERROR; } if( allocateCol( col_cnt, &gParse.status ) ) return pERROR; varInfo = gParse.varData + col_cnt; colIter = gParse.colData + col_cnt; fits_iter_set_by_num( colIter, fptr, colnum, 0, InputCol ); } /* Make sure we don't overflow variable name array */ strncpy(varInfo->name,colName,MAXVARNAME); varInfo->name[MAXVARNAME] = '\0'; if (gParse.hdutype != IMAGE_HDU) { switch( typecode ) { case TBIT: varInfo->type = BITSTR; colIter->datatype = TBYTE; type = BITCOL; break; case TBYTE: case TSHORT: case TLONG: /* The datatype of column with TZERO and TSCALE keywords might be float or double. */ sprintf(temp,"TZERO%d",colnum); istatus = 0; if(fits_read_key(fptr,TDOUBLE,temp,&tzero,NULL,&istatus)) { tzero = 0.0; } sprintf(temp,"TSCAL%d",colnum); istatus = 0; if(fits_read_key(fptr,TDOUBLE,temp,&tscale,NULL,&istatus)) { tscale = 1.0; } if (tscale == 1.0 && (tzero == 0.0 || tzero == 32768.0 )) { varInfo->type = LONG; colIter->datatype = TLONG; /* Reading an unsigned long column as a long can cause overflow errors. Treat the column as a double instead. } else if (tscale == 1.0 && tzero == 2147483648.0 ) { varInfo->type = LONG; colIter->datatype = TULONG; */ } else { varInfo->type = DOUBLE; colIter->datatype = TDOUBLE; } type = COLUMN; break; /* For now, treat 8-byte integer columns as type double. This can lose precision, so the better long term solution will be to add support for TLONGLONG as a separate datatype. */ case TLONGLONG: case TFLOAT: case TDOUBLE: varInfo->type = DOUBLE; colIter->datatype = TDOUBLE; type = COLUMN; break; case TLOGICAL: varInfo->type = BOOLEAN; colIter->datatype = TLOGICAL; type = BCOLUMN; break; case TSTRING: varInfo->type = STRING; colIter->datatype = TSTRING; type = SCOLUMN; if( gParse.hdutype == ASCII_TBL ) repeat = width; break; default: if (typecode < 0) { sprintf(temp, "variable-length array columns are not supported. typecode = %d", typecode); ffpmsg(temp); } gParse.status = PARSE_BAD_TYPE; return pERROR; } varInfo->nelem = repeat; if( repeat>1 && typecode!=TSTRING ) { if( fits_read_tdim( fptr, colnum, MAXDIMS, &varInfo->naxis, &varInfo->naxes[0], &status ) ) { gParse.status = status; return pERROR; } } else { varInfo->naxis = 1; varInfo->naxes[0] = 1; } } gParse.nCols++; thelval->lng = col_cnt; return( type ); } static int find_keywd(char *keyname, void *itslval ) { FFSTYPE *thelval = (FFSTYPE*)itslval; int status, type; char keyvalue[FLEN_VALUE], dtype; fitsfile *fptr; double rval; int bval; long ival; status = 0; fptr = gParse.def_fptr; if( fits_read_keyword( fptr, keyname, keyvalue, NULL, &status ) ) { if( status == KEY_NO_EXIST ) { /* Do this since ffgkey doesn't put an error message on stack */ sprintf(keyvalue, "ffgkey could not find keyword: %s",keyname); ffpmsg(keyvalue); } gParse.status = status; return( pERROR ); } if( fits_get_keytype( keyvalue, &dtype, &status ) ) { gParse.status = status; return( pERROR ); } switch( dtype ) { case 'C': fits_read_key_str( fptr, keyname, keyvalue, NULL, &status ); type = STRING; strcpy( thelval->str , keyvalue ); break; case 'L': fits_read_key_log( fptr, keyname, &bval, NULL, &status ); type = BOOLEAN; thelval->log = bval; break; case 'I': fits_read_key_lng( fptr, keyname, &ival, NULL, &status ); type = LONG; thelval->lng = ival; break; case 'F': fits_read_key_dbl( fptr, keyname, &rval, NULL, &status ); type = DOUBLE; thelval->dbl = rval; break; default: type = pERROR; break; } if( status ) { gParse.status=status; return pERROR; } return( type ); } static int allocateCol( int nCol, int *status ) { if( (nCol%25)==0 ) { if( nCol ) { gParse.colData = (iteratorCol*) realloc( gParse.colData, (nCol+25)*sizeof(iteratorCol) ); gParse.varData = (DataInfo *) realloc( gParse.varData, (nCol+25)*sizeof(DataInfo) ); } else { gParse.colData = (iteratorCol*) malloc( 25*sizeof(iteratorCol) ); gParse.varData = (DataInfo *) malloc( 25*sizeof(DataInfo) ); } if( gParse.colData == NULL || gParse.varData == NULL ) { if( gParse.colData ) free(gParse.colData); if( gParse.varData ) free(gParse.varData); gParse.colData = NULL; gParse.varData = NULL; return( *status = MEMORY_ALLOCATION ); } } gParse.varData[nCol].data = NULL; gParse.varData[nCol].undef = NULL; return 0; } static int load_column( int varNum, long fRow, long nRows, void *data, char *undef ) { iteratorCol *var = gParse.colData+varNum; long nelem,nbytes,row,len,idx; char **bitStrs, msg[80]; unsigned char *bytes; int status = 0, anynul; if (gParse.hdutype == IMAGE_HDU) { /* This test would need to be on a per varNum basis to support * cross HDU operations */ fits_read_imgnull(var->fptr, var->datatype, fRow, nRows, data, undef, &anynul, &status); if (DEBUG_PIXFILTER) printf("load_column: IMAGE_HDU fRow=%ld, nRows=%ld => %d\n", fRow, nRows, status); } else { nelem = nRows * var->repeat; switch( var->datatype ) { case TBYTE: nbytes = ((var->repeat+7)/8) * nRows; bytes = (unsigned char *)malloc( nbytes * sizeof(char) ); ffgcvb(var->fptr, var->colnum, fRow, 1L, nbytes, 0, bytes, &anynul, &status); nelem = var->repeat; bitStrs = (char **)data; for( row=0; rowfptr, var->colnum, fRow, 1L, nRows, (char **)data, undef, &anynul, &status); break; case TLOGICAL: ffgcfl(var->fptr, var->colnum, fRow, 1L, nelem, (char *)data, undef, &anynul, &status); break; case TLONG: ffgcfj(var->fptr, var->colnum, fRow, 1L, nelem, (long *)data, undef, &anynul, &status); break; case TDOUBLE: ffgcfd(var->fptr, var->colnum, fRow, 1L, nelem, (double *)data, undef, &anynul, &status); break; default: sprintf(msg,"load_column: unexpected datatype %d", var->datatype); ffpmsg(msg); } } if( status ) { gParse.status = status; return pERROR; } return 0; } /*--------------------------------------------------------------------------*/ int fits_pixel_filter (PixelFilter * filter, int * status) /* Evaluate an expression using the data in the input FITS file(s) */ /*--------------------------------------------------------------------------*/ { parseInfo Info = { 0 }; int naxis, constant, bitpix; long nelem, naxes[MAXDIMS]; int col_cnt; Node *result; int datatype; fitsfile * infptr; fitsfile * outfptr; char * DEFAULT_TAGS[] = { "X" }; char msg[256]; int writeBlankKwd = 0; /* write BLANK if any output nulls? */ DEBUG_PIXFILTER = getenv("DEBUG_PIXFILTER") ? 1 : 0; if (*status) return (*status); if (!filter->tag || !filter->tag[0] || !filter->tag[0][0]) { filter->tag = DEFAULT_TAGS; if (DEBUG_PIXFILTER) printf("using default tag '%s'\n", filter->tag[0]); } infptr = filter->ifptr[0]; outfptr = filter->ofptr; gParse.pixFilter = filter; if (ffiprs(infptr, 0, filter->expression, MAXDIMS, &Info.datatype, &nelem, &naxis, naxes, status)) { goto CLEANUP; } if (nelem < 0) { constant = 1; nelem = -nelem; } else constant = 0; { /* validate result type */ const char * type = 0; switch (Info.datatype) { case TLOGICAL: type = "LOGICAL"; break; case TLONG: type = "LONG"; break; case TDOUBLE: type = "DOUBLE"; break; case TSTRING: type = "STRING"; *status = pERROR; ffpmsg("pixel_filter: cannot have string image"); case TBIT: type = "BIT"; if (DEBUG_PIXFILTER) printf("hmm, image from bits?\n"); break; default: type = "UNKNOWN?!"; *status = pERROR; ffpmsg("pixel_filter: unexpected result datatype"); } if (DEBUG_PIXFILTER) printf("result type is %s [%d]\n", type, Info.datatype); if (*status) goto CLEANUP; } if (fits_get_img_param(infptr, MAXDIMS, &bitpix, &naxis, &naxes[0], status)) { ffpmsg("pixel_filter: unable to read input image parameters"); goto CLEANUP; } if (DEBUG_PIXFILTER) printf("input bitpix %d\n", bitpix); if (Info.datatype == TDOUBLE) { /* for floating point expressions, set the default output image to bitpix = -32 (float) unless the default is already a double */ if (bitpix != DOUBLE_IMG) bitpix = FLOAT_IMG; } /* override output image bitpix if specified by caller */ if (filter->bitpix) bitpix = filter->bitpix; if (DEBUG_PIXFILTER) printf("output bitpix %d\n", bitpix); if (fits_create_img(outfptr, bitpix, naxis, naxes, status)) { ffpmsg("pixel_filter: unable to create output image"); goto CLEANUP; } /* transfer keycards */ { int i, ncards, more; if (fits_get_hdrspace(infptr, &ncards, &more, status)) { ffpmsg("pixel_filter: unable to determine number of keycards"); goto CLEANUP; } for (i = 1; i <= ncards; ++i) { int keyclass; char card[FLEN_CARD]; if (fits_read_record(infptr, i, card, status)) { sprintf(msg, "pixel_filter: unable to read keycard %d", i); ffpmsg(msg); goto CLEANUP; } keyclass = fits_get_keyclass(card); if (keyclass == TYP_STRUC_KEY) { /* output structure defined by fits_create_img */ } else if (keyclass == TYP_COMM_KEY && i < 12) { /* assume this is one of the FITS standard comments */ } else if (keyclass == TYP_NULL_KEY && bitpix < 0) { /* do not transfer BLANK to real output image */ } else if (keyclass == TYP_SCAL_KEY && bitpix < 0) { /* do not transfer BZERO, BSCALE to real output image */ } else if (fits_write_record(outfptr, card, status)) { sprintf(msg, "pixel_filter: unable to write keycard '%s' [%d]\n", card, *status); ffpmsg(msg); goto CLEANUP; } } } switch (bitpix) { case BYTE_IMG: datatype = TLONG; Info.datatype = TBYTE; break; case SHORT_IMG: datatype = TLONG; Info.datatype = TSHORT; break; case LONG_IMG: datatype = TLONG; Info.datatype = TLONG; break; case FLOAT_IMG: datatype = TDOUBLE; Info.datatype = TFLOAT; break; case DOUBLE_IMG: datatype = TDOUBLE; Info.datatype = TDOUBLE; break; default: sprintf(msg, "pixel_filter: unexpected output bitpix %d\n", bitpix); ffpmsg(msg); *status = pERROR; goto CLEANUP; } if (bitpix > 0) { /* arrange for NULLs in output */ long nullVal = filter->blank; if (!filter->blank) { int tstatus = 0; if (fits_read_key_lng(infptr, "BLANK", &nullVal, 0, &tstatus)) { writeBlankKwd = 1; if (bitpix == BYTE_IMG) nullVal = UCHAR_MAX; else if (bitpix == SHORT_IMG) nullVal = SHRT_MIN; else if (bitpix == LONG_IMG) nullVal = LONG_MIN; else printf("unhandled positive output BITPIX %d\n", bitpix); } filter->blank = nullVal; } fits_set_imgnull(outfptr, filter->blank, status); if (DEBUG_PIXFILTER) printf("using blank %ld\n", nullVal); } if (!filter->keyword[0]) { iteratorCol * colIter; DataInfo * varInfo; /*************************************/ /* Create new iterator Output Column */ /*************************************/ col_cnt = gParse.nCols; if (allocateCol(col_cnt, status)) goto CLEANUP; gParse.nCols++; colIter = &gParse.colData[col_cnt]; colIter->fptr = filter->ofptr; colIter->iotype = OutputCol; varInfo = &gParse.varData[col_cnt]; set_image_col_types(colIter->fptr, "CREATED", bitpix, varInfo, colIter); Info.maxRows = -1; if (ffiter(gParse.nCols, gParse.colData, 0, 0, parse_data, &Info, status) == -1) *status = 0; else if (*status) goto CLEANUP; if (Info.anyNull) { if (writeBlankKwd) { fits_update_key_lng(outfptr, "BLANK", filter->blank, "NULL pixel value", status); if (*status) ffpmsg("pixel_filter: unable to write BLANK keyword"); if (DEBUG_PIXFILTER) { printf("output has NULLs\n"); printf("wrote blank [%d]\n", *status); } } } else if (bitpix > 0) /* never used a null */ if (fits_set_imgnull(outfptr, -1234554321, status)) ffpmsg("pixel_filter: unable to reset imgnull"); } else { /* Put constant result into keyword */ char * parName = filter->keyword; char * parInfo = filter->comment; result = gParse.Nodes + gParse.resultNode; switch (Info.datatype) { case TDOUBLE: ffukyd(outfptr, parName, result->value.data.dbl, 15, parInfo, status); break; case TLONG: ffukyj(outfptr, parName, result->value.data.lng, parInfo, status); break; case TLOGICAL: ffukyl(outfptr, parName, result->value.data.log, parInfo, status); break; case TBIT: case TSTRING: ffukys(outfptr, parName, result->value.data.str, parInfo, status); break; default: sprintf(msg, "pixel_filter: unexpected constant result type [%d]\n", Info.datatype); ffpmsg(msg); } } CLEANUP: ffcprs(); return (*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/eval_l.c000066400000000000000000001644131215713201500220470ustar00rootroot00000000000000/* A lexical scanner generated by flex */ /* Scanner skeleton version: * $Header: /project16/CVS/skycat/astrotcl/cfitsio/eval_l.c,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ */ #define FLEX_SCANNER #define FF_FLEX_MAJOR_VERSION 2 #define FF_FLEX_MINOR_VERSION 5 #include /* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ #ifdef c_plusplus #ifndef __cplusplus #define __cplusplus #endif #endif #ifdef __cplusplus #include #include /* Use prototypes in function declarations. */ #define FF_USE_PROTOS /* The "const" storage-class-modifier is valid. */ #define FF_USE_CONST #else /* ! __cplusplus */ #if __STDC__ #define FF_USE_PROTOS #define FF_USE_CONST #endif /* __STDC__ */ #endif /* ! __cplusplus */ #ifdef __TURBOC__ #pragma warn -rch #pragma warn -use #include #include #define FF_USE_CONST #define FF_USE_PROTOS #endif #ifdef FF_USE_CONST #define ffconst const #else #define ffconst #endif #ifdef FF_USE_PROTOS #define FF_PROTO(proto) proto #else #define FF_PROTO(proto) () #endif /* Returned upon end-of-file. */ #define FF_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define FF_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN ff_start = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The FFSTATE alias is for lex * compatibility. */ #define FF_START ((ff_start - 1) / 2) #define FFSTATE FF_START /* Action number for EOF rule of a given start state. */ #define FF_STATE_EOF(state) (FF_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define FF_NEW_FILE ffrestart( ffin ) #define FF_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #define FF_BUF_SIZE 16384 typedef struct ff_buffer_state *FF_BUFFER_STATE; extern int ffleng; extern FILE *ffin, *ffout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 /* The funky do-while in the following #define is used to turn the definition * int a single C statement (which needs a semi-colon terminator). This * avoids problems with code like: * * if ( condition_holds ) * ffless( 5 ); * else * do_something_else(); * * Prior to using the do-while the compiler would get upset at the * "else" because it interpreted the "if" statement as being all * done when it reached the ';' after the ffless() call. */ /* Return all but the first 'n' matched characters back to the input stream. */ #define ffless(n) \ do \ { \ /* Undo effects of setting up fftext. */ \ *ff_cp = ff_hold_char; \ FF_RESTORE_FF_MORE_OFFSET \ ff_c_buf_p = ff_cp = ff_bp + n - FF_MORE_ADJ; \ FF_DO_BEFORE_ACTION; /* set up fftext again */ \ } \ while ( 0 ) #define unput(c) ffunput( c, fftext_ptr ) /* The following is because we cannot portably get our hands on size_t * (without autoconf's help, which isn't available because we want * flex-generated scanners to compile on their own). */ typedef unsigned int ff_size_t; struct ff_buffer_state { FILE *ff_input_file; char *ff_ch_buf; /* input buffer */ char *ff_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ ff_size_t ff_buf_size; /* Number of characters read into ff_ch_buf, not including EOB * characters. */ int ff_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int ff_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int ff_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int ff_at_bol; /* Whether to try to fill the input buffer when we reach the * end of it. */ int ff_fill_buffer; int ff_buffer_status; #define FF_BUFFER_NEW 0 #define FF_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as FF_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via ffrestart()), so that the user can continue scanning by * just pointing ffin at a new input file. */ #define FF_BUFFER_EOF_PENDING 2 }; static FF_BUFFER_STATE ff_current_buffer = 0; /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". */ #define FF_CURRENT_BUFFER ff_current_buffer /* ff_hold_char holds the character lost when fftext is formed. */ static char ff_hold_char; static int ff_n_chars; /* number of characters read into ff_ch_buf */ int ffleng; /* Points to current character in buffer. */ static char *ff_c_buf_p = (char *) 0; static int ff_init = 1; /* whether we need to initialize */ static int ff_start = 0; /* start state number */ /* Flag which is used to allow ffwrap()'s to do buffer switches * instead of setting up a fresh ffin. A bit of a hack ... */ static int ff_did_buffer_switch_on_eof; void ffrestart FF_PROTO(( FILE *input_file )); void ff_switch_to_buffer FF_PROTO(( FF_BUFFER_STATE new_buffer )); void ff_load_buffer_state FF_PROTO(( void )); FF_BUFFER_STATE ff_create_buffer FF_PROTO(( FILE *file, int size )); void ff_delete_buffer FF_PROTO(( FF_BUFFER_STATE b )); void ff_init_buffer FF_PROTO(( FF_BUFFER_STATE b, FILE *file )); void ff_flush_buffer FF_PROTO(( FF_BUFFER_STATE b )); #define FF_FLUSH_BUFFER ff_flush_buffer( ff_current_buffer ) FF_BUFFER_STATE ff_scan_buffer FF_PROTO(( char *base, ff_size_t size )); FF_BUFFER_STATE ff_scan_string FF_PROTO(( ffconst char *ff_str )); FF_BUFFER_STATE ff_scan_bytes FF_PROTO(( ffconst char *bytes, int len )); static void *ff_flex_alloc FF_PROTO(( ff_size_t )); static void *ff_flex_realloc FF_PROTO(( void *, ff_size_t )); static void ff_flex_free FF_PROTO(( void * )); #define ff_new_buffer ff_create_buffer #define ff_set_interactive(is_interactive) \ { \ if ( ! ff_current_buffer ) \ ff_current_buffer = ff_create_buffer( ffin, FF_BUF_SIZE ); \ ff_current_buffer->ff_is_interactive = is_interactive; \ } #define ff_set_bol(at_bol) \ { \ if ( ! ff_current_buffer ) \ ff_current_buffer = ff_create_buffer( ffin, FF_BUF_SIZE ); \ ff_current_buffer->ff_at_bol = at_bol; \ } #define FF_AT_BOL() (ff_current_buffer->ff_at_bol) typedef unsigned char FF_CHAR; FILE *ffin = (FILE *) 0, *ffout = (FILE *) 0; typedef int ff_state_type; extern char *fftext; #define fftext_ptr fftext static ff_state_type ff_get_previous_state FF_PROTO(( void )); static ff_state_type ff_try_NUL_trans FF_PROTO(( ff_state_type current_state )); static int ff_get_next_buffer FF_PROTO(( void )); static void ff_fatal_error FF_PROTO(( ffconst char msg[] )); /* Done after the current pattern has been matched and before the * corresponding action - sets up fftext. */ #define FF_DO_BEFORE_ACTION \ fftext_ptr = ff_bp; \ ffleng = (int) (ff_cp - ff_bp); \ ff_hold_char = *ff_cp; \ *ff_cp = '\0'; \ ff_c_buf_p = ff_cp; #define FF_NUM_RULES 26 #define FF_END_OF_BUFFER 27 static ffconst short int ff_accept[160] = { 0, 0, 0, 27, 25, 1, 24, 15, 25, 25, 25, 25, 25, 25, 25, 7, 5, 21, 25, 20, 10, 10, 10, 10, 6, 10, 10, 10, 10, 10, 14, 10, 10, 10, 10, 10, 10, 10, 25, 1, 19, 0, 9, 0, 8, 0, 10, 17, 0, 0, 0, 0, 0, 0, 0, 14, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 5, 0, 23, 18, 22, 10, 10, 10, 2, 10, 10, 10, 4, 10, 10, 10, 10, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 16, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 11, 10, 20, 21, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0 } ; static ffconst int ff_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 5, 6, 7, 1, 8, 9, 10, 11, 12, 13, 1, 13, 14, 1, 15, 15, 16, 16, 16, 16, 16, 16, 17, 17, 1, 1, 18, 19, 20, 1, 1, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 30, 31, 30, 32, 33, 30, 34, 35, 30, 36, 37, 30, 30, 38, 30, 30, 1, 1, 1, 39, 40, 1, 41, 42, 23, 43, 44, 45, 46, 28, 47, 30, 30, 48, 30, 49, 50, 30, 51, 52, 30, 53, 54, 30, 30, 38, 30, 30, 1, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static ffconst int ff_meta[56] = { 0, 1, 1, 2, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1 } ; static ffconst short int ff_base[167] = { 0, 0, 0, 367, 368, 364, 368, 346, 359, 356, 355, 353, 351, 32, 347, 66, 103, 339, 44, 338, 25, 52, 316, 26, 315, 34, 133, 48, 61, 125, 368, 0, 29, 45, 60, 81, 82, 93, 299, 351, 368, 347, 368, 344, 343, 342, 368, 368, 339, 314, 315, 313, 294, 295, 293, 368, 121, 164, 307, 301, 70, 117, 43, 296, 276, 271, 58, 86, 79, 269, 152, 168, 181, 368, 368, 368, 151, 162, 0, 180, 189, 190, 191, 309, 196, 199, 205, 204, 211, 214, 207, 223, 224, 232, 238, 243, 245, 222, 246, 368, 311, 310, 279, 282, 278, 259, 262, 258, 252, 286, 295, 294, 293, 292, 291, 290, 267, 288, 258, 285, 284, 278, 270, 268, 259, 218, 252, 264, 272, 368, 251, 368, 368, 260, 280, 283, 236, 222, 230, 193, 184, 212, 208, 202, 173, 156, 368, 133, 126, 368, 104, 98, 119, 132, 80, 94, 92, 368, 78, 368, 323, 325, 329, 333, 68, 67, 337 } ; static ffconst short int ff_def[167] = { 0, 159, 1, 159, 159, 159, 159, 159, 160, 161, 162, 159, 163, 159, 159, 159, 159, 159, 159, 159, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 159, 165, 164, 164, 164, 164, 164, 164, 159, 159, 159, 160, 159, 166, 161, 162, 159, 159, 163, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 164, 164, 165, 164, 164, 164, 164, 26, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 159, 166, 166, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 164, 159, 159, 164, 164, 164, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 0, 159, 159, 159, 159, 159, 159, 159 } ; static ffconst short int ff_nxt[424] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 14, 4, 15, 16, 16, 16, 17, 18, 19, 20, 21, 22, 22, 23, 24, 25, 26, 22, 22, 27, 28, 29, 22, 22, 24, 22, 22, 30, 31, 32, 21, 22, 33, 24, 34, 22, 35, 36, 37, 22, 22, 24, 22, 38, 49, 77, 50, 81, 80, 51, 73, 74, 75, 78, 78, 79, 115, 78, 82, 78, 76, 84, 78, 52, 116, 53, 90, 54, 56, 57, 57, 57, 85, 78, 86, 58, 78, 157, 79, 59, 78, 60, 87, 111, 91, 61, 62, 63, 78, 78, 120, 157, 92, 157, 112, 64, 88, 88, 65, 121, 66, 93, 67, 68, 69, 70, 71, 71, 71, 78, 78, 124, 158, 94, 96, 72, 72, 125, 122, 88, 97, 78, 95, 56, 108, 108, 108, 123, 88, 88, 113, 157, 156, 98, 72, 72, 83, 83, 83, 155, 154, 114, 83, 83, 83, 83, 83, 83, 89, 129, 153, 88, 152, 78, 56, 57, 57, 57, 146, 83, 129, 78, 83, 83, 83, 83, 83, 57, 57, 57, 70, 71, 71, 71, 130, 47, 72, 72, 129, 78, 72, 72, 127, 79, 128, 128, 128, 129, 129, 129, 78, 74, 75, 131, 129, 72, 72, 129, 73, 72, 72, 132, 129, 129, 146, 129, 79, 40, 78, 129, 47, 149, 129, 151, 88, 88, 99, 78, 78, 78, 129, 129, 129, 150, 78, 74, 75, 78, 133, 149, 129, 148, 78, 78, 131, 78, 129, 88, 134, 78, 73, 129, 78, 129, 129, 132, 147, 40, 99, 129, 78, 78, 78, 47, 99, 108, 108, 108, 129, 145, 78, 40, 146, 135, 72, 72, 78, 128, 128, 128, 132, 78, 73, 78, 78, 128, 128, 128, 129, 78, 131, 129, 47, 72, 72, 146, 75, 74, 78, 144, 99, 143, 40, 132, 73, 131, 75, 74, 142, 141, 140, 139, 138, 137, 136, 101, 101, 129, 78, 126, 119, 78, 41, 118, 41, 41, 44, 44, 45, 117, 45, 45, 48, 110, 48, 48, 100, 109, 100, 100, 107, 106, 105, 104, 103, 102, 42, 46, 159, 101, 42, 39, 99, 78, 78, 75, 73, 55, 42, 47, 46, 43, 42, 40, 39, 159, 3, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159 } ; static ffconst short int ff_chk[424] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 13, 20, 13, 25, 23, 13, 18, 18, 18, 20, 23, 21, 62, 32, 25, 165, 164, 27, 25, 13, 62, 13, 32, 13, 15, 15, 15, 15, 27, 33, 28, 15, 27, 158, 21, 15, 21, 15, 28, 60, 33, 15, 15, 15, 34, 28, 66, 156, 34, 155, 60, 15, 37, 37, 15, 66, 15, 34, 15, 15, 15, 16, 16, 16, 16, 35, 36, 68, 154, 35, 36, 16, 16, 68, 67, 37, 36, 37, 35, 56, 56, 56, 56, 67, 29, 29, 61, 153, 152, 37, 16, 16, 26, 26, 26, 151, 150, 61, 26, 26, 26, 26, 26, 26, 29, 76, 148, 29, 147, 29, 70, 70, 70, 70, 145, 26, 77, 26, 26, 26, 26, 26, 26, 57, 57, 57, 71, 71, 71, 71, 77, 144, 57, 57, 79, 76, 71, 71, 72, 79, 72, 72, 72, 80, 81, 82, 77, 80, 81, 82, 84, 57, 57, 85, 84, 71, 71, 85, 87, 86, 143, 90, 79, 86, 79, 88, 142, 141, 89, 140, 88, 88, 89, 80, 81, 82, 97, 91, 92, 139, 84, 91, 92, 85, 87, 138, 93, 137, 87, 86, 93, 90, 94, 88, 90, 88, 94, 95, 89, 96, 98, 95, 136, 96, 98, 130, 97, 91, 92, 130, 126, 108, 108, 108, 133, 125, 93, 124, 133, 97, 108, 108, 94, 127, 127, 127, 123, 95, 122, 96, 98, 128, 128, 128, 134, 130, 121, 135, 134, 108, 108, 135, 120, 119, 133, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 107, 106, 105, 104, 103, 102, 101, 100, 83, 134, 69, 65, 135, 160, 64, 160, 160, 161, 161, 162, 63, 162, 162, 163, 59, 163, 163, 166, 58, 166, 166, 54, 53, 52, 51, 50, 49, 48, 45, 44, 43, 41, 39, 38, 24, 22, 19, 17, 14, 12, 11, 10, 9, 8, 7, 5, 3, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159 } ; static ff_state_type ff_last_accepting_state; static char *ff_last_accepting_cpos; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define ffmore() ffmore_used_but_not_detected #define FF_MORE_ADJ 0 #define FF_RESTORE_FF_MORE_OFFSET char *fftext; #line 1 "eval.l" #define INITIAL 0 #line 2 "eval.l" /************************************************************************/ /* */ /* CFITSIO Lexical Parser */ /* */ /* This file is one of 3 files containing code which parses an */ /* arithmetic expression and evaluates it in the context of an input */ /* FITS file table extension. The CFITSIO lexical parser is divided */ /* into the following 3 parts/files: the CFITSIO "front-end", */ /* eval_f.c, contains the interface between the user/CFITSIO and the */ /* real core of the parser; the FLEX interpreter, eval_l.c, takes the */ /* input string and parses it into tokens and identifies the FITS */ /* information required to evaluate the expression (ie, keywords and */ /* columns); and, the BISON grammar and evaluation routines, eval_y.c, */ /* receives the FLEX output and determines and performs the actual */ /* operations. The files eval_l.c and eval_y.c are produced from */ /* running flex and bison on the files eval.l and eval.y, respectively. */ /* (flex and bison are available from any GNU archive: see www.gnu.org) */ /* */ /* The grammar rules, rather than evaluating the expression in situ, */ /* builds a tree, or Nodal, structure mapping out the order of */ /* operations and expression dependencies. This "compilation" process */ /* allows for much faster processing of multiple rows. This technique */ /* was developed by Uwe Lammers of the XMM Science Analysis System, */ /* although the CFITSIO implementation is entirely code original. */ /* */ /* */ /* Modification History: */ /* */ /* Kent Blackburn c1992 Original parser code developed for the */ /* FTOOLS software package, in particular, */ /* the fselect task. */ /* Kent Blackburn c1995 BIT column support added */ /* Peter D Wilson Feb 1998 Vector column support added */ /* Peter D Wilson May 1998 Ported to CFITSIO library. User */ /* interface routines written, in essence */ /* making fselect, fcalc, and maketime */ /* capabilities available to all tools */ /* via single function calls. */ /* Peter D Wilson Jun 1998 Major rewrite of parser core, so as to */ /* create a run-time evaluation tree, */ /* inspired by the work of Uwe Lammers, */ /* resulting in a speed increase of */ /* 10-100 times. */ /* Peter D Wilson Jul 1998 gtifilter(a,b,c,d) function added */ /* Peter D Wilson Aug 1998 regfilter(a,b,c,d) function added */ /* Peter D Wilson Jul 1999 Make parser fitsfile-independent, */ /* allowing a purely vector-based usage */ /* */ /************************************************************************/ #include #include #include #ifdef sparc #include #else #include #endif #include "eval_defs.h" ParseData gParse; /* Global structure holding all parser information */ /***** Internal functions *****/ int ffGetVariable( char *varName, FFSTYPE *varVal ); static int find_variable( char *varName ); static int expr_read( char *buf, int nbytes ); /***** Definitions *****/ #define FF_NO_UNPUT /* Don't include FFUNPUT function */ #define FF_NEVER_INTERACTIVE 1 #define MAXCHR 256 #define MAXBIT 128 #define OCT_0 "000" #define OCT_1 "001" #define OCT_2 "010" #define OCT_3 "011" #define OCT_4 "100" #define OCT_5 "101" #define OCT_6 "110" #define OCT_7 "111" #define OCT_X "xxx" #define HEX_0 "0000" #define HEX_1 "0001" #define HEX_2 "0010" #define HEX_3 "0011" #define HEX_4 "0100" #define HEX_5 "0101" #define HEX_6 "0110" #define HEX_7 "0111" #define HEX_8 "1000" #define HEX_9 "1001" #define HEX_A "1010" #define HEX_B "1011" #define HEX_C "1100" #define HEX_D "1101" #define HEX_E "1110" #define HEX_F "1111" #define HEX_X "xxxx" /* MJT - 13 June 1996 read from buffer instead of stdin (as per old ftools.skel) */ #undef FF_INPUT #define FF_INPUT(buf,result,max_size) \ if ( (result = expr_read( (char *) buf, max_size )) < 0 ) \ FF_FATAL_ERROR( "read() in flex scanner failed" ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef FF_SKIP_FFWRAP #ifdef __cplusplus extern "C" int ffwrap FF_PROTO(( void )); #else extern int ffwrap FF_PROTO(( void )); #endif #endif #ifndef FF_NO_UNPUT static void ffunput FF_PROTO(( int c, char *buf_ptr )); #endif #ifndef fftext_ptr static void ff_flex_strncpy FF_PROTO(( char *, ffconst char *, int )); #endif #ifdef FF_NEED_STRLEN static int ff_flex_strlen FF_PROTO(( ffconst char * )); #endif #ifndef FF_NO_INPUT #ifdef __cplusplus static int ffinput FF_PROTO(( void )); #else static int input FF_PROTO(( void )); #endif #endif #if FF_STACK_USED static int ff_start_stack_ptr = 0; static int ff_start_stack_depth = 0; static int *ff_start_stack = 0; #ifndef FF_NO_PUSH_STATE static void ff_push_state FF_PROTO(( int new_state )); #endif #ifndef FF_NO_POP_STATE static void ff_pop_state FF_PROTO(( void )); #endif #ifndef FF_NO_TOP_STATE static int ff_top_state FF_PROTO(( void )); #endif #else #define FF_NO_PUSH_STATE 1 #define FF_NO_POP_STATE 1 #define FF_NO_TOP_STATE 1 #endif #ifdef FF_MALLOC_DECL FF_MALLOC_DECL #else #if __STDC__ #ifndef __cplusplus #include #endif #else /* Just try to get by without declaring the routines. This will fail * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) * or sizeof(void*) != sizeof(int). */ #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef FF_READ_BUF_SIZE #define FF_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO (void) fwrite( fftext, ffleng, 1, ffout ) #endif /* Gets input and stuffs it into "buf". number of characters read, or FF_NULL, * is returned in "result". */ #ifndef FF_INPUT #define FF_INPUT(buf,result,max_size) \ if ( ff_current_buffer->ff_is_interactive ) \ { \ int c = '*', n; \ for ( n = 0; n < max_size && \ (c = getc( ffin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( ffin ) ) \ FF_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else if ( ((result = fread( buf, 1, max_size, ffin )) == 0) \ && ferror( ffin ) ) \ FF_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "ffterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef ffterminate #define ffterminate() return FF_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef FF_START_STACK_INCR #define FF_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef FF_FATAL_ERROR #define FF_FATAL_ERROR(msg) ff_fatal_error( msg ) #endif /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef FF_DECL #define FF_DECL int fflex FF_PROTO(( void )) #endif /* Code executed at the beginning of each rule, after fftext and ffleng * have been set up. */ #ifndef FF_USER_ACTION #define FF_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef FF_BREAK #define FF_BREAK break; #endif #define FF_RULE_SETUP \ FF_USER_ACTION FF_DECL { register ff_state_type ff_current_state; register char *ff_cp, *ff_bp; register int ff_act; #line 142 "eval.l" if ( ff_init ) { ff_init = 0; #ifdef FF_USER_INIT FF_USER_INIT; #endif if ( ! ff_start ) ff_start = 1; /* first start state */ if ( ! ffin ) ffin = stdin; if ( ! ffout ) ffout = stdout; if ( ! ff_current_buffer ) ff_current_buffer = ff_create_buffer( ffin, FF_BUF_SIZE ); ff_load_buffer_state(); } while ( 1 ) /* loops until end-of-file is reached */ { ff_cp = ff_c_buf_p; /* Support of fftext. */ *ff_cp = ff_hold_char; /* ff_bp points to the position in ff_ch_buf of the start of * the current run. */ ff_bp = ff_cp; ff_current_state = ff_start; ff_match: do { register FF_CHAR ff_c = ff_ec[FF_SC_TO_UI(*ff_cp)]; if ( ff_accept[ff_current_state] ) { ff_last_accepting_state = ff_current_state; ff_last_accepting_cpos = ff_cp; } while ( ff_chk[ff_base[ff_current_state] + ff_c] != ff_current_state ) { ff_current_state = (int) ff_def[ff_current_state]; if ( ff_current_state >= 160 ) ff_c = ff_meta[(unsigned int) ff_c]; } ff_current_state = ff_nxt[ff_base[ff_current_state] + (unsigned int) ff_c]; ++ff_cp; } while ( ff_base[ff_current_state] != 368 ); ff_find_action: ff_act = ff_accept[ff_current_state]; if ( ff_act == 0 ) { /* have to back up */ ff_cp = ff_last_accepting_cpos; ff_current_state = ff_last_accepting_state; ff_act = ff_accept[ff_current_state]; } FF_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( ff_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of FF_DO_BEFORE_ACTION */ *ff_cp = ff_hold_char; ff_cp = ff_last_accepting_cpos; ff_current_state = ff_last_accepting_state; goto ff_find_action; case 1: FF_RULE_SETUP #line 144 "eval.l" ; FF_BREAK case 2: FF_RULE_SETUP #line 145 "eval.l" { int len; len = strlen(fftext); while (fftext[len] == ' ') len--; len = len - 1; strncpy(fflval.str,&fftext[1],len); fflval.str[len] = '\0'; return( BITSTR ); } FF_BREAK case 3: FF_RULE_SETUP #line 155 "eval.l" { int len; char tmpstring[256]; char bitstring[256]; len = strlen(fftext); while (fftext[len] == ' ') len--; len = len - 1; strncpy(tmpstring,&fftext[1],len); tmpstring[len] = '\0'; bitstring[0] = '\0'; len = 0; while ( tmpstring[len] != '\0') { switch ( tmpstring[len] ) { case '0': strcat(bitstring,OCT_0); break; case '1': strcat(bitstring,OCT_1); break; case '2': strcat(bitstring,OCT_2); break; case '3': strcat(bitstring,OCT_3); break; case '4': strcat(bitstring,OCT_4); break; case '5': strcat(bitstring,OCT_5); break; case '6': strcat(bitstring,OCT_6); break; case '7': strcat(bitstring,OCT_7); break; case 'x': case 'X': strcat(bitstring,OCT_X); break; } len++; } strcpy( fflval.str, bitstring ); return( BITSTR ); } FF_BREAK case 4: FF_RULE_SETUP #line 205 "eval.l" { int len; char tmpstring[256]; char bitstring[256]; len = strlen(fftext); while (fftext[len] == ' ') len--; len = len - 1; strncpy(tmpstring,&fftext[1],len); tmpstring[len] = '\0'; bitstring[0] = '\0'; len = 0; while ( tmpstring[len] != '\0') { switch ( tmpstring[len] ) { case '0': strcat(bitstring,HEX_0); break; case '1': strcat(bitstring,HEX_1); break; case '2': strcat(bitstring,HEX_2); break; case '3': strcat(bitstring,HEX_3); break; case '4': strcat(bitstring,HEX_4); break; case '5': strcat(bitstring,HEX_5); break; case '6': strcat(bitstring,HEX_6); break; case '7': strcat(bitstring,HEX_7); break; case '8': strcat(bitstring,HEX_8); break; case '9': strcat(bitstring,HEX_9); break; case 'a': case 'A': strcat(bitstring,HEX_A); break; case 'b': case 'B': strcat(bitstring,HEX_B); break; case 'c': case 'C': strcat(bitstring,HEX_C); break; case 'd': case 'D': strcat(bitstring,HEX_D); break; case 'e': case 'E': strcat(bitstring,HEX_E); break; case 'f': case 'F': strcat(bitstring,HEX_F); break; case 'x': case 'X': strcat(bitstring,HEX_X); break; } len++; } strcpy( fflval.str, bitstring ); return( BITSTR ); } FF_BREAK case 5: FF_RULE_SETUP #line 286 "eval.l" { fflval.lng = atol(fftext); return( LONG ); } FF_BREAK case 6: FF_RULE_SETUP #line 290 "eval.l" { if ((fftext[0] == 't') || (fftext[0] == 'T')) fflval.log = 1; else fflval.log = 0; return( BOOLEAN ); } FF_BREAK case 7: FF_RULE_SETUP #line 297 "eval.l" { fflval.dbl = atof(fftext); return( DOUBLE ); } FF_BREAK case 8: FF_RULE_SETUP #line 301 "eval.l" { if( !strcasecmp(fftext,"#PI") ) { fflval.dbl = (double)(4) * atan((double)(1)); return( DOUBLE ); } else if( !strcasecmp(fftext,"#E") ) { fflval.dbl = exp((double)(1)); return( DOUBLE ); } else if( !strcasecmp(fftext,"#DEG") ) { fflval.dbl = ((double)4)*atan((double)1)/((double)180); return( DOUBLE ); } else if( !strcasecmp(fftext,"#ROW") ) { return( ROWREF ); } else if( !strcasecmp(fftext,"#NULL") ) { return( NULLREF ); } else if( !strcasecmp(fftext,"#SNULL") ) { return( SNULLREF ); } else { int len; if (fftext[1] == '$') { len = strlen(fftext) - 3; fflval.str[0] = '#'; strncpy(fflval.str+1,&fftext[2],len); fflval.str[len+1] = '\0'; fftext = fflval.str; } return( (*gParse.getData)(fftext, &fflval) ); } } FF_BREAK case 9: FF_RULE_SETUP #line 329 "eval.l" { int len; len = strlen(fftext) - 2; strncpy(fflval.str,&fftext[1],len); fflval.str[len] = '\0'; return( STRING ); } FF_BREAK case 10: FF_RULE_SETUP #line 336 "eval.l" { int len,type; if (fftext[0] == '$') { len = strlen(fftext) - 2; strncpy(fflval.str,&fftext[1],len); fflval.str[len] = '\0'; fftext = fflval.str; } type = ffGetVariable(fftext, &fflval); return( type ); } FF_BREAK case 11: FF_RULE_SETUP #line 348 "eval.l" { char *fname; int len=0; fname = &fflval.str[0]; while( (fname[len]=toupper(fftext[len])) ) len++; if( FSTRCMP(fname,"BOX(")==0 || FSTRCMP(fname,"CIRCLE(")==0 || FSTRCMP(fname,"ELLIPSE(")==0 || FSTRCMP(fname,"NEAR(")==0 || FSTRCMP(fname,"ISNULL(")==0 ) /* Return type is always boolean */ return( BFUNCTION ); else if( FSTRCMP(fname,"GTIFILTER(")==0 ) return( GTIFILTER ); else if( FSTRCMP(fname,"REGFILTER(")==0 ) return( REGFILTER ); else return( FUNCTION ); } FF_BREAK case 12: FF_RULE_SETUP #line 372 "eval.l" { return( INTCAST ); } FF_BREAK case 13: FF_RULE_SETUP #line 373 "eval.l" { return( FLTCAST ); } FF_BREAK case 14: FF_RULE_SETUP #line 374 "eval.l" { return( POWER ); } FF_BREAK case 15: FF_RULE_SETUP #line 375 "eval.l" { return( NOT ); } FF_BREAK case 16: FF_RULE_SETUP #line 376 "eval.l" { return( OR ); } FF_BREAK case 17: FF_RULE_SETUP #line 377 "eval.l" { return( AND ); } FF_BREAK case 18: FF_RULE_SETUP #line 378 "eval.l" { return( EQ ); } FF_BREAK case 19: FF_RULE_SETUP #line 379 "eval.l" { return( NE ); } FF_BREAK case 20: FF_RULE_SETUP #line 380 "eval.l" { return( GT ); } FF_BREAK case 21: FF_RULE_SETUP #line 381 "eval.l" { return( LT ); } FF_BREAK case 22: FF_RULE_SETUP #line 382 "eval.l" { return( GTE ); } FF_BREAK case 23: FF_RULE_SETUP #line 383 "eval.l" { return( LTE ); } FF_BREAK case 24: FF_RULE_SETUP #line 384 "eval.l" { return( '\n' ); } FF_BREAK case 25: FF_RULE_SETUP #line 385 "eval.l" { return( fftext[0] ); } FF_BREAK case 26: FF_RULE_SETUP #line 386 "eval.l" ECHO; FF_BREAK case FF_STATE_EOF(INITIAL): ffterminate(); case FF_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int ff_amount_of_matched_text = (int) (ff_cp - fftext_ptr) - 1; /* Undo the effects of FF_DO_BEFORE_ACTION. */ *ff_cp = ff_hold_char; FF_RESTORE_FF_MORE_OFFSET if ( ff_current_buffer->ff_buffer_status == FF_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed ffin at a new source and called * fflex(). If so, then we have to assure * consistency between ff_current_buffer and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ ff_n_chars = ff_current_buffer->ff_n_chars; ff_current_buffer->ff_input_file = ffin; ff_current_buffer->ff_buffer_status = FF_BUFFER_NORMAL; } /* Note that here we test for ff_c_buf_p "<=" to the position * of the first EOB in the buffer, since ff_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( ff_c_buf_p <= &ff_current_buffer->ff_ch_buf[ff_n_chars] ) { /* This was really a NUL. */ ff_state_type ff_next_state; ff_c_buf_p = fftext_ptr + ff_amount_of_matched_text; ff_current_state = ff_get_previous_state(); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * ff_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ ff_next_state = ff_try_NUL_trans( ff_current_state ); ff_bp = fftext_ptr + FF_MORE_ADJ; if ( ff_next_state ) { /* Consume the NUL. */ ff_cp = ++ff_c_buf_p; ff_current_state = ff_next_state; goto ff_match; } else { ff_cp = ff_c_buf_p; goto ff_find_action; } } else switch ( ff_get_next_buffer() ) { case EOB_ACT_END_OF_FILE: { ff_did_buffer_switch_on_eof = 0; if ( ffwrap() ) { /* Note: because we've taken care in * ff_get_next_buffer() to have set up * fftext, we can now set up * ff_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * FF_NULL, it'll still work - another * FF_NULL will get returned. */ ff_c_buf_p = fftext_ptr + FF_MORE_ADJ; ff_act = FF_STATE_EOF(FF_START); goto do_action; } else { if ( ! ff_did_buffer_switch_on_eof ) FF_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: ff_c_buf_p = fftext_ptr + ff_amount_of_matched_text; ff_current_state = ff_get_previous_state(); ff_cp = ff_c_buf_p; ff_bp = fftext_ptr + FF_MORE_ADJ; goto ff_match; case EOB_ACT_LAST_MATCH: ff_c_buf_p = &ff_current_buffer->ff_ch_buf[ff_n_chars]; ff_current_state = ff_get_previous_state(); ff_cp = ff_c_buf_p; ff_bp = fftext_ptr + FF_MORE_ADJ; goto ff_find_action; } break; } default: FF_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of fflex */ /* ff_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int ff_get_next_buffer() { register char *dest = ff_current_buffer->ff_ch_buf; register char *source = fftext_ptr; register int number_to_move, i; int ret_val; if ( ff_c_buf_p > &ff_current_buffer->ff_ch_buf[ff_n_chars + 1] ) FF_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( ff_current_buffer->ff_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( ff_c_buf_p - fftext_ptr - FF_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) (ff_c_buf_p - fftext_ptr) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( ff_current_buffer->ff_buffer_status == FF_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ ff_current_buffer->ff_n_chars = ff_n_chars = 0; else { int num_to_read = ff_current_buffer->ff_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ #ifdef FF_USES_REJECT FF_FATAL_ERROR( "input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); #else /* just a shorter name for the current buffer */ FF_BUFFER_STATE b = ff_current_buffer; int ff_c_buf_p_offset = (int) (ff_c_buf_p - b->ff_ch_buf); if ( b->ff_is_our_buffer ) { int new_size = b->ff_buf_size * 2; if ( new_size <= 0 ) b->ff_buf_size += b->ff_buf_size / 8; else b->ff_buf_size *= 2; b->ff_ch_buf = (char *) /* Include room in for 2 EOB chars. */ ff_flex_realloc( (void *) b->ff_ch_buf, b->ff_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->ff_ch_buf = 0; if ( ! b->ff_ch_buf ) FF_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); ff_c_buf_p = &b->ff_ch_buf[ff_c_buf_p_offset]; num_to_read = ff_current_buffer->ff_buf_size - number_to_move - 1; #endif } if ( num_to_read > FF_READ_BUF_SIZE ) num_to_read = FF_READ_BUF_SIZE; /* Read in more data. */ FF_INPUT( (&ff_current_buffer->ff_ch_buf[number_to_move]), ff_n_chars, num_to_read ); ff_current_buffer->ff_n_chars = ff_n_chars; } if ( ff_n_chars == 0 ) { if ( number_to_move == FF_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; ffrestart( ffin ); } else { ret_val = EOB_ACT_LAST_MATCH; ff_current_buffer->ff_buffer_status = FF_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; ff_n_chars += number_to_move; ff_current_buffer->ff_ch_buf[ff_n_chars] = FF_END_OF_BUFFER_CHAR; ff_current_buffer->ff_ch_buf[ff_n_chars + 1] = FF_END_OF_BUFFER_CHAR; fftext_ptr = &ff_current_buffer->ff_ch_buf[0]; return ret_val; } /* ff_get_previous_state - get the state just before the EOB char was reached */ static ff_state_type ff_get_previous_state() { register ff_state_type ff_current_state; register char *ff_cp; ff_current_state = ff_start; for ( ff_cp = fftext_ptr + FF_MORE_ADJ; ff_cp < ff_c_buf_p; ++ff_cp ) { register FF_CHAR ff_c = (*ff_cp ? ff_ec[FF_SC_TO_UI(*ff_cp)] : 1); if ( ff_accept[ff_current_state] ) { ff_last_accepting_state = ff_current_state; ff_last_accepting_cpos = ff_cp; } while ( ff_chk[ff_base[ff_current_state] + ff_c] != ff_current_state ) { ff_current_state = (int) ff_def[ff_current_state]; if ( ff_current_state >= 160 ) ff_c = ff_meta[(unsigned int) ff_c]; } ff_current_state = ff_nxt[ff_base[ff_current_state] + (unsigned int) ff_c]; } return ff_current_state; } /* ff_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = ff_try_NUL_trans( current_state ); */ #ifdef FF_USE_PROTOS static ff_state_type ff_try_NUL_trans( ff_state_type ff_current_state ) #else static ff_state_type ff_try_NUL_trans( ff_current_state ) ff_state_type ff_current_state; #endif { register int ff_is_jam; register char *ff_cp = ff_c_buf_p; register FF_CHAR ff_c = 1; if ( ff_accept[ff_current_state] ) { ff_last_accepting_state = ff_current_state; ff_last_accepting_cpos = ff_cp; } while ( ff_chk[ff_base[ff_current_state] + ff_c] != ff_current_state ) { ff_current_state = (int) ff_def[ff_current_state]; if ( ff_current_state >= 160 ) ff_c = ff_meta[(unsigned int) ff_c]; } ff_current_state = ff_nxt[ff_base[ff_current_state] + (unsigned int) ff_c]; ff_is_jam = (ff_current_state == 159); return ff_is_jam ? 0 : ff_current_state; } #ifndef FF_NO_UNPUT #ifdef FF_USE_PROTOS static void ffunput( int c, register char *ff_bp ) #else static void ffunput( c, ff_bp ) int c; register char *ff_bp; #endif { register char *ff_cp = ff_c_buf_p; /* undo effects of setting up fftext */ *ff_cp = ff_hold_char; if ( ff_cp < ff_current_buffer->ff_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register int number_to_move = ff_n_chars + 2; register char *dest = &ff_current_buffer->ff_ch_buf[ ff_current_buffer->ff_buf_size + 2]; register char *source = &ff_current_buffer->ff_ch_buf[number_to_move]; while ( source > ff_current_buffer->ff_ch_buf ) *--dest = *--source; ff_cp += (int) (dest - source); ff_bp += (int) (dest - source); ff_current_buffer->ff_n_chars = ff_n_chars = ff_current_buffer->ff_buf_size; if ( ff_cp < ff_current_buffer->ff_ch_buf + 2 ) FF_FATAL_ERROR( "flex scanner push-back overflow" ); } *--ff_cp = (char) c; fftext_ptr = ff_bp; ff_hold_char = *ff_cp; ff_c_buf_p = ff_cp; } #endif /* ifndef FF_NO_UNPUT */ #ifdef __cplusplus static int ffinput() #else static int input() #endif { int c; *ff_c_buf_p = ff_hold_char; if ( *ff_c_buf_p == FF_END_OF_BUFFER_CHAR ) { /* ff_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( ff_c_buf_p < &ff_current_buffer->ff_ch_buf[ff_n_chars] ) /* This was really a NUL. */ *ff_c_buf_p = '\0'; else { /* need more input */ int offset = ff_c_buf_p - fftext_ptr; ++ff_c_buf_p; switch ( ff_get_next_buffer() ) { case EOB_ACT_LAST_MATCH: /* This happens because ff_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ ffrestart( ffin ); /* fall through */ case EOB_ACT_END_OF_FILE: { if ( ffwrap() ) return EOF; if ( ! ff_did_buffer_switch_on_eof ) FF_NEW_FILE; #ifdef __cplusplus return ffinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: ff_c_buf_p = fftext_ptr + offset; break; } } } c = *(unsigned char *) ff_c_buf_p; /* cast for 8-bit char's */ *ff_c_buf_p = '\0'; /* preserve fftext */ ff_hold_char = *++ff_c_buf_p; return c; } #ifdef FF_USE_PROTOS void ffrestart( FILE *input_file ) #else void ffrestart( input_file ) FILE *input_file; #endif { if ( ! ff_current_buffer ) ff_current_buffer = ff_create_buffer( ffin, FF_BUF_SIZE ); ff_init_buffer( ff_current_buffer, input_file ); ff_load_buffer_state(); } #ifdef FF_USE_PROTOS void ff_switch_to_buffer( FF_BUFFER_STATE new_buffer ) #else void ff_switch_to_buffer( new_buffer ) FF_BUFFER_STATE new_buffer; #endif { if ( ff_current_buffer == new_buffer ) return; if ( ff_current_buffer ) { /* Flush out information for old buffer. */ *ff_c_buf_p = ff_hold_char; ff_current_buffer->ff_buf_pos = ff_c_buf_p; ff_current_buffer->ff_n_chars = ff_n_chars; } ff_current_buffer = new_buffer; ff_load_buffer_state(); /* We don't actually know whether we did this switch during * EOF (ffwrap()) processing, but the only time this flag * is looked at is after ffwrap() is called, so it's safe * to go ahead and always set it. */ ff_did_buffer_switch_on_eof = 1; } #ifdef FF_USE_PROTOS void ff_load_buffer_state( void ) #else void ff_load_buffer_state() #endif { ff_n_chars = ff_current_buffer->ff_n_chars; fftext_ptr = ff_c_buf_p = ff_current_buffer->ff_buf_pos; ffin = ff_current_buffer->ff_input_file; ff_hold_char = *ff_c_buf_p; } #ifdef FF_USE_PROTOS FF_BUFFER_STATE ff_create_buffer( FILE *file, int size ) #else FF_BUFFER_STATE ff_create_buffer( file, size ) FILE *file; int size; #endif { FF_BUFFER_STATE b; b = (FF_BUFFER_STATE) ff_flex_alloc( sizeof( struct ff_buffer_state ) ); if ( ! b ) FF_FATAL_ERROR( "out of dynamic memory in ff_create_buffer()" ); b->ff_buf_size = size; /* ff_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->ff_ch_buf = (char *) ff_flex_alloc( b->ff_buf_size + 2 ); if ( ! b->ff_ch_buf ) FF_FATAL_ERROR( "out of dynamic memory in ff_create_buffer()" ); b->ff_is_our_buffer = 1; ff_init_buffer( b, file ); return b; } #ifdef FF_USE_PROTOS void ff_delete_buffer( FF_BUFFER_STATE b ) #else void ff_delete_buffer( b ) FF_BUFFER_STATE b; #endif { if ( ! b ) return; if ( b == ff_current_buffer ) ff_current_buffer = (FF_BUFFER_STATE) 0; if ( b->ff_is_our_buffer ) ff_flex_free( (void *) b->ff_ch_buf ); ff_flex_free( (void *) b ); } #ifndef FF_ALWAYS_INTERACTIVE #ifndef FF_NEVER_INTERACTIVE extern int isatty FF_PROTO(( int )); #endif #endif #ifdef FF_USE_PROTOS void ff_init_buffer( FF_BUFFER_STATE b, FILE *file ) #else void ff_init_buffer( b, file ) FF_BUFFER_STATE b; FILE *file; #endif { ff_flush_buffer( b ); b->ff_input_file = file; b->ff_fill_buffer = 1; #if FF_ALWAYS_INTERACTIVE b->ff_is_interactive = 1; #else #if FF_NEVER_INTERACTIVE b->ff_is_interactive = 0; #else b->ff_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; #endif #endif } #ifdef FF_USE_PROTOS void ff_flush_buffer( FF_BUFFER_STATE b ) #else void ff_flush_buffer( b ) FF_BUFFER_STATE b; #endif { if ( ! b ) return; b->ff_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->ff_ch_buf[0] = FF_END_OF_BUFFER_CHAR; b->ff_ch_buf[1] = FF_END_OF_BUFFER_CHAR; b->ff_buf_pos = &b->ff_ch_buf[0]; b->ff_at_bol = 1; b->ff_buffer_status = FF_BUFFER_NEW; if ( b == ff_current_buffer ) ff_load_buffer_state(); } #ifndef FF_NO_SCAN_BUFFER #ifdef FF_USE_PROTOS FF_BUFFER_STATE ff_scan_buffer( char *base, ff_size_t size ) #else FF_BUFFER_STATE ff_scan_buffer( base, size ) char *base; ff_size_t size; #endif { FF_BUFFER_STATE b; if ( size < 2 || base[size-2] != FF_END_OF_BUFFER_CHAR || base[size-1] != FF_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; b = (FF_BUFFER_STATE) ff_flex_alloc( sizeof( struct ff_buffer_state ) ); if ( ! b ) FF_FATAL_ERROR( "out of dynamic memory in ff_scan_buffer()" ); b->ff_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->ff_buf_pos = b->ff_ch_buf = base; b->ff_is_our_buffer = 0; b->ff_input_file = 0; b->ff_n_chars = b->ff_buf_size; b->ff_is_interactive = 0; b->ff_at_bol = 1; b->ff_fill_buffer = 0; b->ff_buffer_status = FF_BUFFER_NEW; ff_switch_to_buffer( b ); return b; } #endif #ifndef FF_NO_SCAN_STRING #ifdef FF_USE_PROTOS FF_BUFFER_STATE ff_scan_string( ffconst char *ff_str ) #else FF_BUFFER_STATE ff_scan_string( ff_str ) ffconst char *ff_str; #endif { int len; for ( len = 0; ff_str[len]; ++len ) ; return ff_scan_bytes( ff_str, len ); } #endif #ifndef FF_NO_SCAN_BYTES #ifdef FF_USE_PROTOS FF_BUFFER_STATE ff_scan_bytes( ffconst char *bytes, int len ) #else FF_BUFFER_STATE ff_scan_bytes( bytes, len ) ffconst char *bytes; int len; #endif { FF_BUFFER_STATE b; char *buf; ff_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = len + 2; buf = (char *) ff_flex_alloc( n ); if ( ! buf ) FF_FATAL_ERROR( "out of dynamic memory in ff_scan_bytes()" ); for ( i = 0; i < len; ++i ) buf[i] = bytes[i]; buf[len] = buf[len+1] = FF_END_OF_BUFFER_CHAR; b = ff_scan_buffer( buf, n ); if ( ! b ) FF_FATAL_ERROR( "bad buffer in ff_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->ff_is_our_buffer = 1; return b; } #endif #ifndef FF_NO_PUSH_STATE #ifdef FF_USE_PROTOS static void ff_push_state( int new_state ) #else static void ff_push_state( new_state ) int new_state; #endif { if ( ff_start_stack_ptr >= ff_start_stack_depth ) { ff_size_t new_size; ff_start_stack_depth += FF_START_STACK_INCR; new_size = ff_start_stack_depth * sizeof( int ); if ( ! ff_start_stack ) ff_start_stack = (int *) ff_flex_alloc( new_size ); else ff_start_stack = (int *) ff_flex_realloc( (void *) ff_start_stack, new_size ); if ( ! ff_start_stack ) FF_FATAL_ERROR( "out of memory expanding start-condition stack" ); } ff_start_stack[ff_start_stack_ptr++] = FF_START; BEGIN(new_state); } #endif #ifndef FF_NO_POP_STATE static void ff_pop_state() { if ( --ff_start_stack_ptr < 0 ) FF_FATAL_ERROR( "start-condition stack underflow" ); BEGIN(ff_start_stack[ff_start_stack_ptr]); } #endif #ifndef FF_NO_TOP_STATE static int ff_top_state() { return ff_start_stack[ff_start_stack_ptr - 1]; } #endif #ifndef FF_EXIT_FAILURE #define FF_EXIT_FAILURE 2 #endif #ifdef FF_USE_PROTOS static void ff_fatal_error( ffconst char msg[] ) #else static void ff_fatal_error( msg ) char msg[]; #endif { (void) fprintf( stderr, "%s\n", msg ); exit( FF_EXIT_FAILURE ); } /* Redefine ffless() so it works in section 3 code. */ #undef ffless #define ffless(n) \ do \ { \ /* Undo effects of setting up fftext. */ \ fftext[ffleng] = ff_hold_char; \ ff_c_buf_p = fftext + n; \ ff_hold_char = *ff_c_buf_p; \ *ff_c_buf_p = '\0'; \ ffleng = n; \ } \ while ( 0 ) /* Internal utility routines. */ #ifndef fftext_ptr #ifdef FF_USE_PROTOS static void ff_flex_strncpy( char *s1, ffconst char *s2, int n ) #else static void ff_flex_strncpy( s1, s2, n ) char *s1; ffconst char *s2; int n; #endif { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef FF_NEED_STRLEN #ifdef FF_USE_PROTOS static int ff_flex_strlen( ffconst char *s ) #else static int ff_flex_strlen( s ) ffconst char *s; #endif { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif #ifdef FF_USE_PROTOS static void *ff_flex_alloc( ff_size_t size ) #else static void *ff_flex_alloc( size ) ff_size_t size; #endif { return (void *) malloc( size ); } #ifdef FF_USE_PROTOS static void *ff_flex_realloc( void *ptr, ff_size_t size ) #else static void *ff_flex_realloc( ptr, size ) void *ptr; ff_size_t size; #endif { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } #ifdef FF_USE_PROTOS static void ff_flex_free( void *ptr ) #else static void ff_flex_free( ptr ) void *ptr; #endif { free( ptr ); } #if FF_MAIN int main() { fflex(); return 0; } #endif #line 386 "eval.l" int ffwrap() { /* MJT -- 13 June 1996 Supplied for compatibility with pre-2.5.1 versions of flex which do not recognize %option noffwrap */ return(1); } /* expr_read is lifted from old ftools.skel. Now we can use any version of flex with no .skel file necessary! MJT - 13 June 1996 keep a memory of how many bytes have been read previously, so that an unlimited-sized buffer can be supported. PDW - 28 Feb 1998 */ static int expr_read(char *buf, int nbytes) { int n; n = 0; if( !gParse.is_eobuf ) { do { buf[n++] = gParse.expr[gParse.index++]; } while ((nlng = varNum; } return( type ); } static int find_variable(char *varName) { int i; if( gParse.nCols ) for( i=0; i c2) return(1); if (c1 == 0) return(0); s1++; s2++; } } int strncasecmp(const char *s1, const char *s2, size_t n) { char c1, c2; for (; n-- ;) { c1 = toupper( *s1 ); c2 = toupper( *s2 ); if (c1 < c2) return(-1); if (c1 > c2) return(1); if (c1 == 0) return(0); s1++; s2++; } return(0); } #endif skycat-3.1.2-starlink-1b/astrotcl/cfitsio/eval_tab.h000066400000000000000000000015121215713201500223550ustar00rootroot00000000000000typedef union { int Node; /* Index of Node */ double dbl; /* real value */ long lng; /* integer value */ char log; /* logical value */ char str[256]; /* string value */ } FFSTYPE; #define BOOLEAN 258 #define LONG 259 #define DOUBLE 260 #define STRING 261 #define BITSTR 262 #define FUNCTION 263 #define BFUNCTION 264 #define GTIFILTER 265 #define REGFILTER 266 #define COLUMN 267 #define BCOLUMN 268 #define SCOLUMN 269 #define BITCOL 270 #define ROWREF 271 #define NULLREF 272 #define SNULLREF 273 #define OR 274 #define AND 275 #define EQ 276 #define NE 277 #define GT 278 #define LT 279 #define LTE 280 #define GTE 281 #define POWER 282 #define NOT 283 #define INTCAST 284 #define FLTCAST 285 #define UMINUS 286 #define ACCUM 287 #define DIFF 288 extern FFSTYPE fflval; skycat-3.1.2-starlink-1b/astrotcl/cfitsio/eval_y.c000066400000000000000000007101261215713201500220620ustar00rootroot00000000000000 /* A Bison parser, made from eval.y by GNU Bison version 1.25 */ #define FFBISON 1 /* Identify Bison output. */ #define BOOLEAN 258 #define LONG 259 #define DOUBLE 260 #define STRING 261 #define BITSTR 262 #define FUNCTION 263 #define BFUNCTION 264 #define GTIFILTER 265 #define REGFILTER 266 #define COLUMN 267 #define BCOLUMN 268 #define SCOLUMN 269 #define BITCOL 270 #define ROWREF 271 #define NULLREF 272 #define SNULLREF 273 #define OR 274 #define AND 275 #define EQ 276 #define NE 277 #define GT 278 #define LT 279 #define LTE 280 #define GTE 281 #define POWER 282 #define NOT 283 #define INTCAST 284 #define FLTCAST 285 #define UMINUS 286 #define ACCUM 287 #define DIFF 288 #line 1 "eval.y" /************************************************************************/ /* */ /* CFITSIO Lexical Parser */ /* */ /* This file is one of 3 files containing code which parses an */ /* arithmetic expression and evaluates it in the context of an input */ /* FITS file table extension. The CFITSIO lexical parser is divided */ /* into the following 3 parts/files: the CFITSIO "front-end", */ /* eval_f.c, contains the interface between the user/CFITSIO and the */ /* real core of the parser; the FLEX interpreter, eval_l.c, takes the */ /* input string and parses it into tokens and identifies the FITS */ /* information required to evaluate the expression (ie, keywords and */ /* columns); and, the BISON grammar and evaluation routines, eval_y.c, */ /* receives the FLEX output and determines and performs the actual */ /* operations. The files eval_l.c and eval_y.c are produced from */ /* running flex and bison on the files eval.l and eval.y, respectively. */ /* (flex and bison are available from any GNU archive: see www.gnu.org) */ /* */ /* The grammar rules, rather than evaluating the expression in situ, */ /* builds a tree, or Nodal, structure mapping out the order of */ /* operations and expression dependencies. This "compilation" process */ /* allows for much faster processing of multiple rows. This technique */ /* was developed by Uwe Lammers of the XMM Science Analysis System, */ /* although the CFITSIO implementation is entirely code original. */ /* */ /* */ /* Modification History: */ /* */ /* Kent Blackburn c1992 Original parser code developed for the */ /* FTOOLS software package, in particular, */ /* the fselect task. */ /* Kent Blackburn c1995 BIT column support added */ /* Peter D Wilson Feb 1998 Vector column support added */ /* Peter D Wilson May 1998 Ported to CFITSIO library. User */ /* interface routines written, in essence */ /* making fselect, fcalc, and maketime */ /* capabilities available to all tools */ /* via single function calls. */ /* Peter D Wilson Jun 1998 Major rewrite of parser core, so as to */ /* create a run-time evaluation tree, */ /* inspired by the work of Uwe Lammers, */ /* resulting in a speed increase of */ /* 10-100 times. */ /* Peter D Wilson Jul 1998 gtifilter(a,b,c,d) function added */ /* Peter D Wilson Aug 1998 regfilter(a,b,c,d) function added */ /* Peter D Wilson Jul 1999 Make parser fitsfile-independent, */ /* allowing a purely vector-based usage */ /* Craig B Markwardt Jun 2004 Add MEDIAN() function */ /* Craig B Markwardt Jun 2004 Add SUM(), and MIN/MAX() for bit arrays */ /* Craig B Markwardt Jun 2004 Allow subscripting of nX bit arrays */ /* Craig B Markwardt Jun 2004 Implement statistical functions */ /* NVALID(), AVERAGE(), and STDDEV() */ /* for integer and floating point vectors */ /* Craig B Markwardt Jun 2004 Use NULL values for range errors instead*/ /* of throwing a parse error */ /* Craig B Markwardt Oct 2004 Add ACCUM() and SEQDIFF() functions */ /* Craig B Markwardt Feb 2005 Add ANGSEP() function */ /* Craig B Markwardt Aug 2005 CIRCLE, BOX, ELLIPSE, NEAR and REGFILTER*/ /* functions now accept vector arguments */ /* Craig B Markwardt Sum 2006 Add RANDOMN() and RANDOMP() functions */ /* Craig B Markwardt Mar 2007 Allow arguments to RANDOM and RANDOMN to*/ /* determine the output dimensions */ /* */ /************************************************************************/ #define APPROX 1.0e-7 #include "eval_defs.h" #include "region.h" #include #include #ifndef alloca #define alloca malloc #endif /* Shrink the initial stack depth to keep local data <32K (mac limit) */ /* yacc will allocate more space if needed, though. */ #define FFINITDEPTH 100 /***************************************************************/ /* Replace Bison's BACKUP macro with one that fixes a bug -- */ /* must update state after popping the stack -- and allows */ /* popping multiple terms at one time. */ /***************************************************************/ #define FFNEWBACKUP(token, value) \ do \ if (ffchar == FFEMPTY ) \ { ffchar = (token); \ memcpy( &fflval, &(value), sizeof(value) ); \ ffchar1 = FFTRANSLATE (ffchar); \ while (fflen--) FFPOPSTACK; \ ffstate = *ffssp; \ goto ffbackup; \ } \ else \ { fferror ("syntax error: cannot back up"); FFERROR; } \ while (0) /***************************************************************/ /* Useful macros for accessing/testing Nodes */ /***************************************************************/ #define TEST(a) if( (a)<0 ) FFERROR #define SIZE(a) gParse.Nodes[ a ].value.nelem #define TYPE(a) gParse.Nodes[ a ].type #define PROMOTE(a,b) if( TYPE(a) > TYPE(b) ) \ b = New_Unary( TYPE(a), 0, b ); \ else if( TYPE(a) < TYPE(b) ) \ a = New_Unary( TYPE(b), 0, a ); /***** Internal functions *****/ #ifdef __cplusplus extern "C" { #endif static int Alloc_Node ( void ); static void Free_Last_Node( void ); static void Evaluate_Node ( int thisNode ); static int New_Const ( int returnType, void *value, long len ); static int New_Column( int ColNum ); static int New_Offset( int ColNum, int offset ); static int New_Unary ( int returnType, int Op, int Node1 ); static int New_BinOp ( int returnType, int Node1, int Op, int Node2 ); static int New_Func ( int returnType, funcOp Op, int nNodes, int Node1, int Node2, int Node3, int Node4, int Node5, int Node6, int Node7 ); static int New_Deref ( int Var, int nDim, int Dim1, int Dim2, int Dim3, int Dim4, int Dim5 ); static int New_GTI ( char *fname, int Node1, char *start, char *stop ); static int New_REG ( char *fname, int NodeX, int NodeY, char *colNames ); static int New_Vector( int subNode ); static int Close_Vec ( int vecNode ); static int Locate_Col( Node *this ); static int Test_Dims ( int Node1, int Node2 ); static void Copy_Dims ( int Node1, int Node2 ); static void Allocate_Ptrs( Node *this ); static void Do_Unary ( Node *this ); static void Do_Offset ( Node *this ); static void Do_BinOp_bit ( Node *this ); static void Do_BinOp_str ( Node *this ); static void Do_BinOp_log ( Node *this ); static void Do_BinOp_lng ( Node *this ); static void Do_BinOp_dbl ( Node *this ); static void Do_Func ( Node *this ); static void Do_Deref ( Node *this ); static void Do_GTI ( Node *this ); static void Do_REG ( Node *this ); static void Do_Vector ( Node *this ); static long Search_GTI ( double evtTime, long nGTI, double *start, double *stop, int ordered ); static char saobox (double xcen, double ycen, double xwid, double ywid, double rot, double xcol, double ycol); static char ellipse(double xcen, double ycen, double xrad, double yrad, double rot, double xcol, double ycol); static char circle (double xcen, double ycen, double rad, double xcol, double ycol); static char bnear (double x, double y, double tolerance); static char bitcmp (char *bitstrm1, char *bitstrm2); static char bitlgte(char *bits1, int oper, char *bits2); static void bitand(char *result, char *bitstrm1, char *bitstrm2); static void bitor (char *result, char *bitstrm1, char *bitstrm2); static void bitnot(char *result, char *bits); static void fferror(char *msg); #ifdef __cplusplus } #endif #line 181 "eval.y" typedef union { int Node; /* Index of Node */ double dbl; /* real value */ long lng; /* integer value */ char log; /* logical value */ char str[256]; /* string value */ } FFSTYPE; #include #ifndef __cplusplus #ifndef __STDC__ #define const #endif #endif #define FFFINAL 281 #define FFFLAG -32768 #define FFNTBASE 53 #define FFTRANSLATE(x) ((unsigned)(x) <= 288 ? fftranslate[x] : 61) static const char fftranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 40, 2, 51, 52, 37, 34, 19, 35, 2, 38, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 21, 2, 2, 20, 2, 24, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 46, 2, 50, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 39, 23, 29, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 25, 26, 27, 28, 30, 31, 32, 33, 41, 42, 43, 44, 45, 47, 48 }; #if FFDEBUG != 0 static const short ffprhs[] = { 0, 0, 1, 4, 6, 9, 12, 15, 18, 21, 24, 28, 31, 35, 39, 43, 46, 49, 51, 53, 58, 62, 66, 70, 75, 82, 91, 102, 115, 118, 122, 124, 126, 128, 133, 135, 137, 141, 145, 149, 153, 157, 161, 164, 167, 171, 175, 179, 185, 191, 197, 200, 204, 208, 212, 216, 222, 232, 237, 244, 253, 264, 277, 280, 283, 286, 289, 291, 293, 298, 302, 306, 310, 314, 318, 322, 326, 330, 334, 338, 342, 346, 350, 354, 358, 362, 366, 370, 374, 378, 382, 386, 390, 396, 402, 406, 410, 414, 420, 428, 440, 456, 459, 463, 469, 479, 483, 491, 501, 506, 513, 522, 533, 546, 549, 553, 555, 557, 562, 564, 568, 572, 578 }; static const short ffrhs[] = { -1, 53, 54, 0, 49, 0, 57, 49, 0, 58, 49, 0, 60, 49, 0, 59, 49, 0, 1, 49, 0, 22, 58, 0, 55, 19, 58, 0, 22, 57, 0, 56, 19, 57, 0, 56, 19, 58, 0, 55, 19, 57, 0, 56, 23, 0, 55, 23, 0, 7, 0, 15, 0, 15, 22, 57, 23, 0, 59, 40, 59, 0, 59, 39, 59, 0, 59, 34, 59, 0, 59, 46, 57, 50, 0, 59, 46, 57, 19, 57, 50, 0, 59, 46, 57, 19, 57, 19, 57, 50, 0, 59, 46, 57, 19, 57, 19, 57, 19, 57, 50, 0, 59, 46, 57, 19, 57, 19, 57, 19, 57, 19, 57, 50, 0, 42, 59, 0, 51, 59, 52, 0, 4, 0, 5, 0, 12, 0, 12, 22, 57, 23, 0, 16, 0, 17, 0, 57, 36, 57, 0, 57, 34, 57, 0, 57, 35, 57, 0, 57, 37, 57, 0, 57, 38, 57, 0, 57, 41, 57, 0, 34, 57, 0, 35, 57, 0, 51, 57, 52, 0, 57, 37, 58, 0, 58, 37, 57, 0, 58, 24, 57, 21, 57, 0, 58, 24, 58, 21, 57, 0, 58, 24, 57, 21, 58, 0, 8, 52, 0, 8, 58, 52, 0, 8, 60, 52, 0, 8, 59, 52, 0, 8, 57, 52, 0, 8, 57, 19, 57, 52, 0, 8, 57, 19, 57, 19, 57, 19, 57, 52, 0, 57, 46, 57, 50, 0, 57, 46, 57, 19, 57, 50, 0, 57, 46, 57, 19, 57, 19, 57, 50, 0, 57, 46, 57, 19, 57, 19, 57, 19, 57, 50, 0, 57, 46, 57, 19, 57, 19, 57, 19, 57, 19, 57, 50, 0, 43, 57, 0, 43, 58, 0, 44, 57, 0, 44, 58, 0, 3, 0, 13, 0, 13, 22, 57, 23, 0, 59, 27, 59, 0, 59, 28, 59, 0, 59, 31, 59, 0, 59, 32, 59, 0, 59, 30, 59, 0, 59, 33, 59, 0, 57, 30, 57, 0, 57, 31, 57, 0, 57, 33, 57, 0, 57, 32, 57, 0, 57, 29, 57, 0, 57, 27, 57, 0, 57, 28, 57, 0, 60, 27, 60, 0, 60, 28, 60, 0, 60, 30, 60, 0, 60, 33, 60, 0, 60, 31, 60, 0, 60, 32, 60, 0, 58, 26, 58, 0, 58, 25, 58, 0, 58, 27, 58, 0, 58, 28, 58, 0, 57, 20, 57, 21, 57, 0, 58, 24, 58, 21, 58, 0, 9, 57, 52, 0, 9, 58, 52, 0, 9, 60, 52, 0, 8, 58, 19, 58, 52, 0, 9, 57, 19, 57, 19, 57, 52, 0, 9, 57, 19, 57, 19, 57, 19, 57, 19, 57, 52, 0, 9, 57, 19, 57, 19, 57, 19, 57, 19, 57, 19, 57, 19, 57, 52, 0, 10, 52, 0, 10, 6, 52, 0, 10, 6, 19, 57, 52, 0, 10, 6, 19, 57, 19, 6, 19, 6, 52, 0, 11, 6, 52, 0, 11, 6, 19, 57, 19, 57, 52, 0, 11, 6, 19, 57, 19, 57, 19, 6, 52, 0, 58, 46, 57, 50, 0, 58, 46, 57, 19, 57, 50, 0, 58, 46, 57, 19, 57, 19, 57, 50, 0, 58, 46, 57, 19, 57, 19, 57, 19, 57, 50, 0, 58, 46, 57, 19, 57, 19, 57, 19, 57, 19, 57, 50, 0, 42, 58, 0, 51, 58, 52, 0, 6, 0, 14, 0, 14, 22, 57, 23, 0, 18, 0, 51, 60, 52, 0, 60, 34, 60, 0, 58, 24, 60, 21, 60, 0, 8, 60, 19, 60, 52, 0 }; #endif #if FFDEBUG != 0 static const short ffrline[] = { 0, 232, 233, 236, 237, 243, 249, 255, 261, 264, 266, 279, 281, 294, 305, 319, 323, 327, 332, 334, 343, 346, 349, 352, 354, 356, 358, 360, 362, 365, 369, 371, 373, 375, 384, 386, 388, 391, 394, 397, 400, 403, 406, 408, 410, 412, 416, 420, 439, 458, 477, 490, 504, 516, 541, 637, 689, 713, 715, 717, 719, 721, 723, 725, 727, 729, 733, 735, 737, 746, 749, 752, 755, 758, 761, 764, 767, 770, 773, 776, 779, 782, 785, 788, 791, 794, 797, 800, 803, 805, 807, 809, 812, 819, 836, 849, 862, 873, 889, 913, 941, 978, 982, 986, 989, 993, 997, 1000, 1004, 1006, 1008, 1010, 1012, 1014, 1016, 1020, 1023, 1025, 1034, 1036, 1038, 1041, 1053 }; #endif #if FFDEBUG != 0 || defined (FFERROR_VERBOSE) static const char * const fftname[] = { "$","error","$undefined.","BOOLEAN", "LONG","DOUBLE","STRING","BITSTR","FUNCTION","BFUNCTION","GTIFILTER","REGFILTER", "COLUMN","BCOLUMN","SCOLUMN","BITCOL","ROWREF","NULLREF","SNULLREF","','","'='", "':'","'{'","'}'","'?'","OR","AND","EQ","NE","'~'","GT","LT","LTE","GTE","'+'", "'-'","'%'","'*'","'/'","'|'","'&'","POWER","NOT","INTCAST","FLTCAST","UMINUS", "'['","ACCUM","DIFF","'\\n'","']'","'('","')'","lines","line","bvector","vector", "expr","bexpr","bits","sexpr", NULL }; #endif static const short ffr1[] = { 0, 53, 53, 54, 54, 54, 54, 54, 54, 55, 55, 56, 56, 56, 56, 57, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 60, 60, 60, 60, 60, 60, 60, 60 }; static const short ffr2[] = { 0, 0, 2, 1, 2, 2, 2, 2, 2, 2, 3, 2, 3, 3, 3, 2, 2, 1, 1, 4, 3, 3, 3, 4, 6, 8, 10, 12, 2, 3, 1, 1, 1, 4, 1, 1, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 3, 5, 5, 5, 2, 3, 3, 3, 3, 5, 9, 4, 6, 8, 10, 12, 2, 2, 2, 2, 1, 1, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 3, 3, 3, 5, 7, 11, 15, 2, 3, 5, 9, 3, 7, 9, 4, 6, 8, 10, 12, 2, 3, 1, 1, 4, 1, 3, 3, 5, 5 }; static const short ffdefact[] = { 1, 0, 0, 66, 30, 31, 115, 17, 0, 0, 0, 0, 32, 67, 116, 18, 34, 35, 118, 0, 0, 0, 0, 0, 0, 3, 0, 2, 0, 0, 0, 0, 0, 0, 8, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 11, 9, 0, 42, 0, 43, 0, 113, 28, 62, 63, 64, 65, 0, 0, 0, 0, 0, 16, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 6, 0, 54, 0, 51, 53, 0, 52, 0, 94, 95, 96, 0, 102, 0, 105, 0, 0, 0, 0, 44, 114, 29, 119, 14, 10, 12, 13, 0, 80, 81, 79, 75, 76, 78, 77, 37, 38, 36, 39, 45, 40, 41, 0, 0, 0, 0, 89, 88, 90, 91, 46, 0, 0, 0, 69, 70, 73, 71, 72, 74, 22, 21, 20, 0, 82, 83, 84, 86, 87, 85, 120, 0, 0, 0, 0, 0, 0, 33, 68, 117, 19, 0, 0, 57, 0, 0, 0, 0, 108, 28, 0, 0, 23, 0, 55, 97, 122, 0, 0, 103, 0, 92, 0, 47, 49, 48, 93, 121, 0, 0, 0, 0, 0, 0, 0, 58, 0, 109, 0, 24, 0, 0, 98, 0, 0, 106, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 110, 0, 25, 56, 0, 104, 107, 0, 0, 0, 0, 0, 60, 0, 111, 0, 26, 0, 99, 0, 0, 0, 0, 61, 112, 27, 0, 0, 100, 0, 0 }; static const short ffdefgoto[] = { 1, 27, 28, 29, 57, 55, 42, 53 }; static const short ffpact[] = {-32768, 294, -20,-32768,-32768,-32768,-32768,-32768, 343, 393, -2, 24, 2, 33, 41, 43,-32768,-32768,-32768, 393, 393, 393, 393, 393, 393,-32768, 393,-32768, 8, 67, 1056, 213, 1336, -17,-32768,-32768, 419, 16, 287, 122, 447, 72, 1376, 389, -14,-32768, -13, 393, 393, 393, 393, 1303, 218, 1423, 45, 218, 45, 1303, 57, 59, 45, 57, 45, 57, 614, 140, 336, 1320, 393,-32768, 393, -32768, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393,-32768, 393, 393, 393, 393, 393, 393, 393,-32768, -6, -6, -6, -6, -6, -6, -6, -6, -6, 393,-32768, 393, 393, 393, 393, 393, 393, 393,-32768, 393,-32768, 393,-32768,-32768, 393, -32768, 393,-32768,-32768,-32768, 393,-32768, 393,-32768, 1179, 1199, 1219, 1239,-32768,-32768,-32768,-32768, 1303, 218, 1303, 218, 1261, 1393, 1393, 1393, 1406, 1406, 1406, 1406, 134, 134, 134, 15, 57, 15, 15, 696, 1283, 245, 247, 132, -25, -9, -9, 15, 720, -6, -6, 20, 20, 20, 20, 20, 20, 49, 59, 59, 744, 253, 253, 73, 73, 73, 73,-32768, 475, 163, 1328, 1079, 503, 1099,-32768,-32768,-32768,-32768, 393, 393,-32768, 393, 393, 393, 393,-32768, 59, 18, 393,-32768, 393,-32768,-32768, -32768, 393, 100,-32768, 393, 1359, 768, 1359, 218, 1359, 218, 1423, 792, 816, 1119, 531, 89, 559, 393,-32768, 393,-32768, 393,-32768, 393, 393,-32768, 104, 105,-32768, 840, 864, 888, 641, 1139, 68, 71, 393,-32768, 393, -32768, 393,-32768,-32768, 393,-32768,-32768, 912, 936, 960, 587, 393,-32768, 393,-32768, 393,-32768, 393,-32768, 984, 1008, 1032, 1159,-32768,-32768,-32768, 393, 668,-32768, 126, -32768 }; static const short ffpgoto[] = {-32768, -32768,-32768,-32768, -1, 93, 121, 25 }; #define FFLAST 1457 static const short fftable[] = { 30, 7, 91, 92, 44, 126, 128, 36, 40, 15, 107, 108, 93, 109, 110, 111, 112, 113, 51, 54, 56, 94, 60, 62, 47, 64, 33, 68, 93, 34, 46, 69, 114, 39, 43, 117, 167, 94, 127, 129, 88, 89, 90, 91, 92, 168, 130, 131, 132, 133, 45, 67, 102, 93, 102, 48, 85, 103, 104, 103, 104, 86, 94, 49, 105, 50, 105, 138, 118, 140, 136, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 155, 156, 157, 70, 158, 103, 104, 71, 86, 165, 166, 31, 105, 88, 89, 90, 91, 92, 37, 41, 94, 178, 105, 227, 113, 238, 93, 246, 247, 52, 160, 186, 58, 61, 63, 94, 65, 256, 189, 32, 257, 124, 190, 281, 191, 0, 38, 0, 0, 179, 180, 181, 182, 183, 184, 185, 0, 0, 120, 0, 59, 0, 188, 0, 66, 0, 107, 108, 0, 109, 110, 111, 112, 113, 0, 90, 91, 92, 139, 0, 141, 88, 89, 90, 91, 92, 93, 0, 83, 84, 0, 121, 85, 154, 93, 94, 0, 86, 159, 161, 162, 163, 164, 94, 88, 89, 90, 91, 92, 135, 0, 0, 216, 217, 0, 218, 220, 93, 223, 0, 0, 0, 224, 0, 225, 0, 94, 187, 226, 0, 0, 228, 210, 0, 169, 170, 171, 172, 173, 174, 175, 176, 177, 222, 0, 241, 0, 242, 0, 243, 0, 244, 245, 0, 88, 89, 90, 91, 92, 88, 89, 90, 91, 92, 258, 0, 259, 93, 260, 0, 0, 261, 93, 0, 0, 0, 94, 0, 270, 95, 271, 94, 272, 200, 273, 201, 88, 89, 90, 91, 92, 107, 108, 278, 109, 110, 111, 112, 113, 93, 109, 110, 111, 112, 113, 204, 205, 0, 94, 219, 221, 280, 2, 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 96, 97, 19, 98, 99, 100, 101, 102, 0, 0, 0, 0, 103, 104, 20, 21, 0, 0, 0, 105, 0, 0, 22, 23, 24, 119, 0, 0, 0, 25, 0, 26, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 96, 97, 19, 98, 99, 100, 101, 102, 0, 0, 0, 0, 103, 104, 20, 21, 0, 0, 0, 105, 0, 0, 22, 23, 24, 136, 0, 0, 0, 0, 0, 26, 35, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 19, 107, 108, 0, 109, 110, 111, 112, 113, 0, 0, 0, 20, 21, 0, 0, 0, 0, 0, 0, 22, 23, 24, 115, 72, 0, 125, 0, 0, 26, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 122, 72, 0, 0, 0, 116, 0, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 208, 72, 0, 0, 0, 123, 0, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 213, 72, 0, 0, 0, 209, 0, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 236, 72, 0, 0, 0, 214, 0, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 239, 72, 0, 0, 0, 237, 0, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 268, 72, 0, 0, 0, 240, 0, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 72, 0, 0, 0, 0, 269, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 72, 0, 0, 0, 0, 134, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 72, 0, 0, 0, 0, 254, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 197, 72, 0, 0, 0, 279, 0, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 202, 72, 0, 86, 0, 0, 0, 198, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 206, 72, 0, 86, 0, 0, 0, 203, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 229, 72, 0, 86, 0, 0, 0, 207, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 231, 72, 0, 86, 0, 0, 0, 230, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 233, 72, 0, 86, 0, 0, 0, 232, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 248, 72, 0, 86, 0, 0, 0, 234, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 250, 72, 0, 86, 0, 0, 0, 249, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 252, 72, 0, 86, 0, 0, 0, 251, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 262, 72, 0, 86, 0, 0, 0, 253, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 264, 72, 0, 86, 0, 0, 0, 263, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 266, 72, 0, 86, 0, 0, 0, 265, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 72, 0, 86, 0, 0, 0, 267, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 72, 0, 86, 0, 0, 0, 274, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 72, 0, 86, 0, 0, 0, 275, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 72, 0, 86, 0, 0, 0, 276, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 212, 72, 0, 0, 86, 0, 0, 87, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 215, 72, 85, 0, 0, 0, 0, 86, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 235, 72, 85, 0, 0, 0, 0, 86, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 255, 72, 85, 0, 0, 0, 0, 86, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 277, 72, 85, 0, 0, 0, 0, 86, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 72, 85, 0, 192, 0, 0, 86, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 72, 85, 0, 193, 0, 0, 86, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 72, 85, 0, 194, 0, 0, 86, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 72, 85, 0, 195, 0, 0, 86, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 72, 196, 0, 0, 86, 0, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 72, 199, 0, 0, 86, 0, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 72, 85, 0, 0, 0, 0, 86, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 107, 108, 86, 109, 110, 111, 112, 113, 107, 108, 0, 109, 110, 111, 112, 113, 96, 97, 0, 98, 99, 100, 101, 102, 0, 137, 0, 0, 103, 104, 0, 0, 0, 211, 0, 105, 0, 0, 106, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 96, 97, 86, 98, 99, 100, 101, 102, 0, 0, 0, 0, 103, 104, 0, 0, 0, 0, 0, 105, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 107, 108, 86, 109, 110, 111, 112, 113 }; static const short ffcheck[] = { 1, 7, 27, 28, 6, 19, 19, 8, 9, 15, 27, 28, 37, 30, 31, 32, 33, 34, 19, 20, 21, 46, 23, 24, 22, 26, 1, 19, 37, 49, 6, 23, 49, 8, 9, 19, 42, 46, 52, 52, 24, 25, 26, 27, 28, 51, 47, 48, 49, 50, 52, 26, 34, 37, 34, 22, 41, 39, 40, 39, 40, 46, 46, 22, 46, 22, 46, 68, 52, 70, 52, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 19, 88, 39, 40, 23, 46, 93, 94, 1, 46, 24, 25, 26, 27, 28, 8, 9, 46, 105, 46, 6, 34, 19, 37, 6, 6, 19, 88, 115, 22, 23, 24, 46, 26, 52, 122, 1, 52, 52, 126, 0, 128, -1, 8, -1, -1, 107, 108, 109, 110, 111, 112, 113, -1, -1, 19, -1, 22, -1, 120, -1, 26, -1, 27, 28, -1, 30, 31, 32, 33, 34, -1, 26, 27, 28, 68, -1, 70, 24, 25, 26, 27, 28, 37, -1, 37, 38, -1, 52, 41, 83, 37, 46, -1, 46, 88, 89, 90, 91, 92, 46, 24, 25, 26, 27, 28, 52, -1, -1, 196, 197, -1, 199, 200, 37, 202, -1, -1, -1, 206, -1, 208, -1, 46, 117, 212, -1, -1, 215, 52, -1, 96, 97, 98, 99, 100, 101, 102, 103, 104, 201, -1, 229, -1, 231, -1, 233, -1, 235, 236, -1, 24, 25, 26, 27, 28, 24, 25, 26, 27, 28, 248, -1, 250, 37, 252, -1, -1, 255, 37, -1, -1, -1, 46, -1, 262, 49, 264, 46, 266, 21, 268, 21, 24, 25, 26, 27, 28, 27, 28, 277, 30, 31, 32, 33, 34, 37, 30, 31, 32, 33, 34, 167, 168, -1, 46, 199, 200, 0, 1, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, 27, 28, 22, 30, 31, 32, 33, 34, -1, -1, -1, -1, 39, 40, 34, 35, -1, -1, -1, 46, -1, -1, 42, 43, 44, 52, -1, -1, -1, 49, -1, 51, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, 27, 28, 22, 30, 31, 32, 33, 34, -1, -1, -1, -1, 39, 40, 34, 35, -1, -1, -1, 46, -1, -1, 42, 43, 44, 52, -1, -1, -1, -1, -1, 51, 52, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, 22, 27, 28, -1, 30, 31, 32, 33, 34, -1, -1, -1, 34, 35, -1, -1, -1, -1, -1, -1, 42, 43, 44, 19, 20, -1, 52, -1, -1, 51, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 19, 20, -1, -1, -1, 52, -1, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 19, 20, -1, -1, -1, 52, -1, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 19, 20, -1, -1, -1, 52, -1, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 19, 20, -1, -1, -1, 52, -1, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 19, 20, -1, -1, -1, 52, -1, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 19, 20, -1, -1, -1, 52, -1, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 20, -1, -1, -1, -1, 52, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 20, -1, -1, -1, -1, 52, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 20, -1, -1, -1, -1, 52, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 19, 20, -1, -1, -1, 52, -1, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, 19, 20, -1, -1, 46, -1, -1, 49, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 19, 20, 41, -1, -1, -1, -1, 46, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 19, 20, 41, -1, -1, -1, -1, 46, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 19, 20, 41, -1, -1, -1, -1, 46, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 19, 20, 41, -1, -1, -1, -1, 46, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, 20, 41, -1, 23, -1, -1, 46, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, 20, 41, -1, 23, -1, -1, 46, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, 20, 41, -1, 23, -1, -1, 46, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, 20, 41, -1, 23, -1, -1, 46, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, 20, 21, -1, -1, 46, -1, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, 20, 21, -1, -1, 46, -1, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, 20, 41, -1, -1, -1, -1, 46, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, 27, 28, 46, 30, 31, 32, 33, 34, 27, 28, -1, 30, 31, 32, 33, 34, 27, 28, -1, 30, 31, 32, 33, 34, -1, 52, -1, -1, 39, 40, -1, -1, -1, 52, -1, 46, -1, -1, 49, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, 27, 28, 46, 30, 31, 32, 33, 34, -1, -1, -1, -1, 39, 40, -1, -1, -1, -1, -1, 46, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, 27, 28, 46, 30, 31, 32, 33, 34 }; /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ #line 3 "/usr1/local/share/bison.simple" /* Skeleton output parser for bison, Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* As a special exception, when this file is copied by Bison into a Bison output file, you may use that output file without restriction. This special exception was added by the Free Software Foundation in version 1.24 of Bison. */ #ifndef alloca #ifdef __GNUC__ #define alloca __builtin_alloca #else /* not GNU C. */ #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) #include #else /* not sparc */ #if defined (MSDOS) && !defined (__TURBOC__) #include #else /* not MSDOS, or __TURBOC__ */ #if defined(_AIX) #include #pragma alloca #else /* not MSDOS, __TURBOC__, or _AIX */ #ifdef __hpux #ifdef __cplusplus extern "C" { void *alloca (unsigned int); }; #else /* not __cplusplus */ void *alloca (); #endif /* not __cplusplus */ #endif /* __hpux */ #endif /* not _AIX */ #endif /* not MSDOS, or __TURBOC__ */ #endif /* not sparc. */ #endif /* not GNU C. */ #endif /* alloca not defined. */ /* This is the parser code that is written into each bison parser when the %semantic_parser declaration is not specified in the grammar. It was written by Richard Stallman by simplifying the hairy parser used when %semantic_parser is specified. */ /* Note: there must be only one dollar sign in this file. It is replaced by the list of actions, each action as one case of the switch. */ #define fferrok (fferrstatus = 0) #define ffclearin (ffchar = FFEMPTY) #define FFEMPTY -2 #define FFEOF 0 #define FFACCEPT return(0) #define FFABORT return(1) #define FFERROR goto fferrlab1 /* Like FFERROR except do call fferror. This remains here temporarily to ease the transition to the new meaning of FFERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define FFFAIL goto fferrlab #define FFRECOVERING() (!!fferrstatus) #define FFBACKUP(token, value) \ do \ if (ffchar == FFEMPTY && fflen == 1) \ { ffchar = (token), fflval = (value); \ ffchar1 = FFTRANSLATE (ffchar); \ FFPOPSTACK; \ goto ffbackup; \ } \ else \ { fferror ("syntax error: cannot back up"); FFERROR; } \ while (0) #define FFTERROR 1 #define FFERRCODE 256 #ifndef FFPURE #define FFLEX fflex() #endif #ifdef FFPURE #ifdef FFLSP_NEEDED #ifdef FFLEX_PARAM #define FFLEX fflex(&fflval, &fflloc, FFLEX_PARAM) #else #define FFLEX fflex(&fflval, &fflloc) #endif #else /* not FFLSP_NEEDED */ #ifdef FFLEX_PARAM #define FFLEX fflex(&fflval, FFLEX_PARAM) #else #define FFLEX fflex(&fflval) #endif #endif /* not FFLSP_NEEDED */ #endif /* If nonreentrant, generate the variables here */ #ifndef FFPURE int ffchar; /* the lookahead symbol */ FFSTYPE fflval; /* the semantic value of the */ /* lookahead symbol */ #ifdef FFLSP_NEEDED FFLTYPE fflloc; /* location data for the lookahead */ /* symbol */ #endif int ffnerrs; /* number of parse errors so far */ #endif /* not FFPURE */ #if FFDEBUG != 0 int ffdebug; /* nonzero means print parse trace */ /* Since this is uninitialized, it does not stop multiple parsers from coexisting. */ #endif /* FFINITDEPTH indicates the initial size of the parser's stacks */ #ifndef FFINITDEPTH #define FFINITDEPTH 200 #endif /* FFMAXDEPTH is the maximum size the stacks can grow to (effective only if the built-in stack extension method is used). */ #if FFMAXDEPTH == 0 #undef FFMAXDEPTH #endif #ifndef FFMAXDEPTH #define FFMAXDEPTH 10000 #endif /* Prevent warning if -Wstrict-prototypes. */ #ifdef __GNUC__ int ffparse (void); #endif #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ #define __ff_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) #else /* not GNU C or C++ */ #ifndef __cplusplus /* This is the most reliable way to avoid incompatibilities in available built-in functions on various systems. */ static void __ff_memcpy (to, from, count) char *to; char *from; int count; { register char *f = from; register char *t = to; register int i = count; while (i-- > 0) *t++ = *f++; } #else /* __cplusplus */ /* This is the most reliable way to avoid incompatibilities in available built-in functions on various systems. */ static void __ff_memcpy (char *to, char *from, int count) { register char *f = from; register char *t = to; register int i = count; while (i-- > 0) *t++ = *f++; } #endif #endif #line 196 "/usr1/local/share/bison.simple" /* The user can define FFPARSE_PARAM as the name of an argument to be passed into ffparse. The argument should have type void *. It should actually point to an object. Grammar actions can access the variable by casting it to the proper pointer type. */ #ifdef FFPARSE_PARAM #ifdef __cplusplus #define FFPARSE_PARAM_ARG void *FFPARSE_PARAM #define FFPARSE_PARAM_DECL #else /* not __cplusplus */ #define FFPARSE_PARAM_ARG FFPARSE_PARAM #define FFPARSE_PARAM_DECL void *FFPARSE_PARAM; #endif /* not __cplusplus */ #else /* not FFPARSE_PARAM */ #define FFPARSE_PARAM_ARG #define FFPARSE_PARAM_DECL #endif /* not FFPARSE_PARAM */ int ffparse(FFPARSE_PARAM_ARG) FFPARSE_PARAM_DECL { register int ffstate; register int ffn; register short *ffssp; register FFSTYPE *ffvsp; int fferrstatus; /* number of tokens to shift before error messages enabled */ int ffchar1 = 0; /* lookahead token as an internal (translated) token number */ short ffssa[FFINITDEPTH]; /* the state stack */ FFSTYPE ffvsa[FFINITDEPTH]; /* the semantic value stack */ short *ffss = ffssa; /* refer to the stacks thru separate pointers */ FFSTYPE *ffvs = ffvsa; /* to allow ffoverflow to reallocate them elsewhere */ #ifdef FFLSP_NEEDED FFLTYPE fflsa[FFINITDEPTH]; /* the location stack */ FFLTYPE *ffls = fflsa; FFLTYPE *fflsp; #define FFPOPSTACK (ffvsp--, ffssp--, fflsp--) #else #define FFPOPSTACK (ffvsp--, ffssp--) #endif int ffstacksize = FFINITDEPTH; #ifdef FFPURE int ffchar; FFSTYPE fflval; int ffnerrs; #ifdef FFLSP_NEEDED FFLTYPE fflloc; #endif #endif FFSTYPE ffval; /* the variable used to return */ /* semantic values from the action */ /* routines */ int fflen; #if FFDEBUG != 0 if (ffdebug) fprintf(stderr, "Starting parse\n"); #endif ffstate = 0; fferrstatus = 0; ffnerrs = 0; ffchar = FFEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ ffssp = ffss - 1; ffvsp = ffvs; #ifdef FFLSP_NEEDED fflsp = ffls; #endif /* Push a new state, which is found in ffstate . */ /* In all cases, when you get here, the value and location stacks have just been pushed. so pushing a state here evens the stacks. */ ffnewstate: *++ffssp = ffstate; if (ffssp >= ffss + ffstacksize - 1) { /* Give user a chance to reallocate the stack */ /* Use copies of these so that the &'s don't force the real ones into memory. */ FFSTYPE *ffvs1 = ffvs; short *ffss1 = ffss; #ifdef FFLSP_NEEDED FFLTYPE *ffls1 = ffls; #endif /* Get the current used size of the three stacks, in elements. */ int size = ffssp - ffss + 1; #ifdef ffoverflow /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. */ #ifdef FFLSP_NEEDED /* This used to be a conditional around just the two extra args, but that might be undefined if ffoverflow is a macro. */ ffoverflow("parser stack overflow", &ffss1, size * sizeof (*ffssp), &ffvs1, size * sizeof (*ffvsp), &ffls1, size * sizeof (*fflsp), &ffstacksize); #else ffoverflow("parser stack overflow", &ffss1, size * sizeof (*ffssp), &ffvs1, size * sizeof (*ffvsp), &ffstacksize); #endif ffss = ffss1; ffvs = ffvs1; #ifdef FFLSP_NEEDED ffls = ffls1; #endif #else /* no ffoverflow */ /* Extend the stack our own way. */ if (ffstacksize >= FFMAXDEPTH) { fferror("parser stack overflow"); return 2; } ffstacksize *= 2; if (ffstacksize > FFMAXDEPTH) ffstacksize = FFMAXDEPTH; ffss = (short *) alloca (ffstacksize * sizeof (*ffssp)); __ff_memcpy ((char *)ffss, (char *)ffss1, size * sizeof (*ffssp)); ffvs = (FFSTYPE *) alloca (ffstacksize * sizeof (*ffvsp)); __ff_memcpy ((char *)ffvs, (char *)ffvs1, size * sizeof (*ffvsp)); #ifdef FFLSP_NEEDED ffls = (FFLTYPE *) alloca (ffstacksize * sizeof (*fflsp)); __ff_memcpy ((char *)ffls, (char *)ffls1, size * sizeof (*fflsp)); #endif #endif /* no ffoverflow */ ffssp = ffss + size - 1; ffvsp = ffvs + size - 1; #ifdef FFLSP_NEEDED fflsp = ffls + size - 1; #endif #if FFDEBUG != 0 if (ffdebug) fprintf(stderr, "Stack size increased to %d\n", ffstacksize); #endif if (ffssp >= ffss + ffstacksize - 1) FFABORT; } #if FFDEBUG != 0 if (ffdebug) fprintf(stderr, "Entering state %d\n", ffstate); #endif goto ffbackup; ffbackup: /* Do appropriate processing given the current state. */ /* Read a lookahead token if we need one and don't already have one. */ /* ffresume: */ /* First try to decide what to do without reference to lookahead token. */ ffn = ffpact[ffstate]; if (ffn == FFFLAG) goto ffdefault; /* Not known => get a lookahead token if don't already have one. */ /* ffchar is either FFEMPTY or FFEOF or a valid token in external form. */ if (ffchar == FFEMPTY) { #if FFDEBUG != 0 if (ffdebug) fprintf(stderr, "Reading a token: "); #endif ffchar = FFLEX; } /* Convert token to internal form (in ffchar1) for indexing tables with */ if (ffchar <= 0) /* This means end of input. */ { ffchar1 = 0; ffchar = FFEOF; /* Don't call FFLEX any more */ #if FFDEBUG != 0 if (ffdebug) fprintf(stderr, "Now at end of input.\n"); #endif } else { ffchar1 = FFTRANSLATE(ffchar); #if FFDEBUG != 0 if (ffdebug) { fprintf (stderr, "Next token is %d (%s", ffchar, fftname[ffchar1]); /* Give the individual parser a way to print the precise meaning of a token, for further debugging info. */ #ifdef FFPRINT FFPRINT (stderr, ffchar, fflval); #endif fprintf (stderr, ")\n"); } #endif } ffn += ffchar1; if (ffn < 0 || ffn > FFLAST || ffcheck[ffn] != ffchar1) goto ffdefault; ffn = fftable[ffn]; /* ffn is what to do for this token type in this state. Negative => reduce, -ffn is rule number. Positive => shift, ffn is new state. New state is final state => don't bother to shift, just return success. 0, or most negative number => error. */ if (ffn < 0) { if (ffn == FFFLAG) goto fferrlab; ffn = -ffn; goto ffreduce; } else if (ffn == 0) goto fferrlab; if (ffn == FFFINAL) FFACCEPT; /* Shift the lookahead token. */ #if FFDEBUG != 0 if (ffdebug) fprintf(stderr, "Shifting token %d (%s), ", ffchar, fftname[ffchar1]); #endif /* Discard the token being shifted unless it is eof. */ if (ffchar != FFEOF) ffchar = FFEMPTY; *++ffvsp = fflval; #ifdef FFLSP_NEEDED *++fflsp = fflloc; #endif /* count tokens shifted since error; after three, turn off error status. */ if (fferrstatus) fferrstatus--; ffstate = ffn; goto ffnewstate; /* Do the default action for the current state. */ ffdefault: ffn = ffdefact[ffstate]; if (ffn == 0) goto fferrlab; /* Do a reduction. ffn is the number of a rule to reduce with. */ ffreduce: fflen = ffr2[ffn]; if (fflen > 0) ffval = ffvsp[1-fflen]; /* implement default value of the action */ #if FFDEBUG != 0 if (ffdebug) { int i; fprintf (stderr, "Reducing via rule %d (line %d), ", ffn, ffrline[ffn]); /* Print the symbols being reduced, and their result. */ for (i = ffprhs[ffn]; ffrhs[i] > 0; i++) fprintf (stderr, "%s ", fftname[ffrhs[i]]); fprintf (stderr, " -> %s\n", fftname[ffr1[ffn]]); } #endif switch (ffn) { case 3: #line 236 "eval.y" {; break;} case 4: #line 238 "eval.y" { if( ffvsp[-1].Node<0 ) { fferror("Couldn't build node structure: out of memory?"); FFERROR; } gParse.resultNode = ffvsp[-1].Node; ; break;} case 5: #line 244 "eval.y" { if( ffvsp[-1].Node<0 ) { fferror("Couldn't build node structure: out of memory?"); FFERROR; } gParse.resultNode = ffvsp[-1].Node; ; break;} case 6: #line 250 "eval.y" { if( ffvsp[-1].Node<0 ) { fferror("Couldn't build node structure: out of memory?"); FFERROR; } gParse.resultNode = ffvsp[-1].Node; ; break;} case 7: #line 256 "eval.y" { if( ffvsp[-1].Node<0 ) { fferror("Couldn't build node structure: out of memory?"); FFERROR; } gParse.resultNode = ffvsp[-1].Node; ; break;} case 8: #line 261 "eval.y" { fferrok; ; break;} case 9: #line 265 "eval.y" { ffval.Node = New_Vector( ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 10: #line 267 "eval.y" { if( gParse.Nodes[ffvsp[-2].Node].nSubNodes >= MAXSUBS ) { ffvsp[-2].Node = Close_Vec( ffvsp[-2].Node ); TEST(ffvsp[-2].Node); ffval.Node = New_Vector( ffvsp[-2].Node ); TEST(ffval.Node); } else { ffval.Node = ffvsp[-2].Node; } gParse.Nodes[ffval.Node].SubNodes[ gParse.Nodes[ffval.Node].nSubNodes++ ] = ffvsp[0].Node; ; break;} case 11: #line 280 "eval.y" { ffval.Node = New_Vector( ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 12: #line 282 "eval.y" { if( TYPE(ffvsp[-2].Node) < TYPE(ffvsp[0].Node) ) TYPE(ffvsp[-2].Node) = TYPE(ffvsp[0].Node); if( gParse.Nodes[ffvsp[-2].Node].nSubNodes >= MAXSUBS ) { ffvsp[-2].Node = Close_Vec( ffvsp[-2].Node ); TEST(ffvsp[-2].Node); ffval.Node = New_Vector( ffvsp[-2].Node ); TEST(ffval.Node); } else { ffval.Node = ffvsp[-2].Node; } gParse.Nodes[ffval.Node].SubNodes[ gParse.Nodes[ffval.Node].nSubNodes++ ] = ffvsp[0].Node; ; break;} case 13: #line 295 "eval.y" { if( gParse.Nodes[ffvsp[-2].Node].nSubNodes >= MAXSUBS ) { ffvsp[-2].Node = Close_Vec( ffvsp[-2].Node ); TEST(ffvsp[-2].Node); ffval.Node = New_Vector( ffvsp[-2].Node ); TEST(ffval.Node); } else { ffval.Node = ffvsp[-2].Node; } gParse.Nodes[ffval.Node].SubNodes[ gParse.Nodes[ffval.Node].nSubNodes++ ] = ffvsp[0].Node; ; break;} case 14: #line 306 "eval.y" { TYPE(ffvsp[-2].Node) = TYPE(ffvsp[0].Node); if( gParse.Nodes[ffvsp[-2].Node].nSubNodes >= MAXSUBS ) { ffvsp[-2].Node = Close_Vec( ffvsp[-2].Node ); TEST(ffvsp[-2].Node); ffval.Node = New_Vector( ffvsp[-2].Node ); TEST(ffval.Node); } else { ffval.Node = ffvsp[-2].Node; } gParse.Nodes[ffval.Node].SubNodes[ gParse.Nodes[ffval.Node].nSubNodes++ ] = ffvsp[0].Node; ; break;} case 15: #line 320 "eval.y" { ffval.Node = Close_Vec( ffvsp[-1].Node ); TEST(ffval.Node); ; break;} case 16: #line 324 "eval.y" { ffval.Node = Close_Vec( ffvsp[-1].Node ); TEST(ffval.Node); ; break;} case 17: #line 328 "eval.y" { ffval.Node = New_Const( BITSTR, ffvsp[0].str, strlen(ffvsp[0].str)+1 ); TEST(ffval.Node); SIZE(ffval.Node) = strlen(ffvsp[0].str); ; break;} case 18: #line 333 "eval.y" { ffval.Node = New_Column( ffvsp[0].lng ); TEST(ffval.Node); ; break;} case 19: #line 335 "eval.y" { if( TYPE(ffvsp[-1].Node) != LONG || gParse.Nodes[ffvsp[-1].Node].operation != CONST_OP ) { fferror("Offset argument must be a constant integer"); FFERROR; } ffval.Node = New_Offset( ffvsp[-3].lng, ffvsp[-1].Node ); TEST(ffval.Node); ; break;} case 20: #line 344 "eval.y" { ffval.Node = New_BinOp( BITSTR, ffvsp[-2].Node, '&', ffvsp[0].Node ); TEST(ffval.Node); SIZE(ffval.Node) = ( SIZE(ffvsp[-2].Node)>SIZE(ffvsp[0].Node) ? SIZE(ffvsp[-2].Node) : SIZE(ffvsp[0].Node) ); ; break;} case 21: #line 347 "eval.y" { ffval.Node = New_BinOp( BITSTR, ffvsp[-2].Node, '|', ffvsp[0].Node ); TEST(ffval.Node); SIZE(ffval.Node) = ( SIZE(ffvsp[-2].Node)>SIZE(ffvsp[0].Node) ? SIZE(ffvsp[-2].Node) : SIZE(ffvsp[0].Node) ); ; break;} case 22: #line 350 "eval.y" { ffval.Node = New_BinOp( BITSTR, ffvsp[-2].Node, '+', ffvsp[0].Node ); TEST(ffval.Node); SIZE(ffval.Node) = SIZE(ffvsp[-2].Node) + SIZE(ffvsp[0].Node); ; break;} case 23: #line 353 "eval.y" { ffval.Node = New_Deref( ffvsp[-3].Node, 1, ffvsp[-1].Node, 0, 0, 0, 0 ); TEST(ffval.Node); ; break;} case 24: #line 355 "eval.y" { ffval.Node = New_Deref( ffvsp[-5].Node, 2, ffvsp[-3].Node, ffvsp[-1].Node, 0, 0, 0 ); TEST(ffval.Node); ; break;} case 25: #line 357 "eval.y" { ffval.Node = New_Deref( ffvsp[-7].Node, 3, ffvsp[-5].Node, ffvsp[-3].Node, ffvsp[-1].Node, 0, 0 ); TEST(ffval.Node); ; break;} case 26: #line 359 "eval.y" { ffval.Node = New_Deref( ffvsp[-9].Node, 4, ffvsp[-7].Node, ffvsp[-5].Node, ffvsp[-3].Node, ffvsp[-1].Node, 0 ); TEST(ffval.Node); ; break;} case 27: #line 361 "eval.y" { ffval.Node = New_Deref( ffvsp[-11].Node, 5, ffvsp[-9].Node, ffvsp[-7].Node, ffvsp[-5].Node, ffvsp[-3].Node, ffvsp[-1].Node ); TEST(ffval.Node); ; break;} case 28: #line 363 "eval.y" { ffval.Node = New_Unary( BITSTR, NOT, ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 29: #line 366 "eval.y" { ffval.Node = ffvsp[-1].Node; ; break;} case 30: #line 370 "eval.y" { ffval.Node = New_Const( LONG, &(ffvsp[0].lng), sizeof(long) ); TEST(ffval.Node); ; break;} case 31: #line 372 "eval.y" { ffval.Node = New_Const( DOUBLE, &(ffvsp[0].dbl), sizeof(double) ); TEST(ffval.Node); ; break;} case 32: #line 374 "eval.y" { ffval.Node = New_Column( ffvsp[0].lng ); TEST(ffval.Node); ; break;} case 33: #line 376 "eval.y" { if( TYPE(ffvsp[-1].Node) != LONG || gParse.Nodes[ffvsp[-1].Node].operation != CONST_OP ) { fferror("Offset argument must be a constant integer"); FFERROR; } ffval.Node = New_Offset( ffvsp[-3].lng, ffvsp[-1].Node ); TEST(ffval.Node); ; break;} case 34: #line 385 "eval.y" { ffval.Node = New_Func( LONG, row_fct, 0, 0, 0, 0, 0, 0, 0, 0 ); ; break;} case 35: #line 387 "eval.y" { ffval.Node = New_Func( LONG, null_fct, 0, 0, 0, 0, 0, 0, 0, 0 ); ; break;} case 36: #line 389 "eval.y" { PROMOTE(ffvsp[-2].Node,ffvsp[0].Node); ffval.Node = New_BinOp( TYPE(ffvsp[-2].Node), ffvsp[-2].Node, '%', ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 37: #line 392 "eval.y" { PROMOTE(ffvsp[-2].Node,ffvsp[0].Node); ffval.Node = New_BinOp( TYPE(ffvsp[-2].Node), ffvsp[-2].Node, '+', ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 38: #line 395 "eval.y" { PROMOTE(ffvsp[-2].Node,ffvsp[0].Node); ffval.Node = New_BinOp( TYPE(ffvsp[-2].Node), ffvsp[-2].Node, '-', ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 39: #line 398 "eval.y" { PROMOTE(ffvsp[-2].Node,ffvsp[0].Node); ffval.Node = New_BinOp( TYPE(ffvsp[-2].Node), ffvsp[-2].Node, '*', ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 40: #line 401 "eval.y" { PROMOTE(ffvsp[-2].Node,ffvsp[0].Node); ffval.Node = New_BinOp( TYPE(ffvsp[-2].Node), ffvsp[-2].Node, '/', ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 41: #line 404 "eval.y" { PROMOTE(ffvsp[-2].Node,ffvsp[0].Node); ffval.Node = New_BinOp( TYPE(ffvsp[-2].Node), ffvsp[-2].Node, POWER, ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 42: #line 407 "eval.y" { ffval.Node = ffvsp[0].Node; ; break;} case 43: #line 409 "eval.y" { ffval.Node = New_Unary( TYPE(ffvsp[0].Node), UMINUS, ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 44: #line 411 "eval.y" { ffval.Node = ffvsp[-1].Node; ; break;} case 45: #line 413 "eval.y" { ffvsp[0].Node = New_Unary( TYPE(ffvsp[-2].Node), 0, ffvsp[0].Node ); ffval.Node = New_BinOp( TYPE(ffvsp[-2].Node), ffvsp[-2].Node, '*', ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 46: #line 417 "eval.y" { ffvsp[-2].Node = New_Unary( TYPE(ffvsp[0].Node), 0, ffvsp[-2].Node ); ffval.Node = New_BinOp( TYPE(ffvsp[0].Node), ffvsp[-2].Node, '*', ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 47: #line 421 "eval.y" { PROMOTE(ffvsp[-2].Node,ffvsp[0].Node); if( ! Test_Dims(ffvsp[-2].Node,ffvsp[0].Node) ) { fferror("Incompatible dimensions in '?:' arguments"); FFERROR; } ffval.Node = New_Func( 0, ifthenelse_fct, 3, ffvsp[-2].Node, ffvsp[0].Node, ffvsp[-4].Node, 0, 0, 0, 0 ); TEST(ffval.Node); if( SIZE(ffvsp[-2].Node)=SIZE(ffvsp[-1].Node) && Test_Dims( ffvsp[-3].Node, ffvsp[-1].Node ) ) { PROMOTE(ffvsp[-3].Node,ffvsp[-1].Node); ffval.Node = New_Func( 0, defnull_fct, 2, ffvsp[-3].Node, ffvsp[-1].Node, 0, 0, 0, 0, 0 ); TEST(ffval.Node); } else { fferror("Dimensions of DEFNULL arguments " "are not compatible"); FFERROR; } } else if (FSTRCMP(ffvsp[-4].str,"ARCTAN2(") == 0) { if( TYPE(ffvsp[-3].Node) != DOUBLE ) ffvsp[-3].Node = New_Unary( DOUBLE, 0, ffvsp[-3].Node ); if( TYPE(ffvsp[-1].Node) != DOUBLE ) ffvsp[-1].Node = New_Unary( DOUBLE, 0, ffvsp[-1].Node ); if( Test_Dims( ffvsp[-3].Node, ffvsp[-1].Node ) ) { ffval.Node = New_Func( 0, atan2_fct, 2, ffvsp[-3].Node, ffvsp[-1].Node, 0, 0, 0, 0, 0 ); TEST(ffval.Node); if( SIZE(ffvsp[-3].Node)=SIZE(ffvsp[-1].Node) && Test_Dims( ffvsp[-3].Node, ffvsp[-1].Node ) ) { ffval.Node = New_Func( 0, defnull_fct, 2, ffvsp[-3].Node, ffvsp[-1].Node, 0, 0, 0, 0, 0 ); TEST(ffval.Node); } else { fferror("Dimensions of DEFNULL arguments are not compatible"); FFERROR; } } else { fferror("Boolean Function(expr,expr) not supported"); FFERROR; } ; break;} case 98: #line 890 "eval.y" { if( TYPE(ffvsp[-5].Node) != DOUBLE ) ffvsp[-5].Node = New_Unary( DOUBLE, 0, ffvsp[-5].Node ); if( TYPE(ffvsp[-3].Node) != DOUBLE ) ffvsp[-3].Node = New_Unary( DOUBLE, 0, ffvsp[-3].Node ); if( TYPE(ffvsp[-1].Node) != DOUBLE ) ffvsp[-1].Node = New_Unary( DOUBLE, 0, ffvsp[-1].Node ); if( ! (Test_Dims( ffvsp[-5].Node, ffvsp[-3].Node ) && Test_Dims( ffvsp[-3].Node, ffvsp[-1].Node ) ) ) { fferror("Dimensions of NEAR arguments " "are not compatible"); FFERROR; } else { if (FSTRCMP(ffvsp[-6].str,"NEAR(") == 0) { ffval.Node = New_Func( BOOLEAN, near_fct, 3, ffvsp[-5].Node, ffvsp[-3].Node, ffvsp[-1].Node, 0, 0, 0, 0 ); } else { fferror("Boolean Function not supported"); FFERROR; } TEST(ffval.Node); if( SIZE(ffval.Node)SIZE(ffvsp[-3].Node) ) SIZE(ffval.Node) = SIZE(ffvsp[-1].Node); } ; break;} } /* the action file gets copied in in place of this dollarsign */ #line 498 "/usr1/local/share/bison.simple" ffvsp -= fflen; ffssp -= fflen; #ifdef FFLSP_NEEDED fflsp -= fflen; #endif #if FFDEBUG != 0 if (ffdebug) { short *ssp1 = ffss - 1; fprintf (stderr, "state stack now"); while (ssp1 != ffssp) fprintf (stderr, " %d", *++ssp1); fprintf (stderr, "\n"); } #endif *++ffvsp = ffval; #ifdef FFLSP_NEEDED fflsp++; if (fflen == 0) { fflsp->first_line = fflloc.first_line; fflsp->first_column = fflloc.first_column; fflsp->last_line = (fflsp-1)->last_line; fflsp->last_column = (fflsp-1)->last_column; fflsp->text = 0; } else { fflsp->last_line = (fflsp+fflen-1)->last_line; fflsp->last_column = (fflsp+fflen-1)->last_column; } #endif /* Now "shift" the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ ffn = ffr1[ffn]; ffstate = ffpgoto[ffn - FFNTBASE] + *ffssp; if (ffstate >= 0 && ffstate <= FFLAST && ffcheck[ffstate] == *ffssp) ffstate = fftable[ffstate]; else ffstate = ffdefgoto[ffn - FFNTBASE]; goto ffnewstate; fferrlab: /* here on detecting error */ if (! fferrstatus) /* If not already recovering from an error, report this error. */ { ++ffnerrs; #ifdef FFERROR_VERBOSE ffn = ffpact[ffstate]; if (ffn > FFFLAG && ffn < FFLAST) { int size = 0; char *msg; int x, count; count = 0; /* Start X at -ffn if nec to avoid negative indexes in ffcheck. */ for (x = (ffn < 0 ? -ffn : 0); x < (sizeof(fftname) / sizeof(char *)); x++) if (ffcheck[x + ffn] == x) size += strlen(fftname[x]) + 15, count++; msg = (char *) malloc(size + 15); if (msg != 0) { strcpy(msg, "parse error"); if (count < 5) { count = 0; for (x = (ffn < 0 ? -ffn : 0); x < (sizeof(fftname) / sizeof(char *)); x++) if (ffcheck[x + ffn] == x) { strcat(msg, count == 0 ? ", expecting `" : " or `"); strcat(msg, fftname[x]); strcat(msg, "'"); count++; } } fferror(msg); free(msg); } else fferror ("parse error; also virtual memory exceeded"); } else #endif /* FFERROR_VERBOSE */ fferror("parse error"); } goto fferrlab1; fferrlab1: /* here on error raised explicitly by an action */ if (fferrstatus == 3) { /* if just tried and failed to reuse lookahead token after an error, discard it. */ /* return failure if at end of input */ if (ffchar == FFEOF) FFABORT; #if FFDEBUG != 0 if (ffdebug) fprintf(stderr, "Discarding token %d (%s).\n", ffchar, fftname[ffchar1]); #endif ffchar = FFEMPTY; } /* Else will try to reuse lookahead token after shifting the error token. */ fferrstatus = 3; /* Each real token shifted decrements this */ goto fferrhandle; fferrdefault: /* current state does not do anything special for the error token. */ #if 0 /* This is wrong; only states that explicitly want error tokens should shift them. */ ffn = ffdefact[ffstate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ if (ffn) goto ffdefault; #endif fferrpop: /* pop the current state because it cannot handle the error token */ if (ffssp == ffss) FFABORT; ffvsp--; ffstate = *--ffssp; #ifdef FFLSP_NEEDED fflsp--; #endif #if FFDEBUG != 0 if (ffdebug) { short *ssp1 = ffss - 1; fprintf (stderr, "Error: state stack now"); while (ssp1 != ffssp) fprintf (stderr, " %d", *++ssp1); fprintf (stderr, "\n"); } #endif fferrhandle: ffn = ffpact[ffstate]; if (ffn == FFFLAG) goto fferrdefault; ffn += FFTERROR; if (ffn < 0 || ffn > FFLAST || ffcheck[ffn] != FFTERROR) goto fferrdefault; ffn = fftable[ffn]; if (ffn < 0) { if (ffn == FFFLAG) goto fferrpop; ffn = -ffn; goto ffreduce; } else if (ffn == 0) goto fferrpop; if (ffn == FFFINAL) FFACCEPT; #if FFDEBUG != 0 if (ffdebug) fprintf(stderr, "Shifting error token, "); #endif *++ffvsp = fflval; #ifdef FFLSP_NEEDED *++fflsp = fflloc; #endif ffstate = ffn; goto ffnewstate; } #line 1064 "eval.y" /*************************************************************************/ /* Start of "New" routines which build the expression Nodal structure */ /*************************************************************************/ static int Alloc_Node( void ) { /* Use this for allocation to guarantee *Nodes */ Node *newNodePtr; /* survives on failure, making it still valid */ /* while working our way out of this error */ if( gParse.nNodes == gParse.nNodesAlloc ) { if( gParse.Nodes ) { gParse.nNodesAlloc += gParse.nNodesAlloc; newNodePtr = (Node *)realloc( gParse.Nodes, sizeof(Node)*gParse.nNodesAlloc ); } else { gParse.nNodesAlloc = 100; newNodePtr = (Node *)malloc ( sizeof(Node)*gParse.nNodesAlloc ); } if( newNodePtr ) { gParse.Nodes = newNodePtr; } else { gParse.status = MEMORY_ALLOCATION; return( -1 ); } } return ( gParse.nNodes++ ); } static void Free_Last_Node( void ) { if( gParse.nNodes ) gParse.nNodes--; } static int New_Const( int returnType, void *value, long len ) { Node *this; int n; n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = CONST_OP; /* Flag a constant */ this->DoOp = NULL; this->nSubNodes = 0; this->type = returnType; memcpy( &(this->value.data), value, len ); this->value.undef = NULL; this->value.nelem = 1; this->value.naxis = 1; this->value.naxes[0] = 1; } return(n); } static int New_Column( int ColNum ) { Node *this; int n, i; n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = -ColNum; this->DoOp = NULL; this->nSubNodes = 0; this->type = gParse.varData[ColNum].type; this->value.nelem = gParse.varData[ColNum].nelem; this->value.naxis = gParse.varData[ColNum].naxis; for( i=0; ivalue.naxes[i] = gParse.varData[ColNum].naxes[i]; } return(n); } static int New_Offset( int ColNum, int offsetNode ) { Node *this; int n, i, colNode; colNode = New_Column( ColNum ); if( colNode<0 ) return(-1); n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = '{'; this->DoOp = Do_Offset; this->nSubNodes = 2; this->SubNodes[0] = colNode; this->SubNodes[1] = offsetNode; this->type = gParse.varData[ColNum].type; this->value.nelem = gParse.varData[ColNum].nelem; this->value.naxis = gParse.varData[ColNum].naxis; for( i=0; ivalue.naxes[i] = gParse.varData[ColNum].naxes[i]; } return(n); } static int New_Unary( int returnType, int Op, int Node1 ) { Node *this, *that; int i,n; if( Node1<0 ) return(-1); that = gParse.Nodes + Node1; if( !Op ) Op = returnType; if( (Op==DOUBLE || Op==FLTCAST) && that->type==DOUBLE ) return( Node1 ); if( (Op==LONG || Op==INTCAST) && that->type==LONG ) return( Node1 ); if( (Op==BOOLEAN ) && that->type==BOOLEAN ) return( Node1 ); n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = Op; this->DoOp = Do_Unary; this->nSubNodes = 1; this->SubNodes[0] = Node1; this->type = returnType; that = gParse.Nodes + Node1; /* Reset in case .Nodes mv'd */ this->value.nelem = that->value.nelem; this->value.naxis = that->value.naxis; for( i=0; ivalue.naxis; i++ ) this->value.naxes[i] = that->value.naxes[i]; if( that->operation==CONST_OP ) this->DoOp( this ); } return( n ); } static int New_BinOp( int returnType, int Node1, int Op, int Node2 ) { Node *this,*that1,*that2; int n,i,constant; if( Node1<0 || Node2<0 ) return(-1); n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = Op; this->nSubNodes = 2; this->SubNodes[0]= Node1; this->SubNodes[1]= Node2; this->type = returnType; that1 = gParse.Nodes + Node1; that2 = gParse.Nodes + Node2; constant = (that1->operation==CONST_OP && that2->operation==CONST_OP); if( that1->type!=STRING && that1->type!=BITSTR ) if( !Test_Dims( Node1, Node2 ) ) { Free_Last_Node(); fferror("Array sizes/dims do not match for binary operator"); return(-1); } if( that1->value.nelem == 1 ) that1 = that2; this->value.nelem = that1->value.nelem; this->value.naxis = that1->value.naxis; for( i=0; ivalue.naxis; i++ ) this->value.naxes[i] = that1->value.naxes[i]; if ( Op == ACCUM && that1->type == BITSTR ) { /* ACCUM is rank-reducing on bit strings */ this->value.nelem = 1; this->value.naxis = 1; this->value.naxes[0] = 1; } /* Both subnodes should be of same time */ switch( that1->type ) { case BITSTR: this->DoOp = Do_BinOp_bit; break; case STRING: this->DoOp = Do_BinOp_str; break; case BOOLEAN: this->DoOp = Do_BinOp_log; break; case LONG: this->DoOp = Do_BinOp_lng; break; case DOUBLE: this->DoOp = Do_BinOp_dbl; break; } if( constant ) this->DoOp( this ); } return( n ); } static int New_Func( int returnType, funcOp Op, int nNodes, int Node1, int Node2, int Node3, int Node4, int Node5, int Node6, int Node7 ) /* If returnType==0 , use Node1's type and vector sizes as returnType, */ /* else return a single value of type returnType */ { Node *this, *that; int i,n,constant; if( Node1<0 || Node2<0 || Node3<0 || Node4<0 || Node5<0 || Node6<0 || Node7<0 ) return(-1); n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = (int)Op; this->DoOp = Do_Func; this->nSubNodes = nNodes; this->SubNodes[0] = Node1; this->SubNodes[1] = Node2; this->SubNodes[2] = Node3; this->SubNodes[3] = Node4; this->SubNodes[4] = Node5; this->SubNodes[5] = Node6; this->SubNodes[6] = Node7; i = constant = nNodes; /* Functions with zero params are not const */ if (Op == poirnd_fct) constant = 0; /* Nor is Poisson deviate */ while( i-- ) constant = ( constant && gParse.Nodes[ this->SubNodes[i] ].operation==CONST_OP ); if( returnType ) { this->type = returnType; this->value.nelem = 1; this->value.naxis = 1; this->value.naxes[0] = 1; } else { that = gParse.Nodes + Node1; this->type = that->type; this->value.nelem = that->value.nelem; this->value.naxis = that->value.naxis; for( i=0; ivalue.naxis; i++ ) this->value.naxes[i] = that->value.naxes[i]; } if( constant ) this->DoOp( this ); } return( n ); } static int New_Deref( int Var, int nDim, int Dim1, int Dim2, int Dim3, int Dim4, int Dim5 ) { int n, idx, constant; long elem=0; Node *this, *theVar, *theDim[MAXDIMS]; if( Var<0 || Dim1<0 || Dim2<0 || Dim3<0 || Dim4<0 || Dim5<0 ) return(-1); theVar = gParse.Nodes + Var; if( theVar->operation==CONST_OP || theVar->value.nelem==1 ) { fferror("Cannot index a scalar value"); return(-1); } n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->nSubNodes = nDim+1; theVar = gParse.Nodes + (this->SubNodes[0]=Var); theDim[0] = gParse.Nodes + (this->SubNodes[1]=Dim1); theDim[1] = gParse.Nodes + (this->SubNodes[2]=Dim2); theDim[2] = gParse.Nodes + (this->SubNodes[3]=Dim3); theDim[3] = gParse.Nodes + (this->SubNodes[4]=Dim4); theDim[4] = gParse.Nodes + (this->SubNodes[5]=Dim5); constant = theVar->operation==CONST_OP; for( idx=0; idxoperation==CONST_OP); for( idx=0; idxvalue.nelem>1 ) { Free_Last_Node(); fferror("Cannot use an array as an index value"); return(-1); } else if( theDim[idx]->type!=LONG ) { Free_Last_Node(); fferror("Index value must be an integer type"); return(-1); } this->operation = '['; this->DoOp = Do_Deref; this->type = theVar->type; if( theVar->value.naxis == nDim ) { /* All dimensions specified */ this->value.nelem = 1; this->value.naxis = 1; this->value.naxes[0] = 1; } else if( nDim==1 ) { /* Dereference only one dimension */ elem=1; this->value.naxis = theVar->value.naxis-1; for( idx=0; idxvalue.naxis; idx++ ) { elem *= ( this->value.naxes[idx] = theVar->value.naxes[idx] ); } this->value.nelem = elem; } else { Free_Last_Node(); fferror("Must specify just one or all indices for vector"); return(-1); } if( constant ) this->DoOp( this ); } return(n); } extern int ffGetVariable( char *varName, FFSTYPE *varVal ); static int New_GTI( char *fname, int Node1, char *start, char *stop ) { fitsfile *fptr; Node *this, *that0, *that1; int type,i,n, startCol, stopCol, Node0; int hdutype, hdunum, evthdu, samefile, extvers, movetotype, tstat; char extname[100]; long nrows; double timeZeroI[2], timeZeroF[2], dt, timeSpan; char xcol[20], xexpr[20]; FFSTYPE colVal; if( Node1==-99 ) { type = ffGetVariable( "TIME", &colVal ); if( type==COLUMN ) { Node1 = New_Column( (int)colVal.lng ); } else { fferror("Could not build TIME column for GTIFILTER"); return(-1); } } Node1 = New_Unary( DOUBLE, 0, Node1 ); Node0 = Alloc_Node(); /* This will hold the START/STOP times */ if( Node1<0 || Node0<0 ) return(-1); /* Record current HDU number in case we need to move within this file */ fptr = gParse.def_fptr; ffghdn( fptr, &evthdu ); /* Look for TIMEZERO keywords in current extension */ tstat = 0; if( ffgkyd( fptr, "TIMEZERO", timeZeroI, NULL, &tstat ) ) { tstat = 0; if( ffgkyd( fptr, "TIMEZERI", timeZeroI, NULL, &tstat ) ) { timeZeroI[0] = timeZeroF[0] = 0.0; } else if( ffgkyd( fptr, "TIMEZERF", timeZeroF, NULL, &tstat ) ) { timeZeroF[0] = 0.0; } } else { timeZeroF[0] = 0.0; } /* Resolve filename parameter */ switch( fname[0] ) { case '\0': samefile = 1; hdunum = 1; break; case '[': samefile = 1; i = 1; while( fname[i] != '\0' && fname[i] != ']' ) i++; if( fname[i] ) { fname[i] = '\0'; fname++; ffexts( fname, &hdunum, extname, &extvers, &movetotype, xcol, xexpr, &gParse.status ); if( *extname ) { ffmnhd( fptr, movetotype, extname, extvers, &gParse.status ); ffghdn( fptr, &hdunum ); } else if( hdunum ) { ffmahd( fptr, ++hdunum, &hdutype, &gParse.status ); } else if( !gParse.status ) { fferror("Cannot use primary array for GTI filter"); return( -1 ); } } else { fferror("File extension specifier lacks closing ']'"); return( -1 ); } break; case '+': samefile = 1; hdunum = atoi( fname ) + 1; if( hdunum>1 ) ffmahd( fptr, hdunum, &hdutype, &gParse.status ); else { fferror("Cannot use primary array for GTI filter"); return( -1 ); } break; default: samefile = 0; if( ! ffopen( &fptr, fname, READONLY, &gParse.status ) ) ffghdn( fptr, &hdunum ); break; } if( gParse.status ) return(-1); /* If at primary, search for GTI extension */ if( hdunum==1 ) { while( 1 ) { hdunum++; if( ffmahd( fptr, hdunum, &hdutype, &gParse.status ) ) break; if( hdutype==IMAGE_HDU ) continue; tstat = 0; if( ffgkys( fptr, "EXTNAME", extname, NULL, &tstat ) ) continue; ffupch( extname ); if( strstr( extname, "GTI" ) ) break; } if( gParse.status ) { if( gParse.status==END_OF_FILE ) fferror("GTI extension not found in this file"); return(-1); } } /* Locate START/STOP Columns */ ffgcno( fptr, CASEINSEN, start, &startCol, &gParse.status ); ffgcno( fptr, CASEINSEN, stop, &stopCol, &gParse.status ); if( gParse.status ) return(-1); /* Look for TIMEZERO keywords in GTI extension */ tstat = 0; if( ffgkyd( fptr, "TIMEZERO", timeZeroI+1, NULL, &tstat ) ) { tstat = 0; if( ffgkyd( fptr, "TIMEZERI", timeZeroI+1, NULL, &tstat ) ) { timeZeroI[1] = timeZeroF[1] = 0.0; } else if( ffgkyd( fptr, "TIMEZERF", timeZeroF+1, NULL, &tstat ) ) { timeZeroF[1] = 0.0; } } else { timeZeroF[1] = 0.0; } n = Alloc_Node(); if( n >= 0 ) { this = gParse.Nodes + n; this->nSubNodes = 2; this->SubNodes[1] = Node1; this->operation = (int)gtifilt_fct; this->DoOp = Do_GTI; this->type = BOOLEAN; that1 = gParse.Nodes + Node1; this->value.nelem = that1->value.nelem; this->value.naxis = that1->value.naxis; for( i=0; i < that1->value.naxis; i++ ) this->value.naxes[i] = that1->value.naxes[i]; /* Init START/STOP node to be treated as a "constant" */ this->SubNodes[0] = Node0; that0 = gParse.Nodes + Node0; that0->operation = CONST_OP; that0->DoOp = NULL; that0->value.data.ptr= NULL; /* Read in START/STOP times */ if( ffgkyj( fptr, "NAXIS2", &nrows, NULL, &gParse.status ) ) return(-1); that0->value.nelem = nrows; if( nrows ) { that0->value.data.dblptr = (double*)malloc( 2*nrows*sizeof(double) ); if( !that0->value.data.dblptr ) { gParse.status = MEMORY_ALLOCATION; return(-1); } ffgcvd( fptr, startCol, 1L, 1L, nrows, 0.0, that0->value.data.dblptr, &i, &gParse.status ); ffgcvd( fptr, stopCol, 1L, 1L, nrows, 0.0, that0->value.data.dblptr+nrows, &i, &gParse.status ); if( gParse.status ) { free( that0->value.data.dblptr ); return(-1); } /* Test for fully time-ordered GTI... both START && STOP */ that0->type = 1; /* Assume yes */ i = nrows; while( --i ) if( that0->value.data.dblptr[i-1] >= that0->value.data.dblptr[i] || that0->value.data.dblptr[i-1+nrows] >= that0->value.data.dblptr[i+nrows] ) { that0->type = 0; break; } /* Handle TIMEZERO offset, if any */ dt = (timeZeroI[1] - timeZeroI[0]) + (timeZeroF[1] - timeZeroF[0]); timeSpan = that0->value.data.dblptr[nrows+nrows-1] - that0->value.data.dblptr[0]; if( fabs( dt / timeSpan ) > 1e-12 ) { for( i=0; i<(nrows+nrows); i++ ) that0->value.data.dblptr[i] += dt; } } if( gParse.Nodes[Node1].operation==CONST_OP ) this->DoOp( this ); } if( samefile ) ffmahd( fptr, evthdu, &hdutype, &gParse.status ); else ffclos( fptr, &gParse.status ); return( n ); } static int New_REG( char *fname, int NodeX, int NodeY, char *colNames ) { Node *this, *that0; int type, n, Node0; int Xcol, Ycol, tstat; WCSdata wcs; SAORegion *Rgn; char *cX, *cY; FFSTYPE colVal; if( NodeX==-99 ) { type = ffGetVariable( "X", &colVal ); if( type==COLUMN ) { NodeX = New_Column( (int)colVal.lng ); } else { fferror("Could not build X column for REGFILTER"); return(-1); } } if( NodeY==-99 ) { type = ffGetVariable( "Y", &colVal ); if( type==COLUMN ) { NodeY = New_Column( (int)colVal.lng ); } else { fferror("Could not build Y column for REGFILTER"); return(-1); } } NodeX = New_Unary( DOUBLE, 0, NodeX ); NodeY = New_Unary( DOUBLE, 0, NodeY ); Node0 = Alloc_Node(); /* This will hold the Region Data */ if( NodeX<0 || NodeY<0 || Node0<0 ) return(-1); if( ! (Test_Dims( NodeX, NodeY ) ) ) { fferror("Dimensions of REGFILTER arguments are not compatible"); return (-1); } n = Alloc_Node(); if( n >= 0 ) { this = gParse.Nodes + n; this->nSubNodes = 3; this->SubNodes[0] = Node0; this->SubNodes[1] = NodeX; this->SubNodes[2] = NodeY; this->operation = (int)regfilt_fct; this->DoOp = Do_REG; this->type = BOOLEAN; this->value.nelem = 1; this->value.naxis = 1; this->value.naxes[0] = 1; Copy_Dims(n, NodeX); if( SIZE(NodeX)operation = CONST_OP; that0->DoOp = NULL; /* Identify what columns to use for WCS information */ Xcol = Ycol = 0; if( *colNames ) { /* Use the column names in this string for WCS info */ while( *colNames==' ' ) colNames++; cX = cY = colNames; while( *cY && *cY!=' ' && *cY!=',' ) cY++; if( *cY ) *(cY++) = '\0'; while( *cY==' ' ) cY++; if( !*cY ) { fferror("Could not extract valid pair of column names from REGFILTER"); Free_Last_Node(); return( -1 ); } fits_get_colnum( gParse.def_fptr, CASEINSEN, cX, &Xcol, &gParse.status ); fits_get_colnum( gParse.def_fptr, CASEINSEN, cY, &Ycol, &gParse.status ); if( gParse.status ) { fferror("Could not locate columns indicated for WCS info"); Free_Last_Node(); return( -1 ); } } else { /* Try to find columns used in X/Y expressions */ Xcol = Locate_Col( gParse.Nodes + NodeX ); Ycol = Locate_Col( gParse.Nodes + NodeY ); if( Xcol<0 || Ycol<0 ) { fferror("Found multiple X/Y column references in REGFILTER"); Free_Last_Node(); return( -1 ); } } /* Now, get the WCS info, if it exists, from the indicated columns */ wcs.exists = 0; if( Xcol>0 && Ycol>0 ) { tstat = 0; ffgtcs( gParse.def_fptr, Xcol, Ycol, &wcs.xrefval, &wcs.yrefval, &wcs.xrefpix, &wcs.yrefpix, &wcs.xinc, &wcs.yinc, &wcs.rot, wcs.type, &tstat ); if( tstat==NO_WCS_KEY ) { wcs.exists = 0; } else if( tstat ) { gParse.status = tstat; Free_Last_Node(); return( -1 ); } else { wcs.exists = 1; } } /* Read in Region file */ fits_read_rgnfile( fname, &wcs, &Rgn, &gParse.status ); if( gParse.status ) { Free_Last_Node(); return( -1 ); } that0->value.data.ptr = Rgn; if( gParse.Nodes[NodeX].operation==CONST_OP && gParse.Nodes[NodeY].operation==CONST_OP ) this->DoOp( this ); } return( n ); } static int New_Vector( int subNode ) { Node *this, *that; int n; n = Alloc_Node(); if( n >= 0 ) { this = gParse.Nodes + n; that = gParse.Nodes + subNode; this->type = that->type; this->nSubNodes = 1; this->SubNodes[0] = subNode; this->operation = '{'; this->DoOp = Do_Vector; } return( n ); } static int Close_Vec( int vecNode ) { Node *this; int n, nelem=0; this = gParse.Nodes + vecNode; for( n=0; n < this->nSubNodes; n++ ) { if( TYPE( this->SubNodes[n] ) != this->type ) { this->SubNodes[n] = New_Unary( this->type, 0, this->SubNodes[n] ); if( this->SubNodes[n]<0 ) return(-1); } nelem += SIZE(this->SubNodes[n]); } this->value.naxis = 1; this->value.nelem = nelem; this->value.naxes[0] = nelem; return( vecNode ); } static int Locate_Col( Node *this ) /* Locate the TABLE column number of any columns in "this" calculation. */ /* Return ZERO if none found, or negative if more than 1 found. */ { Node *that; int i, col=0, newCol, nfound=0; if( this->nSubNodes==0 && this->operation<=0 && this->operation!=CONST_OP ) return gParse.colData[ - this->operation].colnum; for( i=0; inSubNodes; i++ ) { that = gParse.Nodes + this->SubNodes[i]; if( that->operation>0 ) { newCol = Locate_Col( that ); if( newCol<=0 ) { nfound += -newCol; } else { if( !nfound ) { col = newCol; nfound++; } else if( col != newCol ) { nfound++; } } } else if( that->operation!=CONST_OP ) { /* Found a Column */ newCol = gParse.colData[- that->operation].colnum; if( !nfound ) { col = newCol; nfound++; } else if( col != newCol ) { nfound++; } } } if( nfound!=1 ) return( - nfound ); else return( col ); } static int Test_Dims( int Node1, int Node2 ) { Node *that1, *that2; int valid, i; if( Node1<0 || Node2<0 ) return(0); that1 = gParse.Nodes + Node1; that2 = gParse.Nodes + Node2; if( that1->value.nelem==1 || that2->value.nelem==1 ) valid = 1; else if( that1->type==that2->type && that1->value.nelem==that2->value.nelem && that1->value.naxis==that2->value.naxis ) { valid = 1; for( i=0; ivalue.naxis; i++ ) { if( that1->value.naxes[i]!=that2->value.naxes[i] ) valid = 0; } } else valid = 0; return( valid ); } static void Copy_Dims( int Node1, int Node2 ) { Node *that1, *that2; int i; if( Node1<0 || Node2<0 ) return; that1 = gParse.Nodes + Node1; that2 = gParse.Nodes + Node2; that1->value.nelem = that2->value.nelem; that1->value.naxis = that2->value.naxis; for( i=0; ivalue.naxis; i++ ) that1->value.naxes[i] = that2->value.naxes[i]; } /********************************************************************/ /* Routines for actually evaluating the expression start here */ /********************************************************************/ void Evaluate_Parser( long firstRow, long nRows ) /***********************************************************************/ /* Reset the parser for processing another batch of data... */ /* firstRow: Row number of the first element to evaluate */ /* nRows: Number of rows to be processed */ /* Initialize each COLUMN node so that its UNDEF and DATA pointers */ /* point to the appropriate column arrays. */ /* Finally, call Evaluate_Node for final node. */ /***********************************************************************/ { int i, column; long offset, rowOffset; gParse.firstRow = firstRow; gParse.nRows = nRows; /* Reset Column Nodes' pointers to point to right data and UNDEF arrays */ rowOffset = firstRow - gParse.firstDataRow; for( i=0; i 0 || gParse.Nodes[i].operation == CONST_OP ) continue; column = -gParse.Nodes[i].operation; offset = gParse.varData[column].nelem * rowOffset; gParse.Nodes[i].value.undef = gParse.varData[column].undef + offset; switch( gParse.Nodes[i].type ) { case BITSTR: gParse.Nodes[i].value.data.strptr = (char**)gParse.varData[column].data + rowOffset; gParse.Nodes[i].value.undef = NULL; break; case STRING: gParse.Nodes[i].value.data.strptr = (char**)gParse.varData[column].data + rowOffset; gParse.Nodes[i].value.undef = gParse.varData[column].undef + rowOffset; break; case BOOLEAN: gParse.Nodes[i].value.data.logptr = (char*)gParse.varData[column].data + offset; break; case LONG: gParse.Nodes[i].value.data.lngptr = (long*)gParse.varData[column].data + offset; break; case DOUBLE: gParse.Nodes[i].value.data.dblptr = (double*)gParse.varData[column].data + offset; break; } } Evaluate_Node( gParse.resultNode ); } static void Evaluate_Node( int thisNode ) /**********************************************************************/ /* Recursively evaluate thisNode's subNodes, then call one of the */ /* Do_ functions pointed to by thisNode's DoOp element. */ /**********************************************************************/ { Node *this; int i; if( gParse.status ) return; this = gParse.Nodes + thisNode; if( this->operation>0 ) { /* <=0 indicate constants and columns */ i = this->nSubNodes; while( i-- ) { Evaluate_Node( this->SubNodes[i] ); if( gParse.status ) return; } this->DoOp( this ); } } static void Allocate_Ptrs( Node *this ) { long elem, row, size; if( this->type==BITSTR || this->type==STRING ) { this->value.data.strptr = (char**)malloc( gParse.nRows * sizeof(char*) ); if( this->value.data.strptr ) { this->value.data.strptr[0] = (char*)malloc( gParse.nRows * (this->value.nelem+2) * sizeof(char) ); if( this->value.data.strptr[0] ) { row = 0; while( (++row)value.data.strptr[row] = this->value.data.strptr[row-1] + this->value.nelem+1; } if( this->type==STRING ) { this->value.undef = this->value.data.strptr[row-1] + this->value.nelem+1; } else { this->value.undef = NULL; /* BITSTRs don't use undef array */ } } else { gParse.status = MEMORY_ALLOCATION; free( this->value.data.strptr ); } } else { gParse.status = MEMORY_ALLOCATION; } } else { elem = this->value.nelem * gParse.nRows; switch( this->type ) { case DOUBLE: size = sizeof( double ); break; case LONG: size = sizeof( long ); break; case BOOLEAN: size = sizeof( char ); break; default: size = 1; break; } this->value.data.ptr = calloc(size+1, elem); if( this->value.data.ptr==NULL ) { gParse.status = MEMORY_ALLOCATION; } else { this->value.undef = (char *)this->value.data.ptr + elem*size; } } } static void Do_Unary( Node *this ) { Node *that; long elem; that = gParse.Nodes + this->SubNodes[0]; if( that->operation==CONST_OP ) { /* Operating on a constant! */ switch( this->operation ) { case DOUBLE: case FLTCAST: if( that->type==LONG ) this->value.data.dbl = (double)that->value.data.lng; else if( that->type==BOOLEAN ) this->value.data.dbl = ( that->value.data.log ? 1.0 : 0.0 ); break; case LONG: case INTCAST: if( that->type==DOUBLE ) this->value.data.lng = (long)that->value.data.dbl; else if( that->type==BOOLEAN ) this->value.data.lng = ( that->value.data.log ? 1L : 0L ); break; case BOOLEAN: if( that->type==DOUBLE ) this->value.data.log = ( that->value.data.dbl != 0.0 ); else if( that->type==LONG ) this->value.data.log = ( that->value.data.lng != 0L ); break; case UMINUS: if( that->type==DOUBLE ) this->value.data.dbl = - that->value.data.dbl; else if( that->type==LONG ) this->value.data.lng = - that->value.data.lng; break; case NOT: if( that->type==BOOLEAN ) this->value.data.log = ( ! that->value.data.log ); else if( that->type==BITSTR ) bitnot( this->value.data.str, that->value.data.str ); break; } this->operation = CONST_OP; } else { Allocate_Ptrs( this ); if( !gParse.status ) { if( this->type!=BITSTR ) { elem = gParse.nRows; if( this->type!=STRING ) elem *= this->value.nelem; while( elem-- ) this->value.undef[elem] = that->value.undef[elem]; } elem = gParse.nRows * this->value.nelem; switch( this->operation ) { case BOOLEAN: if( that->type==DOUBLE ) while( elem-- ) this->value.data.logptr[elem] = ( that->value.data.dblptr[elem] != 0.0 ); else if( that->type==LONG ) while( elem-- ) this->value.data.logptr[elem] = ( that->value.data.lngptr[elem] != 0L ); break; case DOUBLE: case FLTCAST: if( that->type==LONG ) while( elem-- ) this->value.data.dblptr[elem] = (double)that->value.data.lngptr[elem]; else if( that->type==BOOLEAN ) while( elem-- ) this->value.data.dblptr[elem] = ( that->value.data.logptr[elem] ? 1.0 : 0.0 ); break; case LONG: case INTCAST: if( that->type==DOUBLE ) while( elem-- ) this->value.data.lngptr[elem] = (long)that->value.data.dblptr[elem]; else if( that->type==BOOLEAN ) while( elem-- ) this->value.data.lngptr[elem] = ( that->value.data.logptr[elem] ? 1L : 0L ); break; case UMINUS: if( that->type==DOUBLE ) { while( elem-- ) this->value.data.dblptr[elem] = - that->value.data.dblptr[elem]; } else if( that->type==LONG ) { while( elem-- ) this->value.data.lngptr[elem] = - that->value.data.lngptr[elem]; } break; case NOT: if( that->type==BOOLEAN ) { while( elem-- ) this->value.data.logptr[elem] = ( ! that->value.data.logptr[elem] ); } else if( that->type==BITSTR ) { elem = gParse.nRows; while( elem-- ) bitnot( this->value.data.strptr[elem], that->value.data.strptr[elem] ); } break; } } } if( that->operation>0 ) { free( that->value.data.ptr ); } } static void Do_Offset( Node *this ) { Node *col; long fRow, nRowOverlap, nRowReload, rowOffset; long nelem, elem, offset, nRealElem; int status; col = gParse.Nodes + this->SubNodes[0]; rowOffset = gParse.Nodes[ this->SubNodes[1] ].value.data.lng; Allocate_Ptrs( this ); fRow = gParse.firstRow + rowOffset; if( this->type==STRING || this->type==BITSTR ) nRealElem = 1; else nRealElem = this->value.nelem; nelem = nRealElem; if( fRow < gParse.firstDataRow ) { /* Must fill in data at start of array */ nRowReload = gParse.firstDataRow - fRow; if( nRowReload > gParse.nRows ) nRowReload = gParse.nRows; nRowOverlap = gParse.nRows - nRowReload; offset = 0; /* NULLify any values falling out of bounds */ while( fRow<1 && nRowReload>0 ) { if( this->type == BITSTR ) { nelem = this->value.nelem; this->value.data.strptr[offset][ nelem ] = '\0'; while( nelem-- ) this->value.data.strptr[offset][nelem] = '0'; offset++; } else { while( nelem-- ) this->value.undef[offset++] = 1; } nelem = nRealElem; fRow++; nRowReload--; } } else if( fRow + gParse.nRows > gParse.firstDataRow + gParse.nDataRows ) { /* Must fill in data at end of array */ nRowReload = (fRow+gParse.nRows) - (gParse.firstDataRow+gParse.nDataRows); if( nRowReload>gParse.nRows ) { nRowReload = gParse.nRows; } else { fRow = gParse.firstDataRow + gParse.nDataRows; } nRowOverlap = gParse.nRows - nRowReload; offset = nRowOverlap * nelem; /* NULLify any values falling out of bounds */ elem = gParse.nRows * nelem; while( fRow+nRowReload>gParse.totalRows && nRowReload>0 ) { if( this->type == BITSTR ) { nelem = this->value.nelem; elem--; this->value.data.strptr[elem][ nelem ] = '\0'; while( nelem-- ) this->value.data.strptr[elem][nelem] = '0'; } else { while( nelem-- ) this->value.undef[--elem] = 1; } nelem = nRealElem; nRowReload--; } } else { nRowReload = 0; nRowOverlap = gParse.nRows; offset = 0; } if( nRowReload>0 ) { switch( this->type ) { case BITSTR: case STRING: status = (*gParse.loadData)( -col->operation, fRow, nRowReload, this->value.data.strptr+offset, this->value.undef+offset ); break; case BOOLEAN: status = (*gParse.loadData)( -col->operation, fRow, nRowReload, this->value.data.logptr+offset, this->value.undef+offset ); break; case LONG: status = (*gParse.loadData)( -col->operation, fRow, nRowReload, this->value.data.lngptr+offset, this->value.undef+offset ); break; case DOUBLE: status = (*gParse.loadData)( -col->operation, fRow, nRowReload, this->value.data.dblptr+offset, this->value.undef+offset ); break; } } /* Now copy over the overlapping region, if any */ if( nRowOverlap <= 0 ) return; if( rowOffset>0 ) elem = nRowOverlap * nelem; else elem = gParse.nRows * nelem; offset = nelem * rowOffset; while( nRowOverlap-- && !gParse.status ) { while( nelem-- && !gParse.status ) { elem--; if( this->type != BITSTR ) this->value.undef[elem] = col->value.undef[elem+offset]; switch( this->type ) { case BITSTR: strcpy( this->value.data.strptr[elem ], col->value.data.strptr[elem+offset] ); break; case STRING: strcpy( this->value.data.strptr[elem ], col->value.data.strptr[elem+offset] ); break; case BOOLEAN: this->value.data.logptr[elem] = col->value.data.logptr[elem+offset]; break; case LONG: this->value.data.lngptr[elem] = col->value.data.lngptr[elem+offset]; break; case DOUBLE: this->value.data.dblptr[elem] = col->value.data.dblptr[elem+offset]; break; } } nelem = nRealElem; } } static void Do_BinOp_bit( Node *this ) { Node *that1, *that2; char *sptr1=NULL, *sptr2=NULL; int const1, const2; long rows; that1 = gParse.Nodes + this->SubNodes[0]; that2 = gParse.Nodes + this->SubNodes[1]; const1 = ( that1->operation==CONST_OP ); const2 = ( that2->operation==CONST_OP ); sptr1 = ( const1 ? that1->value.data.str : NULL ); sptr2 = ( const2 ? that2->value.data.str : NULL ); if( const1 && const2 ) { switch( this->operation ) { case NE: this->value.data.log = !bitcmp( sptr1, sptr2 ); break; case EQ: this->value.data.log = bitcmp( sptr1, sptr2 ); break; case GT: case LT: case LTE: case GTE: this->value.data.log = bitlgte( sptr1, this->operation, sptr2 ); break; case '|': bitor( this->value.data.str, sptr1, sptr2 ); break; case '&': bitand( this->value.data.str, sptr1, sptr2 ); break; case '+': strcpy( this->value.data.str, sptr1 ); strcat( this->value.data.str, sptr2 ); break; case ACCUM: this->value.data.lng = 0; while( *sptr1 ) { if ( *sptr1 == '1' ) this->value.data.lng ++; sptr1 ++; } break; } this->operation = CONST_OP; } else { Allocate_Ptrs( this ); if( !gParse.status ) { rows = gParse.nRows; switch( this->operation ) { /* BITSTR comparisons */ case NE: case EQ: case GT: case LT: case LTE: case GTE: while( rows-- ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; switch( this->operation ) { case NE: this->value.data.logptr[rows] = !bitcmp( sptr1, sptr2 ); break; case EQ: this->value.data.logptr[rows] = bitcmp( sptr1, sptr2 ); break; case GT: case LT: case LTE: case GTE: this->value.data.logptr[rows] = bitlgte( sptr1, this->operation, sptr2 ); break; } this->value.undef[rows] = 0; } break; /* BITSTR AND/ORs ... no UNDEFS in or out */ case '|': case '&': case '+': while( rows-- ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; if( this->operation=='|' ) bitor( this->value.data.strptr[rows], sptr1, sptr2 ); else if( this->operation=='&' ) bitand( this->value.data.strptr[rows], sptr1, sptr2 ); else { strcpy( this->value.data.strptr[rows], sptr1 ); strcat( this->value.data.strptr[rows], sptr2 ); } } break; /* Accumulate 1 bits */ case ACCUM: { long i, previous, curr; previous = that2->value.data.lng; /* Cumulative sum of this chunk */ for (i=0; ivalue.data.strptr[i]; for (curr = 0; *sptr1; sptr1 ++) { if ( *sptr1 == '1' ) curr ++; } previous += curr; this->value.data.lngptr[i] = previous; this->value.undef[i] = 0; } /* Store final cumulant for next pass */ that2->value.data.lng = previous; } } } } if( that1->operation>0 ) { free( that1->value.data.strptr[0] ); free( that1->value.data.strptr ); } if( that2->operation>0 ) { free( that2->value.data.strptr[0] ); free( that2->value.data.strptr ); } } static void Do_BinOp_str( Node *this ) { Node *that1, *that2; char *sptr1, *sptr2, null1=0, null2=0; int const1, const2, val; long rows; that1 = gParse.Nodes + this->SubNodes[0]; that2 = gParse.Nodes + this->SubNodes[1]; const1 = ( that1->operation==CONST_OP ); const2 = ( that2->operation==CONST_OP ); sptr1 = ( const1 ? that1->value.data.str : NULL ); sptr2 = ( const2 ? that2->value.data.str : NULL ); if( const1 && const2 ) { /* Result is a constant */ switch( this->operation ) { /* Compare Strings */ case NE: case EQ: val = ( FSTRCMP( sptr1, sptr2 ) == 0 ); this->value.data.log = ( this->operation==EQ ? val : !val ); break; case GT: this->value.data.log = ( FSTRCMP( sptr1, sptr2 ) > 0 ); break; case LT: this->value.data.log = ( FSTRCMP( sptr1, sptr2 ) < 0 ); break; case GTE: this->value.data.log = ( FSTRCMP( sptr1, sptr2 ) >= 0 ); break; case LTE: this->value.data.log = ( FSTRCMP( sptr1, sptr2 ) <= 0 ); break; /* Concat Strings */ case '+': strcpy( this->value.data.str, sptr1 ); strcat( this->value.data.str, sptr2 ); break; } this->operation = CONST_OP; } else { /* Not a constant */ Allocate_Ptrs( this ); if( !gParse.status ) { rows = gParse.nRows; switch( this->operation ) { /* Compare Strings */ case NE: case EQ: while( rows-- ) { if( !const1 ) null1 = that1->value.undef[rows]; if( !const2 ) null2 = that2->value.undef[rows]; this->value.undef[rows] = (null1 || null2); if( ! this->value.undef[rows] ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; val = ( FSTRCMP( sptr1, sptr2 ) == 0 ); this->value.data.logptr[rows] = ( this->operation==EQ ? val : !val ); } } break; case GT: case LT: while( rows-- ) { if( !const1 ) null1 = that1->value.undef[rows]; if( !const2 ) null2 = that2->value.undef[rows]; this->value.undef[rows] = (null1 || null2); if( ! this->value.undef[rows] ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; val = ( FSTRCMP( sptr1, sptr2 ) ); this->value.data.logptr[rows] = ( this->operation==GT ? val>0 : val<0 ); } } break; case GTE: case LTE: while( rows-- ) { if( !const1 ) null1 = that1->value.undef[rows]; if( !const2 ) null2 = that2->value.undef[rows]; this->value.undef[rows] = (null1 || null2); if( ! this->value.undef[rows] ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; val = ( FSTRCMP( sptr1, sptr2 ) ); this->value.data.logptr[rows] = ( this->operation==GTE ? val>=0 : val<=0 ); } } break; /* Concat Strings */ case '+': while( rows-- ) { if( !const1 ) null1 = that1->value.undef[rows]; if( !const2 ) null2 = that2->value.undef[rows]; this->value.undef[rows] = (null1 || null2); if( ! this->value.undef[rows] ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; strcpy( this->value.data.strptr[rows], sptr1 ); strcat( this->value.data.strptr[rows], sptr2 ); } } break; } } } if( that1->operation>0 ) { free( that1->value.data.strptr[0] ); free( that1->value.data.strptr ); } if( that2->operation>0 ) { free( that2->value.data.strptr[0] ); free( that2->value.data.strptr ); } } static void Do_BinOp_log( Node *this ) { Node *that1, *that2; int vector1, vector2; char val1=0, val2=0, null1=0, null2=0; long rows, nelem, elem; that1 = gParse.Nodes + this->SubNodes[0]; that2 = gParse.Nodes + this->SubNodes[1]; vector1 = ( that1->operation!=CONST_OP ); if( vector1 ) vector1 = that1->value.nelem; else { val1 = that1->value.data.log; } vector2 = ( that2->operation!=CONST_OP ); if( vector2 ) vector2 = that2->value.nelem; else { val2 = that2->value.data.log; } if( !vector1 && !vector2 ) { /* Result is a constant */ switch( this->operation ) { case OR: this->value.data.log = (val1 || val2); break; case AND: this->value.data.log = (val1 && val2); break; case EQ: this->value.data.log = ( (val1 && val2) || (!val1 && !val2) ); break; case NE: this->value.data.log = ( (val1 && !val2) || (!val1 && val2) ); break; case ACCUM: this->value.data.lng = val1; break; } this->operation=CONST_OP; } else if (this->operation == ACCUM) { long i, previous, curr; rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); if( !gParse.status ) { previous = that2->value.data.lng; /* Cumulative sum of this chunk */ for (i=0; ivalue.undef[i]) { curr = that1->value.data.logptr[i]; previous += curr; } this->value.data.lngptr[i] = previous; this->value.undef[i] = 0; } /* Store final cumulant for next pass */ that2->value.data.lng = previous; } } else { rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); if( !gParse.status ) { if (this->operation == ACCUM) { long i, previous, curr; previous = that2->value.data.lng; /* Cumulative sum of this chunk */ for (i=0; ivalue.undef[i]) { curr = that1->value.data.logptr[i]; previous += curr; } this->value.data.lngptr[i] = previous; this->value.undef[i] = 0; } /* Store final cumulant for next pass */ that2->value.data.lng = previous; } while( rows-- ) { while( nelem-- ) { elem--; if( vector1>1 ) { val1 = that1->value.data.logptr[elem]; null1 = that1->value.undef[elem]; } else if( vector1 ) { val1 = that1->value.data.logptr[rows]; null1 = that1->value.undef[rows]; } if( vector2>1 ) { val2 = that2->value.data.logptr[elem]; null2 = that2->value.undef[elem]; } else if( vector2 ) { val2 = that2->value.data.logptr[rows]; null2 = that2->value.undef[rows]; } this->value.undef[elem] = (null1 || null2); switch( this->operation ) { case OR: /* This is more complicated than others to suppress UNDEFs */ /* in those cases where the other argument is DEF && TRUE */ if( !null1 && !null2 ) { this->value.data.logptr[elem] = (val1 || val2); } else if( (null1 && !null2 && val2) || ( !null1 && null2 && val1 ) ) { this->value.data.logptr[elem] = 1; this->value.undef[elem] = 0; } break; case AND: /* This is more complicated than others to suppress UNDEFs */ /* in those cases where the other argument is DEF && FALSE */ if( !null1 && !null2 ) { this->value.data.logptr[elem] = (val1 && val2); } else if( (null1 && !null2 && !val2) || ( !null1 && null2 && !val1 ) ) { this->value.data.logptr[elem] = 0; this->value.undef[elem] = 0; } break; case EQ: this->value.data.logptr[elem] = ( (val1 && val2) || (!val1 && !val2) ); break; case NE: this->value.data.logptr[elem] = ( (val1 && !val2) || (!val1 && val2) ); break; } } nelem = this->value.nelem; } } } if( that1->operation>0 ) { free( that1->value.data.ptr ); } if( that2->operation>0 ) { free( that2->value.data.ptr ); } } static void Do_BinOp_lng( Node *this ) { Node *that1, *that2; int vector1, vector2; long val1=0, val2=0; char null1=0, null2=0; long rows, nelem, elem; that1 = gParse.Nodes + this->SubNodes[0]; that2 = gParse.Nodes + this->SubNodes[1]; vector1 = ( that1->operation!=CONST_OP ); if( vector1 ) vector1 = that1->value.nelem; else { val1 = that1->value.data.lng; } vector2 = ( that2->operation!=CONST_OP ); if( vector2 ) vector2 = that2->value.nelem; else { val2 = that2->value.data.lng; } if( !vector1 && !vector2 ) { /* Result is a constant */ switch( this->operation ) { case '~': /* Treat as == for LONGS */ case EQ: this->value.data.log = (val1 == val2); break; case NE: this->value.data.log = (val1 != val2); break; case GT: this->value.data.log = (val1 > val2); break; case LT: this->value.data.log = (val1 < val2); break; case LTE: this->value.data.log = (val1 <= val2); break; case GTE: this->value.data.log = (val1 >= val2); break; case '+': this->value.data.lng = (val1 + val2); break; case '-': this->value.data.lng = (val1 - val2); break; case '*': this->value.data.lng = (val1 * val2); break; case '%': if( val2 ) this->value.data.lng = (val1 % val2); else fferror("Divide by Zero"); break; case '/': if( val2 ) this->value.data.lng = (val1 / val2); else fferror("Divide by Zero"); break; case POWER: this->value.data.lng = (long)pow((double)val1,(double)val2); break; case ACCUM: this->value.data.lng = val1; break; case DIFF: this->value.data.lng = 0; break; } this->operation=CONST_OP; } else if ((this->operation == ACCUM) || (this->operation == DIFF)) { long i, previous, curr; long undef; rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); if( !gParse.status ) { previous = that2->value.data.lng; undef = (long) that2->value.undef; if (this->operation == ACCUM) { /* Cumulative sum of this chunk */ for (i=0; ivalue.undef[i]) { curr = that1->value.data.lngptr[i]; previous += curr; } this->value.data.lngptr[i] = previous; this->value.undef[i] = 0; } } else { /* Sequential difference for this chunk */ for (i=0; ivalue.data.lngptr[i]; if (that1->value.undef[i] || undef) { /* Either this, or previous, value was undefined */ this->value.data.lngptr[i] = 0; this->value.undef[i] = 1; } else { /* Both defined, we are okay! */ this->value.data.lngptr[i] = curr - previous; this->value.undef[i] = 0; } previous = curr; undef = that1->value.undef[i]; } } /* Store final cumulant for next pass */ that2->value.data.lng = previous; that2->value.undef = (char *) undef; /* XXX evil, but no harm here */ } } else { rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); while( rows-- && !gParse.status ) { while( nelem-- && !gParse.status ) { elem--; if( vector1>1 ) { val1 = that1->value.data.lngptr[elem]; null1 = that1->value.undef[elem]; } else if( vector1 ) { val1 = that1->value.data.lngptr[rows]; null1 = that1->value.undef[rows]; } if( vector2>1 ) { val2 = that2->value.data.lngptr[elem]; null2 = that2->value.undef[elem]; } else if( vector2 ) { val2 = that2->value.data.lngptr[rows]; null2 = that2->value.undef[rows]; } this->value.undef[elem] = (null1 || null2); switch( this->operation ) { case '~': /* Treat as == for LONGS */ case EQ: this->value.data.logptr[elem] = (val1 == val2); break; case NE: this->value.data.logptr[elem] = (val1 != val2); break; case GT: this->value.data.logptr[elem] = (val1 > val2); break; case LT: this->value.data.logptr[elem] = (val1 < val2); break; case LTE: this->value.data.logptr[elem] = (val1 <= val2); break; case GTE: this->value.data.logptr[elem] = (val1 >= val2); break; case '+': this->value.data.lngptr[elem] = (val1 + val2); break; case '-': this->value.data.lngptr[elem] = (val1 - val2); break; case '*': this->value.data.lngptr[elem] = (val1 * val2); break; case '%': if( val2 ) this->value.data.lngptr[elem] = (val1 % val2); else { this->value.data.lngptr[elem] = 0; this->value.undef[elem] = 1; } break; case '/': if( val2 ) this->value.data.lngptr[elem] = (val1 / val2); else { this->value.data.lngptr[elem] = 0; this->value.undef[elem] = 1; } break; case POWER: this->value.data.lngptr[elem] = (long)pow((double)val1,(double)val2); break; } } nelem = this->value.nelem; } } if( that1->operation>0 ) { free( that1->value.data.ptr ); } if( that2->operation>0 ) { free( that2->value.data.ptr ); } } static void Do_BinOp_dbl( Node *this ) { Node *that1, *that2; int vector1, vector2; double val1=0.0, val2=0.0; char null1=0, null2=0; long rows, nelem, elem; that1 = gParse.Nodes + this->SubNodes[0]; that2 = gParse.Nodes + this->SubNodes[1]; vector1 = ( that1->operation!=CONST_OP ); if( vector1 ) vector1 = that1->value.nelem; else { val1 = that1->value.data.dbl; } vector2 = ( that2->operation!=CONST_OP ); if( vector2 ) vector2 = that2->value.nelem; else { val2 = that2->value.data.dbl; } if( !vector1 && !vector2 ) { /* Result is a constant */ switch( this->operation ) { case '~': this->value.data.log = ( fabs(val1-val2) < APPROX ); break; case EQ: this->value.data.log = (val1 == val2); break; case NE: this->value.data.log = (val1 != val2); break; case GT: this->value.data.log = (val1 > val2); break; case LT: this->value.data.log = (val1 < val2); break; case LTE: this->value.data.log = (val1 <= val2); break; case GTE: this->value.data.log = (val1 >= val2); break; case '+': this->value.data.dbl = (val1 + val2); break; case '-': this->value.data.dbl = (val1 - val2); break; case '*': this->value.data.dbl = (val1 * val2); break; case '%': if( val2 ) this->value.data.dbl = val1 - val2*((int)(val1/val2)); else fferror("Divide by Zero"); break; case '/': if( val2 ) this->value.data.dbl = (val1 / val2); else fferror("Divide by Zero"); break; case POWER: this->value.data.dbl = (double)pow(val1,val2); break; case ACCUM: this->value.data.dbl = val1; break; case DIFF: this->value.data.dbl = 0; break; } this->operation=CONST_OP; } else if ((this->operation == ACCUM) || (this->operation == DIFF)) { long i; long undef; double previous, curr; rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); if( !gParse.status ) { previous = that2->value.data.dbl; undef = (long) that2->value.undef; if (this->operation == ACCUM) { /* Cumulative sum of this chunk */ for (i=0; ivalue.undef[i]) { curr = that1->value.data.dblptr[i]; previous += curr; } this->value.data.dblptr[i] = previous; this->value.undef[i] = 0; } } else { /* Sequential difference for this chunk */ for (i=0; ivalue.data.dblptr[i]; if (that1->value.undef[i] || undef) { /* Either this, or previous, value was undefined */ this->value.data.dblptr[i] = 0; this->value.undef[i] = 1; } else { /* Both defined, we are okay! */ this->value.data.dblptr[i] = curr - previous; this->value.undef[i] = 0; } previous = curr; undef = that1->value.undef[i]; } } /* Store final cumulant for next pass */ that2->value.data.dbl = previous; that2->value.undef = (char *) undef; /* XXX evil, but no harm here */ } } else { rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); while( rows-- && !gParse.status ) { while( nelem-- && !gParse.status ) { elem--; if( vector1>1 ) { val1 = that1->value.data.dblptr[elem]; null1 = that1->value.undef[elem]; } else if( vector1 ) { val1 = that1->value.data.dblptr[rows]; null1 = that1->value.undef[rows]; } if( vector2>1 ) { val2 = that2->value.data.dblptr[elem]; null2 = that2->value.undef[elem]; } else if( vector2 ) { val2 = that2->value.data.dblptr[rows]; null2 = that2->value.undef[rows]; } this->value.undef[elem] = (null1 || null2); switch( this->operation ) { case '~': this->value.data.logptr[elem] = ( fabs(val1-val2) < APPROX ); break; case EQ: this->value.data.logptr[elem] = (val1 == val2); break; case NE: this->value.data.logptr[elem] = (val1 != val2); break; case GT: this->value.data.logptr[elem] = (val1 > val2); break; case LT: this->value.data.logptr[elem] = (val1 < val2); break; case LTE: this->value.data.logptr[elem] = (val1 <= val2); break; case GTE: this->value.data.logptr[elem] = (val1 >= val2); break; case '+': this->value.data.dblptr[elem] = (val1 + val2); break; case '-': this->value.data.dblptr[elem] = (val1 - val2); break; case '*': this->value.data.dblptr[elem] = (val1 * val2); break; case '%': if( val2 ) this->value.data.dblptr[elem] = val1 - val2*((int)(val1/val2)); else { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } break; case '/': if( val2 ) this->value.data.dblptr[elem] = (val1 / val2); else { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } break; case POWER: this->value.data.dblptr[elem] = (double)pow(val1,val2); break; } } nelem = this->value.nelem; } } if( that1->operation>0 ) { free( that1->value.data.ptr ); } if( that2->operation>0 ) { free( that2->value.data.ptr ); } } /* * This Quickselect routine is based on the algorithm described in * "Numerical recipes in C", Second Edition, * Cambridge University Press, 1992, Section 8.5, ISBN 0-521-43108-5 * This code by Nicolas Devillard - 1998. Public domain. * http://ndevilla.free.fr/median/median/src/quickselect.c */ #define ELEM_SWAP(a,b) { register long t=(a);(a)=(b);(b)=t; } /* * qselect_median_lng - select the median value of a long array * * This routine selects the median value of the long integer array * arr[]. If there are an even number of elements, the "lower median" * is selected. * * The array arr[] is scrambled, so users must operate on a scratch * array if they wish the values to be preserved. * * long arr[] - array of values * int n - number of elements in arr * * RETURNS: the lower median value of arr[] * */ long qselect_median_lng(long arr[], int n) { int low, high ; int median; int middle, ll, hh; low = 0 ; high = n-1 ; median = (low + high) / 2; for (;;) { if (high <= low) { /* One element only */ return arr[median]; } if (high == low + 1) { /* Two elements only */ if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; return arr[median]; } /* Find median of low, middle and high items; swap into position low */ middle = (low + high) / 2; if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]) ; if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]) ; /* Swap low item (now in position middle) into position (low+1) */ ELEM_SWAP(arr[middle], arr[low+1]) ; /* Nibble from each end towards middle, swapping items when stuck */ ll = low + 1; hh = high; for (;;) { do ll++; while (arr[low] > arr[ll]) ; do hh--; while (arr[hh] > arr[low]) ; if (hh < ll) break; ELEM_SWAP(arr[ll], arr[hh]) ; } /* Swap middle item (in position low) back into correct position */ ELEM_SWAP(arr[low], arr[hh]) ; /* Re-set active partition */ if (hh <= median) low = ll; if (hh >= median) high = hh - 1; } } #undef ELEM_SWAP #define ELEM_SWAP(a,b) { register double t=(a);(a)=(b);(b)=t; } /* * qselect_median_dbl - select the median value of a double array * * This routine selects the median value of the double array * arr[]. If there are an even number of elements, the "lower median" * is selected. * * The array arr[] is scrambled, so users must operate on a scratch * array if they wish the values to be preserved. * * double arr[] - array of values * int n - number of elements in arr * * RETURNS: the lower median value of arr[] * */ double qselect_median_dbl(double arr[], int n) { int low, high ; int median; int middle, ll, hh; low = 0 ; high = n-1 ; median = (low + high) / 2; for (;;) { if (high <= low) { /* One element only */ return arr[median] ; } if (high == low + 1) { /* Two elements only */ if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; return arr[median] ; } /* Find median of low, middle and high items; swap into position low */ middle = (low + high) / 2; if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]) ; if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]) ; /* Swap low item (now in position middle) into position (low+1) */ ELEM_SWAP(arr[middle], arr[low+1]) ; /* Nibble from each end towards middle, swapping items when stuck */ ll = low + 1; hh = high; for (;;) { do ll++; while (arr[low] > arr[ll]) ; do hh--; while (arr[hh] > arr[low]) ; if (hh < ll) break; ELEM_SWAP(arr[ll], arr[hh]) ; } /* Swap middle item (in position low) back into correct position */ ELEM_SWAP(arr[low], arr[hh]) ; /* Re-set active partition */ if (hh <= median) low = ll; if (hh >= median) high = hh - 1; } } #undef ELEM_SWAP /* * angsep_calc - compute angular separation between celestial coordinates * * This routine computes the angular separation between to coordinates * on the celestial sphere (i.e. RA and Dec). Note that all units are * in DEGREES, unlike the other trig functions in the calculator. * * double ra1, dec1 - RA and Dec of the first position in degrees * double ra2, dec2 - RA and Dec of the second position in degrees * * RETURNS: (double) angular separation in degrees * */ double angsep_calc(double ra1, double dec1, double ra2, double dec2) { double cd; static double deg = 0; if (deg == 0) deg = ((double)4)*atan((double)1)/((double)180); /* deg = 1.0; **** UNCOMMENT IF YOU WANT RADIANS */ cd = sin(dec1*deg)*sin(dec2*deg) + cos(dec1*deg)*cos(dec2*deg)*cos((ra1-ra2)*deg); if (cd < (-1)) cd = -1; if (cd > (+1)) cd = +1; return acos(cd)/deg; } static double ran1() { static double dval = 0.0; double rndVal; if (dval == 0.0) { if( rand()<32768 && rand()<32768 ) dval = 32768.0; else dval = 2147483648.0; } rndVal = (double)rand(); while( rndVal > dval ) dval *= 2.0; return rndVal/dval; } /* Gaussian deviate routine from Numerical Recipes */ static double gasdev() { static int iset = 0; static double gset; double fac, rsq, v1, v2; if (iset == 0) { do { v1 = 2.0*ran1()-1.0; v2 = 2.0*ran1()-1.0; rsq = v1*v1 + v2*v2; } while (rsq >= 1.0 || rsq == 0.0); fac = sqrt(-2.0*log(rsq)/rsq); gset = v1*fac; iset = 1; return v2*fac; } else { iset = 0; return gset; } } /* lgamma function - from Numerical Recipes */ float gammaln(float xx) /* Returns the value ln Gamma[(xx)] for xx > 0. */ { /* Internal arithmetic will be done in double precision, a nicety that you can omit if five-figure accuracy is good enough. */ double x,y,tmp,ser; static double cof[6]={76.18009172947146,-86.50532032941677, 24.01409824083091,-1.231739572450155, 0.1208650973866179e-2,-0.5395239384953e-5}; int j; y=x=xx; tmp=x+5.5; tmp -= (x+0.5)*log(tmp); ser=1.000000000190015; for (j=0;j<=5;j++) ser += cof[j]/++y; return (float) -tmp+log(2.5066282746310005*ser/x); } /* Poisson deviate - derived from Numerical Recipes */ static long poidev(double xm) { static double sq, alxm, g, oldm = -1.0; static double pi = 0; double em, t, y; if (pi == 0) pi = ((double)4)*atan((double)1); if (xm < 20.0) { if (xm != oldm) { oldm = xm; g = exp(-xm); } em = -1; t = 1.0; do { em += 1; t *= ran1(); } while (t > g); } else { if (xm != oldm) { oldm = xm; sq = sqrt(2.0*xm); alxm = log(xm); g = xm*alxm-gammaln( (float) (xm+1.0)); } do { do { y = tan(pi*ran1()); em = sq*y+xm; } while (em < 0.0); em = floor(em); t = 0.9*(1.0+y*y)*exp(em*alxm-gammaln( (float) (em+1.0) )-g); } while (ran1() > t); } /* Return integer version */ return (long int) floor(em+0.5); } static void Do_Func( Node *this ) { Node *theParams[MAXSUBS]; int vector[MAXSUBS], allConst; lval pVals[MAXSUBS]; char pNull[MAXSUBS]; long ival; double dval; int i, valInit; long row, elem, nelem; i = this->nSubNodes; allConst = 1; while( i-- ) { theParams[i] = gParse.Nodes + this->SubNodes[i]; vector[i] = ( theParams[i]->operation!=CONST_OP ); if( vector[i] ) { allConst = 0; vector[i] = theParams[i]->value.nelem; } else { if( theParams[i]->type==DOUBLE ) { pVals[i].data.dbl = theParams[i]->value.data.dbl; } else if( theParams[i]->type==LONG ) { pVals[i].data.lng = theParams[i]->value.data.lng; } else if( theParams[i]->type==BOOLEAN ) { pVals[i].data.log = theParams[i]->value.data.log; } else strcpy(pVals[i].data.str, theParams[i]->value.data.str); pNull[i] = 0; } } if( this->nSubNodes==0 ) allConst = 0; /* These do produce scalars */ if( this->operation == poirnd_fct ) allConst = 0; if( this->operation == gasrnd_fct ) allConst = 0; if( this->operation == rnd_fct ) allConst = 0; if( allConst ) { switch( this->operation ) { /* Non-Trig single-argument functions */ case sum_fct: if( theParams[0]->type==BOOLEAN ) this->value.data.lng = ( pVals[0].data.log ? 1 : 0 ); else if( theParams[0]->type==LONG ) this->value.data.lng = pVals[0].data.lng; else if( theParams[0]->type==DOUBLE ) this->value.data.dbl = pVals[0].data.dbl; else if( theParams[0]->type==BITSTR ) strcpy(this->value.data.str, pVals[0].data.str); break; case average_fct: if( theParams[0]->type==LONG ) this->value.data.dbl = pVals[0].data.lng; else if( theParams[0]->type==DOUBLE ) this->value.data.dbl = pVals[0].data.dbl; break; case stddev_fct: this->value.data.dbl = 0; /* Standard deviation of a constant = 0 */ break; case median_fct: if( theParams[0]->type==BOOLEAN ) this->value.data.lng = ( pVals[0].data.log ? 1 : 0 ); else if( theParams[0]->type==LONG ) this->value.data.lng = pVals[0].data.lng; else this->value.data.dbl = pVals[0].data.dbl; break; case poirnd_fct: if( theParams[0]->type==DOUBLE ) this->value.data.lng = poidev(pVals[0].data.dbl); else this->value.data.lng = poidev(pVals[0].data.lng); break; case abs_fct: if( theParams[0]->type==DOUBLE ) { dval = pVals[0].data.dbl; this->value.data.dbl = (dval>0.0 ? dval : -dval); } else { ival = pVals[0].data.lng; this->value.data.lng = (ival> 0 ? ival : -ival); } break; /* Special Null-Handling Functions */ case nonnull_fct: this->value.data.lng = 1; /* Constants are always 1-element and defined */ break; case isnull_fct: /* Constants are always defined */ this->value.data.log = 0; break; case defnull_fct: if( this->type==BOOLEAN ) this->value.data.log = pVals[0].data.log; else if( this->type==LONG ) this->value.data.lng = pVals[0].data.lng; else if( this->type==DOUBLE ) this->value.data.dbl = pVals[0].data.dbl; else if( this->type==STRING ) strcpy(this->value.data.str,pVals[0].data.str); break; /* Math functions with 1 double argument */ case sin_fct: this->value.data.dbl = sin( pVals[0].data.dbl ); break; case cos_fct: this->value.data.dbl = cos( pVals[0].data.dbl ); break; case tan_fct: this->value.data.dbl = tan( pVals[0].data.dbl ); break; case asin_fct: dval = pVals[0].data.dbl; if( dval<-1.0 || dval>1.0 ) fferror("Out of range argument to arcsin"); else this->value.data.dbl = asin( dval ); break; case acos_fct: dval = pVals[0].data.dbl; if( dval<-1.0 || dval>1.0 ) fferror("Out of range argument to arccos"); else this->value.data.dbl = acos( dval ); break; case atan_fct: this->value.data.dbl = atan( pVals[0].data.dbl ); break; case sinh_fct: this->value.data.dbl = sinh( pVals[0].data.dbl ); break; case cosh_fct: this->value.data.dbl = cosh( pVals[0].data.dbl ); break; case tanh_fct: this->value.data.dbl = tanh( pVals[0].data.dbl ); break; case exp_fct: this->value.data.dbl = exp( pVals[0].data.dbl ); break; case log_fct: dval = pVals[0].data.dbl; if( dval<=0.0 ) fferror("Out of range argument to log"); else this->value.data.dbl = log( dval ); break; case log10_fct: dval = pVals[0].data.dbl; if( dval<=0.0 ) fferror("Out of range argument to log10"); else this->value.data.dbl = log10( dval ); break; case sqrt_fct: dval = pVals[0].data.dbl; if( dval<0.0 ) fferror("Out of range argument to sqrt"); else this->value.data.dbl = sqrt( dval ); break; case ceil_fct: this->value.data.dbl = ceil( pVals[0].data.dbl ); break; case floor_fct: this->value.data.dbl = floor( pVals[0].data.dbl ); break; case round_fct: this->value.data.dbl = floor( pVals[0].data.dbl + 0.5 ); break; /* Two-argument Trig Functions */ case atan2_fct: this->value.data.dbl = atan2( pVals[0].data.dbl, pVals[1].data.dbl ); break; /* Four-argument ANGSEP function */ case angsep_fct: this->value.data.dbl = angsep_calc(pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl); /* Min/Max functions taking 1 or 2 arguments */ case min1_fct: /* No constant vectors! */ if( this->type == DOUBLE ) this->value.data.dbl = pVals[0].data.dbl; else if( this->type == LONG ) this->value.data.lng = pVals[0].data.lng; else if( this->type == BITSTR ) strcpy(this->value.data.str, pVals[0].data.str); break; case min2_fct: if( this->type == DOUBLE ) this->value.data.dbl = minvalue( pVals[0].data.dbl, pVals[1].data.dbl ); else if( this->type == LONG ) this->value.data.lng = minvalue( pVals[0].data.lng, pVals[1].data.lng ); break; case max1_fct: /* No constant vectors! */ if( this->type == DOUBLE ) this->value.data.dbl = pVals[0].data.dbl; else if( this->type == LONG ) this->value.data.lng = pVals[0].data.lng; else if( this->type == BITSTR ) strcpy(this->value.data.str, pVals[0].data.str); break; case max2_fct: if( this->type == DOUBLE ) this->value.data.dbl = maxvalue( pVals[0].data.dbl, pVals[1].data.dbl ); else if( this->type == LONG ) this->value.data.lng = maxvalue( pVals[0].data.lng, pVals[1].data.lng ); break; /* Boolean SAO region Functions... scalar or vector dbls */ case near_fct: this->value.data.log = bnear( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl ); break; case circle_fct: this->value.data.log = circle( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl ); break; case box_fct: this->value.data.log = saobox( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl, pVals[5].data.dbl, pVals[6].data.dbl ); break; case elps_fct: this->value.data.log = ellipse( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl, pVals[5].data.dbl, pVals[6].data.dbl ); break; /* C Conditional expression: bool ? expr : expr */ case ifthenelse_fct: switch( this->type ) { case BOOLEAN: this->value.data.log = ( pVals[2].data.log ? pVals[0].data.log : pVals[1].data.log ); break; case LONG: this->value.data.lng = ( pVals[2].data.log ? pVals[0].data.lng : pVals[1].data.lng ); break; case DOUBLE: this->value.data.dbl = ( pVals[2].data.log ? pVals[0].data.dbl : pVals[1].data.dbl ); break; case STRING: strcpy(this->value.data.str, ( pVals[2].data.log ? pVals[0].data.str : pVals[1].data.str ) ); break; } break; } this->operation = CONST_OP; } else { Allocate_Ptrs( this ); row = gParse.nRows; elem = row * this->value.nelem; if( !gParse.status ) { switch( this->operation ) { /* Special functions with no arguments */ case row_fct: while( row-- ) { this->value.data.lngptr[row] = gParse.firstRow + row; this->value.undef[row] = 0; } break; case null_fct: if( this->type==LONG ) { while( row-- ) { this->value.data.lngptr[row] = 0; this->value.undef[row] = 1; } } else if( this->type==STRING ) { while( row-- ) { this->value.data.strptr[row][0] = '\0'; this->value.undef[row] = 1; } } break; case rnd_fct: while( elem-- ) { this->value.data.dblptr[elem] = ran1(); this->value.undef[elem] = 0; } break; case gasrnd_fct: while( elem-- ) { this->value.data.dblptr[elem] = gasdev(); this->value.undef[elem] = 0; } break; case poirnd_fct: if( theParams[0]->type==DOUBLE ) { if (theParams[0]->operation == CONST_OP) { while( elem-- ) { this->value.undef[elem] = (pVals[0].data.dbl < 0); if (! this->value.undef[elem]) { this->value.data.lngptr[elem] = poidev(pVals[0].data.dbl); } } } else { while( elem-- ) { this->value.undef[elem] = theParams[0]->value.undef[elem]; if (theParams[0]->value.data.dblptr[elem] < 0) this->value.undef[elem] = 1; if (! this->value.undef[elem]) { this->value.data.lngptr[elem] = poidev(theParams[0]->value.data.dblptr[elem]); } } /* while */ } /* ! CONST_OP */ } else { /* LONG */ if (theParams[0]->operation == CONST_OP) { while( elem-- ) { this->value.undef[elem] = (pVals[0].data.lng < 0); if (! this->value.undef[elem]) { this->value.data.lngptr[elem] = poidev(pVals[0].data.lng); } } } else { while( elem-- ) { this->value.undef[elem] = theParams[0]->value.undef[elem]; if (theParams[0]->value.data.lngptr[elem] < 0) this->value.undef[elem] = 1; if (! this->value.undef[elem]) { this->value.data.lngptr[elem] = poidev(theParams[0]->value.data.lngptr[elem]); } } /* while */ } /* ! CONST_OP */ } /* END LONG */ break; /* Non-Trig single-argument functions */ case sum_fct: elem = row * theParams[0]->value.nelem; if( theParams[0]->type==BOOLEAN ) { while( row-- ) { this->value.data.lngptr[row] = 0; /* Default is UNDEF until a defined value is found */ this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( ! theParams[0]->value.undef[elem] ) { this->value.data.lngptr[row] += ( theParams[0]->value.data.logptr[elem] ? 1 : 0 ); this->value.undef[row] = 0; } } } } else if( theParams[0]->type==LONG ) { while( row-- ) { this->value.data.lngptr[row] = 0; /* Default is UNDEF until a defined value is found */ this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( ! theParams[0]->value.undef[elem] ) { this->value.data.lngptr[row] += theParams[0]->value.data.lngptr[elem]; this->value.undef[row] = 0; } } } } else if( theParams[0]->type==DOUBLE ){ while( row-- ) { this->value.data.dblptr[row] = 0.0; /* Default is UNDEF until a defined value is found */ this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( ! theParams[0]->value.undef[elem] ) { this->value.data.dblptr[row] += theParams[0]->value.data.dblptr[elem]; this->value.undef[row] = 0; } } } } else { /* BITSTR */ nelem = theParams[0]->value.nelem; while( row-- ) { char *sptr1 = theParams[0]->value.data.strptr[row]; this->value.data.lngptr[row] = 0; this->value.undef[row] = 0; while (*sptr1) { if (*sptr1 == '1') this->value.data.lngptr[row] ++; sptr1++; } } } break; case average_fct: elem = row * theParams[0]->value.nelem; if( theParams[0]->type==LONG ) { while( row-- ) { int count = 0; this->value.data.dblptr[row] = 0; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { this->value.data.dblptr[row] += theParams[0]->value.data.lngptr[elem]; count ++; } } if (count == 0) { this->value.undef[row] = 1; } else { this->value.undef[row] = 0; this->value.data.dblptr[row] /= count; } } } else if( theParams[0]->type==DOUBLE ){ while( row-- ) { int count = 0; this->value.data.dblptr[row] = 0; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { this->value.data.dblptr[row] += theParams[0]->value.data.dblptr[elem]; count ++; } } if (count == 0) { this->value.undef[row] = 1; } else { this->value.undef[row] = 0; this->value.data.dblptr[row] /= count; } } } break; case stddev_fct: elem = row * theParams[0]->value.nelem; if( theParams[0]->type==LONG ) { /* Compute the mean value */ while( row-- ) { int count = 0; double sum = 0, sum2 = 0; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { sum += theParams[0]->value.data.lngptr[elem]; count ++; } } if (count > 1) { sum /= count; /* Compute the sum of squared deviations */ nelem = theParams[0]->value.nelem; elem += nelem; /* Reset elem for second pass */ while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { double dx = (theParams[0]->value.data.lngptr[elem] - sum); sum2 += (dx*dx); } } sum2 /= (double)count-1; this->value.undef[row] = 0; this->value.data.dblptr[row] = sqrt(sum2); } else { this->value.undef[row] = 0; /* STDDEV => 0 */ this->value.data.dblptr[row] = 0; } } } else if( theParams[0]->type==DOUBLE ){ /* Compute the mean value */ while( row-- ) { int count = 0; double sum = 0, sum2 = 0; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { sum += theParams[0]->value.data.dblptr[elem]; count ++; } } if (count > 1) { sum /= count; /* Compute the sum of squared deviations */ nelem = theParams[0]->value.nelem; elem += nelem; /* Reset elem for second pass */ while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { double dx = (theParams[0]->value.data.dblptr[elem] - sum); sum2 += (dx*dx); } } sum2 /= (double)count-1; this->value.undef[row] = 0; this->value.data.dblptr[row] = sqrt(sum2); } else { this->value.undef[row] = 0; /* STDDEV => 0 */ this->value.data.dblptr[row] = 0; } } } break; case median_fct: elem = row * theParams[0]->value.nelem; nelem = theParams[0]->value.nelem; if( theParams[0]->type==LONG ) { long *dptr = theParams[0]->value.data.lngptr; char *uptr = theParams[0]->value.undef; long *mptr = (long *) malloc(sizeof(long)*nelem); int irow; /* Allocate temporary storage for this row, since the quickselect function will scramble the contents */ if (mptr == 0) { fferror("Could not allocate temporary memory in median function"); free( this->value.data.ptr ); break; } for (irow=0; irow 0) { this->value.undef[irow] = 0; this->value.data.lngptr[irow] = qselect_median_lng(mptr, nelem1); } else { this->value.undef[irow] = 1; this->value.data.lngptr[irow] = 0; } } free(mptr); } else { double *dptr = theParams[0]->value.data.dblptr; char *uptr = theParams[0]->value.undef; double *mptr = (double *) malloc(sizeof(double)*nelem); int irow; /* Allocate temporary storage for this row, since the quickselect function will scramble the contents */ if (mptr == 0) { fferror("Could not allocate temporary memory in median function"); free( this->value.data.ptr ); break; } for (irow=0; irow 0) { this->value.undef[irow] = 0; this->value.data.dblptr[irow] = qselect_median_dbl(mptr, nelem1); } else { this->value.undef[irow] = 1; this->value.data.dblptr[irow] = 0; } } free(mptr); } break; case abs_fct: if( theParams[0]->type==DOUBLE ) while( elem-- ) { dval = theParams[0]->value.data.dblptr[elem]; this->value.data.dblptr[elem] = (dval>0.0 ? dval : -dval); this->value.undef[elem] = theParams[0]->value.undef[elem]; } else while( elem-- ) { ival = theParams[0]->value.data.lngptr[elem]; this->value.data.lngptr[elem] = (ival> 0 ? ival : -ival); this->value.undef[elem] = theParams[0]->value.undef[elem]; } break; /* Special Null-Handling Functions */ case nonnull_fct: nelem = theParams[0]->value.nelem; if ( theParams[0]->type==STRING ) nelem = 1; elem = row * nelem; while( row-- ) { int nelem1 = nelem; this->value.undef[row] = 0; /* Initialize to 0 (defined) */ this->value.data.lngptr[row] = 0; while( nelem1-- ) { elem --; if ( theParams[0]->value.undef[elem] == 0 ) this->value.data.lngptr[row] ++; } } break; case isnull_fct: if( theParams[0]->type==STRING ) elem = row; while( elem-- ) { this->value.data.logptr[elem] = theParams[0]->value.undef[elem]; this->value.undef[elem] = 0; } break; case defnull_fct: switch( this->type ) { case BOOLEAN: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pNull[i] = theParams[i]->value.undef[elem]; pVals[i].data.log = theParams[i]->value.data.logptr[elem]; } else if( vector[i] ) { pNull[i] = theParams[i]->value.undef[row]; pVals[i].data.log = theParams[i]->value.data.logptr[row]; } if( pNull[0] ) { this->value.undef[elem] = pNull[1]; this->value.data.logptr[elem] = pVals[1].data.log; } else { this->value.undef[elem] = 0; this->value.data.logptr[elem] = pVals[0].data.log; } } } break; case LONG: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pNull[i] = theParams[i]->value.undef[elem]; pVals[i].data.lng = theParams[i]->value.data.lngptr[elem]; } else if( vector[i] ) { pNull[i] = theParams[i]->value.undef[row]; pVals[i].data.lng = theParams[i]->value.data.lngptr[row]; } if( pNull[0] ) { this->value.undef[elem] = pNull[1]; this->value.data.lngptr[elem] = pVals[1].data.lng; } else { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = pVals[0].data.lng; } } } break; case DOUBLE: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pNull[i] = theParams[i]->value.undef[elem]; pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; } else if( vector[i] ) { pNull[i] = theParams[i]->value.undef[row]; pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; } if( pNull[0] ) { this->value.undef[elem] = pNull[1]; this->value.data.dblptr[elem] = pVals[1].data.dbl; } else { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = pVals[0].data.dbl; } } } break; case STRING: while( row-- ) { i=2; while( i-- ) if( vector[i] ) { pNull[i] = theParams[i]->value.undef[row]; strcpy(pVals[i].data.str, theParams[i]->value.data.strptr[row]); } if( pNull[0] ) { this->value.undef[row] = pNull[1]; strcpy(this->value.data.strptr[row],pVals[1].data.str); } else { this->value.undef[elem] = 0; strcpy(this->value.data.strptr[row],pVals[0].data.str); } } } break; /* Math functions with 1 double argument */ case sin_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = sin( theParams[0]->value.data.dblptr[elem] ); } break; case cos_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = cos( theParams[0]->value.data.dblptr[elem] ); } break; case tan_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = tan( theParams[0]->value.data.dblptr[elem] ); } break; case asin_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; if( dval<-1.0 || dval>1.0 ) { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } else this->value.data.dblptr[elem] = asin( dval ); } break; case acos_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; if( dval<-1.0 || dval>1.0 ) { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } else this->value.data.dblptr[elem] = acos( dval ); } break; case atan_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; this->value.data.dblptr[elem] = atan( dval ); } break; case sinh_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = sinh( theParams[0]->value.data.dblptr[elem] ); } break; case cosh_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = cosh( theParams[0]->value.data.dblptr[elem] ); } break; case tanh_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = tanh( theParams[0]->value.data.dblptr[elem] ); } break; case exp_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; this->value.data.dblptr[elem] = exp( dval ); } break; case log_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; if( dval<=0.0 ) { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } else this->value.data.dblptr[elem] = log( dval ); } break; case log10_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; if( dval<=0.0 ) { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } else this->value.data.dblptr[elem] = log10( dval ); } break; case sqrt_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; if( dval<0.0 ) { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } else this->value.data.dblptr[elem] = sqrt( dval ); } break; case ceil_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = ceil( theParams[0]->value.data.dblptr[elem] ); } break; case floor_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = floor( theParams[0]->value.data.dblptr[elem] ); } break; case round_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = floor( theParams[0]->value.data.dblptr[elem] + 0.5); } break; /* Two-argument Trig Functions */ case atan2_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1]) ) ) this->value.data.dblptr[elem] = atan2( pVals[0].data.dbl, pVals[1].data.dbl ); } } break; /* Four-argument ANGSEP Function */ case angsep_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=4; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1] || pNull[2] || pNull[3]) ) ) this->value.data.dblptr[elem] = angsep_calc(pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl); } } break; /* Min/Max functions taking 1 or 2 arguments */ case min1_fct: elem = row * theParams[0]->value.nelem; if( this->type==LONG ) { long minVal=0; while( row-- ) { valInit = 1; this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( !theParams[0]->value.undef[elem] ) { if ( valInit ) { valInit = 0; minVal = theParams[0]->value.data.lngptr[elem]; } else { minVal = minvalue( minVal, theParams[0]->value.data.lngptr[elem] ); } this->value.undef[row] = 0; } } this->value.data.lngptr[row] = minVal; } } else if( this->type==DOUBLE ) { double minVal=0.0; while( row-- ) { valInit = 1; this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( !theParams[0]->value.undef[elem] ) { if ( valInit ) { valInit = 0; minVal = theParams[0]->value.data.dblptr[elem]; } else { minVal = minvalue( minVal, theParams[0]->value.data.dblptr[elem] ); } this->value.undef[row] = 0; } } this->value.data.dblptr[row] = minVal; } } else if( this->type==BITSTR ) { char minVal; while( row-- ) { char *sptr1 = theParams[0]->value.data.strptr[row]; minVal = '1'; while (*sptr1) { if (*sptr1 == '0') minVal = '0'; sptr1++; } this->value.data.strptr[row][0] = minVal; this->value.data.strptr[row][1] = 0; /* Null terminate */ } } break; case min2_fct: if( this->type==LONG ) { while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( pNull[0] && pNull[1] ) { this->value.undef[elem] = 1; this->value.data.lngptr[elem] = 0; } else if (pNull[0]) { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = pVals[1].data.lng; } else if (pNull[1]) { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = pVals[0].data.lng; } else { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = minvalue( pVals[0].data.lng, pVals[1].data.lng ); } } } } else if( this->type==DOUBLE ) { while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( pNull[0] && pNull[1] ) { this->value.undef[elem] = 1; this->value.data.dblptr[elem] = 0; } else if (pNull[0]) { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = pVals[1].data.dbl; } else if (pNull[1]) { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = pVals[0].data.dbl; } else { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = minvalue( pVals[0].data.dbl, pVals[1].data.dbl ); } } } } break; case max1_fct: elem = row * theParams[0]->value.nelem; if( this->type==LONG ) { long maxVal=0; while( row-- ) { valInit = 1; this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( !theParams[0]->value.undef[elem] ) { if ( valInit ) { valInit = 0; maxVal = theParams[0]->value.data.lngptr[elem]; } else { maxVal = maxvalue( maxVal, theParams[0]->value.data.lngptr[elem] ); } this->value.undef[row] = 0; } } this->value.data.lngptr[row] = maxVal; } } else if( this->type==DOUBLE ) { double maxVal=0.0; while( row-- ) { valInit = 1; this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( !theParams[0]->value.undef[elem] ) { if ( valInit ) { valInit = 0; maxVal = theParams[0]->value.data.dblptr[elem]; } else { maxVal = maxvalue( maxVal, theParams[0]->value.data.dblptr[elem] ); } this->value.undef[row] = 0; } } this->value.data.dblptr[row] = maxVal; } } else if( this->type==BITSTR ) { char maxVal; while( row-- ) { char *sptr1 = theParams[0]->value.data.strptr[row]; maxVal = '0'; while (*sptr1) { if (*sptr1 == '1') maxVal = '1'; sptr1++; } this->value.data.strptr[row][0] = maxVal; this->value.data.strptr[row][1] = 0; /* Null terminate */ } } break; case max2_fct: if( this->type==LONG ) { while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( pNull[0] && pNull[1] ) { this->value.undef[elem] = 1; this->value.data.lngptr[elem] = 0; } else if (pNull[0]) { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = pVals[1].data.lng; } else if (pNull[1]) { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = pVals[0].data.lng; } else { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = maxvalue( pVals[0].data.lng, pVals[1].data.lng ); } } } } else if( this->type==DOUBLE ) { while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( pNull[0] && pNull[1] ) { this->value.undef[elem] = 1; this->value.data.dblptr[elem] = 0; } else if (pNull[0]) { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = pVals[1].data.dbl; } else if (pNull[1]) { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = pVals[0].data.dbl; } else { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = maxvalue( pVals[0].data.dbl, pVals[1].data.dbl ); } } } } break; /* Boolean SAO region Functions... scalar or vector dbls */ case near_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=3; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1] || pNull[2]) ) ) this->value.data.logptr[elem] = bnear( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl ); } } break; case circle_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=5; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1] || pNull[2] || pNull[3] || pNull[4]) ) ) this->value.data.logptr[elem] = circle( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl ); } } break; case box_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=7; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1] || pNull[2] || pNull[3] || pNull[4] || pNull[5] || pNull[6] ) ) ) this->value.data.logptr[elem] = saobox( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl, pVals[5].data.dbl, pVals[6].data.dbl ); } } break; case elps_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=7; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1] || pNull[2] || pNull[3] || pNull[4] || pNull[5] || pNull[6] ) ) ) this->value.data.logptr[elem] = ellipse( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl, pVals[5].data.dbl, pVals[6].data.dbl ); } } break; /* C Conditional expression: bool ? expr : expr */ case ifthenelse_fct: switch( this->type ) { case BOOLEAN: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; if( vector[2]>1 ) { pVals[2].data.log = theParams[2]->value.data.logptr[elem]; pNull[2] = theParams[2]->value.undef[elem]; } else if( vector[2] ) { pVals[2].data.log = theParams[2]->value.data.logptr[row]; pNull[2] = theParams[2]->value.undef[row]; } i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.log = theParams[i]->value.data.logptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.log = theParams[i]->value.data.logptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = pNull[2]) ) { if( pVals[2].data.log ) { this->value.data.logptr[elem] = pVals[0].data.log; this->value.undef[elem] = pNull[0]; } else { this->value.data.logptr[elem] = pVals[1].data.log; this->value.undef[elem] = pNull[1]; } } } } break; case LONG: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; if( vector[2]>1 ) { pVals[2].data.log = theParams[2]->value.data.logptr[elem]; pNull[2] = theParams[2]->value.undef[elem]; } else if( vector[2] ) { pVals[2].data.log = theParams[2]->value.data.logptr[row]; pNull[2] = theParams[2]->value.undef[row]; } i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = pNull[2]) ) { if( pVals[2].data.log ) { this->value.data.lngptr[elem] = pVals[0].data.lng; this->value.undef[elem] = pNull[0]; } else { this->value.data.lngptr[elem] = pVals[1].data.lng; this->value.undef[elem] = pNull[1]; } } } } break; case DOUBLE: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; if( vector[2]>1 ) { pVals[2].data.log = theParams[2]->value.data.logptr[elem]; pNull[2] = theParams[2]->value.undef[elem]; } else if( vector[2] ) { pVals[2].data.log = theParams[2]->value.data.logptr[row]; pNull[2] = theParams[2]->value.undef[row]; } i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = pNull[2]) ) { if( pVals[2].data.log ) { this->value.data.dblptr[elem] = pVals[0].data.dbl; this->value.undef[elem] = pNull[0]; } else { this->value.data.dblptr[elem] = pVals[1].data.dbl; this->value.undef[elem] = pNull[1]; } } } } break; case STRING: while( row-- ) { if( vector[2] ) { pVals[2].data.log = theParams[2]->value.data.logptr[row]; pNull[2] = theParams[2]->value.undef[row]; } i=2; while( i-- ) if( vector[i] ) { strcpy( pVals[i].data.str, theParams[i]->value.data.strptr[row] ); pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[row] = pNull[2]) ) { if( pVals[2].data.log ) { strcpy( this->value.data.strptr[row], pVals[0].data.str ); this->value.undef[row] = pNull[0]; } else { strcpy( this->value.data.strptr[row], pVals[1].data.str ); this->value.undef[row] = pNull[1]; } } else { this->value.data.strptr[row][0] = '\0'; } } break; } break; } } } i = this->nSubNodes; while( i-- ) { if( theParams[i]->operation>0 ) { /* Currently only numeric params allowed */ free( theParams[i]->value.data.ptr ); } } } static void Do_Deref( Node *this ) { Node *theVar, *theDims[MAXDIMS]; int isConst[MAXDIMS], allConst; long dimVals[MAXDIMS]; int i, nDims; long row, elem, dsize; theVar = gParse.Nodes + this->SubNodes[0]; i = nDims = this->nSubNodes-1; allConst = 1; while( i-- ) { theDims[i] = gParse.Nodes + this->SubNodes[i+1]; isConst[i] = ( theDims[i]->operation==CONST_OP ); if( isConst[i] ) dimVals[i] = theDims[i]->value.data.lng; else allConst = 0; } if( this->type==DOUBLE ) { dsize = sizeof( double ); } else if( this->type==LONG ) { dsize = sizeof( long ); } else if( this->type==BOOLEAN ) { dsize = sizeof( char ); } else dsize = 0; Allocate_Ptrs( this ); if( !gParse.status ) { if( allConst && theVar->value.naxis==nDims ) { /* Dereference completely using constant indices */ elem = 0; i = nDims; while( i-- ) { if( dimVals[i]<1 || dimVals[i]>theVar->value.naxes[i] ) break; elem = theVar->value.naxes[i]*elem + dimVals[i]-1; } if( i<0 ) { for( row=0; rowtype==STRING ) this->value.undef[row] = theVar->value.undef[row]; else if( this->type==BITSTR ) this->value.undef; /* Dummy - BITSTRs do not have undefs */ else this->value.undef[row] = theVar->value.undef[elem]; if( this->type==DOUBLE ) this->value.data.dblptr[row] = theVar->value.data.dblptr[elem]; else if( this->type==LONG ) this->value.data.lngptr[row] = theVar->value.data.lngptr[elem]; else if( this->type==BOOLEAN ) this->value.data.logptr[row] = theVar->value.data.logptr[elem]; else { /* XXX Note, the below expression uses knowledge of the layout of the string format, namely (nelem+1) characters per string, followed by (nelem+1) "undef" values. */ this->value.data.strptr[row][0] = theVar->value.data.strptr[0][elem+row]; this->value.data.strptr[row][1] = 0; /* Null terminate */ } elem += theVar->value.nelem; } } else { fferror("Index out of range"); free( this->value.data.ptr ); } } else if( allConst && nDims==1 ) { /* Reduce dimensions by 1, using a constant index */ if( dimVals[0] < 1 || dimVals[0] > theVar->value.naxes[ theVar->value.naxis-1 ] ) { fferror("Index out of range"); free( this->value.data.ptr ); } else if ( this->type == BITSTR || this->type == STRING ) { elem = this->value.nelem * (dimVals[0]-1); for( row=0; rowvalue.undef) this->value.undef[row] = theVar->value.undef[row]; memcpy( (char*)this->value.data.strptr[0] + row*sizeof(char)*(this->value.nelem+1), (char*)theVar->value.data.strptr[0] + elem*sizeof(char), this->value.nelem * sizeof(char) ); /* Null terminate */ this->value.data.strptr[row][this->value.nelem] = 0; elem += theVar->value.nelem+1; } } else { elem = this->value.nelem * (dimVals[0]-1); for( row=0; rowvalue.undef + row*this->value.nelem, theVar->value.undef + elem, this->value.nelem * sizeof(char) ); memcpy( (char*)this->value.data.ptr + row*dsize*this->value.nelem, (char*)theVar->value.data.ptr + elem*dsize, this->value.nelem * dsize ); elem += theVar->value.nelem; } } } else if( theVar->value.naxis==nDims ) { /* Dereference completely using an expression for the indices */ for( row=0; rowvalue.undef[row] ) { fferror("Null encountered as vector index"); free( this->value.data.ptr ); break; } else dimVals[i] = theDims[i]->value.data.lngptr[row]; } } if( gParse.status ) break; elem = 0; i = nDims; while( i-- ) { if( dimVals[i]<1 || dimVals[i]>theVar->value.naxes[i] ) break; elem = theVar->value.naxes[i]*elem + dimVals[i]-1; } if( i<0 ) { elem += row*theVar->value.nelem; if( this->type==STRING ) this->value.undef[row] = theVar->value.undef[row]; else if( this->type==BITSTR ) this->value.undef; /* Dummy - BITSTRs do not have undefs */ else this->value.undef[row] = theVar->value.undef[elem]; if( this->type==DOUBLE ) this->value.data.dblptr[row] = theVar->value.data.dblptr[elem]; else if( this->type==LONG ) this->value.data.lngptr[row] = theVar->value.data.lngptr[elem]; else if( this->type==BOOLEAN ) this->value.data.logptr[row] = theVar->value.data.logptr[elem]; else { /* XXX Note, the below expression uses knowledge of the layout of the string format, namely (nelem+1) characters per string, followed by (nelem+1) "undef" values. */ this->value.data.strptr[row][0] = theVar->value.data.strptr[0][elem+row]; this->value.data.strptr[row][1] = 0; /* Null terminate */ } } else { fferror("Index out of range"); free( this->value.data.ptr ); } } } else { /* Reduce dimensions by 1, using a nonconstant expression */ for( row=0; rowvalue.undef[row] ) { fferror("Null encountered as vector index"); free( this->value.data.ptr ); break; } else dimVals[0] = theDims[0]->value.data.lngptr[row]; if( dimVals[0] < 1 || dimVals[0] > theVar->value.naxes[ theVar->value.naxis-1 ] ) { fferror("Index out of range"); free( this->value.data.ptr ); } else if ( this->type == BITSTR || this->type == STRING ) { elem = this->value.nelem * (dimVals[0]-1); elem += row*(theVar->value.nelem+1); if (this->value.undef) this->value.undef[row] = theVar->value.undef[row]; memcpy( (char*)this->value.data.strptr[0] + row*sizeof(char)*(this->value.nelem+1), (char*)theVar->value.data.strptr[0] + elem*sizeof(char), this->value.nelem * sizeof(char) ); /* Null terminate */ this->value.data.strptr[row][this->value.nelem] = 0; } else { elem = this->value.nelem * (dimVals[0]-1); elem += row*theVar->value.nelem; memcpy( this->value.undef + row*this->value.nelem, theVar->value.undef + elem, this->value.nelem * sizeof(char) ); memcpy( (char*)this->value.data.ptr + row*dsize*this->value.nelem, (char*)theVar->value.data.ptr + elem*dsize, this->value.nelem * dsize ); } } } } if( theVar->operation>0 ) { if (theVar->type == STRING || theVar->type == BITSTR) free(theVar->value.data.strptr[0] ); else free( theVar->value.data.ptr ); } for( i=0; ioperation>0 ) { free( theDims[i]->value.data.ptr ); } } static void Do_GTI( Node *this ) { Node *theExpr, *theTimes; double *start, *stop, *times; long elem, nGTI, gti; int ordered; theTimes = gParse.Nodes + this->SubNodes[0]; theExpr = gParse.Nodes + this->SubNodes[1]; nGTI = theTimes->value.nelem; start = theTimes->value.data.dblptr; stop = theTimes->value.data.dblptr + nGTI; ordered = theTimes->type; if( theExpr->operation==CONST_OP ) { this->value.data.log = (Search_GTI( theExpr->value.data.dbl, nGTI, start, stop, ordered )>=0); this->operation = CONST_OP; } else { Allocate_Ptrs( this ); times = theExpr->value.data.dblptr; if( !gParse.status ) { elem = gParse.nRows * this->value.nelem; if( nGTI ) { gti = -1; while( elem-- ) { if( (this->value.undef[elem] = theExpr->value.undef[elem]) ) continue; /* Before searching entire GTI, check the GTI found last time */ if( gti<0 || times[elem]stop[gti] ) { gti = Search_GTI( times[elem], nGTI, start, stop, ordered ); } this->value.data.logptr[elem] = ( gti>=0 ); } } else while( elem-- ) { this->value.data.logptr[elem] = 0; this->value.undef[elem] = 0; } } } if( theExpr->operation>0 ) free( theExpr->value.data.ptr ); } static long Search_GTI( double evtTime, long nGTI, double *start, double *stop, int ordered ) { long gti, step; if( ordered && nGTI>15 ) { /* If time-ordered and lots of GTIs, */ /* use "FAST" Binary search algorithm */ if( evtTime>=start[0] && evtTime<=stop[nGTI-1] ) { gti = step = (nGTI >> 1); while(1) { if( step>1L ) step >>= 1; if( evtTime>stop[gti] ) { if( evtTime>=start[gti+1] ) gti += step; else { gti = -1L; break; } } else if( evtTime=start[gti] && evtTime<=stop[gti] ) break; } return( gti ); } static void Do_REG( Node *this ) { Node *theRegion, *theX, *theY; double Xval=0.0, Yval=0.0; char Xnull=0, Ynull=0; int Xvector, Yvector; long nelem, elem, rows; theRegion = gParse.Nodes + this->SubNodes[0]; theX = gParse.Nodes + this->SubNodes[1]; theY = gParse.Nodes + this->SubNodes[2]; Xvector = ( theX->operation!=CONST_OP ); if( Xvector ) Xvector = theX->value.nelem; else { Xval = theX->value.data.dbl; } Yvector = ( theY->operation!=CONST_OP ); if( Yvector ) Yvector = theY->value.nelem; else { Yval = theY->value.data.dbl; } if( !Xvector && !Yvector ) { this->value.data.log = ( fits_in_region( Xval, Yval, (SAORegion *)theRegion->value.data.ptr ) != 0 ); this->operation = CONST_OP; } else { Allocate_Ptrs( this ); if( !gParse.status ) { rows = gParse.nRows; nelem = this->value.nelem; elem = rows*nelem; while( rows-- ) { while( nelem-- ) { elem--; if( Xvector>1 ) { Xval = theX->value.data.dblptr[elem]; Xnull = theX->value.undef[elem]; } else if( Xvector ) { Xval = theX->value.data.dblptr[rows]; Xnull = theX->value.undef[rows]; } if( Yvector>1 ) { Yval = theY->value.data.dblptr[elem]; Ynull = theY->value.undef[elem]; } else if( Yvector ) { Yval = theY->value.data.dblptr[rows]; Ynull = theY->value.undef[rows]; } this->value.undef[elem] = ( Xnull || Ynull ); if( this->value.undef[elem] ) continue; this->value.data.logptr[elem] = ( fits_in_region( Xval, Yval, (SAORegion *)theRegion->value.data.ptr ) != 0 ); } nelem = this->value.nelem; } } } if( theX->operation>0 ) free( theX->value.data.ptr ); if( theY->operation>0 ) free( theY->value.data.ptr ); } static void Do_Vector( Node *this ) { Node *that; long row, elem, idx, jdx, offset=0; int node; Allocate_Ptrs( this ); if( !gParse.status ) { for( node=0; nodenSubNodes; node++ ) { that = gParse.Nodes + this->SubNodes[node]; if( that->operation == CONST_OP ) { idx = gParse.nRows*this->value.nelem + offset; while( (idx-=this->value.nelem)>=0 ) { this->value.undef[idx] = 0; switch( this->type ) { case BOOLEAN: this->value.data.logptr[idx] = that->value.data.log; break; case LONG: this->value.data.lngptr[idx] = that->value.data.lng; break; case DOUBLE: this->value.data.dblptr[idx] = that->value.data.dbl; break; } } } else { row = gParse.nRows; idx = row * that->value.nelem; while( row-- ) { elem = that->value.nelem; jdx = row*this->value.nelem + offset; while( elem-- ) { this->value.undef[jdx+elem] = that->value.undef[--idx]; switch( this->type ) { case BOOLEAN: this->value.data.logptr[jdx+elem] = that->value.data.logptr[idx]; break; case LONG: this->value.data.lngptr[jdx+elem] = that->value.data.lngptr[idx]; break; case DOUBLE: this->value.data.dblptr[jdx+elem] = that->value.data.dblptr[idx]; break; } } } } offset += that->value.nelem; } } for( node=0; node < this->nSubNodes; node++ ) if( gParse.Nodes[this->SubNodes[node]].operation>0 ) free( gParse.Nodes[this->SubNodes[node]].value.data.ptr ); } /*****************************************************************************/ /* Utility routines which perform the calculations on bits and SAO regions */ /*****************************************************************************/ static char bitlgte(char *bits1, int oper, char *bits2) { int val1, val2, nextbit; char result; int i, l1, l2, length, ldiff; char stream[256]; char chr1, chr2; l1 = strlen(bits1); l2 = strlen(bits2); if (l1 < l2) { length = l2; ldiff = l2 - l1; i=0; while( ldiff-- ) stream[i++] = '0'; while( l1-- ) stream[i++] = *(bits1++); stream[i] = '\0'; bits1 = stream; } else if (l2 < l1) { length = l1; ldiff = l1 - l2; i=0; while( ldiff-- ) stream[i++] = '0'; while( l2-- ) stream[i++] = *(bits2++); stream[i] = '\0'; bits2 = stream; } else length = l1; val1 = val2 = 0; nextbit = 1; while( length-- ) { chr1 = bits1[length]; chr2 = bits2[length]; if ((chr1 != 'x')&&(chr1 != 'X')&&(chr2 != 'x')&&(chr2 != 'X')) { if (chr1 == '1') val1 += nextbit; if (chr2 == '1') val2 += nextbit; nextbit *= 2; } } result = 0; switch (oper) { case LT: if (val1 < val2) result = 1; break; case LTE: if (val1 <= val2) result = 1; break; case GT: if (val1 > val2) result = 1; break; case GTE: if (val1 >= val2) result = 1; break; } return (result); } static void bitand(char *result,char *bitstrm1,char *bitstrm2) { int i, l1, l2, ldiff; char stream[256]; char chr1, chr2; l1 = strlen(bitstrm1); l2 = strlen(bitstrm2); if (l1 < l2) { ldiff = l2 - l1; i=0; while( ldiff-- ) stream[i++] = '0'; while( l1-- ) stream[i++] = *(bitstrm1++); stream[i] = '\0'; bitstrm1 = stream; } else if (l2 < l1) { ldiff = l1 - l2; i=0; while( ldiff-- ) stream[i++] = '0'; while( l2-- ) stream[i++] = *(bitstrm2++); stream[i] = '\0'; bitstrm2 = stream; } while ( (chr1 = *(bitstrm1++)) ) { chr2 = *(bitstrm2++); if ((chr1 == 'x') || (chr2 == 'x')) *result = 'x'; else if ((chr1 == '1') && (chr2 == '1')) *result = '1'; else *result = '0'; result++; } *result = '\0'; } static void bitor(char *result,char *bitstrm1,char *bitstrm2) { int i, l1, l2, ldiff; char stream[256]; char chr1, chr2; l1 = strlen(bitstrm1); l2 = strlen(bitstrm2); if (l1 < l2) { ldiff = l2 - l1; i=0; while( ldiff-- ) stream[i++] = '0'; while( l1-- ) stream[i++] = *(bitstrm1++); stream[i] = '\0'; bitstrm1 = stream; } else if (l2 < l1) { ldiff = l1 - l2; i=0; while( ldiff-- ) stream[i++] = '0'; while( l2-- ) stream[i++] = *(bitstrm2++); stream[i] = '\0'; bitstrm2 = stream; } while ( (chr1 = *(bitstrm1++)) ) { chr2 = *(bitstrm2++); if ((chr1 == '1') || (chr2 == '1')) *result = '1'; else if ((chr1 == '0') || (chr2 == '0')) *result = '0'; else *result = 'x'; result++; } *result = '\0'; } static void bitnot(char *result,char *bits) { int length; char chr; length = strlen(bits); while( length-- ) { chr = *(bits++); *(result++) = ( chr=='1' ? '0' : ( chr=='0' ? '1' : chr ) ); } *result = '\0'; } static char bitcmp(char *bitstrm1, char *bitstrm2) { int i, l1, l2, ldiff; char stream[256]; char chr1, chr2; l1 = strlen(bitstrm1); l2 = strlen(bitstrm2); if (l1 < l2) { ldiff = l2 - l1; i=0; while( ldiff-- ) stream[i++] = '0'; while( l1-- ) stream[i++] = *(bitstrm1++); stream[i] = '\0'; bitstrm1 = stream; } else if (l2 < l1) { ldiff = l1 - l2; i=0; while( ldiff-- ) stream[i++] = '0'; while( l2-- ) stream[i++] = *(bitstrm2++); stream[i] = '\0'; bitstrm2 = stream; } while( (chr1 = *(bitstrm1++)) ) { chr2 = *(bitstrm2++); if ( ((chr1 == '0') && (chr2 == '1')) || ((chr1 == '1') && (chr2 == '0')) ) return( 0 ); } return( 1 ); } static char bnear(double x, double y, double tolerance) { if (fabs(x - y) < tolerance) return ( 1 ); else return ( 0 ); } static char saobox(double xcen, double ycen, double xwid, double ywid, double rot, double xcol, double ycol) { double x,y,xprime,yprime,xmin,xmax,ymin,ymax,theta; theta = (rot / 180.0) * myPI; xprime = xcol - xcen; yprime = ycol - ycen; x = xprime * cos(theta) + yprime * sin(theta); y = -xprime * sin(theta) + yprime * cos(theta); xmin = - 0.5 * xwid; xmax = 0.5 * xwid; ymin = - 0.5 * ywid; ymax = 0.5 * ywid; if ((x >= xmin) && (x <= xmax) && (y >= ymin) && (y <= ymax)) return ( 1 ); else return ( 0 ); } static char circle(double xcen, double ycen, double rad, double xcol, double ycol) { double r2,dx,dy,dlen; dx = xcol - xcen; dy = ycol - ycen; dx *= dx; dy *= dy; dlen = dx + dy; r2 = rad * rad; if (dlen <= r2) return ( 1 ); else return ( 0 ); } static char ellipse(double xcen, double ycen, double xrad, double yrad, double rot, double xcol, double ycol) { double x,y,xprime,yprime,dx,dy,dlen,theta; theta = (rot / 180.0) * myPI; xprime = xcol - xcen; yprime = ycol - ycen; x = xprime * cos(theta) + yprime * sin(theta); y = -xprime * sin(theta) + yprime * cos(theta); dx = x / xrad; dy = y / yrad; dx *= dx; dy *= dy; dlen = dx + dy; if (dlen <= 1.0) return ( 1 ); else return ( 0 ); } static void fferror(char *s) { char msg[80]; if( !gParse.status ) gParse.status = PARSE_SYNTAX_ERR; strncpy(msg, s, 80); msg[79] = '\0'; ffpmsg(msg); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/f77_wrap.h000066400000000000000000000243601215713201500222420ustar00rootroot00000000000000#define UNSIGNED_BYTE #include "cfortran.h" /************************************************************************ Some platforms creates longs as 8-byte integers. On other machines, ints and longs are both 4-bytes, so both are compatible with Fortrans default integer which is 4-bytes. To support 8-byte longs, we must redefine LONGs and convert them to 8-bytes when going to C, and restore them to 4-bytes when returning to Fortran. Ugh!!! *************************************************************************/ #if defined(DECFortran) || (defined(__alpha) && defined(g77Fortran)) \ || (defined(mipsFortran) && _MIPS_SZLONG==64) \ || (defined(IBMR2Fortran) && defined(__64BIT__)) \ || defined(__ia64__) \ || defined (__sparcv9) \ || defined (__x86_64__) \ || defined (_SX) \ || defined (__powerpc64__) /* this may be the same as IBMR2Fortran, above */ #define LONG8BYTES_INT4BYTES #undef LONGV_cfSTR #undef PLONG_cfSTR #undef LONGVVVVVVV_cfTYPE #undef PLONG_cfTYPE #undef LONGV_cfT #undef PLONG_cfT #define LONGV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,LONGV,A,B,C,D,E) #define PLONG_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,PLONG,A,B,C,D,E) #define LONGVVVVVVV_cfTYPE int #define PLONG_cfTYPE int #define LONGV_cfQ(B) long *B, _(B,N); #define PLONG_cfQ(B) long B; #define LONGV_cfT(M,I,A,B,D) ( (_(B,N) = * _3(M,_LONGV_A,I)), \ B = F2Clongv(_(B,N),A) ) #define PLONG_cfT(M,I,A,B,D) ((B=*A),&B) #define LONGV_cfR(A,B,D) C2Flongv(_(B,N),A,B); #define PLONG_cfR(A,B,D) *A=B; #define LONGV_cfH(S,U,B) #define PLONG_cfH(S,U,B) static long *F2Clongv(long size, int *A) { long i; long *B; B=(long *)malloc( size*sizeof(long) ); for(i=0;idsc$a_pointer /* We want single strings to be equivalent to string vectors with */ /* a single element, so ignore the number of elements info in the */ /* vector structure, and rely on the NUM_ELEM definitions. */ #undef STRINGV_cfT #define STRINGV_cfT(M,I,A,B,D) TTTTSTRV(A->dsc$a_pointer, B, \ A->dsc$w_length, \ num_elem(A->dsc$a_pointer, \ A->dsc$w_length, \ _3(M,_STRV_A,I) ) ) #else #ifdef CRAYFortran #define PPSTRING_cfT(M,I,A,B,D) (unsigned char*)_fcdtocp(A) #else #define PPSTRING_cfT(M,I,A,B,D) (unsigned char*)A #endif #endif #define _cfMAX(A,B) ( (A>B) ? A : B ) #define STRINGV_cfQ(B) char **B; unsigned int _(B,N), _(B,M); #define STRINGV_cfR(A,B,D) free(B[0]); free(B); #define TTSTR( A,B,D) \ ((B=(char*)malloc(_cfMAX(D,gMinStrLen)+1))[D]='\0',memcpy(B,A,D), \ kill_trailing(B,' ')) #define TTTTSTRV( A,B,D,E) ( \ _(B,N)=_cfMAX(E,1), \ _(B,M)=_cfMAX(D,gMinStrLen)+1, \ B=(char**)malloc(_(B,N)*sizeof(char*)), \ B[0]=(char*)malloc(_(B,N)*_(B,M)), \ vindex(B,_(B,M),_(B,N),f2cstrv2(A,B[0],D,_(B,M),_(B,N))) \ ) #define RRRRPSTRV(A,B,D) \ c2fstrv2(B[0],A,_(B,M),D,_(B,N)), \ free(B[0]), \ free(B); static char **vindex(char **B, int elem_len, int nelem, char *B0) { int i; if( nelem ) for( i=0;idsc$a_pointer)[0]) #define BYTEV_cfT(M,I,A,B,D) (INTEGER_BYTE*)A->dsc$a_pointer #else #ifdef CRAYFortran #define BYTE_cfN(T,A) _fcd A #define BYTEV_cfN(T,A) _fcd A #define BYTE_cfT(M,I,A,B,D) (INTEGER_BYTE)((_fcdtocp(A))[0]) #define BYTEV_cfT(M,I,A,B,D) (INTEGER_BYTE*)_fcdtocp(A) #else #define BYTE_cfN(T,A) INTEGER_BYTE * A #define BYTEV_cfN(T,A) INTEGER_BYTE * A #define BYTE_cfT(M,I,A,B,D) A[0] #define BYTEV_cfT(M,I,A,B,D) A #endif #endif /************************************************************************ The following definitions and functions handle conversions between C and Fortran arrays of LOGICALS. Individually, LOGICALS are treated as int's but as char's when in an array. cfortran defines (F2C/C2F)LOGICALV but never uses them, so these routines also handle TRUE/FALSE conversions. *************************************************************************/ #undef LOGICALV_cfSTR #undef LOGICALV_cfT #define LOGICALV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,LOGICALV,A,B,C,D,E) #define LOGICALV_cfQ(B) char *B; unsigned int _(B,N); #define LOGICALV_cfT(M,I,A,B,D) (_(B,N)= * _3(M,_LOGV_A,I), \ B=F2CcopyLogVect(_(B,N),A)) #define LOGICALV_cfR(A,B,D) C2FcopyLogVect(_(B,N),A,B); #define LOGICALV_cfH(S,U,B) static char *F2CcopyLogVect(long size, int *A) { long i; char *B; B=(char *)malloc(size*sizeof(char)); for( i=0; i #include #include #include #include "fitsio2.h" static long noutchar; static long noutmax; static int htrans(int a[],int nx,int ny); static void digitize(int a[], int nx, int ny, int scale); static int encode(char *outfile, long *nlen, int a[], int nx, int ny, int scale); static void shuffle(int a[], int n, int n2, int tmp[]); static int htrans64(LONGLONG a[],int nx,int ny); static void digitize64(LONGLONG a[], int nx, int ny, int scale); static int encode64(char *outfile, long *nlen, LONGLONG a[], int nx, int ny, int scale); static void shuffle64(LONGLONG a[], int n, int n2, LONGLONG tmp[]); static void writeint(char *outfile, int a); static void writelonglong(char *outfile, LONGLONG a); static int qwrite(char *outfile, char *a, int n); static int doencode(char *outfile, int a[], int nx, int ny, unsigned char nbitplanes[3]); static int doencode64(char *outfile, LONGLONG a[], int nx, int ny, unsigned char nbitplanes[3]); static int mywrite(char *file, char buffer[], int n); static int qtree_encode(char *outfile, int a[], int n, int nqx, int nqy, int nbitplanes); static int qtree_encode64(char *outfile, LONGLONG a[], int n, int nqx, int nqy, int nbitplanes); static void start_outputing_bits(); static void done_outputing_bits(char *outfile); static void output_nbits(char *outfile, int bits, int n); static void qtree_onebit(int a[], int n, int nx, int ny, unsigned char b[], int bit); static void qtree_onebit64(LONGLONG a[], int n, int nx, int ny, unsigned char b[], int bit); static void qtree_reduce(unsigned char a[], int n, int nx, int ny, unsigned char b[]); static int bufcopy(unsigned char a[], int n, unsigned char buffer[], int *b, int bmax); static void write_bdirect(char *outfile, int a[], int n,int nqx, int nqy, unsigned char scratch[], int bit); static void write_bdirect64(char *outfile, LONGLONG a[], int n,int nqx, int nqy, unsigned char scratch[], int bit); #define output_nybble(outfile,c) output_nbits(outfile,c,4) #define output_huffman(outfile,c) output_nbits(outfile,code[c],ncode[c]) /* ---------------------------------------------------------------------- */ int fits_hcompress(int *a, int ny, int nx, int scale, char *output, long *nbytes, int *status) { /* compress the input image using the H-compress algorithm a - input image array nx - size of X axis of image ny - size of Y axis of image scale - quantization scale factor. Larger values results in more (lossy) compression scale = 0 does lossless compression output - pre-allocated array to hold the output compressed stream of bytes nbyts - input value = size of the output buffer; returned value = size of the compressed byte stream, in bytes NOTE: the nx and ny dimensions as defined within this code are reversed from the usual FITS notation. ny is the fastest varying dimension, which is usually considered the X axis in the FITS image display */ int stat; if (*status > 0) return(*status); /* H-transform */ stat = htrans(a, nx, ny); if (stat) { *status = stat; return(*status); } /* digitize */ digitize(a, nx, ny, scale); /* encode and write to output array */ noutmax = *nbytes; /* input value is the allocated size of the array */ *nbytes = 0; /* reset */ stat = encode(output, nbytes, a, nx, ny, scale); *status = stat; return(*status); } /* ---------------------------------------------------------------------- */ int fits_hcompress64(LONGLONG *a, int ny, int nx, int scale, char *output, long *nbytes, int *status) { /* compress the input image using the H-compress algorithm a - input image array nx - size of X axis of image ny - size of Y axis of image scale - quantization scale factor. Larger values results in more (lossy) compression scale = 0 does lossless compression output - pre-allocated array to hold the output compressed stream of bytes nbyts - size of the compressed byte stream, in bytes NOTE: the nx and ny dimensions as defined within this code are reversed from the usual FITS notation. ny is the fastest varying dimension, which is usually considered the X axis in the FITS image display */ int stat; if (*status > 0) return(*status); /* H-transform */ stat = htrans64(a, nx, ny); if (stat) { *status = stat; return(*status); } /* digitize */ digitize64(a, nx, ny, scale); /* encode and write to output array */ noutmax = *nbytes; /* input value is the allocated size of the array */ *nbytes = 0; /* reset */ stat = encode64(output, nbytes, a, nx, ny, scale); *status = stat; return(*status); } /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* htrans.c H-transform of NX x NY integer image * * Programmer: R. White Date: 11 May 1992 */ /* ######################################################################### */ static int htrans(int a[],int nx,int ny) { int nmax, log2n, h0, hx, hy, hc, nxtop, nytop, i, j, k; int oddx, oddy; int shift, mask, mask2, prnd, prnd2, nrnd2; int s10, s00; int *tmp; /* * log2n is log2 of max(nx,ny) rounded up to next power of 2 */ nmax = (nx>ny) ? nx : ny; log2n = (int) (log((float) nmax)/log(2.0)+0.5); if ( nmax > (1<> shift; hx = (a[s10+1] + a[s10] - a[s00+1] - a[s00]) >> shift; hy = (a[s10+1] - a[s10] + a[s00+1] - a[s00]) >> shift; hc = (a[s10+1] - a[s10] - a[s00+1] + a[s00]) >> shift; /* * Throw away the 2 bottom bits of h0, bottom bit of hx,hy. * To get rounding to be same for positive and negative * numbers, nrnd2 = prnd2 - 1. */ a[s10+1] = hc; a[s10 ] = ( (hx>=0) ? (hx+prnd) : hx ) & mask ; a[s00+1] = ( (hy>=0) ? (hy+prnd) : hy ) & mask ; a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; s00 += 2; s10 += 2; } if (oddy) { /* * do last element in row if row length is odd * s00+1, s10+1 are off edge */ h0 = (a[s10] + a[s00]) << (1-shift); hx = (a[s10] - a[s00]) << (1-shift); a[s10 ] = ( (hx>=0) ? (hx+prnd) : hx ) & mask ; a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; s00 += 1; s10 += 1; } } if (oddx) { /* * do last row if column length is odd * s10, s10+1 are off edge */ s00 = i*ny; for (j = 0; j=0) ? (hy+prnd) : hy ) & mask ; a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; s00 += 2; } if (oddy) { /* * do corner element if both row and column lengths are odd * s00+1, s10, s10+1 are off edge */ h0 = a[s00] << (2-shift); a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; } } /* * now shuffle in each dimension to group coefficients by order */ for (i = 0; i>1; nytop = (nytop+1)>>1; /* * divisor doubles after first reduction */ shift = 1; /* * masks, rounding values double after each iteration */ mask = mask2; prnd = prnd2; mask2 = mask2 << 1; prnd2 = prnd2 << 1; nrnd2 = prnd2 - 1; } free(tmp); return(0); } /* ######################################################################### */ static int htrans64(LONGLONG a[],int nx,int ny) { int nmax, log2n, nxtop, nytop, i, j, k; int oddx, oddy; int shift; int s10, s00; LONGLONG h0, hx, hy, hc, prnd, prnd2, nrnd2, mask, mask2; LONGLONG *tmp; /* * log2n is log2 of max(nx,ny) rounded up to next power of 2 */ nmax = (nx>ny) ? nx : ny; log2n = (int) (log((float) nmax)/log(2.0)+0.5); if ( nmax > (1<> shift; hx = (a[s10+1] + a[s10] - a[s00+1] - a[s00]) >> shift; hy = (a[s10+1] - a[s10] + a[s00+1] - a[s00]) >> shift; hc = (a[s10+1] - a[s10] - a[s00+1] + a[s00]) >> shift; /* * Throw away the 2 bottom bits of h0, bottom bit of hx,hy. * To get rounding to be same for positive and negative * numbers, nrnd2 = prnd2 - 1. */ a[s10+1] = hc; a[s10 ] = ( (hx>=0) ? (hx+prnd) : hx ) & mask ; a[s00+1] = ( (hy>=0) ? (hy+prnd) : hy ) & mask ; a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; s00 += 2; s10 += 2; } if (oddy) { /* * do last element in row if row length is odd * s00+1, s10+1 are off edge */ h0 = (a[s10] + a[s00]) << (1-shift); hx = (a[s10] - a[s00]) << (1-shift); a[s10 ] = ( (hx>=0) ? (hx+prnd) : hx ) & mask ; a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; s00 += 1; s10 += 1; } } if (oddx) { /* * do last row if column length is odd * s10, s10+1 are off edge */ s00 = i*ny; for (j = 0; j=0) ? (hy+prnd) : hy ) & mask ; a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; s00 += 2; } if (oddy) { /* * do corner element if both row and column lengths are odd * s00+1, s10, s10+1 are off edge */ h0 = a[s00] << (2-shift); a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; } } /* * now shuffle in each dimension to group coefficients by order */ for (i = 0; i>1; nytop = (nytop+1)>>1; /* * divisor doubles after first reduction */ shift = 1; /* * masks, rounding values double after each iteration */ mask = mask2; prnd = prnd2; mask2 = mask2 << 1; prnd2 = prnd2 << 1; nrnd2 = prnd2 - 1; } free(tmp); return(0); } /* ######################################################################### */ static void shuffle(int a[], int n, int n2, int tmp[]) { /* int a[]; array to shuffle int n; number of elements to shuffle int n2; second dimension int tmp[]; scratch storage */ int i; int *p1, *p2, *pt; /* * copy odd elements to tmp */ pt = tmp; p1 = &a[n2]; for (i=1; i < n; i += 2) { *pt = *p1; pt += 1; p1 += (n2+n2); } /* * compress even elements into first half of A */ p1 = &a[n2]; p2 = &a[n2+n2]; for (i=2; i0) ? (*p+d) : (*p-d))/scale; } /* ######################################################################### */ static void digitize64(LONGLONG a[], int nx, int ny, int scale) { LONGLONG d, *p, scale64; /* * round to multiple of scale */ if (scale <= 1) return; d=(scale+1)/2-1; scale64 = scale; /* use a 64-bit int for efficiency in the big loop */ for (p=a; p <= &a[nx*ny-1]; p++) *p = ((*p>0) ? (*p+d) : (*p-d))/scale64; } /* ######################################################################### */ /* ######################################################################### */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* encode.c encode H-transform and write to outfile * * Programmer: R. White Date: 2 February 1994 */ static char code_magic[2] = { (char)0xDD, (char)0x99 }; /* ######################################################################### */ static int encode(char *outfile, long *nlength, int a[], int nx, int ny, int scale) { /* FILE *outfile; - change outfile to a char array */ /* long * nlength returned length (in bytes) of the encoded array) int a[]; input H-transform array (nx,ny) int nx,ny; size of H-transform array int scale; scale factor for digitization */ int nel, nx2, ny2, i, j, k, q, vmax[3], nsign, bits_to_go; unsigned char nbitplanes[3]; unsigned char *signbits; int stat = 0; noutchar = 0; /* initialize the number of compressed bytes that have been written */ nel = nx*ny; /* * write magic value */ qwrite(outfile, code_magic, sizeof(code_magic)); writeint(outfile, nx); /* size of image */ writeint(outfile, ny); writeint(outfile, scale); /* scale factor for digitization */ /* * write first value of A (sum of all pixels -- the only value * which does not compress well) */ writelonglong(outfile, (LONGLONG) a[0]); a[0] = 0; /* * allocate array for sign bits and save values, 8 per byte */ signbits = (unsigned char *) malloc((nel+7)/8); if (signbits == (unsigned char *) NULL) { /* fprintf(stderr, "encode: insufficient memory\n"); exit(-1); */ ffpmsg("encode: insufficient memory"); return(DATA_COMPRESSION_ERR); } nsign = 0; bits_to_go = 8; signbits[0] = 0; for (i=0; i 0) { /* * positive element, put zero at end of buffer */ signbits[nsign] <<= 1; bits_to_go -= 1; } else if (a[i] < 0) { /* * negative element, shift in a one */ signbits[nsign] <<= 1; signbits[nsign] |= 1; bits_to_go -= 1; /* * replace a by absolute value */ a[i] = -a[i]; } if (bits_to_go == 0) { /* * filled up this byte, go to the next one */ bits_to_go = 8; nsign += 1; signbits[nsign] = 0; } } if (bits_to_go != 8) { /* * some bits in last element * move bits in last byte to bottom and increment nsign */ signbits[nsign] <<= bits_to_go; nsign += 1; } /* * calculate number of bit planes for 3 quadrants * * quadrant 0=bottom left, 1=bottom right or top left, 2=top right, */ for (q=0; q<3; q++) { vmax[q] = 0; } /* * get maximum absolute value in each quadrant */ nx2 = (nx+1)/2; ny2 = (ny+1)/2; j=0; /* column counter */ k=0; /* row counter */ for (i=0; i=ny2) + (k>=nx2); if (vmax[q] < a[i]) vmax[q] = a[i]; if (++j >= ny) { j = 0; k += 1; } } /* * now calculate number of bits for each quadrant */ for (q = 0; q < 3; q++) { nbitplanes[q] = (int) (log((float) (vmax[q]+1))/log(2.0)+0.5); if ( (vmax[q]+1) > (1< 0) { if ( 0 == qwrite(outfile, (char *) signbits, nsign)) { free(signbits); *nlength = noutchar; ffpmsg("encode: output buffer too small"); return(DATA_COMPRESSION_ERR); } } free(signbits); *nlength = noutchar; if (noutchar >= noutmax) { ffpmsg("encode: output buffer too small"); return(DATA_COMPRESSION_ERR); } return(stat); } /* ######################################################################### */ static int encode64(char *outfile, long *nlength, LONGLONG a[], int nx, int ny, int scale) { /* FILE *outfile; - change outfile to a char array */ /* long * nlength returned length (in bytes) of the encoded array) LONGLONG a[]; input H-transform array (nx,ny) int nx,ny; size of H-transform array int scale; scale factor for digitization */ int nel, nx2, ny2, i, j, k, q, nsign, bits_to_go; LONGLONG vmax[3]; unsigned char nbitplanes[3]; unsigned char *signbits; int stat = 0; noutchar = 0; /* initialize the number of compressed bytes that have been written */ nel = nx*ny; /* * write magic value */ qwrite(outfile, code_magic, sizeof(code_magic)); writeint(outfile, nx); /* size of image */ writeint(outfile, ny); writeint(outfile, scale); /* scale factor for digitization */ /* * write first value of A (sum of all pixels -- the only value * which does not compress well) */ writelonglong(outfile, a[0]); a[0] = 0; /* * allocate array for sign bits and save values, 8 per byte */ signbits = (unsigned char *) malloc((nel+7)/8); if (signbits == (unsigned char *) NULL) { /* fprintf(stderr, "encode: insufficient memory\n"); exit(-1); */ ffpmsg("encode64: insufficient memory"); return(DATA_COMPRESSION_ERR); } nsign = 0; bits_to_go = 8; signbits[0] = 0; for (i=0; i 0) { /* * positive element, put zero at end of buffer */ signbits[nsign] <<= 1; bits_to_go -= 1; } else if (a[i] < 0) { /* * negative element, shift in a one */ signbits[nsign] <<= 1; signbits[nsign] |= 1; bits_to_go -= 1; /* * replace a by absolute value */ a[i] = -a[i]; } if (bits_to_go == 0) { /* * filled up this byte, go to the next one */ bits_to_go = 8; nsign += 1; signbits[nsign] = 0; } } if (bits_to_go != 8) { /* * some bits in last element * move bits in last byte to bottom and increment nsign */ signbits[nsign] <<= bits_to_go; nsign += 1; } /* * calculate number of bit planes for 3 quadrants * * quadrant 0=bottom left, 1=bottom right or top left, 2=top right, */ for (q=0; q<3; q++) { vmax[q] = 0; } /* * get maximum absolute value in each quadrant */ nx2 = (nx+1)/2; ny2 = (ny+1)/2; i = 0; for (k=0; k=ny2) + (k>=nx2); vmax[q] |= a[i]; i++; } } /* * now calculate number of bits for each quadrant */ /* this is a more efficient way to do this, */ for (q = 0; q < 3; q++) { for (nbitplanes[q] = 0; vmax[q]>0; vmax[q] = vmax[q]>>1, nbitplanes[q]++) ; } /* for (q = 0; q < 3; q++) { nbitplanes[q] = log((float) (vmax[q]+1))/log(2.0)+0.5; if ( (vmax[q]+1) > (((LONGLONG) 1)< 0) { if ( 0 == qwrite(outfile, (char *) signbits, nsign)) { free(signbits); *nlength = noutchar; ffpmsg("encode: output buffer too small"); return(DATA_COMPRESSION_ERR); } } free(signbits); *nlength = noutchar; if (noutchar >= noutmax) { ffpmsg("encode64: output buffer too small"); return(DATA_COMPRESSION_ERR); } return(stat); } /* ######################################################################### */ /* ######################################################################### */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* qwrite.c Write binary data * * Programmer: R. White Date: 11 March 1991 */ /* ######################################################################### */ static void writeint(char *outfile, int a) { int i; unsigned char b[4]; /* Write integer A one byte at a time to outfile. * * This is portable from Vax to Sun since it eliminates the * need for byte-swapping. */ for (i=3; i>=0; i--) { b[i] = a & 0x000000ff; a >>= 8; } for (i=0; i<4; i++) qwrite(outfile, (char *) &b[i],1); } /* ######################################################################### */ static void writelonglong(char *outfile, LONGLONG a) { int i; unsigned char b[8]; /* Write integer A one byte at a time to outfile. * * This is portable from Vax to Sun since it eliminates the * need for byte-swapping. */ for (i=7; i>=0; i--) { b[i] = (unsigned char) (a & 0x000000ff); a >>= 8; } for (i=0; i<8; i++) qwrite(outfile, (char *) &b[i],1); } /* ######################################################################### */ static int qwrite(char *outfile, char *a, int n) { int nwrite; nwrite = mywrite(outfile, a, n); return(nwrite); /* added by WDP to prevent compiler warning */ } /* ######################################################################### */ static int mywrite(char *file, char buffer[], int n) { /* * write n bytes from buffer into file * returns number of bytes read (=n) if successful, <=0 if not */ if (noutchar + n > noutmax) return(0); /* buffer overflow */ memcpy(&file[noutchar], buffer, n); noutchar += n; return(n); } /* ######################################################################### */ /* ######################################################################### */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* doencode.c Encode 2-D array and write stream of characters on outfile * * This version assumes that A is positive. * * Programmer: R. White Date: 7 May 1991 */ /* ######################################################################### */ static int doencode(char *outfile, int a[], int nx, int ny, unsigned char nbitplanes[3]) { /* char *outfile; output data stream int a[]; Array of values to encode int nx,ny; Array dimensions [nx][ny] unsigned char nbitplanes[3]; Number of bit planes in quadrants */ int nx2, ny2, stat = 0; nx2 = (nx+1)/2; ny2 = (ny+1)/2; /* * Initialize bit output */ start_outputing_bits(); /* * write out the bit planes for each quadrant */ stat = qtree_encode(outfile, &a[0], ny, nx2, ny2, nbitplanes[0]); if (!stat) stat = qtree_encode(outfile, &a[ny2], ny, nx2, ny/2, nbitplanes[1]); if (!stat) stat = qtree_encode(outfile, &a[ny*nx2], ny, nx/2, ny2, nbitplanes[1]); if (!stat) stat = qtree_encode(outfile, &a[ny*nx2+ny2], ny, nx/2, ny/2, nbitplanes[2]); /* * Add zero as an EOF symbol */ output_nybble(outfile, 0); done_outputing_bits(outfile); return(stat); } /* ######################################################################### */ static int doencode64(char *outfile, LONGLONG a[], int nx, int ny, unsigned char nbitplanes[3]) { /* char *outfile; output data stream LONGLONG a[]; Array of values to encode int nx,ny; Array dimensions [nx][ny] unsigned char nbitplanes[3]; Number of bit planes in quadrants */ int nx2, ny2, stat = 0; nx2 = (nx+1)/2; ny2 = (ny+1)/2; /* * Initialize bit output */ start_outputing_bits(); /* * write out the bit planes for each quadrant */ stat = qtree_encode64(outfile, &a[0], ny, nx2, ny2, nbitplanes[0]); if (!stat) stat = qtree_encode64(outfile, &a[ny2], ny, nx2, ny/2, nbitplanes[1]); if (!stat) stat = qtree_encode64(outfile, &a[ny*nx2], ny, nx/2, ny2, nbitplanes[1]); if (!stat) stat = qtree_encode64(outfile, &a[ny*nx2+ny2], ny, nx/2, ny/2, nbitplanes[2]); /* * Add zero as an EOF symbol */ output_nybble(outfile, 0); done_outputing_bits(outfile); return(stat); } /* ######################################################################### */ /* ######################################################################### */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* BIT OUTPUT ROUTINES */ static LONGLONG bitcount; /* THE BIT BUFFER */ static int buffer2; /* Bits buffered for output */ static int bits_to_go2; /* Number of bits free in buffer */ /* ######################################################################### */ /* INITIALIZE FOR BIT OUTPUT */ static void start_outputing_bits() { buffer2 = 0; /* Buffer is empty to start */ bits_to_go2 = 8; /* with */ bitcount = 0; } /* ######################################################################### */ /* OUTPUT N BITS (N must be <= 8) */ static void output_nbits(char *outfile, int bits, int n) { /* * insert bits at end of buffer */ buffer2 <<= n; buffer2 |= ( bits & ((1<>(-bits_to_go2)) & 0xff,outfile); */ outfile[noutchar] = ((buffer2>>(-bits_to_go2)) & 0xff); if (noutchar < noutmax) noutchar++; bits_to_go2 += 8; } bitcount += n; } /* ######################################################################### */ /* FLUSH OUT THE LAST BITS */ static void done_outputing_bits(char *outfile) { if(bits_to_go2 < 8) { /* putc(buffer2<nqy) ? nqx : nqy; log2n = (int) (log((float) nqmax)/log(2.0)+0.5); if (nqmax > (1<= 0; bit--) { /* * initial bit buffer */ b = 0; bitbuffer = 0; bits_to_go3 = 0; /* * on first pass copy A to scratch array */ qtree_onebit(a,n,nqx,nqy,scratch,bit); nx = (nqx+1)>>1; ny = (nqy+1)>>1; /* * copy non-zero values to output buffer, which will be written * in reverse order */ if (bufcopy(scratch,nx*ny,buffer,&b,bmax)) { /* * quadtree is expanding data, * change warning code and just fill buffer with bit-map */ write_bdirect(outfile,a,n,nqx,nqy,scratch,bit); goto bitplane_done; } /* * do log2n reductions */ for (k = 1; k>1; ny = (ny+1)>>1; if (bufcopy(scratch,nx*ny,buffer,&b,bmax)) { write_bdirect(outfile,a,n,nqx,nqy,scratch,bit); goto bitplane_done; } } /* * OK, we've got the code in buffer * Write quadtree warning code, then write buffer in reverse order */ output_nybble(outfile,0xF); if (b==0) { if (bits_to_go3>0) { /* * put out the last few bits */ output_nbits(outfile, bitbuffer & ((1<0) { /* * put out the last few bits */ output_nbits(outfile, bitbuffer & ((1<=0; i--) { output_nbits(outfile,buffer[i],8); } } bitplane_done: ; } free(buffer); free(scratch); return(0); } /* ######################################################################### */ static int qtree_encode64(char *outfile, LONGLONG a[], int n, int nqx, int nqy, int nbitplanes) { /* LONGLONG a[]; int n; physical dimension of row in a int nqx; length of row int nqy; length of column (<=n) int nbitplanes; number of bit planes to output */ int log2n, i, k, bit, b, nqmax, nqx2, nqy2, nx, ny; int bmax; /* this potentially needs to be made a 64-bit int to support large arrays */ unsigned char *scratch, *buffer; /* * log2n is log2 of max(nqx,nqy) rounded up to next power of 2 */ nqmax = (nqx>nqy) ? nqx : nqy; log2n = (int) (log((float) nqmax)/log(2.0)+0.5); if (nqmax > (1<= 0; bit--) { /* * initial bit buffer */ b = 0; bitbuffer = 0; bits_to_go3 = 0; /* * on first pass copy A to scratch array */ qtree_onebit64(a,n,nqx,nqy,scratch,bit); nx = (nqx+1)>>1; ny = (nqy+1)>>1; /* * copy non-zero values to output buffer, which will be written * in reverse order */ if (bufcopy(scratch,nx*ny,buffer,&b,bmax)) { /* * quadtree is expanding data, * change warning code and just fill buffer with bit-map */ write_bdirect64(outfile,a,n,nqx,nqy,scratch,bit); goto bitplane_done; } /* * do log2n reductions */ for (k = 1; k>1; ny = (ny+1)>>1; if (bufcopy(scratch,nx*ny,buffer,&b,bmax)) { write_bdirect64(outfile,a,n,nqx,nqy,scratch,bit); goto bitplane_done; } } /* * OK, we've got the code in buffer * Write quadtree warning code, then write buffer in reverse order */ output_nybble(outfile,0xF); if (b==0) { if (bits_to_go3>0) { /* * put out the last few bits */ output_nbits(outfile, bitbuffer & ((1<0) { /* * put out the last few bits */ output_nbits(outfile, bitbuffer & ((1<=0; i--) { output_nbits(outfile,buffer[i],8); } } bitplane_done: ; } free(buffer); free(scratch); return(0); } /* ######################################################################### */ /* * copy non-zero codes from array to buffer */ static int bufcopy(unsigned char a[], int n, unsigned char buffer[], int *b, int bmax) { int i; for (i = 0; i < n; i++) { if (a[i] != 0) { /* * add Huffman code for a[i] to buffer */ bitbuffer |= code[a[i]] << bits_to_go3; bits_to_go3 += ncode[a[i]]; if (bits_to_go3 >= 8) { buffer[*b] = bitbuffer & 0xFF; *b += 1; /* * return warning code if we fill buffer */ if (*b >= bmax) return(1); bitbuffer >>= 8; bits_to_go3 -= 8; } } } return(0); } /* ######################################################################### */ /* * Do first quadtree reduction step on bit BIT of array A. * Results put into B. * */ static void qtree_onebit(int a[], int n, int nx, int ny, unsigned char b[], int bit) { int i, j, k; int b0, b1, b2, b3; int s10, s00; /* * use selected bit to get amount to shift */ b0 = 1<> bit; k += 1; s00 += 2; s10 += 2; } if (j < ny) { /* * row size is odd, do last element in row * s00+1,s10+1 are off edge */ b[k] = ( ((a[s10 ]<<1) & b1) | ((a[s00 ]<<3) & b3) ) >> bit; k += 1; } } if (i < nx) { /* * column size is odd, do last row * s10,s10+1 are off edge */ s00 = n*i; for (j = 0; j> bit; k += 1; s00 += 2; } if (j < ny) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ b[k] = ( ((a[s00 ]<<3) & b3) ) >> bit; k += 1; } } } /* ######################################################################### */ /* * Do first quadtree reduction step on bit BIT of array A. * Results put into B. * */ static void qtree_onebit64(LONGLONG a[], int n, int nx, int ny, unsigned char b[], int bit) { int i, j, k; LONGLONG b0, b1, b2, b3; int s10, s00; /* * use selected bit to get amount to shift */ b0 = ((LONGLONG) 1)<> bit); k += 1; s00 += 2; s10 += 2; } if (j < ny) { /* * row size is odd, do last element in row * s00+1,s10+1 are off edge */ b[k] = (unsigned char) (( ((a[s10 ]<<1) & b1) | ((a[s00 ]<<3) & b3) ) >> bit); k += 1; } } if (i < nx) { /* * column size is odd, do last row * s10,s10+1 are off edge */ s00 = n*i; for (j = 0; j> bit); k += 1; s00 += 2; } if (j < ny) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ b[k] = (unsigned char) (( ((a[s00 ]<<3) & b3) ) >> bit); k += 1; } } } /* ######################################################################### */ /* * do one quadtree reduction step on array a * results put into b (which may be the same as a) */ static void qtree_reduce(unsigned char a[], int n, int nx, int ny, unsigned char b[]) { int i, j, k; int s10, s00; k = 0; /* k is index of b[i/2,j/2] */ for (i = 0; i #include #include #include #include "fitsio2.h" /* WDP added test to see if min and max are already defined */ #ifndef min #define min(a,b) (((a)<(b))?(a):(b)) #endif #ifndef max #define max(a,b) (((a)>(b))?(a):(b)) #endif #define input_nybble(infile) input_nbits(infile,4) static long nextchar; static int decode(unsigned char *infile, int *a, int *nx, int *ny, int *scale); static int decode64(unsigned char *infile, LONGLONG *a, int *nx, int *ny, int *scale); static int hinv(int a[], int nx, int ny, int smooth ,int scale); static int hinv64(LONGLONG a[], int nx, int ny, int smooth ,int scale); static void undigitize(int a[], int nx, int ny, int scale); static void undigitize64(LONGLONG a[], int nx, int ny, int scale); static void unshuffle(int a[], int n, int n2, int tmp[]); static void unshuffle64(LONGLONG a[], int n, int n2, LONGLONG tmp[]); static void hsmooth(int a[], int nxtop, int nytop, int ny, int scale); static void hsmooth64(LONGLONG a[], int nxtop, int nytop, int ny, int scale); static void qread(unsigned char *infile,char *a, int n); static int readint(unsigned char *infile); static LONGLONG readlonglong(unsigned char *infile); static int dodecode(unsigned char *infile, int a[], int nx, int ny, unsigned char nbitplanes[3]); static int dodecode64(unsigned char *infile, LONGLONG a[], int nx, int ny, unsigned char nbitplanes[3]); static int qtree_decode(unsigned char *infile, int a[], int n, int nqx, int nqy, int nbitplanes); static int qtree_decode64(unsigned char *infile, LONGLONG a[], int n, int nqx, int nqy, int nbitplanes); static void start_inputing_bits(); static int input_bit(unsigned char *infile); static int input_nbits(unsigned char *infile, int n); static void qtree_expand(unsigned char *infile, unsigned char a[], int nx, int ny, unsigned char b[]); static void qtree_bitins(unsigned char a[], int nx, int ny, int b[], int n, int bit); static void qtree_bitins64(unsigned char a[], int nx, int ny, LONGLONG b[], int n, int bit); static void qtree_copy(unsigned char a[], int nx, int ny, unsigned char b[], int n); static void read_bdirect(unsigned char *infile, int a[], int n, int nqx, int nqy, unsigned char scratch[], int bit); static void read_bdirect64(unsigned char *infile, LONGLONG a[], int n, int nqx, int nqy, unsigned char scratch[], int bit); static int input_huffman(unsigned char *infile); static int myread(unsigned char *file, char buffer[], int n); /* ---------------------------------------------------------------------- */ int fits_hdecompress(unsigned char *input, int smooth, int *a, int *ny, int *nx, int *scale, int *status) { /* decompress the input byte stream using the H-compress algorithm input - input array of compressed bytes a - pre-allocated array to hold the output uncompressed image nx - returned X axis size ny - returned Y axis size NOTE: the nx and ny dimensions as defined within this code are reversed from the usual FITS notation. ny is the fastest varying dimension, which is usually considered the X axis in the FITS image display */ int stat; if (*status > 0) return(*status); /* decode the input array */ stat = decode(input, a, nx, ny, scale); *status = stat; if (stat) return(*status); /* * Un-Digitize */ undigitize(a, *nx, *ny, *scale); /* * Inverse H-transform */ stat = hinv(a, *nx, *ny, smooth, *scale); *status = stat; return(*status); } /* ---------------------------------------------------------------------- */ int fits_hdecompress64(unsigned char *input, int smooth, LONGLONG *a, int *ny, int *nx, int *scale, int *status) { /* decompress the input byte stream using the H-compress algorithm input - input array of compressed bytes a - pre-allocated array to hold the output uncompressed image nx - returned X axis size ny - returned Y axis size NOTE: the nx and ny dimensions as defined within this code are reversed from the usual FITS notation. ny is the fastest varying dimension, which is usually considered the X axis in the FITS image display */ int stat, *iarray, ii, nval; if (*status > 0) return(*status); /* decode the input array */ stat = decode64(input, a, nx, ny, scale); *status = stat; if (stat) return(*status); /* * Un-Digitize */ undigitize64(a, *nx, *ny, *scale); /* * Inverse H-transform */ stat = hinv64(a, *nx, *ny, smooth, *scale); *status = stat; /* pack the I*8 values back into an I*4 array */ iarray = (int *) a; nval = (*nx) * (*ny); for (ii = 0; ii < nval; ii++) iarray[ii] = (int) a[ii]; return(*status); } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* hinv.c Inverse H-transform of NX x NY integer image * * Programmer: R. White Date: 23 July 1993 */ /* ############################################################################ */ static int hinv(int a[], int nx, int ny, int smooth ,int scale) /* int smooth; 0 for no smoothing, else smooth during inversion int scale; used if smoothing is specified */ { int nmax, log2n, i, j, k; int nxtop,nytop,nxf,nyf,c; int oddx,oddy; int shift, bit0, bit1, bit2, mask0, mask1, mask2, prnd0, prnd1, prnd2, nrnd0, nrnd1, nrnd2, lowbit0, lowbit1; int h0, hx, hy, hc; int s10, s00; int *tmp; /* * log2n is log2 of max(nx,ny) rounded up to next power of 2 */ nmax = (nx>ny) ? nx : ny; log2n = (int) (log((float) nmax)/log(2.0)+0.5); if ( nmax > (1<> 1; prnd1 = bit1 >> 1; prnd2 = bit2 >> 1; nrnd0 = prnd0 - 1; nrnd1 = prnd1 - 1; nrnd2 = prnd2 - 1; /* * round h0 to multiple of bit2 */ a[0] = (a[0] + ((a[0] >= 0) ? prnd2 : nrnd2)) & mask2; /* * do log2n expansions * * We're indexing a as a 2-D array with dimensions (nx,ny). */ nxtop = 1; nytop = 1; nxf = nx; nyf = ny; c = 1<=0; k--) { /* * this somewhat cryptic code generates the sequence * ntop[k-1] = (ntop[k]+1)/2, where ntop[log2n] = n */ c = c>>1; nxtop = nxtop<<1; nytop = nytop<<1; if (nxf <= c) { nxtop -= 1; } else { nxf -= c; } if (nyf <= c) { nytop -= 1; } else { nyf -= c; } /* * double shift and fix nrnd0 (because prnd0=0) on last pass */ if (k == 0) { nrnd0 = 0; shift = 2; } /* * unshuffle in each dimension to interleave coefficients */ for (i = 0; i= 0) ? prnd1 : nrnd1)) & mask1; hy = (hy + ((hy >= 0) ? prnd1 : nrnd1)) & mask1; hc = (hc + ((hc >= 0) ? prnd0 : nrnd0)) & mask0; /* * propagate bit0 of hc to hx,hy */ lowbit0 = hc & bit0; hx = (hx >= 0) ? (hx - lowbit0) : (hx + lowbit0); hy = (hy >= 0) ? (hy - lowbit0) : (hy + lowbit0); /* * Propagate bits 0 and 1 of hc,hx,hy to h0. * This could be simplified if we assume h0>0, but then * the inversion would not be lossless for images with * negative pixels. */ lowbit1 = (hc ^ hx ^ hy) & bit1; h0 = (h0 >= 0) ? (h0 + lowbit0 - lowbit1) : (h0 + ((lowbit0 == 0) ? lowbit1 : (lowbit0-lowbit1))); /* * Divide sums by 2 (4 last time) */ a[s10+1] = (h0 + hx + hy + hc) >> shift; a[s10 ] = (h0 + hx - hy - hc) >> shift; a[s00+1] = (h0 - hx + hy - hc) >> shift; a[s00 ] = (h0 - hx - hy + hc) >> shift; s00 += 2; s10 += 2; } if (oddy) { /* * do last element in row if row length is odd * s00+1, s10+1 are off edge */ h0 = a[s00 ]; hx = a[s10 ]; hx = ((hx >= 0) ? (hx+prnd1) : (hx+nrnd1)) & mask1; lowbit1 = hx & bit1; h0 = (h0 >= 0) ? (h0 - lowbit1) : (h0 + lowbit1); a[s10 ] = (h0 + hx) >> shift; a[s00 ] = (h0 - hx) >> shift; } } if (oddx) { /* * do last row if column length is odd * s10, s10+1 are off edge */ s00 = ny*i; for (j = 0; j= 0) ? (hy+prnd1) : (hy+nrnd1)) & mask1; lowbit1 = hy & bit1; h0 = (h0 >= 0) ? (h0 - lowbit1) : (h0 + lowbit1); a[s00+1] = (h0 + hy) >> shift; a[s00 ] = (h0 - hy) >> shift; s00 += 2; } if (oddy) { /* * do corner element if both row and column lengths are odd * s00+1, s10, s10+1 are off edge */ h0 = a[s00 ]; a[s00 ] = h0 >> shift; } } /* * divide all the masks and rounding values by 2 */ bit2 = bit1; bit1 = bit0; bit0 = bit0 >> 1; mask1 = mask0; mask0 = mask0 >> 1; prnd1 = prnd0; prnd0 = prnd0 >> 1; nrnd1 = nrnd0; nrnd0 = prnd0 - 1; } free(tmp); return(0); } /* ############################################################################ */ static int hinv64(LONGLONG a[], int nx, int ny, int smooth ,int scale) /* int smooth; 0 for no smoothing, else smooth during inversion int scale; used if smoothing is specified */ { int nmax, log2n, i, j, k; int nxtop,nytop,nxf,nyf,c; int oddx,oddy; int shift; LONGLONG mask0, mask1, mask2, prnd0, prnd1, prnd2, bit0, bit1, bit2; LONGLONG nrnd0, nrnd1, nrnd2, lowbit0, lowbit1; LONGLONG h0, hx, hy, hc; int s10, s00; LONGLONG *tmp; /* * log2n is log2 of max(nx,ny) rounded up to next power of 2 */ nmax = (nx>ny) ? nx : ny; log2n = (int) (log((float) nmax)/log(2.0)+0.5); if ( nmax > (1<> 1; prnd1 = bit1 >> 1; prnd2 = bit2 >> 1; nrnd0 = prnd0 - 1; nrnd1 = prnd1 - 1; nrnd2 = prnd2 - 1; /* * round h0 to multiple of bit2 */ a[0] = (a[0] + ((a[0] >= 0) ? prnd2 : nrnd2)) & mask2; /* * do log2n expansions * * We're indexing a as a 2-D array with dimensions (nx,ny). */ nxtop = 1; nytop = 1; nxf = nx; nyf = ny; c = 1<=0; k--) { /* * this somewhat cryptic code generates the sequence * ntop[k-1] = (ntop[k]+1)/2, where ntop[log2n] = n */ c = c>>1; nxtop = nxtop<<1; nytop = nytop<<1; if (nxf <= c) { nxtop -= 1; } else { nxf -= c; } if (nyf <= c) { nytop -= 1; } else { nyf -= c; } /* * double shift and fix nrnd0 (because prnd0=0) on last pass */ if (k == 0) { nrnd0 = 0; shift = 2; } /* * unshuffle in each dimension to interleave coefficients */ for (i = 0; i= 0) ? prnd1 : nrnd1)) & mask1; hy = (hy + ((hy >= 0) ? prnd1 : nrnd1)) & mask1; hc = (hc + ((hc >= 0) ? prnd0 : nrnd0)) & mask0; /* * propagate bit0 of hc to hx,hy */ lowbit0 = hc & bit0; hx = (hx >= 0) ? (hx - lowbit0) : (hx + lowbit0); hy = (hy >= 0) ? (hy - lowbit0) : (hy + lowbit0); /* * Propagate bits 0 and 1 of hc,hx,hy to h0. * This could be simplified if we assume h0>0, but then * the inversion would not be lossless for images with * negative pixels. */ lowbit1 = (hc ^ hx ^ hy) & bit1; h0 = (h0 >= 0) ? (h0 + lowbit0 - lowbit1) : (h0 + ((lowbit0 == 0) ? lowbit1 : (lowbit0-lowbit1))); /* * Divide sums by 2 (4 last time) */ a[s10+1] = (h0 + hx + hy + hc) >> shift; a[s10 ] = (h0 + hx - hy - hc) >> shift; a[s00+1] = (h0 - hx + hy - hc) >> shift; a[s00 ] = (h0 - hx - hy + hc) >> shift; s00 += 2; s10 += 2; } if (oddy) { /* * do last element in row if row length is odd * s00+1, s10+1 are off edge */ h0 = a[s00 ]; hx = a[s10 ]; hx = ((hx >= 0) ? (hx+prnd1) : (hx+nrnd1)) & mask1; lowbit1 = hx & bit1; h0 = (h0 >= 0) ? (h0 - lowbit1) : (h0 + lowbit1); a[s10 ] = (h0 + hx) >> shift; a[s00 ] = (h0 - hx) >> shift; } } if (oddx) { /* * do last row if column length is odd * s10, s10+1 are off edge */ s00 = ny*i; for (j = 0; j= 0) ? (hy+prnd1) : (hy+nrnd1)) & mask1; lowbit1 = hy & bit1; h0 = (h0 >= 0) ? (h0 - lowbit1) : (h0 + lowbit1); a[s00+1] = (h0 + hy) >> shift; a[s00 ] = (h0 - hy) >> shift; s00 += 2; } if (oddy) { /* * do corner element if both row and column lengths are odd * s00+1, s10, s10+1 are off edge */ h0 = a[s00 ]; a[s00 ] = h0 >> shift; } } /* * divide all the masks and rounding values by 2 */ bit2 = bit1; bit1 = bit0; bit0 = bit0 >> 1; mask1 = mask0; mask0 = mask0 >> 1; prnd1 = prnd0; prnd0 = prnd0 >> 1; nrnd1 = nrnd0; nrnd0 = prnd0 - 1; } free(tmp); return(0); } /* ############################################################################ */ static void unshuffle(int a[], int n, int n2, int tmp[]) /* int a[]; array to shuffle int n; number of elements to shuffle int n2; second dimension int tmp[]; scratch storage */ { int i; int nhalf; int *p1, *p2, *pt; /* * copy 2nd half of array to tmp */ nhalf = (n+1)>>1; pt = tmp; p1 = &a[n2*nhalf]; /* pointer to a[i] */ for (i=nhalf; i= 0; i--) { *p1 = *p2; p2 -= n2; p1 -= (n2+n2); } /* * now distribute 2nd half of array (in tmp) to odd elements */ pt = tmp; p1 = &a[n2]; /* pointer to a[i] */ for (i=1; i>1; pt = tmp; p1 = &a[n2*nhalf]; /* pointer to a[i] */ for (i=nhalf; i= 0; i--) { *p1 = *p2; p2 -= n2; p1 -= (n2+n2); } /* * now distribute 2nd half of array (in tmp) to odd elements */ pt = tmp; p1 = &a[n2]; /* pointer to a[i] */ for (i=1; i> 1); if (smax <= 0) return; ny2 = ny << 1; /* * We're indexing a as a 2-D array with dimensions (nxtop,ny) of which * only (nxtop,nytop) are used. The coefficients on the edge of the * array are not adjusted (which is why the loops below start at 2 * instead of 0 and end at nxtop-2 instead of nxtop.) */ /* * Adjust x difference hx */ for (i = 2; i=0, dmin<=0. */ if (dmin < dmax) { diff = max( min(diff, dmax), dmin); /* * Compute change in slope limited to range +/- smax. * Careful with rounding negative numbers when using * shift for divide by 8. */ s = diff-(a[s10]<<3); s = (s>=0) ? (s>>3) : ((s+7)>>3) ; s = max( min(s, smax), -smax); a[s10] = a[s10]+s; } s00 += 2; s10 += 2; } } /* * Adjust y difference hy */ for (i = 0; i=0) ? (s>>3) : ((s+7)>>3) ; s = max( min(s, smax), -smax); a[s00+1] = a[s00+1]+s; } s00 += 2; s10 += 2; } } /* * Adjust curvature difference hc */ for (i = 2; i=0, dmin<=0. */ if (dmin < dmax) { diff = max( min(diff, dmax), dmin); /* * Compute change in slope limited to range +/- smax. * Careful with rounding negative numbers when using * shift for divide by 64. */ s = diff-(a[s10+1]<<6); s = (s>=0) ? (s>>6) : ((s+63)>>6) ; s = max( min(s, smax), -smax); a[s10+1] = a[s10+1]+s; } s00 += 2; s10 += 2; } } } /* ############################################################################ */ static void hsmooth64(LONGLONG a[], int nxtop, int nytop, int ny, int scale) /* LONGLONG a[]; array of H-transform coefficients int nxtop,nytop; size of coefficient block to use int ny; actual 1st dimension of array int scale; truncation scale factor that was used */ { int i, j; int ny2, s10, s00; LONGLONG hm, h0, hp, hmm, hpm, hmp, hpp, hx2, hy2, diff, dmax, dmin, s, smax, m1, m2; /* * Maximum change in coefficients is determined by scale factor. * Since we rounded during division (see digitize.c), the biggest * permitted change is scale/2. */ smax = (scale >> 1); if (smax <= 0) return; ny2 = ny << 1; /* * We're indexing a as a 2-D array with dimensions (nxtop,ny) of which * only (nxtop,nytop) are used. The coefficients on the edge of the * array are not adjusted (which is why the loops below start at 2 * instead of 0 and end at nxtop-2 instead of nxtop.) */ /* * Adjust x difference hx */ for (i = 2; i=0, dmin<=0. */ if (dmin < dmax) { diff = max( min(diff, dmax), dmin); /* * Compute change in slope limited to range +/- smax. * Careful with rounding negative numbers when using * shift for divide by 8. */ s = diff-(a[s10]<<3); s = (s>=0) ? (s>>3) : ((s+7)>>3) ; s = max( min(s, smax), -smax); a[s10] = a[s10]+s; } s00 += 2; s10 += 2; } } /* * Adjust y difference hy */ for (i = 0; i=0) ? (s>>3) : ((s+7)>>3) ; s = max( min(s, smax), -smax); a[s00+1] = a[s00+1]+s; } s00 += 2; s10 += 2; } } /* * Adjust curvature difference hc */ for (i = 2; i=0, dmin<=0. */ if (dmin < dmax) { diff = max( min(diff, dmax), dmin); /* * Compute change in slope limited to range +/- smax. * Careful with rounding negative numbers when using * shift for divide by 64. */ s = diff-(a[s10+1]<<6); s = (s>=0) ? (s>>6) : ((s+63)>>6) ; s = max( min(s, smax), -smax); a[s10+1] = a[s10+1]+s; } s00 += 2; s10 += 2; } } } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* undigitize.c undigitize H-transform * * Programmer: R. White Date: 9 May 1991 */ /* ############################################################################ */ static void undigitize(int a[], int nx, int ny, int scale) { int *p; /* * multiply by scale */ if (scale <= 1) return; for (p=a; p <= &a[nx*ny-1]; p++) *p = (*p)*scale; } /* ############################################################################ */ static void undigitize64(LONGLONG a[], int nx, int ny, int scale) { LONGLONG *p, scale64; /* * multiply by scale */ if (scale <= 1) return; scale64 = (LONGLONG) scale; /* use a 64-bit int for efficiency in the big loop */ for (p=a; p <= &a[nx*ny-1]; p++) *p = (*p)*scale64; } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* decode.c read codes from infile and construct array * * Programmer: R. White Date: 2 February 1994 */ static char code_magic[2] = { (char)0xDD, (char)0x99 }; /* ############################################################################ */ static int decode(unsigned char *infile, int *a, int *nx, int *ny, int *scale) /* char *infile; input file int *a; address of output array [nx][ny] int *nx,*ny; size of output array int *scale; scale factor for digitization */ { LONGLONG sumall; int nel, stat; unsigned char nbitplanes[3]; char tmagic[2]; /* initialize the byte read position to the beginning of the array */; nextchar = 0; /* * File starts either with special 2-byte magic code or with * FITS keyword "SIMPLE =" */ qread(infile, tmagic, sizeof(tmagic)); /* * check for correct magic code value */ if (memcmp(tmagic,code_magic,sizeof(code_magic)) != 0) { ffpmsg("bad file format"); return(DATA_DECOMPRESSION_ERR); } *nx =readint(infile); /* x size of image */ *ny =readint(infile); /* y size of image */ *scale=readint(infile); /* scale factor for digitization */ nel = (*nx) * (*ny); /* sum of all pixels */ sumall=readlonglong(infile); /* # bits in quadrants */ qread(infile, (char *) nbitplanes, sizeof(nbitplanes)); stat = dodecode(infile, a, *nx, *ny, nbitplanes); /* * put sum of all pixels back into pixel 0 */ a[0] = (int) sumall; return(stat); } /* ############################################################################ */ static int decode64(unsigned char *infile, LONGLONG *a, int *nx, int *ny, int *scale) /* char *infile; input file LONGLONG *a; address of output array [nx][ny] int *nx,*ny; size of output array int *scale; scale factor for digitization */ { int nel, stat; LONGLONG sumall; unsigned char nbitplanes[3]; char tmagic[2]; /* initialize the byte read position to the beginning of the array */; nextchar = 0; /* * File starts either with special 2-byte magic code or with * FITS keyword "SIMPLE =" */ qread(infile, tmagic, sizeof(tmagic)); /* * check for correct magic code value */ if (memcmp(tmagic,code_magic,sizeof(code_magic)) != 0) { ffpmsg("bad file format"); return(DATA_DECOMPRESSION_ERR); } *nx =readint(infile); /* x size of image */ *ny =readint(infile); /* y size of image */ *scale=readint(infile); /* scale factor for digitization */ nel = (*nx) * (*ny); /* sum of all pixels */ sumall=readlonglong(infile); /* # bits in quadrants */ qread(infile, (char *) nbitplanes, sizeof(nbitplanes)); stat = dodecode64(infile, a, *nx, *ny, nbitplanes); /* * put sum of all pixels back into pixel 0 */ a[0] = sumall; return(stat); } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* dodecode.c Decode stream of characters on infile and return array * * This version encodes the different quadrants separately * * Programmer: R. White Date: 9 May 1991 */ /* ############################################################################ */ static int dodecode(unsigned char *infile, int a[], int nx, int ny, unsigned char nbitplanes[3]) /* int a[]; int nx,ny; Array dimensions are [nx][ny] unsigned char nbitplanes[3]; Number of bit planes in quadrants */ { int i, nel, nx2, ny2, stat; nel = nx*ny; nx2 = (nx+1)/2; ny2 = (ny+1)/2; /* * initialize a to zero */ for (i=0; inqy) ? nqx : nqy; log2n = (int) (log((float) nqmax)/log(2.0)+0.5); if (nqmax > (1<= 0; bit--) { /* * Was bitplane was quadtree-coded or written directly? */ b = input_nybble(infile); if(b == 0) { /* * bit map was written directly */ read_bdirect(infile,a,n,nqx,nqy,scratch,bit); } else if (b != 0xf) { ffpmsg("qtree_decode: bad format code"); return(DATA_DECOMPRESSION_ERR); } else { /* * bitmap was quadtree-coded, do log2n expansions * * read first code */ scratch[0] = input_huffman(infile); /* * now do log2n expansions, reading codes from file as necessary */ nx = 1; ny = 1; nfx = nqx; nfy = nqy; c = 1<>1; nx = nx<<1; ny = ny<<1; if (nfx <= c) { nx -= 1; } else { nfx -= c; } if (nfy <= c) { ny -= 1; } else { nfy -= c; } qtree_expand(infile,scratch,nx,ny,scratch); } /* * now copy last set of 4-bit codes to bitplane bit of array a */ qtree_bitins(scratch,nqx,nqy,a,n,bit); } } free(scratch); return(0); } /* ############################################################################ */ static int qtree_decode64(unsigned char *infile, LONGLONG a[], int n, int nqx, int nqy, int nbitplanes) /* char *infile; LONGLONG a[]; a is 2-D array with dimensions (n,n) int n; length of full row in a int nqx; partial length of row to decode int nqy; partial length of column (<=n) int nbitplanes; number of bitplanes to decode */ { int log2n, k, bit, b, nqmax; int nx,ny,nfx,nfy,c; int nqx2, nqy2; unsigned char *scratch; /* * log2n is log2 of max(nqx,nqy) rounded up to next power of 2 */ nqmax = (nqx>nqy) ? nqx : nqy; log2n = (int) (log((float) nqmax)/log(2.0)+0.5); if (nqmax > (1<= 0; bit--) { /* * Was bitplane was quadtree-coded or written directly? */ b = input_nybble(infile); if(b == 0) { /* * bit map was written directly */ read_bdirect64(infile,a,n,nqx,nqy,scratch,bit); } else if (b != 0xf) { ffpmsg("qtree_decode64: bad format code"); return(DATA_DECOMPRESSION_ERR); } else { /* * bitmap was quadtree-coded, do log2n expansions * * read first code */ scratch[0] = input_huffman(infile); /* * now do log2n expansions, reading codes from file as necessary */ nx = 1; ny = 1; nfx = nqx; nfy = nqy; c = 1<>1; nx = nx<<1; ny = ny<<1; if (nfx <= c) { nx -= 1; } else { nfx -= c; } if (nfy <= c) { ny -= 1; } else { nfy -= c; } qtree_expand(infile,scratch,nx,ny,scratch); } /* * now copy last set of 4-bit codes to bitplane bit of array a */ qtree_bitins64(scratch,nqx,nqy,a,n,bit); } } free(scratch); return(0); } /* ############################################################################ */ /* * do one quadtree expansion step on array a[(nqx+1)/2,(nqy+1)/2] * results put into b[nqx,nqy] (which may be the same as a) */ static void qtree_expand(unsigned char *infile, unsigned char a[], int nx, int ny, unsigned char b[]) { int i; /* * first copy a to b, expanding each 4-bit value */ qtree_copy(a,nx,ny,b,ny); /* * now read new 4-bit values into b for each non-zero element */ for (i = nx*ny-1; i >= 0; i--) { if (b[i] != 0) b[i] = input_huffman(infile); } } /* ############################################################################ */ /* * copy 4-bit values from a[(nx+1)/2,(ny+1)/2] to b[nx,ny], expanding * each value to 2x2 pixels * a,b may be same array */ static void qtree_copy(unsigned char a[], int nx, int ny, unsigned char b[], int n) /* int n; declared y dimension of b */ { int i, j, k, nx2, ny2; int s00, s10; /* * first copy 4-bit values to b * start at end in case a,b are same array */ nx2 = (nx+1)/2; ny2 = (ny+1)/2; k = ny2*(nx2-1)+ny2-1; /* k is index of a[i,j] */ for (i = nx2-1; i >= 0; i--) { s00 = 2*(n*i+ny2-1); /* s00 is index of b[2*i,2*j] */ for (j = ny2-1; j >= 0; j--) { b[s00] = a[k]; k -= 1; s00 -= 2; } } /* * now expand each 2x2 block */ for (i = 0; i>1) & 1; b[s00+1] = (b[s00]>>2) & 1; b[s00 ] = (b[s00]>>3) & 1; s00 += 2; s10 += 2; } if (j < ny) { /* * row size is odd, do last element in row * s00+1, s10+1 are off edge */ b[s10 ] = (b[s00]>>1) & 1; b[s00 ] = (b[s00]>>3) & 1; } } if (i < nx) { /* * column size is odd, do last row * s10, s10+1 are off edge */ s00 = n*i; for (j = 0; j>2) & 1; b[s00 ] = (b[s00]>>3) & 1; s00 += 2; } if (j < ny) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ b[s00 ] = (b[s00]>>3) & 1; } } } /* ############################################################################ */ /* * Copy 4-bit values from a[(nx+1)/2,(ny+1)/2] to b[nx,ny], expanding * each value to 2x2 pixels and inserting into bitplane BIT of B. * A,B may NOT be same array (it wouldn't make sense to be inserting * bits into the same array anyway.) */ static void qtree_bitins(unsigned char a[], int nx, int ny, int b[], int n, int bit) /* int n; declared y dimension of b */ { int i, j, k; int s00, s10; /* * expand each 2x2 block */ k = 0; /* k is index of a[i/2,j/2] */ for (i = 0; i>1) & 1) << bit; b[s00+1] |= ((a[k]>>2) & 1) << bit; b[s00 ] |= ((a[k]>>3) & 1) << bit; s00 += 2; s10 += 2; k += 1; } if (j < ny) { /* * row size is odd, do last element in row * s00+1, s10+1 are off edge */ b[s10 ] |= ((a[k]>>1) & 1) << bit; b[s00 ] |= ((a[k]>>3) & 1) << bit; k += 1; } } if (i < nx) { /* * column size is odd, do last row * s10, s10+1 are off edge */ s00 = n*i; for (j = 0; j>2) & 1) << bit; b[s00 ] |= ((a[k]>>3) & 1) << bit; s00 += 2; k += 1; } if (j < ny) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ b[s00 ] |= ((a[k]>>3) & 1) << bit; k += 1; } } } /* ############################################################################ */ /* * Copy 4-bit values from a[(nx+1)/2,(ny+1)/2] to b[nx,ny], expanding * each value to 2x2 pixels and inserting into bitplane BIT of B. * A,B may NOT be same array (it wouldn't make sense to be inserting * bits into the same array anyway.) */ static void qtree_bitins64(unsigned char a[], int nx, int ny, LONGLONG b[], int n, int bit) /* int n; declared y dimension of b */ { int i, j, k; int s00, s10; /* * expand each 2x2 block */ k = 0; /* k is index of a[i/2,j/2] */ for (i = 0; i>1) & 1) << bit; b[s00+1] |= ((((LONGLONG)a[k])>>2) & 1) << bit; b[s00 ] |= ((((LONGLONG)a[k])>>3) & 1) << bit; s00 += 2; s10 += 2; k += 1; } if (j < ny) { /* * row size is odd, do last element in row * s00+1, s10+1 are off edge */ b[s10 ] |= ((((LONGLONG)a[k])>>1) & 1) << bit; b[s00 ] |= ((((LONGLONG)a[k])>>3) & 1) << bit; k += 1; } } if (i < nx) { /* * column size is odd, do last row * s10, s10+1 are off edge */ s00 = n*i; for (j = 0; j>2) & 1) << bit; b[s00 ] |= ((((LONGLONG)a[k])>>3) & 1) << bit; s00 += 2; k += 1; } if (j < ny) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ b[s00 ] |= ((((LONGLONG)a[k])>>3) & 1) << bit; k += 1; } } } /* ############################################################################ */ static void read_bdirect(unsigned char *infile, int a[], int n, int nqx, int nqy, unsigned char scratch[], int bit) { int i; /* * read bit image packed 4 pixels/nybble */ for (i = 0; i < ((nqx+1)/2) * ((nqy+1)/2); i++) { scratch[i] = input_nybble(infile); } /* * insert in bitplane BIT of image A */ qtree_bitins(scratch,nqx,nqy,a,n,bit); } /* ############################################################################ */ static void read_bdirect64(unsigned char *infile, LONGLONG a[], int n, int nqx, int nqy, unsigned char scratch[], int bit) { int i; /* * read bit image packed 4 pixels/nybble */ for (i = 0; i < ((nqx+1)/2) * ((nqy+1)/2); i++) { scratch[i] = input_nybble(infile); } /* * insert in bitplane BIT of image A */ qtree_bitins64(scratch,nqx,nqy,a,n,bit); } /* ############################################################################ */ /* * Huffman decoding for fixed codes * * Coded values range from 0-15 * * Huffman code values (hex): * * 3e, 00, 01, 08, 02, 09, 1a, 1b, * 03, 1c, 0a, 1d, 0b, 1e, 3f, 0c * * and number of bits in each code: * * 6, 3, 3, 4, 3, 4, 5, 5, * 3, 5, 4, 5, 4, 5, 6, 4 */ static int input_huffman(unsigned char *infile) { int c; /* * get first 3 bits to start */ c = input_nbits(infile,3); if (c < 4) { /* * this is all we need * return 1,2,4,8 for c=0,1,2,3 */ return(1< 0) { total += nread; if (total==n) return(total); } */ memcpy(buffer, &file[nextchar], n); nextchar += n; return(n); } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* BIT INPUT ROUTINES */ /* THE BIT BUFFER */ static int buffer2; /* Bits waiting to be input */ static int bits_to_go; /* Number of bits still in buffer */ /* INITIALIZE BIT INPUT */ /* ############################################################################ */ static void start_inputing_bits() { /* * Buffer starts out with no bits in it */ bits_to_go = 0; } /* ############################################################################ */ /* INPUT A BIT */ static int input_bit(unsigned char *infile) { if (bits_to_go == 0) { /* Read the next byte if no */ /* buffer2 = getc(infile); */ /* bits are left in buffer */ buffer2 = infile[nextchar]; nextchar++; /* if (buffer2 == EOF) { */ /* * end of file is an error for this application */ /* fprintf(stderr, "input_bit: unexpected end-of-file\n"); exit(-1); } */ bits_to_go = 8; } /* * Return the next bit */ bits_to_go -= 1; return((buffer2>>bits_to_go) & 1); } /* ############################################################################ */ /* INPUT N BITS (N must be <= 8) */ static int input_nbits(unsigned char *infile, int n) { int c; if (bits_to_go < n) { /* * need another byte's worth of bits */ buffer2 <<= 8; /* c = getc(infile); */ c = infile[nextchar]; nextchar++; /* if (c == EOF) { */ /* * end of file is an error for this application */ /* fprintf(stderr, "input_nbits: unexpected end-of-file\n"); exit(-1); } */ buffer2 |= c; bits_to_go += 8; } /* * now pick off the first n bits */ bits_to_go -= n; return( (buffer2>>bits_to_go) & ((1< #include #include #include #include #include /* stddef.h is apparently needed to define size_t with some compilers ?? */ #include #include "fitsio2.h" #define errmsgsiz 25 #define ESMARKER 27 /* Escape character is used as error stack marker */ #define DelAll 1 /* delete all messages on the error stack */ #define DelMark 2 /* delete newest messages back to and including marker */ #define DelNewest 3 /* delete the newest message from the stack */ #define GetMesg 4 /* pop and return oldest message, ignoring marks */ #define PutMesg 5 /* add a new message to the stack */ #define PutMark 6 /* add a marker to the stack */ /*--------------------------------------------------------------------------*/ float ffvers(float *version) /* IO - version number */ /* return the current version number of the FITSIO software */ { *version = (float) 3.04; /* 12 March 2007 Previous releases: *version = 3.03 11 Dec 2006 *version = 3.02 18 Sep 2006 *version = 3.01 May 2006 included in FTOOLS 6.1 release *version = 3.006 20 Feb 2006 *version = 3.005 20 Dec 2005 (beta, in heasoft swift release *version = 3.004 16 Sep 2005 (beta, in heasoft swift release *version = 3.003 28 Jul 2005 (beta, in heasoft swift release *version = 3.002 15 Apr 2005 (beta) *version = 3.001 15 Mar 2005 (beta) released with heasoft 6.0 *version = 3.000 1 Mar 2005 (internal release only) *version = 2.51 2 Dec 2004 *version = 2.50 28 Jul 2004 *version = 2.49 11 Feb 2004 *version = 2.48 28 Jan 2004 *version = 2.470 18 Aug 2003 *version = 2.460 20 May 2003 *version = 2.450 30 Apr 2003 (internal release only) *version = 2.440 8 Jan 2003 *version = 2.430; 4 Nov 2002 *version = 2.420; 19 Jul 2002 *version = 2.410; 22 Apr 2002 used in ftools v5.2 *version = 2.401; 28 Jan 2002 *version = 2.400; 18 Jan 2002 *version = 2.301; 7 Dec 2001 *version = 2.300; 23 Oct 2001 *version = 2.204; 26 Jul 2001 *version = 2.203; 19 Jul 2001 used in ftools v5.1 *version = 2.202; 22 May 2001 *version = 2.201; 15 Mar 2001 *version = 2.200; 26 Jan 2001 *version = 2.100; 26 Sep 2000 *version = 2.037; 6 Jul 2000 *version = 2.036; 1 Feb 2000 *version = 2.035; 7 Dec 1999 (internal release only) *version = 2.034; 23 Nov 1999 *version = 2.033; 17 Sep 1999 *version = 2.032; 25 May 1999 *version = 2.031; 31 Mar 1999 *version = 2.030; 24 Feb 1999 *version = 2.029; 11 Feb 1999 *version = 2.028; 26 Jan 1999 *version = 2.027; 12 Jan 1999 *version = 2.026; 23 Dec 1998 *version = 2.025; 1 Dec 1998 *version = 2.024; 9 Nov 1998 *version = 2.023; 1 Nov 1998 first full release of V2.0 *version = 1.42; 30 Apr 1998 *version = 1.40; 6 Feb 1998 *version = 1.33; 16 Dec 1997 (internal release only) *version = 1.32; 21 Nov 1997 (internal release only) *version = 1.31; 4 Nov 1997 (internal release only) *version = 1.30; 11 Sep 1997 *version = 1.27; 3 Sep 1997 (internal release only) *version = 1.25; 2 Jul 1997 *version = 1.24; 2 May 1997 *version = 1.23; 24 Apr 1997 *version = 1.22; 18 Apr 1997 *version = 1.21; 26 Mar 1997 *version = 1.2; 29 Jan 1997 *version = 1.11; 04 Dec 1996 *version = 1.101; 13 Nov 1996 *version = 1.1; 6 Nov 1996 *version = 1.04; 17 Sep 1996 *version = 1.03; 20 Aug 1996 *version = 1.02; 15 Aug 1996 *version = 1.01; 12 Aug 1996 */ return(*version); } /*--------------------------------------------------------------------------*/ int ffflnm(fitsfile *fptr, /* I - FITS file pointer */ char *filename, /* O - name of the file */ int *status) /* IO - error status */ /* return the name of the FITS file */ { strcpy(filename,(fptr->Fptr)->filename); return(*status); } /*--------------------------------------------------------------------------*/ int ffflmd(fitsfile *fptr, /* I - FITS file pointer */ int *filemode, /* O - open mode of the file */ int *status) /* IO - error status */ /* return the access mode of the FITS file */ { *filemode = (fptr->Fptr)->writemode; return(*status); } /*--------------------------------------------------------------------------*/ void ffgerr(int status, /* I - error status value */ char *errtext) /* O - error message (max 30 char long + null) */ /* Return a short descriptive error message that corresponds to the input error status value. The message may be up to 30 characters long, plus the terminating null character. */ { errtext[0] = '\0'; if (status >= 0 && status < 300) { switch (status) { case 0: strcpy(errtext, "OK - no error"); break; case 1: strcpy(errtext, "non-CFITSIO program error"); break; case 101: strcpy(errtext, "same input and output files"); break; case 103: strcpy(errtext, "attempt to open too many files"); break; case 104: strcpy(errtext, "could not open the named file"); break; case 105: strcpy(errtext, "couldn't create the named file"); break; case 106: strcpy(errtext, "error writing to FITS file"); break; case 107: strcpy(errtext, "tried to move past end of file"); break; case 108: strcpy(errtext, "error reading from FITS file"); break; case 110: strcpy(errtext, "could not close the file"); break; case 111: strcpy(errtext, "array dimensions too big"); break; case 112: strcpy(errtext, "cannot write to readonly file"); break; case 113: strcpy(errtext, "could not allocate memory"); break; case 114: strcpy(errtext, "invalid fitsfile pointer"); break; case 115: strcpy(errtext, "NULL input pointer"); break; case 116: strcpy(errtext, "error seeking file position"); break; case 121: strcpy(errtext, "invalid URL prefix"); break; case 122: strcpy(errtext, "too many I/O drivers"); break; case 123: strcpy(errtext, "I/O driver init failed"); break; case 124: strcpy(errtext, "no I/O driver for this URLtype"); break; case 125: strcpy(errtext, "parse error in input file URL"); break; case 126: strcpy(errtext, "parse error in range list"); break; case 151: strcpy(errtext, "bad argument (shared mem drvr)"); break; case 152: strcpy(errtext, "null ptr arg (shared mem drvr)"); break; case 153: strcpy(errtext, "no free shared memory handles"); break; case 154: strcpy(errtext, "share mem drvr not initialized"); break; case 155: strcpy(errtext, "IPC system error (shared mem)"); break; case 156: strcpy(errtext, "no memory (shared mem drvr)"); break; case 157: strcpy(errtext, "share mem resource deadlock"); break; case 158: strcpy(errtext, "lock file open/create failed"); break; case 159: strcpy(errtext, "can't resize share mem block"); break; case 201: strcpy(errtext, "header already has keywords"); break; case 202: strcpy(errtext, "keyword not found in header"); break; case 203: strcpy(errtext, "keyword number out of bounds"); break; case 204: strcpy(errtext, "keyword value is undefined"); break; case 205: strcpy(errtext, "string missing closing quote"); break; case 206: strcpy(errtext, "error in indexed keyword name"); break; case 207: strcpy(errtext, "illegal character in keyword"); break; case 208: strcpy(errtext, "required keywords out of order"); break; case 209: strcpy(errtext, "keyword value not positive int"); break; case 210: strcpy(errtext, "END keyword not found"); break; case 211: strcpy(errtext, "illegal BITPIX keyword value"); break; case 212: strcpy(errtext, "illegal NAXIS keyword value"); break; case 213: strcpy(errtext, "illegal NAXISn keyword value"); break; case 214: strcpy(errtext, "illegal PCOUNT keyword value"); break; case 215: strcpy(errtext, "illegal GCOUNT keyword value"); break; case 216: strcpy(errtext, "illegal TFIELDS keyword value"); break; case 217: strcpy(errtext, "negative table row size"); break; case 218: strcpy(errtext, "negative number of rows"); break; case 219: strcpy(errtext, "named column not found"); break; case 220: strcpy(errtext, "illegal SIMPLE keyword value"); break; case 221: strcpy(errtext, "first keyword not SIMPLE"); break; case 222: strcpy(errtext, "second keyword not BITPIX"); break; case 223: strcpy(errtext, "third keyword not NAXIS"); break; case 224: strcpy(errtext, "missing NAXISn keywords"); break; case 225: strcpy(errtext, "first keyword not XTENSION"); break; case 226: strcpy(errtext, "CHDU not an ASCII table"); break; case 227: strcpy(errtext, "CHDU not a binary table"); break; case 228: strcpy(errtext, "PCOUNT keyword not found"); break; case 229: strcpy(errtext, "GCOUNT keyword not found"); break; case 230: strcpy(errtext, "TFIELDS keyword not found"); break; case 231: strcpy(errtext, "missing TBCOLn keyword"); break; case 232: strcpy(errtext, "missing TFORMn keyword"); break; case 233: strcpy(errtext, "CHDU not an IMAGE extension"); break; case 234: strcpy(errtext, "illegal TBCOLn keyword value"); break; case 235: strcpy(errtext, "CHDU not a table extension"); break; case 236: strcpy(errtext, "column exceeds width of table"); break; case 237: strcpy(errtext, "more than 1 matching col. name"); break; case 241: strcpy(errtext, "row width not = field widths"); break; case 251: strcpy(errtext, "unknown FITS extension type"); break; case 252: strcpy(errtext, "1st key not SIMPLE or XTENSION"); break; case 253: strcpy(errtext, "END keyword is not blank"); break; case 254: strcpy(errtext, "Header fill area not blank"); break; case 255: strcpy(errtext, "Data fill area invalid"); break; case 261: strcpy(errtext, "illegal TFORM format code"); break; case 262: strcpy(errtext, "unknown TFORM datatype code"); break; case 263: strcpy(errtext, "illegal TDIMn keyword value"); break; case 264: strcpy(errtext, "invalid BINTABLE heap pointer"); break; default: strcpy(errtext, "unknown error status"); break; } } else if (status < 600) { switch(status) { case 301: strcpy(errtext, "illegal HDU number"); break; case 302: strcpy(errtext, "column number < 1 or > tfields"); break; case 304: strcpy(errtext, "negative byte address"); break; case 306: strcpy(errtext, "negative number of elements"); break; case 307: strcpy(errtext, "bad first row number"); break; case 308: strcpy(errtext, "bad first element number"); break; case 309: strcpy(errtext, "not an ASCII (A) column"); break; case 310: strcpy(errtext, "not a logical (L) column"); break; case 311: strcpy(errtext, "bad ASCII table datatype"); break; case 312: strcpy(errtext, "bad binary table datatype"); break; case 314: strcpy(errtext, "null value not defined"); break; case 317: strcpy(errtext, "not a variable length column"); break; case 320: strcpy(errtext, "illegal number of dimensions"); break; case 321: strcpy(errtext, "1st pixel no. > last pixel no."); break; case 322: strcpy(errtext, "BSCALE or TSCALn = 0."); break; case 323: strcpy(errtext, "illegal axis length < 1"); break; case 340: strcpy(errtext, "not group table"); break; case 341: strcpy(errtext, "HDU already member of group"); break; case 342: strcpy(errtext, "group member not found"); break; case 343: strcpy(errtext, "group not found"); break; case 344: strcpy(errtext, "bad group id"); break; case 345: strcpy(errtext, "too many HDUs tracked"); break; case 346: strcpy(errtext, "HDU alread tracked"); break; case 347: strcpy(errtext, "bad Grouping option"); break; case 348: strcpy(errtext, "identical pointers (groups)"); break; case 360: strcpy(errtext, "malloc failed in parser"); break; case 361: strcpy(errtext, "file read error in parser"); break; case 362: strcpy(errtext, "null pointer arg (parser)"); break; case 363: strcpy(errtext, "empty line (parser)"); break; case 364: strcpy(errtext, "cannot unread > 1 line"); break; case 365: strcpy(errtext, "parser too deeply nested"); break; case 366: strcpy(errtext, "file open failed (parser)"); break; case 367: strcpy(errtext, "hit EOF (parser)"); break; case 368: strcpy(errtext, "bad argument (parser)"); break; case 369: strcpy(errtext, "unexpected token (parser)"); break; case 401: strcpy(errtext, "bad int to string conversion"); break; case 402: strcpy(errtext, "bad float to string conversion"); break; case 403: strcpy(errtext, "keyword value not integer"); break; case 404: strcpy(errtext, "keyword value not logical"); break; case 405: strcpy(errtext, "keyword value not floating pt"); break; case 406: strcpy(errtext, "keyword value not double"); break; case 407: strcpy(errtext, "bad string to int conversion"); break; case 408: strcpy(errtext, "bad string to float conversion"); break; case 409: strcpy(errtext, "bad string to double convert"); break; case 410: strcpy(errtext, "illegal datatype code value"); break; case 411: strcpy(errtext, "illegal no. of decimals"); break; case 412: strcpy(errtext, "datatype conversion overflow"); break; case 413: strcpy(errtext, "error compressing image"); break; case 414: strcpy(errtext, "error uncompressing image"); break; case 420: strcpy(errtext, "bad date or time conversion"); break; case 431: strcpy(errtext, "syntax error in expression"); break; case 432: strcpy(errtext, "expression result wrong type"); break; case 433: strcpy(errtext, "vector result too large"); break; case 434: strcpy(errtext, "missing output column"); break; case 435: strcpy(errtext, "bad data in parsed column"); break; case 436: strcpy(errtext, "output extension of wrong type"); break; case 501: strcpy(errtext, "WCS angle too large"); break; case 502: strcpy(errtext, "bad WCS coordinate"); break; case 503: strcpy(errtext, "error in WCS calculation"); break; case 504: strcpy(errtext, "bad WCS projection type"); break; case 505: strcpy(errtext, "WCS keywords not found"); break; default: strcpy(errtext, "unknown error status"); break; } } else { strcpy(errtext, "unknown error status"); } return; } /*--------------------------------------------------------------------------*/ void ffpmsg(const char *err_message) /* put message on to error stack */ { ffxmsg(PutMesg, (char *)err_message); return; } /*--------------------------------------------------------------------------*/ void ffpmrk(void) /* write a marker to the stack. It is then possible to pop only those messages following the marker off of the stack, leaving the previous messages unaffected. The marker is ignored by the ffgmsg routine. */ { char *dummy = 0; ffxmsg(PutMark, dummy); return; } /*--------------------------------------------------------------------------*/ int ffgmsg(char *err_message) /* get oldest message from error stack, ignoring markers */ { ffxmsg(GetMesg, err_message); return(*err_message); } /*--------------------------------------------------------------------------*/ void ffcmsg(void) /* erase all messages in the error stack */ { char *dummy = 0; ffxmsg(DelAll, dummy); return; } /*--------------------------------------------------------------------------*/ void ffcmrk(void) /* erase newest messages in the error stack, stopping if a marker is found. The marker is also erased in this case. */ { char *dummy = 0; ffxmsg(DelMark, dummy); return; } /*--------------------------------------------------------------------------*/ void ffxmsg( int action, char *errmsg) /* general routine to get, put, or clear the error message stack. Use a static array rather than allocating memory as needed for the error messages because it is likely to be more efficient and simpler to implement. Action Code: DelAll 1 delete all messages on the error stack DelMark 2 delete messages back to and including the 1st marker DelNewest 3 delete the newest message from the stack GetMesg 4 pop and return oldest message, ignoring marks PutMesg 5 add a new message to the stack PutMark 6 add a marker to the stack */ { int ii; char markflag; static char *txtbuff[errmsgsiz], *tmpbuff, *msgptr; static char errbuff[errmsgsiz][81]; /* initialize all = \0 */ static int nummsg = 0; if (action == DelAll) /* clear the whole message stack */ { for (ii = 0; ii < nummsg; ii ++) *txtbuff[ii] = '\0'; nummsg = 0; } else if (action == DelMark) /* clear up to and including first marker */ { while (nummsg > 0) { nummsg--; markflag = *txtbuff[nummsg]; /* store possible marker character */ *txtbuff[nummsg] = '\0'; /* clear the buffer for this msg */ if (markflag == ESMARKER) break; /* found a marker, so quit */ } } else if (action == DelNewest) /* remove newest message from stack */ { if (nummsg > 0) { nummsg--; *txtbuff[nummsg] = '\0'; /* clear the buffer for this msg */ } } else if (action == GetMesg) /* pop and return oldest message from stack */ { /* ignoring markers */ while (nummsg > 0) { strcpy(errmsg, txtbuff[0]); /* copy oldest message to output */ *txtbuff[0] = '\0'; /* clear the buffer for this msg */ nummsg--; for (ii = 0; ii < nummsg; ii++) txtbuff[ii] = txtbuff[ii + 1]; /* shift remaining pointers */ if (errmsg[0] != ESMARKER) /* quit if this is not a marker */ return; } errmsg[0] = '\0'; /* no messages in the stack */ } else if (action == PutMesg) /* add new message to stack */ { msgptr = errmsg; while (strlen(msgptr)) { if (nummsg == errmsgsiz) { tmpbuff = txtbuff[0]; /* buffers full; reuse oldest buffer */ *txtbuff[0] = '\0'; /* clear the buffer for this msg */ nummsg--; for (ii = 0; ii < nummsg; ii++) txtbuff[ii] = txtbuff[ii + 1]; /* shift remaining pointers */ txtbuff[nummsg] = tmpbuff; /* set pointer for the new message */ } else { for (ii = 0; ii < errmsgsiz; ii++) { if (*errbuff[ii] == '\0') /* find first empty buffer */ { txtbuff[nummsg] = errbuff[ii]; break; } } } strncat(txtbuff[nummsg], msgptr, 80); nummsg++; msgptr += minvalue(80, strlen(msgptr)); } } else if (action == PutMark) /* put a marker on the stack */ { if (nummsg == errmsgsiz) { tmpbuff = txtbuff[0]; /* buffers full; reuse oldest buffer */ *txtbuff[0] = '\0'; /* clear the buffer for this msg */ nummsg--; for (ii = 0; ii < nummsg; ii++) txtbuff[ii] = txtbuff[ii + 1]; /* shift remaining pointers */ txtbuff[nummsg] = tmpbuff; /* set pointer for the new message */ } else { for (ii = 0; ii < errmsgsiz; ii++) { if (*errbuff[ii] == '\0') /* find first empty buffer */ { txtbuff[nummsg] = errbuff[ii]; break; } } } *txtbuff[nummsg] = ESMARKER; /* write the marker */ *(txtbuff[nummsg] + 1) = '\0'; nummsg++; } return; } /*--------------------------------------------------------------------------*/ int ffpxsz(int datatype) /* return the number of bytes per pixel associated with the datatype */ { if (datatype == TBYTE) return(sizeof(char)); else if (datatype == TUSHORT) return(sizeof(short)); else if (datatype == TSHORT) return(sizeof(short)); else if (datatype == TULONG) return(sizeof(long)); else if (datatype == TLONG) return(sizeof(long)); else if (datatype == TINT) return(sizeof(int)); else if (datatype == TUINT) return(sizeof(int)); else if (datatype == TFLOAT) return(sizeof(float)); else if (datatype == TDOUBLE) return(sizeof(double)); else if (datatype == TLOGICAL) return(sizeof(char)); else return(0); } /*--------------------------------------------------------------------------*/ int fftkey(char *keyword, /* I - keyword name */ int *status) /* IO - error status */ /* Test that the keyword name conforms to the FITS standard. Must contain only capital letters, digits, minus or underscore chars. Trailing spaces are allowed. If the input status value is less than zero, then the test is modified so that upper or lower case letters are allowed, and no error messages are printed if the keyword is not legal. */ { size_t maxchr, ii; int spaces=0; char msg[81], testchar; if (*status > 0) /* inherit input status value if > 0 */ return(*status); maxchr=strlen(keyword); if (maxchr > 8) maxchr = 8; for (ii = 0; ii < maxchr; ii++) { if (*status == 0) testchar = keyword[ii]; else testchar = toupper(keyword[ii]); if ( (testchar >= 'A' && testchar <= 'Z') || (testchar >= '0' && testchar <= '9') || testchar == '-' || testchar == '_' ) { if (spaces) { if (*status == 0) { /* don't print error message if status < 0 */ sprintf(msg, "Keyword name contains embedded space(s): %.8s", keyword); ffpmsg(msg); } return(*status = BAD_KEYCHAR); } } else if (keyword[ii] == ' ') spaces = 1; else { if (*status == 0) { /* don't print error message if status < 0 */ sprintf(msg, "Character %d in this keyword is illegal: %.8s", (int) (ii+1), keyword); ffpmsg(msg); /* explicitly flag the 2 most common cases */ if (keyword[ii] == 0) ffpmsg(" (This a NULL (0) character)."); else if (keyword[ii] == 9) ffpmsg(" (This an ASCII TAB (9) character)."); } return(*status = BAD_KEYCHAR); } } return(*status); } /*--------------------------------------------------------------------------*/ int fftrec(char *card, /* I - keyword card to test */ int *status) /* IO - error status */ /* Test that the keyword card conforms to the FITS standard. Must contain only printable ASCII characters; */ { size_t ii, maxchr; char msg[81]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); maxchr = strlen(card); for (ii = 8; ii < maxchr; ii++) { if (card[ii] < 32 || card[ii] > 126) { sprintf(msg, "Character %d in this keyword is illegal. Hex Value = %X", (int) (ii+1), (int) card[ii] ); ffpmsg(msg); strncpy(msg, card, 80); msg[80] = '\0'; ffpmsg(msg); return(*status = BAD_KEYCHAR); } } return(*status); } /*--------------------------------------------------------------------------*/ void ffupch(char *string) /* convert string to upper case, in place. */ { size_t len, ii; len = strlen(string); for (ii = 0; ii < len; ii++) string[ii] = toupper(string[ii]); return; } /*--------------------------------------------------------------------------*/ int ffmkky(char *keyname, /* I - keyword name */ char *value, /* I - keyword value */ char *comm, /* I - keyword comment */ char *card, /* O - constructed keyword card */ int *status) /* IO - status value */ /* Make a complete FITS 80-byte keyword card from the input name, value and comment strings. Output card is null terminated without any trailing blanks. */ { size_t namelen, len, ii; char tmpname[FLEN_KEYWORD], *cptr; int tstatus = -1; if (*status > 0) return(*status); *tmpname = '\0'; *card = '\0'; cptr = keyname; while(*cptr == ' ') /* skip leading blanks in the name */ cptr++; strncat(tmpname, cptr, FLEN_KEYWORD - 1); namelen = strlen(tmpname); if (namelen) { cptr = tmpname + namelen - 1; while(*cptr == ' ') /* skip trailing blanks */ { *cptr = '\0'; cptr--; } namelen = cptr - tmpname + 1; } if (namelen <= 8 && (fftkey(keyname, &tstatus) <= 0) ) { /* a normal FITS keyword */ strcat(card, tmpname); /* copy keyword name to buffer */ for (ii = namelen; ii < 8; ii++) card[ii] = ' '; /* pad keyword name with spaces */ card[8] = '='; /* append '= ' in columns 9-10 */ card[9] = ' '; card[10] = '\0'; /* terminate the partial string */ namelen = 10; } else { /* use the ESO HIERARCH convention for longer keyword names */ /* check that the name does not contain an '=' (equals sign) */ if (strchr(tmpname, '=') ) { ffpmsg("Illegal keyword name; contains an equals sign (=)"); ffpmsg(tmpname); return(*status = BAD_KEYCHAR); } /* Don't repeat HIERARCH if the keyword already contains it */ if (FSTRNCMP(tmpname, "HIERARCH ", 9) && FSTRNCMP(tmpname, "hierarch ", 9)) strcat(card, "HIERARCH "); else namelen -= 9; /* deleted the string 'HIERARCH ' */ strcat(card, tmpname); strcat(card, " = "); namelen += 12; } len = strlen(value); if (len > 0) { if (value[0] == '\'') /* is this a quoted string value? */ { if (namelen > 77) { ffpmsg( "The following keyword + value is too long to fit on a card:"); ffpmsg(keyname); ffpmsg(value); return(*status = BAD_KEYCHAR); } strncat(card, value, 80 - namelen); /* append the value string */ len = minvalue(80, namelen + len); /* restore the closing quote if it got truncated */ if (len == 80) { card[79] = '\''; } if (comm) { if (comm[0] != 0) { if (len < 30) { for (ii = len; ii < 30; ii++) card[ii] = ' '; /* fill with spaces to col 30 */ card[30] = '\0'; len = 30; } } } } else { if (namelen + len > 80) { ffpmsg( "The following keyword + value is too long to fit on a card:"); ffpmsg(keyname); ffpmsg(value); return(*status = BAD_KEYCHAR); } else if (namelen + len < 30) { /* add spaces so field ends at least in col 30 */ strncat(card, " ", 30 - (namelen + len)); } strncat(card, value, 80 - namelen); /* append the value string */ len = minvalue(80, namelen + len); len = maxvalue(30, len); } if (comm) { if ((len < 77) && ( strlen(comm) > 0) ) /* room for a comment? */ { strcat(card, " / "); /* append comment separator */ strncat(card, comm, 77 - len); /* append comment (what fits) */ } } } else { if (namelen == 10) /* This case applies to normal keywords only */ { card[8] = ' '; /* keywords with no value have no '=' */ if (comm) { strncat(card, comm, 80 - namelen); /* append comment (what fits) */ } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffmkey(fitsfile *fptr, /* I - FITS file pointer */ char *card, /* I - card string value */ int *status) /* IO - error status */ /* replace the previously read card (i.e. starting 80 bytes before the (fptr->Fptr)->nextkey position) with the contents of the input card. */ { char tcard[81]; size_t len, ii; /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); strncpy(tcard,card,80); tcard[80] = '\0'; len = strlen(tcard); for (ii=len; ii < 80; ii++) /* fill card with spaces if necessary */ tcard[ii] = ' '; for (ii=0; ii < 8; ii++) /* make sure keyword name is uppercase */ tcard[ii] = toupper(tcard[ii]); fftkey(tcard, status); /* test keyword name contains legal chars */ fftrec(tcard, status); /* test rest of keyword for legal chars */ /* move position of keyword to be over written */ ffmbyt(fptr, ((fptr->Fptr)->nextkey) - 80, REPORT_EOF, status); ffpbyt(fptr, 80, tcard, status); /* write the 80 byte card */ return(*status); } /*--------------------------------------------------------------------------*/ int ffkeyn(char *keyroot, /* I - root string for keyword name */ int value, /* I - index number to be appended to root name */ char *keyname, /* O - output root + index keyword name */ int *status) /* IO - error status */ /* Construct a keyword name string by appending the index number to the root. e.g., if root = "TTYPE" and value = 12 then keyname = "TTYPE12". */ { char suffix[16]; size_t rootlen; keyname[0] = '\0'; /* initialize output name to null */ rootlen = strlen(keyroot); if (rootlen == 0 || rootlen > 7 || value < 0 ) return(*status = 206); sprintf(suffix, "%d", value); /* construct keyword suffix */ if ( strlen(suffix) + rootlen > 8) return(*status = 206); strcpy(keyname, keyroot); /* copy root string to name string */ strcat(keyname, suffix); /* append suffix to the root */ return(*status); } /*--------------------------------------------------------------------------*/ int ffnkey(int value, /* I - index number to be appended to root name */ char *keyroot, /* I - root string for keyword name */ char *keyname, /* O - output root + index keyword name */ int *status) /* IO - error status */ /* Construct a keyword name string by appending the root string to the index number. e.g., if root = "TTYPE" and value = 12 then keyname = "12TTYPE". */ { size_t rootlen; keyname[0] = '\0'; /* initialize output name to null */ rootlen = strlen(keyroot); if (rootlen == 0 || rootlen > 7 || value < 0 ) return(*status = 206); sprintf(keyname, "%d", value); /* construct keyword prefix */ if (rootlen + strlen(keyname) > 8) return(*status = 206); strcat(keyname, keyroot); /* append root to the prefix */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpsvc(char *card, /* I - FITS header card (nominally 80 bytes long) */ char *value, /* O - value string parsed from the card */ char *comm, /* O - comment string parsed from the card */ int *status) /* IO - error status */ /* ParSe the Value and Comment strings from the input header card string. If the card contains a quoted string value, the returned value string includes the enclosing quote characters. If comm = NULL, don't return the comment string. */ { int jj; size_t ii, cardlen, nblank, valpos; if (*status > 0) return(*status); value[0] = '\0'; if (comm) comm[0] = '\0'; cardlen = strlen(card); /* support for ESO HIERARCH keywords; find the '=' */ if (FSTRNCMP(card, "HIERARCH ", 9) == 0) { valpos = strcspn(card, "="); if (valpos == cardlen) /* no value indicator ??? */ { if (comm != NULL) { if (cardlen > 8) { strcpy(comm, &card[8]); jj=cardlen - 8; for (jj--; jj >= 0; jj--) /* replace trailing blanks with nulls */ { if (comm[jj] == ' ') comm[jj] = '\0'; else break; } } } return(*status); /* no value indicator */ } valpos++; /* point to the position after the '=' */ } else if (cardlen < 9 || FSTRNCMP(card, "COMMENT ", 8) == 0 || /* keywords with no value */ FSTRNCMP(card, "HISTORY ", 8) == 0 || FSTRNCMP(card, "END ", 8) == 0 || FSTRNCMP(card, " ", 8) == 0 || FSTRNCMP(&card[8], "= ", 2) != 0 ) /* no '= ' in cols 9-10 */ { /* no value, so the comment extends from cols 9 - 80 */ if (comm != NULL) { if (cardlen > 8) { strcpy(comm, &card[8]); jj=cardlen - 8; for (jj--; jj >= 0; jj--) /* replace trailing blanks with nulls */ { if (comm[jj] == ' ') comm[jj] = '\0'; else break; } } } return(*status); } else { valpos = 10; /* starting position of the value field */ } nblank = strspn(&card[valpos], " "); /* find number of leading blanks */ if (nblank + valpos == cardlen) { /* the absence of a value string is legal, and simply indicates that the keyword value is undefined. Don't write an error message in this case. */ return(*status); } ii = valpos + nblank; if (card[ii] == '/' ) /* slash indicates start of the comment */ { ii++; } else if (card[ii] == '\'' ) /* is this a quoted string value? */ { value[0] = card[ii]; for (jj=1, ii++; ii < cardlen; ii++, jj++) { if (card[ii] == '\'') /* is this the closing quote? */ { if (card[ii+1] == '\'') /* 2 successive quotes? */ { value[jj] = card[ii]; ii++; jj++; } else { value[jj] = card[ii]; break; /* found the closing quote, so exit this loop */ } } value[jj] = card[ii]; /* copy the next character to the output */ } if (ii == cardlen) { value[jj] = '\0'; /* terminate the bad value string */ ffpmsg("This keyword string value has no closing quote:"); ffpmsg(card); return(*status = NO_QUOTE); } else { value[jj+1] = '\0'; /* terminate the good value string */ ii++; /* point to the character following the value */ } } else if (card[ii] == '(' ) /* is this a complex value? */ { nblank = strcspn(&card[ii], ")" ); /* find closing ) */ if (nblank == strlen( &card[ii] ) ) { ffpmsg("This complex keyword value has no closing ')':"); ffpmsg(card); return(*status = NO_QUOTE); } nblank++; strncpy(value, &card[ii], nblank); value[nblank] = '\0'; ii = ii + nblank; } else /* an integer, floating point, or logical FITS value string */ { nblank = strcspn(&card[ii], " /"); /* find the end of the token */ strncpy(value, &card[ii], nblank); value[nblank] = '\0'; ii = ii + nblank; } /* now find the comment string, if any */ if (comm) { nblank = strspn(&card[ii], " "); /* find next non-space character */ ii = ii + nblank; if (ii < 80) { if (card[ii] == '/') /* ignore the slash separator */ { ii++; if (card[ii] == ' ') /* also ignore the following space */ ii++; } strcat(comm, &card[ii]); /* copy the remaining characters */ jj=strlen(comm); for (jj--; jj >= 0; jj--) /* replace trailing blanks with nulls */ { if (comm[jj] == ' ') comm[jj] = '\0'; else break; } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgthd(char *tmplt, /* I - input header template string */ char *card, /* O - returned FITS header record */ int *hdtype, /* O - how to interpreter the returned card string */ /* -2 = modify the name of a keyword; the old keyword name is returned starting at address chars[0]; the new name is returned starting at address char[40] (to be consistent with the Fortran version). Both names are null terminated. -1 = card contains the name of a keyword that is to be deleted 0 = append this keyword if it doesn't already exist, or modify the value if the keyword already exists. 1 = append this comment keyword ('HISTORY', 'COMMENT', or blank keyword name) 2 = this is the END keyword; do not write it to the header */ int *status) /* IO - error status */ /* 'Get Template HeaDer' parse a template header line and create a formated character string which is suitable for appending to a FITS header */ { char keyname[FLEN_KEYWORD], value[140], comment[140]; char *tok, *suffix, *loc, tvalue[140]; int len, vlen, more, tstatus; double dval; if (*status > 0) return(*status); card[0] = '\0'; *hdtype = 0; if (!FSTRNCMP(tmplt, " ", 8) ) { /* if first 8 chars of template are blank, then this is a comment */ strncat(card, tmplt, 80); *hdtype = 1; return(*status); } tok = tmplt; /* point to start of template string */ keyname[0] = '\0'; value[0] = '\0'; comment[0] = '\0'; len = strspn(tok, " "); /* no. of spaces before keyword */ tok += len; if (tok[0] == '-') /* is there a leading minus sign? */ { /* first token is name of keyword to be deleted or renamed */ *hdtype = -1; tok++; len = strspn(tok, " "); /* no. of spaces before keyword */ tok += len; if (len < 8) /* not a blank name? */ { len = strcspn(tok, " ="); /* length of name */ if (len >= FLEN_KEYWORD) return(*status = BAD_KEYCHAR); strncat(card, tok, len); /* The HIERARCH convention supports non-standard characters in the keyword name, so don't always convert to upper case or abort if there are illegal characters in the name or if the name is greater than 8 characters long. */ if (len < 9) /* this is possibly a normal FITS keyword name */ { ffupch(card); tstatus = 0; if (fftkey(card, &tstatus) > 0) { /* name contained non-standard characters, so reset */ card[0] = '\0'; strncat(card, tok, len); } } tok += len; } /* second token, if present, is the new name for the keyword */ len = strspn(tok, " "); /* no. of spaces before next token */ tok += len; if (tok[0] == '\0' || tok[0] == '=') return(*status); /* no second token */ *hdtype = -2; len = strcspn(tok, " "); /* length of new name */ if (len > 40) /* name has to fit on columns 41-80 of card */ return(*status = BAD_KEYCHAR); /* copy the new name to card + 40; This is awkward, */ /* but is consistent with the way the Fortran FITSIO works */ strcat(card," "); strncpy(&card[40], tok, len+1); /* copy len+1 to get terminator */ /* The HIERARCH convention supports non-standard characters in the keyword name, so don't always convert to upper case or abort if there are illegal characters in the name or if the name is greater than 8 characters long. */ if (len < 9) /* this is possibly a normal FITS keyword name */ { ffupch(&card[40]); tstatus = 0; if (fftkey(&card[40], &tstatus) > 0) { /* name contained non-standard characters, so reset */ strncpy(&card[40], tok, len); } } } else /* no negative sign at beginning of template */ { /* get the keyword name token */ len = strcspn(tok, " ="); /* length of keyword name */ if (len >= FLEN_KEYWORD) return(*status = BAD_KEYCHAR); strncat(keyname, tok, len); /* The HIERARCH convention supports non-standard characters in the keyword name, so don't always convert to upper case or abort if there are illegal characters in the name or if the name is greater than 8 characters long. */ if (len < 9) /* this is possibly a normal FITS keyword name */ { ffupch(keyname); tstatus = 0; if (fftkey(keyname, &tstatus) > 0) { /* name contained non-standard characters, so reset */ keyname[0] = '\0'; strncat(keyname, tok, len); } } if (!FSTRCMP(keyname, "END") ) { strcpy(card, "END"); *hdtype = 2; return(*status); } tok += len; /* move token pointer to end of the keyword */ if (!FSTRCMP(keyname, "COMMENT") || !FSTRCMP(keyname, "HISTORY") || !FSTRCMP(keyname, "HIERARCH") ) { *hdtype = 1; /* simply append COMMENT and HISTORY keywords */ strcpy(card, keyname); strncat(card, tok, 73); return(*status); } /* look for the value token */ len = strspn(tok, " ="); /* spaces or = between name and value */ tok += len; if (*tok == '\'') /* is value enclosed in quotes? */ { more = TRUE; while (more) { tok++; /* temporarily move past the quote char */ len = strcspn(tok, "'"); /* length of quoted string */ tok--; strncat(value, tok, len + 2); tok += len + 1; if (tok[0] != '\'') /* check there is a closing quote */ return(*status = NO_QUOTE); tok++; if (tok[0] != '\'') /* 2 quote chars = literal quote */ more = FALSE; } } else if (*tok == '/' || *tok == '\0') /* There is no value */ { strcat(value, " "); } else /* not a quoted string value */ { len = strcspn(tok, " /"); /* length of value string */ strncat(value, tok, len); if (!( (tok[0] == 'T' || tok[0] == 'F') && (tok[1] == ' ' || tok[1] == '/' || tok[1] == '\0') )) { /* not a logical value */ dval = strtod(value, &suffix); /* try to read value as number */ if (*suffix != '\0' && *suffix != ' ' && *suffix != '/') { /* value not recognized as a number; might be because it */ /* contains a 'd' or 'D' exponent character */ strcpy(tvalue, value); loc = strchr(tvalue, 'D'); if (loc) { *loc = 'E'; /* replace D's with E's. */ dval = strtod(tvalue, &suffix); /* read value again */ } else { loc = strchr(tvalue, 'd'); if (loc) { *loc = 'E'; /* replace d's with E's. */ dval = strtod(tvalue, &suffix); /* read value again */ } } } if (*suffix != '\0' && *suffix != ' ' && *suffix != '/') { /* value is not a number; must enclose it in quotes */ strcpy(value, "'"); strncat(value, tok, len); strcat(value, "'"); /* the following useless statement stops the compiler warning */ /* that dval is not used anywhere */ if (dval == 0.) len += (int) dval; } else { /* value is a number; convert any 'e' to 'E', or 'd' to 'D' */ loc = strchr(value, 'e'); if (loc) { *loc = 'E'; } else { loc = strchr(value, 'd'); if (loc) { *loc = 'D'; } } } } tok += len; } len = strspn(tok, " /"); /* no. of spaces between value and comment */ tok += len; vlen = strlen(value); if (vlen > 0 && vlen < 10 && value[0] == '\'') { /* pad quoted string with blanks so it is at least 8 chars long */ value[vlen-1] = '\0'; strncat(value, " ", 10 - vlen); strcat(&value[9], "'"); } /* get the comment string */ strncat(comment, tok, 70); /* construct the complete FITS header card */ ffmkky(keyname, value, comment, card, status); } return(*status); } /*--------------------------------------------------------------------------*/ int fits_translate_keyword( char *inrec, /* I - input string */ char *outrec, /* O - output converted string, or */ /* a null string if input does not */ /* match any of the patterns */ char *patterns[][2],/* I - pointer to input / output string */ /* templates */ int npat, /* I - number of templates passed */ int n_value, /* I - base 'n' template value of interest */ int n_offset, /* I - offset to be applied to the 'n' */ /* value in the output string */ int n_range, /* I - controls range of 'n' template */ /* values of interest (-1,0, or +1) */ int *pat_num, /* O - matched pattern number (0 based) or -1 */ int *i, /* O - value of i, if any, else 0 */ int *j, /* O - value of j, if any, else 0 */ int *m, /* O - value of m, if any, else 0 */ int *n, /* O - value of n, if any, else 0 */ int *status) /* IO - error status */ /* Translate a keyword name to a new name, based on a set of patterns. The user passes an array of patterns to be matched. Input pattern number i is pattern[i][0], and output pattern number i is pattern[i][1]. Keywords are matched against the input patterns. If a match is found then the keyword is re-written according to the output pattern. Order is important. The first match is accepted. The fastest match will be made when templates with the same first character are grouped together. Several characters have special meanings: i,j - single digits, preserved in output template n - column number of one or more digits, preserved in output template m - generic number of one or more digits, preserved in output template a - coordinate designator, preserved in output template # - number of one or more digits ? - any character * - only allowed in first character position, to match all keywords; only useful as last pattern in the list i, j, n, and m are returned by the routine. For example, the input pattern "iCTYPn" will match "1CTYP5" (if n_value is 5); the output pattern "CTYPEi" will be re-written as "CTYPE1". Notice that "i" is preserved. The following output patterns are special Special output pattern characters: "-" - do not copy a keyword that matches the corresponding input pattern "+" - copy the input unchanged The inrec string could be just the 8-char keyword name, or the entire 80-char header record. Characters 9 = 80 in the input string simply get appended to the translated keyword name. If n_range = 0, then only keywords with 'n' equal to n_value will be considered as a pattern match. If n_range = +1, then all values of 'n' greater than or equal to n_value will be a match, and if -1, then values of 'n' less than or equal to n_value will match. This routine was written by Craig Markwardt, GSFC */ { int i1 = 0, j1 = 0, n1 = 0, m1 = 0; int fac; char a = ' '; char oldp = ' '; char c, s; int ip, ic, pat, pass = 0, firstfail = 0; char *spat; if (*status > 0) return(*status); if ((inrec == 0) || (outrec == 0)) return (*status = NULL_INPUT_PTR); *outrec = '\0'; if (*inrec == '\0') return 0; oldp = '\0'; firstfail = 0; /* ===== Pattern match stage */ for (pat=0; pat < npat; pat++) { spat = patterns[pat][0]; i1 = 0; j1 = 0; m1 = -1; n1 = -1; a = ' '; /* Initialize the place-holders */ pass = 0; /* Pass the wildcard pattern */ if (spat[0] == '*') { pass = 1; break; } /* Optimization: if we have seen this initial pattern character before, then it must have failed, and we can skip the pattern */ if (firstfail && spat[0] == oldp) continue; oldp = spat[0]; /* ip = index of pattern character being matched ic = index of keyname character being matched firstfail = 1 if we fail on the first characteor (0=not) */ for (ip=0, ic=0, firstfail=1; (spat[ip]) && (ic < 8); ip++, ic++, firstfail=0) { c = inrec[ic]; s = spat[ip]; if (s == 'i') { /* Special pattern: 'i' placeholder */ if (isdigit(c)) { i1 = c - '0'; pass = 1;} } else if (s == 'j') { /* Special pattern: 'j' placeholder */ if (isdigit(c)) { j1 = c - '0'; pass = 1;} } else if ((s == 'n')||(s == 'm')||(s == '#')) { /* Special patterns: multi-digit number */ int val = 0; pass = 0; if (isdigit(c)) { pass = 1; /* NOTE, could fail below */ /* Parse decimal number */ while (ic<8 && isdigit(c)) { val = val*10 + (c - '0'); ic++; c = inrec[ic]; } ic--; c = inrec[ic]; if (s == 'n') { /* Is it a column number? */ if ( val >= 1 && val <= 999 && /* Row range check */ (((n_range == 0) && (val == n_value)) || /* Strict equality */ ((n_range == -1) && (val <= n_value)) || /* n <= n_value */ ((n_range == +1) && (val >= n_value))) ) { /* n >= n_value */ n1 = val; } else { pass = 0; } } else if (s == 'm') { /* Generic number */ m1 = val; } } } else if (s == 'a') { /* Special pattern: coordinate designator */ if (isupper(c) || c == ' ') { a = c; pass = 1;} } else if (s == '?') { /* Match any individual character */ pass = 1; } else if (c == s) { /* Match a specific character */ pass = 1; } else { /* FAIL */ pass = 0; } if (!pass) break; } /* Must pass to the end of the keyword. No partial matches allowed */ if (pass && (ic >= 8 || inrec[ic] == ' ')) break; } /* Transfer the pattern-matched numbers to the output parameters */ if (i) { *i = i1; } if (j) { *j = j1; } if (n) { *n = n1; } if (m) { *m = m1; } if (pat_num) { *pat_num = pat; } /* ===== Keyword rewriting and output stage */ spat = patterns[pat][1]; /* Return case: no match, or explicit deletion pattern */ if (pass == 0 || spat[0] == '\0' || spat[0] == '-') return 0; /* A match: we start by copying the input record to the output */ strcpy(outrec, inrec); /* Return case: return the input record unchanged */ if (spat[0] == '+') return 0; /* Final case: a new output pattern */ for (ip=0, ic=0; spat[ip]; ip++, ic++) { s = spat[ip]; if (s == 'i') { outrec[ic] = (i1+'0'); } else if (s == 'j') { outrec[ic] = (j1+'0'); } else if (s == 'n') { if (n1 == -1) { n1 = n_value; } if (n1 > 0) { n1 += n_offset; for (fac = 1; (n1/fac) > 0; fac *= 10); fac /= 10; while(fac > 0) { outrec[ic] = ((n1/fac) % 10) + '0'; fac /= 10; ic ++; } ic--; } } else if (s == 'm' && m1 >= 0) { for (fac = 1; (m1/fac) > 0; fac *= 10); fac /= 10; while(fac > 0) { outrec[ic] = ((m1/fac) % 10) + '0'; fac /= 10; ic ++; } ic --; } else if (s == 'a') { outrec[ic] = a; } else { outrec[ic] = s; } } /* Pad the keyword name with spaces */ for ( ; ic<8; ic++) { outrec[ic] = ' '; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_translate_keywords( fitsfile *infptr, /* I - pointer to input HDU */ fitsfile *outfptr, /* I - pointer to output HDU */ int firstkey, /* I - first HDU record number to start with */ char *patterns[][2],/* I - pointer to input / output keyword templates */ int npat, /* I - number of templates passed */ int n_value, /* I - base 'n' template value of interest */ int n_offset, /* I - offset to be applied to the 'n' */ /* value in the output string */ int n_range, /* I - controls range of 'n' template */ /* values of interest (-1,0, or +1) */ int *status) /* IO - error status */ /* Copy relevant keywords from the table header into the newly created primary array header. Convert names of keywords where appropriate. See fits_translate_keyword() for the definitions. Translation begins at header record number 'firstkey', and continues to the end of the header. This routine was written by Craig Markwardt, GSFC */ { int nrec, nkeys, nmore; char rec[FLEN_CARD]; int i = 0, j = 0, n = 0, m = 0; int pat_num = 0; char outrec[FLEN_CARD]; if (*status > 0) return(*status); ffghsp(infptr, &nkeys, &nmore, status); /* get number of keywords */ for (nrec = firstkey; nrec <= nkeys; nrec++) { outrec[0] = '\0'; ffgrec(infptr, nrec, rec, status); fits_translate_keyword(rec, outrec, patterns, npat, n_value, n_offset, n_range, &pat_num, &i, &j, &m, &n, status); if (outrec[0]) { ffprec(outfptr, outrec, status); /* copy the keyword */ rec[8] = 0; outrec[8] = 0; } else { rec[8] = 0; outrec[8] = 0; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffasfm(char *tform, /* I - format code from the TFORMn keyword */ int *dtcode, /* O - numerical datatype code */ long *twidth, /* O - width of the field, in chars */ int *decimals, /* O - number of decimal places (F, E, D format) */ int *status) /* IO - error status */ { /* parse the ASCII table TFORM column format to determine the data type, the field width, and number of decimal places (if relevant) */ int ii, datacode; long longval, width; float fwidth; char *form, temp[FLEN_VALUE], message[FLEN_ERRMSG]; if (*status > 0) return(*status); if (dtcode) *dtcode = 0; if (twidth) *twidth = 0; if (decimals) *decimals = 0; ii = 0; while (tform[ii] != 0 && tform[ii] == ' ') /* find first non-blank char */ ii++; strcpy(temp, &tform[ii]); /* copy format string */ ffupch(temp); /* make sure it is in upper case */ form = temp; /* point to start of format string */ if (form[0] == 0) { ffpmsg("Error: ASCII table TFORM code is blank"); return(*status = BAD_TFORM); } /*-----------------------------------------------*/ /* determine default datatype code */ /*-----------------------------------------------*/ if (form[0] == 'A') datacode = TSTRING; else if (form[0] == 'I') datacode = TLONG; else if (form[0] == 'F') datacode = TFLOAT; else if (form[0] == 'E') datacode = TFLOAT; else if (form[0] == 'D') datacode = TDOUBLE; else { sprintf(message, "Illegal ASCII table TFORMn datatype: \'%s\'", tform); ffpmsg(message); return(*status = BAD_TFORM_DTYPE); } if (dtcode) *dtcode = datacode; form++; /* point to the start of field width */ if (datacode == TSTRING || datacode == TLONG) { /*-----------------------------------------------*/ /* A or I data formats: */ /*-----------------------------------------------*/ if (ffc2ii(form, &width, status) <= 0) /* read the width field */ { if (width <= 0) { width = 0; *status = BAD_TFORM; } else { /* set to shorter precision if I4 or less */ if (width <= 4 && datacode == TLONG) datacode = TSHORT; } } } else { /*-----------------------------------------------*/ /* F, E or D data formats: */ /*-----------------------------------------------*/ if (ffc2rr(form, &fwidth, status) <= 0) /* read ww.dd width field */ { if (fwidth <= 0.) *status = BAD_TFORM; else { width = (long) fwidth; /* convert from float to long */ if (width > 7 && *temp == 'F') datacode = TDOUBLE; /* type double if >7 digits */ if (width < 10) form = form + 1; /* skip 1 digit */ else form = form + 2; /* skip 2 digits */ if (form[0] == '.') /* should be a decimal point here */ { form++; /* point to start of decimals field */ if (ffc2ii(form, &longval, status) <= 0) /* read decimals */ { if (decimals) *decimals = longval; /* long to short convertion */ if (longval >= width) /* width < no. of decimals */ *status = BAD_TFORM; if (longval > 6 && *temp == 'E') datacode = TDOUBLE; /* type double if >6 digits */ } } } } } if (*status > 0) { *status = BAD_TFORM; sprintf(message,"Illegal ASCII table TFORMn code: \'%s\'", tform); ffpmsg(message); } if (dtcode) *dtcode = datacode; if (twidth) *twidth = width; return(*status); } /*--------------------------------------------------------------------------*/ int ffbnfm(char *tform, /* I - format code from the TFORMn keyword */ int *dtcode, /* O - numerical datatype code */ long *trepeat, /* O - repeat count of the field */ long *twidth, /* O - width of the field, in chars */ int *status) /* IO - error status */ { /* parse the binary table TFORM column format to determine the data type, repeat count, and the field width (if it is an ASCII (A) field) */ size_t ii, nchar; int datacode, variable, iread; long width, repeat; char *form, temp[FLEN_VALUE], message[FLEN_ERRMSG]; if (*status > 0) return(*status); if (dtcode) *dtcode = 0; if (trepeat) *trepeat = 0; if (twidth) *twidth = 0; nchar = strlen(tform); for (ii = 0; ii < nchar; ii++) { if (tform[ii] != ' ') /* find first non-space char */ break; } if (ii == nchar) { ffpmsg("Error: binary table TFORM code is blank (ffbnfm)."); return(*status = BAD_TFORM); } strcpy(temp, &tform[ii]); /* copy format string */ ffupch(temp); /* make sure it is in upper case */ form = temp; /* point to start of format string */ /*-----------------------------------------------*/ /* get the repeat count */ /*-----------------------------------------------*/ ii = 0; while(isdigit((int) form[ii])) ii++; /* look for leading digits in the field */ if (ii == 0) repeat = 1; /* no explicit repeat count */ else sscanf(form,"%ld", &repeat); /* read repeat count */ /*-----------------------------------------------*/ /* determine datatype code */ /*-----------------------------------------------*/ form = form + ii; /* skip over the repeat field */ if (form[0] == 'P' || form[0] == 'Q') { variable = 1; /* this is a variable length column */ repeat = 1; /* disregard any other repeat value */ form++; /* move to the next data type code char */ } else variable = 0; if (form[0] == 'U') /* internal code to signify unsigned integer */ { datacode = TUSHORT; width = 2; } else if (form[0] == 'I') { datacode = TSHORT; width = 2; } else if (form[0] == 'V') /* internal code to signify unsigned integer */ { datacode = TULONG; width = 4; } else if (form[0] == 'J') { datacode = TLONG; width = 4; } else if (form[0] == 'K') { datacode = TLONGLONG; width = 8; } else if (form[0] == 'E') { datacode = TFLOAT; width = 4; } else if (form[0] == 'D') { datacode = TDOUBLE; width = 8; } else if (form[0] == 'A') { datacode = TSTRING; /* the following code is used to support the non-standard datatype of the form rAw where r = total width of the field and w = width of fixed-length substrings within the field. */ iread = 0; if (form[1] != 0) { if (form[1] == '(' ) /* skip parenthesis around */ form++; /* variable length column width */ iread = sscanf(&form[1],"%ld", &width); } if (iread != 1 || (!variable && (width > repeat)) ) width = repeat; } else if (form[0] == 'L') { datacode = TLOGICAL; width = 1; } else if (form[0] == 'X') { datacode = TBIT; width = 1; } else if (form[0] == 'B') { datacode = TBYTE; width = 1; } else if (form[0] == 'S') /* internal code to signify signed byte */ { datacode = TSBYTE; width = 1; } else if (form[0] == 'C') { datacode = TCOMPLEX; width = 8; } else if (form[0] == 'M') { datacode = TDBLCOMPLEX; width = 16; } else { sprintf(message, "Illegal binary table TFORMn datatype: \'%s\' ", tform); ffpmsg(message); return(*status = BAD_TFORM_DTYPE); } if (variable) datacode = datacode * (-1); /* flag variable cols w/ neg type code */ if (dtcode) *dtcode = datacode; if (trepeat) *trepeat = repeat; if (twidth) *twidth = width; return(*status); } /*--------------------------------------------------------------------------*/ int ffbnfmll(char *tform, /* I - format code from the TFORMn keyword */ int *dtcode, /* O - numerical datatype code */ LONGLONG *trepeat, /* O - repeat count of the field */ long *twidth, /* O - width of the field, in chars */ int *status) /* IO - error status */ { /* parse the binary table TFORM column format to determine the data type, repeat count, and the field width (if it is an ASCII (A) field) */ size_t ii, nchar; int datacode, variable, iread; long width; LONGLONG repeat; char *form, temp[FLEN_VALUE], message[FLEN_ERRMSG]; double drepeat; if (*status > 0) return(*status); if (dtcode) *dtcode = 0; if (trepeat) *trepeat = 0; if (twidth) *twidth = 0; nchar = strlen(tform); for (ii = 0; ii < nchar; ii++) { if (tform[ii] != ' ') /* find first non-space char */ break; } if (ii == nchar) { ffpmsg("Error: binary table TFORM code is blank (ffbnfm)."); return(*status = BAD_TFORM); } strcpy(temp, &tform[ii]); /* copy format string */ ffupch(temp); /* make sure it is in upper case */ form = temp; /* point to start of format string */ /*-----------------------------------------------*/ /* get the repeat count */ /*-----------------------------------------------*/ ii = 0; while(isdigit((int) form[ii])) ii++; /* look for leading digits in the field */ if (ii == 0) repeat = 1; /* no explicit repeat count */ else { /* read repeat count */ /* print as double, because the string-to-64-bit int conversion */ /* character is platform dependent (%lld, %ld, %I64d) */ sscanf(form,"%lf", &drepeat); repeat = (LONGLONG) (drepeat + 0.1); } /*-----------------------------------------------*/ /* determine datatype code */ /*-----------------------------------------------*/ form = form + ii; /* skip over the repeat field */ if (form[0] == 'P' || form[0] == 'Q') { variable = 1; /* this is a variable length column */ repeat = 1; /* disregard any other repeat value */ form++; /* move to the next data type code char */ } else variable = 0; if (form[0] == 'U') /* internal code to signify unsigned integer */ { datacode = TUSHORT; width = 2; } else if (form[0] == 'I') { datacode = TSHORT; width = 2; } else if (form[0] == 'V') /* internal code to signify unsigned integer */ { datacode = TULONG; width = 4; } else if (form[0] == 'J') { datacode = TLONG; width = 4; } else if (form[0] == 'K') { datacode = TLONGLONG; width = 8; } else if (form[0] == 'E') { datacode = TFLOAT; width = 4; } else if (form[0] == 'D') { datacode = TDOUBLE; width = 8; } else if (form[0] == 'A') { datacode = TSTRING; /* the following code is used to support the non-standard datatype of the form rAw where r = total width of the field and w = width of fixed-length substrings within the field. */ iread = 0; if (form[1] != 0) { if (form[1] == '(' ) /* skip parenthesis around */ form++; /* variable length column width */ iread = sscanf(&form[1],"%ld", &width); } if (iread != 1 || (!variable && (width > repeat)) ) width = (long) repeat; } else if (form[0] == 'L') { datacode = TLOGICAL; width = 1; } else if (form[0] == 'X') { datacode = TBIT; width = 1; } else if (form[0] == 'B') { datacode = TBYTE; width = 1; } else if (form[0] == 'S') /* internal code to signify signed byte */ { datacode = TSBYTE; width = 1; } else if (form[0] == 'C') { datacode = TCOMPLEX; width = 8; } else if (form[0] == 'M') { datacode = TDBLCOMPLEX; width = 16; } else { sprintf(message, "Illegal binary table TFORMn datatype: \'%s\' ", tform); ffpmsg(message); return(*status = BAD_TFORM_DTYPE); } if (variable) datacode = datacode * (-1); /* flag variable cols w/ neg type code */ if (dtcode) *dtcode = datacode; if (trepeat) *trepeat = repeat; if (twidth) *twidth = width; return(*status); } /*--------------------------------------------------------------------------*/ void ffcfmt(char *tform, /* value of an ASCII table TFORMn keyword */ char *cform) /* equivalent format code in C language syntax */ /* convert the FITS format string for an ASCII Table extension column into the equivalent C format string that can be used in a printf statement, after the values have been read as a double. */ { int ii; cform[0] = '\0'; ii = 0; while (tform[ii] != 0 && tform[ii] == ' ') /* find first non-blank char */ ii++; if (tform[ii] == 0) return; /* input format string was blank */ cform[0] = '%'; /* start the format string */ strcpy(&cform[1], &tform[ii + 1]); /* append the width and decimal code */ if (tform[ii] == 'A') strcat(cform, "s"); else if (tform[ii] == 'I') strcat(cform, ".0f"); /* 0 precision to suppress decimal point */ if (tform[ii] == 'F') strcat(cform, "f"); if (tform[ii] == 'E') strcat(cform, "E"); if (tform[ii] == 'D') strcat(cform, "E"); return; } /*--------------------------------------------------------------------------*/ void ffcdsp(char *tform, /* value of an ASCII table TFORMn keyword */ char *cform) /* equivalent format code in C language syntax */ /* convert the FITS TDISPn display format into the equivalent C format suitable for use in a printf statement. */ { int ii; cform[0] = '\0'; ii = 0; while (tform[ii] != 0 && tform[ii] == ' ') /* find first non-blank char */ ii++; if (tform[ii] == 0) { cform[0] = '\0'; return; /* input format string was blank */ } cform[0] = '%'; /* start the format string */ strcpy(&cform[1], &tform[ii + 1]); /* append the width and decimal code */ if (tform[ii] == 'A' || tform[ii] == 'a') strcat(cform, "s"); else if (tform[ii] == 'I' || tform[ii] == 'i') strcat(cform, "d"); else if (tform[ii] == 'O' || tform[ii] == 'o') strcat(cform, "o"); else if (tform[ii] == 'Z' || tform[ii] == 'z') strcat(cform, "X"); else if (tform[ii] == 'F' || tform[ii] == 'f') strcat(cform, "f"); else if (tform[ii] == 'E' || tform[ii] == 'e') strcat(cform, "E"); else if (tform[ii] == 'D' || tform[ii] == 'd') strcat(cform, "E"); else if (tform[ii] == 'G' || tform[ii] == 'g') strcat(cform, "G"); else cform[0] = '\0'; /* unrecognized tform code */ return; } /*--------------------------------------------------------------------------*/ int ffgcno( fitsfile *fptr, /* I - FITS file pionter */ int casesen, /* I - case sensitive string comparison? 0=no */ char *templt, /* I - input name of column (w/wildcards) */ int *colnum, /* O - number of the named column; 1=first col */ int *status) /* IO - error status */ /* Determine the column number corresponding to an input column name. The first column of the table = column 1; This supports the * and ? wild cards in the input template. */ { char colname[FLEN_VALUE]; /* temporary string to hold column name */ ffgcnn(fptr, casesen, templt, colname, colnum, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcnn( fitsfile *fptr, /* I - FITS file pointer */ int casesen, /* I - case sensitive string comparison? 0=no */ char *templt, /* I - input name of column (w/wildcards) */ char *colname, /* O - full column name up to 68 + 1 chars long*/ int *colnum, /* O - number of the named column; 1=first col */ int *status) /* IO - error status */ /* Return the full column name and column number of the next column whose TTYPEn keyword value matches the input template string. The template may contain the * and ? wildcards. Status = 237 is returned if the match is not unique. If so, one may call this routine again with input status=237 to get the next match. A status value of 219 is returned when there are no more matching columns. */ { char errmsg[FLEN_ERRMSG]; static int startcol; int tstatus, ii, founde, foundw, match, exact, unique; long ivalue; tcolumn *colptr; if (*status <= 0) { startcol = 0; /* start search with first column */ tstatus = 0; } else if (*status == COL_NOT_UNIQUE) /* start search from previous spot */ { tstatus = COL_NOT_UNIQUE; *status = 0; } else return(*status); /* bad input status value */ colname[0] = 0; /* initialize null return */ *colnum = 0; /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header to get col struct */ return(*status); colptr = (fptr->Fptr)->tableptr; /* pointer to first column */ colptr += (startcol); /* offset to starting column */ founde = FALSE; /* initialize 'found exact match' flag */ foundw = FALSE; /* initialize 'found wildcard match' flag */ unique = FALSE; for (ii = startcol; ii < (fptr->Fptr)->tfield; ii++, colptr++) { ffcmps(templt, colptr->ttype, casesen, &match, &exact); if (match) { if (founde && exact) { /* warning: this is the second exact match we've found */ /*reset pointer to first match so next search starts there */ startcol = *colnum; return(*status = COL_NOT_UNIQUE); } else if (founde) /* a wildcard match */ { /* already found exact match so ignore this non-exact match */ } else if (exact) { /* this is the first exact match we have found, so save it. */ strcpy(colname, colptr->ttype); *colnum = ii + 1; founde = TRUE; } else if (foundw) { /* we have already found a wild card match, so not unique */ /* continue searching for other matches */ unique = FALSE; } else { /* this is the first wild card match we've found. save it */ strcpy(colname, colptr->ttype); *colnum = ii + 1; startcol = *colnum; foundw = TRUE; unique = TRUE; } } } /* OK, we've checked all the names now see if we got any matches */ if (founde) { if (tstatus == COL_NOT_UNIQUE) /* we did find 1 exact match but */ *status = COL_NOT_UNIQUE; /* there was a previous match too */ } else if (foundw) { /* found one or more wildcard matches; report error if not unique */ if (!unique || tstatus == COL_NOT_UNIQUE) *status = COL_NOT_UNIQUE; } else { /* didn't find a match; check if template is a positive integer */ ffc2ii(templt, &ivalue, &tstatus); if (tstatus == 0 && ivalue <= (fptr->Fptr)->tfield && ivalue > 0) { *colnum = ivalue; colptr = (fptr->Fptr)->tableptr; /* pointer to first column */ colptr += (ivalue - 1); /* offset to correct column */ strcpy(colname, colptr->ttype); } else { *status = COL_NOT_FOUND; if (tstatus != COL_NOT_UNIQUE) { sprintf(errmsg, "ffgcnn could not find column: %.45s", templt); ffpmsg(errmsg); } } } startcol = *colnum; /* save pointer for next time */ return(*status); } /*--------------------------------------------------------------------------*/ void ffcmps(char *templt, /* I - input template (may have wildcards) */ char *colname, /* I - full column name up to 68 + 1 chars long */ int casesen, /* I - case sensitive string comparison? 1=yes */ int *match, /* O - do template and colname match? 1=yes */ int *exact) /* O - do strings exactly match, or wildcards */ /* compare the template to the string and test if they match. The strings are limited to 68 characters or less (the max. length of a FITS string keyword value. This routine reports whether the two strings match and whether the match is exact or involves wildcards. This algorithm is very similar to the way unix filename wildcards work except that this first treats a wild card as a literal character when looking for a match. If there is no literal match, then it interpretes it as a wild card. So the template 'AB*DE' is considered to be an exact rather than a wild card match to the string 'AB*DE'. The '#' wild card in the template string will match any consecutive string of decimal digits in the colname. */ { int ii, found, t1, s1, wildsearch = 0, tsave = 0, ssave = 0; char temp[FLEN_VALUE], col[FLEN_VALUE]; *match = FALSE; *exact = TRUE; strncpy(temp, templt, FLEN_VALUE); /* copy strings to work area */ strncpy(col, colname, FLEN_VALUE); temp[FLEN_VALUE - 1] = '\0'; /* make sure strings are terminated */ col[FLEN_VALUE - 1] = '\0'; /* truncate trailing non-significant blanks */ for (ii = strlen(temp) - 1; ii >= 0 && temp[ii] == ' '; ii--) temp[ii] = '\0'; for (ii = strlen(col) - 1; ii >= 0 && col[ii] == ' '; ii--) col[ii] = '\0'; if (!casesen) { /* convert both strings to uppercase before comparison */ ffupch(temp); ffupch(col); } if (!FSTRCMP(temp, col) ) { *match = TRUE; /* strings exactly match */ return; } *exact = FALSE; /* strings don't exactly match */ t1 = 0; /* start comparison with 1st char of each string */ s1 = 0; while(1) /* compare corresponding chars in each string */ { if (temp[t1] == '\0' && col[s1] == '\0') { /* completely scanned both strings so they match */ *match = TRUE; return; } else if (temp[t1] == '\0') { if (wildsearch) { /* the previous wildcard search may have been going down a blind alley. Backtrack, and resume the wildcard search with the next character in the string. */ t1 = tsave; s1 = ssave + 1; } else { /* reached end of template string so they don't match */ return; } } else if (col[s1] == '\0') { /* reached end of other string; they match if the next */ /* character in the template string is a '*' wild card */ if (temp[t1] == '*' && temp[t1 + 1] == '\0') { *match = TRUE; } return; } if (temp[t1] == col[s1] || (temp[t1] == '?') ) { s1++; /* corresponding chars in the 2 strings match */ t1++; /* increment both pointers and loop back again */ } else if (temp[t1] == '#' && isdigit((int) col[s1]) ) { s1++; /* corresponding chars in the 2 strings match */ t1++; /* increment both pointers */ /* find the end of the string of digits */ while (isdigit((int) col[s1]) ) s1++; } else if (temp[t1] == '*') { /* save current string locations, in case we need to restart */ wildsearch = 1; tsave = t1; ssave = s1; /* get next char from template and look for it in the col name */ t1++; if (temp[t1] == '\0' || temp[t1] == ' ') { /* reached end of template so strings match */ *match = TRUE; return; } found = FALSE; while (col[s1] && !found) { if (temp[t1] == col[s1]) { t1++; /* found matching characters; incre both pointers */ s1++; /* and loop back to compare next chars */ found = TRUE; } else s1++; /* increment the column name pointer and try again */ } if (!found) { return; /* hit end of column name and failed to find a match */ } } else { if (wildsearch) { /* the previous wildcard search may have been going down a blind alley. Backtrack, and resume the wildcard search with the next character in the string. */ t1 = tsave; s1 = ssave + 1; } else { return; /* strings don't match */ } } } } /*--------------------------------------------------------------------------*/ int ffgtcl( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ int *typecode, /* O - datatype code (21 = short, etc) */ long *repeat, /* O - repeat count of field */ long *width, /* O - if ASCII, width of field or unit string */ int *status) /* IO - error status */ /* Get Type of table column. Returns the datatype code of the column, as well as the vector repeat count and (if it is an ASCII character column) the width of the field or a unit string within the field. This supports the TFORMn = 'rAw' syntax for specifying arrays of substrings, so if TFORMn = '60A12' then repeat = 60 and width = 12. */ { LONGLONG trepeat, twidth; ffgtclll(fptr, colnum, typecode, &trepeat, &twidth, status); if (*status > 0) return(*status); if (repeat) *repeat= (long) trepeat; if (width) *width = (long) twidth; return(*status); } /*--------------------------------------------------------------------------*/ int ffgtclll( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ int *typecode, /* O - datatype code (21 = short, etc) */ LONGLONG *repeat, /* O - repeat count of field */ LONGLONG *width, /* O - if ASCII, width of field or unit string */ int *status) /* IO - error status */ /* Get Type of table column. Returns the datatype code of the column, as well as the vector repeat count and (if it is an ASCII character column) the width of the field or a unit string within the field. This supports the TFORMn = 'rAw' syntax for specifying arrays of substrings, so if TFORMn = '60A12' then repeat = 60 and width = 12. */ { tcolumn *colptr; int hdutype, decims; long tmpwidth; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) return(*status = BAD_COL_NUM); colptr = (fptr->Fptr)->tableptr; /* pointer to first column */ colptr += (colnum - 1); /* offset to correct column */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == ASCII_TBL) { ffasfm(colptr->tform, typecode, &tmpwidth, &decims, status); *width = tmpwidth; if (repeat) *repeat = 1; } else { if (typecode) *typecode = colptr->tdatatype; if (width) *width = colptr->twidth; if (repeat) *repeat = colptr->trepeat; } return(*status); } /*--------------------------------------------------------------------------*/ int ffeqty( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ int *typecode, /* O - datatype code (21 = short, etc) */ long *repeat, /* O - repeat count of field */ long *width, /* O - if ASCII, width of field or unit string */ int *status) /* IO - error status */ /* Get the 'equivalent' table column type. This routine is similar to the ffgtcl routine (which returns the physical datatype of the column, as stored in the FITS file) except that if the TSCALn and TZEROn keywords are defined for the column, then it returns the 'equivalent' datatype. Thus, if the column is defined as '1I' (short integer) this routine may return the type as 'TUSHORT' or as 'TFLOAT' depending on the TSCALn and TZEROn values. Returns the datatype code of the column, as well as the vector repeat count and (if it is an ASCII character column) the width of the field or a unit string within the field. This supports the TFORMn = 'rAw' syntax for specifying arrays of substrings, so if TFORMn = '60A12' then repeat = 60 and width = 12. */ { LONGLONG trepeat, twidth; ffeqtyll(fptr, colnum, typecode, &trepeat, &twidth, status); if (repeat) *repeat= (long) trepeat; if (width) *width = (long) twidth; return(*status); } /*--------------------------------------------------------------------------*/ int ffeqtyll( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ int *typecode, /* O - datatype code (21 = short, etc) */ LONGLONG *repeat, /* O - repeat count of field */ LONGLONG *width, /* O - if ASCII, width of field or unit string */ int *status) /* IO - error status */ /* Get the 'equivalent' table column type. This routine is similar to the ffgtcl routine (which returns the physical datatype of the column, as stored in the FITS file) except that if the TSCALn and TZEROn keywords are defined for the column, then it returns the 'equivalent' datatype. Thus, if the column is defined as '1I' (short integer) this routine may return the type as 'TUSHORT' or as 'TFLOAT' depending on the TSCALn and TZEROn values. Returns the datatype code of the column, as well as the vector repeat count and (if it is an ASCII character column) the width of the field or a unit string within the field. This supports the TFORMn = 'rAw' syntax for specifying arrays of substrings, so if TFORMn = '60A12' then repeat = 60 and width = 12. */ { tcolumn *colptr; int hdutype, decims, tcode, effcode; double tscale, tzero, min_val, max_val; long lngscale = 1, lngzero = 0, tmpwidth; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) return(*status = BAD_COL_NUM); colptr = (fptr->Fptr)->tableptr; /* pointer to first column */ colptr += (colnum - 1); /* offset to correct column */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == ASCII_TBL) { ffasfm(colptr->tform, typecode, &tmpwidth, &decims, status); *width = tmpwidth; if (repeat) *repeat = 1; } else { if (typecode) *typecode = colptr->tdatatype; if (width) *width = colptr->twidth; if (repeat) *repeat = colptr->trepeat; } /* return if caller is not interested in the typecode value */ if (!typecode) return(*status); /* check if the tscale and tzero keywords are defined, which might change the effective datatype of the column */ tscale = colptr->tscale; tzero = colptr->tzero; if (tscale == 1.0 && tzero == 0.0) /* no scaling */ return(*status); tcode = abs(*typecode); switch (tcode) { case TBYTE: /* binary table 'rB' column */ min_val = 0.; max_val = 255.0; break; case TSHORT: min_val = -32768.0; max_val = 32767.0; break; case TLONG: min_val = -2147483648.0; max_val = 2147483647.0; break; default: /* don't have to deal with other data types */ return(*status); } if (tscale >= 0.) { min_val = tzero + tscale * min_val; max_val = tzero + tscale * max_val; } else { max_val = tzero + tscale * min_val; min_val = tzero + tscale * max_val; } if (tzero < 2147483648.) /* don't exceed range of 32-bit integer */ lngzero = (long) tzero; lngscale = (long) tscale; if ((tzero != 2147483648.) && /* special value that exceeds integer range */ (lngzero != tzero || lngscale != tscale)) { /* not integers? */ /* floating point scaled values; just decide on required precision */ if (tcode == TBYTE || tcode == TSHORT) effcode = TFLOAT; else effcode = TDOUBLE; /* In all the remaining cases, TSCALn and TZEROn are integers, and not equal to 1 and 0, respectively. */ } else if ((min_val == -128.) && (max_val == 127.)) { effcode = TSBYTE; } else if ((min_val >= -32768.0) && (max_val <= 32767.0)) { effcode = TSHORT; } else if ((min_val >= 0.0) && (max_val <= 65535.0)) { effcode = TUSHORT; } else if ((min_val >= -2147483648.0) && (max_val <= 2147483647.0)) { effcode = TLONG; } else if ((min_val >= 0.0) && (max_val < 4294967296.0)) { effcode = TULONG; } else { /* exceeds the range of a 32-bit integer */ effcode = TDOUBLE; } /* return the effective datatype code (negative if variable length col.) */ if (*typecode < 0) /* variable length array column */ *typecode = -effcode; else *typecode = effcode; return(*status); } /*--------------------------------------------------------------------------*/ int ffgncl( fitsfile *fptr, /* I - FITS file pointer */ int *ncols, /* O - number of columns in the table */ int *status) /* IO - error status */ /* Get the number of columns in the table (= TFIELDS keyword) */ { if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) return(*status = NOT_TABLE); *ncols = (fptr->Fptr)->tfield; return(*status); } /*--------------------------------------------------------------------------*/ int ffgnrw( fitsfile *fptr, /* I - FITS file pointer */ long *nrows, /* O - number of rows in the table */ int *status) /* IO - error status */ /* Get the number of rows in the table (= NAXIS2 keyword) */ { if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) return(*status = NOT_TABLE); /* the NAXIS2 keyword may not be up to date, so use the structure value */ *nrows = (long) (fptr->Fptr)->numrows; return(*status); } /*--------------------------------------------------------------------------*/ int ffgnrwll( fitsfile *fptr, /* I - FITS file pointer */ LONGLONG *nrows, /* O - number of rows in the table */ int *status) /* IO - error status */ /* Get the number of rows in the table (= NAXIS2 keyword) */ { if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) return(*status = NOT_TABLE); /* the NAXIS2 keyword may not be up to date, so use the structure value */ *nrows = (fptr->Fptr)->numrows; return(*status); } /*--------------------------------------------------------------------------*/ int ffgacl( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ char *ttype, /* O - TTYPEn keyword value */ long *tbcol, /* O - TBCOLn keyword value */ char *tunit, /* O - TUNITn keyword value */ char *tform, /* O - TFORMn keyword value */ double *tscal, /* O - TSCALn keyword value */ double *tzero, /* O - TZEROn keyword value */ char *tnull, /* O - TNULLn keyword value */ char *tdisp, /* O - TDISPn keyword value */ int *status) /* IO - error status */ /* get ASCII column keyword values */ { char name[FLEN_KEYWORD], comm[FLEN_COMMENT]; tcolumn *colptr; int tstatus; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) return(*status = BAD_COL_NUM); /* get what we can from the column structure */ colptr = (fptr->Fptr)->tableptr; /* pointer to first column */ colptr += (colnum -1); /* offset to correct column */ if (ttype) strcpy(ttype, colptr->ttype); if (tbcol) *tbcol = (long) ((colptr->tbcol) + 1); /* first col is 1, not 0 */ if (tform) strcpy(tform, colptr->tform); if (tscal) *tscal = colptr->tscale; if (tzero) *tzero = colptr->tzero; if (tnull) strcpy(tnull, colptr->strnull); /* read keywords to get additional parameters */ if (tunit) { ffkeyn("TUNIT", colnum, name, status); tstatus = 0; *tunit = '\0'; ffgkys(fptr, name, tunit, comm, &tstatus); } if (tdisp) { ffkeyn("TDISP", colnum, name, status); tstatus = 0; *tdisp = '\0'; ffgkys(fptr, name, tdisp, comm, &tstatus); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgbcl( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ char *ttype, /* O - TTYPEn keyword value */ char *tunit, /* O - TUNITn keyword value */ char *dtype, /* O - datatype char: I, J, E, D, etc. */ long *repeat, /* O - vector column repeat count */ double *tscal, /* O - TSCALn keyword value */ double *tzero, /* O - TZEROn keyword value */ long *tnull, /* O - TNULLn keyword value integer cols only */ char *tdisp, /* O - TDISPn keyword value */ int *status) /* IO - error status */ /* get BINTABLE column keyword values */ { LONGLONG trepeat, ttnull; if (*status > 0) return(*status); ffgbclll(fptr, colnum, ttype, tunit, dtype, &trepeat, tscal, tzero, &ttnull, tdisp, status); if (repeat) *repeat = (long) trepeat; if (tnull) *tnull = (long) ttnull; return(*status); } /*--------------------------------------------------------------------------*/ int ffgbclll( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ char *ttype, /* O - TTYPEn keyword value */ char *tunit, /* O - TUNITn keyword value */ char *dtype, /* O - datatype char: I, J, E, D, etc. */ LONGLONG *repeat, /* O - vector column repeat count */ double *tscal, /* O - TSCALn keyword value */ double *tzero, /* O - TZEROn keyword value */ LONGLONG *tnull, /* O - TNULLn keyword value integer cols only */ char *tdisp, /* O - TDISPn keyword value */ int *status) /* IO - error status */ /* get BINTABLE column keyword values */ { char name[FLEN_KEYWORD], comm[FLEN_COMMENT]; tcolumn *colptr; int tstatus; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) return(*status = BAD_COL_NUM); /* get what we can from the column structure */ colptr = (fptr->Fptr)->tableptr; /* pointer to first column */ colptr += (colnum -1); /* offset to correct column */ if (ttype) strcpy(ttype, colptr->ttype); if (dtype) { if (colptr->tdatatype < 0) /* add the "P" prefix for */ strcpy(dtype, "P"); /* variable length columns */ else dtype[0] = 0; if (abs(colptr->tdatatype) == TBIT) strcat(dtype, "X"); else if (abs(colptr->tdatatype) == TBYTE) strcat(dtype, "B"); else if (abs(colptr->tdatatype) == TLOGICAL) strcat(dtype, "L"); else if (abs(colptr->tdatatype) == TSTRING) strcat(dtype, "A"); else if (abs(colptr->tdatatype) == TSHORT) strcat(dtype, "I"); else if (abs(colptr->tdatatype) == TLONG) strcat(dtype, "J"); else if (abs(colptr->tdatatype) == TLONGLONG) strcat(dtype, "K"); else if (abs(colptr->tdatatype) == TFLOAT) strcat(dtype, "E"); else if (abs(colptr->tdatatype) == TDOUBLE) strcat(dtype, "D"); else if (abs(colptr->tdatatype) == TCOMPLEX) strcat(dtype, "C"); else if (abs(colptr->tdatatype) == TDBLCOMPLEX) strcat(dtype, "M"); } if (repeat) *repeat = colptr->trepeat; if (tscal) *tscal = colptr->tscale; if (tzero) *tzero = colptr->tzero; if (tnull) *tnull = colptr->tnull; /* read keywords to get additional parameters */ if (tunit) { ffkeyn("TUNIT", colnum, name, status); tstatus = 0; *tunit = '\0'; ffgkys(fptr, name, tunit, comm, &tstatus); } if (tdisp) { ffkeyn("TDISP", colnum, name, status); tstatus = 0; *tdisp = '\0'; ffgkys(fptr, name, tdisp, comm, &tstatus); } return(*status); } /*--------------------------------------------------------------------------*/ int ffghdn(fitsfile *fptr, /* I - FITS file pointer */ int *chdunum) /* O - number of the CHDU; 1 = primary array */ /* Return the number of the Current HDU in the FITS file. The primary array is HDU number 1. Note that this is one of the few cfitsio routines that does not return the error status value as the value of the function. */ { *chdunum = (fptr->HDUposition) + 1; return(*chdunum); } /*--------------------------------------------------------------------------*/ int ffghadll(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG *headstart, /* O - byte offset to beginning of CHDU */ LONGLONG *datastart, /* O - byte offset to beginning of next HDU */ LONGLONG *dataend, /* O - byte offset to beginning of next HDU */ int *status) /* IO - error status */ /* Return the address (= byte offset) in the FITS file to the beginning of the current HDU, the beginning of the data unit, and the end of the data unit. */ { if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { if (ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status) > 0) return(*status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if (ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } if (headstart) *headstart = (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]; if (datastart) *datastart = (fptr->Fptr)->datastart; if (dataend) *dataend = (fptr->Fptr)->headstart[((fptr->Fptr)->curhdu) + 1]; return(*status); } /*--------------------------------------------------------------------------*/ int ffghof(fitsfile *fptr, /* I - FITS file pointer */ OFF_T *headstart, /* O - byte offset to beginning of CHDU */ OFF_T *datastart, /* O - byte offset to beginning of next HDU */ OFF_T *dataend, /* O - byte offset to beginning of next HDU */ int *status) /* IO - error status */ /* Return the address (= byte offset) in the FITS file to the beginning of the current HDU, the beginning of the data unit, and the end of the data unit. */ { if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { if (ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status) > 0) return(*status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if (ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } if (headstart) *headstart = (OFF_T) (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]; if (datastart) *datastart = (OFF_T) (fptr->Fptr)->datastart; if (dataend) *dataend = (OFF_T) (fptr->Fptr)->headstart[((fptr->Fptr)->curhdu) + 1]; return(*status); } /*--------------------------------------------------------------------------*/ int ffghad(fitsfile *fptr, /* I - FITS file pointer */ long *headstart, /* O - byte offset to beginning of CHDU */ long *datastart, /* O - byte offset to beginning of next HDU */ long *dataend, /* O - byte offset to beginning of next HDU */ int *status) /* IO - error status */ /* Return the address (= byte offset) in the FITS file to the beginning of the current HDU, the beginning of the data unit, and the end of the data unit. */ { LONGLONG shead, sdata, edata; if (*status > 0) return(*status); ffghadll(fptr, &shead, &sdata, &edata, status); if (headstart) { if (shead > LONG_MAX) *status = NUM_OVERFLOW; else *headstart = (long) shead; } if (datastart) { if (sdata > LONG_MAX) *status = NUM_OVERFLOW; else *datastart = (long) sdata; } if (dataend) { if (edata > LONG_MAX) *status = NUM_OVERFLOW; else *dataend = (long) edata; } return(*status); } /*--------------------------------------------------------------------------*/ int ffrhdu(fitsfile *fptr, /* I - FITS file pointer */ int *hdutype, /* O - type of HDU */ int *status) /* IO - error status */ /* read the required keywords of the CHDU and initialize the corresponding structure elements that describe the format of the HDU */ { int ii, tstatus; char card[FLEN_CARD]; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char xname[FLEN_VALUE], *xtension, urltype[20]; if (*status > 0) return(*status); if (ffgrec(fptr, 1, card, status) > 0 ) /* get the 80-byte card */ { ffpmsg("Cannot read first keyword in header (ffrhdu)."); return(*status); } strncpy(name,card,8); /* first 8 characters = the keyword name */ name[8] = '\0'; for (ii=7; ii >= 0; ii--) /* replace trailing blanks with nulls */ { if (name[ii] == ' ') name[ii] = '\0'; else break; } if (ffpsvc(card, value, comm, status) > 0) /* parse value and comment */ { ffpmsg("Cannot read value of first keyword in header (ffrhdu):"); ffpmsg(card); return(*status); } if (!strcmp(name, "SIMPLE")) /* this is the primary array */ { ffpinit(fptr, status); /* initialize the primary array */ if (hdutype != NULL) *hdutype = 0; } else if (!strcmp(name, "XTENSION")) /* this is an XTENSION keyword */ { if (ffc2s(value, xname, status) > 0) /* get the value string */ { ffpmsg("Bad value string for XTENSION keyword:"); ffpmsg(value); return(*status); } xtension = xname; while (*xtension == ' ') /* ignore any leading spaces in name */ xtension++; if (!strcmp(xtension, "TABLE")) { ffainit(fptr, status); /* initialize the ASCII table */ if (hdutype != NULL) *hdutype = 1; } else if (!strcmp(xtension, "BINTABLE") || !strcmp(xtension, "A3DTABLE") || !strcmp(xtension, "3DTABLE") ) { ffbinit(fptr, status); /* initialize the binary table */ if (hdutype != NULL) *hdutype = 2; } else { tstatus = 0; ffpinit(fptr, &tstatus); /* probably an IMAGE extension */ if (tstatus == UNKNOWN_EXT && hdutype != NULL) *hdutype = -1; /* don't recognize this extension type */ else { *status = tstatus; if (hdutype != NULL) *hdutype = 0; } } } else /* not the start of a new extension */ { if (card[0] == 0 || card[0] == 10) /* some editors append this character to EOF */ { *status = END_OF_FILE; } else { *status = UNKNOWN_REC; /* found unknown type of record */ ffpmsg ("Extension doesn't start with SIMPLE or XTENSION keyword. (ffrhdu)"); ffpmsg(card); } } /* compare the starting position of the next HDU (if any) with the size */ /* of the whole file to see if this is the last HDU in the file */ if ((fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] < (fptr->Fptr)->logfilesize ) { (fptr->Fptr)->lasthdu = 0; /* no, not the last HDU */ } else { (fptr->Fptr)->lasthdu = 1; /* yes, this is the last HDU */ /* special code for mem:// type files (FITS file in memory) */ /* Allocate enough memory to hold the entire HDU. */ /* Without this code, CFITSIO would repeatedly realloc memory */ /* to incrementally increase the size of the file by 2880 bytes */ /* at a time, until it reached the final size */ ffurlt(fptr, urltype, status); if (!strcmp(urltype,"mem://") || !strcmp(urltype,"memkeep://")) { fftrun(fptr, (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1], status); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffpinit(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* initialize the parameters defining the structure of the primary array or an Image extension */ { int groups, tstatus, simple, bitpix, naxis, extend, nspace; int ttype = 0, bytlen = 0, ii; long pcount, gcount; LONGLONG naxes[999], npix, blank; double bscale, bzero; char comm[FLEN_COMMENT]; tcolumn *colptr; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); (fptr->Fptr)->hdutype = IMAGE_HDU; /* primary array or IMAGE extension */ (fptr->Fptr)->headend = (fptr->Fptr)->logfilesize; /* set max size */ groups = 0; tstatus = *status; /* get all the descriptive info about this HDU */ ffgphd(fptr, 999, &simple, &bitpix, &naxis, naxes, &pcount, &gcount, &extend, &bscale, &bzero, &blank, &nspace, status); if (*status == NOT_IMAGE) *status = tstatus; /* ignore 'unknown extension type' error */ else if (*status > 0) return(*status); /* the logical end of the header is 80 bytes before the current position, minus any trailing blank keywords just before the END keyword. */ (fptr->Fptr)->headend = (fptr->Fptr)->nextkey - (80 * (nspace + 1)); /* the data unit begins at the beginning of the next logical block */ (fptr->Fptr)->datastart = (((fptr->Fptr)->nextkey - 80) / 2880 + 1) * 2880; if (naxis > 0 && naxes[0] == 0) /* test for 'random groups' */ { tstatus = 0; if (ffgkyl(fptr, "GROUPS", &groups, comm, &tstatus)) groups = 0; /* GROUPS keyword not found */ } if (bitpix == BYTE_IMG) /* test bitpix and set the datatype code */ { ttype=TBYTE; bytlen=1; } else if (bitpix == SHORT_IMG) { ttype=TSHORT; bytlen=2; } else if (bitpix == LONG_IMG) { ttype=TLONG; bytlen=4; } else if (bitpix == LONGLONG_IMG) { ttype=TLONGLONG; bytlen=8; } else if (bitpix == FLOAT_IMG) { ttype=TFLOAT; bytlen=4; } else if (bitpix == DOUBLE_IMG) { ttype=TDOUBLE; bytlen=8; } /* calculate the size of the primary array */ if (naxis == 0) { npix = 0; } else { if (groups) { npix = 1; /* NAXIS1 = 0 is a special flag for 'random groups' */ } else { npix = naxes[0]; } for (ii=1; ii < naxis; ii++) { npix = npix*naxes[ii]; /* calc number of pixels in the array */ } } /* now we know everything about the array; just fill in the parameters: the next HDU begins in the next logical block after the data */ (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] = (fptr->Fptr)->datastart + ( (LONGLONG)(pcount + npix) * bytlen * gcount + 2879) / 2880 * 2880; /* initialize the fictitious heap starting address (immediately following the array data) and a zero length heap. This is used to find the end of the data when checking the fill values in the last block. */ (fptr->Fptr)->heapstart = (npix + pcount) * bytlen * gcount; (fptr->Fptr)->heapsize = 0; (fptr->Fptr)->compressimg = 0; /* this is not a compressed image */ if (naxis == 0) { (fptr->Fptr)->rowlength = 0; /* rows have zero length */ (fptr->Fptr)->tfield = 0; /* table has no fields */ if ((fptr->Fptr)->tableptr) free((fptr->Fptr)->tableptr); /* free memory for the old CHDU */ (fptr->Fptr)->tableptr = 0; /* set a null table structure pointer */ (fptr->Fptr)->numrows = 0; (fptr->Fptr)->origrows = 0; } else { /* The primary array is actually interpreted as a binary table. There are two columns: the first column contains the group parameters if any. The second column contains the primary array of data as a single vector column element. In the case of 'random grouped' format, each group is stored in a separate row of the table. */ /* the number of rows is equal to the number of groups */ (fptr->Fptr)->numrows = gcount; (fptr->Fptr)->origrows = gcount; (fptr->Fptr)->rowlength = (npix + pcount) * bytlen; /* total size */ (fptr->Fptr)->tfield = 2; /* 2 fields: group params and the image */ if ((fptr->Fptr)->tableptr) free((fptr->Fptr)->tableptr); /* free memory for the old CHDU */ colptr = (tcolumn *) calloc(2, sizeof(tcolumn) ) ; if (!colptr) { ffpmsg ("malloc failed to get memory for FITS array descriptors (ffpinit)"); (fptr->Fptr)->tableptr = 0; /* set a null table structure pointer */ return(*status = ARRAY_TOO_BIG); } /* copy the table structure address to the fitsfile structure */ (fptr->Fptr)->tableptr = colptr; /* the first column represents the group parameters, if any */ colptr->tbcol = 0; colptr->tdatatype = ttype; colptr->twidth = bytlen; colptr->trepeat = (LONGLONG) pcount; colptr->tscale = 1.; colptr->tzero = 0.; colptr->tnull = blank; colptr++; /* increment pointer to the second column */ /* the second column represents the image array */ colptr->tbcol = pcount * bytlen; /* col starts after the group parms */ colptr->tdatatype = ttype; colptr->twidth = bytlen; colptr->trepeat = npix; colptr->tscale = bscale; colptr->tzero = bzero; colptr->tnull = blank; } /* reset next keyword pointer to the start of the header */ (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu ]; return(*status); } /*--------------------------------------------------------------------------*/ int ffainit(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ { /* initialize the parameters defining the structure of an ASCII table */ int ii, nspace; long tfield; LONGLONG pcount, rowlen, nrows, tbcoln; tcolumn *colptr = 0; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char message[FLEN_ERRMSG], errmsg[81]; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); (fptr->Fptr)->hdutype = ASCII_TBL; /* set that this is an ASCII table */ (fptr->Fptr)->headend = (fptr->Fptr)->logfilesize; /* set max size */ /* get table parameters and test that the header is a valid: */ if (ffgttb(fptr, &rowlen, &nrows, &pcount, &tfield, status) > 0) return(*status); if (pcount != 0) { ffpmsg("PCOUNT keyword not equal to 0 in ASCII table (ffainit)."); sprintf(errmsg, " PCOUNT = %ld", (long) pcount); ffpmsg(errmsg); return(*status = BAD_PCOUNT); } (fptr->Fptr)->rowlength = rowlen; /* store length of a row */ (fptr->Fptr)->tfield = tfield; /* store number of table fields in row */ if ((fptr->Fptr)->tableptr) free((fptr->Fptr)->tableptr); /* free memory for the old CHDU */ /* mem for column structures ; space is initialized = 0 */ if (tfield > 0) { colptr = (tcolumn *) calloc(tfield, sizeof(tcolumn) ); if (!colptr) { ffpmsg ("malloc failed to get memory for FITS table descriptors (ffainit)"); (fptr->Fptr)->tableptr = 0; /* set a null table structure pointer */ return(*status = ARRAY_TOO_BIG); } } /* copy the table structure address to the fitsfile structure */ (fptr->Fptr)->tableptr = colptr; /* initialize the table field parameters */ for (ii = 0; ii < tfield; ii++, colptr++) { colptr->ttype[0] = '\0'; /* null column name */ colptr->tscale = 1.; colptr->tzero = 0.; colptr->strnull[0] = ASCII_NULL_UNDEFINED; /* null value undefined */ colptr->tbcol = -1; /* initialize to illegal value */ colptr->tdatatype = -9999; /* initialize to illegal value */ } /* Initialize the fictitious heap starting address (immediately following the table data) and a zero length heap. This is used to find the end of the table data when checking the fill values in the last block. There is no special data following an ASCII table. */ (fptr->Fptr)->numrows = nrows; (fptr->Fptr)->origrows = nrows; (fptr->Fptr)->heapstart = rowlen * nrows; (fptr->Fptr)->heapsize = 0; (fptr->Fptr)->compressimg = 0; /* this is not a compressed image */ /* now search for the table column keywords and the END keyword */ for (nspace = 0, ii = 8; 1; ii++) /* infinite loop */ { ffgkyn(fptr, ii, name, value, comm, status); /* try to ignore minor syntax errors */ if (*status == NO_QUOTE) { strcat(value, "'"); *status = 0; } else if (*status == BAD_KEYCHAR) { *status = 0; } if (*status == END_OF_FILE) { ffpmsg("END keyword not found in ASCII table header (ffainit)."); return(*status = NO_END); } else if (*status > 0) return(*status); else if (name[0] == 'T') /* keyword starts with 'T' ? */ ffgtbp(fptr, name, value, status); /* test if column keyword */ else if (!FSTRCMP(name, "END")) /* is this the END keyword? */ break; if (!name[0] && !value[0] && !comm[0]) /* a blank keyword? */ nspace++; else nspace = 0; } /* test that all required keywords were found and have legal values */ colptr = (fptr->Fptr)->tableptr; for (ii = 0; ii < tfield; ii++, colptr++) { tbcoln = colptr->tbcol; /* the starting column number (zero based) */ if (colptr->tdatatype == -9999) { ffkeyn("TFORM", ii+1, name, status); /* construct keyword name */ sprintf(message,"Required %s keyword not found (ffainit).", name); ffpmsg(message); return(*status = NO_TFORM); } else if (tbcoln == -1) { ffkeyn("TBCOL", ii+1, name, status); /* construct keyword name */ sprintf(message,"Required %s keyword not found (ffainit).", name); ffpmsg(message); return(*status = NO_TBCOL); } else if ((fptr->Fptr)->rowlength != 0 && (tbcoln < 0 || tbcoln >= (fptr->Fptr)->rowlength ) ) { ffkeyn("TBCOL", ii+1, name, status); /* construct keyword name */ sprintf(message,"Value of %s keyword out of range: %ld (ffainit).", name, (long) tbcoln); ffpmsg(message); return(*status = BAD_TBCOL); } else if ((fptr->Fptr)->rowlength != 0 && tbcoln + colptr->twidth > (fptr->Fptr)->rowlength ) { sprintf(message,"Column %d is too wide to fit in table (ffainit)", ii+1); ffpmsg(message); sprintf(message, " TFORM = %s and NAXIS1 = %ld", colptr->tform, (long) (fptr->Fptr)->rowlength); ffpmsg(message); return(*status = COL_TOO_WIDE); } } /* now we know everything about the table; just fill in the parameters: the 'END' record is 80 bytes before the current position, minus any trailing blank keywords just before the END keyword. */ (fptr->Fptr)->headend = (fptr->Fptr)->nextkey - (80 * (nspace + 1)); /* the data unit begins at the beginning of the next logical block */ (fptr->Fptr)->datastart = (((fptr->Fptr)->nextkey - 80) / 2880 + 1) * 2880; /* the next HDU begins in the next logical block after the data */ (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] = (fptr->Fptr)->datastart + ( ((LONGLONG)rowlen * nrows + 2879) / 2880 * 2880 ); /* reset next keyword pointer to the start of the header */ (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu ]; return(*status); } /*--------------------------------------------------------------------------*/ int ffbinit(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ { /* initialize the parameters defining the structure of a binary table */ int ii, nspace; long tfield; LONGLONG pcount, rowlen, nrows, totalwidth; tcolumn *colptr = 0; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char message[FLEN_ERRMSG]; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); (fptr->Fptr)->hdutype = BINARY_TBL; /* set that this is a binary table */ (fptr->Fptr)->headend = (fptr->Fptr)->logfilesize; /* set max size */ /* get table parameters and test that the header is valid: */ if (ffgttb(fptr, &rowlen, &nrows, &pcount, &tfield, status) > 0) return(*status); (fptr->Fptr)->rowlength = rowlen; /* store length of a row */ (fptr->Fptr)->tfield = tfield; /* store number of table fields in row */ if ((fptr->Fptr)->tableptr) free((fptr->Fptr)->tableptr); /* free memory for the old CHDU */ /* mem for column structures ; space is initialized = 0 */ if (tfield > 0) { colptr = (tcolumn *) calloc(tfield, sizeof(tcolumn) ); if (!colptr) { ffpmsg ("malloc failed to get memory for FITS table descriptors (ffbinit)"); (fptr->Fptr)->tableptr = 0; /* set a null table structure pointer */ return(*status = ARRAY_TOO_BIG); } } /* copy the table structure address to the fitsfile structure */ (fptr->Fptr)->tableptr = colptr; /* initialize the table field parameters */ for (ii = 0; ii < tfield; ii++, colptr++) { colptr->ttype[0] = '\0'; /* null column name */ colptr->tscale = 1.; colptr->tzero = 0.; colptr->tnull = NULL_UNDEFINED; /* (integer) null value undefined */ colptr->tdatatype = -9999; /* initialize to illegal value */ colptr->trepeat = 1; colptr->strnull[0] = '\0'; /* for ASCII string columns (TFORM = rA) */ } /* Initialize the heap starting address (immediately following the table data) and the size of the heap. This is used to find the end of the table data when checking the fill values in the last block. */ (fptr->Fptr)->numrows = nrows; (fptr->Fptr)->origrows = nrows; (fptr->Fptr)->heapstart = rowlen * nrows; (fptr->Fptr)->heapsize = pcount; (fptr->Fptr)->compressimg = 0; /* initialize as not a compressed image */ /* now search for the table column keywords and the END keyword */ for (nspace = 0, ii = 8; 1; ii++) /* infinite loop */ { ffgkyn(fptr, ii, name, value, comm, status); /* try to ignore minor syntax errors */ if (*status == NO_QUOTE) { strcat(value, "'"); *status = 0; } else if (*status == BAD_KEYCHAR) { *status = 0; } if (*status == END_OF_FILE) { ffpmsg("END keyword not found in binary table header (ffbinit)."); return(*status = NO_END); } else if (*status > 0) return(*status); else if (name[0] == 'T') /* keyword starts with 'T' ? */ ffgtbp(fptr, name, value, status); /* test if column keyword */ else if (!FSTRCMP(name, "ZIMAGE")) { if (value[0] == 'T') (fptr->Fptr)->compressimg = 1; /* this is a compressed image */ } else if (!FSTRCMP(name, "END")) /* is this the END keyword? */ break; if (!name[0] && !value[0] && !comm[0]) /* a blank keyword? */ nspace++; else nspace = 0; /* reset number of consecutive spaces before END */ } /* test that all the required keywords were found and have legal values */ colptr = (fptr->Fptr)->tableptr; /* set pointer to first column */ for (ii = 0; ii < tfield; ii++, colptr++) { if (colptr->tdatatype == -9999) { ffkeyn("TFORM", ii+1, name, status); /* construct keyword name */ sprintf(message,"Required %s keyword not found (ffbinit).", name); ffpmsg(message); return(*status = NO_TFORM); } } /* now we know everything about the table; just fill in the parameters: the 'END' record is 80 bytes before the current position, minus any trailing blank keywords just before the END keyword. */ (fptr->Fptr)->headend = (fptr->Fptr)->nextkey - (80 * (nspace + 1)); /* the data unit begins at the beginning of the next logical block */ (fptr->Fptr)->datastart = (((fptr->Fptr)->nextkey - 80) / 2880 + 1) * 2880; /* the next HDU begins in the next logical block after the data */ (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] = (fptr->Fptr)->datastart + ( (rowlen * nrows + pcount + 2879) / 2880 * 2880 ); /* determine the byte offset to the beginning of each column */ ffgtbc(fptr, &totalwidth, status); if (totalwidth != rowlen) { sprintf(message, "NAXIS1 = %ld is not equal to the sum of column widths: %ld", (long) rowlen, (long) totalwidth); ffpmsg(message); *status = BAD_ROW_WIDTH; } /* reset next keyword pointer to the start of the header */ (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu ]; if ( (fptr->Fptr)->compressimg == 1) /* Is this a compressed image */ imcomp_get_compressed_image_par(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgabc(int tfields, /* I - number of columns in the table */ char **tform, /* I - value of TFORMn keyword for each column */ int space, /* I - number of spaces to leave between cols */ long *rowlen, /* O - total width of a table row */ long *tbcol, /* O - starting byte in row for each column */ int *status) /* IO - error status */ /* calculate the starting byte offset of each column of an ASCII table and the total length of a row, in bytes. The input space value determines how many blank spaces to leave between each column (1 is recommended). */ { int ii, datacode, decims; long width; if (*status > 0) return(*status); *rowlen=0; if (tfields <= 0) return(*status); tbcol[0] = 1; for (ii = 0; ii < tfields; ii++) { tbcol[ii] = *rowlen + 1; /* starting byte in row of column */ ffasfm(tform[ii], &datacode, &width, &decims, status); *rowlen += (width + space); /* total length of row */ } *rowlen -= space; /* don't add space after the last field */ return (*status); } /*--------------------------------------------------------------------------*/ int ffgtbc(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG *totalwidth, /* O - total width of a table row */ int *status) /* IO - error status */ { /* calculate the starting byte offset of each column of a binary table. Use the values of the datatype code and repeat counts in the column structure. Return the total length of a row, in bytes. */ int tfields, ii; LONGLONG nbytes; tcolumn *colptr; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); tfields = (fptr->Fptr)->tfield; colptr = (fptr->Fptr)->tableptr; /* point to first column structure */ *totalwidth = 0; for (ii = 0; ii < tfields; ii++, colptr++) { colptr->tbcol = *totalwidth; /* byte offset in row to this column */ if (colptr->tdatatype == TSTRING) { nbytes = colptr->trepeat; /* one byte per char */ } else if (colptr->tdatatype == TBIT) { nbytes = ( colptr->trepeat + 7) / 8; } else if (colptr->tdatatype > 0) { nbytes = colptr->trepeat * (colptr->tdatatype / 10); } else if ((colptr->tform[0] == 'P') || (colptr->tform[1] == 'P')) /* this is a 'P' variable length descriptor (neg. tdatatype) */ nbytes = 8; else /* this is a 'Q' variable length descriptor (neg. tdatatype) */ nbytes = 16; *totalwidth = *totalwidth + nbytes; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgtbp(fitsfile *fptr, /* I - FITS file pointer */ char *name, /* I - name of the keyword */ char *value, /* I - value string of the keyword */ int *status) /* IO - error status */ { /* Get TaBle Parameter. The input keyword name begins with the letter T. Test if the keyword is one of the table column definition keywords of an ASCII or binary table. If so, decode it and update the value in the structure. */ int tstatus, datacode, decimals; long width, repeat, nfield, ivalue; LONGLONG jjvalue; double dvalue; char tvalue[FLEN_VALUE], *loc; char message[FLEN_ERRMSG]; tcolumn *colptr; if (*status > 0) return(*status); tstatus = 0; /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if(!FSTRNCMP(name + 1, "TYPE", 4) ) { /* get the index number */ if( ffc2ii(name + 5, &nfield, &tstatus) > 0) /* read index no. */ return(*status); /* must not be an indexed keyword */ if (nfield < 1 || nfield > (fptr->Fptr)->tfield ) /* out of range */ return(*status); colptr = (fptr->Fptr)->tableptr; /* get pointer to columns */ colptr = colptr + nfield - 1; /* point to the correct column */ if (ffc2s(value, tvalue, &tstatus) > 0) /* remove quotes */ return(*status); strcpy(colptr->ttype, tvalue); /* copy col name to structure */ } else if(!FSTRNCMP(name + 1, "FORM", 4) ) { /* get the index number */ if( ffc2ii(name + 5, &nfield, &tstatus) > 0) /* read index no. */ return(*status); /* must not be an indexed keyword */ if (nfield < 1 || nfield > (fptr->Fptr)->tfield ) /* out of range */ return(*status); colptr = (fptr->Fptr)->tableptr; /* get pointer to columns */ colptr = colptr + nfield - 1; /* point to the correct column */ if (ffc2s(value, tvalue, &tstatus) > 0) /* remove quotes */ return(*status); strncpy(colptr->tform, tvalue, 9); /* copy TFORM to structure */ colptr->tform[9] = '\0'; /* make sure it is terminated */ if ((fptr->Fptr)->hdutype == ASCII_TBL) /* ASCII table */ { if (ffasfm(tvalue, &datacode, &width, &decimals, status) > 0) return(*status); /* bad format code */ colptr->tdatatype = TSTRING; /* store datatype code */ colptr->trepeat = 1; /* field repeat count == 1 */ colptr->twidth = width; /* the width of the field, in bytes */ } else /* binary table */ { if (ffbnfm(tvalue, &datacode, &repeat, &width, status) > 0) return(*status); /* bad format code */ colptr->tdatatype = datacode; /* store datatype code */ colptr->trepeat = (LONGLONG) repeat; /* field repeat count */ /* Don't overwrite the unit string width if it was previously */ /* set by a TDIMn keyword and has a legal value */ if (datacode == TSTRING) { if (colptr->twidth == 0 || colptr->twidth > repeat) colptr->twidth = width; /* width of a unit string */ } else { colptr->twidth = width; /* width of a unit value in chars */ } } } else if(!FSTRNCMP(name + 1, "BCOL", 4) ) { /* get the index number */ if( ffc2ii(name + 5, &nfield, &tstatus) > 0) /* read index no. */ return(*status); /* must not be an indexed keyword */ if (nfield < 1 || nfield > (fptr->Fptr)->tfield ) /* out of range */ return(*status); colptr = (fptr->Fptr)->tableptr; /* get pointer to columns */ colptr = colptr + nfield - 1; /* point to the correct column */ if ((fptr->Fptr)->hdutype == BINARY_TBL) return(*status); /* binary tables don't have TBCOL keywords */ if (ffc2ii(value, &ivalue, status) > 0) { sprintf(message, "Error reading value of %s as an integer: %s", name, value); ffpmsg(message); return(*status); } colptr->tbcol = ivalue - 1; /* convert to zero base */ } else if(!FSTRNCMP(name + 1, "SCAL", 4) ) { /* get the index number */ if( ffc2ii(name + 5, &nfield, &tstatus) > 0) /* read index no. */ return(*status); /* must not be an indexed keyword */ if (nfield < 1 || nfield > (fptr->Fptr)->tfield ) /* out of range */ return(*status); colptr = (fptr->Fptr)->tableptr; /* get pointer to columns */ colptr = colptr + nfield - 1; /* point to the correct column */ if (ffc2dd(value, &dvalue, &tstatus) > 0) { sprintf(message, "Error reading value of %s as a double: %s", name, value); ffpmsg(message); /* ignore this error, so don't return error status */ return(*status); } colptr->tscale = dvalue; } else if(!FSTRNCMP(name + 1, "ZERO", 4) ) { /* get the index number */ if( ffc2ii(name + 5, &nfield, &tstatus) > 0) /* read index no. */ return(*status); /* must not be an indexed keyword */ if (nfield < 1 || nfield > (fptr->Fptr)->tfield ) /* out of range */ return(*status); colptr = (fptr->Fptr)->tableptr; /* get pointer to columns */ colptr = colptr + nfield - 1; /* point to the correct column */ if (ffc2dd(value, &dvalue, &tstatus) > 0) { sprintf(message, "Error reading value of %s as a double: %s", name, value); ffpmsg(message); /* ignore this error, so don't return error status */ return(*status); } colptr->tzero = dvalue; } else if(!FSTRNCMP(name + 1, "NULL", 4) ) { /* get the index number */ if( ffc2ii(name + 5, &nfield, &tstatus) > 0) /* read index no. */ return(*status); /* must not be an indexed keyword */ if (nfield < 1 || nfield > (fptr->Fptr)->tfield ) /* out of range */ return(*status); colptr = (fptr->Fptr)->tableptr; /* get pointer to columns */ colptr = colptr + nfield - 1; /* point to the correct column */ if ((fptr->Fptr)->hdutype == ASCII_TBL) /* ASCII table */ { if (ffc2s(value, tvalue, &tstatus) > 0) /* remove quotes */ return(*status); strncpy(colptr->strnull, tvalue, 17); /* copy TNULL string */ colptr->strnull[17] = '\0'; /* terminate the strnull field */ } else /* binary table */ { if (ffc2jj(value, &jjvalue, &tstatus) > 0) { sprintf(message, "Error reading value of %s as an integer: %s", name, value); ffpmsg(message); /* ignore this error, so don't return error status */ return(*status); } colptr->tnull = jjvalue; /* null value for integer column */ } } else if(!FSTRNCMP(name + 1, "DIM", 3) ) { if ((fptr->Fptr)->hdutype == ASCII_TBL) /* ASCII table */ return(*status); /* ASCII tables don't support TDIMn keyword */ /* get the index number */ if( ffc2ii(name + 4, &nfield, &tstatus) > 0) /* read index no. */ return(*status); /* must not be an indexed keyword */ if (nfield < 1 || nfield > (fptr->Fptr)->tfield ) /* out of range */ return(*status); colptr = (fptr->Fptr)->tableptr; /* get pointer to columns */ colptr = colptr + nfield - 1; /* point to the correct column */ /* uninitialized columns have tdatatype set = -9999 */ if (colptr->tdatatype != -9999 && colptr->tdatatype != TSTRING) return(*status); /* this is not an ASCII string column */ loc = strchr(value, '(' ); /* find the opening parenthesis */ if (!loc) return(*status); /* not a proper TDIM keyword */ loc++; width = strtol(loc, &loc, 10); /* read size of first dimension */ if (colptr->trepeat != 1 && colptr->trepeat < width) return(*status); /* string length is greater than column width */ colptr->twidth = width; /* set width of a unit string in chars */ } else if (!FSTRNCMP(name + 1, "HEAP", 4) ) { if ((fptr->Fptr)->hdutype == ASCII_TBL) /* ASCII table */ return(*status); /* ASCII tables don't have a heap */ if (ffc2jj(value, &jjvalue, &tstatus) > 0) { sprintf(message, "Error reading value of %s as an integer: %s", name, value); ffpmsg(message); /* ignore this error, so don't return error status */ return(*status); } (fptr->Fptr)->heapstart = jjvalue; /* starting byte of the heap */ return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgcprll( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number (1 = 1st column of table) */ LONGLONG firstrow, /* I - first row (1 = 1st row of table) */ LONGLONG firstelem, /* I - first element within vector (1 = 1st) */ LONGLONG nelem, /* I - number of elements to read or write */ int writemode, /* I - = 1 if writing data, = 0 if reading data */ /* If = 2, then writing data, but don't modify */ /* the returned values of repeat and incre. */ /* If = -1, then reading data in reverse */ /* direction. */ double *scale, /* O - FITS scaling factor (TSCALn keyword value) */ double *zero, /* O - FITS scaling zero pt (TZEROn keyword value) */ char *tform, /* O - ASCII column format: value of TFORMn keyword */ long *twidth, /* O - width of ASCII column (characters) */ int *tcode, /* O - column datatype code: I*4=41, R*4=42, etc */ int *maxelem, /* O - max number of elements that fit in buffer */ LONGLONG *startpos,/* O - offset in file to starting row & column */ LONGLONG *elemnum, /* O - starting element number ( 0 = 1st element) */ long *incre, /* O - byte offset between elements within a row */ LONGLONG *repeat, /* O - number of elements in a row (vector column) */ LONGLONG *rowlen, /* O - length of a row, in bytes */ int *hdutype, /* O - HDU type: 0, 1, 2 = primary, table, bintable */ LONGLONG *tnull, /* O - null value for integer columns */ char *snull, /* O - null value for ASCII table columns */ int *status) /* IO - error status */ /* Get Column PaRameters, and test starting row and element numbers for validity. This is a workhorse routine that is call by nearly every other routine that reads or writes to FITS files. */ { int nulpos, rangecheck = 1, tstatus = 0; LONGLONG datastart, endpos; long nblock; LONGLONG heapoffset, lrepeat, endrow, nrows, tbcol; char message[81]; tcolumn *colptr; /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); /* Do sanity check of input parameters */ if (firstrow < 1) { if ((fptr->Fptr)->hdutype == IMAGE_HDU) /* Primary Array or IMAGE */ { sprintf(message, "Image group number is less than 1: %.0f", (double) firstrow); ffpmsg(message); return(*status = BAD_ROW_NUM); } else { sprintf(message, "Starting row number is less than 1: %.0f", (double) firstrow); ffpmsg(message); return(*status = BAD_ROW_NUM); } } else if ((fptr->Fptr)->hdutype != ASCII_TBL && firstelem < 1) { sprintf(message, "Starting element number less than 1: %ld", (long) firstelem); ffpmsg(message); return(*status = BAD_ELEM_NUM); } else if (nelem < 0) { sprintf(message, "Tried to read or write less than 0 elements: %.0f", (double) nelem); ffpmsg(message); return(*status = NEG_BYTES); } else if (colnum < 1 || colnum > (fptr->Fptr)->tfield) { sprintf(message, "Specified column number is out of range: %d", colnum); ffpmsg(message); sprintf(message, " There are %d columns in this table.", (fptr->Fptr)->tfield ); ffpmsg(message); return(*status = BAD_COL_NUM); } /* copy relevant parameters from the structure */ *hdutype = (fptr->Fptr)->hdutype; /* image, ASCII table, or BINTABLE */ *rowlen = (fptr->Fptr)->rowlength; /* width of the table, in bytes */ datastart = (fptr->Fptr)->datastart; /* offset in file to start of table */ colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ *scale = colptr->tscale; /* value scaling factor; default = 1.0 */ *zero = colptr->tzero; /* value scaling zeropoint; default = 0.0 */ *tnull = colptr->tnull; /* null value for integer columns */ tbcol = colptr->tbcol; /* offset to start of column within row */ *twidth = colptr->twidth; /* width of a single datum, in bytes */ *incre = colptr->twidth; /* increment between datums, in bytes */ *tcode = colptr->tdatatype; *repeat = colptr->trepeat; strcpy(tform, colptr->tform); /* value of TFORMn keyword */ strcpy(snull, colptr->strnull); /* null value for ASCII table columns */ if (*hdutype == ASCII_TBL && snull[0] == '\0') { /* In ASCII tables, a null value is equivalent to all spaces */ strcpy(snull, " "); /* maximum of 17 spaces */ nulpos = minvalue(17, *twidth); /* truncate to width of column */ snull[nulpos] = '\0'; } /* Special case: interpret writemode = -1 as reading data, but */ /* don't do error check for exceeding the range of pixels */ if (writemode == -1) { writemode = 0; rangecheck = 0; } /* Special case: interprete 'X' column as 'B' */ if (abs(*tcode) == TBIT) { *tcode = *tcode / TBIT * TBYTE; *repeat = (*repeat + 7) / 8; } /* Special case: support the 'rAw' format in BINTABLEs */ if (*hdutype == BINARY_TBL && *tcode == TSTRING) { *repeat = *repeat / *twidth; /* repeat = # of unit strings in field */ } else if (*hdutype == BINARY_TBL && *tcode == -TSTRING) { /* variable length string */ *incre = 1; *twidth = (long) nelem; } if (*hdutype == ASCII_TBL) *elemnum = 0; /* ASCII tables don't have vector elements */ else *elemnum = firstelem - 1; /* interprete complex and double complex as pairs of floats or doubles */ if (abs(*tcode) >= TCOMPLEX) { if (*tcode > 0) *tcode = (*tcode + 1) / 2; else *tcode = (*tcode - 1) / 2; *repeat = *repeat * 2; *twidth = *twidth / 2; *incre = *incre / 2; } /* calculate no. of pixels that fit in buffer */ /* allow for case where floats are 8 bytes long */ if (abs(*tcode) == TFLOAT) *maxelem = DBUFFSIZE / sizeof(float); else if (abs(*tcode) == TDOUBLE) *maxelem = DBUFFSIZE / sizeof(double); else if (abs(*tcode) == TSTRING) { *maxelem = (DBUFFSIZE - 1)/ *twidth; /* leave room for final \0 */ if (*maxelem == 0) { sprintf(message, "ASCII string column is too wide: %ld; max supported width is %d", *twidth, DBUFFSIZE - 1); ffpmsg(message); return(*status = COL_TOO_WIDE); } } else *maxelem = DBUFFSIZE / *twidth; /* calc starting byte position to 1st element of col */ /* (this does not apply to variable length columns) */ *startpos = datastart + ((LONGLONG)(firstrow - 1) * *rowlen) + tbcol; if (*hdutype == IMAGE_HDU && writemode) /* Primary Array or IMAGE */ { /* For primary arrays, set the repeat count greater than the total number of pixels to be written. This prevents an out-of-range error message in cases where the final image array size is not yet known or defined. */ if (*repeat < *elemnum + nelem) *repeat = *elemnum + nelem; } else if (*tcode > 0) /* Fixed length table column */ { if (*elemnum >= *repeat) { sprintf(message, "First element to write is too large: %ld; max allowed value is %ld", (long) ((*elemnum) + 1), (long) *repeat); ffpmsg(message); return(*status = BAD_ELEM_NUM); } /* last row number to be read or written */ endrow = ((*elemnum + nelem - 1) / *repeat) + firstrow; if (writemode) { /* check if we are writing beyond the current end of table */ if ((endrow > (fptr->Fptr)->numrows) && (nelem > 0) ) { /* if there are more HDUs following the current one, or */ /* if there is a data heap, then we must insert space */ /* for the new rows. */ if ( !((fptr->Fptr)->lasthdu) || (fptr->Fptr)->heapsize > 0) { nrows = endrow - ((fptr->Fptr)->numrows); if (ffirow(fptr, (fptr->Fptr)->numrows, nrows, status) > 0) { sprintf(message, "Failed to add space for %.0f new rows in table.", (double) nrows); ffpmsg(message); return(*status); } } else { /* update heap starting address */ (fptr->Fptr)->heapstart += ((LONGLONG)(endrow - (fptr->Fptr)->numrows) * (fptr->Fptr)->rowlength ); (fptr->Fptr)->numrows = endrow; /* update number of rows */ } } } else /* reading from the file */ { if ( endrow > (fptr->Fptr)->numrows && rangecheck) { if (*hdutype == IMAGE_HDU) /* Primary Array or IMAGE */ { if (firstrow > (fptr->Fptr)->numrows) { sprintf(message, "Attempted to read from group %ld of the HDU,", (long) firstrow); ffpmsg(message); sprintf(message, "however the HDU only contains %ld group(s).", (long) ((fptr->Fptr)->numrows) ); ffpmsg(message); } else { ffpmsg("Attempt to read past end of array:"); sprintf(message, " Image has %ld elements;", (long) *repeat); ffpmsg(message); sprintf(message, " Tried to read %ld elements starting at element %ld.", (long) nelem, (long) firstelem); ffpmsg(message); } } else { ffpmsg("Attempt to read past end of table:"); sprintf(message, " Table has %.0f rows with %.0f elements per row;", (double) ((fptr->Fptr)->numrows), (double) *repeat); ffpmsg(message); sprintf(message, " Tried to read %.0f elements starting at row %.0f, element %.0f.", (double) nelem, (double) firstrow, (double) ((*elemnum) + 1)); ffpmsg(message); } return(*status = BAD_ROW_NUM); } } if (*repeat == 1 && nelem > 1 && writemode != 2) { /* When accessing a scalar column, fool the calling routine into thinking that this is a vector column with very big elements. This allows multiple values (up to the maxelem number of elements that will fit in the buffer) to be read or written with a single routine call, which increases the efficiency. If writemode == 2, then the calling program does not want to have this efficiency trick applied. */ *incre = (long) *rowlen; *repeat = nelem; } } else /* Variable length Binary Table column */ { *tcode *= (-1); if (writemode) /* return next empty heap address for writing */ { *repeat = nelem + *elemnum; /* total no. of elements in the field */ /* first, check if we are overwriting an existing row, and */ /* if so, if the existing space is big enough for the new vector */ if ( firstrow <= (fptr->Fptr)->numrows ) { ffgdesll(fptr, colnum, firstrow, &lrepeat, &heapoffset, &tstatus); if (!tstatus) { if (colptr->tdatatype <= -TCOMPLEX) lrepeat = lrepeat * 2; /* no. of float or double values */ else if (colptr->tdatatype == -TBIT) lrepeat = (lrepeat + 7) / 8; /* convert from bits to bytes */ if (lrepeat >= *repeat) /* enough existing space? */ { *startpos = datastart + heapoffset + (fptr->Fptr)->heapstart; /* write the descriptor into the fixed length part of table */ if (colptr->tdatatype <= -TCOMPLEX) { /* divide repeat count by 2 to get no. of complex values */ ffpdes(fptr, colnum, firstrow, *repeat / 2, heapoffset, status); } else { ffpdes(fptr, colnum, firstrow, *repeat, heapoffset, status); } return(*status); } } } /* Add more rows to the table, if writing beyond the end. */ /* It is necessary to shift the heap down in this case */ if ( firstrow > (fptr->Fptr)->numrows) { nrows = firstrow - ((fptr->Fptr)->numrows); if (ffirow(fptr, (fptr->Fptr)->numrows, nrows, status) > 0) { sprintf(message, "Failed to add space for %.0f new rows in table.", (double) nrows); ffpmsg(message); return(*status); } } /* calculate starting position (for writing new data) in the heap */ *startpos = datastart + (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; /* write the descriptor into the fixed length part of table */ if (colptr->tdatatype <= -TCOMPLEX) { /* divide repeat count by 2 to get no. of complex values */ ffpdes(fptr, colnum, firstrow, *repeat / 2, (fptr->Fptr)->heapsize, status); } else { ffpdes(fptr, colnum, firstrow, *repeat, (fptr->Fptr)->heapsize, status); } /* If this is not the last HDU in the file, then check if */ /* extending the heap would overwrite the following header. */ /* If so, then have to insert more blocks. */ if ( !((fptr->Fptr)->lasthdu) ) { endpos = datastart + (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize + ( *repeat * (*incre)); if (endpos > (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1]) { /* calc the number of blocks that need to be added */ nblock = (long) (((endpos - 1 - (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] ) / 2880) + 1); if (ffiblk(fptr, nblock, 1, status) > 0) /* insert blocks */ { sprintf(message, "Failed to extend the size of the variable length heap by %ld blocks.", nblock); ffpmsg(message); return(*status); } } } /* increment the address to the next empty heap position */ (fptr->Fptr)->heapsize += ( *repeat * (*incre)); } else /* get the read start position in the heap */ { if ( firstrow > (fptr->Fptr)->numrows) { ffpmsg("Attempt to read past end of table"); sprintf(message, " Table has %.0f rows and tried to read row %.0f.", (double) ((fptr->Fptr)->numrows), (double) firstrow); ffpmsg(message); return(*status = BAD_ROW_NUM); } ffgdesll(fptr, colnum, firstrow, &lrepeat, &heapoffset, status); *repeat = lrepeat; if (colptr->tdatatype <= -TCOMPLEX) *repeat = *repeat * 2; /* no. of float or double values */ else if (colptr->tdatatype == -TBIT) *repeat = (*repeat + 7) / 8; /* convert from bits to bytes */ if (*elemnum >= *repeat) { sprintf(message, "Starting element to read in variable length column is too large: %ld", (long) firstelem); ffpmsg(message); sprintf(message, " This row only contains %ld elements", (long) *repeat); ffpmsg(message); return(*status = BAD_ELEM_NUM); } *startpos = datastart + heapoffset + (fptr->Fptr)->heapstart; } } return(*status); } /*---------------------------------------------------------------------------*/ int fftheap(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG *heapsz, /* O - current size of the heap */ LONGLONG *unused, /* O - no. of unused bytes in the heap */ LONGLONG *overlap, /* O - no. of bytes shared by > 1 descriptors */ int *valid, /* O - are all the heap addresses valid? */ int *status) /* IO - error status */ /* Tests the contents of the binary table variable length array heap. Returns the number of bytes that are currently not pointed to by any of the descriptors, and also the number of bytes that are pointed to by more than one descriptor. It returns valid = FALSE if any of the descriptors point to addresses that are out of the bounds of the heap. */ { int jj, typecode, pixsize; long ii, kk, theapsz, nbytes; LONGLONG repeat, offset, tunused = 0, toverlap = 0; char *buffer, message[81]; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if ( fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header to make sure everything is up to date */ else if ( ffrdef(fptr, status) > 0) return(*status); if (valid) *valid = TRUE; if (heapsz) *heapsz = (fptr->Fptr)->heapsize; if (unused) *unused = 0; if (overlap) *overlap = 0; /* return if this is not a binary table HDU or if the heap is empty */ if ( (fptr->Fptr)->hdutype != BINARY_TBL || (fptr->Fptr)->heapsize == 0 ) return(*status); if ((fptr->Fptr)->heapsize > LONG_MAX) { ffpmsg("Heap is too big to test ( > 2**31 bytes). (fftheap)"); return(*status = MEMORY_ALLOCATION); } theapsz = (long) (fptr->Fptr)->heapsize; buffer = calloc(1, theapsz); /* allocate temp space */ if (!buffer ) { sprintf(message,"Failed to allocate buffer to test the heap"); ffpmsg(message); return(*status = MEMORY_ALLOCATION); } /* loop over all cols */ for (jj = 1; jj <= (fptr->Fptr)->tfield && *status <= 0; jj++) { ffgtcl(fptr, jj, &typecode, NULL, NULL, status); if (typecode > 0) continue; /* ignore fixed length columns */ pixsize = -typecode / 10; for (ii = 1; ii <= (fptr->Fptr)->numrows; ii++) { ffgdesll(fptr, jj, ii, &repeat, &offset, status); if (typecode == -TBIT) nbytes = (long) (repeat + 7) / 8; else nbytes = (long) repeat * pixsize; if (offset < 0 || offset + nbytes > theapsz) { if (valid) *valid = FALSE; /* address out of bounds */ sprintf(message, "Descriptor in row %ld, column %d has invalid heap address", ii, jj); ffpmsg(message); } else { for (kk = 0; kk < nbytes; kk++) buffer[kk + offset]++; /* increment every used byte */ } } } for (kk = 0; kk < theapsz; kk++) { if (buffer[kk] == 0) tunused++; else if (buffer[kk] > 1) toverlap++; } if (heapsz) *heapsz = theapsz; if (unused) *unused = tunused; if (overlap) *overlap = toverlap; free(buffer); return(*status); } /*--------------------------------------------------------------------------*/ int ffcmph(fitsfile *fptr, /* I -FITS file pointer */ int *status) /* IO - error status */ /* compress the binary table heap by reordering the contents heap and recovering any unused space */ { fitsfile *tptr; int jj, typecode, pixsize, valid; long ii, buffsize = 10000, nblock, nbytes; LONGLONG unused, overlap; LONGLONG repeat, offset; char *buffer, *tbuff = 0, comm[FLEN_COMMENT]; char message[81]; LONGLONG pcount; LONGLONG readheapstart, writeheapstart, endpos, t1heapsize, t2heapsize; if (*status > 0) return(*status); /* get information about the current heap */ fftheap(fptr, NULL, &unused, &overlap, &valid, status); if (!valid) return(*status = BAD_HEAP_PTR); /* bad heap pointers */ /* return if this is not a binary table HDU or if the heap is OK as is */ if ( (fptr->Fptr)->hdutype != BINARY_TBL || (fptr->Fptr)->heapsize == 0 || (unused == 0 && overlap == 0) || *status > 0 ) return(*status); /* copy the current HDU to a temporary file in memory */ if (ffinit( &tptr, "mem://tempheapfile", status) ) { sprintf(message,"Failed to create temporary file for the heap"); ffpmsg(message); return(*status); } if ( ffcopy(fptr, tptr, 0, status) ) { sprintf(message,"Failed to create copy of the heap"); ffpmsg(message); ffclos(tptr, status); return(*status); } buffer = (char *) malloc(buffsize); /* allocate initial buffer */ if (!buffer) { sprintf(message,"Failed to allocate buffer to copy the heap"); ffpmsg(message); ffclos(tptr, status); return(*status = MEMORY_ALLOCATION); } readheapstart = (tptr->Fptr)->datastart + (tptr->Fptr)->heapstart; writeheapstart = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart; t1heapsize = (fptr->Fptr)->heapsize; /* save original heap size */ (fptr->Fptr)->heapsize = 0; /* reset heap to zero */ /* loop over all cols */ for (jj = 1; jj <= (fptr->Fptr)->tfield && *status <= 0; jj++) { ffgtcl(tptr, jj, &typecode, NULL, NULL, status); if (typecode > 0) continue; /* ignore fixed length columns */ pixsize = -typecode / 10; /* copy heap data, row by row */ for (ii = 1; ii <= (fptr->Fptr)->numrows; ii++) { ffgdesll(tptr, jj, ii, &repeat, &offset, status); if (typecode == -TBIT) nbytes = (long) (repeat + 7) / 8; else nbytes = (long) repeat * pixsize; /* increase size of buffer if necessary to read whole array */ if (nbytes > buffsize) { tbuff = realloc(buffer, nbytes); if (tbuff) { buffer = tbuff; buffsize = nbytes; } else *status = MEMORY_ALLOCATION; } /* If this is not the last HDU in the file, then check if */ /* extending the heap would overwrite the following header. */ /* If so, then have to insert more blocks. */ if ( !((fptr->Fptr)->lasthdu) ) { endpos = writeheapstart + (fptr->Fptr)->heapsize + nbytes; if (endpos > (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1]) { /* calc the number of blocks that need to be added */ nblock = (long) (((endpos - 1 - (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] ) / 2880) + 1); if (ffiblk(fptr, nblock, 1, status) > 0) /* insert blocks */ { sprintf(message, "Failed to extend the size of the variable length heap by %ld blocks.", nblock); ffpmsg(message); } } } /* read arrray of bytes from temporary copy */ ffmbyt(tptr, readheapstart + offset, REPORT_EOF, status); ffgbyt(tptr, nbytes, buffer, status); /* write arrray of bytes back to original file */ ffmbyt(fptr, writeheapstart + (fptr->Fptr)->heapsize, IGNORE_EOF, status); ffpbyt(fptr, nbytes, buffer, status); /* write descriptor */ ffpdes(fptr, jj, ii, repeat, (fptr->Fptr)->heapsize, status); (fptr->Fptr)->heapsize += nbytes; /* update heapsize */ if (*status > 0) { free(buffer); ffclos(tptr, status); return(*status); } } } free(buffer); ffclos(tptr, status); /* delete any empty blocks at the end of the HDU */ nblock = (long) (( (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] - (writeheapstart + (fptr->Fptr)->heapsize) ) / 2880); if (nblock > 0) { t2heapsize = (fptr->Fptr)->heapsize; /* save new heap size */ (fptr->Fptr)->heapsize = t1heapsize; /* restore original heap size */ ffdblk(fptr, nblock, status); (fptr->Fptr)->heapsize = t2heapsize; /* reset correct heap size */ } /* update the PCOUNT value (size of heap) */ ffgkyjj(fptr, "PCOUNT", &pcount, comm, status); if ((fptr->Fptr)->heapsize != pcount) { ffmkyj(fptr, "PCOUNT", (fptr->Fptr)->heapsize, comm, status); } ffrdef(fptr, status); /* rescan new HDU structure */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgdes(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number (1 = 1st column of table) */ LONGLONG rownum, /* I - row number (1 = 1st row of table) */ long *length, /* O - number of elements in the row */ long *heapaddr, /* O - heap pointer to the data */ int *status) /* IO - error status */ /* get (read) the variable length vector descriptor from the table. */ { LONGLONG lengthjj, heapaddrjj; if (ffgdesll(fptr, colnum, rownum, &lengthjj, &heapaddrjj, status) > 0) return(*status); /* convert the temporary 8-byte values to 4-byte values */ /* check for overflow */ if (length) { if (lengthjj > LONG_MAX) *status = NUM_OVERFLOW; else *length = (long) lengthjj; } if (heapaddr) { if (heapaddrjj > LONG_MAX) *status = NUM_OVERFLOW; else *heapaddr = (long) heapaddrjj; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgdesll(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number (1 = 1st column of table) */ LONGLONG rownum, /* I - row number (1 = 1st row of table) */ LONGLONG *length, /* O - number of elements in the row */ LONGLONG *heapaddr, /* O - heap pointer to the data */ int *status) /* IO - error status */ /* get (read) the variable length vector descriptor from the binary table. This is similar to ffgdes, except it supports the full 8-byte range of the length and offset values in 'Q' columns, as well as 'P' columns. */ { LONGLONG bytepos; unsigned int descript4[2] = {0,0}; LONGLONG descript8[2] = {0,0}; tcolumn *colptr; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); colptr = (fptr->Fptr)->tableptr; /* point to first column structure */ colptr += (colnum - 1); /* offset to the correct column */ if (colptr->tdatatype >= 0) { *status = NOT_VARI_LEN; return(*status); } bytepos = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * (rownum - 1)) + colptr->tbcol; if (colptr->tform[0] == 'P' || colptr->tform[1] == 'P') { /* read 4-byte descriptor */ if (ffgi4b(fptr, bytepos, 2, 4, (INT32BIT *) descript4, status) <= 0) { if (length) *length = (LONGLONG) descript4[0]; /* 1st word is the length */ if (heapaddr) *heapaddr = (LONGLONG) descript4[1]; /* 2nd word is the address */ } } else /* this is for 'Q' columns */ { /* read 8 byte descriptor */ if (ffgi8b(fptr, bytepos, 2, 8, (long *) descript8, status) <= 0) { if (length) *length = descript8[0]; /* 1st word is the length */ if (heapaddr) *heapaddr = descript8[1]; /* 2nd word is the address */ } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgdess(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number (1 = 1st column of table) */ LONGLONG firstrow, /* I - first row (1 = 1st row of table) */ LONGLONG nrows, /* I - number or rows to read */ long *length, /* O - number of elements in the row */ long *heapaddr, /* O - heap pointer to the data */ int *status) /* IO - error status */ /* get (read) a range of variable length vector descriptors from the table. */ { LONGLONG rowsize, bytepos; long ii; INT32BIT descript4[2] = {0,0}; LONGLONG descript8[2] = {0,0}; tcolumn *colptr; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); colptr = (fptr->Fptr)->tableptr; /* point to first column structure */ colptr += (colnum - 1); /* offset to the correct column */ if (colptr->tdatatype >= 0) { *status = NOT_VARI_LEN; return(*status); } rowsize = (fptr->Fptr)->rowlength; bytepos = (fptr->Fptr)->datastart + (rowsize * (firstrow - 1)) + colptr->tbcol; if (colptr->tform[0] == 'P' || colptr->tform[1] == 'P') { /* read 4-byte descriptors */ for (ii = 0; ii < nrows; ii++) { /* read descriptors */ if (ffgi4b(fptr, bytepos, 2, 4, descript4, status) <= 0) { if (length) { *length = (long) descript4[0]; /* 1st word is the length */ length++; } if (heapaddr) { *heapaddr = (long) descript4[1]; /* 2nd word is the address */ heapaddr++; } bytepos += rowsize; } else return(*status); } } else /* this is for 'Q' columns */ { /* read 8-byte descriptors */ for (ii = 0; ii < nrows; ii++) { /* read descriptors */ if (ffgi8b(fptr, bytepos, 2, 8, (long *) descript8, status) <= 0) { if (length) { if (descript8[0] > LONG_MAX)*status = NUM_OVERFLOW; *length = (long) descript8[0]; /* 1st word is the length */ length++; } if (heapaddr) { if (descript8[1] > LONG_MAX)*status = NUM_OVERFLOW; *heapaddr = (long) descript8[1]; /* 2nd word is the address */ heapaddr++; } bytepos += rowsize; } else return(*status); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgdessll(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number (1 = 1st column of table) */ LONGLONG firstrow, /* I - first row (1 = 1st row of table) */ LONGLONG nrows, /* I - number or rows to read */ LONGLONG *length, /* O - number of elements in the row */ LONGLONG *heapaddr, /* O - heap pointer to the data */ int *status) /* IO - error status */ /* get (read) a range of variable length vector descriptors from the table. */ { LONGLONG rowsize, bytepos; long ii; unsigned int descript4[2] = {0,0}; LONGLONG descript8[2] = {0,0}; tcolumn *colptr; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); colptr = (fptr->Fptr)->tableptr; /* point to first column structure */ colptr += (colnum - 1); /* offset to the correct column */ if (colptr->tdatatype >= 0) { *status = NOT_VARI_LEN; return(*status); } rowsize = (fptr->Fptr)->rowlength; bytepos = (fptr->Fptr)->datastart + (rowsize * (firstrow - 1)) + colptr->tbcol; if (colptr->tform[0] == 'P' || colptr->tform[1] == 'P') { /* read 4-byte descriptors */ for (ii = 0; ii < nrows; ii++) { /* read descriptors */ if (ffgi4b(fptr, bytepos, 2, 4, (INT32BIT *) descript4, status) <= 0) { if (length) { *length = (LONGLONG) descript4[0]; /* 1st word is the length */ length++; } if (heapaddr) { *heapaddr = (LONGLONG) descript4[1]; /* 2nd word is the address */ heapaddr++; } bytepos += rowsize; } else return(*status); } } else /* this is for 'Q' columns */ { /* read 8-byte descriptors */ for (ii = 0; ii < nrows; ii++) { /* read descriptors */ /* cast to type (long *) even though it is actually (LONGLONG *) */ if (ffgi8b(fptr, bytepos, 2, 8, (long *) descript8, status) <= 0) { if (length) { *length = descript8[0]; /* 1st word is the length */ length++; } if (heapaddr) { *heapaddr = descript8[1]; /* 2nd word is the address */ heapaddr++; } bytepos += rowsize; } else return(*status); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffpdes(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number (1 = 1st column of table) */ LONGLONG rownum, /* I - row number (1 = 1st row of table) */ LONGLONG length, /* I - number of elements in the row */ LONGLONG heapaddr, /* I - heap pointer to the data */ int *status) /* IO - error status */ /* put (write) the variable length vector descriptor to the table. */ { LONGLONG bytepos; unsigned int descript4[2]; LONGLONG descript8[2]; tcolumn *colptr; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); colptr = (fptr->Fptr)->tableptr; /* point to first column structure */ colptr += (colnum - 1); /* offset to the correct column */ if (colptr->tdatatype >= 0) *status = NOT_VARI_LEN; bytepos = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * (rownum - 1)) + colptr->tbcol; ffmbyt(fptr, bytepos, IGNORE_EOF, status); /* move to element */ if (colptr->tform[0] == 'P' || colptr->tform[1] == 'P') { if (length > UINT_MAX || length < 0 || heapaddr > UINT_MAX || heapaddr < 0) { ffpmsg("P variable length column descriptor is out of range"); *status = NUM_OVERFLOW; return(*status); } descript4[0] = (unsigned int) length; /* 1st word is the length */ descript4[1] = (unsigned int) heapaddr; /* 2nd word is the address */ ffpi4b(fptr, 2, 4, (INT32BIT *) descript4, status); /* write the descriptor */ } else /* this is a 'Q' descriptor column */ { descript8[0] = length; /* 1st word is the length */ descript8[1] = heapaddr; /* 2nd word is the address */ ffpi8b(fptr, 2, 8, (long *) descript8, status); /* write the descriptor */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffchdu(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ { /* close the current HDU. If we have write access to the file, then: - write the END keyword and pad header with blanks if necessary - check the data fill values, and rewrite them if not correct */ char message[FLEN_ERRMSG]; /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* no need to do any further updating of the HDU */ } else if ((fptr->Fptr)->writemode == 1) { ffrdef(fptr, status); /* scan header to redefine structure */ if ((fptr->Fptr)->heapsize > 0) ffuptf(fptr, status); /* update the variable length TFORM values */ ffpdfl(fptr, status); /* insure correct data file values */ } if ((fptr->Fptr)->open_count == 1) { /* free memory for the CHDU structure only if no other files are using it */ if ((fptr->Fptr)->tableptr) { free((fptr->Fptr)->tableptr); (fptr->Fptr)->tableptr = NULL; } } if (*status > 0 && *status != NO_CLOSE_ERROR) { sprintf(message, "Error while closing HDU number %d (ffchdu).", (fptr->Fptr)->curhdu); ffpmsg(message); } return(*status); } /*--------------------------------------------------------------------------*/ int ffuptf(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Update the value of the TFORM keywords for the variable length array columns to make sure they all have the form 1Px(len) or Px(len) where 'len' is the maximum length of the vector in the table (e.g., '1PE(400)') */ { int ii; long tflds; LONGLONG length, addr, maxlen, naxis2, jj; char comment[FLEN_COMMENT], keyname[FLEN_KEYWORD]; char tform[FLEN_VALUE], newform[FLEN_VALUE], lenval[40]; char card[FLEN_CARD]; char message[FLEN_ERRMSG]; ffgkyj(fptr, "TFIELDS", &tflds, comment, status); ffgkyjj(fptr, "NAXIS2", &naxis2, comment, status); for (ii = 1; ii <= tflds; ii++) /* loop over all the columns */ { ffkeyn("TFORM", ii, keyname, status); /* construct name */ if (ffgkys(fptr, keyname, tform, comment, status) > 0) { sprintf(message, "Error while updating variable length vector TFORMn values (ffuptf)."); ffpmsg(message); return(*status); } /* is this a variable array length column ? */ if (tform[0] == 'P' || tform[1] == 'P' || tform[0] == 'Q' || tform[1] == 'Q') { if (strlen(tform) < 5) /* is maxlen field missing? */ { /* get the max length */ maxlen = 0; for (jj=1; jj <= naxis2; jj++) { ffgdesll(fptr, ii, jj, &length, &addr, status); if (length > maxlen) maxlen = length; } /* construct the new keyword value */ strcpy(newform, "'"); strcat(newform, tform); /* print as double, because the string-to-64-bit */ /* conversion is platform dependent (%lld, %ld, %I64d) */ sprintf(lenval, "(%.0f)", (double) maxlen); strcat(newform,lenval); while(strlen(newform) < 9) strcat(newform," "); /* append spaces 'till length = 8 */ strcat(newform,"'" ); /* append closing parenthesis */ /* would be simpler to just call ffmkyj here, but this */ /* would force linking in all the modkey & putkey routines */ ffmkky(keyname, newform, comment, card, status); /* make new card */ ffmkey(fptr, card, status); /* replace last read keyword */ } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffrdef(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* ReDEFine the structure of a data unit. This routine re-reads the CHDU header keywords to determine the structure and length of the current data unit. This redefines the start of the next HDU. */ { int dummy, tstatus = 0; LONGLONG naxis2; LONGLONG pcount; char card[FLEN_CARD], comm[FLEN_COMMENT], valstring[FLEN_VALUE]; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->writemode == 1) /* write access to the file? */ { /* don't need to check NAXIS2 and PCOUNT if data hasn't been written */ if ((fptr->Fptr)->datastart != DATA_UNDEFINED) { /* update NAXIS2 keyword if more rows were written to the table */ /* and if the user has not explicitly reset the NAXIS2 value */ if ((fptr->Fptr)->hdutype != IMAGE_HDU) { if (ffgkyjj(fptr, "NAXIS2", &naxis2, comm, &tstatus) > 0) { /* Couldn't read NAXIS2 (odd!); in certain circumstances */ /* this may be normal, so ignore the error. */ naxis2 = (fptr->Fptr)->numrows; } if ((fptr->Fptr)->numrows > naxis2 && (fptr->Fptr)->origrows == naxis2) /* if origrows is not equal to naxis2, then the user must */ /* have manually modified the NAXIS2 keyword value, and */ /* we will assume that the current value is correct. */ { /* would be simpler to just call ffmkyj here, but this */ /* would force linking in all the modkey & putkey routines */ /* print as double because the 64-bit int conversion */ /* is platform dependent (%lld, %ld, %I64 ) */ sprintf(valstring, "%.0f", (double) ((fptr->Fptr)->numrows)); ffmkky("NAXIS2", valstring, comm, card, status); ffmkey(fptr, card, status); } } /* if data has been written to variable length columns in a */ /* binary table, then we may need to update the PCOUNT value */ if ((fptr->Fptr)->heapsize > 0) { ffgkyjj(fptr, "PCOUNT", &pcount, comm, status); if ((fptr->Fptr)->heapsize > pcount) { ffmkyj(fptr, "PCOUNT", (fptr->Fptr)->heapsize, comm, status); } } } if (ffwend(fptr, status) <= 0) /* rewrite END keyword and fill */ { ffrhdu(fptr, &dummy, status); /* re-scan the header keywords */ } } return(*status); } /*--------------------------------------------------------------------------*/ int ffhdef(fitsfile *fptr, /* I - FITS file pointer */ int morekeys, /* I - reserve space for this many keywords */ int *status) /* IO - error status */ /* based on the number of keywords which have already been written, plus the number of keywords to reserve space for, we then can define where the data unit should start (it must start at the beginning of a 2880-byte logical block). This routine will only have any effect if the starting location of the data unit following the header is not already defined. In any case, it is always possible to add more keywords to the header even if the data has already been written. It is just more efficient to reserve the space in advance. */ { LONGLONG delta; if (*status > 0 || morekeys < 1) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { ffrdef(fptr, status); /* ffrdef defines the offset to datastart and the start of */ /* the next HDU based on the number of existing keywords. */ /* We need to increment both of these values based on */ /* the number of new keywords to be added. */ delta = (((fptr->Fptr)->headend + (morekeys * 80)) / 2880 + 1) * 2880 - (fptr->Fptr)->datastart; (fptr->Fptr)->datastart += delta; (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] += delta; } return(*status); } /*--------------------------------------------------------------------------*/ int ffwend(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* write the END card and following fill (space chars) in the current header */ { int ii, tstatus; LONGLONG endpos; long nspace; char blankkey[FLEN_CARD], endkey[FLEN_CARD], keyrec[FLEN_CARD]; if (*status > 0) return(*status); endpos = (fptr->Fptr)->headend; /* we assume that the HDUposition == curhdu in all cases */ /* calc the data starting position if not currently defined */ if ((fptr->Fptr)->datastart == DATA_UNDEFINED) (fptr->Fptr)->datastart = ( endpos / 2880 + 1 ) * 2880; /* calculate the number of blank keyword slots in the header */ nspace = (long) (( (fptr->Fptr)->datastart - endpos ) / 80); /* construct a blank and END keyword (80 spaces ) */ strcpy(blankkey, " "); strcat(blankkey, " "); strcpy(endkey, "END "); strcat(endkey, " "); /* check if header is already correctly terminated with END and fill */ tstatus=0; ffmbyt(fptr, endpos, REPORT_EOF, &tstatus); /* move to header end */ for (ii=0; ii < nspace; ii++) { ffgbyt(fptr, 80, keyrec, &tstatus); /* get next keyword */ if (strncmp(keyrec, blankkey, 80) && strncmp(keyrec, endkey, 80)) break; } if (ii == nspace && !tstatus) { /* check if the END keyword exists at the correct position */ endpos=maxvalue( endpos, ( (fptr->Fptr)->datastart - 2880 ) ); ffmbyt(fptr, endpos, REPORT_EOF, &tstatus); /* move to END position */ ffgbyt(fptr, 80, keyrec, &tstatus); /* read the END keyword */ if ( !strncmp(keyrec, endkey, 80) && !tstatus) return(*status); /* END card was already correct */ } /* header was not correctly terminated, so write the END and blank fill */ endpos = (fptr->Fptr)->headend; ffmbyt(fptr, endpos, IGNORE_EOF, status); /* move to header end */ for (ii=0; ii < nspace; ii++) ffpbyt(fptr, 80, blankkey, status); /* write the blank keywords */ /* The END keyword must either be placed immediately after the last keyword that was written (as indicated by the headend value), or must be in the first 80 bytes of the 2880-byte FITS record immediately preceeding the data unit, whichever is further in the file. The latter will occur if space has been reserved for more header keywords which have not yet been written. */ endpos=maxvalue( endpos, ( (fptr->Fptr)->datastart - 2880 ) ); ffmbyt(fptr, endpos, REPORT_EOF, status); /* move to END position */ ffpbyt(fptr, 80, endkey, status); /* write the END keyword to header */ if (*status > 0) ffpmsg("Error while writing END card (ffwend)."); return(*status); } /*--------------------------------------------------------------------------*/ int ffpdfl(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Write the Data Unit Fill values if they are not already correct. The fill values are used to fill out the last 2880 byte block of the HDU. Fill the data unit with zeros or blanks depending on the type of HDU from the end of the data to the end of the current FITS 2880 byte block */ { char chfill, fill[2880]; LONGLONG fillstart; int nfill, tstatus, ii; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) return(*status); /* fill has already been correctly written */ if ((fptr->Fptr)->heapstart == 0) return(*status); /* null data unit, so there is no fill */ fillstart = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; nfill = (long) ((fillstart + 2879) / 2880 * 2880 - fillstart); if ((fptr->Fptr)->hdutype == ASCII_TBL) chfill = 32; /* ASCII tables are filled with spaces */ else chfill = 0; /* all other extensions are filled with zeros */ tstatus = 0; if (!nfill) /* no fill bytes; just check that entire table exists */ { fillstart--; nfill = 1; ffmbyt(fptr, fillstart, REPORT_EOF, &tstatus); /* move to last byte */ ffgbyt(fptr, nfill, fill, &tstatus); /* get the last byte */ if (tstatus == 0) return(*status); /* no EOF error, so everything is OK */ } else { ffmbyt(fptr, fillstart, REPORT_EOF, &tstatus); /* move to fill area */ ffgbyt(fptr, nfill, fill, &tstatus); /* get the fill bytes */ if (tstatus == 0) { for (ii = 0; ii < nfill; ii++) { if (fill[ii] != chfill) break; } if (ii == nfill) return(*status); /* all the fill values were correct */ } } /* fill values are incorrect or have not been written, so write them */ memset(fill, chfill, nfill); /* fill the buffer with the fill value */ ffmbyt(fptr, fillstart, IGNORE_EOF, status); /* move to fill area */ ffpbyt(fptr, nfill, fill, status); /* write the fill bytes */ if (*status > 0) ffpmsg("Error writing Data Unit fill bytes (ffpdfl)."); return(*status); } /********************************************************************** ffchfl : Check Header Fill values Check that the header unit is correctly filled with blanks from the END card to the end of the current FITS 2880-byte block Function parameters: fptr Fits file pointer status output error status Translated ftchfl into C by Peter Wilson, Oct. 1997 **********************************************************************/ int ffchfl( fitsfile *fptr, int *status) { int nblank,i,gotend; LONGLONG endpos; char rec[FLEN_CARD]; char *blanks=" "; /* 80 spaces */ if( *status > 0 ) return (*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* calculate the number of blank keyword slots in the header */ endpos=(fptr->Fptr)->headend; nblank=(long) (((fptr->Fptr)->datastart-endpos)/80); /* move the i/o pointer to the end of the header keywords */ ffmbyt(fptr,endpos,TRUE,status); /* find the END card (there may be blank keywords perceeding it) */ gotend=FALSE; for(i=0;i 0 ) { rec[FLEN_CARD - 1] = '\0'; /* make sure string is null terminated */ ffpmsg(rec); return( *status ); } } return( *status ); } /********************************************************************** ffcdfl : Check Data Unit Fill values Check that the data unit is correctly filled with zeros or blanks from the end of the data to the end of the current FITS 2880 byte block Function parameters: fptr Fits file pointer status output error status Translated ftcdfl into C by Peter Wilson, Oct. 1997 **********************************************************************/ int ffcdfl( fitsfile *fptr, int *status) { int nfill,i; LONGLONG filpos; char chfill,chbuff[2880]; if( *status > 0 ) return( *status ); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* check if the data unit is null */ if( (fptr->Fptr)->heapstart==0 ) return( *status ); /* calculate starting position of the fill bytes, if any */ filpos = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; /* calculate the number of fill bytes */ nfill = (long) ((filpos + 2879) / 2880 * 2880 - filpos); if( nfill == 0 ) return( *status ); /* move to the beginning of the fill bytes */ ffmbyt(fptr, filpos, FALSE, status); if( ffgbyt(fptr, nfill, chbuff, status) > 0) { ffpmsg("Error reading data unit fill bytes (ffcdfl)."); return( *status ); } if( (fptr->Fptr)->hdutype==ASCII_TBL ) chfill = 32; /* ASCII tables are filled with spaces */ else chfill = 0; /* all other extensions are filled with zeros */ /* check for all zeros or blanks */ for(i=0;iFptr)->hdutype==ASCII_TBL ) ffpmsg("Warning: remaining bytes following ASCII table data are not filled with blanks."); else ffpmsg("Warning: remaining bytes following data are not filled with zeros."); return( *status ); } } return( *status ); } /*--------------------------------------------------------------------------*/ int ffcrhd(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* CReate Header Data unit: Create, initialize, and move the i/o pointer to a new extension appended to the end of the FITS file. */ { int tstatus = 0; LONGLONG bytepos, *ptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* If the current header is empty, we don't have to do anything */ if ((fptr->Fptr)->headend == (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) return(*status); while (ffmrhd(fptr, 1, 0, &tstatus) == 0); /* move to end of file */ if ((fptr->Fptr)->maxhdu == (fptr->Fptr)->MAXHDU) { /* allocate more space for the headstart array */ ptr = (LONGLONG*) realloc( (fptr->Fptr)->headstart, ((fptr->Fptr)->MAXHDU + 1001) * sizeof(LONGLONG) ); if (ptr == NULL) return (*status = MEMORY_ALLOCATION); else { (fptr->Fptr)->MAXHDU = (fptr->Fptr)->MAXHDU + 1000; (fptr->Fptr)->headstart = ptr; } } if (ffchdu(fptr, status) <= 0) /* close the current HDU */ { bytepos = (fptr->Fptr)->headstart[(fptr->Fptr)->maxhdu + 1]; /* last */ ffmbyt(fptr, bytepos, IGNORE_EOF, status); /* move file ptr to it */ (fptr->Fptr)->maxhdu++; /* increment the known number of HDUs */ (fptr->Fptr)->curhdu = (fptr->Fptr)->maxhdu; /* set current HDU loc */ fptr->HDUposition = (fptr->Fptr)->maxhdu; /* set current HDU loc */ (fptr->Fptr)->nextkey = bytepos; /* next keyword = start of header */ (fptr->Fptr)->headend = bytepos; /* end of header */ (fptr->Fptr)->datastart = DATA_UNDEFINED; /* start data unit undefined */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffdblk(fitsfile *fptr, /* I - FITS file pointer */ long nblocks, /* I - number of 2880-byte blocks to delete */ int *status) /* IO - error status */ /* Delete the specified number of 2880-byte blocks from the end of the CHDU by shifting all following extensions up this number of blocks. */ { char buffer[2880]; int tstatus, ii; LONGLONG readpos, writepos; if (*status > 0 || nblocks <= 0) return(*status); tstatus = 0; /* pointers to the read and write positions */ readpos = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; readpos = ((readpos + 2879) / 2880) * 2880; /* start of block */ /* the following formula is wrong because the current data unit may have been extended without updating the headstart value of the following HDU. readpos = (fptr->Fptr)->headstart[((fptr->Fptr)->curhdu) + 1]; */ writepos = readpos - ((LONGLONG)nblocks * 2880); while ( !ffmbyt(fptr, readpos, REPORT_EOF, &tstatus) && !ffgbyt(fptr, 2880L, buffer, &tstatus) ) { ffmbyt(fptr, writepos, REPORT_EOF, status); ffpbyt(fptr, 2880L, buffer, status); if (*status > 0) { ffpmsg("Error deleting FITS blocks (ffdblk)"); return(*status); } readpos += 2880; /* increment to next block to transfer */ writepos += 2880; } /* now fill the last nblock blocks with zeros */ memset(buffer, 0, 2880); ffmbyt(fptr, writepos, REPORT_EOF, status); for (ii = 0; ii < nblocks; ii++) ffpbyt(fptr, 2880L, buffer, status); /* move back before the deleted blocks, since they may be deleted */ /* and we do not want to delete the current active buffer */ ffmbyt(fptr, writepos - 1, REPORT_EOF, status); /* truncate the file to the new size, if supported on this device */ fftrun(fptr, writepos, status); /* recalculate the starting location of all subsequent HDUs */ for (ii = (fptr->Fptr)->curhdu; ii <= (fptr->Fptr)->maxhdu; ii++) (fptr->Fptr)->headstart[ii + 1] -= ((LONGLONG)nblocks * 2880); return(*status); } /*--------------------------------------------------------------------------*/ int ffghdt(fitsfile *fptr, /* I - FITS file pointer */ int *exttype, /* O - type of extension, 0, 1, or 2 */ /* for IMAGE_HDU, ASCII_TBL, or BINARY_TBL */ int *status) /* IO - error status */ /* Return the type of the CHDU. This returns the 'logical' type of the HDU, not necessarily the physical type, so in the case of a compressed image stored in a binary table, this will return the type as an Image, not a binary table. */ { if (*status > 0) return(*status); if (fptr->HDUposition == 0 && (fptr->Fptr)->headend == 0) { /* empty primary array is alway an IMAGE_HDU */ *exttype = IMAGE_HDU; } else { /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { /* rescan header if data structure is undefined */ if ( ffrdef(fptr, status) > 0) return(*status); } *exttype = (fptr->Fptr)->hdutype; /* return the type of HDU */ /* check if this is a compressed image */ if ((fptr->Fptr)->compressimg) *exttype = IMAGE_HDU; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_is_compressed_image(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Returns TRUE if the CHDU is a compressed image, else returns zero. */ { if (*status > 0) return(0); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { /* rescan header if data structure is undefined */ if ( ffrdef(fptr, status) > 0) return(*status); } /* check if this is a compressed image */ if ((fptr->Fptr)->compressimg) return(1); return(0); } /*--------------------------------------------------------------------------*/ int ffgipr(fitsfile *infptr, /* I - FITS file pointer */ int maxaxis, /* I - max number of axes to return */ int *bitpix, /* O - image data type */ int *naxis, /* O - image dimension (NAXIS value) */ long *naxes, /* O - size of image dimensions */ int *status) /* IO - error status */ /* get the datatype and size of the input image */ { if (*status > 0) return(*status); /* don't return the parameter if a null pointer was given */ if (bitpix) fits_get_img_type(infptr, bitpix, status); /* get BITPIX value */ if (naxis) fits_get_img_dim(infptr, naxis, status); /* get NAXIS value */ if (naxes) fits_get_img_size(infptr, maxaxis, naxes, status); /* get NAXISn values */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgiprll(fitsfile *infptr, /* I - FITS file pointer */ int maxaxis, /* I - max number of axes to return */ int *bitpix, /* O - image data type */ int *naxis, /* O - image dimension (NAXIS value) */ LONGLONG *naxes, /* O - size of image dimensions */ int *status) /* IO - error status */ /* get the datatype and size of the input image */ { if (*status > 0) return(*status); /* don't return the parameter if a null pointer was given */ if (bitpix) fits_get_img_type(infptr, bitpix, status); /* get BITPIX value */ if (naxis) fits_get_img_dim(infptr, naxis, status); /* get NAXIS value */ if (naxes) fits_get_img_sizell(infptr, maxaxis, naxes, status); /* get NAXISn values */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgidt( fitsfile *fptr, /* I - FITS file pointer */ int *imgtype, /* O - image data type */ int *status) /* IO - error status */ /* Get the datatype of the image (= BITPIX keyword for normal image, or ZBITPIX for a compressed image) */ { if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffgky(fptr, TINT, "BITPIX", imgtype, NULL, status); } else if ((fptr->Fptr)->compressimg) { /* this is a binary table containing a compressed image */ ffgky(fptr, TINT, "ZBITPIX", imgtype, NULL, status); } else { *status = NOT_IMAGE; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgiet( fitsfile *fptr, /* I - FITS file pointer */ int *imgtype, /* O - image data type */ int *status) /* IO - error status */ /* Get the effective datatype of the image (= BITPIX keyword for normal image, or ZBITPIX for a compressed image) */ { int tstatus; long lngscale = 1, lngzero = 0; double bscale, bzero, min_val, max_val; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffgky(fptr, TINT, "BITPIX", imgtype, NULL, status); tstatus = 0; ffgky(fptr, TDOUBLE, "BSCALE", &bscale, NULL, &tstatus); if (tstatus) bscale = 1.0; tstatus = 0; ffgky(fptr, TDOUBLE, "BZERO", &bzero, NULL, &tstatus); if (tstatus) bzero = 0.0; } else if ((fptr->Fptr)->compressimg) { /* this is a binary table containing a compressed image */ ffgky(fptr, TINT, "ZBITPIX", imgtype, NULL, status); } else { *status = NOT_IMAGE; return(*status); } /* check if the BSCALE and BZERO keywords are defined, which might change the effective datatype of the image */ tstatus = 0; ffgky(fptr, TDOUBLE, "BSCALE", &bscale, NULL, &tstatus); if (tstatus) bscale = 1.0; tstatus = 0; ffgky(fptr, TDOUBLE, "BZERO", &bzero, NULL, &tstatus); if (tstatus) bzero = 0.0; if (bscale == 1.0 && bzero == 0.0) /* no scaling */ return(*status); switch (*imgtype) { case BYTE_IMG: /* 8-bit image */ min_val = 0.; max_val = 255.0; break; case SHORT_IMG: min_val = -32768.0; max_val = 32767.0; break; case LONG_IMG: min_val = -2147483648.0; max_val = 2147483647.0; break; default: /* don't have to deal with other data types */ return(*status); } if (bscale >= 0.) { min_val = bzero + bscale * min_val; max_val = bzero + bscale * max_val; } else { max_val = bzero + bscale * min_val; min_val = bzero + bscale * max_val; } if (bzero < 2147483648.) /* don't exceed range of 32-bit integer */ lngzero = (long) bzero; lngscale = (long) bscale; if ((bzero != 2147483648.) && /* special value that exceeds integer range */ (lngzero != bzero || lngscale != bscale)) { /* not integers? */ /* floating point scaled values; just decide on required precision */ if (*imgtype == BYTE_IMG || *imgtype == SHORT_IMG) *imgtype = FLOAT_IMG; else *imgtype = DOUBLE_IMG; /* In all the remaining cases, BSCALE and BZERO are integers, and not equal to 1 and 0, respectively. */ } else if ((min_val == -128.) && (max_val == 127.)) { *imgtype = SBYTE_IMG; } else if ((min_val >= -32768.0) && (max_val <= 32767.0)) { *imgtype = SHORT_IMG; } else if ((min_val >= 0.0) && (max_val <= 65535.0)) { *imgtype = USHORT_IMG; } else if ((min_val >= -2147483648.0) && (max_val <= 2147483647.0)) { *imgtype = LONG_IMG; } else if ((min_val >= 0.0) && (max_val < 4294967296.0)) { *imgtype = ULONG_IMG; } else { /* exceeds the range of a 32-bit integer */ *imgtype = DOUBLE_IMG; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgidm( fitsfile *fptr, /* I - FITS file pointer */ int *naxis , /* O - image dimension (NAXIS value) */ int *status) /* IO - error status */ /* Get the dimension of the image (= NAXIS keyword for normal image, or ZNAXIS for a compressed image) */ { if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffgky(fptr, TINT, "NAXIS", naxis, NULL, status); } else if ((fptr->Fptr)->compressimg) { /* this is a binary table containing a compressed image */ ffgky(fptr, TINT, "ZNAXIS", naxis, NULL, status); } else { *status = NOT_IMAGE; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgisz( fitsfile *fptr, /* I - FITS file pointer */ int nlen, /* I - number of axes to return */ long *naxes, /* O - size of image dimensions */ int *status) /* IO - error status */ /* Get the size of the image dimensions (= NAXISn keywords for normal image, or ZNAXISn for a compressed image) */ { int ii, naxis; char keyroot[FLEN_KEYWORD], keyname[FLEN_KEYWORD]; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { strcpy(keyroot, "NAXIS"); } else if ((fptr->Fptr)->compressimg) { /* this is a binary table containing a compressed image */ strcpy(keyroot, "ZNAXIS"); } else { return(*status = NOT_IMAGE); } /* initialize to 1 */ for (ii = 0; ii < nlen; ii++) naxes[ii] = 1; /* get number of dimensions */ fits_get_img_dim(fptr, &naxis, status); naxis = minvalue(naxis, nlen); for (ii = 0; ii < naxis; ii++) { ffkeyn(keyroot, ii + 1, keyname, status); ffgkyj(fptr, keyname, naxes + ii, NULL, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgiszll( fitsfile *fptr, /* I - FITS file pointer */ int nlen, /* I - number of axes to return */ LONGLONG *naxes, /* O - size of image dimensions */ int *status) /* IO - error status */ /* Get the size of the image dimensions (= NAXISn keywords for normal image, or ZNAXISn for a compressed image) */ { int ii, naxis; char keyroot[FLEN_KEYWORD], keyname[FLEN_KEYWORD]; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { strcpy(keyroot, "NAXIS"); } else if ((fptr->Fptr)->compressimg) { /* this is a binary table containing a compressed image */ strcpy(keyroot, "ZNAXIS"); } else { return(*status = NOT_IMAGE); } /* initialize to 1 */ for (ii = 0; ii < nlen; ii++) naxes[ii] = 1; /* get number of dimensions */ fits_get_img_dim(fptr, &naxis, status); naxis = minvalue(naxis, nlen); for (ii = 0; ii < naxis; ii++) { ffkeyn(keyroot, ii + 1, keyname, status); ffgkyjj(fptr, keyname, naxes + ii, NULL, status); } return(*status); }/*--------------------------------------------------------------------------*/ int ffmahd(fitsfile *fptr, /* I - FITS file pointer */ int hdunum, /* I - number of the HDU to move to */ int *exttype, /* O - type of extension, 0, 1, or 2 */ int *status) /* IO - error status */ /* Move to Absolute Header Data unit. Move to the specified HDU and read the header to initialize the table structure. Note that extnum is one based, so the primary array is extnum = 1. */ { int moveto, tstatus; char message[FLEN_ERRMSG]; LONGLONG *ptr; if (*status > 0) return(*status); else if (hdunum < 1 ) return(*status = BAD_HDU_NUM); else if (hdunum >= (fptr->Fptr)->MAXHDU ) { /* allocate more space for the headstart array */ ptr = (LONGLONG*) realloc( (fptr->Fptr)->headstart, (hdunum + 1001) * sizeof(LONGLONG) ); if (ptr == NULL) return (*status = MEMORY_ALLOCATION); else { (fptr->Fptr)->MAXHDU = hdunum + 1000; (fptr->Fptr)->headstart = ptr; } } /* set logical HDU position to the actual position, in case they differ */ fptr->HDUposition = (fptr->Fptr)->curhdu; while( ((fptr->Fptr)->curhdu) + 1 != hdunum) /* at the correct HDU? */ { /* move directly to the extension if we know that it exists, otherwise move to the highest known extension. */ moveto = minvalue(hdunum - 1, ((fptr->Fptr)->maxhdu) + 1); /* test if HDU exists */ if ((fptr->Fptr)->headstart[moveto] < (fptr->Fptr)->logfilesize ) { if (ffchdu(fptr, status) <= 0) /* close out the current HDU */ { if (ffgext(fptr, moveto, exttype, status) > 0) { /* failed to get the requested extension */ tstatus = 0; ffrhdu(fptr, exttype, &tstatus); /* restore the CHDU */ } } } else *status = END_OF_FILE; if (*status > 0) { if (*status != END_OF_FILE) { /* don't clutter up the message stack in the common case of */ /* simply hitting the end of file (often an expected error) */ sprintf(message, "Failed to move to HDU number %d (ffmahd).", hdunum); ffpmsg(message); } return(*status); } } /* return the type of HDU; tile compressed images which are stored */ /* in a binary table will return exttype = IMAGE_HDU, not BINARY_TBL */ if (exttype != NULL) ffghdt(fptr, exttype, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmrhd(fitsfile *fptr, /* I - FITS file pointer */ int hdumov, /* I - rel. no. of HDUs to move by (+ or -) */ int *exttype, /* O - type of extension, 0, 1, or 2 */ int *status) /* IO - error status */ /* Move a Relative number of Header Data units. Offset to the specified extension and read the header to initialize the HDU structure. */ { int extnum; if (*status > 0) return(*status); extnum = fptr->HDUposition + 1 + hdumov; /* the absolute HDU number */ ffmahd(fptr, extnum, exttype, status); /* move to the HDU */ return(*status); } /*--------------------------------------------------------------------------*/ int ffmnhd(fitsfile *fptr, /* I - FITS file pointer */ int exttype, /* I - desired extension type */ char *hduname, /* I - desired EXTNAME value for the HDU */ int hduver, /* I - desired EXTVERS value for the HDU */ int *status) /* IO - error status */ /* Move to the next HDU with a given extension type (IMAGE_HDU, ASCII_TBL, BINARY_TBL, or ANY_HDU), extension name (EXTNAME or HDUNAME keyword), and EXTVERS keyword values. If hduvers = 0, then move to the first HDU with the given type and name regardless of EXTVERS value. If no matching HDU is found in the file, then the current open HDU will remain unchanged. */ { char extname[FLEN_VALUE]; int ii, hdutype, alttype, extnum, tstatus, match, exact; long extver; if (*status > 0) return(*status); extnum = fptr->HDUposition + 1; /* save the current HDU number */ for (ii=1; 1; ii++) /* loop until EOF */ { tstatus = 0; if (ffmahd(fptr, ii, &hdutype, &tstatus)) /* move to next HDU */ { ffmahd(fptr, extnum, 0, status); /* restore file position */ return(*status = BAD_HDU_NUM); /* couldn't find desired HDU */ } alttype = -1; if (fits_is_compressed_image(fptr, status)) alttype = BINARY_TBL; /* matching type? */ if (exttype == ANY_HDU || hdutype == exttype || hdutype == alttype) { if (ffgkys(fptr, "EXTNAME", extname, 0, &tstatus) > 0) /* name */ { tstatus = 0; /* look for HDUNAME, since EXTNAME didn't exist */ ffgkys(fptr, "HDUNAME", extname, 0, &tstatus); } else { /* check if EXTNAME is the name we are looking for. */ /* If not, try reading the HDUNAME keyword. */ ffcmps(extname, hduname, CASEINSEN, &match, &exact); if (!exact) ffgkys(fptr, "HDUNAME", extname, 0, &tstatus); } if (tstatus <= 0) { ffcmps(extname, hduname, CASEINSEN, &match, &exact); if (exact) /* names match? */ { if (hduver) /* need to check if version numbers match? */ { if (ffgkyj(fptr, "EXTVER", &extver, 0, &tstatus) > 0) extver = 1; /* assume default EXTVER value */ if ( (int) extver == hduver) { return(*status); /* found matching name and vers */ } } else { return(*status); /* found matching name */ } } } } } } /*--------------------------------------------------------------------------*/ int ffthdu(fitsfile *fptr, /* I - FITS file pointer */ int *nhdu, /* O - number of HDUs in the file */ int *status) /* IO - error status */ /* Return the number of HDUs that currently exist in the file. */ { int ii, extnum, tstatus; if (*status > 0) return(*status); extnum = fptr->HDUposition + 1; /* save the current HDU number */ *nhdu = extnum - 1; /* if the CHDU is empty or not completely defined, just return */ if ((fptr->Fptr)->datastart == DATA_UNDEFINED) return(*status); tstatus = 0; /* loop until EOF */ for (ii=extnum; ffmahd(fptr, ii, 0, &tstatus) <= 0; ii++) { *nhdu = ii; } ffmahd(fptr, extnum, 0, status); /* restore orig file position */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgext(fitsfile *fptr, /* I - FITS file pointer */ int hdunum, /* I - no. of HDU to move get (0 based) */ int *exttype, /* O - type of extension, 0, 1, or 2 */ int *status) /* IO - error status */ /* Get Extension. Move to the specified extension and initialize the HDU structure. */ { int xcurhdu, xmaxhdu; LONGLONG xheadend; if (*status > 0) return(*status); if (ffmbyt(fptr, (fptr->Fptr)->headstart[hdunum], REPORT_EOF, status) <= 0) { /* temporarily save current values, in case of error */ xcurhdu = (fptr->Fptr)->curhdu; xmaxhdu = (fptr->Fptr)->maxhdu; xheadend = (fptr->Fptr)->headend; /* set new parameter values */ (fptr->Fptr)->curhdu = hdunum; fptr->HDUposition = hdunum; (fptr->Fptr)->maxhdu = maxvalue((fptr->Fptr)->maxhdu, hdunum); (fptr->Fptr)->headend = (fptr->Fptr)->logfilesize; /* set max size */ if (ffrhdu(fptr, exttype, status) > 0) { /* failed to get the new HDU, so restore previous values */ (fptr->Fptr)->curhdu = xcurhdu; fptr->HDUposition = xcurhdu; (fptr->Fptr)->maxhdu = xmaxhdu; (fptr->Fptr)->headend = xheadend; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffiblk(fitsfile *fptr, /* I - FITS file pointer */ long nblock, /* I - no. of blocks to insert */ int headdata, /* I - insert where? 0=header, 1=data */ /* -1=beginning of file */ int *status) /* IO - error status */ /* insert 2880-byte blocks at the end of the current header or data unit */ { int tstatus, savehdu, typhdu; LONGLONG insertpt, jpoint; long ii, nshift; char charfill; char buff1[2880], buff2[2880]; char *inbuff, *outbuff, *tmpbuff; char card[FLEN_CARD]; if (*status > 0 || nblock <= 0) return(*status); tstatus = *status; if (headdata == 0 || (fptr->Fptr)->hdutype == ASCII_TBL) charfill = 32; /* headers and ASCII tables have space (32) fill */ else charfill = 0; /* images and binary tables have zero fill */ if (headdata == 0) insertpt = (fptr->Fptr)->datastart; /* insert just before data, or */ else if (headdata == -1) { insertpt = 0; strcpy(card, "XTENSION= 'IMAGE ' / IMAGE extension"); } else /* at end of data, */ { insertpt = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; insertpt = ((insertpt + 2879) / 2880) * 2880; /* start of block */ /* the following formula is wrong because the current data unit may have been extended without updating the headstart value of the following HDU. */ /* insertpt = (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu + 1]; */ } inbuff = buff1; /* set pointers to input and output buffers */ outbuff = buff2; memset(outbuff, charfill, 2880); /* initialize buffer with fill */ if (nblock == 1) /* insert one block */ { if (headdata == -1) ffmrec(fptr, 1, card, status); /* change SIMPLE -> XTENSION */ ffmbyt(fptr, insertpt, REPORT_EOF, status); /* move to 1st point */ ffgbyt(fptr, 2880, inbuff, status); /* read first block of bytes */ while (*status <= 0) { ffmbyt(fptr, insertpt, REPORT_EOF, status); /* insert point */ ffpbyt(fptr, 2880, outbuff, status); /* write the output buffer */ if (*status > 0) return(*status); tmpbuff = inbuff; /* swap input and output pointers */ inbuff = outbuff; outbuff = tmpbuff; insertpt += 2880; /* increment insert point by 1 block */ ffmbyt(fptr, insertpt, REPORT_EOF, status); /* move to next block */ ffgbyt(fptr, 2880, inbuff, status); /* read block of bytes */ } *status = tstatus; /* reset status value */ ffmbyt(fptr, insertpt, IGNORE_EOF, status); /* move back to insert pt */ ffpbyt(fptr, 2880, outbuff, status); /* write the final block */ } else /* inserting more than 1 block */ { savehdu = (fptr->Fptr)->curhdu; /* save the current HDU number */ tstatus = *status; while(*status <= 0) /* find the last HDU in file */ ffmrhd(fptr, 1, &typhdu, status); if (*status == END_OF_FILE) { *status = tstatus; } ffmahd(fptr, savehdu + 1, &typhdu, status); /* move back to CHDU */ if (headdata == -1) ffmrec(fptr, 1, card, status); /* NOW change SIMPLE -> XTENSION */ /* number of 2880-byte blocks that have to be shifted down */ nshift = (long) (((fptr->Fptr)->headstart[(fptr->Fptr)->maxhdu + 1] - insertpt) / 2880); /* position of last block in file to be shifted */ jpoint = (fptr->Fptr)->headstart[(fptr->Fptr)->maxhdu + 1] - 2880; /* move all the blocks starting at end of file working backwards */ for (ii = 0; ii < nshift; ii++) { /* move to the read start position */ if (ffmbyt(fptr, jpoint, REPORT_EOF, status) > 0) return(*status); ffgbyt(fptr, 2880, inbuff,status); /* read one record */ /* move forward to the write postion */ ffmbyt(fptr, jpoint + (nblock * 2880), IGNORE_EOF, status); ffpbyt(fptr, 2880, inbuff, status); /* write the record */ jpoint -= 2880; } /* move back to the write start postion (might be EOF) */ ffmbyt(fptr, insertpt, IGNORE_EOF, status); for (ii = 0; ii < nblock; ii++) /* insert correct fill value */ ffpbyt(fptr, 2880, outbuff, status); } if (headdata == 0) /* update data start address */ (fptr->Fptr)->datastart += ((LONGLONG)nblock * 2880); /* update following HDU addresses */ for (ii = (fptr->Fptr)->curhdu; ii <= (fptr->Fptr)->maxhdu; ii++) (fptr->Fptr)->headstart[ii + 1] += ((LONGLONG)nblock * 2880); return(*status); } /*--------------------------------------------------------------------------*/ int ffgkcl(char *tcard) /* Return the type classification of the input header record TYP_STRUC_KEY: SIMPLE, BITPIX, NAXIS, NAXISn, EXTEND, BLOCKED, GROUPS, PCOUNT, GCOUNT, END XTENSION, TFIELDS, TTYPEn, TBCOLn, TFORMn, THEAP, and the first 4 COMMENT keywords in the primary array that define the FITS format. TYP_CMPRS_KEY: The experimental keywords used in the compressed image format ZIMAGE, ZCMPTYPE, ZNAMEn, ZVALn, ZTILEn, ZBITPIX, ZNAXISn, ZSCALE, ZZERO, ZBLANK, EXTNAME = 'COMPRESSED_IMAGE' ZSIMPLE, ZTENSION, ZEXTEND, ZBLOCKED, ZPCOUNT, ZGCOUNT TYP_SCAL_KEY: BSCALE, BZERO, TSCALn, TZEROn TYP_NULL_KEY: BLANK, TNULLn TYP_DIM_KEY: TDIMn TYP_RANG_KEY: TLMINn, TLMAXn, TDMINn, TDMAXn, DATAMIN, DATAMAX TYP_UNIT_KEY: BUNIT, TUNITn TYP_DISP_KEY: TDISPn TYP_HDUID_KEY: EXTNAME, EXTVER, EXTLEVEL, HDUNAME, HDUVER, HDULEVEL TYP_CKSUM_KEY CHECKSUM, DATASUM TYP_WCS_KEY: Primary array: WCAXES, CTYPEn, CUNITn, CRVALn, CRPIXn, CROTAn, CDELTn CDj_is, PVj_ms, LONPOLEs, LATPOLEs Pixel list: TCTYPn, TCTYns, TCUNIn, TCUNns, TCRVLn, TCRVns, TCRPXn, TCRPks, TCDn_k, TCn_ks, TPVn_m, TPn_ms, TCDLTn, TCROTn Bintable vector: jCTYPn, jCTYns, jCUNIn, jCUNns, jCRVLn, jCRVns, iCRPXn, iCRPns, jiCDn, jiCDns, jPVn_m, jPn_ms, jCDLTn, jCROTn TYP_REFSYS_KEY: EQUINOXs, EPOCH, MJD-OBSs, RADECSYS, RADESYSs TYP_COMM_KEY: COMMENT, HISTORY, (blank keyword) TYP_CONT_KEY: CONTINUE TYP_USER_KEY: all other keywords */ { char card[20], *card1, *card5; card[0] = '\0'; strncat(card, tcard, 8); /* copy the keyword name */ strcat(card, " "); /* append blanks to make at least 8 chars long */ ffupch(card); /* make sure it is in upper case */ card1 = card + 1; /* pointer to 2nd character */ card5 = card + 5; /* pointer to 6th character */ /* the strncmp function is slow, so try to be more efficient */ if (*card == 'Z') { if (FSTRNCMP (card1, "IMAGE ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "CMPTYPE", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "NAME", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_CMPRS_KEY); } else if (FSTRNCMP (card1, "VAL", 3) == 0) { if (*(card + 4) >= '0' && *(card + 4) <= '9') return (TYP_CMPRS_KEY); } else if (FSTRNCMP (card1, "TILE", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_CMPRS_KEY); } else if (FSTRNCMP (card1, "BITPIX ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "NAXIS", 5) == 0) { if ( ( *(card + 6) >= '0' && *(card + 6) <= '9' ) || (*(card + 6) == ' ') ) return (TYP_CMPRS_KEY); } else if (FSTRNCMP (card1, "SCALE ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "ZERO ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "BLANK ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "SIMPLE ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "TENSION", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "EXTEND ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "BLOCKED", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "PCOUNT ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "GCOUNT ", 7) == 0) return (TYP_CMPRS_KEY); } else if (*card == ' ') { return (TYP_COMM_KEY); } else if (*card == 'B') { if (FSTRNCMP (card1, "ITPIX ", 7) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (card1, "LOCKED ", 7) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (card1, "LANK ", 7) == 0) return (TYP_NULL_KEY); if (FSTRNCMP (card1, "SCALE ", 7) == 0) return (TYP_SCAL_KEY); if (FSTRNCMP (card1, "ZERO ", 7) == 0) return (TYP_SCAL_KEY); if (FSTRNCMP (card1, "UNIT ", 7) == 0) return (TYP_UNIT_KEY); } else if (*card == 'C') { if (FSTRNCMP (card1, "OMMENT",6) == 0) { /* new comment string starting Oct 2001 */ if (FSTRNCMP (tcard, "COMMENT and Astrophysics', volume 376, page 3", 47) == 0) return (TYP_STRUC_KEY); /* original COMMENT strings from 1993 - 2001 */ if (FSTRNCMP (tcard, "COMMENT FITS (Flexible Image Transport System", 47) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (tcard, "COMMENT Astrophysics Supplement Series v44/p3", 47) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (tcard, "COMMENT Contact the NASA Science Office of St", 47) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (tcard, "COMMENT FITS Definition document #100 and oth", 47) == 0) return (TYP_STRUC_KEY); if (*(card + 7) == ' ') return (TYP_COMM_KEY); else return (TYP_USER_KEY); } if (FSTRNCMP (card1, "HECKSUM", 7) == 0) return (TYP_CKSUM_KEY); if (FSTRNCMP (card1, "ONTINUE", 7) == 0) return (TYP_CONT_KEY); if (FSTRNCMP (card1, "TYPE",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "UNIT",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "RVAL",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "RPIX",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "ROTA",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "RDER",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "SYER",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "DELT",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (*card1 == 'D') { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } } else if (*card == 'D') { if (FSTRNCMP (card1, "ATASUM ", 7) == 0) return (TYP_CKSUM_KEY); if (FSTRNCMP (card1, "ATAMIN ", 7) == 0) return (TYP_RANG_KEY); if (FSTRNCMP (card1, "ATAMAX ", 7) == 0) return (TYP_RANG_KEY); if (FSTRNCMP (card1, "ATE-OBS", 7) == 0) return (TYP_REFSYS_KEY); } else if (*card == 'E') { if (FSTRNCMP (card1, "XTEND ", 7) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (card1, "ND ", 7) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (card1, "XTNAME ", 7) == 0) { /* check for special compressed image value */ if (FSTRNCMP(tcard, "EXTNAME = 'COMPRESSED_IMAGE'", 28) == 0) return (TYP_CMPRS_KEY); else return (TYP_HDUID_KEY); } if (FSTRNCMP (card1, "XTVER ", 7) == 0) return (TYP_HDUID_KEY); if (FSTRNCMP (card1, "XTLEVEL", 7) == 0) return (TYP_HDUID_KEY); if (FSTRNCMP (card1, "QUINOX", 6) == 0) return (TYP_REFSYS_KEY); if (FSTRNCMP (card1, "QUI",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_REFSYS_KEY); } if (FSTRNCMP (card1, "POCH ", 7) == 0) return (TYP_REFSYS_KEY); } else if (*card == 'G') { if (FSTRNCMP (card1, "COUNT ", 7) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (card1, "ROUPS ", 7) == 0) return (TYP_STRUC_KEY); } else if (*card == 'H') { if (FSTRNCMP (card1, "DUNAME ", 7) == 0) return (TYP_HDUID_KEY); if (FSTRNCMP (card1, "DUVER ", 7) == 0) return (TYP_HDUID_KEY); if (FSTRNCMP (card1, "DULEVEL", 7) == 0) return (TYP_HDUID_KEY); if (FSTRNCMP (card1, "ISTORY",6) == 0) { if (*(card + 7) == ' ') return (TYP_COMM_KEY); else return (TYP_USER_KEY); } } else if (*card == 'L') { if (FSTRNCMP (card1, "ONPOLE",6) == 0) return (TYP_WCS_KEY); if (FSTRNCMP (card1, "ATPOLE",6) == 0) return (TYP_WCS_KEY); if (FSTRNCMP (card1, "ONP",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "ATP",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } } else if (*card == 'M') { if (FSTRNCMP (card1, "JD-OBS ", 7) == 0) return (TYP_REFSYS_KEY); if (FSTRNCMP (card1, "JDOB",4) == 0) { if (*(card+5) >= '0' && *(card+5) <= '9') return (TYP_REFSYS_KEY); } } else if (*card == 'N') { if (FSTRNCMP (card1, "AXIS", 4) == 0) { if ((*card5 >= '0' && *card5 <= '9') || (*card5 == ' ')) return (TYP_STRUC_KEY); } } else if (*card == 'P') { if (FSTRNCMP (card1, "COUNT ", 7) == 0) return (TYP_STRUC_KEY); if (*card1 == 'C') { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } else if (*card1 == 'V') { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } else if (*card1 == 'S') { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } } else if (*card == 'R') { if (FSTRNCMP (card1, "ADECSYS", 7) == 0) return (TYP_REFSYS_KEY); if (FSTRNCMP (card1, "ADESYS", 6) == 0) return (TYP_REFSYS_KEY); if (FSTRNCMP (card1, "ADE",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_REFSYS_KEY); } } else if (*card == 'S') { if (FSTRNCMP (card1, "IMPLE ", 7) == 0) return (TYP_STRUC_KEY); } else if (*card == 'T') { if (FSTRNCMP (card1, "TYPE", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_STRUC_KEY); } else if (FSTRNCMP (card1, "FORM", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_STRUC_KEY); } else if (FSTRNCMP (card1, "BCOL", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_STRUC_KEY); } else if (FSTRNCMP (card1, "FIELDS ", 7) == 0) return (TYP_STRUC_KEY); else if (FSTRNCMP (card1, "HEAP ", 7) == 0) return (TYP_STRUC_KEY); else if (FSTRNCMP (card1, "NULL", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_NULL_KEY); } else if (FSTRNCMP (card1, "DIM", 3) == 0) { if (*(card + 4) >= '0' && *(card + 4) <= '9') return (TYP_DIM_KEY); } else if (FSTRNCMP (card1, "UNIT", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_UNIT_KEY); } else if (FSTRNCMP (card1, "DISP", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_DISP_KEY); } else if (FSTRNCMP (card1, "SCAL", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_SCAL_KEY); } else if (FSTRNCMP (card1, "ZERO", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_SCAL_KEY); } else if (FSTRNCMP (card1, "LMIN", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_RANG_KEY); } else if (FSTRNCMP (card1, "LMAX", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_RANG_KEY); } else if (FSTRNCMP (card1, "DMIN", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_RANG_KEY); } else if (FSTRNCMP (card1, "DMAX", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_RANG_KEY); } else if (FSTRNCMP (card1, "CTYP",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CTY",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CUNI",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CUN",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRVL",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRV",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRPX",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRP",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CROT",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CDLT",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CDE",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRD",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CSY",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "WCS",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "C",1) == 0) { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "P",1) == 0) { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "V",1) == 0) { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "S",1) == 0) { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } } else if (*card == 'X') { if (FSTRNCMP (card1, "TENSION", 7) == 0) return (TYP_STRUC_KEY); } else if (*card == 'W') { if (FSTRNCMP (card1, "CSAXES", 6) == 0) return (TYP_WCS_KEY); if (FSTRNCMP (card1, "CSNAME", 6) == 0) return (TYP_WCS_KEY); if (FSTRNCMP (card1, "CAX", 3) == 0) { if (*(card + 4) >= '0' && *(card + 4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CSN", 3) == 0) { if (*(card + 4) >= '0' && *(card + 4) <= '9') return (TYP_WCS_KEY); } } else if (*card >= '0' && *card <= '9') { if (*card1 == 'C') { if (FSTRNCMP (card1, "CTYP",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CTY",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CUNI",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CUN",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRVL",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRV",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRPX",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRP",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CROT",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CDLT",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CDE",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRD",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CSY",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } } else if (FSTRNCMP (card1, "V",1) == 0) { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "S",1) == 0) { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } else if (*card1 >= '0' && *card1 <= '9') { /* 2 digits at beginning of keyword */ if ( (*(card + 2) == 'P') && (*(card + 3) == 'C') ) { if (*(card + 4) >= '0' && *(card + 4) <= '9') return (TYP_WCS_KEY); /* ijPCn keyword */ } else if ( (*(card + 2) == 'C') && (*(card + 3) == 'D') ) { if (*(card + 4) >= '0' && *(card + 4) <= '9') return (TYP_WCS_KEY); /* ijCDn keyword */ } } } return (TYP_USER_KEY); /* by default all others are user keywords */ } /*--------------------------------------------------------------------------*/ int ffdtyp(char *cval, /* I - formatted string representation of the value */ char *dtype, /* O - datatype code: C, L, F, I, or X */ int *status) /* IO - error status */ /* determine implicit datatype of input string. This assumes that the string conforms to the FITS standard for keyword values, so may not detect all invalid formats. */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == '\0') return(*status = VALUE_UNDEFINED); else if (cval[0] == '\'') *dtype = 'C'; /* character string starts with a quote */ else if (cval[0] == 'T' || cval[0] == 'F') *dtype = 'L'; /* logical = T or F character */ else if (cval[0] == '(') *dtype = 'X'; /* complex datatype "(1.2, -3.4)" */ else if (strchr(cval,'.')) *dtype = 'F'; /* float usualy contains a decimal point */ else if (strchr(cval,'E') || strchr(cval,'D') ) *dtype = 'F'; /* exponential contains a E or D */ else *dtype = 'I'; /* if none of the above assume it is integer */ return(*status); } /*--------------------------------------------------------------------------*/ int ffc2x(char *cval, /* I - formatted string representation of the value */ char *dtype, /* O - datatype code: C, L, F, I or X */ /* Only one of the following will be defined, depending on datatype */ long *ival, /* O - integer value */ int *lval, /* O - logical value */ char *sval, /* O - string value */ double *dval, /* O - double value */ int *status) /* IO - error status */ /* high level routine to convert formatted character string to its intrinsic data type */ { ffdtyp(cval, dtype, status); /* determine the datatype */ if (*dtype == 'I') ffc2ii(cval, ival, status); else if (*dtype == 'F') ffc2dd(cval, dval, status); else if (*dtype == 'L') ffc2ll(cval, lval, status); else ffc2s(cval, sval, status); /* C and X formats */ return(*status); } /*--------------------------------------------------------------------------*/ int ffc2xx(char *cval, /* I - formatted string representation of the value */ char *dtype, /* O - datatype code: C, L, F, I or X */ /* Only one of the following will be defined, depending on datatype */ LONGLONG *ival, /* O - integer value */ int *lval, /* O - logical value */ char *sval, /* O - string value */ double *dval, /* O - double value */ int *status) /* IO - error status */ /* high level routine to convert formatted character string to its intrinsic data type */ { ffdtyp(cval, dtype, status); /* determine the datatype */ if (*dtype == 'I') ffc2jj(cval, ival, status); else if (*dtype == 'F') ffc2dd(cval, dval, status); else if (*dtype == 'L') ffc2ll(cval, lval, status); else ffc2s(cval, sval, status); /* C and X formats */ return(*status); } /*--------------------------------------------------------------------------*/ int ffc2i(char *cval, /* I - string representation of the value */ long *ival, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert formatted string to an integer value, doing implicit datatype conversion if necessary. */ { char dtype, sval[81], msg[81]; int lval; double dval; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == '\0') return(*status = VALUE_UNDEFINED); /* null value string */ /* convert the keyword to its native datatype */ ffc2x(cval, &dtype, ival, &lval, sval, &dval, status); if (dtype == 'X' ) { *status = BAD_INTKEY; } else if (dtype == 'C') { /* try reading the string as a number */ if (ffc2dd(sval, &dval, status) <= 0) { if (dval > (double) LONG_MAX || dval < (double) LONG_MIN) *status = NUM_OVERFLOW; else *ival = (long) dval; } } else if (dtype == 'F') { if (dval > (double) LONG_MAX || dval < (double) LONG_MIN) *status = NUM_OVERFLOW; else *ival = (long) dval; } else if (dtype == 'L') { *ival = (long) lval; } if (*status > 0) { *ival = 0; strcpy(msg,"Error in ffc2i evaluating string as an integer: "); strncat(msg,cval,30); ffpmsg(msg); return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2j(char *cval, /* I - string representation of the value */ LONGLONG *ival, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert formatted string to a LONGLONG integer value, doing implicit datatype conversion if necessary. */ { char dtype, sval[81], msg[81]; int lval; double dval; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == '\0') return(*status = VALUE_UNDEFINED); /* null value string */ /* convert the keyword to its native datatype */ ffc2xx(cval, &dtype, ival, &lval, sval, &dval, status); if (dtype == 'X' ) { *status = BAD_INTKEY; } else if (dtype == 'C') { /* try reading the string as a number */ if (ffc2dd(sval, &dval, status) <= 0) { if (dval > (double) LONGLONG_MAX || dval < (double) LONGLONG_MIN) *status = NUM_OVERFLOW; else *ival = (LONGLONG) dval; } } else if (dtype == 'F') { if (dval > (double) LONGLONG_MAX || dval < (double) LONGLONG_MIN) *status = NUM_OVERFLOW; else *ival = (LONGLONG) dval; } else if (dtype == 'L') { *ival = (LONGLONG) lval; } if (*status > 0) { *ival = 0; strcpy(msg,"Error in ffc2j evaluating string as a long integer: "); strncat(msg,cval,30); ffpmsg(msg); return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2l(char *cval, /* I - string representation of the value */ int *lval, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert formatted string to a logical value, doing implicit datatype conversion if necessary */ { char dtype, sval[81], msg[81]; long ival; double dval; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == '\0') return(*status = VALUE_UNDEFINED); /* null value string */ /* convert the keyword to its native datatype */ ffc2x(cval, &dtype, &ival, lval, sval, &dval, status); if (dtype == 'C' || dtype == 'X' ) *status = BAD_LOGICALKEY; if (*status > 0) { *lval = 0; strcpy(msg,"Error in ffc2l evaluating string as a logical: "); strncat(msg,cval,30); ffpmsg(msg); return(*status); } if (dtype == 'I') { if (ival) *lval = 1; else *lval = 0; } else if (dtype == 'F') { if (dval) *lval = 1; else *lval = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2r(char *cval, /* I - string representation of the value */ float *fval, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert formatted string to a real float value, doing implicit datatype conversion if necessary */ { char dtype, sval[81], msg[81]; int lval; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == '\0') return(*status = VALUE_UNDEFINED); /* null value string */ ffdtyp(cval, &dtype, status); /* determine the datatype */ if (dtype == 'I' || dtype == 'F') ffc2rr(cval, fval, status); else if (dtype == 'L') { ffc2ll(cval, &lval, status); *fval = (float) lval; } else if (dtype == 'C') { /* try reading the string as a number */ ffc2s(cval, sval, status); ffc2rr(sval, fval, status); } else *status = BAD_FLOATKEY; if (*status > 0) { *fval = 0.; strcpy(msg,"Error in ffc2r evaluating string as a float: "); strncat(msg,cval,30); ffpmsg(msg); return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2d(char *cval, /* I - string representation of the value */ double *dval, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert formatted string to a double value, doing implicit datatype conversion if necessary */ { char dtype, sval[81], msg[81]; int lval; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == '\0') return(*status = VALUE_UNDEFINED); /* null value string */ ffdtyp(cval, &dtype, status); /* determine the datatype */ if (dtype == 'I' || dtype == 'F') ffc2dd(cval, dval, status); else if (dtype == 'L') { ffc2ll(cval, &lval, status); *dval = (double) lval; } else if (dtype == 'C') { /* try reading the string as a number */ ffc2s(cval, sval, status); ffc2dd(sval, dval, status); } else *status = BAD_DOUBLEKEY; if (*status > 0) { *dval = 0.; strcpy(msg,"Error in ffc2d evaluating string as a double: "); strncat(msg,cval,30); ffpmsg(msg); return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2ii(char *cval, /* I - string representation of the value */ long *ival, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert null-terminated formatted string to an integer value */ { char *loc, msg[81]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); errno = 0; *ival = 0; *ival = strtol(cval, &loc, 10); /* read the string as an integer */ /* check for read error, or junk following the integer */ if (*loc != '\0' && *loc != ' ' ) *status = BAD_C2I; if (errno == ERANGE) { strcpy(msg,"Range Error in ffc2ii converting string to long int: "); strncat(msg,cval,25); ffpmsg(msg); *status = NUM_OVERFLOW; errno = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2jj(char *cval, /* I - string representation of the value */ LONGLONG *ival, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert null-terminated formatted string to an long long integer value */ { char *loc, msg[81]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); errno = 0; *ival = 0; #if defined(_MSC_VER) /* Microsoft Visual C++ 6.0 does not have the strtoll function */ *ival = _atoi64(cval); loc = cval; while (*loc == ' ') loc++; /* skip spaces */ if (*loc == '-') loc++; /* skip minus sign */ if (*loc == '+') loc++; /* skip plus sign */ while (isdigit(*loc)) loc++; /* skip digits */ #elif (USE_LL_SUFFIX == 1) *ival = strtoll(cval, &loc, 10); /* read the string as an integer */ #else *ival = strtol(cval, &loc, 10); /* read the string as an integer */ #endif /* check for read error, or junk following the integer */ if (*loc != '\0' && *loc != ' ' ) *status = BAD_C2I; if (errno == ERANGE) { strcpy(msg,"Range Error in ffc2jj converting string to longlong int: "); strncat(msg,cval,25); ffpmsg(msg); *status = NUM_OVERFLOW; errno = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2ll(char *cval, /* I - string representation of the value: T or F */ int *lval, /* O - numerical value of the input string: 1 or 0 */ int *status) /* IO - error status */ /* convert null-terminated formatted string to a logical value */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == 'T') *lval = 1; else *lval = 0; /* any character besides T is considered false */ return(*status); } /*--------------------------------------------------------------------------*/ int ffc2s(char *instr, /* I - null terminated quoted input string */ char *outstr, /* O - null terminated output string without quotes */ int *status) /* IO - error status */ /* convert an input quoted string to an unquoted string by removing the leading and trailing quote character. Also, replace any pairs of single quote characters with just a single quote character (FITS used a pair of single quotes to represent a literal quote character within the string). */ { int jj; size_t len, ii; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (instr[0] != '\'') { strcpy(outstr, instr); /* no leading quote, so return input string */ return(*status); } len = strlen(instr); for (ii=1, jj=0; ii < len; ii++, jj++) { if (instr[ii] == '\'') /* is this the closing quote? */ { if (instr[ii+1] == '\'') /* 2 successive quotes? */ ii++; /* copy only one of the quotes */ else break; /* found the closing quote, so exit this loop */ } outstr[jj] = instr[ii]; /* copy the next character to the output */ } outstr[jj] = '\0'; /* terminate the output string */ if (ii == len) { ffpmsg("This string value has no closing quote (ffc2s):"); ffpmsg(instr); return(*status = 205); } for (jj--; jj >= 0; jj--) /* replace trailing blanks with nulls */ { if (outstr[jj] == ' ') outstr[jj] = 0; else break; } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2rr(char *cval, /* I - string representation of the value */ float *fval, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert null-terminated formatted string to a float value */ { char *loc, msg[81]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); errno = 0; *fval = 0.; *fval = (float) strtod(cval, &loc); /* read the string as an float */ /* check for read error, or junk following the value */ if (*loc != '\0' && *loc != ' ' ) { strcpy(msg,"Error in ffc2rr converting string to float: "); strncat(msg,cval,30); ffpmsg(msg); *status = BAD_C2F; } if (errno == ERANGE) { strcpy(msg,"Error in ffc2rr converting string to float: "); strncat(msg,cval,30); ffpmsg(msg); *status = NUM_OVERFLOW; errno = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2dd(char *cval, /* I - string representation of the value */ double *dval, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert null-terminated formatted string to a double value */ { char msg[81], tval[73], *loc; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(tval, cval); loc = strchr(tval, 'D'); if (loc) /* The C language does not support a 'D' */ *loc = 'E'; /* exponent so replace any D's with E's. */ errno = 0; *dval = 0.; *dval = strtod(tval, &loc); /* read the string as an double */ /* check for read error, or junk following the value */ if (*loc != '\0' && *loc != ' ' ) { strcpy(msg,"Error in ffc2dd converting string to double: "); strncat(msg,cval,30); ffpmsg(msg); *status = BAD_C2D; } if (errno == ERANGE) { strcpy(msg,"Error in ffc2dd converting string to double: "); strncat(msg,cval,30); ffpmsg(msg); *status = NUM_OVERFLOW; errno = 0; } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/fitsio.h000066400000000000000000002756011215713201500221110ustar00rootroot00000000000000/* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ /* Copyright (Unpublished--all rights reserved under the copyright laws of the United States), U.S. Government as represented by the Administrator of the National Aeronautics and Space Administration. No copyright is claimed in the United States under Title 17, U.S. Code. Permission to freely use, copy, modify, and distribute this software and its documentation without fee is hereby granted, provided that this copyright notice and disclaimer of warranty appears in all copies. DISCLAIMER: THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT SHALL NASA BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, CONTRACT, TORT , OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER." */ #ifndef _FITSIO_H #define _FITSIO_H #define CFITSIO_VERSION 3.04 #include /* the following was provided by Michael Greason (GSFC) to fix a */ /* C/Fortran compatibility problem on an SGI Altix system running */ /* SGI ProPack 4 [this is a Novell SuSE Enterprise 9 derivative] */ /* and using the Intel C++ and Fortran compilers (version 9.1) */ #if defined(__INTEL_COMPILER) && defined(__itanium__) # define mipsFortran 1 # define _MIPS_SZLONG 64 #endif #if defined(linux) || defined(__APPLE__) || defined(__sgi) # include /* apparently needed on debian linux systems */ #endif /* to define off_t */ #include /* apparently needed to define size_t with gcc 2.8.1 */ #include /* needed for LLONG_MAX and INT64_MAX definitions */ /* Define the datatype for variables which store file offset values. */ /* The newer 'off_t' datatype should be used for this purpose, but some */ /* older compilers do not recognize this type, in which case we use 'long' */ /* instead. Note that _OFF_T is defined (or not) in stdio.h depending */ /* on whether _LARGEFILE_SOURCE is defined in sys/feature_tests.h */ /* (at least on Solaris platforms using cc) */ /* Debian systems require the 2nd test, below, */ /* i.e, "(defined(linux) && defined(__off_t_defined))" */ #if defined(_OFF_T) || (defined(linux) && defined(__off_t_defined)) || defined(_MIPS_SZLONG) || defined(__APPLE__) || defined(_AIX) # define OFF_T off_t #else # define OFF_T long #endif /* this block determines if the the string function name is strtol or strtoll, and whether to use %ld or %lld in printf statements */ /* The following 2 cases for that Athon64 were removed on 4 Jan 2006; they appear to be incorrect now that LONGLONG is always typedef'ed to 'long long' || defined(__ia64__) \ || defined(__x86_64__) \ */ #if (defined(__alpha) && ( defined(__unix__) || defined(__NetBSD__) )) \ || defined(__sparcv9) \ || defined(__powerpc64__) || defined(__64BIT__) \ || (defined(_MIPS_SZLONG) && _MIPS_SZLONG == 64) \ || defined( _MSC_VER)|| defined(__BORLANDC__) || defined(__hpux) # define USE_LL_SUFFIX 0 #else # define USE_LL_SUFFIX 1 #endif /* Determine what 8-byte integer data type is available. 'long long' is now supported by most compilers, but older MS Visual C++ compilers before V7.0 use '__int64' instead. */ #ifndef LONGLONG_TYPE /* this may have been previously defined */ #if defined(_MSC_VER) /* Microsoft Visual C++ */ #if (_MSC_VER < 1300) /* versions earlier than V7.0 do not have 'long long' */ typedef __int64 LONGLONG; #else /* newer versions do support 'long long' */ typedef long long LONGLONG; #endif #else typedef long long LONGLONG; #endif #define LONGLONG_TYPE #endif /* ================================================================= */ /* The following exclusion if __CINT__ is defined is needed for ROOT */ #ifndef __CINT__ #include "longnam.h" #endif /* global variables */ #define FLEN_FILENAME 1025 /* max length of a filename */ #define FLEN_KEYWORD 72 /* max length of a keyword (HIERARCH convention) */ #define FLEN_CARD 81 /* length of a FITS header card */ #define FLEN_VALUE 71 /* max length of a keyword value string */ #define FLEN_COMMENT 73 /* max length of a keyword comment string */ #define FLEN_ERRMSG 81 /* max length of a FITSIO error message */ #define FLEN_STATUS 31 /* max length of a FITSIO status text string */ #define TBIT 1 /* codes for FITS table data types */ #define TBYTE 11 #define TSBYTE 12 #define TLOGICAL 14 #define TSTRING 16 #define TUSHORT 20 #define TSHORT 21 #define TUINT 30 #define TINT 31 #define TULONG 40 #define TLONG 41 #define TINT32BIT 41 /* used when returning datatype of a column */ #define TFLOAT 42 #define TLONGLONG 81 #define TDOUBLE 82 #define TCOMPLEX 83 #define TDBLCOMPLEX 163 #define TYP_STRUC_KEY 10 #define TYP_CMPRS_KEY 20 #define TYP_SCAL_KEY 30 #define TYP_NULL_KEY 40 #define TYP_DIM_KEY 50 #define TYP_RANG_KEY 60 #define TYP_UNIT_KEY 70 #define TYP_DISP_KEY 80 #define TYP_HDUID_KEY 90 #define TYP_CKSUM_KEY 100 #define TYP_WCS_KEY 110 #define TYP_REFSYS_KEY 120 #define TYP_COMM_KEY 130 #define TYP_CONT_KEY 140 #define TYP_USER_KEY 150 #define INT32BIT int /* 32-bit integer datatype. Currently this */ /* datatype is an 'int' on all useful platforms */ /* however, it is possible that that are cases */ /* where 'int' is a 2-byte integer, in which case */ /* INT32BIT would need to be defined as 'long'. */ #define BYTE_IMG 8 /* BITPIX code values for FITS image types */ #define SHORT_IMG 16 #define LONG_IMG 32 #define LONGLONG_IMG 64 #define FLOAT_IMG -32 #define DOUBLE_IMG -64 /* The following 2 codes are not true FITS */ /* datatypes; these codes are only used internally */ /* within cfitsio to make it easier for users */ /* to deal with unsigned integers. */ #define SBYTE_IMG 10 #define USHORT_IMG 20 #define ULONG_IMG 40 #define IMAGE_HDU 0 /* Primary Array or IMAGE HDU */ #define ASCII_TBL 1 /* ASCII table HDU */ #define BINARY_TBL 2 /* Binary table HDU */ #define ANY_HDU -1 /* matches any HDU type */ #define READONLY 0 /* options when opening a file */ #define READWRITE 1 /* adopt a hopefully obscure number to use as a null value flag */ /* could be problems if the FITS files contain data with these values */ #define FLOATNULLVALUE -9.11912E-36F #define DOUBLENULLVALUE -9.1191291391491E-36 /* Image compression algorithm types */ #define MAX_COMPRESS_DIM 6 #define RICE_1 11 #define GZIP_1 21 #define PLIO_1 31 #define HCOMPRESS_1 41 #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #define CASESEN 1 /* do case-sensitive string match */ #define CASEINSEN 0 /* do case-insensitive string match */ #define GT_ID_ALL_URI 0 /* hierarchical grouping parameters */ #define GT_ID_REF 1 #define GT_ID_POS 2 #define GT_ID_ALL 3 #define GT_ID_REF_URI 11 #define GT_ID_POS_URI 12 #define OPT_RM_GPT 0 #define OPT_RM_ENTRY 1 #define OPT_RM_MBR 2 #define OPT_RM_ALL 3 #define OPT_GCP_GPT 0 #define OPT_GCP_MBR 1 #define OPT_GCP_ALL 2 #define OPT_MCP_ADD 0 #define OPT_MCP_NADD 1 #define OPT_MCP_REPL 2 #define OPT_MCP_MOV 3 #define OPT_MRG_COPY 0 #define OPT_MRG_MOV 1 #define OPT_CMT_MBR 1 #define OPT_CMT_MBR_DEL 11 typedef struct /* structure used to store table column information */ { char ttype[70]; /* column name = FITS TTYPEn keyword; */ LONGLONG tbcol; /* offset in row to first byte of each column */ int tdatatype; /* datatype code of each column */ LONGLONG trepeat; /* repeat count of column; number of elements */ double tscale; /* FITS TSCALn linear scaling factor */ double tzero; /* FITS TZEROn linear scaling zero point */ LONGLONG tnull; /* FITS null value for int image or binary table cols */ char strnull[20]; /* FITS null value string for ASCII table columns */ char tform[10]; /* FITS tform keyword value */ long twidth; /* width of each ASCII table column */ }tcolumn; #define VALIDSTRUC 555 /* magic value used to identify if structure is valid */ typedef struct /* structure used to store basic FITS file information */ { int filehandle; /* handle returned by the file open function */ int driver; /* defines which set of I/O drivers should be used */ int open_count; /* number of opened 'fitsfiles' using this structure */ char *filename; /* file name */ int validcode; /* magic value used to verify that structure is valid */ LONGLONG filesize; /* current size of the physical disk file in bytes */ LONGLONG logfilesize; /* logical size of file, including unflushed buffers */ int lasthdu; /* is this the last HDU in the file? 0 = no, else yes */ LONGLONG bytepos; /* current logical I/O pointer position in file */ LONGLONG io_pos; /* current I/O pointer position in the physical file */ int curbuf; /* number of I/O buffer currently in use */ int curhdu; /* current HDU number; 0 = primary array */ int hdutype; /* 0 = primary array, 1 = ASCII table, 2 = binary table */ int writemode; /* 0 = readonly, 1 = readwrite */ int maxhdu; /* highest numbered HDU known to exist in the file */ int MAXHDU; /* dynamically allocated dimension of headstart array */ LONGLONG *headstart; /* byte offset in file to start of each HDU */ LONGLONG headend; /* byte offest in file to end of the current HDU header */ LONGLONG nextkey; /* byte offset in file to beginning of next keyword */ LONGLONG datastart; /* byte offset in file to start of the current data unit */ int tfield; /* number of fields in the table (primary array has 2 */ LONGLONG origrows; /* original number of rows (value of NAXIS2 keyword) */ LONGLONG numrows; /* number of rows in the table (dynamically updated) */ LONGLONG rowlength; /* length of a table row or image size (bytes) */ tcolumn *tableptr; /* pointer to the table structure */ LONGLONG heapstart; /* heap start byte relative to start of data unit */ LONGLONG heapsize; /* size of the heap, in bytes */ /* the following elements are related to compressed images */ int request_compress_type; /* requested image compression algorithm */ long request_tilesize[MAX_COMPRESS_DIM]; /* requested tiling size */ int request_noise_nbits; /* requested noise bit parameter value */ int request_hcomp_scale; /* requested HCOMPRESS scale factor */ int request_hcomp_smooth; /* requested HCOMPRESS smooth parameter */ int compressimg; /* 1 if HDU contains a compressed image, else 0 */ char zcmptype[12]; /* compression type string */ int compress_type; /* type of compression algorithm */ int zbitpix; /* FITS data type of image (BITPIX) */ int zndim; /* dimension of image */ long znaxis[MAX_COMPRESS_DIM]; /* length of each axis */ long tilesize[MAX_COMPRESS_DIM]; /* size of compression tiles */ long maxtilelen; /* max number of pixels in each image tile */ long maxelem; /* maximum length of variable length arrays */ int cn_compressed; /* column number for COMPRESSED_DATA column */ int cn_uncompressed; /* column number for UNCOMPRESSED_DATA column */ int cn_zscale; /* column number for ZSCALE column */ int cn_zzero; /* column number for ZZERO column */ int cn_zblank; /* column number for the ZBLANK column */ double zscale; /* scaling value, if same for all tiles */ double zzero; /* zero pt, if same for all tiles */ double cn_bscale; /* value of the BSCALE keyword in header */ double cn_bzero; /* value of the BZERO keyword in header */ int zblank; /* value for null pixels, if not a column */ int rice_blocksize; /* first compression parameter */ int noise_nbits; /* floating point noise parameter */ int hcomp_scale; /* 1st hcompress compression parameter */ int hcomp_smooth; /* 2nd hcompress compression parameter */ } FITSfile; typedef struct /* structure used to store basic HDU information */ { int HDUposition; /* HDU position in file; 0 = first HDU */ FITSfile *Fptr; /* pointer to FITS file structure */ }fitsfile; typedef struct /* structure for the iterator function column information */ { /* elements required as input to fits_iterate_data: */ fitsfile *fptr; /* pointer to the HDU containing the column */ int colnum; /* column number in the table (use name if < 1) */ char colname[70]; /* name (= TTYPEn value) of the column (optional) */ int datatype; /* output datatype (converted if necessary */ int iotype; /* = InputCol, InputOutputCol, or OutputCol */ /* output elements that may be useful for the work function: */ void *array; /* pointer to the array (and the null value) */ long repeat; /* binary table vector repeat value */ long tlmin; /* legal minimum data value */ long tlmax; /* legal maximum data value */ char tunit[70]; /* physical unit string */ char tdisp[70]; /* suggested display format */ } iteratorCol; #define InputCol 0 /* flag for input only iterator column */ #define InputOutputCol 1 /* flag for input and output iterator column */ #define OutputCol 2 /* flag for output only iterator column */ /*============================================================================= * * The following wtbarr typedef is used in the fits_read_wcstab() routine, * which is intended for use with the WCSLIB library written by Mark * Calabretta, http://www.atnf.csiro.au/~mcalabre/index.html * * In order to maintain WCSLIB and CFITSIO as independent libraries it * was not permissible for any CFITSIO library code to include WCSLIB * header files, or vice versa. However, the CFITSIO function * fits_read_wcstab() accepts an array of structs defined by wcs.h within * WCSLIB. The problem then was to define this struct within fitsio.h * without including wcs.h, especially noting that wcs.h will often (but * not always) be included together with fitsio.h in an applications * program that uses fits_read_wcstab(). * * Of the various possibilities, the solution adopted was for WCSLIB to * define "struct wtbarr" while fitsio.h defines "typedef wtbarr", a * untagged struct with identical members. This allows both wcs.h and * fitsio.h to define a wtbarr data type without conflict by virtue of * the fact that structure tags and typedef names share different * namespaces in C. Therefore, declarations within WCSLIB look like * * struct wtbarr *w; * * while within CFITSIO they are simply * * wtbarr *w; * * but as suggested by the commonality of the names, these are really the * same aggregate data type. However, in passing a (struct wtbarr *) to * fits_read_wcstab() a cast to (wtbarr *) is formally required. *===========================================================================*/ #ifndef WCSLIB_GETWCSTAB #define WCSLIB_GETWCSTAB typedef struct { int i; /* Image axis number. */ int m; /* Array axis number for index vectors. */ int kind; /* Array type, 'c' (coord) or 'i' (index). */ char extnam[72]; /* EXTNAME of binary table extension. */ int extver; /* EXTVER of binary table extension. */ int extlev; /* EXTLEV of binary table extension. */ char ttype[72]; /* TTYPEn of column containing the array. */ long row; /* Table row number. */ int ndim; /* Expected array dimensionality. */ int *dimlen; /* Where to write the array axis lengths. */ double **arrayp; /* Where to write the address of the array */ /* allocated to store the array. */ } wtbarr; int fits_read_wcstab(fitsfile *fptr, int nwtb, wtbarr *wtb, int *status); #endif /* WCSLIB_GETWCSTAB */ /* error status codes */ #define CREATE_DISK_FILE -106 /* create disk file, without extended filename syntax */ #define OPEN_DISK_FILE -105 /* open disk file, without extended filename syntax */ #define SKIP_TABLE -104 /* move to 1st image when opening file */ #define SKIP_IMAGE -103 /* move to 1st table when opening file */ #define SKIP_NULL_PRIMARY -102 /* skip null primary array when opening file */ #define USE_MEM_BUFF -101 /* use memory buffer when opening file */ #define OVERFLOW_ERR -11 /* overflow during datatype conversion */ #define PREPEND_PRIMARY -9 /* used in ffiimg to insert new primary array */ #define SAME_FILE 101 /* input and output files are the same */ #define TOO_MANY_FILES 103 /* tried to open too many FITS files */ #define FILE_NOT_OPENED 104 /* could not open the named file */ #define FILE_NOT_CREATED 105 /* could not create the named file */ #define WRITE_ERROR 106 /* error writing to FITS file */ #define END_OF_FILE 107 /* tried to move past end of file */ #define READ_ERROR 108 /* error reading from FITS file */ #define FILE_NOT_CLOSED 110 /* could not close the file */ #define ARRAY_TOO_BIG 111 /* array dimensions exceed internal limit */ #define READONLY_FILE 112 /* Cannot write to readonly file */ #define MEMORY_ALLOCATION 113 /* Could not allocate memory */ #define BAD_FILEPTR 114 /* invalid fitsfile pointer */ #define NULL_INPUT_PTR 115 /* NULL input pointer to routine */ #define SEEK_ERROR 116 /* error seeking position in file */ #define BAD_URL_PREFIX 121 /* invalid URL prefix on file name */ #define TOO_MANY_DRIVERS 122 /* tried to register too many IO drivers */ #define DRIVER_INIT_FAILED 123 /* driver initialization failed */ #define NO_MATCHING_DRIVER 124 /* matching driver is not registered */ #define URL_PARSE_ERROR 125 /* failed to parse input file URL */ #define RANGE_PARSE_ERROR 126 /* failed to parse input file URL */ #define SHARED_ERRBASE (150) #define SHARED_BADARG (SHARED_ERRBASE + 1) #define SHARED_NULPTR (SHARED_ERRBASE + 2) #define SHARED_TABFULL (SHARED_ERRBASE + 3) #define SHARED_NOTINIT (SHARED_ERRBASE + 4) #define SHARED_IPCERR (SHARED_ERRBASE + 5) #define SHARED_NOMEM (SHARED_ERRBASE + 6) #define SHARED_AGAIN (SHARED_ERRBASE + 7) #define SHARED_NOFILE (SHARED_ERRBASE + 8) #define SHARED_NORESIZE (SHARED_ERRBASE + 9) #define HEADER_NOT_EMPTY 201 /* header already contains keywords */ #define KEY_NO_EXIST 202 /* keyword not found in header */ #define KEY_OUT_BOUNDS 203 /* keyword record number is out of bounds */ #define VALUE_UNDEFINED 204 /* keyword value field is blank */ #define NO_QUOTE 205 /* string is missing the closing quote */ #define BAD_INDEX_KEY 206 /* illegal indexed keyword name */ #define BAD_KEYCHAR 207 /* illegal character in keyword name or card */ #define BAD_ORDER 208 /* required keywords out of order */ #define NOT_POS_INT 209 /* keyword value is not a positive integer */ #define NO_END 210 /* couldn't find END keyword */ #define BAD_BITPIX 211 /* illegal BITPIX keyword value*/ #define BAD_NAXIS 212 /* illegal NAXIS keyword value */ #define BAD_NAXES 213 /* illegal NAXISn keyword value */ #define BAD_PCOUNT 214 /* illegal PCOUNT keyword value */ #define BAD_GCOUNT 215 /* illegal GCOUNT keyword value */ #define BAD_TFIELDS 216 /* illegal TFIELDS keyword value */ #define NEG_WIDTH 217 /* negative table row size */ #define NEG_ROWS 218 /* negative number of rows in table */ #define COL_NOT_FOUND 219 /* column with this name not found in table */ #define BAD_SIMPLE 220 /* illegal value of SIMPLE keyword */ #define NO_SIMPLE 221 /* Primary array doesn't start with SIMPLE */ #define NO_BITPIX 222 /* Second keyword not BITPIX */ #define NO_NAXIS 223 /* Third keyword not NAXIS */ #define NO_NAXES 224 /* Couldn't find all the NAXISn keywords */ #define NO_XTENSION 225 /* HDU doesn't start with XTENSION keyword */ #define NOT_ATABLE 226 /* the CHDU is not an ASCII table extension */ #define NOT_BTABLE 227 /* the CHDU is not a binary table extension */ #define NO_PCOUNT 228 /* couldn't find PCOUNT keyword */ #define NO_GCOUNT 229 /* couldn't find GCOUNT keyword */ #define NO_TFIELDS 230 /* couldn't find TFIELDS keyword */ #define NO_TBCOL 231 /* couldn't find TBCOLn keyword */ #define NO_TFORM 232 /* couldn't find TFORMn keyword */ #define NOT_IMAGE 233 /* the CHDU is not an IMAGE extension */ #define BAD_TBCOL 234 /* TBCOLn keyword value < 0 or > rowlength */ #define NOT_TABLE 235 /* the CHDU is not a table */ #define COL_TOO_WIDE 236 /* column is too wide to fit in table */ #define COL_NOT_UNIQUE 237 /* more than 1 column name matches template */ #define BAD_ROW_WIDTH 241 /* sum of column widths not = NAXIS1 */ #define UNKNOWN_EXT 251 /* unrecognizable FITS extension type */ #define UNKNOWN_REC 252 /* unrecognizable FITS record */ #define END_JUNK 253 /* END keyword is not blank */ #define BAD_HEADER_FILL 254 /* Header fill area not blank */ #define BAD_DATA_FILL 255 /* Data fill area not blank or zero */ #define BAD_TFORM 261 /* illegal TFORM format code */ #define BAD_TFORM_DTYPE 262 /* unrecognizable TFORM datatype code */ #define BAD_TDIM 263 /* illegal TDIMn keyword value */ #define BAD_HEAP_PTR 264 /* invalid BINTABLE heap address */ #define BAD_HDU_NUM 301 /* HDU number < 1 or > MAXHDU */ #define BAD_COL_NUM 302 /* column number < 1 or > tfields */ #define NEG_FILE_POS 304 /* tried to move before beginning of file */ #define NEG_BYTES 306 /* tried to read or write negative bytes */ #define BAD_ROW_NUM 307 /* illegal starting row number in table */ #define BAD_ELEM_NUM 308 /* illegal starting element number in vector */ #define NOT_ASCII_COL 309 /* this is not an ASCII string column */ #define NOT_LOGICAL_COL 310 /* this is not a logical datatype column */ #define BAD_ATABLE_FORMAT 311 /* ASCII table column has wrong format */ #define BAD_BTABLE_FORMAT 312 /* Binary table column has wrong format */ #define NO_NULL 314 /* null value has not been defined */ #define NOT_VARI_LEN 317 /* this is not a variable length column */ #define BAD_DIMEN 320 /* illegal number of dimensions in array */ #define BAD_PIX_NUM 321 /* first pixel number greater than last pixel */ #define ZERO_SCALE 322 /* illegal BSCALE or TSCALn keyword = 0 */ #define NEG_AXIS 323 /* illegal axis length < 1 */ #define NOT_GROUP_TABLE 340 #define HDU_ALREADY_MEMBER 341 #define MEMBER_NOT_FOUND 342 #define GROUP_NOT_FOUND 343 #define BAD_GROUP_ID 344 #define TOO_MANY_HDUS_TRACKED 345 #define HDU_ALREADY_TRACKED 346 #define BAD_OPTION 347 #define IDENTICAL_POINTERS 348 #define BAD_GROUP_ATTACH 349 #define BAD_GROUP_DETACH 350 #define BAD_I2C 401 /* bad int to formatted string conversion */ #define BAD_F2C 402 /* bad float to formatted string conversion */ #define BAD_INTKEY 403 /* can't interprete keyword value as integer */ #define BAD_LOGICALKEY 404 /* can't interprete keyword value as logical */ #define BAD_FLOATKEY 405 /* can't interprete keyword value as float */ #define BAD_DOUBLEKEY 406 /* can't interprete keyword value as double */ #define BAD_C2I 407 /* bad formatted string to int conversion */ #define BAD_C2F 408 /* bad formatted string to float conversion */ #define BAD_C2D 409 /* bad formatted string to double conversion */ #define BAD_DATATYPE 410 /* bad keyword datatype code */ #define BAD_DECIM 411 /* bad number of decimal places specified */ #define NUM_OVERFLOW 412 /* overflow during datatype conversion */ # define DATA_COMPRESSION_ERR 413 /* error in imcompress routines */ # define DATA_DECOMPRESSION_ERR 414 /* error in imcompress routines */ # define NO_COMPRESSED_TILE 415 /* compressed tile doesn't exist */ #define BAD_DATE 420 /* error in date or time conversion */ #define PARSE_SYNTAX_ERR 431 /* syntax error in parser expression */ #define PARSE_BAD_TYPE 432 /* expression did not evaluate to desired type */ #define PARSE_LRG_VECTOR 433 /* vector result too large to return in array */ #define PARSE_NO_OUTPUT 434 /* data parser failed not sent an out column */ #define PARSE_BAD_COL 435 /* bad data encounter while parsing column */ #define PARSE_BAD_OUTPUT 436 /* Output file not of proper type */ #define ANGLE_TOO_BIG 501 /* celestial angle too large for projection */ #define BAD_WCS_VAL 502 /* bad celestial coordinate or pixel value */ #define WCS_ERROR 503 /* error in celestial coordinate calculation */ #define BAD_WCS_PROJ 504 /* unsupported type of celestial projection */ #define NO_WCS_KEY 505 /* celestial coordinate keywords not found */ #define APPROX_WCS_KEY 506 /* approximate WCS keywords were calculated */ #define NO_CLOSE_ERROR 999 /* special value used internally to switch off */ /* the error message from ffclos and ffchdu */ /*------- following error codes are used in the grparser.c file -----------*/ #define NGP_ERRBASE (360) /* base chosen so not to interfere with CFITSIO */ #define NGP_OK (0) #define NGP_NO_MEMORY (NGP_ERRBASE + 0) /* malloc failed */ #define NGP_READ_ERR (NGP_ERRBASE + 1) /* read error from file */ #define NGP_NUL_PTR (NGP_ERRBASE + 2) /* null pointer passed as argument */ #define NGP_EMPTY_CURLINE (NGP_ERRBASE + 3) /* line read seems to be empty */ #define NGP_UNREAD_QUEUE_FULL (NGP_ERRBASE + 4) /* cannot unread more then 1 line (or single line twice) */ #define NGP_INC_NESTING (NGP_ERRBASE + 5) /* too deep include file nesting (inf. loop ?) */ #define NGP_ERR_FOPEN (NGP_ERRBASE + 6) /* fopen() failed, cannot open file */ #define NGP_EOF (NGP_ERRBASE + 7) /* end of file encountered */ #define NGP_BAD_ARG (NGP_ERRBASE + 8) /* bad arguments passed */ #define NGP_TOKEN_NOT_EXPECT (NGP_ERRBASE + 9) /* token not expected here */ /* The following exclusion if __CINT__ is defined is needed for ROOT */ #ifndef __CINT__ /* the following 3 lines are needed to support C++ compilers */ #ifdef __cplusplus extern "C" { #endif #endif int CFITS2Unit( fitsfile *fptr ); fitsfile* CUnit2FITS(int unit); /*---------------- FITS file URL parsing routines -------------*/ int fits_get_token(char **ptr, char *delimiter, char *token, int *isanumber); char *fits_split_names(char *list); int ffiurl( char *url, char *urltype, char *infile, char *outfile, char *extspec, char *rowfilter, char *binspec, char *colspec, int *status); int ffifile (char *url, char *urltype, char *infile, char *outfile, char *extspec, char *rowfilter, char *binspec, char *colspec, char *pixfilter, int *status); int ffrtnm(char *url, char *rootname, int *status); int ffexist(const char *infile, int *exists, int *status); int ffexts(char *extspec, int *extnum, char *extname, int *extvers, int *hdutype, char *colname, char *rowexpress, int *status); int ffextn(char *url, int *extension_num, int *status); int ffurlt(fitsfile *fptr, char *urlType, int *status); int ffbins(char *binspec, int *imagetype, int *haxis, char colname[4][FLEN_VALUE], double *minin, double *maxin, double *binsizein, char minname[4][FLEN_VALUE], char maxname[4][FLEN_VALUE], char binname[4][FLEN_VALUE], double *weight, char *wtname, int *recip, int *status); int ffbinr(char **binspec, char *colname, double *minin, double *maxin, double *binsizein, char *minname, char *maxname, char *binname, int *status); int fits_copy_cell2image(fitsfile *fptr, fitsfile *newptr, char *colname, long rownum, int *status); int fits_copy_image2cell(fitsfile *fptr, fitsfile *newptr, char *colname, long rownum, int copykeyflag, int *status); int ffimport_file( char *filename, char **contents, int *status ); int ffrwrg( char *rowlist, LONGLONG maxrows, int maxranges, int *numranges, long *minrow, long *maxrow, int *status); int ffrwrgll( char *rowlist, LONGLONG maxrows, int maxranges, int *numranges, LONGLONG *minrow, LONGLONG *maxrow, int *status); /*---------------- FITS file I/O routines -------------*/ int ffomem(fitsfile **fptr, const char *name, int mode, void **buffptr, size_t *buffsize, size_t deltasize, void *(*mem_realloc)(void *p, size_t newsize), int *status); int ffopen(fitsfile **fptr, const char *filename, int iomode, int *status); int ffopentest(double version, fitsfile **fptr, const char *filename, int iomode, int *status); int ffdopn(fitsfile **fptr, const char *filename, int iomode, int *status); int fftopn(fitsfile **fptr, const char *filename, int iomode, int *status); int ffiopn(fitsfile **fptr, const char *filename, int iomode, int *status); int ffdkopn(fitsfile **fptr, const char *filename, int iomode, int *status); int ffreopen(fitsfile *openfptr, fitsfile **newfptr, int *status); int ffinit( fitsfile **fptr, const char *filename, int *status); int ffdkinit(fitsfile **fptr, const char *filename, int *status); int ffimem(fitsfile **fptr, void **buffptr, size_t *buffsize, size_t deltasize, void *(*mem_realloc)(void *p, size_t newsize), int *status); int fftplt(fitsfile **fptr, const char *filename, const char *tempname, int *status); int ffflus(fitsfile *fptr, int *status); int ffflsh(fitsfile *fptr, int clearbuf, int *status); int ffclos(fitsfile *fptr, int *status); int ffdelt(fitsfile *fptr, int *status); int ffflnm(fitsfile *fptr, char *filename, int *status); int ffflmd(fitsfile *fptr, int *filemode, int *status); /*---------------- utility routines -------------*/ float ffvers(float *version); void ffupch(char *string); void ffgerr(int status, char *errtext); void ffpmsg(const char *err_message); void ffpmrk(void); int ffgmsg(char *err_message); void ffcmsg(void); void ffcmrk(void); void ffrprt(FILE *stream, int status); void ffcmps(char *templt, char *colname, int casesen, int *match, int *exact); int fftkey(char *keyword, int *status); int fftrec(char *card, int *status); int ffnchk(fitsfile *fptr, int *status); int ffkeyn(char *keyroot, int value, char *keyname, int *status); int ffnkey(int value, char *keyroot, char *keyname, int *status); int ffgkcl(char *card); int ffdtyp(char *cval, char *dtype, int *status); int ffpsvc(char *card, char *value, char *comm, int *status); int ffgknm(char *card, char *name, int *length, int *status); int ffgthd(char *tmplt, char *card, int *hdtype, int *status); int fits_translate_keyword(char *inrec, char *outrec, char *patterns[][2], int npat, int n_value, int n_offset, int n_range, int *pat_num, int *i, int *j, int *m, int *n, int *status); int fits_translate_keywords(fitsfile *infptr, fitsfile *outfptr, int firstkey, char *patterns[][2], int npat, int n_value, int n_offset, int n_range, int *status); int ffasfm(char *tform, int *datacode, long *width, int *decim, int *status); int ffbnfm(char *tform, int *datacode, long *repeat, long *width, int *status); int ffbnfmll(char *tform, int *datacode, LONGLONG *repeat, long *width, int *status); int ffgabc(int tfields, char **tform, int space, long *rowlen, long *tbcol, int *status); int fits_get_section_range(char **ptr,long *secmin,long *secmax,long *incre, int *status); /* ffmbyt should not normally be used in application programs, but it is defined here as a publicly available routine because there are a few rare cases where it is needed */ int ffmbyt(fitsfile *fptr, LONGLONG bytpos, int ignore_err, int *status); /*----------------- write single keywords --------------*/ int ffpky(fitsfile *fptr, int datatype, char *keyname, void *value, char *comm, int *status); int ffprec(fitsfile *fptr, const char *card, int *status); int ffpcom(fitsfile *fptr, const char *comm, int *status); int ffpunt(fitsfile *fptr, char *keyname, char *unit, int *status); int ffphis(fitsfile *fptr, const char *history, int *status); int ffpdat(fitsfile *fptr, int *status); int ffverifydate(int year, int month, int day, int *status); int ffgstm(char *timestr, int *timeref, int *status); int ffgsdt(int *day, int *month, int *year, int *status); int ffdt2s(int year, int month, int day, char *datestr, int *status); int fftm2s(int year, int month, int day, int hour, int minute, double second, int decimals, char *datestr, int *status); int ffs2dt(char *datestr, int *year, int *month, int *day, int *status); int ffs2tm(char *datestr, int *year, int *month, int *day, int *hour, int *minute, double *second, int *status); int ffpkyu(fitsfile *fptr, char *keyname, char *comm, int *status); int ffpkys(fitsfile *fptr, char *keyname, char *value, char *comm,int *status); int ffpkls(fitsfile *fptr, char *keyname, char *value, char *comm,int *status); int ffplsw(fitsfile *fptr, int *status); int ffpkyl(fitsfile *fptr, char *keyname, int value, char *comm, int *status); int ffpkyj(fitsfile *fptr, char *keyname, LONGLONG value, char *comm, int *status); int ffpkyf(fitsfile *fptr, char *keyname, float value, int decim, char *comm, int *status); int ffpkye(fitsfile *fptr, char *keyname, float value, int decim, char *comm, int *status); int ffpkyg(fitsfile *fptr, char *keyname, double value, int decim, char *comm, int *status); int ffpkyd(fitsfile *fptr, char *keyname, double value, int decim, char *comm, int *status); int ffpkyc(fitsfile *fptr, char *keyname, float *value, int decim, char *comm, int *status); int ffpkym(fitsfile *fptr, char *keyname, double *value, int decim, char *comm, int *status); int ffpkfc(fitsfile *fptr, char *keyname, float *value, int decim, char *comm, int *status); int ffpkfm(fitsfile *fptr, char *keyname, double *value, int decim, char *comm, int *status); int ffpkyt(fitsfile *fptr, char *keyname, long intval, double frac, char *comm, int *status); int ffptdm( fitsfile *fptr, int colnum, int naxis, long naxes[], int *status); int ffptdmll( fitsfile *fptr, int colnum, int naxis, LONGLONG naxes[], int *status); /*----------------- write array of keywords --------------*/ int ffpkns(fitsfile *fptr, char *keyroot, int nstart, int nkey, char *value[], char *comm[], int *status); int ffpknl(fitsfile *fptr, char *keyroot, int nstart, int nkey, int *value, char *comm[], int *status); int ffpknj(fitsfile *fptr, char *keyroot, int nstart, int nkey, long *value, char *comm[], int *status); int ffpknjj(fitsfile *fptr, char *keyroot, int nstart, int nkey, LONGLONG *value, char *comm[], int *status); int ffpknf(fitsfile *fptr, char *keyroot, int nstart, int nkey, float *value, int decim, char *comm[], int *status); int ffpkne(fitsfile *fptr, char *keyroot, int nstart, int nkey, float *value, int decim, char *comm[], int *status); int ffpkng(fitsfile *fptr, char *keyroot, int nstart, int nkey, double *value, int decim, char *comm[], int *status); int ffpknd(fitsfile *fptr, char *keyroot, int nstart, int nkey, double *value, int decim, char *comm[], int *status); int ffcpky(fitsfile *infptr,fitsfile *outfptr,int incol,int outcol, char *rootname, int *status); /*----------------- write required header keywords --------------*/ int ffphps( fitsfile *fptr, int bitpix, int naxis, long naxes[], int *status); int ffphpsll( fitsfile *fptr, int bitpix, int naxis, LONGLONG naxes[], int *status); int ffphpr( fitsfile *fptr, int simple, int bitpix, int naxis, long naxes[], LONGLONG pcount, LONGLONG gcount, int extend, int *status); int ffphprll( fitsfile *fptr, int simple, int bitpix, int naxis, LONGLONG naxes[], LONGLONG pcount, LONGLONG gcount, int extend, int *status); int ffphtb(fitsfile *fptr, LONGLONG naxis1, LONGLONG naxis2, int tfields, char **ttype, long *tbcol, char **tform, char **tunit, char *extname, int *status); int ffphbn(fitsfile *fptr, LONGLONG naxis2, int tfields, char **ttype, char **tform, char **tunit, char *extname, LONGLONG pcount, int *status); int ffphext( fitsfile *fptr, char *xtension, int bitpix, int naxis, long naxes[], LONGLONG pcount, LONGLONG gcount, int *status); /*----------------- write template keywords --------------*/ int ffpktp(fitsfile *fptr, const char *filename, int *status); /*------------------ get header information --------------*/ int ffghsp(fitsfile *fptr, int *nexist, int *nmore, int *status); int ffghps(fitsfile *fptr, int *nexist, int *position, int *status); /*------------------ move position in header -------------*/ int ffmaky(fitsfile *fptr, int nrec, int *status); int ffmrky(fitsfile *fptr, int nrec, int *status); /*------------------ read single keywords -----------------*/ int ffgnxk(fitsfile *fptr, char **inclist, int ninc, char **exclist, int nexc, char *card, int *status); int ffgrec(fitsfile *fptr, int nrec, char *card, int *status); int ffgcrd(fitsfile *fptr, char *keyname, char *card, int *status); int ffgunt(fitsfile *fptr, char *keyname, char *unit, int *status); int ffgkyn(fitsfile *fptr, int nkey, char *keyname, char *keyval, char *comm, int *status); int ffgkey(fitsfile *fptr, char *keyname, char *keyval, char *comm, int *status); int ffgky( fitsfile *fptr, int datatype, char *keyname, void *value, char *comm, int *status); int ffgkys(fitsfile *fptr, char *keyname, char *value, char *comm, int *status); int ffgkls(fitsfile *fptr, char *keyname, char **value, char *comm, int *status) ; int ffgkyl(fitsfile *fptr, char *keyname, int *value, char *comm, int *status); int ffgkyj(fitsfile *fptr, char *keyname, long *value, char *comm, int *status); int ffgkyjj(fitsfile *fptr, char *keyname, LONGLONG *value, char *comm, int *status); int ffgkye(fitsfile *fptr, char *keyname, float *value, char *comm,int *status); int ffgkyd(fitsfile *fptr, char *keyname, double *value,char *comm,int *status); int ffgkyc(fitsfile *fptr, char *keyname, float *value, char *comm,int *status); int ffgkym(fitsfile *fptr, char *keyname, double *value,char *comm,int *status); int ffgkyt(fitsfile *fptr, char *keyname, long *ivalue, double *dvalue, char *comm, int *status); int ffgtdm(fitsfile *fptr, int colnum, int maxdim, int *naxis, long naxes[], int *status); int ffgtdmll(fitsfile *fptr, int colnum, int maxdim, int *naxis, LONGLONG naxes[], int *status); int ffdtdm(fitsfile *fptr, char *tdimstr, int colnum, int maxdim, int *naxis, long naxes[], int *status); int ffdtdmll(fitsfile *fptr, char *tdimstr, int colnum, int maxdim, int *naxis, LONGLONG naxes[], int *status); /*------------------ read array of keywords -----------------*/ int ffgkns(fitsfile *fptr, char *keyname, int nstart, int nmax, char *value[], int *nfound, int *status); int ffgknl(fitsfile *fptr, char *keyname, int nstart, int nmax, int *value, int *nfound, int *status); int ffgknj(fitsfile *fptr, char *keyname, int nstart, int nmax, long *value, int *nfound, int *status); int ffgknjj(fitsfile *fptr, char *keyname, int nstart, int nmax, LONGLONG *value, int *nfound, int *status); int ffgkne(fitsfile *fptr, char *keyname, int nstart, int nmax, float *value, int *nfound, int *status); int ffgknd(fitsfile *fptr, char *keyname, int nstart, int nmax, double *value, int *nfound, int *status); int ffh2st(fitsfile *fptr, char **header, int *status); int ffhdr2str( fitsfile *fptr, int exclude_comm, char **exclist, int nexc, char **header, int *nkeys, int *status); /*----------------- read required header keywords --------------*/ int ffghpr(fitsfile *fptr, int maxdim, int *simple, int *bitpix, int *naxis, long naxes[], long *pcount, long *gcount, int *extend, int *status); int ffghprll(fitsfile *fptr, int maxdim, int *simple, int *bitpix, int *naxis, LONGLONG naxes[], long *pcount, long *gcount, int *extend, int *status); int ffghtb(fitsfile *fptr,int maxfield, long *naxis1, long *naxis2, int *tfields, char **ttype, long *tbcol, char **tform, char **tunit, char *extname, int *status); int ffghtbll(fitsfile *fptr,int maxfield, LONGLONG *naxis1, LONGLONG *naxis2, int *tfields, char **ttype, LONGLONG *tbcol, char **tform, char **tunit, char *extname, int *status); int ffghbn(fitsfile *fptr, int maxfield, long *naxis2, int *tfields, char **ttype, char **tform, char **tunit, char *extname, long *pcount, int *status); int ffghbnll(fitsfile *fptr, int maxfield, LONGLONG *naxis2, int *tfields, char **ttype, char **tform, char **tunit, char *extname, LONGLONG *pcount, int *status); /*--------------------- update keywords ---------------*/ int ffuky(fitsfile *fptr, int datatype, char *keyname, void *value, char *comm, int *status); int ffucrd(fitsfile *fptr, char *keyname, char *card, int *status); int ffukyu(fitsfile *fptr, char *keyname, char *comm, int *status); int ffukys(fitsfile *fptr, char *keyname, char *value, char *comm, int *status); int ffukls(fitsfile *fptr, char *keyname, char *value, char *comm, int *status); int ffukyl(fitsfile *fptr, char *keyname, int value, char *comm, int *status); int ffukyj(fitsfile *fptr, char *keyname, LONGLONG value, char *comm, int *status); int ffukyf(fitsfile *fptr, char *keyname, float value, int decim, char *comm, int *status); int ffukye(fitsfile *fptr, char *keyname, float value, int decim, char *comm, int *status); int ffukyg(fitsfile *fptr, char *keyname, double value, int decim, char *comm, int *status); int ffukyd(fitsfile *fptr, char *keyname, double value, int decim, char *comm, int *status); int ffukyc(fitsfile *fptr, char *keyname, float *value, int decim, char *comm, int *status); int ffukym(fitsfile *fptr, char *keyname, double *value, int decim, char *comm, int *status); int ffukfc(fitsfile *fptr, char *keyname, float *value, int decim, char *comm, int *status); int ffukfm(fitsfile *fptr, char *keyname, double *value, int decim, char *comm, int *status); /*--------------------- modify keywords ---------------*/ int ffmrec(fitsfile *fptr, int nkey, char *card, int *status); int ffmcrd(fitsfile *fptr, char *keyname, char *card, int *status); int ffmnam(fitsfile *fptr, char *oldname, char *newname, int *status); int ffmcom(fitsfile *fptr, char *keyname, char *comm, int *status); int ffmkyu(fitsfile *fptr, char *keyname, char *comm, int *status); int ffmkys(fitsfile *fptr, char *keyname, char *value, char *comm,int *status); int ffmkls(fitsfile *fptr, char *keyname, char *value, char *comm,int *status); int ffmkyl(fitsfile *fptr, char *keyname, int value, char *comm, int *status); int ffmkyj(fitsfile *fptr, char *keyname, LONGLONG value, char *comm, int *status); int ffmkyf(fitsfile *fptr, char *keyname, float value, int decim, char *comm, int *status); int ffmkye(fitsfile *fptr, char *keyname, float value, int decim, char *comm, int *status); int ffmkyg(fitsfile *fptr, char *keyname, double value, int decim, char *comm, int *status); int ffmkyd(fitsfile *fptr, char *keyname, double value, int decim, char *comm, int *status); int ffmkyc(fitsfile *fptr, char *keyname, float *value, int decim, char *comm, int *status); int ffmkym(fitsfile *fptr, char *keyname, double *value, int decim, char *comm, int *status); int ffmkfc(fitsfile *fptr, char *keyname, float *value, int decim, char *comm, int *status); int ffmkfm(fitsfile *fptr, char *keyname, double *value, int decim, char *comm, int *status); /*--------------------- insert keywords ---------------*/ int ffirec(fitsfile *fptr, int nkey, char *card, int *status); int ffikey(fitsfile *fptr, char *card, int *status); int ffikyu(fitsfile *fptr, char *keyname, char *comm, int *status); int ffikys(fitsfile *fptr, char *keyname, char *value, char *comm,int *status); int ffikls(fitsfile *fptr, char *keyname, char *value, char *comm,int *status); int ffikyl(fitsfile *fptr, char *keyname, int value, char *comm, int *status); int ffikyj(fitsfile *fptr, char *keyname, LONGLONG value, char *comm, int *status); int ffikyf(fitsfile *fptr, char *keyname, float value, int decim, char *comm, int *status); int ffikye(fitsfile *fptr, char *keyname, float value, int decim, char *comm, int *status); int ffikyg(fitsfile *fptr, char *keyname, double value, int decim, char *comm, int *status); int ffikyd(fitsfile *fptr, char *keyname, double value, int decim, char *comm, int *status); int ffikyc(fitsfile *fptr, char *keyname, float *value, int decim, char *comm, int *status); int ffikym(fitsfile *fptr, char *keyname, double *value, int decim, char *comm, int *status); int ffikfc(fitsfile *fptr, char *keyname, float *value, int decim, char *comm, int *status); int ffikfm(fitsfile *fptr, char *keyname, double *value, int decim, char *comm, int *status); /*--------------------- delete keywords ---------------*/ int ffdkey(fitsfile *fptr, char *keyname, int *status); int ffdrec(fitsfile *fptr, int keypos, int *status); /*--------------------- get HDU information -------------*/ int ffghdn(fitsfile *fptr, int *chdunum); int ffghdt(fitsfile *fptr, int *exttype, int *status); int ffghad(fitsfile *fptr, long *headstart, long *datastart, long *dataend, int *status); int ffghadll(fitsfile *fptr, LONGLONG *headstart, LONGLONG *datastart, LONGLONG *dataend, int *status); int ffghof(fitsfile *fptr, OFF_T *headstart, OFF_T *datastart, OFF_T *dataend, int *status); int ffgipr(fitsfile *fptr, int maxaxis, int *imgtype, int *naxis, long *naxes, int *status); int ffgiprll(fitsfile *fptr, int maxaxis, int *imgtype, int *naxis, LONGLONG *naxes, int *status); int ffgidt(fitsfile *fptr, int *imgtype, int *status); int ffgiet(fitsfile *fptr, int *imgtype, int *status); int ffgidm(fitsfile *fptr, int *naxis, int *status); int ffgisz(fitsfile *fptr, int nlen, long *naxes, int *status); int ffgiszll(fitsfile *fptr, int nlen, LONGLONG *naxes, int *status); /*--------------------- HDU operations -------------*/ int ffmahd(fitsfile *fptr, int hdunum, int *exttype, int *status); int ffmrhd(fitsfile *fptr, int hdumov, int *exttype, int *status); int ffmnhd(fitsfile *fptr, int exttype, char *hduname, int hduvers, int *status); int ffthdu(fitsfile *fptr, int *nhdu, int *status); int ffcrhd(fitsfile *fptr, int *status); int ffcrim(fitsfile *fptr, int bitpix, int naxis, long *naxes, int *status); int ffcrimll(fitsfile *fptr, int bitpix, int naxis, LONGLONG *naxes, int *status); int ffcrtb(fitsfile *fptr, int tbltype, LONGLONG naxis2, int tfields, char **ttype, char **tform, char **tunit, char *extname, int *status); int ffiimg(fitsfile *fptr, int bitpix, int naxis, long *naxes, int *status); int ffiimgll(fitsfile *fptr, int bitpix, int naxis, LONGLONG *naxes, int *status); int ffitab(fitsfile *fptr, LONGLONG naxis1, LONGLONG naxis2, int tfields, char **ttype, long *tbcol, char **tform, char **tunit, char *extname, int *status); int ffibin(fitsfile *fptr, LONGLONG naxis2, int tfields, char **ttype, char **tform, char **tunit, char *extname, LONGLONG pcount, int *status); int ffrsim(fitsfile *fptr, int bitpix, int naxis, long *naxes, int *status); int ffrsimll(fitsfile *fptr, int bitpix, int naxis, LONGLONG *naxes, int *status); int ffdhdu(fitsfile *fptr, int *hdutype, int *status); int ffcopy(fitsfile *infptr, fitsfile *outfptr, int morekeys, int *status); int ffcpfl(fitsfile *infptr, fitsfile *outfptr, int prev, int cur, int follow, int *status); int ffcphd(fitsfile *infptr, fitsfile *outfptr, int *status); int ffcpdt(fitsfile *infptr, fitsfile *outfptr, int *status); int ffchfl(fitsfile *fptr, int *status); int ffcdfl(fitsfile *fptr, int *status); int ffwrhdu(fitsfile *fptr, FILE *outstream, int *status); int ffrdef(fitsfile *fptr, int *status); int ffhdef(fitsfile *fptr, int morekeys, int *status); int ffpthp(fitsfile *fptr, long theap, int *status); int ffcsum(fitsfile *fptr, long nrec, unsigned long *sum, int *status); void ffesum(unsigned long sum, int complm, char *ascii); unsigned long ffdsum(char *ascii, int complm, unsigned long *sum); int ffpcks(fitsfile *fptr, int *status); int ffupck(fitsfile *fptr, int *status); int ffvcks(fitsfile *fptr, int *datastatus, int *hdustatus, int *status); int ffgcks(fitsfile *fptr, unsigned long *datasum, unsigned long *hdusum, int *status); /*--------------------- define scaling or null values -------------*/ int ffpscl(fitsfile *fptr, double scale, double zero, int *status); int ffpnul(fitsfile *fptr, LONGLONG nulvalue, int *status); int fftscl(fitsfile *fptr, int colnum, double scale, double zero, int *status); int fftnul(fitsfile *fptr, int colnum, LONGLONG nulvalue, int *status); int ffsnul(fitsfile *fptr, int colnum, char *nulstring, int *status); /*--------------------- get column information -------------*/ int ffgcno(fitsfile *fptr, int casesen, char *templt, int *colnum, int *status); int ffgcnn(fitsfile *fptr, int casesen, char *templt, char *colname, int *colnum, int *status); int ffgtcl(fitsfile *fptr, int colnum, int *typecode, long *repeat, long *width, int *status); int ffgtclll(fitsfile *fptr, int colnum, int *typecode, LONGLONG *repeat, LONGLONG *width, int *status); int ffeqty(fitsfile *fptr, int colnum, int *typecode, long *repeat, long *width, int *status); int ffeqtyll(fitsfile *fptr, int colnum, int *typecode, LONGLONG *repeat, LONGLONG *width, int *status); int ffgncl(fitsfile *fptr, int *ncols, int *status); int ffgnrw(fitsfile *fptr, long *nrows, int *status); int ffgnrwll(fitsfile *fptr, LONGLONG *nrows, int *status); int ffgacl(fitsfile *fptr, int colnum, char *ttype, long *tbcol, char *tunit, char *tform, double *tscal, double *tzero, char *tnull, char *tdisp, int *status); int ffgbcl(fitsfile *fptr, int colnum, char *ttype, char *tunit, char *dtype, long *repeat, double *tscal, double *tzero, long *tnull, char *tdisp, int *status); int ffgbclll(fitsfile *fptr, int colnum, char *ttype, char *tunit, char *dtype, LONGLONG *repeat, double *tscal, double *tzero, LONGLONG *tnull, char *tdisp, int *status); int ffgrsz(fitsfile *fptr, long *nrows, int *status); int ffgcdw(fitsfile *fptr, int colnum, int *width, int *status); /*--------------------- read primary array or image elements -------------*/ int ffgpxv(fitsfile *fptr, int datatype, long *firstpix, LONGLONG nelem, void *nulval, void *array, int *anynul, int *status); int ffgpxvll(fitsfile *fptr, int datatype, LONGLONG *firstpix, LONGLONG nelem, void *nulval, void *array, int *anynul, int *status); int ffgpxf(fitsfile *fptr, int datatype, long *firstpix, LONGLONG nelem, void *array, char *nullarray, int *anynul, int *status); int ffgpxfll(fitsfile *fptr, int datatype, LONGLONG *firstpix, LONGLONG nelem, void *array, char *nullarray, int *anynul, int *status); int ffgsv(fitsfile *fptr, int datatype, long *blc, long *trc, long *inc, void *nulval, void *array, int *anynul, int *status); int ffgpv(fitsfile *fptr, int datatype, LONGLONG firstelem, LONGLONG nelem, void *nulval, void *array, int *anynul, int *status); int ffgpf(fitsfile *fptr, int datatype, LONGLONG firstelem, LONGLONG nelem, void *array, char *nullarray, int *anynul, int *status); int ffgpvb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned char nulval, unsigned char *array, int *anynul, int *status); int ffgpvsb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, signed char nulval, signed char *array, int *anynul, int *status); int ffgpvui(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned short nulval, unsigned short *array, int *anynul, int *status); int ffgpvi(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, short nulval, short *array, int *anynul, int *status); int ffgpvuj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned long nulval, unsigned long *array, int *anynul, int *status); int ffgpvj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, long nulval, long *array, int *anynul, int *status); int ffgpvjj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, LONGLONG nulval, LONGLONG *array, int *anynul, int *status); int ffgpvuk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned int nulval, unsigned int *array, int *anynul, int *status); int ffgpvk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, int nulval, int *array, int *anynul, int *status); int ffgpve(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, float nulval, float *array, int *anynul, int *status); int ffgpvd(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, double nulval, double *array, int *anynul, int *status); int ffgpfb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned char *array, char *nularray, int *anynul, int *status); int ffgpfsb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, signed char *array, char *nularray, int *anynul, int *status); int ffgpfui(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned short *array, char *nularray, int *anynul, int *status); int ffgpfi(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, short *array, char *nularray, int *anynul, int *status); int ffgpfuj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned long *array, char *nularray, int *anynul, int *status); int ffgpfj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, long *array, char *nularray, int *anynul, int *status); int ffgpfjj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, LONGLONG *array, char *nularray, int *anynul, int *status); int ffgpfuk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned int *array, char *nularray, int *anynul, int *status); int ffgpfk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, int *array, char *nularray, int *anynul, int *status); int ffgpfe(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, float *array, char *nularray, int *anynul, int *status); int ffgpfd(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, double *array, char *nularray, int *anynul, int *status); int ffg2db(fitsfile *fptr, long group, unsigned char nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned char *array, int *anynul, int *status); int ffg2dsb(fitsfile *fptr, long group, signed char nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, signed char *array, int *anynul, int *status); int ffg2dui(fitsfile *fptr, long group, unsigned short nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned short *array, int *anynul, int *status); int ffg2di(fitsfile *fptr, long group, short nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, short *array, int *anynul, int *status); int ffg2duj(fitsfile *fptr, long group, unsigned long nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned long *array, int *anynul, int *status); int ffg2dj(fitsfile *fptr, long group, long nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, long *array, int *anynul, int *status); int ffg2djj(fitsfile *fptr, long group, LONGLONG nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, LONGLONG *array, int *anynul, int *status); int ffg2duk(fitsfile *fptr, long group, unsigned int nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned int *array, int *anynul, int *status); int ffg2dk(fitsfile *fptr, long group, int nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, int *array, int *anynul, int *status); int ffg2de(fitsfile *fptr, long group, float nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, float *array, int *anynul, int *status); int ffg2dd(fitsfile *fptr, long group, double nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, double *array, int *anynul, int *status); int ffg3db(fitsfile *fptr, long group, unsigned char nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned char *array, int *anynul, int *status); int ffg3dsb(fitsfile *fptr, long group, signed char nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, signed char *array, int *anynul, int *status); int ffg3dui(fitsfile *fptr, long group, unsigned short nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned short *array, int *anynul, int *status); int ffg3di(fitsfile *fptr, long group, short nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, short *array, int *anynul, int *status); int ffg3duj(fitsfile *fptr, long group, unsigned long nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned long *array, int *anynul, int *status); int ffg3dj(fitsfile *fptr, long group, long nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, long *array, int *anynul, int *status); int ffg3djj(fitsfile *fptr, long group, LONGLONG nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, LONGLONG *array, int *anynul, int *status); int ffg3duk(fitsfile *fptr, long group, unsigned int nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned int *array, int *anynul, int *status); int ffg3dk(fitsfile *fptr, long group, int nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, int *array, int *anynul, int *status); int ffg3de(fitsfile *fptr, long group, float nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, float *array, int *anynul, int *status); int ffg3dd(fitsfile *fptr, long group, double nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, double *array, int *anynul, int *status); int ffgsvb(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned char nulval, unsigned char *array, int *anynul, int *status); int ffgsvsb(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, signed char nulval, signed char *array, int *anynul, int *status); int ffgsvui(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned short nulval, unsigned short *array, int *anynul, int *status); int ffgsvi(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, short nulval, short *array, int *anynul, int *status); int ffgsvuj(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned long nulval, unsigned long *array, int *anynul, int *status); int ffgsvj(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, long nulval, long *array, int *anynul, int *status); int ffgsvjj(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, LONGLONG nulval, LONGLONG *array, int *anynul, int *status); int ffgsvuk(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned int nulval, unsigned int *array, int *anynul, int *status); int ffgsvk(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, int nulval, int *array, int *anynul, int *status); int ffgsve(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, float nulval, float *array, int *anynul, int *status); int ffgsvd(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, double nulval, double *array, int *anynul, int *status); int ffgsfb(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned char *array, char *flagval, int *anynul, int *status); int ffgsfsb(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, signed char *array, char *flagval, int *anynul, int *status); int ffgsfui(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned short *array, char *flagval, int *anynul, int *status); int ffgsfi(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, short *array, char *flagval, int *anynul, int *status); int ffgsfuj(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned long *array, char *flagval, int *anynul, int *status); int ffgsfj(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, long *array, char *flagval, int *anynul, int *status); int ffgsfjj(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, LONGLONG *array, char *flagval, int *anynul, int *status); int ffgsfuk(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned int *array, char *flagval, int *anynul, int *status); int ffgsfk(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, int *array, char *flagval, int *anynul, int *status); int ffgsfe(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, float *array, char *flagval, int *anynul, int *status); int ffgsfd(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, double *array, char *flagval, int *anynul, int *status); int ffggpb(fitsfile *fptr, long group, long firstelem, long nelem, unsigned char *array, int *status); int ffggpsb(fitsfile *fptr, long group, long firstelem, long nelem, signed char *array, int *status); int ffggpui(fitsfile *fptr, long group, long firstelem, long nelem, unsigned short *array, int *status); int ffggpi(fitsfile *fptr, long group, long firstelem, long nelem, short *array, int *status); int ffggpuj(fitsfile *fptr, long group, long firstelem, long nelem, unsigned long *array, int *status); int ffggpj(fitsfile *fptr, long group, long firstelem, long nelem, long *array, int *status); int ffggpjj(fitsfile *fptr, long group, long firstelem, long nelem, LONGLONG *array, int *status); int ffggpuk(fitsfile *fptr, long group, long firstelem, long nelem, unsigned int *array, int *status); int ffggpk(fitsfile *fptr, long group, long firstelem, long nelem, int *array, int *status); int ffggpe(fitsfile *fptr, long group, long firstelem, long nelem, float *array, int *status); int ffggpd(fitsfile *fptr, long group, long firstelem, long nelem, double *array, int *status); /*--------------------- read column elements -------------*/ int ffgcv( fitsfile *fptr, int datatype, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, void *nulval, void *array, int *anynul, int *status); int ffgcf( fitsfile *fptr, int datatype, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, void *array, char *nullarray, int *anynul, int *status); int ffgcvs(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char *nulval, char **array, int *anynul, int *status); int ffgcl (fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char *array, int *status); int ffgcvl (fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char nulval, char *array, int *anynul, int *status); int ffgcvb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned char nulval, unsigned char *array, int *anynul, int *status); int ffgcvsb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, signed char nulval, signed char *array, int *anynul, int *status); int ffgcvui(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned short nulval, unsigned short *array, int *anynul, int *status); int ffgcvi(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, short nulval, short *array, int *anynul, int *status); int ffgcvuj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned long nulval, unsigned long *array, int *anynul, int *status); int ffgcvj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long nulval, long *array, int *anynul, int *status); int ffgcvjj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, LONGLONG nulval, LONGLONG *array, int *anynul, int *status); int ffgcvuk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned int nulval, unsigned int *array, int *anynul, int *status); int ffgcvk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int nulval, int *array, int *anynul, int *status); int ffgcve(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, float nulval, float *array, int *anynul, int *status); int ffgcvd(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, double nulval, double *array, int *anynul, int *status); int ffgcvc(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, float nulval, float *array, int *anynul, int *status); int ffgcvm(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, double nulval, double *array, int *anynul, int *status); int ffgcx(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstbit, LONGLONG nbits, char *larray, int *status); int ffgcxui(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG nrows, long firstbit, int nbits, unsigned short *array, int *status); int ffgcxuk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG nrows, long firstbit, int nbits, unsigned int *array, int *status); int ffgcfs(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char **array, char *nularray, int *anynul, int *status); int ffgcfl(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char *array, char *nularray, int *anynul, int *status); int ffgcfb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned char *array, char *nularray, int *anynul, int *status); int ffgcfsb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, signed char *array, char *nularray, int *anynul, int *status); int ffgcfui(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned short *array, char *nularray, int *anynul, int *status); int ffgcfi(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, short *array, char *nularray, int *anynul, int *status); int ffgcfuj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned long *array, char *nularray, int *anynul, int *status); int ffgcfj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long *array, char *nularray, int *anynul, int *status); int ffgcfjj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, LONGLONG *array, char *nularray, int *anynul, int *status); int ffgcfuk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned int *array, char *nularray, int *anynul, int *status); int ffgcfk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int *array, char *nularray, int *anynul, int *status); int ffgcfe(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, float *array, char *nularray, int *anynul, int *status); int ffgcfd(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, double *array, char *nularray, int *anynul, int *status); int ffgcfc(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, float *array, char *nularray, int *anynul, int *status); int ffgcfm(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, double *array, char *nularray, int *anynul, int *status); int ffgdes(fitsfile *fptr, int colnum, LONGLONG rownum, long *length, long *heapaddr, int *status); int ffgdesll(fitsfile *fptr, int colnum, LONGLONG rownum, LONGLONG *length, LONGLONG *heapaddr, int *status); int ffgdess(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG nrows, long *length, long *heapaddr, int *status); int ffgdessll(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG nrows, LONGLONG *length, LONGLONG *heapaddr, int *status); int ffpdes(fitsfile *fptr, int colnum, LONGLONG rownum, LONGLONG length, LONGLONG heapaddr, int *status); int fftheap(fitsfile *fptr, LONGLONG *heapsize, LONGLONG *unused, LONGLONG *overlap, int *valid, int *status); int ffcmph(fitsfile *fptr, int *status); int ffgtbb(fitsfile *fptr, LONGLONG firstrow, LONGLONG firstchar, LONGLONG nchars, unsigned char *values, int *status); int ffgextn(fitsfile *fptr, LONGLONG offset, LONGLONG nelem, void *array, int *status); int ffpextn(fitsfile *fptr, LONGLONG offset, LONGLONG nelem, void *array, int *status); /*------------ write primary array or image elements -------------*/ int ffppx(fitsfile *fptr, int datatype, long *firstpix, LONGLONG nelem, void *array, int *status); int ffppxll(fitsfile *fptr, int datatype, LONGLONG *firstpix, LONGLONG nelem, void *array, int *status); int ffppxn(fitsfile *fptr, int datatype, long *firstpix, LONGLONG nelem, void *array, void *nulval, int *status); int ffppxnll(fitsfile *fptr, int datatype, LONGLONG *firstpix, LONGLONG nelem, void *array, void *nulval, int *status); int ffppr(fitsfile *fptr, int datatype, LONGLONG firstelem, LONGLONG nelem, void *array, int *status); int ffpprb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned char *array, int *status); int ffpprsb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, signed char *array, int *status); int ffpprui(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned short *array, int *status); int ffppri(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, short *array, int *status); int ffppruj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned long *array, int *status); int ffpprj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, long *array, int *status); int ffppruk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned int *array, int *status); int ffpprk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, int *array, int *status); int ffppre(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, float *array, int *status); int ffpprd(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, double *array, int *status); int ffpprjj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, LONGLONG *array, int *status); int ffppru(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, int *status); int ffpprn(fitsfile *fptr, LONGLONG firstelem, LONGLONG nelem, int *status); int ffppn(fitsfile *fptr, int datatype, LONGLONG firstelem, LONGLONG nelem, void *array, void *nulval, int *status); int ffppnb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned char *array, unsigned char nulval, int *status); int ffppnsb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, signed char *array, signed char nulval, int *status); int ffppnui(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned short *array, unsigned short nulval, int *status); int ffppni(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, short *array, short nulval, int *status); int ffppnj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, long *array, long nulval, int *status); int ffppnuj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned long *array, unsigned long nulval, int *status); int ffppnuk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned int *array, unsigned int nulval, int *status); int ffppnk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, int *array, int nulval, int *status); int ffppne(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, float *array, float nulval, int *status); int ffppnd(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, double *array, double nulval, int *status); int ffppnjj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, LONGLONG *array, LONGLONG nulval, int *status); int ffp2db(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned char *array, int *status); int ffp2dsb(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, signed char *array, int *status); int ffp2dui(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned short *array, int *status); int ffp2di(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, short *array, int *status); int ffp2duj(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned long *array, int *status); int ffp2dj(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, long *array, int *status); int ffp2duk(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned int *array, int *status); int ffp2dk(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, int *array, int *status); int ffp2de(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, float *array, int *status); int ffp2dd(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, double *array, int *status); int ffp2djj(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, LONGLONG *array, int *status); int ffp3db(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned char *array, int *status); int ffp3dsb(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, signed char *array, int *status); int ffp3dui(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned short *array, int *status); int ffp3di(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, short *array, int *status); int ffp3duj(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned long *array, int *status); int ffp3dj(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, long *array, int *status); int ffp3duk(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned int *array, int *status); int ffp3dk(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, int *array, int *status); int ffp3de(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, float *array, int *status); int ffp3dd(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, double *array, int *status); int ffp3djj(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, LONGLONG *array, int *status); int ffpss(fitsfile *fptr, int datatype, long *fpixel, long *lpixel, void *array, int *status); int ffpssb(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, unsigned char *array, int *status); int ffpsssb(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, signed char *array, int *status); int ffpssui(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, unsigned short *array, int *status); int ffpssi(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, short *array, int *status); int ffpssuj(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, unsigned long *array, int *status); int ffpssj(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, long *array, int *status); int ffpssuk(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, unsigned int *array, int *status); int ffpssk(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, int *array, int *status); int ffpsse(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, float *array, int *status); int ffpssd(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, double *array, int *status); int ffpssjj(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, LONGLONG *array, int *status); int ffpgpb(fitsfile *fptr, long group, long firstelem, long nelem, unsigned char *array, int *status); int ffpgpsb(fitsfile *fptr, long group, long firstelem, long nelem, signed char *array, int *status); int ffpgpui(fitsfile *fptr, long group, long firstelem, long nelem, unsigned short *array, int *status); int ffpgpi(fitsfile *fptr, long group, long firstelem, long nelem, short *array, int *status); int ffpgpuj(fitsfile *fptr, long group, long firstelem, long nelem, unsigned long *array, int *status); int ffpgpj(fitsfile *fptr, long group, long firstelem, long nelem, long *array, int *status); int ffpgpuk(fitsfile *fptr, long group, long firstelem, long nelem, unsigned int *array, int *status); int ffpgpk(fitsfile *fptr, long group, long firstelem, long nelem, int *array, int *status); int ffpgpe(fitsfile *fptr, long group, long firstelem, long nelem, float *array, int *status); int ffpgpd(fitsfile *fptr, long group, long firstelem, long nelem, double *array, int *status); int ffpgpjj(fitsfile *fptr, long group, long firstelem, long nelem, LONGLONG *array, int *status); /*--------------------- iterator functions -------------*/ int fits_iter_set_by_name(iteratorCol *col, fitsfile *fptr, char *colname, int datatype, int iotype); int fits_iter_set_by_num(iteratorCol *col, fitsfile *fptr, int colnum, int datatype, int iotype); int fits_iter_set_file(iteratorCol *col, fitsfile *fptr); int fits_iter_set_colname(iteratorCol *col, char *colname); int fits_iter_set_colnum(iteratorCol *col, int colnum); int fits_iter_set_datatype(iteratorCol *col, int datatype); int fits_iter_set_iotype(iteratorCol *col, int iotype); fitsfile * fits_iter_get_file(iteratorCol *col); char * fits_iter_get_colname(iteratorCol *col); int fits_iter_get_colnum(iteratorCol *col); int fits_iter_get_datatype(iteratorCol *col); int fits_iter_get_iotype(iteratorCol *col); void * fits_iter_get_array(iteratorCol *col); long fits_iter_get_tlmin(iteratorCol *col); long fits_iter_get_tlmax(iteratorCol *col); long fits_iter_get_repeat(iteratorCol *col); char * fits_iter_get_tunit(iteratorCol *col); char * fits_iter_get_tdisp(iteratorCol *col); int ffiter(int ncols, iteratorCol *data, long offset, long nPerLoop, int (*workFn)( long totaln, long offset, long firstn, long nvalues, int narrays, iteratorCol *data, void *userPointer), void *userPointer, int *status); /*--------------------- write column elements -------------*/ int ffpcl(fitsfile *fptr, int datatype, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, void *array, int *status); int ffpcls(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char **array, int *status); int ffpcll(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char *array, int *status); int ffpclb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned char *array, int *status); int ffpclsb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, signed char *array, int *status); int ffpclui(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned short *array, int *status); int ffpcli(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, short *array, int *status); int ffpcluj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned long *array, int *status); int ffpclj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long *array, int *status); int ffpcluk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned int *array, int *status); int ffpclk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int *array, int *status); int ffpcle(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, float *array, int *status); int ffpcld(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, double *array, int *status); int ffpclc(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, float *array, int *status); int ffpclm(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, double *array, int *status); int ffpclu(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int *status); int ffprwu(fitsfile *fptr, LONGLONG firstrow, LONGLONG nrows, int *status); int ffpcljj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, LONGLONG *array, int *status); int ffpclx(fitsfile *fptr, int colnum, LONGLONG frow, long fbit, long nbit, char *larray, int *status); int ffpcn(fitsfile *fptr, int datatype, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, void *array, void *nulval, int *status); int ffpcns( fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char **array, char *nulvalue, int *status); int ffpcnl( fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char *array, char nulvalue, int *status); int ffpcnb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned char *array, unsigned char nulvalue, int *status); int ffpcnsb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, signed char *array, signed char nulvalue, int *status); int ffpcnui(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned short *array, unsigned short nulvalue, int *status); int ffpcni(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, short *array, short nulvalue, int *status); int ffpcnuj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned long *array, unsigned long nulvalue, int *status); int ffpcnj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long *array, long nulvalue, int *status); int ffpcnuk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned int *array, unsigned int nulvalue, int *status); int ffpcnk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int *array, int nulvalue, int *status); int ffpcne(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, float *array, float nulvalue, int *status); int ffpcnd(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, double *array, double nulvalue, int *status); int ffpcnjj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, LONGLONG *array, LONGLONG nulvalue, int *status); int ffptbb(fitsfile *fptr, LONGLONG firstrow, LONGLONG firstchar, LONGLONG nchars, unsigned char *values, int *status); int ffirow(fitsfile *fptr, LONGLONG firstrow, LONGLONG nrows, int *status); int ffdrow(fitsfile *fptr, LONGLONG firstrow, LONGLONG nrows, int *status); int ffdrrg(fitsfile *fptr, char *ranges, int *status); int ffdrws(fitsfile *fptr, long *rownum, long nrows, int *status); int ffdrwsll(fitsfile *fptr, LONGLONG *rownum, LONGLONG nrows, int *status); int fficol(fitsfile *fptr, int numcol, char *ttype, char *tform, int *status); int fficls(fitsfile *fptr, int firstcol, int ncols, char **ttype, char **tform, int *status); int ffmvec(fitsfile *fptr, int colnum, LONGLONG newveclen, int *status); int ffdcol(fitsfile *fptr, int numcol, int *status); int ffcpcl(fitsfile *infptr, fitsfile *outfptr, int incol, int outcol, int create_col, int *status); /*--------------------- WCS Utilities ------------------*/ int ffgics(fitsfile *fptr, double *xrval, double *yrval, double *xrpix, double *yrpix, double *xinc, double *yinc, double *rot, char *type, int *status); int ffgtcs(fitsfile *fptr, int xcol, int ycol, double *xrval, double *yrval, double *xrpix, double *yrpix, double *xinc, double *yinc, double *rot, char *type, int *status); int ffwldp(double xpix, double ypix, double xref, double yref, double xrefpix, double yrefpix, double xinc, double yinc, double rot, char *type, double *xpos, double *ypos, int *status); int ffxypx(double xpos, double ypos, double xref, double yref, double xrefpix, double yrefpix, double xinc, double yinc, double rot, char *type, double *xpix, double *ypix, int *status); /* WCS support routines (provide interface to Doug Mink's WCS library */ int ffgiwcs(fitsfile *fptr, char **header, int *status); int ffgtwcs(fitsfile *fptr, int xcol, int ycol, char **header, int *status); /*--------------------- lexical parsing routines ------------------*/ int fftexp( fitsfile *fptr, char *expr, int maxdim, int *datatype, long *nelem, int *naxis, long *naxes, int *status ); int fffrow( fitsfile *infptr, char *expr, long firstrow, long nrows, long *n_good_rows, char *row_status, int *status); int ffffrw( fitsfile *fptr, char *expr, long *rownum, int *status); int fffrwc( fitsfile *fptr, char *expr, char *timeCol, char *parCol, char *valCol, long ntimes, double *times, char *time_status, int *status ); int ffsrow( fitsfile *infptr, fitsfile *outfptr, char *expr, int *status); int ffcrow( fitsfile *fptr, int datatype, char *expr, long firstrow, long nelements, void *nulval, void *array, int *anynul, int *status ); int ffcalc_rng( fitsfile *infptr, char *expr, fitsfile *outfptr, char *parName, char *parInfo, int nRngs, long *start, long *end, int *status ); int ffcalc( fitsfile *infptr, char *expr, fitsfile *outfptr, char *parName, char *parInfo, int *status ); /* ffhist is not really intended as a user-callable routine */ /* but it may be useful for some specialized applications */ int ffhist(fitsfile **fptr, char *outfile, int imagetype, int naxis, char colname[4][FLEN_VALUE], double *minin, double *maxin, double *binsizein, char minname[4][FLEN_VALUE], char maxname[4][FLEN_VALUE], char binname[4][FLEN_VALUE], double weightin, char wtcol[FLEN_VALUE], int recip, char *rowselect, int *status); int fits_select_image_section(fitsfile **fptr, char *outfile, char *imagesection, int *status); int fits_copy_image_section(fitsfile *infptr, fitsfile *outfile, char *imagesection, int *status); typedef struct { /* input(s) */ int count; char ** path; char ** tag; fitsfile ** ifptr; char * expression; /* output control */ int bitpix; long blank; fitsfile * ofptr; char keyword[FLEN_KEYWORD]; char comment[FLEN_COMMENT]; } PixelFilter; int fits_pixel_filter (PixelFilter * filter, int * status); /*--------------------- grouping routines ------------------*/ int ffgtcr(fitsfile *fptr, char *grpname, int grouptype, int *status); int ffgtis(fitsfile *fptr, char *grpname, int grouptype, int *status); int ffgtch(fitsfile *gfptr, int grouptype, int *status); int ffgtrm(fitsfile *gfptr, int rmopt, int *status); int ffgtcp(fitsfile *infptr, fitsfile *outfptr, int cpopt, int *status); int ffgtmg(fitsfile *infptr, fitsfile *outfptr, int mgopt, int *status); int ffgtcm(fitsfile *gfptr, int cmopt, int *status); int ffgtvf(fitsfile *gfptr, long *firstfailed, int *status); int ffgtop(fitsfile *mfptr,int group,fitsfile **gfptr,int *status); int ffgtam(fitsfile *gfptr, fitsfile *mfptr, int hdupos, int *status); int ffgtnm(fitsfile *gfptr, long *nmembers, int *status); int ffgmng(fitsfile *mfptr, long *nmembers, int *status); int ffgmop(fitsfile *gfptr, long member, fitsfile **mfptr, int *status); int ffgmcp(fitsfile *gfptr, fitsfile *mfptr, long member, int cpopt, int *status); int ffgmtf(fitsfile *infptr, fitsfile *outfptr, long member, int tfopt, int *status); int ffgmrm(fitsfile *fptr, long member, int rmopt, int *status); /*--------------------- group template parser routines ------------------*/ int fits_execute_template(fitsfile *ff, char *ngp_template, int *status); /*--------------------- image compression routines ------------------*/ int fits_set_compression_type(fitsfile *fptr, int ctype, int *status); int fits_set_tile_dim(fitsfile *fptr, int ndim, long *dims, int *status); int fits_set_noise_bits(fitsfile *fptr, int noisebits, int *status); int fits_set_hcomp_scale(fitsfile *fptr, int scale, int *status); int fits_set_hcomp_smooth(fitsfile *fptr, int smooth, int *status); int fits_get_compression_type(fitsfile *fptr, int *ctype, int *status); int fits_get_tile_dim(fitsfile *fptr, int ndim, long *dims, int *status); int fits_get_noise_bits(fitsfile *fptr, int *noisebits, int *status); int fits_get_hcomp_scale(fitsfile *fptr, int *scale, int *status); int fits_get_hcomp_smooth(fitsfile *fptr, int *smooth, int *status); int fits_img_compress(fitsfile *infptr, fitsfile *outfptr, int *status); int fits_compress_img(fitsfile *infptr, fitsfile *outfptr, int compress_type, long *tilesize, int parm1, int parm2, int *status); int fits_is_compressed_image(fitsfile *fptr, int *status); int fits_decompress_img (fitsfile *infptr, fitsfile *outfptr, int *status); int fits_img_decompress (fitsfile *infptr, fitsfile *outfptr, int *status); /* H-compress routines */ int fits_hcompress(int *a, int nx, int ny, int scale, char *output, long *nbytes, int *status); int fits_hcompress64(LONGLONG *a, int nx, int ny, int scale, char *output, long *nbytes, int *status); int fits_hdecompress(unsigned char *input, int smooth, int *a, int *nx, int *ny, int *scale, int *status); int fits_hdecompress64(unsigned char *input, int smooth, LONGLONG *a, int *nx, int *ny, int *scale, int *status); int fits_rms_float (float fdata[], int nx, float in_null_value, double *rms, int *status); int fits_rms_short (short fdata[], int nx, short in_null_value, double *rms, int *status); /* The following exclusion if __CINT__ is defined is needed for ROOT */ #ifndef __CINT__ #ifdef __cplusplus } #endif #endif #endif skycat-3.1.2-starlink-1b/astrotcl/cfitsio/fitsio2.h000066400000000000000000001554131215713201500221710ustar00rootroot00000000000000#ifndef _FITSIO2_H #define _FITSIO2_H #include "fitsio.h" /* If REPLACE_LINKS is defined, then whenever CFITSIO fails to open a file with write access because it is a soft link to a file that only has read access, then CFITSIO will attempt to replace the link with a local copy of the file, with write access. This feature was originally added to support the ftools in the Hera environment, where many of the user's data file are soft links. */ #if defined(BUILD_HERA) #define REPLACE_LINKS 1 #endif #define USE_LARGE_VALUE -99 /* flag used when writing images */ #define DBUFFSIZE 28800 /* size of data buffer in bytes */ #define NIOBUF 40 /* number of IO buffers to create */ /* !! Significantly increasing NIOBUF may degrade performance !! */ #define NMAXFILES 300 /* maximum number of FITS files that can be opened */ /* CFITSIO will allocate (NMAXFILES * 80) bytes of memory */ #define IOBUFLEN 2880 /* size in bytes of each IO buffer (DONT CHANGE!) */ #define MINDIRECT 8640 /* minimum size for direct reads and writes */ /* MINDIRECT must have a value >= 8640 */ /* it is useful to identify certain specific types of machines */ #define NATIVE 0 /* machine that uses non-byteswapped IEEE formats */ #define OTHERTYPE 1 /* any other type of machine */ #define VAXVMS 3 /* uses an odd floating point format */ #define ALPHAVMS 4 /* uses an odd floating point format */ #define IBMPC 5 /* used in drvrfile.c to work around a bug on PCs */ #define CRAY 6 /* requires a special NaN test algorithm */ #define GFLOAT 1 /* used for VMS */ #define IEEEFLOAT 2 /* used for VMS */ /* ======================================================================= */ /* The following logic is used to determine the type machine, */ /* whether the bytes are swapped, and the number of bits in a long value */ /* ======================================================================= */ /* The following platforms have sizeof(long) == 8 */ /* This block of code should match a similar block in fitsio.h */ /* and the block of code at the beginning of f77_wrap.h */ #if defined(__alpha) && ( defined(__unix__) || defined(__NetBSD__) ) /* old Dec Alpha platforms running OSF */ #define BYTESWAPPED TRUE #define LONGSIZE 64 #elif defined(__sparcv9) /* SUN Solaris7 in 64-bit mode */ #define BYTESWAPPED FALSE #define MACHINE NATIVE #define LONGSIZE 64 #elif defined(__ia64__) || defined(__x86_64__) /* Intel itanium 64-bit PC, or AMD opteron 64-bit PC */ #define BYTESWAPPED TRUE #define LONGSIZE 64 #elif defined(_SX) /* Nec SuperUx */ #define BYTESWAPPED FALSE #define MACHINE NATIVE #define LONGSIZE 64 #elif defined(__powerpc64__) || defined(__64BIT__) /* IBM 64-bit AIX powerpc*/ /* could also test for __ppc64__ or __PPC64 */ #define BYTESWAPPED FALSE #define MACHINE NATIVE #define LONGSIZE 64 #elif defined(_MIPS_SZLONG) # if defined(MIPSEL) # define BYTESWAPPED TRUE # else # define BYTESWAPPED FALSE # define MACHINE NATIVE # endif # if _MIPS_SZLONG == 32 # define LONGSIZE 32 # elif _MIPS_SZLONG == 64 # define LONGSIZE 64 # else # error "can't handle long size given by _MIPS_SZLONG" # endif /* ============================================================== */ /* the following are all 32-bit byteswapped platforms */ #elif defined(vax) && defined(VMS) #define MACHINE VAXVMS #define BYTESWAPPED TRUE #elif defined(__alpha) && defined(__VMS) #if (__D_FLOAT == TRUE) /* this float option is the same as for VAX/VMS machines. */ #define MACHINE VAXVMS #define BYTESWAPPED TRUE #elif (__G_FLOAT == TRUE) /* G_FLOAT is the default for ALPHA VMS systems */ #define MACHINE ALPHAVMS #define BYTESWAPPED TRUE #define FLOATTYPE GFLOAT #elif (__IEEE_FLOAT == TRUE) #define MACHINE ALPHAVMS #define BYTESWAPPED TRUE #define FLOATTYPE IEEEFLOAT #endif /* end of alpha VMS case */ #elif defined(ultrix) && defined(unix) /* old Dec ultrix machines */ #define BYTESWAPPED TRUE #elif defined(__i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) \ || defined(_MSC_VER) || defined(__BORLANDC__) || defined(__TURBOC__) \ || defined(_NI_mswin_) || defined(__EMX__) /* generic 32-bit IBM PC */ #define MACHINE IBMPC #define BYTESWAPPED TRUE #elif defined(__arm__) /* This assumes all ARM are little endian. In the future, it might be */ /* necessary to use "if defined(__ARMEL__)" to distinguish little from big. */ /* (__ARMEL__ would be defined on little-endian, but not on big-endian). */ #define BYTESWAPPED TRUE #else /* assume all other machine uses the same IEEE formats as used in FITS files */ /* e.g., Macs fall into this category */ #define MACHINE NATIVE #define BYTESWAPPED FALSE #endif #ifndef MACHINE #define MACHINE OTHERTYPE #endif /* assume longs are 4 bytes long, unless previously set otherwise */ #ifndef LONGSIZE #define LONGSIZE 32 #endif /* end of block that determine long size and byte swapping */ /* ==================================================================== */ #define IGNORE_EOF 1 #define REPORT_EOF 0 #define DATA_UNDEFINED -1 #define NULL_UNDEFINED 1234554321 #define ASCII_NULL_UNDEFINED 1 /* indicate no defined null value */ #define maxvalue(A,B) ((A) > (B) ? (A) : (B)) #define minvalue(A,B) ((A) < (B) ? (A) : (B)) /* faster string comparison macros */ #define FSTRCMP(a,b) ((a)[0]<(b)[0]? -1:(a)[0]>(b)[0]?1:strcmp((a),(b))) #define FSTRNCMP(a,b,n) ((a)[0]<(b)[0]?-1:(a)[0]>(b)[0]?1:strncmp((a),(b),(n))) #if defined(__VMS) || defined(VMS) #define FNANMASK 0xFFFF /* mask all bits */ #define DNANMASK 0xFFFF /* mask all bits */ #else #define FNANMASK 0x7F80 /* mask bits 1 - 8; all set on NaNs */ /* all 0 on underflow or 0. */ #define DNANMASK 0x7FF0 /* mask bits 1 - 11; all set on NaNs */ /* all 0 on underflow or 0. */ #endif #if MACHINE == CRAY /* Cray machines: the large negative integer corresponds to the 3 most sig digits set to 1. If these 3 bits are set in a floating point number (64 bits), then it represents a reserved value (i.e., a NaN) */ #define fnan(L) ( (L) >= 0xE000000000000000 ? 1 : 0) ) #else /* these functions work for both big and little endian machines */ /* that use the IEEE floating point format for internal numbers */ /* These functions tests whether the float value is a reserved IEEE */ /* value such as a Not-a-Number (NaN), or underflow, overflow, or */ /* infinity. The functions returns 1 if the value is a NaN, overflow */ /* or infinity; it returns 2 if the value is an denormalized underflow */ /* value; otherwise it returns 0. fnan tests floats, dnan tests doubles */ #define fnan(L) \ ( (L & FNANMASK) == FNANMASK ? 1 : (L & FNANMASK) == 0 ? 2 : 0) #define dnan(L) \ ( (L & DNANMASK) == DNANMASK ? 1 : (L & DNANMASK) == 0 ? 2 : 0) #endif #define DSCHAR_MAX 127.49 /* max double value that fits in an signed char */ #define DSCHAR_MIN -128.49 /* min double value that fits in an signed char */ #define DUCHAR_MAX 255.49 /* max double value that fits in an unsigned char */ #define DUCHAR_MIN -0.49 /* min double value that fits in an unsigned char */ #define DUSHRT_MAX 65535.49 /* max double value that fits in a unsigned short*/ #define DUSHRT_MIN -0.49 /* min double value that fits in an unsigned short */ #define DSHRT_MAX 32767.49 /* max double value that fits in a short */ #define DSHRT_MIN -32768.49 /* min double value that fits in a short */ #if LONGSIZE == 32 # define DLONG_MAX 2147483647.49 /* max double value that fits in a long */ # define DLONG_MIN -2147483648.49 /* min double value that fits in a long */ # define DULONG_MAX 4294967295.49 /* max double that fits in a unsigned long */ #else # define DLONG_MAX 9.2233720368547752E18 /* max double value long */ # define DLONG_MIN -9.2233720368547752E18 /* min double value long */ # define DULONG_MAX 1.84467440737095504E19 /* max double value ulong */ #endif #define DULONG_MIN -0.49 /* min double value that fits in an unsigned long */ #define DLONGLONG_MAX 9.2233720368547755807E18 /* max double value longlong */ #define DLONGLONG_MIN -9.2233720368547755808E18 /* min double value longlong */ #define DUINT_MAX 4294967295.49 /* max dbl that fits in a unsigned 4-byte int */ #define DUINT_MIN -0.49 /* min dbl that fits in an unsigned 4-byte int */ #define DINT_MAX 2147483647.49 /* max double value that fits in a 4-byte int */ #define DINT_MIN -2147483648.49 /* min double value that fits in a 4-byte int */ #ifndef UINT32_MAX #define UINT32_MAX 4294967295U /* max unsigned 32-bit integer */ #endif #ifndef INT32_MAX #define INT32_MAX 2147483647 /* max 32-bit integer */ #endif #ifndef INT32_MIN #define INT32_MIN (-INT32_MAX -1) /* min 32-bit integer */ #endif #ifndef LONGLONG_MAX #ifdef LLONG_MAX /* Linux and Solaris definition */ #define LONGLONG_MAX LLONG_MAX #define LONGLONG_MIN LLONG_MIN #elif defined(LONG_LONG_MAX) #define LONGLONG_MAX LONG_LONG_MAX #define LONGLONG_MIN LONG_LONG_MIN #elif defined(__LONG_LONG_MAX__) /* Mac OS X & CYGWIN defintion */ #define LONGLONG_MAX __LONG_LONG_MAX__ #define LONGLONG_MIN (-LONGLONG_MAX -1LL) #elif defined(INT64_MAX) /* windows definition */ #define LONGLONG_MAX INT64_MAX #define LONGLONG_MIN INT64_MIN #elif defined(_I64_MAX) /* windows definition */ #define LONGLONG_MAX _I64_MAX #define LONGLONG_MIN _I64_MIN #elif (LONGSIZE == 64) /* sizeof(long) = 64 */ #define LONGLONG_MAX 9223372036854775807L /* max 64-bit integer */ #define LONGLONG_MIN (-LONGLONG_MAX -1L) /* min 64-bit integer */ #else /* define a default value, even if it is never used */ #define LONGLONG_MAX 9223372036854775807LL /* max 64-bit integer */ #define LONGLONG_MIN (-LONGLONG_MAX -1LL) /* min 64-bit integer */ #endif #endif /* end of ndef LONGLONG_MAX section */ #define COMPRESS_NULL_VALUE -2147483647 int ffmkky(char *keyname, char *keyval, char *comm, char *card, int *status); int ffgnky(fitsfile *fptr, char *card, int *status); void ffcfmt(char *tform, char *cform); void ffcdsp(char *tform, char *cform); void ffswap2(short *values, long nvalues); void ffswap4(INT32BIT *values, long nvalues); void ffswap8(double *values, long nvalues); int ffi2c(LONGLONG ival, char *cval, int *status); int ffl2c(int lval, char *cval, int *status); int ffs2c(char *instr, char *outstr, int *status); int ffr2f(float fval, int decim, char *cval, int *status); int ffr2e(float fval, int decim, char *cval, int *status); int ffd2f(double dval, int decim, char *cval, int *status); int ffd2e(double dval, int decim, char *cval, int *status); int ffc2ii(char *cval, long *ival, int *status); int ffc2jj(char *cval, LONGLONG *ival, int *status); int ffc2ll(char *cval, int *lval, int *status); int ffc2rr(char *cval, float *fval, int *status); int ffc2dd(char *cval, double *dval, int *status); int ffc2x(char *cval, char *dtype, long *ival, int *lval, char *sval, double *dval, int *status); int ffc2s(char *instr, char *outstr, int *status); int ffc2i(char *cval, long *ival, int *status); int ffc2j(char *cval, LONGLONG *ival, int *status); int ffc2r(char *cval, float *fval, int *status); int ffc2d(char *cval, double *dval, int *status); int ffc2l(char *cval, int *lval, int *status); void ffxmsg(int action, char *err_message); int ffgcnt(fitsfile *fptr, char *value, int *status); int ffgtkn(fitsfile *fptr, int numkey, char *keyname, long *value, int *status); int ffgtknjj(fitsfile *fptr, int numkey, char *keyname, LONGLONG *value, int *status); int fftkyn(fitsfile *fptr, int numkey, char *keyname, char *value, int *status); int ffgphd(fitsfile *fptr, int maxdim, int *simple, int *bitpix, int *naxis, LONGLONG naxes[], long *pcount, long *gcount, int *extend, double *bscale, double *bzero, LONGLONG *blank, int *nspace, int *status); int ffgttb(fitsfile *fptr, LONGLONG *rowlen, LONGLONG *nrows, LONGLONG *pcount, long *tfield, int *status); int ffmkey(fitsfile *fptr, char *card, int *status); /* ffmbyt has been moved to fitsio.h */ int ffgbyt(fitsfile *fptr, LONGLONG nbytes, void *buffer, int *status); int ffpbyt(fitsfile *fptr, LONGLONG nbytes, void *buffer, int *status); int ffgbytoff(fitsfile *fptr, long gsize, long ngroups, long offset, void *buffer, int *status); int ffpbytoff(fitsfile *fptr, long gsize, long ngroups, long offset, void *buffer, int *status); int ffldrc(fitsfile *fptr, long record, int err_mode, int *status); int ffwhbf(fitsfile *fptr, int *nbuff); int ffbfeof(fitsfile *fptr, int *status); int ffbfwt(int nbuff, int *status); int fits_get_num_files(void); int ffpxsz(int datatype); int ffourl(char *url, char *urltype, char *outfile, char *tmplfile, char *compspec, int *status); int ffparsecompspec(fitsfile *fptr, char *compspec, int *status); int ffoptplt(fitsfile *fptr, const char *tempname, int *status); int fits_is_this_a_copy(char *urltype); int fits_store_Fptr(FITSfile *Fptr, int *status); int fits_clear_Fptr(FITSfile *Fptr, int *status); int fits_already_open(fitsfile **fptr, char *url, char *urltype, char *infile, char *extspec, char *rowfilter, char *binspec, char *colspec, int mode,int *isopen, int *status); int ffedit_columns(fitsfile **fptr, char *outfile, char *expr, int *status); int fits_get_col_minmax(fitsfile *fptr, int colnum, float *datamin, float *datamax, int *status); int ffwritehisto(long totaln, long offset, long firstn, long nvalues, int narrays, iteratorCol *imagepars, void *userPointer); int ffcalchist(long totalrows, long offset, long firstrow, long nrows, int ncols, iteratorCol *colpars, void *userPointer); int ffrhdu(fitsfile *fptr, int *hdutype, int *status); int ffpinit(fitsfile *fptr, int *status); int ffainit(fitsfile *fptr, int *status); int ffbinit(fitsfile *fptr, int *status); int ffchdu(fitsfile *fptr, int *status); int ffwend(fitsfile *fptr, int *status); int ffpdfl(fitsfile *fptr, int *status); int ffuptf(fitsfile *fptr, int *status); int ffdblk(fitsfile *fptr, long nblocks, int *status); int ffgext(fitsfile *fptr, int moveto, int *exttype, int *status); int ffgtbc(fitsfile *fptr, LONGLONG *totalwidth, int *status); int ffgtbp(fitsfile *fptr, char *name, char *value, int *status); int ffiblk(fitsfile *fptr, long nblock, int headdata, int *status); int ffshft(fitsfile *fptr, LONGLONG firstbyte, LONGLONG nbytes, LONGLONG nshift, int *status); int ffgcprll(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int writemode, double *scale, double *zero, char *tform, long *twidth, int *tcode, int *maxelem, LONGLONG *startpos, LONGLONG *elemnum, long *incre, LONGLONG *repeat, LONGLONG *rowlen, int *hdutype, LONGLONG *tnull, char *snull, int *status); int ffflushx(FITSfile *fptr); int ffseek(FITSfile *fptr, LONGLONG position); int ffread(FITSfile *fptr, long nbytes, void *buffer, int *status); int ffwrite(FITSfile *fptr, long nbytes, void *buffer, int *status); int fftrun(fitsfile *fptr, LONGLONG filesize, int *status); int ffpcluc(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int *status); int ffgcll(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int nultyp, char nulval, char *array, char *nularray, int *anynul, int *status); int ffgcls(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int nultyp, char *nulval, char **array, char *nularray, int *anynul, int *status); int ffgcls2(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int nultyp, char *nulval, char **array, char *nularray, int *anynul, int *status); int ffgclb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, unsigned char nulval, unsigned char *array, char *nularray, int *anynul, int *status); int ffgclsb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, signed char nulval, signed char *array, char *nularray, int *anynul, int *status); int ffgclui(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, unsigned short nulval, unsigned short *array, char *nularray, int *anynul, int *status); int ffgcli(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, short nulval, short *array, char *nularray, int *anynul, int *status); int ffgcluj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, unsigned long nulval, unsigned long *array, char *nularray, int *anynul, int *status); int ffgcljj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, LONGLONG nulval, LONGLONG *array, char *nularray, int *anynul, int *status); int ffgclj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, long nulval, long *array, char *nularray, int *anynul, int *status); int ffgcluk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, unsigned int nulval, unsigned int *array, char *nularray, int *anynul, int *status); int ffgclk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, int nulval, int *array, char *nularray, int *anynul, int *status); int ffgcle(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, float nulval, float *array, char *nularray, int *anynul, int *status); int ffgcld(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, double nulval, double *array, char *nularray, int *anynul, int *status); int ffpi1b(fitsfile *fptr, long nelem, long incre, unsigned char *buffer, int *status); int ffpi2b(fitsfile *fptr, long nelem, long incre, short *buffer, int *status); int ffpi4b(fitsfile *fptr, long nelem, long incre, INT32BIT *buffer, int *status); int ffpi8b(fitsfile *fptr, long nelem, long incre, long *buffer, int *status); int ffpr4b(fitsfile *fptr, long nelem, long incre, float *buffer, int *status); int ffpr8b(fitsfile *fptr, long nelem, long incre, double *buffer, int *status); int ffgi1b(fitsfile *fptr, LONGLONG pos, long nelem, long incre, unsigned char *buffer, int *status); int ffgi2b(fitsfile *fptr, LONGLONG pos, long nelem, long incre, short *buffer, int *status); int ffgi4b(fitsfile *fptr, LONGLONG pos, long nelem, long incre, INT32BIT *buffer, int *status); int ffgi8b(fitsfile *fptr, LONGLONG pos, long nelem, long incre, long *buffer, int *status); int ffgr4b(fitsfile *fptr, LONGLONG pos, long nelem, long incre, float *buffer, int *status); int ffgr8b(fitsfile *fptr, LONGLONG pos, long nelem, long incre, double *buffer, int *status); int ffcins(fitsfile *fptr, LONGLONG naxis1, LONGLONG naxis2, LONGLONG nbytes, LONGLONG bytepos, int *status); int ffcdel(fitsfile *fptr, LONGLONG naxis1, LONGLONG naxis2, LONGLONG nbytes, LONGLONG bytepos, int *status); int ffkshf(fitsfile *fptr, int firstcol, int tfields, int nshift, int *status); int fffi1i1(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, unsigned char nullval, char *nullarray, int *anynull, unsigned char *output, int *status); int fffi2i1(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, unsigned char nullval, char *nullarray, int *anynull, unsigned char *output, int *status); int fffi4i1(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, unsigned char nullval, char *nullarray, int *anynull, unsigned char *output, int *status); int fffi8i1(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, unsigned char nullval, char *nullarray, int *anynull, unsigned char *output, int *status); int fffr4i1(float *input, long ntodo, double scale, double zero, int nullcheck, unsigned char nullval, char *nullarray, int *anynull, unsigned char *output, int *status); int fffr8i1(double *input, long ntodo, double scale, double zero, int nullcheck, unsigned char nullval, char *nullarray, int *anynull, unsigned char *output, int *status); int fffstri1(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, unsigned char nullval, char *nullarray, int *anynull, unsigned char *output, int *status); int fffi1s1(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, signed char nullval, char *nullarray, int *anynull, signed char *output, int *status); int fffi2s1(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, signed char nullval, char *nullarray, int *anynull, signed char *output, int *status); int fffi4s1(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, signed char nullval, char *nullarray, int *anynull, signed char *output, int *status); int fffi8s1(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, signed char nullval, char *nullarray, int *anynull, signed char *output, int *status); int fffr4s1(float *input, long ntodo, double scale, double zero, int nullcheck, signed char nullval, char *nullarray, int *anynull, signed char *output, int *status); int fffr8s1(double *input, long ntodo, double scale, double zero, int nullcheck, signed char nullval, char *nullarray, int *anynull, signed char *output, int *status); int fffstrs1(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, signed char nullval, char *nullarray, int *anynull, signed char *output, int *status); int fffi1u2(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, unsigned short nullval, char *nullarray, int *anynull, unsigned short *output, int *status); int fffi2u2(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, unsigned short nullval, char *nullarray, int *anynull, unsigned short *output, int *status); int fffi4u2(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, unsigned short nullval, char *nullarray, int *anynull, unsigned short *output, int *status); int fffi8u2(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, unsigned short nullval, char *nullarray, int *anynull, unsigned short *output, int *status); int fffr4u2(float *input, long ntodo, double scale, double zero, int nullcheck, unsigned short nullval, char *nullarray, int *anynull, unsigned short *output, int *status); int fffr8u2(double *input, long ntodo, double scale, double zero, int nullcheck, unsigned short nullval, char *nullarray, int *anynull, unsigned short *output, int *status); int fffstru2(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, unsigned short nullval, char *nullarray, int *anynull, unsigned short *output, int *status); int fffi1i2(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, short nullval, char *nullarray, int *anynull, short *output, int *status); int fffi2i2(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, short nullval, char *nullarray, int *anynull, short *output, int *status); int fffi4i2(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, short nullval, char *nullarray, int *anynull, short *output, int *status); int fffi8i2(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, short nullval, char *nullarray, int *anynull, short *output, int *status); int fffr4i2(float *input, long ntodo, double scale, double zero, int nullcheck, short nullval, char *nullarray, int *anynull, short *output, int *status); int fffr8i2(double *input, long ntodo, double scale, double zero, int nullcheck, short nullval, char *nullarray, int *anynull, short *output, int *status); int fffstri2(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, short nullval, char *nullarray, int *anynull, short *output, int *status); int fffi1u4(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, unsigned long nullval, char *nullarray, int *anynull, unsigned long *output, int *status); int fffi2u4(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, unsigned long nullval, char *nullarray, int *anynull, unsigned long *output, int *status); int fffi4u4(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, unsigned long nullval, char *nullarray, int *anynull, unsigned long *output, int *status); int fffi8u4(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, unsigned long nullval, char *nullarray, int *anynull, unsigned long *output, int *status); int fffr4u4(float *input, long ntodo, double scale, double zero, int nullcheck, unsigned long nullval, char *nullarray, int *anynull, unsigned long *output, int *status); int fffr8u4(double *input, long ntodo, double scale, double zero, int nullcheck, unsigned long nullval, char *nullarray, int *anynull, unsigned long *output, int *status); int fffstru4(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, unsigned long nullval, char *nullarray, int *anynull, unsigned long *output, int *status); int fffi1i4(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, long nullval, char *nullarray, int *anynull, long *output, int *status); int fffi2i4(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, long nullval, char *nullarray, int *anynull, long *output, int *status); int fffi4i4(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, long nullval, char *nullarray, int *anynull, long *output, int *status); int fffi8i4(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, long nullval, char *nullarray, int *anynull, long *output, int *status); int fffr4i4(float *input, long ntodo, double scale, double zero, int nullcheck, long nullval, char *nullarray, int *anynull, long *output, int *status); int fffr8i4(double *input, long ntodo, double scale, double zero, int nullcheck, long nullval, char *nullarray, int *anynull, long *output, int *status); int fffstri4(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, long nullval, char *nullarray, int *anynull, long *output, int *status); int fffi1int(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, int nullval, char *nullarray, int *anynull, int *output, int *status); int fffi2int(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, int nullval, char *nullarray, int *anynull, int *output, int *status); int fffi4int(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, int nullval, char *nullarray, int *anynull, int *output, int *status); int fffi8int(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, int nullval, char *nullarray, int *anynull, int *output, int *status); int fffr4int(float *input, long ntodo, double scale, double zero, int nullcheck, int nullval, char *nullarray, int *anynull, int *output, int *status); int fffr8int(double *input, long ntodo, double scale, double zero, int nullcheck, int nullval, char *nullarray, int *anynull, int *output, int *status); int fffstrint(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, int nullval, char *nullarray, int *anynull, int *output, int *status); int fffi1uint(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, unsigned int nullval, char *nullarray, int *anynull, unsigned int *output, int *status); int fffi2uint(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, unsigned int nullval, char *nullarray, int *anynull, unsigned int *output, int *status); int fffi4uint(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, unsigned int nullval, char *nullarray, int *anynull, unsigned int *output, int *status); int fffi8uint(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, unsigned int nullval, char *nullarray, int *anynull, unsigned int *output, int *status); int fffr4uint(float *input, long ntodo, double scale, double zero, int nullcheck, unsigned int nullval, char *nullarray, int *anynull, unsigned int *output, int *status); int fffr8uint(double *input, long ntodo, double scale, double zero, int nullcheck, unsigned int nullval, char *nullarray, int *anynull, unsigned int *output, int *status); int fffstruint(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, unsigned int nullval, char *nullarray, int *anynull, unsigned int *output, int *status); int fffi1i8(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, LONGLONG nullval, char *nullarray, int *anynull, LONGLONG *output, int *status); int fffi2i8(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, LONGLONG nullval, char *nullarray, int *anynull, LONGLONG *output, int *status); int fffi4i8(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, LONGLONG nullval, char *nullarray, int *anynull, LONGLONG *output, int *status); int fffi8i8(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, LONGLONG nullval, char *nullarray, int *anynull, LONGLONG *output, int *status); int fffr4i8(float *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG nullval, char *nullarray, int *anynull, LONGLONG *output, int *status); int fffr8i8(double *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG nullval, char *nullarray, int *anynull, LONGLONG *output, int *status); int fffstri8(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, LONGLONG nullval, char *nullarray, int *anynull, LONGLONG *output, int *status); int fffi1r4(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, float nullval, char *nullarray, int *anynull, float *output, int *status); int fffi2r4(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, float nullval, char *nullarray, int *anynull, float *output, int *status); int fffi4r4(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, float nullval, char *nullarray, int *anynull, float *output, int *status); int fffi8r4(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, float nullval, char *nullarray, int *anynull, float *output, int *status); int fffr4r4(float *input, long ntodo, double scale, double zero, int nullcheck, float nullval, char *nullarray, int *anynull, float *output, int *status); int fffr8r4(double *input, long ntodo, double scale, double zero, int nullcheck, float nullval, char *nullarray, int *anynull, float *output, int *status); int fffstrr4(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, float nullval, char *nullarray, int *anynull, float *output, int *status); int fffi1r8(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, double nullval, char *nullarray, int *anynull, double *output, int *status); int fffi2r8(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, double nullval, char *nullarray, int *anynull, double *output, int *status); int fffi4r8(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, double nullval, char *nullarray, int *anynull, double *output, int *status); int fffi8r8(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, double nullval, char *nullarray, int *anynull, double *output, int *status); int fffr4r8(float *input, long ntodo, double scale, double zero, int nullcheck, double nullval, char *nullarray, int *anynull, double *output, int *status); int fffr8r8(double *input, long ntodo, double scale, double zero, int nullcheck, double nullval, char *nullarray, int *anynull, double *output, int *status); int fffstrr8(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, double nullval, char *nullarray, int *anynull, double *output, int *status); int ffi1fi1(unsigned char *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffs1fi1(signed char *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffu2fi1(unsigned short *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffi2fi1(short *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffu4fi1(unsigned long *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffi4fi1(long *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffi8fi1(LONGLONG *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffuintfi1(unsigned int *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffintfi1(int *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffr4fi1(float *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffr8fi1(double *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffi1fi2(unsigned char *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffs1fi2(signed char *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffu2fi2(unsigned short *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffi2fi2(short *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffu4fi2(unsigned long *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffi4fi2(long *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffi8fi2(LONGLONG *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffuintfi2(unsigned int *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffintfi2(int *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffr4fi2(float *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffr8fi2(double *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffi1fi4(unsigned char *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffs1fi4(signed char *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffu2fi4(unsigned short *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffi2fi4(short *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffu4fi4(unsigned long *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffi4fi4(long *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffi8fi4(LONGLONG *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffuintfi4(unsigned int *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffintfi4(int *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffr4fi4(float *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffr8fi4(double *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int fflongfi8(long *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffi8fi8(LONGLONG *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffi2fi8(short *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffi1fi8(unsigned char *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffs1fi8(signed char *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffr4fi8(float *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffr8fi8(double *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffintfi8(int *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffu2fi8(unsigned short *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffu4fi8(unsigned long *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffuintfi8(unsigned int *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffi1fr4(unsigned char *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffs1fr4(signed char *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffu2fr4(unsigned short *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffi2fr4(short *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffu4fr4(unsigned long *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffi4fr4(long *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffi8fr4(LONGLONG *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffuintfr4(unsigned int *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffintfr4(int *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffr4fr4(float *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffr8fr4(double *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffi1fr8(unsigned char *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffs1fr8(signed char *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffu2fr8(unsigned short *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffi2fr8(short *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffu4fr8(unsigned long *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffi4fr8(long *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffi8fr8(LONGLONG *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffuintfr8(unsigned int *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffintfr8(int *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffr4fr8(float *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffr8fr8(double *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffi1fstr(unsigned char *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffs1fstr(signed char *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffu2fstr(unsigned short *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffi2fstr(short *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffu4fstr(unsigned long *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffi4fstr(long *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffi8fstr(LONGLONG *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffintfstr(int *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffuintfstr(unsigned int *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffr4fstr(float *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffr8fstr(double *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); /* the following 4 routines are VMS macros used on VAX or Alpha VMS */ void ieevpd(double *inarray, double *outarray, long *nvals); void ieevud(double *inarray, double *outarray, long *nvals); void ieevpr(float *inarray, float *outarray, long *nvals); void ieevur(float *inarray, float *outarray, long *nvals); /* routines related to the lexical parser */ int ffselect_table(fitsfile **fptr, char *outfile, char *expr, int *status); int ffiprs( fitsfile *fptr, int compressed, char *expr, int maxdim, int *datatype, long *nelem, int *naxis, long *naxes, int *status ); void ffcprs( void ); int ffcvtn( int inputType, void *input, char *undef, long ntodo, int outputType, void *nulval, void *output, int *anynull, int *status ); int parse_data( long totalrows, long offset, long firstrow, long nrows, int nCols, iteratorCol *colData, void *userPtr ); int uncompress_hkdata( fitsfile *fptr, long ntimes, double *times, int *status ); int ffffrw_work( long totalrows, long offset, long firstrow, long nrows, int nCols, iteratorCol *colData, void *userPtr ); /* image compression routines */ int fits_write_compressed_img(fitsfile *fptr, int datatype, long *fpixel, long *lpixel, int nullcheck, void *array, void *nulval, int *status); int fits_write_compressed_pixels(fitsfile *fptr, int datatype, LONGLONG fpixel, LONGLONG npixels, int nullcheck, void *array, void *nulval, int *status); int fits_write_compressed_img_plane(fitsfile *fptr, int datatype, int bytesperpixel, long nplane, long *firstcoord, long *lastcoord, long *naxes, int nullcheck, void *array, void *nullval, long *nread, int *status); int imcomp_init_table(fitsfile *outfptr, int bitpix, int naxis,long *naxes, int writebitpix, int *status); int imcomp_calc_max_elem (int comptype, int nx, int zbitpix, int blocksize); int imcomp_copy_imheader(fitsfile *infptr, fitsfile *outfptr, int *status); int imcomp_copy_img2comp(fitsfile *infptr, fitsfile *outfptr, int *status); int imcomp_copy_comp2img(fitsfile *infptr, fitsfile *outfptr, int norec, int *status); int imcomp_compress_image (fitsfile *infptr, fitsfile *outfptr, int *status); int imcomp_compress_tile (fitsfile *outfptr, long row, int datatype, void *tiledata, long tilelen, long nx, long ny, int *status); /* image decompression routines */ int fits_read_compressed_img(fitsfile *fptr, int datatype, LONGLONG *fpixel,LONGLONG *lpixel,long *inc, int nullcheck, void *nulval, void *array, char *nullarray, int *anynul, int *status); int fits_read_compressed_pixels(fitsfile *fptr, int datatype, LONGLONG fpixel, LONGLONG npixels, int nullcheck, void *nulval, void *array, char *nullarray, int *anynul, int *status); int fits_read_compressed_img_plane(fitsfile *fptr, int datatype, int bytesperpixel, long nplane, LONGLONG *firstcoord, LONGLONG *lastcoord, long *inc, long *naxes, int nullcheck, void *nullval, void *array, char *nullarray, int *anynul, long *nread, int *status); int imcomp_get_compressed_image_par(fitsfile *infptr, int *status); int imcomp_decompress_tile (fitsfile *infptr, int nrow, int tilesize, int datatype, int nullcheck, void *nulval, void *buffer, char *bnullarray, int *anynul, int *status); int imcomp_copy_overlap (char *tile, int pixlen, int ndim, long *tfpixel, long *tlpixel, char *bnullarray, char *image, long *fpixel, long *lpixel, long *inc, int nullcheck, char *nullarray, int *status); int imcomp_merge_overlap (char *tile, int pixlen, int ndim, long *tfpixel, long *tlpixel, char *bnullarray, char *image, long *fpixel, long *lpixel, int nullcheck, int *status); int fits_quantize_float (float fdata[], int nx, float in_null_value, int noise_bits, int idata[], double *bscale, double *bzero, int *iminval, int *imaxval); int fits_quantize_double (double fdata[], int nx, double in_null_value, int noise_bits, int idata[], double *bscale, double *bzero, int *iminval, int *imaxval); int fits_rcomp(int a[], int nx, unsigned char *c, int clen,int nblock); int fits_rdecomp (unsigned char *c, int clen, unsigned int array[], int nx, int nblock); int pl_p2li (int *pxsrc, int xs, short *lldst, int npix); int pl_l2pi (short *ll_src, int xs, int *px_dst, int npix); /* general driver routines */ int urltype2driver(char *urltype, int *driver); int fits_init_cfitsio(void); int fits_register_driver( char *prefix, int (*init)(void), int (*fitsshutdown)(void), int (*setoptions)(int option), int (*getoptions)(int *options), int (*getversion)(int *version), int (*checkfile) (char *urltype, char *infile, char *outfile), int (*fitsopen)(char *filename, int rwmode, int *driverhandle), int (*fitscreate)(char *filename, int *driverhandle), int (*fitstruncate)(int driverhandle, LONGLONG filesize), int (*fitsclose)(int driverhandle), int (*fremove)(char *filename), int (*size)(int driverhandle, LONGLONG *size), int (*flush)(int driverhandle), int (*seek)(int driverhandle, LONGLONG offset), int (*fitsread) (int driverhandle, void *buffer, long nbytes), int (*fitswrite)(int driverhandle, void *buffer, long nbytes)); /* file driver I/O routines */ int file_init(void); int file_setoptions(int options); int file_getoptions(int *options); int file_getversion(int *version); int file_shutdown(void); int file_checkfile(char *urltype, char *infile, char *outfile); int file_open(char *filename, int rwmode, int *driverhandle); int file_compress_open(char *filename, int rwmode, int *hdl); int file_openfile(char *filename, int rwmode, FILE **diskfile); int file_create(char *filename, int *driverhandle); int file_truncate(int driverhandle, LONGLONG filesize); int file_size(int driverhandle, LONGLONG *filesize); int file_close(int driverhandle); int file_remove(char *filename); int file_flush(int driverhandle); int file_seek(int driverhandle, LONGLONG offset); int file_read (int driverhandle, void *buffer, long nbytes); int file_write(int driverhandle, void *buffer, long nbytes); int file_is_compressed(char *filename); /* memory driver I/O routines */ int mem_init(void); int mem_setoptions(int options); int mem_getoptions(int *options); int mem_getversion(int *version); int mem_shutdown(void); int mem_create(char *filename, int *handle); int mem_create_comp(char *filename, int *handle); int mem_openmem(void **buffptr, size_t *buffsize, size_t deltasize, void *(*memrealloc)(void *p, size_t newsize), int *handle); int mem_createmem(size_t memsize, int *handle); int stdin_checkfile(char *urltype, char *infile, char *outfile); int stdin_open(char *filename, int rwmode, int *handle); int stdin2mem(int hd); int stdin2file(int hd); int stdout_close(int handle); int mem_compress_openrw(char *filename, int rwmode, int *hdl); int mem_compress_open(char *filename, int rwmode, int *hdl); int mem_compress_stdin_open(char *filename, int rwmode, int *hdl); int mem_iraf_open(char *filename, int rwmode, int *hdl); int mem_rawfile_open(char *filename, int rwmode, int *hdl); int mem_size(int handle, LONGLONG *filesize); int mem_truncate(int handle, LONGLONG filesize); int mem_close_free(int handle); int mem_close_keep(int handle); int mem_close_comp(int handle); int mem_seek(int handle, LONGLONG offset); int mem_read(int hdl, void *buffer, long nbytes); int mem_write(int hdl, void *buffer, long nbytes); int mem_uncompress2mem(char *filename, FILE *diskfile, int hdl); int iraf2mem(char *filename, char **buffptr, size_t *buffsize, size_t *filesize, int *status); /* root driver I/O routines */ int root_init(void); int root_setoptions(int options); int root_getoptions(int *options); int root_getversion(int *version); int root_shutdown(void); int root_open(char *filename, int rwmode, int *driverhandle); int root_create(char *filename, int *driverhandle); int root_close(int driverhandle); int root_flush(int driverhandle); int root_seek(int driverhandle, LONGLONG offset); int root_read (int driverhandle, void *buffer, long nbytes); int root_write(int driverhandle, void *buffer, long nbytes); int root_size(int handle, LONGLONG *filesize); /* http driver I/O routines */ int http_checkfile(char *urltype, char *infile, char *outfile); int http_open(char *filename, int rwmode, int *driverhandle); int http_file_open(char *filename, int rwmode, int *driverhandle); int http_compress_open(char *filename, int rwmode, int *driverhandle); /* ftp driver I/O routines */ int ftp_checkfile(char *urltype, char *infile, char *outfile); int ftp_open(char *filename, int rwmode, int *driverhandle); int ftp_file_open(char *filename, int rwmode, int *driverhandle); int ftp_compress_open(char *filename, int rwmode, int *driverhandle); int uncompress2mem(char *filename, FILE *diskfile, char **buffptr, size_t *buffsize, void *(*mem_realloc)(void *p, size_t newsize), size_t *filesize, int *status); int uncompress2mem_from_mem( char *inmemptr, size_t inmemsize, char **buffptr, size_t *buffsize, void *(*mem_realloc)(void *p, size_t newsize), size_t *filesize, int *status); int uncompress2file(char *filename, FILE *indiskfile, FILE *outdiskfile, int *status); int compress2mem_from_mem( char *inmemptr, size_t inmemsize, char **buffptr, size_t *buffsize, void *(*mem_realloc)(void *p, size_t newsize), size_t *filesize, int *status); int compress2file_from_mem( char *inmemptr, size_t inmemsize, FILE *outdiskfile, size_t *filesize, /* O - size of file, in bytes */ int *status); #ifdef HAVE_GSIFTP /* prototypes for gsiftp driver I/O routines */ #include "drvrgsiftp.h" #endif #ifdef HAVE_SHMEM_SERVICES /* prototypes for shared memory driver I/O routines */ #include "drvrsmem.h" #endif #if defined(vms) || defined(__vms) || defined(WIN32) || defined(__WIN32__) || (defined(macintosh) && !defined(TARGET_API_MAC_CARBON)) /* A hack for nonunix machines, which lack strcasecmp and strncasecmp */ int strcasecmp (const char *s1, const char *s2 ); int strncasecmp(const char *s1, const char *s2, size_t n); #endif /* end of the entire "ifndef _FITSIO2_H" block */ #endif skycat-3.1.2-starlink-1b/astrotcl/cfitsio/getcol.c000066400000000000000000001125621215713201500220600ustar00rootroot00000000000000 /* This file, getcol.c, contains routines that read data elements from */ /* a FITS image or table. There are generic datatype routines. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpxv( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ long *firstpix, /* I - coord of first pixel to read (1s based) */ LONGLONG nelem, /* I - number of values to read */ void *nulval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { LONGLONG tfirstpix[99]; int naxis, ii; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); for (ii=0; ii < naxis; ii++) tfirstpix[ii] = firstpix[ii]; ffgpxvll(fptr, datatype, tfirstpix, nelem, nulval, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpxvll( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG *firstpix, /* I - coord of first pixel to read (1s based) */ LONGLONG nelem, /* I - number of values to read */ void *nulval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { int naxis, ii; char cdummy; int nullcheck = 1; LONGLONG naxes[9]; LONGLONG dimsize = 1, firstelem; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgiszll(fptr, 9, naxes, status); /* calculate the position of the first element in the array */ firstelem = 0; for (ii=0; ii < naxis; ii++) { firstelem += ((firstpix[ii] - 1) * dimsize); dimsize *= naxes[ii]; } firstelem++; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, datatype, firstelem, nelem, nullcheck, nulval, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (datatype == TBYTE) { if (nulval == 0) ffgclb(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (unsigned char *) array, &cdummy, anynul, status); else ffgclb(fptr, 2, 1, firstelem, nelem, 1, 1, *(unsigned char *) nulval, (unsigned char *) array, &cdummy, anynul, status); } else if (datatype == TSBYTE) { if (nulval == 0) ffgclsb(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (signed char *) array, &cdummy, anynul, status); else ffgclsb(fptr, 2, 1, firstelem, nelem, 1, 1, *(signed char *) nulval, (signed char *) array, &cdummy, anynul, status); } else if (datatype == TUSHORT) { if (nulval == 0) ffgclui(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (unsigned short *) array, &cdummy, anynul, status); else ffgclui(fptr, 2, 1, firstelem, nelem, 1, 1, *(unsigned short *) nulval, (unsigned short *) array, &cdummy, anynul, status); } else if (datatype == TSHORT) { if (nulval == 0) ffgcli(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (short *) array, &cdummy, anynul, status); else ffgcli(fptr, 2, 1, firstelem, nelem, 1, 1, *(short *) nulval, (short *) array, &cdummy, anynul, status); } else if (datatype == TUINT) { if (nulval == 0) ffgcluk(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (unsigned int *) array, &cdummy, anynul, status); else ffgcluk(fptr, 2, 1, firstelem, nelem, 1, 1, *(unsigned int *) nulval, (unsigned int *) array, &cdummy, anynul, status); } else if (datatype == TINT) { if (nulval == 0) ffgclk(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (int *) array, &cdummy, anynul, status); else ffgclk(fptr, 2, 1, firstelem, nelem, 1, 1, *(int *) nulval, (int *) array, &cdummy, anynul, status); } else if (datatype == TULONG) { if (nulval == 0) ffgcluj(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (unsigned long *) array, &cdummy, anynul, status); else ffgcluj(fptr, 2, 1, firstelem, nelem, 1, 1, *(unsigned long *) nulval, (unsigned long *) array, &cdummy, anynul, status); } else if (datatype == TLONG) { if (nulval == 0) ffgclj(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (long *) array, &cdummy, anynul, status); else ffgclj(fptr, 2, 1, firstelem, nelem, 1, 1, *(long *) nulval, (long *) array, &cdummy, anynul, status); } else if (datatype == TLONGLONG) { if (nulval == 0) ffgcljj(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (LONGLONG *) array, &cdummy, anynul, status); else ffgcljj(fptr, 2, 1, firstelem, nelem, 1, 1, *(LONGLONG *) nulval, (LONGLONG *) array, &cdummy, anynul, status); } else if (datatype == TFLOAT) { if (nulval == 0) ffgcle(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (float *) array, &cdummy, anynul, status); else ffgcle(fptr, 2, 1, firstelem, nelem, 1, 1, *(float *) nulval, (float *) array, &cdummy, anynul, status); } else if (datatype == TDOUBLE) { if (nulval == 0) ffgcld(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (double *) array, &cdummy, anynul, status); else ffgcld(fptr, 2, 1, firstelem, nelem, 1, 1, *(double *) nulval, (double *) array, &cdummy, anynul, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgpxf( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ long *firstpix, /* I - coord of first pixel to read (1s based) */ LONGLONG nelem, /* I - number of values to read */ void *array, /* O - array of values that are returned */ char *nullarray, /* O - returned array of null value flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). The nullarray values will = 1 if the corresponding array value is null. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { LONGLONG tfirstpix[99]; int naxis, ii; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); for (ii=0; ii < naxis; ii++) tfirstpix[ii] = firstpix[ii]; ffgpxfll(fptr, datatype, tfirstpix, nelem, array, nullarray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpxfll( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG *firstpix, /* I - coord of first pixel to read (1s based) */ LONGLONG nelem, /* I - number of values to read */ void *array, /* O - array of values that are returned */ char *nullarray, /* O - returned array of null value flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). The nullarray values will = 1 if the corresponding array value is null. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { int naxis, ii; int nullcheck = 2; LONGLONG naxes[9]; LONGLONG dimsize = 1, firstelem; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgiszll(fptr, 9, naxes, status); /* calculate the position of the first element in the array */ firstelem = 0; for (ii=0; ii < naxis; ii++) { firstelem += ((firstpix[ii] - 1) * dimsize); dimsize *= naxes[ii]; } firstelem++; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, datatype, firstelem, nelem, nullcheck, NULL, array, nullarray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (datatype == TBYTE) { ffgclb(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (unsigned char *) array, nullarray, anynul, status); } else if (datatype == TSBYTE) { ffgclsb(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (signed char *) array, nullarray, anynul, status); } else if (datatype == TUSHORT) { ffgclui(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (unsigned short *) array, nullarray, anynul, status); } else if (datatype == TSHORT) { ffgcli(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (short *) array, nullarray, anynul, status); } else if (datatype == TUINT) { ffgcluk(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (unsigned int *) array, nullarray, anynul, status); } else if (datatype == TINT) { ffgclk(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (int *) array, nullarray, anynul, status); } else if (datatype == TULONG) { ffgcluj(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (unsigned long *) array, nullarray, anynul, status); } else if (datatype == TLONG) { ffgclj(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (long *) array, nullarray, anynul, status); } else if (datatype == TLONGLONG) { ffgcljj(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (LONGLONG *) array, nullarray, anynul, status); } else if (datatype == TFLOAT) { ffgcle(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (float *) array, nullarray, anynul, status); } else if (datatype == TDOUBLE) { ffgcld(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (double *) array, nullarray, anynul, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgsv( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc , /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dim. */ void *nulval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an section of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { int naxis; long naxes[9]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgisz(fptr, 9, naxes, status); if (datatype == TBYTE) { if (nulval == 0) ffgsvb(fptr, 1, naxis, naxes, blc, trc, inc, 0, (unsigned char *) array, anynul, status); else ffgsvb(fptr, 1, naxis, naxes, blc, trc, inc, *(unsigned char *) nulval, (unsigned char *) array, anynul, status); } else if (datatype == TSBYTE) { if (nulval == 0) ffgsvsb(fptr, 1, naxis, naxes, blc, trc, inc, 0, (signed char *) array, anynul, status); else ffgsvsb(fptr, 1, naxis, naxes, blc, trc, inc, *(signed char *) nulval, (signed char *) array, anynul, status); } else if (datatype == TUSHORT) { if (nulval == 0) ffgsvui(fptr, 1, naxis, naxes, blc, trc, inc, 0, (unsigned short *) array, anynul, status); else ffgsvui(fptr, 1, naxis, naxes,blc, trc, inc, *(unsigned short *) nulval, (unsigned short *) array, anynul, status); } else if (datatype == TSHORT) { if (nulval == 0) ffgsvi(fptr, 1, naxis, naxes, blc, trc, inc, 0, (short *) array, anynul, status); else ffgsvi(fptr, 1, naxis, naxes, blc, trc, inc, *(short *) nulval, (short *) array, anynul, status); } else if (datatype == TUINT) { if (nulval == 0) ffgsvuk(fptr, 1, naxis, naxes, blc, trc, inc, 0, (unsigned int *) array, anynul, status); else ffgsvuk(fptr, 1, naxis, naxes, blc, trc, inc, *(unsigned int *) nulval, (unsigned int *) array, anynul, status); } else if (datatype == TINT) { if (nulval == 0) ffgsvk(fptr, 1, naxis, naxes, blc, trc, inc, 0, (int *) array, anynul, status); else ffgsvk(fptr, 1, naxis, naxes, blc, trc, inc, *(int *) nulval, (int *) array, anynul, status); } else if (datatype == TULONG) { if (nulval == 0) ffgsvuj(fptr, 1, naxis, naxes, blc, trc, inc, 0, (unsigned long *) array, anynul, status); else ffgsvuj(fptr, 1, naxis, naxes, blc, trc, inc, *(unsigned long *) nulval, (unsigned long *) array, anynul, status); } else if (datatype == TLONG) { if (nulval == 0) ffgsvj(fptr, 1, naxis, naxes, blc, trc, inc, 0, (long *) array, anynul, status); else ffgsvj(fptr, 1, naxis, naxes, blc, trc, inc, *(long *) nulval, (long *) array, anynul, status); } else if (datatype == TLONGLONG) { if (nulval == 0) ffgsvjj(fptr, 1, naxis, naxes, blc, trc, inc, 0, (LONGLONG *) array, anynul, status); else ffgsvjj(fptr, 1, naxis, naxes, blc, trc, inc, *(LONGLONG *) nulval, (LONGLONG *) array, anynul, status); } else if (datatype == TFLOAT) { if (nulval == 0) ffgsve(fptr, 1, naxis, naxes, blc, trc, inc, 0, (float *) array, anynul, status); else ffgsve(fptr, 1, naxis, naxes, blc, trc, inc, *(float *) nulval, (float *) array, anynul, status); } else if (datatype == TDOUBLE) { if (nulval == 0) ffgsvd(fptr, 1, naxis, naxes, blc, trc, inc, 0, (double *) array, anynul, status); else ffgsvd(fptr, 1, naxis, naxes, blc, trc, inc, *(double *) nulval, (double *) array, anynul, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgpv( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ void *nulval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (datatype == TBYTE) { if (nulval == 0) ffgpvb(fptr, 1, firstelem, nelem, 0, (unsigned char *) array, anynul, status); else ffgpvb(fptr, 1, firstelem, nelem, *(unsigned char *) nulval, (unsigned char *) array, anynul, status); } else if (datatype == TSBYTE) { if (nulval == 0) ffgpvsb(fptr, 1, firstelem, nelem, 0, (signed char *) array, anynul, status); else ffgpvsb(fptr, 1, firstelem, nelem, *(signed char *) nulval, (signed char *) array, anynul, status); } else if (datatype == TUSHORT) { if (nulval == 0) ffgpvui(fptr, 1, firstelem, nelem, 0, (unsigned short *) array, anynul, status); else ffgpvui(fptr, 1, firstelem, nelem, *(unsigned short *) nulval, (unsigned short *) array, anynul, status); } else if (datatype == TSHORT) { if (nulval == 0) ffgpvi(fptr, 1, firstelem, nelem, 0, (short *) array, anynul, status); else ffgpvi(fptr, 1, firstelem, nelem, *(short *) nulval, (short *) array, anynul, status); } else if (datatype == TUINT) { if (nulval == 0) ffgpvuk(fptr, 1, firstelem, nelem, 0, (unsigned int *) array, anynul, status); else ffgpvuk(fptr, 1, firstelem, nelem, *(unsigned int *) nulval, (unsigned int *) array, anynul, status); } else if (datatype == TINT) { if (nulval == 0) ffgpvk(fptr, 1, firstelem, nelem, 0, (int *) array, anynul, status); else ffgpvk(fptr, 1, firstelem, nelem, *(int *) nulval, (int *) array, anynul, status); } else if (datatype == TULONG) { if (nulval == 0) ffgpvuj(fptr, 1, firstelem, nelem, 0, (unsigned long *) array, anynul, status); else ffgpvuj(fptr, 1, firstelem, nelem, *(unsigned long *) nulval, (unsigned long *) array, anynul, status); } else if (datatype == TLONG) { if (nulval == 0) ffgpvj(fptr, 1, firstelem, nelem, 0, (long *) array, anynul, status); else ffgpvj(fptr, 1, firstelem, nelem, *(long *) nulval, (long *) array, anynul, status); } else if (datatype == TLONGLONG) { if (nulval == 0) ffgpvjj(fptr, 1, firstelem, nelem, 0, (LONGLONG *) array, anynul, status); else ffgpvjj(fptr, 1, firstelem, nelem, *(LONGLONG *) nulval, (LONGLONG *) array, anynul, status); } else if (datatype == TFLOAT) { if (nulval == 0) ffgpve(fptr, 1, firstelem, nelem, 0, (float *) array, anynul, status); else ffgpve(fptr, 1, firstelem, nelem, *(float *) nulval, (float *) array, anynul, status); } else if (datatype == TDOUBLE) { if (nulval == 0) ffgpvd(fptr, 1, firstelem, nelem, 0, (double *) array, anynul, status); else { ffgpvd(fptr, 1, firstelem, nelem, *(double *) nulval, (double *) array, anynul, status); } } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgpf( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ void *array, /* O - array of values that are returned */ char *nullarray, /* O - array of null value flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). The nullarray values will = 1 if the corresponding array value is null. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (datatype == TBYTE) { ffgpfb(fptr, 1, firstelem, nelem, (unsigned char *) array, nullarray, anynul, status); } else if (datatype == TSBYTE) { ffgpfsb(fptr, 1, firstelem, nelem, (signed char *) array, nullarray, anynul, status); } else if (datatype == TUSHORT) { ffgpfui(fptr, 1, firstelem, nelem, (unsigned short *) array, nullarray, anynul, status); } else if (datatype == TSHORT) { ffgpfi(fptr, 1, firstelem, nelem, (short *) array, nullarray, anynul, status); } else if (datatype == TUINT) { ffgpfuk(fptr, 1, firstelem, nelem, (unsigned int *) array, nullarray, anynul, status); } else if (datatype == TINT) { ffgpfk(fptr, 1, firstelem, nelem, (int *) array, nullarray, anynul, status); } else if (datatype == TULONG) { ffgpfuj(fptr, 1, firstelem, nelem, (unsigned long *) array, nullarray, anynul, status); } else if (datatype == TLONG) { ffgpfj(fptr, 1, firstelem, nelem, (long *) array, nullarray, anynul, status); } else if (datatype == TLONGLONG) { ffgpfjj(fptr, 1, firstelem, nelem, (LONGLONG *) array, nullarray, anynul, status); } else if (datatype == TFLOAT) { ffgpfe(fptr, 1, firstelem, nelem, (float *) array, nullarray, anynul, status); } else if (datatype == TDOUBLE) { ffgpfd(fptr, 1, firstelem, nelem, (double *) array, nullarray, anynul, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgcv( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ void *nulval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a table column. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of true if any pixels are undefined. */ { char cdummy[2]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (datatype == TBIT) { ffgcx(fptr, colnum, firstrow, firstelem, nelem, (char *) array, status); } else if (datatype == TBYTE) { if (nulval == 0) ffgclb(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (unsigned char *) array, cdummy, anynul, status); else ffgclb(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(unsigned char *) nulval, (unsigned char *) array, cdummy, anynul, status); } else if (datatype == TSBYTE) { if (nulval == 0) ffgclsb(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (signed char *) array, cdummy, anynul, status); else ffgclsb(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(signed char *) nulval, (signed char *) array, cdummy, anynul, status); } else if (datatype == TUSHORT) { if (nulval == 0) ffgclui(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (unsigned short *) array, cdummy, anynul, status); else ffgclui(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(unsigned short *) nulval, (unsigned short *) array, cdummy, anynul, status); } else if (datatype == TSHORT) { if (nulval == 0) ffgcli(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (short *) array, cdummy, anynul, status); else ffgcli(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(short *) nulval, (short *) array, cdummy, anynul, status); } else if (datatype == TUINT) { if (nulval == 0) ffgcluk(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (unsigned int *) array, cdummy, anynul, status); else ffgcluk(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(unsigned int *) nulval, (unsigned int *) array, cdummy, anynul, status); } else if (datatype == TINT) { if (nulval == 0) ffgclk(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (int *) array, cdummy, anynul, status); else ffgclk(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(int *) nulval, (int *) array, cdummy, anynul, status); } else if (datatype == TULONG) { if (nulval == 0) ffgcluj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (unsigned long *) array, cdummy, anynul, status); else ffgcluj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(unsigned long *) nulval, (unsigned long *) array, cdummy, anynul, status); } else if (datatype == TLONG) { if (nulval == 0) ffgclj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (long *) array, cdummy, anynul, status); else ffgclj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(long *) nulval, (long *) array, cdummy, anynul, status); } else if (datatype == TLONGLONG) { if (nulval == 0) ffgcljj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (LONGLONG *) array, cdummy, anynul, status); else ffgcljj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(LONGLONG *) nulval, (LONGLONG *) array, cdummy, anynul, status); } else if (datatype == TFLOAT) { if (nulval == 0) ffgcle(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0., (float *) array, cdummy, anynul, status); else ffgcle(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(float *) nulval,(float *) array, cdummy, anynul, status); } else if (datatype == TDOUBLE) { if (nulval == 0) ffgcld(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0., (double *) array, cdummy, anynul, status); else ffgcld(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(double *) nulval, (double *) array, cdummy, anynul, status); } else if (datatype == TCOMPLEX) { if (nulval == 0) ffgcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 1, 0., (float *) array, cdummy, anynul, status); else ffgcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 1, *(float *) nulval, (float *) array, cdummy, anynul, status); } else if (datatype == TDBLCOMPLEX) { if (nulval == 0) ffgcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 1, 0., (double *) array, cdummy, anynul, status); else ffgcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 1, *(double *) nulval, (double *) array, cdummy, anynul, status); } else if (datatype == TLOGICAL) { if (nulval == 0) ffgcll(fptr, colnum, firstrow, firstelem, nelem, 1, 0, (char *) array, cdummy, anynul, status); else ffgcll(fptr, colnum, firstrow, firstelem, nelem, 1, *(char *) nulval, (char *) array, cdummy, anynul, status); } else if (datatype == TSTRING) { if (nulval == 0) { cdummy[0] = '\0'; ffgcls(fptr, colnum, firstrow, firstelem, nelem, 1, cdummy, (char **) array, cdummy, anynul, status); } else ffgcls(fptr, colnum, firstrow, firstelem, nelem, 1, (char *) nulval, (char **) array, cdummy, anynul, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgcf( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ void *array, /* O - array of values that are returned */ char *nullarray, /* O - array of null value flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a table column. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). ANYNUL is returned with a value of true if any pixels are undefined. */ { void *nulval; /* dummy argument */ double dnulval = 0.; if (*status > 0) /* inherit input status value if > 0 */ return(*status); nulval = &dnulval; /* set to a harmless value; this is never used */ if (datatype == TBIT) { ffgcx(fptr, colnum, firstrow, firstelem, nelem, (char *) array, status); } else if (datatype == TBYTE) { ffgclb(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(unsigned char *) nulval, (unsigned char *) array, nullarray, anynul, status); } else if (datatype == TSBYTE) { ffgclsb(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(signed char *) nulval, (signed char *) array, nullarray, anynul, status); } else if (datatype == TUSHORT) { ffgclui(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(unsigned short *) nulval, (unsigned short *) array, nullarray, anynul, status); } else if (datatype == TSHORT) { ffgcli(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(short *) nulval, (short *) array, nullarray, anynul, status); } else if (datatype == TUINT) { ffgcluk(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(unsigned int *) nulval, (unsigned int *) array, nullarray, anynul, status); } else if (datatype == TINT) { ffgclk(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(int *) nulval, (int *) array, nullarray, anynul, status); } else if (datatype == TULONG) { ffgcluj(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(unsigned long *) nulval, (unsigned long *) array, nullarray, anynul, status); } else if (datatype == TLONG) { ffgclj(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(long *) nulval, (long *) array, nullarray, anynul, status); } else if (datatype == TLONGLONG) { ffgcljj(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(LONGLONG *) nulval, (LONGLONG *) array, nullarray, anynul, status); } else if (datatype == TFLOAT) { ffgcle(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(float *) nulval,(float *) array, nullarray, anynul, status); } else if (datatype == TDOUBLE) { ffgcld(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(double *) nulval, (double *) array, nullarray, anynul, status); } else if (datatype == TCOMPLEX) { ffgcfc(fptr, colnum, firstrow, firstelem, nelem, (float *) array, nullarray, anynul, status); } else if (datatype == TDBLCOMPLEX) { ffgcfm(fptr, colnum, firstrow, firstelem, nelem, (double *) array, nullarray, anynul, status); } else if (datatype == TLOGICAL) { ffgcll(fptr, colnum, firstrow, firstelem, nelem, 2, *(char *) nulval, (char *) array, nullarray, anynul, status); } else if (datatype == TSTRING) { ffgcls(fptr, colnum, firstrow, firstelem, nelem, 2, (char *) nulval, (char **) array, nullarray, anynul, status); } else *status = BAD_DATATYPE; return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/getcolb.c000066400000000000000000002252461215713201500222260ustar00rootroot00000000000000/* This file, getcolb.c, contains routines that read data elements from */ /* a FITS image or table, with unsigned char (unsigned byte) data type. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned char nulval, /* I - value for undefined pixels */ unsigned char *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; unsigned char nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TBYTE, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclb(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned char *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TBYTE, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclb(fptr, 2, row, firstelem, nelem, 1, 2, 0, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2db(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned char nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned char *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3db(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3db(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned char nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned char *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; LONGLONG narray, nfits; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}; LONGLONG lpixel[3]; unsigned char nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TBYTE, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgclb(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgclb(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned char nulval, /* I - value to set undefined pixels */ unsigned char *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii, i0, i1, i2, i3, i4, i5, i6, i7, i8, row, rstr, rstp, rinc; long str[9], stp[9], incr[9], dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; unsigned char nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvb is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TBYTE, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { sprintf(msg, "ffgsvb: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgclb(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned char *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; int hdutype, anyf; unsigned char nulval = 0; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvb is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TBYTE, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvb: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgclb(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ unsigned char *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclb(fptr, 1, row, firstelem, nelem, 1, 1, 0, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned char nulval, /* I - value for null pixels */ unsigned char *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgclb(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned char *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { unsigned char dummy = 0; ffgclb(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgclb( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ unsigned char nulval, /* I - value for null pixels if nultyp = 1 */ unsigned char *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem, hdutype, xcode, decimals; long twidth, incre, ntodo; long ii, xwidth; int convert, nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; union u_tag { char charval; unsigned char ucharval; } u; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ ffgcprll( fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status); /* special case */ if (tcode == TLOGICAL && elemincre == 1) { u.ucharval = nulval; ffgcll(fptr, colnum, firstrow, firstelem, nelem, nultyp, u.charval, (char *) array, nularray, anynul, status); return(*status); } if (strchr(tform,'A') != NULL) { if (*status == BAD_ELEM_NUM) { /* ignore this error message */ *status = 0; ffcmsg(); /* clear error stack */ } /* interpret a 'A' ASCII column as a 'B' byte column ('8A' == '8B') */ /* This is an undocumented 'feature' in CFITSIO */ /* we have to reset some of the values returned by ffgcpr */ tcode = TBYTE; incre = 1; /* each element is 1 byte wide */ repeat = twidth; /* total no. of chars in the col */ twidth = 1; /* width of each element */ scale = 1.0; /* no scaling */ zero = 0.0; tnull = NULL_UNDEFINED; /* don't test for nulls */ maxelem = DBUFFSIZE; } if (*status > 0) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING && hdutype == ASCII_TBL) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default, check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ convert = 1; if (tcode == TBYTE) /* Special Case: */ { /* no type convertion required, so read */ maxelem = (int) nelem; /* data directly into output buffer. */ if (nulcheck == 0 && scale == 1. && zero == 0.) convert = 0; /* no need to scale data or find nulls */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, &array[next], status); if (convert) fffi1i1(&array[next], ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2i1((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4i1((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8i1( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4i1((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8i1((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); /* interpret the string as an ASCII formated number */ fffstri1((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read bytes from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgclb).", dtemp+1., dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgclb).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgextn( fitsfile *fptr, /* I - FITS file pointer */ LONGLONG offset, /* I - byte offset from start of extension data */ LONGLONG nelem, /* I - number of elements to read */ void *buffer, /* I - stream of bytes to read */ int *status) /* IO - error status */ /* Read a stream of bytes from the current FITS HDU. This primative routine is mainly for reading non-standard "conforming" extensions and should not be used for standard IMAGE, TABLE or BINTABLE extensions. */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); /* move to write position */ ffmbyt(fptr, (fptr->Fptr)->datastart+ offset, IGNORE_EOF, status); /* read the buffer */ ffgbyt(fptr, nelem, buffer, status); return(*status); } /*--------------------------------------------------------------------------*/ int fffi1i1(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ unsigned char nullval,/* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned char *output,/* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { /* this routine is normally not called in this case */ memcpy(output, input, ntodo ); } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2i1(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ unsigned char nullval,/* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned char *output,/* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4i1(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ unsigned char nullval,/* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned char *output,/* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8i1(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ unsigned char nullval,/* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned char *output,/* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4i1(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char nullval,/* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned char *output,/* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { /* use redundant boolean logic in following statement */ /* to suppress irritating Borland compiler warning message */ if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8i1(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char nullval,/* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned char *output,/* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstri1(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ unsigned char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/getcold.c000066400000000000000000002030431215713201500222170ustar00rootroot00000000000000/* This file, getcold.c, contains routines that read data elements from */ /* a FITS image or table, with double datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvd( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ double nulval, /* I - value for undefined pixels */ double *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; double nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TDOUBLE, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcld(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfd( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ double *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TDOUBLE, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcld(fptr, 2, row, firstelem, nelem, 1, 2, 0., array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2dd(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ double nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ double *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3dd(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3dd(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ double nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ double *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { LONGLONG nfits, narray; long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}; LONGLONG lpixel[3]; double nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TDOUBLE, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgcld(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgcld(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvd(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ double nulval, /* I - value to set undefined pixels */ double *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; double nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvd is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TDOUBLE, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { sprintf(msg, "ffgsvd: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgcld(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfd(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ double *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; int hdutype, anyf; double nulval = 0; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvd is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TDOUBLE, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvd: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcld(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpd( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ double *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcld(fptr, 1, row, firstelem, nelem, 1, 1, 0., array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvd(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ double nulval, /* I - value for null pixels */ double *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgcld(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvm(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ double nulval, /* I - value for null pixels */ double *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. TSCAL and ZERO should not be used with complex values. */ { char cdummy; /* a complex double value is interpreted as a pair of double values, */ /* thus need to multiply the first element and number of elements by 2 */ ffgcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfd(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ double *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { double dummy = 0; ffgcld(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfm(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ double *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. TSCAL and ZERO should not be used with complex values. */ { long ii, jj; float dummy = 0; char *carray; /* a complex double value is interpreted as a pair of double values, */ /* thus need to multiply the first element and number of elements by 2 */ /* allocate temporary array */ carray = (char *) calloc( (size_t) (nelem * 2), 1); ffgcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 2, dummy, array, carray, anynul, status); for (ii = 0, jj = 0; jj < nelem; ii += 2, jj++) { if (carray[ii] || carray[ii + 1]) nularray[jj] = 1; else nularray[jj] = 0; } free(carray); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcld( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ double nulval, /* I - value for null pixels if nultyp = 1 */ double *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1, dtemp; int tcode, hdutype, xcode, decimals, maxelem; long twidth, incre; long ii, xwidth, ntodo; int convert, nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ convert = 1; if (tcode == TDOUBLE) /* Special Case: */ { /* no type convertion required, so read */ maxelem = (int) nelem; /* data directly into output buffer. */ if (nulcheck == 0 && scale == 1. && zero == 0.) convert = 0; /* no need to scale data or find nulls */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, &array[next], status); if (convert) fffr8r8(&array[next], ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1r8((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2r8((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4r8((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8r8( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4r8((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstrr8((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgcld).", dtemp+1., dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgcld).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = (long) (elemnum / repeat); rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (long) ((-elemnum - 1) / repeat + 1); rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1r8(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = input[ii] * scale + zero; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (double) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = input[ii] * scale + zero; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2r8(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = input[ii] * scale + zero; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (double) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = input[ii] * scale + zero; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4r8(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = input[ii] * scale + zero; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (double) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = input[ii] * scale + zero; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8r8(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = input[ii] * scale + zero; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (double) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = input[ii] * scale + zero; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4r8(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = input[ii] * scale + zero; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else output[ii] = (double) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = zero; } else output[ii] = input[ii] * scale + zero; } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8r8(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { memcpy(output, input, ntodo * sizeof(double) ); } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = input[ii] * scale + zero; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else { nullarray[ii] = 1; /* explicitly set value in case output contains a NaN */ output[ii] = DOUBLENULLVALUE; } } else /* it's an underflow */ output[ii] = 0; } else output[ii] = input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else { nullarray[ii] = 1; /* explicitly set value in case output contains a NaN */ output[ii] = DOUBLENULLVALUE; } } else /* it's an underflow */ output[ii] = zero; } else output[ii] = input[ii] * scale + zero; } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstrr8(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); output[ii] = (dvalue * scale + zero); /* apply the scaling */ } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/getcole.c000066400000000000000000002032231215713201500222200ustar00rootroot00000000000000/* This file, getcole.c, contains routines that read data elements from */ /* a FITS image or table, with float datatype */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpve( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ float nulval, /* I - value for undefined pixels */ float *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; float nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TFLOAT, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcle(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfe( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ float *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TFLOAT, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcle(fptr, 2, row, firstelem, nelem, 1, 2, 0.F, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2de(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ float nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ float *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3de(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3de(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ float nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ float *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; LONGLONG narray, nfits; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}; LONGLONG lpixel[3]; float nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TFLOAT, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgcle(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgcle(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsve(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ float nulval, /* I - value to set undefined pixels */ float *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; float nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsve is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TFLOAT, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { sprintf(msg, "ffgsve: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgcle(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfe(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ float *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; int hdutype, anyf; float nulval = 0; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsve is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TFLOAT, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsve: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcle(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpe( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ float *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcle(fptr, 1, row, firstelem, nelem, 1, 1, 0.F, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcve(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ float nulval, /* I - value for null pixels */ float *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgcle(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvc(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ float nulval, /* I - value for null pixels */ float *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. TSCAL and ZERO should not be used with complex values. */ { char cdummy; /* a complex value is interpreted as a pair of float values, thus */ /* need to multiply the first element and number of elements by 2 */ ffgcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem *2, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfe(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ float *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { float dummy = 0; ffgcle(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfc(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ float *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. TSCAL and ZERO should not be used with complex values. */ { long ii, jj; float dummy = 0; char *carray; /* a complex value is interpreted as a pair of float values, thus */ /* need to multiply the first element and number of elements by 2 */ /* allocate temporary array */ carray = (char *) calloc( (size_t) (nelem * 2), 1); ffgcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 2, dummy, array, carray, anynul, status); for (ii = 0, jj = 0; jj < nelem; ii += 2, jj++) { if (carray[ii] || carray[ii + 1]) nularray[jj] = 1; else nularray[jj] = 0; } free(carray); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcle( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ float nulval, /* I - value for null pixels if nultyp = 1 */ float *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int convert, nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ convert = 1; if (tcode == TFLOAT) /* Special Case: */ { /* no type convertion required, so read */ maxelem = (int) nelem; /* data directly into output buffer. */ if (nulcheck == 0 && scale == 1. && zero == 0.) convert = 0; /* no need to scale data or find nulls */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, &array[next], status); if (convert) fffr4r4(&array[next], ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1r4((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2r4((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4r4((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8r4( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8r4((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstrr4((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgcle).", dtemp+1., dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgcle).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1r4(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = (float) (( (double) input[ii] ) * scale + zero); } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (float) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = (float) (( (double) input[ii] ) * scale + zero); } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2r4(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = (float) (input[ii] * scale + zero); } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (float) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = (float) (input[ii] * scale + zero); } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4r4(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = (float) (input[ii] * scale + zero); } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (float) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = (float) (input[ii] * scale + zero); } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8r4(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = (float) (input[ii] * scale + zero); } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (float) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = (float) (input[ii] * scale + zero); } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4r4(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { memcpy(output, input, ntodo * sizeof(float) ); } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = (float) (input[ii] * scale + zero); } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else { nullarray[ii] = 1; /* explicitly set value in case output contains a NaN */ output[ii] = FLOATNULLVALUE; } } else /* it's an underflow */ output[ii] = 0; } else output[ii] = input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else { nullarray[ii] = 1; /* explicitly set value in case output contains a NaN */ output[ii] = FLOATNULLVALUE; } } else /* it's an underflow */ output[ii] = (float) zero; } else output[ii] = (float) (input[ii] * scale + zero); } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8r4(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = (float) (input[ii] * scale + zero); } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else output[ii] = (float) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = (float) zero; } else output[ii] = (float) (input[ii] * scale + zero); } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstrr4(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); output[ii] = (float) (dvalue * scale + zero); /* apply the scaling */ } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/getcoli.c000066400000000000000000002161031215713201500222250ustar00rootroot00000000000000/* This file, getcoli.c, contains routines that read data elements from */ /* a FITS image or table, with short datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvi( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ short nulval, /* I - value for undefined pixels */ short *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; short nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TSHORT, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcli(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfi( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ short *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TSHORT, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcli(fptr, 2, row, firstelem, nelem, 1, 2, 0, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2di(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ short nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ short *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3di(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3di(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ short nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ short *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; LONGLONG nfits, narray; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}; LONGLONG lpixel[3]; short nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TSHORT, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgcli(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgcli(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvi(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ short nulval, /* I - value to set undefined pixels */ short *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; short nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvi is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TSHORT, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { sprintf(msg, "ffgsvi: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgcli(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfi(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ short *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; int hdutype, anyf; short nulval = 0; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvi is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TSHORT, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvi: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcli(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpi( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ short *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcli(fptr, 1, row, firstelem, nelem, 1, 1, 0, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvi(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ short nulval, /* I - value for null pixels */ short *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgcli(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfi(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ short *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { short dummy = 0; ffgcli(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcli( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ short nulval, /* I - value for null pixels if nultyp = 1 */ short *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int convert, nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ convert = 1; if (tcode == TSHORT) /* Special Case: */ { /* no type convertion required, so read */ maxelem = (int) nelem; /* data directly into output buffer. */ if (nulcheck == 0 && scale == 1. && zero == 0.) convert = 0; /* no need to scale data or find nulls */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, &array[next], status); if (convert) fffi2i2(&array[next], ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8i2( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1i2((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4i2((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4i2((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8i2((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstri2((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgcli).", dtemp+1, dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgcli).", dtemp+1, dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1i2(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (short) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2i2(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { memcpy(output, input, ntodo * sizeof(short) ); } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4i2(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < SHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < SHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8i2(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < SHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < SHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4i2(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (zero > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8i2(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (zero > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstri2(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/getcolj.c000066400000000000000000004305441215713201500222350ustar00rootroot00000000000000/* This file, getcolj.c, contains routines that read data elements from */ /* a FITS image or table, with long data type. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long nulval, /* I - value for undefined pixels */ long *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; long nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TLONG, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclj(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TLONG, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclj(fptr, 2, row, firstelem, nelem, 1, 2, 0L, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2dj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ long *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3dj(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3dj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ long *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}, nfits, narray; LONGLONG lpixel[3], nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TLONG, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgclj(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgclj(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ long nulval, /* I - value to set undefined pixels */ long *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; long nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TLONG, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { sprintf(msg, "ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgclj(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ long *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; long nulval = 0; int hdutype, anyf; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TLONG, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgclj(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ long *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclj(fptr, 1, row, firstelem, nelem, 1, 1, 0L, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long nulval, /* I - value for null pixels */ long *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgclj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { long dummy = 0; ffgclj(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgclj( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ long nulval, /* I - value for null pixels if nultyp = 1 */ long *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int convert, nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ if (ffgcprll(fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ convert = 1; if (tcode == TLONG) /* Special Case: */ { /* no type convertion required, so read */ maxelem = (int) nelem; /* data directly into output buffer. */ if (nulcheck == 0 && scale == 1. && zero == 0. && LONGSIZE == 32) convert = 0; /* no need to scale data or find nulls */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) &array[next], status); if (convert) fffi4i4((INT32BIT *) &array[next], ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8i4((LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1i4((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2i4((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4i4((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8i4((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstri4((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgclj).", dtemp+1., dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgclj).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1i4(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (long) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2i4(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (long) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4i4(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; Process the array of data in reverse order, to handle the case where the input data is 4-bytes and the output is 8-bytes and the conversion is being done in place in the same array. */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = ntodo - 1; ii >= 0; ii--) output[ii] = (long) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = ntodo - 1; ii >= 0; ii--) { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = ntodo - 1; ii >= 0; ii--) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = input[ii]; } } else /* must scale the data */ { for (ii = ntodo - 1; ii >= 0; ii--) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8i4(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < LONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (input[ii] > LONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < LONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (input[ii] > LONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4i4(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (input[ii] > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (input[ii] > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (zero > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8i4(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (input[ii] > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (input[ii] > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (zero > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstri4(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } /* ======================================================================== */ /* the following routines support the 'long long' data type */ /* ======================================================================== */ /*--------------------------------------------------------------------------*/ int ffgpvjj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ LONGLONG nulval, /* I - value for undefined pixels */ LONGLONG *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; LONGLONG nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TLONGLONG, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcljj(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfjj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ LONGLONG *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; LONGLONG dummy = 0; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TLONGLONG, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcljj(fptr, 2, row, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2djj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG nulval ,/* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG *array,/* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3djj(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3djj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ LONGLONG *array,/* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}, nfits, narray; LONGLONG lpixel[3]; LONGLONG nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TLONGLONG, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgcljj(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgcljj(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvjj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ LONGLONG nulval,/* I - value to set undefined pixels */ LONGLONG *array,/* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; LONGLONG nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TLONGLONG, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { sprintf(msg, "ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgcljj(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfjj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ LONGLONG *array,/* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; LONGLONG nulval = 0; int hdutype, anyf; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TLONGLONG, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcljj(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpjj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ LONGLONG *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; LONGLONG dummy = 0; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcljj(fptr, 1, row, firstelem, nelem, 1, 1, dummy, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvjj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ LONGLONG nulval, /* I - value for null pixels */ LONGLONG *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgcljj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfjj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ LONGLONG *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { LONGLONG dummy = 0; ffgcljj(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcljj( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ LONGLONG nulval, /* I - value for null pixels if nultyp = 1 */ LONGLONG *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int convert, nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ if (ffgcprll(fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ convert = 1; if (tcode == TLONGLONG) /* Special Case: */ { /* no type convertion required, so read */ maxelem = (int) nelem; /* data directly into output buffer. */ if (nulcheck == 0 && scale == 1. && zero == 0.) convert = 0; /* no need to scale data or find nulls */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) &array[next], status); if (convert) fffi8i8((LONGLONG *) &array[next], ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4i8((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1i8((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2i8((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4i8((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8i8((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstri8((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgclj).", dtemp+1., dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgclj).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1i8(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ LONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ LONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (LONGLONG) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (LONGLONG) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2i8(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ LONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ LONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (LONGLONG) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (LONGLONG) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4i8(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ LONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ LONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (LONGLONG) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (LONGLONG) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8i8(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ LONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ LONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4i8(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ LONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (input[ii] > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (input[ii] > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (zero > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8i8(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ LONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (input[ii] > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (input[ii] > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (zero > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstri8(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ LONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ LONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/getcolk.c000066400000000000000000002157041215713201500222350ustar00rootroot00000000000000/* This file, getcolk.c, contains routines that read data elements from */ /* a FITS image or table, with 'int' data type. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ int nulval, /* I - value for undefined pixels */ int *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; int nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TINT, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclk(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ int *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TINT, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclk(fptr, 2, row, firstelem, nelem, 1, 2, 0L, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2dk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ int nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ int *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3dk(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3dk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ int nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ int *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}, nfits, narray; LONGLONG lpixel[3]; int nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TINT, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgclk(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgclk(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ int nulval, /* I - value to set undefined pixels */ int *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; int nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TINT, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { sprintf(msg, "ffgsvk: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgclk(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ int *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; long nulval = 0; int hdutype, anyf; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TINT, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgclk(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ int *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclk(fptr, 1, row, firstelem, nelem, 1, 1, 0L, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ int nulval, /* I - value for null pixels */ int *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgclk(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ int *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { int dummy = 0; ffgclk(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgclk( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ int nulval, /* I - value for null pixels if nultyp = 1 */ int *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power, dtemp; int tcode, maxelem, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int convert, nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* call the 'short' or 'long' version of this routine, if possible */ if (sizeof(int) == sizeof(short)) ffgcli(fptr, colnum, firstrow, firstelem, nelem, elemincre, nultyp, (short) nulval, (short *) array, nularray, anynul, status); else if (sizeof(int) == sizeof(long)) ffgclj(fptr, colnum, firstrow, firstelem, nelem, elemincre, nultyp, (long) nulval, (long *) array, nularray, anynul, status); else { /* This is a special case: sizeof(int) is not equal to sizeof(short) or sizeof(long). This occurs on Alpha OSF systems where short = 2 bytes, int = 4 bytes, and long = 8 bytes. */ buffer = cbuff; power = 1.; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ convert = 1; if (tcode == TLONG) /* Special Case: */ { /* no type convertion required, so read */ maxelem = (int) nelem; /* data directly into output buffer. */ if (nulcheck == 0 && scale == 1. && zero == 0.) convert = 0; /* no need to scale data or find nulls */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) &array[next], status); if (convert) fffi4int((INT32BIT *) &array[next], ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8int( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1int((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2int((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4int((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8int((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstrint((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgclk).", dtemp+1., dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgclk).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } } /* end of DEC Alpha special case */ return(*status); } /*--------------------------------------------------------------------------*/ int fffi1int(unsigned char *input,/* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (int) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2int(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (int) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4int(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (int) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8int(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < INT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (input[ii] > INT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < INT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (input[ii] > INT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4int(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (input[ii] > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (input[ii] > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (zero > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8int(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (input[ii] > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (input[ii] > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (zero > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstrint(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (long) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/getcoll.c000066400000000000000000000544521215713201500222370ustar00rootroot00000000000000/* This file, getcoll.c, contains routines that read data elements from */ /* a FITS image or table, with logical datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgcvl( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ char nulval, /* I - value for null pixels */ char *array, /* O - array of values */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of logical values from a column in the current FITS HDU. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgcll( fptr, colnum, firstrow, firstelem, nelem, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcl( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ char *array, /* O - array of values */ int *status) /* IO - error status */ /* !!!! THIS ROUTINE IS DEPRECATED AND SHOULD NOT BE USED !!!!!! !!!! USE ffgcvl INSTEAD !!!!!! Read an array of logical values from a column in the current FITS HDU. No checking for null values will be performed. */ { char nulval = 0; int anynul; ffgcvl( fptr, colnum, firstrow, firstelem, nelem, nulval, array, &anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfl( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ char *array, /* O - array of values */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of logical values from a column in the current FITS HDU. */ { char nulval = 0; ffgcll( fptr, colnum, firstrow, firstelem, nelem, 2, nulval, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcll( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ char nulval, /* I - value for null pixels if nultyp = 1 */ char *array, /* O - array of values */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of logical values from a column in the current FITS HDU. */ { double dtemp; int tcode, maxelem, hdutype, ii, nulcheck; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, readptr, tnull, rowlen, rownum, remain, next; double scale, zero; char tform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ unsigned char buffer[DBUFFSIZE], *buffptr; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 0, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode != TLOGICAL) return(*status = NOT_LOGICAL_COL); /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default, check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ /*---------------------------------------------------------------------*/ /* Now read the logical values from the FITS column. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ ntodo = (long) remain; /* max number of elements to read at one time */ while (ntodo) { /* limit the number of pixels to read at one time to the number that remain in the current vector. */ ntodo = (long) minvalue(ntodo, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); readptr = startpos + (rowlen * rownum) + (elemnum * incre); ffgi1b(fptr, readptr, ntodo, incre, buffer, status); /* convert from T or F to 1 or 0 */ buffptr = buffer; for (ii = 0; ii < ntodo; ii++, next++, buffptr++) { if (*buffptr == 'T') array[next] = 1; else if (*buffptr =='F') array[next] = 0; else if (*buffptr == 0) { array[next] = nulval; /* set null values to input nulval */ if (anynul) *anynul = 1; if (nulcheck == 2) { nularray[next] = 1; /* set null flags */ } } else /* some other illegal character; return the char value */ { array[next] = (char) *buffptr; } } if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; sprintf(message, "Error reading elements %.0f thruough %.0f of logical array (ffgcl).", dtemp+1., dtemp + ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on later row */ { elemnum = 0; rownum++; } } ntodo = (long) remain; /* this is the maximum number to do in next loop */ } /* End of main while Loop */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgcx( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG frow, /* I - first row to write (1 = 1st row) */ LONGLONG fbit, /* I - first bit to write (1 = 1st) */ LONGLONG nbit, /* I - number of bits to write */ char *larray, /* O - array of logicals corresponding to bits */ int *status) /* IO - error status */ /* read an array of logical values from a specified bit or byte column of the binary table. larray is set = TRUE, if the corresponding bit = 1, otherwise it is set to FALSE. The binary table column being read from must have datatype 'B' or 'X'. */ { LONGLONG bstart; long offset, ndone, ii, repeat, bitloc, fbyte; LONGLONG rstart, estart; int tcode, descrp; unsigned char cbuff; static unsigned char onbit[8] = {128, 64, 32, 16, 8, 4, 2, 1}; tcolumn *colptr; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check input parameters */ if (nbit < 1) return(*status); else if (frow < 1) return(*status = BAD_ROW_NUM); else if (fbit < 1) return(*status = BAD_ELEM_NUM); /* position to the correct HDU */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); fbyte = (long) ((fbit + 7) / 8); bitloc = (long) (fbit - 1 - ((fbit - 1) / 8 * 8)); ndone = 0; rstart = frow - 1; estart = fbyte - 1; colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (abs(tcode) > TBYTE) return(*status = NOT_LOGICAL_COL); /* not correct datatype column */ if (tcode > 0) { descrp = FALSE; /* not a variable length descriptor column */ /* N.B: REPEAT is the number of bytes, not number of bits */ repeat = (long) colptr->trepeat; if (tcode == TBIT) repeat = (repeat + 7) / 8; /* convert from bits to bytes */ if (fbyte > repeat) return(*status = BAD_ELEM_NUM); /* calc the i/o pointer location to start of sequence of pixels */ bstart = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * rstart) + colptr->tbcol + estart; } else { descrp = TRUE; /* a variable length descriptor column */ /* only bit arrays (tform = 'X') are supported for variable */ /* length arrays. REPEAT is the number of BITS in the array. */ ffgdes(fptr, colnum, frow, &repeat, &offset, status); if (tcode == -TBIT) repeat = (repeat + 7) / 8; if ((fbit + nbit + 6) / 8 > repeat) return(*status = BAD_ELEM_NUM); /* calc the i/o pointer location to start of sequence of pixels */ bstart = (fptr->Fptr)->datastart + offset + (fptr->Fptr)->heapstart + estart; } /* move the i/o pointer to the start of the pixel sequence */ if (ffmbyt(fptr, bstart, REPORT_EOF, status) > 0) return(*status); /* read the next byte */ while (1) { if (ffgbyt(fptr, 1, &cbuff, status) > 0) return(*status); for (ii = bitloc; (ii < 8) && (ndone < nbit); ii++, ndone++) { if(cbuff & onbit[ii]) /* test if bit is set */ larray[ndone] = TRUE; else larray[ndone] = FALSE; } if (ndone == nbit) /* finished all the bits */ return(*status); /* not done, so get the next byte */ if (!descrp) { estart++; if (estart == repeat) { /* move the i/o pointer to the next row of pixels */ estart = 0; rstart = rstart + 1; bstart = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * rstart) + colptr->tbcol; ffmbyt(fptr, bstart, REPORT_EOF, status); } } bitloc = 0; } } /*--------------------------------------------------------------------------*/ int ffgcxui(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG nrows, /* I - no. of rows to read */ long input_first_bit, /* I - first bit to read (1 = 1st) */ int input_nbits, /* I - number of bits to read (<= 32) */ unsigned short *array, /* O - array of integer values */ int *status) /* IO - error status */ /* Read a consecutive string of bits from an 'X' or 'B' column and interprete them as an unsigned integer. The number of bits must be less than or equal to 16 or the total number of bits in the column, which ever is less. */ { int ii, firstbit, nbits, bytenum, startbit, numbits, endbit; int firstbyte, lastbyte, nbytes, rshift, lshift; unsigned short colbyte[5]; tcolumn *colptr; char message[81]; if (*status > 0 || nrows == 0) return(*status); /* check input parameters */ if (firstrow < 1) { sprintf(message, "Starting row number is less than 1: %ld (ffgcxui)", (long) firstrow); ffpmsg(message); return(*status = BAD_ROW_NUM); } else if (input_first_bit < 1) { sprintf(message, "Starting bit number is less than 1: %ld (ffgcxui)", input_first_bit); ffpmsg(message); return(*status = BAD_ELEM_NUM); } else if (input_nbits > 16) { sprintf(message, "Number of bits to read is > 16: %d (ffgcxui)", input_nbits); ffpmsg(message); return(*status = BAD_ELEM_NUM); } /* position to the correct HDU */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype != BINARY_TBL) { ffpmsg("This is not a binary table extension (ffgcxui)"); return(*status = NOT_BTABLE); } if (colnum > (fptr->Fptr)->tfield) { sprintf(message, "Specified column number is out of range: %d (ffgcxui)", colnum); ffpmsg(message); sprintf(message, " There are %d columns in this table.", (fptr->Fptr)->tfield ); ffpmsg(message); return(*status = BAD_COL_NUM); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ if (abs(colptr->tdatatype) > TBYTE) { ffpmsg("Can only read bits from X or B type columns. (ffgcxui)"); return(*status = NOT_LOGICAL_COL); /* not correct datatype column */ } firstbyte = (input_first_bit - 1 ) / 8 + 1; lastbyte = (input_first_bit + input_nbits - 2) / 8 + 1; nbytes = lastbyte - firstbyte + 1; if (colptr->tdatatype == TBIT && input_first_bit + input_nbits - 1 > (long) colptr->trepeat) { ffpmsg("Too many bits. Tried to read past width of column (ffgcxui)"); return(*status = BAD_ELEM_NUM); } else if (colptr->tdatatype == TBYTE && lastbyte > (long) colptr->trepeat) { ffpmsg("Too many bits. Tried to read past width of column (ffgcxui)"); return(*status = BAD_ELEM_NUM); } for (ii = 0; ii < nrows; ii++) { /* read the relevant bytes from the row */ if (ffgcvui(fptr, colnum, firstrow+ii, firstbyte, nbytes, 0, colbyte, NULL, status) > 0) { ffpmsg("Error reading bytes from column (ffgcxui)"); return(*status); } firstbit = (input_first_bit - 1) % 8; /* modulus operator */ nbits = input_nbits; array[ii] = 0; /* select and shift the bits from each byte into the output word */ while(nbits) { bytenum = firstbit / 8; startbit = firstbit % 8; numbits = minvalue(nbits, 8 - startbit); endbit = startbit + numbits - 1; rshift = 7 - endbit; lshift = nbits - numbits; array[ii] = ((colbyte[bytenum] >> rshift) << lshift) | array[ii]; nbits -= numbits; firstbit += numbits; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgcxuk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG nrows, /* I - no. of rows to read */ long input_first_bit, /* I - first bit to read (1 = 1st) */ int input_nbits, /* I - number of bits to read (<= 32) */ unsigned int *array, /* O - array of integer values */ int *status) /* IO - error status */ /* Read a consecutive string of bits from an 'X' or 'B' column and interprete them as an unsigned integer. The number of bits must be less than or equal to 32 or the total number of bits in the column, which ever is less. */ { int ii, firstbit, nbits, bytenum, startbit, numbits, endbit; int firstbyte, lastbyte, nbytes, rshift, lshift; unsigned int colbyte[5]; tcolumn *colptr; char message[81]; if (*status > 0 || nrows == 0) return(*status); /* check input parameters */ if (firstrow < 1) { sprintf(message, "Starting row number is less than 1: %ld (ffgcxuk)", (long) firstrow); ffpmsg(message); return(*status = BAD_ROW_NUM); } else if (input_first_bit < 1) { sprintf(message, "Starting bit number is less than 1: %ld (ffgcxuk)", input_first_bit); ffpmsg(message); return(*status = BAD_ELEM_NUM); } else if (input_nbits > 32) { sprintf(message, "Number of bits to read is > 32: %d (ffgcxuk)", input_nbits); ffpmsg(message); return(*status = BAD_ELEM_NUM); } /* position to the correct HDU */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype != BINARY_TBL) { ffpmsg("This is not a binary table extension (ffgcxuk)"); return(*status = NOT_BTABLE); } if (colnum > (fptr->Fptr)->tfield) { sprintf(message, "Specified column number is out of range: %d (ffgcxuk)", colnum); ffpmsg(message); sprintf(message, " There are %d columns in this table.", (fptr->Fptr)->tfield ); ffpmsg(message); return(*status = BAD_COL_NUM); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ if (abs(colptr->tdatatype) > TBYTE) { ffpmsg("Can only read bits from X or B type columns. (ffgcxuk)"); return(*status = NOT_LOGICAL_COL); /* not correct datatype column */ } firstbyte = (input_first_bit - 1 ) / 8 + 1; lastbyte = (input_first_bit + input_nbits - 2) / 8 + 1; nbytes = lastbyte - firstbyte + 1; if (colptr->tdatatype == TBIT && input_first_bit + input_nbits - 1 > (long) colptr->trepeat) { ffpmsg("Too many bits. Tried to read past width of column (ffgcxuk)"); return(*status = BAD_ELEM_NUM); } else if (colptr->tdatatype == TBYTE && lastbyte > (long) colptr->trepeat) { ffpmsg("Too many bits. Tried to read past width of column (ffgcxuk)"); return(*status = BAD_ELEM_NUM); } for (ii = 0; ii < nrows; ii++) { /* read the relevant bytes from the row */ if (ffgcvuk(fptr, colnum, firstrow+ii, firstbyte, nbytes, 0, colbyte, NULL, status) > 0) { ffpmsg("Error reading bytes from column (ffgcxuk)"); return(*status); } firstbit = (input_first_bit - 1) % 8; /* modulus operator */ nbits = input_nbits; array[ii] = 0; /* select and shift the bits from each byte into the output word */ while(nbits) { bytenum = firstbit / 8; startbit = firstbit % 8; numbits = minvalue(nbits, 8 - startbit); endbit = startbit + numbits - 1; rshift = 7 - endbit; lshift = nbits - numbits; array[ii] = ((colbyte[bytenum] >> rshift) << lshift) | array[ii]; nbits -= numbits; firstbit += numbits; } } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/getcols.c000066400000000000000000000700441215713201500222410ustar00rootroot00000000000000/* This file, getcols.c, contains routines that read data elements from */ /* a FITS image or table, with a character string datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include /* stddef.h is apparently needed to define size_t */ #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgcvs( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of strings to read */ char *nulval, /* I - string for null pixels */ char **array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of string values from a column in the current FITS HDU. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = null in which case no checks for undefined pixels will be made. */ { char cdummy[2]; ffgcls(fptr, colnum, firstrow, firstelem, nelem, 1, nulval, array, cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfs( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of strings to read */ char **array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of string values from a column in the current FITS HDU. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { char dummy[2]; ffgcls(fptr, colnum, firstrow, firstelem, nelem, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcls( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of strings to read */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ char *nulval, /* I - value for null pixels if nultyp = 1 */ char **array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of string values from a column in the current FITS HDU. Returns a formated string value, regardless of the datatype of the column */ { int tcode, hdutype, tstatus, scaled, intcol, dwidth, nulwidth, ll, dlen; long ii, jj; tcolumn *colptr; char message[FLEN_ERRMSG], *carray, keyname[FLEN_KEYWORD]; char cform[20], dispfmt[20], tmpstr[400], *flgarray, tmpnull[80]; unsigned char byteval; float *earray; double *darray, tscale = 1.0; LONGLONG *llarray; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) { sprintf(message, "Specified column number is out of range: %d", colnum); ffpmsg(message); return(*status = BAD_COL_NUM); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = abs(colptr->tdatatype); if (tcode == TSTRING) { /* simply call the string column reading routine */ ffgcls2(fptr, colnum, firstrow, firstelem, nelem, nultyp, nulval, array, nularray, anynul, status); } else if (tcode == TLOGICAL) { /* allocate memory for the array of logical values */ carray = (char *) malloc((size_t) nelem); /* call the logical column reading routine */ ffgcll(fptr, colnum, firstrow, firstelem, nelem, nultyp, *nulval, carray, nularray, anynul, status); if (*status <= 0) { /* convert logical values to "T", "F", or "N" (Null) */ for (ii = 0; ii < nelem; ii++) { if (carray[ii] == 1) strcpy(array[ii], "T"); else if (carray[ii] == 0) strcpy(array[ii], "F"); else /* undefined values = 2 */ strcpy(array[ii],"N"); } } free(carray); /* free the memory */ } else if (tcode == TCOMPLEX) { /* allocate memory for the array of double values */ earray = (float *) calloc((size_t) (nelem * 2), sizeof(float) ); ffgcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 1, FLOATNULLVALUE, earray, nularray, anynul, status); if (*status <= 0) { /* determine the format for the output strings */ ffgcdw(fptr, colnum, &dwidth, status); dwidth = (dwidth - 3) / 2; /* use the TDISPn keyword if it exists */ ffkeyn("TDISP", colnum, keyname, status); tstatus = 0; cform[0] = '\0'; if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0) { /* convert the Fortran style format to a C style format */ ffcdsp(dispfmt, cform); } if (!cform[0]) strcpy(cform, "%14.6E"); /* write the formated string for each value: "(real,imag)" */ jj = 0; for (ii = 0; ii < nelem; ii++) { strcpy(array[ii], "("); /* test for null value */ if (earray[jj] == FLOATNULLVALUE) { strcpy(tmpstr, "NULL"); if (nultyp == 2) nularray[ii] = 1; } else sprintf(tmpstr, cform, earray[jj]); strncat(array[ii], tmpstr, dwidth); strcat(array[ii], ","); jj++; /* test for null value */ if (earray[jj] == FLOATNULLVALUE) { strcpy(tmpstr, "NULL"); if (nultyp == 2) nularray[ii] = 1; } else sprintf(tmpstr, cform, earray[jj]); strncat(array[ii], tmpstr, dwidth); strcat(array[ii], ")"); jj++; } } free(earray); /* free the memory */ } else if (tcode == TDBLCOMPLEX) { /* allocate memory for the array of double values */ darray = (double *) calloc((size_t) (nelem * 2), sizeof(double) ); ffgcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 1, DOUBLENULLVALUE, darray, nularray, anynul, status); if (*status <= 0) { /* determine the format for the output strings */ ffgcdw(fptr, colnum, &dwidth, status); dwidth = (dwidth - 3) / 2; /* use the TDISPn keyword if it exists */ ffkeyn("TDISP", colnum, keyname, status); tstatus = 0; cform[0] = '\0'; if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0) { /* convert the Fortran style format to a C style format */ ffcdsp(dispfmt, cform); } if (!cform[0]) strcpy(cform, "%23.15E"); /* write the formated string for each value: "(real,imag)" */ jj = 0; for (ii = 0; ii < nelem; ii++) { strcpy(array[ii], "("); /* test for null value */ if (darray[jj] == DOUBLENULLVALUE) { strcpy(tmpstr, "NULL"); if (nultyp == 2) nularray[ii] = 1; } else sprintf(tmpstr, cform, darray[jj]); strncat(array[ii], tmpstr, dwidth); strcat(array[ii], ","); jj++; /* test for null value */ if (darray[jj] == DOUBLENULLVALUE) { strcpy(tmpstr, "NULL"); if (nultyp == 2) nularray[ii] = 1; } else sprintf(tmpstr, cform, darray[jj]); strncat(array[ii], tmpstr, dwidth); strcat(array[ii], ")"); jj++; } } free(darray); /* free the memory */ } else if (tcode == TLONGLONG) { /* allocate memory for the array of LONGLONG values */ llarray = (LONGLONG *) calloc((size_t) nelem, sizeof(LONGLONG) ); flgarray = (char *) calloc((size_t) nelem, sizeof(char) ); dwidth = 20; /* max width of displayed long long integer value */ if (ffgcfjj(fptr, colnum, firstrow, firstelem, nelem, llarray, flgarray, anynul, status) > 0) { free(flgarray); free(llarray); return(*status); } /* write the formated string for each value */ if (nulval) { strcpy(tmpnull, nulval); nulwidth = strlen(nulval); } else { strcpy(tmpnull, " "); nulwidth = 1; } for (ii = 0; ii < nelem; ii++) { if ( flgarray[ii] ) { *array[ii] = '\0'; if (dwidth < nulwidth) strncat(array[ii], tmpnull, dwidth); else sprintf(array[ii],"%*s",dwidth,tmpnull); if (nultyp == 2) nularray[ii] = 1; } else { #if defined(_MSC_VER) /* Microsoft Visual C++ 6.0 uses '%I64d' syntax for 8-byte integers */ sprintf(tmpstr, "%20I64d", llarray[ii]); #elif (USE_LL_SUFFIX == 1) sprintf(tmpstr, "%20lld", llarray[ii]); #else sprintf(tmpstr, "%20ld", llarray[ii]); #endif *array[ii] = '\0'; strncat(array[ii], tmpstr, 20); } } free(flgarray); free(llarray); /* free the memory */ } else { /* allocate memory for the array of double values */ darray = (double *) calloc((size_t) nelem, sizeof(double) ); /* read all other numeric type columns as doubles */ if (ffgcld(fptr, colnum, firstrow, firstelem, nelem, 1, nultyp, DOUBLENULLVALUE, darray, nularray, anynul, status) > 0) { free(darray); return(*status); } /* determine the format for the output strings */ ffgcdw(fptr, colnum, &dwidth, status); /* check if column is scaled */ ffkeyn("TSCAL", colnum, keyname, status); tstatus = 0; scaled = 0; if (ffgkyd(fptr, keyname, &tscale, NULL, &tstatus) == 0) { if (tscale != 1.0) scaled = 1; /* yes, this is a scaled column */ } intcol = 0; if (tcode <= TLONG && !scaled) intcol = 1; /* this is an unscaled integer column */ /* use the TDISPn keyword if it exists */ ffkeyn("TDISP", colnum, keyname, status); tstatus = 0; cform[0] = '\0'; if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0) { /* convert the Fortran style TDISPn to a C style format */ ffcdsp(dispfmt, cform); } if (!cform[0]) { /* no TDISPn keyword; use TFORMn instead */ ffkeyn("TFORM", colnum, keyname, status); ffgkys(fptr, keyname, dispfmt, NULL, status); if (scaled && tcode <= TSHORT) { /* scaled short integer column == float */ strcpy(cform, "%#14.6G"); } else if (scaled && tcode == TLONG) { /* scaled long integer column == double */ strcpy(cform, "%#23.15G"); } else { ffghdt(fptr, &hdutype, status); if (hdutype == ASCII_TBL) { /* convert the Fortran style TFORMn to a C style format */ ffcdsp(dispfmt, cform); } else { /* this is a binary table, need to convert the format */ if (tcode == TBIT) { /* 'X' */ strcpy(cform, "%4d"); } else if (tcode == TBYTE) { /* 'B' */ strcpy(cform, "%4d"); } else if (tcode == TSHORT) { /* 'I' */ strcpy(cform, "%6d"); } else if (tcode == TLONG) { /* 'J' */ strcpy(cform, "%11.0f"); intcol = 0; /* needed to support unsigned int */ } else if (tcode == TFLOAT) { /* 'E' */ strcpy(cform, "%#14.6G"); } else if (tcode == TDOUBLE) { /* 'D' */ strcpy(cform, "%#23.15G"); } } } } if (nulval) { strcpy(tmpnull, nulval); nulwidth = strlen(nulval); } else { strcpy(tmpnull, " "); nulwidth = 1; } /* write the formated string for each value */ for (ii = 0; ii < nelem; ii++) { if (tcode == TBIT) { byteval = (char) darray[ii]; for (ll=0; ll < 8; ll++) { if ( ((unsigned char) (byteval << ll)) >> 7 ) *(array[ii] + ll) = '1'; else *(array[ii] + ll) = '0'; } *(array[ii] + 8) = '\0'; } /* test for null value */ else if ( (nultyp == 1 && darray[ii] == DOUBLENULLVALUE) || (nultyp == 2 && nularray[ii]) ) { *array[ii] = '\0'; if (dwidth < nulwidth) strncat(array[ii], tmpnull, dwidth); else sprintf(array[ii],"%*s",dwidth,tmpnull); } else { if (intcol) sprintf(tmpstr, cform, (int) darray[ii]); else sprintf(tmpstr, cform, darray[ii]); /* fill field with '*' if number is too wide */ dlen = strlen(tmpstr); if (dlen > dwidth) { memset(tmpstr, '*', dwidth); } *array[ii] = '\0'; strncat(array[ii], tmpstr, dwidth); } } free(darray); /* free the memory */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffgcdw( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column (1 = 1st col) */ int *width, /* O - display width */ int *status) /* IO - error status */ /* Get Column Display Width. */ { tcolumn *colptr; char *cptr; char message[FLEN_ERRMSG], keyname[FLEN_KEYWORD], dispfmt[20]; int tcode, hdutype, tstatus, scaled; double tscale; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) { sprintf(message, "Specified column number is out of range: %d", colnum); ffpmsg(message); return(*status = BAD_COL_NUM); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = abs(colptr->tdatatype); /* use the TDISPn keyword if it exists */ ffkeyn("TDISP", colnum, keyname, status); *width = 0; tstatus = 0; if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0) { /* parse TDISPn get the display width */ cptr = dispfmt; while(*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == 'A' || *cptr == 'a' || *cptr == 'I' || *cptr == 'i' || *cptr == 'O' || *cptr == 'o' || *cptr == 'Z' || *cptr == 'z' || *cptr == 'F' || *cptr == 'f' || *cptr == 'E' || *cptr == 'e' || *cptr == 'D' || *cptr == 'd' || *cptr == 'G' || *cptr == 'g') { while(!isdigit((int) *cptr) && *cptr != '\0') /* find 1st digit */ cptr++; *width = atoi(cptr); if (tcode >= TCOMPLEX) *width = (2 * (*width)) + 3; } } if (*width == 0) { /* no valid TDISPn keyword; use TFORMn instead */ ffkeyn("TFORM", colnum, keyname, status); ffgkys(fptr, keyname, dispfmt, NULL, status); /* check if column is scaled */ ffkeyn("TSCAL", colnum, keyname, status); tstatus = 0; scaled = 0; if (ffgkyd(fptr, keyname, &tscale, NULL, &tstatus) == 0) { if (tscale != 1.0) scaled = 1; /* yes, this is a scaled column */ } if (scaled && tcode <= TSHORT) { /* scaled short integer col == float; default format is 14.6G */ *width = 14; } else if (scaled && tcode == TLONG) { /* scaled long integer col == double; default format is 23.15G */ *width = 23; } else { ffghdt(fptr, &hdutype, status); /* get type of table */ if (hdutype == ASCII_TBL) { /* parse TFORMn get the display width */ cptr = dispfmt; while(!isdigit((int) *cptr) && *cptr != '\0') /* find 1st digit */ cptr++; *width = atoi(cptr); } else { /* this is a binary table */ if (tcode == TBIT) /* 'X' */ *width = 8; else if (tcode == TBYTE) /* 'B' */ *width = 4; else if (tcode == TSHORT) /* 'I' */ *width = 6; else if (tcode == TLONG) /* 'J' */ *width = 11; else if (tcode == TLONGLONG) /* 'K' */ *width = 20; else if (tcode == TFLOAT) /* 'E' */ *width = 14; else if (tcode == TDOUBLE) /* 'D' */ *width = 23; else if (tcode == TCOMPLEX) /* 'C' */ *width = 31; else if (tcode == TDBLCOMPLEX) /* 'M' */ *width = 49; else if (tcode == TLOGICAL) /* 'L' */ *width = 1; else if (tcode == TSTRING) /* 'A' */ { cptr = dispfmt; while(!isdigit((int) *cptr) && *cptr != '\0') cptr++; *width = atoi(cptr); if (*width < 1) *width = 1; /* default is at least 1 column */ } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgcls2 ( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of strings to read */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ char *nulval, /* I - value for null pixels if nultyp = 1 */ char **array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of string values from a column in the current FITS HDU. */ { double dtemp; long nullen; int tcode, maxelem, hdutype, nulcheck; long twidth, incre; long ii, jj, ntodo; LONGLONG repeat, startpos, elemnum, readptr, tnull, rowlen, rownum, remain, next; double scale, zero; char tform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ tcolumn *colptr; double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ char *buffer, *arrayptr; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (colnum < 1 || colnum > (fptr->Fptr)->tfield) { sprintf(message, "Specified column number is out of range: %d", colnum); ffpmsg(message); return(*status = BAD_COL_NUM); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode == -TSTRING) /* variable length column in a binary table? */ { /* only read a single string; ignore value of firstelem */ if (ffgcprll( fptr, colnum, firstrow, 1, 1, 0, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); remain = 1; twidth = (long) repeat; } else if (tcode == TSTRING) { if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 0, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); remain = nelem; } else return(*status = NOT_ASCII_COL); nullen = strlen(snull); /* length of the undefined pixel string */ if (nullen == 0) nullen = 1; /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (nultyp == 1 && nulval && nulval[0] == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /* null value string in ASCII table not defined */ else if (nullen > twidth) nulcheck = 0; /* null value string is longer than width of column */ /* thus impossible for any column elements to = null */ /*---------------------------------------------------------------------*/ /* Now read the strings one at a time from the FITS column. */ /*---------------------------------------------------------------------*/ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, readptr, REPORT_EOF, status); /* move to read position */ /* read the array of strings from the FITS file into the buffer */ if (incre == twidth) ffgbyt(fptr, ntodo * twidth, cbuff, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, cbuff, status); /* copy from the buffer into the user's array of strings */ /* work backwards from last char of last string to 1st char of 1st */ buffer = ((char *) cbuff) + (ntodo * twidth) - 1; for (ii = (long) (next + ntodo - 1); ii >= next; ii--) { arrayptr = array[ii] + twidth - 1; for (jj = twidth - 1; jj > 0; jj--) /* ignore trailing blanks */ { if (*buffer == ' ') { buffer--; arrayptr--; } else break; } *(arrayptr + 1) = 0; /* write the string terminator */ for (; jj >= 0; jj--) /* copy the string itself */ { *arrayptr = *buffer; buffer--; arrayptr--; } /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (nulcheck && !strncmp(snull, array[ii], nullen) ) { *anynul = 1; /* this is a null value */ if (nultyp == 1) { if (nulval) strcpy(array[ii], nulval); else strcpy(array[ii], " "); } else nularray[ii] = 1; } } if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; sprintf(message, "Error reading elements %.0f thru %.0f of data array (ffpcls).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ next += ntodo; remain -= ntodo; if (remain) { elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/getcolsb.c000066400000000000000000002232341215713201500224040ustar00rootroot00000000000000/* This file, getcolsb.c, contains routines that read data elements from */ /* a FITS image or table, with signed char (signed byte) data type. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvsb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ signed char nulval, /* I - value for undefined pixels */ signed char *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; signed char nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TSBYTE, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclsb(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfsb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ signed char *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TSBYTE, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclsb(fptr, 2, row, firstelem, nelem, 1, 2, 0, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2dsb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ signed char nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ signed char *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3dsb(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3dsb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ signed char nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ signed char *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; LONGLONG nfits, narray; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}; LONGLONG lpixel[3]; signed char nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TSBYTE, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgclsb(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgclsb(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvsb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ signed char nulval, /* I - value to set undefined pixels */ signed char *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii, i0, i1, i2, i3, i4, i5, i6, i7, i8, row, rstr, rstp, rinc; long str[9], stp[9], incr[9], dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; signed char nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvsb is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TSBYTE, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { sprintf(msg, "ffgsvsb: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgclsb(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfsb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ signed char *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; int hdutype, anyf; signed char nulval = 0; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvsb is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TSBYTE, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvsb: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgclsb(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpsb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ signed char *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclsb(fptr, 1, row, firstelem, nelem, 1, 1, 0, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvsb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ signed char nulval, /* I - value for null pixels */ signed char *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgclsb(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfsb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ signed char *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { signed char dummy = 0; ffgclsb(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgclsb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ signed char nulval, /* I - value for null pixels if nultyp = 1 */ signed char *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; union u_tag { char charval; signed char scharval; } u; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ ffgcprll( fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status); /* special case: read column of T/F logicals */ if (tcode == TLOGICAL && elemincre == 1) { u.scharval = nulval; ffgcll(fptr, colnum, firstrow, firstelem, nelem, nultyp, u.charval, (char *) array, nularray, anynul, status); return(*status); } if (strchr(tform,'A') != NULL) { if (*status == BAD_ELEM_NUM) { /* ignore this error message */ *status = 0; ffcmsg(); /* clear error stack */ } /* interpret a 'A' ASCII column as a 'B' byte column ('8A' == '8B') */ /* This is an undocumented 'feature' in CFITSIO */ /* we have to reset some of the values returned by ffgcpr */ tcode = TBYTE; incre = 1; /* each element is 1 byte wide */ repeat = twidth; /* total no. of chars in the col */ twidth = 1; /* width of each element */ scale = 1.0; /* no scaling */ zero = 0.0; tnull = NULL_UNDEFINED; /* don't test for nulls */ maxelem = DBUFFSIZE; } if (*status > 0) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING && hdutype == ASCII_TBL) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default, check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + (rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) &array[next], status); fffi1s1((unsigned char *)&array[next], ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2s1((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4s1((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8s1( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4s1((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8s1((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); /* interpret the string as an ASCII formated number */ fffstrs1((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read bytes from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgclsb).", dtemp+1., dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgclsb).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1s1(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ signed char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ signed char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == -128.) { /* Instead of subtracting 128, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) output[ii] = ( *(signed char *) &input[ii] ) ^ 0x80; } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; /* copy input */ } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == -128.) { /* Instead of subtracting 128, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = ( *(signed char *) &input[ii] ) ^ 0x80; } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (signed char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2s1(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ signed char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ signed char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < -128) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < -128) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4s1(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ signed char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ signed char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < -128) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < -128) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8s1(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ signed char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ signed char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < -128) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < -128) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4s1(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ signed char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ signed char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { /* use redundant boolean logic in following statement */ /* to suppress irritating Borland compiler warning message */ if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (zero > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8s1(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ signed char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ signed char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (zero > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstrs1(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ signed char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ signed char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/getcolui.c000066400000000000000000002166701215713201500224230ustar00rootroot00000000000000/* This file, getcolui.c, contains routines that read data elements from */ /* a FITS image or table, with unsigned short datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvui( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned short nulval, /* I - value for undefined pixels */ unsigned short *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; unsigned short nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TUSHORT, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclui(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfui( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned short *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TUSHORT, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclui(fptr, 2, row, firstelem, nelem, 1, 2, 0, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2dui(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned short nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned short *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3dui(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3dui(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned short nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned short *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}, nfits, narray; LONGLONG lpixel[3]; unsigned short nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TUSHORT, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgclui(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgclui(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvui(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned short nulval, /* I - value to set undefined pixels */ unsigned short *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; unsigned short nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvui is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TUSHORT, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvui: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgclui(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfui(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned short *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; int hdutype, anyf; unsigned short nulval = 0; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvi is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TUSHORT, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvi: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgclui(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpui( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ unsigned short *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclui(fptr, 1, row, firstelem, nelem, 1, 1, 0, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvui(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned short nulval, /* I - value for null pixels */ unsigned short *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgclui(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfui(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned short *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { unsigned short dummy = 0; ffgclui(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgclui( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ unsigned short nulval, /* I - value for null pixels if nultyp = 1 */ unsigned short *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int nulcheck; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 0, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ if (tcode == TSHORT) /* Special Case: */ { /* no type convertion required, so read */ maxelem = (int) nelem; /* data directly into output buffer. */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) &array[next], status); fffi2u2((short *) &array[next], ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8u2( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1u2((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4u2((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4u2((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8u2((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstru2((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgclui).", dtemp+1., dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgclui).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1u2(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ unsigned short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (unsigned short) input[ii]; /* copy input */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (unsigned short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2u2(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ unsigned short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 32768.) { /* Instead of adding 32768, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) output[ii] = ( *(unsigned short *) &input[ii] ) ^ 0x8000; } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned short) input[ii]; /* copy input */ } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 32768.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = ( *(unsigned short *) &input[ii] ) ^ 0x8000; } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned short) input[ii]; /* copy input */ } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4u2(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ unsigned short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > USHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > USHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8u2(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ unsigned short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > USHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > USHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4u2(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8u2(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstru2(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ unsigned short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/getcoluj.c000066400000000000000000002163711215713201500224220ustar00rootroot00000000000000/* This file, getcoluj.c, contains routines that read data elements from */ /* a FITS image or table, with unsigned long data type. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvuj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned long nulval, /* I - value for undefined pixels */ unsigned long *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; unsigned long nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TULONG, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcluj(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfuj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned long *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TULONG, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcluj(fptr, 2, row, firstelem, nelem, 1, 2, 0L, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2duj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned long nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned long *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3duj(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3duj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned long nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned long *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}, nfits, narray; LONGLONG lpixel[3]; unsigned long nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TULONG, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgcluj(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgcluj(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvuj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned long nulval, /* I - value to set undefined pixels */ unsigned long *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; unsigned long nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvuj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TULONG, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvuj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcluj(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfuj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned long *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; unsigned long nulval = 0; int hdutype, anyf; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TULONG, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcluj(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpuj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ unsigned long *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcluj(fptr, 1, row, firstelem, nelem, 1, 1, 0L, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvuj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned long nulval, /* I - value for null pixels */ unsigned long *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgcluj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfuj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned long *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { unsigned long dummy = 0; ffgcluj(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcluj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ unsigned long nulval, /* I - value for null pixels if nultyp = 1 */ unsigned long *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int nulcheck; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 0, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ if (tcode == TLONG) /* Special Case: */ { /* no type convertion required, so read */ maxelem = (int) nelem; /* data directly into output buffer. */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) &array[next], status); fffi4u4((INT32BIT *) &array[next], ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8u4( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1u4((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2u4((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4u4((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8u4((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstru4((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgcluj).", dtemp+1., dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgcluj).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1u4(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ unsigned long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (unsigned long) input[ii]; /* copy input */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (unsigned long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2u4(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ unsigned long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned long) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4u4(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ unsigned long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; Process the array of data in reverse order, to handle the case where the input data is 4-bytes and the output is 8-bytes and the conversion is being done in place in the same array. */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 2147483648.) { /* Instead of adding 2147483648, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = ntodo - 1; ii >= 0; ii--) output[ii] = ( *(unsigned int *) &input[ii] ) ^ 0x80000000; } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = ntodo - 1; ii >= 0; ii--) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned long) input[ii]; /* copy input */ } } else /* must scale the data */ { for (ii = ntodo - 1; ii >= 0; ii--) { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 2147483648.) { for (ii = ntodo - 1; ii >= 0; ii--) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = ( *(unsigned int *) &input[ii] ) ^ 0x80000000; } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = ntodo - 1; ii >= 0; ii--) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned long) input[ii]; /* copy input */ } } else /* must scale the data */ { for (ii = ntodo - 1; ii >= 0; ii--) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8u4(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ unsigned long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > ULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > ULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4u4(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8u4(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstru4(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ unsigned long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/getcoluk.c000066400000000000000000002172251215713201500224220ustar00rootroot00000000000000/* This file, getcolk.c, contains routines that read data elements from */ /* a FITS image or table, with 'unsigned int' data type. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvuk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned int nulval, /* I - value for undefined pixels */ unsigned int *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; unsigned int nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TUINT, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcluk(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfuk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned int *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TUINT, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcluk(fptr, 2, row, firstelem, nelem, 1, 2, 0L, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2duk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned int nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned int *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3duk(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3duk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned int nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned int *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}, nfits, narray; LONGLONG lpixel[3]; unsigned int nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TUINT, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgcluk(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgcluk(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvuk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned int nulval, /* I - value to set undefined pixels */ unsigned int *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; unsigned int nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvuk is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TUINT, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvuk: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcluk(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfuk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned int *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; long nulval = 0; int hdutype, anyf; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TUINT, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcluk(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpuk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ unsigned int *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcluk(fptr, 1, row, firstelem, nelem, 1, 1, 0L, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvuk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned int nulval, /* I - value for null pixels */ unsigned int *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgcluk(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfuk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned int *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { int dummy = 0; ffgcluk(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcluk( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ unsigned int nulval, /* I - value for null pixels if nultyp = 1 */ unsigned int *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int nulcheck; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* call the 'short' or 'long' version of this routine, if possible */ if (sizeof(int) == sizeof(short)) ffgclui(fptr, colnum, firstrow, firstelem, nelem, elemincre, nultyp, (unsigned short) nulval, (unsigned short *) array, nularray, anynul, status); else if (sizeof(int) == sizeof(long)) ffgcluj(fptr, colnum, firstrow, firstelem, nelem, elemincre, nultyp, (unsigned long) nulval, (unsigned long *) array, nularray, anynul, status); else { /* This is a special case: sizeof(int) is not equal to sizeof(short) or sizeof(long). This occurs on Alpha OSF systems where short = 2 bytes, int = 4 bytes, and long = 8 bytes. */ buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 0, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ if (tcode == TLONG) /* Special Case: */ { /* data are 4-bytes long, so read */ maxelem = (int) nelem; /* data directly into output buffer. */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) &array[next], status); fffi4uint((INT32BIT *) &array[next], ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8uint( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1uint((unsigned char *) buffer, ntodo, scale, zero,nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2uint((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4uint((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8uint((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstruint((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgcluk).", dtemp+1., dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgcluk).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } } /* end of DEC Alpha special case */ return(*status); } /*--------------------------------------------------------------------------*/ int fffi1uint(unsigned char *input,/* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ unsigned int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (unsigned int) input[ii]; /* copy input */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (unsigned int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2uint(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ unsigned int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned int) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4uint(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ unsigned int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 2147483648.) { /* Instead of adding 2147483648, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) output[ii] = ( *(unsigned int *) &input[ii] ) ^ 0x80000000; } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned int) input[ii]; /* copy to output */ } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 2147483648.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = ( *(unsigned int *) &input[ii] ) ^ 0x80000000; } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8uint(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ unsigned int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4uint(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8uint(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstruint(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ unsigned int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (long) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/getkey.c000066400000000000000000003302551215713201500220740ustar00rootroot00000000000000/* This file, getkey.c, contains routines that read keywords from */ /* a FITS header. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include /* stddef.h is apparently needed to define size_t */ #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffghsp(fitsfile *fptr, /* I - FITS file pointer */ int *nexist, /* O - number of existing keywords in header */ int *nmore, /* O - how many more keywords will fit */ int *status) /* IO - error status */ /* returns the number of existing keywords (not counting the END keyword) and the number of more keyword that will fit in the current header without having to insert more FITS blocks. */ { if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); *nexist = (int) (( ((fptr->Fptr)->headend) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]) ) / 80); if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if (nmore) *nmore = -1; /* data not written yet, so room for any keywords */ } else { /* calculate space available between the data and the END card */ if (nmore) *nmore = (int) (((fptr->Fptr)->datastart - (fptr->Fptr)->headend) / 80 - 1); } return(*status); } /*--------------------------------------------------------------------------*/ int ffghps(fitsfile *fptr, /* I - FITS file pointer */ int *nexist, /* O - number of existing keywords in header */ int *position, /* O - position of next keyword to be read */ int *status) /* IO - error status */ /* return the number of existing keywords and the position of the next keyword that will be read. */ { if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); *nexist = (int) (( ((fptr->Fptr)->headend) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]) ) / 80); *position = (int) (( ((fptr->Fptr)->nextkey) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]) ) / 80 + 1); return(*status); } /*--------------------------------------------------------------------------*/ int ffnchk(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* function returns the position of the first null character (ASCII 0), if any, in the current header. Null characters are illegal, but the other CFITSIO routines that read the header will not detect this error, because the null gets interpreted as a normal end of string character. */ { long ii, nblock; LONGLONG bytepos; int length, nullpos; char block[2881]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { return(0); /* Don't check a file that is just being created. */ /* It cannot contain nulls since CFITSIO wrote it. */ } else { /* calculate number of blocks in the header */ nblock = (long) (( (fptr->Fptr)->datastart - (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) / 2880); } bytepos = (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]; ffmbyt(fptr, bytepos, REPORT_EOF, status); /* move to read pos. */ block[2880] = '\0'; for (ii = 0; ii < nblock; ii++) { if (ffgbyt(fptr, 2880, block, status) > 0) return(0); /* read error of some sort */ length = strlen(block); if (length != 2880) { nullpos = (ii * 2880) + length + 1; return(nullpos); } } return(0); } /*--------------------------------------------------------------------------*/ int ffmaky(fitsfile *fptr, /* I - FITS file pointer */ int nrec, /* I - one-based keyword number to move to */ int *status) /* IO - error status */ { /* move pointer to the specified absolute keyword position. E.g. this keyword will then be read by the next call to ffgnky. */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] + ( (nrec - 1) * 80); return(*status); } /*--------------------------------------------------------------------------*/ int ffmrky(fitsfile *fptr, /* I - FITS file pointer */ int nmove, /* I - relative number of keywords to move */ int *status) /* IO - error status */ { /* move pointer to the specified keyword position relative to the current position. E.g. this keyword will then be read by the next call to ffgnky. */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); (fptr->Fptr)->nextkey += (nmove * 80); return(*status); } /*--------------------------------------------------------------------------*/ int ffgnky(fitsfile *fptr, /* I - FITS file pointer */ char *card, /* O - card string */ int *status) /* IO - error status */ /* read the next keyword from the header - used internally by cfitsio */ { int jj, nrec; LONGLONG bytepos, endhead; char message[FLEN_ERRMSG]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); card[0] = '\0'; /* make sure card is terminated, even affer read error */ /* Check that nextkey points to a legal keyword position. Note that headend is the current end of the header, i.e., the position where a new keyword would be appended, however, if there are more than 1 FITS block worth of blank keywords at the end of the header (36 keywords per 2880 byte block) then the actual physical END card must be located at a starting position which is just 2880 bytes prior to the start of the data unit. */ bytepos = (fptr->Fptr)->nextkey; endhead = maxvalue( ((fptr->Fptr)->headend), ((fptr->Fptr)->datastart - 2880) ); /* nextkey must be < endhead and > than headstart */ if (bytepos > endhead || bytepos < (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) { nrec= (int) ((bytepos - (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]) / 80 + 1); sprintf(message, "Cannot get keyword number %d. It does not exist.", nrec); ffpmsg(message); return(*status = KEY_OUT_BOUNDS); } ffmbyt(fptr, bytepos, REPORT_EOF, status); /* move to read pos. */ card[80] = '\0'; /* make sure card is terminate, even if ffgbyt fails */ if (ffgbyt(fptr, 80, card, status) <= 0) { (fptr->Fptr)->nextkey += 80; /* increment pointer to next keyword */ /* strip off trailing blanks with terminated string */ jj = 79; while (jj >= 0 && card[jj] == ' ') jj--; card[jj + 1] = '\0'; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgnxk( fitsfile *fptr, /* I - FITS file pointer */ char **inclist, /* I - list of included keyword names */ int ninc, /* I - number of names in inclist */ char **exclist, /* I - list of excluded keyword names */ int nexc, /* I - number of names in exclist */ char *card, /* O - first matching keyword */ int *status) /* IO - error status */ /* Return the next keyword that matches one of the names in inclist but does not match any of the names in exclist. The search goes from the current position to the end of the header, only. Wild card characters may be used in the name lists ('*', '?' and '#'). */ { int casesn, match, exact, namelen; long ii, jj; char keybuf[FLEN_CARD], keyname[FLEN_KEYWORD]; card[0] = '\0'; if (*status > 0) return(*status); casesn = FALSE; /* get next card, and return with an error if hit end of header */ while( ffgcrd(fptr, "*", keybuf, status) <= 0) { ffgknm(keybuf, keyname, &namelen, status); /* get the keyword name */ /* does keyword match any names in the include list? */ for (ii = 0; ii < ninc; ii++) { ffcmps(inclist[ii], keyname, casesn, &match, &exact); if (match) { /* does keyword match any names in the exclusion list? */ jj = -1; while ( ++jj < nexc ) { ffcmps(exclist[jj], keyname, casesn, &match, &exact); if (match) break; } if (jj >= nexc) { /* not in exclusion list, so return this keyword */ strcat(card, keybuf); return(*status); } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgky( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ char *keyname, /* I - name of keyword to read */ void *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the keyword value and comment from the FITS header. Reads a keyword value with the datatype specified by the 2nd argument. */ { long longval; double doubleval; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (datatype == TSTRING) { ffgkys(fptr, keyname, (char *) value, comm, status); } else if (datatype == TBYTE) { if (ffgkyj(fptr, keyname, &longval, comm, status) <= 0) { if (longval > UCHAR_MAX || longval < 0) *status = NUM_OVERFLOW; else *(unsigned char *) value = (unsigned char) longval; } } else if (datatype == TSBYTE) { if (ffgkyj(fptr, keyname, &longval, comm, status) <= 0) { if (longval > 127 || longval < -128) *status = NUM_OVERFLOW; else *(signed char *) value = (signed char) longval; } } else if (datatype == TUSHORT) { if (ffgkyj(fptr, keyname, &longval, comm, status) <= 0) { if (longval > USHRT_MAX || longval < 0) *status = NUM_OVERFLOW; else *(unsigned short *) value = (unsigned short) longval; } } else if (datatype == TSHORT) { if (ffgkyj(fptr, keyname, &longval, comm, status) <= 0) { if (longval > SHRT_MAX || longval < SHRT_MIN) *status = NUM_OVERFLOW; else *(short *) value = (short) longval; } } else if (datatype == TUINT) { if (ffgkyj(fptr, keyname, &longval, comm, status) <= 0) { if (longval > (long) UINT_MAX || longval < 0) *status = NUM_OVERFLOW; else *(unsigned int *) value = longval; } } else if (datatype == TINT) { if (ffgkyj(fptr, keyname, &longval, comm, status) <= 0) { if (longval > INT_MAX || longval < INT_MIN) *status = NUM_OVERFLOW; else *(int *) value = longval; } } else if (datatype == TLOGICAL) { ffgkyl(fptr, keyname, (int *) value, comm, status); } else if (datatype == TULONG) { if (ffgkyd(fptr, keyname, &doubleval, comm, status) <= 0) { if (doubleval > (double) ULONG_MAX || doubleval < 0) *status = NUM_OVERFLOW; else *(unsigned long *) value = (unsigned long) doubleval; } } else if (datatype == TLONG) { ffgkyj(fptr, keyname, (long *) value, comm, status); } else if (datatype == TLONGLONG) { ffgkyjj(fptr, keyname, (LONGLONG *) value, comm, status); } else if (datatype == TFLOAT) { ffgkye(fptr, keyname, (float *) value, comm, status); } else if (datatype == TDOUBLE) { ffgkyd(fptr, keyname, (double *) value, comm, status); } else if (datatype == TCOMPLEX) { ffgkyc(fptr, keyname, (float *) value, comm, status); } else if (datatype == TDBLCOMPLEX) { ffgkym(fptr, keyname, (double *) value, comm, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgkey( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ char *keyval, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the keyword value and comment. The value is just the literal string of characters in the value field of the keyword. In the case of a string valued keyword, the returned value includes the leading and closing quote characters. The value may be up to 70 characters long, and the comment may be up to 72 characters long. If the keyword has no value (no equal sign in column 9) then a null value is returned. */ { char card[FLEN_CARD]; keyval[0] = '\0'; if (comm) comm[0] = '\0'; if (*status > 0) return(*status); if (ffgcrd(fptr, keyname, card, status) > 0) /* get the 80-byte card */ return(*status); ffpsvc(card, keyval, comm, status); /* parse the value and comment */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgrec( fitsfile *fptr, /* I - FITS file pointer */ int nrec, /* I - number of keyword to read */ char *card, /* O - keyword card */ int *status) /* IO - error status */ /* Read (get) the nrec-th keyword, returning the entire keyword card up to 80 characters long. The first keyword in the header has nrec = 1, not 0. The returned card value is null terminated with any trailing blank characters removed. If nrec = 0, then this routine simply moves the current header pointer to the top of the header. */ { if (*status > 0) return(*status); if (nrec == 0) { ffmaky(fptr, 1, status); /* simply move to beginning of header */ card[0] = '\0'; /* and return null card */ } else if (nrec > 0) { ffmaky(fptr, nrec, status); ffgnky(fptr, card, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgcrd( fitsfile *fptr, /* I - FITS file pointer */ char *name, /* I - name of keyword to read */ char *card, /* O - keyword card */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the entire keyword card up to 80 characters long. The first keyword in the header has nrec = 1, not 0. The returned card value is null terminated with any trailing blank characters removed. If the input name contains wild cards ('?' matches any single char and '*' matches any sequence of chars, # matches any string of decimal digits) then the search ends once the end of header is reached and does not automatically resume from the top of the header. */ { int nkeys, nextkey, ntodo, namelen, namelen_limit, namelenminus1, cardlen; int ii = 0, jj, kk, wild, match, exact, hier = 0; char keyname[FLEN_KEYWORD], cardname[FLEN_KEYWORD]; char *ptr1, *ptr2, *gotstar; if (*status > 0) return(*status); *keyname = '\0'; while (name[ii] == ' ') /* skip leading blanks in name */ ii++; strncat(keyname, &name[ii], FLEN_KEYWORD - 1); namelen = strlen(keyname); while (namelen > 0 && keyname[namelen - 1] == ' ') namelen--; /* ignore trailing blanks in name */ keyname[namelen] = '\0'; /* terminate the name */ for (ii=0; ii < namelen; ii++) keyname[ii] = toupper(keyname[ii]); /* make upper case */ if (FSTRNCMP("HIERARCH", keyname, 8) == 0) { if (namelen == 8) { /* special case: just looking for any HIERARCH keyword */ hier = 1; } else { /* ignore the leading HIERARCH and look for the 'real' name */ /* starting with first non-blank character following HIERARCH */ ptr1 = keyname; ptr2 = &keyname[8]; while(*ptr2 == ' ') ptr2++; namelen = 0; while(*ptr2) { *ptr1 = *ptr2; ptr1++; ptr2++; namelen++; } *ptr1 = '\0'; } } /* does input name contain wild card chars? ('?', '*', or '#') */ /* wild cards are currently not supported with HIERARCH keywords */ namelen_limit = namelen; gotstar = 0; if (namelen < 9 && (strchr(keyname,'?') || (gotstar = strchr(keyname,'*')) || strchr(keyname,'#')) ) { wild = 1; /* if we found a '*' wild card in the name, there might be */ /* more than one. Support up to 2 '*' in the template. */ /* Thus we need to compare keywords whose names have at least */ /* namelen - 2 characters. */ if (gotstar) namelen_limit -= 2; } else wild = 0; ffghps(fptr, &nkeys, &nextkey, status); /* get no. keywords and position */ namelenminus1 = maxvalue(namelen - 1, 1); ntodo = nkeys - nextkey + 1; /* first, read from next keyword to end */ for (jj=0; jj < 2; jj++) { for (kk = 0; kk < ntodo; kk++) { ffgnky(fptr, card, status); /* get next keyword */ if (hier) { if (FSTRNCMP("HIERARCH", card, 8) == 0) return(*status); /* found a HIERARCH keyword */ } else { ffgknm(card, cardname, &cardlen, status); /* get the keyword name */ if (cardlen >= namelen_limit) /* can't match if card < name */ { /* if there are no wild cards, lengths must be the same */ if (!( !wild && cardlen != namelen) ) { for (ii=0; ii < cardlen; ii++) { /* make sure keyword is in uppercase */ if (cardname[ii] > 96) { /* This assumes the ASCII character set in which */ /* upper case characters start at ASCII(97) */ /* Timing tests showed that this is 20% faster */ /* than calling the isupper function. */ cardname[ii] = toupper(cardname[ii]); /* make upper case */ } } if (wild) { ffcmps(keyname, cardname, 1, &match, &exact); if (match) return(*status); /* found a matching keyword */ } else if (keyname[namelenminus1] == cardname[namelenminus1]) { /* test the last character of the keyword name first, on */ /* the theory that it is less likely to match then the first */ /* character since many keywords begin with 'T', for example */ if (FSTRNCMP(keyname, cardname, namelenminus1) == 0) { return(*status); /* found the matching keyword */ } } } } } } if (wild || jj == 1) break; /* stop at end of header if template contains wildcards */ ffmaky(fptr, 1, status); /* reset pointer to beginning of header */ ntodo = nextkey - 1; /* number of keyword to read */ } return(*status = KEY_NO_EXIST); /* couldn't find the keyword */ } /*--------------------------------------------------------------------------*/ int ffgknm( char *card, /* I - keyword card */ char *name, /* O - name of the keyword */ int *length, /* O - length of the keyword name */ int *status) /* IO - error status */ /* Return the name of the keyword, and the name length. This supports the ESO HIERARCH convention where keyword names may be > 8 characters long. */ { char *ptr1, *ptr2; int ii; *name = '\0'; *length = 0; /* support for ESO HIERARCH keywords; find the '=' */ if (FSTRNCMP(card, "HIERARCH ", 9) == 0) { ptr2 = strchr(card, '='); if (!ptr2) /* no value indicator ??? */ { /* this probably indicates an error, so just return FITS name */ strcat(name, "HIERARCH"); *length = 8; return(*status); } /* find the start and end of the HIERARCH name */ ptr1 = &card[9]; while (*ptr1 == ' ') /* skip spaces */ ptr1++; strncat(name, ptr1, ptr2 - ptr1); ii = ptr2 - ptr1; while (ii > 0 && name[ii - 1] == ' ') /* remove trailing spaces */ ii--; name[ii] = '\0'; *length = ii; } else { for (ii = 0; ii < 8; ii++) { /* look for string terminator, or a blank */ if (*(card+ii) != ' ' && *(card+ii) !='\0') { *(name+ii) = *(card+ii); } else { name[ii] = '\0'; *length = ii; return(*status); } } /* if we got here, keyword is 8 characters long */ name[8] = '\0'; *length = 8; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgunt( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ char *unit, /* O - keyword units */ int *status) /* IO - error status */ /* Read (get) the units string from the comment field of the existing keyword. This routine uses a local FITS convention (not defined in the official FITS standard) in which the units are enclosed in square brackets following the '/' comment field delimiter, e.g.: KEYWORD = 12 / [kpc] comment string goes here */ { char valstring[FLEN_VALUE]; char comm[FLEN_COMMENT]; char *loc; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ if (comm[0] == '[') { loc = strchr(comm, ']'); /* find the closing bracket */ if (loc) *loc = '\0'; /* terminate the string */ strcpy(unit, &comm[1]); /* copy the string */ } else unit[0] = '\0'; return(*status); } /*--------------------------------------------------------------------------*/ int ffgkys( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ char *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Get KeYword with a String value: Read (get) a simple string valued keyword. The returned value may be up to 68 chars long ( + 1 null terminator char). The routine does not support the HEASARC convention for continuing long string values over multiple keywords. The ffgkls routine may be used to read long continued strings. The returned comment string may be up to 69 characters long (including null terminator). */ { char valstring[FLEN_VALUE]; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ value[0] = '\0'; ffc2s(valstring, value, status); /* remove quotes from string */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkls( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ char **value, /* O - pointer to keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Get Keyword with possible Long String value: Read (get) the named keyword, returning the value and comment. The returned value string may be arbitrarily long (by using the HEASARC convention for continuing long string values over multiple keywords) so this routine allocates the required memory for the returned string value. It is up to the calling routine to free the memory once it is finished with the value string. The returned comment string may be up to 69 characters long. */ { char valstring[FLEN_VALUE]; int contin; size_t len; if (*status > 0) return(*status); *value = NULL; /* initialize a null pointer in case of error */ ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ if (*status > 0) return(*status); if (!valstring[0]) /* null value string? */ { *value = (char *) malloc(1); /* allocate and return a null string */ **value = '\0'; } else { /* allocate space, plus 1 for null */ *value = (char *) malloc(strlen(valstring) + 1); ffc2s(valstring, *value, status); /* convert string to value */ len = strlen(*value); /* If last character is a & then value may be continued on next keyword */ contin = 1; while (contin) { if (len && *(*value+len-1) == '&') /* is last char an anpersand? */ { ffgcnt(fptr, valstring, status); if (*valstring) /* a null valstring indicates no continuation */ { *(*value+len-1) = '\0'; /* erase the trailing & char */ len += strlen(valstring) - 1; *value = (char *) realloc(*value, len + 1); /* increase size */ strcat(*value, valstring); /* append the continued chars */ } else contin = 0; } else contin = 0; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgcnt( fitsfile *fptr, /* I - FITS file pointer */ char *value, /* O - continued string value */ int *status) /* IO - error status */ /* Attempt to read the next keyword, returning the string value if it is a continuation of the previous string keyword value. This uses the HEASARC convention for continuing long string values over multiple keywords. Each continued string is terminated with a backslash character, and the continuation follows on the next keyword which must have the name CONTINUE without an equal sign in column 9 of the card. If the next card is not a continuation, then the returned value string will be null. */ { int tstatus; char card[FLEN_CARD], strval[FLEN_VALUE], comm[FLEN_COMMENT]; if (*status > 0) return(*status); tstatus = 0; value[0] = '\0'; if (ffgnky(fptr, card, &tstatus) > 0) /* read next keyword */ return(*status); /* hit end of header */ if (strncmp(card, "CONTINUE ", 10) == 0) /* a continuation card? */ { strncpy(card, "D2345678= ", 10); /* overwrite a dummy keyword name */ ffpsvc(card, strval, comm, &tstatus); /* get the string value */ ffc2s(strval, value, &tstatus); /* remove the surrounding quotes */ if (tstatus) /* return null if error status was returned */ value[0] = '\0'; } else ffmrky(fptr, -1, status); /* reset the keyword pointer */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyl( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ int *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The returned value = 1 if the keyword is true, else = 0 if false. The comment may be up to 69 characters long. */ { char valstring[FLEN_VALUE]; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ ffc2l(valstring, value, status); /* convert string to value */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyj( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ long *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The value will be implicitly converted to a (long) integer if it not already of this datatype. The comment may be up to 69 characters long. */ { char valstring[FLEN_VALUE]; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ ffc2i(valstring, value, status); /* convert string to value */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyjj( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ LONGLONG *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The value will be implicitly converted to a (long) integer if it not already of this datatype. The comment may be up to 69 characters long. */ { char valstring[FLEN_VALUE]; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ ffc2j(valstring, value, status); /* convert string to value */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkye( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ float *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The value will be implicitly converted to a float if it not already of this datatype. The comment may be up to 69 characters long. */ { char valstring[FLEN_VALUE]; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ ffc2r(valstring, value, status); /* convert string to value */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyd( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ double *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The value will be implicitly converted to a double if it not already of this datatype. The comment may be up to 69 characters long. */ { char valstring[FLEN_VALUE]; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ ffc2d(valstring, value, status); /* convert string to value */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyc( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ float *value, /* O - keyword value (real,imag) */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The keyword must have a complex value. No implicit data conversion will be performed. */ { char valstring[FLEN_VALUE], message[81]; int len; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ if (valstring[0] != '(' ) /* test that this is a complex keyword */ { sprintf(message, "keyword %s does not have a complex value (ffgkyc):", keyname); ffpmsg(message); ffpmsg(valstring); return(*status = BAD_C2F); } valstring[0] = ' '; /* delete the opening parenthesis */ len = strcspn(valstring, ")" ); valstring[len] = '\0'; /* delete the closing parenthesis */ len = strcspn(valstring, ","); valstring[len] = '\0'; ffc2r(valstring, &value[0], status); /* convert the real part */ ffc2r(&valstring[len + 1], &value[1], status); /* convert imag. part */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkym( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ double *value, /* O - keyword value (real,imag) */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The keyword must have a complex value. No implicit data conversion will be performed. */ { char valstring[FLEN_VALUE], message[81]; int len; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ if (valstring[0] != '(' ) /* test that this is a complex keyword */ { sprintf(message, "keyword %s does not have a complex value (ffgkym):", keyname); ffpmsg(message); ffpmsg(valstring); return(*status = BAD_C2D); } valstring[0] = ' '; /* delete the opening parenthesis */ len = strcspn(valstring, ")" ); valstring[len] = '\0'; /* delete the closing parenthesis */ len = strcspn(valstring, ","); valstring[len] = '\0'; ffc2d(valstring, &value[0], status); /* convert the real part */ ffc2d(&valstring[len + 1], &value[1], status); /* convert the imag. part */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyt( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ long *ivalue, /* O - integer part of keyword value */ double *fraction, /* O - fractional part of keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The integer and fractional parts of the value are returned in separate variables, to allow more numerical precision to be passed. This effectively passes a 'triple' precision value, with a 4-byte integer and an 8-byte fraction. The comment may be up to 69 characters long. */ { char valstring[FLEN_VALUE]; char *loc; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ /* read the entire value string as a double, to get the integer part */ ffc2d(valstring, fraction, status); *ivalue = (long) *fraction; *fraction = *fraction - *ivalue; /* see if we need to read the fractional part again with more precision */ /* look for decimal point, without an exponential E or D character */ loc = strchr(valstring, '.'); if (loc) { if (!strchr(valstring, 'E') && !strchr(valstring, 'D')) ffc2d(loc, fraction, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyn( fitsfile *fptr, /* I - FITS file pointer */ int nkey, /* I - number of the keyword to read */ char *keyname, /* O - name of the keyword */ char *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the nkey-th keyword returning the keyword name, value and comment. The value is just the literal string of characters in the value field of the keyword. In the case of a string valued keyword, the returned value includes the leading and closing quote characters. The value may be up to 70 characters long, and the comment may be up to 72 characters long. If the keyword has no value (no equal sign in column 9) then a null value is returned. If comm = NULL, then do not return the comment string. */ { char card[FLEN_CARD], sbuff[FLEN_CARD]; int namelen; keyname[0] = '\0'; value[0] = '\0'; if (comm) comm[0] = '\0'; if (*status > 0) return(*status); if (ffgrec(fptr, nkey, card, status) > 0 ) /* get the 80-byte card */ return(*status); ffgknm(card, keyname, &namelen, status); /* get the keyword name */ if (ffpsvc(card, value, comm, status) > 0) /* parse value and comment */ return(*status); if (fftrec(keyname, status) > 0) /* test keyword name; catches no END */ { sprintf(sbuff,"Name of keyword no. %d contains illegal character(s): %s", nkey, keyname); ffpmsg(sbuff); if (nkey % 36 == 0) /* test if at beginning of 36-card FITS record */ ffpmsg(" (This may indicate a missing END keyword)."); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgkns( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - root name of keywords to read */ int nstart, /* I - starting index number */ int nmax, /* I - maximum number of keywords to return */ char *value[], /* O - array of pointers to keyword values */ int *nfound, /* O - number of values that were returned */ int *status) /* IO - error status */ /* Read (get) an indexed array of keywords with index numbers between NSTART and (NSTART + NMAX -1) inclusive. This routine does NOT support the HEASARC long string convention. */ { int nend, lenroot, ii, nkeys, mkeys, tstatus, undefinedval; long ival; char keyroot[FLEN_KEYWORD], keyindex[8], card[FLEN_CARD]; char svalue[FLEN_VALUE], comm[FLEN_COMMENT]; if (*status > 0) return(*status); *nfound = 0; nend = nstart + nmax - 1; keyroot[0] = '\0'; strncat(keyroot, keyname, 8); lenroot = strlen(keyroot); if (lenroot == 0 || lenroot > 7) /* root must be 1 - 7 chars long */ return(*status); for (ii=0; ii < lenroot; ii++) /* make sure upper case */ keyroot[ii] = toupper(keyroot[ii]); ffghps(fptr, &nkeys, &mkeys, status); /* get the number of keywords */ undefinedval = FALSE; for (ii=3; ii <= nkeys; ii++) { if (ffgrec(fptr, ii, card, status) > 0) /* get next keyword */ return(*status); if (strncmp(keyroot, card, lenroot) == 0) /* see if keyword matches */ { keyindex[0] = '\0'; strncat(keyindex, &card[lenroot], 8-lenroot); /* copy suffix */ tstatus = 0; if (ffc2ii(keyindex, &ival, &tstatus) <= 0) /* test suffix */ { if (ival <= nend && ival >= nstart) { ffpsvc(card, svalue, comm, status); /* parse the value */ ffc2s(svalue, value[ival-nstart], status); /* convert */ if (ival - nstart + 1 > *nfound) *nfound = ival - nstart + 1; /* max found */ if (*status == VALUE_UNDEFINED) { undefinedval = TRUE; *status = 0; /* reset status to read remaining values */ } } } } } if (undefinedval && (*status <= 0) ) *status = VALUE_UNDEFINED; /* report at least 1 value undefined */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgknl( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - root name of keywords to read */ int nstart, /* I - starting index number */ int nmax, /* I - maximum number of keywords to return */ int *value, /* O - array of keyword values */ int *nfound, /* O - number of values that were returned */ int *status) /* IO - error status */ /* Read (get) an indexed array of keywords with index numbers between NSTART and (NSTART + NMAX -1) inclusive. The returned value = 1 if the keyword is true, else = 0 if false. */ { int nend, lenroot, ii, nkeys, mkeys, tstatus, undefinedval; long ival; char keyroot[FLEN_KEYWORD], keyindex[8], card[FLEN_CARD]; char svalue[FLEN_VALUE], comm[FLEN_COMMENT]; if (*status > 0) return(*status); *nfound = 0; nend = nstart + nmax - 1; keyroot[0] = '\0'; strncat(keyroot, keyname, 8); lenroot = strlen(keyroot); if (lenroot == 0 || lenroot > 7) /* root must be 1 - 7 chars long */ return(*status); for (ii=0; ii < lenroot; ii++) /* make sure upper case */ keyroot[ii] = toupper(keyroot[ii]); ffghps(fptr, &nkeys, &mkeys, status); /* get the number of keywords */ ffmaky(fptr, 3, status); /* move to 3rd keyword (skip 1st 2 keywords) */ undefinedval = FALSE; for (ii=3; ii <= nkeys; ii++) { if (ffgnky(fptr, card, status) > 0) /* get next keyword */ return(*status); if (strncmp(keyroot, card, lenroot) == 0) /* see if keyword matches */ { keyindex[0] = '\0'; strncat(keyindex, &card[lenroot], 8-lenroot); /* copy suffix */ tstatus = 0; if (ffc2ii(keyindex, &ival, &tstatus) <= 0) /* test suffix */ { if (ival <= nend && ival >= nstart) { ffpsvc(card, svalue, comm, status); /* parse the value */ ffc2l(svalue, &value[ival-nstart], status); /* convert*/ if (ival - nstart + 1 > *nfound) *nfound = ival - nstart + 1; /* max found */ if (*status == VALUE_UNDEFINED) { undefinedval = TRUE; *status = 0; /* reset status to read remaining values */ } } } } } if (undefinedval && (*status <= 0) ) *status = VALUE_UNDEFINED; /* report at least 1 value undefined */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgknj( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - root name of keywords to read */ int nstart, /* I - starting index number */ int nmax, /* I - maximum number of keywords to return */ long *value, /* O - array of keyword values */ int *nfound, /* O - number of values that were returned */ int *status) /* IO - error status */ /* Read (get) an indexed array of keywords with index numbers between NSTART and (NSTART + NMAX -1) inclusive. */ { int nend, lenroot, ii, nkeys, mkeys, tstatus, undefinedval; long ival; char keyroot[FLEN_KEYWORD], keyindex[8], card[FLEN_CARD]; char svalue[FLEN_VALUE], comm[FLEN_COMMENT]; if (*status > 0) return(*status); *nfound = 0; nend = nstart + nmax - 1; keyroot[0] = '\0'; strncat(keyroot, keyname, 8); lenroot = strlen(keyroot); if (lenroot == 0 || lenroot > 7) /* root must be 1 - 7 chars long */ return(*status); for (ii=0; ii < lenroot; ii++) /* make sure upper case */ keyroot[ii] = toupper(keyroot[ii]); ffghps(fptr, &nkeys, &mkeys, status); /* get the number of keywords */ ffmaky(fptr, 3, status); /* move to 3rd keyword (skip 1st 2 keywords) */ undefinedval = FALSE; for (ii=3; ii <= nkeys; ii++) { if (ffgnky(fptr, card, status) > 0) /* get next keyword */ return(*status); if (strncmp(keyroot, card, lenroot) == 0) /* see if keyword matches */ { keyindex[0] = '\0'; strncat(keyindex, &card[lenroot], 8-lenroot); /* copy suffix */ tstatus = 0; if (ffc2ii(keyindex, &ival, &tstatus) <= 0) /* test suffix */ { if (ival <= nend && ival >= nstart) { ffpsvc(card, svalue, comm, status); /* parse the value */ ffc2i(svalue, &value[ival-nstart], status); /* convert */ if (ival - nstart + 1 > *nfound) *nfound = ival - nstart + 1; /* max found */ if (*status == VALUE_UNDEFINED) { undefinedval = TRUE; *status = 0; /* reset status to read remaining values */ } } } } } if (undefinedval && (*status <= 0) ) *status = VALUE_UNDEFINED; /* report at least 1 value undefined */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgknjj( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - root name of keywords to read */ int nstart, /* I - starting index number */ int nmax, /* I - maximum number of keywords to return */ LONGLONG *value, /* O - array of keyword values */ int *nfound, /* O - number of values that were returned */ int *status) /* IO - error status */ /* Read (get) an indexed array of keywords with index numbers between NSTART and (NSTART + NMAX -1) inclusive. */ { int nend, lenroot, ii, nkeys, mkeys, tstatus, undefinedval; long ival; char keyroot[FLEN_KEYWORD], keyindex[8], card[FLEN_CARD]; char svalue[FLEN_VALUE], comm[FLEN_COMMENT]; if (*status > 0) return(*status); *nfound = 0; nend = nstart + nmax - 1; keyroot[0] = '\0'; strncat(keyroot, keyname, 8); lenroot = strlen(keyroot); if (lenroot == 0 || lenroot > 7) /* root must be 1 - 7 chars long */ return(*status); for (ii=0; ii < lenroot; ii++) /* make sure upper case */ keyroot[ii] = toupper(keyroot[ii]); ffghps(fptr, &nkeys, &mkeys, status); /* get the number of keywords */ ffmaky(fptr, 3, status); /* move to 3rd keyword (skip 1st 2 keywords) */ undefinedval = FALSE; for (ii=3; ii <= nkeys; ii++) { if (ffgnky(fptr, card, status) > 0) /* get next keyword */ return(*status); if (strncmp(keyroot, card, lenroot) == 0) /* see if keyword matches */ { keyindex[0] = '\0'; strncat(keyindex, &card[lenroot], 8-lenroot); /* copy suffix */ tstatus = 0; if (ffc2ii(keyindex, &ival, &tstatus) <= 0) /* test suffix */ { if (ival <= nend && ival >= nstart) { ffpsvc(card, svalue, comm, status); /* parse the value */ ffc2j(svalue, &value[ival-nstart], status); /* convert */ if (ival - nstart + 1 > *nfound) *nfound = ival - nstart + 1; /* max found */ if (*status == VALUE_UNDEFINED) { undefinedval = TRUE; *status = 0; /* reset status to read remaining values */ } } } } } if (undefinedval && (*status <= 0) ) *status = VALUE_UNDEFINED; /* report at least 1 value undefined */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkne( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - root name of keywords to read */ int nstart, /* I - starting index number */ int nmax, /* I - maximum number of keywords to return */ float *value, /* O - array of keyword values */ int *nfound, /* O - number of values that were returned */ int *status) /* IO - error status */ /* Read (get) an indexed array of keywords with index numbers between NSTART and (NSTART + NMAX -1) inclusive. */ { int nend, lenroot, ii, nkeys, mkeys, tstatus, undefinedval; long ival; char keyroot[FLEN_KEYWORD], keyindex[8], card[FLEN_CARD]; char svalue[FLEN_VALUE], comm[FLEN_COMMENT]; if (*status > 0) return(*status); *nfound = 0; nend = nstart + nmax - 1; keyroot[0] = '\0'; strncat(keyroot, keyname, 8); lenroot = strlen(keyroot); if (lenroot == 0 || lenroot > 7) /* root must be 1 - 7 chars long */ return(*status); for (ii=0; ii < lenroot; ii++) /* make sure upper case */ keyroot[ii] = toupper(keyroot[ii]); ffghps(fptr, &nkeys, &mkeys, status); /* get the number of keywords */ ffmaky(fptr, 3, status); /* move to 3rd keyword (skip 1st 2 keywords) */ undefinedval = FALSE; for (ii=3; ii <= nkeys; ii++) { if (ffgnky(fptr, card, status) > 0) /* get next keyword */ return(*status); if (strncmp(keyroot, card, lenroot) == 0) /* see if keyword matches */ { keyindex[0] = '\0'; strncat(keyindex, &card[lenroot], 8-lenroot); /* copy suffix */ tstatus = 0; if (ffc2ii(keyindex, &ival, &tstatus) <= 0) /* test suffix */ { if (ival <= nend && ival >= nstart) { ffpsvc(card, svalue, comm, status); /* parse the value */ ffc2r(svalue, &value[ival-nstart], status); /* convert */ if (ival - nstart + 1 > *nfound) *nfound = ival - nstart + 1; /* max found */ if (*status == VALUE_UNDEFINED) { undefinedval = TRUE; *status = 0; /* reset status to read remaining values */ } } } } } if (undefinedval && (*status <= 0) ) *status = VALUE_UNDEFINED; /* report at least 1 value undefined */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgknd( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - root name of keywords to read */ int nstart, /* I - starting index number */ int nmax, /* I - maximum number of keywords to return */ double *value, /* O - array of keyword values */ int *nfound, /* O - number of values that were returned */ int *status) /* IO - error status */ /* Read (get) an indexed array of keywords with index numbers between NSTART and (NSTART + NMAX -1) inclusive. */ { int nend, lenroot, ii, nkeys, mkeys, tstatus, undefinedval; long ival; char keyroot[FLEN_KEYWORD], keyindex[8], card[FLEN_CARD]; char svalue[FLEN_VALUE], comm[FLEN_COMMENT]; if (*status > 0) return(*status); *nfound = 0; nend = nstart + nmax - 1; keyroot[0] = '\0'; strncat(keyroot, keyname, 8); lenroot = strlen(keyroot); if (lenroot == 0 || lenroot > 7) /* root must be 1 - 7 chars long */ return(*status); for (ii=0; ii < lenroot; ii++) /* make sure upper case */ keyroot[ii] = toupper(keyroot[ii]); ffghps(fptr, &nkeys, &mkeys, status); /* get the number of keywords */ ffmaky(fptr, 3, status); /* move to 3rd keyword (skip 1st 2 keywords) */ undefinedval = FALSE; for (ii=3; ii <= nkeys; ii++) { if (ffgnky(fptr, card, status) > 0) /* get next keyword */ return(*status); if (strncmp(keyroot, card, lenroot) == 0) /* see if keyword matches */ { keyindex[0] = '\0'; strncat(keyindex, &card[lenroot], 8-lenroot); /* copy suffix */ tstatus = 0; if (ffc2ii(keyindex, &ival, &tstatus) <= 0) /* test suffix */ { if (ival <= nend && ival >= nstart) /* is index within range? */ { ffpsvc(card, svalue, comm, status); /* parse the value */ ffc2d(svalue, &value[ival-nstart], status); /* convert */ if (ival - nstart + 1 > *nfound) *nfound = ival - nstart + 1; /* max found */ if (*status == VALUE_UNDEFINED) { undefinedval = TRUE; *status = 0; /* reset status to read remaining values */ } } } } } if (undefinedval && (*status <= 0) ) *status = VALUE_UNDEFINED; /* report at least 1 value undefined */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgtdm(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read */ int maxdim, /* I - maximum no. of dimensions to read; */ int *naxis, /* O - number of axes in the data array */ long naxes[], /* O - length of each data axis */ int *status) /* IO - error status */ /* read and parse the TDIMnnn keyword to get the dimensionality of a column */ { int tstatus = 0; char keyname[FLEN_KEYWORD], tdimstr[FLEN_VALUE]; if (*status > 0) return(*status); ffkeyn("TDIM", colnum, keyname, status); /* construct keyword name */ ffgkys(fptr, keyname, tdimstr, NULL, &tstatus); /* try reading keyword */ ffdtdm(fptr, tdimstr, colnum, maxdim,naxis, naxes, status); /* decode it */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgtdmll(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read */ int maxdim, /* I - maximum no. of dimensions to read; */ int *naxis, /* O - number of axes in the data array */ LONGLONG naxes[], /* O - length of each data axis */ int *status) /* IO - error status */ /* read and parse the TDIMnnn keyword to get the dimensionality of a column */ { int tstatus = 0; char keyname[FLEN_KEYWORD], tdimstr[FLEN_VALUE]; if (*status > 0) return(*status); ffkeyn("TDIM", colnum, keyname, status); /* construct keyword name */ ffgkys(fptr, keyname, tdimstr, NULL, &tstatus); /* try reading keyword */ ffdtdmll(fptr, tdimstr, colnum, maxdim,naxis, naxes, status); /* decode it */ return(*status); } /*--------------------------------------------------------------------------*/ int ffdtdm(fitsfile *fptr, /* I - FITS file pointer */ char *tdimstr, /* I - TDIMn keyword value string. e.g. (10,10) */ int colnum, /* I - number of the column */ int maxdim, /* I - maximum no. of dimensions to read; */ int *naxis, /* O - number of axes in the data array */ long naxes[], /* O - length of each data axis */ int *status) /* IO - error status */ /* decode the TDIMnnn keyword to get the dimensionality of a column. Check that the value is legal and consistent with the TFORM value. */ { long dimsize, totalpix = 1; char *loc, *lastloc, message[81]; tcolumn *colptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) return(*status = BAD_COL_NUM); colptr = (fptr->Fptr)->tableptr; /* set pointer to the first column */ colptr += (colnum - 1); /* increment to the correct column */ if (!tdimstr[0]) /* TDIMn keyword doesn't exist? */ { *naxis = 1; /* default = 1 dimensional */ if (maxdim > 0) naxes[0] = (long) colptr->trepeat; /* default length = repeat */ } else { *naxis = 0; loc = strchr(tdimstr, '(' ); /* find the opening quote */ if (!loc) { sprintf(message, "Illegal TDIM keyword value: %s", tdimstr); return(*status = BAD_TDIM); } while (loc) { loc++; dimsize = strtol(loc, &loc, 10); /* read size of next dimension */ if (*naxis < maxdim) naxes[*naxis] = dimsize; if (dimsize < 0) { ffpmsg("one or more TDIM values are less than 0 (ffdtdm)"); ffpmsg(tdimstr); return(*status = BAD_TDIM); } totalpix *= dimsize; (*naxis)++; lastloc = loc; loc = strchr(loc, ','); /* look for comma before next dimension */ } loc = strchr(lastloc, ')' ); /* check for the closing quote */ if (!loc) { sprintf(message, "Illegal TDIM keyword value: %s", tdimstr); return(*status = BAD_TDIM); } if ((colptr->tdatatype > 0) && ((long) colptr->trepeat != totalpix)) { sprintf(message, "column vector length, %ld, does not equal TDIMn array size, %ld", (long) colptr->trepeat, totalpix); ffpmsg(message); ffpmsg(tdimstr); return(*status = BAD_TDIM); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffdtdmll(fitsfile *fptr, /* I - FITS file pointer */ char *tdimstr, /* I - TDIMn keyword value string. e.g. (10,10) */ int colnum, /* I - number of the column */ int maxdim, /* I - maximum no. of dimensions to read; */ int *naxis, /* O - number of axes in the data array */ LONGLONG naxes[], /* O - length of each data axis */ int *status) /* IO - error status */ /* decode the TDIMnnn keyword to get the dimensionality of a column. Check that the value is legal and consistent with the TFORM value. */ { LONGLONG dimsize; LONGLONG totalpix = 1; char *loc, *lastloc, message[81]; tcolumn *colptr; double doublesize; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) return(*status = BAD_COL_NUM); colptr = (fptr->Fptr)->tableptr; /* set pointer to the first column */ colptr += (colnum - 1); /* increment to the correct column */ if (!tdimstr[0]) /* TDIMn keyword doesn't exist? */ { *naxis = 1; /* default = 1 dimensional */ if (maxdim > 0) naxes[0] = colptr->trepeat; /* default length = repeat */ } else { *naxis = 0; loc = strchr(tdimstr, '(' ); /* find the opening quote */ if (!loc) { sprintf(message, "Illegal TDIM keyword value: %s", tdimstr); return(*status = BAD_TDIM); } while (loc) { loc++; /* Read value as a double because the string to 64-bit int function is */ /* platform dependent (strtoll, strtol, _atoI64). This still gives */ /* about 48 bits of precision, which is plenty for this purpose. */ doublesize = strtod(loc, &loc); dimsize = (LONGLONG) (doublesize + 0.1); if (*naxis < maxdim) naxes[*naxis] = dimsize; if (dimsize < 0) { ffpmsg("one or more TDIM values are less than 0 (ffdtdm)"); ffpmsg(tdimstr); return(*status = BAD_TDIM); } totalpix *= dimsize; (*naxis)++; lastloc = loc; loc = strchr(loc, ','); /* look for comma before next dimension */ } loc = strchr(lastloc, ')' ); /* check for the closing quote */ if (!loc) { sprintf(message, "Illegal TDIM keyword value: %s", tdimstr); return(*status = BAD_TDIM); } if ((colptr->tdatatype > 0) && (colptr->trepeat != totalpix)) { sprintf(message, "column vector length, %.0f, does not equal TDIMn array size, %.0f", (double) (colptr->trepeat), (double) totalpix); ffpmsg(message); ffpmsg(tdimstr); return(*status = BAD_TDIM); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffghpr(fitsfile *fptr, /* I - FITS file pointer */ int maxdim, /* I - maximum no. of dimensions to read; */ int *simple, /* O - does file conform to FITS standard? 1/0 */ int *bitpix, /* O - number of bits per data value pixel */ int *naxis, /* O - number of axes in the data array */ long naxes[], /* O - length of each data axis */ long *pcount, /* O - number of group parameters (usually 0) */ long *gcount, /* O - number of random groups (usually 1 or 0) */ int *extend, /* O - may FITS file haave extensions? */ int *status) /* IO - error status */ /* Get keywords from the Header of the PRimary array: Check that the keywords conform to the FITS standard and return the parameters which determine the size and structure of the primary array or IMAGE extension. */ { int idummy, ii; LONGLONG lldummy; double ddummy; LONGLONG tnaxes[99]; ffgphd(fptr, maxdim, simple, bitpix, naxis, tnaxes, pcount, gcount, extend, &ddummy, &ddummy, &lldummy, &idummy, status); if (naxis && naxes) { for (ii = 0; (ii < *naxis) && (ii < maxdim); ii++) naxes[ii] = (long) tnaxes[ii]; } else if (naxes) { for (ii = 0; ii < maxdim; ii++) naxes[ii] = (long) tnaxes[ii]; } return(*status); } /*--------------------------------------------------------------------------*/ int ffghprll(fitsfile *fptr, /* I - FITS file pointer */ int maxdim, /* I - maximum no. of dimensions to read; */ int *simple, /* O - does file conform to FITS standard? 1/0 */ int *bitpix, /* O - number of bits per data value pixel */ int *naxis, /* O - number of axes in the data array */ LONGLONG naxes[], /* O - length of each data axis */ long *pcount, /* O - number of group parameters (usually 0) */ long *gcount, /* O - number of random groups (usually 1 or 0) */ int *extend, /* O - may FITS file haave extensions? */ int *status) /* IO - error status */ /* Get keywords from the Header of the PRimary array: Check that the keywords conform to the FITS standard and return the parameters which determine the size and structure of the primary array or IMAGE extension. */ { int idummy; LONGLONG lldummy; double ddummy; ffgphd(fptr, maxdim, simple, bitpix, naxis, naxes, pcount, gcount, extend, &ddummy, &ddummy, &lldummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffghtb(fitsfile *fptr, /* I - FITS file pointer */ int maxfield, /* I - maximum no. of columns to read; */ long *naxis1, /* O - length of table row in bytes */ long *naxis2, /* O - number of rows in the table */ int *tfields, /* O - number of columns in the table */ char **ttype, /* O - name of each column */ long *tbcol, /* O - byte offset in row to each column */ char **tform, /* O - value of TFORMn keyword for each column */ char **tunit, /* O - value of TUNITn keyword for each column */ char *extnm, /* O - value of EXTNAME keyword, if any */ int *status) /* IO - error status */ /* Get keywords from the Header of the ASCII TaBle: Check that the keywords conform to the FITS standard and return the parameters which describe the table. */ { int ii, maxf, nfound, tstatus; long fields; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char xtension[FLEN_VALUE], message[81]; LONGLONG llnaxis1, llnaxis2, pcount; if (*status > 0) return(*status); /* read the first keyword of the extension */ ffgkyn(fptr, 1, name, value, comm, status); if (!strcmp(name, "XTENSION")) { if (ffc2s(value, xtension, status) > 0) /* get the value string */ { ffpmsg("Bad value string for XTENSION keyword:"); ffpmsg(value); return(*status); } /* allow the quoted string value to begin in any column and */ /* allow any number of trailing blanks before the closing quote */ if ( (value[0] != '\'') || /* first char must be a quote */ ( strcmp(xtension, "TABLE") ) ) { sprintf(message, "This is not a TABLE extension: %s", value); ffpmsg(message); return(*status = NOT_ATABLE); } } else /* error: 1st keyword of extension != XTENSION */ { sprintf(message, "First keyword of the extension is not XTENSION: %s", name); ffpmsg(message); return(*status = NO_XTENSION); } if (ffgttb(fptr, &llnaxis1, &llnaxis2, &pcount, &fields, status) > 0) return(*status); if (naxis1) *naxis1 = (long) llnaxis1; if (naxis2) *naxis2 = (long) llnaxis2; if (pcount != 0) { sprintf(message, "PCOUNT = %.0f is illegal in ASCII table; must = 0", (double) pcount); ffpmsg(message); return(*status = BAD_PCOUNT); } if (tfields) *tfields = fields; if (maxfield < 0) maxf = fields; else maxf = minvalue(maxfield, fields); if (maxf > 0) { for (ii = 0; ii < maxf; ii++) { /* initialize optional keyword values */ if (ttype) *ttype[ii] = '\0'; if (tunit) *tunit[ii] = '\0'; } if (ttype) ffgkns(fptr, "TTYPE", 1, maxf, ttype, &nfound, status); if (tunit) ffgkns(fptr, "TUNIT", 1, maxf, tunit, &nfound, status); if (*status > 0) return(*status); if (tbcol) { ffgknj(fptr, "TBCOL", 1, maxf, tbcol, &nfound, status); if (*status > 0 || nfound != maxf) { ffpmsg( "Required TBCOL keyword(s) not found in ASCII table header (ffghtb)."); return(*status = NO_TBCOL); } } if (tform) { ffgkns(fptr, "TFORM", 1, maxf, tform, &nfound, status); if (*status > 0 || nfound != maxf) { ffpmsg( "Required TFORM keyword(s) not found in ASCII table header (ffghtb)."); return(*status = NO_TFORM); } } } if (extnm) { extnm[0] = '\0'; tstatus = *status; ffgkys(fptr, "EXTNAME", extnm, comm, status); if (*status == KEY_NO_EXIST) *status = tstatus; /* keyword not required, so ignore error */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffghtbll(fitsfile *fptr, /* I - FITS file pointer */ int maxfield, /* I - maximum no. of columns to read; */ LONGLONG *naxis1, /* O - length of table row in bytes */ LONGLONG *naxis2, /* O - number of rows in the table */ int *tfields, /* O - number of columns in the table */ char **ttype, /* O - name of each column */ LONGLONG *tbcol, /* O - byte offset in row to each column */ char **tform, /* O - value of TFORMn keyword for each column */ char **tunit, /* O - value of TUNITn keyword for each column */ char *extnm, /* O - value of EXTNAME keyword, if any */ int *status) /* IO - error status */ /* Get keywords from the Header of the ASCII TaBle: Check that the keywords conform to the FITS standard and return the parameters which describe the table. */ { int ii, maxf, nfound, tstatus; long fields; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char xtension[FLEN_VALUE], message[81]; LONGLONG llnaxis1, llnaxis2, pcount; if (*status > 0) return(*status); /* read the first keyword of the extension */ ffgkyn(fptr, 1, name, value, comm, status); if (!strcmp(name, "XTENSION")) { if (ffc2s(value, xtension, status) > 0) /* get the value string */ { ffpmsg("Bad value string for XTENSION keyword:"); ffpmsg(value); return(*status); } /* allow the quoted string value to begin in any column and */ /* allow any number of trailing blanks before the closing quote */ if ( (value[0] != '\'') || /* first char must be a quote */ ( strcmp(xtension, "TABLE") ) ) { sprintf(message, "This is not a TABLE extension: %s", value); ffpmsg(message); return(*status = NOT_ATABLE); } } else /* error: 1st keyword of extension != XTENSION */ { sprintf(message, "First keyword of the extension is not XTENSION: %s", name); ffpmsg(message); return(*status = NO_XTENSION); } if (ffgttb(fptr, &llnaxis1, &llnaxis2, &pcount, &fields, status) > 0) return(*status); if (naxis1) *naxis1 = llnaxis1; if (naxis2) *naxis2 = llnaxis2; if (pcount != 0) { sprintf(message, "PCOUNT = %.0f is illegal in ASCII table; must = 0", (double) pcount); ffpmsg(message); return(*status = BAD_PCOUNT); } if (tfields) *tfields = fields; if (maxfield < 0) maxf = fields; else maxf = minvalue(maxfield, fields); if (maxf > 0) { for (ii = 0; ii < maxf; ii++) { /* initialize optional keyword values */ if (ttype) *ttype[ii] = '\0'; if (tunit) *tunit[ii] = '\0'; } if (ttype) ffgkns(fptr, "TTYPE", 1, maxf, ttype, &nfound, status); if (tunit) ffgkns(fptr, "TUNIT", 1, maxf, tunit, &nfound, status); if (*status > 0) return(*status); if (tbcol) { ffgknjj(fptr, "TBCOL", 1, maxf, tbcol, &nfound, status); if (*status > 0 || nfound != maxf) { ffpmsg( "Required TBCOL keyword(s) not found in ASCII table header (ffghtbll)."); return(*status = NO_TBCOL); } } if (tform) { ffgkns(fptr, "TFORM", 1, maxf, tform, &nfound, status); if (*status > 0 || nfound != maxf) { ffpmsg( "Required TFORM keyword(s) not found in ASCII table header (ffghtbll)."); return(*status = NO_TFORM); } } } if (extnm) { extnm[0] = '\0'; tstatus = *status; ffgkys(fptr, "EXTNAME", extnm, comm, status); if (*status == KEY_NO_EXIST) *status = tstatus; /* keyword not required, so ignore error */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffghbn(fitsfile *fptr, /* I - FITS file pointer */ int maxfield, /* I - maximum no. of columns to read; */ long *naxis2, /* O - number of rows in the table */ int *tfields, /* O - number of columns in the table */ char **ttype, /* O - name of each column */ char **tform, /* O - TFORMn value for each column */ char **tunit, /* O - TUNITn value for each column */ char *extnm, /* O - value of EXTNAME keyword, if any */ long *pcount, /* O - value of PCOUNT keyword */ int *status) /* IO - error status */ /* Get keywords from the Header of the BiNary table: Check that the keywords conform to the FITS standard and return the parameters which describe the table. */ { int ii, maxf, nfound, tstatus; long fields; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char xtension[FLEN_VALUE], message[81]; LONGLONG naxis1ll, naxis2ll, pcountll; if (*status > 0) return(*status); /* read the first keyword of the extension */ ffgkyn(fptr, 1, name, value, comm, status); if (!strcmp(name, "XTENSION")) { if (ffc2s(value, xtension, status) > 0) /* get the value string */ { ffpmsg("Bad value string for XTENSION keyword:"); ffpmsg(value); return(*status); } /* allow the quoted string value to begin in any column and */ /* allow any number of trailing blanks before the closing quote */ if ( (value[0] != '\'') || /* first char must be a quote */ ( strcmp(xtension, "BINTABLE") && strcmp(xtension, "A3DTABLE") && strcmp(xtension, "3DTABLE") ) ) { sprintf(message, "This is not a BINTABLE extension: %s", value); ffpmsg(message); return(*status = NOT_BTABLE); } } else /* error: 1st keyword of extension != XTENSION */ { sprintf(message, "First keyword of the extension is not XTENSION: %s", name); ffpmsg(message); return(*status = NO_XTENSION); } if (ffgttb(fptr, &naxis1ll, &naxis2ll, &pcountll, &fields, status) > 0) return(*status); if (naxis2) *naxis2 = (long) naxis2ll; if (pcount) *pcount = (long) pcountll; if (tfields) *tfields = fields; if (maxfield < 0) maxf = fields; else maxf = minvalue(maxfield, fields); if (maxf > 0) { for (ii = 0; ii < maxf; ii++) { /* initialize optional keyword values */ if (ttype) *ttype[ii] = '\0'; if (tunit) *tunit[ii] = '\0'; } if (ttype) ffgkns(fptr, "TTYPE", 1, maxf, ttype, &nfound, status); if (tunit) ffgkns(fptr, "TUNIT", 1, maxf, tunit, &nfound, status); if (*status > 0) return(*status); if (tform) { ffgkns(fptr, "TFORM", 1, maxf, tform, &nfound, status); if (*status > 0 || nfound != maxf) { ffpmsg( "Required TFORM keyword(s) not found in binary table header (ffghbn)."); return(*status = NO_TFORM); } } } if (extnm) { extnm[0] = '\0'; tstatus = *status; ffgkys(fptr, "EXTNAME", extnm, comm, status); if (*status == KEY_NO_EXIST) *status = tstatus; /* keyword not required, so ignore error */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffghbnll(fitsfile *fptr, /* I - FITS file pointer */ int maxfield, /* I - maximum no. of columns to read; */ LONGLONG *naxis2, /* O - number of rows in the table */ int *tfields, /* O - number of columns in the table */ char **ttype, /* O - name of each column */ char **tform, /* O - TFORMn value for each column */ char **tunit, /* O - TUNITn value for each column */ char *extnm, /* O - value of EXTNAME keyword, if any */ LONGLONG *pcount, /* O - value of PCOUNT keyword */ int *status) /* IO - error status */ /* Get keywords from the Header of the BiNary table: Check that the keywords conform to the FITS standard and return the parameters which describe the table. */ { int ii, maxf, nfound, tstatus; long fields; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char xtension[FLEN_VALUE], message[81]; LONGLONG naxis1ll, naxis2ll, pcountll; if (*status > 0) return(*status); /* read the first keyword of the extension */ ffgkyn(fptr, 1, name, value, comm, status); if (!strcmp(name, "XTENSION")) { if (ffc2s(value, xtension, status) > 0) /* get the value string */ { ffpmsg("Bad value string for XTENSION keyword:"); ffpmsg(value); return(*status); } /* allow the quoted string value to begin in any column and */ /* allow any number of trailing blanks before the closing quote */ if ( (value[0] != '\'') || /* first char must be a quote */ ( strcmp(xtension, "BINTABLE") && strcmp(xtension, "A3DTABLE") && strcmp(xtension, "3DTABLE") ) ) { sprintf(message, "This is not a BINTABLE extension: %s", value); ffpmsg(message); return(*status = NOT_BTABLE); } } else /* error: 1st keyword of extension != XTENSION */ { sprintf(message, "First keyword of the extension is not XTENSION: %s", name); ffpmsg(message); return(*status = NO_XTENSION); } if (ffgttb(fptr, &naxis1ll, &naxis2ll, &pcountll, &fields, status) > 0) return(*status); if (naxis2) *naxis2 = naxis2ll; if (pcount) *pcount = pcountll; if (tfields) *tfields = fields; if (maxfield < 0) maxf = fields; else maxf = minvalue(maxfield, fields); if (maxf > 0) { for (ii = 0; ii < maxf; ii++) { /* initialize optional keyword values */ if (ttype) *ttype[ii] = '\0'; if (tunit) *tunit[ii] = '\0'; } if (ttype) ffgkns(fptr, "TTYPE", 1, maxf, ttype, &nfound, status); if (tunit) ffgkns(fptr, "TUNIT", 1, maxf, tunit, &nfound, status); if (*status > 0) return(*status); if (tform) { ffgkns(fptr, "TFORM", 1, maxf, tform, &nfound, status); if (*status > 0 || nfound != maxf) { ffpmsg( "Required TFORM keyword(s) not found in binary table header (ffghbn)."); return(*status = NO_TFORM); } } } if (extnm) { extnm[0] = '\0'; tstatus = *status; ffgkys(fptr, "EXTNAME", extnm, comm, status); if (*status == KEY_NO_EXIST) *status = tstatus; /* keyword not required, so ignore error */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffgphd(fitsfile *fptr, /* I - FITS file pointer */ int maxdim, /* I - maximum no. of dimensions to read; */ int *simple, /* O - does file conform to FITS standard? 1/0 */ int *bitpix, /* O - number of bits per data value pixel */ int *naxis, /* O - number of axes in the data array */ LONGLONG naxes[], /* O - length of each data axis */ long *pcount, /* O - number of group parameters (usually 0) */ long *gcount, /* O - number of random groups (usually 1 or 0) */ int *extend, /* O - may FITS file haave extensions? */ double *bscale, /* O - array pixel linear scaling factor */ double *bzero, /* O - array pixel linear scaling zero point */ LONGLONG *blank, /* O - value used to represent undefined pixels */ int *nspace, /* O - number of blank keywords prior to END */ int *status) /* IO - error status */ { /* Get the Primary HeaDer parameters. Check that the keywords conform to the FITS standard and return the parameters which determine the size and structure of the primary array or IMAGE extension. */ int unknown, found_end, tstatus, ii, nextkey, namelen; long longbitpix, longnaxis; LONGLONG axislen; char message[FLEN_ERRMSG], keyword[FLEN_KEYWORD]; char card[FLEN_CARD]; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char xtension[FLEN_VALUE]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (simple) *simple = 1; unknown = 0; /*--------------------------------------------------------------------*/ /* Get 1st keyword of HDU and test whether it is SIMPLE or XTENSION */ /*--------------------------------------------------------------------*/ ffgkyn(fptr, 1, name, value, comm, status); if ((fptr->Fptr)->curhdu == 0) /* Is this the beginning of the FITS file? */ { if (!strcmp(name, "SIMPLE")) { if (value[0] == 'F') { if (simple) *simple=0; /* not a simple FITS file */ } else if (value[0] != 'T') return(*status = BAD_SIMPLE); } else { sprintf(message, "First keyword of the file is not SIMPLE: %s", name); ffpmsg(message); return(*status = NO_SIMPLE); } } else /* not beginning of the file, so presumably an IMAGE extension */ { /* or it could be a compressed image in a binary table */ if (!strcmp(name, "XTENSION")) { if (ffc2s(value, xtension, status) > 0) /* get the value string */ { ffpmsg("Bad value string for XTENSION keyword:"); ffpmsg(value); return(*status); } /* allow the quoted string value to begin in any column and */ /* allow any number of trailing blanks before the closing quote */ if ( (value[0] != '\'') || /* first char must be a quote */ ( strcmp(xtension, "IMAGE") && strcmp(xtension, "IUEIMAGE") ) ) { unknown = 1; /* unknown type of extension; press on anyway */ sprintf(message, "This is not an IMAGE extension: %s", value); ffpmsg(message); } } else /* error: 1st keyword of extension != XTENSION */ { sprintf(message, "First keyword of the extension is not XTENSION: %s", name); ffpmsg(message); return(*status = NO_XTENSION); } } if (unknown && (fptr->Fptr)->compressimg) { /* this is a compressed image, so read ZBITPIX, ZNAXIS keywords */ unknown = 0; /* reset flag */ ffxmsg(3, message); /* clear previous spurious error message */ if (bitpix) { ffgidt(fptr, bitpix, status); /* get bitpix value */ if (*status > 0) { ffpmsg("Error reading BITPIX value of compressed image"); return(*status); } } if (naxis) { ffgidm(fptr, naxis, status); /* get NAXIS value */ if (*status > 0) { ffpmsg("Error reading NAXIS value of compressed image"); return(*status); } } if (naxes) { ffgiszll(fptr, maxdim, naxes, status); /* get NAXISn value */ if (*status > 0) { ffpmsg("Error reading NAXISn values of compressed image"); return(*status); } } nextkey = 9; /* skip required table keywords in the following search */ } else { /*----------------------------------------------------------------*/ /* Get 2nd keyword; test whether it is BITPIX with legal value */ /*----------------------------------------------------------------*/ ffgkyn(fptr, 2, name, value, comm, status); /* BITPIX = 2nd keyword */ if (strcmp(name, "BITPIX")) { sprintf(message, "Second keyword of the extension is not BITPIX: %s", name); ffpmsg(message); return(*status = NO_BITPIX); } if (ffc2ii(value, &longbitpix, status) > 0) { sprintf(message, "Value of BITPIX keyword is not an integer: %s", value); ffpmsg(message); return(*status = BAD_BITPIX); } else if (longbitpix != BYTE_IMG && longbitpix != SHORT_IMG && longbitpix != LONG_IMG && longbitpix != LONGLONG_IMG && longbitpix != FLOAT_IMG && longbitpix != DOUBLE_IMG) { sprintf(message, "Illegal value for BITPIX keyword: %s", value); ffpmsg(message); return(*status = BAD_BITPIX); } if (bitpix) *bitpix = longbitpix; /* do explicit type conversion */ /*---------------------------------------------------------------*/ /* Get 3rd keyword; test whether it is NAXIS with legal value */ /*---------------------------------------------------------------*/ ffgtkn(fptr, 3, "NAXIS", &longnaxis, status); if (*status == BAD_ORDER) return(*status = NO_NAXIS); else if (*status == NOT_POS_INT || longnaxis > 999) { sprintf(message,"NAXIS = %ld is illegal", longnaxis); ffpmsg(message); return(*status = BAD_NAXIS); } else if (naxis) *naxis = longnaxis; /* do explicit type conversion */ /*---------------------------------------------------------*/ /* Get the next NAXISn keywords and test for legal values */ /*---------------------------------------------------------*/ for (ii=0, nextkey=4; ii < longnaxis; ii++, nextkey++) { ffkeyn("NAXIS", ii+1, keyword, status); ffgtknjj(fptr, 4+ii, keyword, &axislen, status); if (*status == BAD_ORDER) return(*status = NO_NAXES); else if (*status == NOT_POS_INT) return(*status = BAD_NAXES); else if (ii < maxdim) if (naxes) naxes[ii] = axislen; } } /*---------------------------------------------------------*/ /* now look for other keywords of interest: */ /* BSCALE, BZERO, BLANK, PCOUNT, GCOUNT, EXTEND, and END */ /*---------------------------------------------------------*/ /* initialize default values in case keyword is not present */ if (bscale) *bscale = 1.0; if (bzero) *bzero = 0.0; if (pcount) *pcount = 0; if (gcount) *gcount = 1; if (extend) *extend = 0; if (blank) *blank = NULL_UNDEFINED; /* no default null value for BITPIX=8,16,32 */ *nspace = 0; found_end = 0; tstatus = *status; for (; !found_end; nextkey++) { /* get next keyword */ /* don't use ffgkyn here because it trys to parse the card to read */ /* the value string, thus failing to read the file just because of */ /* minor syntax errors in optional keywords. */ if (ffgrec(fptr, nextkey, card, status) > 0 ) /* get the 80-byte card */ { if (*status == KEY_OUT_BOUNDS) { found_end = 1; /* simply hit the end of the header */ *status = tstatus; /* reset error status */ } else { ffpmsg("Failed to find the END keyword in header (ffgphd)."); } } else /* got the next keyword without error */ { ffgknm(card, name, &namelen, status); /* get the keyword name */ if (fftrec(name, status) > 0) /* test keyword name; catches no END */ { sprintf(message, "Name of keyword no. %d contains illegal character(s): %s", nextkey, name); ffpmsg(message); if (nextkey % 36 == 0) /* test if at beginning of 36-card record */ ffpmsg(" (This may indicate a missing END keyword)."); } if (!strcmp(name, "BSCALE") && bscale) { *nspace = 0; /* reset count of blank keywords */ ffpsvc(card, value, comm, status); /* parse value and comment */ if (ffc2dd(value, bscale, status) > 0) /* convert to double */ { /* reset error status and continue, but still issue warning */ *status = tstatus; *bscale = 1.0; sprintf(message, "Error reading BSCALE keyword value as a double: %s", value); ffpmsg(message); } } else if (!strcmp(name, "BZERO") && bzero) { *nspace = 0; /* reset count of blank keywords */ ffpsvc(card, value, comm, status); /* parse value and comment */ if (ffc2dd(value, bzero, status) > 0) /* convert to double */ { /* reset error status and continue, but still issue warning */ *status = tstatus; *bzero = 0.0; sprintf(message, "Error reading BZERO keyword value as a double: %s", value); ffpmsg(message); } } else if (!strcmp(name, "BLANK") && blank) { *nspace = 0; /* reset count of blank keywords */ ffpsvc(card, value, comm, status); /* parse value and comment */ if (ffc2jj(value, blank, status) > 0) /* convert to LONGLONG */ { /* reset error status and continue, but still issue warning */ *status = tstatus; *blank = NULL_UNDEFINED; sprintf(message, "Error reading BLANK keyword value as an integer: %s", value); ffpmsg(message); } } else if (!strcmp(name, "PCOUNT") && pcount) { *nspace = 0; /* reset count of blank keywords */ ffpsvc(card, value, comm, status); /* parse value and comment */ if (ffc2ii(value, pcount, status) > 0) /* convert to long */ { sprintf(message, "Error reading PCOUNT keyword value as an integer: %s", value); ffpmsg(message); } } else if (!strcmp(name, "GCOUNT") && gcount) { *nspace = 0; /* reset count of blank keywords */ ffpsvc(card, value, comm, status); /* parse value and comment */ if (ffc2ii(value, gcount, status) > 0) /* convert to long */ { sprintf(message, "Error reading GCOUNT keyword value as an integer: %s", value); ffpmsg(message); } } else if (!strcmp(name, "EXTEND") && extend) { *nspace = 0; /* reset count of blank keywords */ ffpsvc(card, value, comm, status); /* parse value and comment */ if (ffc2ll(value, extend, status) > 0) /* convert to logical */ { /* reset error status and continue, but still issue warning */ *status = tstatus; *extend = 0; sprintf(message, "Error reading EXTEND keyword value as a logical: %s", value); ffpmsg(message); } } else if (!strcmp(name, "END")) found_end = 1; else if (!card[0] ) *nspace = *nspace + 1; /* this is a blank card in the header */ else *nspace = 0; /* reset count of blank keywords immediately before the END keyword to zero */ } if (*status > 0) /* exit on error after writing error message */ { if ((fptr->Fptr)->curhdu == 0) ffpmsg( "Failed to read the required primary array header keywords."); else ffpmsg( "Failed to read the required image extension header keywords."); return(*status); } } if (unknown) *status = NOT_IMAGE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgttb(fitsfile *fptr, /* I - FITS file pointer*/ LONGLONG *rowlen, /* O - length of a table row, in bytes */ LONGLONG *nrows, /* O - number of rows in the table */ LONGLONG *pcount, /* O - value of PCOUNT keyword */ long *tfields, /* O - number of fields in the table */ int *status) /* IO - error status */ { /* Get and Test TaBle; Test that this is a legal ASCII or binary table and get some keyword values. We assume that the calling routine has already tested the 1st keyword of the extension to ensure that this is really a table extension. */ if (*status > 0) return(*status); if (fftkyn(fptr, 2, "BITPIX", "8", status) == BAD_ORDER) /* 2nd keyword */ return(*status = NO_BITPIX); /* keyword not BITPIX */ else if (*status == NOT_POS_INT) return(*status = BAD_BITPIX); /* value != 8 */ if (fftkyn(fptr, 3, "NAXIS", "2", status) == BAD_ORDER) /* 3rd keyword */ return(*status = NO_NAXIS); /* keyword not NAXIS */ else if (*status == NOT_POS_INT) return(*status = BAD_NAXIS); /* value != 2 */ if (ffgtknjj(fptr, 4, "NAXIS1", rowlen, status) == BAD_ORDER) /* 4th key */ return(*status = NO_NAXES); /* keyword not NAXIS1 */ else if (*status == NOT_POS_INT) return(*status == BAD_NAXES); /* bad NAXIS1 value */ if (ffgtknjj(fptr, 5, "NAXIS2", nrows, status) == BAD_ORDER) /* 5th key */ return(*status = NO_NAXES); /* keyword not NAXIS2 */ else if (*status == NOT_POS_INT) return(*status == BAD_NAXES); /* bad NAXIS2 value */ if (ffgtknjj(fptr, 6, "PCOUNT", pcount, status) == BAD_ORDER) /* 6th key */ return(*status = NO_PCOUNT); /* keyword not PCOUNT */ else if (*status == NOT_POS_INT) return(*status = BAD_PCOUNT); /* bad PCOUNT value */ if (fftkyn(fptr, 7, "GCOUNT", "1", status) == BAD_ORDER) /* 7th keyword */ return(*status = NO_GCOUNT); /* keyword not GCOUNT */ else if (*status == NOT_POS_INT) return(*status = BAD_GCOUNT); /* value != 1 */ if (ffgtkn(fptr, 8, "TFIELDS", tfields, status) == BAD_ORDER) /* 8th key*/ return(*status = NO_TFIELDS); /* keyword not TFIELDS */ else if (*status == NOT_POS_INT || *tfields > 999) return(*status == BAD_TFIELDS); /* bad TFIELDS value */ if (*status > 0) ffpmsg( "Error reading required keywords in the table header (FTGTTB)."); return(*status); } /*--------------------------------------------------------------------------*/ int ffgtkn(fitsfile *fptr, /* I - FITS file pointer */ int numkey, /* I - number of the keyword to read */ char *name, /* I - expected name of the keyword */ long *value, /* O - integer value of the keyword */ int *status) /* IO - error status */ { /* test that keyword number NUMKEY has the expected name and get the integer value of the keyword. Return an error if the keyword name does not match the input name, or if the value of the keyword is not a positive integer. */ char keyname[FLEN_KEYWORD], valuestring[FLEN_VALUE]; char comm[FLEN_COMMENT], message[FLEN_ERRMSG]; if (*status > 0) return(*status); keyname[0] = '\0'; valuestring[0] = '\0'; if (ffgkyn(fptr, numkey, keyname, valuestring, comm, status) <= 0) { if (strcmp(keyname, name) ) *status = BAD_ORDER; /* incorrect keyword name */ else { ffc2ii(valuestring, value, status); /* convert to integer */ if (*status > 0 || *value < 0 ) *status = NOT_POS_INT; } if (*status > 0) { sprintf(message, "ffgtkn found unexpected keyword or value for keyword no. %d.", numkey); ffpmsg(message); sprintf(message, " Expected positive integer keyword %s, but instead", name); ffpmsg(message); sprintf(message, " found keyword %s with value %s", keyname, valuestring); ffpmsg(message); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgtknjj(fitsfile *fptr, /* I - FITS file pointer */ int numkey, /* I - number of the keyword to read */ char *name, /* I - expected name of the keyword */ LONGLONG *value, /* O - integer value of the keyword */ int *status) /* IO - error status */ { /* test that keyword number NUMKEY has the expected name and get the integer value of the keyword. Return an error if the keyword name does not match the input name, or if the value of the keyword is not a positive integer. */ char keyname[FLEN_KEYWORD], valuestring[FLEN_VALUE]; char comm[FLEN_COMMENT], message[FLEN_ERRMSG]; if (*status > 0) return(*status); keyname[0] = '\0'; valuestring[0] = '\0'; if (ffgkyn(fptr, numkey, keyname, valuestring, comm, status) <= 0) { if (strcmp(keyname, name) ) *status = BAD_ORDER; /* incorrect keyword name */ else { ffc2jj(valuestring, value, status); /* convert to integer */ if (*status > 0 || *value < 0 ) *status = NOT_POS_INT; } if (*status > 0) { sprintf(message, "ffgtknjj found unexpected keyword or value for keyword no. %d.", numkey); ffpmsg(message); sprintf(message, " Expected positive integer keyword %s, but instead", name); ffpmsg(message); sprintf(message, " found keyword %s with value %s", keyname, valuestring); ffpmsg(message); } } return(*status); } /*--------------------------------------------------------------------------*/ int fftkyn(fitsfile *fptr, /* I - FITS file pointer */ int numkey, /* I - number of the keyword to read */ char *name, /* I - expected name of the keyword */ char *value, /* I - expected value of the keyword */ int *status) /* IO - error status */ { /* test that keyword number NUMKEY has the expected name and the expected value string. */ char keyname[FLEN_KEYWORD], valuestring[FLEN_VALUE]; char comm[FLEN_COMMENT], message[FLEN_ERRMSG]; if (*status > 0) return(*status); keyname[0] = '\0'; valuestring[0] = '\0'; if (ffgkyn(fptr, numkey, keyname, valuestring, comm, status) <= 0) { if (strcmp(keyname, name) ) *status = BAD_ORDER; /* incorrect keyword name */ if (strcmp(value, valuestring) ) *status = NOT_POS_INT; /* incorrect keyword value */ } if (*status > 0) { sprintf(message, "fftkyn found unexpected keyword or value for keyword no. %d.", numkey); ffpmsg(message); sprintf(message, " Expected keyword %s with value %s, but", name, value); ffpmsg(message); sprintf(message, " found keyword %s with value %s", keyname, valuestring); ffpmsg(message); } return(*status); } /*--------------------------------------------------------------------------*/ int ffh2st(fitsfile *fptr, /* I - FITS file pointer */ char **header, /* O - returned header string */ int *status) /* IO - error status */ /* read header keywords into a long string of chars. This routine allocates memory for the string, so the calling routine must eventually free the memory when it is not needed any more. */ { int nkeys; long nrec; LONGLONG headstart; if (*status > 0) return(*status); /* get number of keywords in the header (doesn't include END) */ if (ffghsp(fptr, &nkeys, NULL, status) > 0) return(*status); nrec = (nkeys / 36 + 1); /* allocate memory for all the keywords (multiple of 2880 bytes) */ *header = (char *) calloc ( nrec * 2880 + 1, 1); if (!(*header)) { *status = MEMORY_ALLOCATION; ffpmsg("failed to allocate memory to hold all the header keywords"); return(*status); } ffghadll(fptr, &headstart, NULL, NULL, status); /* get header address */ ffmbyt(fptr, headstart, REPORT_EOF, status); /* move to header */ ffgbyt(fptr, nrec * 2880, *header, status); /* copy header */ *(*header + (nrec * 2880)) = '\0'; return(*status); } /*--------------------------------------------------------------------------*/ int ffhdr2str( fitsfile *fptr, /* I - FITS file pointer */ int exclude_comm, /* I - if TRUE, exclude commentary keywords */ char **exclist, /* I - list of excluded keyword names */ int nexc, /* I - number of names in exclist */ char **header, /* O - returned header string */ int *nkeys, /* O - returned number of 80-char keywords */ int *status) /* IO - error status */ /* read header keywords into a long string of chars. This routine allocates memory for the string, so the calling routine must eventually free the memory when it is not needed any more. If exclude_comm is TRUE, then all the COMMENT, HISTORY, and keywords will be excluded from the output string of keywords. Any other list of keywords to be excluded may be specified with the exclist parameter. */ { int casesn, match, exact, totkeys; long ii, jj; char keybuf[162], keyname[FLEN_KEYWORD], *headptr; *nkeys = 0; if (*status > 0) return(*status); /* get number of keywords in the header (doesn't include END) */ if (ffghsp(fptr, &totkeys, NULL, status) > 0) return(*status); /* allocate memory for all the keywords (multiple of 2880 bytes) */ *header = (char *) calloc ( (totkeys + 1) * 80 + 1, 1); if (!(*header)) { *status = MEMORY_ALLOCATION; ffpmsg("failed to allocate memory to hold all the header keywords"); return(*status); } headptr = *header; casesn = FALSE; /* read every keyword */ for (ii = 1; ii <= totkeys; ii++) { ffgrec(fptr, ii, keybuf, status); /* pad record with blanks so that it is at least 80 chars long */ strcat(keybuf, " "); keyname[0] = '\0'; strncat(keyname, keybuf, 8); /* copy the keyword name */ if (exclude_comm) { if (!FSTRCMP("COMMENT ", keyname) || !FSTRCMP("HISTORY ", keyname) || !FSTRCMP(" ", keyname) ) continue; /* skip this commentary keyword */ } /* does keyword match any names in the exclusion list? */ for (jj = 0; jj < nexc; jj++ ) { ffcmps(exclist[jj], keyname, casesn, &match, &exact); if (match) break; } if (jj == nexc) { /* not in exclusion list, add this keyword to the string */ strcpy(headptr, keybuf); headptr += 80; (*nkeys)++; } } /* add the END keyword */ strcpy(headptr, "END "); headptr += 80; (*nkeys)++; *headptr = '\0'; /* terminate the header string */ /* minimize the allocated memory */ *header = (char *) realloc(*header, (*nkeys *80) + 1); return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/group.c000066400000000000000000005206401215713201500217370ustar00rootroot00000000000000/* This file, group.c, contains the grouping convention suport routines. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ /* */ /* The group.c module of CFITSIO was written by Donald G. Jennings of */ /* the INTEGRAL Science Data Centre (ISDC) under NASA contract task */ /* 66002J6. The above copyright laws apply. Copyright guidelines of The */ /* University of Geneva might also apply. */ /* The following routines are designed to create, read, and manipulate */ /* FITS Grouping Tables as defined in the FITS Grouping Convention paper */ /* by Jennings, Pence, Folk and Schlesinger. The development of the */ /* grouping structure was partially funded under the NASA AISRP Program. */ #include "fitsio2.h" #include "group.h" #include #include #include #if defined(WIN32) || defined(__WIN32__) #include /* defines the getcwd function on Windows PCs */ #endif #if defined(unix) || defined(__unix__) || defined(__unix) #include /* needed for getcwd prototype on unix machines */ #endif #define HEX_ESCAPE '%' /*--------------------------------------------------------------------------- Change record: D. Jennings, 18/06/98, version 1.0 of group module delivered to B. Pence for integration into CFITSIO 2.005 D. Jennings, 17/11/98, fixed bug in ffgtcpr(). Now use fits_find_nextkey() correctly and insert auxiliary keyword records directly before the TTYPE1 keyword in the copied group table. D. Jennings, 22/01/99, ffgmop() now looks for relative file paths when the MEMBER_LOCATION information is given in a grouping table. D. Jennings, 01/02/99, ffgtop() now looks for relatve file paths when the GRPLCn keyword value is supplied in the member HDU header. D. Jennings, 01/02/99, ffgtam() now trys to construct relative file paths from the member's file to the group table's file (and visa versa) when both the member's file and group table file are of access type FILE://. D. Jennings, 05/05/99, removed the ffgtcn() function; made obsolete by fits_get_url(). D. Jennings, 05/05/99, updated entire module to handle partial URLs and absolute URLs more robustly. Host dependent directory paths are now converted to true URLs before being read from/written to grouping tables. D. Jennings, 05/05/99, added the following new functions (note, none of these are directly callable by the application) int fits_path2url() int fits_url2path() int fits_get_cwd() int fits_get_url() int fits_clean_url() int fits_relurl2url() int fits_encode_url() int fits_unencode_url() int fits_is_url_absolute() -----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ int ffgtcr(fitsfile *fptr, /* FITS file pointer */ char *grpname, /* name of the grouping table */ int grouptype, /* code specifying the type of grouping table information: GT_ID_ALL_URI 0 ==> defualt (all columns) GT_ID_REF 1 ==> ID by reference GT_ID_POS 2 ==> ID by position GT_ID_ALL 3 ==> ID by ref. and position GT_ID_REF_URI 11 ==> (1) + URI info GT_ID_POS_URI 12 ==> (2) + URI info */ int *status )/* return status code */ /* create a grouping table at the end of the current FITS file. This function makes the last HDU in the file the CHDU, then calls the fits_insert_group() function to actually create the new grouping table. */ { int hdutype; int hdunum; if(*status != 0) return(*status); *status = fits_get_num_hdus(fptr,&hdunum,status); /* If hdunum is 0 then we are at the beginning of the file and we actually haven't closed the first header yet, so don't do anything more */ if (0 != hdunum) { *status = fits_movabs_hdu(fptr,hdunum,&hdutype,status); } /* Now, the whole point of the above two fits_ calls was to get to the end of file. Let's ignore errors at this point and keep going since any error is likely to mean that we are already at the EOF, or the file is fatally corrupted. If we are at the EOF then the next fits_ call will be ok. If it's corrupted then the next call will fail, but that's not big deal at this point. */ if (0 != *status ) *status = 0; *status = fits_insert_group(fptr,grpname,grouptype,status); return(*status); } /*---------------------------------------------------------------------------*/ int ffgtis(fitsfile *fptr, /* FITS file pointer */ char *grpname, /* name of the grouping table */ int grouptype, /* code specifying the type of grouping table information: GT_ID_ALL_URI 0 ==> defualt (all columns) GT_ID_REF 1 ==> ID by reference GT_ID_POS 2 ==> ID by position GT_ID_ALL 3 ==> ID by ref. and position GT_ID_REF_URI 11 ==> (1) + URI info GT_ID_POS_URI 12 ==> (2) + URI info */ int *status) /* return status code */ /* insert a grouping table just after the current HDU of the current FITS file. This is the same as fits_create_group() only it allows the user to select the place within the FITS file to add the grouping table. */ { int tfields = 0; int hdunum = 0; int hdutype = 0; int extver = 0; int i; long pcount = 0; char *ttype[6]; char *tform[6]; char ttypeBuff[102]; char tformBuff[54]; char extname[] = "GROUPING"; char keyword[FLEN_KEYWORD]; char keyvalue[FLEN_VALUE]; char comment[FLEN_COMMENT]; do { /* set up the ttype and tform character buffers */ for(i = 0; i < 6; ++i) { ttype[i] = ttypeBuff+(i*17); tform[i] = tformBuff+(i*9); } /* define the columns required according to the grouptype parameter */ *status = ffgtdc(grouptype,0,0,0,0,0,0,ttype,tform,&tfields,status); /* create the grouping table using the columns defined above */ *status = fits_insert_btbl(fptr,0,tfields,ttype,tform,NULL, NULL,pcount,status); if(*status != 0) continue; /* retrieve the hdu position of the new grouping table for future use */ fits_get_hdu_num(fptr,&hdunum); /* add the EXTNAME and EXTVER keywords to the HDU just after the TFIELDS keyword; for now the EXTVER value is set to 0, it will be set to the correct value later on */ fits_read_keyword(fptr,"TFIELDS",keyvalue,comment,status); fits_insert_key_str(fptr,"EXTNAME",extname, "HDU contains a Grouping Table",status); fits_insert_key_lng(fptr,"EXTVER",0,"Grouping Table vers. (this file)", status); /* if the grpname parameter value was defined (Non NULL and non zero length) then add the GRPNAME keyword and value */ if(grpname != NULL && strlen(grpname) > 0) fits_insert_key_str(fptr,"GRPNAME",grpname,"Grouping Table name", status); /* add the TNULL keywords and values for each integer column defined; integer null values are zero (0) for the MEMBER_POSITION and MEMBER_VERSION columns. */ for(i = 0; i < tfields && *status == 0; ++i) { if(strcasecmp(ttype[i],"MEMBER_POSITION") == 0 || strcasecmp(ttype[i],"MEMBER_VERSION") == 0) { sprintf(keyword,"TFORM%d",i+1); *status = fits_read_key_str(fptr,keyword,keyvalue,comment, status); sprintf(keyword,"TNULL%d",i+1); *status = fits_insert_key_lng(fptr,keyword,0,"Column Null Value", status); } } /* determine the correct EXTVER value for the new grouping table by finding the highest numbered grouping table EXTVER value the currently exists */ for(extver = 1; (fits_movnam_hdu(fptr,ANY_HDU,"GROUPING",extver,status)) == 0; ++extver); if(*status == BAD_HDU_NUM) *status = 0; /* move back to the new grouping table HDU and update the EXTVER keyword value */ fits_movabs_hdu(fptr,hdunum,&hdutype,status); fits_modify_key_lng(fptr,"EXTVER",extver,"&",status); }while(0); return(*status); } /*---------------------------------------------------------------------------*/ int ffgtch(fitsfile *gfptr, /* FITS pointer to group */ int grouptype, /* code specifying the type of grouping table information: GT_ID_ALL_URI 0 ==> defualt (all columns) GT_ID_REF 1 ==> ID by reference GT_ID_POS 2 ==> ID by position GT_ID_ALL 3 ==> ID by ref. and position GT_ID_REF_URI 11 ==> (1) + URI info GT_ID_POS_URI 12 ==> (2) + URI info */ int *status) /* return status code */ /* Change the grouping table structure of the grouping table pointed to by gfptr. The grouptype code specifies the new structure of the table. This operation only adds or removes grouping table columns, it does not add or delete group members (i.e., table rows). If the grouping table already has the desired structure then no operations are performed and function simply returns with a (0) success status code. If the requested structure change creates new grouping table columns, then the column values for all existing members will be filled with the appropriate null values. */ { int xtensionCol, extnameCol, extverCol, positionCol, locationCol, uriCol; int ncols = 0; int colnum = 0; int nrows = 0; int grptype = 0; int i,j; long intNull = 0; long tfields = 0; char *tform[6]; char *ttype[6]; unsigned char charNull[1] = {'\0'}; char ttypeBuff[102]; char tformBuff[54]; char keyword[FLEN_KEYWORD]; char keyvalue[FLEN_VALUE]; char comment[FLEN_COMMENT]; if(*status != 0) return(*status); do { /* set up the ttype and tform character buffers */ for(i = 0; i < 6; ++i) { ttype[i] = ttypeBuff+(i*17); tform[i] = tformBuff+(i*9); } /* retrieve positions of all Grouping table reserved columns */ *status = ffgtgc(gfptr,&xtensionCol,&extnameCol,&extverCol,&positionCol, &locationCol,&uriCol,&grptype,status); if(*status != 0) continue; /* determine the total number of grouping table columns */ *status = fits_read_key_lng(gfptr,"TFIELDS",&tfields,comment,status); /* define grouping table columns to be added to the configuration */ *status = ffgtdc(grouptype,xtensionCol,extnameCol,extverCol,positionCol, locationCol,uriCol,ttype,tform,&ncols,status); /* delete any grouping tables columns that exist but do not belong to new desired configuration; note that we delete before creating new columns for (file size) efficiency reasons */ switch(grouptype) { case GT_ID_ALL_URI: /* no columns to be deleted in this case */ break; case GT_ID_REF: if(positionCol != 0) { *status = fits_delete_col(gfptr,positionCol,status); --tfields; if(uriCol > positionCol) --uriCol; if(locationCol > positionCol) --locationCol; } if(uriCol != 0) { *status = fits_delete_col(gfptr,uriCol,status); --tfields; if(locationCol > uriCol) --locationCol; } if(locationCol != 0) *status = fits_delete_col(gfptr,locationCol,status); break; case GT_ID_POS: if(xtensionCol != 0) { *status = fits_delete_col(gfptr,xtensionCol,status); --tfields; if(extnameCol > xtensionCol) --extnameCol; if(extverCol > xtensionCol) --extverCol; if(uriCol > xtensionCol) --uriCol; if(locationCol > xtensionCol) --locationCol; } if(extnameCol != 0) { *status = fits_delete_col(gfptr,extnameCol,status); --tfields; if(extverCol > extnameCol) --extverCol; if(uriCol > extnameCol) --uriCol; if(locationCol > extnameCol) --locationCol; } if(extverCol != 0) { *status = fits_delete_col(gfptr,extverCol,status); --tfields; if(uriCol > extverCol) --uriCol; if(locationCol > extverCol) --locationCol; } if(uriCol != 0) { *status = fits_delete_col(gfptr,uriCol,status); --tfields; if(locationCol > uriCol) --locationCol; } if(locationCol != 0) { *status = fits_delete_col(gfptr,locationCol,status); --tfields; } break; case GT_ID_ALL: if(uriCol != 0) { *status = fits_delete_col(gfptr,uriCol,status); --tfields; if(locationCol > uriCol) --locationCol; } if(locationCol != 0) { *status = fits_delete_col(gfptr,locationCol,status); --tfields; } break; case GT_ID_REF_URI: if(positionCol != 0) { *status = fits_delete_col(gfptr,positionCol,status); --tfields; } break; case GT_ID_POS_URI: if(xtensionCol != 0) { *status = fits_delete_col(gfptr,xtensionCol,status); --tfields; if(extnameCol > xtensionCol) --extnameCol; if(extverCol > xtensionCol) --extverCol; } if(extnameCol != 0) { *status = fits_delete_col(gfptr,extnameCol,status); --tfields; if(extverCol > extnameCol) --extverCol; } if(extverCol != 0) { *status = fits_delete_col(gfptr,extverCol,status); --tfields; } break; default: *status = BAD_OPTION; ffpmsg("Invalid value for grouptype parameter specified (ffgtch)"); break; } /* add all the new grouping table columns that were not there previously but are called for by the grouptype parameter */ for(i = 0; i < ncols && *status == 0; ++i) *status = fits_insert_col(gfptr,tfields+i+1,ttype[i],tform[i],status); /* add the TNULL keywords and values for each new integer column defined; integer null values are zero (0) for the MEMBER_POSITION and MEMBER_VERSION columns. Insert a null ("/0") into each new string column defined: MEMBER_XTENSION, MEMBER_NAME, MEMBER_URI_TYPE and MEMBER_LOCATION. Note that by convention a null string is the TNULL value for character fields so no TNULL is required. */ for(i = 0; i < ncols && *status == 0; ++i) { if(strcasecmp(ttype[i],"MEMBER_POSITION") == 0 || strcasecmp(ttype[i],"MEMBER_VERSION") == 0) { /* col contains int data; set TNULL and insert 0 for each col */ *status = fits_get_colnum(gfptr,CASESEN,ttype[i],&colnum, status); sprintf(keyword,"TFORM%d",colnum); *status = fits_read_key_str(gfptr,keyword,keyvalue,comment, status); sprintf(keyword,"TNULL%d",colnum); *status = fits_insert_key_lng(gfptr,keyword,0, "Column Null Value",status); for(j = 1; j <= nrows && *status == 0; ++j) *status = fits_write_col_lng(gfptr,colnum,j,1,1,&intNull, status); } else if(strcasecmp(ttype[i],"MEMBER_XTENSION") == 0 || strcasecmp(ttype[i],"MEMBER_NAME") == 0 || strcasecmp(ttype[i],"MEMBER_URI_TYPE") == 0 || strcasecmp(ttype[i],"MEMBER_LOCATION") == 0) { /* new col contains character data; insert NULLs into each col */ *status = fits_get_colnum(gfptr,CASESEN,ttype[i],&colnum, status); for(j = 1; j <= nrows && *status == 0; ++j) /* WILL THIS WORK FOR VAR LENTH CHAR COLS??????*/ *status = fits_write_col_byt(gfptr,colnum,j,1,1,charNull, status); } } }while(0); return(*status); } /*---------------------------------------------------------------------------*/ int ffgtrm(fitsfile *gfptr, /* FITS file pointer to group */ int rmopt, /* code specifying if member elements are to be deleted: OPT_RM_GPT ==> remove only group table OPT_RM_ALL ==> recursively remove members and their members (if groups) */ int *status) /* return status code */ /* remove a grouping table, and optionally all its members. Any groups containing the grouping table are updated, and all members (if not deleted) have their GRPIDn and GRPLCn keywords updated accordingly. If the (deleted) members are members of another grouping table then those tables are also updated. The CHDU of the FITS file pointed to by gfptr must be positioned to the grouping table to be deleted. */ { int hdutype; long i; long nmembers = 0; HDUtracker HDU; if(*status != 0) return(*status); /* remove the grouping table depending upon the rmopt parameter */ switch(rmopt) { case OPT_RM_GPT: /* for this option, the grouping table is deleted, but the member HDUs remain; in this case we only have to remove each member from the grouping table by calling fits_remove_member() with the OPT_RM_ENTRY option */ /* get the number of members contained by this table */ *status = fits_get_num_members(gfptr,&nmembers,status); /* loop over all grouping table members and remove them */ for(i = nmembers; i > 0 && *status == 0; --i) *status = fits_remove_member(gfptr,i,OPT_RM_ENTRY,status); break; case OPT_RM_ALL: /* for this option the entire Group is deleted -- this includes all members and their members (if grouping tables themselves). Call the recursive form of this function to perform the removal. */ /* add the current grouping table to the HDUtracker struct */ HDU.nHDU = 0; *status = fftsad(gfptr,&HDU,NULL,NULL); /* call the recursive group remove function */ *status = ffgtrmr(gfptr,&HDU,status); /* free the memory allocated to the HDUtracker struct */ for(i = 0; i < HDU.nHDU; ++i) { free(HDU.filename[i]); free(HDU.newFilename[i]); } break; default: *status = BAD_OPTION; ffpmsg("Invalid value for the rmopt parameter specified (ffgtrm)"); break; } /* if all went well then unlink and delete the grouping table HDU */ *status = ffgmul(gfptr,0,status); *status = fits_delete_hdu(gfptr,&hdutype,status); return(*status); } /*---------------------------------------------------------------------------*/ int ffgtcp(fitsfile *infptr, /* input FITS file pointer */ fitsfile *outfptr, /* output FITS file pointer */ int cpopt, /* code specifying copy options: OPT_GCP_GPT (0) ==> copy only grouping table OPT_GCP_ALL (2) ==> recusrively copy members and their members (if groups) */ int *status) /* return status code */ /* copy a grouping table, and optionally all its members, to a new FITS file. If the cpopt is set to OPT_GCP_GPT (copy grouping table only) then the existing members have their GRPIDn and GRPLCn keywords updated to reflect the existance of the new group, since they now belong to another group. If cpopt is set to OPT_GCP_ALL (copy grouping table and members recursively) then the original members are not updated; the new grouping table is modified to include only the copied member HDUs and not the original members. Note that the recursive version of this function, ffgtcpr(), is called to perform the group table copy. In the case of cpopt == OPT_GCP_GPT ffgtcpr() does not actually use recursion. */ { int i; HDUtracker HDU; if(*status != 0) return(*status); /* make sure infptr and outfptr are not the same pointer */ if(infptr == outfptr) *status = IDENTICAL_POINTERS; else { /* initialize the HDUtracker struct */ HDU.nHDU = 0; *status = fftsad(infptr,&HDU,NULL,NULL); /* call the recursive form of this function to copy the grouping table. If the cpopt is OPT_GCP_GPT then there is actually no recursion performed */ *status = ffgtcpr(infptr,outfptr,cpopt,&HDU,status); /* free memory allocated for the HDUtracker struct */ for(i = 0; i < HDU.nHDU; ++i) { free(HDU.filename[i]); free(HDU.newFilename[i]); } } return(*status); } /*---------------------------------------------------------------------------*/ int ffgtmg(fitsfile *infptr, /* FITS file ptr to source grouping table */ fitsfile *outfptr, /* FITS file ptr to target grouping table */ int mgopt, /* code specifying merge options: OPT_MRG_COPY (0) ==> copy members to target group, leaving source group in place OPT_MRG_MOV (1) ==> move members to target group, source group is deleted after merge */ int *status) /* return status code */ /* merge two grouping tables by combining their members into a single table. The source grouping table must be the CHDU of the fitsfile pointed to by infptr, and the target grouping table must be the CHDU of the fitsfile to by outfptr. All members of the source grouping table shall be copied to the target grouping table. If the mgopt parameter is OPT_MRG_COPY then the source grouping table continues to exist after the merge. If the mgopt parameter is OPT_MRG_MOV then the source grouping table is deleted after the merge, and all member HDUs are updated accordingly. */ { long i ; long nmembers = 0; fitsfile *tmpfptr = NULL; if(*status != 0) return(*status); do { *status = fits_get_num_members(infptr,&nmembers,status); for(i = 1; i <= nmembers && *status == 0; ++i) { *status = fits_open_member(infptr,i,&tmpfptr,status); *status = fits_add_group_member(outfptr,tmpfptr,0,status); if(*status == HDU_ALREADY_MEMBER) *status = 0; if(tmpfptr != NULL) { fits_close_file(tmpfptr,status); tmpfptr = NULL; } } if(*status != 0) continue; if(mgopt == OPT_MRG_MOV) *status = fits_remove_group(infptr,OPT_RM_GPT,status); }while(0); if(tmpfptr != NULL) { fits_close_file(tmpfptr,status); } return(*status); } /*---------------------------------------------------------------------------*/ int ffgtcm(fitsfile *gfptr, /* FITS file pointer to grouping table */ int cmopt, /* code specifying compact options OPT_CMT_MBR (1) ==> compact only direct members (if groups) OPT_CMT_MBR_DEL (11) ==> (1) + delete all compacted groups */ int *status) /* return status code */ /* "Compact" a group pointed to by the FITS file pointer gfptr. This is achieved by flattening the tree structure of a group and its (grouping table) members. All members HDUs of a grouping table which is itself a member of the grouping table gfptr are added to gfptr. Optionally, the grouping tables which are "compacted" are deleted. If the grouping table contains no members that are themselves grouping tables then this function performs a NOOP. */ { long i; long nmembers = 0; char keyvalue[FLEN_VALUE]; char comment[FLEN_COMMENT]; fitsfile *mfptr = NULL; if(*status != 0) return(*status); do { if(cmopt != OPT_CMT_MBR && cmopt != OPT_CMT_MBR_DEL) { *status = BAD_OPTION; ffpmsg("Invalid value for cmopt parameter specified (ffgtcm)"); continue; } /* reteive the number of grouping table members */ *status = fits_get_num_members(gfptr,&nmembers,status); /* loop over all the grouping table members; if the member is a grouping table then merge its members with the parent grouping table */ for(i = 1; i <= nmembers && *status == 0; ++i) { *status = fits_open_member(gfptr,i,&mfptr,status); if(*status != 0) continue; *status = fits_read_key_str(mfptr,"EXTNAME",keyvalue,comment,status); /* if no EXTNAME keyword then cannot be a grouping table */ if(*status == KEY_NO_EXIST) { *status = 0; continue; } prepare_keyvalue(keyvalue); if(*status != 0) continue; /* if EXTNAME == "GROUPING" then process member as grouping table */ if(strcasecmp(keyvalue,"GROUPING") == 0) { /* merge the member (grouping table) into the grouping table */ *status = fits_merge_groups(mfptr,gfptr,OPT_MRG_COPY,status); *status = fits_close_file(mfptr,status); mfptr = NULL; /* remove the member from the grouping table now that all of its members have been transferred; if cmopt is set to OPT_CMT_MBR_DEL then remove and delete the member */ if(cmopt == OPT_CMT_MBR) *status = fits_remove_member(gfptr,i,OPT_RM_ENTRY,status); else *status = fits_remove_member(gfptr,i,OPT_RM_MBR,status); } else { /* not a grouping table; just close the opened member */ *status = fits_close_file(mfptr,status); mfptr = NULL; } } }while(0); return(*status); } /*--------------------------------------------------------------------------*/ int ffgtvf(fitsfile *gfptr, /* FITS file pointer to group */ long *firstfailed, /* Member ID (if positive) of first failed member HDU verify check or GRPID index (if negitive) of first failed group link verify check. */ int *status) /* return status code */ /* check the integrity of a grouping table to make sure that all group members are accessible and all the links to other grouping tables are valid. The firstfailed parameter returns the member ID of the first member HDU to fail verification if positive or the first group link to fail if negative; otherwise firstfailed contains a return value of 0. */ { long i; long nmembers = 0; long ngroups = 0; char errstr[FLEN_VALUE]; fitsfile *fptr = NULL; if(*status != 0) return(*status); *firstfailed = 0; do { /* attempt to open all the members of the grouping table. We stop at the first member which cannot be opened (which implies that it cannot be located) */ *status = fits_get_num_members(gfptr,&nmembers,status); for(i = 1; i <= nmembers && *status == 0; ++i) { *status = fits_open_member(gfptr,i,&fptr,status); fits_close_file(fptr,status); } /* if the status is non-zero from the above loop then record the member index that caused the error */ if(*status != 0) { *firstfailed = i; sprintf(errstr,"Group table verify failed for member %ld (ffgtvf)", i); ffpmsg(errstr); continue; } /* attempt to open all the groups linked to this grouping table. We stop at the first group which cannot be opened (which implies that it cannot be located) */ *status = fits_get_num_groups(gfptr,&ngroups,status); for(i = 1; i <= ngroups && *status == 0; ++i) { *status = fits_open_group(gfptr,i,&fptr,status); fits_close_file(fptr,status); } /* if the status from the above loop is non-zero, then record the GRPIDn index of the group that caused the failure */ if(*status != 0) { *firstfailed = -1*i; sprintf(errstr, "Group table verify failed for GRPID index %ld (ffgtvf)",i); ffpmsg(errstr); continue; } }while(0); return(*status); } /*---------------------------------------------------------------------------*/ int ffgtop(fitsfile *mfptr, /* FITS file pointer to the member HDU */ int grpid, /* group ID (GRPIDn index) within member HDU */ fitsfile **gfptr, /* FITS file pointer to grouping table HDU */ int *status) /* return status code */ /* open the grouping table that contains the member HDU. The member HDU must be the CHDU of the FITS file pointed to by mfptr, and the grouping table is identified by the Nth index number of the GRPIDn keywords specified in the member HDU's header. The fitsfile gfptr pointer is positioned with the appropriate FITS file with the grouping table as the CHDU. If the group grouping table resides in a file other than the member then an attempt is first made to open the file readwrite, and failing that readonly. Note that it is possible for the GRPIDn/GRPLCn keywords in a member header to be non-continuous, e.g., GRPID1, GRPID2, GRPID5, GRPID6. In such cases, the grpid index value specified in the function call shall identify the (grpid)th GRPID value. In the above example, if grpid == 3, then the group specified by GRPID5 would be opened. */ { int i; int found; long ngroups = 0; long grpExtver = 0; char keyword[FLEN_KEYWORD]; char keyvalue[FLEN_FILENAME]; char *tkeyvalue; char location[FLEN_FILENAME]; char location1[FLEN_FILENAME]; char location2[FLEN_FILENAME]; char comment[FLEN_COMMENT]; char *url[2]; if(*status != 0) return(*status); do { /* set the grouping table pointer to NULL for error checking later */ *gfptr = NULL; /* make sure that the group ID requested is valid ==> cannot be larger than the number of GRPIDn keywords in the member HDU header */ *status = fits_get_num_groups(mfptr,&ngroups,status); if(grpid > ngroups) { *status = BAD_GROUP_ID; sprintf(comment, "GRPID index %d larger total GRPID keywords %ld (ffgtop)", grpid,ngroups); ffpmsg(comment); continue; } /* find the (grpid)th group that the member HDU belongs to and read the value of the GRPID(grpid) keyword; fits_get_num_groups() automatically re-enumerates the GRPIDn/GRPLCn keywords to fill in any gaps */ sprintf(keyword,"GRPID%d",grpid); *status = fits_read_key_lng(mfptr,keyword,&grpExtver,comment,status); if(*status != 0) continue; /* if the value of the GRPIDn keyword is positive then the member is in the same FITS file as the grouping table and we only have to reopen the current FITS file. Else the member and grouping table HDUs reside in different files and another FITS file must be opened as specified by the corresponding GRPLCn keyword The DO WHILE loop only executes once and is used to control the file opening logic. */ do { if(grpExtver > 0) { /* the member resides in the same file as the grouping table, so just reopen the grouping table file */ *status = fits_reopen_file(mfptr,gfptr,status); continue; } else if(grpExtver == 0) { /* a GRPIDn value of zero (0) is undefined */ *status = BAD_GROUP_ID; sprintf(comment,"Invalid value of %ld for GRPID%d (ffgtop)", grpExtver,grpid); ffpmsg(comment); continue; } /* The GRPLCn keyword value is negative, which implies that the grouping table must reside in another FITS file; search for the corresponding GRPLCn keyword */ /* set the grpExtver value positive */ grpExtver = -1*grpExtver; /* read the GRPLCn keyword value */ sprintf(keyword,"GRPLC%d",grpid); /* SPR 1738 */ *status = fits_read_key_longstr(mfptr,keyword,&tkeyvalue,comment, status); if (0 == *status) { strcpy(keyvalue,tkeyvalue); free(tkeyvalue); } /* if the GRPLCn keyword was not found then there is a problem */ if(*status == KEY_NO_EXIST) { *status = BAD_GROUP_ID; sprintf(comment,"Cannot find GRPLC%d keyword (ffgtop)", grpid); ffpmsg(comment); continue; } prepare_keyvalue(keyvalue); /* if the GRPLCn keyword value specifies an absolute URL then try to open the file; we cannot attempt any relative URL or host-dependent file path reconstruction */ if(fits_is_url_absolute(keyvalue)) { ffpmsg("Try to open group table file as absolute URL (ffgtop)"); *status = fits_open_file(gfptr,keyvalue,READWRITE,status); /* if the open was successful then continue */ if(*status == 0) continue; /* if READWRITE failed then try opening it READONLY */ ffpmsg("OK, try open group table file as READONLY (ffgtop)"); *status = 0; *status = fits_open_file(gfptr,keyvalue,READONLY,status); /* continue regardless of the outcome */ continue; } /* see if the URL gives a file path that is absolute on the host machine */ *status = fits_url2path(keyvalue,location1,status); *status = fits_open_file(gfptr,location1,READWRITE,status); /* if the file opened then continue */ if(*status == 0) continue; /* if READWRITE failed then try opening it READONLY */ ffpmsg("OK, try open group table file as READONLY (ffgtop)"); *status = 0; *status = fits_open_file(gfptr,location1,READONLY,status); /* if the file opened then continue */ if(*status == 0) continue; /* the grouping table location given by GRPLCn must specify a relative URL. We assume that this URL is relative to the member HDU's FITS file. Try to construct a full URL location for the grouping table's FITS file and then open it */ *status = 0; /* retrieve the URL information for the member HDU's file */ url[0] = location1; url[1] = location2; *status = fits_get_url(mfptr,url[0],url[1],NULL,NULL,NULL,status); /* It is possible that the member HDU file has an initial URL it was opened with and a real URL that the file actually exists at (e.g., an HTTP accessed file copied to a local file). For each possible URL try to construct a */ for(i = 0, found = 0, *gfptr = NULL; i < 2 && !found; ++i) { /* the url string could be empty */ if(*url[i] == 0) continue; /* create a full URL from the partial and the member HDU file URL */ *status = fits_relurl2url(url[i],keyvalue,location,status); /* if an error occured then contniue */ if(*status != 0) { *status = 0; continue; } /* if the location does not specify an access method then turn it into a host dependent path */ if(! fits_is_url_absolute(location)) { *status = fits_url2path(location,url[i],status); strcpy(location,url[i]); } /* try to open the grouping table file READWRITE */ *status = fits_open_file(gfptr,location,READWRITE,status); if(*status != 0) { /* try to open the grouping table file READONLY */ ffpmsg("opening file as READWRITE failed (ffgtop)"); ffpmsg("OK, try to open file as READONLY (ffgtop)"); *status = 0; *status = fits_open_file(gfptr,location,READONLY,status); } /* either set the found flag or reset the status flag */ if(*status == 0) found = 1; else *status = 0; } }while(0); /* end of file opening loop */ /* if an error occured with the file opening then exit */ if(*status != 0) continue; if(*gfptr == NULL) { ffpmsg("Cannot open or find grouping table FITS file (ffgtop)"); *status = GROUP_NOT_FOUND; continue; } /* search for the grouping table in its FITS file */ *status = fits_movnam_hdu(*gfptr,ANY_HDU,"GROUPING",(int)grpExtver, status); if(*status != 0) *status = GROUP_NOT_FOUND; }while(0); if(*status != 0 && *gfptr != NULL) { fits_close_file(*gfptr,status); *gfptr = NULL; } return(*status); } /*---------------------------------------------------------------------------*/ int ffgtam(fitsfile *gfptr, /* FITS file pointer to grouping table HDU */ fitsfile *mfptr, /* FITS file pointer to member HDU */ int hdupos, /* member HDU position IF in the same file as the grouping table AND mfptr == NULL */ int *status) /* return status code */ /* add a member HDU to an existing grouping table. The fitsfile pointer gfptr must be positioned with the grouping table as the CHDU. The member HDU may either be identifed with the fitsfile *mfptr (which must be positioned to the member HDU) or the hdupos parameter (the HDU number of the member HDU) if both reside in the same FITS file. The hdupos value is only used if the mfptr parameter has a value of NULL (0). The new member HDU shall have the appropriate GRPIDn and GRPLCn keywords created in its header. Note that if the member HDU to be added to the grouping table is already a member of the group then it will not be added a sceond time. */ { int xtensionCol,extnameCol,extverCol,positionCol,locationCol,uriCol; int memberPosition = 0; int grptype = 0; int hdutype = 0; int useLocation = 0; int nkeys = 6; int found; int i; int memberIOstate; int groupIOstate; int iomode; long memberExtver = 0; long groupExtver = 0; long memberID = 0; long nmembers = 0; long ngroups = 0; long grpid = 0; char memberAccess1[FLEN_VALUE]; char memberAccess2[FLEN_VALUE]; char memberFileName[FLEN_FILENAME]; char memberLocation[FLEN_FILENAME]; char grplc[FLEN_FILENAME]; char *tgrplc; char memberHDUtype[FLEN_VALUE]; char memberExtname[FLEN_VALUE]; char memberURI[] = "URL"; char groupAccess1[FLEN_VALUE]; char groupAccess2[FLEN_VALUE]; char groupFileName[FLEN_FILENAME]; char groupLocation[FLEN_FILENAME]; char cwd[FLEN_FILENAME]; char *keys[] = {"GRPNAME","EXTVER","EXTNAME","TFIELDS","GCOUNT","EXTEND"}; char *tmpPtr[1]; char keyword[FLEN_KEYWORD]; char card[FLEN_CARD]; unsigned char charNull[] = {'\0'}; fitsfile *tmpfptr = NULL; int parentStatus = 0; if(*status != 0) return(*status); do { /* make sure the grouping table can be modified before proceeding */ fits_file_mode(gfptr,&iomode,status); if(iomode != READWRITE) { ffpmsg("cannot modify grouping table (ffgtam)"); *status = BAD_GROUP_ATTACH; continue; } /* if the calling function supplied the HDU position of the member HDU instead of fitsfile pointer then get a fitsfile pointer */ if(mfptr == NULL) { *status = fits_reopen_file(gfptr,&tmpfptr,status); *status = fits_movabs_hdu(tmpfptr,hdupos,&hdutype,status); if(*status != 0) continue; } else tmpfptr = mfptr; /* determine all the information about the member HDU that will be needed later; note that we establish the default values for all information values that are not explicitly found */ *status = fits_read_key_str(tmpfptr,"XTENSION",memberHDUtype,card, status); if(*status == KEY_NO_EXIST) { strcpy(memberHDUtype,"PRIMARY"); *status = 0; } prepare_keyvalue(memberHDUtype); *status = fits_read_key_lng(tmpfptr,"EXTVER",&memberExtver,card,status); if(*status == KEY_NO_EXIST) { memberExtver = 1; *status = 0; } *status = fits_read_key_str(tmpfptr,"EXTNAME",memberExtname,card, status); if(*status == KEY_NO_EXIST) { memberExtname[0] = 0; *status = 0; } prepare_keyvalue(memberExtname); fits_get_hdu_num(tmpfptr,&memberPosition); /* Determine if the member HDU's FITS file location needs to be taken into account when building its grouping table reference If the member location needs to be used (==> grouping table and member HDU reside in different files) then create an appropriate URL for the member HDU's file and grouping table's file. Note that the logic for this is rather complicated */ /* SPR 3463, don't do this if(tmpfptr->Fptr == gfptr->Fptr) { */ /* member HDU and grouping table reside in the same file, no need to use the location information */ /* printf ("same file\n"); useLocation = 0; memberIOstate = 1; *memberFileName = 0; } else { */ /* the member HDU and grouping table FITS file location information must be used. First determine the correct driver and file name for the group table and member HDU files. If either are disk files then construct an absolute file path for them. Finally, if both are disk files construct relative file paths from the group(member) file to the member(group) file. */ /* set the USELOCATION flag to true */ useLocation = 1; /* get the location, access type and iostate (RO, RW) of the member HDU file */ *status = fits_get_url(tmpfptr,memberFileName,memberLocation, memberAccess1,memberAccess2,&memberIOstate, status); /* if the memberFileName string is empty then use the values of the memberLocation string. This corresponds to a file where the "real" file is a temporary memory file, and we must assume the the application really wants the original file to be the group member */ if(strlen(memberFileName) == 0) { strcpy(memberFileName,memberLocation); strcpy(memberAccess1,memberAccess2); } /* get the location, access type and iostate (RO, RW) of the grouping table file */ *status = fits_get_url(gfptr,groupFileName,groupLocation, groupAccess1,groupAccess2,&groupIOstate, status); if(*status != 0) continue; /* the grouping table file must be writable to continue */ if(groupIOstate == 0) { ffpmsg("cannot modify grouping table (ffgtam)"); *status = BAD_GROUP_ATTACH; continue; } /* determine how to construct the resulting URLs for the member and group files */ if(strcasecmp(groupAccess1,"file://") && strcasecmp(memberAccess1,"file://")) { *cwd = 0; /* nothing to do in this case; both the member and group files must be of an access type that already gives valid URLs; i.e., URLs that we can pass directly to the file drivers */ } else { /* retrieve the Current Working Directory as a Unix-like URL standard string */ *status = fits_get_cwd(cwd,status); /* create full file path for the member HDU FITS file URL if it is of access type file:// */ if(strcasecmp(memberAccess1,"file://") == 0) { if(*memberFileName == '/') { strcpy(memberLocation,memberFileName); } else { strcpy(memberLocation,cwd); strcat(memberLocation,"/"); strcat(memberLocation,memberFileName); } *status = fits_clean_url(memberLocation,memberFileName, status); } /* create full file path for the grouping table HDU FITS file URL if it is of access type file:// */ if(strcasecmp(groupAccess1,"file://") == 0) { if(*groupFileName == '/') { strcpy(groupLocation,groupFileName); } else { strcpy(groupLocation,cwd); strcat(groupLocation,"/"); strcat(groupLocation,groupFileName); } *status = fits_clean_url(groupLocation,groupFileName,status); } /* if both the member and group files are disk files then create a relative path (relative URL) strings with respect to the grouping table's file and the grouping table's file with respect to the member HDU's file */ if(strcasecmp(groupAccess1,"file://") == 0 && strcasecmp(memberAccess1,"file://") == 0) { fits_url2relurl(memberFileName,groupFileName, groupLocation,status); fits_url2relurl(groupFileName,memberFileName, memberLocation,status); /* copy the resulting partial URL strings to the memberFileName and groupFileName variables for latter use in the function */ strcpy(memberFileName,memberLocation); strcpy(groupFileName,groupLocation); } } /* beo done */ /* } */ /* retrieve the grouping table's EXTVER value */ *status = fits_read_key_lng(gfptr,"EXTVER",&groupExtver,card,status); /* if useLocation is true then make the group EXTVER value negative for the subsequent GRPIDn/GRPLCn matching */ /* SPR 3463 change test */ if(tmpfptr->Fptr != gfptr->Fptr) groupExtver = -1*groupExtver; /* retrieve the number of group members */ *status = fits_get_num_members(gfptr,&nmembers,status); do { /* make sure the member HDU is not already an entry in the grouping table before adding it */ *status = ffgmf(gfptr,memberHDUtype,memberExtname,memberExtver, memberPosition,memberFileName,&memberID,status); if(*status == MEMBER_NOT_FOUND) *status = 0; else if(*status == 0) { parentStatus = HDU_ALREADY_MEMBER; ffpmsg("Specified HDU is already a member of the Grouping table (ffgtam)"); continue; } else continue; /* if the member HDU is not already recorded in the grouping table then add it */ /* add a new row to the grouping table */ *status = fits_insert_rows(gfptr,nmembers,1,status); ++nmembers; /* retrieve the grouping table column IDs and structure type */ *status = ffgtgc(gfptr,&xtensionCol,&extnameCol,&extverCol,&positionCol, &locationCol,&uriCol,&grptype,status); /* fill in the member HDU data in the new grouping table row */ *tmpPtr = memberHDUtype; if(xtensionCol != 0) fits_write_col_str(gfptr,xtensionCol,nmembers,1,1,tmpPtr,status); *tmpPtr = memberExtname; if(extnameCol != 0) { if(strlen(memberExtname) != 0) fits_write_col_str(gfptr,extnameCol,nmembers,1,1,tmpPtr,status); else /* WILL THIS WORK FOR VAR LENTH CHAR COLS??????*/ fits_write_col_byt(gfptr,extnameCol,nmembers,1,1,charNull,status); } if(extverCol != 0) fits_write_col_lng(gfptr,extverCol,nmembers,1,1,&memberExtver, status); if(positionCol != 0) fits_write_col_int(gfptr,positionCol,nmembers,1,1, &memberPosition,status); *tmpPtr = memberFileName; if(locationCol != 0) { /* Change the test for SPR 3463 */ if(tmpfptr->Fptr != gfptr->Fptr) fits_write_col_str(gfptr,locationCol,nmembers,1,1,tmpPtr,status); else /* WILL THIS WORK FOR VAR LENTH CHAR COLS??????*/ fits_write_col_byt(gfptr,locationCol,nmembers,1,1,charNull,status); } *tmpPtr = memberURI; if(uriCol != 0) { /* Change the test for SPR 3463 */ if(tmpfptr->Fptr != gfptr->Fptr) fits_write_col_str(gfptr,uriCol,nmembers,1,1,tmpPtr,status); else /* WILL THIS WORK FOR VAR LENTH CHAR COLS??????*/ fits_write_col_byt(gfptr,uriCol,nmembers,1,1,charNull,status); } } while(0); if(0 != *status) continue; /* add GRPIDn/GRPLCn keywords to the member HDU header to link it to the grouing table if the they do not already exist and the member file is RW */ fits_file_mode(tmpfptr,&iomode,status); if(memberIOstate == 0 || iomode != READWRITE) { ffpmsg("cannot add GRPID/LC keywords to member HDU: (ffgtam)"); ffpmsg(memberFileName); continue; } *status = fits_get_num_groups(tmpfptr,&ngroups,status); /* look for the GRPID/LC keywords in the member HDU; if the keywords for the back-link to the grouping table already exist then no need to add them again */ for(i = 1, found = 0; i <= ngroups && !found && *status == 0; ++i) { sprintf(keyword,"GRPID%d",(int)ngroups); *status = fits_read_key_lng(tmpfptr,keyword,&grpid,card,status); if(grpid == groupExtver) { if(grpid < 0) { /* have to make sure the GRPLCn keyword matches too */ sprintf(keyword,"GRPLC%d",(int)ngroups); /* SPR 1738 */ *status = fits_read_key_longstr(mfptr,keyword,&tgrplc,card, status); if (0 == *status) { strcpy(grplc,tgrplc); free(tgrplc); } /* always compare files using absolute paths the presence of a non-empty cwd indicates that the file names may require conversion to absolute paths */ if(0 < strlen(cwd)) { /* temp buffer for use in assembling abs. path(s) */ char tmp[FLEN_FILENAME]; /* make grplc absolute if necessary */ if(!fits_is_url_absolute(grplc)) { fits_path2url(grplc,groupLocation,status); if(groupLocation[0] != '/') { strcpy(tmp, cwd); strcat(tmp,"/"); strcat(tmp,groupLocation); fits_clean_url(tmp,grplc,status); } } /* make groupFileName absolute if necessary */ if(!fits_is_url_absolute(groupFileName)) { fits_path2url(groupFileName,groupLocation,status); if(groupLocation[0] != '/') { strcpy(tmp, cwd); strcat(tmp,"/"); strcat(tmp,groupLocation); /* note: use groupLocation (which is not used below this block), to store the absolute file name instead of using groupFileName. The latter may be needed unaltered if the GRPLC is written below */ fits_clean_url(tmp,groupLocation,status); } } } /* see if the grplc value and the group file name match */ if(strcmp(grplc,groupLocation) == 0) found = 1; } else { /* the match is found with GRPIDn alone */ found = 1; } } } /* if FOUND is true then no need to continue */ if(found) { ffpmsg("HDU already has GRPID/LC keywords for group table (ffgtam)"); continue; } /* add the GRPID/LC keywords to the member header for this grouping table If NGROUPS == 0 then we must position the header pointer to the record where we want to insert the GRPID/LC keywords (the pointer is already correctly positioned if the above search loop activiated) */ if(ngroups == 0) { /* no GRPIDn/GRPLCn keywords currently exist in header so try to position the header pointer to a desirable position */ for(i = 0, *status = KEY_NO_EXIST; i < nkeys && *status == KEY_NO_EXIST; ++i) { *status = 0; *status = fits_read_card(tmpfptr,keys[i],card,status); } /* all else fails: move write pointer to end of header */ if(*status == KEY_NO_EXIST) { *status = 0; fits_get_hdrspace(tmpfptr,&nkeys,&i,status); ffgrec(tmpfptr,nkeys,card,status); } /* any other error status then abort */ if(*status != 0) continue; } /* now that the header pointer is positioned for the GRPID/LC keyword insertion increment the number of group links counter for the member HDU */ ++ngroups; /* if the member HDU and grouping table reside in the same FITS file then there is no need to add a GRPLCn keyword */ /* SPR 3463 change test */ if(tmpfptr->Fptr == gfptr->Fptr) { /* add the GRPIDn keyword only */ sprintf(keyword,"GRPID%d",(int)ngroups); fits_insert_key_lng(tmpfptr,keyword,groupExtver, "EXTVER of Group containing this HDU",status); } else { /* add the GRPIDn and GRPLCn keywords */ sprintf(keyword,"GRPID%d",(int)ngroups); fits_insert_key_lng(tmpfptr,keyword,groupExtver, "EXTVER of Group containing this HDU",status); sprintf(keyword,"GRPLC%d",(int)ngroups); /* SPR 1738 */ fits_insert_key_longstr(tmpfptr,keyword,groupFileName, "URL of file containing Group",status); fits_write_key_longwarn(tmpfptr,status); } }while(0); /* close the tmpfptr pointer if it was opened in this function */ if(mfptr == NULL) { *status = fits_close_file(tmpfptr,status); } *status = 0 == *status ? parentStatus : *status; return(*status); } /*---------------------------------------------------------------------------*/ int ffgtnm(fitsfile *gfptr, /* FITS file pointer to grouping table */ long *nmembers, /* member count of the groping table */ int *status) /* return status code */ /* return the number of member HDUs in a grouping table. The fitsfile pointer gfptr must be positioned with the grouping table as the CHDU. The number of grouping table member HDUs is just the NAXIS2 value of the grouping table. */ { char keyvalue[FLEN_VALUE]; char comment[FLEN_COMMENT]; if(*status != 0) return(*status); *status = fits_read_keyword(gfptr,"EXTNAME",keyvalue,comment,status); if(*status == KEY_NO_EXIST) *status = NOT_GROUP_TABLE; else { prepare_keyvalue(keyvalue); if(strcasecmp(keyvalue,"GROUPING") != 0) { *status = NOT_GROUP_TABLE; ffpmsg("Specified HDU is not a Grouping table (ffgtnm)"); } *status = fits_read_key_lng(gfptr,"NAXIS2",nmembers,comment,status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgmng(fitsfile *mfptr, /* FITS file pointer to member HDU */ long *ngroups, /* total number of groups linked to HDU */ int *status) /* return status code */ /* return the number of groups to which a HDU belongs, as defined by the number of GRPIDn/GRPLCn keyword records that appear in the HDU header. The fitsfile pointer mfptr must be positioned with the member HDU as the CHDU. Each time this function is called, the indicies of the GRPIDn/GRPLCn keywords are checked to make sure they are continuous (ie no gaps) and are re-enumerated to eliminate gaps if gaps are found to be present. */ { int offset; int index; int newIndex; int i; long grpid; char *inclist[] = {"GRPID#"}; char keyword[FLEN_KEYWORD]; char newKeyword[FLEN_KEYWORD]; char card[FLEN_CARD]; char comment[FLEN_COMMENT]; char *tkeyvalue; if(*status != 0) return(*status); *ngroups = 0; /* reset the member HDU keyword counter to the beginning */ *status = ffgrec(mfptr,0,card,status); /* search for the number of GRPIDn keywords in the member HDU header and count them with the ngroups variable */ while(*status == 0) { /* read the next GRPIDn keyword in the series */ *status = fits_find_nextkey(mfptr,inclist,1,NULL,0,card,status); if(*status != 0) continue; ++(*ngroups); } if(*status == KEY_NO_EXIST) *status = 0; /* read each GRPIDn/GRPLCn keyword and adjust their index values so that there are no gaps in the index count */ for(index = 1, offset = 0, i = 1; i <= *ngroups && *status == 0; ++index) { sprintf(keyword,"GRPID%d",index); /* try to read the next GRPIDn keyword in the series */ *status = fits_read_key_lng(mfptr,keyword,&grpid,card,status); /* if not found then increment the offset counter and continue */ if(*status == KEY_NO_EXIST) { *status = 0; ++offset; } else { /* increment the number_keys_found counter and see if the index of the keyword needs to be updated */ ++i; if(offset > 0) { /* compute the new index for the GRPIDn/GRPLCn keywords */ newIndex = index - offset; /* update the GRPIDn keyword index */ sprintf(newKeyword,"GRPID%d",newIndex); fits_modify_name(mfptr,keyword,newKeyword,status); /* If present, update the GRPLCn keyword index */ sprintf(keyword,"GRPLC%d",index); sprintf(newKeyword,"GRPLC%d",newIndex); /* SPR 1738 */ *status = fits_read_key_longstr(mfptr,keyword,&tkeyvalue,comment, status); if (0 == *status) { fits_delete_key(mfptr,keyword,status); fits_insert_key_longstr(mfptr,newKeyword,tkeyvalue,comment,status); fits_write_key_longwarn(mfptr,status); free(tkeyvalue); } if(*status == KEY_NO_EXIST) *status = 0; } } } return(*status); } /*---------------------------------------------------------------------------*/ int ffgmop(fitsfile *gfptr, /* FITS file pointer to grouping table */ long member, /* member ID (row num) within grouping table */ fitsfile **mfptr, /* FITS file pointer to member HDU */ int *status) /* return status code */ /* open a grouping table member, returning a pointer to the member's FITS file with the CHDU set to the member HDU. The grouping table must be the CHDU of the FITS file pointed to by gfptr. The member to open is identified by its row number within the grouping table (first row/member == 1). If the member resides in a FITS file different from the grouping table the member file is first opened readwrite and if this fails then it is opened readonly. For access type of FILE:// the member file is searched for assuming (1) an absolute path is given, (2) a path relative to the CWD is given, and (3) a path relative to the grouping table file but not relative to the CWD is given. If all of these fail then the error FILE_NOT_FOUND is returned. */ { int xtensionCol,extnameCol,extverCol,positionCol,locationCol,uriCol; int grptype,hdutype; int dummy; long hdupos = 0; long extver = 0; char xtension[FLEN_VALUE]; char extname[FLEN_VALUE]; char uri[FLEN_VALUE]; char grpLocation1[FLEN_FILENAME]; char grpLocation2[FLEN_FILENAME]; char mbrLocation1[FLEN_FILENAME]; char mbrLocation2[FLEN_FILENAME]; char mbrLocation3[FLEN_FILENAME]; char cwd[FLEN_FILENAME]; char card[FLEN_CARD]; char nstr[] = {'\0'}; char *tmpPtr[1]; if(*status != 0) return(*status); do { /* retrieve the Grouping Convention reserved column positions within the grouping table */ *status = ffgtgc(gfptr,&xtensionCol,&extnameCol,&extverCol,&positionCol, &locationCol,&uriCol,&grptype,status); if(*status != 0) continue; /* extract the member information from grouping table */ tmpPtr[0] = xtension; if(xtensionCol != 0) { *status = fits_read_col_str(gfptr,xtensionCol,member,1,1,nstr, tmpPtr,&dummy,status); /* convert the xtension string to a hdutype code */ if(strcasecmp(xtension,"PRIMARY") == 0) hdutype = IMAGE_HDU; else if(strcasecmp(xtension,"IMAGE") == 0) hdutype = IMAGE_HDU; else if(strcasecmp(xtension,"TABLE") == 0) hdutype = ASCII_TBL; else if(strcasecmp(xtension,"BINTABLE") == 0) hdutype = BINARY_TBL; else hdutype = ANY_HDU; } tmpPtr[0] = extname; if(extnameCol != 0) *status = fits_read_col_str(gfptr,extnameCol,member,1,1,nstr, tmpPtr,&dummy,status); if(extverCol != 0) *status = fits_read_col_lng(gfptr,extverCol,member,1,1,0, (long*)&extver,&dummy,status); if(positionCol != 0) *status = fits_read_col_lng(gfptr,positionCol,member,1,1,0, (long*)&hdupos,&dummy,status); tmpPtr[0] = mbrLocation1; if(locationCol != 0) *status = fits_read_col_str(gfptr,locationCol,member,1,1,nstr, tmpPtr,&dummy,status); tmpPtr[0] = uri; if(uriCol != 0) *status = fits_read_col_str(gfptr,uriCol,member,1,1,nstr, tmpPtr,&dummy,status); if(*status != 0) continue; /* decide what FITS file the member HDU resides in and open the file using the fitsfile* pointer mfptr; note that this logic is rather complicated and is based primiarly upon if a URL specifier is given for the member file in the grouping table */ switch(grptype) { case GT_ID_POS: case GT_ID_REF: case GT_ID_ALL: /* no location information is given so we must assume that the member HDU resides in the same FITS file as the grouping table; if the grouping table was incorrectly constructed then this assumption will be false, but there is nothing to be done about it at this point */ *status = fits_reopen_file(gfptr,mfptr,status); break; case GT_ID_REF_URI: case GT_ID_POS_URI: case GT_ID_ALL_URI: /* The member location column exists. Determine if the member resides in the same file as the grouping table or in a separate file; open the member file in either case */ if(strlen(mbrLocation1) == 0) { /* since no location information was given we must assume that the member is in the same FITS file as the grouping table */ *status = fits_reopen_file(gfptr,mfptr,status); } else { /* make sure the location specifiation is "URL"; we cannot decode any other URI types at this time */ if(strcasecmp(uri,"URL") != 0) { *status = FILE_NOT_OPENED; sprintf(card, "Cannot open member HDU file with URI type %s (ffgmop)", uri); ffpmsg(card); continue; } /* The location string for the member is not NULL, so it does not necessially reside in the same FITS file as the grouping table. Three cases are attempted for opening the member's file in the following order: 1. The URL given for the member's file is absolute (i.e., access method supplied); try to open the member 2. The URL given for the member's file is not absolute but is an absolute file path; try to open the member as a file after the file path is converted to a host-dependent form 3. The URL given for the member's file is not absolute and is given as a relative path to the location of the grouping table's file. Create an absolute URL using the grouping table's file URL and try to open the member. If all three cases fail then an error is returned. In each case the file is first opened in read/write mode and failing that readonly mode. The following DO loop is only used as a mechanism to break (continue) when the proper file opening method is found */ do { /* CASE 1: See if the member URL is absolute (i.e., includes a access directive) and if so open the file */ if(fits_is_url_absolute(mbrLocation1)) { /* the URL must specify an access method, which implies that its an absolute reference regardless of the access method, pass the whole URL to the open function for processing */ ffpmsg("member URL is absolute, try open R/W (ffgmop)"); *status = fits_open_file(mfptr,mbrLocation1,READWRITE, status); if(*status == 0) continue; *status = 0; /* now try to open file using full URL specs in readonly mode */ ffpmsg("OK, now try to open read-only (ffgmop)"); *status = fits_open_file(mfptr,mbrLocation1,READONLY, status); /* break from DO loop regardless of status */ continue; } /* CASE 2: If we got this far then the member URL location has no access type ==> FILE:// Try to open the member file using the URL as is, i.e., assume that it is given as absolute, if it starts with a '/' character */ ffpmsg("Member URL is of type FILE (ffgmop)"); if(*mbrLocation1 == '/') { ffpmsg("Member URL specifies abs file path (ffgmop)"); /* convert the URL path to a host dependent path */ *status = fits_url2path(mbrLocation1,mbrLocation2, status); ffpmsg("Try to open member URL in R/W mode (ffgmop)"); *status = fits_open_file(mfptr,mbrLocation2,READWRITE, status); if(*status == 0) continue; *status = 0; /* now try to open file using the URL as an absolute path in readonly mode */ ffpmsg("OK, now try to open read-only (ffgmop)"); *status = fits_open_file(mfptr,mbrLocation2,READONLY, status); /* break from the Do loop regardless of the status */ continue; } /* CASE 3: If we got this far then the URL does not specify an absoulte file path or URL with access method. Since the path to the group table's file is (obviously) valid for the CWD, create a full location string for the member HDU using the grouping table URL as a basis The only problem is that the grouping table file might have two URLs, the original one used to open it and the one that points to the real file being accessed (i.e., a file accessed via HTTP but transferred to a local disk file). Have to attempt to build a URL to the member HDU file using both of these URLs if defined. */ ffpmsg("Try to open member file as relative URL (ffgmop)"); /* get the URL information for the grouping table file */ *status = fits_get_url(gfptr,grpLocation1,grpLocation2, NULL,NULL,NULL,status); /* if the "real" grouping table file URL is defined then build a full url for the member HDU file using it and try to open the member HDU file */ if(*grpLocation1) { /* make sure the group location is absolute */ if(! fits_is_url_absolute(grpLocation1) && *grpLocation1 != '/') { fits_get_cwd(cwd,status); strcat(cwd,"/"); strcat(cwd,grpLocation1); strcpy(grpLocation1,cwd); } /* create a full URL for the member HDU file */ *status = fits_relurl2url(grpLocation1,mbrLocation1, mbrLocation2,status); if(*status != 0) continue; /* if the URL does not have an access method given then translate it into a host dependent file path */ if(! fits_is_url_absolute(mbrLocation2)) { *status = fits_url2path(mbrLocation2,mbrLocation3, status); strcpy(mbrLocation2,mbrLocation3); } /* try to open the member file READWRITE */ *status = fits_open_file(mfptr,mbrLocation2,READWRITE, status); if(*status == 0) continue; *status = 0; /* now try to open in readonly mode */ ffpmsg("now try to open file as READONLY (ffgmop)"); *status = fits_open_file(mfptr,mbrLocation2,READONLY, status); if(*status == 0) continue; *status = 0; } /* if we got this far then either the "real" grouping table file URL was not defined or all attempts to open the resulting member HDU file URL failed. if the "original" grouping table file URL is defined then build a full url for the member HDU file using it and try to open the member HDU file */ if(*grpLocation2) { /* make sure the group location is absolute */ if(! fits_is_url_absolute(grpLocation2) && *grpLocation2 != '/') { fits_get_cwd(cwd,status); strcat(cwd,"/"); strcat(cwd,grpLocation2); strcpy(grpLocation2,cwd); } /* create an absolute URL for the member HDU file */ *status = fits_relurl2url(grpLocation2,mbrLocation1, mbrLocation2,status); if(*status != 0) continue; /* if the URL does not have an access method given then translate it into a host dependent file path */ if(! fits_is_url_absolute(mbrLocation2)) { *status = fits_url2path(mbrLocation2,mbrLocation3, status); strcpy(mbrLocation2,mbrLocation3); } /* try to open the member file READWRITE */ *status = fits_open_file(mfptr,mbrLocation2,READWRITE, status); if(*status == 0) continue; *status = 0; /* now try to open in readonly mode */ ffpmsg("now try to open file as READONLY (ffgmop)"); *status = fits_open_file(mfptr,mbrLocation2,READONLY, status); if(*status == 0) continue; *status = 0; } /* if we got this far then the member HDU file could not be opened using any method. Log the error. */ ffpmsg("Cannot open member HDU FITS file (ffgmop)"); *status = MEMBER_NOT_FOUND; }while(0); } break; default: /* no default action */ break; } if(*status != 0) continue; /* attempt to locate the member HDU within its FITS file as determined and opened above */ switch(grptype) { case GT_ID_POS: case GT_ID_POS_URI: /* try to find the member hdu in the the FITS file pointed to by mfptr based upon its HDU posistion value. Note that is impossible to verify if the HDU is actually the correct HDU due to a lack of information. */ *status = fits_movabs_hdu(*mfptr,(int)hdupos,&hdutype,status); break; case GT_ID_REF: case GT_ID_REF_URI: /* try to find the member hdu in the FITS file pointed to by mfptr based upon its XTENSION, EXTNAME and EXTVER keyword values */ *status = fits_movnam_hdu(*mfptr,hdutype,extname,extver,status); if(*status == BAD_HDU_NUM) { *status = MEMBER_NOT_FOUND; ffpmsg("Cannot find specified member HDU (ffgmop)"); } /* if the above function returned without error then the mfptr is pointed to the member HDU */ break; case GT_ID_ALL: case GT_ID_ALL_URI: /* if the member entry has reference information then use it (ID by reference is safer than ID by position) else use the position information */ if(strlen(xtension) > 0 && strlen(extname) > 0 && extver > 0) { /* valid reference info exists so use it */ /* try to find the member hdu in the grouping table's file */ *status = fits_movnam_hdu(*mfptr,hdutype,extname,extver,status); if(*status == BAD_HDU_NUM) { *status = MEMBER_NOT_FOUND; ffpmsg("Cannot find specified member HDU (ffgmop)"); } } else { *status = fits_movabs_hdu(*mfptr,(int)hdupos,&hdutype, status); if(*status == END_OF_FILE) *status = MEMBER_NOT_FOUND; } /* if the above function returned without error then the mfptr is pointed to the member HDU */ break; default: /* no default action */ break; } }while(0); if(*status != 0 && *mfptr != NULL) { fits_close_file(*mfptr,status); } return(*status); } /*---------------------------------------------------------------------------*/ int ffgmcp(fitsfile *gfptr, /* FITS file pointer to group */ fitsfile *mfptr, /* FITS file pointer to new member FITS file */ long member, /* member ID (row num) within grouping table */ int cpopt, /* code specifying copy options: OPT_MCP_ADD (0) ==> add copied member to the grouping table OPT_MCP_NADD (1) ==> do not add member copy to the grouping table OPT_MCP_REPL (2) ==> replace current member entry with member copy */ int *status) /* return status code */ /* copy a member HDU of a grouping table to a new FITS file. The grouping table must be the CHDU of the FITS file pointed to by gfptr. The copy of the group member shall be appended to the end of the FITS file pointed to by mfptr. If the cpopt parameter is set to OPT_MCP_ADD then the copy of the member is added to the grouping table as a new member, if OPT_MCP_NADD then the copied member is not added to the grouping table, and if OPT_MCP_REPL then the copied member is used to replace the original member. The copied member HDU also has its EXTVER value updated so that its combination of XTENSION, EXTNAME and EXVTER is unique within its new FITS file. */ { int numkeys = 0; int keypos = 0; int hdunum = 0; int hdutype = 0; int i; char *incList[] = {"GRPID#","GRPLC#"}; char extname[FLEN_VALUE]; char card[FLEN_CARD]; char comment[FLEN_COMMENT]; char keyname[FLEN_CARD]; char value[FLEN_CARD]; fitsfile *tmpfptr = NULL; if(*status != 0) return(*status); do { /* open the member HDU to be copied */ *status = fits_open_member(gfptr,member,&tmpfptr,status); if(*status != 0) continue; /* if the member is a grouping table then copy it with a call to fits_copy_group() using the "copy only the grouping table" option if it is not a grouping table then copy the hdu with fits_copy_hdu() remove all GRPIDn and GRPLCn keywords, and update the EXTVER keyword value */ /* get the member HDU's EXTNAME value */ *status = fits_read_key_str(tmpfptr,"EXTNAME",extname,comment,status); /* if no EXTNAME value was found then set the extname to a null string */ if(*status == KEY_NO_EXIST) { extname[0] = 0; *status = 0; } else if(*status != 0) continue; prepare_keyvalue(extname); /* if a grouping table then copy with fits_copy_group() */ if(strcasecmp(extname,"GROUPING") == 0) *status = fits_copy_group(tmpfptr,mfptr,OPT_GCP_GPT,status); else { /* copy the non-grouping table HDU the conventional way */ *status = fits_copy_hdu(tmpfptr,mfptr,0,status); ffgrec(mfptr,0,card,status); /* delete all the GRPIDn and GRPLCn keywords in the copied HDU */ while(*status == 0) { *status = fits_find_nextkey(mfptr,incList,2,NULL,0,card,status); *status = fits_get_hdrpos(mfptr,&numkeys,&keypos,status); /* SPR 1738 */ *status = fits_read_keyn(mfptr,keypos-1,keyname,value, comment,status); *status = fits_read_record(mfptr,keypos-1,card,status); *status = fits_delete_key(mfptr,keyname,status); } if(*status == KEY_NO_EXIST) *status = 0; if(*status != 0) continue; } /* if the member HDU does not have an EXTNAME keyword then add one with a default value */ if(strlen(extname) == 0) { if(fits_get_hdu_num(tmpfptr,&hdunum) == 1) { strcpy(extname,"PRIMARY"); *status = fits_write_key_str(mfptr,"EXTNAME",extname, "HDU was Formerly a Primary Array", status); } else { strcpy(extname,"DEFAULT"); *status = fits_write_key_str(mfptr,"EXTNAME",extname, "default EXTNAME set by CFITSIO", status); } } /* update the member HDU's EXTVER value (add it if not present) */ fits_get_hdu_num(mfptr,&hdunum); fits_get_hdu_type(mfptr,&hdutype,status); /* set the EXTVER value to 0 for now */ *status = fits_modify_key_lng(mfptr,"EXTVER",0,NULL,status); /* if the EXTVER keyword was not found then add it */ if(*status == KEY_NO_EXIST) { *status = 0; *status = fits_read_key_str(mfptr,"EXTNAME",extname,comment, status); *status = fits_insert_key_lng(mfptr,"EXTVER",0, "Extension version ID",status); } if(*status != 0) continue; /* find the first available EXTVER value for the copied HDU */ for(i = 1; fits_movnam_hdu(mfptr,hdutype,extname,i,status) == 0; ++i); *status = 0; fits_movabs_hdu(mfptr,hdunum,&hdutype,status); /* reset the copied member HDUs EXTVER value */ *status = fits_modify_key_lng(mfptr,"EXTVER",(long)i,NULL,status); /* perform member copy operations that are dependent upon the cpopt parameter value */ switch(cpopt) { case OPT_MCP_ADD: /* add the copied member to the grouping table, leaving the entry for the original member in place */ *status = fits_add_group_member(gfptr,mfptr,0,status); break; case OPT_MCP_NADD: /* nothing to do for this copy option */ break; case OPT_MCP_REPL: /* remove the original member from the grouping table and add the copied member in its place */ *status = fits_remove_member(gfptr,member,OPT_RM_ENTRY,status); *status = fits_add_group_member(gfptr,mfptr,0,status); break; default: *status = BAD_OPTION; ffpmsg("Invalid value specified for the cmopt parameter (ffgmcp)"); break; } }while(0); if(tmpfptr != NULL) { fits_close_file(tmpfptr,status); } return(*status); } /*---------------------------------------------------------------------------*/ int ffgmtf(fitsfile *infptr, /* FITS file pointer to source grouping table */ fitsfile *outfptr, /* FITS file pointer to target grouping table */ long member, /* member ID within source grouping table */ int tfopt, /* code specifying transfer opts: OPT_MCP_ADD (0) ==> copy member to dest. OPT_MCP_MOV (3) ==> move member to dest. */ int *status) /* return status code */ /* transfer a group member from one grouping table to another. The source grouping table must be the CHDU of the fitsfile pointed to by infptr, and the destination grouping table must be the CHDU of the fitsfile to by outfptr. If the tfopt parameter is OPT_MCP_ADD then the member is made a member of the target group and remains a member of the source group. If the tfopt parameter is OPT_MCP_MOV then the member is deleted from the source group after the transfer to the destination group. The member to be transfered is identified by its row number within the source grouping table. */ { fitsfile *mfptr = NULL; if(*status != 0) return(*status); if(tfopt != OPT_MCP_MOV && tfopt != OPT_MCP_ADD) { *status = BAD_OPTION; ffpmsg("Invalid value specified for the tfopt parameter (ffgmtf)"); } else { /* open the member of infptr to be transfered */ *status = fits_open_member(infptr,member,&mfptr,status); /* add the member to the outfptr grouping table */ *status = fits_add_group_member(outfptr,mfptr,0,status); /* close the member HDU */ *status = fits_close_file(mfptr,status); /* if the tfopt is "move member" then remove it from the infptr grouping table */ if(tfopt == OPT_MCP_MOV) *status = fits_remove_member(infptr,member,OPT_RM_ENTRY,status); } return(*status); } /*---------------------------------------------------------------------------*/ int ffgmrm(fitsfile *gfptr, /* FITS file pointer to group table */ long member, /* member ID (row num) in the group */ int rmopt, /* code specifying the delete option: OPT_RM_ENTRY ==> delete the member entry OPT_RM_MBR ==> delete entry and member HDU */ int *status) /* return status code */ /* remove a member HDU from a grouping table. The fitsfile pointer gfptr must be positioned with the grouping table as the CHDU, and the member to delete is identified by its row number in the table (first member == 1). The rmopt parameter determines if the member entry is deleted from the grouping table (in which case GRPIDn and GRPLCn keywords in the member HDU's header shall be updated accordingly) or if the member HDU shall itself be removed from its FITS file. */ { int found = 0; int hdutype = 0; int index = 0; int iomode = 0; long i; long ngroups = 0; long nmembers = 0; long groupExtver = 0; long grpid = 0; char grpLocation1[FLEN_FILENAME]; char grpLocation2[FLEN_FILENAME]; char grpLocation3[FLEN_FILENAME]; char cwd[FLEN_FILENAME]; char keyword[FLEN_KEYWORD]; /* SPR 1738 This can now be longer */ char grplc[FLEN_FILENAME]; char *tgrplc; char keyvalue[FLEN_VALUE]; char card[FLEN_CARD]; char *editLocation; fitsfile *mfptr = NULL; if(*status != 0) return(*status); do { /* make sure the grouping table can be modified before proceeding */ fits_file_mode(gfptr,&iomode,status); if(iomode != READWRITE) { ffpmsg("cannot modify grouping table (ffgtam)"); *status = BAD_GROUP_DETACH; continue; } /* open the group member to be deleted and get its IOstatus*/ *status = fits_open_member(gfptr,member,&mfptr,status); *status = fits_file_mode(mfptr,&iomode,status); /* if the member HDU is to be deleted then call fits_unlink_member() to remove it from all groups to which it belongs (including this one) and then delete it. Note that if the member is a grouping table then we have to recursively call fits_remove_member() for each member of the member before we delete the member itself. */ if(rmopt == OPT_RM_MBR) { /* cannot delete a PHDU */ if(fits_get_hdu_num(mfptr,&hdutype) == 1) { *status = BAD_HDU_NUM; continue; } /* determine if the member HDU is itself a grouping table */ *status = fits_read_key_str(mfptr,"EXTNAME",keyvalue,card,status); /* if no EXTNAME is found then the HDU cannot be a grouping table */ if(*status == KEY_NO_EXIST) { keyvalue[0] = 0; *status = 0; } prepare_keyvalue(keyvalue); /* Any other error is a reason to abort */ if(*status != 0) continue; /* if the EXTNAME == GROUPING then the member is a grouping table */ if(strcasecmp(keyvalue,"GROUPING") == 0) { /* remove each of the grouping table members */ *status = fits_get_num_members(mfptr,&nmembers,status); for(i = nmembers; i > 0 && *status == 0; --i) *status = fits_remove_member(mfptr,i,OPT_RM_ENTRY,status); if(*status != 0) continue; } /* unlink the member HDU from all groups that contain it */ *status = ffgmul(mfptr,0,status); if(*status != 0) continue; /* reset the grouping table HDU struct */ fits_set_hdustruc(gfptr,status); /* delete the member HDU */ if(iomode != READONLY) *status = fits_delete_hdu(mfptr,&hdutype,status); } else if(rmopt == OPT_RM_ENTRY) { /* The member HDU is only to be removed as an entry from this grouping table. Actions are (1) find the GRPIDn/GRPLCn keywords that link the member to the grouping table, (2) remove the GRPIDn/GRPLCn keyword from the member HDU header and (3) remove the member entry from the grouping table */ /* there is no need to seach for and remove the GRPIDn/GRPLCn keywords from the member HDU if it has not been opened in READWRITE mode */ if(iomode == READWRITE) { /* determine the group EXTVER value of the grouping table; if the member HDU and grouping table HDU do not reside in the same file then set the groupExtver value to its negative */ *status = fits_read_key_lng(gfptr,"EXTVER",&groupExtver,card, status); if(mfptr->Fptr != gfptr->Fptr) groupExtver = -1*groupExtver; /* retrieve the URLs for the grouping table; note that it is possible that the grouping table file has two URLs, the one used to open it and the "real" one pointing to the actual file being accessed */ *status = fits_get_url(gfptr,grpLocation1,grpLocation2,NULL, NULL,NULL,status); if(*status != 0) continue; /* if either of the group location strings specify a relative file path then convert them into absolute file paths */ *status = fits_get_cwd(cwd,status); if(*grpLocation1 != 0 && *grpLocation1 != '/' && !fits_is_url_absolute(grpLocation1)) { strcpy(grpLocation3,cwd); strcat(grpLocation3,"/"); strcat(grpLocation3,grpLocation1); fits_clean_url(grpLocation3,grpLocation1,status); } if(*grpLocation2 != 0 && *grpLocation2 != '/' && !fits_is_url_absolute(grpLocation2)) { strcpy(grpLocation3,cwd); strcat(grpLocation3,"/"); strcat(grpLocation3,grpLocation2); fits_clean_url(grpLocation3,grpLocation2,status); } /* determine the number of groups to which the member HDU belongs */ *status = fits_get_num_groups(mfptr,&ngroups,status); /* reset the HDU keyword position counter to the beginning */ *status = ffgrec(mfptr,0,card,status); /* loop over all the GRPIDn keywords in the member HDU header and find the appropriate GRPIDn and GRPLCn keywords that identify it as belonging to the group */ for(index = 1, found = 0; index <= ngroups && *status == 0 && !found; ++index) { /* read the next GRPIDn keyword in the series */ sprintf(keyword,"GRPID%d",index); *status = fits_read_key_lng(mfptr,keyword,&grpid,card, status); if(*status != 0) continue; /* grpid value == group EXTVER value then we could have a match */ if(grpid == groupExtver && grpid > 0) { /* if GRPID is positive then its a match because both the member HDU and grouping table HDU reside in the same FITS file */ found = index; } else if(grpid == groupExtver && grpid < 0) { /* have to look at the GRPLCn value to determine a match because the member HDU and grouping table HDU reside in different FITS files */ sprintf(keyword,"GRPLC%d",index); /* SPR 1738 */ *status = fits_read_key_longstr(mfptr,keyword,&tgrplc, card, status); if (0 == *status) { strcpy(grplc,tgrplc); free(tgrplc); } if(*status == KEY_NO_EXIST) { /* no GRPLCn keyword value found ==> grouping convention not followed; nothing we can do about it, so just continue */ sprintf(card,"No GRPLC%d found for GRPID%d", index,index); ffpmsg(card); *status = 0; continue; } else if (*status != 0) continue; /* construct the URL for the GRPLCn value */ prepare_keyvalue(grplc); /* if the grplc value specifies a relative path then turn it into a absolute file path for comparison purposes */ if(*grplc != 0 && !fits_is_url_absolute(grplc) && *grplc != '/') { /* No, wrong, strcpy(grpLocation3,cwd); should be */ *status = fits_file_name(mfptr,grpLocation3,status); /* Remove everything after the last / */ if (NULL != (editLocation = strrchr(grpLocation3,'/'))) { *editLocation = '\0'; } strcat(grpLocation3,"/"); strcat(grpLocation3,grplc); *status = fits_clean_url(grpLocation3,grplc, status); } /* if the absolute value of GRPIDn is equal to the EXTVER value of the grouping table and (one of the possible two) grouping table file URL matches the GRPLCn keyword value then we hava a match */ if(strcmp(grplc,grpLocation1) == 0 || strcmp(grplc,grpLocation2) == 0) found = index; } } /* if found == 0 (false) after the above search then we assume that it is due to an inpromper updating of the GRPIDn and GRPLCn keywords in the member header ==> nothing to delete in the header. Else delete the GRPLCn and GRPIDn keywords that identify the member HDU with the group HDU and re-enumerate the remaining GRPIDn and GRPLCn keywords */ if(found != 0) { sprintf(keyword,"GRPID%d",found); *status = fits_delete_key(mfptr,keyword,status); sprintf(keyword,"GRPLC%d",found); *status = fits_delete_key(mfptr,keyword,status); *status = 0; /* call fits_get_num_groups() to re-enumerate the GRPIDn */ *status = fits_get_num_groups(mfptr,&ngroups,status); } } /* finally, remove the member entry from the current grouping table pointed to by gfptr */ *status = fits_delete_rows(gfptr,member,1,status); } else { *status = BAD_OPTION; ffpmsg("Invalid value specified for the rmopt parameter (ffgmrm)"); } }while(0); if(mfptr != NULL) { fits_close_file(mfptr,status); } return(*status); } /*--------------------------------------------------------------------------- Grouping Table support functions ---------------------------------------------------------------------------*/ int ffgtgc(fitsfile *gfptr, /* pointer to the grouping table */ int *xtensionCol, /* column ID of the MEMBER_XTENSION column */ int *extnameCol, /* column ID of the MEMBER_NAME column */ int *extverCol, /* column ID of the MEMBER_VERSION column */ int *positionCol, /* column ID of the MEMBER_POSITION column */ int *locationCol, /* column ID of the MEMBER_LOCATION column */ int *uriCol, /* column ID of the MEMBER_URI_TYPE column */ int *grptype, /* group structure type code specifying the grouping table columns that are defined: GT_ID_ALL_URI (0) ==> all columns defined GT_ID_REF (1) ==> reference cols only GT_ID_POS (2) ==> position col only GT_ID_ALL (3) ==> ref & pos cols GT_ID_REF_URI (11) ==> ref & loc cols GT_ID_POS_URI (12) ==> pos & loc cols */ int *status) /* return status code */ /* examine the grouping table pointed to by gfptr and determine the column index ID of each possible grouping column. If a column is not found then an index of 0 is returned. the grptype parameter returns the structure of the grouping table ==> what columns are defined. */ { char keyvalue[FLEN_VALUE]; char comment[FLEN_COMMENT]; if(*status != 0) return(*status); do { /* if the HDU does not have an extname of "GROUPING" then it is not a grouping table */ *status = fits_read_key_str(gfptr,"EXTNAME",keyvalue,comment,status); if(*status == KEY_NO_EXIST) { *status = NOT_GROUP_TABLE; ffpmsg("Specified HDU is not a Grouping Table (ffgtgc)"); } if(*status != 0) continue; prepare_keyvalue(keyvalue); if(strcasecmp(keyvalue,"GROUPING") != 0) { *status = NOT_GROUP_TABLE; continue; } /* search for the MEMBER_XTENSION, MEMBER_NAME, MEMBER_VERSION, MEMBER_POSITION, MEMBER_LOCATION and MEMBER_URI_TYPE columns and determine their column index ID */ *status = fits_get_colnum(gfptr,CASESEN,"MEMBER_XTENSION",xtensionCol, status); if(*status == COL_NOT_FOUND) { *status = 0; *xtensionCol = 0; } if(*status != 0) continue; *status = fits_get_colnum(gfptr,CASESEN,"MEMBER_NAME",extnameCol,status); if(*status == COL_NOT_FOUND) { *status = 0; *extnameCol = 0; } if(*status != 0) continue; *status = fits_get_colnum(gfptr,CASESEN,"MEMBER_VERSION",extverCol, status); if(*status == COL_NOT_FOUND) { *status = 0; *extverCol = 0; } if(*status != 0) continue; *status = fits_get_colnum(gfptr,CASESEN,"MEMBER_POSITION",positionCol, status); if(*status == COL_NOT_FOUND) { *status = 0; *positionCol = 0; } if(*status != 0) continue; *status = fits_get_colnum(gfptr,CASESEN,"MEMBER_LOCATION",locationCol, status); if(*status == COL_NOT_FOUND) { *status = 0; *locationCol = 0; } if(*status != 0) continue; *status = fits_get_colnum(gfptr,CASESEN,"MEMBER_URI_TYPE",uriCol, status); if(*status == COL_NOT_FOUND) { *status = 0; *uriCol = 0; } if(*status != 0) continue; /* determine the type of grouping table structure used by this grouping table and record it in the grptype parameter */ if(*xtensionCol && *extnameCol && *extverCol && *positionCol && *locationCol && *uriCol) *grptype = GT_ID_ALL_URI; else if(*xtensionCol && *extnameCol && *extverCol && *locationCol && *uriCol) *grptype = GT_ID_REF_URI; else if(*xtensionCol && *extnameCol && *extverCol && *positionCol) *grptype = GT_ID_ALL; else if(*xtensionCol && *extnameCol && *extverCol) *grptype = GT_ID_REF; else if(*positionCol && *locationCol && *uriCol) *grptype = GT_ID_POS_URI; else if(*positionCol) *grptype = GT_ID_POS; else *status = NOT_GROUP_TABLE; }while(0); /* if the table contained more than one column with a reserved name then this cannot be considered a vailid grouping table */ if(*status == COL_NOT_UNIQUE) { *status = NOT_GROUP_TABLE; ffpmsg("Specified HDU has multipule Group table cols defined (ffgtgc)"); } return(*status); } /*****************************************************************************/ int ffgtdc(int grouptype, /* code specifying the type of grouping table information: GT_ID_ALL_URI 0 ==> defualt (all columns) GT_ID_REF 1 ==> ID by reference GT_ID_POS 2 ==> ID by position GT_ID_ALL 3 ==> ID by ref. and position GT_ID_REF_URI 11 ==> (1) + URI info GT_ID_POS_URI 12 ==> (2) + URI info */ int xtensioncol, /* does MEMBER_XTENSION already exist? */ int extnamecol, /* does MEMBER_NAME aleady exist? */ int extvercol, /* does MEMBER_VERSION already exist? */ int positioncol, /* does MEMBER_POSITION already exist? */ int locationcol, /* does MEMBER_LOCATION already exist? */ int uricol, /* does MEMBER_URI_TYPE aleardy exist? */ char *ttype[], /* array of grouping table column TTYPE names to define (if *col var false) */ char *tform[], /* array of grouping table column TFORM values to define (if*col variable false) */ int *ncols, /* number of TTYPE and TFORM values returned */ int *status) /* return status code */ /* create the TTYPE and TFORM values for the grouping table according to the value of the grouptype parameter and the values of the *col flags. The resulting TTYPE and TFORM are returned in ttype[] and tform[] respectively. The number of TTYPE and TFORMs returned is given by ncols. Both the TTYPE[] and TTFORM[] arrays must contain enough pre-allocated strings to hold the returned information. */ { int i = 0; char xtension[] = "MEMBER_XTENSION"; char xtenTform[] = "8A"; char name[] = "MEMBER_NAME"; char nameTform[] = "32A"; char version[] = "MEMBER_VERSION"; char verTform[] = "1J"; char position[] = "MEMBER_POSITION"; char posTform[] = "1J"; char URI[] = "MEMBER_URI_TYPE"; char URITform[] = "3A"; char location[] = "MEMBER_LOCATION"; /* SPR 01720, move from 160A to 256A */ char locTform[] = "256A"; if(*status != 0) return(*status); switch(grouptype) { case GT_ID_ALL_URI: if(xtensioncol == 0) { strcpy(ttype[i],xtension); strcpy(tform[i],xtenTform); ++i; } if(extnamecol == 0) { strcpy(ttype[i],name); strcpy(tform[i],nameTform); ++i; } if(extvercol == 0) { strcpy(ttype[i],version); strcpy(tform[i],verTform); ++i; } if(positioncol == 0) { strcpy(ttype[i],position); strcpy(tform[i],posTform); ++i; } if(locationcol == 0) { strcpy(ttype[i],location); strcpy(tform[i],locTform); ++i; } if(uricol == 0) { strcpy(ttype[i],URI); strcpy(tform[i],URITform); ++i; } break; case GT_ID_REF: if(xtensioncol == 0) { strcpy(ttype[i],xtension); strcpy(tform[i],xtenTform); ++i; } if(extnamecol == 0) { strcpy(ttype[i],name); strcpy(tform[i],nameTform); ++i; } if(extvercol == 0) { strcpy(ttype[i],version); strcpy(tform[i],verTform); ++i; } break; case GT_ID_POS: if(positioncol == 0) { strcpy(ttype[i],position); strcpy(tform[i],posTform); ++i; } break; case GT_ID_ALL: if(xtensioncol == 0) { strcpy(ttype[i],xtension); strcpy(tform[i],xtenTform); ++i; } if(extnamecol == 0) { strcpy(ttype[i],name); strcpy(tform[i],nameTform); ++i; } if(extvercol == 0) { strcpy(ttype[i],version); strcpy(tform[i],verTform); ++i; } if(positioncol == 0) { strcpy(ttype[i],position); strcpy(tform[i], posTform); ++i; } break; case GT_ID_REF_URI: if(xtensioncol == 0) { strcpy(ttype[i],xtension); strcpy(tform[i],xtenTform); ++i; } if(extnamecol == 0) { strcpy(ttype[i],name); strcpy(tform[i],nameTform); ++i; } if(extvercol == 0) { strcpy(ttype[i],version); strcpy(tform[i],verTform); ++i; } if(locationcol == 0) { strcpy(ttype[i],location); strcpy(tform[i],locTform); ++i; } if(uricol == 0) { strcpy(ttype[i],URI); strcpy(tform[i],URITform); ++i; } break; case GT_ID_POS_URI: if(positioncol == 0) { strcpy(ttype[i],position); strcpy(tform[i],posTform); ++i; } if(locationcol == 0) { strcpy(ttype[i],location); strcpy(tform[i],locTform); ++i; } if(uricol == 0) { strcpy(ttype[i],URI); strcpy(tform[i],URITform); ++i; } break; default: *status = BAD_OPTION; ffpmsg("Invalid value specified for the grouptype parameter (ffgtdc)"); break; } *ncols = i; return(*status); } /*****************************************************************************/ int ffgmul(fitsfile *mfptr, /* pointer to the grouping table member HDU */ int rmopt, /* 0 ==> leave GRPIDn/GRPLCn keywords, 1 ==> remove GRPIDn/GRPLCn keywords */ int *status) /* return status code */ /* examine all the GRPIDn and GRPLCn keywords in the member HDUs header and remove the member from the grouping tables referenced; This effectively "unlinks" the member from all of its groups. The rmopt specifies if the GRPIDn/GRPLCn keywords are to be removed from the member HDUs header after the unlinking. */ { int memberPosition = 0; int iomode; long index = 0; long ngroups = 0; long memberExtver = 0; long memberID = 0; char mbrLocation1[FLEN_FILENAME]; char mbrLocation2[FLEN_FILENAME]; char memberHDUtype[FLEN_VALUE]; char memberExtname[FLEN_VALUE]; char keyword[FLEN_KEYWORD]; char card[FLEN_CARD]; fitsfile *gfptr = NULL; if(*status != 0) return(*status); do { /* determine location parameters of the member HDU; note that default values are supplied if the expected keywords are not found */ *status = fits_read_key_str(mfptr,"XTENSION",memberHDUtype,card,status); if(*status == KEY_NO_EXIST) { strcpy(memberHDUtype,"PRIMARY"); *status = 0; } prepare_keyvalue(memberHDUtype); *status = fits_read_key_lng(mfptr,"EXTVER",&memberExtver,card,status); if(*status == KEY_NO_EXIST) { memberExtver = 1; *status = 0; } *status = fits_read_key_str(mfptr,"EXTNAME",memberExtname,card,status); if(*status == KEY_NO_EXIST) { memberExtname[0] = 0; *status = 0; } prepare_keyvalue(memberExtname); fits_get_hdu_num(mfptr,&memberPosition); *status = fits_get_url(mfptr,mbrLocation1,mbrLocation2,NULL,NULL, NULL,status); if(*status != 0) continue; /* open each grouping table linked to this HDU and remove the member from the grouping tables */ *status = fits_get_num_groups(mfptr,&ngroups,status); /* loop over each group linked to the member HDU */ for(index = 1; index <= ngroups && *status == 0; ++index) { /* open the (index)th group linked to the member HDU */ *status = fits_open_group(mfptr,index,&gfptr,status); /* if the group could not be opened then just skip it */ if(*status != 0) { *status = 0; sprintf(card,"Cannot open the %dth group table (ffgmul)", (int)index); ffpmsg(card); continue; } /* make sure the grouping table can be modified before proceeding */ fits_file_mode(gfptr,&iomode,status); if(iomode != READWRITE) { sprintf(card,"The %dth group cannot be modified (ffgtam)", (int)index); ffpmsg(card); continue; } /* try to find the member's row within the grouping table; first try using the member HDU file's "real" URL string then try using its originally opened URL string if either string exist */ memberID = 0; if(strlen(mbrLocation1) != 0) { *status = ffgmf(gfptr,memberHDUtype,memberExtname,memberExtver, memberPosition,mbrLocation1,&memberID,status); } if(*status == MEMBER_NOT_FOUND && strlen(mbrLocation2) != 0) { *status = 0; *status = ffgmf(gfptr,memberHDUtype,memberExtname,memberExtver, memberPosition,mbrLocation2,&memberID,status); } /* if the member was found then delete it from the grouping table */ if(*status == 0) *status = fits_delete_rows(gfptr,memberID,1,status); /* continue the loop over all member groups even if an error was generated */ if(*status == MEMBER_NOT_FOUND) { ffpmsg("cannot locate member's entry in group table (ffgmul)"); } *status = 0; /* close the file pointed to by gfptr if it is non NULL to prepare for the next loop iterration */ if(gfptr != NULL) { fits_close_file(gfptr,status); gfptr = NULL; } } if(*status != 0) continue; /* if rmopt is non-zero then find and delete the GRPIDn/GRPLCn keywords from the member HDU header */ if(rmopt != 0) { fits_file_mode(mfptr,&iomode,status); if(iomode == READONLY) { ffpmsg("Cannot modify member HDU, opened READONLY (ffgmul)"); continue; } /* delete all the GRPIDn/GRPLCn keywords */ for(index = 1; index <= ngroups && *status == 0; ++index) { sprintf(keyword,"GRPID%d",(int)index); fits_delete_key(mfptr,keyword,status); sprintf(keyword,"GRPLC%d",(int)index); fits_delete_key(mfptr,keyword,status); if(*status == KEY_NO_EXIST) *status = 0; } } }while(0); /* make sure the gfptr has been closed */ if(gfptr != NULL) { fits_close_file(gfptr,status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgmf(fitsfile *gfptr, /* pointer to grouping table HDU to search */ char *xtension, /* XTENSION value for member HDU */ char *extname, /* EXTNAME value for member HDU */ int extver, /* EXTVER value for member HDU */ int position, /* HDU position value for member HDU */ char *location, /* FITS file location value for member HDU */ long *member, /* member HDU ID within group table (if found) */ int *status) /* return status code */ /* try to find the entry for the member HDU defined by the xtension, extname, extver, position, and location parameters within the grouping table pointed to by gfptr. If the member HDU is found then its ID (row number) within the grouping table is returned in the member variable; if not found then member is returned with a value of 0 and the status return code will be set to MEMBER_NOT_FOUND. Note that the member HDU postion information is used to obtain a member match only if the grouping table type is GT_ID_POS_URI or GT_ID_POS. This is because the position information can become invalid much more easily then the reference information for a group member. */ { int xtensionCol,extnameCol,extverCol,positionCol,locationCol,uriCol; int mposition = 0; int grptype; int dummy; int i; long nmembers = 0; long mextver = 0; char charBuff1[FLEN_FILENAME]; char charBuff2[FLEN_FILENAME]; char tmpLocation[FLEN_FILENAME]; char mbrLocation1[FLEN_FILENAME]; char mbrLocation2[FLEN_FILENAME]; char mbrLocation3[FLEN_FILENAME]; char grpLocation1[FLEN_FILENAME]; char grpLocation2[FLEN_FILENAME]; char cwd[FLEN_FILENAME]; char nstr[] = {'\0'}; char *tmpPtr[2]; if(*status != 0) return(*status); *member = 0; tmpPtr[0] = charBuff1; tmpPtr[1] = charBuff2; if(*status != 0) return(*status); /* if the passed LOCATION value is not an absolute URL then turn it into an absolute path */ if(location == NULL) { *tmpLocation = 0; } else if(*location == 0) { *tmpLocation = 0; } else if(!fits_is_url_absolute(location)) { fits_path2url(location,tmpLocation,status); if(*tmpLocation != '/') { fits_get_cwd(cwd,status); strcat(cwd,"/"); strcat(cwd,tmpLocation); fits_clean_url(cwd,tmpLocation,status); } } else strcpy(tmpLocation,location); /* retrieve the Grouping Convention reserved column positions within the grouping table */ *status = ffgtgc(gfptr,&xtensionCol,&extnameCol,&extverCol,&positionCol, &locationCol,&uriCol,&grptype,status); /* retrieve the number of group members */ *status = fits_get_num_members(gfptr,&nmembers,status); /* loop over all grouping table rows until the member HDU is found */ for(i = 1; i <= nmembers && *member == 0 && *status == 0; ++i) { if(xtensionCol != 0) { fits_read_col_str(gfptr,xtensionCol,i,1,1,nstr,tmpPtr,&dummy,status); if(strcasecmp(tmpPtr[0],xtension) != 0) continue; } if(extnameCol != 0) { fits_read_col_str(gfptr,extnameCol,i,1,1,nstr,tmpPtr,&dummy,status); if(strcasecmp(tmpPtr[0],extname) != 0) continue; } if(extverCol != 0) { fits_read_col_lng(gfptr,extverCol,i,1,1,0, (long*)&mextver,&dummy,status); if(extver != mextver) continue; } /* note we only use postionCol if we have to */ if(positionCol != 0 && (grptype == GT_ID_POS || grptype == GT_ID_POS_URI)) { fits_read_col_int(gfptr,positionCol,i,1,1,0, &mposition,&dummy,status); if(position != mposition) continue; } /* if no location string was passed to the function then assume that the calling application does not wish to use it as a comparision critera ==> if we got this far then we have a match */ if(location == NULL) { ffpmsg("NULL Location string given ==> ingore location (ffgmf)"); *member = i; continue; } /* if the grouping table MEMBER_LOCATION column exists then read the location URL for the member, else set the location string to a zero-length string for subsequent comparisions */ if(locationCol != 0) { fits_read_col_str(gfptr,locationCol,i,1,1,nstr,tmpPtr,&dummy,status); strcpy(mbrLocation1,tmpPtr[0]); *mbrLocation2 = 0; } else *mbrLocation1 = 0; /* if the member location string from the grouping table is zero length (either implicitly or explicitly) then assume that the member HDU is in the same file as the grouping table HDU; retrieve the possible URL values of the grouping table HDU file */ if(*mbrLocation1 == 0) { /* retrieve the possible URLs of the grouping table file */ *status = fits_get_url(gfptr,mbrLocation1,mbrLocation2,NULL,NULL, NULL,status); /* if non-NULL, make sure the first URL is absolute or a full path */ if(*mbrLocation1 != 0 && !fits_is_url_absolute(mbrLocation1) && *mbrLocation1 != '/') { fits_get_cwd(cwd,status); strcat(cwd,"/"); strcat(cwd,mbrLocation1); fits_clean_url(cwd,mbrLocation1,status); } /* if non-NULL, make sure the first URL is absolute or a full path */ if(*mbrLocation2 != 0 && !fits_is_url_absolute(mbrLocation2) && *mbrLocation2 != '/') { fits_get_cwd(cwd,status); strcat(cwd,"/"); strcat(cwd,mbrLocation2); fits_clean_url(cwd,mbrLocation2,status); } } /* if the member location was specified, then make sure that it is either an absolute URL or specifies a full path */ else if(!fits_is_url_absolute(mbrLocation1) && *mbrLocation1 != '/') { strcpy(mbrLocation2,mbrLocation1); /* get the possible URLs for the grouping table file */ *status = fits_get_url(gfptr,grpLocation1,grpLocation2,NULL,NULL, NULL,status); if(*grpLocation1 != 0) { /* make sure the first grouping table URL is absolute */ if(!fits_is_url_absolute(grpLocation1) && *grpLocation1 != '/') { fits_get_cwd(cwd,status); strcat(cwd,"/"); strcat(cwd,grpLocation1); fits_clean_url(cwd,grpLocation1,status); } /* create an absoute URL for the member */ fits_relurl2url(grpLocation1,mbrLocation1,mbrLocation3,status); /* if URL construction succeeded then copy it to the first location string; else set the location string to empty */ if(*status == 0) { strcpy(mbrLocation1,mbrLocation3); } else if(*status == URL_PARSE_ERROR) { *status = 0; *mbrLocation1 = 0; } } else *mbrLocation1 = 0; if(*grpLocation2 != 0) { /* make sure the second grouping table URL is absolute */ if(!fits_is_url_absolute(grpLocation2) && *grpLocation2 != '/') { fits_get_cwd(cwd,status); strcat(cwd,"/"); strcat(cwd,grpLocation2); fits_clean_url(cwd,grpLocation2,status); } /* create an absolute URL for the member */ fits_relurl2url(grpLocation2,mbrLocation2,mbrLocation3,status); /* if URL construction succeeded then copy it to the second location string; else set the location string to empty */ if(*status == 0) { strcpy(mbrLocation2,mbrLocation3); } else if(*status == URL_PARSE_ERROR) { *status = 0; *mbrLocation2 = 0; } } else *mbrLocation2 = 0; } /* compare the passed member HDU file location string with the (possibly two) member location strings to see if there is a match */ if(strcmp(mbrLocation1,tmpLocation) != 0 && strcmp(mbrLocation2,tmpLocation) != 0 ) continue; /* if we made it this far then a match to the member HDU was found */ *member = i; } /* if a match was not found then set the return status code */ if(*member == 0 && *status == 0) { *status = MEMBER_NOT_FOUND; ffpmsg("Cannot find specified member HDU (ffgmf)"); } return(*status); } /*-------------------------------------------------------------------------- Recursive Group Functions --------------------------------------------------------------------------*/ int ffgtrmr(fitsfile *gfptr, /* FITS file pointer to group */ HDUtracker *HDU, /* list of processed HDUs */ int *status) /* return status code */ /* recursively remove a grouping table and all its members. Each member of the grouping table pointed to by gfptr it processed. If the member is itself a grouping table then ffgtrmr() is recursively called to process all of its members. The HDUtracker struct *HDU is used to make sure a member is not processed twice, thus avoiding an infinite loop (e.g., a grouping table contains itself as a member). */ { int i; int hdutype; long nmembers = 0; char keyvalue[FLEN_VALUE]; char comment[FLEN_COMMENT]; fitsfile *mfptr = NULL; if(*status != 0) return(*status); /* get the number of members contained by this grouping table */ *status = fits_get_num_members(gfptr,&nmembers,status); /* loop over all group members and delete them */ for(i = nmembers; i > 0 && *status == 0; --i) { /* open the member HDU */ *status = fits_open_member(gfptr,i,&mfptr,status); /* if the member cannot be opened then just skip it and continue */ if(*status == MEMBER_NOT_FOUND) { *status = 0; continue; } /* Any other error is a reason to abort */ if(*status != 0) continue; /* add the member HDU to the HDUtracker struct */ *status = fftsad(mfptr,HDU,NULL,NULL); /* status == HDU_ALREADY_TRACKED ==> HDU has already been processed */ if(*status == HDU_ALREADY_TRACKED) { *status = 0; fits_close_file(mfptr,status); continue; } else if(*status != 0) continue; /* determine if the member HDU is itself a grouping table */ *status = fits_read_key_str(mfptr,"EXTNAME",keyvalue,comment,status); /* if no EXTNAME is found then the HDU cannot be a grouping table */ if(*status == KEY_NO_EXIST) { *status = 0; keyvalue[0] = 0; } prepare_keyvalue(keyvalue); /* Any other error is a reason to abort */ if(*status != 0) continue; /* if the EXTNAME == GROUPING then the member is a grouping table and we must call ffgtrmr() to process its members */ if(strcasecmp(keyvalue,"GROUPING") == 0) *status = ffgtrmr(mfptr,HDU,status); /* unlink all the grouping tables that contain this HDU as a member and then delete the HDU (if not a PHDU) */ if(fits_get_hdu_num(mfptr,&hdutype) == 1) *status = ffgmul(mfptr,1,status); else { *status = ffgmul(mfptr,0,status); *status = fits_delete_hdu(mfptr,&hdutype,status); } /* close the fitsfile pointer */ fits_close_file(mfptr,status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgtcpr(fitsfile *infptr, /* input FITS file pointer */ fitsfile *outfptr, /* output FITS file pointer */ int cpopt, /* code specifying copy options: OPT_GCP_GPT (0) ==> cp only grouping table OPT_GCP_ALL (2) ==> recusrively copy members and their members (if groups) */ HDUtracker *HDU, /* list of already copied HDUs */ int *status) /* return status code */ /* copy a Group to a new FITS file. If the cpopt parameter is set to OPT_GCP_GPT (copy grouping table only) then the existing members have their GRPIDn and GRPLCn keywords updated to reflect the existance of the new group, since they now belong to another group. If cpopt is set to OPT_GCP_ALL (copy grouping table and members recursively) then the original members are not updated; the new grouping table is modified to include only the copied member HDUs and not the original members. Note that this function is recursive. When copt is OPT_GCP_ALL it will call itself whenever a member HDU of the current grouping table is itself a grouping table (i.e., EXTNAME = 'GROUPING'). */ { int i; int nexclude = 8; int hdutype = 0; int groupHDUnum = 0; int numkeys = 0; int keypos = 0; int startSearch = 0; int newPosition = 0; long nmembers = 0; long tfields = 0; long newTfields = 0; char keyword[FLEN_KEYWORD]; char keyvalue[FLEN_VALUE]; char card[FLEN_CARD]; char comment[FLEN_CARD]; char *tkeyvalue; char *includeList[] = {"*"}; char *excludeList[] = {"EXTNAME","EXTVER","GRPNAME","GRPID#","GRPLC#", "THEAP","TDIM#","T????#"}; fitsfile *mfptr = NULL; if(*status != 0) return(*status); do { /* create a new grouping table in the FITS file pointed to by outptr */ *status = fits_get_num_members(infptr,&nmembers,status); *status = fits_read_key_str(infptr,"GRPNAME",keyvalue,card,status); if(*status == KEY_NO_EXIST) { keyvalue[0] = 0; *status = 0; } prepare_keyvalue(keyvalue); *status = fits_create_group(outfptr,keyvalue,GT_ID_ALL_URI,status); /* save the new grouping table's HDU position for future use */ fits_get_hdu_num(outfptr,&groupHDUnum); /* update the HDUtracker struct with the grouping table's new position */ *status = fftsud(infptr,HDU,groupHDUnum,NULL); /* Now populate the copied grouping table depending upon the copy option parameter value */ switch(cpopt) { /* for the "copy grouping table only" option we only have to add the members of the original grouping table to the new grouping table */ case OPT_GCP_GPT: for(i = 1; i <= nmembers && *status == 0; ++i) { *status = fits_open_member(infptr,i,&mfptr,status); *status = fits_add_group_member(outfptr,mfptr,0,status); fits_close_file(mfptr,status); mfptr = NULL; } break; case OPT_GCP_ALL: /* for the "copy the entire group" option */ /* loop over all the grouping table members */ for(i = 1; i <= nmembers && *status == 0; ++i) { /* open the ith member */ *status = fits_open_member(infptr,i,&mfptr,status); if(*status != 0) continue; /* add it to the HDUtracker struct */ *status = fftsad(mfptr,HDU,&newPosition,NULL); /* if already copied then just add the member to the group */ if(*status == HDU_ALREADY_TRACKED) { *status = 0; *status = fits_add_group_member(outfptr,NULL,newPosition, status); fits_close_file(mfptr,status); mfptr = NULL; continue; } else if(*status != 0) continue; /* see if the member is a grouping table */ *status = fits_read_key_str(mfptr,"EXTNAME",keyvalue,card, status); if(*status == KEY_NO_EXIST) { keyvalue[0] = 0; *status = 0; } prepare_keyvalue(keyvalue); /* if the member is a grouping table then copy it and all of its members using ffgtcpr(), else copy it using fits_copy_member(); the outptr will point to the newly copied member upon return from both functions */ if(strcasecmp(keyvalue,"GROUPING") == 0) *status = ffgtcpr(mfptr,outfptr,OPT_GCP_ALL,HDU,status); else *status = fits_copy_member(infptr,outfptr,i,OPT_MCP_NADD, status); /* retrieve the position of the newly copied member */ fits_get_hdu_num(outfptr,&newPosition); /* update the HDUtracker struct with member's new position */ if(strcasecmp(keyvalue,"GROUPING") != 0) *status = fftsud(mfptr,HDU,newPosition,NULL); /* move the outfptr back to the copied grouping table HDU */ *status = fits_movabs_hdu(outfptr,groupHDUnum,&hdutype,status); /* add the copied member HDU to the copied grouping table */ *status = fits_add_group_member(outfptr,NULL,newPosition,status); /* close the mfptr pointer */ fits_close_file(mfptr,status); mfptr = NULL; } break; default: *status = BAD_OPTION; ffpmsg("Invalid value specified for cmopt parameter (ffgtcpr)"); break; } if(*status != 0) continue; /* reposition the outfptr to the grouping table so that the grouping table is the CHDU upon return to the calling function */ fits_movabs_hdu(outfptr,groupHDUnum,&hdutype,status); /* copy all auxiliary keyword records from the original grouping table to the new grouping table; they are copied in their original order and inserted just before the TTYPE1 keyword record */ *status = fits_read_card(outfptr,"TTYPE1",card,status); *status = fits_get_hdrpos(outfptr,&numkeys,&keypos,status); --keypos; startSearch = 8; while(*status == 0) { ffgrec(infptr,startSearch,card,status); *status = fits_find_nextkey(infptr,includeList,1,excludeList, nexclude,card,status); *status = fits_get_hdrpos(infptr,&numkeys,&startSearch,status); --startSearch; /* SPR 1738 */ if (strncmp(card,"GRPLC",5)) { /* Not going to be a long string so we're ok */ *status = fits_insert_record(outfptr,keypos,card,status); } else { /* We could have a long string */ *status = fits_read_record(infptr,startSearch,card,status); card[9] = '\0'; *status = fits_read_key_longstr(infptr,card,&tkeyvalue,comment, status); if (0 == *status) { fits_insert_key_longstr(outfptr,card,tkeyvalue,comment,status); fits_write_key_longwarn(outfptr,status); free(tkeyvalue); } } ++keypos; } if(*status == KEY_NO_EXIST) *status = 0; else if(*status != 0) continue; /* search all the columns of the original grouping table and copy those to the new grouping table that were not part of the grouping convention. Note that is legal to have additional columns in a grouping table. Also note that the order of the columns may not be the same in the original and copied grouping table. */ /* retrieve the number of columns in the original and new group tables */ *status = fits_read_key_lng(infptr,"TFIELDS",&tfields,card,status); *status = fits_read_key_lng(outfptr,"TFIELDS",&newTfields,card,status); for(i = 1; i <= tfields; ++i) { sprintf(keyword,"TTYPE%d",i); *status = fits_read_key_str(infptr,keyword,keyvalue,card,status); if(*status == KEY_NO_EXIST) { *status = 0; keyvalue[0] = 0; } prepare_keyvalue(keyvalue); if(strcasecmp(keyvalue,"MEMBER_XTENSION") != 0 && strcasecmp(keyvalue,"MEMBER_NAME") != 0 && strcasecmp(keyvalue,"MEMBER_VERSION") != 0 && strcasecmp(keyvalue,"MEMBER_POSITION") != 0 && strcasecmp(keyvalue,"MEMBER_LOCATION") != 0 && strcasecmp(keyvalue,"MEMBER_URI_TYPE") != 0 ) { /* SPR 3956, add at the end of the table */ *status = fits_copy_col(infptr,outfptr,i,newTfields+1,1,status); ++newTfields; } } }while(0); if(mfptr != NULL) { fits_close_file(mfptr,status); } return(*status); } /*-------------------------------------------------------------------------- HDUtracker struct manipulation functions --------------------------------------------------------------------------*/ int fftsad(fitsfile *mfptr, /* pointer to an member HDU */ HDUtracker *HDU, /* pointer to an HDU tracker struct */ int *newPosition, /* new HDU position of the member HDU */ char *newFileName) /* file containing member HDU */ /* add an HDU to the HDUtracker struct pointed to by HDU. The HDU is only added if it does not already reside in the HDUtracker. If it already resides in the HDUtracker then the new HDU postion and file name are returned in newPosition and newFileName (if != NULL) */ { int i; int hdunum; int status = 0; char filename1[FLEN_FILENAME]; char filename2[FLEN_FILENAME]; do { /* retrieve the HDU's position within the FITS file */ fits_get_hdu_num(mfptr,&hdunum); /* retrieve the HDU's file name */ status = fits_file_name(mfptr,filename1,&status); /* parse the file name and construct the "standard" URL for it */ status = ffrtnm(filename1,filename2,&status); /* examine all the existing HDUs in the HDUtracker an see if this HDU has already been registered */ for(i = 0; i < HDU->nHDU && !(HDU->position[i] == hdunum && strcmp(HDU->filename[i],filename2) == 0); ++i); if(i != HDU->nHDU) { status = HDU_ALREADY_TRACKED; if(newPosition != NULL) *newPosition = HDU->newPosition[i]; if(newFileName != NULL) strcpy(newFileName,HDU->newFilename[i]); continue; } if(HDU->nHDU == MAX_HDU_TRACKER) { status = TOO_MANY_HDUS_TRACKED; continue; } HDU->filename[i] = (char*) malloc(FLEN_FILENAME * sizeof(char)); if(HDU->filename[i] == NULL) { status = MEMORY_ALLOCATION; continue; } HDU->newFilename[i] = (char*) malloc(FLEN_FILENAME * sizeof(char)); if(HDU->newFilename[i] == NULL) { status = MEMORY_ALLOCATION; free(HDU->filename[i]); continue; } HDU->position[i] = hdunum; HDU->newPosition[i] = hdunum; strcpy(HDU->filename[i],filename2); strcpy(HDU->newFilename[i],filename2); ++(HDU->nHDU); }while(0); return(status); } /*--------------------------------------------------------------------------*/ int fftsud(fitsfile *mfptr, /* pointer to an member HDU */ HDUtracker *HDU, /* pointer to an HDU tracker struct */ int newPosition, /* new HDU position of the member HDU */ char *newFileName) /* file containing member HDU */ /* update the HDU information in the HDUtracker struct pointed to by HDU. The HDU to update is pointed to by mfptr. If non-zero, the value of newPosition is used to update the HDU->newPosition[] value for the mfptr, and if non-NULL the newFileName value is used to update the HDU->newFilename[] value for mfptr. */ { int i; int hdunum; int status = 0; char filename1[FLEN_FILENAME]; char filename2[FLEN_FILENAME]; /* retrieve the HDU's position within the FITS file */ fits_get_hdu_num(mfptr,&hdunum); /* retrieve the HDU's file name */ status = fits_file_name(mfptr,filename1,&status); /* parse the file name and construct the "standard" URL for it */ status = ffrtnm(filename1,filename2,&status); /* examine all the existing HDUs in the HDUtracker an see if this HDU has already been registered */ for(i = 0; i < HDU->nHDU && !(HDU->position[i] == hdunum && strcmp(HDU->filename[i],filename2) == 0); ++i); /* if previously registered then change newPosition and newFileName */ if(i != HDU->nHDU) { if(newPosition != 0) HDU->newPosition[i] = newPosition; if(newFileName != NULL) { strcpy(HDU->newFilename[i],newFileName); } } else status = MEMBER_NOT_FOUND; return(status); } /*---------------------------------------------------------------------------*/ void prepare_keyvalue(char *keyvalue) /* string containing keyword value */ /* strip off all single quote characters "'" and blank spaces from a keyword value retrieved via fits_read_key*() routines this is necessary so that a standard comparision of keyword values may be made */ { int i; int length; /* strip off any leading or trailing single quotes (`) and (') from the keyword value */ length = strlen(keyvalue) - 1; if(keyvalue[0] == '\'' && keyvalue[length] == '\'') { for(i = 0; i < length - 1; ++i) keyvalue[i] = keyvalue[i+1]; keyvalue[length-1] = 0; } /* strip off any trailing blanks from the keyword value; note that if the keyvalue consists of nothing but blanks then no blanks are stripped */ length = strlen(keyvalue) - 1; for(i = 0; i < length && keyvalue[i] == ' '; ++i); if(i != length) { for(i = length; i >= 0 && keyvalue[i] == ' '; --i) keyvalue[i] = '\0'; } } /*--------------------------------------------------------------------------- Host dependent directory path to/from URL functions --------------------------------------------------------------------------*/ int fits_path2url(char *inpath, /* input file path string */ char *outpath, /* output file path string */ int *status) /* convert a file path into its Unix-style equivelent for URL purposes. Note that this process is platform dependent. This function supports Unix, MSDOS/WIN32, VMS and Macintosh platforms. The plaform dependant code is conditionally compiled depending upon the setting of the appropriate C preprocessor macros. */ { char buff[FLEN_FILENAME]; #if defined(WINNT) || defined(__WINNT__) /* Microsoft Windows NT case. We assume input file paths of the form: //disk/path/filename All path segments may be null, so that a single file name is the simplist case. The leading "//" becomes a single "/" if present. If no "//" is present, then make sure the resulting URL path is relative, i.e., does not begin with a "/". In other words, the only way that an absolute URL file path may be generated is if the drive specification is given. */ if(*status > 0) return(*status); if(inpath[0] == '/') { strcpy(buff,inpath+1); } else { strcpy(buff,inpath); } #elif defined(MSDOS) || defined(__WIN32__) || defined(WIN32) /* MSDOS or Microsoft windows/NT case. The assumed form of the input path is: disk:\path\filename All path segments may be null, so that a single file name is the simplist case. All back-slashes '\' become slashes '/'; if the path starts with a string of the form "X:" then it is replaced with "/X/" */ int i,j,k; int size; if(*status > 0) return(*status); for(i = 0, j = 0, size = strlen(inpath), buff[0] = 0; i < size; j = strlen(buff)) { switch(inpath[i]) { case ':': /* must be a disk desiginator; add a slash '/' at the start of outpath to designate that the path is absolute, then change the colon ':' to a slash '/' */ for(k = j; k >= 0; --k) buff[k+1] = buff[k]; buff[0] = '/'; strcat(buff,"/"); ++i; break; case '\\': /* just replace the '\' with a '/' IF its not the first character */ if(i != 0 && buff[(j == 0 ? 0 : j-1)] != '/') { buff[j] = '/'; buff[j+1] = 0; } ++i; break; default: /* copy the character from inpath to buff as is */ buff[j] = inpath[i]; buff[j+1] = 0; ++i; break; } } #elif defined(VMS) || defined(vms) || defined(__vms) /* VMS case. Assumed format of the input path is: node::disk:[path]filename.ext;version Any part of the file path may be missing, so that in the simplist case a single file name/extension is given. all brackets "[", "]" and dots "." become "/"; dashes "-" become "..", all single colons ":" become ":/", all double colons "::" become "FILE://" */ int i,j,k; int done; int size; if(*status > 0) return(*status); /* see if inpath contains a directory specification */ if(strchr(inpath,']') == NULL) done = 1; else done = 0; for(i = 0, j = 0, size = strlen(inpath), buff[0] = 0; i < size && j < FLEN_FILENAME - 8; j = strlen(buff)) { switch(inpath[i]) { case ':': /* must be a logical/symbol separator or (in the case of a double colon "::") machine node separator */ if(inpath[i+1] == ':') { /* insert a "FILE://" at the start of buff ==> machine given */ for(k = j; k >= 0; --k) buff[k+7] = buff[k]; strncpy(buff,"FILE://",7); i += 2; } else if(strstr(buff,"FILE://") == NULL) { /* insert a "/" at the start of buff ==> absolute path */ for(k = j; k >= 0; --k) buff[k+1] = buff[k]; buff[0] = '/'; ++i; } else ++i; /* a colon always ==> path separator */ strcat(buff,"/"); break; case ']': /* end of directory spec, file name spec begins after this */ done = 1; buff[j] = '/'; buff[j+1] = 0; ++i; break; case '[': /* begin directory specification; add a '/' only if the last char is not '/' */ if(i != 0 && buff[(j == 0 ? 0 : j-1)] != '/') { buff[j] = '/'; buff[j+1] = 0; } ++i; break; case '.': /* directory segment separator or file name/extension separator; we decide which by looking at the value of done */ if(!done) { /* must be a directory segment separator */ if(inpath[i-1] == '[') { strcat(buff,"./"); ++j; } else buff[j] = '/'; } else /* must be a filename/extension separator */ buff[j] = '.'; buff[j+1] = 0; ++i; break; case '-': /* a dash is the same as ".." in Unix speak, but lets make sure that its not part of the file name first! */ if(!done) /* must be part of the directory path specification */ strcat(buff,".."); else { /* the dash is part of the filename, so just copy it as is */ buff[j] = '-'; buff[j+1] = 0; } ++i; break; default: /* nothing special, just copy the character as is */ buff[j] = inpath[i]; buff[j+1] = 0; ++i; break; } } if(j > FLEN_FILENAME - 8) { *status = URL_PARSE_ERROR; ffpmsg("resulting path to URL conversion too big (fits_path2url)"); } #elif defined(macintosh) /* MacOS case. The assumed form of the input path is: disk:path:filename It is assumed that all paths are absolute with disk and path specified, unless no colons ":" are supplied with the string ==> a single file name only. All colons ":" become slashes "/", and if one or more colon is encountered then the path is specified as absolute. */ int i,j,k; int firstColon; int size; if(*status > 0) return(*status); for(i = 0, j = 0, firstColon = 1, size = strlen(inpath), buff[0] = 0; i < size; j = strlen(buff)) { switch(inpath[i]) { case ':': /* colons imply path separators. If its the first colon encountered then assume that its the disk designator and add a slash to the beginning of the buff string */ if(firstColon) { firstColon = 0; for(k = j; k >= 0; --k) buff[k+1] = buff[k]; buff[0] = '/'; } /* all colons become slashes */ strcat(buff,"/"); ++i; break; default: /* copy the character from inpath to buff as is */ buff[j] = inpath[i]; buff[j+1] = 0; ++i; break; } } #else /* Default Unix case. Nothing special to do here except to remove the double or more // and replace them with single / */ int ii = 0; int jj = 0; if(*status > 0) return(*status); while (inpath[ii]) { if (inpath[ii] == '/' && inpath[ii+1] == '/') { /* do nothing */ } else { buff[jj] = inpath[ii]; jj++; } ii++; } buff[jj] = '\0'; /* printf("buff is %s\ninpath is %s\n",buff,inpath); */ /* strcpy(buff,inpath); */ #endif /* encode all "unsafe" and "reserved" URL characters */ *status = fits_encode_url(buff,outpath,status); return(*status); } /*---------------------------------------------------------------------------*/ int fits_url2path(char *inpath, /* input file path string */ char *outpath, /* output file path string */ int *status) /* convert a Unix-style URL into a platform dependent directory path. Note that this process is platform dependent. This function supports Unix, MSDOS/WIN32, VMS and Macintosh platforms. Each platform dependent code segment is conditionally compiled depending upon the setting of the appropriate C preprocesser macros. */ { char buff[FLEN_FILENAME]; int absolute; #if defined(MSDOS) || defined(__WIN32__) || defined(WIN32) char *tmpStr; #elif defined(VMS) || defined(vms) || defined(__vms) int i; char *tmpStr; #elif defined(macintosh) char *tmpStr; #endif if(*status != 0) return(*status); /* make a copy of the inpath so that we can manipulate it */ strcpy(buff,inpath); /* convert any encoded characters to their unencoded values */ *status = fits_unencode_url(inpath,buff,status); /* see if the URL is given as absolute w.r.t. the "local" file system */ if(buff[0] == '/') absolute = 1; else absolute = 0; #if defined(WINNT) || defined(__WINNT__) /* Microsoft Windows NT case. We create output paths of the form //disk/path/filename All path segments but the last may be null, so that a single file name is the simplist case. */ if(absolute) { strcpy(outpath,"/"); strcat(outpath,buff); } else { strcpy(outpath,buff); } #elif defined(MSDOS) || defined(__WIN32__) || defined(WIN32) /* MSDOS or Microsoft windows/NT case. The output path will be of the form disk:\path\filename All path segments but the last may be null, so that a single file name is the simplist case. */ /* separate the URL into tokens at each slash '/' and process until all tokens have been examined */ for(tmpStr = strtok(buff,"/"), outpath[0] = 0; tmpStr != NULL; tmpStr = strtok(NULL,"/")) { strcat(outpath,tmpStr); /* if the absolute flag is set then process the token as a disk specification; else just process it as a directory path or filename */ if(absolute) { strcat(outpath,":\\"); absolute = 0; } else strcat(outpath,"\\"); } /* remove the last "\" from the outpath, it does not belong there */ outpath[strlen(outpath)-1] = 0; #elif defined(VMS) || defined(vms) || defined(__vms) /* VMS case. The output path will be of the form: node::disk:[path]filename.ext;version Any part of the file path may be missing execpt filename.ext, so that in the simplist case a single file name/extension is given. if the path is specified as relative starting with "./" then the first part of the VMS path is "[.". If the path is relative and does not start with "./" (e.g., "a/b/c") then the VMS path is constructed as "[a.b.c]" */ /* separate the URL into tokens at each slash '/' and process until all tokens have been examined */ for(tmpStr = strtok(buff,"/"), outpath[0] = 0; tmpStr != NULL; tmpStr = strtok(NULL,"/")) { if(strcasecmp(tmpStr,"FILE:") == 0) { /* the next token should contain the DECnet machine name */ tmpStr = strtok(NULL,"/"); if(tmpStr == NULL) continue; strcat(outpath,tmpStr); strcat(outpath,"::"); /* set the absolute flag to true for the next token */ absolute = 1; } else if(strcmp(tmpStr,"..") == 0) { /* replace all Unix-like ".." with VMS "-" */ if(strlen(outpath) == 0) strcat(outpath,"["); strcat(outpath,"-."); } else if(strcmp(tmpStr,".") == 0 && strlen(outpath) == 0) { /* must indicate a relative path specifier */ strcat(outpath,"[."); } else if(strchr(tmpStr,'.') != NULL) { /* must be up to the file name; turn the last "." path separator into a "]" and then add the file name to the outpath */ i = strlen(outpath); if(i > 0 && outpath[i-1] == '.') outpath[i-1] = ']'; strcat(outpath,tmpStr); } else { /* process the token as a a directory path segement */ if(absolute) { /* treat the token as a disk specifier */ absolute = 0; strcat(outpath,tmpStr); strcat(outpath,":["); } else if(strlen(outpath) == 0) { /* treat the token as the first directory path specifier */ strcat(outpath,"["); strcat(outpath,tmpStr); strcat(outpath,"."); } else { /* treat the token as an imtermediate path specifier */ strcat(outpath,tmpStr); strcat(outpath,"."); } } } #elif defined(macintosh) /* MacOS case. The output path will be of the form disk:path:filename All path segments but the last may be null, so that a single file name is the simplist case. */ /* separate the URL into tokens at each slash '/' and process until all tokens have been examined */ for(tmpStr = strtok(buff,"/"), outpath[0] = 0; tmpStr != NULL; tmpStr = strtok(NULL,"/")) { strcat(outpath,tmpStr); strcat(outpath,":"); } /* remove the last ":" from the outpath, it does not belong there */ outpath[strlen(outpath)-1] = 0; #else /* Default Unix case. Nothing special to do here */ strcpy(outpath,buff); #endif return(*status); } /****************************************************************************/ int fits_get_cwd(char *cwd, /* IO current working directory string */ int *status) /* retrieve the string containing the current working directory absolute path in Unix-like URL standard notation. It is assumed that the CWD string has a size of at least FLEN_FILENAME. Note that this process is platform dependent. This function supports Unix, MSDOS/WIN32, VMS and Macintosh platforms. Each platform dependent code segment is conditionally compiled depending upon the setting of the appropriate C preprocesser macros. */ { char buff[FLEN_FILENAME]; if(*status != 0) return(*status); #if defined(macintosh) /* MacOS case. Currently unknown !!!! */ *buff = 0; #else /* Good old getcwd() seems to work with all other platforms */ getcwd(buff,FLEN_FILENAME); #endif /* convert the cwd string to a URL standard path string */ fits_path2url(buff,cwd,status); return(*status); } /*---------------------------------------------------------------------------*/ int fits_get_url(fitsfile *fptr, /* I ptr to FITS file to evaluate */ char *realURL, /* O URL of real FITS file */ char *startURL, /* O URL of starting FITS file */ char *realAccess, /* O true access method of FITS file */ char *startAccess,/* O "official" access of FITS file */ int *iostate, /* O can this file be modified? */ int *status) /* For grouping convention purposes, determine the URL of the FITS file associated with the fitsfile pointer fptr. The true access type (file://, mem://, shmem://, root://), starting "official" access type, and iostate (0 ==> readonly, 1 ==> readwrite) are also returned. It is assumed that the url string has enough room to hold the resulting URL, and the the accessType string has enough room to hold the access type. */ { int i; int tmpIOstate = 0; char infile[FLEN_FILENAME]; char outfile[FLEN_FILENAME]; char tmpStr1[FLEN_FILENAME]; char tmpStr2[FLEN_FILENAME]; char tmpStr3[FLEN_FILENAME]; char tmpStr4[FLEN_FILENAME]; char *tmpPtr; if(*status != 0) return(*status); do { /* retrieve the member HDU's file name as opened by ffopen() and parse it into its constitutent pieces; get the currently active driver token too */ *tmpStr1 = *tmpStr2 = *tmpStr3 = *tmpStr4 = 0; *status = fits_file_name(fptr,tmpStr1,status); *status = ffiurl(tmpStr1,NULL,infile,outfile,NULL,tmpStr2,tmpStr3, tmpStr4,status); if((*tmpStr2) || (*tmpStr3) || (*tmpStr4)) tmpIOstate = -1; *status = ffurlt(fptr,tmpStr3,status); strcpy(tmpStr4,tmpStr3); *status = ffrtnm(tmpStr1,tmpStr2,status); strcpy(tmpStr1,tmpStr2); /* for grouping convention purposes (only) determine the URL of the actual FITS file being used for the given fptr, its true access type (file://, mem://, shmem://, root://) and its iostate (0 ==> read only, 1 ==> readwrite) */ /* The first set of access types are "simple" in that they do not use any redirection to temporary memory or outfiles */ /* standard disk file driver is in use */ if(strcasecmp(tmpStr3,"file://") == 0) { tmpIOstate = 1; if(strlen(outfile)) strcpy(tmpStr1,outfile); else *tmpStr2 = 0; /* make sure no FILE:// specifier is given in the tmpStr1 or tmpStr2 strings; the convention calls for local files to have no access specification */ if((tmpPtr = strstr(tmpStr1,"://")) != NULL) { strcpy(infile,tmpPtr+3); strcpy(tmpStr1,infile); } if((tmpPtr = strstr(tmpStr2,"://")) != NULL) { strcpy(infile,tmpPtr+3); strcpy(tmpStr2,infile); } } /* file stored in conventional memory */ else if(strcasecmp(tmpStr3,"mem://") == 0) { if(tmpIOstate < 0) { /* file is a temp mem file only */ ffpmsg("cannot make URL from temp MEM:// file (fits_get_url)"); *status = URL_PARSE_ERROR; } else { /* file is a "perminate" mem file for this process */ tmpIOstate = 1; *tmpStr2 = 0; } } /* file stored in conventional memory */ else if(strcasecmp(tmpStr3,"memkeep://") == 0) { strcpy(tmpStr3,"mem://"); *tmpStr4 = 0; *tmpStr2 = 0; tmpIOstate = 1; } /* file residing in shared memory */ else if(strcasecmp(tmpStr3,"shmem://") == 0) { *tmpStr4 = 0; *tmpStr2 = 0; tmpIOstate = 1; } /* file accessed via the ROOT network protocol */ else if(strcasecmp(tmpStr3,"root://") == 0) { *tmpStr4 = 0; *tmpStr2 = 0; tmpIOstate = 1; } /* the next set of access types redirect the contents of the original file to an special outfile because the original could not be directly modified (i.e., resides on the network, was compressed). In these cases the URL string takes on the value of the OUTFILE, the access type becomes file://, and the iostate is set to 1 (can read/write to the file). */ /* compressed file uncompressed and written to disk */ else if(strcasecmp(tmpStr3,"compressfile://") == 0) { strcpy(tmpStr1,outfile); strcpy(tmpStr2,infile); strcpy(tmpStr3,"file://"); strcpy(tmpStr4,"file://"); tmpIOstate = 1; } /* HTTP accessed file written locally to disk */ else if(strcasecmp(tmpStr3,"httpfile://") == 0) { strcpy(tmpStr1,outfile); strcpy(tmpStr3,"file://"); strcpy(tmpStr4,"http://"); tmpIOstate = 1; } /* FTP accessd file written locally to disk */ else if(strcasecmp(tmpStr3,"ftpfile://") == 0) { strcpy(tmpStr1,outfile); strcpy(tmpStr3,"file://"); strcpy(tmpStr4,"ftp://"); tmpIOstate = 1; } /* file from STDIN written to disk */ else if(strcasecmp(tmpStr3,"stdinfile://") == 0) { strcpy(tmpStr1,outfile); strcpy(tmpStr3,"file://"); strcpy(tmpStr4,"stdin://"); tmpIOstate = 1; } /* the following access types use memory resident files as temporary storage; they cannot be modified or be made group members for grouping conventions purposes, but their original files can be. Thus, their tmpStr3s are reset to mem://, their iostate values are set to 0 (for no-modification), and their URL string values remain set to their original values */ /* compressed disk file uncompressed into memory */ else if(strcasecmp(tmpStr3,"compress://") == 0) { *tmpStr1 = 0; strcpy(tmpStr2,infile); strcpy(tmpStr3,"mem://"); strcpy(tmpStr4,"file://"); tmpIOstate = 0; } /* HTTP accessed file transferred into memory */ else if(strcasecmp(tmpStr3,"http://") == 0) { *tmpStr1 = 0; strcpy(tmpStr3,"mem://"); strcpy(tmpStr4,"http://"); tmpIOstate = 0; } /* HTTP accessed compressed file transferred into memory */ else if(strcasecmp(tmpStr3,"httpcompress://") == 0) { *tmpStr1 = 0; strcpy(tmpStr3,"mem://"); strcpy(tmpStr4,"http://"); tmpIOstate = 0; } /* FTP accessed file transferred into memory */ else if(strcasecmp(tmpStr3,"ftp://") == 0) { *tmpStr1 = 0; strcpy(tmpStr3,"mem://"); strcpy(tmpStr4,"ftp://"); tmpIOstate = 0; } /* FTP accessed compressed file transferred into memory */ else if(strcasecmp(tmpStr3,"ftpcompress://") == 0) { *tmpStr1 = 0; strcpy(tmpStr3,"mem://"); strcpy(tmpStr4,"ftp://"); tmpIOstate = 0; } /* The last set of access types cannot be used to make a meaningful URL strings from; thus an error is generated */ else if(strcasecmp(tmpStr3,"stdin://") == 0) { *status = URL_PARSE_ERROR; ffpmsg("cannot make vaild URL from stdin:// (fits_get_url)"); *tmpStr1 = *tmpStr2 = 0; } else if(strcasecmp(tmpStr3,"stdout://") == 0) { *status = URL_PARSE_ERROR; ffpmsg("cannot make vaild URL from stdout:// (fits_get_url)"); *tmpStr1 = *tmpStr2 = 0; } else if(strcasecmp(tmpStr3,"irafmem://") == 0) { *status = URL_PARSE_ERROR; ffpmsg("cannot make vaild URL from irafmem:// (fits_get_url)"); *tmpStr1 = *tmpStr2 = 0; } if(*status != 0) continue; /* assign values to the calling parameters if they are non-NULL */ if(realURL != NULL) { if(strlen(tmpStr1) == 0) *realURL = 0; else { if((tmpPtr = strstr(tmpStr1,"://")) != NULL) { tmpPtr += 3; i = (long)tmpPtr - (long)tmpStr1; strncpy(realURL,tmpStr1,i); } else { tmpPtr = tmpStr1; i = 0; } *status = fits_path2url(tmpPtr,realURL+i,status); } } if(startURL != NULL) { if(strlen(tmpStr2) == 0) *startURL = 0; else { if((tmpPtr = strstr(tmpStr2,"://")) != NULL) { tmpPtr += 3; i = (long)tmpPtr - (long)tmpStr2; strncpy(startURL,tmpStr2,i); } else { tmpPtr = tmpStr2; i = 0; } *status = fits_path2url(tmpPtr,startURL+i,status); } } if(realAccess != NULL) strcpy(realAccess,tmpStr3); if(startAccess != NULL) strcpy(startAccess,tmpStr4); if(iostate != NULL) *iostate = tmpIOstate; }while(0); return(*status); } /*-------------------------------------------------------------------------- URL parse support functions --------------------------------------------------------------------------*/ /* simple push/pop/shift/unshift string stack for use by fits_clean_url */ typedef char* grp_stack_data; /* type of data held by grp_stack */ typedef struct grp_stack_item_struct { grp_stack_data data; /* value of this stack item */ struct grp_stack_item_struct* next; /* next stack item */ struct grp_stack_item_struct* prev; /* previous stack item */ } grp_stack_item; typedef struct grp_stack_struct { size_t stack_size; /* number of items on stack */ grp_stack_item* top; /* top item */ } grp_stack; static char* grp_stack_default = NULL; /* initial value for new instances of grp_stack_data */ /* the following functions implement the group string stack grp_stack */ static void delete_grp_stack(grp_stack** mystack); static grp_stack_item* grp_stack_append( grp_stack_item* last, grp_stack_data data ); static grp_stack_data grp_stack_remove(grp_stack_item* last); static grp_stack* new_grp_stack(void); static grp_stack_data pop_grp_stack(grp_stack* mystack); static void push_grp_stack(grp_stack* mystack, grp_stack_data data); static grp_stack_data shift_grp_stack(grp_stack* mystack); /* static void unshift_grp_stack(grp_stack* mystack, grp_stack_data data); */ int fits_clean_url(char *inURL, /* I input URL string */ char *outURL, /* O output URL string */ int *status) /* clean the URL by eliminating any ".." or "." specifiers in the inURL string, and write the output to the outURL string. Note that this function must have a valid Unix-style URL as input; platform dependent path strings are not allowed. */ { grp_stack* mystack; /* stack to hold pieces of URL */ char* tmp; if(*status) return *status; mystack = new_grp_stack(); *outURL = 0; do { /* handle URL scheme and domain if they exist */ tmp = strstr(inURL, "://"); if(tmp) { /* there is a URL scheme, so look for the end of the domain too */ tmp = strchr(tmp + 3, '/'); if(tmp) { /* tmp is now the end of the domain, so * copy URL scheme and domain as is, and terminate by hand */ size_t string_size = (size_t) (tmp - inURL); strncpy(outURL, inURL, string_size); outURL[string_size] = 0; /* now advance the input pointer to just after the domain and go on */ inURL = tmp; } else { /* '/' was not found, which means there are no path-like * portions, so copy whole inURL to outURL and we're done */ strcpy(outURL, inURL); continue; /* while(0) */ } } /* explicitly copy a leading / (absolute path) */ if('/' == *inURL) strcat(outURL, "/"); /* now clean the remainder of the inURL. push URL segments onto * stack, dealing with .. and . as we go */ tmp = strtok(inURL, "/"); /* finds first / */ while(tmp) { if(!strcmp(tmp, "..")) { /* discard previous URL segment, if there was one. if not, * add the .. to the stack if this is *not* an absolute path * (for absolute paths, leading .. has no effect, so skip it) */ if(0 < mystack->stack_size) pop_grp_stack(mystack); else if('/' != *inURL) push_grp_stack(mystack, tmp); } else { /* always just skip ., but otherwise add segment to stack */ if(strcmp(tmp, ".")) push_grp_stack(mystack, tmp); } tmp = strtok(NULL, "/"); /* get the next segment */ } /* stack now has pieces of cleaned URL, so just catenate them * onto output string until stack is empty */ while(0 < mystack->stack_size) { tmp = shift_grp_stack(mystack); strcat(outURL, tmp); strcat(outURL, "/"); } outURL[strlen(outURL) - 1] = 0; /* blank out trailing / */ } while(0); delete_grp_stack(&mystack); return *status; } /* free all stack contents using pop_grp_stack before freeing the * grp_stack itself */ static void delete_grp_stack(grp_stack** mystack) { if(!mystack || !*mystack) return; while((*mystack)->stack_size) pop_grp_stack(*mystack); free(*mystack); *mystack = NULL; } /* append an item to the stack, handling the special case of the first * item appended */ static grp_stack_item* grp_stack_append( grp_stack_item* last, grp_stack_data data ) { /* first create a new stack item, and copy data to it */ grp_stack_item* new_item = (grp_stack_item*) malloc(sizeof(grp_stack_item)); new_item->data = data; if(last) { /* attach this item between the "last" item and its "next" item */ new_item->next = last->next; new_item->prev = last; last->next->prev = new_item; last->next = new_item; } else { /* stack is empty, so "next" and "previous" both point back to it */ new_item->next = new_item; new_item->prev = new_item; } return new_item; } /* remove an item from the stack, handling the special case of the last * item removed */ static grp_stack_data grp_stack_remove(grp_stack_item* last) { grp_stack_data retval = last->data; last->prev->next = last->next; last->next->prev = last->prev; free(last); return retval; } /* create new stack dynamically, and give it valid initial values */ static grp_stack* new_grp_stack(void) { grp_stack* retval = (grp_stack*) malloc(sizeof(grp_stack)); if(retval) { retval->stack_size = 0; retval->top = NULL; } return retval; } /* return the value at the top of the stack and remove it, updating * stack_size. top->prev becomes the new "top" */ static grp_stack_data pop_grp_stack(grp_stack* mystack) { grp_stack_data retval = grp_stack_default; if(mystack && mystack->top) { grp_stack_item* newtop = mystack->top->prev; retval = grp_stack_remove(mystack->top); mystack->top = newtop; if(0 == --mystack->stack_size) mystack->top = NULL; } return retval; } /* add to the stack after the top element. the added element becomes * the new "top" */ static void push_grp_stack(grp_stack* mystack, grp_stack_data data) { if(!mystack) return; mystack->top = grp_stack_append(mystack->top, data); ++mystack->stack_size; return; } /* return the value at the bottom of the stack and remove it, updating * stack_size. "top" pointer is unaffected */ static grp_stack_data shift_grp_stack(grp_stack* mystack) { grp_stack_data retval = grp_stack_default; if(mystack && mystack->top) { retval = grp_stack_remove(mystack->top->next); /* top->next == bottom */ if(0 == --mystack->stack_size) mystack->top = NULL; } return retval; } /* add to the stack after the top element. "top" is unaffected, except * in the special case of an initially empty stack */ /* static void unshift_grp_stack(grp_stack* mystack, grp_stack_data data) { if(!mystack) return; if(mystack->top) grp_stack_append(mystack->top, data); else mystack->top = grp_stack_append(NULL, data); ++mystack->stack_size; return; } */ /*--------------------------------------------------------------------------*/ int fits_url2relurl(char *refURL, /* I reference URL string */ char *absURL, /* I absoulute URL string to process */ char *relURL, /* O resulting relative URL string */ int *status) /* create a relative URL to the file referenced by absURL with respect to the reference URL refURL. The relative URL is returned in relURL. Both refURL and absURL must be absolute URL strings; i.e. either begin with an access method specification "XXX://" or with a '/' character signifiying that they are absolute file paths. Note that it is possible to make a relative URL from two input URLs (absURL and refURL) that are not compatable. This function does not check to see if the resulting relative URL makes any sence. For instance, it is impossible to make a relative URL from the following two inputs: absURL = ftp://a.b.c.com/x/y/z/foo.fits refURL = /a/b/c/ttt.fits The resulting relURL will be: ../../../ftp://a.b.c.com/x/y/z/foo.fits Which is syntically correct but meaningless. The problem is that a file with an access method of ftp:// cannot be expressed a a relative URL to a local disk file. */ { int i,j; int refcount,abscount; int refsize,abssize; int done; if(*status != 0) return(*status); do { /* refURL and absURL must be absolute to process */ if(!(fits_is_url_absolute(refURL) || *refURL == '/') || !(fits_is_url_absolute(absURL) || *absURL == '/')) { *status = URL_PARSE_ERROR; ffpmsg("Cannot make rel. URL from non abs. URLs (fits_url2relurl)"); continue; } /* determine the size of the refURL and absURL strings */ refsize = strlen(refURL); abssize = strlen(absURL); /* process the two URL strings and build the relative URL between them */ for(done = 0, refcount = 0, abscount = 0; !done && refcount < refsize && abscount < abssize; ++refcount, ++abscount) { for(; abscount < abssize && absURL[abscount] == '/'; ++abscount); for(; refcount < refsize && refURL[refcount] == '/'; ++refcount); /* find the next path segment in absURL */ for(i = abscount; absURL[i] != '/' && i < abssize; ++i); /* find the next path segment in refURL */ for(j = refcount; refURL[j] != '/' && j < refsize; ++j); /* do the two path segments match? */ if(i == j && strncmp(absURL+abscount, refURL+refcount,i-refcount) == 0) { /* they match, so ignore them and continue */ abscount = i; refcount = j; continue; } /* we found a difference in the paths in refURL and absURL */ /* initialize the relative URL string */ relURL[0] = 0; /* for every path segment remaining in the refURL string, append a "../" path segment to the relataive URL relURL */ for(j = refcount; j < refsize; ++j) if(refURL[j] == '/') strcat(relURL,"../"); /* copy all remaining characters of absURL to the output relURL */ strcat(relURL,absURL+abscount); /* we are done building the relative URL */ done = 1; } }while(0); return(*status); } /*--------------------------------------------------------------------------*/ int fits_relurl2url(char *refURL, /* I reference URL string */ char *relURL, /* I relative URL string to process */ char *absURL, /* O absolute URL string */ int *status) /* create an absolute URL from a relative url and a reference URL. The reference URL is given by the FITS file pointed to by fptr. The construction of the absolute URL from the partial and reference URl is performed using the rules set forth in: http://www.w3.org/Addressing/URL/URL_TOC.html and http://www.w3.org/Addressing/URL/4_3_Partial.html Note that the relative URL string relURL must conform to the Unix-like URL syntax; host dependent partial URL strings are not allowed. */ { int i; char tmpStr[FLEN_FILENAME]; char *tmpStr1, *tmpStr2; if(*status != 0) return(*status); do { /* make a copy of the reference URL string refURL for parsing purposes */ strcpy(tmpStr,refURL); /* if the reference file has an access method of mem:// or shmem:// then we cannot use it as the basis of an absolute URL construction for a partial URL */ if(strncasecmp(tmpStr,"MEM:",4) == 0 || strncasecmp(tmpStr,"SHMEM:",6) == 0) { ffpmsg("ref URL has access mem:// or shmem:// (fits_relurl2url)"); ffpmsg(" cannot construct full URL from a partial URL and "); ffpmsg(" MEM/SHMEM base URL"); *status = URL_PARSE_ERROR; continue; } if(relURL[0] != '/') { /* just append the relative URL string to the reference URL string (minus the reference URL file name) to form the absolute URL string */ tmpStr1 = strrchr(tmpStr,'/'); if(tmpStr1 != NULL) tmpStr1[1] = 0; else tmpStr[0] = 0; strcat(tmpStr,relURL); } else { /* have to parse the refURL string for the first occurnace of the same number of '/' characters as contained in the beginning of location that is not followed by a greater number of consective '/' charaters (yes, that is a confusing statement); this is the location in the refURL string where the relURL string is to be appended to form the new absolute URL string */ /* first, build up a slash pattern string that has one more slash in it than the starting slash pattern of the relURL string */ strcpy(absURL,"/"); for(i = 0; relURL[i] == '/'; ++i) strcat(absURL,"/"); /* loop over the refURL string until the slash pattern stored in absURL is no longer found */ for(tmpStr1 = tmpStr, i = strlen(absURL); (tmpStr2 = strstr(tmpStr1,absURL)) != NULL; tmpStr1 = tmpStr2 + i); /* reduce the slash pattern string by one slash */ absURL[i-1] = 0; /* search for the slash pattern in the remaining portion of the refURL string */ tmpStr2 = strstr(tmpStr1,absURL); /* if no slash pattern match was found */ if(tmpStr2 == NULL) { /* just strip off the file name from the refURL */ tmpStr2 = strrchr(tmpStr1,'/'); if(tmpStr2 != NULL) tmpStr2[0] = 0; else tmpStr[0] = 0; } else { /* set a string terminator at the slash pattern match */ *tmpStr2 = 0; } /* conatenate the relURL string to the refURL string to form the absURL */ strcat(tmpStr,relURL); } /* normalize the absURL by removing any ".." or "." specifiers in the string */ *status = fits_clean_url(tmpStr,absURL,status); }while(0); return(*status); } /*--------------------------------------------------------------------------*/ int fits_encode_url(char *inpath, /* I URL to be encoded */ char *outpath, /* O output encoded URL */ int *status) /* encode all URL "unsafe" and "reserved" characters using the "%XX" convention, where XX stand for the two hexidecimal digits of the encode character's ASCII code. Note that the output path is at least as large as, if not larger than the input path, so that OUTPATH should be passed to this function with room for growth. If not a runtime error could result. It is assumed that OUTPATH has been allocated with enough room to hold the resulting encoded URL. This function was adopted from code in the libwww.a library available via the W3 consortium */ { unsigned char a; char *p; char *q; char *hex = "0123456789ABCDEF"; unsigned const char isAcceptable[96] = {/* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xA 0xB 0xC 0xD 0xE 0xF */ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xF,0xE,0x0,0xF,0xF,0xC, /* 2x !"#$%&'()*+,-./ */ 0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0x8,0x0,0x0,0x0,0x0,0x0, /* 3x 0123456789:;<=>? */ 0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF, /* 4x @ABCDEFGHIJKLMNO */ 0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0x0,0x0,0x0,0x0,0xF, /* 5X PQRSTUVWXYZ[\]^_ */ 0x0,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF, /* 6x `abcdefghijklmno */ 0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0x0,0x0,0x0,0x0,0x0 /* 7X pqrstuvwxyz{\}~DEL */ }; if(*status != 0) return(*status); /* loop over all characters in inpath until '\0' is encountered */ for(q = outpath, p = inpath; *p; p++) { a = (unsigned char)*p; /* if the charcter requires encoding then process it */ if(!( a>=32 && a<128 && (isAcceptable[a-32]))) { /* add a '%' character to the outpath */ *q++ = HEX_ESCAPE; /* add the most significant ASCII code hex value */ *q++ = hex[a >> 4]; /* add the least significant ASCII code hex value */ *q++ = hex[a & 15]; } /* else just copy the character as is */ else *q++ = *p; } /* null terminate the outpath string */ *q++ = 0; return(*status); } /*---------------------------------------------------------------------------*/ int fits_unencode_url(char *inpath, /* I input URL with encoding */ char *outpath, /* O unencoded URL */ int *status) /* unencode all URL "unsafe" and "reserved" characters to their actual ASCII representation. All tokens of the form "%XX" where XX is the hexidecimal code for an ASCII character, are searched for and translated into the actuall ASCII character (so three chars become 1 char). It is assumed that OUTPATH has enough room to hold the unencoded URL. This function was adopted from code in the libwww.a library available via the W3 consortium */ { char *p; char *q; char c; if(*status != 0) return(*status); p = inpath; q = outpath; /* loop over all characters in the inpath looking for the '%' escape character; if found the process the escape sequence */ while(*p != 0) { /* if the character is '%' then unencode the sequence, else just copy the character from inpath to outpath */ if (*p == HEX_ESCAPE) { if((c = *(++p)) != 0) { *q = ( (c >= '0' && c <= '9') ? (c - '0') : ((c >= 'A' && c <= 'F') ? (c - 'A' + 10) : (c - 'a' + 10)) )*16; if((c = *(++p)) != 0) { *q = *q + ( (c >= '0' && c <= '9') ? (c - '0') : ((c >= 'A' && c <= 'F') ? (c - 'A' + 10) : (c - 'a' + 10)) ); p++, q++; } } } else *q++ = *p++; } /* terminate the outpath */ *q = 0; return(*status); } /*---------------------------------------------------------------------------*/ int fits_is_url_absolute(char *url) /* Return a True (1) or False (0) value indicating whether or not the passed URL string contains an access method specifier or not. Note that this is a boolean function and it neither reads nor returns the standard error status parameter */ { char *tmpStr1, *tmpStr2; char reserved[] = {':',';','/','?','@','&','=','+','$',','}; /* The rule for determing if an URL is relative or absolute is that it (1) must have a colon ":" and (2) that the colon must appear before any other reserved URL character in the URL string. We first see if a colon exists, get its position in the string, and then check to see if any of the other reserved characters exists and if their position in the string is greater than that of the colons. */ if( (tmpStr1 = strchr(url,reserved[0])) != NULL && ((tmpStr2 = strchr(url,reserved[1])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[2])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[3])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[4])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[5])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[6])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[7])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[8])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[9])) == NULL || tmpStr2 > tmpStr1) ) { return(1); } else { return(0); } } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/group.h000066400000000000000000000036061215713201500217420ustar00rootroot00000000000000#define MAX_HDU_TRACKER 1000 typedef struct _HDUtracker HDUtracker; struct _HDUtracker { int nHDU; char *filename[MAX_HDU_TRACKER]; int position[MAX_HDU_TRACKER]; char *newFilename[MAX_HDU_TRACKER]; int newPosition[MAX_HDU_TRACKER]; }; /* functions used internally in the grouping convention module */ int ffgtdc(int grouptype, int xtensioncol, int extnamecol, int extvercol, int positioncol, int locationcol, int uricol, char *ttype[], char *tform[], int *ncols, int *status); int ffgtgc(fitsfile *gfptr, int *xtensionCol, int *extnameCol, int *extverCol, int *positionCol, int *locationCol, int *uriCol, int *grptype, int *status); int ffgmul(fitsfile *mfptr, int rmopt, int *status); int ffgmf(fitsfile *gfptr, char *xtension, char *extname, int extver, int position, char *location, long *member, int *status); int ffgtrmr(fitsfile *gfptr, HDUtracker *HDU, int *status); int ffgtcpr(fitsfile *infptr, fitsfile *outfptr, int cpopt, HDUtracker *HDU, int *status); int fftsad(fitsfile *mfptr, HDUtracker *HDU, int *newPosition, char *newFileName); int fftsud(fitsfile *mfptr, HDUtracker *HDU, int newPosition, char *newFileName); void prepare_keyvalue(char *keyvalue); int fits_path2url(char *inpath, char *outpath, int *status); int fits_url2path(char *inpath, char *outpath, int *status); int fits_get_cwd(char *cwd, int *status); int fits_get_url(fitsfile *fptr, char *realURL, char *startURL, char *realAccess, char *startAccess, int *iostate, int *status); int fits_clean_url(char *inURL, char *outURL, int *status); int fits_relurl2url(char *refURL, char *relURL, char *absURL, int *status); int fits_url2relurl(char *refURL, char *absURL, char *relURL, int *status); int fits_encode_url(char *inpath, char *outpath, int *status); int fits_unencode_url(char *inpath, char *outpath, int *status); int fits_is_url_absolute(char *url); skycat-3.1.2-starlink-1b/astrotcl/cfitsio/grparser.c000066400000000000000000001315471215713201500224340ustar00rootroot00000000000000/* T E M P L A T E P A R S E R ============================= by Jerzy.Borkowski@obs.unige.ch Integral Science Data Center ch. d'Ecogia 16 1290 Versoix Switzerland 14-Oct-98: initial release 16-Oct-98: code cleanup, #include included, now gcc -Wall prints no warnings during compilation. Bugfix: now one can specify additional columns in group HDU. Autoindexing also works in this situation (colunms are number from 7 however). 17-Oct-98: bugfix: complex keywords were incorrectly written (was TCOMPLEX should be TDBLCOMPLEX). 20-Oct-98: bugfix: parser was writing EXTNAME twice, when first HDU in template is defined with XTENSION IMAGE then parser creates now dummy PHDU, SIMPLE T is now allowed only at most once and in first HDU only. WARNING: one should not define EXTNAME keyword for GROUP HDUs, as they have them already defined by parser (EXTNAME = GROUPING). Parser accepts EXTNAME oin GROUP HDU definition, but in this case multiple EXTNAME keywords will present in HDU header. 23-Oct-98: bugfix: unnecessary space was written to FITS file for blank keywords. 24-Oct-98: syntax change: empty lines and lines with only whitespaces are written to FITS files as blank keywords (if inside group/hdu definition). Previously lines had to have at least 8 spaces. Please note, that due to pecularities of CFITSIO if the last keyword(s) defined for given HDU are blank keywords consisting of only 80 spaces, then (some of) those keywords may be silently deleted by CFITSIO. 13-Nov-98: bugfix: parser was writing GRPNAME twice. Parser still creates GRPNAME keywords for GROUP HDU's which do not specify them. However, values (of form DEFAULT_GROUP_XXX) are assigned not necessarily in order HDUs appear in template file, but rather in order parser completes their creation in FITS file. Also, when including files, if fopen fails, parser tries to open file with a name = directory_of_top_level file + name of file to be included, as long as name of file to be included does not specify absolute pathname. 16-Nov-98: bugfix to bugfix from 13-Nov-98 19-Nov-98: EXTVER keyword is now automatically assigned value by parser. 17-Dev-98: 2 new things added: 1st: CFITSIO_INCLUDE_FILES environment variable can contain a colon separated list of directories to look for when looking for template include files (and master template also). 2nd: it is now possible to append template to nonempty FITS. file. fitsfile *ff no longer needs to point to an empty FITS file with 0 HDUs in it. All data written by parser will simple be appended at the end of file. 22-Jan-99: changes to parser: when in append mode parser initially scans all existing HDUs to built a list of already used EXTNAME/EXTVERs 22-Jan-99: Bruce O'Neel, bugfix : TLONG should always reference long type variable on OSF/Alpha and on 64-bit archs in general 20-Jun-2002 Wm Pence, added support for the HIERARCH keyword convention in which keyword names can effectively be longer than 8 characters. Example: HIERARCH LongKeywordName = 'value' / comment 30-Jan-2003 Wm Pence, bugfix: ngp_read_xtension was testing for "ASCIITABLE" instead of "TABLE" as the XTENSION value of an ASCII table, and it did not allow for optional trailing spaces in the "IMAGE" or "TABLE" string. 16-Dec-2003 James Peachey: ngp_keyword_all_write was modified to apply comments from the template file to the output file in the case of reserved keywords (e.g. tform#, ttype# etcetera). */ #include #include #ifdef sparc #include #include #endif #include #include "fitsio2.h" #include "grparser.h" NGP_RAW_LINE ngp_curline = { NULL, NULL, NULL, NGP_TTYPE_UNKNOWN, NULL, NGP_FORMAT_OK, 0 }; NGP_RAW_LINE ngp_prevline = { NULL, NULL, NULL, NGP_TTYPE_UNKNOWN, NULL, NGP_FORMAT_OK, 0 }; int ngp_inclevel = 0; /* number of included files, 1 - means mean file */ int ngp_grplevel = 0; /* group nesting level, 0 - means no grouping */ FILE *ngp_fp[NGP_MAX_INCLUDE]; /* stack of included file handles */ int ngp_keyidx = NGP_TOKEN_UNKNOWN; /* index of token in current line */ NGP_TOKEN ngp_linkey; /* keyword after line analyze */ char ngp_master_dir[NGP_MAX_FNAME]; /* directory of top level include file */ NGP_TKDEF ngp_tkdef[] = /* tokens recognized by parser */ { { "\\INCLUDE", NGP_TOKEN_INCLUDE }, { "\\GROUP", NGP_TOKEN_GROUP }, { "\\END", NGP_TOKEN_END }, { "XTENSION", NGP_TOKEN_XTENSION }, { "SIMPLE", NGP_TOKEN_SIMPLE }, { NULL, NGP_TOKEN_UNKNOWN } }; int master_grp_idx = 1; /* current unnamed group in object */ int ngp_extver_tab_size = 0; NGP_EXTVER_TAB *ngp_extver_tab = NULL; int ngp_get_extver(char *extname, int *version) { NGP_EXTVER_TAB *p; char *p2; int i; if ((NULL == extname) || (NULL == version)) return(NGP_BAD_ARG); if ((NULL == ngp_extver_tab) && (ngp_extver_tab_size > 0)) return(NGP_BAD_ARG); if ((NULL != ngp_extver_tab) && (ngp_extver_tab_size <= 0)) return(NGP_BAD_ARG); for (i=0; i 0)) return(NGP_BAD_ARG); if ((NULL != ngp_extver_tab) && (ngp_extver_tab_size <= 0)) return(NGP_BAD_ARG); for (i=0; i ngp_extver_tab[i].version) ngp_extver_tab[i].version = version; return(NGP_OK); } } if (NULL == ngp_extver_tab) { p = (NGP_EXTVER_TAB *)ngp_alloc(sizeof(NGP_EXTVER_TAB)); } else { p = (NGP_EXTVER_TAB *)ngp_realloc(ngp_extver_tab, (ngp_extver_tab_size + 1) * sizeof(NGP_EXTVER_TAB)); } if (NULL == p) return(NGP_NO_MEMORY); p2 = ngp_alloc(strlen(extname) + 1); if (NULL == p2) { ngp_free(p); return(NGP_NO_MEMORY); } strcpy(p2, extname); ngp_extver_tab = p; ngp_extver_tab[ngp_extver_tab_size].extname = p2; ngp_extver_tab[ngp_extver_tab_size].version = version; ngp_extver_tab_size++; return(NGP_OK); } int ngp_delete_extver_tab(void) { int i; if ((NULL == ngp_extver_tab) && (ngp_extver_tab_size > 0)) return(NGP_BAD_ARG); if ((NULL != ngp_extver_tab) && (ngp_extver_tab_size <= 0)) return(NGP_BAD_ARG); if ((NULL == ngp_extver_tab) && (0 == ngp_extver_tab_size)) return(NGP_OK); for (i=0; i= 'a') && (c1 <= 'z')) c1 += ('A' - 'a'); c2 = *p2; if ((c2 >= 'a') && (c2 <= 'z')) c2 += ('A' - 'a'); if (c1 < c2) return(-1); if (c1 > c2) return(1); if (0 == c1) return(0); p1++; p2++; } } int ngp_strcasencmp(char *p1, char *p2, int n) { char c1, c2; int ii; for (ii=0;ii= 'a') && (c1 <= 'z')) c1 += ('A' - 'a'); c2 = *p2; if ((c2 >= 'a') && (c2 <= 'z')) c2 += ('A' - 'a'); if (c1 < c2) return(-1); if (c1 > c2) return(1); if (0 == c1) return(0); p1++; p2++; } return(0); } /* read one line from file */ int ngp_line_from_file(FILE *fp, char **p) { int c, r, llen, allocsize, alen; char *p2; if (NULL == fp) return(NGP_NUL_PTR); /* check for stupid args */ if (NULL == p) return(NGP_NUL_PTR); /* more foolproof checks */ r = NGP_OK; /* initialize stuff, reset err code */ llen = 0; /* 0 characters read so far */ *p = (char *)ngp_alloc(1); /* preallocate 1 byte */ allocsize = 1; /* signal that we have allocated 1 byte */ if (NULL == *p) return(NGP_NO_MEMORY); /* if this failed, system is in dire straits */ for (;;) { c = getc(fp); /* get next character */ if (EOF == c) /* EOF signalled ? */ { if (ferror(fp)) r = NGP_READ_ERR; /* was it real error or simply EOF ? */ if (0 == llen) return(NGP_EOF); /* signal EOF only if 0 characters read so far */ break; } if ('\n' == c) break; /* end of line character ? */ llen++; /* we have new character, make room for it */ alen = ((llen + NGP_ALLOCCHUNK) / NGP_ALLOCCHUNK) * NGP_ALLOCCHUNK; if (alen > allocsize) { p2 = (char *)ngp_realloc(*p, alen); /* realloc buffer, if there is need */ if (NULL == p2) { r = NGP_NO_MEMORY; break; } *p = p2; allocsize = alen; } (*p)[llen - 1] = c; /* copy character to buffer */ } llen++; /* place for terminating \0 */ if (llen != allocsize) { p2 = (char *)ngp_realloc(*p, llen); if (NULL == p2) r = NGP_NO_MEMORY; else { *p = p2; (*p)[llen - 1] = 0; /* copy \0 to buffer */ } } else { (*p)[llen - 1] = 0; /* necessary when line read was empty */ } if ((NGP_EOF != r) && (NGP_OK != r)) /* in case of errors free resources */ { ngp_free(*p); *p = NULL; } return(r); /* return status code */ } /* free current line structure */ int ngp_free_line(void) { if (NULL != ngp_curline.line) { ngp_free(ngp_curline.line); ngp_curline.line = NULL; ngp_curline.name = NULL; ngp_curline.value = NULL; ngp_curline.comment = NULL; ngp_curline.type = NGP_TTYPE_UNKNOWN; ngp_curline.format = NGP_FORMAT_OK; ngp_curline.flags = 0; } return(NGP_OK); } /* free cached line structure */ int ngp_free_prevline(void) { if (NULL != ngp_prevline.line) { ngp_free(ngp_prevline.line); ngp_prevline.line = NULL; ngp_prevline.name = NULL; ngp_prevline.value = NULL; ngp_prevline.comment = NULL; ngp_prevline.type = NGP_TTYPE_UNKNOWN; ngp_prevline.format = NGP_FORMAT_OK; ngp_prevline.flags = 0; } return(NGP_OK); } /* read one line */ int ngp_read_line_buffered(FILE *fp) { ngp_free_line(); /* first free current line (if any) */ if (NULL != ngp_prevline.line) /* if cached, return cached line */ { ngp_curline = ngp_prevline; ngp_prevline.line = NULL; ngp_prevline.name = NULL; ngp_prevline.value = NULL; ngp_prevline.comment = NULL; ngp_prevline.type = NGP_TTYPE_UNKNOWN; ngp_prevline.format = NGP_FORMAT_OK; ngp_prevline.flags = 0; ngp_curline.flags = NGP_LINE_REREAD; return(NGP_OK); } ngp_curline.flags = 0; /* if not cached really read line from file */ return(ngp_line_from_file(fp, &(ngp_curline.line))); } /* unread line */ int ngp_unread_line(void) { if (NULL == ngp_curline.line) /* nothing to unread */ return(NGP_EMPTY_CURLINE); if (NULL != ngp_prevline.line) /* we cannot unread line twice */ return(NGP_UNREAD_QUEUE_FULL); ngp_prevline = ngp_curline; ngp_curline.line = NULL; return(NGP_OK); } /* a first guess line decomposition */ int ngp_extract_tokens(NGP_RAW_LINE *cl) { char *p, *s; int cl_flags, i; p = cl->line; /* start from beginning of line */ if (NULL == p) return(NGP_NUL_PTR); cl->name = cl->value = cl->comment = NULL; cl->type = NGP_TTYPE_UNKNOWN; cl->format = NGP_FORMAT_OK; cl_flags = 0; for (i=0;; i++) /* if 8 spaces at beginning then line is comment */ { if ((0 == *p) || ('\n' == *p)) { /* if line has only blanks -> write blank keyword */ cl->line[0] = 0; /* create empty name (0 length string) */ cl->comment = cl->name = cl->line; cl->type = NGP_TTYPE_RAW; /* signal write unformatted to FITS file */ return(NGP_OK); } if ((' ' != *p) && ('\t' != *p)) break; if (i >= 7) { cl->comment = p + 1; for (s = cl->comment;; s++) /* filter out any EOS characters in comment */ { if ('\n' == *s) *s = 0; if (0 == *s) break; } cl->line[0] = 0; /* create empty name (0 length string) */ cl->name = cl->line; cl->type = NGP_TTYPE_RAW; return(NGP_OK); } p++; } cl->name = p; for (;;) /* we need to find 1st whitespace */ { if ((0 == *p) || ('\n' == *p)) { *p = 0; break; } /* from Richard Mathar, 2002-05-03, add 10 lines: if upper/lowercase HIERARCH followed also by an equal sign... */ if( strncasecmp("HIERARCH",p,strlen("HIERARCH")) == 0 ) { char * const eqsi=strchr(p,'=') ; if( eqsi ) { cl_flags |= NGP_FOUND_EQUAL_SIGN ; p=eqsi ; break ; } } if ((' ' == *p) || ('\t' == *p)) break; if ('=' == *p) { cl_flags |= NGP_FOUND_EQUAL_SIGN; break; } p++; } if (*p) *(p++) = 0; /* found end of keyname so terminate string with zero */ if ((!ngp_strcasecmp("HISTORY", cl->name)) || (!ngp_strcasecmp("COMMENT", cl->name)) || (!ngp_strcasecmp("CONTINUE", cl->name))) { cl->comment = p; for (s = cl->comment;; s++) /* filter out any EOS characters in comment */ { if ('\n' == *s) *s = 0; if (0 == *s) break; } cl->type = NGP_TTYPE_RAW; return(NGP_OK); } if (!ngp_strcasecmp("\\INCLUDE", cl->name)) { for (;; p++) if ((' ' != *p) && ('\t' != *p)) break; /* skip whitespace */ cl->value = p; for (s = cl->value;; s++) /* filter out any EOS characters */ { if ('\n' == *s) *s = 0; if (0 == *s) break; } cl->type = NGP_TTYPE_UNKNOWN; return(NGP_OK); } for (;; p++) { if ((0 == *p) || ('\n' == *p)) return(NGP_OK); /* test if at end of string */ if ((' ' == *p) || ('\t' == *p)) continue; /* skip whitespace */ if (cl_flags & NGP_FOUND_EQUAL_SIGN) break; if ('=' != *p) break; /* ignore initial equal sign */ cl_flags |= NGP_FOUND_EQUAL_SIGN; } if ('/' == *p) /* no value specified, comment only */ { p++; if ((' ' == *p) || ('\t' == *p)) p++; cl->comment = p; for (s = cl->comment;; s++) /* filter out any EOS characters in comment */ { if ('\n' == *s) *s = 0; if (0 == *s) break; } return(NGP_OK); } if ('\'' == *p) /* we have found string within quotes */ { cl->value = s = ++p; /* set pointer to beginning of that string */ cl->type = NGP_TTYPE_STRING; /* signal that it is of string type */ for (;;) /* analyze it */ { if ((0 == *p) || ('\n' == *p)) /* end of line -> end of string */ { *s = 0; return(NGP_OK); } if ('\'' == *p) /* we have found doublequote */ { if ((0 == p[1]) || ('\n' == p[1]))/* doublequote is the last character in line */ { *s = 0; return(NGP_OK); } if (('\t' == p[1]) || (' ' == p[1])) /* duoblequote was string terminator */ { *s = 0; p++; break; } if ('\'' == p[1]) p++; /* doublequote is inside string, convert "" -> " */ } *(s++) = *(p++); /* compact string in place, necess. by "" -> " conversion */ } } else /* regular token */ { cl->value = p; /* set pointer to token */ cl->type = NGP_TTYPE_UNKNOWN; /* we dont know type at the moment */ for (;; p++) /* we need to find 1st whitespace */ { if ((0 == *p) || ('\n' == *p)) { *p = 0; return(NGP_OK); } if ((' ' == *p) || ('\t' == *p)) break; } if (*p) *(p++) = 0; /* found so terminate string with zero */ } for (;; p++) { if ((0 == *p) || ('\n' == *p)) return(NGP_OK); /* test if at end of string */ if ((' ' != *p) && ('\t' != *p)) break; /* skip whitespace */ } if ('/' == *p) /* no value specified, comment only */ { p++; if ((' ' == *p) || ('\t' == *p)) p++; cl->comment = p; for (s = cl->comment;; s++) /* filter out any EOS characters in comment */ { if ('\n' == *s) *s = 0; if (0 == *s) break; } return(NGP_OK); } cl->format = NGP_FORMAT_ERROR; return(NGP_OK); /* too many tokens ... */ } /* try to open include file. If open fails and fname does not specify absolute pathname, try to open fname in any directory specified in CFITSIO_INCLUDE_FILES environment variable. Finally try to open fname relative to ngp_master_dir, which is directory of top level include file */ int ngp_include_file(char *fname) /* try to open include file */ { char *p, *p2, *cp, *envar, envfiles[NGP_MAX_ENVFILES]; if (NULL == fname) return(NGP_NUL_PTR); if (ngp_inclevel >= NGP_MAX_INCLUDE) /* too many include files */ return(NGP_INC_NESTING); if (NULL == (ngp_fp[ngp_inclevel] = fopen(fname, "r"))) { /* if simple open failed .. */ envar = getenv("CFITSIO_INCLUDE_FILES"); /* scan env. variable, and retry to open */ if (NULL != envar) /* is env. variable defined ? */ { strncpy(envfiles, envar, NGP_MAX_ENVFILES - 1); envfiles[NGP_MAX_ENVFILES - 1] = 0; /* copy search path to local variable, env. is fragile */ for (p2 = strtok(envfiles, ":"); NULL != p2; p2 = strtok(NULL, ":")) { cp = (char *)ngp_alloc(strlen(fname) + strlen(p2) + 2); if (NULL == cp) return(NGP_NO_MEMORY); strcpy(cp, p2); #ifdef MSDOS strcat(cp, "\\"); /* abs. pathname for MSDOS */ #else strcat(cp, "/"); /* and for unix */ #endif strcat(cp, fname); ngp_fp[ngp_inclevel] = fopen(cp, "r"); ngp_free(cp); if (NULL != ngp_fp[ngp_inclevel]) break; } } if (NULL == ngp_fp[ngp_inclevel]) /* finally try to open relative to top level */ { #ifdef MSDOS if ('\\' == fname[0]) return(NGP_ERR_FOPEN); /* abs. pathname for MSDOS, does not support C:\\PATH */ #else if ('/' == fname[0]) return(NGP_ERR_FOPEN); /* and for unix */ #endif if (0 == ngp_master_dir[0]) return(NGP_ERR_FOPEN); p = ngp_alloc(strlen(fname) + strlen(ngp_master_dir) + 1); if (NULL == p) return(NGP_NO_MEMORY); strcpy(p, ngp_master_dir); /* construct composite pathname */ strcat(p, fname); /* comp = master + fname */ ngp_fp[ngp_inclevel] = fopen(p, "r");/* try to open composite */ ngp_free(p); /* we don't need buffer anymore */ if (NULL == ngp_fp[ngp_inclevel]) return(NGP_ERR_FOPEN); /* fail if error */ } } ngp_inclevel++; return(NGP_OK); } /* read line in the intelligent way. All \INCLUDE directives are handled, empty and comment line skipped. If this function returns NGP_OK, than decomposed line (name, type, value in proper type and comment) are stored in ngp_linkey structure. ignore_blank_lines parameter is zero when parser is inside GROUP or HDU definition. Nonzero otherwise. */ int ngp_read_line(int ignore_blank_lines) { int r, nc; unsigned k; if (ngp_inclevel <= 0) /* do some sanity checking first */ { ngp_keyidx = NGP_TOKEN_EOF; /* no parents, so report error */ return(NGP_OK); } if (ngp_inclevel > NGP_MAX_INCLUDE) return(NGP_INC_NESTING); if (NULL == ngp_fp[ngp_inclevel - 1]) return(NGP_NUL_PTR); for (;;) { switch (r = ngp_read_line_buffered(ngp_fp[ngp_inclevel - 1])) { case NGP_EOF: ngp_inclevel--; /* end of file, revert to parent */ if (ngp_fp[ngp_inclevel]) /* we can close old file */ fclose(ngp_fp[ngp_inclevel]); ngp_fp[ngp_inclevel] = NULL; if (ngp_inclevel <= 0) { ngp_keyidx = NGP_TOKEN_EOF; /* no parents, so report error */ return(NGP_OK); } continue; case NGP_OK: if (ngp_curline.flags & NGP_LINE_REREAD) return(r); break; default: return(r); } switch (ngp_curline.line[0]) { case 0: if (0 == ignore_blank_lines) break; /* ignore empty lines if told so */ case '#': continue; /* ignore comment lines */ } r = ngp_extract_tokens(&ngp_curline); /* analyse line, extract tokens and comment */ if (NGP_OK != r) return(r); if (NULL == ngp_curline.name) continue; /* skip lines consisting only of whitespaces */ for (k = 0; k < strlen(ngp_curline.name); k++) { if ((ngp_curline.name[k] >= 'a') && (ngp_curline.name[k] <= 'z')) ngp_curline.name[k] += 'A' - 'a'; /* force keyword to be upper case */ if (k == 7) break; /* only first 8 chars are required to be upper case */ } for (k=0;; k++) /* find index of keyword in keyword table */ { if (NGP_TOKEN_UNKNOWN == ngp_tkdef[k].code) break; if (0 == strcmp(ngp_curline.name, ngp_tkdef[k].name)) break; } ngp_keyidx = ngp_tkdef[k].code; /* save this index, grammar parser will need this */ if (NGP_TOKEN_INCLUDE == ngp_keyidx) /* if this is \INCLUDE keyword, try to include file */ { if (NGP_OK != (r = ngp_include_file(ngp_curline.value))) return(r); continue; /* and read next line */ } ngp_linkey.type = NGP_TTYPE_UNKNOWN; /* now, get the keyword type, it's a long story ... */ if (NULL != ngp_curline.value) /* if no value given signal it */ { if (NGP_TTYPE_STRING == ngp_curline.type) /* string type test */ { ngp_linkey.type = NGP_TTYPE_STRING; ngp_linkey.value.s = ngp_curline.value; } if (NGP_TTYPE_UNKNOWN == ngp_linkey.type) /* bool type test */ { if ((!ngp_strcasecmp("T", ngp_curline.value)) || (!ngp_strcasecmp("F", ngp_curline.value))) { ngp_linkey.type = NGP_TTYPE_BOOL; ngp_linkey.value.b = (ngp_strcasecmp("T", ngp_curline.value) ? 0 : 1); } } if (NGP_TTYPE_UNKNOWN == ngp_linkey.type) /* complex type test */ { if (2 == sscanf(ngp_curline.value, "(%lg,%lg)%n", &(ngp_linkey.value.c.re), &(ngp_linkey.value.c.im), &nc)) { if ((' ' == ngp_curline.value[nc]) || ('\t' == ngp_curline.value[nc]) || ('\n' == ngp_curline.value[nc]) || (0 == ngp_curline.value[nc])) { ngp_linkey.type = NGP_TTYPE_COMPLEX; } } } if (NGP_TTYPE_UNKNOWN == ngp_linkey.type) /* real type test */ { if (strchr(ngp_curline.value, '.') && (1 == sscanf(ngp_curline.value, "%lg%n", &(ngp_linkey.value.d), &nc))) { if ((' ' == ngp_curline.value[nc]) || ('\t' == ngp_curline.value[nc]) || ('\n' == ngp_curline.value[nc]) || (0 == ngp_curline.value[nc])) { ngp_linkey.type = NGP_TTYPE_REAL; } } } if (NGP_TTYPE_UNKNOWN == ngp_linkey.type) /* integer type test */ { if (1 == sscanf(ngp_curline.value, "%d%n", &(ngp_linkey.value.i), &nc)) { if ((' ' == ngp_curline.value[nc]) || ('\t' == ngp_curline.value[nc]) || ('\n' == ngp_curline.value[nc]) || (0 == ngp_curline.value[nc])) { ngp_linkey.type = NGP_TTYPE_INT; } } } if (NGP_TTYPE_UNKNOWN == ngp_linkey.type) /* force string type */ { ngp_linkey.type = NGP_TTYPE_STRING; ngp_linkey.value.s = ngp_curline.value; } } else { if (NGP_TTYPE_RAW == ngp_curline.type) ngp_linkey.type = NGP_TTYPE_RAW; else ngp_linkey.type = NGP_TTYPE_NULL; } if (NULL != ngp_curline.comment) { strncpy(ngp_linkey.comment, ngp_curline.comment, NGP_MAX_COMMENT); /* store comment */ ngp_linkey.comment[NGP_MAX_COMMENT - 1] = 0; } else { ngp_linkey.comment[0] = 0; } strncpy(ngp_linkey.name, ngp_curline.name, NGP_MAX_NAME); /* and keyword's name */ ngp_linkey.name[NGP_MAX_NAME - 1] = 0; if (strlen(ngp_linkey.name) > FLEN_KEYWORD) /* WDP: 20-Jun-2002: mod to support HIERARCH */ { return(NGP_BAD_ARG); /* cfitsio does not allow names > 8 chars */ } return(NGP_OK); /* we have valid non empty line, so return success */ } } /* check whether keyword can be written as is */ int ngp_keyword_is_write(NGP_TOKEN *ngp_tok) { int i, j, r, l, spc; /* indexed variables not to write */ static char *nm[] = { "NAXIS", "TFORM", "TTYPE", NULL } ; /* non indexed variables not allowed to write */ static char *nmni[] = { "SIMPLE", "XTENSION", "BITPIX", "NAXIS", "PCOUNT", "GCOUNT", "TFIELDS", "THEAP", "EXTEND", "EXTVER", NULL } ; if (NULL == ngp_tok) return(NGP_NUL_PTR); r = NGP_OK; for (j = 0; ; j++) /* first check non indexed */ { if (NULL == nmni[j]) break; if (0 == strcmp(nmni[j], ngp_tok->name)) return(NGP_BAD_ARG); } for (j = 0; ; j++) /* now check indexed */ { if (NULL == nm[j]) return(NGP_OK); l = strlen(nm[j]); if ((l < 1) || (l > 5)) continue; if (0 == strncmp(nm[j], ngp_tok->name, l)) break; } if ((ngp_tok->name[l] < '1') || (ngp_tok->name[l] > '9')) return(NGP_OK); spc = 0; for (i = l + 1; i < 8; i++) { if (spc) { if (' ' != ngp_tok->name[i]) return(NGP_OK); } else { if ((ngp_tok->name[i] >= '0') || (ngp_tok->name[i] <= '9')) continue; if (' ' == ngp_tok->name[i]) { spc = 1; continue; } if (0 == ngp_tok->name[i]) break; return(NGP_OK); } } return(NGP_BAD_ARG); } /* write (almost) all keywords from given HDU to disk */ int ngp_keyword_all_write(NGP_HDU *ngph, fitsfile *ffp, int mode) { int i, r, ib; char buf[200]; long l; if (NULL == ngph) return(NGP_NUL_PTR); if (NULL == ffp) return(NGP_NUL_PTR); r = NGP_OK; for (i=0; itokcnt; i++) { r = ngp_keyword_is_write(&(ngph->tok[i])); if ((NGP_REALLY_ALL & mode) || (NGP_OK == r)) { switch (ngph->tok[i].type) { case NGP_TTYPE_BOOL: ib = ngph->tok[i].value.b; fits_write_key(ffp, TLOGICAL, ngph->tok[i].name, &ib, ngph->tok[i].comment, &r); break; case NGP_TTYPE_STRING: fits_write_key_longstr(ffp, ngph->tok[i].name, ngph->tok[i].value.s, ngph->tok[i].comment, &r); break; case NGP_TTYPE_INT: l = ngph->tok[i].value.i; /* bugfix - 22-Jan-99, BO - nonalignment of OSF/Alpha */ fits_write_key(ffp, TLONG, ngph->tok[i].name, &l, ngph->tok[i].comment, &r); break; case NGP_TTYPE_REAL: fits_write_key(ffp, TDOUBLE, ngph->tok[i].name, &(ngph->tok[i].value.d), ngph->tok[i].comment, &r); break; case NGP_TTYPE_COMPLEX: fits_write_key(ffp, TDBLCOMPLEX, ngph->tok[i].name, &(ngph->tok[i].value.c), ngph->tok[i].comment, &r); break; case NGP_TTYPE_NULL: fits_write_key_null(ffp, ngph->tok[i].name, ngph->tok[i].comment, &r); break; case NGP_TTYPE_RAW: if (0 == strcmp("HISTORY", ngph->tok[i].name)) { fits_write_history(ffp, ngph->tok[i].comment, &r); break; } if (0 == strcmp("COMMENT", ngph->tok[i].name)) { fits_write_comment(ffp, ngph->tok[i].comment, &r); break; } sprintf(buf, "%-8.8s%s", ngph->tok[i].name, ngph->tok[i].comment); fits_write_record(ffp, buf, &r); break; } } else if (NGP_BAD_ARG == r) /* enhancement 10 dec 2003, James Peachey: template comments replace defaults */ { r = NGP_OK; /* update comments of special keywords like TFORM */ if (ngph->tok[i].comment && *ngph->tok[i].comment) /* do not update with a blank comment */ { fits_modify_comment(ffp, ngph->tok[i].name, ngph->tok[i].comment, &r); } } else /* other problem, typically a blank token */ { r = NGP_OK; /* skip this token, but continue */ } if (r) return(r); } fits_set_hdustruc(ffp, &r); /* resync cfitsio */ return(r); } /* init HDU structure */ int ngp_hdu_init(NGP_HDU *ngph) { if (NULL == ngph) return(NGP_NUL_PTR); ngph->tok = NULL; ngph->tokcnt = 0; return(NGP_OK); } /* clear HDU structure */ int ngp_hdu_clear(NGP_HDU *ngph) { int i; if (NULL == ngph) return(NGP_NUL_PTR); for (i=0; itokcnt; i++) { if (NGP_TTYPE_STRING == ngph->tok[i].type) if (NULL != ngph->tok[i].value.s) { ngp_free(ngph->tok[i].value.s); ngph->tok[i].value.s = NULL; } } if (NULL != ngph->tok) ngp_free(ngph->tok); ngph->tok = NULL; ngph->tokcnt = 0; return(NGP_OK); } /* insert new token to HDU structure */ int ngp_hdu_insert_token(NGP_HDU *ngph, NGP_TOKEN *newtok) { NGP_TOKEN *tkp; if (NULL == ngph) return(NGP_NUL_PTR); if (NULL == newtok) return(NGP_NUL_PTR); if (0 == ngph->tokcnt) tkp = (NGP_TOKEN *)ngp_alloc((ngph->tokcnt + 1) * sizeof(NGP_TOKEN)); else tkp = (NGP_TOKEN *)ngp_realloc(ngph->tok, (ngph->tokcnt + 1) * sizeof(NGP_TOKEN)); if (NULL == tkp) return(NGP_NO_MEMORY); ngph->tok = tkp; ngph->tok[ngph->tokcnt] = *newtok; if (NGP_TTYPE_STRING == newtok->type) { if (NULL != newtok->value.s) { ngph->tok[ngph->tokcnt].value.s = (char *)ngp_alloc(1 + strlen(newtok->value.s)); if (NULL == ngph->tok[ngph->tokcnt].value.s) return(NGP_NO_MEMORY); strcpy(ngph->tok[ngph->tokcnt].value.s, newtok->value.s); } } ngph->tokcnt++; return(NGP_OK); } int ngp_append_columns(fitsfile *ff, NGP_HDU *ngph, int aftercol) { int r, i, j, exitflg, ngph_i; char *my_tform, *my_ttype; char ngph_ctmp; if (NULL == ff) return(NGP_NUL_PTR); if (NULL == ngph) return(NGP_NUL_PTR); if (0 == ngph->tokcnt) return(NGP_OK); /* nothing to do ! */ r = NGP_OK; exitflg = 0; for (j=aftercol; jtok[i].name, "TFORM%d%c", &ngph_i, &ngph_ctmp)) { if ((NGP_TTYPE_STRING == ngph->tok[i].type) && (ngph_i == (j + 1))) { my_tform = ngph->tok[i].value.s; } } else if (1 == sscanf(ngph->tok[i].name, "TTYPE%d%c", &ngph_i, &ngph_ctmp)) { if ((NGP_TTYPE_STRING == ngph->tok[i].type) && (ngph_i == (j + 1))) { my_ttype = ngph->tok[i].value.s; } } if ((NULL != my_tform) && (my_ttype[0])) break; if (i < (ngph->tokcnt - 1)) continue; exitflg = 1; break; } if ((NGP_OK == r) && (NULL != my_tform)) fits_insert_col(ff, j + 1, my_ttype, my_tform, &r); if ((NGP_OK != r) || exitflg) break; } return(r); } /* read complete HDU */ int ngp_read_xtension(fitsfile *ff, int parent_hn, int simple_mode) { int r, exflg, l, my_hn, tmp0, incrementor_index, i, j; int ngph_dim, ngph_bitpix, ngph_node_type, my_version; char incrementor_name[NGP_MAX_STRING], ngph_ctmp; char *ngph_extname = 0; long ngph_size[NGP_MAX_ARRAY_DIM]; NGP_HDU ngph; long lv; incrementor_name[0] = 0; /* signal no keyword+'#' found yet */ incrementor_index = 0; if (NGP_OK != (r = ngp_hdu_init(&ngph))) return(r); if (NGP_OK != (r = ngp_read_line(0))) return(r); /* EOF always means error here */ switch (NGP_XTENSION_SIMPLE & simple_mode) { case 0: if (NGP_TOKEN_XTENSION != ngp_keyidx) return(NGP_TOKEN_NOT_EXPECT); break; default: if (NGP_TOKEN_SIMPLE != ngp_keyidx) return(NGP_TOKEN_NOT_EXPECT); break; } if (NGP_OK != (r = ngp_hdu_insert_token(&ngph, &ngp_linkey))) return(r); for (;;) { if (NGP_OK != (r = ngp_read_line(0))) return(r); /* EOF always means error here */ exflg = 0; switch (ngp_keyidx) { case NGP_TOKEN_SIMPLE: r = NGP_TOKEN_NOT_EXPECT; break; case NGP_TOKEN_END: case NGP_TOKEN_XTENSION: case NGP_TOKEN_GROUP: r = ngp_unread_line(); /* WARNING - not break here .... */ case NGP_TOKEN_EOF: exflg = 1; break; default: l = strlen(ngp_linkey.name); if ((l >= 2) && (l <= 6)) { if ('#' == ngp_linkey.name[l - 1]) { if (0 == incrementor_name[0]) { memcpy(incrementor_name, ngp_linkey.name, l - 1); incrementor_name[l - 1] = 0; } if (((l - 1) == (int)strlen(incrementor_name)) && (0 == memcmp(incrementor_name, ngp_linkey.name, l - 1))) { incrementor_index++; } sprintf(ngp_linkey.name + l - 1, "%d", incrementor_index); } } r = ngp_hdu_insert_token(&ngph, &ngp_linkey); break; } if ((NGP_OK != r) || exflg) break; } if (NGP_OK == r) { /* we should scan keywords, and calculate HDU's */ /* structure ourselves .... */ ngph_node_type = NGP_NODE_INVALID; /* init variables */ ngph_bitpix = 0; ngph_extname = NULL; for (i=0; i=1) && (j <= NGP_MAX_ARRAY_DIM)) { ngph_size[j - 1] = ngph.tok[i].value.i; } } } switch (ngph_node_type) { case NGP_NODE_IMAGE: if (NGP_XTENSION_FIRST == ((NGP_XTENSION_FIRST | NGP_XTENSION_SIMPLE) & simple_mode)) { /* if caller signals that this is 1st HDU in file */ /* and it is IMAGE defined with XTENSION, then we */ /* need create dummy Primary HDU */ fits_create_img(ff, 16, 0, NULL, &r); } /* create image */ fits_create_img(ff, ngph_bitpix, ngph_dim, ngph_size, &r); /* update keywords */ if (NGP_OK == r) r = ngp_keyword_all_write(&ngph, ff, NGP_NON_SYSTEM_ONLY); break; case NGP_NODE_ATABLE: case NGP_NODE_BTABLE: /* create table, 0 rows and 0 columns for the moment */ fits_create_tbl(ff, ((NGP_NODE_ATABLE == ngph_node_type) ? ASCII_TBL : BINARY_TBL), 0, 0, NULL, NULL, NULL, NULL, &r); if (NGP_OK != r) break; /* add columns ... */ r = ngp_append_columns(ff, &ngph, 0); if (NGP_OK != r) break; /* add remaining keywords */ r = ngp_keyword_all_write(&ngph, ff, NGP_NON_SYSTEM_ONLY); if (NGP_OK != r) break; /* if requested add rows */ if (ngph_size[1] > 0) fits_insert_rows(ff, 0, ngph_size[1], &r); break; default: r = NGP_BAD_ARG; break; } } if ((NGP_OK == r) && (NULL != ngph_extname)) { r = ngp_get_extver(ngph_extname, &my_version); /* write correct ext version number */ lv = my_version; /* bugfix - 22-Jan-99, BO - nonalignment of OSF/Alpha */ fits_write_key(ff, TLONG, "EXTVER", &lv, "auto assigned by template parser", &r); } if (NGP_OK == r) { if (parent_hn > 0) { fits_get_hdu_num(ff, &my_hn); fits_movabs_hdu(ff, parent_hn, &tmp0, &r); /* link us to parent */ fits_add_group_member(ff, NULL, my_hn, &r); fits_movabs_hdu(ff, my_hn, &tmp0, &r); if (NGP_OK != r) return(r); } } if (NGP_OK != r) /* in case of error - delete hdu */ { tmp0 = 0; fits_delete_hdu(ff, NULL, &tmp0); } ngp_hdu_clear(&ngph); return(r); } /* read complete GROUP */ int ngp_read_group(fitsfile *ff, char *grpname, int parent_hn) { int r, exitflg, l, my_hn, tmp0, incrementor_index; char grnm[NGP_MAX_STRING]; /* keyword holding group name */ char incrementor_name[NGP_MAX_STRING]; NGP_HDU ngph; incrementor_name[0] = 0; /* signal no keyword+'#' found yet */ incrementor_index = 6; /* first 6 cols are used by group */ ngp_grplevel++; if (NGP_OK != (r = ngp_hdu_init(&ngph))) return(r); r = NGP_OK; if (NGP_OK != (r = fits_create_group(ff, grpname, GT_ID_ALL_URI, &r))) return(r); fits_get_hdu_num(ff, &my_hn); if (parent_hn > 0) { fits_movabs_hdu(ff, parent_hn, &tmp0, &r); /* link us to parent */ fits_add_group_member(ff, NULL, my_hn, &r); fits_movabs_hdu(ff, my_hn, &tmp0, &r); if (NGP_OK != r) return(r); } for (exitflg = 0; 0 == exitflg;) { if (NGP_OK != (r = ngp_read_line(0))) break; /* EOF always means error here */ switch (ngp_keyidx) { case NGP_TOKEN_SIMPLE: case NGP_TOKEN_EOF: r = NGP_TOKEN_NOT_EXPECT; break; case NGP_TOKEN_END: ngp_grplevel--; exitflg = 1; break; case NGP_TOKEN_GROUP: if (NGP_TTYPE_STRING == ngp_linkey.type) { strncpy(grnm, ngp_linkey.value.s, NGP_MAX_STRING); } else { sprintf(grnm, "DEFAULT_GROUP_%d", master_grp_idx++); } grnm[NGP_MAX_STRING - 1] = 0; r = ngp_read_group(ff, grnm, my_hn); break; /* we can have many subsequent GROUP defs */ case NGP_TOKEN_XTENSION: r = ngp_unread_line(); if (NGP_OK != r) break; r = ngp_read_xtension(ff, my_hn, 0); break; /* we can have many subsequent HDU defs */ default: l = strlen(ngp_linkey.name); if ((l >= 2) && (l <= 6)) { if ('#' == ngp_linkey.name[l - 1]) { if (0 == incrementor_name[0]) { memcpy(incrementor_name, ngp_linkey.name, l - 1); incrementor_name[l - 1] = 0; } if (((l - 1) == (int)strlen(incrementor_name)) && (0 == memcmp(incrementor_name, ngp_linkey.name, l - 1))) { incrementor_index++; } sprintf(ngp_linkey.name + l - 1, "%d", incrementor_index); } } r = ngp_hdu_insert_token(&ngph, &ngp_linkey); break; /* here we can add keyword */ } if (NGP_OK != r) break; } fits_movabs_hdu(ff, my_hn, &tmp0, &r); /* back to our HDU */ if (NGP_OK == r) /* create additional columns, if requested */ r = ngp_append_columns(ff, &ngph, 6); if (NGP_OK == r) /* and write keywords */ r = ngp_keyword_all_write(&ngph, ff, NGP_NON_SYSTEM_ONLY); if (NGP_OK != r) /* delete group in case of error */ { tmp0 = 0; fits_remove_group(ff, OPT_RM_GPT, &tmp0); } ngp_hdu_clear(&ngph); /* we are done with this HDU, so delete it */ return(r); } /* top level API functions */ /* read whole template. ff should point to the opened empty fits file. */ int fits_execute_template(fitsfile *ff, char *ngp_template, int *status) { int r, exit_flg, first_extension, i, my_hn, tmp0, keys_exist, more_keys, used_ver; char grnm[NGP_MAX_STRING], used_name[NGP_MAX_STRING]; long luv; if (NULL == status) return(NGP_NUL_PTR); if (NGP_OK != *status) return(*status); if ((NULL == ff) || (NULL == ngp_template)) { *status = NGP_NUL_PTR; return(*status); } ngp_inclevel = 0; /* initialize things, not all should be zero */ ngp_grplevel = 0; master_grp_idx = 1; exit_flg = 0; ngp_master_dir[0] = 0; /* this should be before 1st call to ngp_include_file */ first_extension = 1; /* we need to create PHDU */ if (NGP_OK != (r = ngp_delete_extver_tab())) { *status = r; return(r); } fits_get_hdu_num(ff, &my_hn); /* our HDU position */ if (my_hn <= 1) /* check whether we really need to create PHDU */ { fits_movabs_hdu(ff, 1, &tmp0, status); fits_get_hdrspace(ff, &keys_exist, &more_keys, status); fits_movabs_hdu(ff, my_hn, &tmp0, status); if (NGP_OK != *status) return(*status); /* error here means file is corrupted */ if (keys_exist > 0) first_extension = 0; /* if keywords exist assume PHDU already exist */ } else { first_extension = 0; /* PHDU (followed by 1+ extensions) exist */ for (i = 2; i<= my_hn; i++) { *status = NGP_OK; fits_movabs_hdu(ff, 1, &tmp0, status); if (NGP_OK != *status) break; fits_read_key(ff, TSTRING, "EXTNAME", used_name, NULL, status); if (NGP_OK != *status) continue; fits_read_key(ff, TLONG, "EXTVER", &luv, NULL, status); used_ver = luv; /* bugfix - 22-Jan-99, BO - nonalignment of OSF/Alpha */ if (VALUE_UNDEFINED == *status) { used_ver = 1; *status = NGP_OK; } if (NGP_OK == *status) *status = ngp_set_extver(used_name, used_ver); } fits_movabs_hdu(ff, my_hn, &tmp0, status); } if (NGP_OK != *status) return(*status); if (NGP_OK != (*status = ngp_include_file(ngp_template))) return(*status); for (i = strlen(ngp_template) - 1; i >= 0; i--) /* strlen is > 0, otherwise fopen failed */ { #ifdef MSDOS if ('\\' == ngp_template[i]) break; #else if ('/' == ngp_template[i]) break; #endif } i++; if (i > (NGP_MAX_FNAME - 1)) i = NGP_MAX_FNAME - 1; if (i > 0) { memcpy(ngp_master_dir, ngp_template, i); ngp_master_dir[i] = 0; } for (;;) { if (NGP_OK != (r = ngp_read_line(1))) break; /* EOF always means error here */ switch (ngp_keyidx) { case NGP_TOKEN_SIMPLE: if (0 == first_extension) /* simple only allowed in first HDU */ { r = NGP_TOKEN_NOT_EXPECT; break; } if (NGP_OK != (r = ngp_unread_line())) break; r = ngp_read_xtension(ff, 0, NGP_XTENSION_SIMPLE | NGP_XTENSION_FIRST); first_extension = 0; break; case NGP_TOKEN_XTENSION: if (NGP_OK != (r = ngp_unread_line())) break; r = ngp_read_xtension(ff, 0, (first_extension ? NGP_XTENSION_FIRST : 0)); first_extension = 0; break; case NGP_TOKEN_GROUP: if (NGP_TTYPE_STRING == ngp_linkey.type) { strncpy(grnm, ngp_linkey.value.s, NGP_MAX_STRING); } else { sprintf(grnm, "DEFAULT_GROUP_%d", master_grp_idx++); } grnm[NGP_MAX_STRING - 1] = 0; r = ngp_read_group(ff, grnm, 0); first_extension = 0; break; case NGP_TOKEN_EOF: exit_flg = 1; break; default: r = NGP_TOKEN_NOT_EXPECT; break; } if (exit_flg || (NGP_OK != r)) break; } /* all top level HDUs up to faulty one are left intact in case of i/o error. It is up to the caller to call fits_close_file or fits_delete_file when this function returns error. */ ngp_free_line(); /* deallocate last line (if any) */ ngp_free_prevline(); /* deallocate cached line (if any) */ ngp_delete_extver_tab(); /* delete extver table (if present), error ignored */ *status = r; return(r); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/grparser.h000066400000000000000000000132651215713201500224350ustar00rootroot00000000000000/* T E M P L A T E P A R S E R H E A D E R F I L E ===================================================== by Jerzy.Borkowski@obs.unige.ch Integral Science Data Center ch. d'Ecogia 16 1290 Versoix Switzerland 14-Oct-98: initial release 16-Oct-98: reference to fitsio.h removed, also removed strings after #endif directives to make gcc -Wall not to complain 20-Oct-98: added declarations NGP_XTENSION_SIMPLE and NGP_XTENSION_FIRST 24-Oct-98: prototype of ngp_read_line() function updated. 22-Jan-99: prototype for ngp_set_extver() function added. 20-Jun-2002 Wm Pence, added support for the HIERARCH keyword convention (changed NGP_MAX_NAME from (20) to FLEN_KEYWORD) */ #ifndef GRPARSER_H_INCLUDED #define GRPARSER_H_INCLUDED #ifdef __cplusplus extern "C" { #endif /* error codes - now defined in fitsio.h */ /* common constants definitions */ #define NGP_ALLOCCHUNK (1000) #define NGP_MAX_INCLUDE (10) /* include file nesting limit */ #define NGP_MAX_COMMENT (80) /* max size for comment */ #define NGP_MAX_NAME FLEN_KEYWORD /* max size for KEYWORD (FITS limits it to 8 chars) */ /* except HIERARCH can have longer effective keyword names */ #define NGP_MAX_STRING (80) /* max size for various strings */ #define NGP_MAX_ARRAY_DIM (999) /* max. number of dimensions in array */ #define NGP_MAX_FNAME (1000) /* max size of combined path+fname */ #define NGP_MAX_ENVFILES (10000) /* max size of CFITSIO_INCLUDE_FILES env. variable */ #define NGP_TOKEN_UNKNOWN (-1) /* token type unknown */ #define NGP_TOKEN_INCLUDE (0) /* \INCLUDE token */ #define NGP_TOKEN_GROUP (1) /* \GROUP token */ #define NGP_TOKEN_END (2) /* \END token */ #define NGP_TOKEN_XTENSION (3) /* XTENSION token */ #define NGP_TOKEN_SIMPLE (4) /* SIMPLE token */ #define NGP_TOKEN_EOF (5) /* End Of File pseudo token */ #define NGP_TTYPE_UNKNOWN (0) /* undef (yet) token type - invalid to print/write to disk */ #define NGP_TTYPE_BOOL (1) /* boolean, it is 'T' or 'F' */ #define NGP_TTYPE_STRING (2) /* something withing "" or starting with letter */ #define NGP_TTYPE_INT (3) /* starting with digit and not with '.' */ #define NGP_TTYPE_REAL (4) /* digits + '.' */ #define NGP_TTYPE_COMPLEX (5) /* 2 reals, separated with ',' */ #define NGP_TTYPE_NULL (6) /* NULL token, format is : NAME = / comment */ #define NGP_TTYPE_RAW (7) /* HISTORY/COMMENT/8SPACES + comment string without / */ #define NGP_FOUND_EQUAL_SIGN (1) /* line contains '=' after keyword name */ #define NGP_FORMAT_OK (0) /* line format OK */ #define NGP_FORMAT_ERROR (1) /* line format error */ #define NGP_NODE_INVALID (0) /* default node type - invalid (to catch errors) */ #define NGP_NODE_IMAGE (1) /* IMAGE type */ #define NGP_NODE_ATABLE (2) /* ASCII table type */ #define NGP_NODE_BTABLE (3) /* BINARY table type */ #define NGP_NON_SYSTEM_ONLY (0) /* save all keywords except NAXIS,BITPIX,etc.. */ #define NGP_REALLY_ALL (1) /* save really all keywords */ #define NGP_XTENSION_SIMPLE (1) /* HDU defined with SIMPLE T */ #define NGP_XTENSION_FIRST (2) /* this is first extension in template */ #define NGP_LINE_REREAD (1) /* reread line */ #define NGP_BITPIX_INVALID (-12345) /* default BITPIX (to catch errors) */ /* common macro definitions */ #ifdef NGP_PARSER_DEBUG_MALLOC #define ngp_alloc(x) dal_malloc(x) #define ngp_free(x) dal_free(x) #define ngp_realloc(x,y) dal_realloc(x,y) #else #define ngp_alloc(x) malloc(x) #define ngp_free(x) free(x) #define ngp_realloc(x,y) realloc(x,y) #endif /* type definitions */ typedef struct NGP_RAW_LINE_STRUCT { char *line; char *name; char *value; int type; char *comment; int format; int flags; } NGP_RAW_LINE; typedef union NGP_TOKVAL_UNION { char *s; /* space allocated separately, be careful !!! */ char b; int i; double d; struct NGP_COMPLEX_STRUCT { double re; double im; } c; /* complex value */ } NGP_TOKVAL; typedef struct NGP_TOKEN_STRUCT { int type; char name[NGP_MAX_NAME]; NGP_TOKVAL value; char comment[NGP_MAX_COMMENT]; } NGP_TOKEN; typedef struct NGP_HDU_STRUCT { int tokcnt; NGP_TOKEN *tok; } NGP_HDU; typedef struct NGP_TKDEF_STRUCT { char *name; int code; } NGP_TKDEF; typedef struct NGP_EXTVER_TAB_STRUCT { char *extname; int version; } NGP_EXTVER_TAB; /* globally visible variables declarations */ extern NGP_RAW_LINE ngp_curline; extern NGP_RAW_LINE ngp_prevline; extern int ngp_extver_tab_size; extern NGP_EXTVER_TAB *ngp_extver_tab; /* globally visible functions declarations */ int ngp_get_extver(char *extname, int *version); int ngp_set_extver(char *extname, int version); int ngp_delete_extver_tab(void); int ngp_strcasecmp(char *p1, char *p2); int ngp_strcasencmp(char *p1, char *p2, int n); int ngp_line_from_file(FILE *fp, char **p); int ngp_free_line(void); int ngp_free_prevline(void); int ngp_read_line_buffered(FILE *fp); int ngp_unread_line(void); int ngp_extract_tokens(NGP_RAW_LINE *cl); int ngp_include_file(char *fname); int ngp_read_line(int ignore_blank_lines); int ngp_keyword_is_write(NGP_TOKEN *ngp_tok); int ngp_keyword_all_write(NGP_HDU *ngph, fitsfile *ffp, int mode); int ngp_hdu_init(NGP_HDU *ngph); int ngp_hdu_clear(NGP_HDU *ngph); int ngp_hdu_insert_token(NGP_HDU *ngph, NGP_TOKEN *newtok); int ngp_append_columns(fitsfile *ff, NGP_HDU *ngph, int aftercol); int ngp_read_xtension(fitsfile *ff, int parent_hn, int simple_mode); int ngp_read_group(fitsfile *ff, char *grpname, int parent_hn); /* top level API function - now defined in fitsio.h */ #ifdef __cplusplus } #endif #endif skycat-3.1.2-starlink-1b/astrotcl/cfitsio/histo.c000066400000000000000000001302271215713201500217270ustar00rootroot00000000000000/* Globally defined histogram parameters */ #include #include #include #include #include "fitsio2.h" typedef struct { /* Structure holding all the histogramming information */ union { /* the iterator work functions (ffwritehist, ffcalchist) */ char *b; /* need to do their job... passed via *userPointer. */ short *i; int *j; float *r; double *d; } hist; fitsfile *tblptr; int haxis, hcolnum[4], himagetype; long haxis1, haxis2, haxis3, haxis4; float amin1, amin2, amin3, amin4; float maxbin1, maxbin2, maxbin3, maxbin4; float binsize1, binsize2, binsize3, binsize4; int wtrecip, wtcolnum; float weight; char *rowselector; } histType; /*--------------------------------------------------------------------------*/ int ffbins(char *binspec, /* I - binning specification */ int *imagetype, /* O - image type, TINT or TSHORT */ int *histaxis, /* O - no. of axes in the histogram */ char colname[4][FLEN_VALUE], /* column name for axis */ double *minin, /* minimum value for each axis */ double *maxin, /* maximum value for each axis */ double *binsizein, /* size of bins on each axis */ char minname[4][FLEN_VALUE], /* keyword name for min */ char maxname[4][FLEN_VALUE], /* keyword name for max */ char binname[4][FLEN_VALUE], /* keyword name for binsize */ double *wt, /* weighting factor */ char *wtname, /* keyword or column name for weight */ int *recip, /* the reciprocal of the weight? */ int *status) { /* Parse the input binning specification string, returning the binning parameters. Supports up to 4 dimensions. The binspec string has one of these forms: bin binsize - 2D histogram with binsize on each axis bin xcol - 1D histogram on column xcol bin (xcol, ycol) = binsize - 2D histogram with binsize on each axis bin x=min:max:size, y=min:max:size, z..., t... bin x=:max, y=::size bin x=size, y=min::size most other reasonable combinations are supported. */ int ii, slen, defaulttype; char *ptr, tmpname[30], *file_expr = NULL; double dummy; if (*status > 0) return(*status); /* set the default values */ *histaxis = 2; *imagetype = TINT; defaulttype = 1; *wt = 1.; *recip = 0; *wtname = '\0'; /* set default values */ for (ii = 0; ii < 4; ii++) { *colname[ii] = '\0'; *minname[ii] = '\0'; *maxname[ii] = '\0'; *binname[ii] = '\0'; minin[ii] = DOUBLENULLVALUE; /* undefined values */ maxin[ii] = DOUBLENULLVALUE; binsizein[ii] = DOUBLENULLVALUE; } ptr = binspec + 3; /* skip over 'bin' */ if (*ptr == 'i' ) /* bini */ { *imagetype = TSHORT; defaulttype = 0; ptr++; } else if (*ptr == 'j' ) /* binj; same as default */ { defaulttype = 0; ptr ++; } else if (*ptr == 'r' ) /* binr */ { *imagetype = TFLOAT; defaulttype = 0; ptr ++; } else if (*ptr == 'd' ) /* bind */ { *imagetype = TDOUBLE; defaulttype = 0; ptr ++; } else if (*ptr == 'b' ) /* binb */ { *imagetype = TBYTE; defaulttype = 0; ptr ++; } if (*ptr == '\0') /* use all defaults for other parameters */ return(*status); else if (*ptr != ' ') /* must be at least one blank */ { ffpmsg("binning specification syntax error:"); ffpmsg(binspec); return(*status = URL_PARSE_ERROR); } while (*ptr == ' ') /* skip over blanks */ ptr++; if (*ptr == '\0') /* no other parameters; use defaults */ return(*status); /* Check if need to import expression from a file */ if( *ptr=='@' ) { if( ffimport_file( ptr+1, &file_expr, status ) ) return(*status); ptr = file_expr; while (*ptr == ' ') ptr++; /* skip leading white space... again */ } if (*ptr == '(' ) { /* this must be the opening parenthesis around a list of column */ /* names, optionally followed by a '=' and the binning spec. */ for (ii = 0; ii < 4; ii++) { ptr++; /* skip over the '(', ',', or ' ') */ while (*ptr == ' ') /* skip over blanks */ ptr++; slen = strcspn(ptr, " ,)"); strncat(colname[ii], ptr, slen); /* copy 1st column name */ ptr += slen; while (*ptr == ' ') /* skip over blanks */ ptr++; if (*ptr == ')' ) /* end of the list of names */ { *histaxis = ii + 1; break; } } if (ii == 4) /* too many names in the list , or missing ')' */ { ffpmsg( "binning specification has too many column names or is missing closing ')':"); ffpmsg(binspec); if( file_expr ) free( file_expr ); return(*status = URL_PARSE_ERROR); } ptr++; /* skip over the closing parenthesis */ while (*ptr == ' ') /* skip over blanks */ ptr++; if (*ptr == '\0') { if( file_expr ) free( file_expr ); return(*status); /* parsed the entire string */ } else if (*ptr != '=') /* must be an equals sign now*/ { ffpmsg("illegal binning specification in URL:"); ffpmsg(" an equals sign '=' must follow the column names"); ffpmsg(binspec); if( file_expr ) free( file_expr ); return(*status = URL_PARSE_ERROR); } ptr++; /* skip over the equals sign */ while (*ptr == ' ') /* skip over blanks */ ptr++; /* get the single range specification for all the columns */ ffbinr(&ptr, tmpname, minin, maxin, binsizein, minname[0], maxname[0], binname[0], status); if (*status > 0) { ffpmsg("illegal binning specification in URL:"); ffpmsg(binspec); if( file_expr ) free( file_expr ); return(*status); } for (ii = 1; ii < *histaxis; ii++) { minin[ii] = minin[0]; maxin[ii] = maxin[0]; binsizein[ii] = binsizein[0]; strcpy(minname[ii], minname[0]); strcpy(maxname[ii], maxname[0]); strcpy(binname[ii], binname[0]); } while (*ptr == ' ') /* skip over blanks */ ptr++; if (*ptr == ';') goto getweight; /* a weighting factor is specified */ if (*ptr != '\0') /* must have reached end of string */ { ffpmsg("illegal syntax after binning range specification in URL:"); ffpmsg(binspec); if( file_expr ) free( file_expr ); return(*status = URL_PARSE_ERROR); } return(*status); } /* end of case with list of column names in ( ) */ /* if we've reached this point, then the binning specification */ /* must be of the form: XCOL = min:max:binsize, YCOL = ... */ /* where the column name followed by '=' are optional. */ /* If the column name is not specified, then use the default name */ for (ii = 0; ii < 4; ii++) /* allow up to 4 histogram dimensions */ { ffbinr(&ptr, colname[ii], &minin[ii], &maxin[ii], &binsizein[ii], minname[ii], maxname[ii], binname[ii], status); if (*status > 0) { ffpmsg("illegal syntax in binning range specification in URL:"); ffpmsg(binspec); if( file_expr ) free( file_expr ); return(*status); } if (*ptr == '\0' || *ptr == ';') break; /* reached the end of the string */ if (*ptr == ' ') { while (*ptr == ' ') /* skip over blanks */ ptr++; if (*ptr == '\0' || *ptr == ';') break; /* reached the end of the string */ if (*ptr == ',') ptr++; /* comma separates the next column specification */ } else if (*ptr == ',') { ptr++; /* comma separates the next column specification */ } else { ffpmsg("illegal characters following binning specification in URL:"); ffpmsg(binspec); if( file_expr ) free( file_expr ); return(*status = URL_PARSE_ERROR); } } if (ii == 4) { /* there are yet more characters in the string */ ffpmsg("illegal binning specification in URL:"); ffpmsg("apparently greater than 4 histogram dimensions"); ffpmsg(binspec); return(*status = URL_PARSE_ERROR); } else *histaxis = ii + 1; /* special case: if a single number was entered it should be */ /* interpreted as the binning factor for the default X and Y axes */ if (*histaxis == 1 && *colname[0] == '\0' && minin[0] == DOUBLENULLVALUE && maxin[0] == DOUBLENULLVALUE) { *histaxis = 2; binsizein[1] = binsizein[0]; } getweight: if (*ptr == ';') /* looks like a weighting factor is given */ { ptr++; while (*ptr == ' ') /* skip over blanks */ ptr++; recip = 0; if (*ptr == '/') { *recip = 1; /* the reciprocal of the weight is entered */ ptr++; while (*ptr == ' ') /* skip over blanks */ ptr++; } /* parse the weight as though it were a binrange. */ /* either a column name or a numerical value will be returned */ ffbinr(&ptr, wtname, &dummy, &dummy, wt, tmpname, tmpname, tmpname, status); if (*status > 0) { ffpmsg("illegal binning weight specification in URL:"); ffpmsg(binspec); if( file_expr ) free( file_expr ); return(*status); } /* creat a float datatype histogram by default, if weight */ /* factor is not = 1.0 */ if (defaulttype && *wt != 1.0) *imagetype = TFLOAT; } while (*ptr == ' ') /* skip over blanks */ ptr++; if (*ptr != '\0') /* should have reached the end of string */ { ffpmsg("illegal syntax after binning weight specification in URL:"); ffpmsg(binspec); *status = URL_PARSE_ERROR; } if( file_expr ) free( file_expr ); return(*status); } /*--------------------------------------------------------------------------*/ int ffbinr(char **ptr, char *colname, double *minin, double *maxin, double *binsizein, char *minname, char *maxname, char *binname, int *status) /* Parse the input binning range specification string, returning the column name, histogram min and max values, and bin size. */ { int slen, isanumber; char token[FLEN_VALUE]; if (*status > 0) return(*status); slen = fits_get_token(ptr, " ,=:;", token, &isanumber); /* get 1st token */ if (slen == 0 && (**ptr == '\0' || **ptr == ',' || **ptr == ';') ) return(*status); /* a null range string */ if (!isanumber && **ptr != ':') { /* this looks like the column name */ if (token[0] == '#' && isdigit((int) token[1]) ) { /* omit the leading '#' in the column number */ strcpy(colname, token+1); } else strcpy(colname, token); while (**ptr == ' ') /* skip over blanks */ (*ptr)++; if (**ptr != '=') return(*status); /* reached the end */ (*ptr)++; /* skip over the = sign */ while (**ptr == ' ') /* skip over blanks */ (*ptr)++; slen = fits_get_token(ptr, " ,:;", token, &isanumber); /* get token */ } if (**ptr != ':') { /* this is the first token, and since it is not followed by */ /* a ':' this must be the binsize token */ if (!isanumber) strcpy(binname, token); else *binsizein = strtod(token, NULL); return(*status); /* reached the end */ } else { /* the token contains the min value */ if (slen) { if (!isanumber) strcpy(minname, token); else *minin = strtod(token, NULL); } } (*ptr)++; /* skip the colon between the min and max values */ slen = fits_get_token(ptr, " ,:;", token, &isanumber); /* get token */ /* the token contains the max value */ if (slen) { if (!isanumber) strcpy(maxname, token); else *maxin = strtod(token, NULL); } if (**ptr != ':') return(*status); /* reached the end; no binsize token */ (*ptr)++; /* skip the colon between the max and binsize values */ slen = fits_get_token(ptr, " ,:;", token, &isanumber); /* get token */ /* the token contains the binsize value */ if (slen) { if (!isanumber) strcpy(binname, token); else *binsizein = strtod(token, NULL); } return(*status); } /*--------------------------------------------------------------------------*/ int ffhist(fitsfile **fptr, /* IO - pointer to table with X and Y cols; */ /* on output, points to histogram image */ char *outfile, /* I - name for the output histogram file */ int imagetype, /* I - datatype for image: TINT, TSHORT, etc */ int naxis, /* I - number of axes in the histogram image */ char colname[4][FLEN_VALUE], /* I - column names */ double *minin, /* I - minimum histogram value, for each axis */ double *maxin, /* I - maximum histogram value, for each axis */ double *binsizein, /* I - bin size along each axis */ char minname[4][FLEN_VALUE], /* I - optional keywords for min */ char maxname[4][FLEN_VALUE], /* I - optional keywords for max */ char binname[4][FLEN_VALUE], /* I - optional keywords for binsize */ double weightin, /* I - binning weighting factor */ char wtcol[FLEN_VALUE], /* I - optional keyword or col for weight*/ int recip, /* I - use reciprocal of the weight? */ char *selectrow, /* I - optional array (length = no. of */ /* rows in the table). If the element is true */ /* then the corresponding row of the table will*/ /* be included in the histogram, otherwise the */ /* row will be skipped. Ingnored if *selectrow*/ /* is equal to NULL. */ int *status) { int ii, datatype, repeat, imin, imax, ibin, bitpix, tstatus, use_datamax = 0; long haxes[4]; fitsfile *histptr; char errmsg[FLEN_ERRMSG], keyname[FLEN_KEYWORD], card[FLEN_CARD]; tcolumn *colptr; iteratorCol imagepars[1]; int n_cols = 1, nkeys; long offset = 0; long n_per_loop = -1; /* force whole array to be passed at one time */ histType histData; /* Structure holding histogram info for iterator */ float amin[4], amax[4], binsize[4], maxbin[4]; float datamin = FLOATNULLVALUE, datamax = FLOATNULLVALUE; char svalue[FLEN_VALUE]; double dvalue; char cpref[4][FLEN_VALUE]; char *cptr; if (*status > 0) return(*status); if (naxis > 4) { ffpmsg("histogram has more than 4 dimensions"); return(*status = BAD_DIMEN); } /* reset position to the correct HDU if necessary */ if ((*fptr)->HDUposition != ((*fptr)->Fptr)->curhdu) ffmahd(*fptr, ((*fptr)->HDUposition) + 1, NULL, status); histData.tblptr = *fptr; histData.himagetype = imagetype; histData.haxis = naxis; histData.rowselector = selectrow; if (imagetype == TBYTE) bitpix = BYTE_IMG; else if (imagetype == TSHORT) bitpix = SHORT_IMG; else if (imagetype == TINT) bitpix = LONG_IMG; else if (imagetype == TFLOAT) bitpix = FLOAT_IMG; else if (imagetype == TDOUBLE) bitpix = DOUBLE_IMG; else return(*status = BAD_DATATYPE); /* The CPREF keyword, if it exists, gives the preferred columns. */ /* Otherwise, assume "X", "Y", "Z", and "T" */ tstatus = 0; ffgky(*fptr, TSTRING, "CPREF", cpref[0], NULL, &tstatus); if (!tstatus) { /* Preferred column names are given; separate them */ cptr = cpref[0]; /* the first preferred axis... */ while (*cptr != ',' && *cptr != '\0') cptr++; if (*cptr != '\0') { *cptr = '\0'; cptr++; while (*cptr == ' ') cptr++; strcpy(cpref[1], cptr); cptr = cpref[1]; /* the second preferred axis... */ while (*cptr != ',' && *cptr != '\0') cptr++; if (*cptr != '\0') { *cptr = '\0'; cptr++; while (*cptr == ' ') cptr++; strcpy(cpref[2], cptr); cptr = cpref[2]; /* the third preferred axis... */ while (*cptr != ',' && *cptr != '\0') cptr++; if (*cptr != '\0') { *cptr = '\0'; cptr++; while (*cptr == ' ') cptr++; strcpy(cpref[3], cptr); } } } } for (ii = 0; ii < naxis; ii++) { /* get the min, max, and binsize values from keywords, if specified */ if (*minname[ii]) { if (ffgky(*fptr, TDOUBLE, minname[ii], &minin[ii], NULL, status) ) { ffpmsg("error reading histogramming minimum keyword"); ffpmsg(minname[ii]); return(*status); } } if (*maxname[ii]) { if (ffgky(*fptr, TDOUBLE, maxname[ii], &maxin[ii], NULL, status) ) { ffpmsg("error reading histogramming maximum keyword"); ffpmsg(maxname[ii]); return(*status); } } if (*binname[ii]) { if (ffgky(*fptr, TDOUBLE, binname[ii], &binsizein[ii], NULL, status) ) { ffpmsg("error reading histogramming binsize keyword"); ffpmsg(binname[ii]); return(*status); } } if (binsizein[ii] == 0.) { ffpmsg("error: histogram binsize = 0"); return(*status = ZERO_SCALE); } if (*colname[ii] == '\0') { strcpy(colname[ii], cpref[ii]); /* try using the preferred column */ if (*colname[ii] == '\0') { if (ii == 0) strcpy(colname[ii], "X"); else if (ii == 1) strcpy(colname[ii], "Y"); else if (ii == 2) strcpy(colname[ii], "Z"); else if (ii == 3) strcpy(colname[ii], "T"); } } /* get the column number in the table */ if (ffgcno(*fptr, CASEINSEN, colname[ii], histData.hcolnum+ii, status) > 0) { strcpy(errmsg, "column for histogram axis doesn't exist: "); strcat(errmsg, colname[ii]); ffpmsg(errmsg); return(*status); } colptr = ((*fptr)->Fptr)->tableptr; colptr += (histData.hcolnum[ii] - 1); repeat = (int) colptr->trepeat; /* vector repeat factor of the column */ if (repeat > 1) { strcpy(errmsg, "Can't bin a vector column: "); strcat(errmsg, colname[ii]); ffpmsg(errmsg); return(*status = BAD_DATATYPE); } /* get the datatype of the column */ fits_get_coltype(*fptr, histData.hcolnum[ii], &datatype, NULL, NULL, status); if (datatype < 0 || datatype == TSTRING) { strcpy(errmsg, "Inappropriate datatype; can't bin this column: "); strcat(errmsg, colname[ii]); ffpmsg(errmsg); return(*status = BAD_DATATYPE); } /* use TLMINn and TLMAXn keyword values if min and max were not given */ /* else use actual data min and max if TLMINn and TLMAXn don't exist */ if (minin[ii] == DOUBLENULLVALUE) { ffkeyn("TLMIN", histData.hcolnum[ii], keyname, status); if (ffgky(*fptr, TFLOAT, keyname, amin+ii, NULL, status) > 0) { /* use actual data minimum value for the histogram minimum */ *status = 0; if (fits_get_col_minmax(*fptr, histData.hcolnum[ii], amin+ii, &datamax, status) > 0) { strcpy(errmsg, "Error calculating datamin and datamax for column: "); strcat(errmsg, colname[ii]); ffpmsg(errmsg); return(*status); } } } else { amin[ii] = (float) minin[ii]; } if (maxin[ii] == DOUBLENULLVALUE) { ffkeyn("TLMAX", histData.hcolnum[ii], keyname, status); if (ffgky(*fptr, TFLOAT, keyname, &amax[ii], NULL, status) > 0) { *status = 0; if(datamax != FLOATNULLVALUE) /* already computed max value */ { amax[ii] = datamax; } else { /* use actual data maximum value for the histogram maximum */ if (fits_get_col_minmax(*fptr, histData.hcolnum[ii], &datamin, &amax[ii], status) > 0) { strcpy(errmsg, "Error calculating datamin and datamax for column: "); strcat(errmsg, colname[ii]); ffpmsg(errmsg); return(*status); } } } use_datamax = 1; /* flag that the max was determined by the data values */ /* and not specifically set by the calling program */ } else { amax[ii] = (float) maxin[ii]; } /* use TDBINn keyword or else 1 if bin size is not given */ if (binsizein[ii] == DOUBLENULLVALUE) { tstatus = 0; ffkeyn("TDBIN", histData.hcolnum[ii], keyname, &tstatus); if (ffgky(*fptr, TDOUBLE, keyname, binsizein + ii, NULL, &tstatus) > 0) { /* make at least 10 bins */ binsizein[ii] = (amax[ii] - amin[ii]) / 10. ; if (binsizein[ii] > 1.) binsizein[ii] = 1.; /* use default bin size */ } } if ( (amin[ii] > amax[ii] && binsizein[ii] > 0. ) || (amin[ii] < amax[ii] && binsizein[ii] < 0. ) ) binsize[ii] = (float) -binsizein[ii]; /* reverse the sign of binsize */ else binsize[ii] = (float) binsizein[ii]; /* binsize has the correct sign */ ibin = (int) binsize[ii]; imin = (int) amin[ii]; imax = (int) amax[ii]; /* Determine the range and number of bins in the histogram. This */ /* depends on whether the input columns are integer or floats, so */ /* treat each case separately. */ if (datatype <= TLONG && (float) imin == amin[ii] && (float) imax == amax[ii] && (float) ibin == binsize[ii] ) { /* This is an integer column and integer limits were entered. */ /* Shift the lower and upper histogramming limits by 0.5, so that */ /* the values fall in the center of the bin, not on the edge. */ haxes[ii] = (imax - imin) / ibin + 1; /* last bin may only */ /* be partially full */ maxbin[ii] = (float) (haxes[ii] + 1.); /* add 1. instead of .5 to avoid roundoff */ if (amin[ii] < amax[ii]) { amin[ii] = (float) (amin[ii] - 0.5); amax[ii] = (float) (amax[ii] + 0.5); } else { amin[ii] = (float) (amin[ii] + 0.5); amax[ii] = (float) (amax[ii] - 0.5); } } else if (use_datamax) { /* Either the column datatype and/or the limits are floating point, */ /* and the histogram limits are being defined by the min and max */ /* values of the array. Add 1 to the number of histogram bins to */ /* make sure that pixels that are equal to the maximum or are */ /* in the last partial bin are included. */ maxbin[ii] = (amax[ii] - amin[ii]) / binsize[ii]; haxes[ii] = (long) (maxbin[ii] + 1); } else { /* float datatype column and/or limits, and the maximum value to */ /* include in the histogram is specified by the calling program. */ /* The lower limit is inclusive, but upper limit is exclusive */ maxbin[ii] = (amax[ii] - amin[ii]) / binsize[ii]; haxes[ii] = (long) maxbin[ii]; if (amin[ii] < amax[ii]) { if (amin[ii] + (haxes[ii] * binsize[ii]) < amax[ii]) haxes[ii]++; /* need to include another partial bin */ } else { if (amin[ii] + (haxes[ii] * binsize[ii]) > amax[ii]) haxes[ii]++; /* need to include another partial bin */ } } } /* get the histogramming weighting factor */ if (*wtcol) { /* first, look for a keyword with the weight value */ if (ffgky(*fptr, TFLOAT, wtcol, &histData.weight, NULL, status) ) { /* not a keyword, so look for column with this name */ *status = 0; /* get the column number in the table */ if (ffgcno(*fptr, CASEINSEN, wtcol, &histData.wtcolnum, status) > 0) { ffpmsg( "keyword or column for histogram weights doesn't exist: "); ffpmsg(wtcol); return(*status); } histData.weight = FLOATNULLVALUE; } } else histData.weight = (float) weightin; if (histData.weight <= 0. && histData.weight != FLOATNULLVALUE) { ffpmsg("Illegal histogramming weighting factor <= 0."); return(*status = URL_PARSE_ERROR); } if (recip && histData.weight != FLOATNULLVALUE) /* take reciprocal of weight */ histData.weight = (float) (1.0 / histData.weight); histData.wtrecip = recip; /* size of histogram is now known, so create temp output file */ if (ffinit(&histptr, outfile, status) > 0) { ffpmsg("failed to create temp output file for histogram"); return(*status); } if (ffcrim(histptr, bitpix, histData.haxis, haxes, status) > 0) { ffpmsg("failed to create primary array histogram in temp file"); ffclos(histptr, status); return(*status); } /* copy all non-structural keywords from the table to the image */ fits_get_hdrspace(*fptr, &nkeys, NULL, status); for (ii = 1; ii <= nkeys; ii++) { fits_read_record(*fptr, ii, card, status); if (fits_get_keyclass(card) >= 120) fits_write_record(histptr, card, status); } /* Set global variables with histogram parameter values. */ /* Use separate scalar variables rather than arrays because */ /* it is more efficient when computing the histogram. */ histData.amin1 = amin[0]; histData.maxbin1 = maxbin[0]; histData.binsize1 = binsize[0]; histData.haxis1 = haxes[0]; if (histData.haxis > 1) { histData.amin2 = amin[1]; histData.maxbin2 = maxbin[1]; histData.binsize2 = binsize[1]; histData.haxis2 = haxes[1]; if (histData.haxis > 2) { histData.amin3 = amin[2]; histData.maxbin3 = maxbin[2]; histData.binsize3 = binsize[2]; histData.haxis3 = haxes[2]; if (histData.haxis > 3) { histData.amin4 = amin[3]; histData.maxbin4 = maxbin[3]; histData.binsize4 = binsize[3]; histData.haxis4 = haxes[3]; } } } /* define parameters of image for the iterator function */ fits_iter_set_file(imagepars, histptr); /* pointer to image */ fits_iter_set_datatype(imagepars, imagetype); /* image datatype */ fits_iter_set_iotype(imagepars, OutputCol); /* image is output */ /* call the iterator function to write out the histogram image */ if (fits_iterate_data(n_cols, imagepars, offset, n_per_loop, ffwritehisto, (void*)&histData, status) ) return(*status); /* write the World Coordinate System (WCS) keywords */ /* create default values if WCS keywords are not present in the table */ for (ii = 0; ii < histData.haxis; ii++) { /* CTYPEn */ tstatus = 0; ffkeyn("TCTYP", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TSTRING, keyname, svalue, NULL, &tstatus); if (tstatus) { /* just use column name as the type */ tstatus = 0; ffkeyn("TTYPE", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TSTRING, keyname, svalue, NULL, &tstatus); } if (!tstatus) { ffkeyn("CTYPE", ii + 1, keyname, &tstatus); ffpky(histptr, TSTRING, keyname, svalue, "Coordinate Type", &tstatus); } else tstatus = 0; /* CUNITn */ ffkeyn("TCUNI", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TSTRING, keyname, svalue, NULL, &tstatus); if (tstatus) { /* use the column units */ tstatus = 0; ffkeyn("TUNIT", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TSTRING, keyname, svalue, NULL, &tstatus); } if (!tstatus) { ffkeyn("CUNIT", ii + 1, keyname, &tstatus); ffpky(histptr, TSTRING, keyname, svalue, "Coordinate Units", &tstatus); } else tstatus = 0; /* CRPIXn - Reference Pixel */ ffkeyn("TCRPX", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (tstatus) { dvalue = 1.0; /* choose first pixel in new image as ref. pix. */ tstatus = 0; } else { /* calculate locate of the ref. pix. in the new image */ dvalue = (dvalue - amin[ii]) / binsize[ii] + .5; } ffkeyn("CRPIX", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Reference Pixel", &tstatus); /* CRVALn - Value at the location of the reference pixel */ ffkeyn("TCRVL", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (tstatus) { /* calculate value at ref. pix. location (at center of 1st pixel) */ dvalue = amin[ii] + binsize[ii]/2.; tstatus = 0; } ffkeyn("CRVAL", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Reference Value", &tstatus); /* CDELTn - unit size of pixels */ ffkeyn("TCDLT", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (tstatus) { dvalue = 1.0; /* use default pixel size */ tstatus = 0; } dvalue = dvalue * binsize[ii]; ffkeyn("CDELT", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Pixel size", &tstatus); /* CROTAn - Rotation angle (degrees CCW) */ /* There should only be a CROTA2 keyword, and only for 2+ D images */ if (ii == 1) { ffkeyn("TCROT", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (!tstatus && dvalue != 0.) /* only write keyword if angle != 0 */ { ffkeyn("CROTA", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Rotation angle", &tstatus); } else { /* didn't find CROTA for the 2nd axis, so look for one */ /* on the first axis */ tstatus = 0; ffkeyn("TCROT", histData.hcolnum[0], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (!tstatus && dvalue != 0.) /* only write keyword if angle != 0 */ { dvalue *= -1.; /* negate the value, because mirror image */ ffkeyn("CROTA", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Rotation angle", &tstatus); } } } } /* convert any TPn_k keywords to PCi_j; the value remains unchanged */ /* also convert any TCn_k to CDi_j; the value is modified by n binning size */ /* This is a bit of a kludge, and only works for 2D WCS */ if (histData.haxis == 2) { /* PC1_1 */ tstatus = 0; ffkeyn("TP", histData.hcolnum[0], card, &tstatus); strcat(card,"_"); ffkeyn(card, histData.hcolnum[0], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) ffpky(histptr, TDOUBLE, "PC1_1", &dvalue, card, &tstatus); tstatus = 0; keyname[1] = 'C'; ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) { dvalue *= binsize[0]; ffpky(histptr, TDOUBLE, "CD1_1", &dvalue, card, &tstatus); } /* PC1_2 */ tstatus = 0; ffkeyn("TP", histData.hcolnum[0], card, &tstatus); strcat(card,"_"); ffkeyn(card, histData.hcolnum[1], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) ffpky(histptr, TDOUBLE, "PC1_2", &dvalue, card, &tstatus); tstatus = 0; keyname[1] = 'C'; ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) { dvalue *= binsize[0]; ffpky(histptr, TDOUBLE, "CD1_2", &dvalue, card, &tstatus); } /* PC2_1 */ tstatus = 0; ffkeyn("TP", histData.hcolnum[1], card, &tstatus); strcat(card,"_"); ffkeyn(card, histData.hcolnum[0], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) ffpky(histptr, TDOUBLE, "PC2_1", &dvalue, card, &tstatus); tstatus = 0; keyname[1] = 'C'; ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) { dvalue *= binsize[1]; ffpky(histptr, TDOUBLE, "CD2_1", &dvalue, card, &tstatus); } /* PC2_2 */ tstatus = 0; ffkeyn("TP", histData.hcolnum[1], card, &tstatus); strcat(card,"_"); ffkeyn(card, histData.hcolnum[1], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) ffpky(histptr, TDOUBLE, "PC2_2", &dvalue, card, &tstatus); tstatus = 0; keyname[1] = 'C'; ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) { dvalue *= binsize[1]; ffpky(histptr, TDOUBLE, "CD2_2", &dvalue, card, &tstatus); } } /* finally, close the original file and return ptr to the new image */ ffclos(*fptr, status); *fptr = histptr; return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_col_minmax(fitsfile *fptr, int colnum, float *datamin, float *datamax, int *status) /* Simple utility routine to compute the min and max value in a column */ { int anynul; long nrows, ntodo, firstrow, ii; float array[1000], nulval; ffgky(fptr, TLONG, "NAXIS2", &nrows, NULL, status); /* no. of rows */ firstrow = 1; nulval = FLOATNULLVALUE; *datamin = 9.0E36F; *datamax = -9.0E36F; while(nrows) { ntodo = minvalue(nrows, 100); ffgcv(fptr, TFLOAT, colnum, firstrow, 1, ntodo, &nulval, array, &anynul, status); for (ii = 0; ii < ntodo; ii++) { if (array[ii] != nulval) { *datamin = minvalue(*datamin, array[ii]); *datamax = maxvalue(*datamax, array[ii]); } } nrows -= ntodo; firstrow += ntodo; } return(*status); } /*--------------------------------------------------------------------------*/ int ffwritehisto(long totaln, long pixoffset, long firstn, long nvalues, int narrays, iteratorCol *imagepars, void *userPointer) /* Interator work function that writes out the histogram. The histogram values are calculated by another work function, ffcalchisto. This work function only gets called once, and totaln = nvalues. */ { iteratorCol colpars[5]; int ii, status = 0, ncols; long rows_per_loop = 0, offset = 0; histType *histData; histData = (histType *)userPointer; /* store pointer to the histogram array, and initialize to zero */ switch( histData->himagetype ) { case TBYTE: histData->hist.b = (char * ) fits_iter_get_array(imagepars); break; case TSHORT: histData->hist.i = (short * ) fits_iter_get_array(imagepars); break; case TINT: histData->hist.j = (int * ) fits_iter_get_array(imagepars); break; case TFLOAT: histData->hist.r = (float * ) fits_iter_get_array(imagepars); break; case TDOUBLE: histData->hist.d = (double *) fits_iter_get_array(imagepars); break; } /* set the column parameters for the iterator function */ for (ii = 0; ii < histData->haxis; ii++) { fits_iter_set_by_num(&colpars[ii], histData->tblptr, histData->hcolnum[ii], TFLOAT, InputCol); } ncols = histData->haxis; if (histData->weight == FLOATNULLVALUE) { fits_iter_set_by_num(&colpars[histData->haxis], histData->tblptr, histData->wtcolnum, TFLOAT, InputCol); ncols = histData->haxis + 1; } /* call iterator function to calc the histogram pixel values */ fits_iterate_data(ncols, colpars, offset, rows_per_loop, ffcalchist, (void*)histData, &status); return(status); } /*--------------------------------------------------------------------------*/ int ffcalchist(long totalrows, long offset, long firstrow, long nrows, int ncols, iteratorCol *colpars, void *userPointer) /* Interator work function that calculates values for the 2D histogram. */ { long ii, ipix, iaxisbin; float pix, axisbin; static float *col1, *col2, *col3, *col4; /* static to preserve values */ static float *wtcol; static long incr2, incr3, incr4; static histType histData; static char *rowselect; /* Initialization procedures: execute on the first call */ if (firstrow == 1) { /* Copy input histogram data to static local variable so we */ /* don't have to constantly dereference it. */ histData = *(histType*)userPointer; rowselect = histData.rowselector; /* assign the input array pointers to local pointers */ col1 = (float *) fits_iter_get_array(&colpars[0]); if (histData.haxis > 1) { col2 = (float *) fits_iter_get_array(&colpars[1]); incr2 = histData.haxis1; if (histData.haxis > 2) { col3 = (float *) fits_iter_get_array(&colpars[2]); incr3 = incr2 * histData.haxis2; if (histData.haxis > 3) { col4 = (float *) fits_iter_get_array(&colpars[3]); incr4 = incr3 * histData.haxis3; } } } if (ncols > histData.haxis) /* then weights are give in a column */ { wtcol = (float *) fits_iter_get_array(&colpars[histData.haxis]); } } /* end of Initialization procedures */ /* Main loop: increment the histogram at position of each event */ for (ii = 1; ii <= nrows; ii++) { if (rowselect) /* if a row selector array is supplied... */ { if (*rowselect) { rowselect++; /* this row is included in the histogram */ } else { rowselect++; /* this row is excluded from the histogram */ continue; } } if (col1[ii] == FLOATNULLVALUE) /* test for null value */ continue; pix = (col1[ii] - histData.amin1) / histData.binsize1; ipix = (long) (pix + 1.); /* add 1 because the 1st pixel is the null value */ /* test if bin is within range */ if (ipix < 1 || ipix > histData.haxis1 || pix > histData.maxbin1) continue; if (histData.haxis > 1) { if (col2[ii] == FLOATNULLVALUE) continue; axisbin = (col2[ii] - histData.amin2) / histData.binsize2; iaxisbin = (long) axisbin; if (axisbin < 0. || iaxisbin >= histData.haxis2 || axisbin > histData.maxbin2) continue; ipix += (iaxisbin * incr2); if (histData.haxis > 2) { if (col3[ii] == FLOATNULLVALUE) continue; axisbin = (col3[ii] - histData.amin3) / histData.binsize3; iaxisbin = (long) axisbin; if (axisbin < 0. || iaxisbin >= histData.haxis3 || axisbin > histData.maxbin3) continue; ipix += (iaxisbin * incr3); if (histData.haxis > 3) { if (col4[ii] == FLOATNULLVALUE) continue; axisbin = (col4[ii] - histData.amin4) / histData.binsize4; iaxisbin = (long) axisbin; if (axisbin < 0. || iaxisbin >= histData.haxis4 || axisbin > histData.maxbin4) continue; ipix += (iaxisbin * incr4); } /* end of haxis > 3 case */ } /* end of haxis > 2 case */ } /* end of haxis > 1 case */ /* increment the histogram pixel */ if (histData.weight != FLOATNULLVALUE) /* constant weight factor */ { if (histData.himagetype == TINT) histData.hist.j[ipix] += (int) histData.weight; else if (histData.himagetype == TSHORT) histData.hist.i[ipix] += (short) histData.weight; else if (histData.himagetype == TFLOAT) histData.hist.r[ipix] += histData.weight; else if (histData.himagetype == TDOUBLE) histData.hist.d[ipix] += histData.weight; else if (histData.himagetype == TBYTE) histData.hist.b[ipix] += (char) histData.weight; } else if (histData.wtrecip) /* use reciprocal of the weight */ { if (histData.himagetype == TINT) histData.hist.j[ipix] += (int) (1./wtcol[ii]); else if (histData.himagetype == TSHORT) histData.hist.i[ipix] += (short) (1./wtcol[ii]); else if (histData.himagetype == TFLOAT) histData.hist.r[ipix] += (float) (1./wtcol[ii]); else if (histData.himagetype == TDOUBLE) histData.hist.d[ipix] += 1./wtcol[ii]; else if (histData.himagetype == TBYTE) histData.hist.b[ipix] += (char) (1./wtcol[ii]); } else /* no weights */ { if (histData.himagetype == TINT) histData.hist.j[ipix] += (int) wtcol[ii]; else if (histData.himagetype == TSHORT) histData.hist.i[ipix] += (short) wtcol[ii]; else if (histData.himagetype == TFLOAT) histData.hist.r[ipix] += wtcol[ii]; else if (histData.himagetype == TDOUBLE) histData.hist.d[ipix] += wtcol[ii]; else if (histData.himagetype == TBYTE) histData.hist.b[ipix] += (char) wtcol[ii]; } } /* end of main loop over all rows */ return(0); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/imcompress.c000066400000000000000000004052011215713201500227570ustar00rootroot00000000000000# include # include # include # include # include "fitsio2.h" /*--------------------------------------------------------------------------*/ int fits_set_compression_type(fitsfile *fptr, /* I - FITS file pointer */ int ctype, /* image compression type code; */ /* allowed values: RICE_1, GZIP_1, PLIO_1, HCOMPRESS_1 */ int *status) /* IO - error status */ { /* This routine specifies the image compression algorithm that should be used when writing a FITS image. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ (fptr->Fptr)->request_compress_type = ctype; return(*status); } /*--------------------------------------------------------------------------*/ int fits_set_tile_dim(fitsfile *fptr, /* I - FITS file pointer */ int ndim, /* number of dimensions in the compressed image */ long *dims, /* size of image compression tile in each dimension */ /* default tile size = (NAXIS1, 1, 1, ...) */ int *status) /* IO - error status */ { /* This routine specifies the size (dimension) of the image compression tiles that should be used when writing a FITS image. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ int ii; if (ndim < 0 || ndim > MAX_COMPRESS_DIM) { *status = BAD_DIMEN; return(*status); } for (ii = 0; ii < ndim; ii++) { (fptr->Fptr)->request_tilesize[ii] = dims[ii]; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_set_noise_bits(fitsfile *fptr, /* I - FITS file pointer */ int noisebits, /* noise_bits parameter value */ /* (default = 4) */ int *status) /* IO - error status */ { /* This routine specifies the value of the noice_bits parameter that should be used when compressing floating point images. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ if (noisebits < 1 || noisebits > 16) { *status = DATA_COMPRESSION_ERR; return(*status); } (fptr->Fptr)->request_noise_nbits = noisebits; return(*status); } /*--------------------------------------------------------------------------*/ int fits_set_hcomp_scale(fitsfile *fptr, /* I - FITS file pointer */ int scale, /* hcompress scale parameter value */ /* (default = 4) */ int *status) /* IO - error status */ { /* This routine specifies the value of the hcompress scale parameter that The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ (fptr->Fptr)->request_hcomp_scale = scale; return(*status); } /*--------------------------------------------------------------------------*/ int fits_set_hcomp_smooth(fitsfile *fptr, /* I - FITS file pointer */ int smooth, /* hcompress smooth parameter value */ /* if scale > 1 and smooth != 0, then */ /* the image will be smoothed when it is */ /* decompressed to remove some of the */ /* 'blockiness' in the image produced */ /* by the lossy compression */ int *status) /* IO - error status */ { /* This routine specifies the value of the hcompress scale parameter that The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ (fptr->Fptr)->request_hcomp_smooth = smooth; return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_compression_type(fitsfile *fptr, /* I - FITS file pointer */ int *ctype, /* image compression type code; */ /* allowed values: RICE_1, GZIP_1, PLIO_1, HCOMPRESS_1 */ int *status) /* IO - error status */ { /* This routine returns the image compression algorithm that should be used when writing a FITS image. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ *ctype = (fptr->Fptr)->request_compress_type; return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_tile_dim(fitsfile *fptr, /* I - FITS file pointer */ int ndim, /* number of dimensions in the compressed image */ long *dims, /* size of image compression tile in each dimension */ /* default tile size = (NAXIS1, 1, 1, ...) */ int *status) /* IO - error status */ { /* This routine returns the size (dimension) of the image compression tiles that should be used when writing a FITS image. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ int ii; if (ndim < 0 || ndim > MAX_COMPRESS_DIM) { *status = BAD_DIMEN; return(*status); } for (ii = 0; ii < ndim; ii++) { dims[ii] = (fptr->Fptr)->request_tilesize[ii]; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_noise_bits(fitsfile *fptr, /* I - FITS file pointer */ int *noisebits, /* noise_bits parameter value */ /* (default = 4) */ int *status) /* IO - error status */ { /* This routine returns the value of the noice_bits parameter that should be used when compressing floating point images. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ *noisebits = (fptr->Fptr)->request_noise_nbits; return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_hcomp_scale(fitsfile *fptr, /* I - FITS file pointer */ int *scale, /* Hcompress scale parameter value */ int *status) /* IO - error status */ { /* This routine returns the value of the noice_bits parameter that should be used when compressing floating point images. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ *scale = (fptr->Fptr)->request_hcomp_scale; return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_hcomp_smooth(fitsfile *fptr, /* I - FITS file pointer */ int *smooth, /* Hcompress smooth parameter value */ int *status) /* IO - error status */ { *smooth = (fptr->Fptr)->request_hcomp_smooth; return(*status); } /*--------------------------------------------------------------------------*/ int fits_img_compress(fitsfile *infptr, /* pointer to image to be compressed */ fitsfile *outfptr, /* empty HDU for output compressed image */ int *status) /* IO - error status */ /* This routine initializes the output table, copies all the keywords, and loops through the input image, compressing the data and writing the compressed tiles to the output table. */ { int bitpix, naxis; long naxes[MAX_COMPRESS_DIM]; if (*status > 0) return(*status); /* get datatype and size of input image */ if (fits_get_img_param(infptr, MAX_COMPRESS_DIM, &bitpix, &naxis, naxes, status) > 0) return(*status); if (naxis < 1 || naxis > MAX_COMPRESS_DIM) { ffpmsg("Image cannot be compressed: NAXIS out of range"); return(*status = BAD_NAXIS); } /* initialize output table */ if (imcomp_init_table(outfptr, bitpix, naxis, naxes, 0, status) > 0) return (*status); /* Copy the image header keywords to the table header. */ if (imcomp_copy_img2comp(infptr, outfptr, status) > 0) return (*status); /* turn off any intensity scaling (defined by BSCALE and BZERO */ /* keywords) so that unscaled values will be read by CFITSIO */ ffpscl(infptr, 1.0, 0.0, status); /* force a rescan of the output file keywords, so that */ /* the compression parameters will be copied to the internal */ /* fitsfile structure used by CFITSIO */ ffrdef(outfptr, status); /* Read each image tile, compress, and write to a table row. */ imcomp_compress_image (infptr, outfptr, status); /* force another rescan of the output file keywords, to */ /* update PCOUNT and TFORMn = '1PB(iii)' keyword values. */ ffrdef(outfptr, status); return (*status); } /*--------------------------------------------------------------------------*/ int fits_compress_img(fitsfile *infptr, /* pointer to image to be compressed */ fitsfile *outfptr, /* empty HDU for output compressed image */ int compress_type, /* compression type code */ /* RICE_1, HCOMPRESS_1, etc. */ long *intilesize, /* size in each dimension of the tiles */ /* NULL pointer means tile by rows */ int blocksize, /* compression parameter: blocksize */ int nbits, /* compression parameter: nbits */ int *status) /* IO - error status */ /* !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! This routine is obsolete and should not be used. Currently the ftools 'fimgzip' task calls this; it should be modified to call fits_img_compress instead. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! This routine initializes the output table, copies all the keywords, and loops through the input image, compressing the data and writing the compressed tiles to the output table. */ { int bitpix, naxis; long naxes[MAX_COMPRESS_DIM]; if (*status > 0) return(*status); /* get datatype and size of input image */ if (fits_get_img_param(infptr, MAX_COMPRESS_DIM, &bitpix, &naxis, naxes, status) > 0) return(*status); if (naxis < 1 || naxis > MAX_COMPRESS_DIM) { ffpmsg("Image cannot be compressed: NAXIS out of range"); return(*status = BAD_NAXIS); } /* initialize output table */ if (imcomp_init_table(outfptr, bitpix, naxis, naxes, 0, status) > 0) return (*status); /* Copy the image header keywords to the table header. */ if (imcomp_copy_imheader(infptr, outfptr, status) > 0) return (*status); /* turn off any intensity scaling (defined by BSCALE and BZERO */ /* keywords) so that unscaled values will be read by CFITSIO */ ffpscl(infptr, 1.0, 0.0, status); /* force a rescan of the output file keywords, so that */ /* the compression parameters will be copied to the internal */ /* fitsfile structure used by CFITSIO */ ffrdef(outfptr, status); /* Read each image tile, compress, and write to a table row. */ imcomp_compress_image (infptr, outfptr, status); /* force another rescan of the output file keywords, to */ /* update PCOUNT and TFORMn = '1PB(iii)' keyword values. */ ffrdef(outfptr, status); return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_init_table(fitsfile *outfptr, int inbitpix, int naxis, long *naxes, int writebitpix, /* write the ZBITPIX, ZNAXIS, and ZNAXES keyword? */ int *status) /* create a BINTABLE extension for the output compressed image. */ { char keyname[FLEN_KEYWORD], zcmptype[12]; int ii, jj, minspace, tempsize, remain, leftspace, ncols, bitpix; long nrows; char *ttype[] = {"COMPRESSED_DATA", "UNCOMPRESSED_DATA", "ZSCALE", "ZZERO"}; char *tform[4]; char tf0[4], tf1[4], tf2[4], tf3[4]; char *tunit[] = {"\0", "\0", "\0", "\0" }; char comm[FLEN_COMMENT]; if (*status > 0) return(*status); /* test for the 2 special cases that represent unsigned integers */ if (inbitpix == USHORT_IMG) bitpix = SHORT_IMG; else if (inbitpix == ULONG_IMG) bitpix = LONG_IMG; else bitpix = inbitpix; /* reset default tile dimensions too if required */ if ((outfptr->Fptr)->request_compress_type == HCOMPRESS_1) { if (((outfptr->Fptr)->request_tilesize[0] == 0) && ((outfptr->Fptr)->request_tilesize[1] == 1) ){ for (ii = 0; ii < 2 && ii < naxis; ii++) { /* only reset the 1st 2 dimensions */ if (naxes[ii] <= 600) { /* use the full dimension of the image as the tile dimension */ (outfptr->Fptr)->request_tilesize[ii] = naxes[ii]; } else { /* look for an even tile size in the range 200 - 600 */ /* This is a brute force algorithm; probably more efficient ways to do this */ minspace = naxes[ii]; tempsize = naxes[ii]; for (jj = 600; jj >= 200; jj -= 2) { remain = naxes[ii] % jj; if (!remain) { /* found an even multiple tile size */ tempsize = jj; break; } else { leftspace = jj - remain; if (leftspace < minspace) { /* save the best case found so far */ minspace = leftspace; tempsize = jj; } } } /* end of for jj loop */ (outfptr->Fptr)->request_tilesize[ii] = tempsize; } } /* end of for ii loop */ } } /* end, if HCOMPRESS_1 */ for (ii = 0; ii < naxis; ii++) { if ((outfptr->Fptr)->request_tilesize[ii] <= 0) { /* tile size of 0 means use the image size of that dimension */ (outfptr->Fptr)->request_tilesize[ii] = naxes[ii]; } } /* (only used to quantize floating point images) */ if ((outfptr->Fptr)->request_noise_nbits < 1) /* use default value if input is not legal */ (outfptr->Fptr)->request_noise_nbits = 4; /* ---- set up array of TFORM strings -------------------------------*/ strcpy(tf0, "1PB"); strcpy(tf2, "1D"); strcpy(tf3, "1D"); tform[0] = tf0; tform[1] = tf1; tform[2] = tf2; tform[3] = tf3; /* calculate number of rows in output table */ nrows = 1; for (ii = 0; ii < naxis; ii++) { nrows = nrows * ((naxes[ii] - 1)/ ((outfptr->Fptr)->request_tilesize[ii]) + 1); } if (bitpix < 0 ) /* floating point image */ ncols = 4; else ncols = 1; /* default table has just one 'COMPRESSED_DATA' column */ if ((outfptr->Fptr)->request_compress_type == RICE_1) { strcpy(zcmptype, "RICE_1"); } else if ((outfptr->Fptr)->request_compress_type == GZIP_1) { strcpy(zcmptype, "GZIP_1"); } else if ((outfptr->Fptr)->request_compress_type == PLIO_1) { strcpy(zcmptype, "PLIO_1"); /* the PLIO compression algorithm outputs short integers, not bytes */ strcpy(tform[0], "1PI"); } else if ((outfptr->Fptr)->request_compress_type == HCOMPRESS_1) { strcpy(zcmptype, "HCOMPRESS_1"); } else { ffpmsg("unknown compression type (imcomp_init_table)"); return(*status = DATA_COMPRESSION_ERR); } /* set correct datatype for any tiles that cannot be compressed */ if (bitpix == SHORT_IMG) strcpy(tform[1], "1PI"); else if (bitpix == LONG_IMG) strcpy(tform[1], "1PJ"); else if (bitpix == FLOAT_IMG) strcpy(tform[1], "1PE"); else if (bitpix == DOUBLE_IMG) strcpy(tform[1], "1PD"); /* create the bintable extension to contain the compressed image */ ffcrtb(outfptr, BINARY_TBL, nrows, ncols, ttype, tform, tunit, 0, status); /* Add standard header keywords. */ ffpkyl (outfptr, "ZIMAGE", 1, "extension contains compressed image", status); if (writebitpix) { /* write the keywords defining the datatype and dimensions of */ /* the uncompressed image. These keywords may get created */ /* later, copied from the input uncompressed image */ ffpkyj (outfptr, "ZBITPIX", bitpix, "data type of original image", status); ffpkyj (outfptr, "ZNAXIS", naxis, "dimension of original image", status); for (ii = 0; ii < naxis; ii++) { sprintf (keyname, "ZNAXIS%d", ii+1); ffpkyj (outfptr, keyname, naxes[ii], "length of original image axis", status); } } for (ii = 0; ii < naxis; ii++) { sprintf (keyname, "ZTILE%d", ii+1); ffpkyj (outfptr, keyname, (outfptr->Fptr)->request_tilesize[ii], "size of tiles to be compressed", status); } ffpkys (outfptr, "ZCMPTYPE", zcmptype, "compression algorithm", status); /* write any algorithm-specific keywords */ if ((outfptr->Fptr)->request_compress_type == RICE_1) { ffpkys (outfptr, "ZNAME1", "BLOCKSIZE", "compression block size", status); /* for now at least, the block size is always 32 */ ffpkyj (outfptr, "ZVAL1", 32, "pixels per block", status); if (bitpix < 0 ) /* floating point image */ { ffpkys (outfptr, "ZNAME2", "NOISEBIT", "floating point quantization level", status); ffpkyj (outfptr, "ZVAL2", (long) (outfptr->Fptr)->request_noise_nbits, "floating point quantization level", status); } } else if ((outfptr->Fptr)->request_compress_type == HCOMPRESS_1) { ffpkys (outfptr, "ZNAME1", "SCALE", "HCOMPRESS scale factor", status); ffpkyj (outfptr, "ZVAL1", (long) (outfptr->Fptr)->request_hcomp_scale, "HCOMPRESS scale factor", status); ffpkys (outfptr, "ZNAME2", "SMOOTH", "HCOMPRESS smooth option", status); ffpkyj (outfptr, "ZVAL2", (long) (outfptr->Fptr)->request_hcomp_smooth, "HCOMPRESS smooth option", status); if (bitpix < 0 ) /* floating point image */ { ffpkys (outfptr, "ZNAME3", "NOISEBIT", "floating point quantization level", status); ffpkyj (outfptr, "ZVAL3", (long) (outfptr->Fptr)->request_noise_nbits, "floating point quantization level", status); } } else { if (bitpix < 0 ) /* floating point image */ { ffpkys (outfptr, "ZNAME1", "NOISEBIT", "floating point quantization level", status); ffpkyj (outfptr, "ZVAL1", (long) (outfptr->Fptr)->request_noise_nbits, "floating point quantization level", status); } } /* Write the BSCALE and BZERO keywords, if an unsigned integer image */ if (inbitpix == USHORT_IMG) { strcpy(comm, "offset data range to that of unsigned short"); ffpkyg(outfptr, "BZERO", 32768., 0, comm, status); strcpy(comm, "default scaling factor"); ffpkyg(outfptr, "BSCALE", 1.0, 0, comm, status); } else if (inbitpix == ULONG_IMG) { strcpy(comm, "offset data range to that of unsigned long"); ffpkyg(outfptr, "BZERO", 2147483648., 0, comm, status); strcpy(comm, "default scaling factor"); ffpkyg(outfptr, "BSCALE", 1.0, 0, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int imcomp_calc_max_elem (int comptype, int nx, int zbitpix, int blocksize) /* This function returns the maximum number of bytes in a compressed image line. nx = maximum number of pixels in a tile blocksize is only relevant for RICE compression */ { if (comptype == RICE_1) { return (sizeof(float) * nx + nx / blocksize + 2 + 4); } else if (comptype == GZIP_1) { /* gzip usually compressed by at least a factor of 2 */ /* If this size turns out to be too small, then the gzip */ /* compression routine will allocate more space as required */ return(nx * sizeof(int) / 2); } else if (comptype == HCOMPRESS_1) { /* Imperical evidence suggests in the worst case, the compressed stream could be up to 10% larger than the original image. Add 26 byte overhead, only significant for very small tiles Possible improvement: may need to allow a larger size for 32-bit images */ if (zbitpix == 16 || zbitpix == 8) return( (int) (nx * 2.2 + 26)); /* will be compressing 16-bit int array */ else return( (int) (nx * 4.4 + 26)); /* will be compressing 32-bit int array */ } else return(nx * sizeof(int)); } /*--------------------------------------------------------------------------*/ int imcomp_compress_image (fitsfile *infptr, fitsfile *outfptr, int *status) /* This routine does the following: - reads an image one tile at a time - if it is a float or double image, then it quantizes the pixels - compresses the integer pixel values - writes the compressed byte stream to the FITS file. If the tile cannot be quantized than the raw float or double values are written to the output table. */ { double *tiledata = 0; int anynul, gotnulls = 0, datatype, tstatus, colnum; long ii, row, nelem, offset; int naxis; long maxtilelen, tilelen, incre[] = {1, 1, 1, 1, 1, 1}; long naxes[MAX_COMPRESS_DIM], fpixel[MAX_COMPRESS_DIM]; long lpixel[MAX_COMPRESS_DIM], tile[MAX_COMPRESS_DIM]; long tilesize[MAX_COMPRESS_DIM]; long i0, i1, i2, i3, i4, i5; char card[FLEN_CARD]; if (*status > 0) return(*status); maxtilelen = (outfptr->Fptr)->maxtilelen; /* allocate buffer to hold 1 tile of data */ /* if the hcompress algorithm is being used on BITPIX = 32, -32, or -64 */ /* image, then we need to allocate 8-bytes per pixel buffer */ if ((outfptr->Fptr)->zbitpix == FLOAT_IMG) { datatype = TFLOAT; if ( (outfptr->Fptr)->compress_type == HCOMPRESS_1) { /* need twice as much scratch space (8 bytes per pixel) */ tiledata = (double*) calloc (maxtilelen * 2, sizeof (float)); } else { tiledata = (double*) calloc (maxtilelen, sizeof (float)); } } else if ((outfptr->Fptr)->zbitpix == DOUBLE_IMG) { datatype = TDOUBLE; tiledata = (double*) calloc (maxtilelen, sizeof (double)); } else { datatype = TINT; if ( (outfptr->Fptr)->compress_type == HCOMPRESS_1 && (outfptr->Fptr)->zbitpix == LONG_IMG) { /* need twice as much scratch space (8 bytes per pixel) */ tiledata = (double*) calloc (maxtilelen * 2, sizeof (int)); } else { tiledata = (double*) calloc (maxtilelen, sizeof (int)); } } if (tiledata == NULL) { ffpmsg("Out of memory. (imcomp_compress_image)"); return (*status = MEMORY_ALLOCATION); } /* calculate size of tile in each dimension */ naxis = (outfptr->Fptr)->zndim; for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { if (ii < naxis) { naxes[ii] = (outfptr->Fptr)->znaxis[ii]; tilesize[ii] = (outfptr->Fptr)->tilesize[ii]; } else { naxes[ii] = 1; tilesize[ii] = 1; } } row = 1; /* set up big loop over up to 6 dimensions */ for (i5 = 1; i5 <= naxes[5]; i5 += tilesize[5]) { fpixel[5] = i5; lpixel[5] = minvalue(i5 + tilesize[5] - 1, naxes[5]); tile[5] = lpixel[5] - fpixel[5] + 1; for (i4 = 1; i4 <= naxes[4]; i4 += tilesize[4]) { fpixel[4] = i4; lpixel[4] = minvalue(i4 + tilesize[4] - 1, naxes[4]); tile[4] = lpixel[4] - fpixel[4] + 1; for (i3 = 1; i3 <= naxes[3]; i3 += tilesize[3]) { fpixel[3] = i3; lpixel[3] = minvalue(i3 + tilesize[3] - 1, naxes[3]); tile[3] = lpixel[3] - fpixel[3] + 1; for (i2 = 1; i2 <= naxes[2]; i2 += tilesize[2]) { fpixel[2] = i2; lpixel[2] = minvalue(i2 + tilesize[2] - 1, naxes[2]); tile[2] = lpixel[2] - fpixel[2] + 1; for (i1 = 1; i1 <= naxes[1]; i1 += tilesize[1]) { fpixel[1] = i1; lpixel[1] = minvalue(i1 + tilesize[1] - 1, naxes[1]); tile[1] = lpixel[1] - fpixel[1] + 1; for (i0 = 1; i0 <= naxes[0]; i0 += tilesize[0]) { fpixel[0] = i0; lpixel[0] = minvalue(i0 + tilesize[0] - 1, naxes[0]); tile[0] = lpixel[0] - fpixel[0] + 1; /* number of pixels in this tile */ tilelen = tile[0]; for (ii = 1; ii < naxis; ii++) { tilelen *= tile[ii]; } /* read next tile of data from image */ if (datatype == TFLOAT) { ffgsve(infptr, 1, naxis, naxes, fpixel, lpixel, incre, FLOATNULLVALUE, (float *) tiledata, &anynul, status); } else if (datatype == TDOUBLE) { ffgsvd(infptr, 1, naxis, naxes, fpixel, lpixel, incre, DOUBLENULLVALUE, tiledata, &anynul, status); } else /* read all integer data types as int */ { ffgsvk(infptr, 1, naxis, naxes, fpixel, lpixel, incre, 0, (int *) tiledata, &anynul, status); } /* now compress the tile, and write to row of binary table */ imcomp_compress_tile(outfptr, row, datatype, tiledata, tilelen, tile[0], tile[1], status); /* set flag if we found any null values */ if (anynul) gotnulls = 1; /* check for any error in the previous operations */ if (*status > 0) { ffpmsg("Error writing compressed image to table"); free(tiledata); return (*status); } row++; } } } } } } free (tiledata); /* finished with this buffer */ /* insert ZBLANK keyword if necessary */ if (gotnulls) { ffgcrd(outfptr, "ZCMPTYPE", card, status); ffikyj(outfptr, "ZBLANK", COMPRESS_NULL_VALUE, "null value in the compressed integer array", status); } if (datatype >= TFLOAT ) { /* check if any data were written to the UNCOMPRESSED_DATA column */ /* If not, then delete that column from the table */ for (ii = 1; ii < row; ii++) { ffgdes (outfptr, (outfptr->Fptr)->cn_uncompressed, ii, &nelem, &offset, status); if (nelem) break; } if (!nelem) { tstatus = 0; ffgcno(outfptr, CASEINSEN, "UNCOMPRESSED_DATA", &colnum, &tstatus); if (tstatus == 0) { /* make sure table is properly terminated before deleting col */ /* (in particular, make sure the '1PB(nnn)' keyword is updated */ ffrdef(outfptr, status); ffdcol(outfptr, colnum, status); } } } return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_compress_tile (fitsfile *outfptr, long row, int datatype, void *tiledata, long tilelen, long tilenx, long tileny, int *status) /* This is the main compression routine. This routine does the following to the input tile of pixels: - if it is a float or double image, then it quantizes the pixels - compresses the integer pixel values - writes the compressed byte stream to the FITS file. If the tile cannot be quantized than the raw float or double values are written to the output table. The input tiledata array must only be of type TINT, TFLOAT, or TDOUBLE. Shorter integer types will be type converted to TINT, under the assumption that the input array was allocated with enough scratch space to do this in place in memory. This array may be modified by this routine. If the array is of type TINT or TFLOAT, and the compression type is HCOMPRESS, then it must have been allocated to be twice as large (8 bytes per pixel) to provide scratch space. */ { int *idata = 0; /* quantized integer data */ short *cbuf; /* compressed data */ short *sbuff; unsigned short *usbuff; int clen; /* size of cbuf */ int flag = 1; /* true by default; only = 0 if float data couldn't be quantized */ int iminval = 0, imaxval = 0; /* min and max quantized integers */ double bscale[1] = {1.}, bzero[1] = {0.}; /* scaling parameters */ int nelem = 0; /* number of bytes */ size_t gzip_nelem = 0; long ii, hcomp_len; LONGLONG *lldata; signed char *sbbuff; unsigned char *usbbuff; long *lbuff; unsigned long *ulbuff; int hcompscale; if (*status > 0) return(*status); idata = (int *) tiledata; hcompscale = (outfptr->Fptr)->hcomp_scale; /* convert input tile array in place to 4-byte ints for compression */ /* Note that the calling routine must have allocated the array big enough */ /* to be able to do this. */ if (datatype == TSHORT) { sbuff = (short *) tiledata; for (ii = tilelen; ii >= 0; ii--) idata[ii] = (int) sbuff[ii]; } else if (datatype == TUSHORT) { usbuff = (unsigned short *) tiledata; for (ii = tilelen; ii >= 0; ii--) idata[ii] = (int) usbuff[ii]; } else if (datatype == TBYTE) { usbbuff = (unsigned char *) tiledata; for (ii = tilelen; ii >= 0; ii--) idata[ii] = (int) usbbuff[ii]; } else if (datatype == TSBYTE) { sbbuff = (signed char *) tiledata; for (ii = tilelen; ii >= 0; ii--) idata[ii] = (int) sbbuff[ii]; } else if (datatype == TLONG && sizeof(long) == 8) { /* warning: potential for data overflow here */ lbuff = (long *) tiledata; for (ii = 0; ii < tilelen; ii++) idata[ii] = (int) lbuff[ii]; } else if (datatype == TULONG && sizeof(long) == 8) { /* warning: potential for data overflow here */ ulbuff = (unsigned long *) tiledata; for (ii = 0; ii < tilelen; ii++) idata[ii] = (int) ulbuff[ii]; } else if (datatype == TFLOAT) { /* if the tile-compressed table contains zscale and zzero columns */ /* then scale and quantize the input floating point data. */ /* Otherwise, just truncate the floats to integers. */ if ((outfptr->Fptr)->cn_zscale > 0) { /* quantize the float values into integers */ flag = fits_quantize_float ((float *) tiledata, tilelen, FLOATNULLVALUE, (outfptr->Fptr)->noise_nbits, idata, bscale, bzero, &iminval, &imaxval); /* adjust the hcompress scale by the same scaling factor */ if (hcompscale > 1) hcompscale = (int) (hcompscale / bscale[0]); } else { for (ii = 0; ii < tilelen; ii++) idata[ii] = (int) (((float *)tiledata)[ii]); } } else if (datatype == TDOUBLE) { /* if the tile-compressed table contains zscale and zzero columns */ /* then scale and quantize the input floating point data. */ /* Otherwise, just truncate the floats to integers. */ if ((outfptr->Fptr)->cn_zscale > 0) { /* quantize the double values into integers */ flag = fits_quantize_double ((double *) tiledata, tilelen, DOUBLENULLVALUE, (outfptr->Fptr)->noise_nbits, idata, bscale, bzero, &iminval, &imaxval); /* adjust the hcompress scale by the same scaling factor */ if (hcompscale > 1) hcompscale = (int) (hcompscale / bscale[0]); } else { for (ii = 0; ii < tilelen; ii++) idata[ii] = (int) (((double *)tiledata)[ii]); } } else if (datatype != TINT && datatype != TUINT) { ffpmsg("unsupported datatype (imcomp_compress_tile)"); return(*status = BAD_DATATYPE); } if (flag) /* we can now compress the int array */ { /* allocate buffer for the compressed tile bytes */ clen = (outfptr->Fptr)->maxelem; cbuf = (short *) calloc (clen, sizeof (unsigned char)); if (cbuf == NULL) { ffpmsg("Out of memory. (imcomp_compress_tile)"); return (*status = MEMORY_ALLOCATION); } /* Compress the integer data, then write the compressed bytes */ if ( (outfptr->Fptr)->compress_type == RICE_1) { nelem = fits_rcomp (idata, tilelen, (unsigned char *) cbuf, clen, (outfptr->Fptr)->rice_blocksize); /* Write the compressed byte stream. */ ffpclb(outfptr, (outfptr->Fptr)->cn_compressed, row, 1, nelem, (unsigned char *) cbuf, status); } else if ( (outfptr->Fptr)->compress_type == PLIO_1) { if (iminval < 0 || imaxval > 16777215) { /* plio algorithn only supports positive 24 bit ints */ ffpmsg("data out of range for PLIO compression (0 - 2**24)"); return(*status = DATA_DECOMPRESSION_ERR); } nelem = pl_p2li (idata, 1, cbuf, tilelen); /* Write the compressed byte stream. */ ffpcli(outfptr, (outfptr->Fptr)->cn_compressed, row, 1, nelem, cbuf, status); } else if ( (outfptr->Fptr)->compress_type == GZIP_1) { #if BYTESWAPPED ffswap4(idata, tilelen); /* reverse order of bytes */ #endif compress2mem_from_mem((char *) idata, tilelen * sizeof(int), (char **) &cbuf, (size_t *) &clen, realloc, &gzip_nelem, status); /* Write the compressed byte stream. */ ffpclb(outfptr, (outfptr->Fptr)->cn_compressed, row, 1, gzip_nelem, (unsigned char *) cbuf, status); } else if ( (outfptr->Fptr)->compress_type == HCOMPRESS_1) { hcomp_len = clen; /* allocated size of the buffer */ if ((outfptr->Fptr)->zbitpix == BYTE_IMG || (outfptr->Fptr)->zbitpix == SHORT_IMG) { fits_hcompress(idata, tilenx, tileny, hcompscale, (char *) cbuf, &hcomp_len, status); } else { /* have to convert idata to an I*8 array, in place */ /* idata must have been allocated large enough to do this */ lldata = (LONGLONG *) idata; for (ii = tilelen; ii >= 0; ii--) { lldata[ii] = idata[ii];; } fits_hcompress64(lldata, tilenx, tileny, hcompscale, (char *) cbuf, &hcomp_len, status); } /* Write the compressed byte stream. */ ffpclb(outfptr, (outfptr->Fptr)->cn_compressed, row, 1, hcomp_len, (unsigned char *) cbuf, status); } if (nelem < 0) /* error condition */ { free (cbuf); ffpmsg ("error compressing row of the image (imcomp_compress_tile)"); return (*status = DATA_COMPRESSION_ERR); } if ((outfptr->Fptr)->cn_zscale > 0) { /* write the linear scaling parameters */ ffpcld (outfptr, (outfptr->Fptr)->cn_zscale, row, 1, 1, bscale, status); ffpcld (outfptr, (outfptr->Fptr)->cn_zzero, row, 1, 1, bzero, status); } free(cbuf); /* finished with this buffer */ } else /* floating point data couldn't be quantized */ { /* Write the original floating point data. */ if (datatype == TFLOAT) { ffpcle (outfptr, (outfptr->Fptr)->cn_uncompressed, row, 1, tilelen, (float *)tiledata, status); } else if (datatype == TDOUBLE) { ffpcld (outfptr, (outfptr->Fptr)->cn_uncompressed, row, 1, tilelen, (double *)tiledata, status); } } return (*status); } /*---------------------------------------------------------------------------*/ int fits_write_compressed_img(fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the array to be written */ long *infpixel, /* I - 'bottom left corner' of the subsection */ long *inlpixel, /* I - 'top right corner' of the subsection */ int nullcheck, /* I - 0 for no null checking */ /* 1: pixels that are = nullval will be */ /* written with the FITS null pixel value */ /* (floating point arrays only) */ void *array, /* I - array of values to be written */ void *nullval, /* I - undefined pixel value (floating pt only) */ int *status) /* IO - error status */ /* Write a section of a compressed image. */ { int naxis[MAX_COMPRESS_DIM], tiledim[MAX_COMPRESS_DIM]; long tilesize[MAX_COMPRESS_DIM], thistilesize[MAX_COMPRESS_DIM]; long ftile[MAX_COMPRESS_DIM], ltile[MAX_COMPRESS_DIM]; long tfpixel[MAX_COMPRESS_DIM], tlpixel[MAX_COMPRESS_DIM]; long rowdim[MAX_COMPRESS_DIM], offset[MAX_COMPRESS_DIM],ntemp; long fpixel[MAX_COMPRESS_DIM], lpixel[MAX_COMPRESS_DIM]; int ii, i5, i4, i3, i2, i1, i0, ndim, irow, pixlen, tilenul; int anynull, tstatus, buffpixsiz; long totpix; void *buffer; char *bnullarray = 0, card[FLEN_CARD]; float floatnull = 0.; double doublenull = 0.; if (*status > 0) return(*status); if (!fits_is_compressed_image(fptr, status) ) { ffpmsg("CHDU is not a compressed image (fits_write_compressed_img)"); return(*status = DATA_COMPRESSION_ERR); } /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); /* get temporary space for uncompressing one image tile */ /* Need at least 4-byte per pixel, and in some cases 8-bytes per pixel, */ buffpixsiz = 4; if ( (fptr->Fptr)->compress_type == HCOMPRESS_1 && ((fptr->Fptr)->zbitpix != BYTE_IMG && (fptr->Fptr)->zbitpix != SHORT_IMG) ){ buffpixsiz = 8; } if (datatype == TDOUBLE) buffpixsiz = 8; /* cast to double to force alignment on 8-byte addresses */ buffer = (double *) calloc ((fptr->Fptr)->maxtilelen, buffpixsiz); if (datatype == TSHORT || datatype == TUSHORT) { pixlen = sizeof(short); } else if (datatype == TINT || datatype == TUINT) { pixlen = sizeof(int); } else if (datatype == TBYTE || datatype == TSBYTE) { pixlen = 1; } else if (datatype == TLONG || datatype == TULONG) { pixlen = sizeof(long); } else if (datatype == TFLOAT) { pixlen = sizeof(float); } else if (datatype == TDOUBLE) { pixlen = sizeof(double); } else { ffpmsg("unsupported datatype for compressing image"); return(*status = BAD_DATATYPE); } if (buffer == NULL) { ffpmsg("Out of memory (fits_write_compress_img)"); return (*status = MEMORY_ALLOCATION); } /* initialize all the arrays */ for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { naxis[ii] = 1; tiledim[ii] = 1; tilesize[ii] = 1; ftile[ii] = 1; ltile[ii] = 1; rowdim[ii] = 1; } ndim = (fptr->Fptr)->zndim; ntemp = 1; for (ii = 0; ii < ndim; ii++) { fpixel[ii] = infpixel[ii]; lpixel[ii] = inlpixel[ii]; /* calc number of tiles in each dimension, and tile containing */ /* the first and last pixel we want to read in each dimension */ naxis[ii] = (fptr->Fptr)->znaxis[ii]; if (fpixel[ii] < 1) { free(buffer); return(*status = BAD_PIX_NUM); } tilesize[ii] = (fptr->Fptr)->tilesize[ii]; tiledim[ii] = (naxis[ii] - 1) / tilesize[ii] + 1; ftile[ii] = (fpixel[ii] - 1) / tilesize[ii] + 1; ltile[ii] = minvalue((lpixel[ii] - 1) / tilesize[ii] + 1, tiledim[ii]); rowdim[ii] = ntemp; /* total tiles in each dimension */ ntemp *= tiledim[ii]; } /* support up to 6 dimensions for now */ /* tfpixel and tlpixel are the first and last image pixels */ /* along each dimension of the compression tile */ for (i5 = ftile[5]; i5 <= ltile[5]; i5++) { tfpixel[5] = (i5 - 1) * tilesize[5] + 1; tlpixel[5] = minvalue(tfpixel[5] + tilesize[5] - 1, naxis[5]); thistilesize[5] = tlpixel[5] - tfpixel[5] + 1; offset[5] = (i5 - 1) * rowdim[5]; for (i4 = ftile[4]; i4 <= ltile[4]; i4++) { tfpixel[4] = (i4 - 1) * tilesize[4] + 1; tlpixel[4] = minvalue(tfpixel[4] + tilesize[4] - 1, naxis[4]); thistilesize[4] = thistilesize[5] * (tlpixel[4] - tfpixel[4] + 1); offset[4] = (i4 - 1) * rowdim[4] + offset[5]; for (i3 = ftile[3]; i3 <= ltile[3]; i3++) { tfpixel[3] = (i3 - 1) * tilesize[3] + 1; tlpixel[3] = minvalue(tfpixel[3] + tilesize[3] - 1, naxis[3]); thistilesize[3] = thistilesize[4] * (tlpixel[3] - tfpixel[3] + 1); offset[3] = (i3 - 1) * rowdim[3] + offset[4]; for (i2 = ftile[2]; i2 <= ltile[2]; i2++) { tfpixel[2] = (i2 - 1) * tilesize[2] + 1; tlpixel[2] = minvalue(tfpixel[2] + tilesize[2] - 1, naxis[2]); thistilesize[2] = thistilesize[3] * (tlpixel[2] - tfpixel[2] + 1); offset[2] = (i2 - 1) * rowdim[2] + offset[3]; for (i1 = ftile[1]; i1 <= ltile[1]; i1++) { tfpixel[1] = (i1 - 1) * tilesize[1] + 1; tlpixel[1] = minvalue(tfpixel[1] + tilesize[1] - 1, naxis[1]); thistilesize[1] = thistilesize[2] * (tlpixel[1] - tfpixel[1] + 1); offset[1] = (i1 - 1) * rowdim[1] + offset[2]; for (i0 = ftile[0]; i0 <= ltile[0]; i0++) { tfpixel[0] = (i0 - 1) * tilesize[0] + 1; tlpixel[0] = minvalue(tfpixel[0] + tilesize[0] - 1, naxis[0]); thistilesize[0] = thistilesize[1] * (tlpixel[0] - tfpixel[0] + 1); /* calculate row of table containing this tile */ irow = i0 + offset[1]; /* read and uncompress this row (tile) of the table */ /* also do type conversion and undefined pixel substitution */ /* at this point */ imcomp_decompress_tile(fptr, irow, thistilesize[0], datatype, nullcheck, nullval, buffer, bnullarray, &tilenul, status); if (*status == NO_COMPRESSED_TILE) { /* tile doesn't exist, so initialize to zero */ memset(buffer, 0, pixlen * thistilesize[0]); *status = 0; } /* copy the intersecting pixels to this tile from the input */ imcomp_merge_overlap(buffer, pixlen, ndim, tfpixel, tlpixel, bnullarray, array, fpixel, lpixel, nullcheck, status); /* compress the tile again, and write it back to the FITS file */ imcomp_compress_tile (fptr, irow, datatype, buffer, thistilesize[0], tlpixel[0] - tfpixel[0] + 1, tlpixel[1] - tfpixel[1] + 1, status); } } } } } } free(buffer); /* if the input array has a floating point datatype, and if *nullval is not equal to zero, and if there are any pixels in the array that are equal to the value of *nullval, then we need to make sure that the ZBLANK keyword is present in the compressed image header. If it is not there then we need to insert the keyword. */ if (datatype >= TFLOAT && nullval != 0) { /* OK, this is a floating point data type, with a null value */ if (datatype == TFLOAT) floatnull = *((float *) nullval); else if (datatype == TDOUBLE) doublenull = *((double *) nullval); if (floatnull != 0. || doublenull != 0.) { /* OK, the null value is not = 0 */ /* calculate the size of the imput array */ totpix = 1; for (ii = 0; ii < ndim; ii++) { totpix *= (inlpixel[ii] - infpixel[ii]); } if (totpix <= 0) return(*status); anynull = 0; if (datatype == TFLOAT) { for (ii = 0; ii < totpix; ii++) { if (((float *)array)[ii] == floatnull) { anynull = 1; break; } } } else if (datatype == TDOUBLE) { for (ii = 0; ii < totpix; ii++) { if (((double *)array)[ii] == doublenull) { anynull = 1; break; } } } if (anynull) { /* there are null values in the array */ tstatus = 0; ffgcrd(fptr, "ZBLANK", card, &tstatus); if (tstatus) { /* have to insert the ZBLANK keyword */ ffgcrd(fptr, "ZCMPTYPE", card, status); ffikyj(fptr, "ZBLANK", COMPRESS_NULL_VALUE, "null value in the compressed integer array", status); } } /* there are null values in the array */ } /* non-zero null value */ } /* floating point data type */ return(*status); } /*--------------------------------------------------------------------------*/ int fits_write_compressed_pixels(fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the array to be written */ LONGLONG fpixel, /* I - 'first pixel to write */ LONGLONG npixel, /* I - number of pixels to write */ int nullcheck, /* I - 0 for no null checking */ /* 1: pixels that are = nullval will be */ /* written with the FITS null pixel value */ /* (floating point arrays only) */ void *array, /* I - array of values to write */ void *nullval, /* I - value used to represent undefined pixels*/ int *status) /* IO - error status */ /* Write a consecutive set of pixels to a compressed image. This routine interpretes the n-dimensional image as a long one-dimensional array. This is actually a rather inconvenient way to write compressed images in general, and could be rather inefficient if the requested pixels to be written are located in many different image compression tiles. The general strategy used here is to write the requested pixels in blocks that correspond to rectangular image sections. */ { int naxis, ii, bytesperpixel; long naxes[MAX_COMPRESS_DIM], nread; LONGLONG tfirst, tlast, last0, last1, dimsize[MAX_COMPRESS_DIM]; long nplane, firstcoord[MAX_COMPRESS_DIM], lastcoord[MAX_COMPRESS_DIM]; char *arrayptr; if (*status > 0) return(*status); arrayptr = (char *) array; /* get size of array pixels, in bytes */ bytesperpixel = ffpxsz(datatype); for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { naxes[ii] = 1; firstcoord[ii] = 0; lastcoord[ii] = 0; } /* determine the dimensions of the image to be read */ ffgidm(fptr, &naxis, status); ffgisz(fptr, MAX_COMPRESS_DIM, naxes, status); /* calc the cumulative number of pixels in each successive dimension */ dimsize[0] = 1; for (ii = 1; ii < MAX_COMPRESS_DIM; ii++) dimsize[ii] = dimsize[ii - 1] * naxes[ii - 1]; /* determine the coordinate of the first and last pixel in the image */ /* Use zero based indexes here */ tfirst = fpixel - 1; tlast = tfirst + npixel - 1; for (ii = naxis - 1; ii >= 0; ii--) { firstcoord[ii] = (long) (tfirst / dimsize[ii]); lastcoord[ii] = (long) (tlast / dimsize[ii]); tfirst = tfirst - firstcoord[ii] * dimsize[ii]; tlast = tlast - lastcoord[ii] * dimsize[ii]; } /* to simplify things, treat 1-D, 2-D, and 3-D images as separate cases */ if (naxis == 1) { /* Simple: just write the requested range of pixels */ firstcoord[0] = firstcoord[0] + 1; lastcoord[0] = lastcoord[0] + 1; fits_write_compressed_img(fptr, datatype, firstcoord, lastcoord, nullcheck, array, nullval, status); return(*status); } else if (naxis == 2) { nplane = 0; /* write 1st (and only) plane of the image */ fits_write_compressed_img_plane(fptr, datatype, bytesperpixel, nplane, firstcoord, lastcoord, naxes, nullcheck, array, nullval, &nread, status); } else if (naxis == 3) { /* test for special case: writing an integral number of planes */ if (firstcoord[0] == 0 && firstcoord[1] == 0 && lastcoord[0] == naxes[0] - 1 && lastcoord[1] == naxes[1] - 1) { for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { /* convert from zero base to 1 base */ (firstcoord[ii])++; (lastcoord[ii])++; } /* we can write the contiguous block of pixels in one go */ fits_write_compressed_img(fptr, datatype, firstcoord, lastcoord, nullcheck, array, nullval, status); return(*status); } /* save last coordinate in temporary variables */ last0 = lastcoord[0]; last1 = lastcoord[1]; if (firstcoord[2] < lastcoord[2]) { /* we will write up to the last pixel in all but the last plane */ lastcoord[0] = naxes[0] - 1; lastcoord[1] = naxes[1] - 1; } /* write one plane of the cube at a time, for simplicity */ for (nplane = firstcoord[2]; nplane <= lastcoord[2]; nplane++) { if (nplane == lastcoord[2]) { lastcoord[0] = (long) last0; lastcoord[1] = (long) last1; } fits_write_compressed_img_plane(fptr, datatype, bytesperpixel, nplane, firstcoord, lastcoord, naxes, nullcheck, arrayptr, nullval, &nread, status); /* for all subsequent planes, we start with the first pixel */ firstcoord[0] = 0; firstcoord[1] = 0; /* increment pointers to next elements to be written */ arrayptr = arrayptr + nread * bytesperpixel; } } else { ffpmsg("only 1D, 2D, or 3D images are currently supported"); return(*status = DATA_COMPRESSION_ERR); } return(*status); } /*--------------------------------------------------------------------------*/ int fits_write_compressed_img_plane(fitsfile *fptr, /* I - FITS file */ int datatype, /* I - datatype of the array to be written */ int bytesperpixel, /* I - number of bytes per pixel in array */ long nplane, /* I - which plane of the cube to write */ long *firstcoord, /* I coordinate of first pixel to write */ long *lastcoord, /* I coordinate of last pixel to write */ long *naxes, /* I size of each image dimension */ int nullcheck, /* I - 0 for no null checking */ /* 1: pixels that are = nullval will be */ /* written with the FITS null pixel value */ /* (floating point arrays only) */ void *array, /* I - array of values that are written */ void *nullval, /* I - value for undefined pixels */ long *nread, /* O - total number of pixels written */ int *status) /* IO - error status */ /* in general we have to write the first partial row of the image, followed by the middle complete rows, followed by the last partial row of the image. If the first or last rows are complete, then write them at the same time as all the middle rows. */ { /* bottom left coord. and top right coord. */ long blc[MAX_COMPRESS_DIM], trc[MAX_COMPRESS_DIM]; char *arrayptr; *nread = 0; arrayptr = (char *) array; blc[2] = nplane + 1; trc[2] = nplane + 1; if (firstcoord[0] != 0) { /* have to read a partial first row */ blc[0] = firstcoord[0] + 1; blc[1] = firstcoord[1] + 1; trc[1] = blc[1]; if (lastcoord[1] == firstcoord[1]) trc[0] = lastcoord[0] + 1; /* 1st and last pixels in same row */ else trc[0] = naxes[0]; /* read entire rest of the row */ fits_write_compressed_img(fptr, datatype, blc, trc, nullcheck, arrayptr, nullval, status); *nread = *nread + trc[0] - blc[0] + 1; if (lastcoord[1] == firstcoord[1]) { return(*status); /* finished */ } /* set starting coord to beginning of next line */ firstcoord[0] = 0; firstcoord[1] += 1; arrayptr = arrayptr + (trc[0] - blc[0] + 1) * bytesperpixel; } /* write contiguous complete rows of the image, if any */ blc[0] = 1; blc[1] = firstcoord[1] + 1; trc[0] = naxes[0]; if (lastcoord[0] + 1 == naxes[0]) { /* can write the last complete row, too */ trc[1] = lastcoord[1] + 1; } else { /* last row is incomplete; have to read it separately */ trc[1] = lastcoord[1]; } if (trc[1] >= blc[1]) /* must have at least one whole line to read */ { fits_write_compressed_img(fptr, datatype, blc, trc, nullcheck, arrayptr, nullval, status); *nread = *nread + (trc[1] - blc[1] + 1) * naxes[0]; if (lastcoord[1] + 1 == trc[1]) return(*status); /* finished */ /* increment pointers for the last partial row */ arrayptr = arrayptr + (trc[1] - blc[1] + 1) * naxes[0] * bytesperpixel; } if (trc[1] == lastcoord[1] + 1) return(*status); /* all done */ /* set starting and ending coord to last line */ trc[0] = lastcoord[0] + 1; trc[1] = lastcoord[1] + 1; blc[1] = trc[1]; fits_write_compressed_img(fptr, datatype, blc, trc, nullcheck, arrayptr, nullval, status); *nread = *nread + trc[0] - blc[0] + 1; return(*status); } /* ######################################################################## */ /* ### Image Decompression Routines ### */ /* ######################################################################## */ /*--------------------------------------------------------------------------*/ int fits_img_decompress (fitsfile *infptr, /* image (bintable) to uncompress */ fitsfile *outfptr, /* empty HDU for output uncompressed image */ int *status) /* IO - error status */ /* This routine decompresses the whole image and writes it to the output file. */ { double *data; int ii, datatype = 0, byte_per_pix = 0, naxis, bitpix, numkeys; int nullcheck, anynul, tstatus, nullprime = 0, hdupos, norec = 0; LONGLONG fpixel[MAX_COMPRESS_DIM], lpixel[MAX_COMPRESS_DIM]; long inc[MAX_COMPRESS_DIM], naxes[MAX_COMPRESS_DIM]; long imgsize, memsize; float *nulladdr, fnulval; double dnulval; char card[FLEN_CARD]; if (*status > 0) return(*status); if (!fits_is_compressed_image(infptr, status) ) { ffpmsg("CHDU is not a compressed image (fits_img_decompress)"); return(*status = DATA_DECOMPRESSION_ERR); } /* get information about the state of the output file; does it already */ /* contain any keywords and HDUs? */ fits_get_hdu_num(outfptr, &hdupos); /* Get the current output HDU position */ fits_get_hdrspace(outfptr, &numkeys, 0, status); /* Was the input compressed HDU originally the primary array image? */ tstatus = 0; if (!fits_read_card(infptr, "ZSIMPLE", card, &tstatus)) { /* yes, input HDU was a primary array (not an IMAGE extension) */ /* Now determine if we can uncompress it into the primary array of */ /* the output file. This is only possible if the output file */ /* currently only contains a null primary array, with no addition */ /* header keywords and with no following extension in the FITS file. */ if (hdupos == 1) { /* are we positioned at the primary array? */ if (numkeys <= 10) { /* is the header practically empty? */ if (numkeys == 0) { /* primary HDU is completely empty */ nullprime = 1; } else { fits_get_img_param(outfptr, MAX_COMPRESS_DIM, &bitpix, &naxis, naxes, status); if (naxis == 0) /* is this a null image? */ nullprime = 1; } } } } if (nullprime) { /* We will delete the existing keywords in the null primary array and uncompress the input image into the primary array of the output */ for (ii = numkeys; ii > 0; ii--) fits_delete_record(outfptr, ii, status); } else { /* if the ZTENSION keyword doesn't exist, then we have to write the required keywords manually */ tstatus = 0; if (fits_read_card(infptr, "ZTENSION", card, &tstatus)) { /* create an empty output image with the correct dimensions */ if (ffcrim(outfptr, (infptr->Fptr)->zbitpix, (infptr->Fptr)->zndim, (infptr->Fptr)->znaxis, status) > 0) { ffpmsg("error creating output decompressed image HDU"); return (*status); } norec = 1; /* the required keywords have already been written */ } else { if (numkeys == 0) { /* the output file is currently completely empty */ /* In this case, the input is a compressed IMAGE extension. */ /* Since the uncompressed output file is currently completely empty, */ /* we need to write a null primary array before uncompressing the */ /* image extension */ ffcrim(outfptr, 8, 0, naxes, status); /* naxes is not used */ /* now create the empty extension to uncompress into */ if (fits_create_hdu(outfptr, status) > 0) { ffpmsg("error creating output decompressed image HDU"); return (*status); } } else { /* just create a new empty extension, then copy all the required */ /* keywords into it. */ fits_create_hdu(outfptr, status); } } } if (*status > 0) { ffpmsg("error creating output decompressed image HDU"); return (*status); } /* Copy the table header to the image header. */ if (imcomp_copy_comp2img(infptr, outfptr, norec, status) > 0) { ffpmsg("error copying header keywords from compressed image"); return (*status); } /* force a rescan of the output header keywords, then reset the scaling */ /* in case the BSCALE and BZERO keywords are present, so that the */ /* decompressed values won't be scaled when written to the output image */ ffrdef(outfptr, status); ffpscl(outfptr, 1.0, 0.0, status); ffpscl(infptr, 1.0, 0.0, status); /* initialize; no null checking is needed for integer images */ nullcheck = 0; nulladdr = &fnulval; /* determine datatype for image */ if ((infptr->Fptr)->zbitpix == BYTE_IMG) { datatype = TBYTE; byte_per_pix = 1; } else if ((infptr->Fptr)->zbitpix == SHORT_IMG) { datatype = TSHORT; byte_per_pix = sizeof(short); } else if ((infptr->Fptr)->zbitpix == LONG_IMG) { datatype = TINT; byte_per_pix = sizeof(int); } else if ((infptr->Fptr)->zbitpix == FLOAT_IMG) { /* In the case of float images we must check for NaNs */ nullcheck = 1; fnulval = FLOATNULLVALUE; nulladdr = &fnulval; datatype = TFLOAT; byte_per_pix = sizeof(float); } else if ((infptr->Fptr)->zbitpix == DOUBLE_IMG) { /* In the case of double images we must check for NaNs */ nullcheck = 1; dnulval = DOUBLENULLVALUE; nulladdr = (float *) &dnulval; datatype = TDOUBLE; byte_per_pix = sizeof(double); } /* calculate size of the image (in pixels) */ imgsize = 1; for (ii = 0; ii < (infptr->Fptr)->zndim; ii++) { imgsize *= (infptr->Fptr)->znaxis[ii]; fpixel[ii] = 1; /* Set first and last pixel to */ lpixel[ii] = (infptr->Fptr)->znaxis[ii]; /* include the entire image. */ inc[ii] = 1; } /* Calc equivalent number of double pixels same size as whole the image. */ /* We use double datatype to force the memory to be aligned properly */ memsize = ((imgsize * byte_per_pix) - 1) / sizeof(double) + 1; /* allocate memory for the image */ data = (double*) calloc (memsize, sizeof(double)); if (!data) { ffpmsg("Couldn't allocate memory for the uncompressed image"); return(*status = MEMORY_ALLOCATION); } /* uncompress the entire image into memory */ /* This routine should be enhanced sometime to only need enough */ /* memory to uncompress one tile at a time. */ fits_read_compressed_img(infptr, datatype, fpixel, lpixel, inc, nullcheck, nulladdr, data, NULL, &anynul, status); /* write the image to the output file */ if (anynul) fits_write_imgnull(outfptr, datatype, 1, imgsize, data, nulladdr, status); else fits_write_img(outfptr, datatype, 1, imgsize, data, status); free(data); return (*status); } /*--------------------------------------------------------------------------*/ int fits_decompress_img (fitsfile *infptr, /* image (bintable) to uncompress */ fitsfile *outfptr, /* empty HDU for output uncompressed image */ int *status) /* IO - error status */ /* This routine decompresses the whole image and writes it to the output file. */ { double *data; int ii, datatype = 0, byte_per_pix = 0; int nullcheck, anynul; LONGLONG fpixel[MAX_COMPRESS_DIM], lpixel[MAX_COMPRESS_DIM]; long inc[MAX_COMPRESS_DIM]; long imgsize, memsize; float *nulladdr, fnulval; double dnulval; if (*status > 0) return(*status); if (!fits_is_compressed_image(infptr, status) ) { ffpmsg("CHDU is not a compressed image (fits_decompress_img)"); return(*status = DATA_DECOMPRESSION_ERR); } /* create an empty output image with the correct dimensions */ if (ffcrim(outfptr, (infptr->Fptr)->zbitpix, (infptr->Fptr)->zndim, (infptr->Fptr)->znaxis, status) > 0) { ffpmsg("error creating output decompressed image HDU"); return (*status); } /* Copy the table header to the image header. */ if (imcomp_copy_imheader(infptr, outfptr, status) > 0) { ffpmsg("error copying header of compressed image"); return (*status); } /* force a rescan of the output header keywords, then reset the scaling */ /* in case the BSCALE and BZERO keywords are present, so that the */ /* decompressed values won't be scaled when written to the output image */ ffrdef(outfptr, status); ffpscl(outfptr, 1.0, 0.0, status); ffpscl(infptr, 1.0, 0.0, status); /* initialize; no null checking is needed for integer images */ nullcheck = 0; nulladdr = &fnulval; /* determine datatype for image */ if ((infptr->Fptr)->zbitpix == BYTE_IMG) { datatype = TBYTE; byte_per_pix = 1; } else if ((infptr->Fptr)->zbitpix == SHORT_IMG) { datatype = TSHORT; byte_per_pix = sizeof(short); } else if ((infptr->Fptr)->zbitpix == LONG_IMG) { datatype = TINT; byte_per_pix = sizeof(int); } else if ((infptr->Fptr)->zbitpix == FLOAT_IMG) { /* In the case of float images we must check for NaNs */ nullcheck = 1; fnulval = FLOATNULLVALUE; nulladdr = &fnulval; datatype = TFLOAT; byte_per_pix = sizeof(float); } else if ((infptr->Fptr)->zbitpix == DOUBLE_IMG) { /* In the case of double images we must check for NaNs */ nullcheck = 1; dnulval = DOUBLENULLVALUE; nulladdr = (float *) &dnulval; datatype = TDOUBLE; byte_per_pix = sizeof(double); } /* calculate size of the image (in pixels) */ imgsize = 1; for (ii = 0; ii < (infptr->Fptr)->zndim; ii++) { imgsize *= (infptr->Fptr)->znaxis[ii]; fpixel[ii] = 1; /* Set first and last pixel to */ lpixel[ii] = (infptr->Fptr)->znaxis[ii]; /* include the entire image. */ inc[ii] = 1; } /* Calc equivalent number of double pixels same size as whole the image. */ /* We use double datatype to force the memory to be aligned properly */ memsize = ((imgsize * byte_per_pix) - 1) / sizeof(double) + 1; /* allocate memory for the image */ data = (double*) calloc (memsize, sizeof(double)); if (!data) { ffpmsg("Couldn't allocate memory for the uncompressed image"); return(*status = MEMORY_ALLOCATION); } /* uncompress the entire image into memory */ /* This routine should be enhanced sometime to only need enough */ /* memory to uncompress one tile at a time. */ fits_read_compressed_img(infptr, datatype, fpixel, lpixel, inc, nullcheck, nulladdr, data, NULL, &anynul, status); /* write the image to the output file */ if (anynul) fits_write_imgnull(outfptr, datatype, 1, imgsize, data, nulladdr, status); else fits_write_img(outfptr, datatype, 1, imgsize, data, status); free(data); return (*status); } /*---------------------------------------------------------------------------*/ int fits_read_compressed_img(fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the array to be returned */ LONGLONG *infpixel, /* I - 'bottom left corner' of the subsection */ LONGLONG *inlpixel, /* I - 'top right corner' of the subsection */ long *ininc, /* I - increment to be applied in each dimension */ int nullcheck, /* I - 0 for no null checking */ /* 1: set undefined pixels = nullval */ /* 2: set nullarray=1 for undefined pixels */ void *nullval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ char *nullarray, /* O - array of flags = 1 if nullcheck = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a section of a compressed image; Note: lpixel may be larger than the size of the uncompressed image. Only the pixels within the image will be returned. */ { int naxis[MAX_COMPRESS_DIM], tiledim[MAX_COMPRESS_DIM]; long tilesize[MAX_COMPRESS_DIM], thistilesize[MAX_COMPRESS_DIM]; long ftile[MAX_COMPRESS_DIM], ltile[MAX_COMPRESS_DIM]; long tfpixel[MAX_COMPRESS_DIM], tlpixel[MAX_COMPRESS_DIM]; long rowdim[MAX_COMPRESS_DIM], offset[MAX_COMPRESS_DIM],ntemp; long fpixel[MAX_COMPRESS_DIM], lpixel[MAX_COMPRESS_DIM]; long inc[MAX_COMPRESS_DIM]; int ii, i5, i4, i3, i2, i1, i0, ndim, irow, pixlen, tilenul; void *buffer; char *bnullarray = 0; if (*status > 0) return(*status); if (!fits_is_compressed_image(fptr, status) ) { ffpmsg("CHDU is not a compressed image (fits_read_compressed_img)"); return(*status = DATA_DECOMPRESSION_ERR); } /* get temporary space for uncompressing one image tile */ if (datatype == TSHORT) { buffer = calloc ((fptr->Fptr)->maxtilelen, sizeof (short)); pixlen = sizeof(short); } else if (datatype == TINT) { buffer = calloc ((fptr->Fptr)->maxtilelen, sizeof (int)); pixlen = sizeof(int); } else if (datatype == TLONG) { buffer = calloc ((fptr->Fptr)->maxtilelen, sizeof (long)); pixlen = sizeof(long); } else if (datatype == TFLOAT) { buffer = calloc ((fptr->Fptr)->maxtilelen, sizeof (float)); pixlen = sizeof(float); } else if (datatype == TDOUBLE) { buffer = calloc ((fptr->Fptr)->maxtilelen, sizeof (double)); pixlen = sizeof(double); } else if (datatype == TUSHORT) { buffer = calloc ((fptr->Fptr)->maxtilelen, sizeof (unsigned short)); pixlen = sizeof(short); } else if (datatype == TUINT) { buffer = calloc ((fptr->Fptr)->maxtilelen, sizeof (unsigned int)); pixlen = sizeof(int); } else if (datatype == TULONG) { buffer = calloc ((fptr->Fptr)->maxtilelen, sizeof (unsigned long)); pixlen = sizeof(long); } else if (datatype == TBYTE || datatype == TSBYTE) { buffer = calloc ((fptr->Fptr)->maxtilelen, sizeof (char)); pixlen = 1; } else { ffpmsg("unsupported datatype for uncompressing image"); return(*status = BAD_DATATYPE); } if (buffer == NULL) { ffpmsg("Out of memory (fits_read_compress_img)"); return (*status = MEMORY_ALLOCATION); } /* allocate memory for a null flag array, if needed */ if (nullcheck == 2) { bnullarray = calloc ((fptr->Fptr)->maxtilelen, sizeof (char)); if (bnullarray == NULL) { ffpmsg("Out of memory (fits_read_compress_img)"); free(buffer); return (*status = MEMORY_ALLOCATION); } } /* initialize all the arrays */ for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { naxis[ii] = 1; tiledim[ii] = 1; tilesize[ii] = 1; ftile[ii] = 1; ltile[ii] = 1; rowdim[ii] = 1; } ndim = (fptr->Fptr)->zndim; ntemp = 1; for (ii = 0; ii < ndim; ii++) { /* support for mirror-reversed image sections */ if (infpixel[ii] <= inlpixel[ii]) { fpixel[ii] = (long) infpixel[ii]; lpixel[ii] = (long) inlpixel[ii]; inc[ii] = ininc[ii]; } else { fpixel[ii] = (long) inlpixel[ii]; lpixel[ii] = (long) infpixel[ii]; inc[ii] = -ininc[ii]; } /* calc number of tiles in each dimension, and tile containing */ /* the first and last pixel we want to read in each dimension */ naxis[ii] = (fptr->Fptr)->znaxis[ii]; if (fpixel[ii] < 1) { if (nullcheck == 2) { free(bnullarray); } free(buffer); return(*status = BAD_PIX_NUM); } tilesize[ii] = (fptr->Fptr)->tilesize[ii]; tiledim[ii] = (naxis[ii] - 1) / tilesize[ii] + 1; ftile[ii] = (fpixel[ii] - 1) / tilesize[ii] + 1; ltile[ii] = minvalue((lpixel[ii] - 1) / tilesize[ii] + 1, tiledim[ii]); rowdim[ii] = ntemp; /* total tiles in each dimension */ ntemp *= tiledim[ii]; } if (anynul) *anynul = 0; /* initialize */ /* support up to 6 dimensions for now */ /* tfpixel and tlpixel are the first and last image pixels */ /* along each dimension of the compression tile */ for (i5 = ftile[5]; i5 <= ltile[5]; i5++) { tfpixel[5] = (i5 - 1) * tilesize[5] + 1; tlpixel[5] = minvalue(tfpixel[5] + tilesize[5] - 1, naxis[5]); thistilesize[5] = tlpixel[5] - tfpixel[5] + 1; offset[5] = (i5 - 1) * rowdim[5]; for (i4 = ftile[4]; i4 <= ltile[4]; i4++) { tfpixel[4] = (i4 - 1) * tilesize[4] + 1; tlpixel[4] = minvalue(tfpixel[4] + tilesize[4] - 1, naxis[4]); thistilesize[4] = thistilesize[5] * (tlpixel[4] - tfpixel[4] + 1); offset[4] = (i4 - 1) * rowdim[4] + offset[5]; for (i3 = ftile[3]; i3 <= ltile[3]; i3++) { tfpixel[3] = (i3 - 1) * tilesize[3] + 1; tlpixel[3] = minvalue(tfpixel[3] + tilesize[3] - 1, naxis[3]); thistilesize[3] = thistilesize[4] * (tlpixel[3] - tfpixel[3] + 1); offset[3] = (i3 - 1) * rowdim[3] + offset[4]; for (i2 = ftile[2]; i2 <= ltile[2]; i2++) { tfpixel[2] = (i2 - 1) * tilesize[2] + 1; tlpixel[2] = minvalue(tfpixel[2] + tilesize[2] - 1, naxis[2]); thistilesize[2] = thistilesize[3] * (tlpixel[2] - tfpixel[2] + 1); offset[2] = (i2 - 1) * rowdim[2] + offset[3]; for (i1 = ftile[1]; i1 <= ltile[1]; i1++) { tfpixel[1] = (i1 - 1) * tilesize[1] + 1; tlpixel[1] = minvalue(tfpixel[1] + tilesize[1] - 1, naxis[1]); thistilesize[1] = thistilesize[2] * (tlpixel[1] - tfpixel[1] + 1); offset[1] = (i1 - 1) * rowdim[1] + offset[2]; for (i0 = ftile[0]; i0 <= ltile[0]; i0++) { tfpixel[0] = (i0 - 1) * tilesize[0] + 1; tlpixel[0] = minvalue(tfpixel[0] + tilesize[0] - 1, naxis[0]); thistilesize[0] = thistilesize[1] * (tlpixel[0] - tfpixel[0] + 1); /* calculate row of table containing this tile */ irow = i0 + offset[1]; /* printf("row %d, %d %d, %d %d, %d %d; %d\n", irow, tfpixel[0],tlpixel[0],tfpixel[1],tlpixel[1],tfpixel[2],tlpixel[2], thistilesize[0]); */ /* read and uncompress this row (tile) of the table */ /* also do type conversion and undefined pixel substitution */ /* at this point */ imcomp_decompress_tile(fptr, irow, thistilesize[0], datatype, nullcheck, nullval, buffer, bnullarray, &tilenul, status); if (tilenul && anynul) *anynul = 1; /* there are null pixels */ /* printf(" pixlen=%d, ndim=%d, %d %d %d, %d %d %d, %d %d %d\n", pixlen, ndim, fpixel[0],lpixel[0],inc[0],fpixel[1],lpixel[1],inc[1], fpixel[2],lpixel[2],inc[2]); */ /* copy the intersecting pixels from this tile to the output */ imcomp_copy_overlap(buffer, pixlen, ndim, tfpixel, tlpixel, bnullarray, array, fpixel, lpixel, inc, nullcheck, nullarray, status); } } } } } } if (nullcheck == 2) { free(bnullarray); } free(buffer); return(*status); } /*--------------------------------------------------------------------------*/ int fits_read_compressed_pixels(fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the array to be returned */ LONGLONG fpixel, /* I - 'first pixel to read */ LONGLONG npixel, /* I - number of pixels to read */ int nullcheck, /* I - 0 for no null checking */ /* 1: set undefined pixels = nullval */ /* 2: set nullarray=1 for undefined pixels */ void *nullval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ char *nullarray, /* O - array of flags = 1 if nullcheck = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a consecutive set of pixels from a compressed image. This routine interpretes the n-dimensional image as a long one-dimensional array. This is actually a rather inconvenient way to read compressed images in general, and could be rather inefficient if the requested pixels to be read are located in many different image compression tiles. The general strategy used here is to read the requested pixels in blocks that correspond to rectangular image sections. */ { int naxis, ii, bytesperpixel, planenul; long naxes[MAX_COMPRESS_DIM], nread; long nplane, inc[MAX_COMPRESS_DIM]; LONGLONG tfirst, tlast, last0, last1, dimsize[MAX_COMPRESS_DIM]; LONGLONG firstcoord[MAX_COMPRESS_DIM], lastcoord[MAX_COMPRESS_DIM]; char *arrayptr, *nullarrayptr; if (*status > 0) return(*status); arrayptr = (char *) array; nullarrayptr = nullarray; /* get size of array pixels, in bytes */ bytesperpixel = ffpxsz(datatype); for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { naxes[ii] = 1; firstcoord[ii] = 0; lastcoord[ii] = 0; inc[ii] = 1; } /* determine the dimensions of the image to be read */ ffgidm(fptr, &naxis, status); ffgisz(fptr, MAX_COMPRESS_DIM, naxes, status); /* calc the cumulative number of pixels in each successive dimension */ dimsize[0] = 1; for (ii = 1; ii < MAX_COMPRESS_DIM; ii++) dimsize[ii] = dimsize[ii - 1] * naxes[ii - 1]; /* determine the coordinate of the first and last pixel in the image */ /* Use zero based indexes here */ tfirst = fpixel - 1; tlast = tfirst + npixel - 1; for (ii = naxis - 1; ii >= 0; ii--) { firstcoord[ii] = tfirst / dimsize[ii]; lastcoord[ii] = tlast / dimsize[ii]; tfirst = tfirst - firstcoord[ii] * dimsize[ii]; tlast = tlast - lastcoord[ii] * dimsize[ii]; } /* to simplify things, treat 1-D, 2-D, and 3-D images as separate cases */ if (naxis == 1) { /* Simple: just read the requested range of pixels */ firstcoord[0] = firstcoord[0] + 1; lastcoord[0] = lastcoord[0] + 1; fits_read_compressed_img(fptr, datatype, firstcoord, lastcoord, inc, nullcheck, nullval, array, nullarray, anynul, status); return(*status); } else if (naxis == 2) { nplane = 0; /* read 1st (and only) plane of the image */ fits_read_compressed_img_plane(fptr, datatype, bytesperpixel, nplane, firstcoord, lastcoord, inc, naxes, nullcheck, nullval, array, nullarray, anynul, &nread, status); } else if (naxis == 3) { /* test for special case: reading an integral number of planes */ if (firstcoord[0] == 0 && firstcoord[1] == 0 && lastcoord[0] == naxes[0] - 1 && lastcoord[1] == naxes[1] - 1) { for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { /* convert from zero base to 1 base */ (firstcoord[ii])++; (lastcoord[ii])++; } /* we can read the contiguous block of pixels in one go */ fits_read_compressed_img(fptr, datatype, firstcoord, lastcoord, inc, nullcheck, nullval, array, nullarray, anynul, status); return(*status); } if (anynul) *anynul = 0; /* initialize */ /* save last coordinate in temporary variables */ last0 = lastcoord[0]; last1 = lastcoord[1]; if (firstcoord[2] < lastcoord[2]) { /* we will read up to the last pixel in all but the last plane */ lastcoord[0] = naxes[0] - 1; lastcoord[1] = naxes[1] - 1; } /* read one plane of the cube at a time, for simplicity */ for (nplane = (long) firstcoord[2]; nplane <= lastcoord[2]; nplane++) { if (nplane == lastcoord[2]) { lastcoord[0] = last0; lastcoord[1] = last1; } fits_read_compressed_img_plane(fptr, datatype, bytesperpixel, nplane, firstcoord, lastcoord, inc, naxes, nullcheck, nullval, arrayptr, nullarrayptr, &planenul, &nread, status); if (planenul && anynul) *anynul = 1; /* there are null pixels */ /* for all subsequent planes, we start with the first pixel */ firstcoord[0] = 0; firstcoord[1] = 0; /* increment pointers to next elements to be read */ arrayptr = arrayptr + nread * bytesperpixel; if (nullarrayptr && (nullcheck == 2) ) nullarrayptr = nullarrayptr + nread; } } else { ffpmsg("only 1D, 2D, or 3D images are currently supported"); return(*status = DATA_DECOMPRESSION_ERR); } return(*status); } /*--------------------------------------------------------------------------*/ int fits_read_compressed_img_plane(fitsfile *fptr, /* I - FITS file */ int datatype, /* I - datatype of the array to be returned */ int bytesperpixel, /* I - number of bytes per pixel in array */ long nplane, /* I - which plane of the cube to read */ LONGLONG *firstcoord, /* coordinate of first pixel to read */ LONGLONG *lastcoord, /* coordinate of last pixel to read */ long *inc, /* increment of pixels to read */ long *naxes, /* size of each image dimension */ int nullcheck, /* I - 0 for no null checking */ /* 1: set undefined pixels = nullval */ /* 2: set nullarray=1 for undefined pixels */ void *nullval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ char *nullarray, /* O - array of flags = 1 if nullcheck = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ long *nread, /* O - total number of pixels read and returned*/ int *status) /* IO - error status */ /* in general we have to read the first partial row of the image, followed by the middle complete rows, followed by the last partial row of the image. If the first or last rows are complete, then read them at the same time as all the middle rows. */ { /* bottom left coord. and top right coord. */ LONGLONG blc[MAX_COMPRESS_DIM], trc[MAX_COMPRESS_DIM]; char *arrayptr, *nullarrayptr; int tnull; if (anynul) *anynul = 0; *nread = 0; arrayptr = (char *) array; nullarrayptr = nullarray; blc[2] = nplane + 1; trc[2] = nplane + 1; if (firstcoord[0] != 0) { /* have to read a partial first row */ blc[0] = firstcoord[0] + 1; blc[1] = firstcoord[1] + 1; trc[1] = blc[1]; if (lastcoord[1] == firstcoord[1]) trc[0] = lastcoord[0] + 1; /* 1st and last pixels in same row */ else trc[0] = naxes[0]; /* read entire rest of the row */ fits_read_compressed_img(fptr, datatype, blc, trc, inc, nullcheck, nullval, arrayptr, nullarrayptr, &tnull, status); *nread = *nread + (long) (trc[0] - blc[0] + 1); if (tnull && anynul) *anynul = 1; /* there are null pixels */ if (lastcoord[1] == firstcoord[1]) { return(*status); /* finished */ } /* set starting coord to beginning of next line */ firstcoord[0] = 0; firstcoord[1] += 1; arrayptr = arrayptr + (trc[0] - blc[0] + 1) * bytesperpixel; if (nullarrayptr && (nullcheck == 2) ) nullarrayptr = nullarrayptr + (trc[0] - blc[0] + 1); } /* read contiguous complete rows of the image, if any */ blc[0] = 1; blc[1] = firstcoord[1] + 1; trc[0] = naxes[0]; if (lastcoord[0] + 1 == naxes[0]) { /* can read the last complete row, too */ trc[1] = lastcoord[1] + 1; } else { /* last row is incomplete; have to read it separately */ trc[1] = lastcoord[1]; } if (trc[1] >= blc[1]) /* must have at least one whole line to read */ { fits_read_compressed_img(fptr, datatype, blc, trc, inc, nullcheck, nullval, arrayptr, nullarrayptr, &tnull, status); *nread = *nread + (long) ((trc[1] - blc[1] + 1) * naxes[0]); if (tnull && anynul) *anynul = 1; if (lastcoord[1] + 1 == trc[1]) return(*status); /* finished */ /* increment pointers for the last partial row */ arrayptr = arrayptr + (trc[1] - blc[1] + 1) * naxes[0] * bytesperpixel; if (nullarrayptr && (nullcheck == 2) ) nullarrayptr = nullarrayptr + (trc[1] - blc[1] + 1) * naxes[0]; } if (trc[1] == lastcoord[1] + 1) return(*status); /* all done */ /* set starting and ending coord to last line */ trc[0] = lastcoord[0] + 1; trc[1] = lastcoord[1] + 1; blc[1] = trc[1]; fits_read_compressed_img(fptr, datatype, blc, trc, inc, nullcheck, nullval, arrayptr, nullarrayptr, &tnull, status); if (tnull && anynul) *anynul = 1; *nread = *nread + (long) (trc[0] - blc[0] + 1); return(*status); } /*--------------------------------------------------------------------------*/ int imcomp_get_compressed_image_par(fitsfile *infptr, int *status) /* This routine reads keywords from a BINTABLE extension containing a compressed image. */ { char keyword[FLEN_KEYWORD]; char value[FLEN_VALUE]; int ii, tstatus; long expect_nrows, maxtilelen; if (*status > 0) return(*status); /* Copy relevant header keyword values to structure */ if (ffgky (infptr, TSTRING, "ZCMPTYPE", value, NULL, status) > 0) { ffpmsg("required ZCMPTYPE compression keyword not found in"); ffpmsg(" imcomp_get_compressed_image_par"); return(*status); } (infptr->Fptr)->zcmptype[0] = '\0'; strncat((infptr->Fptr)->zcmptype, value, 11); if (!FSTRCMP(value, "RICE_1") ) (infptr->Fptr)->compress_type = RICE_1; else if (!FSTRCMP(value, "HCOMPRESS_1") ) (infptr->Fptr)->compress_type = HCOMPRESS_1; else if (!FSTRCMP(value, "GZIP_1") ) (infptr->Fptr)->compress_type = GZIP_1; else if (!FSTRCMP(value, "PLIO_1") ) (infptr->Fptr)->compress_type = PLIO_1; else { ffpmsg("Unknown image compression type:"); ffpmsg(value); return (*status = DATA_DECOMPRESSION_ERR); } if (ffgky (infptr, TINT, "ZBITPIX", &(infptr->Fptr)->zbitpix, NULL, status) > 0) { ffpmsg("required ZBITPIX compression keyword not found"); return(*status); } if (ffgky (infptr,TINT, "ZNAXIS", &(infptr->Fptr)->zndim, NULL, status) > 0) { ffpmsg("required ZNAXIS compression keyword not found"); return(*status); } if ((infptr->Fptr)->zndim < 1) { ffpmsg("Compressed image has no data (ZNAXIS < 1)"); return (*status = BAD_NAXIS); } if ((infptr->Fptr)->zndim > MAX_COMPRESS_DIM) { ffpmsg("Compressed image has too many dimensions"); return(*status = BAD_NAXIS); } expect_nrows = 1; maxtilelen = 1; for (ii = 0; ii < (infptr->Fptr)->zndim; ii++) { /* get image size */ sprintf (keyword, "ZNAXIS%d", ii+1); ffgky (infptr, TLONG,keyword, &(infptr->Fptr)->znaxis[ii],NULL,status); if (*status > 0) { ffpmsg("required ZNAXISn compression keyword not found"); return(*status); } /* get compression tile size */ sprintf (keyword, "ZTILE%d", ii+1); /* set default tile size in case keywords are not present */ if (ii == 0) (infptr->Fptr)->tilesize[0] = (infptr->Fptr)->znaxis[0]; else (infptr->Fptr)->tilesize[ii] = 1; tstatus = 0; ffgky (infptr, TLONG, keyword, &(infptr->Fptr)->tilesize[ii], NULL, &tstatus); expect_nrows *= (((infptr->Fptr)->znaxis[ii] - 1) / (infptr->Fptr)->tilesize[ii]+ 1); maxtilelen *= (infptr->Fptr)->tilesize[ii]; } /* check number of rows */ if (expect_nrows != (infptr->Fptr)->numrows) { ffpmsg( "number of table rows != the number of tiles in compressed image"); return (*status = DATA_DECOMPRESSION_ERR); } /* read any algorithm specific parameters */ if ((infptr->Fptr)->compress_type == RICE_1 ) { if (ffgky(infptr, TINT,"ZVAL1", &(infptr->Fptr)->rice_blocksize, NULL, status) > 0) { ffpmsg("required ZVAL1 compression keyword not found"); return(*status); } if ((infptr->Fptr)->zbitpix < 0) { /* try to read the floating point quantization parameter */ tstatus = 0; ffgky(infptr, TINT,"ZVAL2", &(infptr->Fptr)->noise_nbits, NULL, &tstatus); } } else if ((infptr->Fptr)->compress_type == HCOMPRESS_1 ) { if (ffgky(infptr, TINT,"ZVAL1", &(infptr->Fptr)->hcomp_scale, NULL, status) > 0) { ffpmsg("required ZVAL1 compression keyword not found"); return(*status); } tstatus = 0; ffgky(infptr, TINT,"ZVAL2", &(infptr->Fptr)->hcomp_smooth, NULL, &tstatus); if ((infptr->Fptr)->zbitpix < 0) { /* try to read the floating point quantization parameter */ tstatus = 0; ffgky(infptr, TINT,"ZVAL3", &(infptr->Fptr)->noise_nbits, NULL, &tstatus); } } else { if ((infptr->Fptr)->zbitpix < 0) { /* try to read the floating point quantization parameter */ tstatus = 0; ffgky(infptr, TINT,"ZVAL1", &(infptr->Fptr)->noise_nbits, NULL, &tstatus); } } /* store number of pixels in each compression tile, */ /* and max size of the compressed tile buffer */ (infptr->Fptr)->maxtilelen = maxtilelen; (infptr->Fptr)->maxelem = imcomp_calc_max_elem ((infptr->Fptr)->compress_type, maxtilelen, (infptr->Fptr)->zbitpix, (infptr->Fptr)->rice_blocksize); /* Get Column numbers. */ if (ffgcno(infptr, CASEINSEN, "COMPRESSED_DATA", &(infptr->Fptr)->cn_compressed, status) > 0) { ffpmsg("couldn't find COMPRESSED_DATA column (fits_get_compressed_img_par)"); return(*status = DATA_DECOMPRESSION_ERR); } ffpmrk(); /* put mark on message stack; erase any messages after this */ tstatus = 0; ffgcno(infptr,CASEINSEN, "UNCOMPRESSED_DATA", &(infptr->Fptr)->cn_uncompressed, &tstatus); tstatus = 0; if (ffgcno(infptr, CASEINSEN, "ZSCALE", &(infptr->Fptr)->cn_zscale, &tstatus) > 0) { /* CMPSCALE column doesn't exist; see if there is a keyword */ tstatus = 0; if (ffgky(infptr, TDOUBLE, "ZSCALE", &(infptr->Fptr)->zscale, NULL, &tstatus) <= 0) (infptr->Fptr)->cn_zscale = -1; /* flag for a constant ZSCALE */ } tstatus = 0; if (ffgcno(infptr, CASEINSEN, "ZZERO", &(infptr->Fptr)->cn_zzero, &tstatus) > 0) { /* CMPZERO column doesn't exist; see if there is a keyword */ tstatus = 0; if (ffgky(infptr, TDOUBLE, "ZZERO", &(infptr->Fptr)->zzero, NULL, &tstatus) <= 0) (infptr->Fptr)->cn_zzero = -1; /* flag for a constant ZZERO */ } tstatus = 0; if (ffgcno(infptr, CASEINSEN, "ZBLANK", &(infptr->Fptr)->cn_zblank, &tstatus) > 0) { /* CMPZERO column doesn't exist; see if there is a keyword */ tstatus = 0; if (ffgky(infptr, TINT, "ZBLANK", &(infptr->Fptr)->zblank, NULL, &tstatus) <= 0) (infptr->Fptr)->cn_zblank = -1; /* flag for a constant ZBLANK */ } /* read the conventional BSCALE and BZERO scaling keywords, if present */ tstatus = 0; if (ffgky (infptr, TDOUBLE, "BSCALE", &(infptr->Fptr)->cn_bscale, NULL, &tstatus) > 0) { (infptr->Fptr)->cn_bscale = 1.0; } tstatus = 0; if (ffgky (infptr, TDOUBLE, "BZERO", &(infptr->Fptr)->cn_bzero, NULL, &tstatus) > 0) { (infptr->Fptr)->cn_bzero = 0.0; } ffcmrk(); /* clear any spurious error messages, back to the mark */ return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_copy_imheader(fitsfile *infptr, fitsfile *outfptr, int *status) /* This routine reads the header keywords from the input image and copies them to the output image; the manditory structural keywords and the checksum keywords are not copied. If the DATE keyword is copied, then it is updated with the current date and time. */ { int nkeys, ii, keyclass; char card[FLEN_CARD]; /* a header record */ if (*status > 0) return(*status); ffghsp(infptr, &nkeys, NULL, status); /* get number of keywords in image */ for (ii = 5; ii <= nkeys; ii++) /* skip the first 4 keywords */ { ffgrec(infptr, ii, card, status); keyclass = ffgkcl(card); /* Get the type/class of keyword */ /* don't copy structural keywords or checksum keywords */ if ((keyclass <= TYP_CMPRS_KEY) || (keyclass == TYP_CKSUM_KEY)) continue; if (FSTRNCMP(card, "DATE ", 5) == 0) /* write current date */ { ffpdat(outfptr, status); } else if (FSTRNCMP(card, "EXTNAME ", 8) == 0) { /* don't copy default EXTNAME keyword from a compressed image */ if (FSTRNCMP(card, "EXTNAME = 'COMPRESSED_IMAGE'", 28)) { /* if EXTNAME keyword already exists, overwrite it */ /* otherwise append a new EXTNAME keyword */ ffucrd(outfptr, "EXTNAME", card, status); } } else { /* just copy the keyword to the output header */ ffprec (outfptr, card, status); } if (*status > 0) return (*status); } return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_copy_img2comp(fitsfile *infptr, fitsfile *outfptr, int *status) /* This routine copies the header keywords from the uncompressed input image and to the compressed image (in a binary table) */ { char card[FLEN_CARD]; /* a header record */ /* tile compressed image keyword translation table */ /* INPUT OUTPUT */ /* 01234567 01234567 */ char *patterns[][2] = {{"SIMPLE", "ZSIMPLE" }, {"XTENSION", "ZTENSION" }, {"BITPIX", "ZBITPIX" }, {"NAXIS", "ZNAXIS" }, {"NAXISm", "ZNAXISm" }, {"EXTEND", "ZEXTEND" }, {"BLOCKED", "ZBLOCKED"}, {"PCOUNT", "ZPCOUNT" }, {"GCOUNT", "ZGCOUNT" }, {"CHECKSUM","ZHECKSUM"}, /* save original checksums */ {"DATASUM", "ZDATASUM"}, {"*", "+" }}; /* copy all other keywords */ int npat; if (*status > 0) return(*status); /* write a default EXTNAME keyword if it doesn't exist in input file*/ fits_read_card(infptr, "EXTNAME", card, status); if (*status) { *status = 0; strcpy(card, "EXTNAME = 'COMPRESSED_IMAGE'"); fits_write_record(outfptr, card, status); } /* copy all the keywords from the input file to the output */ npat = sizeof(patterns)/sizeof(patterns[0][0])/2; fits_translate_keywords(infptr, outfptr, 1, patterns, npat, 0, 0, 0, status); if (*status > 0) return (*status); return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_copy_comp2img(fitsfile *infptr, fitsfile *outfptr, int norec, int *status) /* This routine copies the header keywords from the compressed input image and to the uncompressed image (in a binary table) */ { char card[FLEN_CARD]; /* a header record */ char *patterns[40][2]; char negative[] = "-"; int ii, npat, nreq, nsp; /* tile compressed image keyword translation table */ /* INPUT OUTPUT */ /* 01234567 01234567 */ /* only translate these if required keywords not already written */ char *reqkeys[][2] = { {"ZSIMPLE", "SIMPLE" }, {"ZTENSION", "XTENSION"}, {"ZBITPIX", "BITPIX" }, {"ZNAXIS", "NAXIS" }, {"ZNAXISm", "NAXISm" }, {"ZEXTEND", "EXTEND" }, {"ZBLOCKED", "BLOCKED"}, {"ZPCOUNT", "PCOUNT" }, {"ZGCOUNT", "GCOUNT" }, {"ZHECKSUM", "CHECKSUM"}, /* restore original checksums */ {"ZDATASUM", "DATASUM"}}; /* other special keywords */ char *spkeys[][2] = { {"XTENSION", "-" }, {"BITPIX", "-" }, {"NAXIS", "-" }, {"NAXISm", "-" }, {"PCOUNT", "-" }, {"GCOUNT", "-" }, {"TFIELDS", "-" }, {"TTYPEm", "-" }, {"TFORMm", "-" }, {"ZIMAGE", "-" }, {"ZTILEm", "-" }, {"ZCMPTYPE", "-" }, {"ZNAMEm", "-" }, {"ZVALm", "-" }, {"CHECKSUM","-" }, /* delete checksums */ {"DATASUM", "-" }, {"EXTNAME", "+" }, /* we may change this, below */ {"*", "+" }}; if (*status > 0) return(*status); nreq = sizeof(reqkeys)/sizeof(reqkeys[0][0])/2; nsp = sizeof(spkeys)/sizeof(spkeys[0][0])/2; /* construct translation patterns */ for (ii = 0; ii < nreq; ii++) { patterns[ii][0] = reqkeys[ii][0]; if (norec) patterns[ii][1] = negative; else patterns[ii][1] = reqkeys[ii][1]; } for (ii = 0; ii < nsp; ii++) { patterns[ii+nreq][0] = spkeys[ii][0]; patterns[ii+nreq][1] = spkeys[ii][1]; } npat = nreq + nsp; /* see if the EXTNAME keyword should be copied or not */ fits_read_card(infptr, "EXTNAME", card, status); if (!strncmp(card, "EXTNAME = 'COMPRESSED_IMAGE'", 28)) patterns[npat-2][1] = negative; /* translate and copy the keywords from the input file to the output */ fits_translate_keywords(infptr, outfptr, 1, patterns, npat, 0, 0, 0, status); if (*status > 0) return (*status); return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_decompress_tile (fitsfile *infptr, int nrow, /* I - row of table to read and uncompress */ int tilelen, /* I - number of pixels in the tile */ int datatype, /* I - datatype to be returned in 'buffer' */ int nullcheck, /* I - 0 for no null checking */ void *nulval, /* I - value to be used for undefined pixels */ void *buffer, /* O - buffer for returned decompressed values */ char *bnullarray, /* O - buffer for returned null flags */ int *anynul, /* O - any null values returned? */ int *status) /* This routine decompresses one tile of the image */ { int *idata = 0; /* uncompressed integer data */ LONGLONG *lldata; size_t idatalen, tilebytesize; int ii, tnull; /* value in the data which represents nulls */ unsigned char *cbuf = 0; /* compressed data */ unsigned char charnull = 0; short *sbuf = 0; short snull = 0; int blocksize; double bscale, bzero, dummy = 0; /* scaling parameters */ long nelem = 0, offset = 0; /* number of bytes */ int smooth, nx, ny, scale; /* hcompress parameters */ if (*status > 0) return(*status); /* get length of the compressed byte stream */ ffgdes (infptr, (infptr->Fptr)->cn_compressed, nrow, &nelem, &offset, status); /* EOF error here indicates that this tile has not yet been written */ if (*status == END_OF_FILE) return(*status = NO_COMPRESSED_TILE); /* **************************************************************** */ if (nelem == 0) /* tile was not compressed; read uncompressed data */ { if ((infptr->Fptr)->cn_uncompressed < 1 ) { return (*status = NO_COMPRESSED_TILE); } /* no compressed data, so simply read the uncompressed data */ /* directly from the UNCOMPRESSED_DATA column, then return */ ffgdes (infptr, (infptr->Fptr)->cn_uncompressed, nrow, &nelem, &offset, status); if (nelem == 0 && offset == 0) return (*status = NO_COMPRESSED_TILE); if (nullcheck <= 1) fits_read_col(infptr, datatype, (infptr->Fptr)->cn_uncompressed, nrow, 1, nelem, nulval, buffer, anynul, status); else fits_read_colnull(infptr, datatype, (infptr->Fptr)->cn_uncompressed, nrow, 1, nelem, buffer, bnullarray, anynul, status); return(*status); } /* **************************************************************** */ if (nullcheck == 2) { for (ii = 0; ii < tilelen; ii++) /* initialize the null array */ bnullarray[ii] = 0; } if (anynul) *anynul = 0; /* get linear scaling and offset values, if they exist */ if ((infptr->Fptr)->cn_zscale == 0) { /* set default scaling, if scaling is not defined */ bscale = 1.; bzero = 0.; } else if ((infptr->Fptr)->cn_zscale == -1) { bscale = (infptr->Fptr)->zscale; bzero = (infptr->Fptr)->zzero; } else { /* read the linear scale and offset values for this row */ ffgcvd (infptr, (infptr->Fptr)->cn_zscale, nrow, 1, 1, 0., &bscale, NULL, status); ffgcvd (infptr, (infptr->Fptr)->cn_zzero, nrow, 1, 1, 0., &bzero, NULL, status); if (*status > 0) { ffpmsg("error reading scaling factor and offset for compressed tile"); free(idata); free (cbuf); return (*status); } } if (bscale == 1.0 && bzero == 0.0 ) { /* if no other scaling has been specified, try using the values given by the BSCALE and BZERO keywords, if any */ bscale = (infptr->Fptr)->cn_bscale; bzero = (infptr->Fptr)->cn_bzero; } /* ************************************************************* */ /* get the value used to represent nulls in the int array */ if ((infptr->Fptr)->cn_zblank == 0) { nullcheck = 0; /* no null value; don't check for nulls */ } else if ((infptr->Fptr)->cn_zblank == -1) { tnull = (infptr->Fptr)->zblank; /* use the the ZBLANK keyword */ } else { /* read the null value for this row */ ffgcvk (infptr, (infptr->Fptr)->cn_zblank, nrow, 1, 1, 0, &tnull, NULL, status); if (*status > 0) { ffpmsg("error reading null value for compressed tile"); free(idata); free (cbuf); return (*status); } } /* ************************************************************* */ /* allocate memory for uncompressed integers */ if ((infptr->Fptr)->compress_type == HCOMPRESS_1 && ((infptr->Fptr)->zbitpix != BYTE_IMG && (infptr->Fptr)->zbitpix != SHORT_IMG) ) { /* must allocate 8 bytes per pixel of scratch space */ lldata = (LONGLONG*) calloc (tilelen, sizeof (LONGLONG)); idata = (int *) lldata; } else { idata = (int*) calloc (tilelen, sizeof (int)); } if (idata == NULL) { ffpmsg("Out of memory for idata. (imcomp_decompress_tile)"); return (*status = MEMORY_ALLOCATION); } /* ************************************************************* */ if ((infptr->Fptr)->compress_type == RICE_1) { cbuf = (unsigned char *) calloc (nelem, sizeof (unsigned char)); if (cbuf == NULL) { ffpmsg("Out of memory for cbuf. (imcomp_decompress_tile)"); free(idata); return (*status = MEMORY_ALLOCATION); } /* read array of compressed bytes */ if (fits_read_col(infptr, TBYTE, (infptr->Fptr)->cn_compressed, nrow, 1, nelem, &charnull, cbuf, NULL, status) > 0) { ffpmsg("error reading compressed byte stream from binary table"); free (cbuf); free(idata); return (*status); } /* uncompress the data */ blocksize = (infptr->Fptr)->rice_blocksize; if ((*status = fits_rdecomp (cbuf, nelem, (unsigned int *)idata, tilelen, blocksize))) { free (cbuf); free(idata); return (*status); } free(cbuf); } /* ************************************************************* */ else if ((infptr->Fptr)->compress_type == HCOMPRESS_1) { cbuf = (unsigned char *) calloc (nelem, sizeof (unsigned char)); if (cbuf == NULL) { ffpmsg("Out of memory for cbuf. (imcomp_decompress_tile)"); free(idata); return (*status = MEMORY_ALLOCATION); } /* read array of compressed bytes */ if (fits_read_col(infptr, TBYTE, (infptr->Fptr)->cn_compressed, nrow, 1, nelem, &charnull, cbuf, NULL, status) > 0) { ffpmsg("error reading compressed byte stream from binary table"); free (cbuf); free(idata); return (*status); } /* uncompress the data */ smooth = (infptr->Fptr)->hcomp_smooth; if ( ((infptr->Fptr)->zbitpix == BYTE_IMG || (infptr->Fptr)->zbitpix == SHORT_IMG) ) { if ((*status = fits_hdecompress(cbuf, smooth, idata, &nx, &ny, &scale, status))) { free (cbuf); free(idata); return (*status); } } else { /* idata must have been allocated twice as large for this to work */ if ((*status = fits_hdecompress64(cbuf, smooth, lldata, &nx, &ny, &scale, status))) { free (cbuf); free(idata); return (*status); } } free(cbuf); } /* ************************************************************* */ else if ((infptr->Fptr)->compress_type == PLIO_1) { sbuf = (short *) calloc (nelem, sizeof (short)); if (sbuf == NULL) { ffpmsg("Out of memory for sbuf. (imcomp_decompress_tile)"); free(idata); return (*status = MEMORY_ALLOCATION); } /* read array of compressed bytes */ if (fits_read_col(infptr, TSHORT, (infptr->Fptr)->cn_compressed, nrow, 1, nelem, &snull, sbuf, NULL, status) > 0) { ffpmsg("error reading compressed byte stream from binary table"); free(idata); free (sbuf); return (*status); } pl_l2pi (sbuf, 1, idata, tilelen); /* uncompress the data */ free(sbuf); } /* ************************************************************* */ else if ((infptr->Fptr)->compress_type == GZIP_1) { cbuf = (unsigned char *) calloc (nelem, sizeof (unsigned char)); if (cbuf == NULL) { ffpmsg("Out of memory for cbuf. (imcomp_decompress_tile)"); free(idata); return (*status = MEMORY_ALLOCATION); } /* read array of compressed bytes */ if (fits_read_col(infptr, TBYTE, (infptr->Fptr)->cn_compressed, nrow, 1, nelem, &charnull, cbuf, NULL, status) > 0) { ffpmsg("error reading compressed byte stream from binary table"); free(idata); free (cbuf); return (*status); } /* uncompress the data */ idatalen = tilelen * sizeof(int); if (uncompress2mem_from_mem ((char *)cbuf, nelem, (char **) &idata, &idatalen, realloc, &tilebytesize, status)) { ffpmsg("uncompress2mem_from_mem returned with an error"); free(idata); free (cbuf); return (*status); } #if BYTESWAPPED ffswap4(idata, tilelen); /* reverse order of bytes */ #endif if (idatalen != tilebytesize) { ffpmsg("error: uncompressed tile has wrong size"); free(idata); free (cbuf); return (*status = DATA_DECOMPRESSION_ERR); } free(cbuf); } /* ************************************************************* */ else { ffpmsg("unknown compression algorithm"); free(idata); return (*status = DATA_DECOMPRESSION_ERR); } /* ************************************************************* */ /* copy the uncompressed tile data to the output buffer, doing */ /* null checking, datatype conversion and linear scaling, if necessary */ if (nulval == 0) nulval = &dummy; /* set address to dummy value */ if (datatype == TSHORT) { fffi4i2(idata, tilelen, bscale, bzero, nullcheck, tnull, *(short *) nulval, bnullarray, anynul, (short *) buffer, status); } else if (datatype == TINT) { fffi4int(idata, (long) tilelen, bscale, bzero, nullcheck, tnull, *(int *) nulval, bnullarray, anynul, (int *) buffer, status); } else if (datatype == TLONG) { fffi4i4(idata, tilelen, bscale, bzero, nullcheck, tnull, *(long *) nulval, bnullarray, anynul, (long *) buffer, status); } else if (datatype == TFLOAT) { fffi4r4(idata, tilelen, bscale, bzero, nullcheck, tnull, *(float *) nulval, bnullarray, anynul, (float *) buffer, status); } else if (datatype == TDOUBLE) { fffi4r8(idata, tilelen, bscale, bzero, nullcheck, tnull, *(double *) nulval, bnullarray, anynul, (double *) buffer, status); } else if (datatype == TBYTE) { fffi4i1(idata, tilelen, bscale, bzero, nullcheck, tnull, *(unsigned char *) nulval, bnullarray, anynul, (unsigned char *) buffer, status); } else if (datatype == TSBYTE) { fffi4s1(idata, tilelen, bscale, bzero, nullcheck, tnull, *(signed char *) nulval, bnullarray, anynul, (signed char *) buffer, status); } else if (datatype == TUSHORT) { fffi4u2(idata, tilelen, bscale, bzero, nullcheck, tnull, *(unsigned short *) nulval, bnullarray, anynul, (unsigned short *) buffer, status); } else if (datatype == TUINT) { fffi4uint(idata, tilelen, bscale, bzero, nullcheck, tnull, *(unsigned int *) nulval, bnullarray, anynul, (unsigned int *) buffer, status); } else if (datatype == TULONG) { fffi4u4(idata, tilelen, bscale, bzero, nullcheck, tnull, *(unsigned long *) nulval, bnullarray, anynul, (unsigned long *) buffer, status); } else *status = BAD_DATATYPE; free(idata); return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_copy_overlap ( char *tile, /* I - multi dimensional array of tile pixels */ int pixlen, /* I - number of bytes in each tile or image pixel */ int ndim, /* I - number of dimension in the tile and image */ long *tfpixel, /* I - first pixel number in each dim. of the tile */ long *tlpixel, /* I - last pixel number in each dim. of the tile */ char *bnullarray, /* I - array of null flags; used if nullcheck = 2 */ char *image, /* O - multi dimensional output image */ long *fpixel, /* I - first pixel number in each dim. of the image */ long *lpixel, /* I - last pixel number in each dim. of the image */ long *ininc, /* I - increment to be applied in each image dimen. */ int nullcheck, /* I - 0, 1: do nothing; 2: set nullarray for nulls */ char *nullarray, int *status) /* copy the intersecting pixels from a decompressed tile to the output image. Both the tile and the image must have the same number of dimensions. */ { long imgdim[MAX_COMPRESS_DIM]; /* product of preceding dimensions in the */ /* output image, allowing for inc factor */ long tiledim[MAX_COMPRESS_DIM]; /* product of preceding dimensions in the */ /* tile, array; inc factor is not relevant */ long imgfpix[MAX_COMPRESS_DIM]; /* 1st img pix overlapping tile: 0 base, */ /* allowing for inc factor */ long imglpix[MAX_COMPRESS_DIM]; /* last img pix overlapping tile 0 base, */ /* allowing for inc factor */ long tilefpix[MAX_COMPRESS_DIM]; /* 1st tile pix overlapping img 0 base, */ /* allowing for inc factor */ long inc[MAX_COMPRESS_DIM]; /* local copy of input ininc */ long i1, i2, i3, i4; /* offset along each axis of the image */ long it1, it2, it3, it4; long im1, im2, im3, im4; /* offset to image pixel, allowing for inc */ long ipos, tf, tl; long t2, t3, t4; /* offset along each axis of the tile */ long tilepix, imgpix, tilepixbyte, imgpixbyte; int ii, overlap_bytes, overlap_flags; if (*status > 0) return(*status); for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { /* set default values for higher dimensions */ inc[ii] = 1; imgdim[ii] = 1; tiledim[ii] = 1; imgfpix[ii] = 0; imglpix[ii] = 0; tilefpix[ii] = 0; } /* ------------------------------------------------------------ */ /* calc amount of overlap in each dimension; if there is zero */ /* overlap in any dimension then just return */ /* ------------------------------------------------------------ */ for (ii = 0; ii < ndim; ii++) { if (tlpixel[ii] < fpixel[ii] || tfpixel[ii] > lpixel[ii]) return(*status); /* there are no overlapping pixels */ inc[ii] = ininc[ii]; /* calc dimensions of the output image section */ imgdim[ii] = (lpixel[ii] - fpixel[ii]) / labs(inc[ii]) + 1; if (imgdim[ii] < 1) return(*status = NEG_AXIS); /* calc dimensions of the tile */ tiledim[ii] = tlpixel[ii] - tfpixel[ii] + 1; if (tiledim[ii] < 1) return(*status = NEG_AXIS); if (ii > 0) tiledim[ii] *= tiledim[ii - 1]; /* product of dimensions */ /* first and last pixels in image that overlap with the tile, 0 base */ tf = tfpixel[ii] - 1; tl = tlpixel[ii] - 1; /* skip this plane if it falls in the cracks of the subsampled image */ while ((tf-(fpixel[ii] - 1)) % labs(inc[ii])) { tf++; if (tf > tl) return(*status); /* no overlapping pixels */ } while ((tl-(fpixel[ii] - 1)) % labs(inc[ii])) { tl--; if (tf > tl) return(*status); /* no overlapping pixels */ } imgfpix[ii] = maxvalue((tf - fpixel[ii] +1) / labs(inc[ii]) , 0); imglpix[ii] = minvalue((tl - fpixel[ii] +1) / labs(inc[ii]) , imgdim[ii] - 1); /* first pixel in the tile that overlaps with the image (0 base) */ tilefpix[ii] = maxvalue(fpixel[ii] - tfpixel[ii], 0); while ((tfpixel[ii] + tilefpix[ii] - fpixel[ii]) % labs(inc[ii])) { (tilefpix[ii])++; if (tilefpix[ii] >= tiledim[ii]) return(*status); /* no overlapping pixels */ } /* printf("ii tfpixel, tlpixel %d %d %d \n",ii, tfpixel[ii], tlpixel[ii]); printf("ii, tf, tl, imgfpix,imglpix, tilefpix %d %d %d %d %d %d\n",ii, tf,tl,imgfpix[ii], imglpix[ii],tilefpix[ii]); */ if (ii > 0) imgdim[ii] *= imgdim[ii - 1]; /* product of dimensions */ } /* ---------------------------------------------------------------- */ /* calc number of pixels in each row (first dimension) that overlap */ /* multiply by pixlen to get number of bytes to copy in each loop */ /* ---------------------------------------------------------------- */ if (inc[0] != 1) overlap_flags = 1; /* can only copy 1 pixel at a time */ else overlap_flags = imglpix[0] - imgfpix[0] + 1; /* can copy whole row */ overlap_bytes = overlap_flags * pixlen; /* support up to 5 dimensions for now */ for (i4 = 0, it4=0; i4 <= imglpix[4] - imgfpix[4]; i4++, it4++) { /* increment plane if it falls in the cracks of the subsampled image */ while (ndim > 4 && (tfpixel[4] + tilefpix[4] - fpixel[4] + it4) % labs(inc[4]) != 0) it4++; /* offset to start of hypercube */ if (inc[4] > 0) im4 = (i4 + imgfpix[4]) * imgdim[3]; else im4 = imgdim[4] - (i4 + 1 + imgfpix[4]) * imgdim[3]; t4 = (tilefpix[4] + it4) * tiledim[3]; for (i3 = 0, it3=0; i3 <= imglpix[3] - imgfpix[3]; i3++, it3++) { /* increment plane if it falls in the cracks of the subsampled image */ while (ndim > 3 && (tfpixel[3] + tilefpix[3] - fpixel[3] + it3) % labs(inc[3]) != 0) it3++; /* offset to start of cube */ if (inc[3] > 0) im3 = (i3 + imgfpix[3]) * imgdim[2] + im4; else im3 = imgdim[3] - (i3 + 1 + imgfpix[3]) * imgdim[2] + im4; t3 = (tilefpix[3] + it3) * tiledim[2] + t4; /* loop through planes of the image */ for (i2 = 0, it2=0; i2 <= imglpix[2] - imgfpix[2]; i2++, it2++) { /* incre plane if it falls in the cracks of the subsampled image */ while (ndim > 2 && (tfpixel[2] + tilefpix[2] - fpixel[2] + it2) % labs(inc[2]) != 0) it2++; /* offset to start of plane */ if (inc[2] > 0) im2 = (i2 + imgfpix[2]) * imgdim[1] + im3; else im2 = imgdim[2] - (i2 + 1 + imgfpix[2]) * imgdim[1] + im3; t2 = (tilefpix[2] + it2) * tiledim[1] + t3; /* loop through rows of the image */ for (i1 = 0, it1=0; i1 <= imglpix[1] - imgfpix[1]; i1++, it1++) { /* incre row if it falls in the cracks of the subsampled image */ while (ndim > 1 && (tfpixel[1] + tilefpix[1] - fpixel[1] + it1) % labs(inc[1]) != 0) it1++; /* calc position of first pixel in tile to be copied */ tilepix = tilefpix[0] + (tilefpix[1] + it1) * tiledim[0] + t2; /* offset to start of row */ if (inc[1] > 0) im1 = (i1 + imgfpix[1]) * imgdim[0] + im2; else im1 = imgdim[1] - (i1 + 1 + imgfpix[1]) * imgdim[0] + im2; /* printf("inc = %d %d %d %d\n",inc[0],inc[1],inc[2],inc[3]); printf("im1,im2,im3,im4 = %d %d %d %d\n",im1,im2,im3,im4); */ /* offset to byte within the row */ if (inc[0] > 0) imgpix = imgfpix[0] + im1; else imgpix = imgdim[0] - 1 - imgfpix[0] + im1; /* printf("tilefpix0,1, imgfpix1, it1, inc1, t2= %d %d %d %d %d %d\n", tilefpix[0],tilefpix[1],imgfpix[1],it1,inc[1], t2); printf("i1, it1, tilepix, imgpix %d %d %d %d \n", i1, it1, tilepix, imgpix); */ /* loop over pixels along one row of the image */ for (ipos = imgfpix[0]; ipos <= imglpix[0]; ipos += overlap_flags) { if (nullcheck == 2) { /* copy overlapping null flags from tile to image */ memcpy(nullarray + imgpix, bnullarray + tilepix, overlap_flags); } /* convert from image pixel to byte offset */ tilepixbyte = tilepix * pixlen; imgpixbyte = imgpix * pixlen; /* printf(" tilepix, tilepixbyte, imgpix, imgpixbyte= %d %d %d %d\n", tilepix, tilepixbyte, imgpix, imgpixbyte); */ /* copy overlapping row of pixels from tile to image */ memcpy(image + imgpixbyte, tile + tilepixbyte, overlap_bytes); tilepix += (overlap_flags * labs(inc[0])); if (inc[0] > 0) imgpix += overlap_flags; else imgpix -= overlap_flags; } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int imcomp_merge_overlap ( char *tile, /* O - multi dimensional array of tile pixels */ int pixlen, /* I - number of bytes in each tile or image pixel */ int ndim, /* I - number of dimension in the tile and image */ long *tfpixel, /* I - first pixel number in each dim. of the tile */ long *tlpixel, /* I - last pixel number in each dim. of the tile */ char *bnullarray, /* I - array of null flags; used if nullcheck = 2 */ char *image, /* I - multi dimensional output image */ long *fpixel, /* I - first pixel number in each dim. of the image */ long *lpixel, /* I - last pixel number in each dim. of the image */ int nullcheck, /* I - 0, 1: do nothing; 2: set nullarray for nulls */ int *status) /* Similar to imcomp_copy_overlap, except it copies the overlapping pixels from the 'image' to the 'tile'. */ { long imgdim[MAX_COMPRESS_DIM]; /* product of preceding dimensions in the */ /* output image, allowing for inc factor */ long tiledim[MAX_COMPRESS_DIM]; /* product of preceding dimensions in the */ /* tile, array; inc factor is not relevant */ long imgfpix[MAX_COMPRESS_DIM]; /* 1st img pix overlapping tile: 0 base, */ /* allowing for inc factor */ long imglpix[MAX_COMPRESS_DIM]; /* last img pix overlapping tile 0 base, */ /* allowing for inc factor */ long tilefpix[MAX_COMPRESS_DIM]; /* 1st tile pix overlapping img 0 base, */ /* allowing for inc factor */ long inc[MAX_COMPRESS_DIM]; /* local copy of input ininc */ long i1, i2, i3, i4; /* offset along each axis of the image */ long it1, it2, it3, it4; long im1, im2, im3, im4; /* offset to image pixel, allowing for inc */ long ipos, tf, tl; long t2, t3, t4; /* offset along each axis of the tile */ long tilepix, imgpix, tilepixbyte, imgpixbyte; int ii, overlap_bytes, overlap_flags; if (*status > 0) return(*status); for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { /* set default values for higher dimensions */ inc[ii] = 1; imgdim[ii] = 1; tiledim[ii] = 1; imgfpix[ii] = 0; imglpix[ii] = 0; tilefpix[ii] = 0; } /* ------------------------------------------------------------ */ /* calc amount of overlap in each dimension; if there is zero */ /* overlap in any dimension then just return */ /* ------------------------------------------------------------ */ for (ii = 0; ii < ndim; ii++) { if (tlpixel[ii] < fpixel[ii] || tfpixel[ii] > lpixel[ii]) return(*status); /* there are no overlapping pixels */ /* calc dimensions of the output image section */ imgdim[ii] = (lpixel[ii] - fpixel[ii]) / labs(inc[ii]) + 1; if (imgdim[ii] < 1) return(*status = NEG_AXIS); /* calc dimensions of the tile */ tiledim[ii] = tlpixel[ii] - tfpixel[ii] + 1; if (tiledim[ii] < 1) return(*status = NEG_AXIS); if (ii > 0) tiledim[ii] *= tiledim[ii - 1]; /* product of dimensions */ /* first and last pixels in image that overlap with the tile, 0 base */ tf = tfpixel[ii] - 1; tl = tlpixel[ii] - 1; /* skip this plane if it falls in the cracks of the subsampled image */ while ((tf-(fpixel[ii] - 1)) % labs(inc[ii])) { tf++; if (tf > tl) return(*status); /* no overlapping pixels */ } while ((tl-(fpixel[ii] - 1)) % labs(inc[ii])) { tl--; if (tf > tl) return(*status); /* no overlapping pixels */ } imgfpix[ii] = maxvalue((tf - fpixel[ii] +1) / labs(inc[ii]) , 0); imglpix[ii] = minvalue((tl - fpixel[ii] +1) / labs(inc[ii]) , imgdim[ii] - 1); /* first pixel in the tile that overlaps with the image (0 base) */ tilefpix[ii] = maxvalue(fpixel[ii] - tfpixel[ii], 0); while ((tfpixel[ii] + tilefpix[ii] - fpixel[ii]) % labs(inc[ii])) { (tilefpix[ii])++; if (tilefpix[ii] >= tiledim[ii]) return(*status); /* no overlapping pixels */ } /* printf("ii tfpixel, tlpixel %d %d %d \n",ii, tfpixel[ii], tlpixel[ii]); printf("ii, tf, tl, imgfpix,imglpix, tilefpix %d %d %d %d %d %d\n",ii, tf,tl,imgfpix[ii], imglpix[ii],tilefpix[ii]); */ if (ii > 0) imgdim[ii] *= imgdim[ii - 1]; /* product of dimensions */ } /* ---------------------------------------------------------------- */ /* calc number of pixels in each row (first dimension) that overlap */ /* multiply by pixlen to get number of bytes to copy in each loop */ /* ---------------------------------------------------------------- */ if (inc[0] != 1) overlap_flags = 1; /* can only copy 1 pixel at a time */ else overlap_flags = imglpix[0] - imgfpix[0] + 1; /* can copy whole row */ overlap_bytes = overlap_flags * pixlen; /* support up to 5 dimensions for now */ for (i4 = 0, it4=0; i4 <= imglpix[4] - imgfpix[4]; i4++, it4++) { /* increment plane if it falls in the cracks of the subsampled image */ while (ndim > 4 && (tfpixel[4] + tilefpix[4] - fpixel[4] + it4) % labs(inc[4]) != 0) it4++; /* offset to start of hypercube */ if (inc[4] > 0) im4 = (i4 + imgfpix[4]) * imgdim[3]; else im4 = imgdim[4] - (i4 + 1 + imgfpix[4]) * imgdim[3]; t4 = (tilefpix[4] + it4) * tiledim[3]; for (i3 = 0, it3=0; i3 <= imglpix[3] - imgfpix[3]; i3++, it3++) { /* increment plane if it falls in the cracks of the subsampled image */ while (ndim > 3 && (tfpixel[3] + tilefpix[3] - fpixel[3] + it3) % labs(inc[3]) != 0) it3++; /* offset to start of cube */ if (inc[3] > 0) im3 = (i3 + imgfpix[3]) * imgdim[2] + im4; else im3 = imgdim[3] - (i3 + 1 + imgfpix[3]) * imgdim[2] + im4; t3 = (tilefpix[3] + it3) * tiledim[2] + t4; /* loop through planes of the image */ for (i2 = 0, it2=0; i2 <= imglpix[2] - imgfpix[2]; i2++, it2++) { /* incre plane if it falls in the cracks of the subsampled image */ while (ndim > 2 && (tfpixel[2] + tilefpix[2] - fpixel[2] + it2) % labs(inc[2]) != 0) it2++; /* offset to start of plane */ if (inc[2] > 0) im2 = (i2 + imgfpix[2]) * imgdim[1] + im3; else im2 = imgdim[2] - (i2 + 1 + imgfpix[2]) * imgdim[1] + im3; t2 = (tilefpix[2] + it2) * tiledim[1] + t3; /* loop through rows of the image */ for (i1 = 0, it1=0; i1 <= imglpix[1] - imgfpix[1]; i1++, it1++) { /* incre row if it falls in the cracks of the subsampled image */ while (ndim > 1 && (tfpixel[1] + tilefpix[1] - fpixel[1] + it1) % labs(inc[1]) != 0) it1++; /* calc position of first pixel in tile to be copied */ tilepix = tilefpix[0] + (tilefpix[1] + it1) * tiledim[0] + t2; /* offset to start of row */ if (inc[1] > 0) im1 = (i1 + imgfpix[1]) * imgdim[0] + im2; else im1 = imgdim[1] - (i1 + 1 + imgfpix[1]) * imgdim[0] + im2; /* printf("inc = %d %d %d %d\n",inc[0],inc[1],inc[2],inc[3]); printf("im1,im2,im3,im4 = %d %d %d %d\n",im1,im2,im3,im4); */ /* offset to byte within the row */ if (inc[0] > 0) imgpix = imgfpix[0] + im1; else imgpix = imgdim[0] - 1 - imgfpix[0] + im1; /* printf("tilefpix0,1, imgfpix1, it1, inc1, t2= %d %d %d %d %d %d\n", tilefpix[0],tilefpix[1],imgfpix[1],it1,inc[1], t2); printf("i1, it1, tilepix, imgpix %d %d %d %d \n", i1, it1, tilepix, imgpix); */ /* loop over pixels along one row of the image */ for (ipos = imgfpix[0]; ipos <= imglpix[0]; ipos += overlap_flags) { /* convert from image pixel to byte offset */ tilepixbyte = tilepix * pixlen; imgpixbyte = imgpix * pixlen; /* printf(" tilepix, tilepixbyte, imgpix, imgpixbyte= %d %d %d %d\n", tilepix, tilepixbyte, imgpix, imgpixbyte); */ /* copy overlapping row of pixels from image to tile */ memcpy(tile + tilepixbyte, image + imgpixbyte, overlap_bytes); tilepix += (overlap_flags * labs(inc[0])); if (inc[0] > 0) imgpix += overlap_flags; else imgpix -= overlap_flags; } } } } } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/iraffits.c000066400000000000000000001515061215713201500224130ustar00rootroot00000000000000/*------------------------------------------------------------------------*/ /* */ /* These routines have been modified by William Pence for use by CFITSIO */ /* The original files were provided by Doug Mink */ /*------------------------------------------------------------------------*/ /* File imhfile.c * August 6, 1998 * By Doug Mink, based on Mike VanHilst's readiraf.c * Module: imhfile.c (IRAF .imh image file reading and writing) * Purpose: Read and write IRAF image files (and translate headers) * Subroutine: irafrhead (filename, lfhead, fitsheader, lihead) * Read IRAF image header * Subroutine: irafrimage (fitsheader) * Read IRAF image pixels (call after irafrhead) * Subroutine: same_path (pixname, hdrname) * Put filename and header path together * Subroutine: iraf2fits (hdrname, irafheader, nbiraf, nbfits) * Convert IRAF image header to FITS image header * Subroutine: irafgeti4 (irafheader, offset) * Get 4-byte integer from arbitrary part of IRAF header * Subroutine: irafgetc2 (irafheader, offset) * Get character string from arbitrary part of IRAF v.1 header * Subroutine: irafgetc (irafheader, offset) * Get character string from arbitrary part of IRAF header * Subroutine: iraf2str (irafstring, nchar) * Convert 2-byte/char IRAF string to 1-byte/char string * Subroutine: irafswap (bitpix,string,nbytes) * Swap bytes in string in place, with FITS bits/pixel code * Subroutine: irafswap2 (string,nbytes) * Swap bytes in string in place * Subroutine irafswap4 (string,nbytes) * Reverse bytes of Integer*4 or Real*4 vector in place * Subroutine irafswap8 (string,nbytes) * Reverse bytes of Real*8 vector in place * Copyright: 2000 Smithsonian Astrophysical Observatory * You may do anything you like with this file except remove * this copyright. The Smithsonian Astrophysical Observatory * makes no representations about the suitability of this * software for any purpose. It is provided "as is" without * express or implied warranty. */ #include /* define stderr, FD, and NULL */ #include #include /* stddef.h is apparently needed to define size_t */ #include #define FILE_NOT_OPENED 104 /* Parameters from iraf/lib/imhdr.h for IRAF version 1 images */ #define SZ_IMPIXFILE 79 /* name of pixel storage file */ #define SZ_IMHDRFILE 79 /* length of header storage file */ #define SZ_IMTITLE 79 /* image title string */ #define LEN_IMHDR 2052 /* length of std header */ /* Parameters from iraf/lib/imhdr.h for IRAF version 2 images */ #define SZ_IM2PIXFILE 255 /* name of pixel storage file */ #define SZ_IM2HDRFILE 255 /* name of header storage file */ #define SZ_IM2TITLE 383 /* image title string */ #define LEN_IM2HDR 2046 /* length of std header */ /* Offsets into header in bytes for parameters in IRAF version 1 images */ #define IM_HDRLEN 12 /* Length of header in 4-byte ints */ #define IM_PIXTYPE 16 /* Datatype of the pixels */ #define IM_NDIM 20 /* Number of dimensions */ #define IM_LEN 24 /* Length (as stored) */ #define IM_PHYSLEN 52 /* Physical length (as stored) */ #define IM_PIXOFF 88 /* Offset of the pixels */ #define IM_CTIME 108 /* Time of image creation */ #define IM_MTIME 112 /* Time of last modification */ #define IM_LIMTIME 116 /* Time of min,max computation */ #define IM_MAX 120 /* Maximum pixel value */ #define IM_MIN 124 /* Maximum pixel value */ #define IM_PIXFILE 412 /* Name of pixel storage file */ #define IM_HDRFILE 572 /* Name of header storage file */ #define IM_TITLE 732 /* Image name string */ /* Offsets into header in bytes for parameters in IRAF version 2 images */ #define IM2_HDRLEN 6 /* Length of header in 4-byte ints */ #define IM2_PIXTYPE 10 /* Datatype of the pixels */ #define IM2_SWAPPED 14 /* Pixels are byte swapped */ #define IM2_NDIM 18 /* Number of dimensions */ #define IM2_LEN 22 /* Length (as stored) */ #define IM2_PHYSLEN 50 /* Physical length (as stored) */ #define IM2_PIXOFF 86 /* Offset of the pixels */ #define IM2_CTIME 106 /* Time of image creation */ #define IM2_MTIME 110 /* Time of last modification */ #define IM2_LIMTIME 114 /* Time of min,max computation */ #define IM2_MAX 118 /* Maximum pixel value */ #define IM2_MIN 122 /* Maximum pixel value */ #define IM2_PIXFILE 126 /* Name of pixel storage file */ #define IM2_HDRFILE 382 /* Name of header storage file */ #define IM2_TITLE 638 /* Image name string */ /* Codes from iraf/unix/hlib/iraf.h */ #define TY_CHAR 2 #define TY_SHORT 3 #define TY_INT 4 #define TY_LONG 5 #define TY_REAL 6 #define TY_DOUBLE 7 #define TY_COMPLEX 8 #define TY_POINTER 9 #define TY_STRUCT 10 #define TY_USHORT 11 #define TY_UBYTE 12 #define LEN_PIXHDR 1024 #define MAXINT 2147483647 /* Biggest number that can fit in long */ static int isirafswapped(char *irafheader, int offset); static int irafgeti4(char *irafheader, int offset); static char *irafgetc2(char *irafheader, int offset, int nc); static char *irafgetc(char *irafheader, int offset, int nc); static char *iraf2str(char *irafstring, int nchar); static char *irafrdhead(char *filename, int *lihead); static int irafrdimage (char **buffptr, size_t *buffsize, size_t *filesize, int *status); static int iraftofits (char *hdrname, char *irafheader, int nbiraf, char **buffptr, size_t *nbfits, size_t *fitssize, int *status); static char *same_path(char *pixname, char *hdrname); static int swaphead=0; /* =1 to swap data bytes of IRAF header values */ static int swapdata=0; /* =1 to swap bytes in IRAF data pixels */ static void irafswap(int bitpix, char *string, int nbytes); static void irafswap2(char *string, int nbytes); static void irafswap4(char *string, int nbytes); static void irafswap8(char *string, int nbytes); static int pix_version (char *irafheader); static int irafncmp (char *irafheader, char *teststring, int nc); static int machswap(void); static int head_version (char *irafheader); static int hgeti4(char* hstring, char* keyword, int* val); static int hgets(char* hstring, char* keyword, int lstr, char* string); static char* hgetc(char* hstring, char* keyword); static char* ksearch(char* hstring, char* keyword); static char *blsearch (char* hstring, char* keyword); static char *strsrch (char* s1, char* s2); static char *strnsrch ( char* s1,char* s2,int ls1); static void hputi4(char* hstring,char* keyword, int ival); static void hputs(char* hstring,char* keyword,char* cval); static void hputcom(char* hstring,char* keyword,char* comment); static void hputl(char* hstring,char* keyword,int lval); static void hputc(char* hstring,char* keyword,char* cval); int iraf2mem(char *filename, char **buffptr, size_t *buffsize, size_t *filesize, int *status); void ffpmsg(const char *err_message); /*--------------------------------------------------------------------------*/ int iraf2mem(char *filename, /* name of input file */ char **buffptr, /* O - memory pointer (initially NULL) */ size_t *buffsize, /* O - size of mem buffer, in bytes */ size_t *filesize, /* O - size of FITS file, in bytes */ int *status) /* IO - error status */ /* Driver routine that reads an IRAF image into memory, also converting it into FITS format. */ { char *irafheader; int lenirafhead; *buffptr = NULL; *buffsize = 0; *filesize = 0; /* read IRAF header into dynamically created char array (free it later!) */ irafheader = irafrdhead(filename, &lenirafhead); if (!irafheader) { return(*status = FILE_NOT_OPENED); } /* convert IRAF header to FITS header in memory */ iraftofits(filename, irafheader, lenirafhead, buffptr, buffsize, filesize, status); /* don't need the IRAF header any more */ free(irafheader); if (*status > 0) return(*status); *filesize = (((*filesize - 1) / 2880 ) + 1 ) * 2880; /* multiple of 2880 */ /* append the image data onto the FITS header */ irafrdimage(buffptr, buffsize, filesize, status); return(*status); } /*--------------------------------------------------------------------------*/ /* Subroutine: irafrdhead (was irafrhead in D. Mink's original code) * Purpose: Open and read the iraf .imh file. * Returns: NULL if failure, else pointer to IRAF .imh image header * Notes: The imhdr format is defined in iraf/lib/imhdr.h, some of * which defines or mimicked, above. */ static char *irafrdhead ( char *filename, /* Name of IRAF header file */ int *lihead) /* Length of IRAF image header in bytes (returned) */ { FILE *fd; int nbr; char *irafheader; char errmsg[81]; long nbhead; int nihead; *lihead = 0; /* open the image header file */ fd = fopen (filename, "rb"); if (fd == NULL) { ffpmsg("unable to open IRAF header file:"); ffpmsg(filename); return (NULL); } /* Find size of image header file */ if (fseek(fd, 0, 2) != 0) /* move to end of the file */ { ffpmsg("IRAFRHEAD: cannot seek in file:"); ffpmsg(filename); return(NULL); } nbhead = ftell(fd); /* position = size of file */ if (nbhead < 0) { ffpmsg("IRAFRHEAD: cannot get pos. in file:"); ffpmsg(filename); return(NULL); } if (fseek(fd, 0, 0) != 0) /* move back to beginning */ { ffpmsg("IRAFRHEAD: cannot seek to beginning of file:"); ffpmsg(filename); return(NULL); } /* allocate initial sized buffer */ nihead = nbhead + 5000; irafheader = (char *) calloc (1, nihead); if (irafheader == NULL) { sprintf(errmsg, "IRAFRHEAD Cannot allocate %d-byte header", nihead); ffpmsg(errmsg); ffpmsg(filename); return (NULL); } *lihead = nihead; /* Read IRAF header */ nbr = fread (irafheader, 1, nbhead, fd); fclose (fd); /* Reject if header less than minimum length */ if (nbr < LEN_PIXHDR) { sprintf(errmsg, "IRAFRHEAD header file: %d / %d bytes read.", nbr,LEN_PIXHDR); ffpmsg(errmsg); ffpmsg(filename); free (irafheader); return (NULL); } return (irafheader); } /*--------------------------------------------------------------------------*/ static int irafrdimage ( char **buffptr, /* FITS image header (filled) */ size_t *buffsize, /* allocated size of the buffer */ size_t *filesize, /* actual size of the FITS file */ int *status) { FILE *fd; char *bang; int nax = 1, naxis1 = 1, naxis2 = 1, naxis3 = 1, naxis4 = 1, npaxis1 = 1, npaxis2; int bitpix, bytepix, i; char *fitsheader, *image; int nbr, nbimage, nbaxis, nbl, nbx, nbdiff; char *pixheader; char *linebuff; int imhver, lpixhead = 0; char pixname[SZ_IM2PIXFILE+1]; char errmsg[81]; size_t newfilesize; fitsheader = *buffptr; /* pointer to start of header */ image = fitsheader + *filesize; /* pointer to start of the data */ /* Convert pixel file name to character string */ hgets (fitsheader, "PIXFILE", SZ_IM2PIXFILE, pixname); hgeti4 (fitsheader, "PIXOFF", &lpixhead); /* Open pixel file, ignoring machine name if present */ if ((bang = strchr (pixname, '!')) != NULL ) fd = fopen (bang + 1, "rb"); else fd = fopen (pixname, "rb"); /* Print error message and exit if pixel file is not found */ if (!fd) { ffpmsg("IRAFRIMAGE: Cannot open IRAF pixel file:"); ffpmsg(pixname); return (*status = FILE_NOT_OPENED); } /* Read pixel header */ pixheader = (char *) calloc (lpixhead, 1); if (pixheader == NULL) { ffpmsg("IRAFRIMAGE: Cannot alloc memory for pixel header"); ffpmsg(pixname); fclose (fd); return (*status = FILE_NOT_OPENED); } nbr = fread (pixheader, 1, lpixhead, fd); /* Check size of pixel header */ if (nbr < lpixhead) { sprintf(errmsg, "IRAF pixel file: %d / %d bytes read.", nbr,LEN_PIXHDR); ffpmsg(errmsg); free (pixheader); fclose (fd); return (*status = FILE_NOT_OPENED); } /* check pixel header magic word */ imhver = pix_version (pixheader); if (imhver < 1) { ffpmsg("File not valid IRAF pixel file:"); ffpmsg(pixname); free (pixheader); fclose (fd); return (*status = FILE_NOT_OPENED); } free (pixheader); /* Find number of bytes to read */ hgeti4 (fitsheader,"NAXIS",&nax); hgeti4 (fitsheader,"NAXIS1",&naxis1); hgeti4 (fitsheader,"NPAXIS1",&npaxis1); if (nax > 1) { hgeti4 (fitsheader,"NAXIS2",&naxis2); hgeti4 (fitsheader,"NPAXIS2",&npaxis2); } if (nax > 2) hgeti4 (fitsheader,"NAXIS3",&naxis3); if (nax > 3) hgeti4 (fitsheader,"NAXIS4",&naxis4); hgeti4 (fitsheader,"BITPIX",&bitpix); if (bitpix < 0) bytepix = -bitpix / 8; else bytepix = bitpix / 8; nbimage = naxis1 * naxis2 * naxis3 * naxis4 * bytepix; newfilesize = *filesize + nbimage; /* header + data */ newfilesize = (((newfilesize - 1) / 2880 ) + 1 ) * 2880; if (newfilesize > *buffsize) /* need to allocate more memory? */ { fitsheader = (char *) realloc (*buffptr, newfilesize); if (fitsheader == NULL) { sprintf(errmsg, "IRAFRIMAGE Cannot allocate %d-byte image buffer", (int) (*filesize)); ffpmsg(errmsg); ffpmsg(pixname); fclose (fd); return (*status = FILE_NOT_OPENED); } } *buffptr = fitsheader; *buffsize = newfilesize; image = fitsheader + *filesize; *filesize = newfilesize; /* Read IRAF image all at once if physical and image dimensions are the same */ if (npaxis1 == naxis1) nbr = fread (image, 1, nbimage, fd); /* Read IRAF image one line at a time if physical and image dimensions differ */ else { nbdiff = (npaxis1 - naxis1) * bytepix; nbaxis = naxis1 * bytepix; linebuff = image; nbr = 0; if (naxis2 == 1 && naxis3 > 1) naxis2 = naxis3; for (i = 0; i < naxis2; i++) { nbl = fread (linebuff, 1, nbaxis, fd); nbr = nbr + nbl; nbx = fseek (fd, nbdiff, 1); linebuff = linebuff + nbaxis; } } fclose (fd); /* Check size of image */ if (nbr < nbimage) { sprintf(errmsg, "IRAF pixel file: %d / %d bytes read.", nbr,nbimage); ffpmsg(errmsg); ffpmsg(pixname); return (*status = FILE_NOT_OPENED); } /* Byte-reverse image, if necessary */ if (swapdata) irafswap (bitpix, image, nbimage); return (*status); } /*--------------------------------------------------------------------------*/ /* Return IRAF image format version number from magic word in IRAF header*/ static int head_version ( char *irafheader) /* IRAF image header from file */ { /* Check header file magic word */ if (irafncmp (irafheader, "imhdr", 5) != 0 ) { if (strncmp (irafheader, "imhv2", 5) != 0) return (0); else return (2); } else return (1); } /*--------------------------------------------------------------------------*/ /* Return IRAF image format version number from magic word in IRAF pixel file */ static int pix_version ( char *irafheader) /* IRAF image header from file */ { /* Check pixel file header magic word */ if (irafncmp (irafheader, "impix", 5) != 0) { if (strncmp (irafheader, "impv2", 5) != 0) return (0); else return (2); } else return (1); } /*--------------------------------------------------------------------------*/ /* Verify that file is valid IRAF imhdr or impix by checking first 5 chars * Returns: 0 on success, 1 on failure */ static int irafncmp ( char *irafheader, /* IRAF image header from file */ char *teststring, /* C character string to compare */ int nc) /* Number of characters to compate */ { char *line; if ((line = iraf2str (irafheader, nc)) == NULL) return (1); if (strncmp (line, teststring, nc) == 0) { free (line); return (0); } else { free (line); return (1); } } /*--------------------------------------------------------------------------*/ /* Convert IRAF image header to FITS image header, returning FITS header */ static int iraftofits ( char *hdrname, /* IRAF header file name (may be path) */ char *irafheader, /* IRAF image header */ int nbiraf, /* Number of bytes in IRAF header */ char **buffptr, /* pointer to the FITS header */ size_t *nbfits, /* allocated size of the FITS header buffer */ size_t *fitssize, /* Number of bytes in FITS header (returned) */ /* = number of bytes to the end of the END keyword */ int *status) { char *objname; /* object name from FITS file */ int lstr, i, j, k, ib, nax, nbits; char *pixname, *newpixname, *bang, *chead; char *fitsheader; int nblock, nlines; char *fhead, *fhead1, *fp, endline[81]; char irafchar; char fitsline[81]; int pixtype; int imhver, n, imu, pixoff, impixoff, immax, immin, imtime; int imndim, imlen, imphyslen, impixtype; char errmsg[81]; /* Set up last line of FITS header */ (void)strncpy (endline,"END", 3); for (i = 3; i < 80; i++) endline[i] = ' '; endline[80] = 0; /* Check header magic word */ imhver = head_version (irafheader); if (imhver < 1) { ffpmsg("File not valid IRAF image header"); ffpmsg(hdrname); return(*status = FILE_NOT_OPENED); } if (imhver == 2) { nlines = 24 + ((nbiraf - LEN_IM2HDR) / 81); imndim = IM2_NDIM; imlen = IM2_LEN; imphyslen = IM2_PHYSLEN; impixtype = IM2_PIXTYPE; impixoff = IM2_PIXOFF; imtime = IM2_MTIME; immax = IM2_MAX; immin = IM2_MIN; } else { nlines = 24 + ((nbiraf - LEN_IMHDR) / 162); imndim = IM_NDIM; imlen = IM_LEN; imphyslen = IM_PHYSLEN; impixtype = IM_PIXTYPE; impixoff = IM_PIXOFF; imtime = IM_MTIME; immax = IM_MAX; immin = IM_MIN; } /* Initialize FITS header */ nblock = (nlines * 80) / 2880; *nbfits = (nblock + 5) * 2880 + 4; fitsheader = (char *) calloc (*nbfits, 1); if (fitsheader == NULL) { sprintf(errmsg, "IRAF2FITS Cannot allocate %d-byte FITS header", (int) (*nbfits)); ffpmsg(hdrname); return (*status = FILE_NOT_OPENED); } fhead = fitsheader; *buffptr = fitsheader; (void)strncpy (fitsheader, endline, 80); hputl (fitsheader, "SIMPLE", 1); fhead = fhead + 80; /* check if the IRAF file is in big endian (sun) format (= 0) or not. */ /* This is done by checking the 4 byte integer in the header that */ /* represents the iraf pixel type. This 4-byte word is guaranteed to */ /* have the least sig byte != 0 and the most sig byte = 0, so if the */ /* first byte of the word != 0, then the file in little endian format */ /* like on an Alpha machine. */ swaphead = isirafswapped(irafheader, impixtype); if (imhver == 1) swapdata = swaphead; /* vers 1 data has same swapness as header */ else swapdata = irafgeti4 (irafheader, IM2_SWAPPED); /* Set pixel size in FITS header */ pixtype = irafgeti4 (irafheader, impixtype); switch (pixtype) { case TY_CHAR: nbits = 8; break; case TY_UBYTE: nbits = 8; break; case TY_SHORT: nbits = 16; break; case TY_USHORT: nbits = -16; break; case TY_INT: case TY_LONG: nbits = 32; break; case TY_REAL: nbits = -32; break; case TY_DOUBLE: nbits = -64; break; default: sprintf(errmsg,"Unsupported IRAF data type: %d", pixtype); ffpmsg(errmsg); ffpmsg(hdrname); return (*status = FILE_NOT_OPENED); } hputi4 (fitsheader,"BITPIX",nbits); hputcom (fitsheader,"BITPIX", "IRAF .imh pixel type"); fhead = fhead + 80; /* Set image dimensions in FITS header */ nax = irafgeti4 (irafheader, imndim); hputi4 (fitsheader,"NAXIS",nax); hputcom (fitsheader,"NAXIS", "IRAF .imh naxis"); fhead = fhead + 80; n = irafgeti4 (irafheader, imlen); hputi4 (fitsheader, "NAXIS1", n); hputcom (fitsheader,"NAXIS1", "IRAF .imh image naxis[1]"); fhead = fhead + 80; if (nax > 1) { n = irafgeti4 (irafheader, imlen+4); hputi4 (fitsheader, "NAXIS2", n); hputcom (fitsheader,"NAXIS2", "IRAF .imh image naxis[2]"); fhead = fhead + 80; } if (nax > 2) { n = irafgeti4 (irafheader, imlen+8); hputi4 (fitsheader, "NAXIS3", n); hputcom (fitsheader,"NAXIS3", "IRAF .imh image naxis[3]"); fhead = fhead + 80; } if (nax > 3) { n = irafgeti4 (irafheader, imlen+12); hputi4 (fitsheader, "NAXIS4", n); hputcom (fitsheader,"NAXIS4", "IRAF .imh image naxis[4]"); fhead = fhead + 80; } /* Set object name in FITS header */ if (imhver == 2) objname = irafgetc (irafheader, IM2_TITLE, SZ_IM2TITLE); else objname = irafgetc2 (irafheader, IM_TITLE, SZ_IMTITLE); if ((lstr = strlen (objname)) < 8) { for (i = lstr; i < 8; i++) objname[i] = ' '; objname[8] = 0; } hputs (fitsheader,"OBJECT",objname); hputcom (fitsheader,"OBJECT", "IRAF .imh title"); free (objname); fhead = fhead + 80; /* Save physical axis lengths so image file can be read */ n = irafgeti4 (irafheader, imphyslen); hputi4 (fitsheader, "NPAXIS1", n); hputcom (fitsheader,"NPAXIS1", "IRAF .imh physical naxis[1]"); fhead = fhead + 80; if (nax > 1) { n = irafgeti4 (irafheader, imphyslen+4); hputi4 (fitsheader, "NPAXIS2", n); hputcom (fitsheader,"NPAXIS2", "IRAF .imh physical naxis[2]"); fhead = fhead + 80; } if (nax > 2) { n = irafgeti4 (irafheader, imphyslen+8); hputi4 (fitsheader, "NPAXIS3", n); hputcom (fitsheader,"NPAXIS3", "IRAF .imh physical naxis[3]"); fhead = fhead + 80; } if (nax > 3) { n = irafgeti4 (irafheader, imphyslen+12); hputi4 (fitsheader, "NPAXIS4", n); hputcom (fitsheader,"NPAXIS4", "IRAF .imh physical naxis[4]"); fhead = fhead + 80; } /* Save image header filename in header */ hputs (fitsheader,"IMHFILE",hdrname); hputcom (fitsheader,"IMHFILE", "IRAF header file name"); fhead = fhead + 80; /* Save image pixel file pathname in header */ if (imhver == 2) pixname = irafgetc (irafheader, IM2_PIXFILE, SZ_IM2PIXFILE); else pixname = irafgetc2 (irafheader, IM_PIXFILE, SZ_IMPIXFILE); if (strncmp(pixname, "HDR", 3) == 0 ) { newpixname = same_path (pixname, hdrname); free (pixname); pixname = newpixname; } if (strchr (pixname, '/') == NULL && strchr (pixname, '$') == NULL) { newpixname = same_path (pixname, hdrname); free (pixname); pixname = newpixname; } if ((bang = strchr (pixname, '!')) != NULL ) hputs (fitsheader,"PIXFILE",bang+1); else hputs (fitsheader,"PIXFILE",pixname); free (pixname); hputcom (fitsheader,"PIXFILE", "IRAF .pix pixel file"); fhead = fhead + 80; /* Save image offset from star of pixel file */ pixoff = irafgeti4 (irafheader, impixoff); pixoff = (pixoff - 1) * 2; hputi4 (fitsheader, "PIXOFF", pixoff); hputcom (fitsheader,"PIXOFF", "IRAF .pix pixel offset (Do not change!)"); fhead = fhead + 80; /* Save IRAF file format version in header */ hputi4 (fitsheader,"IMHVER",imhver); hputcom (fitsheader,"IMHVER", "IRAF .imh format version (1 or 2)"); fhead = fhead + 80; /* Save flag as to whether to swap IRAF data for this file and machine */ if (swapdata) hputl (fitsheader, "PIXSWAP", 1); else hputl (fitsheader, "PIXSWAP", 0); hputcom (fitsheader,"PIXSWAP", "IRAF pixels, FITS byte orders differ if T"); fhead = fhead + 80; /* Add user portion of IRAF header to FITS header */ fitsline[80] = 0; if (imhver == 2) { imu = LEN_IM2HDR; chead = irafheader; j = 0; for (k = 0; k < 80; k++) fitsline[k] = ' '; for (i = imu; i < nbiraf; i++) { irafchar = chead[i]; if (irafchar == 0) break; else if (irafchar == 10) { (void)strncpy (fhead, fitsline, 80); /* fprintf (stderr,"%80s\n",fitsline); */ if (strncmp (fitsline, "OBJECT ", 7) != 0) { fhead = fhead + 80; } for (k = 0; k < 80; k++) fitsline[k] = ' '; j = 0; } else { if (j > 80) { if (strncmp (fitsline, "OBJECT ", 7) != 0) { (void)strncpy (fhead, fitsline, 80); /* fprintf (stderr,"%80s\n",fitsline); */ j = 9; fhead = fhead + 80; } for (k = 0; k < 80; k++) fitsline[k] = ' '; } if (irafchar > 32 && irafchar < 127) fitsline[j] = irafchar; j++; } } } else { imu = LEN_IMHDR; chead = irafheader; if (swaphead == 1) ib = 0; else ib = 1; for (k = 0; k < 80; k++) fitsline[k] = ' '; j = 0; for (i = imu; i < nbiraf; i=i+2) { irafchar = chead[i+ib]; if (irafchar == 0) break; else if (irafchar == 10) { if (strncmp (fitsline, "OBJECT ", 7) != 0) { (void)strncpy (fhead, fitsline, 80); fhead = fhead + 80; } /* fprintf (stderr,"%80s\n",fitsline); */ j = 0; for (k = 0; k < 80; k++) fitsline[k] = ' '; } else { if (j > 80) { if (strncmp (fitsline, "OBJECT ", 7) != 0) { (void)strncpy (fhead, fitsline, 80); j = 9; fhead = fhead + 80; } /* fprintf (stderr,"%80s\n",fitsline); */ for (k = 0; k < 80; k++) fitsline[k] = ' '; } if (irafchar > 32 && irafchar < 127) fitsline[j] = irafchar; j++; } } } /* Add END to last line */ (void)strncpy (fhead, endline, 80); /* Find end of last 2880-byte block of header */ fhead = ksearch (fitsheader, "END") + 80; nblock = *nbfits / 2880; fhead1 = fitsheader + (nblock * 2880); *fitssize = fhead - fitsheader; /* no. of bytes to end of END keyword */ /* Pad rest of header with spaces */ strncpy (endline," ",3); for (fp = fhead; fp < fhead1; fp = fp + 80) { (void)strncpy (fp, endline,80); } return (*status); } /*--------------------------------------------------------------------------*/ /* Put filename and header path together */ static char *same_path ( char *pixname, /* IRAF pixel file pathname */ char *hdrname) /* IRAF image header file pathname */ { int len; char *newpixname; newpixname = (char *) calloc (SZ_IM2PIXFILE, sizeof (char)); /* Pixel file is in same directory as header */ if (strncmp(pixname, "HDR$", 4) == 0 ) { (void)strncpy (newpixname, hdrname, SZ_IM2PIXFILE); /* find the end of the pathname */ len = strlen (newpixname); #ifndef VMS while( (len > 0) && (newpixname[len-1] != '/') ) #else while( (len > 0) && (newpixname[len-1] != ']') && (newpixname[len-1] != ':') ) #endif len--; /* add name */ newpixname[len] = '\0'; (void)strncat (newpixname, &pixname[4], SZ_IM2PIXFILE); } /* Bare pixel file with no path is assumed to be same as HDR$filename */ else if (strchr (pixname, '/') == NULL && strchr (pixname, '$') == NULL) { (void)strncpy (newpixname, hdrname, SZ_IM2PIXFILE); /* find the end of the pathname */ len = strlen (newpixname); #ifndef VMS while( (len > 0) && (newpixname[len-1] != '/') ) #else while( (len > 0) && (newpixname[len-1] != ']') && (newpixname[len-1] != ':') ) #endif len--; /* add name */ newpixname[len] = '\0'; (void)strncat (newpixname, pixname, SZ_IM2PIXFILE); } /* Pixel file has same name as header file, but with .pix extension */ else if (strncmp (pixname, "HDR", 3) == 0) { /* load entire header name string into name buffer */ (void)strncpy (newpixname, hdrname, SZ_IM2PIXFILE); len = strlen (newpixname); newpixname[len-3] = 'p'; newpixname[len-2] = 'i'; newpixname[len-1] = 'x'; } return (newpixname); } /*--------------------------------------------------------------------------*/ static int isirafswapped ( char *irafheader, /* IRAF image header */ int offset) /* Number of bytes to skip before number */ /* check if the IRAF file is in big endian (sun) format (= 0) or not */ /* This is done by checking the 4 byte integer in the header that */ /* represents the iraf pixel type. This 4-byte word is guaranteed to */ /* have the least sig byte != 0 and the most sig byte = 0, so if the */ /* first byte of the word != 0, then the file in little endian format */ /* like on an Alpha machine. */ { int swapped; if (irafheader[offset] != 0) swapped = 1; else swapped = 0; return (swapped); } /*--------------------------------------------------------------------------*/ static int irafgeti4 ( char *irafheader, /* IRAF image header */ int offset) /* Number of bytes to skip before number */ { char *ctemp, *cheader; int temp; cheader = irafheader; ctemp = (char *) &temp; if (machswap() != swaphead) { ctemp[3] = cheader[offset]; ctemp[2] = cheader[offset+1]; ctemp[1] = cheader[offset+2]; ctemp[0] = cheader[offset+3]; } else { ctemp[0] = cheader[offset]; ctemp[1] = cheader[offset+1]; ctemp[2] = cheader[offset+2]; ctemp[3] = cheader[offset+3]; } return (temp); } /*--------------------------------------------------------------------------*/ /* IRAFGETC2 -- Get character string from arbitrary part of v.1 IRAF header */ static char *irafgetc2 ( char *irafheader, /* IRAF image header */ int offset, /* Number of bytes to skip before string */ int nc) /* Maximum number of characters in string */ { char *irafstring, *string; irafstring = irafgetc (irafheader, offset, 2*(nc+1)); string = iraf2str (irafstring, nc); free (irafstring); return (string); } /*--------------------------------------------------------------------------*/ /* IRAFGETC -- Get character string from arbitrary part of IRAF header */ static char *irafgetc ( char *irafheader, /* IRAF image header */ int offset, /* Number of bytes to skip before string */ int nc) /* Maximum number of characters in string */ { char *ctemp, *cheader; int i; cheader = irafheader; ctemp = (char *) calloc (nc+1, 1); if (ctemp == NULL) { ffpmsg("IRAFGETC Cannot allocate memory for string variable"); return (NULL); } for (i = 0; i < nc; i++) { ctemp[i] = cheader[offset+i]; if (ctemp[i] > 0 && ctemp[i] < 32) ctemp[i] = ' '; } return (ctemp); } /*--------------------------------------------------------------------------*/ /* Convert IRAF 2-byte/char string to 1-byte/char string */ static char *iraf2str ( char *irafstring, /* IRAF 2-byte/character string */ int nchar) /* Number of characters in string */ { char *string; int i, j; string = (char *) calloc (nchar+1, 1); if (string == NULL) { ffpmsg("IRAF2STR Cannot allocate memory for string variable"); return (NULL); } /* the chars are in bytes 1, 3, 5, ... if bigendian format (SUN) */ /* else in bytes 0, 2, 4, ... if little endian format (Alpha) */ if (irafstring[0] != 0) j = 0; else j = 1; /* Convert appropriate byte of input to output character */ for (i = 0; i < nchar; i++) { string[i] = irafstring[j]; j = j + 2; } return (string); } /*--------------------------------------------------------------------------*/ /* IRAFSWAP -- Reverse bytes of any type of vector in place */ static void irafswap ( int bitpix, /* Number of bits per pixel */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ char *string, /* Address of starting point of bytes to swap */ int nbytes) /* Number of bytes to swap */ { switch (bitpix) { case 16: if (nbytes < 2) return; irafswap2 (string,nbytes); break; case 32: if (nbytes < 4) return; irafswap4 (string,nbytes); break; case -16: if (nbytes < 2) return; irafswap2 (string,nbytes); break; case -32: if (nbytes < 4) return; irafswap4 (string,nbytes); break; case -64: if (nbytes < 8) return; irafswap8 (string,nbytes); break; } return; } /*--------------------------------------------------------------------------*/ /* IRAFSWAP2 -- Swap bytes in string in place */ static void irafswap2 ( char *string, /* Address of starting point of bytes to swap */ int nbytes) /* Number of bytes to swap */ { char *sbyte, temp, *slast; slast = string + nbytes; sbyte = string; while (sbyte < slast) { temp = sbyte[0]; sbyte[0] = sbyte[1]; sbyte[1] = temp; sbyte= sbyte + 2; } return; } /*--------------------------------------------------------------------------*/ /* IRAFSWAP4 -- Reverse bytes of Integer*4 or Real*4 vector in place */ static void irafswap4 ( char *string, /* Address of Integer*4 or Real*4 vector */ int nbytes) /* Number of bytes to reverse */ { char *sbyte, *slast; char temp0, temp1, temp2, temp3; slast = string + nbytes; sbyte = string; while (sbyte < slast) { temp3 = sbyte[0]; temp2 = sbyte[1]; temp1 = sbyte[2]; temp0 = sbyte[3]; sbyte[0] = temp0; sbyte[1] = temp1; sbyte[2] = temp2; sbyte[3] = temp3; sbyte = sbyte + 4; } return; } /*--------------------------------------------------------------------------*/ /* IRAFSWAP8 -- Reverse bytes of Real*8 vector in place */ static void irafswap8 ( char *string, /* Address of Real*8 vector */ int nbytes) /* Number of bytes to reverse */ { char *sbyte, *slast; char temp[8]; slast = string + nbytes; sbyte = string; while (sbyte < slast) { temp[7] = sbyte[0]; temp[6] = sbyte[1]; temp[5] = sbyte[2]; temp[4] = sbyte[3]; temp[3] = sbyte[4]; temp[2] = sbyte[5]; temp[1] = sbyte[6]; temp[0] = sbyte[7]; sbyte[0] = temp[0]; sbyte[1] = temp[1]; sbyte[2] = temp[2]; sbyte[3] = temp[3]; sbyte[4] = temp[4]; sbyte[5] = temp[5]; sbyte[6] = temp[6]; sbyte[7] = temp[7]; sbyte = sbyte + 8; } return; } /*--------------------------------------------------------------------------*/ static int machswap (void) { char *ctest; int itest; itest = 1; ctest = (char *)&itest; if (*ctest) return (1); else return (0); } /*--------------------------------------------------------------------------*/ /* the following routines were originally in hget.c */ /*--------------------------------------------------------------------------*/ static int lhead0 = 0; /*--------------------------------------------------------------------------*/ /* Extract long value for variable from FITS header string */ static int hgeti4 (hstring,keyword,ival) char *hstring; /* character string containing FITS header information in the format = {/ } */ char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ int *ival; { char *value; double dval; int minint; char val[30]; /* Get value and comment from header string */ value = hgetc (hstring,keyword); /* Translate value from ASCII to binary */ if (value != NULL) { minint = -MAXINT - 1; strcpy (val, value); dval = atof (val); if (dval+0.001 > MAXINT) *ival = MAXINT; else if (dval >= 0) *ival = (int) (dval + 0.001); else if (dval-0.001 < minint) *ival = minint; else *ival = (int) (dval - 0.001); return (1); } else { return (0); } } /*-------------------------------------------------------------------*/ /* Extract string value for variable from FITS header string */ static int hgets (hstring, keyword, lstr, str) char *hstring; /* character string containing FITS header information in the format = {/ } */ char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ int lstr; /* Size of str in characters */ char *str; /* String (returned) */ { char *value; int lval; /* Get value and comment from header string */ value = hgetc (hstring,keyword); if (value != NULL) { lval = strlen (value); if (lval < lstr) strcpy (str, value); else if (lstr > 1) strncpy (str, value, lstr-1); else str[0] = value[0]; return (1); } else return (0); } /*-------------------------------------------------------------------*/ /* Extract character value for variable from FITS header string */ static char * hgetc (hstring,keyword0) char *hstring; /* character string containing FITS header information in the format = {/ } */ char *keyword0; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ { static char cval[80]; char *value; char cwhite[2]; char squot[2], dquot[2], lbracket[2], rbracket[2], slash[2], comma[2]; char keyword[81]; /* large for ESO hierarchical keywords */ char line[100]; char *vpos, *cpar = NULL; char *q1, *q2 = NULL, *v1, *v2, *c1, *brack1, *brack2; int ipar, i; squot[0] = 39; squot[1] = 0; dquot[0] = 34; dquot[1] = 0; lbracket[0] = 91; lbracket[1] = 0; comma[0] = 44; comma[1] = 0; rbracket[0] = 93; rbracket[1] = 0; slash[0] = 47; slash[1] = 0; /* Find length of variable name */ strncpy (keyword,keyword0, sizeof(keyword)-1); brack1 = strsrch (keyword,lbracket); if (brack1 == NULL) brack1 = strsrch (keyword,comma); if (brack1 != NULL) { *brack1 = '\0'; brack1++; } /* Search header string for variable name */ vpos = ksearch (hstring,keyword); /* Exit if not found */ if (vpos == NULL) { return (NULL); } /* Initialize line to nulls */ for (i = 0; i < 100; i++) line[i] = 0; /* In standard FITS, data lasts until 80th character */ /* Extract entry for this variable from the header */ strncpy (line,vpos,80); /* check for quoted value */ q1 = strsrch (line,squot); c1 = strsrch (line,slash); if (q1 != NULL) { if (c1 != NULL && q1 < c1) q2 = strsrch (q1+1,squot); else if (c1 == NULL) q2 = strsrch (q1+1,squot); else q1 = NULL; } else { q1 = strsrch (line,dquot); if (q1 != NULL) { if (c1 != NULL && q1 < c1) q2 = strsrch (q1+1,dquot); else if (c1 == NULL) q2 = strsrch (q1+1,dquot); else q1 = NULL; } else { q1 = NULL; q2 = line + 10; } } /* Extract value and remove excess spaces */ if (q1 != NULL) { v1 = q1 + 1;; v2 = q2; c1 = strsrch (q2,"/"); } else { v1 = strsrch (line,"=") + 1; c1 = strsrch (line,"/"); if (c1 != NULL) v2 = c1; else v2 = line + 79; } /* Ignore leading spaces */ while (*v1 == ' ' && v1 < v2) { v1++; } /* Drop trailing spaces */ *v2 = '\0'; v2--; while (*v2 == ' ' && v2 > v1) { *v2 = '\0'; v2--; } if (!strcmp (v1, "-0")) v1++; strcpy (cval,v1); value = cval; /* If keyword has brackets, extract appropriate token from value */ if (brack1 != NULL) { brack2 = strsrch (brack1,rbracket); if (brack2 != NULL) *brack2 = '\0'; ipar = atoi (brack1); if (ipar > 0) { cwhite[0] = ' '; cwhite[1] = '\0'; for (i = 1; i <= ipar; i++) { cpar = strtok (v1,cwhite); v1 = NULL; } if (cpar != NULL) { strcpy (cval,cpar); } else value = NULL; } } return (value); } /*-------------------------------------------------------------------*/ /* Find beginning of fillable blank line before FITS header keyword line */ static char * blsearch (hstring,keyword) /* Find entry for keyword keyword in FITS header string hstring. (the keyword may have a maximum of eight letters) NULL is returned if the keyword is not found */ char *hstring; /* character string containing fits-style header information in the format = {/ } the default is that each entry is 80 characters long; however, lines may be of arbitrary length terminated by nulls, carriage returns or linefeeds, if packed is true. */ char *keyword; /* character string containing the name of the variable to be returned. ksearch searches for a line beginning with this string. The string may be a character literal or a character variable terminated by a null or '$'. it is truncated to 8 characters. */ { char *loc, *headnext, *headlast, *pval, *lc, *line; char *bval; int icol, nextchar, lkey, nleft, lhstr; pval = 0; /* Search header string for variable name */ if (lhead0) lhstr = lhead0; else { lhstr = 0; while (lhstr < 57600 && hstring[lhstr] != 0) lhstr++; } headlast = hstring + lhstr; headnext = hstring; pval = NULL; while (headnext < headlast) { nleft = headlast - headnext; loc = strnsrch (headnext, keyword, nleft); /* Exit if keyword is not found */ if (loc == NULL) { break; } icol = (loc - hstring) % 80; lkey = strlen (keyword); nextchar = (int) *(loc + lkey); /* If this is not in the first 8 characters of a line, keep searching */ if (icol > 7) headnext = loc + 1; /* If parameter name in header is longer, keep searching */ else if (nextchar != 61 && nextchar > 32 && nextchar < 127) headnext = loc + 1; /* If preceeding characters in line are not blanks, keep searching */ else { line = loc - icol; for (lc = line; lc < loc; lc++) { if (*lc != ' ') headnext = loc + 1; } /* Return pointer to start of line if match */ if (loc >= headnext) { pval = line; break; } } } /* Return NULL if keyword is found at start of FITS header string */ if (pval == NULL) return (pval); /* Return NULL if found the first keyword in the header */ if (pval == hstring) return (NULL); /* Find last nonblank line before requested keyword */ bval = pval - 80; while (!strncmp (bval," ",8)) bval = bval - 80; bval = bval + 80; /* Return pointer to calling program if blank lines found */ if (bval < pval) return (bval); else return (NULL); } /*-------------------------------------------------------------------*/ /* Find FITS header line containing specified keyword */ static char *ksearch (hstring,keyword) /* Find entry for keyword keyword in FITS header string hstring. (the keyword may have a maximum of eight letters) NULL is returned if the keyword is not found */ char *hstring; /* character string containing fits-style header information in the format = {/ } the default is that each entry is 80 characters long; however, lines may be of arbitrary length terminated by nulls, carriage returns or linefeeds, if packed is true. */ char *keyword; /* character string containing the name of the variable to be returned. ksearch searches for a line beginning with this string. The string may be a character literal or a character variable terminated by a null or '$'. it is truncated to 8 characters. */ { char *loc, *headnext, *headlast, *pval, *lc, *line; int icol, nextchar, lkey, nleft, lhstr; pval = 0; /* Search header string for variable name */ if (lhead0) lhstr = lhead0; else { lhstr = 0; while (lhstr < 57600 && hstring[lhstr] != 0) lhstr++; } headlast = hstring + lhstr; headnext = hstring; pval = NULL; while (headnext < headlast) { nleft = headlast - headnext; loc = strnsrch (headnext, keyword, nleft); /* Exit if keyword is not found */ if (loc == NULL) { break; } icol = (loc - hstring) % 80; lkey = strlen (keyword); nextchar = (int) *(loc + lkey); /* If this is not in the first 8 characters of a line, keep searching */ if (icol > 7) headnext = loc + 1; /* If parameter name in header is longer, keep searching */ else if (nextchar != 61 && nextchar > 32 && nextchar < 127) headnext = loc + 1; /* If preceeding characters in line are not blanks, keep searching */ else { line = loc - icol; for (lc = line; lc < loc; lc++) { if (*lc != ' ') headnext = loc + 1; } /* Return pointer to start of line if match */ if (loc >= headnext) { pval = line; break; } } } /* Return pointer to calling program */ return (pval); } /*-------------------------------------------------------------------*/ /* Find string s2 within null-terminated string s1 */ static char * strsrch (s1, s2) char *s1; /* String to search */ char *s2; /* String to look for */ { int ls1; ls1 = strlen (s1); return (strnsrch (s1, s2, ls1)); } /*-------------------------------------------------------------------*/ /* Find string s2 within string s1 */ static char * strnsrch (s1, s2, ls1) char *s1; /* String to search */ char *s2; /* String to look for */ int ls1; /* Length of string being searched */ { char *s,*s1e; char cfirst,clast; int i,ls2; /* Return null string if either pointer is NULL */ if (s1 == NULL || s2 == NULL) return (NULL); /* A zero-length pattern is found in any string */ ls2 = strlen (s2); if (ls2 ==0) return (s1); /* Only a zero-length string can be found in a zero-length string */ if (ls1 ==0) return (NULL); cfirst = s2[0]; clast = s2[ls2-1]; s1e = s1 + ls1 - ls2 + 1; s = s1; while (s < s1e) { /* Search for first character in pattern string */ if (*s == cfirst) { /* If single character search, return */ if (ls2 == 1) return (s); /* Search for last character in pattern string if first found */ if (s[ls2-1] == clast) { /* If two-character search, return */ if (ls2 == 2) return (s); /* If 3 or more characters, check for rest of search string */ i = 1; while (i < ls2 && s[i] == s2[i]) i++; /* If entire string matches, return */ if (i >= ls2) return (s); } } s++; } return (NULL); } /*-------------------------------------------------------------------*/ /* the following routines were originally in hget.c */ /*-------------------------------------------------------------------*/ /* HPUTI4 - Set int keyword = ival in FITS header string */ static void hputi4 (hstring,keyword,ival) char *hstring; /* character string containing FITS-style header information in the format = {/ } each entry is padded with spaces to 80 characters */ char *keyword; /* character string containing the name of the variable to be returned. hput searches for a line beginning with this string, and if there isn't one, creates one. The first 8 characters of keyword must be unique. */ int ival; /* int number */ { char value[30]; /* Translate value from binary to ASCII */ sprintf (value,"%d",ival); /* Put value into header string */ hputc (hstring,keyword,value); /* Return to calling program */ return; } /*-------------------------------------------------------------------*/ /* HPUTL - Set keyword = F if lval=0, else T, in FITS header string */ static void hputl (hstring, keyword,lval) char *hstring; /* FITS header */ char *keyword; /* Keyword name */ int lval; /* logical variable (0=false, else true) */ { char value[8]; /* Translate value from binary to ASCII */ if (lval) strcpy (value, "T"); else strcpy (value, "F"); /* Put value into header string */ hputc (hstring,keyword,value); /* Return to calling program */ return; } /*-------------------------------------------------------------------*/ /* HPUTS - Set character string keyword = 'cval' in FITS header string */ static void hputs (hstring,keyword,cval) char *hstring; /* FITS header */ char *keyword; /* Keyword name */ char *cval; /* character string containing the value for variable keyword. trailing and leading blanks are removed. */ { char squot = 39; char value[70]; int lcval; /* find length of variable string */ lcval = strlen (cval); if (lcval > 67) lcval = 67; /* Put quotes around string */ value[0] = squot; strncpy (&value[1],cval,lcval); value[lcval+1] = squot; value[lcval+2] = 0; /* Put value into header string */ hputc (hstring,keyword,value); /* Return to calling program */ return; } /*---------------------------------------------------------------------*/ /* HPUTC - Set character string keyword = value in FITS header string */ static void hputc (hstring,keyword,value) char *hstring; char *keyword; char *value; /* character string containing the value for variable keyword. trailing and leading blanks are removed. */ { char squot = 39; char line[100]; char newcom[50]; char blank[80]; char *v, *vp, *v1, *v2, *q1, *q2, *c1, *ve; int lkeyword, lcom, lval, lc, i; for (i = 0; i < 80; i++) blank[i] = ' '; /* find length of keyword and value */ lkeyword = strlen (keyword); lval = strlen (value); /* If COMMENT or HISTORY, always add it just before the END */ if (lkeyword == 7 && (strncmp (keyword,"COMMENT",7) == 0 || strncmp (keyword,"HISTORY",7) == 0)) { /* Find end of header */ v1 = ksearch (hstring,"END"); v2 = v1 + 80; /* Move END down one line */ strncpy (v2, v1, 80); /* Insert keyword */ strncpy (v1,keyword,7); /* Pad with spaces */ for (vp = v1+lkeyword; vp < v2; vp++) *vp = ' '; /* Insert comment */ strncpy (v1+9,value,lval); return; } /* Otherwise search for keyword */ else v1 = ksearch (hstring,keyword); /* If parameter is not found, find a place to put it */ if (v1 == NULL) { /* First look for blank lines before END */ v1 = blsearch (hstring, "END"); /* Otherwise, create a space for it at the end of the header */ if (v1 == NULL) { ve = ksearch (hstring,"END"); v1 = ve; v2 = v1 + 80; strncpy (v2, ve, 80); } else v2 = v1 + 80; lcom = 0; newcom[0] = 0; } /* Otherwise, extract the entry for this keyword from the header */ else { strncpy (line, v1, 80); line[80] = 0; v2 = v1 + 80; /* check for quoted value */ q1 = strchr (line, squot); if (q1 != NULL) q2 = strchr (q1+1,squot); else q2 = line; /* extract comment and remove trailing spaces */ c1 = strchr (q2,'/'); if (c1 != NULL) { lcom = 80 - (c1 - line); strncpy (newcom, c1+1, lcom); vp = newcom + lcom - 1; while (vp-- > newcom && *vp == ' ') *vp = 0; lcom = strlen (newcom); } else { newcom[0] = 0; lcom = 0; } } /* Fill new entry with spaces */ for (vp = v1; vp < v2; vp++) *vp = ' '; /* Copy keyword to new entry */ strncpy (v1, keyword, lkeyword); /* Add parameter value in the appropriate place */ vp = v1 + 8; *vp = '='; vp = v1 + 9; *vp = ' '; vp = vp + 1; if (*value == squot) { strncpy (vp, value, lval); if (lval+12 > 31) lc = lval + 12; else lc = 30; } else { vp = v1 + 30 - lval; strncpy (vp, value, lval); lc = 30; } /* Add comment in the appropriate place */ if (lcom > 0) { if (lc+2+lcom > 80) lcom = 78 - lc; vp = v1 + lc + 2; /* Jul 16 1997: was vp = v1 + lc * 2 */ *vp = '/'; vp = vp + 1; strncpy (vp, newcom, lcom); for (v = vp + lcom; v < v2; v++) *v = ' '; } return; } /*-------------------------------------------------------------------*/ /* HPUTCOM - Set comment for keyword or on line in FITS header string */ static void hputcom (hstring,keyword,comment) char *hstring; char *keyword; char *comment; { char squot; char line[100]; int lkeyword, lcom; char *vp, *v1, *v2, *c0 = NULL, *c1, *q1, *q2; squot = 39; /* Find length of variable name */ lkeyword = strlen (keyword); /* If COMMENT or HISTORY, always add it just before the END */ if (lkeyword == 7 && (strncmp (keyword,"COMMENT",7) == 0 || strncmp (keyword,"HISTORY",7) == 0)) { /* Find end of header */ v1 = ksearch (hstring,"END"); v2 = v1 + 80; strncpy (v2, v1, 80); /* blank out new line and insert keyword */ for (vp = v1; vp < v2; vp++) *vp = ' '; strncpy (v1, keyword, lkeyword); } /* search header string for variable name */ else { v1 = ksearch (hstring,keyword); v2 = v1 + 80; /* if parameter is not found, return without doing anything */ if (v1 == NULL) { return; } /* otherwise, extract entry for this variable from the header */ strncpy (line, v1, 80); /* check for quoted value */ q1 = strchr (line,squot); if (q1 != NULL) q2 = strchr (q1+1,squot); else q2 = NULL; if (q2 == NULL || q2-line < 31) c0 = v1 + 31; else c0 = v1 + (q2-line) + 2; /* allan: 1997-09-30, was c0=q2+2 */ strncpy (c0, "/ ",2); } /* create new entry */ lcom = strlen (comment); if (lcom > 0) { c1 = c0 + 2; if (c1+lcom > v2) lcom = v2 - c1; strncpy (c1, comment, lcom); } } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/longnam.h000066400000000000000000000473451215713201500222510ustar00rootroot00000000000000#ifndef _LONGNAME_H #define _LONGNAME_H #define fits_parse_input_url ffiurl #define fits_parse_input_filename ffifile #define fits_parse_rootname ffrtnm #define fits_file_exists ffexist #define fits_parse_output_url ffourl #define fits_parse_extspec ffexts #define fits_parse_extnum ffextn #define fits_parse_binspec ffbins #define fits_parse_binrange ffbinr #define fits_parse_range ffrwrg #define fits_parse_rangell ffrwrgll #define fits_open_memfile ffomem /* use the following special macro to test that the fitsio.h include file that was used to build the CFITSIO library is the same version as included when compiling the application program */ #define fits_open_file(A, B, C, D) ffopentest( CFITSIO_VERSION, A, B, C, D) #define fits_open_data ffdopn #define fits_open_table fftopn #define fits_open_image ffiopn #define fits_open_diskfile ffdkopn #define fits_reopen_file ffreopen #define fits_create_file ffinit #define fits_create_diskfile ffdkinit #define fits_create_memfile ffimem #define fits_create_template fftplt #define fits_flush_file ffflus #define fits_flush_buffer ffflsh #define fits_close_file ffclos #define fits_delete_file ffdelt #define fits_file_name ffflnm #define fits_file_mode ffflmd #define fits_url_type ffurlt #define fits_get_version ffvers #define fits_uppercase ffupch #define fits_get_errstatus ffgerr #define fits_write_errmsg ffpmsg #define fits_write_errmark ffpmrk #define fits_read_errmsg ffgmsg #define fits_clear_errmsg ffcmsg #define fits_clear_errmark ffcmrk #define fits_report_error ffrprt #define fits_compare_str ffcmps #define fits_test_keyword fftkey #define fits_test_record fftrec #define fits_null_check ffnchk #define fits_make_keyn ffkeyn #define fits_make_nkey ffnkey #define fits_get_keyclass ffgkcl #define fits_get_keytype ffdtyp #define fits_parse_value ffpsvc #define fits_get_keyname ffgknm #define fits_parse_template ffgthd #define fits_ascii_tform ffasfm #define fits_binary_tform ffbnfm #define fits_binary_tformll ffbnfmll #define fits_get_tbcol ffgabc #define fits_get_rowsize ffgrsz #define fits_get_col_display_width ffgcdw #define fits_write_record ffprec #define fits_write_key ffpky #define fits_write_key_unit ffpunt #define fits_write_comment ffpcom #define fits_write_history ffphis #define fits_write_date ffpdat #define fits_get_system_time ffgstm #define fits_get_system_date ffgsdt #define fits_date2str ffdt2s #define fits_time2str fftm2s #define fits_str2date ffs2dt #define fits_str2time ffs2tm #define fits_write_key_longstr ffpkls #define fits_write_key_longwarn ffplsw #define fits_write_key_null ffpkyu #define fits_write_key_str ffpkys #define fits_write_key_log ffpkyl #define fits_write_key_lng ffpkyj #define fits_write_key_fixflt ffpkyf #define fits_write_key_flt ffpkye #define fits_write_key_fixdbl ffpkyg #define fits_write_key_dbl ffpkyd #define fits_write_key_fixcmp ffpkfc #define fits_write_key_cmp ffpkyc #define fits_write_key_fixdblcmp ffpkfm #define fits_write_key_dblcmp ffpkym #define fits_write_key_triple ffpkyt #define fits_write_tdim ffptdm #define fits_write_tdimll ffptdmll #define fits_write_keys_str ffpkns #define fits_write_keys_log ffpknl #define fits_write_keys_lng ffpknj #define fits_write_keys_fixflt ffpknf #define fits_write_keys_flt ffpkne #define fits_write_keys_fixdbl ffpkng #define fits_write_keys_dbl ffpknd #define fits_copy_key ffcpky #define fits_write_imghdr ffphps #define fits_write_imghdrll ffphpsll #define fits_write_grphdr ffphpr #define fits_write_grphdrll ffphprll #define fits_write_atblhdr ffphtb #define fits_write_btblhdr ffphbn #define fits_write_exthdr ffphext #define fits_write_key_template ffpktp #define fits_get_hdrspace ffghsp #define fits_get_hdrpos ffghps #define fits_movabs_key ffmaky #define fits_movrel_key ffmrky #define fits_find_nextkey ffgnxk #define fits_read_record ffgrec #define fits_read_card ffgcrd #define fits_read_key_unit ffgunt #define fits_read_keyn ffgkyn #define fits_read_key ffgky #define fits_read_keyword ffgkey #define fits_read_key_str ffgkys #define fits_read_key_log ffgkyl #define fits_read_key_lng ffgkyj #define fits_read_key_lnglng ffgkyjj #define fits_read_key_flt ffgkye #define fits_read_key_dbl ffgkyd #define fits_read_key_cmp ffgkyc #define fits_read_key_dblcmp ffgkym #define fits_read_key_triple ffgkyt #define fits_read_key_longstr ffgkls #define fits_read_tdim ffgtdm #define fits_read_tdimll ffgtdmll #define fits_decode_tdim ffdtdm #define fits_decode_tdimll ffdtdmll #define fits_read_keys_str ffgkns #define fits_read_keys_log ffgknl #define fits_read_keys_lng ffgknj #define fits_read_keys_flt ffgkne #define fits_read_keys_dbl ffgknd #define fits_read_imghdr ffghpr #define fits_read_imghdrll ffghprll #define fits_read_atblhdr ffghtb #define fits_read_btblhdr ffghbn #define fits_read_atblhdrll ffghtbll #define fits_read_btblhdrll ffghbnll #define fits_hdr2str ffhdr2str #define fits_update_card ffucrd #define fits_update_key ffuky #define fits_update_key_null ffukyu #define fits_update_key_str ffukys #define fits_update_key_longstr ffukls #define fits_update_key_log ffukyl #define fits_update_key_lng ffukyj #define fits_update_key_fixflt ffukyf #define fits_update_key_flt ffukye #define fits_update_key_fixdbl ffukyg #define fits_update_key_dbl ffukyd #define fits_update_key_fixcmp ffukfc #define fits_update_key_cmp ffukyc #define fits_update_key_fixdblcmp ffukfm #define fits_update_key_dblcmp ffukym #define fits_modify_record ffmrec #define fits_modify_card ffmcrd #define fits_modify_name ffmnam #define fits_modify_comment ffmcom #define fits_modify_key_null ffmkyu #define fits_modify_key_str ffmkys #define fits_modify_key_longstr ffmkls #define fits_modify_key_log ffmkyl #define fits_modify_key_lng ffmkyj #define fits_modify_key_fixflt ffmkyf #define fits_modify_key_flt ffmkye #define fits_modify_key_fixdbl ffmkyg #define fits_modify_key_dbl ffmkyd #define fits_modify_key_fixcmp ffmkfc #define fits_modify_key_cmp ffmkyc #define fits_modify_key_fixdblcmp ffmkfm #define fits_modify_key_dblcmp ffmkym #define fits_insert_record ffirec #define fits_insert_card ffikey #define fits_insert_key_null ffikyu #define fits_insert_key_str ffikys #define fits_insert_key_longstr ffikls #define fits_insert_key_log ffikyl #define fits_insert_key_lng ffikyj #define fits_insert_key_fixflt ffikyf #define fits_insert_key_flt ffikye #define fits_insert_key_fixdbl ffikyg #define fits_insert_key_dbl ffikyd #define fits_insert_key_fixcmp ffikfc #define fits_insert_key_cmp ffikyc #define fits_insert_key_fixdblcmp ffikfm #define fits_insert_key_dblcmp ffikym #define fits_delete_key ffdkey #define fits_delete_record ffdrec #define fits_get_hdu_num ffghdn #define fits_get_hdu_type ffghdt #define fits_get_hduaddr ffghad #define fits_get_hduaddrll ffghadll #define fits_get_hduoff ffghof #define fits_get_img_param ffgipr #define fits_get_img_paramll ffgiprll #define fits_get_img_type ffgidt #define fits_get_img_equivtype ffgiet #define fits_get_img_dim ffgidm #define fits_get_img_size ffgisz #define fits_get_img_sizell ffgiszll #define fits_movabs_hdu ffmahd #define fits_movrel_hdu ffmrhd #define fits_movnam_hdu ffmnhd #define fits_get_num_hdus ffthdu #define fits_create_img ffcrim #define fits_create_imgll ffcrimll #define fits_create_tbl ffcrtb #define fits_create_hdu ffcrhd #define fits_insert_img ffiimg #define fits_insert_imgll ffiimgll #define fits_insert_atbl ffitab #define fits_insert_btbl ffibin #define fits_resize_img ffrsim #define fits_resize_imgll ffrsimll #define fits_delete_hdu ffdhdu #define fits_copy_hdu ffcopy #define fits_copy_file ffcpfl #define fits_copy_header ffcphd #define fits_copy_data ffcpdt #define fits_write_hdu ffwrhdu #define fits_set_hdustruc ffrdef #define fits_set_hdrsize ffhdef #define fits_write_theap ffpthp #define fits_encode_chksum ffesum #define fits_decode_chksum ffdsum #define fits_write_chksum ffpcks #define fits_update_chksum ffupck #define fits_verify_chksum ffvcks #define fits_get_chksum ffgcks #define fits_set_bscale ffpscl #define fits_set_tscale fftscl #define fits_set_imgnull ffpnul #define fits_set_btblnull fftnul #define fits_set_atblnull ffsnul #define fits_get_colnum ffgcno #define fits_get_colname ffgcnn #define fits_get_coltype ffgtcl #define fits_get_coltypell ffgtclll #define fits_get_eqcoltype ffeqty #define fits_get_eqcoltypell ffeqtyll #define fits_get_num_rows ffgnrw #define fits_get_num_rowsll ffgnrwll #define fits_get_num_cols ffgncl #define fits_get_acolparms ffgacl #define fits_get_bcolparms ffgbcl #define fits_get_bcolparmsll ffgbclll #define fits_iterate_data ffiter #define fits_read_grppar_byt ffggpb #define fits_read_grppar_sbyt ffggpsb #define fits_read_grppar_usht ffggpui #define fits_read_grppar_ulng ffggpuj #define fits_read_grppar_sht ffggpi #define fits_read_grppar_lng ffggpj #define fits_read_grppar_lnglng ffggpjj #define fits_read_grppar_int ffggpk #define fits_read_grppar_uint ffggpuk #define fits_read_grppar_flt ffggpe #define fits_read_grppar_dbl ffggpd #define fits_read_pix ffgpxv #define fits_read_pixll ffgpxvll #define fits_read_pixnull ffgpxf #define fits_read_pixnullll ffgpxfll #define fits_read_img ffgpv #define fits_read_imgnull ffgpf #define fits_read_img_byt ffgpvb #define fits_read_img_sbyt ffgpvsb #define fits_read_img_usht ffgpvui #define fits_read_img_ulng ffgpvuj #define fits_read_img_sht ffgpvi #define fits_read_img_lng ffgpvj #define fits_read_img_lnglng ffgpvjj #define fits_read_img_uint ffgpvuk #define fits_read_img_int ffgpvk #define fits_read_img_flt ffgpve #define fits_read_img_dbl ffgpvd #define fits_read_imgnull_byt ffgpfb #define fits_read_imgnull_sbyt ffgpfsb #define fits_read_imgnull_usht ffgpfui #define fits_read_imgnull_ulng ffgpfuj #define fits_read_imgnull_sht ffgpfi #define fits_read_imgnull_lng ffgpfj #define fits_read_imgnull_lnglng ffgpfjj #define fits_read_imgnull_uint ffgpfuk #define fits_read_imgnull_int ffgpfk #define fits_read_imgnull_flt ffgpfe #define fits_read_imgnull_dbl ffgpfd #define fits_read_2d_byt ffg2db #define fits_read_2d_sbyt ffg2dsb #define fits_read_2d_usht ffg2dui #define fits_read_2d_ulng ffg2duj #define fits_read_2d_sht ffg2di #define fits_read_2d_lng ffg2dj #define fits_read_2d_lnglng ffg2djj #define fits_read_2d_uint ffg2duk #define fits_read_2d_int ffg2dk #define fits_read_2d_flt ffg2de #define fits_read_2d_dbl ffg2dd #define fits_read_3d_byt ffg3db #define fits_read_3d_sbyt ffg3dsb #define fits_read_3d_usht ffg3dui #define fits_read_3d_ulng ffg3duj #define fits_read_3d_sht ffg3di #define fits_read_3d_lng ffg3dj #define fits_read_3d_lnglng ffg3djj #define fits_read_3d_uint ffg3duk #define fits_read_3d_int ffg3dk #define fits_read_3d_flt ffg3de #define fits_read_3d_dbl ffg3dd #define fits_read_subset ffgsv #define fits_read_subset_byt ffgsvb #define fits_read_subset_sbyt ffgsvsb #define fits_read_subset_usht ffgsvui #define fits_read_subset_ulng ffgsvuj #define fits_read_subset_sht ffgsvi #define fits_read_subset_lng ffgsvj #define fits_read_subset_lnglng ffgsvjj #define fits_read_subset_uint ffgsvuk #define fits_read_subset_int ffgsvk #define fits_read_subset_flt ffgsve #define fits_read_subset_dbl ffgsvd #define fits_read_subsetnull_byt ffgsfb #define fits_read_subsetnull_sbyt ffgsfsb #define fits_read_subsetnull_usht ffgsfui #define fits_read_subsetnull_ulng ffgsfuj #define fits_read_subsetnull_sht ffgsfi #define fits_read_subsetnull_lng ffgsfj #define fits_read_subsetnull_lnglng ffgsfjj #define fits_read_subsetnull_uint ffgsfuk #define fits_read_subsetnull_int ffgsfk #define fits_read_subsetnull_flt ffgsfe #define fits_read_subsetnull_dbl ffgsfd #define ffcpimg fits_copy_image_section #define fits_compress_img fits_comp_img #define fits_decompress_img fits_decomp_img #define fits_read_col ffgcv #define fits_read_colnull ffgcf #define fits_read_col_str ffgcvs #define fits_read_col_log ffgcvl #define fits_read_col_byt ffgcvb #define fits_read_col_sbyt ffgcvsb #define fits_read_col_usht ffgcvui #define fits_read_col_ulng ffgcvuj #define fits_read_col_sht ffgcvi #define fits_read_col_lng ffgcvj #define fits_read_col_lnglng ffgcvjj #define fits_read_col_uint ffgcvuk #define fits_read_col_int ffgcvk #define fits_read_col_flt ffgcve #define fits_read_col_dbl ffgcvd #define fits_read_col_cmp ffgcvc #define fits_read_col_dblcmp ffgcvm #define fits_read_col_bit ffgcx #define fits_read_col_bit_usht ffgcxui #define fits_read_col_bit_uint ffgcxuk #define fits_read_colnull_str ffgcfs #define fits_read_colnull_log ffgcfl #define fits_read_colnull_byt ffgcfb #define fits_read_colnull_sbyt ffgcfsb #define fits_read_colnull_usht ffgcfui #define fits_read_colnull_ulng ffgcfuj #define fits_read_colnull_sht ffgcfi #define fits_read_colnull_lng ffgcfj #define fits_read_colnull_lnglng ffgcfjj #define fits_read_colnull_uint ffgcfuk #define fits_read_colnull_int ffgcfk #define fits_read_colnull_flt ffgcfe #define fits_read_colnull_dbl ffgcfd #define fits_read_colnull_cmp ffgcfc #define fits_read_colnull_dblcmp ffgcfm #define fits_read_descript ffgdes #define fits_read_descriptll ffgdesll #define fits_read_descripts ffgdess #define fits_read_descriptsll ffgdessll #define fits_read_tblbytes ffgtbb #define fits_write_grppar_byt ffpgpb #define fits_write_grppar_sbyt ffpgpsb #define fits_write_grppar_usht ffpgpui #define fits_write_grppar_ulng ffpgpuj #define fits_write_grppar_sht ffpgpi #define fits_write_grppar_lng ffpgpj #define fits_write_grppar_lnglng ffpgpjj #define fits_write_grppar_uint ffpgpuk #define fits_write_grppar_int ffpgpk #define fits_write_grppar_flt ffpgpe #define fits_write_grppar_dbl ffpgpd #define fits_write_pix ffppx #define fits_write_pixll ffppxll #define fits_write_pixnull ffppxn #define fits_write_pixnullll ffppxnll #define fits_write_img ffppr #define fits_write_img_byt ffpprb #define fits_write_img_sbyt ffpprsb #define fits_write_img_usht ffpprui #define fits_write_img_ulng ffppruj #define fits_write_img_sht ffppri #define fits_write_img_lng ffpprj #define fits_write_img_lnglng ffpprjj #define fits_write_img_uint ffppruk #define fits_write_img_int ffpprk #define fits_write_img_flt ffppre #define fits_write_img_dbl ffpprd #define fits_write_imgnull ffppn #define fits_write_imgnull_byt ffppnb #define fits_write_imgnull_sbyt ffppnsb #define fits_write_imgnull_usht ffppnui #define fits_write_imgnull_ulng ffppnuj #define fits_write_imgnull_sht ffppni #define fits_write_imgnull_lng ffppnj #define fits_write_imgnull_lnglng ffppnjj #define fits_write_imgnull_uint ffppnuk #define fits_write_imgnull_int ffppnk #define fits_write_imgnull_flt ffppne #define fits_write_imgnull_dbl ffppnd #define fits_write_img_null ffppru #define fits_write_null_img ffpprn #define fits_write_2d_byt ffp2db #define fits_write_2d_sbyt ffp2dsb #define fits_write_2d_usht ffp2dui #define fits_write_2d_ulng ffp2duj #define fits_write_2d_sht ffp2di #define fits_write_2d_lng ffp2dj #define fits_write_2d_lnglng ffp2djj #define fits_write_2d_uint ffp2duk #define fits_write_2d_int ffp2dk #define fits_write_2d_flt ffp2de #define fits_write_2d_dbl ffp2dd #define fits_write_3d_byt ffp3db #define fits_write_3d_sbyt ffp3dsb #define fits_write_3d_usht ffp3dui #define fits_write_3d_ulng ffp3duj #define fits_write_3d_sht ffp3di #define fits_write_3d_lng ffp3dj #define fits_write_3d_lnglng ffp3djj #define fits_write_3d_uint ffp3duk #define fits_write_3d_int ffp3dk #define fits_write_3d_flt ffp3de #define fits_write_3d_dbl ffp3dd #define fits_write_subset ffpss #define fits_write_subset_byt ffpssb #define fits_write_subset_sbyt ffpsssb #define fits_write_subset_usht ffpssui #define fits_write_subset_ulng ffpssuj #define fits_write_subset_sht ffpssi #define fits_write_subset_lng ffpssj #define fits_write_subset_lnglng ffpssjj #define fits_write_subset_uint ffpssuk #define fits_write_subset_int ffpssk #define fits_write_subset_flt ffpsse #define fits_write_subset_dbl ffpssd #define fits_write_col ffpcl #define fits_write_col_str ffpcls #define fits_write_col_log ffpcll #define fits_write_col_byt ffpclb #define fits_write_col_sbyt ffpclsb #define fits_write_col_usht ffpclui #define fits_write_col_ulng ffpcluj #define fits_write_col_sht ffpcli #define fits_write_col_lng ffpclj #define fits_write_col_lnglng ffpcljj #define fits_write_col_uint ffpcluk #define fits_write_col_int ffpclk #define fits_write_col_flt ffpcle #define fits_write_col_dbl ffpcld #define fits_write_col_cmp ffpclc #define fits_write_col_dblcmp ffpclm #define fits_write_col_null ffpclu #define fits_write_col_bit ffpclx #define fits_write_nulrows ffprwu #define fits_write_nullrows ffprwu #define fits_write_colnull ffpcn #define fits_write_colnull_str ffpcns #define fits_write_colnull_log ffpcnl #define fits_write_colnull_byt ffpcnb #define fits_write_colnull_sbyt ffpcnsb #define fits_write_colnull_usht ffpcnui #define fits_write_colnull_ulng ffpcnuj #define fits_write_colnull_sht ffpcni #define fits_write_colnull_lng ffpcnj #define fits_write_colnull_lnglng ffpcnjj #define fits_write_colnull_uint ffpcnuk #define fits_write_colnull_int ffpcnk #define fits_write_colnull_flt ffpcne #define fits_write_colnull_dbl ffpcnd #define fits_write_ext ffpextn #define fits_read_ext ffgextn #define fits_write_descript ffpdes #define fits_compress_heap ffcmph #define fits_test_heap fftheap #define fits_write_tblbytes ffptbb #define fits_insert_rows ffirow #define fits_delete_rows ffdrow #define fits_delete_rowrange ffdrrg #define fits_delete_rowlist ffdrws #define fits_delete_rowlistll ffdrwsll #define fits_insert_col fficol #define fits_insert_cols fficls #define fits_delete_col ffdcol #define fits_copy_col ffcpcl #define fits_modify_vector_len ffmvec #define fits_read_img_coord ffgics #define fits_read_tbl_coord ffgtcs #define fits_pix_to_world ffwldp #define fits_world_to_pix ffxypx #define fits_get_image_wcs_keys ffgiwcs #define fits_get_table_wcs_keys ffgtwcs #define fits_find_rows fffrow #define fits_find_first_row ffffrw #define fits_find_rows_cmp fffrwc #define fits_select_rows ffsrow #define fits_calc_rows ffcrow #define fits_calculator ffcalc #define fits_calculator_rng ffcalc_rng #define fits_test_expr fftexp #define fits_create_group ffgtcr #define fits_insert_group ffgtis #define fits_change_group ffgtch #define fits_remove_group ffgtrm #define fits_copy_group ffgtcp #define fits_merge_groups ffgtmg #define fits_compact_group ffgtcm #define fits_verify_group ffgtvf #define fits_open_group ffgtop #define fits_add_group_member ffgtam #define fits_get_num_members ffgtnm #define fits_get_num_groups ffgmng #define fits_open_member ffgmop #define fits_copy_member ffgmcp #define fits_transfer_member ffgmtf #define fits_remove_member ffgmrm #endif skycat-3.1.2-starlink-1b/astrotcl/cfitsio/modkey.c000066400000000000000000001645661215713201500221060ustar00rootroot00000000000000/* This file, modkey.c, contains routines that modify, insert, or update */ /* keywords in a FITS header. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include /* stddef.h is apparently needed to define size_t */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffuky( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ char *keyname, /* I - name of keyword to write */ void *value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Update the keyword, value and comment in the FITS header. The datatype is specified by the 2nd argument. */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (datatype == TSTRING) { ffukys(fptr, keyname, (char *) value, comm, status); } else if (datatype == TBYTE) { ffukyj(fptr, keyname, (LONGLONG) *(unsigned char *) value, comm, status); } else if (datatype == TSBYTE) { ffukyj(fptr, keyname, (LONGLONG) *(signed char *) value, comm, status); } else if (datatype == TUSHORT) { ffukyj(fptr, keyname, (LONGLONG) *(unsigned short *) value, comm, status); } else if (datatype == TSHORT) { ffukyj(fptr, keyname, (LONGLONG) *(short *) value, comm, status); } else if (datatype == TINT) { ffukyj(fptr, keyname, (LONGLONG) *(int *) value, comm, status); } else if (datatype == TUINT) { ffukyg(fptr, keyname, (double) *(unsigned int *) value, 0, comm, status); } else if (datatype == TLOGICAL) { ffukyl(fptr, keyname, *(int *) value, comm, status); } else if (datatype == TULONG) { ffukyg(fptr, keyname, (double) *(unsigned long *) value, 0, comm, status); } else if (datatype == TLONG) { ffukyj(fptr, keyname, (LONGLONG) *(long *) value, comm, status); } else if (datatype == TLONGLONG) { ffukyj(fptr, keyname, *(LONGLONG *) value, comm, status); } else if (datatype == TFLOAT) { ffukye(fptr, keyname, *(float *) value, -7, comm, status); } else if (datatype == TDOUBLE) { ffukyd(fptr, keyname, *(double *) value, -15, comm, status); } else if (datatype == TCOMPLEX) { ffukyc(fptr, keyname, (float *) value, -7, comm, status); } else if (datatype == TDBLCOMPLEX) { ffukym(fptr, keyname, (double *) value, -15, comm, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffukyu(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkyu(fptr, keyname, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkyu(fptr, keyname, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukys(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkys(fptr, keyname, value, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkys(fptr, keyname, value, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukls(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { /* update a long string keyword */ int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkls(fptr, keyname, value, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkls(fptr, keyname, value, comm, status); } return(*status); }/*--------------------------------------------------------------------------*/ int ffukyl(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ int value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkyl(fptr, keyname, value, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkyl(fptr, keyname, value, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukyj(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ LONGLONG value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkyj(fptr, keyname, value, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkyj(fptr, keyname, value, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukyf(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkyf(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkyf(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukye(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkye(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkye(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukyg(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkyg(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkyg(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukyd(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkyd(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkyd(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukfc(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkfc(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkfc(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukyc(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkyc(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkyc(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukfm(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkfm(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkfm(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukym(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkym(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkym(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffucrd(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *card, /* I - card string value */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmcrd(fptr, keyname, card, status) == KEY_NO_EXIST) { *status = tstatus; ffprec(fptr, card, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffmrec(fitsfile *fptr, /* I - FITS file pointer */ int nkey, /* I - number of the keyword to modify */ char *card, /* I - card string value */ int *status) /* IO - error status */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffmaky(fptr, nkey+1, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmcrd(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *card, /* I - card string value */ int *status) /* IO - error status */ { char tcard[FLEN_CARD], valstring[FLEN_CARD], comm[FLEN_CARD], value[FLEN_CARD]; int keypos, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgcrd(fptr, keyname, tcard, status) > 0) return(*status); ffmkey(fptr, card, status); /* calc position of keyword in header */ keypos = (int) ((((fptr->Fptr)->nextkey) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu])) / 80) + 1; ffpsvc(tcard, valstring, comm, status); /* check for string value which may be continued over multiple keywords */ ffc2s(valstring, value, status); /* remove quotes and trailing spaces */ len = strlen(value); while (len && value[len - 1] == '&') /* ampersand used as continuation char */ { ffgcnt(fptr, value, status); if (*value) { ffdrec(fptr, keypos, status); /* delete the keyword */ len = strlen(value); } else /* a null valstring indicates no continuation */ len = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int ffmnam(fitsfile *fptr, /* I - FITS file pointer */ char *oldname, /* I - existing keyword name */ char *newname, /* I - new name for keyword */ int *status) /* IO - error status */ { char comm[FLEN_COMMENT]; char value[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, oldname, value, comm, status) > 0) return(*status); ffmkky(newname, value, comm, card, status); /* construct the card */ ffmkey(fptr, card, status); /* rewrite with new name */ return(*status); } /*--------------------------------------------------------------------------*/ int ffmcom(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char oldcomm[FLEN_COMMENT]; char value[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, value, oldcomm, status) > 0) return(*status); ffmkky(keyname, value, comm, card, status); /* construct the card */ ffmkey(fptr, card, status); /* rewrite with new comment */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpunt(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *unit, /* I - keyword unit string */ int *status) /* IO - error status */ /* Write (put) the units string into the comment field of the existing keyword. This routine uses a local FITS convention (not defined in the official FITS standard) in which the units are enclosed in square brackets following the '/' comment field delimiter, e.g.: KEYWORD = 12 / [kpc] comment string goes here */ { char oldcomm[FLEN_COMMENT]; char newcomm[FLEN_COMMENT]; char value[FLEN_VALUE]; char card[FLEN_CARD]; char *loc; size_t len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, value, oldcomm, status) > 0) return(*status); /* copy the units string to the new comment string if not null */ if (*unit) { strcpy(newcomm, "["); strncat(newcomm, unit, 45); /* max allowed length is about 45 chars */ strcat(newcomm, "] "); len = strlen(newcomm); len = FLEN_COMMENT - len - 1; /* amount of space left in the field */ } else { newcomm[0] = '\0'; len = FLEN_COMMENT - 1; } if (oldcomm[0] == '[') /* check for existing units field */ { loc = strchr(oldcomm, ']'); /* look for the closing bracket */ if (loc) { loc++; while (*loc == ' ') /* skip any blank spaces */ loc++; strncat(newcomm, loc, len); /* concat remainder of comment */ } else { strncat(newcomm, oldcomm, len); /* append old comment onto new */ } } else { strncat(newcomm, oldcomm, len); } ffmkky(keyname, value, newcomm, card, status); /* construct the card */ ffmkey(fptr, card, status); /* rewrite with new units string */ return(*status); } /*--------------------------------------------------------------------------*/ int ffmkyu(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ strcpy(valstring," "); /* create a dummy value string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkys(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { /* NOTE: This routine does not support long continued strings */ /* It will correctly overwrite an existing long continued string, */ /* but it will not write a new long string. */ char oldval[FLEN_VALUE], valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; int len, keypos; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, oldval, oldcomm, status) > 0) return(*status); /* get old comment */ ffs2c(value, valstring, status); /* convert value to a string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); /* overwrite the previous keyword */ keypos = (int) (((((fptr->Fptr)->nextkey) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu])) / 80) + 1); /* check if old string value was continued over multiple keywords */ ffc2s(oldval, valstring, status); /* remove quotes and trailing spaces */ len = strlen(valstring); while (len && valstring[len - 1] == '&') /* ampersand is continuation char */ { ffgcnt(fptr, valstring, status); if (*valstring) { ffdrec(fptr, keypos, status); /* delete the continuation */ len = strlen(valstring); } else /* a null valstring indicates no continuation */ len = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int ffmkls( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ char *value, /* I - keyword value */ char *incomm, /* I - keyword comment */ int *status) /* IO - error status */ /* Modify the value and optionally the comment of a long string keyword. This routine supports the HEASARC long string convention and can modify arbitrarily long string keyword values. The value is continued over multiple keywords that have the name COMTINUE without an equal sign in column 9 of the card. This routine also supports simple string keywords which are less than 69 characters in length. This routine is not very efficient, so it should be used sparingly. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; char comm[FLEN_COMMENT]; char tstring[FLEN_VALUE], *cptr; char *longval; int next, remain, vlen, nquote, nchar, namelen, contin, tstatus = -1; int nkeys, keypos; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (!incomm || incomm[0] == '&') /* preserve the old comment string */ { ffghps(fptr, &nkeys, &keypos, status); /* save current position */ if (ffgkls(fptr, keyname, &longval, comm, status) > 0) return(*status); /* keyword doesn't exist */ free(longval); /* don't need the old value */ /* move back to previous position to ensure that we delete */ /* the right keyword in case there are more than one keyword */ /* with this same name. */ ffgrec(fptr, keypos - 1, card, status); } else strcpy(comm, incomm); /* copy the input comment string */ /* delete the old keyword */ if (ffdkey(fptr, keyname, status) > 0) return(*status); /* keyword doesn't exist */ ffghps(fptr, &nkeys, &keypos, status); /* save current position */ /* now construct the new keyword, and insert into header */ remain = strlen(value); /* number of characters to write out */ next = 0; /* pointer to next character to write */ /* count the number of single quote characters in the string */ nquote = 0; cptr = strchr(value, '\''); /* search for quote character */ while (cptr) /* search for quote character */ { nquote++; /* increment no. of quote characters */ cptr++; /* increment pointer to next character */ cptr = strchr(cptr, '\''); /* search for another quote char */ } cptr = keyname; while(*cptr == ' ') /* skip over leading spaces in name */ cptr++; /* determine the number of characters that will fit on the line */ /* Note: each quote character is expanded to 2 quotes */ namelen = strlen(cptr); if (namelen <= 8 && (fftkey(cptr, &tstatus) <= 0) ) { /* This a normal 8-character FITS keyword */ nchar = 68 - nquote; /* max of 68 chars fit in a FITS string value */ } else { /* This a HIERARCH keyword */ if (FSTRNCMP(cptr, "HIERARCH ", 9) && FSTRNCMP(cptr, "hierarch ", 9)) nchar = 66 - nquote - namelen; else nchar = 75 - nquote - namelen; /* don't count 'HIERARCH' twice */ } contin = 0; while (remain > 0) { strncpy(tstring, &value[next], nchar); /* copy string to temp buff */ tstring[nchar] = '\0'; ffs2c(tstring, valstring, status); /* put quotes around the string */ if (remain > nchar) /* if string is continued, put & as last char */ { vlen = strlen(valstring); nchar -= 1; /* outputting one less character now */ if (valstring[vlen-2] != '\'') valstring[vlen-2] = '&'; /* over write last char with & */ else { /* last char was a pair of single quotes, so over write both */ valstring[vlen-3] = '&'; valstring[vlen-1] = '\0'; } } if (contin) /* This is a CONTINUEd keyword */ { ffmkky("CONTINUE", valstring, comm, card, status); /* make keyword */ strncpy(&card[8], " ", 2); /* overwrite the '=' */ } else { ffmkky(keyname, valstring, comm, card, status); /* make keyword */ } ffirec(fptr, keypos, card, status); /* insert the keyword */ keypos++; /* next insert position */ contin = 1; remain -= nchar; next += nchar; nchar = 68 - nquote; } return(*status); } /*--------------------------------------------------------------------------*/ int ffmkyl(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ int value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ ffl2c(value, valstring, status); /* convert value to a string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkyj(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ LONGLONG value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ ffi2c(value, valstring, status); /* convert value to a string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkyf(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ ffr2f(value, decim, valstring, status); /* convert value to a string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkye(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ ffr2e(value, decim, valstring, status); /* convert value to a string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkyg(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ ffd2f(value, decim, valstring, status); /* convert value to a string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkyd(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ ffd2e(value, decim, valstring, status); /* convert value to a string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkfc(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ strcpy(valstring, "(" ); ffr2f(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffr2f(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkyc(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ strcpy(valstring, "(" ); ffr2e(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffr2e(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkfm(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ strcpy(valstring, "(" ); ffd2f(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffd2f(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkym(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ strcpy(valstring, "(" ); ffd2e(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffd2e(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffikyu(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Insert a null-valued keyword and comment into the FITS header. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring," "); /* create a dummy value string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffikys(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffs2c(value, valstring, status); /* put quotes around the string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffikls( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ char *value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Insert a long string keyword. This routine supports the HEASARC long string convention and can insert arbitrarily long string keyword values. The value is continued over multiple keywords that have the name COMTINUE without an equal sign in column 9 of the card. This routine also supports simple string keywords which are less than 69 characters in length. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; char tstring[FLEN_VALUE], *cptr; int next, remain, vlen, nquote, nchar, namelen, contin, tstatus = -1; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* construct the new keyword, and insert into header */ remain = strlen(value); /* number of characters to write out */ next = 0; /* pointer to next character to write */ /* count the number of single quote characters in the string */ nquote = 0; cptr = strchr(value, '\''); /* search for quote character */ while (cptr) /* search for quote character */ { nquote++; /* increment no. of quote characters */ cptr++; /* increment pointer to next character */ cptr = strchr(cptr, '\''); /* search for another quote char */ } cptr = keyname; while(*cptr == ' ') /* skip over leading spaces in name */ cptr++; /* determine the number of characters that will fit on the line */ /* Note: each quote character is expanded to 2 quotes */ namelen = strlen(cptr); if (namelen <= 8 && (fftkey(cptr, &tstatus) <= 0) ) { /* This a normal 8-character FITS keyword */ nchar = 68 - nquote; /* max of 68 chars fit in a FITS string value */ } else { /* This a HIERARCH keyword */ if (FSTRNCMP(cptr, "HIERARCH ", 9) && FSTRNCMP(cptr, "hierarch ", 9)) nchar = 66 - nquote - namelen; else nchar = 75 - nquote - namelen; /* don't count 'HIERARCH' twice */ } contin = 0; while (remain > 0) { strncpy(tstring, &value[next], nchar); /* copy string to temp buff */ tstring[nchar] = '\0'; ffs2c(tstring, valstring, status); /* put quotes around the string */ if (remain > nchar) /* if string is continued, put & as last char */ { vlen = strlen(valstring); nchar -= 1; /* outputting one less character now */ if (valstring[vlen-2] != '\'') valstring[vlen-2] = '&'; /* over write last char with & */ else { /* last char was a pair of single quotes, so over write both */ valstring[vlen-3] = '&'; valstring[vlen-1] = '\0'; } } if (contin) /* This is a CONTINUEd keyword */ { ffmkky("CONTINUE", valstring, comm, card, status); /* make keyword */ strncpy(&card[8], " ", 2); /* overwrite the '=' */ } else { ffmkky(keyname, valstring, comm, card, status); /* make keyword */ } ffikey(fptr, card, status); /* insert the keyword */ contin = 1; remain -= nchar; next += nchar; nchar = 68 - nquote; } return(*status); } /*--------------------------------------------------------------------------*/ int ffikyl(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ int value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffl2c(value, valstring, status); /* convert logical to 'T' or 'F' */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikyj(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ LONGLONG value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffi2c(value, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikyf(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffr2f(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikye(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffr2e(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikyg(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffd2f(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikyd(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffd2e(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikfc(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffr2f(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffr2f(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikyc(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffr2e(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffr2e(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikfm(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffd2f(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffd2f(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikym(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffd2e(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffd2e(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffirec(fitsfile *fptr, /* I - FITS file pointer */ int nkey, /* I - position to insert new keyword */ char *card, /* I - card string value */ int *status) /* IO - error status */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffmaky(fptr, nkey, status); /* move to insert position */ ffikey(fptr, card, status); /* insert the keyword card */ return(*status); } /*--------------------------------------------------------------------------*/ int ffikey(fitsfile *fptr, /* I - FITS file pointer */ char *card, /* I - card string value */ int *status) /* IO - error status */ /* insert a keyword at the position of (fptr->Fptr)->nextkey */ { int ii, len, nshift; long nblocks; LONGLONG bytepos; char *inbuff, *outbuff, *tmpbuff, buff1[FLEN_CARD], buff2[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ( ((fptr->Fptr)->datastart - (fptr->Fptr)->headend) == 80) /* only room for END card */ { nblocks = 1; if (ffiblk(fptr, nblocks, 0, status) > 0) /* add new 2880-byte block*/ return(*status); } /* no. keywords to shift */ nshift= (int) (( (fptr->Fptr)->headend - (fptr->Fptr)->nextkey ) / 80); strncpy(buff2, card, 80); /* copy card to output buffer */ buff2[80] = '\0'; len = strlen(buff2); for (ii=len; ii < 80; ii++) /* fill buffer with spaces if necessary */ buff2[ii] = ' '; for (ii=0; ii < 8; ii++) /* make sure keyword name is uppercase */ buff2[ii] = toupper(buff2[ii]); fftkey(buff2, status); /* test keyword name contains legal chars */ fftrec(buff2, status); /* test rest of keyword for legal chars */ inbuff = buff1; outbuff = buff2; bytepos = (fptr->Fptr)->nextkey; /* pointer to next keyword in header */ ffmbyt(fptr, bytepos, REPORT_EOF, status); for (ii = 0; ii < nshift; ii++) /* shift each keyword down one position */ { ffgbyt(fptr, 80, inbuff, status); /* read the current keyword */ ffmbyt(fptr, bytepos, REPORT_EOF, status); /* move back */ ffpbyt(fptr, 80, outbuff, status); /* overwrite with other buffer */ tmpbuff = inbuff; /* swap input and output buffers */ inbuff = outbuff; outbuff = tmpbuff; bytepos += 80; } ffpbyt(fptr, 80, outbuff, status); /* write the final keyword */ (fptr->Fptr)->headend += 80; /* increment the position of the END keyword */ (fptr->Fptr)->nextkey += 80; /* increment the pointer to next keyword */ return(*status); } /*--------------------------------------------------------------------------*/ int ffdkey(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ int *status) /* IO - error status */ /* delete a specified header keyword */ { int keypos, len; char valstring[FLEN_VALUE], comm[FLEN_COMMENT], value[FLEN_VALUE]; char message[FLEN_ERRMSG]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, comm, status) > 0) /* read keyword */ { sprintf(message, "Could not find the %s keyword to delete (ffdkey)", keyname); ffpmsg(message); return(*status); } /* calc position of keyword in header */ keypos = (int) ((((fptr->Fptr)->nextkey) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu])) / 80); ffdrec(fptr, keypos, status); /* delete the keyword */ /* check for string value which may be continued over multiple keywords */ ffc2s(valstring, value, status); /* remove quotes and trailing spaces */ len = strlen(value); while (len && value[len - 1] == '&') /* ampersand used as continuation char */ { ffgcnt(fptr, value, status); if (*value) { ffdrec(fptr, keypos, status); /* delete the keyword */ len = strlen(value); } else /* a null valstring indicates no continuation */ len = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int ffdrec(fitsfile *fptr, /* I - FITS file pointer */ int keypos, /* I - position in header of keyword to delete */ int *status) /* IO - error status */ /* Delete a header keyword at position keypos. The 1st keyword is at keypos=1. */ { int ii, nshift; LONGLONG bytepos; char *inbuff, *outbuff, *tmpbuff, buff1[81], buff2[81]; char message[FLEN_ERRMSG]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (keypos < 1 || keypos > (fptr->Fptr)->headend - (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] / 80 ) return(*status = KEY_OUT_BOUNDS); (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] + (keypos - 1) * 80; nshift=(int) (( (fptr->Fptr)->headend - (fptr->Fptr)->nextkey ) / 80); /* no. keywords to shift */ if (nshift <= 0) { sprintf(message, "Cannot delete keyword number %d. It does not exist.", keypos); ffpmsg(message); return(*status = KEY_OUT_BOUNDS); } bytepos = (fptr->Fptr)->headend - 80; /* last keyword in header */ /* construct a blank keyword */ strcpy(buff2, " "); strcat(buff2, " "); inbuff = buff1; outbuff = buff2; for (ii = 0; ii < nshift; ii++) /* shift each keyword up one position */ { ffmbyt(fptr, bytepos, REPORT_EOF, status); ffgbyt(fptr, 80, inbuff, status); /* read the current keyword */ ffmbyt(fptr, bytepos, REPORT_EOF, status); ffpbyt(fptr, 80, outbuff, status); /* overwrite with next keyword */ tmpbuff = inbuff; /* swap input and output buffers */ inbuff = outbuff; outbuff = tmpbuff; bytepos -= 80; } (fptr->Fptr)->headend -= 80; /* decrement the position of the END keyword */ return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/pliocomp.c000066400000000000000000000156541215713201500224310ustar00rootroot00000000000000/* stdlib is needed for the abs function */ #include /* The following prototype code was provided by Doug Tody, NRAO, for performing conversion between pixel arrays and line lists. The compression technique is used in IRAF. */ int pl_p2li (int *pxsrc, int xs, short *lldst, int npix); int pl_l2pi (short *ll_src, int xs, int *px_dst, int npix); /* * PL_P2L -- Convert a pixel array to a line list. The length of the list is * returned as the function value. * * Translated from the SPP version using xc -f, f2c. 8Sep99 DCT. */ #ifndef min #define min(a,b) (((a)<(b))?(a):(b)) #endif #ifndef max #define max(a,b) (((a)>(b))?(a):(b)) #endif int pl_p2li (int *pxsrc, int xs, short *lldst, int npix) /* int *pxsrc; input pixel array */ /* int xs; starting index in pxsrc (?) */ /* short *lldst; encoded line list */ /* int npix; number of pixels to convert */ { /* System generated locals */ int ret_val, i__1, i__2, i__3; /* Local variables */ static int zero, v, x1, hi, ip, dv, xe, np, op, iz, nv, pv, nz; /* Parameter adjustments */ --lldst; --pxsrc; /* Function Body */ if (! (npix <= 0)) { goto L110; } ret_val = 0; goto L100; L110: lldst[3] = -100; lldst[2] = 7; lldst[1] = 0; lldst[6] = 0; lldst[7] = 0; xe = xs + npix - 1; op = 8; zero = 0; /* Computing MAX */ i__1 = zero, i__2 = pxsrc[xs]; pv = max(i__1,i__2); x1 = xs; iz = xs; hi = 1; i__1 = xe; for (ip = xs; ip <= i__1; ++ip) { if (! (ip < xe)) { goto L130; } /* Computing MAX */ i__2 = zero, i__3 = pxsrc[ip + 1]; nv = max(i__2,i__3); if (! (nv == pv)) { goto L140; } goto L120; L140: if (! (pv == 0)) { goto L150; } pv = nv; x1 = ip + 1; goto L120; L150: goto L131; L130: if (! (pv == 0)) { goto L160; } x1 = xe + 1; L160: L131: np = ip - x1 + 1; nz = x1 - iz; if (! (pv > 0)) { goto L170; } dv = pv - hi; if (! (dv != 0)) { goto L180; } hi = pv; if (! (abs(dv) > 4095)) { goto L190; } lldst[op] = (short) ((pv & 4095) + 4096); ++op; lldst[op] = (short) (pv / 4096); ++op; goto L191; L190: if (! (dv < 0)) { goto L200; } lldst[op] = (short) (-dv + 12288); goto L201; L200: lldst[op] = (short) (dv + 8192); L201: ++op; if (! (np == 1 && nz == 0)) { goto L210; } v = lldst[op - 1]; lldst[op - 1] = (short) (v | 16384); goto L91; L210: L191: L180: L170: if (! (nz > 0)) { goto L220; } L230: if (! (nz > 0)) { goto L232; } lldst[op] = (short) min(4095,nz); ++op; /* L231: */ nz += -4095; goto L230; L232: if (! (np == 1 && pv > 0)) { goto L240; } lldst[op - 1] = (short) (lldst[op - 1] + 20481); goto L91; L240: L220: L250: if (! (np > 0)) { goto L252; } lldst[op] = (short) (min(4095,np) + 16384); ++op; /* L251: */ np += -4095; goto L250; L252: L91: x1 = ip + 1; iz = x1; pv = nv; L120: ; } /* L121: */ lldst[4] = (short) ((op - 1) % 32768); lldst[5] = (short) ((op - 1) / 32768); ret_val = op - 1; goto L100; L100: return ret_val; } /* plp2li_ */ /* * PL_L2PI -- Translate a PLIO line list into an integer pixel array. * The number of pixels output (always npix) is returned as the function * value. * * Translated from the SPP version using xc -f, f2c. 8Sep99 DCT. */ int pl_l2pi (short *ll_src, int xs, int *px_dst, int npix) /* short *ll_src; encoded line list */ /* int xs; starting index in ll_src */ /* int *px_dst; output pixel array */ /* int npix; number of pixels to convert */ { /* System generated locals */ int ret_val, i__1, i__2; /* Local variables */ static int data, sw0001, otop, i__, lllen, i1, i2, x1, x2, ip, xe, np, op, pv, opcode, llfirt; static int skipwd; /* Parameter adjustments */ --px_dst; --ll_src; /* Function Body */ if (! (ll_src[3] > 0)) { goto L110; } lllen = ll_src[3]; llfirt = 4; goto L111; L110: lllen = (ll_src[5] << 15) + ll_src[4]; llfirt = ll_src[2] + 1; L111: if (! (npix <= 0 || lllen <= 0)) { goto L120; } ret_val = 0; goto L100; L120: xe = xs + npix - 1; skipwd = 0; op = 1; x1 = 1; pv = 1; i__1 = lllen; for (ip = llfirt; ip <= i__1; ++ip) { if (! skipwd) { goto L140; } skipwd = 0; goto L130; L140: opcode = ll_src[ip] / 4096; data = ll_src[ip] & 4095; sw0001 = opcode; goto L150; L160: x2 = x1 + data - 1; i1 = max(x1,xs); i2 = min(x2,xe); np = i2 - i1 + 1; if (! (np > 0)) { goto L170; } otop = op + np - 1; if (! (opcode == 4)) { goto L180; } i__2 = otop; for (i__ = op; i__ <= i__2; ++i__) { px_dst[i__] = pv; /* L190: */ } /* L191: */ goto L181; L180: i__2 = otop; for (i__ = op; i__ <= i__2; ++i__) { px_dst[i__] = 0; /* L200: */ } /* L201: */ if (! (opcode == 5 && i2 == x2)) { goto L210; } px_dst[otop] = pv; L210: L181: op = otop + 1; L170: x1 = x2 + 1; goto L151; L220: pv = (ll_src[ip + 1] << 12) + data; skipwd = 1; goto L151; L230: pv += data; goto L151; L240: pv -= data; goto L151; L250: pv += data; goto L91; L260: pv -= data; L91: if (! (x1 >= xs && x1 <= xe)) { goto L270; } px_dst[op] = pv; ++op; L270: ++x1; goto L151; L150: ++sw0001; if (sw0001 < 1 || sw0001 > 8) { goto L151; } switch ((int)sw0001) { case 1: goto L160; case 2: goto L220; case 3: goto L230; case 4: goto L240; case 5: goto L160; case 6: goto L160; case 7: goto L250; case 8: goto L260; } L151: if (! (x1 > xe)) { goto L280; } goto L131; L280: L130: ; } L131: i__1 = npix; for (i__ = op; i__ <= i__1; ++i__) { px_dst[i__] = 0; /* L290: */ } /* L291: */ ret_val = npix; goto L100; L100: return ret_val; } /* pll2pi_ */ skycat-3.1.2-starlink-1b/astrotcl/cfitsio/putcol.c000066400000000000000000001767361215713201500221260ustar00rootroot00000000000000/* This file, putcol.c, contains routines that write data elements to */ /* a FITS image or table. These are the generic routines. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffppx( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ long *firstpix, /* I - coord of first pixel to write(1 based) */ LONGLONG nelem, /* I - number of values to write */ void *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of pixels to the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine is simillar to ffppr, except it supports writing to large images with more than 2**31 pixels. */ { int naxis, ii; long group = 1; LONGLONG firstelem, dimsize = 1, naxes[9]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgiszll(fptr, 9, naxes, status); firstelem = 0; for (ii=0; ii < naxis; ii++) { firstelem += ((firstpix[ii] - 1) * dimsize); dimsize *= naxes[ii]; } firstelem++; if (datatype == TBYTE) { ffpprb(fptr, group, firstelem, nelem, (unsigned char *) array, status); } else if (datatype == TSBYTE) { ffpprsb(fptr, group, firstelem, nelem, (signed char *) array, status); } else if (datatype == TUSHORT) { ffpprui(fptr, group, firstelem, nelem, (unsigned short *) array, status); } else if (datatype == TSHORT) { ffppri(fptr, group, firstelem, nelem, (short *) array, status); } else if (datatype == TUINT) { ffppruk(fptr, group, firstelem, nelem, (unsigned int *) array, status); } else if (datatype == TINT) { ffpprk(fptr, group, firstelem, nelem, (int *) array, status); } else if (datatype == TULONG) { ffppruj(fptr, group, firstelem, nelem, (unsigned long *) array, status); } else if (datatype == TLONG) { ffpprj(fptr, group, firstelem, nelem, (long *) array, status); } else if (datatype == TLONGLONG) { ffpprjj(fptr, group, firstelem, nelem, (LONGLONG *) array, status); } else if (datatype == TFLOAT) { ffppre(fptr, group, firstelem, nelem, (float *) array, status); } else if (datatype == TDOUBLE) { ffpprd(fptr, group, firstelem, nelem, (double *) array, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffppxll( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG *firstpix, /* I - coord of first pixel to write(1 based) */ LONGLONG nelem, /* I - number of values to write */ void *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of pixels to the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine is simillar to ffppr, except it supports writing to large images with more than 2**31 pixels. */ { int naxis, ii; long group = 1; LONGLONG firstelem, dimsize = 1, naxes[9]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgiszll(fptr, 9, naxes, status); firstelem = 0; for (ii=0; ii < naxis; ii++) { firstelem += ((firstpix[ii] - 1) * dimsize); dimsize *= naxes[ii]; } firstelem++; if (datatype == TBYTE) { ffpprb(fptr, group, firstelem, nelem, (unsigned char *) array, status); } else if (datatype == TSBYTE) { ffpprsb(fptr, group, firstelem, nelem, (signed char *) array, status); } else if (datatype == TUSHORT) { ffpprui(fptr, group, firstelem, nelem, (unsigned short *) array, status); } else if (datatype == TSHORT) { ffppri(fptr, group, firstelem, nelem, (short *) array, status); } else if (datatype == TUINT) { ffppruk(fptr, group, firstelem, nelem, (unsigned int *) array, status); } else if (datatype == TINT) { ffpprk(fptr, group, firstelem, nelem, (int *) array, status); } else if (datatype == TULONG) { ffppruj(fptr, group, firstelem, nelem, (unsigned long *) array, status); } else if (datatype == TLONG) { ffpprj(fptr, group, firstelem, nelem, (long *) array, status); } else if (datatype == TLONGLONG) { ffpprjj(fptr, group, firstelem, nelem, (LONGLONG *) array, status); } else if (datatype == TFLOAT) { ffppre(fptr, group, firstelem, nelem, (float *) array, status); } else if (datatype == TDOUBLE) { ffpprd(fptr, group, firstelem, nelem, (double *) array, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffppxn( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ long *firstpix, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ void *array, /* I - array of values that are written */ void *nulval, /* I - pointer to the null value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine supports writing to large images with more than 2**31 pixels. */ { int naxis, ii; long group = 1; LONGLONG firstelem, dimsize = 1, naxes[9]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (nulval == NULL) /* null value not defined? */ { ffppx(fptr, datatype, firstpix, nelem, array, status); return(*status); } /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgiszll(fptr, 9, naxes, status); firstelem = 0; for (ii=0; ii < naxis; ii++) { firstelem += ((firstpix[ii] - 1) * dimsize); dimsize *= naxes[ii]; } firstelem++; if (datatype == TBYTE) { ffppnb(fptr, group, firstelem, nelem, (unsigned char *) array, *(unsigned char *) nulval, status); } else if (datatype == TSBYTE) { ffppnsb(fptr, group, firstelem, nelem, (signed char *) array, *(signed char *) nulval, status); } else if (datatype == TUSHORT) { ffppnui(fptr, group, firstelem, nelem, (unsigned short *) array, *(unsigned short *) nulval,status); } else if (datatype == TSHORT) { ffppni(fptr, group, firstelem, nelem, (short *) array, *(short *) nulval, status); } else if (datatype == TUINT) { ffppnuk(fptr, group, firstelem, nelem, (unsigned int *) array, *(unsigned int *) nulval, status); } else if (datatype == TINT) { ffppnk(fptr, group, firstelem, nelem, (int *) array, *(int *) nulval, status); } else if (datatype == TULONG) { ffppnuj(fptr, group, firstelem, nelem, (unsigned long *) array, *(unsigned long *) nulval,status); } else if (datatype == TLONG) { ffppnj(fptr, group, firstelem, nelem, (long *) array, *(long *) nulval, status); } else if (datatype == TLONGLONG) { ffppnjj(fptr, group, firstelem, nelem, (LONGLONG *) array, *(LONGLONG *) nulval, status); } else if (datatype == TFLOAT) { ffppne(fptr, group, firstelem, nelem, (float *) array, *(float *) nulval, status); } else if (datatype == TDOUBLE) { ffppnd(fptr, group, firstelem, nelem, (double *) array, *(double *) nulval, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffppxnll( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG *firstpix, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ void *array, /* I - array of values that are written */ void *nulval, /* I - pointer to the null value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine supports writing to large images with more than 2**31 pixels. */ { int naxis, ii; long group = 1; LONGLONG firstelem, dimsize = 1, naxes[9]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (nulval == NULL) /* null value not defined? */ { ffppxll(fptr, datatype, firstpix, nelem, array, status); return(*status); } /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgiszll(fptr, 9, naxes, status); firstelem = 0; for (ii=0; ii < naxis; ii++) { firstelem += ((firstpix[ii] - 1) * dimsize); dimsize *= naxes[ii]; } firstelem++; if (datatype == TBYTE) { ffppnb(fptr, group, firstelem, nelem, (unsigned char *) array, *(unsigned char *) nulval, status); } else if (datatype == TSBYTE) { ffppnsb(fptr, group, firstelem, nelem, (signed char *) array, *(signed char *) nulval, status); } else if (datatype == TUSHORT) { ffppnui(fptr, group, firstelem, nelem, (unsigned short *) array, *(unsigned short *) nulval,status); } else if (datatype == TSHORT) { ffppni(fptr, group, firstelem, nelem, (short *) array, *(short *) nulval, status); } else if (datatype == TUINT) { ffppnuk(fptr, group, firstelem, nelem, (unsigned int *) array, *(unsigned int *) nulval, status); } else if (datatype == TINT) { ffppnk(fptr, group, firstelem, nelem, (int *) array, *(int *) nulval, status); } else if (datatype == TULONG) { ffppnuj(fptr, group, firstelem, nelem, (unsigned long *) array, *(unsigned long *) nulval,status); } else if (datatype == TLONG) { ffppnj(fptr, group, firstelem, nelem, (long *) array, *(long *) nulval, status); } else if (datatype == TLONGLONG) { ffppnjj(fptr, group, firstelem, nelem, (LONGLONG *) array, *(LONGLONG *) nulval, status); } else if (datatype == TFLOAT) { ffppne(fptr, group, firstelem, nelem, (float *) array, *(float *) nulval, status); } else if (datatype == TDOUBLE) { ffppnd(fptr, group, firstelem, nelem, (double *) array, *(double *) nulval, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffppr( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ void *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long group = 1; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (datatype == TBYTE) { ffpprb(fptr, group, firstelem, nelem, (unsigned char *) array, status); } else if (datatype == TSBYTE) { ffpprsb(fptr, group, firstelem, nelem, (signed char *) array, status); } else if (datatype == TUSHORT) { ffpprui(fptr, group, firstelem, nelem, (unsigned short *) array, status); } else if (datatype == TSHORT) { ffppri(fptr, group, firstelem, nelem, (short *) array, status); } else if (datatype == TUINT) { ffppruk(fptr, group, firstelem, nelem, (unsigned int *) array, status); } else if (datatype == TINT) { ffpprk(fptr, group, firstelem, nelem, (int *) array, status); } else if (datatype == TULONG) { ffppruj(fptr, group, firstelem, nelem, (unsigned long *) array, status); } else if (datatype == TLONG) { ffpprj(fptr, group, firstelem, nelem, (long *) array, status); } else if (datatype == TLONGLONG) { ffpprjj(fptr, group, firstelem, nelem, (LONGLONG *) array, status); } else if (datatype == TFLOAT) { ffppre(fptr, group, firstelem, nelem, (float *) array, status); } else if (datatype == TDOUBLE) { ffpprd(fptr, group, firstelem, nelem, (double *) array, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffppn( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ void *array, /* I - array of values that are written */ void *nulval, /* I - pointer to the null value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long group = 1; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (nulval == NULL) /* null value not defined? */ { ffppr(fptr, datatype, firstelem, nelem, array, status); return(*status); } if (datatype == TBYTE) { ffppnb(fptr, group, firstelem, nelem, (unsigned char *) array, *(unsigned char *) nulval, status); } else if (datatype == TSBYTE) { ffppnsb(fptr, group, firstelem, nelem, (signed char *) array, *(signed char *) nulval, status); } else if (datatype == TUSHORT) { ffppnui(fptr, group, firstelem, nelem, (unsigned short *) array, *(unsigned short *) nulval,status); } else if (datatype == TSHORT) { ffppni(fptr, group, firstelem, nelem, (short *) array, *(short *) nulval, status); } else if (datatype == TUINT) { ffppnuk(fptr, group, firstelem, nelem, (unsigned int *) array, *(unsigned int *) nulval, status); } else if (datatype == TINT) { ffppnk(fptr, group, firstelem, nelem, (int *) array, *(int *) nulval, status); } else if (datatype == TULONG) { ffppnuj(fptr, group, firstelem, nelem, (unsigned long *) array, *(unsigned long *) nulval,status); } else if (datatype == TLONG) { ffppnj(fptr, group, firstelem, nelem, (long *) array, *(long *) nulval, status); } else if (datatype == TLONGLONG) { ffppnjj(fptr, group, firstelem, nelem, (LONGLONG *) array, *(LONGLONG *) nulval, status); } else if (datatype == TFLOAT) { ffppne(fptr, group, firstelem, nelem, (float *) array, *(float *) nulval, status); } else if (datatype == TDOUBLE) { ffppnd(fptr, group, firstelem, nelem, (double *) array, *(double *) nulval, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffpss( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc , /* I - 'top right corner' of the subsection */ void *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write a section of values to the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine supports writing to large images with more than 2**31 pixels. */ { int naxis; long naxes[9]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgisz(fptr, 9, naxes, status); if (datatype == TBYTE) { ffpssb(fptr, 1, naxis, naxes, blc, trc, (unsigned char *) array, status); } else if (datatype == TSBYTE) { ffpsssb(fptr, 1, naxis, naxes, blc, trc, (signed char *) array, status); } else if (datatype == TUSHORT) { ffpssui(fptr, 1, naxis, naxes, blc, trc, (unsigned short *) array, status); } else if (datatype == TSHORT) { ffpssi(fptr, 1, naxis, naxes, blc, trc, (short *) array, status); } else if (datatype == TUINT) { ffpssuk(fptr, 1, naxis, naxes, blc, trc, (unsigned int *) array, status); } else if (datatype == TINT) { ffpssk(fptr, 1, naxis, naxes, blc, trc, (int *) array, status); } else if (datatype == TULONG) { ffpssuj(fptr, 1, naxis, naxes, blc, trc, (unsigned long *) array, status); } else if (datatype == TLONG) { ffpssj(fptr, 1, naxis, naxes, blc, trc, (long *) array, status); } else if (datatype == TLONGLONG) { ffpssjj(fptr, 1, naxis, naxes, blc, trc, (LONGLONG *) array, status); } else if (datatype == TFLOAT) { ffpsse(fptr, 1, naxis, naxes, blc, trc, (float *) array, status); } else if (datatype == TDOUBLE) { ffpssd(fptr, 1, naxis, naxes, blc, trc, (double *) array, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffpcl( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of elements to write */ void *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to a table column. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS column is not the same as the array being written). */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (datatype == TBIT) { ffpclx(fptr, colnum, firstrow, (long) firstelem, (long) nelem, (char *) array, status); } else if (datatype == TBYTE) { ffpclb(fptr, colnum, firstrow, firstelem, nelem, (unsigned char *) array, status); } else if (datatype == TSBYTE) { ffpclsb(fptr, colnum, firstrow, firstelem, nelem, (signed char *) array, status); } else if (datatype == TUSHORT) { ffpclui(fptr, colnum, firstrow, firstelem, nelem, (unsigned short *) array, status); } else if (datatype == TSHORT) { ffpcli(fptr, colnum, firstrow, firstelem, nelem, (short *) array, status); } else if (datatype == TUINT) { ffpcluk(fptr, colnum, firstrow, firstelem, nelem, (unsigned int *) array, status); } else if (datatype == TINT) { ffpclk(fptr, colnum, firstrow, firstelem, nelem, (int *) array, status); } else if (datatype == TULONG) { ffpcluj(fptr, colnum, firstrow, firstelem, nelem, (unsigned long *) array, status); } else if (datatype == TLONG) { ffpclj(fptr, colnum, firstrow, firstelem, nelem, (long *) array, status); } else if (datatype == TLONGLONG) { ffpcljj(fptr, colnum, firstrow, firstelem, nelem, (LONGLONG *) array, status); } else if (datatype == TFLOAT) { ffpcle(fptr, colnum, firstrow, firstelem, nelem, (float *) array, status); } else if (datatype == TDOUBLE) { ffpcld(fptr, colnum, firstrow, firstelem, nelem, (double *) array, status); } else if (datatype == TCOMPLEX) { ffpcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, (float *) array, status); } else if (datatype == TDBLCOMPLEX) { ffpcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, (double *) array, status); } else if (datatype == TLOGICAL) { ffpcll(fptr, colnum, firstrow, firstelem, nelem, (char *) array, status); } else if (datatype == TSTRING) { ffpcls(fptr, colnum, firstrow, firstelem, nelem, (char **) array, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffpcn( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of elements to write */ void *array, /* I - array of values that are written */ void *nulval, /* I - pointer to the null value */ int *status) /* IO - error status */ /* Write an array of values to a table column. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS column is not the same as the array being written). */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (nulval == NULL) /* null value not defined? */ { ffpcl(fptr, datatype, colnum, firstrow, firstelem, nelem, array, status); return(*status); } if (datatype == TBYTE) { ffpcnb(fptr, colnum, firstrow, firstelem, nelem, (unsigned char *) array, *(unsigned char *) nulval, status); } else if (datatype == TSBYTE) { ffpcnsb(fptr, colnum, firstrow, firstelem, nelem, (signed char *) array, *(signed char *) nulval, status); } else if (datatype == TUSHORT) { ffpcnui(fptr, colnum, firstrow, firstelem, nelem, (unsigned short *) array, *(unsigned short *) nulval, status); } else if (datatype == TSHORT) { ffpcni(fptr, colnum, firstrow, firstelem, nelem, (short *) array, *(unsigned short *) nulval, status); } else if (datatype == TUINT) { ffpcnuk(fptr, colnum, firstrow, firstelem, nelem, (unsigned int *) array, *(unsigned int *) nulval, status); } else if (datatype == TINT) { ffpcnk(fptr, colnum, firstrow, firstelem, nelem, (int *) array, *(int *) nulval, status); } else if (datatype == TULONG) { ffpcnuj(fptr, colnum, firstrow, firstelem, nelem, (unsigned long *) array, *(unsigned long *) nulval, status); } else if (datatype == TLONG) { ffpcnj(fptr, colnum, firstrow, firstelem, nelem, (long *) array, *(long *) nulval, status); } else if (datatype == TLONGLONG) { ffpcnjj(fptr, colnum, firstrow, firstelem, nelem, (LONGLONG *) array, *(LONGLONG *) nulval, status); } else if (datatype == TFLOAT) { ffpcne(fptr, colnum, firstrow, firstelem, nelem, (float *) array, *(float *) nulval, status); } else if (datatype == TDOUBLE) { ffpcnd(fptr, colnum, firstrow, firstelem, nelem, (double *) array, *(double *) nulval, status); } else if (datatype == TCOMPLEX) { ffpcne(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, (float *) array, *(float *) nulval, status); } else if (datatype == TDBLCOMPLEX) { ffpcnd(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, (double *) array, *(double *) nulval, status); } else if (datatype == TLOGICAL) { ffpcnl(fptr, colnum, firstrow, firstelem, nelem, (char *) array, *(char *) nulval, status); } else if (datatype == TSTRING) { ffpcns(fptr, colnum, firstrow, firstelem, nelem, (char **) array, (char *) nulval, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int fits_iter_set_by_name(iteratorCol *col, /* I - iterator col structure */ fitsfile *fptr, /* I - FITS file pointer */ char *colname, /* I - column name */ int datatype, /* I - column datatype */ int iotype) /* I - InputCol, InputOutputCol, or OutputCol */ /* set all the parameters for an iterator column, by column name */ { col->fptr = fptr; strcpy(col->colname, colname); col->colnum = 0; /* set column number undefined since name is given */ col->datatype = datatype; col->iotype = iotype; return(0); } /*--------------------------------------------------------------------------*/ int fits_iter_set_by_num(iteratorCol *col, /* I - iterator column structure */ fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ int datatype, /* I - column datatype */ int iotype) /* I - InputCol, InputOutputCol, or OutputCol */ /* set all the parameters for an iterator column, by column number */ { col->fptr = fptr; col->colnum = colnum; col->datatype = datatype; col->iotype = iotype; return(0); } /*--------------------------------------------------------------------------*/ int fits_iter_set_file(iteratorCol *col, /* I - iterator column structure */ fitsfile *fptr) /* I - FITS file pointer */ /* set iterator column parameter */ { col->fptr = fptr; return(0); } /*--------------------------------------------------------------------------*/ int fits_iter_set_colname(iteratorCol *col, /* I - iterator col structure */ char *colname) /* I - column name */ /* set iterator column parameter */ { strcpy(col->colname, colname); col->colnum = 0; /* set column number undefined since name is given */ return(0); } /*--------------------------------------------------------------------------*/ int fits_iter_set_colnum(iteratorCol *col, /* I - iterator column structure */ int colnum) /* I - column number */ /* set iterator column parameter */ { col->colnum = colnum; return(0); } /*--------------------------------------------------------------------------*/ int fits_iter_set_datatype(iteratorCol *col, /* I - iterator col structure */ int datatype) /* I - column datatype */ /* set iterator column parameter */ { col->datatype = datatype; return(0); } /*--------------------------------------------------------------------------*/ int fits_iter_set_iotype(iteratorCol *col, /* I - iterator column structure */ int iotype) /* I - InputCol, InputOutputCol, or OutputCol */ /* set iterator column parameter */ { col->iotype = iotype; return(0); } /*--------------------------------------------------------------------------*/ fitsfile * fits_iter_get_file(iteratorCol *col) /* I -iterator col structure */ /* get iterator column parameter */ { return(col->fptr); } /*--------------------------------------------------------------------------*/ char * fits_iter_get_colname(iteratorCol *col) /* I -iterator col structure */ /* get iterator column parameter */ { return(col->colname); } /*--------------------------------------------------------------------------*/ int fits_iter_get_colnum(iteratorCol *col) /* I - iterator column structure */ /* get iterator column parameter */ { return(col->colnum); } /*--------------------------------------------------------------------------*/ int fits_iter_get_datatype(iteratorCol *col) /* I - iterator col structure */ /* get iterator column parameter */ { return(col->datatype); } /*--------------------------------------------------------------------------*/ int fits_iter_get_iotype(iteratorCol *col) /* I - iterator column structure */ /* get iterator column parameter */ { return(col->iotype); } /*--------------------------------------------------------------------------*/ void * fits_iter_get_array(iteratorCol *col) /* I - iterator col structure */ /* get iterator column parameter */ { return(col->array); } /*--------------------------------------------------------------------------*/ long fits_iter_get_tlmin(iteratorCol *col) /* I - iterator column structure */ /* get iterator column parameter */ { return(col->tlmin); } /*--------------------------------------------------------------------------*/ long fits_iter_get_tlmax(iteratorCol *col) /* I - iterator column structure */ /* get iterator column parameter */ { return(col->tlmax); } /*--------------------------------------------------------------------------*/ long fits_iter_get_repeat(iteratorCol *col) /* I - iterator col structure */ /* get iterator column parameter */ { return(col->repeat); } /*--------------------------------------------------------------------------*/ char * fits_iter_get_tunit(iteratorCol *col) /* I - iterator col structure */ /* get iterator column parameter */ { return(col->tunit); } /*--------------------------------------------------------------------------*/ char * fits_iter_get_tdisp(iteratorCol *col) /* I -iterator col structure */ /* get iterator column parameter */ { return(col->tdisp); } /*--------------------------------------------------------------------------*/ int ffiter(int n_cols, iteratorCol *cols, long offset, long n_per_loop, int (*work_fn)(long total_n, long offset, long first_n, long n_values, int n_cols, iteratorCol *cols, void *userPointer), void *userPointer, int *status) /* The iterator function. This function will pass the specified columns from a FITS table or pixels from a FITS image to the user-supplied function. Depending on the size of the table or image, only a subset of the rows or pixels may be passed to the function on each call, in which case the function will be called multiple times until all the rows or pixels have been processed. */ { typedef struct /* structure to store the column null value */ { int nullsize; /* length of the null value, in bytes */ union { /* default null value for the column */ char *stringnull; unsigned char charnull; signed char scharnull; int intnull; short shortnull; long longnull; unsigned int uintnull; unsigned short ushortnull; unsigned long ulongnull; float floatnull; double doublenull; LONGLONG longlongnull; } null; } colNulls; void *dataptr, *defaultnull; colNulls *col; int ii, jj, tstatus, naxis, bitpix; int typecode, hdutype, jtype, type, anynul, nfiles, nbytes; long totaln, nleft, frow, felement, n_optimum, i_optimum, ntodo; long rept, rowrept, width, tnull, naxes[9] = {1,1,1,1,1,1,1,1,1}, groups; double zeros = 0.; char message[FLEN_ERRMSG], keyname[FLEN_KEYWORD], nullstr[FLEN_VALUE]; char **stringptr, *nullptr, *cptr; if (*status > 0) return(*status); if (n_cols < 0 || n_cols > 999 ) { ffpmsg("Illegal number of columms (ffiter)"); return(*status = BAD_COL_NUM); /* negative number of columns */ } col = calloc(n_cols, sizeof(colNulls) ); /* memory for the null values */ /*------------------------------------------------------------*/ /* Make sure column numbers and datatypes are in legal range */ /* and column numbers and datatypes are legal. */ /* Also fill in other parameters in the column structure. */ /*------------------------------------------------------------*/ ffghdt(cols[0].fptr, &hdutype, status); /* type of first HDU */ for (jj = 0; jj < n_cols; jj++) { /* check that output datatype code value is legal */ type = cols[jj].datatype; /* Allow variable length arrays for InputCol and InputOutputCol columns, but not for OutputCol columns. Variable length arrays have a negative type code value. */ if ((cols[jj].iotype != OutputCol) && (type<0)) { type*=-1; } if (type != 0 && type != TBYTE && type != TSBYTE && type != TLOGICAL && type != TSTRING && type != TSHORT && type != TINT && type != TLONG && type != TFLOAT && type != TDOUBLE && type != TCOMPLEX && type != TULONG && type != TUSHORT && type != TDBLCOMPLEX && type != TLONGLONG ) { if (type < 0) { sprintf(message, "Variable length array not allowed for output column number %d (ffiter)", jj + 1); } else { sprintf(message, "Illegal datatype for column number %d: %d (ffiter)", jj + 1, cols[jj].datatype); } ffpmsg(message); return(*status = BAD_DATATYPE); } /* initialize TLMINn, TLMAXn, column name, and display format */ cols[jj].tlmin = 0; cols[jj].tlmax = 0; cols[jj].tunit[0] = '\0'; cols[jj].tdisp[0] = '\0'; ffghdt(cols[jj].fptr, &jtype, status); /* get HDU type */ if (hdutype == IMAGE_HDU) { if (jtype != IMAGE_HDU) { sprintf(message, "File %d not positioned to an image extension (ffiter)", jj + 1); return(*status = NOT_IMAGE); } /* since this is an image, set a dummy column number = 0 */ cols[jj].colnum = 0; strcpy(cols[jj].colname, "IMAGE"); /* dummy name for images */ tstatus = 0; ffgkys(cols[jj].fptr, "BUNIT", cols[jj].tunit, 0, &tstatus); } else { if (jtype == IMAGE_HDU) { sprintf(message, "File %d not positioned to a table extension (ffiter)", jj + 1); return(*status = NOT_TABLE); } if (cols[jj].colnum < 1) { /* find the column number for the named column */ if (ffgcno(cols[jj].fptr, CASEINSEN, cols[jj].colname, &cols[jj].colnum, status) ) { sprintf(message, "Column '%s' not found for column number %d (ffiter)", cols[jj].colname, jj + 1); ffpmsg(message); return(*status); } } if (cols[jj].colnum < 1 || cols[jj].colnum > ((cols[jj].fptr)->Fptr)->tfield) { sprintf(message, "Column %d has illegal table position number: %d (ffiter)", jj + 1, cols[jj].colnum); ffpmsg(message); return(*status = BAD_COL_NUM); } /* look for column description keywords and update structure */ tstatus = 0; ffkeyn("TLMIN", cols[jj].colnum, keyname, &tstatus); ffgkyj(cols[jj].fptr, keyname, &cols[jj].tlmin, 0, &tstatus); tstatus = 0; ffkeyn("TLMAX", cols[jj].colnum, keyname, &tstatus); ffgkyj(cols[jj].fptr, keyname, &cols[jj].tlmax, 0, &tstatus); tstatus = 0; ffkeyn("TTYPE", cols[jj].colnum, keyname, &tstatus); ffgkys(cols[jj].fptr, keyname, cols[jj].colname, 0, &tstatus); if (tstatus) cols[jj].colname[0] = '\0'; tstatus = 0; ffkeyn("TUNIT", cols[jj].colnum, keyname, &tstatus); ffgkys(cols[jj].fptr, keyname, cols[jj].tunit, 0, &tstatus); tstatus = 0; ffkeyn("TDISP", cols[jj].colnum, keyname, &tstatus); ffgkys(cols[jj].fptr, keyname, cols[jj].tdisp, 0, &tstatus); } } /*-----------------------------------------------------------------*/ /* use the first file to set the total number of values to process */ /*-----------------------------------------------------------------*/ offset = maxvalue(offset, 0L); /* make sure offset is legal */ if (hdutype == IMAGE_HDU) /* get total number of pixels in the image */ { fits_get_img_dim(cols[0].fptr, &naxis, status); fits_get_img_size(cols[0].fptr, 9, naxes, status); tstatus = 0; ffgkyj(cols[0].fptr, "GROUPS", &groups, NULL, &tstatus); if (!tstatus && groups && (naxis > 1) && (naxes[0] == 0) ) { /* this is a random groups file, with NAXIS1 = 0 */ /* Use GCOUNT, the number of groups, as the first multiplier */ /* to calculate the total number of pixels in all the groups. */ ffgkyj(cols[0].fptr, "GCOUNT", &totaln, NULL, status); } else { totaln = naxes[0]; } for (ii = 1; ii < naxis; ii++) totaln *= naxes[ii]; frow = 1; felement = 1 + offset; } else /* get total number or rows in the table */ { ffgkyj(cols[0].fptr, "NAXIS2", &totaln, 0, status); frow = 1 + offset; felement = 1; } /* adjust total by the input starting offset value */ totaln -= offset; totaln = maxvalue(totaln, 0L); /* don't allow negative number */ /*------------------------------------------------------------------*/ /* Determine number of values to pass to work function on each loop */ /*------------------------------------------------------------------*/ if (n_per_loop == 0) { /* Determine optimum number of values for each iteration. */ /* Look at all the fitsfile pointers to determine the number */ /* of unique files. */ nfiles = 1; ffgrsz(cols[0].fptr, &n_optimum, status); for (jj = 1; jj < n_cols; jj++) { for (ii = 0; ii < jj; ii++) { if (cols[ii].fptr == cols[jj].fptr) break; } if (ii == jj) /* this is a new file */ { nfiles++; ffgrsz(cols[jj].fptr, &i_optimum, status); n_optimum = minvalue(n_optimum, i_optimum); } } n_optimum = n_optimum / nfiles; n_optimum = maxvalue(n_optimum, 1); } else if (n_per_loop < 0) /* must pass all the values at one time */ { n_optimum = totaln; } else /* calling routine specified how many values to pass at a time */ { n_optimum = minvalue(n_per_loop, totaln); } /*--------------------------------------*/ /* allocate work arrays for each column */ /* and determine the null pixel value */ /*--------------------------------------*/ for (jj = 0; jj < n_cols; jj++) { /* get image or column datatype and vector length */ if (hdutype == IMAGE_HDU) /* get total number of pixels in the image */ { fits_get_img_type(cols[jj].fptr, &bitpix, status); switch(bitpix) { case BYTE_IMG: typecode = TBYTE; break; case SHORT_IMG: typecode = TSHORT; break; case LONG_IMG: typecode = TLONG; break; case FLOAT_IMG: typecode = TFLOAT; break; case DOUBLE_IMG: typecode = TDOUBLE; break; case LONGLONG_IMG: typecode = TLONGLONG; break; } } else { if (ffgtcl(cols[jj].fptr, cols[jj].colnum, &typecode, &rept, &width, status) > 0) goto cleanup; if (typecode < 0) { /* if any variable length arrays, then the */ n_optimum = 1; /* must process the table 1 row at a time */ /* Allow variable length arrays for InputCol and InputOutputCol columns, but not for OutputCol columns. Variable length arrays have a negative type code value. */ if (cols[jj].iotype == OutputCol) { sprintf(message, "Variable length array not allowed for output column number %d (ffiter)", jj + 1); ffpmsg(message); return(*status = BAD_DATATYPE); } } } /* special case where sizeof(long) = 8: use TINT instead of TLONG */ if (abs(typecode) == TLONG && sizeof(long) == 8 && sizeof(int) == 4) { if(typecode<0) { typecode = -TINT; } else { typecode = TINT; } } /* Special case: interprete 'X' column as 'B' */ if (abs(typecode) == TBIT) { typecode = typecode / TBIT * TBYTE; rept = (rept + 7) / 8; } if (cols[jj].datatype == 0) /* output datatype not specified? */ { /* special case if sizeof(long) = 8: use TINT instead of TLONG */ if (abs(typecode) == TLONG && sizeof(long) == 8 && sizeof(int) == 4) cols[jj].datatype = TINT; else cols[jj].datatype = abs(typecode); } /* calc total number of elements to do on each iteration */ if (hdutype == IMAGE_HDU || cols[jj].datatype == TSTRING) { ntodo = n_optimum; cols[jj].repeat = 1; /* get the BLANK keyword value, if it exists */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { tstatus = 0; ffgkyj(cols[jj].fptr, "BLANK", &tnull, 0, &tstatus); if (tstatus) { tnull = 0L; /* no null values */ } } } else { if (typecode < 0) { /* get max size of the variable length vector; dont't trust the value given by the TFORM keyword */ rept = 1; for (ii = 0; ii < totaln; ii++) { ffgdes(cols[jj].fptr, cols[jj].colnum, frow + ii, &rowrept, NULL, status); rept = maxvalue(rept, rowrept); } } ntodo = n_optimum * rept; /* vector columns */ cols[jj].repeat = rept; /* get the TNULL keyword value, if it exists */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { tstatus = 0; if (hdutype == ASCII_TBL) /* TNULLn value is a string */ { ffkeyn("TNULL", cols[jj].colnum, keyname, &tstatus); ffgkys(cols[jj].fptr, keyname, nullstr, 0, &tstatus); if (tstatus) { tnull = 0L; /* keyword doesn't exist; no null values */ } else { cptr = nullstr; while (*cptr == ' ') /* skip over leading blanks */ cptr++; if (*cptr == '\0') /* TNULLn is all blanks? */ tnull = LONG_MIN; else { /* attempt to read TNULLn string as an integer */ ffc2ii(nullstr, &tnull, &tstatus); if (tstatus) tnull = LONG_MIN; /* choose smallest value */ } /* to represent nulls */ } } else /* Binary table; TNULLn value is an integer */ { ffkeyn("TNULL", cols[jj].colnum, keyname, &tstatus); ffgkyj(cols[jj].fptr, keyname, &tnull, 0, &tstatus); if (tstatus) { tnull = 0L; /* keyword doesn't exist; no null values */ } else if (tnull == 0) { /* worst possible case: a value of 0 is used to */ /* represent nulls in the FITS file. We have to */ /* use a non-zero null value here (zero is used to */ /* mean there are no null values in the array) so we */ /* will use the smallest possible integer instead. */ tnull = LONG_MIN; /* choose smallest possible value */ } } } } /* Note that the data array starts with 2nd element; */ /* 1st element of the array gives the null data value */ switch (cols[jj].datatype) { case TBYTE: cols[jj].array = calloc(ntodo + 1, sizeof(char)); col[jj].nullsize = sizeof(char); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { tnull = minvalue(tnull, 255); tnull = maxvalue(tnull, 0); col[jj].null.charnull = (unsigned char) tnull; } else { col[jj].null.charnull = (unsigned char) 255; /* use 255 as null */ } break; case TSBYTE: cols[jj].array = calloc(ntodo + 1, sizeof(char)); col[jj].nullsize = sizeof(char); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { tnull = minvalue(tnull, 127); tnull = maxvalue(tnull, -128); col[jj].null.scharnull = (signed char) tnull; } else { col[jj].null.scharnull = (signed char) -128; /* use -128 null */ } break; case TSHORT: cols[jj].array = calloc(ntodo + 1, sizeof(short)); col[jj].nullsize = sizeof(short); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { tnull = minvalue(tnull, SHRT_MAX); tnull = maxvalue(tnull, SHRT_MIN); col[jj].null.shortnull = (short) tnull; } else { col[jj].null.shortnull = SHRT_MIN; /* use minimum as null */ } break; case TUSHORT: cols[jj].array = calloc(ntodo + 1, sizeof(unsigned short)); col[jj].nullsize = sizeof(unsigned short); /* bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { tnull = minvalue(tnull, USHRT_MAX); tnull = maxvalue(tnull, 0); /* don't allow negative value */ col[jj].null.ushortnull = (unsigned short) tnull; } else { col[jj].null.ushortnull = USHRT_MAX; /* use maximum null */ } break; case TINT: cols[jj].array = calloc(sizeof(int), ntodo + 1); col[jj].nullsize = sizeof(int); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { tnull = minvalue(tnull, INT_MAX); tnull = maxvalue(tnull, INT_MIN); col[jj].null.intnull = (int) tnull; } else { col[jj].null.intnull = INT_MIN; /* use minimum as null */ } break; case TUINT: cols[jj].array = calloc(ntodo + 1, sizeof(unsigned int)); col[jj].nullsize = sizeof(unsigned int); /* bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { tnull = minvalue(tnull, INT32_MAX); tnull = maxvalue(tnull, 0); col[jj].null.uintnull = (unsigned int) tnull; } else { col[jj].null.intnull = UINT_MAX; /* use maximum as null */ } break; case TLONG: cols[jj].array = calloc(ntodo + 1, sizeof(long)); col[jj].nullsize = sizeof(long); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { col[jj].null.longnull = tnull; } else { col[jj].null.longnull = LONG_MIN; /* use minimum as null */ } break; case TULONG: cols[jj].array = calloc(ntodo + 1, sizeof(unsigned long)); col[jj].nullsize = sizeof(unsigned long); /* bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { if (tnull < 0) /* can't use a negative null value */ col[jj].null.ulongnull = LONG_MAX; else col[jj].null.ulongnull = (unsigned long) tnull; } else { col[jj].null.ulongnull = LONG_MAX; /* use maximum as null */ } break; case TFLOAT: cols[jj].array = calloc(ntodo + 1, sizeof(float)); col[jj].nullsize = sizeof(float); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { col[jj].null.floatnull = (float) tnull; } else { col[jj].null.floatnull = FLOATNULLVALUE; /* special value */ } break; case TCOMPLEX: cols[jj].array = calloc((ntodo * 2) + 1, sizeof(float)); col[jj].nullsize = sizeof(float); /* number of bytes per value */ col[jj].null.floatnull = FLOATNULLVALUE; /* special value */ break; case TDOUBLE: cols[jj].array = calloc(ntodo + 1, sizeof(double)); col[jj].nullsize = sizeof(double); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { col[jj].null.doublenull = (double) tnull; } else { col[jj].null.doublenull = DOUBLENULLVALUE; /* special value */ } break; case TDBLCOMPLEX: cols[jj].array = calloc((ntodo * 2) + 1, sizeof(double)); col[jj].nullsize = sizeof(double); /* number of bytes per value */ col[jj].null.doublenull = DOUBLENULLVALUE; /* special value */ break; case TSTRING: /* allocate array of pointers to all the strings */ if( hdutype==ASCII_TBL ) rept = width; stringptr = calloc((ntodo + 1) , sizeof(stringptr)); cols[jj].array = stringptr; col[jj].nullsize = rept + 1; /* number of bytes per value */ if (stringptr) { /* allocate string to store the null string value */ col[jj].null.stringnull = calloc(rept + 1, sizeof(char) ); col[jj].null.stringnull[1] = 1; /* to make sure string != 0 */ /* allocate big block for the array of table column strings */ stringptr[0] = calloc((ntodo + 1) * (rept + 1), sizeof(char) ); if (stringptr[0]) { for (ii = 1; ii <= ntodo; ii++) { /* pointer to each string */ stringptr[ii] = stringptr[ii - 1] + (rept + 1); } /* get the TNULL keyword value, if it exists */ tstatus = 0; ffkeyn("TNULL", cols[jj].colnum, keyname, &tstatus); ffgkys(cols[jj].fptr, keyname, nullstr, 0, &tstatus); if (!tstatus) strncat(col[jj].null.stringnull, nullstr, rept); } else { ffpmsg("ffiter failed to allocate memory arrays"); *status = MEMORY_ALLOCATION; /* memory allocation failed */ goto cleanup; } } break; case TLOGICAL: cols[jj].array = calloc(ntodo + 1, sizeof(char)); col[jj].nullsize = sizeof(char); /* number of bytes per value */ /* use value = 2 to flag null values in logical columns */ col[jj].null.charnull = 2; break; case TLONGLONG: cols[jj].array = calloc(ntodo + 1, sizeof(LONGLONG)); col[jj].nullsize = sizeof(LONGLONG); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG || abs(typecode) == TLONGLONG) { col[jj].null.longlongnull = tnull; } else { col[jj].null.longlongnull = LONGLONG_MIN; /* use minimum as null */ } break; default: sprintf(message, "Column %d datatype currently not supported: %d: (ffiter)", jj + 1, cols[jj].datatype); ffpmsg(message); *status = BAD_DATATYPE; goto cleanup; } /* end of switch block */ /* check that all the arrays were allocated successfully */ if (!cols[jj].array) { ffpmsg("ffiter failed to allocate memory arrays"); *status = MEMORY_ALLOCATION; /* memory allocation failed */ goto cleanup; } } /*--------------------------------------------------*/ /* main loop while there are values left to process */ /*--------------------------------------------------*/ nleft = totaln; while (nleft) { ntodo = minvalue(nleft, n_optimum); /* no. of values for this loop */ /* read input columns from FITS file(s) */ for (jj = 0; jj < n_cols; jj++) { if (cols[jj].iotype != OutputCol) { if (cols[jj].datatype == TSTRING) { stringptr = cols[jj].array; dataptr = stringptr + 1; defaultnull = col[jj].null.stringnull; /* ptr to the null value */ } else { dataptr = (char *) cols[jj].array + col[jj].nullsize; defaultnull = &col[jj].null.charnull; /* ptr to the null value */ } if (hdutype == IMAGE_HDU) { if (ffgpv(cols[jj].fptr, cols[jj].datatype, felement, cols[jj].repeat * ntodo, defaultnull, dataptr, &anynul, status) > 0) { break; } } else { if (ffgtcl(cols[jj].fptr, cols[jj].colnum, &typecode, &rept,&width, status) > 0) goto cleanup; if (typecode<0) { /* get size of the variable length vector */ ffgdes(cols[jj].fptr, cols[jj].colnum, frow,&cols[jj].repeat, NULL,status); } if (ffgcv(cols[jj].fptr, cols[jj].datatype, cols[jj].colnum, frow, felement, cols[jj].repeat * ntodo, defaultnull, dataptr, &anynul, status) > 0) { break; } } /* copy the appropriate null value into first array element */ if (anynul) /* are there any nulls in the data? */ { if (cols[jj].datatype == TSTRING) { stringptr = cols[jj].array; memcpy(*stringptr, col[jj].null.stringnull, col[jj].nullsize); } else { memcpy(cols[jj].array, defaultnull, col[jj].nullsize); } } else /* no null values so copy zero into first element */ { if (cols[jj].datatype == TSTRING) { stringptr = cols[jj].array; memset(*stringptr, 0, col[jj].nullsize); } else { memset(cols[jj].array, 0, col[jj].nullsize); } } } } if (*status > 0) break; /* looks like an error occurred; quit immediately */ /* call work function */ if (hdutype == IMAGE_HDU) *status = work_fn(totaln, offset, felement, ntodo, n_cols, cols, userPointer); else *status = work_fn(totaln, offset, frow, ntodo, n_cols, cols, userPointer); if (*status > 0 || *status < -1 ) break; /* looks like an error occurred; quit immediately */ /* write output columns before quiting if status = -1 */ tstatus = 0; for (jj = 0; jj < n_cols; jj++) { if (cols[jj].iotype != InputCol) { if (cols[jj].datatype == TSTRING) { stringptr = cols[jj].array; dataptr = stringptr + 1; nullptr = *stringptr; nbytes = 2; } else { dataptr = (char *) cols[jj].array + col[jj].nullsize; nullptr = (char *) cols[jj].array; nbytes = col[jj].nullsize; } if (memcmp(nullptr, &zeros, nbytes) ) { /* null value flag not zero; must check for and write nulls */ if (hdutype == IMAGE_HDU) { if (ffppn(cols[jj].fptr, cols[jj].datatype, felement, cols[jj].repeat * ntodo, dataptr, nullptr, &tstatus) > 0) break; } else { if (ffgtcl(cols[jj].fptr, cols[jj].colnum, &typecode, &rept,&width, status) > 0) goto cleanup; if (typecode<0) /* variable length array colum */ { ffgdes(cols[jj].fptr, cols[jj].colnum, frow,&cols[jj].repeat, NULL,status); } if (ffpcn(cols[jj].fptr, cols[jj].datatype, cols[jj].colnum, frow, felement, cols[jj].repeat * ntodo, dataptr, nullptr, &tstatus) > 0) break; } } else { /* no null values; just write the array */ if (hdutype == IMAGE_HDU) { if (ffppr(cols[jj].fptr, cols[jj].datatype, felement, cols[jj].repeat * ntodo, dataptr, &tstatus) > 0) break; } else { if (ffgtcl(cols[jj].fptr, cols[jj].colnum, &typecode, &rept,&width, status) > 0) goto cleanup; if (typecode<0) /* variable length array column */ { ffgdes(cols[jj].fptr, cols[jj].colnum, frow,&cols[jj].repeat, NULL,status); } if (ffpcl(cols[jj].fptr, cols[jj].datatype, cols[jj].colnum, frow, felement, cols[jj].repeat * ntodo, dataptr, &tstatus) > 0) break; } } } } if (*status == 0) *status = tstatus; /* propagate any error status from the writes */ if (*status) break; /* exit on any error */ nleft -= ntodo; if (hdutype == IMAGE_HDU) felement += ntodo; else frow += ntodo; } cleanup: /*----------------------------------*/ /* free work arrays for the columns */ /*----------------------------------*/ for (jj = 0; jj < n_cols; jj++) { if (cols[jj].datatype == TSTRING) { if (cols[jj].array) { stringptr = cols[jj].array; free(*stringptr); /* free the block of strings */ free(col[jj].null.stringnull); /* free the null string */ } } free(cols[jj].array); /* memory for the array of values from the col */ } free(col); /* the structure containing the null values */ return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/putcolb.c000066400000000000000000001070531215713201500222520ustar00rootroot00000000000000/* This file, putcolb.c, contains routines that write data elements to */ /* a FITS image or table with char (byte) datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpprb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned char *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; unsigned char nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TBYTE, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpclb(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned char *array, /* I - array of values that are written */ unsigned char nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; unsigned char nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TBYTE, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnb(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2db(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned char *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3db(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3db(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned char *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; LONGLONG nfits, narray; long fpixel[3]= {1,1,1}, lpixel[3]; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TBYTE, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpclb(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpclb(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ unsigned char *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TBYTE, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpclb(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ unsigned char *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpclb(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpclb( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned char *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype, writeraw; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /* if there is no scaling then we can simply write the raw data bytes into the FITS file if the datatype of the FITS column is the same as the input values. Otherwise, we must convert the raw values into the scaled and/or machine dependent format in a temporary buffer that has been allocated for this purpose. */ if (scale == 1. && zero == 0. && tcode == TBYTE) { writeraw = 1; maxelem = (int) nelem; /* we can write the entire array at one time */ } else writeraw = 0; /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TBYTE): if (writeraw) { /* write raw input bytes without conversion */ ffpi1b(fptr, ntodo, incre, &array[next], status); } else { /* convert the raw data before writing to FITS file */ ffi1fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); } break; case (TLONGLONG): ffi1fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TSHORT): ffi1fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TLONG): ffi1fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TFLOAT): ffi1fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffi1fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (strchr(tform,'A')) { /* write raw input bytes without conversion */ /* This case is a hack to let users write a stream */ /* of bytes directly to the 'A' format column */ if (incre == twidth) ffpbyt(fptr, ntodo, &array[next], status); else ffpbytoff(fptr, twidth, ntodo/twidth, incre - twidth, &array[next], status); break; } else if (cform[1] != 's') /* "%s" format is a string */ { ffi1fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpclb).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnb( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned char *array, /* I - array of values to write */ unsigned char nulvalue, /* I - flag for undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpclb(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood + 1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpclb(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad + 1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpclb(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffpextn( fitsfile *fptr, /* I - FITS file pointer */ LONGLONG offset, /* I - byte offset from start of extension data */ LONGLONG nelem, /* I - number of elements to write */ void *buffer, /* I - stream of bytes to write */ int *status) /* IO - error status */ /* Write a stream of bytes to the current FITS HDU. This primative routine is mainly for writing non-standard "conforming" extensions and should not be used for standard IMAGE, TABLE or BINTABLE extensions. */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); /* move to write position */ ffmbyt(fptr, (fptr->Fptr)->datastart+ offset, IGNORE_EOF, status); /* write the buffer */ ffpbyt(fptr, nelem, buffer, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffi1fi1(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { memcpy(output, input, ntodo); /* just copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ( ((double) input[ii]) - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi1fi2(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; /* just copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (((double) input[ii]) - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi1fi4(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (INT32BIT) input[ii]; /* copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (((double) input[ii]) - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi1fi8(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi1fr4(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) (( ( (double) input[ii] ) - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffi1fr8(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = ( ( (double) input[ii] ) - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffi1fstr(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ((double) input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/putcold.c000066400000000000000000001114631215713201500222540ustar00rootroot00000000000000/* This file, putcold.c, contains routines that write data elements to */ /* a FITS image or table, with double datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpprd( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ double *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; double nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TDOUBLE, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcld(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnd( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ double *array, /* I - array of values that are written */ double nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; double nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TDOUBLE, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnd(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2dd(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ double *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3dd(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3dd(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ double *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TDOUBLE, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpcld(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpcld(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssd(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ double *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TDOUBLE, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpcld(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpd( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ double *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpcld(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcld( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ double *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype, writeraw; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /* if there is no scaling and the native machine format is not byteswapped, then we can simply write the raw data bytes into the FITS file if the datatype of the FITS column is the same as the input values. Otherwise, we must convert the raw values into the scaled and/or machine dependent format in a temporary buffer that has been allocated for this purpose. */ if (scale == 1. && zero == 0. && MACHINE == NATIVE && tcode == TDOUBLE) { writeraw = 1; maxelem = (int) nelem; /* we can write the entire array at one time */ } else writeraw = 0; /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TDOUBLE): if (writeraw) { /* write raw input bytes without conversion */ ffpr8b(fptr, ntodo, incre, &array[next], status); } else { /* convert the raw data before writing to FITS file */ ffr8fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); } break; case (TLONGLONG): ffr8fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffr8fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffr8fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TLONG): ffr8fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TFLOAT): ffr8fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffr8fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpcld).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpclm( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ double *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of double complex values to a column in the current FITS HDU. Each complex number if interpreted as a pair of float values. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column if necessary, but normally complex values should only be written to a binary table with TFORMn = 'rM' where r is an optional repeat count. The TSCALn and TZERO keywords should not be used with complex numbers because mathmatically the scaling should only be applied to the real (first) component of the complex value. */ { /* simply multiply the number of elements by 2, and call ffpcld */ ffpcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnd( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ double *array, /* I - array of values to write */ double nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ if (abs(tcode) >= TCOMPLEX) { /* treat complex columns as pairs of numbers */ repeat *= 2; } /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpcld(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ /* call ffpcluc, not ffpclu, in case we are writing to a complex ('C') binary table column */ if (ffpcluc(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpcld(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpcld(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpcluc(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr8fi1(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr8fi2(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr8fi4(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (input[ii] > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else output[ii] = (INT32BIT) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr8fi8(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (input[ii] > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr8fr4(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffr8fr8(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { memcpy(output, input, ntodo * sizeof(double) ); /* copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffr8fstr(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/putcole.c000066400000000000000000001125471215713201500222610ustar00rootroot00000000000000/* This file, putcole.c, contains routines that write data elements to */ /* a FITS image or table, with float datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffppre( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ float *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine cannot be called directly by users to write to large arrays with > 2**31 pixels (although CFITSIO can do so by passing the firstelem thru a LONGLONG sized global variable) */ { long row; float nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TFLOAT, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcle(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppne( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ float *array, /* I - array of values that are written */ float nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. This routine cannot be called directly by users to write to large arrays with > 2**31 pixels (although CFITSIO can do so by passing the firstelem thru a LONGLONG sized global variable) */ { long row; float nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TFLOAT, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcne(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2de(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ float *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine does not support writing to large images with more than 2**31 pixels. */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3de(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3de(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ float *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine does not support writing to large images with more than 2**31 pixels. */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TFLOAT, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpcle(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpcle(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpsse(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ float *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TFLOAT, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpcle(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpe( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ float *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpcle(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcle( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ float *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype, writeraw; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /* if there is no scaling and the native machine format is not byteswapped then we can simply write the raw data bytes into the FITS file if the datatype of the FITS column is the same as the input values. Otherwise, we must convert the raw values into the scaled and/or machine dependent format in a temporary buffer that has been allocated for this purpose. */ if (scale == 1. && zero == 0. && MACHINE == NATIVE && tcode == TFLOAT) { writeraw = 1; maxelem = (int) nelem; /* we can write the entire array at one time */ } else writeraw = 0; /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TFLOAT): if (writeraw) { /* write raw input bytes without conversion */ ffpr4b(fptr, ntodo, incre, &array[next], status); } else { /* convert the raw data before writing to FITS file */ ffr4fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); } break; case (TLONGLONG): ffr4fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffr4fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffr4fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TLONG): ffr4fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TDOUBLE): ffr4fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffr4fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpcle).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpclc( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ float *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of complex values to a column in the current FITS HDU. Each complex number if interpreted as a pair of float values. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column if necessary, but normally complex values should only be written to a binary table with TFORMn = 'rC' where r is an optional repeat count. The TSCALn and TZERO keywords should not be used with complex numbers because mathmatically the scaling should only be applied to the real (first) component of the complex value. */ { /* simply multiply the number of elements by 2, and call ffpcle */ ffpcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcne( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ float *array, /* I - array of values to write */ float nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ if (abs(tcode) >= TCOMPLEX) { /* treat complex columns as pairs of numbers */ repeat *= 2; } /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpcle(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ /* call ffpcluc, not ffpclu, in case we are writing to a complex ('C') binary table column */ if (ffpcluc(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpcle(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpcle(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpcluc(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr4fi1(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr4fi2(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr4fi4(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (input[ii] > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else output[ii] = (INT32BIT) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr4fi8(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (input[ii] > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (long) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr4fr4(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { memcpy(output, input, ntodo * sizeof(float) ); /* copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffr4fr8(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffr4fstr(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/putcoli.c000066400000000000000000001034101215713201500222520ustar00rootroot00000000000000/* This file, putcoli.c, contains routines that write data elements to */ /* a FITS image or table, with short datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffppri( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ short *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; short nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TSHORT, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcli(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppni( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ short *array, /* I - array of values that are written */ short nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; short nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TSHORT, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcni(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2di(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ short *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3di(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3di(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ short *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TSHORT, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpcli(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpcli(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssi(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ short *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TSHORT, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpcli(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpi( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ short *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpcli(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcli( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ short *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype, writeraw; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /* if there is no scaling and the native machine format is not byteswapped, then we can simply write the raw data bytes into the FITS file if the datatype of the FITS column is the same as the input values. Otherwise, we must convert the raw values into the scaled and/or machine dependent format in a temporary buffer that has been allocated for this purpose. */ if (scale == 1. && zero == 0. && MACHINE == NATIVE && tcode == TSHORT) { writeraw = 1; maxelem = (int) nelem; /* we can write the entire array at one time */ } else writeraw = 0; /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TSHORT): if (writeraw) { /* write raw input bytes without conversion */ ffpi2b(fptr, ntodo, incre, &array[next], status); } else { /* convert the raw data before writing to FITS file */ ffi2fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); } break; case (TLONGLONG): ffi2fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffi2fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TLONG): ffi2fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TFLOAT): ffi2fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffi2fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffi2fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpcli).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcni( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ short *array, /* I - array of values to write */ short nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpcli(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpcli(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpcli(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi2fi1(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi2fi2(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { memcpy(output, input, ntodo * sizeof(short) ); } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi2fi4(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (INT32BIT) input[ii]; /* just copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi2fi8(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi2fr4(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffi2fr8(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffi2fstr(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/putcolj.c000066400000000000000000002100231215713201500222520ustar00rootroot00000000000000/* This file, putcolj.c, contains routines that write data elements to */ /* a FITS image or table, with long datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpprj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ long *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; long nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TLONG, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpclj(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ long *array, /* I - array of values that are written */ long nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; long nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TLONG, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnj(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2dj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ long *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3dj(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3dj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ long *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TLONG, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpclj(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpclj(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ long *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TLONG, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpclj(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ long *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpclj(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpclj( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ long *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype, writeraw; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /* if there is no scaling and the native machine format is not byteswapped then we can simply write the raw data bytes into the FITS file if the datatype of the FITS column is the same as the input values. Otherwise we must convert the raw values into the scaled and/or machine dependent format in a temporary buffer that has been allocated for this purpose. */ if (scale == 1. && zero == 0. && MACHINE == NATIVE && tcode == TLONG && LONGSIZE == 32) { writeraw = 1; maxelem = (int) nelem; /* we can write the entire array at one time */ } else writeraw = 0; /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TLONG): if (writeraw) { /* write raw input bytes without conversion */ ffpi4b(fptr, ntodo, incre, (INT32BIT *) &array[next], status); } else { /* convert the raw data before writing to FITS file */ ffi4fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); } break; case (TLONGLONG): fflongfi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffi4fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffi4fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TFLOAT): ffi4fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffi4fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffi4fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpclj).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnj( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ long *array, /* I - array of values to write */ long nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpclj(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood + 1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpclj(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpclj(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi4fi1(long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi4fi2(long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < SHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi4fi4(long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (INT32BIT) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int fflongfi8(long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi4fr4(long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffi4fr8(long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffi4fstr(long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } /* ======================================================================== */ /* the following routines support the 'long long' data type */ /* ======================================================================== */ /*--------------------------------------------------------------------------*/ int ffpprjj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ LONGLONG *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } row=maxvalue(1,group); ffpcljj(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnjj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ LONGLONG *array, /* I - array of values that are written */ LONGLONG nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } row=maxvalue(1,group); ffpcnjj(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2djj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3djj(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3djj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ LONGLONG *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpcljj(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpcljj(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssjj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ LONGLONG *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpcljj(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpjj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ LONGLONG *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpcljj(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcljj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ LONGLONG *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype, writeraw; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /* if there is no scaling and the native machine format is not byteswapped then we can simply write the raw data bytes into the FITS file if the datatype of the FITS column is the same as the input values. Otherwise we must convert the raw values into the scaled and/or machine dependent format in a temporary buffer that has been allocated for this purpose. */ if (scale == 1. && zero == 0. && MACHINE == NATIVE && tcode == TLONGLONG) { writeraw = 1; maxelem = (int) nelem; /* we can write the entire array at one time */ } else writeraw = 0; /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TLONGLONG): if (writeraw) { /* write raw input bytes without conversion */ ffpi8b(fptr, ntodo, incre, (long *) &array[next], status); } else { /* convert the raw data before writing to FITS file */ ffi8fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); } break; case (TLONG): ffi8fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TBYTE): ffi8fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffi8fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TFLOAT): ffi8fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffi8fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffi8fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpclj).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnjj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ LONGLONG *array, /* I - array of values to write */ LONGLONG nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpcljj(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpcljj(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpcljj(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi8fi1(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi8fi2(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < SHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi8fi4(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < INT32_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (input[ii] > INT32_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else output[ii] = (INT32BIT) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi8fi8(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi8fr4(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffi8fr8(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffi8fstr(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/putcolk.c000066400000000000000000001052561215713201500222660ustar00rootroot00000000000000/* This file, putcolk.c, contains routines that write data elements to */ /* a FITS image or table, with 'int' datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpprk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ int *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; int nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TINT, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpclk(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ int *array, /* I - array of values that are written */ int nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; int nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TINT, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnk(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2dk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ int *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3dk(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3dk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ int *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TINT, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpclk(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpclk(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ int *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TINT, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpclk(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ int *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpclk(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpclk( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ int *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype, writeraw; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* call the 'short' or 'long' version of this routine, if possible */ if (sizeof(int) == sizeof(short)) ffpcli(fptr, colnum, firstrow, firstelem, nelem, (short *) array, status); else if (sizeof(int) == sizeof(long)) ffpclj(fptr, colnum, firstrow, firstelem, nelem, (long *) array, status); else { /* This is a special case: sizeof(int) is not equal to sizeof(short) or sizeof(long). This occurs on Alpha OSF systems where short = 2 bytes, int = 4 bytes, and long = 8 bytes. */ buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /* if there is no scaling and the native machine format is not byteswapped then we can simply write the raw data bytes into the FITS file if the datatype of the FITS column is the same as the input values. Otherwise we must convert the raw values into the scaled and/or machine dependent format in a temporary buffer that has been allocated for this purpose. */ if (scale == 1. && zero == 0. && MACHINE == NATIVE && tcode == TLONG) { writeraw = 1; maxelem = (int) nelem; /* we can write the entire array at one time */ } else writeraw = 0; /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TLONG): if (writeraw) { /* write raw input bytes without conversion */ ffpi4b(fptr, ntodo, incre, (INT32BIT *) &array[next], status); } else { /* convert the raw data before writing to FITS file */ ffintfi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); } break; case (TLONGLONG): ffintfi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffintfi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffintfi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TFLOAT): ffintfr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffintfr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffintfstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpclk).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } } /* end of Dec ALPHA special case */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnk( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ int *array, /* I - array of values to write */ int nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpclk(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpclk(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpclk(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffintfi1(int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffintfi2(int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < SHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffintfi4(int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { memcpy(output, input, ntodo * sizeof(int) ); } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffintfi8(int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffintfr4(int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffintfr8(int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffintfstr(int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/putcoll.c000066400000000000000000000326411215713201500222640ustar00rootroot00000000000000/* This file, putcoll.c, contains routines that write data elements to */ /* a FITS image or table, with logical datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpcll( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ char *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of logical values to a column in the current FITS HDU. */ { int tcode, maxelem, hdutype; long twidth, incre; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], ctrue = 'T', cfalse = 'F'; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ if (*status > 0) /* inherit input status value if > 0 */ return(*status); /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode != TLOGICAL) return(*status = NOT_LOGICAL_COL); /*---------------------------------------------------------------------*/ /* Now write the logical values one at a time to the FITS column. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { wrtptr = startpos + (rowlen * rownum) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ if (array[next]) ffpbyt(fptr, 1, &ctrue, status); else ffpbyt(fptr, 1, &cfalse, status); if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing element %.0f of input array of logicals (ffpcll).", (double) (next+1)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain--; if (remain) { next++; elemnum++; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnl( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ char *array, /* I - array of values to write */ char nulvalue, /* I - array flagging undefined pixels if true */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels flagged as null will be replaced by the appropriate null value in the output FITS file. */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* first write the whole input vector, then go back and fill in the nulls */ if (ffpcll(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) return(*status); /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ /* good values have already been written if (ffpcll(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) return(*status); */ ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ /* these have already been written ffpcll(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); */ } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpclx( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG frow, /* I - first row to write (1 = 1st row) */ long fbit, /* I - first bit to write (1 = 1st) */ long nbit, /* I - number of bits to write */ char *larray, /* I - array of logicals corresponding to bits */ int *status) /* IO - error status */ /* write an array of logical values to a specified bit or byte column of the binary table. If larray is TRUE, then the corresponding bit is set to 1, otherwise it is set to 0. The binary table column being written to must have datatype 'B' or 'X'. */ { LONGLONG offset, bstart, repeat, rowlen, elemnum, rstart, estart, tnull; long fbyte, lbyte, nbyte, bitloc, ndone; long ii, twidth, incre; int tcode, descrp, maxelem, hdutype; double dummyd; char tform[12], snull[12]; unsigned char cbuff; static unsigned char onbit[8] = {128, 64, 32, 16, 8, 4, 2, 1}; static unsigned char offbit[8] = {127, 191, 223, 239, 247, 251, 253, 254}; tcolumn *colptr; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check input parameters */ if (nbit < 1) return(*status); else if (frow < 1) return(*status = BAD_ROW_NUM); else if (fbit < 1) return(*status = BAD_ELEM_NUM); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); fbyte = (fbit + 7) / 8; lbyte = (fbit + nbit + 6) / 8; nbyte = lbyte - fbyte +1; /* Save the current heapsize; ffgcprll will increment the value if */ /* we are writing to a variable length column. */ offset = (fptr->Fptr)->heapsize; /* call ffgcprll in case we are writing beyond the current end of */ /* the table; it will allocate more space and shift any following */ /* HDU's. Otherwise, we have little use for most of the returned */ /* parameters, therefore just use dummy parameters. */ if (ffgcprll( fptr, colnum, frow, fbyte, nbyte, 1, &dummyd, &dummyd, tform, &twidth, &tcode, &maxelem, &bstart, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); bitloc = fbit - 1 - ((fbit - 1) / 8 * 8); ndone = 0; rstart = frow - 1; estart = fbyte - 1; colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (abs(tcode) > TBYTE) return(*status = NOT_LOGICAL_COL); /* not correct datatype column */ if (tcode > 0) { descrp = FALSE; /* not a variable length descriptor column */ repeat = colptr->trepeat; if (tcode == TBIT) repeat = (repeat + 7) / 8; /* convert from bits to bytes */ if (fbyte > repeat) return(*status = BAD_ELEM_NUM); /* calc the i/o pointer location to start of sequence of pixels */ bstart = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * rstart) + colptr->tbcol + estart; } else { descrp = TRUE; /* a variable length descriptor column */ /* only bit arrays (tform = 'X') are supported for variable */ /* length arrays. REPEAT is the number of BITS in the array. */ repeat = fbit + nbit -1; /* write the number of elements and the starting offset. */ /* Note: ffgcprll previous wrote the descripter, but with the */ /* wrong repeat value (gave bytes instead of bits). */ if (tcode == -TBIT) ffpdes(fptr, colnum, frow, (long) repeat, offset, status); /* Calc the i/o pointer location to start of sequence of pixels. */ /* ffgcprll has already calculated a value for bstart that */ /* points to the first element of the vector; we just have to */ /* increment it to point to the first element we want to write to. */ /* Note: ffgcprll also already updated the size of the heap, so we */ /* don't have to do that again here. */ bstart += estart; } /* move the i/o pointer to the start of the pixel sequence */ ffmbyt(fptr, bstart, IGNORE_EOF, status); /* read the next byte (we may only be modifying some of the bits) */ while (1) { if (ffgbyt(fptr, 1, &cbuff, status) == END_OF_FILE) { /* hit end of file trying to read the byte, so just set byte = 0 */ *status = 0; cbuff = 0; } /* move back, to be able to overwrite the byte */ ffmbyt(fptr, bstart, IGNORE_EOF, status); for (ii = bitloc; (ii < 8) && (ndone < nbit); ii++, ndone++) { if(larray[ndone]) cbuff = cbuff | onbit[ii]; else cbuff = cbuff & offbit[ii]; } ffpbyt(fptr, 1, &cbuff, status); /* write the modified byte */ if (ndone == nbit) /* finished all the bits */ return(*status); /* not done, so get the next byte */ bstart++; if (!descrp) { estart++; if (estart == repeat) { /* move the i/o pointer to the next row of pixels */ estart = 0; rstart = rstart + 1; bstart = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * rstart) + colptr->tbcol; ffmbyt(fptr, bstart, IGNORE_EOF, status); } } bitloc = 0; } } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/putcols.c000066400000000000000000000245061215713201500222740ustar00rootroot00000000000000/* This file, putcols.c, contains routines that write data elements to */ /* a FITS image or table, of type character string. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpcls( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of strings to write */ char **array, /* I - array of pointers to strings */ int *status) /* IO - error status */ /* Write an array of string values to a column in the current FITS HDU. */ { int tcode, maxelem, hdutype, nchar; long twidth, incre; long ii, jj, ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], *blanks; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ tcolumn *colptr; double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ char *buffer, *arrayptr; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (colnum < 1 || colnum > (fptr->Fptr)->tfield) { sprintf(message, "Specified column number is out of range: %d", colnum); ffpmsg(message); return(*status = BAD_COL_NUM); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode == -TSTRING) /* variable length column in a binary table? */ { /* only write a single string; ignore value of firstelem */ nchar = maxvalue(1,strlen(array[0])); /* will write at least 1 char */ /* even if input string is null */ if (ffgcprll( fptr, colnum, firstrow, 1, nchar, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); /* simply move to write position, then write the string */ ffmbyt(fptr, startpos, IGNORE_EOF, status); ffpbyt(fptr, nchar, array[0], status); if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing to variable length string column (ffpcls)."); ffpmsg(message); } return(*status); } else if (tcode == TSTRING) { if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); blanks = (char *) malloc(twidth); /* string for blank fill values */ if (!blanks) { ffpmsg("Could not allocate memory for string (ffpcls)"); return(*status = ARRAY_TOO_BIG); } for (ii = 0; ii < twidth; ii++) blanks[ii] = ' '; /* fill string with blanks */ remain = nelem; /* remaining number of values to write */ } else return(*status = NOT_ASCII_COL); /*-------------------------------------------------------*/ /* Now write the strings to the FITS column. */ /*-------------------------------------------------------*/ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process at one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + (rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ buffer = (char *) cbuff; /* copy the user's strings into the buffer */ for (ii = 0; ii < ntodo; ii++) { arrayptr = array[next]; for (jj = 0; jj < twidth; jj++) /* copy the string, char by char */ { if (*arrayptr) { *buffer = *arrayptr; buffer++; arrayptr++; } else break; } for (;jj < twidth; jj++) /* fill field with blanks, if needed */ { *buffer = ' '; buffer++; } next++; } /* write the buffer full of strings to the FITS file */ if (incre == twidth) ffpbyt(fptr, ntodo * twidth, cbuff, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, cbuff, status); if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpcls).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); if (blanks) free(blanks); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ if (blanks) free(blanks); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcns( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ char **array, /* I - array of values to write */ char *nulvalue, /* I - string representing a null value */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels flagged as null will be replaced by the appropriate null value in the output FITS file. */ { long repeat, width, ngood = 0, nbad = 0, ii; LONGLONG first, fstelm, fstrow; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } /* get the vector repeat length of the column */ ffgtcl(fptr, colnum, NULL, &repeat, &width, status); if ((fptr->Fptr)->hdutype == BINARY_TBL) repeat = repeat / width; /* convert from chars to unit strings */ /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (strcmp(nulvalue, array[ii])) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpcls(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) return(*status); ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpcls(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/putcolsb.c000066400000000000000000001035671215713201500224430ustar00rootroot00000000000000/* This file, putcolsb.c, contains routines that write data elements to */ /* a FITS image or table with signed char (signed byte) datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpprsb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ signed char *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; signed char nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TSBYTE, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpclsb(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnsb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ signed char *array, /* I - array of values that are written */ signed char nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; signed char nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TSBYTE, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnsb(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2dsb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ signed char *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3dsb(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3dsb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ signed char *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TSBYTE, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpclsb(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpclsb(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpsssb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ signed char *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TSBYTE, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpclsb(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpsb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ signed char *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpclsb(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpclsb( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ signed char *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TBYTE): /* convert the raw data before writing to FITS file */ ffs1fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TLONGLONG): ffs1fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TSHORT): ffs1fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TLONG): ffs1fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TFLOAT): ffs1fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffs1fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (strchr(tform,'A')) { /* write raw input bytes without conversion */ /* This case is a hack to let users write a stream */ /* of bytes directly to the 'A' format column */ if (incre == twidth) ffpbyt(fptr, ntodo, &array[next], status); else ffpbytoff(fptr, twidth, ntodo/twidth, incre - twidth, &array[next], status); break; } else if (cform[1] != 's') /* "%s" format is a string */ { ffs1fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpclsb).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnsb( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ signed char *array, /* I - array of values to write */ signed char nulvalue, /* I - flag for undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpclsb(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood + 1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpclsb(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad + 1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpclsb(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffs1fi1(signed char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == -128.) { /* Instead of adding 128, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) output[ii] = ( *(unsigned char *) &input[ii] ) ^ 0x80; } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ( ((double) input[ii]) - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffs1fi2(signed char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; /* just copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (((double) input[ii]) - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffs1fi4(signed char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (INT32BIT) input[ii]; /* copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (((double) input[ii]) - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffs1fi8(signed char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffs1fr4(signed char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) (( ( (double) input[ii] ) - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffs1fr8(signed char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = ( ( (double) input[ii] ) - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffs1fstr(signed char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ((double) input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/putcolu.c000066400000000000000000000517711215713201500223020ustar00rootroot00000000000000/* This file, putcolu.c, contains routines that write data elements to */ /* a FITS image or table. Writes null values. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffppru( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ int *status) /* IO - error status */ /* Write null values to the primary array. */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } row=maxvalue(1,group); ffpclu(fptr, 2, row, firstelem, nelem, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpprn( fitsfile *fptr, /* I - FITS file pointer */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ int *status) /* IO - error status */ /* Write null values to the primary array. (Doesn't support groups). */ { long row = 1; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } ffpclu(fptr, 2, row, firstelem, nelem, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpclu( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelempar, /* I - number of values to write */ int *status) /* IO - error status */ /* Set elements of a table column to the appropriate null value for the column The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. This routine support COMPLEX and DOUBLE COMPLEX binary table columns, and sets both the real and imaginary components of the element to a NaN. */ { int tcode, maxelem, hdutype, writemode = 2, leng; short i2null; INT32BIT i4null; long twidth, incre; long ii; LONGLONG largeelem, nelem, tnull, i8null; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, ntodo; double scale, zero; unsigned char i1null, lognul = 0; char tform[20], *cstring = 0; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ long jbuff[2] = { -1, -1}; /* all bits set is equivalent to a NaN */ size_t buffsize; if (*status > 0) /* inherit input status value if > 0 */ return(*status); nelem = nelempar; largeelem = firstelem; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ /* note that writemode = 2 by default (not 1), so that the returned */ /* repeat and incre values will be the actual values for this column. */ /* If writing nulls to a variable length column then dummy data values */ /* must have already been written to the heap. */ /* We just have to overwrite the previous values with null values. */ /* Set writemode = 0 in this case, to test that values have been written */ fits_get_coltype(fptr, colnum, &tcode, NULL, NULL, status); if (tcode < 0) writemode = 0; /* this is a variable length column */ if (abs(tcode) >= TCOMPLEX) { /* treat complex columns as pairs of numbers */ largeelem = (largeelem - 1) * 2 + 1; nelem *= 2; } if (ffgcprll( fptr, colnum, firstrow, largeelem, nelem, writemode, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) { if (snull[0] == ASCII_NULL_UNDEFINED) { ffpmsg( "Null value string for ASCII table column is not defined (FTPCLU)."); return(*status = NO_NULL); } /* allocate buffer to hold the null string. Must write the entire */ /* width of the column (twidth bytes) to avoid possible problems */ /* with uninitialized FITS blocks, in case the field spans blocks */ buffsize = maxvalue(20, twidth); cstring = (char *) malloc(buffsize); if (!cstring) return(*status = MEMORY_ALLOCATION); memset(cstring, ' ', buffsize); /* initialize with blanks */ leng = strlen(snull); if (hdutype == BINARY_TBL) leng++; /* copy the terminator too in binary tables */ strncpy(cstring, snull, leng); /* copy null string to temp buffer */ } else if ( tcode == TBYTE || tcode == TSHORT || tcode == TLONG || tcode == TLONGLONG) { if (tnull == NULL_UNDEFINED) { ffpmsg( "Null value for integer table column is not defined (FTPCLU)."); return(*status = NO_NULL); } if (tcode == TBYTE) i1null = (unsigned char) tnull; else if (tcode == TSHORT) { i2null = (short) tnull; #if BYTESWAPPED ffswap2(&i2null, 1); /* reverse order of bytes */ #endif } else if (tcode == TLONG) { i4null = (INT32BIT) tnull; #if BYTESWAPPED ffswap4(&i4null, 1); /* reverse order of bytes */ #endif } else { i8null = tnull; #if BYTESWAPPED ffswap4( (INT32BIT*) (&i8null), 2); /* reverse order of bytes */ #endif } } /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ ntodo = remain; /* number of elements to write at one time */ while (ntodo) { /* limit the number of pixels to process at one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TBYTE): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 1, &i1null, status); break; case (TSHORT): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 2, &i2null, status); break; case (TLONG): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 4, &i4null, status); break; case (TLONGLONG): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 8, &i8null, status); break; case (TFLOAT): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 4, jbuff, status); break; case (TDOUBLE): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 8, jbuff, status); break; case (TLOGICAL): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 1, &lognul, status); break; case (TSTRING): /* an ASCII table column */ /* repeat always = 1, so ntodo is also guaranteed to = 1 */ ffpbyt(fptr, twidth, cstring, status); break; default: /* error trap */ sprintf(message, "Cannot write null value to column %d which has format %s", colnum,tform); ffpmsg(message); return(*status); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing %.0f thru %.0f of null values (ffpclu).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); if (cstring) free(cstring); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } ntodo = remain; /* this is the maximum number to do in next loop */ } /* End of main while Loop */ if (cstring) free(cstring); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcluc( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ int *status) /* IO - error status */ /* Set elements of a table column to the appropriate null value for the column The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. This routine does not do anything special in the case of COMPLEX table columns (unlike the similar ffpclu routine). This routine is mainly for use by ffpcne which already compensates for the effective doubling of the number of elements in a complex column. */ { int tcode, maxelem, hdutype, writemode = 2, leng; short i2null; INT32BIT i4null; long twidth, incre; long ii; LONGLONG tnull, i8null; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, ntodo; double scale, zero; unsigned char i1null, lognul = 0; char tform[20], *cstring = 0; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ long jbuff[2] = { -1, -1}; /* all bits set is equivalent to a NaN */ size_t buffsize; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ /* note that writemode = 2 by default (not 1), so that the returned */ /* repeat and incre values will be the actual values for this column. */ /* If writing nulls to a variable length column then dummy data values */ /* must have already been written to the heap. */ /* We just have to overwrite the previous values with null values. */ /* Set writemode = 0 in this case, to test that values have been written */ fits_get_coltype(fptr, colnum, &tcode, NULL, NULL, status); if (tcode < 0) writemode = 0; /* this is a variable length column */ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, writemode, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) { if (snull[0] == ASCII_NULL_UNDEFINED) { ffpmsg( "Null value string for ASCII table column is not defined (FTPCLU)."); return(*status = NO_NULL); } /* allocate buffer to hold the null string. Must write the entire */ /* width of the column (twidth bytes) to avoid possible problems */ /* with uninitialized FITS blocks, in case the field spans blocks */ buffsize = maxvalue(20, twidth); cstring = (char *) malloc(buffsize); if (!cstring) return(*status = MEMORY_ALLOCATION); memset(cstring, ' ', buffsize); /* initialize with blanks */ leng = strlen(snull); if (hdutype == BINARY_TBL) leng++; /* copy the terminator too in binary tables */ strncpy(cstring, snull, leng); /* copy null string to temp buffer */ } else if ( tcode == TBYTE || tcode == TSHORT || tcode == TLONG || tcode == TLONGLONG) { if (tnull == NULL_UNDEFINED) { ffpmsg( "Null value for integer table column is not defined (FTPCLU)."); return(*status = NO_NULL); } if (tcode == TBYTE) i1null = (unsigned char) tnull; else if (tcode == TSHORT) { i2null = (short) tnull; #if BYTESWAPPED ffswap2(&i2null, 1); /* reverse order of bytes */ #endif } else if (tcode == TLONG) { i4null = (INT32BIT) tnull; #if BYTESWAPPED ffswap4(&i4null, 1); /* reverse order of bytes */ #endif } else { i8null = tnull; #if BYTESWAPPED ffswap4( (INT32BIT*) &i8null, 2); /* reverse order of bytes */ #endif } } /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ ntodo = remain; /* number of elements to write at one time */ while (ntodo) { /* limit the number of pixels to process at one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TBYTE): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 1, &i1null, status); break; case (TSHORT): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 2, &i2null, status); break; case (TLONG): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 4, &i4null, status); break; case (TLONGLONG): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 8, &i8null, status); break; case (TFLOAT): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 4, jbuff, status); break; case (TDOUBLE): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 8, jbuff, status); break; case (TLOGICAL): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 1, &lognul, status); break; case (TSTRING): /* an ASCII table column */ /* repeat always = 1, so ntodo is also guaranteed to = 1 */ ffpbyt(fptr, twidth, cstring, status); break; default: /* error trap */ sprintf(message, "Cannot write null value to column %d which has format %s", colnum,tform); ffpmsg(message); return(*status); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing %.0f thru %.0f of null values (ffpclu).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); if (cstring) free(cstring); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } ntodo = remain; /* this is the maximum number to do in next loop */ } /* End of main while Loop */ if (cstring) free(cstring); return(*status); } /*--------------------------------------------------------------------------*/ int ffprwu(fitsfile *fptr, LONGLONG firstrow, LONGLONG nrows, int *status) /* * fits_write_nullrows / ffprwu - write TNULLs to all columns in one or more rows * * fitsfile *fptr - pointer to FITS HDU opened for read/write * long int firstrow - first table row to set to null. (firstrow >= 1) * long int nrows - total number or rows to set to null. (nrows >= 1) * int *status - upon return, *status contains CFITSIO status code * * RETURNS: CFITSIO status code * * written by Craig Markwardt, GSFC */ { LONGLONG ntotrows; int ncols, i; int typecode = 0; LONGLONG repeat = 0, width = 0; int nullstatus; if (*status > 0) return *status; if ((firstrow <= 0) || (nrows <= 0)) return (*status = BAD_ROW_NUM); fits_get_num_rowsll(fptr, &ntotrows, status); if (firstrow + nrows - 1 > ntotrows) return (*status = BAD_ROW_NUM); fits_get_num_cols(fptr, &ncols, status); if (*status) return *status; /* Loop through each column and write nulls */ for (i=1; i <= ncols; i++) { repeat = 0; typecode = 0; width = 0; fits_get_coltypell(fptr, i, &typecode, &repeat, &width, status); if (*status) break; /* NOTE: data of TSTRING type must not write the total repeat count, since the repeat count is the *character* count, not the nstring count. Divide by string width to get number of strings. */ if (typecode == TSTRING) repeat /= width; /* Write NULLs */ nullstatus = 0; fits_write_col_null(fptr, i, firstrow, 1, repeat*nrows, &nullstatus); /* ignore error if no null value is defined for the column */ if (nullstatus && nullstatus != NO_NULL) return (*status = nullstatus); } return *status; } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/putcolui.c000066400000000000000000001025041215713201500224420ustar00rootroot00000000000000/* This file, putcolui.c, contains routines that write data elements to */ /* a FITS image or table, with unsigned short datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpprui(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned short *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; unsigned short nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TUSHORT, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpclui(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnui(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned short *array, /* I - array of values that are written */ unsigned short nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; unsigned short nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TUSHORT, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnui(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2dui(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned short *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3dui(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3dui(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned short *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TUSHORT, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpclui(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpclui(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssui(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ unsigned short *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TUSHORT, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpclui(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpui( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ unsigned short *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpclui(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpclui( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned short *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TSHORT): ffu2fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TLONGLONG): ffu2fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffu2fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TLONG): ffu2fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TFLOAT): ffu2fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffu2fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffu2fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpclui).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnui(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned short *array, /* I - array of values to write */ unsigned short nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpclui(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpclui(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpclui(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2fi1(unsigned short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ((double) input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2fi2(unsigned short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 32768.) { /* Instead of subtracting 32768, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) output[ii] = ( *(short *) &input[ii] ) ^ 0x8000; } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ((double) input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2fi4(unsigned short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (INT32BIT) input[ii]; /* copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ((double) input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2fi8(unsigned short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2fr4(unsigned short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) (((double) input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2fr8(unsigned short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = ((double) input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2fstr(unsigned short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ((double) input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/putcoluj.c000066400000000000000000001027131215713201500224450ustar00rootroot00000000000000/* This file, putcoluj.c, contains routines that write data elements to */ /* a FITS image or table, with unsigned long datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffppruj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned long *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; unsigned long nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TULONG, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcluj(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnuj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned long *array, /* I - array of values that are written */ unsigned long nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; unsigned long nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TULONG, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnuj(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2duj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned long *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3duj(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3duj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned long *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TULONG, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpcluj(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpcluj(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssuj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ unsigned long *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TULONG, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpcluj(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpuj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ unsigned long *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpcluj(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcluj( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned long *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TLONG): ffu4fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TLONGLONG): ffu4fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffu4fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffu4fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TFLOAT): ffu4fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffu4fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffu4fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpcluj).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnuj( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned long *array, /* I - array of values to write */ unsigned long nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpcluj(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpcluj(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpcluj(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu4fi1(unsigned long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu4fi2(unsigned long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu4fi4(unsigned long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 2147483648. && sizeof(long) == 4) { /* Instead of subtracting 2147483648, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) output[ii] = ( *(long *) &input[ii] ) ^ 0x80000000; } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > INT32_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu4fi8(unsigned long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu4fr4(unsigned long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffu4fr8(unsigned long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffu4fstr(unsigned long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/putcoluk.c000066400000000000000000001041521215713201500224450ustar00rootroot00000000000000/* This file, putcolk.c, contains routines that write data elements to */ /* a FITS image or table, with 'unsigned int' datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffppruk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned int *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; unsigned int nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TUINT, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcluk(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnuk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned int *array, /* I - array of values that are written */ unsigned int nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; unsigned int nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TUINT, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnuk(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2duk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned int *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3duk(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3duk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned int *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TUINT, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpcluk(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpcluk(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssuk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ unsigned int *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TUINT, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpcluk(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpuk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ unsigned int *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpcluk(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcluk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned int *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* call the 'short' or 'long' version of this routine, if possible */ if (sizeof(int) == sizeof(short)) ffpclui(fptr, colnum, firstrow, firstelem, nelem, (unsigned short *) array, status); else if (sizeof(int) == sizeof(long)) ffpcluj(fptr, colnum, firstrow, firstelem, nelem, (unsigned long *) array, status); else { /* This is a special case: sizeof(int) is not equal to sizeof(short) or sizeof(long). This occurs on Alpha OSF systems where short = 2 bytes, int = 4 bytes, and long = 8 bytes. */ buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TLONG): /* convert the raw data before writing to FITS file */ ffuintfi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TLONGLONG): ffuintfi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffuintfi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffuintfi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TFLOAT): ffuintfr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffuintfr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffuintfstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpcluk).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } } /* end of Dec ALPHA special case */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnuk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned int *array, /* I - array of values to write */ unsigned int nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpcluk(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpcluk(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpcluk(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffuintfi1(unsigned int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffuintfi2(unsigned int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffuintfi4(unsigned int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 2147483648.) { /* Instead of subtracting 2147483648, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) output[ii] = ( *(int *) &input[ii] ) ^ 0x80000000; } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > INT32_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffuintfi8(unsigned int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffuintfr4(unsigned int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffuintfr8(unsigned int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffuintfstr(unsigned int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/putkey.c000066400000000000000000003174711215713201500221320ustar00rootroot00000000000000/* This file, putkey.c, contains routines that write keywords to */ /* a FITS header. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include /* stddef.h is apparently needed to define size_t */ #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffcrim(fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - bits per pixel */ int naxis, /* I - number of axes in the array */ long *naxes, /* I - size of each axis */ int *status) /* IO - error status */ /* create an IMAGE extension following the current HDU. If the current HDU is empty (contains no header keywords), then simply write the required image (or primary array) keywords to the current HDU. */ { if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* create new extension if current header is not empty */ if ((fptr->Fptr)->headend != (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) ffcrhd(fptr, status); /* write the required header keywords */ ffphpr(fptr, TRUE, bitpix, naxis, naxes, 0, 1, TRUE, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffcrimll(fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - bits per pixel */ int naxis, /* I - number of axes in the array */ LONGLONG *naxes, /* I - size of each axis */ int *status) /* IO - error status */ /* create an IMAGE extension following the current HDU. If the current HDU is empty (contains no header keywords), then simply write the required image (or primary array) keywords to the current HDU. */ { if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* create new extension if current header is not empty */ if ((fptr->Fptr)->headend != (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) ffcrhd(fptr, status); /* write the required header keywords */ ffphprll(fptr, TRUE, bitpix, naxis, naxes, 0, 1, TRUE, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffcrtb(fitsfile *fptr, /* I - FITS file pointer */ int tbltype, /* I - type of table to create */ LONGLONG naxis2, /* I - number of rows in the table */ int tfields, /* I - number of columns in the table */ char **ttype, /* I - name of each column */ char **tform, /* I - value of TFORMn keyword for each column */ char **tunit, /* I - value of TUNITn keyword for each column */ char *extnm, /* I - value of EXTNAME keyword, if any */ int *status) /* IO - error status */ /* Create a table extension in a FITS file. */ { LONGLONG naxis1 = 0; long *tbcol = 0; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* create new extension if current header is not empty */ if ((fptr->Fptr)->headend != (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) ffcrhd(fptr, status); if ((fptr->Fptr)->curhdu == 0) /* have to create dummy primary array */ { ffcrim(fptr, 16, 0, tbcol, status); ffcrhd(fptr, status); } if (tbltype == BINARY_TBL) { /* write the required header keywords. This will write PCOUNT = 0 */ ffphbn(fptr, naxis2, tfields, ttype, tform, tunit, extnm, 0, status); } else if (tbltype == ASCII_TBL) { /* write the required header keywords */ /* default values for naxis1 and tbcol will be calculated */ ffphtb(fptr, naxis1, naxis2, tfields, ttype, tbcol, tform, tunit, extnm, status); } else *status = NOT_TABLE; return(*status); } /*-------------------------------------------------------------------------*/ int ffpktp(fitsfile *fptr, /* I - FITS file pointer */ const char *filename, /* I - name of template file */ int *status) /* IO - error status */ /* read keywords from template file and append to the FITS file */ { FILE *diskfile; char card[FLEN_CARD], template[161]; char keyname[FLEN_KEYWORD], newname[FLEN_KEYWORD]; int keytype; size_t slen; if (*status > 0) /* inherit input status value if > 0 */ return(*status); diskfile = fopen(filename,"r"); if (!diskfile) /* couldn't open file */ { ffpmsg("ffpktp could not open the following template file:"); ffpmsg(filename); return(*status = FILE_NOT_OPENED); } while (fgets(template, 160, diskfile) ) /* get next template line */ { template[160] = '\0'; /* make sure string is terminated */ slen = strlen(template); /* get string length */ template[slen - 1] = '\0'; /* over write the 'newline' char */ if (ffgthd(template, card, &keytype, status) > 0) /* parse template */ break; strncpy(keyname, card, 8); keyname[8] = '\0'; if (keytype == -2) /* rename the card */ { strncpy(newname, &card[40], 8); newname[8] = '\0'; ffmnam(fptr, keyname, newname, status); } else if (keytype == -1) /* delete the card */ { ffdkey(fptr, keyname, status); } else if (keytype == 0) /* update the card */ { ffucrd(fptr, keyname, card, status); } else if (keytype == 1) /* append the card */ { ffprec(fptr, card, status); } else /* END card; stop here */ { break; } } fclose(diskfile); /* close the template file */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpky( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ char *keyname, /* I - name of keyword to write */ void *value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes a keyword value with the datatype specified by the 2nd argument. */ { char errmsg[81]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (datatype == TSTRING) { ffpkys(fptr, keyname, (char *) value, comm, status); } else if (datatype == TBYTE) { ffpkyj(fptr, keyname, (LONGLONG) *(unsigned char *) value, comm, status); } else if (datatype == TSBYTE) { ffpkyj(fptr, keyname, (LONGLONG) *(signed char *) value, comm, status); } else if (datatype == TUSHORT) { ffpkyj(fptr, keyname, (LONGLONG) *(unsigned short *) value, comm, status); } else if (datatype == TSHORT) { ffpkyj(fptr, keyname, (LONGLONG) *(short *) value, comm, status); } else if (datatype == TUINT) { ffpkyg(fptr, keyname, (double) *(unsigned int *) value, 0, comm, status); } else if (datatype == TINT) { ffpkyj(fptr, keyname, (LONGLONG) *(int *) value, comm, status); } else if (datatype == TLOGICAL) { ffpkyl(fptr, keyname, *(int *) value, comm, status); } else if (datatype == TULONG) { ffpkyg(fptr, keyname, (double) *(unsigned long *) value, 0, comm, status); } else if (datatype == TLONG) { ffpkyj(fptr, keyname, (LONGLONG) *(long *) value, comm, status); } else if (datatype == TLONGLONG) { ffpkyj(fptr, keyname, *(LONGLONG *) value, comm, status); } else if (datatype == TFLOAT) { ffpkye(fptr, keyname, *(float *) value, -7, comm, status); } else if (datatype == TDOUBLE) { ffpkyd(fptr, keyname, *(double *) value, -15, comm, status); } else if (datatype == TCOMPLEX) { ffpkyc(fptr, keyname, (float *) value, -7, comm, status); } else if (datatype == TDBLCOMPLEX) { ffpkym(fptr, keyname, (double *) value, -15, comm, status); } else { sprintf(errmsg, "Bad keyword datatype code: %d (ffpky)", datatype); ffpmsg(errmsg); *status = BAD_DATATYPE; } return(*status); } /*-------------------------------------------------------------------------*/ int ffprec(fitsfile *fptr, /* I - FITS file pointer */ const char *card, /* I - string to be written */ int *status) /* IO - error status */ /* write a keyword record (80 bytes long) to the end of the header */ { char tcard[FLEN_CARD]; size_t len, ii; long nblocks; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ( ((fptr->Fptr)->datastart - (fptr->Fptr)->headend) == 80) /* no room */ { nblocks = 1; if (ffiblk(fptr, nblocks, 0, status) > 0) /* insert 2880-byte block */ return(*status); } strncpy(tcard,card,80); tcard[80] = '\0'; len = strlen(tcard); for (ii=len; ii < 80; ii++) /* fill card with spaces if necessary */ tcard[ii] = ' '; for (ii=0; ii < 8; ii++) /* make sure keyword name is uppercase */ tcard[ii] = toupper(tcard[ii]); fftkey(tcard, status); /* test keyword name contains legal chars */ fftrec(tcard, status); /* test rest of keyword for legal chars */ ffmbyt(fptr, (fptr->Fptr)->headend, IGNORE_EOF, status); /* move to end */ ffpbyt(fptr, 80, tcard, status); /* write the 80 byte card */ if (*status <= 0) (fptr->Fptr)->headend += 80; /* update end-of-header position */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyu( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) a null-valued keyword and comment into the FITS header. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring," "); /* create a dummy value string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword */ ffprec(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpkys( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ char *value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. The value string will be truncated at 68 characters which is the maximum length that will fit on a single FITS keyword. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffs2c(value, valstring, status); /* put quotes around the string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword */ ffprec(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpkls( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ char *value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. This routine is a modified version of ffpkys which supports the HEASARC long string convention and can write arbitrarily long string keyword values. The value is continued over multiple keywords that have the name COMTINUE without an equal sign in column 9 of the card. This routine also supports simple string keywords which are less than 69 characters in length. */ { char valstring[FLEN_CARD]; char card[FLEN_CARD]; char tstring[FLEN_CARD], *cptr; int next, remain, vlen, nquote, nchar, namelen, contin, tstatus = -1; if (*status > 0) /* inherit input status value if > 0 */ return(*status); remain = maxvalue(strlen(value), 1); /* no. of chars to write (at least 1) */ /* count the number of single quote characters are in the string */ tstring[0] = '\0'; strncat(tstring, value, 68); /* copy 1st part of string to temp buff */ nquote = 0; cptr = strchr(tstring, '\''); /* search for quote character */ while (cptr) /* search for quote character */ { nquote++; /* increment no. of quote characters */ cptr++; /* increment pointer to next character */ cptr = strchr(cptr, '\''); /* search for another quote char */ } cptr = keyname; while(*cptr == ' ') /* skip over leading spaces in name */ cptr++; /* determine the number of characters that will fit on the line */ /* Note: each quote character is expanded to 2 quotes */ namelen = strlen(cptr); if (namelen <= 8 && (fftkey(cptr, &tstatus) <= 0) ) { /* This a normal 8-character FITS keyword */ nchar = 68 - nquote; /* max of 68 chars fit in a FITS string value */ } else { /* This a HIERARCH keyword */ if (FSTRNCMP(cptr, "HIERARCH ", 9) && FSTRNCMP(cptr, "hierarch ", 9)) nchar = 66 - nquote - namelen; else nchar = 75 - nquote - namelen; /* don't count 'HIERARCH' twice */ } contin = 0; next = 0; /* pointer to next character to write */ while (remain > 0) { tstring[0] = '\0'; strncat(tstring, &value[next], nchar); /* copy string to temp buff */ ffs2c(tstring, valstring, status); /* put quotes around the string */ if (remain > nchar) /* if string is continued, put & as last char */ { vlen = strlen(valstring); nchar -= 1; /* outputting one less character now */ if (valstring[vlen-2] != '\'') valstring[vlen-2] = '&'; /* over write last char with & */ else { /* last char was a pair of single quotes, so over write both */ valstring[vlen-3] = '&'; valstring[vlen-1] = '\0'; } } if (contin) /* This is a CONTINUEd keyword */ { ffmkky("CONTINUE", valstring, comm, card, status); /* make keyword */ strncpy(&card[8], " ", 2); /* overwrite the '=' */ } else { ffmkky(keyname, valstring, comm, card, status); /* make keyword */ } ffprec(fptr, card, status); /* write the keyword */ contin = 1; remain -= nchar; next += nchar; if (remain > 0) { /* count the number of single quote characters in next section */ tstring[0] = '\0'; strncat(tstring, &value[next], 68); /* copy next part of string */ nquote = 0; cptr = strchr(tstring, '\''); /* search for quote character */ while (cptr) /* search for quote character */ { nquote++; /* increment no. of quote characters */ cptr++; /* increment pointer to next character */ cptr = strchr(cptr, '\''); /* search for another quote char */ } nchar = 68 - nquote; /* max number of chars to write this time */ } } return(*status); } /*--------------------------------------------------------------------------*/ int ffplsw( fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Write the LONGSTRN keyword and a series of related COMMENT keywords which document that this FITS header may contain long string keyword values which are continued over multiple keywords using the HEASARC long string keyword convention. If the LONGSTRN keyword already exists then this routine simple returns without doing anything. */ { char valstring[FLEN_VALUE], comm[FLEN_COMMENT]; int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = 0; if (ffgkys(fptr, "LONGSTRN", valstring, comm, &tstatus) == 0) return(*status); /* keyword already exists, so just return */ ffpkys(fptr, "LONGSTRN", "OGIP 1.0", "The HEASARC Long String Convention may be used.", status); ffpcom(fptr, " This FITS file may contain long string keyword values that are", status); ffpcom(fptr, " continued over multiple keywords. The HEASARC convention uses the &", status); ffpcom(fptr, " character at the end of each substring which is then continued", status); ffpcom(fptr, " on the next keyword which has the name CONTINUE.", status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyl( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ int value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Values equal to 0 will result in a False FITS keyword; any other non-zero value will result in a True FITS keyword. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffl2c(value, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyj( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ LONGLONG value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an integer keyword value. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffi2c(value, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyf( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ float value, /* I - keyword value */ int decim, /* I - number of decimal places to display */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes a fixed float keyword value. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffr2f(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkye( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ float value, /* I - keyword value */ int decim, /* I - number of decimal places to display */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an exponential float keyword value. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffr2e(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyg( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ double value, /* I - keyword value */ int decim, /* I - number of decimal places to display */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes a fixed double keyword value.*/ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffd2f(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyd( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ double value, /* I - keyword value */ int decim, /* I - number of decimal places to display */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an exponential double keyword value.*/ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffd2e(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyc( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ float *value, /* I - keyword value (real, imaginary) */ int decim, /* I - number of decimal places to display */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an complex float keyword value. Format = (realvalue, imagvalue) */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffr2e(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffr2e(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkym( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ double *value, /* I - keyword value (real, imaginary) */ int decim, /* I - number of decimal places to display */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an complex double keyword value. Format = (realvalue, imagvalue) */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffd2e(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffd2e(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkfc( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ float *value, /* I - keyword value (real, imaginary) */ int decim, /* I - number of decimal places to display */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an complex float keyword value. Format = (realvalue, imagvalue) */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffr2f(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffr2f(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkfm( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ double *value, /* I - keyword value (real, imaginary) */ int decim, /* I - number of decimal places to display */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an complex double keyword value. Format = (realvalue, imagvalue) */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffd2f(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffd2f(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyt( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ long intval, /* I - integer part of value */ double fraction, /* I - fractional part of value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) a 'triple' precision keyword where the integer and fractional parts of the value are passed in separate parameters to increase the total amount of numerical precision. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; char fstring[20], *cptr; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (fraction > 1. || fraction < 0.) { ffpmsg("fraction must be between 0. and 1. (ffpkyt)"); return(*status = BAD_F2C); } ffi2c(intval, valstring, status); /* convert integer to string */ ffd2f(fraction, 16, fstring, status); /* convert to 16 decimal string */ cptr = strchr(fstring, '.'); /* find the decimal point */ strcat(valstring, cptr); /* append the fraction to the integer */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*-----------------------------------------------------------------*/ int ffpcom( fitsfile *fptr, /* I - FITS file pointer */ const char *comm, /* I - comment string */ int *status) /* IO - error status */ /* Write 1 or more COMMENT keywords. If the comment string is too long to fit on a single keyword (72 chars) then it will automatically be continued on multiple CONTINUE keywords. */ { char card[FLEN_CARD]; int len, ii; if (*status > 0) /* inherit input status value if > 0 */ return(*status); len = strlen(comm); ii = 0; for (; len > 0; len -= 72) { strcpy(card, "COMMENT "); strncat(card, &comm[ii], 72); ffprec(fptr, card, status); ii += 72; } return(*status); } /*-----------------------------------------------------------------*/ int ffphis( fitsfile *fptr, /* I - FITS file pointer */ const char *history, /* I - history string */ int *status) /* IO - error status */ /* Write 1 or more HISTORY keywords. If the history string is too long to fit on a single keyword (72 chars) then it will automatically be continued on multiple HISTORY keywords. */ { char card[FLEN_CARD]; int len, ii; if (*status > 0) /* inherit input status value if > 0 */ return(*status); len = strlen(history); ii = 0; for (; len > 0; len -= 72) { strcpy(card, "HISTORY "); strncat(card, &history[ii], 72); ffprec(fptr, card, status); ii += 72; } return(*status); } /*-----------------------------------------------------------------*/ int ffpdat( fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Write the DATE keyword into the FITS header. If the keyword already exists then the date will simply be updated in the existing keyword. */ { int timeref; char date[30], tmzone[10], card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffgstm(date, &timeref, status); if (timeref) /* GMT not available on this machine */ strcpy(tmzone, " Local"); else strcpy(tmzone, " UT"); strcpy(card, "DATE = '"); strcat(card, date); strcat(card, "' / file creation date (YYYY-MM-DDThh:mm:ss"); strcat(card, tmzone); strcat(card, ")"); ffucrd(fptr, "DATE", card, status); return(*status); } /*-------------------------------------------------------------------*/ int ffverifydate(int year, /* I - year (0 - 9999) */ int month, /* I - month (1 - 12) */ int day, /* I - day (1 - 31) */ int *status) /* IO - error status */ /* Verify that the date is valid */ { int ndays[] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; char errmsg[81]; if (year < 0 || year > 9999) { sprintf(errmsg, "input year value = %d is out of range 0 - 9999", year); ffpmsg(errmsg); return(*status = BAD_DATE); } else if (month < 1 || month > 12) { sprintf(errmsg, "input month value = %d is out of range 1 - 12", month); ffpmsg(errmsg); return(*status = BAD_DATE); } if (ndays[month] == 31) { if (day < 1 || day > 31) { sprintf(errmsg, "input day value = %d is out of range 1 - 31 for month %d", day, month); ffpmsg(errmsg); return(*status = BAD_DATE); } } else if (ndays[month] == 30) { if (day < 1 || day > 30) { sprintf(errmsg, "input day value = %d is out of range 1 - 30 for month %d", day, month); ffpmsg(errmsg); return(*status = BAD_DATE); } } else { if (day < 1 || day > 28) { if (day == 29) { /* year is a leap year if it is divisible by 4 but not by 100, except years divisible by 400 are leap years */ if ((year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0) return (*status); sprintf(errmsg, "input day value = %d is out of range 1 - 28 for February %d (not leap year)", day, year); ffpmsg(errmsg); } else { sprintf(errmsg, "input day value = %d is out of range 1 - 28 (or 29) for February", day); ffpmsg(errmsg); } return(*status = BAD_DATE); } } return(*status); } /*-----------------------------------------------------------------*/ int ffgstm( char *timestr, /* O - returned system date and time string */ int *timeref, /* O - GMT = 0, Local time = 1 */ int *status) /* IO - error status */ /* Returns the current date and time in format 'yyyy-mm-ddThh:mm:ss'. */ { time_t tp; struct tm *ptr; if (*status > 0) /* inherit input status value if > 0 */ return(*status); time(&tp); ptr = gmtime(&tp); /* get GMT (= UTC) time */ if (timeref) { if (ptr) *timeref = 0; /* returning GMT */ else *timeref = 1; /* returning local time */ } if (!ptr) /* GMT not available on this machine */ ptr = localtime(&tp); strftime(timestr, 25, "%Y-%m-%dT%H:%M:%S", ptr); return(*status); } /*-----------------------------------------------------------------*/ int ffdt2s(int year, /* I - year (0 - 9999) */ int month, /* I - month (1 - 12) */ int day, /* I - day (1 - 31) */ char *datestr, /* O - date string: "YYYY-MM-DD" */ int *status) /* IO - error status */ /* Construct a date character string */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); *datestr = '\0'; if (ffverifydate(year, month, day, status) > 0) { ffpmsg("invalid date (ffdt2s)"); return(*status); } if (year >= 1900 && year <= 1998) /* use old 'dd/mm/yy' format */ sprintf(datestr, "%.2d/%.2d/%.2d", day, month, year - 1900); else /* use the new 'YYYY-MM-DD' format */ sprintf(datestr, "%.4d-%.2d-%.2d", year, month, day); return(*status); } /*-----------------------------------------------------------------*/ int ffs2dt(char *datestr, /* I - date string: "YYYY-MM-DD" or "dd/mm/yy" */ int *year, /* O - year (0 - 9999) */ int *month, /* O - month (1 - 12) */ int *day, /* O - day (1 - 31) */ int *status) /* IO - error status */ /* Parse a date character string into year, month, and day values */ { int slen, lyear, lmonth, lday; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (year) *year = 0; if (month) *month = 0; if (day) *day = 0; if (!datestr) { ffpmsg("error: null input date string (ffs2dt)"); return(*status = BAD_DATE); /* Null datestr pointer ??? */ } slen = strlen(datestr); if (slen == 8 && datestr[2] == '/' && datestr[5] == '/') { if (isdigit((int) datestr[0]) && isdigit((int) datestr[1]) && isdigit((int) datestr[3]) && isdigit((int) datestr[4]) && isdigit((int) datestr[6]) && isdigit((int) datestr[7]) ) { /* this is an old format string: "dd/mm/yy" */ lyear = atoi(&datestr[6]) + 1900; lmonth = atoi(&datestr[3]); lday = atoi(datestr); if (year) *year = lyear; if (month) *month = lmonth; if (day) *day = lday; } else { ffpmsg("input date string has illegal format (ffs2dt):"); ffpmsg(datestr); return(*status = BAD_DATE); } } else if (slen >= 10 && datestr[4] == '-' && datestr[7] == '-') { if (isdigit((int) datestr[0]) && isdigit((int) datestr[1]) && isdigit((int) datestr[2]) && isdigit((int) datestr[3]) && isdigit((int) datestr[5]) && isdigit((int) datestr[6]) && isdigit((int) datestr[8]) && isdigit((int) datestr[9]) ) { if (slen > 10 && datestr[10] != 'T') { ffpmsg("input date string has illegal format (ffs2dt):"); ffpmsg(datestr); return(*status = BAD_DATE); } /* this is a new format string: "yyyy-mm-dd" */ lyear = atoi(datestr); lmonth = atoi(&datestr[5]); lday = atoi(&datestr[8]); if (year) *year = lyear; if (month) *month = lmonth; if (day) *day = lday; } else { ffpmsg("input date string has illegal format (ffs2dt):"); ffpmsg(datestr); return(*status = BAD_DATE); } } else { ffpmsg("input date string has illegal format (ffs2dt):"); ffpmsg(datestr); return(*status = BAD_DATE); } if (ffverifydate(lyear, lmonth, lday, status) > 0) { ffpmsg("invalid date (ffs2dt)"); } return(*status); } /*-----------------------------------------------------------------*/ int fftm2s(int year, /* I - year (0 - 9999) */ int month, /* I - month (1 - 12) */ int day, /* I - day (1 - 31) */ int hour, /* I - hour (0 - 23) */ int minute, /* I - minute (0 - 59) */ double second, /* I - second (0. - 60.9999999) */ int decimals, /* I - number of decimal points to write */ char *datestr, /* O - date string: "YYYY-MM-DDThh:mm:ss.ddd" */ /* or "hh:mm:ss.ddd" if year, month day = 0 */ int *status) /* IO - error status */ /* Construct a date and time character string */ { int width; char errmsg[81]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); *datestr='\0'; if (year != 0 || month != 0 || day !=0) { if (ffverifydate(year, month, day, status) > 0) { ffpmsg("invalid date (fftm2s)"); return(*status); } } if (hour < 0 || hour > 23) { sprintf(errmsg, "input hour value is out of range 0 - 23: %d (fftm2s)", hour); ffpmsg(errmsg); return(*status = BAD_DATE); } else if (minute < 0 || minute > 59) { sprintf(errmsg, "input minute value is out of range 0 - 59: %d (fftm2s)", minute); ffpmsg(errmsg); return(*status = BAD_DATE); } else if (second < 0. || second >= 61) { sprintf(errmsg, "input second value is out of range 0 - 60.999: %f (fftm2s)", second); ffpmsg(errmsg); return(*status = BAD_DATE); } else if (decimals > 25) { sprintf(errmsg, "input decimals value is out of range 0 - 25: %d (fftm2s)", decimals); ffpmsg(errmsg); return(*status = BAD_DATE); } if (decimals == 0) width = 2; else width = decimals + 3; if (decimals < 0) { /* a negative decimals value means return only the date, not time */ sprintf(datestr, "%.4d-%.2d-%.2d", year, month, day); } else if (year == 0 && month == 0 && day == 0) { /* return only the time, not the date */ sprintf(datestr, "%.2d:%.2d:%0*.*f", hour, minute, width, decimals, second); } else { /* return both the time and date */ sprintf(datestr, "%.4d-%.2d-%.2dT%.2d:%.2d:%0*.*f", year, month, day, hour, minute, width, decimals, second); } return(*status); } /*-----------------------------------------------------------------*/ int ffs2tm(char *datestr, /* I - date string: "YYYY-MM-DD" */ /* or "YYYY-MM-DDThh:mm:ss.ddd" */ /* or "dd/mm/yy" */ int *year, /* O - year (0 - 9999) */ int *month, /* O - month (1 - 12) */ int *day, /* O - day (1 - 31) */ int *hour, /* I - hour (0 - 23) */ int *minute, /* I - minute (0 - 59) */ double *second, /* I - second (0. - 60.9999999) */ int *status) /* IO - error status */ /* Parse a date character string into date and time values */ { int slen; char errmsg[81]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (year) *year = 0; if (month) *month = 0; if (day) *day = 0; if (hour) *hour = 0; if (minute) *minute = 0; if (second) *second = 0.; if (!datestr) { ffpmsg("error: null input date string (ffs2tm)"); return(*status = BAD_DATE); /* Null datestr pointer ??? */ } if (datestr[2] == '/' || datestr[4] == '-') { /* Parse the year, month, and date */ if (ffs2dt(datestr, year, month, day, status) > 0) return(*status); slen = strlen(datestr); if (slen == 8 || slen == 10) return(*status); /* OK, no time fields */ else if (slen < 19) { ffpmsg("input date string has illegal format:"); ffpmsg(datestr); return(*status = BAD_DATE); } else if (datestr[10] == 'T' && datestr[13] == ':' && datestr[16] == ':') { if (isdigit((int) datestr[11]) && isdigit((int) datestr[12]) && isdigit((int) datestr[14]) && isdigit((int) datestr[15]) && isdigit((int) datestr[17]) && isdigit((int) datestr[18]) ) { if (slen > 19 && datestr[19] != '.') { ffpmsg("input date string has illegal format:"); ffpmsg(datestr); return(*status = BAD_DATE); } /* this is a new format string: "yyyy-mm-ddThh:mm:ss.dddd" */ if (hour) *hour = atoi(&datestr[11]); if (minute) *minute = atoi(&datestr[14]); if (second) *second = atof(&datestr[17]); } else { ffpmsg("input date string has illegal format:"); ffpmsg(datestr); return(*status = BAD_DATE); } } } else /* no date fields */ { if (datestr[2] == ':' && datestr[5] == ':') /* time string */ { if (isdigit((int) datestr[0]) && isdigit((int) datestr[1]) && isdigit((int) datestr[3]) && isdigit((int) datestr[4]) && isdigit((int) datestr[6]) && isdigit((int) datestr[7]) ) { /* this is a time string: "hh:mm:ss.dddd" */ if (hour) *hour = atoi(&datestr[0]); if (minute) *minute = atoi(&datestr[3]); if (second) *second = atof(&datestr[6]); } else { ffpmsg("input date string has illegal format:"); ffpmsg(datestr); return(*status = BAD_DATE); } } else { ffpmsg("input date string has illegal format:"); ffpmsg(datestr); return(*status = BAD_DATE); } } if (hour) if (*hour < 0 || *hour > 23) { sprintf(errmsg, "hour value is out of range 0 - 23: %d (ffs2tm)", *hour); ffpmsg(errmsg); return(*status = BAD_DATE); } if (minute) if (*minute < 0 || *minute > 59) { sprintf(errmsg, "minute value is out of range 0 - 59: %d (ffs2tm)", *minute); ffpmsg(errmsg); return(*status = BAD_DATE); } if (second) if (*second < 0 || *second >= 61.) { sprintf(errmsg, "second value is out of range 0 - 60.9999: %f (ffs2tm)", *second); ffpmsg(errmsg); return(*status = BAD_DATE); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsdt( int *day, int *month, int *year, int *status ) { /* This routine is included for backward compatibility with the Fortran FITSIO library. ffgsdt : Get current System DaTe (GMT if available) Return integer values of the day, month, and year Function parameters: day Day of the month month Numerical month (1=Jan, etc.) year Year (1999, 2000, etc.) status output error status */ time_t now; struct tm *date; now = time( NULL ); date = gmtime(&now); /* get GMT (= UTC) time */ if (!date) /* GMT not available on this machine */ { date = localtime(&now); } *day = date->tm_mday; *month = date->tm_mon + 1; *year = date->tm_year + 1900; /* tm_year is defined as years since 1900 */ return( *status ); } /*--------------------------------------------------------------------------*/ int ffpkns( fitsfile *fptr, /* I - FITS file pointer */ char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ char *value[], /* I - array of pointers to keyword values */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Writes string keywords. The value strings will be truncated at 68 characters, and the HEASARC long string keyword convention is not supported by this routine. */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkys(fptr, keyname, value[ii], tcomment, status); else ffpkys(fptr, keyname, value[ii], comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpknl( fitsfile *fptr, /* I - FITS file pointer */ char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ int *value, /* I - array of keyword values */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Writes logical keywords Values equal to zero will be written as a False FITS keyword value; any other non-zero value will result in a True FITS keyword. */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkyl(fptr, keyname, value[ii], tcomment, status); else ffpkyl(fptr, keyname, value[ii], comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpknj( fitsfile *fptr, /* I - FITS file pointer */ char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ long *value, /* I - array of keyword values */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Write integer keywords */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkyj(fptr, keyname, value[ii], tcomment, status); else ffpkyj(fptr, keyname, value[ii], comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpknjj( fitsfile *fptr, /* I - FITS file pointer */ char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ LONGLONG *value, /* I - array of keyword values */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Write integer keywords */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkyj(fptr, keyname, value[ii], tcomment, status); else ffpkyj(fptr, keyname, value[ii], comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpknf( fitsfile *fptr, /* I - FITS file pointer */ char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ float *value, /* I - array of keyword values */ int decim, /* I - number of decimals to display */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Writes fixed float values. */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkyf(fptr, keyname, value[ii], decim, tcomment, status); else ffpkyf(fptr, keyname, value[ii], decim, comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpkne( fitsfile *fptr, /* I - FITS file pointer */ char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ float *value, /* I - array of keyword values */ int decim, /* I - number of decimals to display */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Writes exponential float values. */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkye(fptr, keyname, value[ii], decim, tcomment, status); else ffpkye(fptr, keyname, value[ii], decim, comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpkng( fitsfile *fptr, /* I - FITS file pointer */ char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ double *value, /* I - array of keyword values */ int decim, /* I - number of decimals to display */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Writes fixed double values. */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkyg(fptr, keyname, value[ii], decim, tcomment, status); else ffpkyg(fptr, keyname, value[ii], decim, comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpknd( fitsfile *fptr, /* I - FITS file pointer */ char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ double *value, /* I - array of keyword values */ int decim, /* I - number of decimals to display */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Writes exponential double values. */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkyd(fptr, keyname, value[ii], decim, tcomment, status); else ffpkyd(fptr, keyname, value[ii], decim, comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffptdm( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ int naxis, /* I - number of axes in the data array */ long naxes[], /* I - length of each data axis */ int *status) /* IO - error status */ /* write the TDIMnnn keyword describing the dimensionality of a column */ { char keyname[FLEN_KEYWORD], tdimstr[FLEN_VALUE], comm[FLEN_COMMENT]; char value[80], message[81]; int ii; long totalpix = 1, repeat; tcolumn *colptr; if (*status > 0) return(*status); if (colnum < 1 || colnum > 999) { ffpmsg("column number is out of range 1 - 999 (ffptdm)"); return(*status = BAD_COL_NUM); } if (naxis < 1) { ffpmsg("naxis is less than 1 (ffptdm)"); return(*status = BAD_DIMEN); } /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ( (fptr->Fptr)->hdutype != BINARY_TBL) { ffpmsg( "Error: The TDIMn keyword is only allowed in BINTABLE extensions (ffptdm)"); return(*status = NOT_BTABLE); } strcpy(tdimstr, "("); /* start constructing the TDIM value */ for (ii = 0; ii < naxis; ii++) { if (ii > 0) strcat(tdimstr, ","); /* append the comma separator */ if (naxes[ii] < 0) { ffpmsg("one or more TDIM values are less than 0 (ffptdm)"); return(*status = BAD_TDIM); } sprintf(value, "%ld", naxes[ii]); strcat(tdimstr, value); /* append the axis size */ totalpix *= naxes[ii]; } colptr = (fptr->Fptr)->tableptr; /* point to first column structure */ colptr += (colnum - 1); /* point to the specified column number */ if ((long) colptr->trepeat != totalpix) { /* There is an apparent inconsistency between TDIMn and TFORMn. */ /* The colptr->trepeat value may be out of date, so re-read */ /* the TFORMn keyword to be sure. */ ffkeyn("TFORM", colnum, keyname, status); /* construct TFORMn name */ ffgkys(fptr, keyname, value, NULL, status); /* read TFORMn keyword */ ffbnfm(value, NULL, &repeat, NULL, status); /* parse the repeat count */ if (*status > 0 || repeat != totalpix) { sprintf(message, "column vector length, %ld, does not equal TDIMn array size, %ld", (long) colptr->trepeat, totalpix); ffpmsg(message); return(*status = BAD_TDIM); } } strcat(tdimstr, ")" ); /* append the closing parenthesis */ strcpy(comm, "size of the multidimensional array"); ffkeyn("TDIM", colnum, keyname, status); /* construct TDIMn name */ ffpkys(fptr, keyname, tdimstr, comm, status); /* write the keyword */ return(*status); } /*--------------------------------------------------------------------------*/ int ffptdmll( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ int naxis, /* I - number of axes in the data array */ LONGLONG naxes[], /* I - length of each data axis */ int *status) /* IO - error status */ /* write the TDIMnnn keyword describing the dimensionality of a column */ { char keyname[FLEN_KEYWORD], tdimstr[FLEN_VALUE], comm[FLEN_COMMENT]; char value[80], message[81]; int ii; LONGLONG totalpix = 1, repeat; tcolumn *colptr; if (*status > 0) return(*status); if (colnum < 1 || colnum > 999) { ffpmsg("column number is out of range 1 - 999 (ffptdm)"); return(*status = BAD_COL_NUM); } if (naxis < 1) { ffpmsg("naxis is less than 1 (ffptdm)"); return(*status = BAD_DIMEN); } /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ( (fptr->Fptr)->hdutype != BINARY_TBL) { ffpmsg( "Error: The TDIMn keyword is only allowed in BINTABLE extensions (ffptdm)"); return(*status = NOT_BTABLE); } strcpy(tdimstr, "("); /* start constructing the TDIM value */ for (ii = 0; ii < naxis; ii++) { if (ii > 0) strcat(tdimstr, ","); /* append the comma separator */ if (naxes[ii] < 0) { ffpmsg("one or more TDIM values are less than 0 (ffptdm)"); return(*status = BAD_TDIM); } /* cast to double because the 64-bit int conversion character in */ /* sprintf is platform dependent ( %lld, %ld, %I64d ) */ sprintf(value, "%.0f", (double) naxes[ii]); strcat(tdimstr, value); /* append the axis size */ totalpix *= naxes[ii]; } colptr = (fptr->Fptr)->tableptr; /* point to first column structure */ colptr += (colnum - 1); /* point to the specified column number */ if ( colptr->trepeat != totalpix) { /* There is an apparent inconsistency between TDIMn and TFORMn. */ /* The colptr->trepeat value may be out of date, so re-read */ /* the TFORMn keyword to be sure. */ ffkeyn("TFORM", colnum, keyname, status); /* construct TFORMn name */ ffgkys(fptr, keyname, value, NULL, status); /* read TFORMn keyword */ ffbnfmll(value, NULL, &repeat, NULL, status); /* parse the repeat count */ if (*status > 0 || repeat != totalpix) { sprintf(message, "column vector length, %.0f, does not equal TDIMn array size, %.0f", (double) (colptr->trepeat), (double) totalpix); ffpmsg(message); return(*status = BAD_TDIM); } } strcat(tdimstr, ")" ); /* append the closing parenthesis */ strcpy(comm, "size of the multidimensional array"); ffkeyn("TDIM", colnum, keyname, status); /* construct TDIMn name */ ffpkys(fptr, keyname, tdimstr, comm, status); /* write the keyword */ return(*status); } /*--------------------------------------------------------------------------*/ int ffphps( fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - number of bits per data value pixel */ int naxis, /* I - number of axes in the data array */ long naxes[], /* I - length of each data axis */ int *status) /* IO - error status */ /* write STANDARD set of required primary header keywords */ { int simple = 1; /* does file conform to FITS standard? 1/0 */ long pcount = 0; /* number of group parameters (usually 0) */ long gcount = 1; /* number of random groups (usually 1 or 0) */ int extend = 1; /* may FITS file have extensions? */ ffphpr(fptr, simple, bitpix, naxis, naxes, pcount, gcount, extend, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffphpsll( fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - number of bits per data value pixel */ int naxis, /* I - number of axes in the data array */ LONGLONG naxes[], /* I - length of each data axis */ int *status) /* IO - error status */ /* write STANDARD set of required primary header keywords */ { int simple = 1; /* does file conform to FITS standard? 1/0 */ LONGLONG pcount = 0; /* number of group parameters (usually 0) */ LONGLONG gcount = 1; /* number of random groups (usually 1 or 0) */ int extend = 1; /* may FITS file have extensions? */ ffphprll(fptr, simple, bitpix, naxis, naxes, pcount, gcount, extend, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffphpr( fitsfile *fptr, /* I - FITS file pointer */ int simple, /* I - does file conform to FITS standard? 1/0 */ int bitpix, /* I - number of bits per data value pixel */ int naxis, /* I - number of axes in the data array */ long naxes[], /* I - length of each data axis */ LONGLONG pcount, /* I - number of group parameters (usually 0) */ LONGLONG gcount, /* I - number of random groups (usually 1 or 0) */ int extend, /* I - may FITS file have extensions? */ int *status) /* IO - error status */ /* write required primary header keywords */ { int ii; LONGLONG naxesll[20]; for (ii = 0; (ii < naxis) && (ii < 20); ii++) naxesll[ii] = naxes[ii]; ffphprll(fptr, simple, bitpix, naxis, naxesll, pcount, gcount, extend, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffphprll( fitsfile *fptr, /* I - FITS file pointer */ int simple, /* I - does file conform to FITS standard? 1/0 */ int bitpix, /* I - number of bits per data value pixel */ int naxis, /* I - number of axes in the data array */ LONGLONG naxes[], /* I - length of each data axis */ LONGLONG pcount, /* I - number of group parameters (usually 0) */ LONGLONG gcount, /* I - number of random groups (usually 1 or 0) */ int extend, /* I - may FITS file have extensions? */ int *status) /* IO - error status */ /* write required primary header keywords */ { int ii; long longbitpix, tnaxes[20]; char name[FLEN_KEYWORD], comm[FLEN_COMMENT], message[FLEN_ERRMSG]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ((fptr->Fptr)->headend != (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) return(*status = HEADER_NOT_EMPTY); if (naxis != 0) /* never try to compress a null image */ { if ( (fptr->Fptr)->request_compress_type ) { for (ii = 0; ii < naxis; ii++) tnaxes[ii] = (long) naxes[ii]; /* write header for a compressed image */ imcomp_init_table(fptr, bitpix, naxis, tnaxes, 1, status); return(*status); } } if ((fptr->Fptr)->curhdu == 0) { /* write primary array header */ if (simple) strcpy(comm, "file does conform to FITS standard"); else strcpy(comm, "file does not conform to FITS standard"); ffpkyl(fptr, "SIMPLE", simple, comm, status); } else { /* write IMAGE extension header */ strcpy(comm, "IMAGE extension"); ffpkys(fptr, "XTENSION", "IMAGE", comm, status); } longbitpix = bitpix; /* test for the 3 special cases that represent unsigned integers */ if (longbitpix == USHORT_IMG) longbitpix = SHORT_IMG; else if (longbitpix == ULONG_IMG) longbitpix = LONG_IMG; else if (longbitpix == SBYTE_IMG) longbitpix = BYTE_IMG; if (longbitpix != BYTE_IMG && longbitpix != SHORT_IMG && longbitpix != LONG_IMG && longbitpix != LONGLONG_IMG && longbitpix != FLOAT_IMG && longbitpix != DOUBLE_IMG) { sprintf(message, "Illegal value for BITPIX keyword: %d", bitpix); ffpmsg(message); return(*status = BAD_BITPIX); } strcpy(comm, "number of bits per data pixel"); if (ffpkyj(fptr, "BITPIX", longbitpix, comm, status) > 0) return(*status); if (naxis < 0 || naxis > 999) { sprintf(message, "Illegal value for NAXIS keyword: %d", naxis); ffpmsg(message); return(*status = BAD_NAXIS); } strcpy(comm, "number of data axes"); ffpkyj(fptr, "NAXIS", naxis, comm, status); strcpy(comm, "length of data axis "); for (ii = 0; ii < naxis; ii++) { if (naxes[ii] < 0) { sprintf(message, "Illegal negative value for NAXIS%d keyword: %.0f", ii + 1, (double) (naxes[ii])); ffpmsg(message); return(*status = BAD_NAXES); } sprintf(&comm[20], "%d", ii + 1); ffkeyn("NAXIS", ii + 1, name, status); ffpkyj(fptr, name, naxes[ii], comm, status); } if ((fptr->Fptr)->curhdu == 0) /* the primary array */ { if (extend) { /* only write EXTEND keyword if value = true */ strcpy(comm, "FITS dataset may contain extensions"); ffpkyl(fptr, "EXTEND", extend, comm, status); } if (pcount < 0) { ffpmsg("pcount value is less than 0"); return(*status = BAD_PCOUNT); } else if (gcount < 1) { ffpmsg("gcount value is less than 1"); return(*status = BAD_GCOUNT); } else if (pcount > 0 || gcount > 1) { /* only write these keyword if non-standard values */ strcpy(comm, "random group records are present"); ffpkyl(fptr, "GROUPS", 1, comm, status); strcpy(comm, "number of random group parameters"); ffpkyj(fptr, "PCOUNT", pcount, comm, status); strcpy(comm, "number of random groups"); ffpkyj(fptr, "GCOUNT", gcount, comm, status); } /* write standard block of self-documentating comments */ ffprec(fptr, "COMMENT FITS (Flexible Image Transport System) format is defined in 'Astronomy", status); ffprec(fptr, "COMMENT and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H", status); } else /* an IMAGE extension */ { /* image extension; cannot have random groups */ if (pcount != 0) { ffpmsg("image extensions must have pcount = 0"); *status = BAD_PCOUNT; } else if (gcount != 1) { ffpmsg("image extensions must have gcount = 1"); *status = BAD_GCOUNT; } else { strcpy(comm, "required keyword; must = 0"); ffpkyj(fptr, "PCOUNT", 0, comm, status); strcpy(comm, "required keyword; must = 1"); ffpkyj(fptr, "GCOUNT", 1, comm, status); } } /* Write the BSCALE and BZERO keywords, if an unsigned integer image */ if (bitpix == USHORT_IMG) { strcpy(comm, "offset data range to that of unsigned short"); ffpkyg(fptr, "BZERO", 32768., 0, comm, status); strcpy(comm, "default scaling factor"); ffpkyg(fptr, "BSCALE", 1.0, 0, comm, status); } else if (bitpix == ULONG_IMG) { strcpy(comm, "offset data range to that of unsigned long"); ffpkyg(fptr, "BZERO", 2147483648., 0, comm, status); strcpy(comm, "default scaling factor"); ffpkyg(fptr, "BSCALE", 1.0, 0, comm, status); } else if (bitpix == SBYTE_IMG) { strcpy(comm, "offset data range to that of signed byte"); ffpkyg(fptr, "BZERO", -128., 0, comm, status); strcpy(comm, "default scaling factor"); ffpkyg(fptr, "BSCALE", 1.0, 0, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffphtb(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG naxis1, /* I - width of row in the table */ LONGLONG naxis2, /* I - number of rows in the table */ int tfields, /* I - number of columns in the table */ char **ttype, /* I - name of each column */ long *tbcol, /* I - byte offset in row to each column */ char **tform, /* I - value of TFORMn keyword for each column */ char **tunit, /* I - value of TUNITn keyword for each column */ char *extnm, /* I - value of EXTNAME keyword, if any */ int *status) /* IO - error status */ /* Put required Header keywords into the ASCII TaBle: */ { int ii, ncols, gotmem = 0; long rowlen; /* must be 'long' because it is passed to ffgabc */ char tfmt[30], name[FLEN_KEYWORD], comm[FLEN_COMMENT]; if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (*status > 0) return(*status); else if ((fptr->Fptr)->headend != (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) return(*status = HEADER_NOT_EMPTY); else if (naxis1 < 0) return(*status = NEG_WIDTH); else if (naxis2 < 0) return(*status = NEG_ROWS); else if (tfields < 0 || tfields > 999) return(*status = BAD_TFIELDS); rowlen = (long) naxis1; if (!tbcol || !tbcol[0] || (!naxis1 && tfields)) /* spacing not defined? */ { /* allocate mem for tbcol; malloc can have problems allocating small */ /* arrays, so allocate at least 20 bytes */ ncols = maxvalue(5, tfields); tbcol = (long *) calloc(ncols, sizeof(long)); if (tbcol) { gotmem = 1; /* calculate width of a row and starting position of each column. */ /* Each column will be separated by 1 blank space */ ffgabc(tfields, tform, 1, &rowlen, tbcol, status); } } ffpkys(fptr, "XTENSION", "TABLE", "ASCII table extension", status); ffpkyj(fptr, "BITPIX", 8, "8-bit ASCII characters", status); ffpkyj(fptr, "NAXIS", 2, "2-dimensional ASCII table", status); ffpkyj(fptr, "NAXIS1", rowlen, "width of table in characters", status); ffpkyj(fptr, "NAXIS2", naxis2, "number of rows in table", status); ffpkyj(fptr, "PCOUNT", 0, "no group parameters (required keyword)", status); ffpkyj(fptr, "GCOUNT", 1, "one data group (required keyword)", status); ffpkyj(fptr, "TFIELDS", tfields, "number of fields in each row", status); for (ii = 0; ii < tfields; ii++) /* loop over every column */ { if ( *(ttype[ii]) ) /* optional TTYPEn keyword */ { sprintf(comm, "label for field %3d", ii + 1); ffkeyn("TTYPE", ii + 1, name, status); ffpkys(fptr, name, ttype[ii], comm, status); } if (tbcol[ii] < 1 || tbcol[ii] > rowlen) *status = BAD_TBCOL; sprintf(comm, "beginning column of field %3d", ii + 1); ffkeyn("TBCOL", ii + 1, name, status); ffpkyj(fptr, name, tbcol[ii], comm, status); strcpy(tfmt, tform[ii]); /* required TFORMn keyword */ ffupch(tfmt); ffkeyn("TFORM", ii + 1, name, status); ffpkys(fptr, name, tfmt, "Fortran-77 format of field", status); if (tunit) { if (tunit[ii] && *(tunit[ii]) ) /* optional TUNITn keyword */ { ffkeyn("TUNIT", ii + 1, name, status); ffpkys(fptr, name, tunit[ii], "physical unit of field", status) ; } } if (*status > 0) break; /* abort loop on error */ } if (extnm) { if (extnm[0]) /* optional EXTNAME keyword */ ffpkys(fptr, "EXTNAME", extnm, "name of this ASCII table extension", status); } if (*status > 0) ffpmsg("Failed to write ASCII table header keywords (ffphtb)"); if (gotmem) free(tbcol); return(*status); } /*--------------------------------------------------------------------------*/ int ffphbn(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG naxis2, /* I - number of rows in the table */ int tfields, /* I - number of columns in the table */ char **ttype, /* I - name of each column */ char **tform, /* I - value of TFORMn keyword for each column */ char **tunit, /* I - value of TUNITn keyword for each column */ char *extnm, /* I - value of EXTNAME keyword, if any */ LONGLONG pcount, /* I - size of the variable length heap area */ int *status) /* IO - error status */ /* Put required Header keywords into the Binary Table: */ { int ii, datatype, iread = 0; long repeat, width; LONGLONG naxis1; char tfmt[30], name[FLEN_KEYWORD], comm[FLEN_COMMENT]; char *cptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ((fptr->Fptr)->headend != (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) return(*status = HEADER_NOT_EMPTY); else if (naxis2 < 0) return(*status = NEG_ROWS); else if (pcount < 0) return(*status = BAD_PCOUNT); else if (tfields < 0 || tfields > 999) return(*status = BAD_TFIELDS); ffpkys(fptr, "XTENSION", "BINTABLE", "binary table extension", status); ffpkyj(fptr, "BITPIX", 8, "8-bit bytes", status); ffpkyj(fptr, "NAXIS", 2, "2-dimensional binary table", status); naxis1 = 0; for (ii = 0; ii < tfields; ii++) /* sum the width of each field */ { ffbnfm(tform[ii], &datatype, &repeat, &width, status); if (datatype == TSTRING) naxis1 += repeat; /* one byte per char */ else if (datatype == TBIT) naxis1 += (repeat + 7) / 8; else if (datatype > 0) naxis1 += repeat * (datatype / 10); else if (tform[ii][0] == 'P' || tform[ii][1] == 'P') /* this is a 'P' variable length descriptor (neg. datatype) */ naxis1 += 8; else /* this is a 'Q' variable length descriptor (neg. datatype) */ naxis1 += 16; if (*status > 0) break; /* abort loop on error */ } ffpkyj(fptr, "NAXIS1", naxis1, "width of table in bytes", status); ffpkyj(fptr, "NAXIS2", naxis2, "number of rows in table", status); /* the initial value of PCOUNT (= size of the variable length array heap) should always be zero. If any variable length data is written, then the value of PCOUNT will be updated when the HDU is closed */ ffpkyj(fptr, "PCOUNT", 0, "size of special data area", status); ffpkyj(fptr, "GCOUNT", 1, "one data group (required keyword)", status); ffpkyj(fptr, "TFIELDS", tfields, "number of fields in each row", status); for (ii = 0; ii < tfields; ii++) /* loop over every column */ { if ( *(ttype[ii]) ) /* optional TTYPEn keyword */ { sprintf(comm, "label for field %3d", ii + 1); ffkeyn("TTYPE", ii + 1, name, status); ffpkys(fptr, name, ttype[ii], comm, status); } strcpy(tfmt, tform[ii]); /* required TFORMn keyword */ ffupch(tfmt); ffkeyn("TFORM", ii + 1, name, status); strcpy(comm, "data format of field"); ffbnfm(tfmt, &datatype, &repeat, &width, status); if (datatype == TSTRING) { strcat(comm, ": ASCII Character"); /* Do sanity check to see if an ASCII table format was used, */ /* e.g., 'A8' instead of '8A', or a bad unit width eg '8A9'. */ /* Don't want to return an error status, so write error into */ /* the keyword comment. */ cptr = strchr(tfmt,'A'); cptr++; if (cptr) iread = sscanf(cptr,"%ld", &width); if (iread == 1 && (width > repeat)) { if (repeat == 1) strcpy(comm, "ERROR?? USING ASCII TABLE SYNTAX BY MISTAKE??"); else strcpy(comm, "rAw FORMAT ERROR! UNIT WIDTH w > COLUMN WIDTH r"); } } else if (datatype == TBIT) strcat(comm, ": BIT"); else if (datatype == TBYTE) strcat(comm, ": BYTE"); else if (datatype == TLOGICAL) strcat(comm, ": 1-byte LOGICAL"); else if (datatype == TSHORT) strcat(comm, ": 2-byte INTEGER"); else if (datatype == TUSHORT) strcat(comm, ": 2-byte INTEGER"); else if (datatype == TLONG) strcat(comm, ": 4-byte INTEGER"); else if (datatype == TLONGLONG) strcat(comm, ": 8-byte INTEGER"); else if (datatype == TULONG) strcat(comm, ": 4-byte INTEGER"); else if (datatype == TFLOAT) strcat(comm, ": 4-byte REAL"); else if (datatype == TDOUBLE) strcat(comm, ": 8-byte DOUBLE"); else if (datatype == TCOMPLEX) strcat(comm, ": COMPLEX"); else if (datatype == TDBLCOMPLEX) strcat(comm, ": DOUBLE COMPLEX"); else if (datatype < 0) strcat(comm, ": variable length array"); if (abs(datatype) == TSBYTE) /* signed bytes */ { /* Replace the 'S' with an 'B' in the TFORMn code */ cptr = tfmt; while (*cptr != 'S') cptr++; *cptr = 'B'; ffpkys(fptr, name, tfmt, comm, status); /* write the TZEROn and TSCALn keywords */ ffkeyn("TZERO", ii + 1, name, status); strcpy(comm, "offset for signed bytes"); ffpkyg(fptr, name, -128., 0, comm, status); ffkeyn("TSCAL", ii + 1, name, status); strcpy(comm, "data are not scaled"); ffpkyg(fptr, name, 1., 0, comm, status); } else if (abs(datatype) == TUSHORT) { /* Replace the 'U' with an 'I' in the TFORMn code */ cptr = tfmt; while (*cptr != 'U') cptr++; *cptr = 'I'; ffpkys(fptr, name, tfmt, comm, status); /* write the TZEROn and TSCALn keywords */ ffkeyn("TZERO", ii + 1, name, status); strcpy(comm, "offset for unsigned integers"); ffpkyg(fptr, name, 32768., 0, comm, status); ffkeyn("TSCAL", ii + 1, name, status); strcpy(comm, "data are not scaled"); ffpkyg(fptr, name, 1., 0, comm, status); } else if (abs(datatype) == TULONG) { /* Replace the 'V' with an 'J' in the TFORMn code */ cptr = tfmt; while (*cptr != 'V') cptr++; *cptr = 'J'; ffpkys(fptr, name, tfmt, comm, status); /* write the TZEROn and TSCALn keywords */ ffkeyn("TZERO", ii + 1, name, status); strcpy(comm, "offset for unsigned integers"); ffpkyg(fptr, name, 2147483648., 0, comm, status); ffkeyn("TSCAL", ii + 1, name, status); strcpy(comm, "data are not scaled"); ffpkyg(fptr, name, 1., 0, comm, status); } else { ffpkys(fptr, name, tfmt, comm, status); } if (tunit) { if (tunit[ii] && *(tunit[ii]) ) /* optional TUNITn keyword */ { ffkeyn("TUNIT", ii + 1, name, status); ffpkys(fptr, name, tunit[ii], "physical unit of field", status); } } if (*status > 0) break; /* abort loop on error */ } if (extnm) { if (extnm[0]) /* optional EXTNAME keyword */ ffpkys(fptr, "EXTNAME", extnm, "name of this binary table extension", status); } if (*status > 0) ffpmsg("Failed to write binary table header keywords (ffphbn)"); return(*status); } /*--------------------------------------------------------------------------*/ int ffphext(fitsfile *fptr, /* I - FITS file pointer */ char *xtension, /* I - value for the XTENSION keyword */ int bitpix, /* I - value for the BIXPIX keyword */ int naxis, /* I - value for the NAXIS keyword */ long naxes[], /* I - value for the NAXISn keywords */ LONGLONG pcount, /* I - value for the PCOUNT keyword */ LONGLONG gcount, /* I - value for the GCOUNT keyword */ int *status) /* IO - error status */ /* Put required Header keywords into a conforming extension: */ { char message[FLEN_ERRMSG],comm[81], name[20]; int ii; if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (*status > 0) return(*status); else if ((fptr->Fptr)->headend != (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) return(*status = HEADER_NOT_EMPTY); if (naxis < 0 || naxis > 999) { sprintf(message, "Illegal value for NAXIS keyword: %d", naxis); ffpmsg(message); return(*status = BAD_NAXIS); } ffpkys(fptr, "XTENSION", xtension, "extension type", status); ffpkyj(fptr, "BITPIX", bitpix, "number of bits per data pixel", status); ffpkyj(fptr, "NAXIS", naxis, "number of data axes", status); strcpy(comm, "length of data axis "); for (ii = 0; ii < naxis; ii++) { if (naxes[ii] < 0) { sprintf(message, "Illegal negative value for NAXIS%d keyword: %.0f", ii + 1, (double) (naxes[ii])); ffpmsg(message); return(*status = BAD_NAXES); } sprintf(&comm[20], "%d", ii + 1); ffkeyn("NAXIS", ii + 1, name, status); ffpkyj(fptr, name, naxes[ii], comm, status); } ffpkyj(fptr, "PCOUNT", pcount, " ", status); ffpkyj(fptr, "GCOUNT", gcount, " ", status); if (*status > 0) ffpmsg("Failed to write extension header keywords (ffphext)"); return(*status); } /*--------------------------------------------------------------------------*/ int ffi2c(LONGLONG ival, /* I - value to be converted to a string */ char *cval, /* O - character string representation of the value */ int *status) /* IO - error status */ /* convert value to a null-terminated formatted string. */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); cval[0] = '\0'; #if defined(_MSC_VER) /* Microsoft Visual C++ 6.0 uses '%I64d' syntax for 8-byte integers */ if (sprintf(cval, "%I64d", ival) < 0) #elif (USE_LL_SUFFIX == 1) if (sprintf(cval, "%lld", ival) < 0) #else if (sprintf(cval, "%ld", ival) < 0) #endif { ffpmsg("Error in ffi2c converting integer to string"); *status = BAD_I2C; } return(*status); } /*--------------------------------------------------------------------------*/ int ffl2c(int lval, /* I - value to be converted to a string */ char *cval, /* O - character string representation of the value */ int *status) /* IO - error status ) */ /* convert logical value to a null-terminated formatted string. If the input value == 0, then the output character is the letter F, else the output character is the letter T. The output string is null terminated. */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (lval) strcpy(cval,"T"); else strcpy(cval,"F"); return(*status); } /*--------------------------------------------------------------------------*/ int ffs2c(char *instr, /* I - null terminated input string */ char *outstr, /* O - null terminated quoted output string */ int *status) /* IO - error status */ /* convert an input string to a quoted string. Leading spaces are significant. FITS string keyword values must be at least 8 chars long so pad out string with spaces if necessary. Example: km/s ==> 'km/s ' Single quote characters in the input string will be replace by two single quote characters. e.g., o'brian ==> 'o''brian' */ { size_t len, ii, jj; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (!instr) /* a null input pointer?? */ { strcpy(outstr, "''"); /* a null FITS string */ return(*status); } outstr[0] = '\''; /* start output string with a quote */ len = strlen(instr); if (len > 68) len = 68; /* limit input string to 68 chars */ for (ii=0, jj=1; ii < len && jj < 69; ii++, jj++) { outstr[jj] = instr[ii]; /* copy each char from input to output */ if (instr[ii] == '\'') { jj++; outstr[jj]='\''; /* duplicate any apostrophies in the input */ } } for (; jj < 9; jj++) /* pad string so it is at least 8 chars long */ outstr[jj] = ' '; if (jj == 70) /* only occurs if the last char of string was a quote */ outstr[69] = '\0'; else { outstr[jj] = '\''; /* append closing quote character */ outstr[jj+1] = '\0'; /* terminate the string */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffr2f(float fval, /* I - value to be converted to a string */ int decim, /* I - number of decimal places to display */ char *cval, /* O - character string representation of the value */ int *status) /* IO - error status */ /* convert float value to a null-terminated F format string */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); cval[0] = '\0'; if (decim < 0) { ffpmsg("Error in ffr2f: no. of decimal places < 0"); return(*status = BAD_DECIM); } if (sprintf(cval, "%.*f", decim, fval) < 0) { ffpmsg("Error in ffr2f converting float to string"); *status = BAD_F2C; } /* test if output string is 'NaN', 'INDEF', or 'INF' */ if (strchr(cval, 'N')) { ffpmsg("Error in ffr2f: float value is a NaN or INDEF"); *status = BAD_F2C; } return(*status); } /*--------------------------------------------------------------------------*/ int ffr2e(float fval, /* I - value to be converted to a string */ int decim, /* I - number of decimal places to display */ char *cval, /* O - character string representation of the value */ int *status) /* IO - error status */ /* convert float value to a null-terminated exponential format string */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); cval[0] = '\0'; if (decim < 0) { /* use G format if decim is negative */ if ( sprintf(cval, "%.*G", -decim, fval) < 0) { ffpmsg("Error in ffr2e converting float to string"); *status = BAD_F2C; } else { /* test if E format was used, and there is no displayed decimal */ if ( !strchr(cval, '.') && strchr(cval,'E') ) { /* reformat value with a decimal point and single zero */ if ( sprintf(cval, "%.1E", fval) < 0) { ffpmsg("Error in ffr2e converting float to string"); *status = BAD_F2C; } return(*status); } } } else { if ( sprintf(cval, "%.*E", decim, fval) < 0) { ffpmsg("Error in ffr2e converting float to string"); *status = BAD_F2C; } } if (*status <= 0) { /* test if output string is 'NaN', 'INDEF', or 'INF' */ if (strchr(cval, 'N')) { ffpmsg("Error in ffr2e: float value is a NaN or INDEF"); *status = BAD_F2C; } else if ( !strchr(cval, '.') && !strchr(cval,'E') ) { /* add decimal point if necessary to distinquish from integer */ strcat(cval, "."); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffd2f(double dval, /* I - value to be converted to a string */ int decim, /* I - number of decimal places to display */ char *cval, /* O - character string representation of the value */ int *status) /* IO - error status */ /* convert double value to a null-terminated F format string */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); cval[0] = '\0'; if (decim < 0) { ffpmsg("Error in ffd2f: no. of decimal places < 0"); return(*status = BAD_DECIM); } if (sprintf(cval, "%.*f", decim, dval) < 0) { ffpmsg("Error in ffd2f converting double to string"); *status = BAD_F2C; } /* test if output string is 'NaN', 'INDEF', or 'INF' */ if (strchr(cval, 'N')) { ffpmsg("Error in ffd2f: double value is a NaN or INDEF"); *status = BAD_F2C; } return(*status); } /*--------------------------------------------------------------------------*/ int ffd2e(double dval, /* I - value to be converted to a string */ int decim, /* I - number of decimal places to display */ char *cval, /* O - character string representation of the value */ int *status) /* IO - error status */ /* convert double value to a null-terminated exponential format string. */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); cval[0] = '\0'; if (decim < 0) { /* use G format if decim is negative */ if ( sprintf(cval, "%.*G", -decim, dval) < 0) { ffpmsg("Error in ffd2e converting float to string"); *status = BAD_F2C; } else { /* test if E format was used, and there is no displayed decimal */ if ( !strchr(cval, '.') && strchr(cval,'E') ) { /* reformat value with a decimal point and single zero */ if ( sprintf(cval, "%.1E", dval) < 0) { ffpmsg("Error in ffd2e converting float to string"); *status = BAD_F2C; } return(*status); } } } else { if ( sprintf(cval, "%.*E", decim, dval) < 0) { ffpmsg("Error in ffd2e converting float to string"); *status = BAD_F2C; } } if (*status <= 0) { /* test if output string is 'NaN', 'INDEF', or 'INF' */ if (strchr(cval, 'N')) { ffpmsg("Error in ffd2e: double value is a NaN or INDEF"); *status = BAD_F2C; } else if ( !strchr(cval, '.') && !strchr(cval,'E') ) { /* add decimal point if necessary to distinquish from integer */ strcat(cval, "."); } } return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/quantize.c000066400000000000000000000605251215713201500224440ustar00rootroot00000000000000/* The following code was written by Richard White at STScI and made available for use in CFITSIO in July 1999. */ # include # include # include #include "fitsio2.h" /* nearest integer function */ # define NINT(x) ((x >= 0.) ? (int) (x + 0.5) : (int) (x - 0.5)) # define SORT_CUTOFF 100 /* used by xMedian */ # define NELEM 5 /* used by xMedian */ #define NULL_VALUE -2147483647 /* value used to represent undefined pixels */ #define N_RESERVED_VALUES 1 /* number of reserved values, starting with */ /* and including NULL_VALUE. These values */ /* may not be used to represent the quantized */ /* and scaled floating point pixel values */ /* factor to convert from median deviation to rms */ # define MEDIAN_TO_RMS 1.4826 /* more than this many standard deviations from the mean is an outlier */ # define SIGMA_CLIP 5. # define NITER 3 /* number of sigma-clipping iterations */ static float xMedian (float [], int); static void InsertionSort (float x[], int); static int FqCompare (const void *, const void *); static void FqMean (float [], int, double *, double *); /*---------------------------------------------------------------------------*/ /* this routine used to be called 'quantize' (WDP) */ int fits_quantize_float (float fdata[], int nx, float in_null_value, int noise_bits, int idata[], double *bscale, double *bzero, int *iminval, int *imaxval) { /* arguments: float fdata[] i: array of image pixels to be compressed int nx i: length of fdata array float in_null_value i: value used to represent undefined pixels in fdata int noise_bits i: quantization level (number of bits) int idata[] o: values of fdata after applying bzero and bscale double bscale o: scale factor double bzero o: zero offset int iminval o: minimum quantized value that is returned int imaxval o: maximum quantized value that is returned The function value will be one if the input fdata were copied to idata; in this case the parameters bscale and bzero can be used to convert back to nearly the original floating point values: fdata ~= idata * bscale + bzero. If the function value is zero, the data were not copied to idata. */ float *diff; /* difference array */ int ndiff; /* size of diff array */ int intflag; /* true if data are really integer */ int i, j, iter; /* loop indices */ int anynulls = 0; /* set if fdata contains any null values */ int nshift, itemp; int first_nonnull = 0; double mean, stdev; /* mean and RMS of differences */ double minval = 0., maxval = 0.; /* min & max of fdata */ double delta; /* bscale, 1 in idata = delta in fdata */ double zeropt; /* bzero */ double median; /* median of diff array */ double temp; if (nx <= 1) { *bscale = 1.; *bzero = 0.; return (0); } *iminval = INT32_MAX; *imaxval = INT32_MIN; /* Check to see if data are "floating point integer." */ /* This also catches the case where all the pixels are null */ /* Since idata and fdata may point to the same memory location, */ /* we cannot write to idata unless we are sure we don't need */ /* the corresponding float value any more */ intflag = 1; /* initial value */ for (i = 0; i < nx; i++) { if (fdata[i] == in_null_value) { anynulls = 1; } else if (fdata[i] > INT32_MAX || fdata[i] < NULL_VALUE + N_RESERVED_VALUES) { intflag = 0; /* not integer */ break; } else { itemp = (int)(fdata[i] + 0.5); if (itemp != fdata[i]) { intflag = 0; /* not integer */ break; } } } if (intflag) { /* data are "floating point integer" */ for (i = 0; i < nx; i++) { if (fdata[i] == in_null_value) { idata[i] = NULL_VALUE; anynulls = 1; } else { idata[i] = (int)(fdata[i] + 0.5); *iminval = minvalue(idata[i], *iminval); *imaxval = maxvalue(idata[i], *imaxval); } } } if (intflag) { /* data are "floating point integer" */ if (anynulls) { /* Shift the range of values so they lie close to NULL_VALUE. */ /* This will make the compression more efficient. */ /* Maximum allowed shift is 2^31 - 1 = 2147483646 */ /* Can't use 2147483647 because OSF says this is not a legal number */ if (*iminval >= 0) { nshift = -(NULL_VALUE + 1) - N_RESERVED_VALUES; } else { nshift = *iminval - NULL_VALUE - N_RESERVED_VALUES; } for (i = 0; i < nx; i++) { if (idata[i] != NULL_VALUE) { idata[i] -= nshift; } } *iminval = *iminval - nshift; *imaxval = *imaxval - nshift; *bscale = 1.; *bzero = (double) nshift; } else { /* there were no null values, so no need to shift the range */ *bscale = 1.; *bzero = 0.; } return (1); } /* data are not "floating point integer"; need to quantize them */ /* find first non-null pixel, and initialize min and max values */ for (i = 0; i < nx; i++) { if (fdata[i] != in_null_value) { minval = fdata[i]; maxval = fdata[i]; first_nonnull = i; break; } } /* allocate temporary buffer for differences */ ndiff = nx - first_nonnull - 1; if ((diff = (float *) malloc (ndiff * sizeof (float))) == NULL) { ffpmsg("Out of memory in 'fits_quantize_float'."); return (0); } /* calc ABS difference between successive non-null pixels */ j = first_nonnull; ndiff = 0; for (i = j + 1 ; i < nx; i++) { if (fdata[i] != in_null_value) { diff[ndiff] = (float) (fabs (fdata[i] - fdata[j])); j = i; ndiff++; minval = minvalue(minval, fdata[i]); maxval = maxvalue(maxval, fdata[i]); } } /* check if there were any null values */ if (ndiff + 1 == nx) anynulls = 0; else anynulls = 1; /* use median of absolute deviations */ median = xMedian (diff, ndiff); stdev = median * MEDIAN_TO_RMS; /* substitute sigma-clipping if median is zero */ if (stdev == 0.0) { /* calculate differences between non-null pixels */ j = first_nonnull; ndiff = 0; for (i = j + 1 ; i < nx; i++) { if (fdata[i] != in_null_value) { diff[ndiff] = fdata[i] - fdata[j]; j = i; ndiff++; } } FqMean (diff, ndiff, &mean, &stdev); for (iter = 0; iter < NITER; iter++) { j = 0; for (i = 0; i < ndiff; i++) { if (fabs (diff[i] - mean) < SIGMA_CLIP * stdev) { if (j < i) diff[j] = diff[i]; j++; } } if (j == ndiff) break; ndiff = j; FqMean (diff, ndiff, &mean, &stdev); } } free (diff); delta = stdev / pow (2., (double)noise_bits); if (delta == 0. && ndiff > 0) return (0); /* Zero variance in differences! Don't quantize. */ /* check that the range of quantized levels is not > range of int */ if ((maxval - minval) / delta > 2. * 2147483647. - N_RESERVED_VALUES ) return (0); /* don't quantize */ if (!anynulls) { /* don't have to check for nulls */ /* return all positive values, if possible since some */ /* compression algorithms either only work for positive integers, */ /* or are more efficient. */ if ((maxval - minval) / delta < 2147483647. - N_RESERVED_VALUES ) { zeropt = minval; } else { /* center the quantized levels around zero */ zeropt = (minval + maxval) / 2.; } for (i = 0; i < nx; i++) { temp = (fdata[i] - zeropt) / delta; idata[i] = NINT (temp); } } else { /* data contains null values; shift the range to be */ /* close to the value used to represent null values */ zeropt = minval - delta * (NULL_VALUE + N_RESERVED_VALUES); for (i = 0; i < nx; i++) { if (fdata[i] != in_null_value) { temp = (fdata[i] - zeropt) / delta; idata[i] = NINT (temp); } else idata[i] = NULL_VALUE; } } /* calc min and max values */ temp = (minval - zeropt) / delta; *iminval = NINT (temp); temp = (maxval - zeropt) / delta; *imaxval = NINT (temp); *bscale = delta; *bzero = zeropt; return (1); /* yes, data have been quantized */ } /*---------------------------------------------------------------------------*/ int fits_quantize_double (double fdata[], int nx, double in_null_value, int noise_bits, int idata[], double *bscale, double *bzero, int *iminval, int *imaxval) { /* arguments: double fdata[] i: array of image pixels to be compressed int nx i: length of fdata array double in_null_value i: value used to represent undefined pixels in fdata int noise_bits i: quantization level (number of bits) int idata[] o: values of fdata after applying bzero and bscale double bscale o: scale factor double bzero o: zero offset int imaxval o: maximum quantized value that is returned int iminval o: minimum quantized value that is returned The function value will be one if the input fdata were copied to idata; in this case the parameters bscale and bzero can be used to convert back to nearly the original floating point values: fdata ~= idata * bscale + bzero. If the function value is zero, the data were not copied to idata. */ float *diff; /* difference array */ int ndiff; /* size of diff array */ int intflag; /* true if data are really integer */ int i, j, iter; /* loop indices */ int anynulls = 0; /* set if fdata contains any null values */ int nshift, itemp; int first_nonnull = 0; double mean, stdev; /* mean and RMS of differences */ double minval = 0., maxval = 0.; /* min & max of fdata */ double delta; /* bscale, 1 in idata = delta in fdata */ double zeropt; /* bzero */ double median; /* median of diff array */ double temp; if (nx <= 1) { *bscale = 1.; *bzero = 0.; return (0); } *iminval = INT32_MAX; *imaxval = INT32_MIN; /* Check to see if data are "floating point integer." */ /* This also catches the case where all the pixels are null */ /* Since idata and fdata may point to the same memory location, */ /* we cannot write to idata unless we are sure we don't need */ /* the corresponding float value any more */ intflag = 1; /* initial value */ for (i = 0; i < nx; i++) { if (fdata[i] == in_null_value) { anynulls = 1; } else if (fdata[i] > INT32_MAX || fdata[i] < NULL_VALUE + N_RESERVED_VALUES) { intflag = 0; /* not integer */ break; } else { itemp = (int)(fdata[i] + 0.5); if (itemp != fdata[i]) { intflag = 0; /* not integer */ break; } } } if (intflag) { /* data are "floating point integer" */ for (i = 0; i < nx; i++) { if (fdata[i] == in_null_value) { idata[i] = NULL_VALUE; anynulls = 1; } else { idata[i] = (int)(fdata[i] + 0.5); *iminval = minvalue(idata[i], *iminval); *imaxval = maxvalue(idata[i], *imaxval); } } } if (intflag) { /* data are "floating point integer" */ if (anynulls) { /* Shift the range of values so they lie close to NULL_VALUE. */ /* This will make the compression more efficient. */ /* Maximum allowed shift is 2^31 - 1 = 2147483646 */ /* Can't use 2147483647 because OSF says this is not a legal number */ if (*iminval >= 0) { nshift = -(NULL_VALUE +1) - N_RESERVED_VALUES; } else { nshift = *iminval - NULL_VALUE - N_RESERVED_VALUES; } for (i = 0; i < nx; i++) { if (idata[i] != NULL_VALUE) { idata[i] -= nshift; } } *iminval = *iminval - nshift; *imaxval = *imaxval - nshift; *bscale = 1.; *bzero = (double) nshift; } else { /* there were no null values, so no need to shift the range */ *bscale = 1.; *bzero = 0.; } return (1); } /* data are not "floating point integer"; need to quantize them */ /* find first non-null pixel, and initialize min and max values */ for (i = 0; i < nx; i++) { if (fdata[i] != in_null_value) { minval = fdata[i]; maxval = fdata[i]; first_nonnull = i; break; } } /* allocate temporary buffer for differences */ ndiff = nx - first_nonnull - 1; if ((diff = (float *) malloc (ndiff * sizeof (float))) == NULL) { ffpmsg("Out of memory in 'fits_quantize_double'."); return (0); } /* calc ABS difference between successive non-null pixels */ j = first_nonnull; ndiff = 0; for (i = j + 1 ; i < nx; i++) { if (fdata[i] != in_null_value) { diff[ndiff] = (float) (fabs (fdata[i] - fdata[j])); j = i; ndiff++; minval = minvalue(minval, fdata[i]); maxval = maxvalue(maxval, fdata[i]); } } /* check if there were any null values */ if (ndiff + 1 == nx) anynulls = 0; else anynulls = 1; /* use median of absolute deviations */ median = xMedian (diff, ndiff); stdev = median * MEDIAN_TO_RMS; /* substitute sigma-clipping if median is zero */ if (stdev == 0.0) { /* calculate differences between non-null pixels */ j = first_nonnull; ndiff = 0; for (i = j + 1 ; i < nx; i++) { if (fdata[i] != in_null_value) { diff[ndiff] = (float) (fdata[i] - fdata[j]); j = i; ndiff++; } } FqMean (diff, ndiff, &mean, &stdev); for (iter = 0; iter < NITER; iter++) { j = 0; for (i = 0; i < ndiff; i++) { if (fabs (diff[i] - mean) < SIGMA_CLIP * stdev) { if (j < i) diff[j] = diff[i]; j++; } } if (j == ndiff) break; ndiff = j; FqMean (diff, ndiff, &mean, &stdev); } } free (diff); delta = stdev / pow (2., (double)noise_bits); if (delta == 0. && ndiff > 0) return (0); /* Zero variance in differences! Don't quantize. */ /* check that the range of quantized levels is not > range of int */ if ((maxval - minval) / delta > 2. * 2147483647 - N_RESERVED_VALUES ) return (0); /* don't quantize */ if (!anynulls) { /* don't have to check for nulls */ /* center the quantized levels around zero */ zeropt = (minval + maxval) / 2.; for (i = 0; i < nx; i++) { temp = (fdata[i] - zeropt) / delta; idata[i] = NINT (temp); } } else { /* data contains null values; shift the range to be */ /* close to the value used to represent null values */ zeropt = minval - delta * (NULL_VALUE + N_RESERVED_VALUES); for (i = 0; i < nx; i++) { if (fdata[i] != in_null_value) { temp = (fdata[i] - zeropt) / delta; idata[i] = NINT (temp); } else idata[i] = NULL_VALUE; } } /* calc min and max values */ temp = (minval - zeropt) / delta; *iminval = NINT (temp); temp = (maxval - zeropt) / delta; *imaxval = NINT (temp); *bscale = delta; *bzero = zeropt; return (1); /* yes, data have been quantized */ } /*---------------------------------------------------------------------------*/ int fits_rms_float (float fdata[], int nx, float in_null_value, double *rms, int *status) { /* Compute the background RMS (noise) in an array of image pixels. arguments: float fdata[] i: array of image pixels int nx i: length of fdata array float in_null_value i: value used to represent undefined pixels in fdata double rms o: computed RMS value */ float *diff; /* difference array */ int ndiff; /* size of diff array */ int i, j, iter; /* loop indices */ int first_nonnull = 0; double mean, stdev; /* mean and RMS of differences */ double median; /* median of diff array */ if (*status) return (*status); if (nx <= 1) { *rms = 0; return (0); } /* find first non-null pixel, and initialize min and max values */ for (i = 0; i < nx; i++) { if (fdata[i] != in_null_value) { first_nonnull = i; break; } } /* allocate temporary buffer for differences */ ndiff = nx - first_nonnull - 1; if ((diff = (float *) malloc (ndiff * sizeof (float))) == NULL) { ffpmsg("Out of memory in 'fits_float_rms'."); *status = 113; /* memory allocation error */ return (0); } /* calc ABS difference between successive non-null pixels */ j = first_nonnull; ndiff = 0; for (i = j + 1 ; i < nx; i++) { if (fdata[i] != in_null_value) { diff[ndiff] = (float) (fabs (fdata[i] - fdata[j])); j = i; ndiff++; } } /* use median of absolute deviations */ median = xMedian (diff, ndiff); stdev = median * MEDIAN_TO_RMS; /* substitute sigma-clipping if median is zero */ if (stdev == 0.0) { /* calculate differences between non-null pixels */ j = first_nonnull; ndiff = 0; for (i = j + 1 ; i < nx; i++) { if (fdata[i] != in_null_value) { diff[ndiff] = fdata[i] - fdata[j]; j = i; ndiff++; } } FqMean (diff, ndiff, &mean, &stdev); for (iter = 0; iter < NITER; iter++) { j = 0; for (i = 0; i < ndiff; i++) { if (fabs (diff[i] - mean) < SIGMA_CLIP * stdev) { if (j < i) diff[j] = diff[i]; j++; } } if (j == ndiff) break; ndiff = j; FqMean (diff, ndiff, &mean, &stdev); } } free (diff); *rms = stdev; return (0); } /*---------------------------------------------------------------------------*/ int fits_rms_short (short fdata[], int nx, short in_null_value, double *rms, int *status) { /* Compute the background RMS (noise) in an array of image pixels. arguments: short fdata[] i: array of image pixels int nx i: length of fdata array short in_null_value i: value used to represent undefined pixels in fdata double rms o: computed RMS value */ float *diff; /* difference array */ int ndiff; /* size of diff array */ int i, j, iter; /* loop indices */ int first_nonnull = 0; double mean, stdev; /* mean and RMS of differences */ double median; /* median of diff array */ if (*status) return (*status); if (nx <= 1) { *rms = 0; return (0); } /* find first non-null pixel, and initialize min and max values */ for (i = 0; i < nx; i++) { if (fdata[i] != in_null_value) { first_nonnull = i; break; } } /* allocate temporary buffer for differences */ ndiff = nx - first_nonnull - 1; if ((diff = (float *) malloc (ndiff * sizeof (float))) == NULL) { ffpmsg("Out of memory in 'fits_float_rms'."); *status = 113; /* memory allocation error */ return (0); } /* calc ABS difference between successive non-null pixels */ j = first_nonnull; ndiff = 0; for (i = j + 1 ; i < nx; i++) { if (fdata[i] != in_null_value) { diff[ndiff] = (float) (abs (fdata[i] - fdata[j])); j = i; ndiff++; } } /* use median of absolute deviations */ median = xMedian (diff, ndiff); stdev = median * MEDIAN_TO_RMS; /* substitute sigma-clipping if median is zero */ if (stdev == 0.0) { /* calculate differences between non-null pixels */ j = first_nonnull; ndiff = 0; for (i = j + 1 ; i < nx; i++) { if (fdata[i] != in_null_value) { diff[ndiff] = (float) (fdata[i] - fdata[j]); j = i; ndiff++; } } FqMean (diff, ndiff, &mean, &stdev); for (iter = 0; iter < NITER; iter++) { j = 0; for (i = 0; i < ndiff; i++) { if (fabs (diff[i] - mean) < SIGMA_CLIP * stdev) { if (j < i) diff[j] = diff[i]; j++; } } if (j == ndiff) break; ndiff = j; FqMean (diff, ndiff, &mean, &stdev); } } free (diff); *rms = stdev; return (0); } /*---------------------------------------------------------------------------*/ /* This computes the mean and standard deviation. */ static void FqMean (float diff[], int ndiff, double *mean, double *stdev) { int i; double sum, sumsq; double m; /* mean */ double xn; /* = ndiff */ double temp; if (ndiff < 2) { if (ndiff < 1) *mean = 0.; else *mean = diff[0]; *stdev = 0.; return; } xn = (double)ndiff; sum = 0.; sumsq = 0.; for (i = 0; i < ndiff; i++) { sum += diff[i]; sumsq += (diff[i] * diff[i]); } m = sum / xn; *mean = m; temp = (sumsq / xn - m*m) * xn; if (temp <= 0) *stdev = 0.; else *stdev = sqrt (temp / (xn-1.)); } /*---------------------------------------------------------------------------*/ /* This returns an approximation to the median. The input array will be clobbered. */ static float xMedian (float x[], int n) { /* arguments: float x[] io: the array (will be scrambled and possibly modified) int n i: number of elements in x (modified locally) */ int i, j; int next_n; int npix; int done; float median = 0.; if (n < 1) { ffpmsg("xMedian: no data"); return (0.); } if (n == 1) return (x[0]); if (n == 2) return ((float) ((x[0] + x[1]) / 2.)); done = 0; while (!done) { if (n < SORT_CUTOFF) { qsort (x, n, sizeof (float), FqCompare); if (n / 2 * 2 == n) median = (float) ((x[n/2-1] + x[n/2]) / 2.); else median = x[n/2]; return (median); } /* ignore trailing groups of less than three elements */ next_n = (n + NELEM-3) / NELEM; for (j = 0; j < next_n; j++) { i = j * NELEM; npix = minvalue (NELEM, n - j*NELEM); InsertionSort (&x[i], npix); switch (npix) { case 1: median = x[i]; break; case 2: median = (float) ((x[i] + x[i+1]) / 2.); break; case 3: median = x[i+1]; break; case 4: median = (float) ((x[i+1] + x[i+2]) / 2.); break; case 5: /* NELEM = 5 */ median = x[i+2]; break; default: ffpmsg("npix should be 1..5"); } x[j] = median; } if (next_n <= 1) done = 1; else n = next_n; } return (x[0]); } /*---------------------------------------------------------------------------*/ static void InsertionSort (float x[], int n) { float a; int i, j; for (j = 1; j < n; j++) { a = x[j]; i = j - 1; while (i >= 0 && x[i] > a) { x[i+1] = x[i]; i--; } x[i+1] = a; } } /*---------------------------------------------------------------------------*/ static int FqCompare (const void *vp, const void *vq) { const float *p = vp; const float *q = vq; if (*p > *q) return (1); else if (*p < *q) return (-1); else return (0); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/region.c000066400000000000000000001040531215713201500220620ustar00rootroot00000000000000#include #include #include #include #include "fitsio2.h" #include "region.h" static int Pt_in_Poly( double x, double y, int nPts, double *Pts ); /*---------------------------------------------------------------------------*/ int ffrrgn( const char *filename, WCSdata *wcs, SAORegion **Rgn, int *status ) /* Read regions from a SAO-style region file and return the information */ /* in the "SAORegion" structure. If it is nonNULL, use wcs to convert the */ /* region coordinates to pixels. Return an error if region is in degrees */ /* but no WCS data is provided. */ /*---------------------------------------------------------------------------*/ { char *currLine; char *namePtr, *paramPtr, *currLoc; char *pX, *pY, *endp; long allocLen, lineLen, hh, mm, dd; double *coords = 0, X, Y, R, x, y, ss, xsave= 0., ysave= 0.; int nParams, nCoords, negdec; int i, done; FILE *rgnFile; coordFmt cFmt; SAORegion *aRgn; RgnShape *newShape, *tmpShape; if( *status ) return( *status ); aRgn = (SAORegion *)malloc( sizeof(SAORegion) ); if( ! aRgn ) { ffpmsg("Couldn't allocate memory to hold Region file contents."); return(*status = MEMORY_ALLOCATION ); } aRgn->nShapes = 0; aRgn->Shapes = NULL; if( wcs && wcs->exists ) aRgn->wcs = *wcs; else aRgn->wcs.exists = 0; cFmt = pixel_fmt; /* set default format */ /* Allocate Line Buffer */ allocLen = 512; currLine = (char *)malloc( allocLen * sizeof(char) ); if( !currLine ) { free( aRgn ); ffpmsg("Couldn't allocate memory to hold Region file contents."); return(*status = MEMORY_ALLOCATION ); } /* Open Region File */ if( (rgnFile = fopen( filename, "r" ))==NULL ) { sprintf(currLine,"Could not open Region file %s.",filename); ffpmsg( currLine ); free( currLine ); free( aRgn ); return( *status = FILE_NOT_OPENED ); } /* Read in file, line by line */ while( fgets(currLine,allocLen,rgnFile) != NULL ) { /* Make sure we have a full line of text */ lineLen = strlen(currLine); while( lineLen==allocLen-1 && currLine[lineLen-1]!='\n' ) { currLoc = (char *)realloc( currLine, 2 * allocLen * sizeof(char) ); if( !currLoc ) { ffpmsg("Couldn't allocate memory to hold Region file contents."); *status = MEMORY_ALLOCATION; goto error; } else { currLine = currLoc; } fgets( currLine+lineLen, allocLen+1, rgnFile ); allocLen += allocLen; lineLen += strlen(currLine+lineLen); } currLoc = currLine; if( *currLoc == '#' ) { /* Look to see if it is followed by a format statement... */ /* if not skip line */ currLoc++; while( *currLoc==' ' ) currLoc++; if( !strncasecmp( currLoc, "format:", 7 ) ) { if( aRgn->nShapes ) { ffpmsg("Format code encountered after reading 1 or more shapes."); *status = PARSE_SYNTAX_ERR; goto error; } currLoc += 7; while( *currLoc==' ' ) currLoc++; if( !strncasecmp( currLoc, "pixel", 5 ) ) { cFmt = pixel_fmt; } else if( !strncasecmp( currLoc, "degree", 6 ) ) { cFmt = degree_fmt; } else if( !strncasecmp( currLoc, "hhmmss", 6 ) ) { cFmt = hhmmss_fmt; } else if( !strncasecmp( currLoc, "hms", 3 ) ) { cFmt = hhmmss_fmt; } else { ffpmsg("Unknown format code encountered in region file."); *status = PARSE_SYNTAX_ERR; goto error; } } } else if( !strncasecmp( currLoc, "glob", 4 ) ) { /* skip lines that begin with the word 'global' */ } else { while( *currLoc != '\0' ) { namePtr = currLoc; paramPtr = NULL; nParams = 1; /* Search for closing parenthesis */ done = 0; while( !done && !*status && *currLoc ) { switch (*currLoc) { case '(': *currLoc = '\0'; currLoc++; if( paramPtr ) /* Can't have two '(' in a region! */ *status = 1; else paramPtr = currLoc; break; case ')': *currLoc = '\0'; currLoc++; if( !paramPtr ) /* Can't have a ')' without a '(' first */ *status = 1; else done = 1; break; case '#': case '\n': *currLoc = '\0'; if( !paramPtr ) /* Allow for a blank line */ done = 1; break; case ':': currLoc++; cFmt = hhmmss_fmt; break; case 'd': currLoc++; cFmt = degree_fmt; break; case ',': nParams++; /* Fall through to default */ default: currLoc++; break; } } if( *status || !done ) { ffpmsg( "Error reading Region file" ); *status = PARSE_SYNTAX_ERR; goto error; } /* Skip white space in region name */ while( *namePtr==' ' ) namePtr++; /* Was this a blank line? Or the end of the current one */ if( ! *namePtr && ! paramPtr ) continue; /* Check for format code at beginning of the line */ if( !strncasecmp( namePtr, "image;", 6 ) ) { namePtr += 6; cFmt = pixel_fmt; } else if( !strncasecmp( namePtr, "physical;", 9 ) ) { namePtr += 9; cFmt = pixel_fmt; } else if( !strncasecmp( namePtr, "linear;", 7 ) ) { namePtr += 7; cFmt = pixel_fmt; } else if( !strncasecmp( namePtr, "fk4;", 4 ) ) { namePtr += 4; cFmt = degree_fmt; } else if( !strncasecmp( namePtr, "fk5;", 4 ) ) { namePtr += 4; cFmt = degree_fmt; } else if( !strncasecmp( namePtr, "icrs;", 5 ) ) { namePtr += 5; cFmt = degree_fmt; /* the following 5 cases support region files created by POW (or ds9 Version 4.x) which may have lines containing only a format code, not followed by a ';' (and with no region specifier on the line). We use the 'continue' statement to jump to the end of the loop and then continue reading the next line of the region file. */ } else if( !strncasecmp( namePtr, "fk5", 3 ) ) { cFmt = degree_fmt; continue; /* supports POW region file format */ } else if( !strncasecmp( namePtr, "fk4", 3 ) ) { cFmt = degree_fmt; continue; /* supports POW region file format */ } else if( !strncasecmp( namePtr, "icrs", 4 ) ) { cFmt = degree_fmt; continue; /* supports POW region file format */ } else if( !strncasecmp( namePtr, "image", 5 ) ) { cFmt = pixel_fmt; continue; /* supports POW region file format */ } else if( !strncasecmp( namePtr, "physical", 8 ) ) { cFmt = pixel_fmt; continue; /* supports POW region file format */ } else if( !strncasecmp( namePtr, "galactic;", 9 ) ) { ffpmsg( "Galactic region coordinates not supported" ); ffpmsg( namePtr ); *status = PARSE_SYNTAX_ERR; goto error; } else if( !strncasecmp( namePtr, "ecliptic;", 9 ) ) { ffpmsg( "ecliptic region coordinates not supported" ); ffpmsg( namePtr ); *status = PARSE_SYNTAX_ERR; goto error; } /**************************************************/ /* We've apparently found a region... Set it up */ /**************************************************/ if( !(aRgn->nShapes % 10) ) { if( aRgn->Shapes ) tmpShape = (RgnShape *)realloc( aRgn->Shapes, (10+aRgn->nShapes) * sizeof(RgnShape) ); else tmpShape = (RgnShape *) malloc( 10 * sizeof(RgnShape) ); if( tmpShape ) { aRgn->Shapes = tmpShape; } else { ffpmsg( "Failed to allocate memory for Region data"); *status = MEMORY_ALLOCATION; goto error; } } newShape = &aRgn->Shapes[aRgn->nShapes++]; newShape->sign = 1; newShape->shape = point_rgn; while( *namePtr==' ' ) namePtr++; /* Check for the shape's sign */ if( *namePtr=='+' ) { namePtr++; } else if( *namePtr=='-' ) { namePtr++; newShape->sign = 0; } /* Skip white space in region name */ while( *namePtr==' ' ) namePtr++; if( *namePtr=='\0' ) { ffpmsg( "Error reading Region file" ); *status = PARSE_SYNTAX_ERR; goto error; } lineLen = strlen( namePtr ) - 1; while( namePtr[lineLen]==' ' ) namePtr[lineLen--] = '\0'; /* Now identify the region */ if( !strcasecmp( namePtr, "circle" ) ) { newShape->shape = circle_rgn; if( nParams != 3 ) *status = PARSE_SYNTAX_ERR; nCoords = 2; } else if( !strcasecmp( namePtr, "annulus" ) ) { newShape->shape = annulus_rgn; if( nParams != 4 ) *status = PARSE_SYNTAX_ERR; nCoords = 2; } else if( !strcasecmp( namePtr, "ellipse" ) ) { newShape->shape = ellipse_rgn; if( nParams < 4 || nParams > 5 ) *status = PARSE_SYNTAX_ERR; newShape->param.gen.p[4] = 0.0; nCoords = 2; } else if( !strcasecmp( namePtr, "elliptannulus" ) ) { newShape->shape = elliptannulus_rgn; if( !( nParams==8 || nParams==6 ) ) *status = PARSE_SYNTAX_ERR; newShape->param.gen.p[6] = 0.0; newShape->param.gen.p[7] = 0.0; nCoords = 2; } else if( !strcasecmp( namePtr, "box" ) || !strcasecmp( namePtr, "rotbox" ) ) { newShape->shape = box_rgn; if( nParams < 4 || nParams > 5 ) *status = PARSE_SYNTAX_ERR; newShape->param.gen.p[4] = 0.0; nCoords = 2; } else if( !strcasecmp( namePtr, "rectangle" ) || !strcasecmp( namePtr, "rotrectangle" ) ) { newShape->shape = rectangle_rgn; if( nParams < 4 || nParams > 5 ) *status = PARSE_SYNTAX_ERR; newShape->param.gen.p[4] = 0.0; nCoords = 4; } else if( !strcasecmp( namePtr, "diamond" ) || !strcasecmp( namePtr, "rotdiamond" ) || !strcasecmp( namePtr, "rhombus" ) || !strcasecmp( namePtr, "rotrhombus" ) ) { newShape->shape = diamond_rgn; if( nParams < 4 || nParams > 5 ) *status = PARSE_SYNTAX_ERR; newShape->param.gen.p[4] = 0.0; nCoords = 2; } else if( !strcasecmp( namePtr, "sector" ) || !strcasecmp( namePtr, "pie" ) ) { newShape->shape = sector_rgn; if( nParams != 4 ) *status = PARSE_SYNTAX_ERR; nCoords = 2; } else if( !strcasecmp( namePtr, "point" ) ) { newShape->shape = point_rgn; if( nParams != 2 ) *status = PARSE_SYNTAX_ERR; nCoords = 2; } else if( !strcasecmp( namePtr, "line" ) ) { newShape->shape = line_rgn; if( nParams != 4 ) *status = PARSE_SYNTAX_ERR; nCoords = 4; } else if( !strcasecmp( namePtr, "polygon" ) ) { newShape->shape = poly_rgn; if( nParams < 6 || (nParams&1) ) *status = PARSE_SYNTAX_ERR; nCoords = nParams; } else { ffpmsg( "Unrecognized region found in region file:" ); ffpmsg( namePtr ); *status = PARSE_SYNTAX_ERR; goto error; } if( *status ) { ffpmsg( "Wrong number of parameters found for region" ); ffpmsg( namePtr ); goto error; } /* Parse Parameter string... convert to pixels if necessary */ if( newShape->shape==poly_rgn ) { newShape->param.poly.Pts = (double *)malloc( nParams * sizeof(double) ); if( !newShape->param.poly.Pts ) { ffpmsg( "Could not allocate memory to hold polygon parameters" ); *status = MEMORY_ALLOCATION; goto error; } newShape->param.poly.nPts = nParams; coords = newShape->param.poly.Pts; } else coords = newShape->param.gen.p; /* Parse the initial "WCS?" coordinates */ for( i=0; iexists ) { ffpmsg("WCS information needed to convert region coordinates."); *status = NO_WCS_KEY; goto error; } if( ffxypx( X, Y, wcs->xrefval, wcs->yrefval, wcs->xrefpix, wcs->yrefpix, wcs->xinc, wcs->yinc, wcs->rot, wcs->type, &x, &y, status ) ) { ffpmsg("Error converting region to pixel coordinates."); goto error; } X = x; Y = y; } coords[i] = X; coords[i+1] = Y; } /* Read in remaining parameters... */ for( ; ixrefval, wcs->yrefval, wcs->xrefpix, wcs->yrefpix, wcs->xinc, wcs->yinc, wcs->rot, wcs->type, &x, &y, status ) ) { ffpmsg("Error converting region to pixel coordinates."); goto error; } coords[i] = sqrt( pow(x-coords[0],2) + pow(y-coords[1],2) ); } else if (endp && *endp=='\'') { /* parameter given in arcmin so convert to pixels. */ /* Increment first Y coordinate by this amount, then calc */ /* the distance in pixels from the original coordinate. */ /* NOTE: This assumes the pixels are square!! */ if (ysave < 0.) Y = ysave + coords[i]/60.; /* don't exceed -90 */ else Y = ysave - coords[i]/60.; /* don't exceed +90 */ X = xsave; if( ffxypx( X, Y, wcs->xrefval, wcs->yrefval, wcs->xrefpix, wcs->yrefpix, wcs->xinc, wcs->yinc, wcs->rot, wcs->type, &x, &y, status ) ) { ffpmsg("Error converting region to pixel coordinates."); goto error; } coords[i] = sqrt( pow(x-coords[0],2) + pow(y-coords[1],2) ); } else if (endp && *endp=='d') { /* parameter given in degrees so convert to pixels. */ /* Increment first Y coordinate by this amount, then calc */ /* the distance in pixels from the original coordinate. */ /* NOTE: This assumes the pixels are square!! */ if (ysave < 0.) Y = ysave + coords[i]; /* don't exceed -90 */ else Y = ysave - coords[i]; /* don't exceed +90 */ X = xsave; if( ffxypx( X, Y, wcs->xrefval, wcs->yrefval, wcs->xrefpix, wcs->yrefpix, wcs->xinc, wcs->yinc, wcs->rot, wcs->type, &x, &y, status ) ) { ffpmsg("Error converting region to pixel coordinates."); goto error; } coords[i] = sqrt( pow(x-coords[0],2) + pow(y-coords[1],2) ); } } /* Perform some useful calculations now to speed up filter later */ /* Also, correct the position angle for any WCS rotation: */ /* If regions are specified in WCS coordintes, then the angles */ /* are relative to the WCS system, not the pixel X,Y system */ switch( newShape->shape ) { case circle_rgn: newShape->param.gen.a = coords[2] * coords[2]; break; case annulus_rgn: newShape->param.gen.a = coords[2] * coords[2]; newShape->param.gen.b = coords[3] * coords[3]; break; case sector_rgn: if( cFmt!=pixel_fmt ) { coords[2] += (wcs->rot); coords[3] += (wcs->rot); } while( coords[2]> 180.0 ) coords[2] -= 360.0; while( coords[2]<=-180.0 ) coords[2] += 360.0; while( coords[3]> 180.0 ) coords[3] -= 360.0; while( coords[3]<=-180.0 ) coords[3] += 360.0; break; case ellipse_rgn: if( cFmt!=pixel_fmt ) { coords[4] += (wcs->rot); } newShape->param.gen.sinT = sin( myPI * (coords[4] / 180.0) ); newShape->param.gen.cosT = cos( myPI * (coords[4] / 180.0) ); break; case elliptannulus_rgn: if( cFmt!=pixel_fmt ) { coords[6] += (wcs->rot); coords[7] += (wcs->rot); } newShape->param.gen.a = sin( myPI * (coords[6] / 180.0) ); newShape->param.gen.b = cos( myPI * (coords[6] / 180.0) ); newShape->param.gen.sinT = sin( myPI * (coords[7] / 180.0) ); newShape->param.gen.cosT = cos( myPI * (coords[7] / 180.0) ); break; case box_rgn: if( cFmt!=pixel_fmt ) { coords[4] += (wcs->rot); } newShape->param.gen.sinT = sin( myPI * (coords[4] / 180.0) ); newShape->param.gen.cosT = cos( myPI * (coords[4] / 180.0) ); break; case rectangle_rgn: if( cFmt!=pixel_fmt ) { coords[4] += (wcs->rot); } newShape->param.gen.sinT = sin( myPI * (coords[4] / 180.0) ); newShape->param.gen.cosT = cos( myPI * (coords[4] / 180.0) ); X = 0.5 * ( coords[2]-coords[0] ); Y = 0.5 * ( coords[3]-coords[1] ); newShape->param.gen.a = fabs( X * newShape->param.gen.cosT + Y * newShape->param.gen.sinT ); newShape->param.gen.b = fabs( Y * newShape->param.gen.cosT - X * newShape->param.gen.sinT ); newShape->param.gen.p[5] = 0.5 * ( coords[2]+coords[0] ); newShape->param.gen.p[6] = 0.5 * ( coords[3]+coords[1] ); break; case diamond_rgn: if( cFmt!=pixel_fmt ) { coords[4] += (wcs->rot); } newShape->param.gen.sinT = sin( myPI * (coords[4] / 180.0) ); newShape->param.gen.cosT = cos( myPI * (coords[4] / 180.0) ); break; case line_rgn: X = coords[2] - coords[0]; Y = coords[3] - coords[1]; R = sqrt( X*X + Y*Y ); newShape->param.gen.sinT = ( R ? Y/R : 0.0 ); newShape->param.gen.cosT = ( R ? X/R : 1.0 ); newShape->param.gen.a = R + 0.5; break; case point_rgn: break; case poly_rgn: /* Find bounding box */ newShape->param.poly.xmin = coords[0]; newShape->param.poly.xmax = coords[0]; newShape->param.poly.ymin = coords[1]; newShape->param.poly.ymax = coords[1]; for( i=2; iparam.poly.xmin > coords[i] ) /* Min X */ newShape->param.poly.xmin = coords[i]; if( newShape->param.poly.xmax < coords[i] ) /* Max X */ newShape->param.poly.xmax = coords[i]; i++; if( newShape->param.poly.ymin > coords[i] ) /* Min Y */ newShape->param.poly.ymin = coords[i]; if( newShape->param.poly.ymax < coords[i] ) /* Max Y */ newShape->param.poly.ymax = coords[i]; i++; } break; } } /* End of while( *currLoc ) */ /* if (coords)printf("%.8f %.8f %.8f %.8f %.8f\n", coords[0],coords[1],coords[2],coords[3],coords[4]); */ } /* End of if...else parse line */ } /* End of while( fgets(rgnFile) ) */ error: if( *status ) fits_free_region( aRgn ); else *Rgn = aRgn; fclose( rgnFile ); free( currLine ); return( *status ); } /*---------------------------------------------------------------------------*/ int fftrgn( double X, double Y, SAORegion *Rgn ) /* Test if the given point is within the region described by Rgn. X and */ /* Y are in pixel coordinates. */ /*---------------------------------------------------------------------------*/ { double x, y, dx, dy, xprime, yprime, r; RgnShape *Shapes; int i; int result = 0; Shapes = Rgn->Shapes; /* if an excluded region is given first, then implicitly */ /* assume a previous shape that includes the entire image. */ if (!Shapes->sign) result = 1; for( i=0; inShapes; i++, Shapes++ ) { /* only need to test if */ /* the point is not already included and this is an include region, */ /* or the point is included and this is an excluded region */ if ( (!result && Shapes->sign) || (result && !Shapes->sign) ) { result = 1; switch( Shapes->shape ) { case box_rgn: /* Shift origin to center of region */ xprime = X - Shapes->param.gen.p[0]; yprime = Y - Shapes->param.gen.p[1]; /* Rotate point to region's orientation */ x = xprime * Shapes->param.gen.cosT + yprime * Shapes->param.gen.sinT; y = -xprime * Shapes->param.gen.sinT + yprime * Shapes->param.gen.cosT; dx = 0.5 * Shapes->param.gen.p[2]; dy = 0.5 * Shapes->param.gen.p[3]; if( (x < -dx) || (x > dx) || (y < -dy) || (y > dy) ) result = 0; break; case rectangle_rgn: /* Shift origin to center of region */ xprime = X - Shapes->param.gen.p[5]; yprime = Y - Shapes->param.gen.p[6]; /* Rotate point to region's orientation */ x = xprime * Shapes->param.gen.cosT + yprime * Shapes->param.gen.sinT; y = -xprime * Shapes->param.gen.sinT + yprime * Shapes->param.gen.cosT; dx = Shapes->param.gen.a; dy = Shapes->param.gen.b; if( (x < -dx) || (x > dx) || (y < -dy) || (y > dy) ) result = 0; break; case diamond_rgn: /* Shift origin to center of region */ xprime = X - Shapes->param.gen.p[0]; yprime = Y - Shapes->param.gen.p[1]; /* Rotate point to region's orientation */ x = xprime * Shapes->param.gen.cosT + yprime * Shapes->param.gen.sinT; y = -xprime * Shapes->param.gen.sinT + yprime * Shapes->param.gen.cosT; dx = 0.5 * Shapes->param.gen.p[2]; dy = 0.5 * Shapes->param.gen.p[3]; r = fabs(x/dx) + fabs(y/dy); if( r > 1 ) result = 0; break; case circle_rgn: /* Shift origin to center of region */ x = X - Shapes->param.gen.p[0]; y = Y - Shapes->param.gen.p[1]; r = x*x + y*y; if ( r > Shapes->param.gen.a ) result = 0; break; case annulus_rgn: /* Shift origin to center of region */ x = X - Shapes->param.gen.p[0]; y = Y - Shapes->param.gen.p[1]; r = x*x + y*y; if ( r < Shapes->param.gen.a || r > Shapes->param.gen.b ) result = 0; break; case sector_rgn: /* Shift origin to center of region */ x = X - Shapes->param.gen.p[0]; y = Y - Shapes->param.gen.p[1]; if( x || y ) { r = atan2( y, x ) * 180.0 / myPI; if( Shapes->param.gen.p[2] <= Shapes->param.gen.p[3] ) { if( r < Shapes->param.gen.p[2] || r > Shapes->param.gen.p[3] ) result = 0; } else { if( r < Shapes->param.gen.p[2] && r > Shapes->param.gen.p[3] ) result = 0; } } break; case ellipse_rgn: /* Shift origin to center of region */ xprime = X - Shapes->param.gen.p[0]; yprime = Y - Shapes->param.gen.p[1]; /* Rotate point to region's orientation */ x = xprime * Shapes->param.gen.cosT + yprime * Shapes->param.gen.sinT; y = -xprime * Shapes->param.gen.sinT + yprime * Shapes->param.gen.cosT; x /= Shapes->param.gen.p[2]; y /= Shapes->param.gen.p[3]; r = x*x + y*y; if( r>1.0 ) result = 0; break; case elliptannulus_rgn: /* Shift origin to center of region */ xprime = X - Shapes->param.gen.p[0]; yprime = Y - Shapes->param.gen.p[1]; /* Rotate point to outer ellipse's orientation */ x = xprime * Shapes->param.gen.cosT + yprime * Shapes->param.gen.sinT; y = -xprime * Shapes->param.gen.sinT + yprime * Shapes->param.gen.cosT; x /= Shapes->param.gen.p[4]; y /= Shapes->param.gen.p[5]; r = x*x + y*y; if( r>1.0 ) result = 0; else { /* Repeat test for inner ellipse */ x = xprime * Shapes->param.gen.b + yprime * Shapes->param.gen.a; y = -xprime * Shapes->param.gen.a + yprime * Shapes->param.gen.b; x /= Shapes->param.gen.p[2]; y /= Shapes->param.gen.p[3]; r = x*x + y*y; if( r<1.0 ) result = 0; } break; case line_rgn: /* Shift origin to first point of line */ xprime = X - Shapes->param.gen.p[0]; yprime = Y - Shapes->param.gen.p[1]; /* Rotate point to line's orientation */ x = xprime * Shapes->param.gen.cosT + yprime * Shapes->param.gen.sinT; y = -xprime * Shapes->param.gen.sinT + yprime * Shapes->param.gen.cosT; if( (y < -0.5) || (y >= 0.5) || (x < -0.5) || (x >= Shapes->param.gen.a) ) result = 0; break; case point_rgn: /* Shift origin to center of region */ x = X - Shapes->param.gen.p[0]; y = Y - Shapes->param.gen.p[1]; if ( (x<-0.5) || (x>=0.5) || (y<-0.5) || (y>=0.5) ) result = 0; break; case poly_rgn: if( Xparam.poly.xmin || X>Shapes->param.poly.xmax || Yparam.poly.ymin || Y>Shapes->param.poly.ymax ) result = 0; else result = Pt_in_Poly( X, Y, Shapes->param.poly.nPts, Shapes->param.poly.Pts ); break; } if( !Shapes->sign ) result = !result; } } return( result ); } /*---------------------------------------------------------------------------*/ void fffrgn( SAORegion *Rgn ) /* Free up memory allocated to hold the region data. */ /*---------------------------------------------------------------------------*/ { int i; for( i=0; inShapes; i++ ) if( Rgn->Shapes[i].shape == poly_rgn ) free( Rgn->Shapes[i].param.poly.Pts ); if( Rgn->Shapes ) free( Rgn->Shapes ); free( Rgn ); } /*---------------------------------------------------------------------------*/ static int Pt_in_Poly( double x, double y, int nPts, double *Pts ) /* Internal routine for testing whether the coordinate x,y is within the */ /* polygon region traced out by the array Pts. */ /*---------------------------------------------------------------------------*/ { int i, j, flag=0; double prevX, prevY; double nextX, nextY; double dx, dy, Dy; nextX = Pts[nPts-2]; nextY = Pts[nPts-1]; for( i=0; iprevY && y>=nextY) || (yprevX && x>=nextX) ) continue; /* Check to see if x,y lies right on the segment */ if( x>=prevX || x>nextX ) { dy = y - prevY; Dy = nextY - prevY; if( fabs(Dy)<1e-10 ) { if( fabs(dy)<1e-10 ) return( 1 ); else continue; } dx = prevX + ( (nextX-prevX)/(Dy) ) * dy - x; if( dx < -1e-10 ) continue; if( dx < 1e-10 ) return( 1 ); } /* There is an intersection! Make sure it isn't a V point. */ if( y != prevY ) { flag = 1 - flag; } else { j = i+1; /* Point to Y component */ do { if( j>1 ) j -= 2; else j = nPts-1; } while( y == Pts[j] ); if( (nextY-y)*(y-Pts[j]) > 0 ) flag = 1-flag; } } return( flag ); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/region.h000066400000000000000000000034231215713201500220660ustar00rootroot00000000000000/***************************************************************/ /* REGION STUFF */ /***************************************************************/ #define myPI 3.1415926535897932385 typedef struct { int exists; double xrefval, yrefval; double xrefpix, yrefpix; double xinc, yinc; double rot; char type[6]; } WCSdata; typedef enum { point_rgn, line_rgn, circle_rgn, annulus_rgn, ellipse_rgn, elliptannulus_rgn, box_rgn, rectangle_rgn, diamond_rgn, sector_rgn, poly_rgn } shapeType; typedef enum { pixel_fmt, degree_fmt, hhmmss_fmt } coordFmt; typedef struct { char sign; /* Include or exclude? */ shapeType shape; /* Shape of this region */ union { /* Parameters - In pixels */ /**** Generic Shape Data ****/ struct { double p[8]; /* Region parameters */ double sinT, cosT; /* For rotated shapes */ double a, b; /* Extra scratch area */ } gen; /**** Polygon Data ****/ struct { int nPts; /* Number of Polygon pts */ double *Pts; /* Polygon points */ double xmin,xmax; /* Polygon bounding box */ double ymin,ymax; } poly; } param; } RgnShape; typedef struct { int nShapes; RgnShape *Shapes; WCSdata wcs; } SAORegion; #ifdef __cplusplus extern "C" { #endif int ffrrgn( const char *filename, WCSdata *wcs, SAORegion **Rgn, int *status ); int fftrgn( double X, double Y, SAORegion *Rgn ); void fffrgn( SAORegion *Rgn ); #ifdef __cplusplus } #endif #define fits_read_rgnfile ffrrgn #define fits_in_region fftrgn #define fits_free_region fffrgn skycat-3.1.2-starlink-1b/astrotcl/cfitsio/ricecomp.c000066400000000000000000000326401215713201500224020ustar00rootroot00000000000000/* The following code was written by Richard White at STScI and made available for use in CFITSIO in July 1999. These routines were originally contained in 2 source files: rcomp.c and rdecomp.c, and the 'include' file now called ricecomp.h was originally called buffer.h. */ /*----------------------------------------------------------*/ /* */ /* START OF SOURCE FILE ORIGINALLY CALLED rcomp.c */ /* */ /*----------------------------------------------------------*/ /* @(#) rcomp.c 1.5 99/03/01 12:40:27 */ /* rcomp.c Compress image line using * (1) Difference of adjacent pixels * (2) Rice algorithm coding * * Returns number of bytes written to code buffer or * -1 on failure */ #include #include #include #include "ricecomp.h" /* originally included in rcomp.c file (WDP) */ #include "fitsio2.h" static void start_outputing_bits(Buffer *buffer); static int done_outputing_bits(Buffer *buffer); static int output_nbits(Buffer *buffer, int bits, int n); /* this routine used to be called 'rcomp' (WDP) */ int fits_rcomp(int a[], /* input array */ int nx, /* number of input pixels */ unsigned char *c, /* output buffer */ int clen, /* max length of output */ int nblock) /* coding block size */ { Buffer bufmem, *buffer = &bufmem; int bsize, i, j, thisblock; int lastpix, nextpix, pdiff; int v, fs, fsmask, top, fsmax, fsbits, bbits; int lbitbuffer, lbits_to_go; unsigned int psum; double pixelsum, dpsum; unsigned int *diff; /* * Original size of each pixel (bsize, bytes) and coding block * size (nblock, pixels) * Could make bsize a parameter to allow more efficient * compression of short & byte images. */ bsize = 4; /* nblock = 32; */ /* * From bsize derive: * FSBITS = # bits required to store FS * FSMAX = maximum value for FS * BBITS = bits/pixel for direct coding */ switch (bsize) { case 1: fsbits = 3; fsmax = 6; break; case 2: fsbits = 4; fsmax = 14; break; case 4: fsbits = 5; fsmax = 25; break; default: ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes"); return(-1); } bbits = 1<start = c; buffer->current = c; buffer->end = c+clen; buffer->bits_to_go = 8; /* * array for differences mapped to non-negative values */ diff = (unsigned int *) malloc(nblock*sizeof(unsigned int)); if (diff == (unsigned int *) NULL) { ffpmsg("fits_rcomp: insufficient memory"); return(-1); } /* * Code in blocks of nblock pixels */ start_outputing_bits(buffer); /* write out first int value to the first 4 bytes of the buffer */ if (output_nbits(buffer, a[0], 32) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } lastpix = a[0]; /* the first difference will always be zero */ thisblock = nblock; for (i=0; i> 1; for (fs = 0; psum>0; fs++) psum >>= 1; /* * write the codes * fsbits ID bits used to indicate split level */ if (fs >= fsmax) { /* Special high entropy case when FS >= fsmax * Just write pixel difference values directly, no Rice coding at all. */ if (output_nbits(buffer, fsmax+1, fsbits) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } for (j=0; jbitbuffer; lbits_to_go = buffer->bits_to_go; for (j=0; j> fs; /* * top is coded by top zeros + 1 */ if (lbits_to_go >= top+1) { lbitbuffer <<= top+1; lbitbuffer |= 1; lbits_to_go -= top+1; } else { lbitbuffer <<= lbits_to_go; if (putcbuf(lbitbuffer & 0xff,buffer) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } for (top -= lbits_to_go; top>=8; top -= 8) { if (putcbuf(0, buffer) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } } lbitbuffer = 1; lbits_to_go = 7-top; } /* * bottom FS bits are written without coding * code is output_nbits, moved into this routine to reduce overheads * This code potentially breaks if FS>24, so I am limiting * FS to 24 by choice of FSMAX above. */ if (fs > 0) { lbitbuffer <<= fs; lbitbuffer |= v & fsmask; lbits_to_go -= fs; while (lbits_to_go <= 0) { if (putcbuf((lbitbuffer>>(-lbits_to_go)) & 0xff,buffer)==EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } lbits_to_go += 8; } } } buffer->bitbuffer = lbitbuffer; buffer->bits_to_go = lbits_to_go; } } done_outputing_bits(buffer); free(diff); /* * return number of bytes used */ return(buffer->current - buffer->start); } /*---------------------------------------------------------------------------*/ /* bit_output.c * * Bit output routines * Procedures return zero on success, EOF on end-of-buffer * * Programmer: R. White Date: 20 July 1998 */ /* Initialize for bit output */ static void start_outputing_bits(Buffer *buffer) { /* * Buffer is empty to start with */ buffer->bitbuffer = 0; buffer->bits_to_go = 8; } /*---------------------------------------------------------------------------*/ /* Output N bits (N must be <= 32) */ static int output_nbits(Buffer *buffer, int bits, int n) { /* local copies */ int lbitbuffer; int lbits_to_go; /* * insert bits at end of bitbuffer */ lbitbuffer = buffer->bitbuffer; lbits_to_go = buffer->bits_to_go; if (lbits_to_go+n > 32) { /* * special case for large n: put out the top lbits_to_go bits first * note that 0 < lbits_to_go <= 8 */ lbitbuffer <<= lbits_to_go; lbitbuffer |= (bits>>(n-lbits_to_go)) & ((1<>(-lbits_to_go)) & 0xff,buffer) == EOF) return(EOF); lbits_to_go += 8; } buffer->bitbuffer = lbitbuffer; buffer->bits_to_go = lbits_to_go; return(0); } /*---------------------------------------------------------------------------*/ /* Flush out the last bits */ static int done_outputing_bits(Buffer *buffer) { if(buffer->bits_to_go < 8) { if (putcbuf(buffer->bitbuffer<bits_to_go,buffer) == EOF) return(EOF); } return(0); } /*---------------------------------------------------------------------------*/ /*----------------------------------------------------------*/ /* */ /* START OF SOURCE FILE ORIGINALLY CALLED rdecomp.c */ /* */ /*----------------------------------------------------------*/ /* @(#) rdecomp.c 1.4 99/03/01 12:38:41 */ /* rdecomp.c Decompress image line using * (1) Difference of adjacent pixels * (2) Rice algorithm coding * * Returns 0 on success or 1 on failure */ /* moved these 'includes' to the beginning of the file (WDP) #include #include */ /* this routine used to be called 'rdecomp' (WDP) */ int fits_rdecomp (unsigned char *c, /* input buffer */ int clen, /* length of input */ unsigned int array[], /* output array */ int nx, /* number of output pixels */ int nblock) /* coding block size */ { int bsize, i, k, imax; int nbits, nzero, fs; unsigned char *cend, bytevalue; unsigned int b, diff, lastpix; int fsmax, fsbits, bbits; static int *nonzero_count = (int *)NULL; /* * Original size of each pixel (bsize, bytes) and coding block * size (nblock, pixels) * Could make bsize a parameter to allow more efficient * compression of short & byte images. */ bsize = 4; /* nblock = 32; */ /* * From bsize derive: * FSBITS = # bits required to store FS * FSMAX = maximum value for FS * BBITS = bits/pixel for direct coding */ switch (bsize) { case 1: fsbits = 3; fsmax = 6; break; case 2: fsbits = 4; fsmax = 14; break; case 4: fsbits = 5; fsmax = 25; break; default: ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes"); return 1; } bbits = 1<=0; ) { for ( ; i>=k; i--) nonzero_count[i] = nzero; k = k/2; nzero--; } } /* * Decode in blocks of nblock pixels */ /* first 4 bytes of input buffer contain the value of the first */ /* 4 byte integer value, without any encoding */ lastpix = 0; bytevalue = c[0]; lastpix = lastpix | (bytevalue<<24); bytevalue = c[1]; lastpix = lastpix | (bytevalue<<16); bytevalue = c[2]; lastpix = lastpix | (bytevalue<<8); bytevalue = c[3]; lastpix = lastpix | bytevalue; c += 4; cend = c + clen - 4; b = *c++; /* bit buffer */ nbits = 8; /* number of bits remaining in b */ for (i = 0; i> nbits) - 1; b &= (1< nx) imax = nx; if (fs<0) { /* low-entropy case, all zero differences */ for ( ; i= 0; k -= 8) { b = *c++; diff |= b<0) { b = *c++; diff |= b>>(-k); b &= (1<>1; } else { diff = ~(diff>>1); } array[i] = diff+lastpix; lastpix = array[i]; } } else { /* normal case, Rice coding */ for ( ; i>nbits); b &= (1<>1; } else { diff = ~(diff>>1); } array[i] = diff+lastpix; lastpix = array[i]; } } if (c > cend) { ffpmsg("decompression error: hit end of compressed byte stream"); return 1; } } if (c < cend) { ffpmsg("decompression warning: unused bytes at end of compressed buffer"); } return 0; } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/ricecomp.h000066400000000000000000000046151215713201500224100ustar00rootroot00000000000000/* @(#) buffer.h 1.1 98/07/21 12:34:27 */ /* buffer.h: structure for compression to buffer rather than to a file, including * bit I/O buffer * * R. White, 19 June 1998 */ typedef unsigned char Buffer_t; typedef struct { int bitbuffer; /* bit buffer */ int bits_to_go; /* bits to go in buffer */ Buffer_t *start; /* start of buffer */ Buffer_t *current; /* current position in buffer */ Buffer_t *end; /* end of buffer */ } Buffer; #define buffree(mf) (free(mf->start), free(mf)) #define bufused(mf) (mf->current - mf->start) #define bufreset(mf) (mf->current = mf->start) /* * getcbuf, putcbuf macros for character IO to buffer * putcbuf returns EOF on end of buffer, else returns 0 */ #define getcbuf(mf) ((mf->current >= mf->end) ? EOF : *(mf->current)++) #define putcbuf(c,mf) \ ((mf->current >= mf->end) ? \ EOF :\ ((*(mf->current)++ = c), 0)) /* * bufalloc sets up buffer of length n */ /* not needed by CFITSIO static Buffer *bufalloc(int n) { Buffer *mf; mf = (Buffer *) malloc(sizeof(Buffer)); if (mf == (Buffer *)NULL) return((Buffer *)NULL); mf->start = (Buffer_t *) malloc(n*sizeof(Buffer_t)); if (mf->start == (Buffer_t *)NULL) { free(mf); return((Buffer *)NULL); } mf->bits_to_go = 8; mf->end = mf->start + n; mf->current = mf->start; return(mf); } */ /* * bufrealloc extends buffer (or truncates it) by * reallocating memory */ /* not needed by CFITSIO static int bufrealloc(Buffer *mf, int n) { int len; len = mf->current - mf->start; * silently throw away data if buffer is already longer than n * if (len>n) len = n; if (len<0) len = 0; mf->start = (Buffer_t *) realloc(mf->start, n*sizeof(Buffer_t)); if (mf->start == (Buffer_t *)NULL) return(0); mf->end = mf->start + n; mf->current = mf->start + len; return(n); } */ /* * bufdump dumps contents of buffer to outfile and resets * it to be empty. Returns number of bytes written. * * Note we don't write out the bit buffer -- you must call * done_outputing_bits() first to ensure that the bit buffer * is written out. I do it this way to allow incremental * buffer dumps while bit IO is still going on. */ /* not needed by CFITSIO static int bufdump(FILE *outfile, Buffer *buffer) { int ndump; ndump = bufused(buffer); if (fwrite(buffer->start, 1, ndump, outfile) != ndump) { fprintf(stderr, "bufdump: error in write\n"); exit(1); } bufreset(buffer); return(ndump); } */ skycat-3.1.2-starlink-1b/astrotcl/cfitsio/scalnull.c000066400000000000000000000214161215713201500224150ustar00rootroot00000000000000/* This file, scalnull.c, contains the FITSIO routines used to define */ /* the starting heap address, the value scaling and the null values. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpthp(fitsfile *fptr, /* I - FITS file pointer */ long theap, /* I - starting addrss for the heap */ int *status) /* IO - error status */ /* Define the starting address for the heap for a binary table. The default address is NAXIS1 * NAXIS2. It is in units of bytes relative to the beginning of the regular binary table data. This routine also writes the appropriate THEAP keyword to the FITS header. */ { if (*status > 0 || theap < 1) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); (fptr->Fptr)->heapstart = theap; ffukyj(fptr, "THEAP", theap, "byte offset to heap area", status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpscl(fitsfile *fptr, /* I - FITS file pointer */ double scale, /* I - scaling factor: value of BSCALE */ double zero, /* I - zero point: value of BZERO */ int *status) /* IO - error status */ /* Define the linear scaling factor for the primary array or image extension pixel values. This routine overrides the scaling values given by the BSCALE and BZERO keywords if present. Note that this routine does not write or modify the BSCALE and BZERO keywords, but instead only modifies the values temporarily in the internal buffer. Thus, a subsequent call to the ffrdef routine will reset the scaling back to the BSCALE and BZERO keyword values (or 1. and 0. respectively if the keywords are not present). */ { tcolumn *colptr; int hdutype; if (*status > 0) return(*status); if (scale == 0) return(*status = ZERO_SCALE); /* zero scale value is illegal */ if (ffghdt(fptr, &hdutype, status) > 0) /* get HDU type */ return(*status); if (hdutype != IMAGE_HDU) return(*status = NOT_IMAGE); /* not proper HDU type */ if (fits_is_compressed_image(fptr, status)) /* compressed images */ { (fptr->Fptr)->cn_bscale = scale; (fptr->Fptr)->cn_bzero = zero; return(*status); } /* set pointer to the first 'column' (contains group parameters if any) */ colptr = (fptr->Fptr)->tableptr; colptr++; /* increment to the 2nd 'column' pointer (the image itself) */ colptr->tscale = scale; colptr->tzero = zero; return(*status); } /*--------------------------------------------------------------------------*/ int ffpnul(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG nulvalue, /* I - null pixel value: value of BLANK */ int *status) /* IO - error status */ /* Define the value used to represent undefined pixels in the primary array or image extension. This only applies to integer image pixel (i.e. BITPIX > 0). This routine overrides the null pixel value given by the BLANK keyword if present. Note that this routine does not write or modify the BLANK keyword, but instead only modifies the value temporarily in the internal buffer. Thus, a subsequent call to the ffrdef routine will reset the null value back to the BLANK keyword value (or not defined if the keyword is not present). */ { tcolumn *colptr; int hdutype; if (*status > 0) return(*status); if (ffghdt(fptr, &hdutype, status) > 0) /* get HDU type */ return(*status); if (hdutype != IMAGE_HDU) return(*status = NOT_IMAGE); /* not proper HDU type */ if (fits_is_compressed_image(fptr, status)) /* ignore compressed images */ return(*status); /* set pointer to the first 'column' (contains group parameters if any) */ colptr = (fptr->Fptr)->tableptr; colptr++; /* increment to the 2nd 'column' pointer (the image itself) */ colptr->tnull = nulvalue; return(*status); } /*--------------------------------------------------------------------------*/ int fftscl(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number to apply scaling to */ double scale, /* I - scaling factor: value of TSCALn */ double zero, /* I - zero point: value of TZEROn */ int *status) /* IO - error status */ /* Define the linear scaling factor for the TABLE or BINTABLE extension column values. This routine overrides the scaling values given by the TSCALn and TZEROn keywords if present. Note that this routine does not write or modify the TSCALn and TZEROn keywords, but instead only modifies the values temporarily in the internal buffer. Thus, a subsequent call to the ffrdef routine will reset the scaling back to the TSCALn and TZEROn keyword values (or 1. and 0. respectively if the keywords are not present). */ { tcolumn *colptr; int hdutype; if (*status > 0) return(*status); if (scale == 0) return(*status = ZERO_SCALE); /* zero scale value is illegal */ if (ffghdt(fptr, &hdutype, status) > 0) /* get HDU type */ return(*status); if (hdutype == IMAGE_HDU) return(*status = NOT_TABLE); /* not proper HDU type */ colptr = (fptr->Fptr)->tableptr; /* set pointer to the first column */ colptr += (colnum - 1); /* increment to the correct column */ colptr->tscale = scale; colptr->tzero = zero; return(*status); } /*--------------------------------------------------------------------------*/ int fftnul(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number to apply nulvalue to */ LONGLONG nulvalue, /* I - null pixel value: value of TNULLn */ int *status) /* IO - error status */ /* Define the value used to represent undefined pixels in the BINTABLE column. This only applies to integer datatype columns (TFORM = B, I, or J). This routine overrides the null pixel value given by the TNULLn keyword if present. Note that this routine does not write or modify the TNULLn keyword, but instead only modifies the value temporarily in the internal buffer. Thus, a subsequent call to the ffrdef routine will reset the null value back to the TNULLn keyword value (or not defined if the keyword is not present). */ { tcolumn *colptr; int hdutype; if (*status > 0) return(*status); if (ffghdt(fptr, &hdutype, status) > 0) /* get HDU type */ return(*status); if (hdutype != BINARY_TBL) return(*status = NOT_BTABLE); /* not proper HDU type */ colptr = (fptr->Fptr)->tableptr; /* set pointer to the first column */ colptr += (colnum - 1); /* increment to the correct column */ colptr->tnull = nulvalue; return(*status); } /*--------------------------------------------------------------------------*/ int ffsnul(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number to apply nulvalue to */ char *nulstring, /* I - null pixel value: value of TNULLn */ int *status) /* IO - error status */ /* Define the string used to represent undefined pixels in the ASCII TABLE column. This routine overrides the null value given by the TNULLn keyword if present. Note that this routine does not write or modify the TNULLn keyword, but instead only modifies the value temporarily in the internal buffer. Thus, a subsequent call to the ffrdef routine will reset the null value back to the TNULLn keyword value (or not defined if the keyword is not present). */ { tcolumn *colptr; int hdutype; if (*status > 0) return(*status); if (ffghdt(fptr, &hdutype, status) > 0) /* get HDU type */ return(*status); if (hdutype != ASCII_TBL) return(*status = NOT_ATABLE); /* not proper HDU type */ colptr = (fptr->Fptr)->tableptr; /* set pointer to the first column */ colptr += (colnum - 1); /* increment to the correct column */ colptr->strnull[0] = '\0'; strncat(colptr->strnull, nulstring, 19); /* limit string to 19 chars */ return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/swapproc.c000066400000000000000000000057351215713201500224440ustar00rootroot00000000000000/* This file, swapproc.c, contains general utility routines that are */ /* used by other FITSIO routines to swap bytes. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ void ffswap2(short *svalues, /* IO - pointer to shorts to be swapped */ long nvals) /* I - number of shorts to be swapped */ /* swap the bytes in the input short integers: ( 0 1 -> 1 0 ) */ { register char *cvalues; register long ii; union u_tag { char cvals[2]; /* equivalence an array of 4 bytes with */ short sval; /* a short */ } u; cvalues = (char *) svalues; /* copy the initial pointer value */ for (ii = 0; ii < nvals;) { u.sval = svalues[ii++]; /* copy next short to temporary buffer */ *cvalues++ = u.cvals[1]; /* copy the 2 bytes to output in turn */ *cvalues++ = u.cvals[0]; } return; } /*--------------------------------------------------------------------------*/ void ffswap4(INT32BIT *ivalues, /* IO - pointer to floats to be swapped */ long nvals) /* I - number of floats to be swapped */ /* swap the bytes in the input 4-byte integer: ( 0 1 2 3 -> 3 2 1 0 ) */ { register char *cvalues; register long ii; union u_tag { char cvals[4]; /* equivalence an array of 4 bytes with */ INT32BIT ival; /* a float */ } u; cvalues = (char *) ivalues; /* copy the initial pointer value */ for (ii = 0; ii < nvals;) { u.ival = ivalues[ii++]; /* copy next float to buffer */ *cvalues++ = u.cvals[3]; /* copy the 4 bytes in turn */ *cvalues++ = u.cvals[2]; *cvalues++ = u.cvals[1]; *cvalues++ = u.cvals[0]; } return; } /*--------------------------------------------------------------------------*/ void ffswap8(double *dvalues, /* IO - pointer to doubles to be swapped */ long nvals) /* I - number of doubles to be swapped */ /* swap the bytes in the input doubles: ( 01234567 -> 76543210 ) */ { register char *cvalues; register long ii; register char temp; cvalues = (char *) dvalues; /* copy the pointer value */ for (ii = 0; ii < nvals*8; ii += 8) { temp = cvalues[ii]; cvalues[ii] = cvalues[ii+7]; cvalues[ii+7] = temp; temp = cvalues[ii+1]; cvalues[ii+1] = cvalues[ii+6]; cvalues[ii+6] = temp; temp = cvalues[ii+2]; cvalues[ii+2] = cvalues[ii+5]; cvalues[ii+5] = temp; temp = cvalues[ii+3]; cvalues[ii+3] = cvalues[ii+4]; cvalues[ii+4] = temp; } return; } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/wcssub.c000066400000000000000000000613011215713201500221030ustar00rootroot00000000000000#include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int fits_read_wcstab( fitsfile *fptr, /* I - FITS file pointer */ int nwtb, /* Number of arrays to be read from the binary table(s) */ wtbarr *wtb, /* Address of the first element of an array of wtbarr typedefs. This wtbarr typedef is defined below to match the wtbarr struct defined in WCSLIB. An array of such structs returned by the WCSLIB function wcstab(). */ int *status) /* * Author: Mark Calabretta, Australia Telescope National Facility * http://www.atnf.csiro.au/~mcalabre/index.html * * fits_read_wcstab() extracts arrays from a binary table required in * constructing -TAB coordinates. This helper routine is intended for * use by routines in the WCSLIB library when dealing with the -TAB table * look up WCS convention. */ { int anynul, colnum, hdunum, iwtb, m, naxis, nostat; long *naxes = 0, nelem; wtbarr *wtbp; if (*status) return *status; if (fptr == 0) { return (*status = NULL_INPUT_PTR); } if (nwtb == 0) return 0; /* Zero the array pointers. */ wtbp = wtb; for (iwtb = 0; iwtb < nwtb; iwtb++, wtbp++) { *wtbp->arrayp = 0x0; } /* Save HDU number so that we can move back to it later. */ fits_get_hdu_num(fptr, &hdunum); wtbp = wtb; for (iwtb = 0; iwtb < nwtb; iwtb++, wtbp++) { /* Move to the required binary table extension. */ if (fits_movnam_hdu(fptr, BINARY_TBL, (char *)(wtbp->extnam), wtbp->extver, status)) { goto cleanup; } /* Locate the table column. */ if (fits_get_colnum(fptr, CASEINSEN, (char *)(wtbp->ttype), &colnum, status)) { goto cleanup; } /* Get the array dimensions and check for consistency. */ if (wtbp->ndim < 1) { *status = NEG_AXIS; goto cleanup; } if (!(naxes = calloc(wtbp->ndim, sizeof(long)))) { *status = MEMORY_ALLOCATION; goto cleanup; } if (fits_read_tdim(fptr, colnum, wtbp->ndim, &naxis, naxes, status)) { goto cleanup; } if (naxis != wtbp->ndim) { if (wtbp->kind == 'c' && wtbp->ndim == 2) { /* Allow TDIMn to be omitted for degenerate coordinate arrays. */ naxis = 2; naxes[1] = naxes[0]; naxes[0] = 1; } else { *status = BAD_TDIM; goto cleanup; } } if (wtbp->kind == 'c') { /* Coordinate array; calculate the array size. */ nelem = naxes[0]; for (m = 0; m < naxis-1; m++) { *(wtbp->dimlen + m) = naxes[m+1]; nelem *= naxes[m+1]; } } else { /* Index vector; check length. */ if ((nelem = naxes[0]) != *(wtbp->dimlen)) { /* N.B. coordinate array precedes the index vectors. */ *status = BAD_TDIM; goto cleanup; } } free(naxes); naxes = 0; /* Allocate memory for the array. */ if (!(*wtbp->arrayp = calloc((size_t)nelem, sizeof(double)))) { *status = MEMORY_ALLOCATION; goto cleanup; } /* Read the array from the table. */ if (fits_read_col_dbl(fptr, colnum, wtbp->row, 1L, nelem, 0.0, *wtbp->arrayp, &anynul, status)) { goto cleanup; } } cleanup: /* Move back to the starting HDU. */ nostat = 0; fits_movabs_hdu(fptr, hdunum, 0, &nostat); /* Release allocated memory. */ if (naxes) free(naxes); if (*status) { wtbp = wtb; for (iwtb = 0; iwtb < nwtb; iwtb++, wtbp++) { if (*wtbp->arrayp) free(*wtbp->arrayp); } } return *status; } /*--------------------------------------------------------------------------*/ int ffgiwcs(fitsfile *fptr, /* I - FITS file pointer */ char **header, /* O - pointer to the WCS related keywords */ int *status) /* IO - error status */ /* int fits_get_image_wcs_keys return a string containing all the image WCS header keywords. This string is then used as input to the wcsinit WCSlib routine. THIS ROUTINE IS DEPRECATED. USE fits_hdr2str INSTEAD */ { int hdutype; if (*status > 0) return(*status); fits_get_hdu_type(fptr, &hdutype, status); if (hdutype != IMAGE_HDU) { ffpmsg( "Error in ffgiwcs. This HDU is not an image. Can't read WCS keywords"); return(*status = NOT_IMAGE); } /* read header keywords into a long string of chars */ if (ffh2st(fptr, header, status) > 0) { ffpmsg("error creating string of image WCS keywords (ffgiwcs)"); return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgics(fitsfile *fptr, /* I - FITS file pointer */ double *xrval, /* O - X reference value */ double *yrval, /* O - Y reference value */ double *xrpix, /* O - X reference pixel */ double *yrpix, /* O - Y reference pixel */ double *xinc, /* O - X increment per pixel */ double *yinc, /* O - Y increment per pixel */ double *rot, /* O - rotation angle (degrees) */ char *type, /* O - type of projection ('-tan') */ int *status) /* IO - error status */ /* read the values of the celestial coordinate system keywords. These values may be used as input to the subroutines that calculate celestial coordinates. (ffxypx, ffwldp) Modified in Nov 1999 to convert the CD matrix keywords back to the old CDELTn form, and to swap the axes if the dec-like axis is given first, and to assume default values if any of the keywords are not present. */ { int tstat = 0, cd_exists = 0, pc_exists = 0; char ctype[FLEN_VALUE]; double cd11 = 0.0, cd21 = 0.0, cd22 = 0.0, cd12 = 0.0; double pc11 = 1.0, pc21 = 0.0, pc22 = 1.0, pc12 = 0.0; double pi = 3.1415926535897932; double phia, phib, temp; double toler = .0002; /* tolerance for angles to agree (radians) */ /* (= approximately 0.01 degrees) */ if (*status > 0) return(*status); tstat = 0; if (ffgkyd(fptr, "CRVAL1", xrval, NULL, &tstat)) *xrval = 0.; tstat = 0; if (ffgkyd(fptr, "CRVAL2", yrval, NULL, &tstat)) *yrval = 0.; tstat = 0; if (ffgkyd(fptr, "CRPIX1", xrpix, NULL, &tstat)) *xrpix = 0.; tstat = 0; if (ffgkyd(fptr, "CRPIX2", yrpix, NULL, &tstat)) *yrpix = 0.; /* look for CDELTn first, then CDi_j keywords */ tstat = 0; if (ffgkyd(fptr, "CDELT1", xinc, NULL, &tstat)) { /* CASE 1: no CDELTn keyword, so look for the CD matrix */ tstat = 0; if (ffgkyd(fptr, "CD1_1", &cd11, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else cd_exists = 1; /* found at least 1 CD_ keyword */ if (ffgkyd(fptr, "CD2_1", &cd21, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else cd_exists = 1; /* found at least 1 CD_ keyword */ if (ffgkyd(fptr, "CD1_2", &cd12, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else cd_exists = 1; /* found at least 1 CD_ keyword */ if (ffgkyd(fptr, "CD2_2", &cd22, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else cd_exists = 1; /* found at least 1 CD_ keyword */ if (cd_exists) /* convert CDi_j back to CDELTn */ { /* there are 2 ways to compute the angle: */ phia = atan2( cd21, cd11); phib = atan2(-cd12, cd22); /* ensure that phia <= phib */ temp = minvalue(phia, phib); phib = maxvalue(phia, phib); phia = temp; /* there is a possible 180 degree ambiguity in the angles */ /* so add 180 degress to the smaller value if the values */ /* differ by more than 90 degrees = pi/2 radians. */ /* (Later, we may decide to take the other solution by */ /* subtracting 180 degrees from the larger value). */ if ((phib - phia) > (pi / 2.)) phia += pi; if (fabs(phia - phib) > toler) { /* angles don't agree, so looks like there is some skewness */ /* between the axes. Return with an error to be safe. */ *status = APPROX_WCS_KEY; } phia = (phia + phib) /2.; /* use the average of the 2 values */ *xinc = cd11 / cos(phia); *yinc = cd22 / cos(phia); *rot = phia * 180. / pi; /* common usage is to have a positive yinc value. If it is */ /* negative, then subtract 180 degrees from rot and negate */ /* both xinc and yinc. */ if (*yinc < 0) { *xinc = -(*xinc); *yinc = -(*yinc); *rot = *rot - 180.; } } else /* no CD matrix keywords either */ { *xinc = 1.; /* there was no CDELT1 keyword, but check for CDELT2 just in case */ tstat = 0; if (ffgkyd(fptr, "CDELT2", yinc, NULL, &tstat)) *yinc = 1.; tstat = 0; if (ffgkyd(fptr, "CROTA2", rot, NULL, &tstat)) *rot=0.; } } else /* Case 2: CDELTn + optional PC matrix */ { if (ffgkyd(fptr, "CDELT2", yinc, NULL, &tstat)) *yinc = 1.; tstat = 0; if (ffgkyd(fptr, "CROTA2", rot, NULL, &tstat)) { *rot=0.; /* no CROTA2 keyword, so look for the PC matrix */ tstat = 0; if (ffgkyd(fptr, "PC1_1", &pc11, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else pc_exists = 1; /* found at least 1 PC_ keyword */ if (ffgkyd(fptr, "PC2_1", &pc21, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else pc_exists = 1; /* found at least 1 PC_ keyword */ if (ffgkyd(fptr, "PC1_2", &pc12, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else pc_exists = 1; /* found at least 1 PC_ keyword */ if (ffgkyd(fptr, "PC2_2", &pc22, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else pc_exists = 1; /* found at least 1 PC_ keyword */ if (pc_exists) /* convert PCi_j back to CDELTn */ { /* there are 2 ways to compute the angle: */ phia = atan2( pc21, pc11); phib = atan2(-pc12, pc22); /* ensure that phia <= phib */ temp = minvalue(phia, phib); phib = maxvalue(phia, phib); phia = temp; /* there is a possible 180 degree ambiguity in the angles */ /* so add 180 degress to the smaller value if the values */ /* differ by more than 90 degrees = pi/2 radians. */ /* (Later, we may decide to take the other solution by */ /* subtracting 180 degrees from the larger value). */ if ((phib - phia) > (pi / 2.)) phia += pi; if (fabs(phia - phib) > toler) { /* angles don't agree, so looks like there is some skewness */ /* between the axes. Return with an error to be safe. */ *status = APPROX_WCS_KEY; } phia = (phia + phib) /2.; /* use the average of the 2 values */ *rot = phia * 180. / pi; } } } /* get the type of projection, if any */ tstat = 0; if (ffgkys(fptr, "CTYPE1", ctype, NULL, &tstat)) type[0] = '\0'; else { /* copy the projection type string */ strncpy(type, &ctype[4], 4); type[4] = '\0'; /* check if RA and DEC are inverted */ if (!strncmp(ctype, "DEC-", 4) || !strncmp(ctype+1, "LAT", 3)) { /* the latitudinal axis is given first, so swap them */ /* this case was removed on 12/9. Apparently not correct. if ((*xinc / *yinc) < 0. ) *rot = -90. - (*rot); else */ *rot = 90. - (*rot); /* Empirical tests with ds9 show the y-axis sign must be negated */ /* and the xinc and yinc values must NOT be swapped. */ *yinc = -(*yinc); temp = *xrval; *xrval = *yrval; *yrval = temp; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgtcs(fitsfile *fptr, /* I - FITS file pointer */ int xcol, /* I - column containing the RA coordinate */ int ycol, /* I - column containing the DEC coordinate */ double *xrval, /* O - X reference value */ double *yrval, /* O - Y reference value */ double *xrpix, /* O - X reference pixel */ double *yrpix, /* O - Y reference pixel */ double *xinc, /* O - X increment per pixel */ double *yinc, /* O - Y increment per pixel */ double *rot, /* O - rotation angle (degrees) */ char *type, /* O - type of projection ('-sin') */ int *status) /* IO - error status */ /* read the values of the celestial coordinate system keywords from a FITS table where the X and Y or RA and DEC coordinates are stored in separate column. These values may be used as input to the subroutines that calculate celestial coordinates. (ffxypx, ffwldp) */ { char comm[FLEN_COMMENT],ctype[FLEN_VALUE],keynam[FLEN_KEYWORD]; int tstatus = 0; if (*status > 0) return(*status); ffkeyn("TCRVL",xcol,keynam,status); ffgkyd(fptr,keynam,xrval,comm,status); ffkeyn("TCRVL",ycol,keynam,status); ffgkyd(fptr,keynam,yrval,comm,status); ffkeyn("TCRPX",xcol,keynam,status); ffgkyd(fptr,keynam,xrpix,comm,status); ffkeyn("TCRPX",ycol,keynam,status); ffgkyd(fptr,keynam,yrpix,comm,status); ffkeyn("TCDLT",xcol,keynam,status); ffgkyd(fptr,keynam,xinc,comm,status); ffkeyn("TCDLT",ycol,keynam,status); ffgkyd(fptr,keynam,yinc,comm,status); ffkeyn("TCTYP",xcol,keynam,status); ffgkys(fptr,keynam,ctype,comm,status); if (*status > 0) { ffpmsg ("ffgtcs could not find all the celestial coordinate keywords"); return(*status = NO_WCS_KEY); } /* copy the projection type string */ strncpy(type, &ctype[4], 4); type[4] = '\0'; *rot=0.; /* default rotation is 0 */ ffkeyn("TCROT",ycol,keynam,status); ffgkyd(fptr,keynam,rot,comm,&tstatus); /* keyword may not exist */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgtwcs(fitsfile *fptr, /* I - FITS file pointer */ int xcol, /* I - column number for the X column */ int ycol, /* I - column number for the Y column */ char **header, /* O - string of all the WCS keywords */ int *status) /* IO - error status */ /* int fits_get_table_wcs_keys Return string containing all the WCS keywords appropriate for the pair of X and Y columns containing the coordinate of each event in an event list table. This string may then be passed to Doug Mink's WCS library wcsinit routine, to create and initialize the WCS structure. The calling routine must free the header character string when it is no longer needed. THIS ROUTINE IS DEPRECATED. USE fits_hdr2str INSTEAD */ { int hdutype, ncols, tstatus, length; int naxis1 = 1, naxis2 = 1; long tlmin, tlmax; char keyname[FLEN_KEYWORD]; char valstring[FLEN_VALUE]; char comm[2]; char *cptr; /* construct a string of 80 blanks, for adding fill to the keywords */ /* 12345678901234567890123456789012345678901234567890123456789012345678901234567890 */ char blanks[] = " "; if (*status > 0) return(*status); fits_get_hdu_type(fptr, &hdutype, status); if (hdutype == IMAGE_HDU) { ffpmsg("Can't read table WSC keywords. This HDU is not a table"); return(*status = NOT_TABLE); } fits_get_num_cols(fptr, &ncols, status); if (xcol < 1 || xcol > ncols) { ffpmsg("illegal X axis column number in fftwcs"); return(*status = BAD_COL_NUM); } if (ycol < 1 || ycol > ncols) { ffpmsg("illegal Y axis column number in fftwcs"); return(*status = BAD_COL_NUM); } /* allocate character string for all the WCS keywords */ *header = calloc(1, 2401); /* room for up to 30 keywords */ if (*header == 0) { ffpmsg("error allocating memory for WCS header keywords (fftwcs)"); return(*status = MEMORY_ALLOCATION); } cptr = *header; comm[0] = '\0'; tstatus = 0; ffkeyn("TLMIN",xcol,keyname,status); ffgkyj(fptr,keyname, &tlmin,NULL,&tstatus); if (!tstatus) { ffkeyn("TLMAX",xcol,keyname,status); ffgkyj(fptr,keyname, &tlmax,NULL,&tstatus); } if (!tstatus) { naxis1 = tlmax - tlmin + 1; } tstatus = 0; ffkeyn("TLMIN",ycol,keyname,status); ffgkyj(fptr,keyname, &tlmin,NULL,&tstatus); if (!tstatus) { ffkeyn("TLMAX",ycol,keyname,status); ffgkyj(fptr,keyname, &tlmax,NULL,&tstatus); } if (!tstatus) { naxis2 = tlmax - tlmin + 1; } /* 123456789012345678901234567890 */ strcat(cptr, "NAXIS = 2"); strncat(cptr, blanks, 50); cptr += 80; ffi2c(naxis1, valstring, status); /* convert to formatted string */ ffmkky("NAXIS1", valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; strcpy(keyname, "NAXIS2"); ffi2c(naxis2, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; /* read the required header keywords (use defaults if not found) */ /* CTYPE1 keyword */ tstatus = 0; ffkeyn("TCTYP",xcol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) valstring[0] = '\0'; ffmkky("CTYPE1", valstring, comm, cptr, status); /* construct the keyword*/ length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; /* CTYPE2 keyword */ tstatus = 0; ffkeyn("TCTYP",ycol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) valstring[0] = '\0'; ffmkky("CTYPE2", valstring, comm, cptr, status); /* construct the keyword*/ length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; /* CRPIX1 keyword */ tstatus = 0; ffkeyn("TCRPX",xcol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) strcpy(valstring, "1"); ffmkky("CRPIX1", valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; /* CRPIX2 keyword */ tstatus = 0; ffkeyn("TCRPX",ycol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) strcpy(valstring, "1"); ffmkky("CRPIX2", valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; /* CRVAL1 keyword */ tstatus = 0; ffkeyn("TCRVL",xcol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) strcpy(valstring, "1"); ffmkky("CRVAL1", valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; /* CRVAL2 keyword */ tstatus = 0; ffkeyn("TCRVL",ycol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) strcpy(valstring, "1"); ffmkky("CRVAL2", valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; /* CDELT1 keyword */ tstatus = 0; ffkeyn("TCDLT",xcol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) strcpy(valstring, "1"); ffmkky("CDELT1", valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; /* CDELT2 keyword */ tstatus = 0; ffkeyn("TCDLT",ycol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) strcpy(valstring, "1"); ffmkky("CDELT2", valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; /* the following keywords may not exist */ /* CROTA2 keyword */ tstatus = 0; ffkeyn("TCROT",ycol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) == 0 ) { ffmkky("CROTA2", valstring, comm, cptr, status); /* construct keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; } /* EPOCH keyword */ tstatus = 0; if (ffgkey(fptr, "EPOCH", valstring, NULL, &tstatus) == 0 ) { ffmkky("EPOCH", valstring, comm, cptr, status); /* construct keyword*/ length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* EQUINOX keyword */ tstatus = 0; if (ffgkey(fptr, "EQUINOX", valstring, NULL, &tstatus) == 0 ) { ffmkky("EQUINOX", valstring, comm, cptr, status); /* construct keyword*/ length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* RADECSYS keyword */ tstatus = 0; if (ffgkey(fptr, "RADECSYS", valstring, NULL, &tstatus) == 0 ) { ffmkky("RADECSYS", valstring, comm, cptr, status); /*construct keyword*/ length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* TELESCOPE keyword */ tstatus = 0; if (ffgkey(fptr, "TELESCOP", valstring, NULL, &tstatus) == 0 ) { ffmkky("TELESCOP", valstring, comm, cptr, status); length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* INSTRUME keyword */ tstatus = 0; if (ffgkey(fptr, "INSTRUME", valstring, NULL, &tstatus) == 0 ) { ffmkky("INSTRUME", valstring, comm, cptr, status); length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* DETECTOR keyword */ tstatus = 0; if (ffgkey(fptr, "DETECTOR", valstring, NULL, &tstatus) == 0 ) { ffmkky("DETECTOR", valstring, comm, cptr, status); length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* MJD-OBS keyword */ tstatus = 0; if (ffgkey(fptr, "MJD-OBS", valstring, NULL, &tstatus) == 0 ) { ffmkky("MJD-OBS", valstring, comm, cptr, status); length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* DATE-OBS keyword */ tstatus = 0; if (ffgkey(fptr, "DATE-OBS", valstring, NULL, &tstatus) == 0 ) { ffmkky("DATE-OBS", valstring, comm, cptr, status); length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* DATE keyword */ tstatus = 0; if (ffgkey(fptr, "DATE", valstring, NULL, &tstatus) == 0 ) { ffmkky("DATE", valstring, comm, cptr, status); length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } strcat(cptr, "END"); strncat(cptr, blanks, 77); return(*status); } skycat-3.1.2-starlink-1b/astrotcl/cfitsio/wcsutil.c000066400000000000000000000455561215713201500223050ustar00rootroot00000000000000#include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffwldp(double xpix, double ypix, double xref, double yref, double xrefpix, double yrefpix, double xinc, double yinc, double rot, char *type, double *xpos, double *ypos, int *status) /* WDP 1/97: change the name of the routine from 'worldpos' to 'ffwldp' */ /* worldpos.c -- WCS Algorithms from Classic AIPS. Copyright (C) 1994 Associated Universities, Inc. Washington DC, USA. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. Correspondence concerning AIPS should be addressed as follows: Internet email: aipsmail@nrao.edu Postal address: AIPS Group National Radio Astronomy Observatory 520 Edgemont Road Charlottesville, VA 22903-2475 USA -=-=-=-=-=-=- These two ANSI C functions, worldpos() and xypix(), perform forward and reverse WCS computations for 8 types of projective geometries ("-SIN", "-TAN", "-ARC", "-NCP", "-GLS", "-MER", "-AIT" and "-STG"): worldpos() converts from pixel location to RA,Dec xypix() converts from RA,Dec to pixel location where "(RA,Dec)" are more generically (long,lat). These functions are based on the WCS implementation of Classic AIPS, an implementation which has been in production use for more than ten years. See the two memos by Eric Greisen ftp://fits.cv.nrao.edu/fits/documents/wcs/aips27.ps.Z ftp://fits.cv.nrao.edu/fits/documents/wcs/aips46.ps.Z for descriptions of the 8 projective geometries and the algorithms. Footnotes in these two documents describe the differences between these algorithms and the 1993-94 WCS draft proposal (see URL below). In particular, these algorithms support ordinary field rotation, but not skew geometries (CD or PC matrix cases). Also, the MER and AIT algorithms work correctly only for CRVALi=(0,0). Users should note that GLS projections with yref!=0 will behave differently in this code than in the draft WCS proposal. The NCP projection is now obsolete (it is a special case of SIN). WCS syntax and semantics for various advanced features is discussed in the draft WCS proposal by Greisen and Calabretta at: ftp://fits.cv.nrao.edu/fits/documents/wcs/wcs.all.ps.Z -=-=-=- The original version of this code was Emailed to D.Wells on Friday, 23 September by Bill Cotton , who described it as a "..more or less.. exact translation from the AIPSish..". Changes were made by Don Wells during the period October 11-13, 1994: 1) added GNU license and header comments 2) added testpos.c program to perform extensive circularity tests 3) changed float-->double to get more than 7 significant figures 4) testpos.c circularity test failed on MER and AIT. B.Cotton found that "..there were a couple of lines of code [in] the wrong place as a result of merging several Fortran routines." 5) testpos.c found 0h wraparound in xypix() and worldpos(). 6) E.Greisen recommended removal of various redundant if-statements, and addition of a 360d difference test to MER case of worldpos(). */ /*-----------------------------------------------------------------------*/ /* routine to determine accurate position for pixel coordinates */ /* returns 0 if successful otherwise: */ /* 1 = angle too large for projection; */ /* (WDP 1/97: changed the return value to 501 instead of 1) */ /* does: -SIN, -TAN, -ARC, -NCP, -GLS, -MER, -AIT projections */ /* anything else is linear (== -CAR) */ /* Input: */ /* f xpix x pixel number (RA or long without rotation) */ /* f ypiy y pixel number (dec or lat without rotation) */ /* d xref x reference coordinate value (deg) */ /* d yref y reference coordinate value (deg) */ /* f xrefpix x reference pixel */ /* f yrefpix y reference pixel */ /* f xinc x coordinate increment (deg) */ /* f yinc y coordinate increment (deg) */ /* f rot rotation (deg) (from N through E) */ /* c *type projection type code e.g. "-SIN"; */ /* Output: */ /* d *xpos x (RA) coordinate (deg) */ /* d *ypos y (dec) coordinate (deg) */ /*-----------------------------------------------------------------------*/ {double cosr, sinr, dx, dy, dz, temp, x, y, z; double sins, coss, dect, rat, dt, l, m, mg, da, dd, cos0, sin0; double dec0, ra0, decout, raout; double geo1, geo2, geo3; double cond2r=1.745329252e-2; double twopi = 6.28318530717959, deps = 1.0e-5; int i, itype; char ctypes[9][5] ={"-CAR","-SIN","-TAN","-ARC","-NCP", "-GLS", "-MER", "-AIT", "-STG"}; if (*status > 0) return(*status); /* Offset from ref pixel */ dx = (xpix-xrefpix) * xinc; dy = (ypix-yrefpix) * yinc; /* Take out rotation */ cosr = cos(rot*cond2r); sinr = sin(rot*cond2r); if (rot!=0.0) {temp = dx * cosr - dy * sinr; dy = dy * cosr + dx * sinr; dx = temp;} /* find type */ /* WDP 1/97: removed support for default type for better error checking */ /* itype = 0; default type is linear */ itype = -1; /* no default type */ for (i=0;i<9;i++) if (!strncmp(type, ctypes[i], 4)) itype = i; /* default, linear result for error return */ *xpos = xref + dx; *ypos = yref + dy; /* convert to radians */ ra0 = xref * cond2r; dec0 = yref * cond2r; l = dx * cond2r; m = dy * cond2r; sins = l*l + m*m; cos0 = cos(dec0); sin0 = sin(dec0); /* process by case */ switch (itype) { case 0: /* linear -CAR */ rat = ra0 + l; dect = dec0 + m; break; case 1: /* -SIN sin*/ if (sins>1.0) return(*status = 501); coss = sqrt (1.0 - sins); dt = sin0 * coss + cos0 * m; if ((dt>1.0) || (dt<-1.0)) return(*status = 501); dect = asin (dt); rat = cos0 * coss - sin0 * m; if ((rat==0.0) && (l==0.0)) return(*status = 501); rat = atan2 (l, rat) + ra0; break; case 2: /* -TAN tan */ x = cos0*cos(ra0) - l*sin(ra0) - m*cos(ra0)*sin0; y = cos0*sin(ra0) + l*cos(ra0) - m*sin(ra0)*sin0; z = sin0 + m* cos0; rat = atan2( y, x ); dect = atan ( z / sqrt(x*x+y*y) ); break; case 3: /* -ARC Arc*/ if (sins>=twopi*twopi/4.0) return(*status = 501); sins = sqrt(sins); coss = cos (sins); if (sins!=0.0) sins = sin (sins) / sins; else sins = 1.0; dt = m * cos0 * sins + sin0 * coss; if ((dt>1.0) || (dt<-1.0)) return(*status = 501); dect = asin (dt); da = coss - dt * sin0; dt = l * sins * cos0; if ((da==0.0) && (dt==0.0)) return(*status = 501); rat = ra0 + atan2 (dt, da); break; case 4: /* -NCP North celestial pole*/ dect = cos0 - m * sin0; if (dect==0.0) return(*status = 501); rat = ra0 + atan2 (l, dect); dt = cos (rat-ra0); if (dt==0.0) return(*status = 501); dect = dect / dt; if ((dect>1.0) || (dect<-1.0)) return(*status = 501); dect = acos (dect); if (dec0<0.0) dect = -dect; break; case 5: /* -GLS global sinusoid */ dect = dec0 + m; if (fabs(dect)>twopi/4.0) return(*status = 501); coss = cos (dect); if (fabs(l)>twopi*coss/2.0) return(*status = 501); rat = ra0; if (coss>deps) rat = rat + l / coss; break; case 6: /* -MER mercator*/ dt = yinc * cosr + xinc * sinr; if (dt==0.0) dt = 1.0; dy = (yref/2.0 + 45.0) * cond2r; dx = dy + dt / 2.0 * cond2r; dy = log (tan (dy)); dx = log (tan (dx)); geo2 = dt * cond2r / (dx - dy); geo3 = geo2 * dy; geo1 = cos (yref*cond2r); if (geo1<=0.0) geo1 = 1.0; rat = l / geo1 + ra0; if (fabs(rat - ra0) > twopi) return(*status = 501); /* added 10/13/94 DCW/EWG */ dt = 0.0; if (geo2!=0.0) dt = (m + geo3) / geo2; dt = exp (dt); dect = 2.0 * atan (dt) - twopi / 4.0; break; case 7: /* -AIT Aitoff*/ dt = yinc*cosr + xinc*sinr; if (dt==0.0) dt = 1.0; dt = dt * cond2r; dy = yref * cond2r; dx = sin(dy+dt)/sqrt((1.0+cos(dy+dt))/2.0) - sin(dy)/sqrt((1.0+cos(dy))/2.0); if (dx==0.0) dx = 1.0; geo2 = dt / dx; dt = xinc*cosr - yinc* sinr; if (dt==0.0) dt = 1.0; dt = dt * cond2r; dx = 2.0 * cos(dy) * sin(dt/2.0); if (dx==0.0) dx = 1.0; geo1 = dt * sqrt((1.0+cos(dy)*cos(dt/2.0))/2.0) / dx; geo3 = geo2 * sin(dy) / sqrt((1.0+cos(dy))/2.0); rat = ra0; dect = dec0; if ((l==0.0) && (m==0.0)) break; dz = 4.0 - l*l/(4.0*geo1*geo1) - ((m+geo3)/geo2)*((m+geo3)/geo2) ; if ((dz>4.0) || (dz<2.0)) return(*status = 501);; dz = 0.5 * sqrt (dz); dd = (m+geo3) * dz / geo2; if (fabs(dd)>1.0) return(*status = 501);; dd = asin (dd); if (fabs(cos(dd))1.0) return(*status = 501);; da = asin (da); rat = ra0 + 2.0 * da; dect = dd; break; case 8: /* -STG Sterographic*/ dz = (4.0 - sins) / (4.0 + sins); if (fabs(dz)>1.0) return(*status = 501); dect = dz * sin0 + m * cos0 * (1.0+dz) / 2.0; if (fabs(dect)>1.0) return(*status = 501); dect = asin (dect); rat = cos(dect); if (fabs(rat)1.0) return(*status = 501); rat = asin (rat); mg = 1.0 + sin(dect) * sin0 + cos(dect) * cos0 * cos(rat); if (fabs(mg)deps) rat = twopi/2.0 - rat; rat = ra0 + rat; break; default: /* fall through to here on error */ return(*status = 504); } /* return ra in range */ raout = rat; decout = dect; if (raout-ra0>twopi/2.0) raout = raout - twopi; if (raout-ra0<-twopi/2.0) raout = raout + twopi; if (raout < 0.0) raout += twopi; /* added by DCW 10/12/94 */ /* correct units back to degrees */ *xpos = raout / cond2r; *ypos = decout / cond2r; return(*status); } /* End of worldpos */ /*--------------------------------------------------------------------------*/ int ffxypx(double xpos, double ypos, double xref, double yref, double xrefpix, double yrefpix, double xinc, double yinc, double rot, char *type, double *xpix, double *ypix, int *status) /* WDP 1/97: changed name of routine from xypix to ffxypx */ /*-----------------------------------------------------------------------*/ /* routine to determine accurate pixel coordinates for an RA and Dec */ /* returns 0 if successful otherwise: */ /* 1 = angle too large for projection; */ /* 2 = bad values */ /* WDP 1/97: changed the return values to 501 and 502 instead of 1 and 2 */ /* does: -SIN, -TAN, -ARC, -NCP, -GLS, -MER, -AIT projections */ /* anything else is linear */ /* Input: */ /* d xpos x (RA) coordinate (deg) */ /* d ypos y (dec) coordinate (deg) */ /* d xref x reference coordinate value (deg) */ /* d yref y reference coordinate value (deg) */ /* f xrefpix x reference pixel */ /* f yrefpix y reference pixel */ /* f xinc x coordinate increment (deg) */ /* f yinc y coordinate increment (deg) */ /* f rot rotation (deg) (from N through E) */ /* c *type projection type code e.g. "-SIN"; */ /* Output: */ /* f *xpix x pixel number (RA or long without rotation) */ /* f *ypiy y pixel number (dec or lat without rotation) */ /*-----------------------------------------------------------------------*/ {double dx, dy, dz, r, ra0, dec0, ra, dec, coss, sins, dt, da, dd, sint; double l, m, geo1, geo2, geo3, sinr, cosr, cos0, sin0; double cond2r=1.745329252e-2, deps=1.0e-5, twopi=6.28318530717959; int i, itype; char ctypes[9][5] ={"-CAR","-SIN","-TAN","-ARC","-NCP", "-GLS", "-MER", "-AIT", "-STG"}; /* 0h wrap-around tests added by D.Wells 10/12/94: */ dt = (xpos - xref); if (dt > 180) xpos -= 360; if (dt < -180) xpos += 360; /* NOTE: changing input argument xpos is OK (call-by-value in C!) */ /* default values - linear */ dx = xpos - xref; dy = ypos - yref; /* dz = 0.0; */ /* Correct for rotation */ r = rot * cond2r; cosr = cos (r); sinr = sin (r); dz = dx*cosr + dy*sinr; dy = dy*cosr - dx*sinr; dx = dz; /* check axis increments - bail out if either 0 */ if ((xinc==0.0) || (yinc==0.0)) {*xpix=0.0; *ypix=0.0; return(*status = 502);} /* convert to pixels */ *xpix = dx / xinc + xrefpix; *ypix = dy / yinc + yrefpix; /* find type */ /* WDP 1/97: removed support for default type for better error checking */ /* itype = 0; default type is linear */ itype = -1; /* no default type */ for (i=0;i<9;i++) if (!strncmp(type, ctypes[i], 4)) itype = i; if (itype==0) return(*status); /* done if linear */ /* Non linear position */ ra0 = xref * cond2r; dec0 = yref * cond2r; ra = xpos * cond2r; dec = ypos * cond2r; /* compute direction cosine */ coss = cos (dec); sins = sin (dec); cos0 = cos (dec0); sin0 = sin (dec0); l = sin(ra-ra0) * coss; sint = sins * sin0 + coss * cos0 * cos(ra-ra0); /* process by case */ switch (itype) { case 1: /* -SIN sin*/ if (sint<0.0) return(*status = 501); m = sins * cos(dec0) - coss * sin(dec0) * cos(ra-ra0); break; case 2: /* -TAN tan */ if (sint<=0.0) return(*status = 501); if( cos0<0.001 ) { /* Do a first order expansion around pole */ m = (coss * cos(ra-ra0)) / (sins * sin0); m = (-m + cos0 * (1.0 + m*m)) / sin0; } else { m = ( sins/sint - sin0 ) / cos0; } if( fabs(sin(ra0)) < 0.3 ) { l = coss*sin(ra)/sint - cos0*sin(ra0) + m*sin(ra0)*sin0; l /= cos(ra0); } else { l = coss*cos(ra)/sint - cos0*cos(ra0) + m*cos(ra0)*sin0; l /= -sin(ra0); } break; case 3: /* -ARC Arc*/ m = sins * sin(dec0) + coss * cos(dec0) * cos(ra-ra0); if (m<-1.0) m = -1.0; if (m>1.0) m = 1.0; m = acos (m); if (m!=0) m = m / sin(m); else m = 1.0; l = l * m; m = (sins * cos(dec0) - coss * sin(dec0) * cos(ra-ra0)) * m; break; case 4: /* -NCP North celestial pole*/ if (dec0==0.0) return(*status = 501); /* can't stand the equator */ else m = (cos(dec0) - coss * cos(ra-ra0)) / sin(dec0); break; case 5: /* -GLS global sinusoid */ dt = ra - ra0; if (fabs(dec)>twopi/4.0) return(*status = 501); if (fabs(dec0)>twopi/4.0) return(*status = 501); m = dec - dec0; l = dt * coss; break; case 6: /* -MER mercator*/ dt = yinc * cosr + xinc * sinr; if (dt==0.0) dt = 1.0; dy = (yref/2.0 + 45.0) * cond2r; dx = dy + dt / 2.0 * cond2r; dy = log (tan (dy)); dx = log (tan (dx)); geo2 = dt * cond2r / (dx - dy); geo3 = geo2 * dy; geo1 = cos (yref*cond2r); if (geo1<=0.0) geo1 = 1.0; dt = ra - ra0; l = geo1 * dt; dt = dec / 2.0 + twopi / 8.0; dt = tan (dt); if (dttwopi/4.0) return(*status = 501); dt = yinc*cosr + xinc*sinr; if (dt==0.0) dt = 1.0; dt = dt * cond2r; dy = yref * cond2r; dx = sin(dy+dt)/sqrt((1.0+cos(dy+dt))/2.0) - sin(dy)/sqrt((1.0+cos(dy))/2.0); if (dx==0.0) dx = 1.0; geo2 = dt / dx; dt = xinc*cosr - yinc* sinr; if (dt==0.0) dt = 1.0; dt = dt * cond2r; dx = 2.0 * cos(dy) * sin(dt/2.0); if (dx==0.0) dx = 1.0; geo1 = dt * sqrt((1.0+cos(dy)*cos(dt/2.0))/2.0) / dx; geo3 = geo2 * sin(dy) / sqrt((1.0+cos(dy))/2.0); dt = sqrt ((1.0 + cos(dec) * cos(da))/2.0); if (fabs(dt)twopi/4.0) return(*status = 501); dd = 1.0 + sins * sin(dec0) + coss * cos(dec0) * cos(da); if (fabs(dd)/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` exec 6>&1 # # Initializations. # ac_default_prefix=/usr/local ac_config_libobj_dir=. cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. # This variable seems obsolete. It should probably be removed, and # only ac_max_sed_lines should be used. : ${ac_max_here_lines=38} # Identity of this package. PACKAGE_NAME='astrotcl' PACKAGE_TARNAME='astrotcl' PACKAGE_VERSION='2.1.0' PACKAGE_STRING='astrotcl 2.1.0' PACKAGE_BUGREPORT='' # Factoring default headers for most tests. ac_includes_default="\ #include #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_STAT_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #if HAVE_INTTYPES_H # include #else # if HAVE_STDINT_H # include # endif #endif #if HAVE_UNISTD_H # include #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CYGPATH EXEEXT PKG_LIB_FILE PKG_STUB_LIB_FILE PKG_STUB_SOURCES PKG_STUB_OBJECTS PKG_TCL_SOURCES PKG_HEADERS PKG_INCLUDES PKG_LIBS PKG_CFLAGS TCL_VERSION TCL_BIN_DIR TCL_SRC_DIR TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_LIBS TCL_DEFS TCL_EXTRA_CFLAGS TCL_LD_FLAGS TCL_SHLIB_LD_LIBS TK_VERSION TK_BIN_DIR TK_SRC_DIR TK_LIB_FILE TK_LIB_FLAG TK_LIB_SPEC TK_STUB_LIB_FILE TK_STUB_LIB_FLAG TK_STUB_LIB_SPEC TK_LIBS TK_XINCLUDES CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT CPP CXX CXXFLAGS ac_ct_CXX INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA SET_MAKE RANLIB ac_ct_RANLIB EGREP MATH_LIBS tclutil_VERSION tclutil_LIB_FILE tclutil_BUILD_LIB_SPEC tclutil_LIB_SPEC BLT_LIB_SPEC tclutil_SRC_DIR CFITSIO_LIB_SPEC my_shmem SHLIB_LD_CXX_LIBS PKG_SOURCES PKG_OBJECTS CLEANFILES TCL_INCLUDES TK_INCLUDES TCL_THREADS SHARED_BUILD AR CELIB_DIR LIBOBJS SHLIB_SUFFIX DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING STLIB_LD SHLIB_LD SHLIB_CFLAGS SHLIB_LD_LIBS LDFLAGS_DEBUG LDFLAGS_OPTIMIZE LD_LIBRARY_PATH_VAR CFITSIO_LIB_DIR TCL_DBGX CFLAGS_DEFAULT LDFLAGS_DEFAULT MAKE_LIB MAKE_SHARED_LIB MAKE_STATIC_LIB MAKE_STUB_LIB RANLIB_STUB TCLSH_PROG WISH_PROG astrotcl_LIB_FILE astrotcl_BUILD_DIR astrotcl_BUILD_LIB_SPEC astrotcl_LIB_SPEC astrotcl_PKG_OBJECTS astrotcl_SRC_DIR LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_option in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval "enable_$ac_feature=no" ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "enable_$ac_feature='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "with_$ac_package='$ac_optarg'" ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/-/_/g'` eval "with_$ac_package=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` eval "$ac_envvar='$ac_optarg'" export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute paths. for ac_var in exec_prefix prefix do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* | NONE | '' ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # Be sure to have absolute paths. for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ localstatedir libdir includedir oldincludedir infodir mandir do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_confdir=`(dirname "$0") 2>/dev/null || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 { (exit 1); exit 1; }; } else { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi fi (cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 { (exit 1); exit 1; }; } srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` ac_env_build_alias_set=${build_alias+set} ac_env_build_alias_value=$build_alias ac_cv_env_build_alias_set=${build_alias+set} ac_cv_env_build_alias_value=$build_alias ac_env_host_alias_set=${host_alias+set} ac_env_host_alias_value=$host_alias ac_cv_env_host_alias_set=${host_alias+set} ac_cv_env_host_alias_value=$host_alias ac_env_target_alias_set=${target_alias+set} ac_env_target_alias_value=$target_alias ac_cv_env_target_alias_set=${target_alias+set} ac_cv_env_target_alias_value=$target_alias ac_env_CC_set=${CC+set} ac_env_CC_value=$CC ac_cv_env_CC_set=${CC+set} ac_cv_env_CC_value=$CC ac_env_CFLAGS_set=${CFLAGS+set} ac_env_CFLAGS_value=$CFLAGS ac_cv_env_CFLAGS_set=${CFLAGS+set} ac_cv_env_CFLAGS_value=$CFLAGS ac_env_LDFLAGS_set=${LDFLAGS+set} ac_env_LDFLAGS_value=$LDFLAGS ac_cv_env_LDFLAGS_set=${LDFLAGS+set} ac_cv_env_LDFLAGS_value=$LDFLAGS ac_env_CPPFLAGS_set=${CPPFLAGS+set} ac_env_CPPFLAGS_value=$CPPFLAGS ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} ac_cv_env_CPPFLAGS_value=$CPPFLAGS ac_env_CPP_set=${CPP+set} ac_env_CPP_value=$CPP ac_cv_env_CPP_set=${CPP+set} ac_cv_env_CPP_value=$CPP ac_env_CXX_set=${CXX+set} ac_env_CXX_value=$CXX ac_cv_env_CXX_set=${CXX+set} ac_cv_env_CXX_value=$CXX ac_env_CXXFLAGS_set=${CXXFLAGS+set} ac_env_CXXFLAGS_value=$CXXFLAGS ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set} ac_cv_env_CXXFLAGS_value=$CXXFLAGS # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures astrotcl 2.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] _ACEOF cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --infodir=DIR info documentation [PREFIX/info] --mandir=DIR man documentation [PREFIX/man] _ACEOF cat <<\_ACEOF X features: --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of astrotcl 2.1.0:";; esac cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-threads build with threads --enable-shared build and link with shared libraries --enable-shared --enable-64bit enable 64bit support (where applicable) --enable-64bit-vis enable 64bit Sparc VIS support --enable-wince enable Win/CE support (where applicable) --disable-load disallow dynamic loading and "load" command --enable-symbols build with debugging symbols --disable-symbols Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-tcl directory containing tcl configuration (tclConfig.sh) --with-tk directory containing tk configuration (tkConfig.sh) --with-tclinclude directory containing the public Tcl header files --with-tkinclude directory containing the public Tk header files. --with-x use the X Window System --with-celib=DIR use Windows/CE support library from DIR --with-cfitsio=DIR link with CFITSIO library installed in DIR Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor CXX C++ compiler command CXXFLAGS C++ compiler flags Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d $ac_dir || continue ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_srcdir/configure.gnu; then echo $SHELL $ac_srcdir/configure.gnu --help=recursive elif test -f $ac_srcdir/configure; then echo $SHELL $ac_srcdir/configure --help=recursive elif test -f $ac_srcdir/configure.ac || test -f $ac_srcdir/configure.in; then echo $ac_configure --help else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi cd $ac_popdir done fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF astrotcl configure 2.1.0 generated by Starlink Autoconf 2.59 Copyright (C) 2003 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit 0 fi exec 5>config.log cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by astrotcl $as_me 2.1.0, which was generated by Starlink Autoconf 2.59. Invocation command line was $ $0 $@ _ACEOF { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` hostinfo = `(hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" # Get rid of the leading space. ac_sep=" " ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Be sure not to use single quotes in there, as some shells, # such as our DU 5.0 friend, will then `close' the trap. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, { (set) 2>&1 | case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in *ac_space=\ *) sed -n \ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" ;; *) sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------- ## ## Output files. ## ## ------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo sed "/^$/d" confdefs.h | sort echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core && rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo >confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . $cache_file;; *) . ./$cache_file;; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in `(set) 2>&1 | sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val="\$ac_cv_env_${ac_var}_value" eval ac_new_val="\$ac_env_${ac_var}_value" case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu #-------------------------------------------------------------------- # Call TEA_INIT as the first TEA_ macro to set up initial vars. # This will define a ${TEA_PLATFORM} variable == "unix" or "windows" # as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE. #-------------------------------------------------------------------- # TEA extensions pass this us the version of TEA they think they # are compatible with. TEA_VERSION="3.4" echo "$as_me:$LINENO: checking for correct TEA configuration" >&5 echo $ECHO_N "checking for correct TEA configuration... $ECHO_C" >&6 if test x"${PACKAGE_NAME}" = x ; then { { echo "$as_me:$LINENO: error: The PACKAGE_NAME variable must be defined by your TEA configure.in" >&5 echo "$as_me: error: The PACKAGE_NAME variable must be defined by your TEA configure.in" >&2;} { (exit 1); exit 1; }; } fi if test x"3.4" = x ; then { { echo "$as_me:$LINENO: error: TEA version not specified." >&5 echo "$as_me: error: TEA version not specified." >&2;} { (exit 1); exit 1; }; } elif test "3.4" != "${TEA_VERSION}" ; then echo "$as_me:$LINENO: result: warning: requested TEA version \"3.4\", have \"${TEA_VERSION}\"" >&5 echo "${ECHO_T}warning: requested TEA version \"3.4\", have \"${TEA_VERSION}\"" >&6 else echo "$as_me:$LINENO: result: ok (TEA ${TEA_VERSION})" >&5 echo "${ECHO_T}ok (TEA ${TEA_VERSION})" >&6 fi case "`uname -s`" in *win32*|*WIN32*|*CYGWIN_NT*|*CYGWIN_9*|*CYGWIN_ME*|*MINGW32_*) # Extract the first word of "cygpath", so it can be a program name with args. set dummy cygpath; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CYGPATH+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CYGPATH"; then ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CYGPATH="cygpath -w" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo" fi fi CYGPATH=$ac_cv_prog_CYGPATH if test -n "$CYGPATH"; then echo "$as_me:$LINENO: result: $CYGPATH" >&5 echo "${ECHO_T}$CYGPATH" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi EXEEXT=".exe" TEA_PLATFORM="windows" ;; *) CYGPATH=echo EXEEXT="" TEA_PLATFORM="unix" ;; esac # Check if exec_prefix is set. If not use fall back to prefix. # Note when adjusted, so that TEA_PREFIX can correct for this. # This is needed for recursive configures, since autoconf propagates # $prefix, but not $exec_prefix (doh!). if test x$exec_prefix = xNONE ; then exec_prefix_default=yes exec_prefix=$prefix fi # This package name must be replaced statically for AC_SUBST to work # Substitute STUB_LIB_FILE in case package creates a stub library too. # We AC_SUBST these here to ensure they are subst'ed, # in case the user doesn't call TEA_ADD_... #-------------------------------------------------------------------- # Load the tclConfig.sh file #-------------------------------------------------------------------- # # Ok, lets find the tcl configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tcl # if test x"${no_tcl}" = x ; then # we reset no_tcl in case something fails here no_tcl=true # Check whether --with-tcl or --without-tcl was given. if test "${with_tcl+set}" = set; then withval="$with_tcl" with_tclconfig=${withval} fi; echo "$as_me:$LINENO: checking for Tcl configuration" >&5 echo $ECHO_N "checking for Tcl configuration... $ECHO_C" >&6 if test "${ac_cv_c_tclconfig+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # First check to see if --with-tcl was specified. if test x"${with_tclconfig}" != x ; then case ${with_tclconfig} in */tclConfig.sh ) if test -f ${with_tclconfig}; then { echo "$as_me:$LINENO: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5 echo "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;} with_tclconfig=`echo ${with_tclconfig} | sed 's!/tclConfig\.sh$!!'` fi ;; esac if test -f "${with_tclconfig}/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` else { { echo "$as_me:$LINENO: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&5 echo "$as_me: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&2;} { (exit 1); exit 1; }; } fi fi # check in a few common install locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d ${TCLTK_ROOT}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i; pwd)` break fi done fi # then check for a private Tcl installation if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ../tcl \ `ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \ ../../tcl \ `ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \ ../../../tcl \ `ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ `ls -d /System/Library/Frameworks 2>/dev/null` \ ; do if test -f "$i/Tcl.framework/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi fi if test x"${ac_cv_c_tclconfig}" = x ; then TCL_BIN_DIR="# no Tcl configs found" { echo "$as_me:$LINENO: WARNING: \"Cannot find Tcl configuration definitions\"" >&5 echo "$as_me: WARNING: \"Cannot find Tcl configuration definitions\"" >&2;} exit 0 else no_tcl= TCL_BIN_DIR=${ac_cv_c_tclconfig} echo "$as_me:$LINENO: result: found $TCL_BIN_DIR/tclConfig.sh" >&5 echo "${ECHO_T}found $TCL_BIN_DIR/tclConfig.sh" >&6 fi fi echo "$as_me:$LINENO: checking for existence of $TCL_BIN_DIR/tclConfig.sh" >&5 echo $ECHO_N "checking for existence of $TCL_BIN_DIR/tclConfig.sh... $ECHO_C" >&6 if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then echo "$as_me:$LINENO: result: loading" >&5 echo "${ECHO_T}loading" >&6 . $TCL_BIN_DIR/tclConfig.sh else echo "$as_me:$LINENO: result: file not found" >&5 echo "${ECHO_T}file not found" >&6 fi # # If the TCL_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TCL_LIB_SPEC will be set to the value # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC # instead of TCL_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. # if test -f $TCL_BIN_DIR/Makefile ; then TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC} TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC} TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH} fi # # eval is required to do the TCL_DBGX substitution # eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\"" eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\"" #AC_SUBST(TCL_BUILD_LIB_SPEC) #AC_SUBST(TCL_BUILD_STUB_LIB_SPEC) #-------------------------------------------------------------------- # Load the tkConfig.sh file if necessary (Tk extension) #-------------------------------------------------------------------- # # Ok, lets find the tk configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tk # if test x"${no_tk}" = x ; then # we reset no_tk in case something fails here no_tk=true # Check whether --with-tk or --without-tk was given. if test "${with_tk+set}" = set; then withval="$with_tk" with_tkconfig=${withval} fi; echo "$as_me:$LINENO: checking for Tk configuration" >&5 echo $ECHO_N "checking for Tk configuration... $ECHO_C" >&6 if test "${ac_cv_c_tkconfig+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # First check to see if --with-tkconfig was specified. if test x"${with_tkconfig}" != x ; then case ${with_tkconfig} in */tkConfig.sh ) if test -f ${with_tkconfig}; then { echo "$as_me:$LINENO: WARNING: --with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself" >&5 echo "$as_me: WARNING: --with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself" >&2;} with_tkconfig=`echo ${with_tkconfig} | sed 's!/tkConfig\.sh$!!'` fi ;; esac if test -f "${with_tkconfig}/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)` else { { echo "$as_me:$LINENO: error: ${with_tkconfig} directory doesn't contain tkConfig.sh" >&5 echo "$as_me: error: ${with_tkconfig} directory doesn't contain tkConfig.sh" >&2;} { (exit 1); exit 1; }; } fi fi # check in a few common install locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d ${TCLTK_ROOT}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ ; do if test -f "$i/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i; pwd)` break fi done fi # then check for a private Tk library if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ../tk \ `ls -dr ../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../tk[8-9].[0-9] 2>/dev/null` \ `ls -dr ../tk[8-9].[0-9]* 2>/dev/null` \ ../../tk \ `ls -dr ../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../tk[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../tk[8-9].[0-9]* 2>/dev/null` \ ../../../tk \ `ls -dr ../../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../../tk[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../../tk[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/unix; pwd)` break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ `ls -d /System/Library/Frameworks 2>/dev/null` \ ; do if test -f "$i/Tk.framework/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/Tk.framework; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ${srcdir}/../tk \ `ls -dr ${srcdir}/../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ${srcdir}/../tk[8-9].[0-9] 2>/dev/null` \ `ls -dr ${srcdir}/../tk[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/unix; pwd)` break fi done fi fi if test x"${ac_cv_c_tkconfig}" = x ; then TK_BIN_DIR="# no Tk configs found" { echo "$as_me:$LINENO: WARNING: \"Cannot find Tk configuration definitions\"" >&5 echo "$as_me: WARNING: \"Cannot find Tk configuration definitions\"" >&2;} exit 0 else no_tk= TK_BIN_DIR=${ac_cv_c_tkconfig} echo "$as_me:$LINENO: result: found $TK_BIN_DIR/tkConfig.sh" >&5 echo "${ECHO_T}found $TK_BIN_DIR/tkConfig.sh" >&6 fi fi echo "$as_me:$LINENO: checking for existence of ${TK_BIN_DIR}/tkConfig.sh" >&5 echo $ECHO_N "checking for existence of ${TK_BIN_DIR}/tkConfig.sh... $ECHO_C" >&6 if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then echo "$as_me:$LINENO: result: loading" >&5 echo "${ECHO_T}loading" >&6 . $TK_BIN_DIR/tkConfig.sh else echo "$as_me:$LINENO: result: could not find ${TK_BIN_DIR}/tkConfig.sh" >&5 echo "${ECHO_T}could not find ${TK_BIN_DIR}/tkConfig.sh" >&6 fi # # If the TK_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TK_LIB_SPEC will be set to the value # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC # instead of TK_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. # if test -f $TK_BIN_DIR/Makefile ; then TK_LIB_SPEC=${TK_BUILD_LIB_SPEC} TK_STUB_LIB_SPEC=${TK_BUILD_STUB_LIB_SPEC} TK_STUB_LIB_PATH=${TK_BUILD_STUB_LIB_PATH} fi # Ensure windowingsystem is defined if test "${TEA_PLATFORM}" = "unix" ; then case ${TK_DEFS} in *MAC_OSX_TK*) cat >>confdefs.h <<\_ACEOF #define MAC_OSX_TK 1 _ACEOF TEA_WINDOWINGSYSTEM="aqua" ;; *) TEA_WINDOWINGSYSTEM="x11" ;; esac elif test "${TEA_PLATFORM}" = "windows" ; then TEA_WINDOWINGSYSTEM="win32" fi # # eval is required to do the TK_DBGX substitution # eval "TK_LIB_FILE=\"${TK_LIB_FILE}\"" eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\"" eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\"" eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\"" eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\"" eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\"" #----------------------------------------------------------------------- # Handle the --prefix=... option by defaulting to what Tcl gave. # Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER. #----------------------------------------------------------------------- if test "${prefix}" = "NONE"; then prefix_default=yes if test x"${TCL_PREFIX}" != x; then { echo "$as_me:$LINENO: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&5 echo "$as_me: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&6;} prefix=${TCL_PREFIX} else { echo "$as_me:$LINENO: --prefix defaulting to /usr/local" >&5 echo "$as_me: --prefix defaulting to /usr/local" >&6;} prefix=/usr/local fi fi if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \ -o x"${exec_prefix_default}" = x"yes" ; then #if test x"${TCL_EXEC_PREFIX}" != x; then #AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}]) #exec_prefix=${TCL_EXEC_PREFIX} #else { echo "$as_me:$LINENO: --exec-prefix defaulting to ${prefix}" >&5 echo "$as_me: --exec-prefix defaulting to ${prefix}" >&6;} exec_prefix=$prefix #fi fi #----------------------------------------------------------------------- # Standard compiler checks. # This sets up CC by using the CC env var, or looks for gcc otherwise. # This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create # the basic setup necessary to compile executables. #----------------------------------------------------------------------- ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f $ac_dir/shtool; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} { (exit 1); exit 1; }; } fi ac_config_guess="$SHELL $ac_aux_dir/config.guess" ac_config_sub="$SHELL $ac_aux_dir/config.sub" ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE) # in this macro, they need to go into TEA_SETUP_COMPILER instead. # If the user did not set CFLAGS, set it now to keep # the AC_PROG_CC macro from adding "-g -O2". if test "${CFLAGS+set}" != "set" ; then CFLAGS="" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CC" && break done CC=$ac_ct_CC fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 (eval $ac_link_default) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Find the output, starting from the most likely. This scheme is # not robust to junk in `.', hence go to wildcards (a.*) only as a last # resort. # Be careful to initialize this variable, since it used to be cached. # Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. ac_cv_exeext= # b.out is created by i960 compilers. for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; conftest.$ac_ext ) # This is the source file. ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` # FIXME: I believe we export ac_cv_exeext for Libtool, # but it would be cool to find out if it's true. Does anybody # maintain Libtool? --akim. export ac_cv_exeext break;; * ) break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6 # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6 echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` export ac_cv_exeext break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6 rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6 OBJEXT=$ac_cv_objext ac_objext=$OBJEXT echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS CFLAGS="-g" echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cc_g=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 if test "${ac_cv_prog_cc_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_stdc=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std1 is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std1. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX 10.20 and later -Ae # HP-UX older versions -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_stdc=$ac_arg break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext done rm -f conftest.$ac_ext conftest.$ac_objext CC=$ac_save_CC fi case "x$ac_cv_prog_cc_stdc" in x|xno) echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6 ;; *) echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 CC="$CC $ac_cv_prog_cc_stdc" ;; esac # Some people use a C++ compiler to compile C. Since we use `exit', # in C++ we need to declare it. In case someone uses the same compiler # for both compiling C and C++ we need to have the C++ compiler decide # the declaration of exit, since it's the most demanding environment. cat >conftest.$ac_ext <<_ACEOF #ifndef __cplusplus choke me #endif _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration #include int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_cv_c_compiler_gnu = yes; then GCC=yes fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6 ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=cc ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -n "$ac_tool_prefix"; then for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then echo "$as_me:$LINENO: result: $CXX" >&5 echo "${ECHO_T}$CXX" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 echo "${ECHO_T}$ac_ct_CXX" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CXX" && break done test -n "$ac_ct_CXX" || ac_ct_CXX="g++" CXX=$ac_ct_CXX fi # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C++ compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 if test "${ac_cv_cxx_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 GXX=`test $ac_compiler_gnu = yes && echo yes` ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS CXXFLAGS="-g" echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cxx_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cxx_g=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi for ac_declaration in \ '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration #include int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL=$ac_install_sh fi fi echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' #-------------------------------------------------------------------- # Checks to see if the make program sets the $MAKE variable. #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.make <<\_ACEOF all: @echo 'ac_maketemp="$(MAKE)"' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi rm -f conftest.make fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 SET_MAKE= else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 SET_MAKE="MAKE=${MAKE-make}" fi #-------------------------------------------------------------------- # Find ranlib #-------------------------------------------------------------------- if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then echo "$as_me:$LINENO: result: $RANLIB" >&5 echo "${ECHO_T}$RANLIB" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 echo "${ECHO_T}$ac_ct_RANLIB" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi RANLIB=$ac_ct_RANLIB else RANLIB="$ac_cv_prog_RANLIB" fi #-------------------------------------------------------------------- # Determines the correct binary file extension (.o, .obj, .exe etc.) #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6 if test "${ac_cv_prog_egrep+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | (grep -E '(a|b)') >/dev/null 2>&1 then ac_cv_prog_egrep='grep -E' else ac_cv_prog_egrep='egrep' fi fi echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 echo "${ECHO_T}$ac_cv_prog_egrep" >&6 EGREP=$ac_cv_prog_egrep echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6 if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here. #------------------------------------------------------------------------ # If we're using GCC, see if the compiler understands -pipe. If so, use it. # It makes compiling go faster. (This is only a performance feature.) #------------------------------------------------------------------------ if test -z "$no_pipe" -a -n "$GCC"; then echo "$as_me:$LINENO: checking if the compiler understands -pipe" >&5 echo $ECHO_N "checking if the compiler understands -pipe... $ECHO_C" >&6 OLDCC="$CC" CC="$CC -pipe" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CC="$OLDCC" echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi #-------------------------------------------------------------------- # Pick up flags from the environment (user). #-------------------------------------------------------------------- CC="${CC} $CFLAGS" CXX="${CXX} $CXXFLAGS $CFLAGS" #-------------------------------------------------------------------- # Common compiler flag setup #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6 if test "${ac_cv_c_bigendian+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # See if sys/param.h defines the BYTE_ORDER macro. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN bogus endian macros #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then # It does; now see whether it defined to BIG_ENDIAN or not. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_bigendian=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_bigendian=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # It does not; compile a test program. if test "$cross_compiling" = yes; then # try to guess the endianness by grepping values into an object file ac_cv_c_bigendian=unknown cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } int main () { _ascii (); _ebcdic (); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long l; char c[sizeof (long)]; } u; u.l = 1; exit (u.c[sizeof (long) - 1] == 1); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_bigendian=no else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_c_bigendian=yes fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 echo "${ECHO_T}$ac_cv_c_bigendian" >&6 case $ac_cv_c_bigendian in yes) cat >>confdefs.h <<\_ACEOF #define WORDS_BIGENDIAN 1 _ACEOF ;; no) ;; *) { { echo "$as_me:$LINENO: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&5 echo "$as_me: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} { (exit 1); exit 1; }; } ;; esac if test "${TEA_PLATFORM}" = "unix" ; then #-------------------------------------------------------------------- # On a few very rare systems, all of the libm.a stuff is # already in libc.a. Set compiler flags accordingly. # Also, Linux requires the "ieee" library for math to work # right (and it must appear before "-lm"). #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking for sin" >&5 echo $ECHO_N "checking for sin... $ECHO_C" >&6 if test "${ac_cv_func_sin+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define sin to an innocuous variant, in case declares sin. For example, HP-UX 11i declares gettimeofday. */ #define sin innocuous_sin /* System header to define __stub macros and hopefully few prototypes, which can conflict with char sin (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef sin /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char sin (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_sin) || defined (__stub___sin) choke me #else char (*f) () = sin; #endif #ifdef __cplusplus } #endif int main () { return f != sin; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_sin=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_sin=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_sin" >&5 echo "${ECHO_T}$ac_cv_func_sin" >&6 if test $ac_cv_func_sin = yes; then MATH_LIBS="" else MATH_LIBS="-lm" fi echo "$as_me:$LINENO: checking for main in -lieee" >&5 echo $ECHO_N "checking for main in -lieee... $ECHO_C" >&6 if test "${ac_cv_lib_ieee_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lieee $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_ieee_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ieee_main=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_ieee_main" >&5 echo "${ECHO_T}$ac_cv_lib_ieee_main" >&6 if test $ac_cv_lib_ieee_main = yes; then MATH_LIBS="-lieee $MATH_LIBS" fi #-------------------------------------------------------------------- # Interactive UNIX requires -linet instead of -lsocket, plus it # needs net/errno.h to define the socket-related error codes. #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking for main in -linet" >&5 echo $ECHO_N "checking for main in -linet... $ECHO_C" >&6 if test "${ac_cv_lib_inet_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-linet $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_inet_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_inet_main=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_inet_main" >&5 echo "${ECHO_T}$ac_cv_lib_inet_main" >&6 if test $ac_cv_lib_inet_main = yes; then LIBS="$LIBS -linet" fi if test "${ac_cv_header_net_errno_h+set}" = set; then echo "$as_me:$LINENO: checking for net/errno.h" >&5 echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6 if test "${ac_cv_header_net_errno_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5 echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking net/errno.h usability" >&5 echo $ECHO_N "checking net/errno.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking net/errno.h presence" >&5 echo $ECHO_N "checking net/errno.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: net/errno.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: net/errno.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: net/errno.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: net/errno.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: net/errno.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: net/errno.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: net/errno.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: net/errno.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------- ## ## Report this to the astrotcl lists. ## ## ----------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for net/errno.h" >&5 echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6 if test "${ac_cv_header_net_errno_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_net_errno_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5 echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6 fi if test $ac_cv_header_net_errno_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_NET_ERRNO_H 1 _ACEOF fi #-------------------------------------------------------------------- # Check for the existence of the -lsocket and -lnsl libraries. # The order here is important, so that they end up in the right # order in the command line generated by make. Here are some # special considerations: # 1. Use "connect" and "accept" to check for -lsocket, and # "gethostbyname" to check for -lnsl. # 2. Use each function name only once: can't redo a check because # autoconf caches the results of the last check and won't redo it. # 3. Use -lnsl and -lsocket only if they supply procedures that # aren't already present in the normal libraries. This is because # IRIX 5.2 has libraries, but they aren't needed and they're # bogus: they goof up name resolution if used. # 4. On some SVR4 systems, can't use -lsocket without -lnsl too. # To get around this problem, check for both libraries together # if -lsocket doesn't work by itself. #-------------------------------------------------------------------- tcl_checkBoth=0 echo "$as_me:$LINENO: checking for connect" >&5 echo $ECHO_N "checking for connect... $ECHO_C" >&6 if test "${ac_cv_func_connect+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define connect to an innocuous variant, in case declares connect. For example, HP-UX 11i declares gettimeofday. */ #define connect innocuous_connect /* System header to define __stub macros and hopefully few prototypes, which can conflict with char connect (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef connect /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char connect (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_connect) || defined (__stub___connect) choke me #else char (*f) () = connect; #endif #ifdef __cplusplus } #endif int main () { return f != connect; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_connect=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_connect=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5 echo "${ECHO_T}$ac_cv_func_connect" >&6 if test $ac_cv_func_connect = yes; then tcl_checkSocket=0 else tcl_checkSocket=1 fi if test "$tcl_checkSocket" = 1; then echo "$as_me:$LINENO: checking for setsockopt" >&5 echo $ECHO_N "checking for setsockopt... $ECHO_C" >&6 if test "${ac_cv_func_setsockopt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define setsockopt to an innocuous variant, in case declares setsockopt. For example, HP-UX 11i declares gettimeofday. */ #define setsockopt innocuous_setsockopt /* System header to define __stub macros and hopefully few prototypes, which can conflict with char setsockopt (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef setsockopt /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char setsockopt (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_setsockopt) || defined (__stub___setsockopt) choke me #else char (*f) () = setsockopt; #endif #ifdef __cplusplus } #endif int main () { return f != setsockopt; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_setsockopt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_setsockopt=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_setsockopt" >&5 echo "${ECHO_T}$ac_cv_func_setsockopt" >&6 if test $ac_cv_func_setsockopt = yes; then : else echo "$as_me:$LINENO: checking for setsockopt in -lsocket" >&5 echo $ECHO_N "checking for setsockopt in -lsocket... $ECHO_C" >&6 if test "${ac_cv_lib_socket_setsockopt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char setsockopt (); int main () { setsockopt (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_socket_setsockopt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_socket_setsockopt=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_socket_setsockopt" >&5 echo "${ECHO_T}$ac_cv_lib_socket_setsockopt" >&6 if test $ac_cv_lib_socket_setsockopt = yes; then LIBS="$LIBS -lsocket" else tcl_checkBoth=1 fi fi fi if test "$tcl_checkBoth" = 1; then tk_oldLibs=$LIBS LIBS="$LIBS -lsocket -lnsl" echo "$as_me:$LINENO: checking for accept" >&5 echo $ECHO_N "checking for accept... $ECHO_C" >&6 if test "${ac_cv_func_accept+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define accept to an innocuous variant, in case declares accept. For example, HP-UX 11i declares gettimeofday. */ #define accept innocuous_accept /* System header to define __stub macros and hopefully few prototypes, which can conflict with char accept (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef accept /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char accept (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_accept) || defined (__stub___accept) choke me #else char (*f) () = accept; #endif #ifdef __cplusplus } #endif int main () { return f != accept; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_accept=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_accept=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_accept" >&5 echo "${ECHO_T}$ac_cv_func_accept" >&6 if test $ac_cv_func_accept = yes; then tcl_checkNsl=0 else LIBS=$tk_oldLibs fi fi echo "$as_me:$LINENO: checking for gethostbyname" >&5 echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6 if test "${ac_cv_func_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define gethostbyname to an innocuous variant, in case declares gethostbyname. For example, HP-UX 11i declares gettimeofday. */ #define gethostbyname innocuous_gethostbyname /* System header to define __stub macros and hopefully few prototypes, which can conflict with char gethostbyname (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef gethostbyname /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostbyname (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) choke me #else char (*f) () = gethostbyname; #endif #ifdef __cplusplus } #endif int main () { return f != gethostbyname; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_gethostbyname=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_gethostbyname=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6 if test $ac_cv_func_gethostbyname = yes; then : else echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5 echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6 if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostbyname (); int main () { gethostbyname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_nsl_gethostbyname=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_nsl_gethostbyname=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6 if test $ac_cv_lib_nsl_gethostbyname = yes; then LIBS="$LIBS -lnsl" fi fi # Don't perform the eval of the libraries here because DL_LIBS # won't be set until we call TEA_CONFIG_CFLAGS TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}' echo "$as_me:$LINENO: checking dirent.h" >&5 echo $ECHO_N "checking dirent.h... $ECHO_C" >&6 if test "${tcl_cv_dirent_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #ifndef _POSIX_SOURCE # ifdef __Lynx__ /* * Generate compilation error to make the test fail: Lynx headers * are only valid if really in the POSIX environment. */ missing_procedure(); # endif #endif DIR *d; struct dirent *entryPtr; char *p; d = opendir("foobar"); entryPtr = readdir(d); p = entryPtr->d_name; closedir(d); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_dirent_h=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_dirent_h=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi if test $tcl_cv_dirent_h = no; then cat >>confdefs.h <<\_ACEOF #define NO_DIRENT_H 1 _ACEOF fi echo "$as_me:$LINENO: result: $tcl_ok" >&5 echo "${ECHO_T}$tcl_ok" >&6 if test "${ac_cv_header_errno_h+set}" = set; then echo "$as_me:$LINENO: checking for errno.h" >&5 echo $ECHO_N "checking for errno.h... $ECHO_C" >&6 if test "${ac_cv_header_errno_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5 echo "${ECHO_T}$ac_cv_header_errno_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking errno.h usability" >&5 echo $ECHO_N "checking errno.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking errno.h presence" >&5 echo $ECHO_N "checking errno.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: errno.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: errno.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: errno.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: errno.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: errno.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: errno.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: errno.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: errno.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------- ## ## Report this to the astrotcl lists. ## ## ----------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for errno.h" >&5 echo $ECHO_N "checking for errno.h... $ECHO_C" >&6 if test "${ac_cv_header_errno_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_errno_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5 echo "${ECHO_T}$ac_cv_header_errno_h" >&6 fi if test $ac_cv_header_errno_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_ERRNO_H 1 _ACEOF fi if test "${ac_cv_header_float_h+set}" = set; then echo "$as_me:$LINENO: checking for float.h" >&5 echo $ECHO_N "checking for float.h... $ECHO_C" >&6 if test "${ac_cv_header_float_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5 echo "${ECHO_T}$ac_cv_header_float_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking float.h usability" >&5 echo $ECHO_N "checking float.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking float.h presence" >&5 echo $ECHO_N "checking float.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: float.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: float.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: float.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: float.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: float.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: float.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: float.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: float.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------- ## ## Report this to the astrotcl lists. ## ## ----------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for float.h" >&5 echo $ECHO_N "checking for float.h... $ECHO_C" >&6 if test "${ac_cv_header_float_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_float_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5 echo "${ECHO_T}$ac_cv_header_float_h" >&6 fi if test $ac_cv_header_float_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_FLOAT_H 1 _ACEOF fi if test "${ac_cv_header_values_h+set}" = set; then echo "$as_me:$LINENO: checking for values.h" >&5 echo $ECHO_N "checking for values.h... $ECHO_C" >&6 if test "${ac_cv_header_values_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5 echo "${ECHO_T}$ac_cv_header_values_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking values.h usability" >&5 echo $ECHO_N "checking values.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking values.h presence" >&5 echo $ECHO_N "checking values.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: values.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: values.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: values.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: values.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: values.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: values.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: values.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: values.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------- ## ## Report this to the astrotcl lists. ## ## ----------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for values.h" >&5 echo $ECHO_N "checking for values.h... $ECHO_C" >&6 if test "${ac_cv_header_values_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_values_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5 echo "${ECHO_T}$ac_cv_header_values_h" >&6 fi if test $ac_cv_header_values_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_VALUES_H 1 _ACEOF fi if test "${ac_cv_header_limits_h+set}" = set; then echo "$as_me:$LINENO: checking for limits.h" >&5 echo $ECHO_N "checking for limits.h... $ECHO_C" >&6 if test "${ac_cv_header_limits_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5 echo "${ECHO_T}$ac_cv_header_limits_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking limits.h usability" >&5 echo $ECHO_N "checking limits.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking limits.h presence" >&5 echo $ECHO_N "checking limits.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: limits.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: limits.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: limits.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: limits.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: limits.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: limits.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: limits.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: limits.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------- ## ## Report this to the astrotcl lists. ## ## ----------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for limits.h" >&5 echo $ECHO_N "checking for limits.h... $ECHO_C" >&6 if test "${ac_cv_header_limits_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_limits_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5 echo "${ECHO_T}$ac_cv_header_limits_h" >&6 fi if test $ac_cv_header_limits_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIMITS_H 1 _ACEOF else cat >>confdefs.h <<\_ACEOF #define NO_LIMITS_H 1 _ACEOF fi if test "${ac_cv_header_stdlib_h+set}" = set; then echo "$as_me:$LINENO: checking for stdlib.h" >&5 echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6 if test "${ac_cv_header_stdlib_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5 echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking stdlib.h usability" >&5 echo $ECHO_N "checking stdlib.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking stdlib.h presence" >&5 echo $ECHO_N "checking stdlib.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: stdlib.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: stdlib.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: stdlib.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: stdlib.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: stdlib.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: stdlib.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: stdlib.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: stdlib.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------- ## ## Report this to the astrotcl lists. ## ## ----------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for stdlib.h" >&5 echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6 if test "${ac_cv_header_stdlib_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_stdlib_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5 echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6 fi if test $ac_cv_header_stdlib_h = yes; then tcl_ok=1 else tcl_ok=0 fi cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strtol" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strtoul" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strtod" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* if test $tcl_ok = 0; then cat >>confdefs.h <<\_ACEOF #define NO_STDLIB_H 1 _ACEOF fi if test "${ac_cv_header_string_h+set}" = set; then echo "$as_me:$LINENO: checking for string.h" >&5 echo $ECHO_N "checking for string.h... $ECHO_C" >&6 if test "${ac_cv_header_string_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5 echo "${ECHO_T}$ac_cv_header_string_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking string.h usability" >&5 echo $ECHO_N "checking string.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking string.h presence" >&5 echo $ECHO_N "checking string.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: string.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: string.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: string.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: string.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: string.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: string.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: string.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: string.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------- ## ## Report this to the astrotcl lists. ## ## ----------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for string.h" >&5 echo $ECHO_N "checking for string.h... $ECHO_C" >&6 if test "${ac_cv_header_string_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_string_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5 echo "${ECHO_T}$ac_cv_header_string_h" >&6 fi if test $ac_cv_header_string_h = yes; then tcl_ok=1 else tcl_ok=0 fi cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strstr" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strerror" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* # See also memmove check below for a place where NO_STRING_H can be # set and why. if test $tcl_ok = 0; then cat >>confdefs.h <<\_ACEOF #define NO_STRING_H 1 _ACEOF fi if test "${ac_cv_header_sys_wait_h+set}" = set; then echo "$as_me:$LINENO: checking for sys/wait.h" >&5 echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6 if test "${ac_cv_header_sys_wait_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking sys/wait.h usability" >&5 echo $ECHO_N "checking sys/wait.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking sys/wait.h presence" >&5 echo $ECHO_N "checking sys/wait.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: sys/wait.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: sys/wait.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: sys/wait.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: sys/wait.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: sys/wait.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: sys/wait.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------- ## ## Report this to the astrotcl lists. ## ## ----------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for sys/wait.h" >&5 echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6 if test "${ac_cv_header_sys_wait_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_sys_wait_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 fi if test $ac_cv_header_sys_wait_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_SYS_WAIT_H 1 _ACEOF fi if test "${ac_cv_header_dlfcn_h+set}" = set; then echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking dlfcn.h usability" >&5 echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking dlfcn.h presence" >&5 echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: dlfcn.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------- ## ## Report this to the astrotcl lists. ## ## ----------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_dlfcn_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 fi if test $ac_cv_header_dlfcn_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_DLFCN_H 1 _ACEOF fi # OS/390 lacks sys/param.h (and doesn't need it, by chance). for ac_header in sys/param.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------- ## ## Report this to the astrotcl lists. ## ## ----------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Let the user call this, because if it triggers, they will # need a compat/strtod.c that is correct. Users can also # use Tcl_GetDouble(FromObj) instead. #TEA_BUGGY_STRTOD fi #-------------------------------------------------------------------- # Do application specific checks (see aclocal.m4) #-------------------------------------------------------------------- # Load the Tclutil definitions cf=../tclutil/tclutilConfig.sh if test -f $cf ; then . $cf else { { echo "$as_me:$LINENO: error: $cf doesn't exist" >&5 echo "$as_me: error: $cf doesn't exist" >&2;} { (exit 1); exit 1; }; } fi for ac_header in sys/filio.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------- ## ## Report this to the astrotcl lists. ## ## ----------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Check if we need (or can use) the socklen_t type. echo "$as_me:$LINENO: checking for socklen_t" >&5 echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6 if test "${ac_cv_type_socklen_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { if ((socklen_t *) 0) return 0; if (sizeof (socklen_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_socklen_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_socklen_t=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_socklen_t" >&5 echo "${ECHO_T}$ac_cv_type_socklen_t" >&6 if test $ac_cv_type_socklen_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_SOCKLEN_T 1 _ACEOF fi cat >>confdefs.h <<\_ACEOF #define USE_COMPAT_CONST 1 _ACEOF #-------------------------------------------------------------------- # From the cfitsio configure script #-------------------------------------------------------------------- for ac_header in stdlib.h string.h math.h limits.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------- ## ## Report this to the astrotcl lists. ## ## ----------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF ANSI_HEADER=yes else ANSI_HEADER=no fi done # ================= test for the unix ftruncate function ================ echo "$as_me:$LINENO: checking \"whether ftruncate works\"" >&5 echo $ECHO_N "checking \"whether ftruncate works\"... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { ftruncate(0, 0); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cat >>confdefs.h <<\_ACEOF #define HAVE_FTRUNCATE 1 _ACEOF echo "$as_me:$LINENO: result: \"yes\"" >&5 echo "${ECHO_T}\"yes\"" >&6 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 echo "$as_me:$LINENO: result: \"no\"" >&5 echo "${ECHO_T}\"no\"" >&6 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # --------------------------------------------------------- # some systems define long long for 64-bit ints # --------------------------------------------------------- echo "$as_me:$LINENO: checking \"whether long long is defined\"" >&5 echo $ECHO_N "checking \"whether long long is defined\"... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { long long filler; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cat >>confdefs.h <<\_ACEOF #define HAVE_LONGLONG 1 _ACEOF echo "$as_me:$LINENO: result: \"yes\"" >&5 echo "${ECHO_T}\"yes\"" >&6 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 echo "$as_me:$LINENO: result: \"no\"" >&5 echo "${ECHO_T}\"no\"" >&6 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext # ------------------------------------------------------------------------- # check is System V IPC is supported on this machine # ------------------------------------------------------------------------- echo "$as_me:$LINENO: checking \"whether system V style IPC services are supported\"" >&5 echo $ECHO_N "checking \"whether system V style IPC services are supported\"... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { shmat(0, 0, 0); shmdt(0); shmget(0, 0, 0); semget(0, 0, 0); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cat >>confdefs.h <<\_ACEOF #define HAVE_SHMEM_SERVICES 1 _ACEOF my_shmem=\${SOURCES_SHMEM} echo "$as_me:$LINENO: result: \"yes\"" >&5 echo "${ECHO_T}\"yes\"" >&6 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 echo "$as_me:$LINENO: result: \"no\"" >&5 echo "${ECHO_T}\"no\"" >&6 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # ------------------------------------------------------------------------- # some systems define flock_t, for others we have to define it ourselves # ------------------------------------------------------------------------- echo "$as_me:$LINENO: checking \"do we have flock_t defined in sys/fcntl.h\"" >&5 echo $ECHO_N "checking \"do we have flock_t defined in sys/fcntl.h\"... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { flock_t filler; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cat >>confdefs.h <<\_ACEOF #define HAVE_FLOCK_T 1 _ACEOF echo "$as_me:$LINENO: result: \"yes\"" >&5 echo "${ECHO_T}\"yes\"" >&6 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 echo "$as_me:$LINENO: result: \"no\"" >&5 echo "${ECHO_T}\"no\"" >&6 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext if test "$HAVE_FLOCK_T" != 1; then echo "$as_me:$LINENO: checking \"do we have flock_t defined in sys/flock.h\"" >&5 echo $ECHO_N "checking \"do we have flock_t defined in sys/flock.h\"... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { flock_t filler; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cat >>confdefs.h <<\_ACEOF #define HAVE_FLOCK_T 1 _ACEOF echo "$as_me:$LINENO: result: \"yes\"" >&5 echo "${ECHO_T}\"yes\"" >&6 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 echo "$as_me:$LINENO: result: \"no\"" >&5 echo "${ECHO_T}\"no\"" >&6 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi # ------------------------------------------------------------------------- # there are some idiosyncrasies with semun defs (used in semxxx). Solaris # does not define it at all # ------------------------------------------------------------------------- echo "$as_me:$LINENO: checking \"do we have union semun defined\"" >&5 echo $ECHO_N "checking \"do we have union semun defined\"... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { union semun filler; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cat >>confdefs.h <<\_ACEOF #define HAVE_UNION_SEMUN 1 _ACEOF echo "$as_me:$LINENO: result: \"yes\"" >&5 echo "${ECHO_T}\"yes\"" >&6 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 echo "$as_me:$LINENO: result: \"no\"" >&5 echo "${ECHO_T}\"no\"" >&6 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >>confdefs.h <<\_ACEOF #define HAVE_NET_SERVICES 1 _ACEOF # ==================== END OF cfitsio SECTION ================ #------------------------------------------------------------------------ # ASTROTCL_PATH_CFITSIO -- # # Locate the CFITSIO library # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-cfitsio=... # # Defines the following vars: # CFITSIO_LIB_SPEC String to add to link the CFITSIO lib (-L... -lBLT) # CFITSIO_LIB_DIR Directory containing libcfitsio.so #------------------------------------------------------------------------ #------------------------------------------------------------------------ # Check if we require additional libraries to support C++ shareable # libraries. system=`uname -s`-`uname -r` SHLIB_LD_CXX_LIBS="" export SHLIB_LD_CXX_LIBS case $system in SunOS-5*) SHLIB_LD_CXX_LIBS="-lCrun -lCstd" ;; OSF*) SHLIB_LD_CXX_LIBS="-lcxx -lcxxstd" ;; esac #------------------------------------------------------------------------- # The cxx C++ compiler under Tru64 UNIX needs the special # CXXFLAGS "-std gnu -D__USE_STD_IOSTREAM=1". These allow the standard # library streams headers to work and to generate templates that do # not require special handling throughout skycat directories (normally # template object files are created in various cxx_repository subdirectories, # this way the object files are kept embedded the usual object files, see # the cxx man page for details). #------------------------------------------------------------------------- export CXXFLAGS case $system in OSF*) case "x$CXX" in xcxx*) CXXFLAGS="$CXXFLAGS -g3 -std gnu -D__USE_STD_IOSTREAM=1" ;; esac ;; esac #----------------------------------------------------------------------- # __CHANGE__ # Specify the C source files to compile in TEA_ADD_SOURCES, # public headers that need to be installed in TEA_ADD_HEADERS, # stub library C source files to compile in TEA_ADD_STUB_SOURCES, # and runtime Tcl library files in TEA_ADD_TCL_SOURCES. # This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS # and PKG_TCL_SOURCES. #----------------------------------------------------------------------- csources=`cd $srcdir; echo generic/*.[Cc] press/*.[Cc] libwcs/*.[Cc]` cheaders=`cd $srcdir; echo generic/*.h press/*.h libwcs/*.h` cincludes="-I$srcdir/../tclutil/generic -I$srcdir/generic -I$srcdir/press -I$srcdir/libwcs" tclsources=`cd $srcdir; echo library/*.tcl` vars="${csources}" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done vars="${cheaders}" for i in $vars; do # check for existence, be strict because it is installed if test ! -f "${srcdir}/$i" ; then { { echo "$as_me:$LINENO: error: could not find header file '${srcdir}/$i'" >&5 echo "$as_me: error: could not find header file '${srcdir}/$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_HEADERS="$PKG_HEADERS $i" done vars="$cincludes" for i in $vars; do PKG_INCLUDES="$PKG_INCLUDES $i" done vars="$tclutil_BUILD_LIB_SPEC ${BLT_LIB_SPEC} ${CFITSIO_LIB_SPEC}" for i in $vars; do if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then # Convert foo.lib to -lfoo for GCC. No-op if not *.lib i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'` fi PKG_LIBS="$PKG_LIBS $i" done PKG_CFLAGS="$PKG_CFLAGS " vars="" for i in $vars; do # check for existence - allows for generic/win/unix VPATH if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find stub source file '$i'" >&5 echo "$as_me: error: could not find stub source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j" done vars="${tclsources}" for i in $vars; do # check for existence, be strict because it is installed if test ! -f "${srcdir}/$i" ; then { { echo "$as_me:$LINENO: error: could not find tcl source file '${srcdir}/$i'" >&5 echo "$as_me: error: could not find tcl source file '${srcdir}/$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i" done #-------------------------------------------------------------------- # __CHANGE__ # A few miscellaneous platform-specific items: # # Define a special symbol for Windows (BUILD_sample in this case) so # that we create the export library with the dll. # # Windows creates a few extra files that need to be cleaned up. # You can add more files to clean if your extension creates any extra # files. # # TEA_ADD_* any platform specific compiler/build info here. #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" ; then cat >>confdefs.h <<\_ACEOF #define BUILD_astrotcl 1 _ACEOF CLEANFILES="*.lib *.dll *.exp *.ilk *.pdb vc*.pch" #TEA_ADD_SOURCES([win/winFile.c]) #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"]) else CLEANFILES="" #TEA_ADD_SOURCES([unix/unixFile.c]) #TEA_ADD_LIBS([-lsuperfly]) fi #-------------------------------------------------------------------- # __CHANGE__ # Choose which headers you need. Extension authors should try very # hard to only rely on the Tcl public header files. Internal headers # contain private data structures and are subject to change without # notice. # This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking for Tcl public headers" >&5 echo $ECHO_N "checking for Tcl public headers... $ECHO_C" >&6 # Check whether --with-tclinclude or --without-tclinclude was given. if test "${with_tclinclude+set}" = set; then withval="$with_tclinclude" with_tclinclude=${withval} fi; if test "${ac_cv_c_tclh+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Use the value from --with-tclinclude, if it was given if test x"${with_tclinclude}" != x ; then if test -f "${with_tclinclude}/tcl.h" ; then ac_cv_c_tclh=${with_tclinclude} else { { echo "$as_me:$LINENO: error: ${with_tclinclude} directory does not contain tcl.h" >&5 echo "$as_me: error: ${with_tclinclude} directory does not contain tcl.h" >&2;} { (exit 1); exit 1; }; } fi else # If Tcl was built as a framework, attempt to use # the framework's Headers directory case ${TCL_DEFS} in *TCL_FRAMEWORK*) list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`" ;; *) list="" ;; esac # Look in the source dir only if Tcl is not installed, # and in that situation, look there before installed locations. if test -f "$TCL_BIN_DIR/Makefile" ; then list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`" fi # Check order: pkg --prefix location, Tcl's --prefix location, # relative to directory of tclConfig.sh. eval "temp_includedir=${includedir}" list="$list \ `ls -d ${temp_includedir} 2>/dev/null` \ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then list="$list /usr/local/include /usr/include" if test x"${TCL_INCLUDE_SPEC}" != x ; then d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'` list="$list `ls -d ${d} 2>/dev/null`" fi fi for i in $list ; do if test -f "$i/tcl.h" ; then ac_cv_c_tclh=$i break fi done fi fi # Print a message based on how we determined the include path if test x"${ac_cv_c_tclh}" = x ; then { { echo "$as_me:$LINENO: error: tcl.h not found. Please specify its location with --with-tclinclude" >&5 echo "$as_me: error: tcl.h not found. Please specify its location with --with-tclinclude" >&2;} { (exit 1); exit 1; }; } else echo "$as_me:$LINENO: result: ${ac_cv_c_tclh}" >&5 echo "${ECHO_T}${ac_cv_c_tclh}" >&6 fi # Convert to a native path and substitute into the output files. INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}` TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" #TEA_PRIVATE_TCL_HEADERS echo "$as_me:$LINENO: checking for Tk public headers" >&5 echo $ECHO_N "checking for Tk public headers... $ECHO_C" >&6 # Check whether --with-tkinclude or --without-tkinclude was given. if test "${with_tkinclude+set}" = set; then withval="$with_tkinclude" with_tkinclude=${withval} fi; if test "${ac_cv_c_tkh+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Use the value from --with-tkinclude, if it was given if test x"${with_tkinclude}" != x ; then if test -f "${with_tkinclude}/tk.h" ; then ac_cv_c_tkh=${with_tkinclude} else { { echo "$as_me:$LINENO: error: ${with_tkinclude} directory does not contain tk.h" >&5 echo "$as_me: error: ${with_tkinclude} directory does not contain tk.h" >&2;} { (exit 1); exit 1; }; } fi else # If Tk was built as a framework, attempt to use # the framework's Headers directory. case ${TK_DEFS} in *TK_FRAMEWORK*) list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`" ;; *) list="" ;; esac # Look in the source dir only if Tk is not installed, # and in that situation, look there before installed locations. if test -f "$TK_BIN_DIR/Makefile" ; then list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`" fi # Check order: pkg --prefix location, Tk's --prefix location, # relative to directory of tkConfig.sh, Tcl's --prefix location, # relative to directory of tclConfig.sh. eval "temp_includedir=${includedir}" list="$list \ `ls -d ${temp_includedir} 2>/dev/null` \ `ls -d ${TK_PREFIX}/include 2>/dev/null` \ `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then list="$list /usr/local/include /usr/include" fi for i in $list ; do if test -f "$i/tk.h" ; then ac_cv_c_tkh=$i break fi done fi fi # Print a message based on how we determined the include path if test x"${ac_cv_c_tkh}" = x ; then { { echo "$as_me:$LINENO: error: tk.h not found. Please specify its location with --with-tkinclude" >&5 echo "$as_me: error: tk.h not found. Please specify its location with --with-tkinclude" >&2;} { (exit 1); exit 1; }; } else echo "$as_me:$LINENO: result: ${ac_cv_c_tkh}" >&5 echo "${ECHO_T}${ac_cv_c_tkh}" >&6 fi # Convert to a native path and substitute into the output files. INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}` TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" if test "${TEA_WINDOWINGSYSTEM}" = "win32" \ -o "${TEA_WINDOWINGSYSTEM}" = "aqua"; then # On Windows and Aqua, we need the X compat headers echo "$as_me:$LINENO: checking for X11 header files" >&5 echo $ECHO_N "checking for X11 header files... $ECHO_C" >&6 if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`" TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" fi echo "$as_me:$LINENO: result: ${INCLUDE_DIR_NATIVE}" >&5 echo "${ECHO_T}${INCLUDE_DIR_NATIVE}" >&6 fi #TEA_PRIVATE_TK_HEADERS if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then echo "$as_me:$LINENO: checking for X" >&5 echo $ECHO_N "checking for X... $ECHO_C" >&6 # Check whether --with-x or --without-x was given. if test "${with_x+set}" = set; then withval="$with_x" fi; # $have_x is `yes', `no', `disabled', or empty when we do not yet know. if test "x$with_x" = xno; then # The user explicitly disabled X. have_x=disabled else if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then # Both variables are already set. have_x=yes else if test "${ac_cv_have_x+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # One or both of the vars are not set, and there is no cached value. ac_x_includes=no ac_x_libraries=no rm -fr conftest.dir if mkdir conftest.dir; then cd conftest.dir # Make sure to not put "make" in the Imakefile rules, since we grep it out. cat >Imakefile <<'_ACEOF' acfindx: @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"' _ACEOF if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} acfindx 2>/dev/null | grep -v make` # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. for ac_extension in a so sl dylib la dll; do if test ! -f $ac_im_usrlibdir/libX11.$ac_extension && test -f $ac_im_libdir/libX11.$ac_extension; then ac_im_usrlibdir=$ac_im_libdir; break fi done # Screen out bogus values from the imake configuration. They are # bogus both because they are the default anyway, and because # using them would break gcc on systems where it needs fixed includes. case $ac_im_incroot in /usr/include) ;; *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; esac case $ac_im_usrlibdir in /usr/lib | /lib) ;; *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; esac fi cd .. rm -fr conftest.dir fi # Standard set of common directories for X headers. # Check X11 before X11Rn because it is often a symlink to the current release. ac_x_header_dirs=' /usr/X11/include /usr/X11R6/include /usr/X11R5/include /usr/X11R4/include /usr/include/X11 /usr/include/X11R6 /usr/include/X11R5 /usr/include/X11R4 /usr/local/X11/include /usr/local/X11R6/include /usr/local/X11R5/include /usr/local/X11R4/include /usr/local/include/X11 /usr/local/include/X11R6 /usr/local/include/X11R5 /usr/local/include/X11R4 /usr/X386/include /usr/x386/include /usr/XFree86/include/X11 /usr/include /usr/local/include /usr/unsupported/include /usr/athena/include /usr/local/x11r5/include /usr/lpp/Xamples/include /usr/openwin/include /usr/openwin/share/include' if test "$ac_x_includes" = no; then # Guess where to find include files, by looking for Intrinsic.h. # First, try using that file with no special directory specified. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # We can compile using X headers with no special include directory. ac_x_includes= else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 for ac_dir in $ac_x_header_dirs; do if test -r "$ac_dir/X11/Intrinsic.h"; then ac_x_includes=$ac_dir break fi done fi rm -f conftest.err conftest.$ac_ext fi # $ac_x_includes = no if test "$ac_x_libraries" = no; then # Check for the libraries. # See if we find them without any special options. # Don't add to $LIBS permanently. ac_save_LIBS=$LIBS LIBS="-lXt $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { XtMalloc (0) ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then LIBS=$ac_save_LIBS # We can link X programs with no special library path. ac_x_libraries= else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 LIBS=$ac_save_LIBS for ac_dir in `echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` do # Don't even attempt the hair of trying to link an X program! for ac_extension in a so sl dylib la dll; do if test -r $ac_dir/libXt.$ac_extension; then ac_x_libraries=$ac_dir break 2 fi done done fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi # $ac_x_libraries = no if test "$ac_x_includes" = no || test "$ac_x_libraries" = no; then # Didn't find X anywhere. Cache the known absence of X. ac_cv_have_x="have_x=no" else # Record where we found X for the cache. ac_cv_have_x="have_x=yes \ ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries" fi fi fi eval "$ac_cv_have_x" fi # $with_x != no if test "$have_x" != yes; then echo "$as_me:$LINENO: result: $have_x" >&5 echo "${ECHO_T}$have_x" >&6 no_x=yes else # If each of the values was on the command line, it overrides each guess. test "x$x_includes" = xNONE && x_includes=$ac_x_includes test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries # Update the cache value to reflect the command line values. ac_cv_have_x="have_x=yes \ ac_x_includes=$x_includes ac_x_libraries=$x_libraries" echo "$as_me:$LINENO: result: libraries $x_libraries, headers $x_includes" >&5 echo "${ECHO_T}libraries $x_libraries, headers $x_includes" >&6 fi not_really_there="" if test "$no_x" = ""; then if test "$x_includes" = ""; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 not_really_there="yes" fi rm -f conftest.err conftest.$ac_ext else if test ! -r $x_includes/X11/Intrinsic.h; then not_really_there="yes" fi fi fi if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then echo "$as_me:$LINENO: checking for X11 header files" >&5 echo $ECHO_N "checking for X11 header files... $ECHO_C" >&6 XINCLUDES="# no special path needed" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 XINCLUDES="nope" fi rm -f conftest.err conftest.$ac_ext if test "$XINCLUDES" = nope; then dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include" for i in $dirs ; do if test -r $i/X11/Intrinsic.h; then echo "$as_me:$LINENO: result: $i" >&5 echo "${ECHO_T}$i" >&6 XINCLUDES=" -I$i" break fi done fi else if test "$x_includes" != ""; then XINCLUDES=-I$x_includes else XINCLUDES="# no special path needed" fi fi if test "$XINCLUDES" = nope; then echo "$as_me:$LINENO: result: could not find any!" >&5 echo "${ECHO_T}could not find any!" >&6 XINCLUDES="# no include files found" fi if test "$no_x" = yes; then echo "$as_me:$LINENO: checking for X11 libraries" >&5 echo $ECHO_N "checking for X11 libraries... $ECHO_C" >&6 XLIBSW=nope dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib" for i in $dirs ; do if test -r $i/libX11.dylib -o -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl; then echo "$as_me:$LINENO: result: $i" >&5 echo "${ECHO_T}$i" >&6 XLIBSW="-L$i -lX11" x_libraries="$i" break fi done else if test "$x_libraries" = ""; then XLIBSW=-lX11 else XLIBSW="-L$x_libraries -lX11" fi fi if test "$XLIBSW" = nope ; then echo "$as_me:$LINENO: checking for XCreateWindow in -lXwindow" >&5 echo $ECHO_N "checking for XCreateWindow in -lXwindow... $ECHO_C" >&6 if test "${ac_cv_lib_Xwindow_XCreateWindow+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXwindow $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char XCreateWindow (); int main () { XCreateWindow (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_Xwindow_XCreateWindow=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xwindow_XCreateWindow=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_Xwindow_XCreateWindow" >&5 echo "${ECHO_T}$ac_cv_lib_Xwindow_XCreateWindow" >&6 if test $ac_cv_lib_Xwindow_XCreateWindow = yes; then XLIBSW=-lXwindow fi fi if test "$XLIBSW" = nope ; then echo "$as_me:$LINENO: result: could not find any! Using -lX11." >&5 echo "${ECHO_T}could not find any! Using -lX11." >&6 XLIBSW=-lX11 fi if test x"${XLIBSW}" != x ; then PKG_LIBS="${PKG_LIBS} ${XLIBSW}" fi fi #-------------------------------------------------------------------- # Check whether --enable-threads or --disable-threads was given. # This auto-enables if Tcl was compiled threaded. #-------------------------------------------------------------------- # Check whether --enable-threads or --disable-threads was given. if test "${enable_threads+set}" = set; then enableval="$enable_threads" tcl_ok=$enableval else tcl_ok=yes fi; if test "${enable_threads+set}" = set; then enableval="$enable_threads" tcl_ok=$enableval else tcl_ok=yes fi if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then TCL_THREADS=1 if test "${TEA_PLATFORM}" != "windows" ; then # We are always OK on Windows, so check what this platform wants. cat >>confdefs.h <<\_ACEOF #define USE_THREAD_ALLOC 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _REENTRANT 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _THREAD_SAFE 1 _ACEOF echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthread" >&5 echo $ECHO_N "checking for pthread_mutex_init in -lpthread... $ECHO_C" >&6 if test "${ac_cv_lib_pthread_pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_pthread_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthread_pthread_mutex_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_pthread_pthread_mutex_init" >&6 if test $ac_cv_lib_pthread_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "no"; then # Check a little harder for __pthread_mutex_init in the # same library, as some systems hide it there until # pthread.h is defined. We could alternatively do an # AC_TRY_COMPILE with pthread.h, but that will work with # libpthread really doesn't exist, like AIX 4.2. # [Bug: 4359] echo "$as_me:$LINENO: checking for __pthread_mutex_init in -lpthread" >&5 echo $ECHO_N "checking for __pthread_mutex_init in -lpthread... $ECHO_C" >&6 if test "${ac_cv_lib_pthread___pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char __pthread_mutex_init (); int main () { __pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_pthread___pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthread___pthread_mutex_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_pthread___pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_pthread___pthread_mutex_init" >&6 if test $ac_cv_lib_pthread___pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthread" else echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthreads" >&5 echo $ECHO_N "checking for pthread_mutex_init in -lpthreads... $ECHO_C" >&6 if test "${ac_cv_lib_pthreads_pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthreads $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_pthreads_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthreads_pthread_mutex_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_pthreads_pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_pthreads_pthread_mutex_init" >&6 if test $ac_cv_lib_pthreads_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthreads" else echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc" >&5 echo $ECHO_N "checking for pthread_mutex_init in -lc... $ECHO_C" >&6 if test "${ac_cv_lib_c_pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_c_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_c_pthread_mutex_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_c_pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_c_pthread_mutex_init" >&6 if test $ac_cv_lib_c_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "no"; then echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc_r" >&5 echo $ECHO_N "checking for pthread_mutex_init in -lc_r... $ECHO_C" >&6 if test "${ac_cv_lib_c_r_pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc_r $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_c_r_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_c_r_pthread_mutex_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_c_r_pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_c_r_pthread_mutex_init" >&6 if test $ac_cv_lib_c_r_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -pthread" else TCL_THREADS=0 { echo "$as_me:$LINENO: WARNING: \"Don t know how to find pthread lib on your system - thread support disabled\"" >&5 echo "$as_me: WARNING: \"Don t know how to find pthread lib on your system - thread support disabled\"" >&2;} fi fi fi fi fi else TCL_THREADS=0 fi # Do checking message here to not mess up interleaved configure output echo "$as_me:$LINENO: checking for building with threads" >&5 echo $ECHO_N "checking for building with threads... $ECHO_C" >&6 if test "${TCL_THREADS}" = "1"; then cat >>confdefs.h <<\_ACEOF #define TCL_THREADS 1 _ACEOF #LIBS="$LIBS $THREADS_LIBS" echo "$as_me:$LINENO: result: yes (default)" >&5 echo "${ECHO_T}yes (default)" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi # TCL_THREADS sanity checking. See if our request for building with # threads is the same as the way Tcl was built. If not, warn the user. case ${TCL_DEFS} in *THREADS=1*) if test "${TCL_THREADS}" = "0"; then { echo "$as_me:$LINENO: WARNING: Building ${PACKAGE_NAME} without threads enabled, but building against Tcl that IS thread-enabled. It is recommended to use --enable-threads." >&5 echo "$as_me: WARNING: Building ${PACKAGE_NAME} without threads enabled, but building against Tcl that IS thread-enabled. It is recommended to use --enable-threads." >&2;} fi ;; *) if test "${TCL_THREADS}" = "1"; then { echo "$as_me:$LINENO: WARNING: --enable-threads requested, but building against a Tcl that is NOT thread-enabled. This is an OK configuration that will also run in a thread-enabled core." >&5 echo "$as_me: WARNING: --enable-threads requested, but building against a Tcl that is NOT thread-enabled. This is an OK configuration that will also run in a thread-enabled core." >&2;} fi ;; esac #-------------------------------------------------------------------- # The statement below defines a collection of symbols related to # building as a shared library instead of a static library. #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking how to build libraries" >&5 echo $ECHO_N "checking how to build libraries... $ECHO_C" >&6 # Check whether --enable-shared or --disable-shared was given. if test "${enable_shared+set}" = set; then enableval="$enable_shared" tcl_ok=$enableval else tcl_ok=yes fi; if test "${enable_shared+set}" = set; then enableval="$enable_shared" tcl_ok=$enableval else tcl_ok=yes fi if test "$tcl_ok" = "yes" ; then echo "$as_me:$LINENO: result: shared" >&5 echo "${ECHO_T}shared" >&6 SHARED_BUILD=1 else echo "$as_me:$LINENO: result: static" >&5 echo "${ECHO_T}static" >&6 SHARED_BUILD=0 cat >>confdefs.h <<\_ACEOF #define STATIC_BUILD 1 _ACEOF fi #-------------------------------------------------------------------- # This macro figures out what flags to use with the compiler/linker # when building shared/static debug/optimized objects. This information # can be taken from the tclConfig.sh file, but this figures it all out. #-------------------------------------------------------------------- # Step 0: Enable 64 bit support? echo "$as_me:$LINENO: checking if 64bit support is enabled" >&5 echo $ECHO_N "checking if 64bit support is enabled... $ECHO_C" >&6 # Check whether --enable-64bit or --disable-64bit was given. if test "${enable_64bit+set}" = set; then enableval="$enable_64bit" do64bit=$enableval else do64bit=no fi; echo "$as_me:$LINENO: result: $do64bit" >&5 echo "${ECHO_T}$do64bit" >&6 # Step 0.b: Enable Solaris 64 bit VIS support? echo "$as_me:$LINENO: checking if 64bit Sparc VIS support is requested" >&5 echo $ECHO_N "checking if 64bit Sparc VIS support is requested... $ECHO_C" >&6 # Check whether --enable-64bit-vis or --disable-64bit-vis was given. if test "${enable_64bit_vis+set}" = set; then enableval="$enable_64bit_vis" do64bitVIS=$enableval else do64bitVIS=no fi; echo "$as_me:$LINENO: result: $do64bitVIS" >&5 echo "${ECHO_T}$do64bitVIS" >&6 if test "$do64bitVIS" = "yes"; then # Force 64bit on with VIS do64bit=yes fi # Step 0.c: Cross-compiling options for Windows/CE builds? if test "${TEA_PLATFORM}" = "windows" ; then echo "$as_me:$LINENO: checking if Windows/CE build is requested" >&5 echo $ECHO_N "checking if Windows/CE build is requested... $ECHO_C" >&6 # Check whether --enable-wince or --disable-wince was given. if test "${enable_wince+set}" = set; then enableval="$enable_wince" doWince=$enableval else doWince=no fi; echo "$as_me:$LINENO: result: $doWince" >&5 echo "${ECHO_T}$doWince" >&6 fi # Step 1: set the variable "system" to hold the name and version number # for the system. This can usually be done via the "uname" command, but # there are a few systems, like Next, where this doesn't work. echo "$as_me:$LINENO: checking system version (for dynamic loading)" >&5 echo $ECHO_N "checking system version (for dynamic loading)... $ECHO_C" >&6 if test -f /usr/lib/NextStep/software_version; then system=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version` else system=`uname -s`-`uname -r` if test "$?" -ne 0 ; then echo "$as_me:$LINENO: result: unknown (can't find uname command)" >&5 echo "${ECHO_T}unknown (can't find uname command)" >&6 system=unknown else # Special check for weird MP-RAS system (uname returns weird # results, and the version is kept in special file). if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then system=MP-RAS-`awk '{print }' /etc/.relid` fi if test "`uname -s`" = "AIX" ; then system=AIX-`uname -v`.`uname -r` fi if test "${TEA_PLATFORM}" = "windows" ; then system=windows fi echo "$as_me:$LINENO: result: $system" >&5 echo "${ECHO_T}$system" >&6 fi fi # Step 2: check for existence of -ldl library. This is needed because # Linux can use either -ldl or -ldld for dynamic loading. echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 if test "${ac_cv_lib_dl_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char dlopen (); int main () { dlopen (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 if test $ac_cv_lib_dl_dlopen = yes; then have_dl=yes else have_dl=no fi # Step 3: set configuration options based on system name and version. # This is similar to Tcl's unix/tcl.m4 except that we've added a # "windows" case and CC_SEARCH_FLAGS becomes LD_SEARCH_FLAGS for us # (and we have no CC_SEARCH_FLAGS). do64bit_ok=no LDFLAGS_ORIG="$LDFLAGS" TCL_EXPORT_FILE_SUFFIX="" UNSHARED_LIB_SUFFIX="" TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`' ECHO_VERSION='`echo ${PACKAGE_VERSION}`' TCL_LIB_VERSIONS_OK=ok CFLAGS_DEBUG=-g if test "$GCC" = "yes" ; then CFLAGS_OPTIMIZE=-O2 CFLAGS_WARNING="-Wall -Wno-implicit-int" else CFLAGS_OPTIMIZE=-O CFLAGS_WARNING="" fi TCL_NEEDS_EXP_FILE=0 TCL_BUILD_EXP_FILE="" TCL_EXP_FILE="" # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_AR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="ar" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then echo "$as_me:$LINENO: result: $AR" >&5 echo "${ECHO_T}$AR" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi STLIB_LD='${AR} cr' LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH" case $system in windows) # This is a 2-stage check to make sure we have the 64-bit SDK # We have to know where the SDK is installed. # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs # MACHINE is IX86 for LINK, but this is used by the manifest, # which requires x86|amd64|ia64. MACHINE="X86" if test "$do64bit" != "no" ; then if test "x${MSSDK}x" = "xx" ; then MSSDK="C:/Progra~1/Microsoft Platform SDK" fi MSSDK=`echo "$MSSDK" | sed -e 's!\\\!/!g'` PATH64="" case "$do64bit" in amd64|x64|yes) MACHINE="AMD64" ; # default to AMD64 64-bit build PATH64="${MSSDK}/Bin/Win64/x86/AMD64" ;; ia64) MACHINE="IA64" PATH64="${MSSDK}/Bin/Win64" ;; esac if test ! -d "${PATH64}" ; then { echo "$as_me:$LINENO: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&5 echo "$as_me: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&2;} { echo "$as_me:$LINENO: WARNING: Ensure latest Platform SDK is installed" >&5 echo "$as_me: WARNING: Ensure latest Platform SDK is installed" >&2;} do64bit="no" else echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5 echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6 do64bit_ok="yes" fi fi if test "$doWince" != "no" ; then if test "$do64bit" != "no" ; then { { echo "$as_me:$LINENO: error: Windows/CE and 64-bit builds incompatible" >&5 echo "$as_me: error: Windows/CE and 64-bit builds incompatible" >&2;} { (exit 1); exit 1; }; } fi if test "$GCC" = "yes" ; then { { echo "$as_me:$LINENO: error: Windows/CE and GCC builds incompatible" >&5 echo "$as_me: error: Windows/CE and GCC builds incompatible" >&2;} { (exit 1); exit 1; }; } fi # First, look for one uninstalled. # the alternative search directory is invoked by --with-celib if test x"${no_celib}" = x ; then # we reset no_celib in case something fails here no_celib=true # Check whether --with-celib or --without-celib was given. if test "${with_celib+set}" = set; then withval="$with_celib" with_celibconfig=${withval} fi; echo "$as_me:$LINENO: checking for Windows/CE celib directory" >&5 echo $ECHO_N "checking for Windows/CE celib directory... $ECHO_C" >&6 if test "${ac_cv_c_celibconfig+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # First check to see if --with-celibconfig was specified. if test x"${with_celibconfig}" != x ; then if test -d "${with_celibconfig}/inc" ; then ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)` else { { echo "$as_me:$LINENO: error: ${with_celibconfig} directory doesn't contain inc directory" >&5 echo "$as_me: error: ${with_celibconfig} directory doesn't contain inc directory" >&2;} { (exit 1); exit 1; }; } fi fi # then check for a celib library if test x"${ac_cv_c_celibconfig}" = x ; then for i in \ ../celib-palm-3.0 \ ../celib \ ../../celib-palm-3.0 \ ../../celib \ `ls -dr ../celib-*3.[0-9]* 2>/dev/null` \ ${srcdir}/../celib-palm-3.0 \ ${srcdir}/../celib \ `ls -dr ${srcdir}/../celib-*3.[0-9]* 2>/dev/null` \ ; do if test -d "$i/inc" ; then ac_cv_c_celibconfig=`(cd $i; pwd)` break fi done fi fi if test x"${ac_cv_c_celibconfig}" = x ; then { { echo "$as_me:$LINENO: error: Cannot find celib support library directory" >&5 echo "$as_me: error: Cannot find celib support library directory" >&2;} { (exit 1); exit 1; }; } else no_celib= CELIB_DIR=${ac_cv_c_celibconfig} CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'` echo "$as_me:$LINENO: result: found $CELIB_DIR" >&5 echo "${ECHO_T}found $CELIB_DIR" >&6 fi fi # Set defaults for common evc4/PPC2003 setup # Currently Tcl requires 300+, possibly 420+ for sockets CEVERSION=420; # could be 211 300 301 400 420 ... TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ... ARCH=ARM; # could be ARM MIPS X86EM ... PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002" if test "$doWince" != "yes"; then # If !yes then the user specified something # Reset ARCH to allow user to skip specifying it ARCH= eval `echo $doWince | awk -F, '{ \ if (length($1)) { printf "CEVERSION=\"%s\"\n", $1; \ if ($1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \ if (length($2)) { printf "TARGETCPU=\"%s\"\n", toupper($2) }; \ if (length($3)) { printf "ARCH=\"%s\"\n", toupper($3) }; \ if (length($4)) { printf "PLATFORM=\"%s\"\n", $4 }; \ }'` if test "x${ARCH}" = "x" ; then ARCH=$TARGETCPU; fi fi OSVERSION=WCE$CEVERSION; if test "x${WCEROOT}" = "x" ; then WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0" if test ! -d "${WCEROOT}" ; then WCEROOT="C:/Program Files/Microsoft eMbedded Tools" fi fi if test "x${SDKROOT}" = "x" ; then SDKROOT="C:/Program Files/Windows CE Tools" if test ! -d "${SDKROOT}" ; then SDKROOT="C:/Windows CE Tools" fi fi WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'` SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'` if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \ -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then { { echo "$as_me:$LINENO: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&5 echo "$as_me: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&2;} { (exit 1); exit 1; }; } doWince="no" else # We could PATH_NOSPACE these, but that's not important, # as long as we quote them when used. CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include" if test -d "${CEINCLUDE}/${TARGETCPU}" ; then CEINCLUDE="${CEINCLUDE}/${TARGETCPU}" fi CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" fi fi if test "$GCC" != "yes" ; then if test "${SHARED_BUILD}" = "0" ; then runtime=-MT else runtime=-MD fi if test "$do64bit" != "no" ; then # All this magic is necessary for the Win64 SDK RC1 - hobbs CC="\"${PATH64}/cl.exe\"" CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\"" RC="\"${MSSDK}/bin/rc.exe\"" lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\"" LINKBIN="\"${PATH64}/link.exe\"" CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d" CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" # Avoid 'unresolved external symbol __security_cookie' # errors, c.f. http://support.microsoft.com/?id=894573 vars="bufferoverflowU.lib" for i in $vars; do if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then # Convert foo.lib to -lfoo for GCC. No-op if not *.lib i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'` fi PKG_LIBS="$PKG_LIBS $i" done elif test "$doWince" != "no" ; then CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin" if test "${TARGETCPU}" = "X86"; then CC="\"${CEBINROOT}/cl.exe\"" else CC="\"${CEBINROOT}/cl${ARCH}.exe\"" fi CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\"" RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\"" arch=`echo ${ARCH} | awk '{print tolower($0)}'` defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS" if test "${SHARED_BUILD}" = "1" ; then # Static CE builds require static celib as well defs="${defs} _DLL" fi for i in $defs ; do cat >>confdefs.h <<_ACEOF #define $i 1 _ACEOF done cat >>confdefs.h <<_ACEOF #define _WIN32_WCE $CEVERSION _ACEOF cat >>confdefs.h <<_ACEOF #define UNDER_CE $CEVERSION _ACEOF CFLAGS_DEBUG="-nologo -Zi -Od" CFLAGS_OPTIMIZE="-nologo -Ox" lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'` lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo" LINKBIN="\"${CEBINROOT}/link.exe\"" else RC="rc" lflags="-nologo" LINKBIN="link" CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d" CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" fi fi if test "$GCC" = "yes"; then # mingw gcc mode RC="windres" CFLAGS_DEBUG="-g" CFLAGS_OPTIMIZE="-O2" SHLIB_LD="$CXX -shared" UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}" LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}" else SHLIB_LD="${LINKBIN} -dll ${lflags}" # link -lib only works when -lib is the first arg STLIB_LD="${LINKBIN} -lib ${lflags}" UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib' PATHTYPE=-w # For information on what debugtype is most useful, see: # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp # This essentially turns it all on. LDFLAGS_DEBUG="-debug:full -debugtype:both -warn:2" LDFLAGS_OPTIMIZE="-release" if test "$doWince" != "no" ; then LDFLAGS_CONSOLE="-link ${lflags}" LDFLAGS_WINDOW=${LDFLAGS_CONSOLE} else LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}" LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}" fi fi SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".dll" SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll' TCL_LIB_VERSIONS_OK=nodots # Bogus to avoid getting this turned off DL_OBJS="tclLoadNone.obj" ;; AIX-*) if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes" ; then # AIX requires the _r compiler when gcc isn't being used case "${CC}" in *_r) # ok ... ;; *) CC=${CC}_r ;; esac echo "$as_me:$LINENO: result: Using $CC for compiling with threads" >&5 echo "${ECHO_T}Using $CC for compiling with threads" >&6 fi LIBS="$LIBS -lc" SHLIB_CFLAGS="" SHLIB_SUFFIX=".so" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadDl.o" LD_LIBRARY_PATH_VAR="LIBPATH" # AIX v<=4.1 has some different flags than 4.2+ if test "$system" = "AIX-4.1" -o "`uname -v`" -lt "4" ; then #LIBOBJS="$LIBOBJS tclLoadAix.o" case $LIBOBJS in "tclLoadAix.$ac_objext" | \ *" tclLoadAix.$ac_objext" | \ "tclLoadAix.$ac_objext "* | \ *" tclLoadAix.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS tclLoadAix.$ac_objext" ;; esac DL_LIBS="-lld" fi # Check to enable 64-bit flags for compiler/linker on AIX 4+ if test "$do64bit" = "yes" -a "`uname -v`" -gt "3" ; then if test "$GCC" = "yes" ; then { echo "$as_me:$LINENO: WARNING: \"64bit mode not supported with GCC on $system\"" >&5 echo "$as_me: WARNING: \"64bit mode not supported with GCC on $system\"" >&2;} else do64bit_ok=yes CFLAGS="$CFLAGS -q64" LDFLAGS="$LDFLAGS -q64" RANLIB="${RANLIB} -X64" AR="${AR} -X64" SHLIB_LD_FLAGS="-b64" fi fi if test "`uname -m`" = "ia64" ; then # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC SHLIB_LD="/usr/ccs/bin/ld -G -z text" # AIX-5 has dl* in libc.so DL_LIBS="" if test "$GCC" = "yes" ; then LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' else LD_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}' fi else if test "$GCC" = "yes" ; then SHLIB_LD="$CXX -shared" else SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry" fi SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}" DL_LIBS="-ldl" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' TCL_NEEDS_EXP_FILE=1 TCL_EXPORT_FILE_SUFFIX='${PACKAGE_VERSION}.exp' fi # On AIX <=v4 systems, libbsd.a has to be linked in to support # non-blocking file IO. This library has to be linked in after # the MATH_LIBS or it breaks the pow() function. The way to # insure proper sequencing, is to add it to the tail of MATH_LIBS. # This library also supplies gettimeofday. # # AIX does not have a timezone field in struct tm. When the AIX # bsd library is used, the timezone global and the gettimeofday # methods are to be avoided for timezone deduction instead, we # deduce the timezone by comparing the localtime result on a # known GMT value. echo "$as_me:$LINENO: checking for gettimeofday in -lbsd" >&5 echo $ECHO_N "checking for gettimeofday in -lbsd... $ECHO_C" >&6 if test "${ac_cv_lib_bsd_gettimeofday+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbsd $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gettimeofday (); int main () { gettimeofday (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_bsd_gettimeofday=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_bsd_gettimeofday=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_gettimeofday" >&5 echo "${ECHO_T}$ac_cv_lib_bsd_gettimeofday" >&6 if test $ac_cv_lib_bsd_gettimeofday = yes; then libbsd=yes else libbsd=no fi if test $libbsd = yes; then MATH_LIBS="$MATH_LIBS -lbsd" cat >>confdefs.h <<\_ACEOF #define USE_DELTA_FOR_TZ 1 _ACEOF fi ;; BeOS*) SHLIB_CFLAGS="-fPIC" SHLIB_LD="${CXX} -nostart" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" ;; BSD/OS-2.1*|BSD/OS-3*) SHLIB_CFLAGS="" SHLIB_LD="shlicc -r" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS="" ;; BSD/OS-4.*) SHLIB_CFLAGS="-export-dynamic -fPIC" SHLIB_LD="$CXX -shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -export-dynamic" LD_SEARCH_FLAGS="" ;; dgux*) SHLIB_CFLAGS="-K PIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS="" ;; HP-UX-*.11.*) # Use updated header definitions where possible cat >>confdefs.h <<\_ACEOF #define _XOPEN_SOURCE_EXTENDED 1 _ACEOF SHLIB_SUFFIX=".sl" echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 if test "${ac_cv_lib_dld_shl_load+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char shl_load (); int main () { shl_load (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dld_shl_load=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_shl_load=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 if test $ac_cv_lib_dld_shl_load = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = yes; then SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadShl.o" DL_LIBS="-ldld" LDFLAGS="$LDFLAGS -Wl,-E" LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.' LD_LIBRARY_PATH_VAR="SHLIB_PATH" fi if test "$GCC" = "yes" ; then SHLIB_LD="$CXX -shared -fPIC" SHLIB_LD_LIBS='${LIBS}' LD_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.' fi # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc #CFLAGS="$CFLAGS +DAportable" # Check to enable 64-bit flags for compiler/linker if test "$do64bit" = "yes" ; then if test "$GCC" = "yes" ; then hpux_arch=`${CC} -dumpmachine` case $hpux_arch in hppa64*) # 64-bit gcc in use. Fix flags for GNU ld. do64bit_ok=yes SHLIB_LD="${CXX} -shared -fPIC" SHLIB_LD_LIBS='${LIBS}' ;; *) { echo "$as_me:$LINENO: WARNING: \"64bit mode not supported with GCC on $system\"" >&5 echo "$as_me: WARNING: \"64bit mode not supported with GCC on $system\"" >&2;} ;; esac else do64bit_ok=yes CFLAGS="$CFLAGS +DD64" LDFLAGS="$LDFLAGS +DD64" fi fi ;; HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*) SHLIB_SUFFIX=".sl" echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 if test "${ac_cv_lib_dld_shl_load+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char shl_load (); int main () { shl_load (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dld_shl_load=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_shl_load=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 if test $ac_cv_lib_dld_shl_load = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = yes; then SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" SHLIB_LD_LIBS="" DL_OBJS="tclLoadShl.o" DL_LIBS="-ldld" LDFLAGS="$LDFLAGS -Wl,-E" LD_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.' fi LD_LIBRARY_PATH_VAR="SHLIB_PATH" ;; IRIX-4.*) SHLIB_CFLAGS="-G 0" SHLIB_SUFFIX=".a" SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadAout.o" DL_LIBS="" LDFLAGS="$LDFLAGS -Wl,-D,08000000" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' SHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a' ;; IRIX-5.*) SHLIB_CFLAGS="" SHLIB_LD="ld -shared -rdata_shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' ;; IRIX-6.*|IRIX64-6.5*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' if test "$GCC" = "yes" ; then CFLAGS="$CFLAGS -mabi=n32" LDFLAGS="$LDFLAGS -mabi=n32" else case $system in IRIX-6.3) # Use to build 6.2 compatible binaries on 6.3. CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS" ;; *) CFLAGS="$CFLAGS -n32" ;; esac LDFLAGS="$LDFLAGS -n32" fi ;; IRIX64-6.*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' # Check to enable 64-bit flags for compiler/linker if test "$do64bit" = "yes" ; then if test "$GCC" = "yes" ; then { echo "$as_me:$LINENO: WARNING: 64bit mode not supported by gcc" >&5 echo "$as_me: WARNING: 64bit mode not supported by gcc" >&2;} else do64bit_ok=yes SHLIB_LD="ld -64 -shared -rdata_shared" CFLAGS="$CFLAGS -64" LDFLAGS="$LDFLAGS -64" fi fi ;; Linux*) SHLIB_CFLAGS="-fPIC" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" CFLAGS_OPTIMIZE="-O2" # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings # when you inline the string and math operations. Turn this off to # get rid of the warnings. #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES" if test "$have_dl" = yes; then SHLIB_LD="${CXX} -shared" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,--export-dynamic" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' else if test "${ac_cv_header_dld_h+set}" = set; then echo "$as_me:$LINENO: checking for dld.h" >&5 echo $ECHO_N "checking for dld.h... $ECHO_C" >&6 if test "${ac_cv_header_dld_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_dld_h" >&5 echo "${ECHO_T}$ac_cv_header_dld_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking dld.h usability" >&5 echo $ECHO_N "checking dld.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking dld.h presence" >&5 echo $ECHO_N "checking dld.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: dld.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: dld.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: dld.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: dld.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: dld.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: dld.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: dld.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: dld.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: dld.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: dld.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------- ## ## Report this to the astrotcl lists. ## ## ----------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for dld.h" >&5 echo $ECHO_N "checking for dld.h... $ECHO_C" >&6 if test "${ac_cv_header_dld_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_dld_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_dld_h" >&5 echo "${ECHO_T}$ac_cv_header_dld_h" >&6 fi if test $ac_cv_header_dld_h = yes; then SHLIB_LD="ld -shared" DL_OBJS="tclLoadDld.o" DL_LIBS="-ldld" LD_SEARCH_FLAGS="" fi fi if test "`uname -m`" = "alpha" ; then CFLAGS="$CFLAGS -mieee" fi # The combo of gcc + glibc has a bug related # to inlining of functions like strtod(). The # -fno-builtin flag should address this problem # but it does not work. The -fno-inline flag # is kind of overkill but it works. # Disable inlining only when one of the # files in compat/*.c is being linked in. if test x"${USE_COMPAT}" != x ; then CFLAGS="$CFLAGS -fno-inline" fi ;; GNU*) SHLIB_CFLAGS="-fPIC" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" if test "$have_dl" = yes; then SHLIB_LD="${CXX} -shared" DL_OBJS="" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,--export-dynamic" LD_SEARCH_FLAGS="" else if test "${ac_cv_header_dld_h+set}" = set; then echo "$as_me:$LINENO: checking for dld.h" >&5 echo $ECHO_N "checking for dld.h... $ECHO_C" >&6 if test "${ac_cv_header_dld_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_dld_h" >&5 echo "${ECHO_T}$ac_cv_header_dld_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking dld.h usability" >&5 echo $ECHO_N "checking dld.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking dld.h presence" >&5 echo $ECHO_N "checking dld.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: dld.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: dld.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: dld.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: dld.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: dld.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: dld.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: dld.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: dld.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: dld.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: dld.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------- ## ## Report this to the astrotcl lists. ## ## ----------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for dld.h" >&5 echo $ECHO_N "checking for dld.h... $ECHO_C" >&6 if test "${ac_cv_header_dld_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_dld_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_dld_h" >&5 echo "${ECHO_T}$ac_cv_header_dld_h" >&6 fi if test $ac_cv_header_dld_h = yes; then SHLIB_LD="ld -shared" DL_OBJS="" DL_LIBS="-ldld" LD_SEARCH_FLAGS="" fi fi if test "`uname -m`" = "alpha" ; then CFLAGS="$CFLAGS -mieee" fi ;; MP-RAS-02*) SHLIB_CFLAGS="-K PIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS="" ;; MP-RAS-*) SHLIB_CFLAGS="-K PIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,-Bexport" LD_SEARCH_FLAGS="" ;; NetBSD-*|FreeBSD-[1-2].*) # Not available on all versions: check for include file. if test "${ac_cv_header_dlfcn_h+set}" = set; then echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking dlfcn.h usability" >&5 echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking dlfcn.h presence" >&5 echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: dlfcn.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ----------------------------------- ## ## Report this to the astrotcl lists. ## ## ----------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_dlfcn_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 fi if test $ac_cv_header_dlfcn_h = yes; then # NetBSD/SPARC needs -fPIC, -fpic will not do. SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' echo "$as_me:$LINENO: checking for ELF" >&5 echo $ECHO_N "checking for ELF... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __ELF__ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so' else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' fi rm -f conftest* else SHLIB_CFLAGS="" SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".a" DL_OBJS="tclLoadAout.o" DL_LIBS="" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' fi # FreeBSD doesn't handle version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; OpenBSD-*) SHLIB_LD="${CXX} -shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS="" echo "$as_me:$LINENO: checking for ELF" >&5 echo $ECHO_N "checking for ELF... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __ELF__ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' fi rm -f conftest* # OpenBSD doesn't do version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; FreeBSD-*) # FreeBSD 3.* and greater have ELF. SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LDFLAGS="$LDFLAGS -export-dynamic" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' if test "${TCL_THREADS}" = "1" ; then # The -pthread needs to go in the CFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` CFLAGS="$CFLAGS -pthread" LDFLAGS="$LDFLAGS -pthread" fi case $system in FreeBSD-3.*) # FreeBSD-3 doesn't handle version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so' TCL_LIB_VERSIONS_OK=nodots ;; esac ;; Darwin-*) CFLAGS_OPTIMIZE="-Os" SHLIB_CFLAGS="-fno-common" if test $do64bit = yes; then do64bit_ok=yes CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" fi SHLIB_LD='${CXX} -dynamiclib ${CFLAGS} ${LDFLAGS}' echo "$as_me:$LINENO: checking if ld accepts -single_module flag" >&5 echo $ECHO_N "checking if ld accepts -single_module flag... $ECHO_C" >&6 if test "${tcl_cv_ld_single_module+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { int i; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_ld_single_module=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_ld_single_module=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$hold_ldflags fi echo "$as_me:$LINENO: result: $tcl_cv_ld_single_module" >&5 echo "${ECHO_T}$tcl_cv_ld_single_module" >&6 if test $tcl_cv_ld_single_module = yes; then SHLIB_LD="${SHLIB_LD} -Wl,-single_module" fi SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".dylib" DL_OBJS="tclLoadDyld.o" DL_LIBS="" # Don't use -prebind when building for Mac OS X 10.4 or later only: test -z "${MACOSX_DEPLOYMENT_TARGET}" || \ test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F. '{print $2}'`" -lt 4 && \ LDFLAGS="$LDFLAGS -prebind" LDFLAGS="$LDFLAGS -headerpad_max_install_names" echo "$as_me:$LINENO: checking if ld accepts -search_paths_first flag" >&5 echo $ECHO_N "checking if ld accepts -search_paths_first flag... $ECHO_C" >&6 if test "${tcl_cv_ld_search_paths_first+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-search_paths_first" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { int i; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_ld_search_paths_first=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_ld_search_paths_first=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$hold_ldflags fi echo "$as_me:$LINENO: result: $tcl_cv_ld_search_paths_first" >&5 echo "${ECHO_T}$tcl_cv_ld_search_paths_first" >&6 if test $tcl_cv_ld_search_paths_first = yes; then LDFLAGS="$LDFLAGS -Wl,-search_paths_first" fi LD_SEARCH_FLAGS="" LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH" ;; NEXTSTEP-*) SHLIB_CFLAGS="" SHLIB_LD="$CXX -nostdlib -r" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadNext.o" DL_LIBS="" LD_SEARCH_FLAGS="" ;; OS/390-*) CFLAGS_OPTIMIZE="" # Optimizer is buggy cat >>confdefs.h <<\_ACEOF #define _OE_SOCKETS 1 _ACEOF ;; OSF1-1.0|OSF1-1.1|OSF1-1.2) # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1 SHLIB_CFLAGS="" # Hack: make package name same as library name SHLIB_LD='ld -R -export :' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadOSF.o" DL_LIBS="" LD_SEARCH_FLAGS="" ;; OSF1-1.*) # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2 SHLIB_CFLAGS="-fPIC" if test "$SHARED_BUILD" = "1" ; then SHLIB_LD="ld -shared" else SHLIB_LD="ld -non_shared" fi SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS="" ;; OSF1-V*) # Digital OSF/1 SHLIB_CFLAGS="" if test "$SHARED_BUILD" = "1" ; then SHLIB_LD='ld -shared -expect_unresolved "*"' else SHLIB_LD='ld -non_shared -expect_unresolved "*"' fi SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' if test "$GCC" = "yes" ; then CFLAGS="$CFLAGS -mieee" else CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee" fi # see pthread_intro(3) for pthread support on osf1, k.furukawa if test "${TCL_THREADS}" = "1" ; then CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE" CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64" LIBS=`echo $LIBS | sed s/-lpthreads//` if test "$GCC" = "yes" ; then LIBS="$LIBS -lpthread -lmach -lexc" else CFLAGS="$CFLAGS -pthread" # PWD: don't need this. #LDFLAGS="$LDFLAGS -pthread" fi fi ;; QNX-6*) # QNX RTP # This may work for all QNX, but it was only reported for v6. SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" # dlopen is in -lc on QNX DL_LIBS="" LD_SEARCH_FLAGS="" ;; RISCos-*) SHLIB_CFLAGS="-G 0" SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".a" DL_OBJS="tclLoadAout.o" DL_LIBS="" LDFLAGS="$LDFLAGS -Wl,-D,08000000" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' ;; SCO_SV-3.2*) # Note, dlopen is available only on SCO 3.2.5 and greater. However, # this test works, since "uname -s" was non-standard in 3.2.4 and # below. if test "$GCC" = "yes" ; then SHLIB_CFLAGS="-fPIC -melf" LDFLAGS="$LDFLAGS -melf -Wl,-Bexport" else SHLIB_CFLAGS="-Kpic -belf" LDFLAGS="$LDFLAGS -belf -Wl,-Bexport" fi SHLIB_LD="ld -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS="" ;; SINIX*5.4*) SHLIB_CFLAGS="-K PIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS="" ;; SunOS-4*) SHLIB_CFLAGS="-PIC" SHLIB_LD="ld" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' # SunOS can't handle version numbers with dots in them in library # specs, like -ltcl7.5, so use -ltcl75 instead. Also, it # requires an extra version number at the end of .so file names. # So, the library has to have a name like libtcl75.so.1.0 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; SunOS-5.[0-6]) # Careful to not let 5.10+ fall into this case # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. cat >>confdefs.h <<\_ACEOF #define _REENTRANT 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _POSIX_PTHREAD_SEMANTICS 1 _ACEOF # Note: need the LIBS below, otherwise Tk won't find Tcl's # symbols when dynamically loaded into tclsh. SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" if test "$GCC" = "yes" ; then SHLIB_CFLAGS="-fPIC" SHLIB_LD="$CXX -shared" LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' else SHLIB_LD="$CXX -G -z text" LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' SHLIB_CFLAGS="-KPIC" fi ;; SunOS-5*) # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. cat >>confdefs.h <<\_ACEOF #define _REENTRANT 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _POSIX_PTHREAD_SEMANTICS 1 _ACEOF # Check to enable 64-bit flags for compiler/linker if test "$do64bit" = "yes" ; then arch=`isainfo` if test "$arch" = "sparcv9 sparc" ; then if test "$GCC" = "yes" ; then if test "`gcc -dumpversion` | awk -F. '{print }'" -lt "3" ; then { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5 echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;} else do64bit_ok=yes CFLAGS="$CFLAGS -m64 -mcpu=v9" LDFLAGS="$LDFLAGS -m64 -mcpu=v9" fi else do64bit_ok=yes if test "$do64bitVIS" = "yes" ; then CFLAGS="$CFLAGS -xarch=v9a" LDFLAGS="$LDFLAGS -xarch=v9a" else CFLAGS="$CFLAGS -xarch=v9" LDFLAGS="$LDFLAGS -xarch=v9" fi # Solaris 64 uses this as well #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64" fi elif test "$arch" = "amd64 i386" ; then if test "$GCC" = "yes" ; then { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5 echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;} else do64bit_ok=yes CFLAGS="$CFLAGS -xarch=amd64" LDFLAGS="$LDFLAGS -xarch=amd64" fi else { echo "$as_me:$LINENO: WARNING: 64bit mode not supported for $arch" >&5 echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;} fi fi # Note: need the LIBS below, otherwise Tk won't find Tcl's # symbols when dynamically loaded into tclsh. SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" if test "$GCC" = "yes" ; then SHLIB_CFLAGS="-fPIC" SHLIB_LD="$CXX -shared" LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' if test "$do64bit" = "yes" ; then # We need to specify -static-libgcc or we need to # add the path to the sparv9 libgcc. # JH: static-libgcc is necessary for core Tcl, but may # not be necessary for extensions. SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc" # for finding sparcv9 libgcc, get the regular libgcc # path, remove so name and append 'sparcv9' #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..." #LD_SEARCH_FLAGS="${LD_SEARCH_FLAGS},-R,$v9gcclibdir" fi else SHLIB_CFLAGS="-KPIC" SHLIB_LD="$CXX -G -z text" LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' fi ;; ULTRIX-4.*) SHLIB_CFLAGS="-G 0" SHLIB_SUFFIX=".a" SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadAout.o" DL_LIBS="" LDFLAGS="$LDFLAGS -Wl,-D,08000000" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' if test "$GCC" != "yes" ; then CFLAGS="$CFLAGS -DHAVE_TZSET -std1" fi ;; UNIX_SV* | UnixWare-5*) SHLIB_CFLAGS="-KPIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers # that don't grok the -Bexport option. Test that it does. hold_ldflags=$LDFLAGS echo "$as_me:$LINENO: checking for ld accepts -Bexport flag" >&5 echo $ECHO_N "checking for ld accepts -Bexport flag... $ECHO_C" >&6 LDFLAGS="$LDFLAGS -Wl,-Bexport" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { int i; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then found=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 LDFLAGS=$hold_ldflags found=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext echo "$as_me:$LINENO: result: $found" >&5 echo "${ECHO_T}$found" >&6 LD_SEARCH_FLAGS="" ;; esac if test "$do64bit" != "no" -a "$do64bit_ok" = "no" ; then { echo "$as_me:$LINENO: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5 echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;} fi # Step 4: If pseudo-static linking is in use (see K. B. Kenny, "Dynamic # Loading for Tcl -- What Became of It?". Proc. 2nd Tcl/Tk Workshop, # New Orleans, LA, Computerized Processes Unlimited, 1994), then we need # to determine which of several header files defines the a.out file # format (a.out.h, sys/exec.h, or sys/exec_aout.h). At present, we # support only a file format that is more or less version-7-compatible. # In particular, # - a.out files must begin with `struct exec'. # - the N_TXTOFF on the `struct exec' must compute the seek address # of the text segment # - The `struct exec' must contain a_magic, a_text, a_data, a_bss # and a_entry fields. # The following compilation should succeed if and only if either sys/exec.h # or a.out.h is usable for the purpose. # # Note that the modified COFF format used on MIPS Ultrix 4.x is usable; the # `struct exec' includes a second header that contains information that # duplicates the v7 fields that are needed. if test "x$DL_OBJS" = "xtclLoadAout.o" ; then echo "$as_me:$LINENO: checking sys/exec.h" >&5 echo $ECHO_N "checking sys/exec.h... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct exec foo; unsigned long seek; int flag; #if defined(__mips) || defined(mips) seek = N_TXTOFF (foo.ex_f, foo.ex_o); #else seek = N_TXTOFF (foo); #endif flag = (foo.a_magic == OMAGIC); return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_ok=usable else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_ok=unusable fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $tcl_ok" >&5 echo "${ECHO_T}$tcl_ok" >&6 if test $tcl_ok = usable; then cat >>confdefs.h <<\_ACEOF #define USE_SYS_EXEC_H 1 _ACEOF else echo "$as_me:$LINENO: checking a.out.h" >&5 echo $ECHO_N "checking a.out.h... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct exec foo; unsigned long seek; int flag; #if defined(__mips) || defined(mips) seek = N_TXTOFF (foo.ex_f, foo.ex_o); #else seek = N_TXTOFF (foo); #endif flag = (foo.a_magic == OMAGIC); return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_ok=usable else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_ok=unusable fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $tcl_ok" >&5 echo "${ECHO_T}$tcl_ok" >&6 if test $tcl_ok = usable; then cat >>confdefs.h <<\_ACEOF #define USE_A_OUT_H 1 _ACEOF else echo "$as_me:$LINENO: checking sys/exec_aout.h" >&5 echo $ECHO_N "checking sys/exec_aout.h... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct exec foo; unsigned long seek; int flag; #if defined(__mips) || defined(mips) seek = N_TXTOFF (foo.ex_f, foo.ex_o); #else seek = N_TXTOFF (foo); #endif flag = (foo.a_midmag == OMAGIC); return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_ok=usable else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_ok=unusable fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $tcl_ok" >&5 echo "${ECHO_T}$tcl_ok" >&6 if test $tcl_ok = usable; then cat >>confdefs.h <<\_ACEOF #define USE_SYS_EXEC_AOUT_H 1 _ACEOF else DL_OBJS="" fi fi fi fi # Step 5: disable dynamic loading if requested via a command-line switch. # Check whether --enable-load or --disable-load was given. if test "${enable_load+set}" = set; then enableval="$enable_load" tcl_ok=$enableval else tcl_ok=yes fi; if test "$tcl_ok" = "no"; then DL_OBJS="" fi if test "x$DL_OBJS" != "x" ; then BUILD_DLTEST="\$(DLTEST_TARGETS)" else echo "Can't figure out how to do dynamic loading or shared libraries" echo "on this system." SHLIB_CFLAGS="" SHLIB_LD="" SHLIB_SUFFIX="" DL_OBJS="tclLoadNone.o" DL_LIBS="" LDFLAGS="$LDFLAGS_ORIG" LD_SEARCH_FLAGS="" BUILD_DLTEST="" fi # If we're running gcc, then change the C flags for compiling shared # libraries to the right flags for gcc, instead of those for the # standard manufacturer compiler. if test "$DL_OBJS" != "tclLoadNone.o" ; then if test "$GCC" = "yes" ; then case $system in AIX-*) ;; BSD/OS*) ;; IRIX*) ;; NetBSD-*|FreeBSD-*) ;; Darwin-*) ;; RISCos-*) ;; SCO_SV-3.2*) ;; ULTRIX-4.*) ;; windows) ;; *) SHLIB_CFLAGS="-fPIC" ;; esac fi fi if test "$SHARED_LIB_SUFFIX" = "" ; then SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}' fi if test "$UNSHARED_LIB_SUFFIX" = "" ; then UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a' fi # These must be called after we do the basic CFLAGS checks and # verify any possible 64-bit or similar switches are necessary echo "$as_me:$LINENO: checking for required early compiler flags" >&5 echo $ECHO_N "checking for required early compiler flags... $ECHO_C" >&6 tcl_flags="" if test "${tcl_cv_flag__isoc99_source+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char *p = (char *)strtoll; char *q = (char *)strtoull; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_flag__isoc99_source=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _ISOC99_SOURCE 1 #include int main () { char *p = (char *)strtoll; char *q = (char *)strtoull; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_flag__isoc99_source=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_flag__isoc99_source=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_flag__isoc99_source}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define _ISOC99_SOURCE 1 _ACEOF tcl_flags="$tcl_flags _ISOC99_SOURCE" fi if test "${tcl_cv_flag__largefile64_source+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct stat64 buf; int i = stat64("/", &buf); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_flag__largefile64_source=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _LARGEFILE64_SOURCE 1 #include int main () { struct stat64 buf; int i = stat64("/", &buf); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_flag__largefile64_source=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_flag__largefile64_source=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_flag__largefile64_source}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define _LARGEFILE64_SOURCE 1 _ACEOF tcl_flags="$tcl_flags _LARGEFILE64_SOURCE" fi if test "x${tcl_flags}" = "x" ; then echo "$as_me:$LINENO: result: none" >&5 echo "${ECHO_T}none" >&6 else echo "$as_me:$LINENO: result: ${tcl_flags}" >&5 echo "${ECHO_T}${tcl_flags}" >&6 fi echo "$as_me:$LINENO: checking for 64-bit integer type" >&5 echo $ECHO_N "checking for 64-bit integer type... $ECHO_C" >&6 if test "${tcl_cv_type_64bit+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else tcl_cv_type_64bit=none # See if the compiler knows natively about __int64 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { __int64 value = (__int64) 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_type_64bit=__int64 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_type_64bit="long long" fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext # See if we should use long anyway Note that we substitute in the # type that is our current guess for a 64-bit type inside this check # program, so it should be modified only carefully... cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { switch (0) { case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ; } ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_type_64bit=${tcl_type_64bit} else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "${tcl_cv_type_64bit}" = none ; then cat >>confdefs.h <<\_ACEOF #define TCL_WIDE_INT_IS_LONG 1 _ACEOF echo "$as_me:$LINENO: result: using long" >&5 echo "${ECHO_T}using long" >&6 elif test "${tcl_cv_type_64bit}" = "__int64" \ -a "${TEA_PLATFORM}" = "windows" ; then # We actually want to use the default tcl.h checks in this # case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER* echo "$as_me:$LINENO: result: using Tcl header defaults" >&5 echo "${ECHO_T}using Tcl header defaults" >&6 else cat >>confdefs.h <<_ACEOF #define TCL_WIDE_INT_TYPE ${tcl_cv_type_64bit} _ACEOF echo "$as_me:$LINENO: result: ${tcl_cv_type_64bit}" >&5 echo "${ECHO_T}${tcl_cv_type_64bit}" >&6 # Now check for auxiliary declarations echo "$as_me:$LINENO: checking for struct dirent64" >&5 echo $ECHO_N "checking for struct dirent64... $ECHO_C" >&6 if test "${tcl_cv_struct_dirent64+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { struct dirent64 p; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_struct_dirent64=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_struct_dirent64=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRUCT_DIRENT64 1 _ACEOF fi echo "$as_me:$LINENO: result: ${tcl_cv_struct_dirent64}" >&5 echo "${ECHO_T}${tcl_cv_struct_dirent64}" >&6 echo "$as_me:$LINENO: checking for struct stat64" >&5 echo $ECHO_N "checking for struct stat64... $ECHO_C" >&6 if test "${tcl_cv_struct_stat64+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct stat64 p; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_struct_stat64=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_struct_stat64=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_struct_stat64}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRUCT_STAT64 1 _ACEOF fi echo "$as_me:$LINENO: result: ${tcl_cv_struct_stat64}" >&5 echo "${ECHO_T}${tcl_cv_struct_stat64}" >&6 echo "$as_me:$LINENO: checking for off64_t" >&5 echo $ECHO_N "checking for off64_t... $ECHO_C" >&6 if test "${tcl_cv_type_off64_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { off64_t offset; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_type_off64_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_type_off64_t=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_type_off64_t}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_TYPE_OFF64_T 1 _ACEOF fi echo "$as_me:$LINENO: result: ${tcl_cv_type_off64_t}" >&5 echo "${ECHO_T}${tcl_cv_type_off64_t}" >&6 fi #-------------------------------------------------------------------- # Find the CFITSIO library. #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking for CFITSIO library" >&5 echo $ECHO_N "checking for CFITSIO library... $ECHO_C" >&6 # Check whether --with-cfitsio or --without-cfitsio was given. if test "${with_cfitsio+set}" = set; then withval="$with_cfitsio" CFITSIO_LIB_DIR=$withval fi; CFITSIO_LIBNAME=libcfitsio${SHLIB_SUFFIX} CFITSIO_LIBFLAG=-lcfitsio if test -z "$CFITSIO_LIB_DIR" ; then # If --with-cfitsio=dir was not specified, try the exec-prefix/lib dir places="\ $exec_prefix/lib \ $prefix/lib \ " for i in $places ; do if test -f $i/$CFITSIO_LIBNAME then CFITSIO_LIB_DIR=$i break fi done if test -z "$CFITSIO_LIB_DIR" ; then echo { { echo "$as_me:$LINENO: error: could not find $CFITSIO_LIBNAME: Please use the --with-cfitsio=DIR option." >&5 echo "$as_me: error: could not find $CFITSIO_LIBNAME: Please use the --with-cfitsio=DIR option." >&2;} { (exit 1); exit 1; }; } fi else # Just assume the given value will work. This may not be true if # CFITSIO itself isn't built yet, so allow the flexibility. CFITSIO_LIB_DIR=$CFITSIO_LIB_DIR/lib fi CFITSIO_LIB_SPEC="-L$CFITSIO_LIB_DIR $CFITSIO_LIBFLAG" echo "$as_me:$LINENO: result: $CFITSIO_LIB_DIR" >&5 echo "${ECHO_T}$CFITSIO_LIB_DIR" >&6 vars="${CFITSIO_LIB_SPEC}" for i in $vars; do if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then # Convert foo.lib to -lfoo for GCC. No-op if not *.lib i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'` fi PKG_LIBS="$PKG_LIBS $i" done #-------------------------------------------------------------------- # Set the default compiler switches based on the --enable-symbols option. #-------------------------------------------------------------------- DBGX="" echo "$as_me:$LINENO: checking for build with symbols" >&5 echo $ECHO_N "checking for build with symbols... $ECHO_C" >&6 # Check whether --enable-symbols or --disable-symbols was given. if test "${enable_symbols+set}" = set; then enableval="$enable_symbols" tcl_ok=$enableval else tcl_ok=no fi; if test "$tcl_ok" = "no"; then CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}" LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}" echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 else CFLAGS_DEFAULT="${CFLAGS_DEBUG}" LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}" if test "$tcl_ok" = "yes"; then echo "$as_me:$LINENO: result: yes (standard debugging)" >&5 echo "${ECHO_T}yes (standard debugging)" >&6 fi fi if test "${TEA_PLATFORM}" != "windows" ; then LDFLAGS_DEFAULT="${LDFLAGS}" fi if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then cat >>confdefs.h <<\_ACEOF #define TCL_MEM_DEBUG 1 _ACEOF fi if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then if test "$tcl_ok" = "all"; then echo "$as_me:$LINENO: result: enabled symbols mem debugging" >&5 echo "${ECHO_T}enabled symbols mem debugging" >&6 else echo "$as_me:$LINENO: result: enabled $tcl_ok debugging" >&5 echo "${ECHO_T}enabled $tcl_ok debugging" >&6 fi fi #-------------------------------------------------------------------- # Everyone should be linking against the Tcl stub library. If you # can't for some reason, remove this definition. If you aren't using # stubs, you also need to modify the SHLIB_LD_LIBS setting below to # link against the non-stubbed Tcl library. Add Tk too if necessary. #-------------------------------------------------------------------- # allan: can't use stubs, due to BLT dependency #AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs]) #AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs]) #-------------------------------------------------------------------- # This macro generates a line to use when building a library. It # depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS, # and TEA_LOAD_TCLCONFIG macros above. #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then MAKE_STATIC_LIB="\${STLIB_LD} -out:\$@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\$@ \$(PKG_OBJECTS)" MAKE_STUB_LIB="\${STLIB_LD} -out:\$@ \$(PKG_STUB_OBJECTS)" else MAKE_STATIC_LIB="\${STLIB_LD} \$@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} -o \$@ \$(PKG_OBJECTS) \${LDFLAGS_DEFAULT} \${SHLIB_LD_LIBS}" MAKE_STUB_LIB="\${STLIB_LD} \$@ \$(PKG_STUB_OBJECTS)" fi if test "${SHARED_BUILD}" = "1" ; then MAKE_LIB="${MAKE_SHARED_LIB} " else MAKE_LIB="${MAKE_STATIC_LIB} " fi #-------------------------------------------------------------------- # Shared libraries and static libraries have different names. # Use the double eval to make sure any variables in the suffix is # substituted. (@@@ Might not be necessary anymore) #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" ; then if test "${SHARED_BUILD}" = "1" ; then # We force the unresolved linking of symbols that are really in # the private libraries of Tcl and Tk. SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_LIB_FILE}`\"" if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_LIB_FILE}`\"" fi eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" else eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" fi # Some packages build there own stubs libraries eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" # These aren't needed on Windows (either MSVC or gcc) RANLIB=: RANLIB_STUB=: else RANLIB_STUB="${RANLIB}" if test "${SHARED_BUILD}" = "1" ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_LIB_SPEC}" if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_LIB_SPEC}" fi eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" RANLIB=: else eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" fi # Some packages build there own stubs libraries eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" fi # These are escaped so that only CFLAGS is picked up at configure time. # The other values will be substituted at make time. CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}" if test "${SHARED_BUILD}" = "1" ; then CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}" fi #-------------------------------------------------------------------- # Determine the name of the tclsh and/or wish executables in the # Tcl and Tk build directories or the location they were installed # into. These paths are used to support running test cases only, # the Makefile should not be making use of these paths to generate # a pkgIndex.tcl file or anything else at extension build time. #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking for tclsh" >&5 echo $ECHO_N "checking for tclsh... $ECHO_C" >&6 if test -f "${TCL_BIN_DIR}/Makefile" ; then # tclConfig.sh is in Tcl build directory if test "${TEA_PLATFORM}" = "windows"; then TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" else TCLSH_PROG="${TCL_BIN_DIR}/tclsh" fi else # tclConfig.sh is in install location if test "${TEA_PLATFORM}" = "windows"; then TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" else TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}" fi list="`ls -d ${TCL_PREFIX}/bin 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null`" for i in $list ; do if test -f "$i/${TCLSH_PROG}" ; then REAL_TCL_BIN_DIR="`cd "$i"; pwd`" break fi done TCLSH_PROG="${REAL_TCL_BIN_DIR}/${TCLSH_PROG}" fi echo "$as_me:$LINENO: result: ${TCLSH_PROG}" >&5 echo "${ECHO_T}${TCLSH_PROG}" >&6 echo "$as_me:$LINENO: checking for wish" >&5 echo $ECHO_N "checking for wish... $ECHO_C" >&6 if test -f "${TK_BIN_DIR}/Makefile" ; then # tkConfig.sh is in Tk build directory if test "${TEA_PLATFORM}" = "windows"; then WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" else WISH_PROG="${TK_BIN_DIR}/wish" fi else # tkConfig.sh is in install location if test "${TEA_PLATFORM}" = "windows"; then WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" else WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}" fi list="`ls -d ${TK_PREFIX}/bin 2>/dev/null` \ `ls -d ${TK_BIN_DIR}/../bin 2>/dev/null`" for i in $list ; do if test -f "$i/${WISH_PROG}" ; then REAL_TK_BIN_DIR="`cd "$i"; pwd`" break fi done WISH_PROG="${REAL_TK_BIN_DIR}/${WISH_PROG}" fi echo "$as_me:$LINENO: result: ${WISH_PROG}" >&5 echo "${ECHO_T}${WISH_PROG}" >&6 #-------------------------------------------------------------------- # These are for astrotclConfig.sh #-------------------------------------------------------------------- astrotcl_LIB_FILE=${PKG_LIB_FILE} eval pkglibdir="${libdir}" if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then eval astrotcl_LIB_FLAG="-lastrotcl${PACKAGE_VERSION}" else eval astrotcl_LIB_FLAG="-lastrotcl`echo ${PACKAGE_VERSION} | tr -d .`" fi astrotcl_BUILD_DIR="`pwd`" astrotcl_BUILD_LIB_SPEC="-L`pwd` ${astrotcl_LIB_FLAG}" astrotcl_LIB_SPEC="-L${pkglibdir} ${astrotcl_LIB_FLAG}" for i in ${PKG_OBJECTS} ; do astrotcl_PKG_OBJECTS="$astrotcl_PKG_OBJECTS ../astrotcl/$i" done # astrotcl_SRC_DIR must be a fully qualified path eval astrotcl_SRC_DIR="$srcdir" astrotcl_SRC_DIR=`cd "${astrotcl_SRC_DIR}"; pwd` #-------------------------------------------------------------------- # Finally, substitute all of the various values into the Makefile. # You may alternatively have a special pkgIndex.tcl.in or other files # which require substituting th AC variables in. Include these here. #-------------------------------------------------------------------- ac_config_files="$ac_config_files Makefile pkgIndex.tcl astrotclConfig.sh" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. { (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } | sed ' t clear : clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ : end' >>confcache if diff $cache_file confcache >/dev/null 2>&1; then :; else if test -w $cache_file; then test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" cat confcache >$cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/; s/:*\${srcdir}:*/:/; s/:*@srcdir@:*/:/; s/^\([^=]*=[ ]*\):*/\1/; s/:*$//; s/^[^=]*=[ ]*$//; }' fi # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then we branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. cat >confdef2opt.sed <<\_ACEOF t clear : clear s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g t quote s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g t quote d : quote s,[ `~#$^&*(){}\\|;'"<>?],\\&,g s,\[,\\&,g s,\],\\&,g s,\$,$$,g p _ACEOF # We use echo to avoid assuming a particular line-breaking character. # The extra dot is to prevent the shell from consuming trailing # line-breaks from the sub-command output. A line-break within # single-quotes doesn't work because, if this script is created in a # platform that uses two characters for line-breaks (e.g., DOS), tr # would break. ac_LF_and_DOT=`echo; echo .` DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` rm -f confdef2opt.sed ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_i=`echo "$ac_i" | sed 's/\$U\././;s/\.o$//;s/\.obj$//'` # 2. Add them. ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH exec 6>&1 # Open the log real soon, to keep \$[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. Logging --version etc. is OK. exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX } >&5 cat >&5 <<_CSEOF This file was extended by astrotcl $as_me 2.1.0, which was generated by Starlink Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ _CSEOF echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 echo >&5 _ACEOF # Files that config.status was made for. if test -n "$ac_config_files"; then echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS fi if test -n "$ac_config_headers"; then echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS fi if test -n "$ac_config_links"; then echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS fi if test -n "$ac_config_commands"; then echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS fi cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ astrotcl config.status 2.1.0 configured by $0, generated by Starlink Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2003 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." srcdir=$srcdir INSTALL="$INSTALL" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "x$1" : 'x\([^=]*\)='` ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` ac_shift=: ;; -*) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; *) # This is not an option, so the user has probably given explicit # arguments. ac_option=$1 ac_need_defaults=false;; esac case $ac_option in # Handling of the options. _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --vers* | -V ) echo "$ac_cs_version"; exit 0 ;; --he | --h) # Conflict between --help and --header { { echo "$as_me:$LINENO: error: ambiguous option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_config_target in $ac_config_targets do case "$ac_config_target" in # Handling of arguments. "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; "pkgIndex.tcl" ) CONFIG_FILES="$CONFIG_FILES pkgIndex.tcl" ;; "astrotclConfig.sh" ) CONFIG_FILES="$CONFIG_FILES astrotclConfig.sh" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason to put it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Create a temporary directory, and hook for its removal unless debugging. $debug || { trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./confstat$$-$RANDOM (umask 077 && mkdir $tmp) } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "\$CONFIG_FILES"; then # Protect against being on the right side of a sed subst in config.status. sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF s,@SHELL@,$SHELL,;t t s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t s,@exec_prefix@,$exec_prefix,;t t s,@prefix@,$prefix,;t t s,@program_transform_name@,$program_transform_name,;t t s,@bindir@,$bindir,;t t s,@sbindir@,$sbindir,;t t s,@libexecdir@,$libexecdir,;t t s,@datadir@,$datadir,;t t s,@sysconfdir@,$sysconfdir,;t t s,@sharedstatedir@,$sharedstatedir,;t t s,@localstatedir@,$localstatedir,;t t s,@libdir@,$libdir,;t t s,@includedir@,$includedir,;t t s,@oldincludedir@,$oldincludedir,;t t s,@infodir@,$infodir,;t t s,@mandir@,$mandir,;t t s,@build_alias@,$build_alias,;t t s,@host_alias@,$host_alias,;t t s,@target_alias@,$target_alias,;t t s,@DEFS@,$DEFS,;t t s,@ECHO_C@,$ECHO_C,;t t s,@ECHO_N@,$ECHO_N,;t t s,@ECHO_T@,$ECHO_T,;t t s,@LIBS@,$LIBS,;t t s,@CYGPATH@,$CYGPATH,;t t s,@EXEEXT@,$EXEEXT,;t t s,@PKG_LIB_FILE@,$PKG_LIB_FILE,;t t s,@PKG_STUB_LIB_FILE@,$PKG_STUB_LIB_FILE,;t t s,@PKG_STUB_SOURCES@,$PKG_STUB_SOURCES,;t t s,@PKG_STUB_OBJECTS@,$PKG_STUB_OBJECTS,;t t s,@PKG_TCL_SOURCES@,$PKG_TCL_SOURCES,;t t s,@PKG_HEADERS@,$PKG_HEADERS,;t t s,@PKG_INCLUDES@,$PKG_INCLUDES,;t t s,@PKG_LIBS@,$PKG_LIBS,;t t s,@PKG_CFLAGS@,$PKG_CFLAGS,;t t s,@TCL_VERSION@,$TCL_VERSION,;t t s,@TCL_BIN_DIR@,$TCL_BIN_DIR,;t t s,@TCL_SRC_DIR@,$TCL_SRC_DIR,;t t s,@TCL_LIB_FILE@,$TCL_LIB_FILE,;t t s,@TCL_LIB_FLAG@,$TCL_LIB_FLAG,;t t s,@TCL_LIB_SPEC@,$TCL_LIB_SPEC,;t t s,@TCL_STUB_LIB_FILE@,$TCL_STUB_LIB_FILE,;t t s,@TCL_STUB_LIB_FLAG@,$TCL_STUB_LIB_FLAG,;t t s,@TCL_STUB_LIB_SPEC@,$TCL_STUB_LIB_SPEC,;t t s,@TCL_LIBS@,$TCL_LIBS,;t t s,@TCL_DEFS@,$TCL_DEFS,;t t s,@TCL_EXTRA_CFLAGS@,$TCL_EXTRA_CFLAGS,;t t s,@TCL_LD_FLAGS@,$TCL_LD_FLAGS,;t t s,@TCL_SHLIB_LD_LIBS@,$TCL_SHLIB_LD_LIBS,;t t s,@TK_VERSION@,$TK_VERSION,;t t s,@TK_BIN_DIR@,$TK_BIN_DIR,;t t s,@TK_SRC_DIR@,$TK_SRC_DIR,;t t s,@TK_LIB_FILE@,$TK_LIB_FILE,;t t s,@TK_LIB_FLAG@,$TK_LIB_FLAG,;t t s,@TK_LIB_SPEC@,$TK_LIB_SPEC,;t t s,@TK_STUB_LIB_FILE@,$TK_STUB_LIB_FILE,;t t s,@TK_STUB_LIB_FLAG@,$TK_STUB_LIB_FLAG,;t t s,@TK_STUB_LIB_SPEC@,$TK_STUB_LIB_SPEC,;t t s,@TK_LIBS@,$TK_LIBS,;t t s,@TK_XINCLUDES@,$TK_XINCLUDES,;t t s,@CC@,$CC,;t t s,@CFLAGS@,$CFLAGS,;t t s,@LDFLAGS@,$LDFLAGS,;t t s,@CPPFLAGS@,$CPPFLAGS,;t t s,@ac_ct_CC@,$ac_ct_CC,;t t s,@OBJEXT@,$OBJEXT,;t t s,@CPP@,$CPP,;t t s,@CXX@,$CXX,;t t s,@CXXFLAGS@,$CXXFLAGS,;t t s,@ac_ct_CXX@,$ac_ct_CXX,;t t s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t s,@INSTALL_DATA@,$INSTALL_DATA,;t t s,@SET_MAKE@,$SET_MAKE,;t t s,@RANLIB@,$RANLIB,;t t s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t s,@EGREP@,$EGREP,;t t s,@MATH_LIBS@,$MATH_LIBS,;t t s,@tclutil_VERSION@,$tclutil_VERSION,;t t s,@tclutil_LIB_FILE@,$tclutil_LIB_FILE,;t t s,@tclutil_BUILD_LIB_SPEC@,$tclutil_BUILD_LIB_SPEC,;t t s,@tclutil_LIB_SPEC@,$tclutil_LIB_SPEC,;t t s,@BLT_LIB_SPEC@,$BLT_LIB_SPEC,;t t s,@tclutil_SRC_DIR@,$tclutil_SRC_DIR,;t t s,@CFITSIO_LIB_SPEC@,$CFITSIO_LIB_SPEC,;t t s,@my_shmem@,$my_shmem,;t t s,@SHLIB_LD_CXX_LIBS@,$SHLIB_LD_CXX_LIBS,;t t s,@PKG_SOURCES@,$PKG_SOURCES,;t t s,@PKG_OBJECTS@,$PKG_OBJECTS,;t t s,@CLEANFILES@,$CLEANFILES,;t t s,@TCL_INCLUDES@,$TCL_INCLUDES,;t t s,@TK_INCLUDES@,$TK_INCLUDES,;t t s,@TCL_THREADS@,$TCL_THREADS,;t t s,@SHARED_BUILD@,$SHARED_BUILD,;t t s,@AR@,$AR,;t t s,@CELIB_DIR@,$CELIB_DIR,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@SHLIB_SUFFIX@,$SHLIB_SUFFIX,;t t s,@DL_LIBS@,$DL_LIBS,;t t s,@CFLAGS_DEBUG@,$CFLAGS_DEBUG,;t t s,@CFLAGS_OPTIMIZE@,$CFLAGS_OPTIMIZE,;t t s,@CFLAGS_WARNING@,$CFLAGS_WARNING,;t t s,@STLIB_LD@,$STLIB_LD,;t t s,@SHLIB_LD@,$SHLIB_LD,;t t s,@SHLIB_CFLAGS@,$SHLIB_CFLAGS,;t t s,@SHLIB_LD_LIBS@,$SHLIB_LD_LIBS,;t t s,@LDFLAGS_DEBUG@,$LDFLAGS_DEBUG,;t t s,@LDFLAGS_OPTIMIZE@,$LDFLAGS_OPTIMIZE,;t t s,@LD_LIBRARY_PATH_VAR@,$LD_LIBRARY_PATH_VAR,;t t s,@CFITSIO_LIB_DIR@,$CFITSIO_LIB_DIR,;t t s,@TCL_DBGX@,$TCL_DBGX,;t t s,@CFLAGS_DEFAULT@,$CFLAGS_DEFAULT,;t t s,@LDFLAGS_DEFAULT@,$LDFLAGS_DEFAULT,;t t s,@MAKE_LIB@,$MAKE_LIB,;t t s,@MAKE_SHARED_LIB@,$MAKE_SHARED_LIB,;t t s,@MAKE_STATIC_LIB@,$MAKE_STATIC_LIB,;t t s,@MAKE_STUB_LIB@,$MAKE_STUB_LIB,;t t s,@RANLIB_STUB@,$RANLIB_STUB,;t t s,@TCLSH_PROG@,$TCLSH_PROG,;t t s,@WISH_PROG@,$WISH_PROG,;t t s,@astrotcl_LIB_FILE@,$astrotcl_LIB_FILE,;t t s,@astrotcl_BUILD_DIR@,$astrotcl_BUILD_DIR,;t t s,@astrotcl_BUILD_LIB_SPEC@,$astrotcl_BUILD_LIB_SPEC,;t t s,@astrotcl_LIB_SPEC@,$astrotcl_LIB_SPEC,;t t s,@astrotcl_PKG_OBJECTS@,$astrotcl_PKG_OBJECTS,;t t s,@astrotcl_SRC_DIR@,$astrotcl_SRC_DIR,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_lines=48 ac_sed_frag=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_lines # Line after last line for current file. ac_more_lines=: ac_sed_cmds= while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag else sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag fi if test ! -s $tmp/subs.frag; then ac_more_lines=false else # The purpose of the label and of the branching condition is to # speed up the sed processing (if there are no `@' at all, there # is no need to browse any of the substitutions). # These are the two extra sed commands mentioned above. (echo ':t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" else ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" fi ac_sed_frag=`expr $ac_sed_frag + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_lines` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi fi # test -n "$CONFIG_FILES" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_builddir$INSTALL ;; esac if test x"$ac_file" != x-; then { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} rm -f "$ac_file" fi # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then configure_input= else configure_input="$ac_file. " fi configure_input=$configure_input"Generated from `echo $ac_file_in | sed 's,.*/,,'` by configure." # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo "$f";; *) # Relative if test -f "$f"; then # Build tree echo "$f" elif test -f "$srcdir/$f"; then # Source tree echo "$srcdir/$f" else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s,@configure_input@,$configure_input,;t t s,@srcdir@,$ac_srcdir,;t t s,@abs_srcdir@,$ac_abs_srcdir,;t t s,@top_srcdir@,$ac_top_srcdir,;t t s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t s,@builddir@,$ac_builddir,;t t s,@abs_builddir@,$ac_abs_builddir,;t t s,@top_builddir@,$ac_top_builddir,;t t s,@abs_top_builddir@,$ac_abs_top_builddir,;t t s,@INSTALL@,$ac_INSTALL,;t t " $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out rm -f $tmp/stdin if test x"$ac_file" != x-; then mv $tmp/out $ac_file else cat $tmp/out rm -f $tmp/out fi done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi skycat-3.1.2-starlink-1b/astrotcl/configure.in000066400000000000000000000225701215713201500213070ustar00rootroot00000000000000# E.S.O. - VLT project # $Id: configure.in,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is used with GNU autoconf to generate a configure script # # usage: % autoconf # only if configure.in changed # % configure # % make # % make install # # who when what # -------------- -------- --------------------------------------------- # Allan Brighton 15/12/05 Rewrote using TCL TEA standard # ----------------------------------------------------------------------- #----------------------------------------------------------------------- # Sample configure.in for Tcl Extensions. The only places you should # need to modify this file are marked by the string __CHANGE__ #----------------------------------------------------------------------- #----------------------------------------------------------------------- # __CHANGE__ # Set your package name and version numbers here. # # This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION # set as provided. These will also be added as -D defs in your Makefile # so you can encode the package version directly into the source files. #----------------------------------------------------------------------- AC_INIT([astrotcl], [2.1.0]) #-------------------------------------------------------------------- # Call TEA_INIT as the first TEA_ macro to set up initial vars. # This will define a ${TEA_PLATFORM} variable == "unix" or "windows" # as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE. #-------------------------------------------------------------------- TEA_INIT([3.4]) #-------------------------------------------------------------------- # Load the tclConfig.sh file #-------------------------------------------------------------------- TEA_PATH_TCLCONFIG TEA_LOAD_TCLCONFIG #-------------------------------------------------------------------- # Load the tkConfig.sh file if necessary (Tk extension) #-------------------------------------------------------------------- TEA_PATH_TKCONFIG TEA_LOAD_TKCONFIG #----------------------------------------------------------------------- # Handle the --prefix=... option by defaulting to what Tcl gave. # Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER. #----------------------------------------------------------------------- TEA_PREFIX #----------------------------------------------------------------------- # Standard compiler checks. # This sets up CC by using the CC env var, or looks for gcc otherwise. # This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create # the basic setup necessary to compile executables. #----------------------------------------------------------------------- TEA_SETUP_COMPILER #-------------------------------------------------------------------- # Do application specific checks (see aclocal.m4) #-------------------------------------------------------------------- ASTROTCL_CONFIG #----------------------------------------------------------------------- # __CHANGE__ # Specify the C source files to compile in TEA_ADD_SOURCES, # public headers that need to be installed in TEA_ADD_HEADERS, # stub library C source files to compile in TEA_ADD_STUB_SOURCES, # and runtime Tcl library files in TEA_ADD_TCL_SOURCES. # This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS # and PKG_TCL_SOURCES. #----------------------------------------------------------------------- changequote(<<, >>) csources=`cd $srcdir; echo generic/*.[Cc] press/*.[Cc] libwcs/*.[Cc]` changequote([, ]) cheaders=`cd $srcdir; echo generic/*.h press/*.h libwcs/*.h` cincludes="-I$srcdir/../tclutil/generic -I$srcdir/generic -I$srcdir/press -I$srcdir/libwcs" tclsources=`cd $srcdir; echo library/*.tcl` TEA_ADD_SOURCES([${csources}]) TEA_ADD_HEADERS([${cheaders}]) TEA_ADD_INCLUDES([$cincludes]) TEA_ADD_LIBS([$tclutil_BUILD_LIB_SPEC ${BLT_LIB_SPEC} ${CFITSIO_LIB_SPEC}]) TEA_ADD_CFLAGS([]) TEA_ADD_STUB_SOURCES([]) TEA_ADD_TCL_SOURCES([${tclsources}]) #-------------------------------------------------------------------- # __CHANGE__ # A few miscellaneous platform-specific items: # # Define a special symbol for Windows (BUILD_sample in this case) so # that we create the export library with the dll. # # Windows creates a few extra files that need to be cleaned up. # You can add more files to clean if your extension creates any extra # files. # # TEA_ADD_* any platform specific compiler/build info here. #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" ; then AC_DEFINE(BUILD_astrotcl, 1, [Build windows export dll]) CLEANFILES="*.lib *.dll *.exp *.ilk *.pdb vc*.pch" #TEA_ADD_SOURCES([win/winFile.c]) #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"]) else CLEANFILES="" #TEA_ADD_SOURCES([unix/unixFile.c]) #TEA_ADD_LIBS([-lsuperfly]) fi AC_SUBST(CLEANFILES) #-------------------------------------------------------------------- # __CHANGE__ # Choose which headers you need. Extension authors should try very # hard to only rely on the Tcl public header files. Internal headers # contain private data structures and are subject to change without # notice. # This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG #-------------------------------------------------------------------- TEA_PUBLIC_TCL_HEADERS #TEA_PRIVATE_TCL_HEADERS TEA_PUBLIC_TK_HEADERS #TEA_PRIVATE_TK_HEADERS TEA_PATH_X #-------------------------------------------------------------------- # Check whether --enable-threads or --disable-threads was given. # This auto-enables if Tcl was compiled threaded. #-------------------------------------------------------------------- TEA_ENABLE_THREADS #-------------------------------------------------------------------- # The statement below defines a collection of symbols related to # building as a shared library instead of a static library. #-------------------------------------------------------------------- TEA_ENABLE_SHARED #-------------------------------------------------------------------- # This macro figures out what flags to use with the compiler/linker # when building shared/static debug/optimized objects. This information # can be taken from the tclConfig.sh file, but this figures it all out. #-------------------------------------------------------------------- TEA_CONFIG_CFLAGS #-------------------------------------------------------------------- # Find the CFITSIO library. #-------------------------------------------------------------------- ASTROTCL_PATH_CFITSIO TEA_ADD_LIBS([${CFITSIO_LIB_SPEC}]) #-------------------------------------------------------------------- # Set the default compiler switches based on the --enable-symbols option. #-------------------------------------------------------------------- TEA_ENABLE_SYMBOLS #-------------------------------------------------------------------- # Everyone should be linking against the Tcl stub library. If you # can't for some reason, remove this definition. If you aren't using # stubs, you also need to modify the SHLIB_LD_LIBS setting below to # link against the non-stubbed Tcl library. Add Tk too if necessary. #-------------------------------------------------------------------- # allan: can't use stubs, due to BLT dependency #AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs]) #AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs]) #-------------------------------------------------------------------- # This macro generates a line to use when building a library. It # depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS, # and TEA_LOAD_TCLCONFIG macros above. #-------------------------------------------------------------------- TEA_MAKE_LIB #-------------------------------------------------------------------- # Determine the name of the tclsh and/or wish executables in the # Tcl and Tk build directories or the location they were installed # into. These paths are used to support running test cases only, # the Makefile should not be making use of these paths to generate # a pkgIndex.tcl file or anything else at extension build time. #-------------------------------------------------------------------- TEA_PROG_TCLSH TEA_PROG_WISH #-------------------------------------------------------------------- # These are for astrotclConfig.sh #-------------------------------------------------------------------- astrotcl_LIB_FILE=${PKG_LIB_FILE} eval pkglibdir="${libdir}" if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then eval astrotcl_LIB_FLAG="-lastrotcl${PACKAGE_VERSION}" else eval astrotcl_LIB_FLAG="-lastrotcl`echo ${PACKAGE_VERSION} | tr -d .`" fi astrotcl_BUILD_DIR="`pwd`" astrotcl_BUILD_LIB_SPEC="-L`pwd` ${astrotcl_LIB_FLAG}" astrotcl_LIB_SPEC="-L${pkglibdir} ${astrotcl_LIB_FLAG}" for i in ${PKG_OBJECTS} ; do astrotcl_PKG_OBJECTS="$astrotcl_PKG_OBJECTS ../astrotcl/$i" done AC_SUBST(astrotcl_LIB_FILE) AC_SUBST(astrotcl_BUILD_DIR) AC_SUBST(astrotcl_BUILD_LIB_SPEC) AC_SUBST(astrotcl_LIB_SPEC) AC_SUBST(astrotcl_PKG_OBJECTS) # astrotcl_SRC_DIR must be a fully qualified path eval astrotcl_SRC_DIR="$srcdir" astrotcl_SRC_DIR=`cd "${astrotcl_SRC_DIR}"; pwd` AC_SUBST(astrotcl_SRC_DIR) #-------------------------------------------------------------------- # Finally, substitute all of the various values into the Makefile. # You may alternatively have a special pkgIndex.tcl.in or other files # which require substituting th AC variables in. Include these here. #-------------------------------------------------------------------- AC_OUTPUT([Makefile pkgIndex.tcl astrotclConfig.sh]) skycat-3.1.2-starlink-1b/astrotcl/doit000077500000000000000000000002411215713201500176520ustar00rootroot00000000000000#!/bin/sh set -x autoconf \ && configure --prefix=$HOME/work/eso/skycat/src/install --exec_prefix=$HOME/work/eso/skycat/src/install \ && make \ && make install skycat-3.1.2-starlink-1b/astrotcl/generic/000077500000000000000000000000001215713201500204045ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/astrotcl/generic/Astrotcl.C000066400000000000000000000041671215713201500223130ustar00rootroot00000000000000/* * E.S.O. - VLT project * "@(#) $Id: Astrotcl.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $" * * Astrotcl.C - Initialize Astrotcl package * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 21 Nov 97 Created * pbiereic 26/08/99 Changed Astrotcl_Init() */ static const char* const rcsId="@(#) $Id: Astrotcl.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $"; #include #include #include #include #include #include #include #include #include #include #include #include "error.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" extern "C" int TclWorldCoords_Init(Tcl_Interp* interp); // Tcl procedure to search for an init for Astrotcl startup file. static char initScript[] = "if {[info proc ::util::Init]==\"\"} {\n\ namespace eval ::util {}\n\ proc ::util::Init {} {\n" #ifdef MAC_TCL " source -rsrc AstrotclInit.tcl\n" #else " global astrotcl_library\n\ tcl_findLibrary astrotcl " PACKAGE_VERSION " " PACKAGE_VERSION " AstrotclInit.tcl ASTROTCL_LIBRARY astrotcl_library\n" #endif " }\n\ }\n\ ::util::Init"; // dummy Tcl command implementation static int astrotcl_cmd(ClientData, Tcl_Interp* interp, int argc, char** argv) { return TCL_OK; } /* * A call to this function is made from the tkAppInit file at startup * to initialize this package */ extern "C" int Astrotcl_Init(Tcl_Interp* interp) { char buf[1024]; static int initialized = 0; if (initialized++) return TCL_OK; // set up Tcl package if (Tcl_PkgProvide (interp, "Astrotcl", PACKAGE_VERSION) != TCL_OK) { return TCL_ERROR; } // add a dummy tcl command (this command doesn't do anything currently) Tcl_CreateCommand(interp, "astrotcl", (Tcl_CmdProc*)astrotcl_cmd, NULL, NULL); // add the wcs command TclWorldCoords_Init(interp); // Set the global Tcl variable astrotcl_version Tcl_SetVar(interp, "astrotcl_version", PACKAGE_VERSION, TCL_GLOBAL_ONLY); return Tcl_Eval(interp, initScript); } skycat-3.1.2-starlink-1b/astrotcl/generic/DCompress.C000066400000000000000000000136361215713201500224200ustar00rootroot00000000000000 /* * E.S.O. - VLT project/ESO Archive * $Id: DCompress.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ * * Compress.C - method definitions for class Compress * (based on Archive/CADC press routines) * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 2 Aug 96 Created * 2 Jan 06 Renamed file to avoid name conflict with fitsio's * "compress.c" on file systems that ignore case. */ static const char* const rcsId="@(#) $Id: DCompress.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $"; #include #include #include #include #include #include #include #include #include #include "error.h" #include "Mem.h" #include "DCompress.h" extern "C" { #include "gen_types.h" #include "press.h" } // must correspond to enum CompressType static char* types_[] = {(char *)"NONE", (char *)"UCMP", (char *)"HCMP", (char *)"ULDA", (char *)"GZIP"}; /* * local util to report an error */ static int compress_error(int compress_flag) { if (compress_flag) return error("could not compress data: ", pr_msg); else return error("could not decompress data: ", pr_msg); } /* * compress (or decompress) from read_fd and write results to write_fd * If compress_flag is true, compress, otherwise decompress the file. */ int Compress::compress(int read_fd, int write_fd, CompressType ctype, int compress_flag) { if (ctype == NO_COMPRESS) { // no compression ? just copy int n; char buf[8*1024]; while((n = read(read_fd, buf, sizeof(buf))) > 0) { write(write_fd, buf, n); } return 0; } char* type = types_[ctype]; int status = (compress_flag ? press_f2f(read_fd, write_fd, type) : unpress_f2f(read_fd, write_fd, type)); if (status != 0) return compress_error(compress_flag); return 0; } /* * compress (or decompress) infile using the given compress type and * put the results in outfile. * If compress_flag is true, compress, otherwise decompress the file. * If mmap_flag is true, use mmap to map the file to memory. * * Note: we can just open the file and use the fd, but the "press" C * routines do unbuffered I/O on each char, which is slow. We can * mmap the file to memory and use the "mem to mem" version to improve * speed somewhat... */ int Compress::compress(const char* infile, const char* outfile, CompressType ctype, int compress_flag, int mmap_flag) { if (ctype == NO_COMPRESS) return 0; int status = 0; char* type = types_[ctype]; int write_fd = open(outfile, O_WRONLY|O_CREAT|O_TRUNC, 0777); if (write_fd < 0 ) { return sys_error("can't create output file: ", outfile); } if (mmap_flag) { // map input file to memory Mem inbuf(infile); if (inbuf.status() != 0) { close(write_fd); return ERROR; } unsigned char* outbuf = NULL; int outsize = inbuf.size(); int factor = 2; // estimated comp/decomp factor if (compress_flag) { outsize /= factor; status = press_m2m((unsigned char*)inbuf.ptr(), inbuf.size(), &outbuf, &outsize, type); } else { outsize *= factor; status = unpress_m2m((unsigned char*)inbuf.ptr(), inbuf.size(), &outbuf, &outsize, type); } if (status == 0) { if (write(write_fd, outbuf, outsize) != outsize) status = 1; close(write_fd); free(outbuf); if (status != 0) return sys_error("error writing file: ", outfile); } } else { // use standard read/write sys calls int read_fd = open(infile, O_RDONLY); if (read_fd < 0 ) { close(write_fd); return sys_error("can't open file: ", infile); } status = (compress_flag ? press_f2f(read_fd, write_fd, type) : unpress_f2f(read_fd, write_fd, type)); close(read_fd); close(write_fd); } if (status != 0) return compress_error(compress_flag); return 0; } /* * compress (decompress) the file in place using the given compress type. * If compress_flag is true, compress, otherwise decompress the file. */ int Compress::compress(const char* file, CompressType ctype, int compress_flag, int mmap_flag) { char tmpfile[1024]; sprintf(tmpfile, "%s.comp", file); int status = compress(file, tmpfile, ctype, compress_flag, mmap_flag); if (status != 0) { unlink(tmpfile); return status; } if (rename(tmpfile, file) != 0) return sys_error("rename failed for: ", file); return 0; } /* * compress (or decompress) the contents of inbuf using the given compress type and * allocate the results to outbuf. * * - inbufsz is the size of the input buffer. * * - outbufsz is an estimate of the outbuf size on input and the actual size * on output. * * If compress_flag is true, compress, otherwise decompress the file. * * It is the caller's responsibility to free() the outbuf when no longer needed. */ int Compress::compress(const char* inbuf, int inbufsz, char*& outbuf, int& outbufsz, CompressType ctype, int compress_flag) { if (ctype == NO_COMPRESS) return 0; char* type = types_[ctype]; int status = (compress_flag ? press_m2m((unsigned char*)inbuf, inbufsz, (unsigned char**)&outbuf, &outbufsz, type) : unpress_m2m((unsigned char*)inbuf, inbufsz, (unsigned char**)&outbuf, &outbufsz, type)); if (status != 0) return compress_error(compress_flag); return 0; } /* * Optionally set global compress options. * The first argument indicates the compression type. * "scale" is supported by gzip and h_compress. * "do_smoothing" (boolean) is only supported for h_compress. */ int Compress::set_options(CompressType ctype, int scale, int do_smoothing) { char* type = types_[ctype]; switch(ctype) { case H_COMPRESS: press_setopt(type, 0, do_smoothing, scale, "fits", 0, 0); break; case GZIP_COMPRESS: press_setopt(type, 0, scale); break; default: break; } return 0; } skycat-3.1.2-starlink-1b/astrotcl/generic/DCompress.h000066400000000000000000000051401215713201500224540ustar00rootroot00000000000000// -*-c++-*- #ifndef _Compress_h_ #define _Compress_h_ /* * E.S.O. - VLT project * $Id: DCompress.h,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ * * DCompress.h - utility class for compressing/decompressing FITS files * * (wrapper for archive/CADC "press" routines) * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 2 Aug 96 Created * 2 Jan 06 Renamed file to avoid name conflict with fitsio's * "compress.h" on file systems that ignore case. */ /* * Class Compress * */ class Compress { protected: public: // constructor Compress() {} // types of compression enum CompressType { NO_COMPRESS, // no compression UNIX_COMPRESS, // Compressed FITS file (UNIX) H_COMPRESS, // Hcompressed FITS file ULDA_COMPRESS, // ULDA compressed FITS file GZIP_COMPRESS // GZIPed FITS file }; // compress (or decompress) from read_fd and write results to write_fd int compress(int read_fd, int write_fd, CompressType type, int compress_flag = 1); // decompress from read_fd and write results to write_fd int decompress(int read_fd, int write_fd, CompressType type) { return compress(read_fd, write_fd, type, 0); } // compress (or decompress) infile and put the result in outfile int compress(const char* infile, const char* outfile, CompressType type, int compress_flag = 1, int mmap_flag = 1); // decompress infile and put the result in outfile int decompress(const char* infile, const char* outfile, CompressType type, int mmap_flag = 1) { return compress(infile, outfile, type, 0, mmap_flag); } // compress (or decompress) the file in place int compress(const char* file, CompressType type, int compress_flag = 1, int mmap_flag = 1); // decompress the file in place int decompress(const char* file, CompressType type, int mmap_flag = 1) { return compress(file, type, 0, mmap_flag); } // compress (or decompress) inbuf and allocate results in outbuf int compress(const char* inbuf, int inbufsz, char*& outbuf, int& outbufsz, CompressType ctype, int compress_flag = 1); // decompress inbuf and allocate results in outbuf int decompress(const char* inbuf, int inbufsz, char*& outbuf, int& outbufsz, CompressType ctype) { return compress(inbuf, inbufsz, outbuf, outbufsz, ctype, 0); } // optionally set global compress options for scale and smoothing static int set_options(CompressType ctype, int scale = 10, int do_smoothing = 0); }; #endif /* _Compress_h_ */ skycat-3.1.2-starlink-1b/astrotcl/generic/FitsIO.C000066400000000000000000001532151215713201500216540ustar00rootroot00000000000000/* * E.S.O. - VLT project / ESO Archive * * "@(#) $Id: FitsIO.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $" * * FitsIO.C - method definitions for class FitsIO, for operating on * Fits files. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * P.Biereichel 18/07/96 put_keyword char version added for SIMPLE. BITPIX=-16 fixed * Allan Brighton 16/02/98 renamed check_decompress to check_compress and added check * for bitpix=16 for H_COMPRESS. * 12/03/98 Initialize WCS in constructor. * Peter W. Draper 26/01/00 Now adds SIMPLE=T when saving extensions. * Made strftime call Y2K compliant. * Peter W. Draper 04/02/00 Changed constness of write so that * non-const member can be used within this * member. * pbiereic 17/02/03 Added 'using namespace std'. Removed ::std specs. * pbiereic 20/07/04 use %20 field width for keywords in methods put_keyword, * so that other tools like xv, ds9, fv can read stored real-time * images. * abrighto 02/01/05 Renamed .h file to avoid conflict with cfitsio's * "fitsio.h" on case-ignoring file systems, such as * Mac OSX. * Peter W. Draper 05/01/07 Set OBJECT card to value "RTD_BLANK" to determine * that a blank image has been generated. * 08/01/07 Write "END" keyword to blank image headers stream. * Previously written to buffer only. * 01/03/07 Added putcard method for pre-formatted cards. * Peter W. Draper 24/04/07 Handle table columns with K format, that's * TLONGLONG. * 22/05/07 Extend getTableValue so that the value can be scaled * (so that radian table values can be converted into degrees. * Needed for sky coordinates). Could do with a more * general system to determine which columns should * be converted (using the catalogue info?). * 23/05/07 Return compressed images (of the inline type * stored in an extension, RICE etc.) as binary * tables. As images they are garbled anyway. * (GAIA spots this and decompresses them). * 24/06/08 Remove restriction that requires a backing file * when moving HDU. This operation can be done * on memory FITS. * 27/08/08 Use DBL_DIG and FLT_DIG to encode double and * float values so that we do not lose any precision. * 16/03/09 Add getComment function to get the comment * part of a card. * 30/06/09 Check that the length of a opening file is not * less than expected. If true return a NULL in * reallocFile rather than the given pointer. This * protects against opening truncated files. * pbiereic 10/07/07 FitsIO::reallocFile returns the client data pointer when there * is no current FitsIO object. * pbiereic 10/08/07 FitsIO::write: using ISO date string (VLTSW20070156) * pbiereic 12/08/07 added support for data types double and long long int * pbiereic 07/09/07 added support for tiled-image compressed files * pbiereic 26/11/08 FitsIO::write: add basic FITS keys to HDU data */ static const char* const rcsId="@(#) $Id: FitsIO.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $"; #include #include #include #include #include #include #include #include #include #include #include #include "util.h" #include "error.h" #include "fitsio2.h" #include "SAOWCS.h" #include "DCompress.h" #include "Mem.h" #include "Fits_IO.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" using namespace std; // The type "long" may have 64 bits. #if LONGSIZE == 64 #define FITS_ULONG unsigned long #define FITS_UINT unsigned int #else #define FITS_ULONG unsigned long long #define FITS_UINT unsigned long #endif // size of a FITS block enum {FITSBLOCK=2880}; // common error message const char* noFitsErrMsg = "No FITS file is currently open"; const char* noHdrErrMsg = "Can't get keyword: no FITS header."; // local buffer used to return keyword and table values static char buf_[1024]; // "current" FitsIO object pointer, needed for cfitsio realloc callback FitsIO* FitsIO::fits_ = NULL; // length of memory mapped for current FitsIO object, needed for realloc // callback checks. size_t FitsIO::length_ = 0; /* * constructor: initialize from the given header and data objects * and, optionally, the cfitsio handle used to open the file. * * Note: the public interface is normally via FitsIO::read(), * when reading from a file. This constructor may be usefull * though when creating a FitsIO object from memory data. */ FitsIO::FitsIO(int width, int height, int bitpix, double bzero, double bscale, const Mem& header, const Mem& data, fitsfile* fitsio) : ImageIORep(width, height, bitpix, bzero, bscale, header, data), fitsio_(fitsio) { // Save a reference to the primary header primaryHeader_ = header; // ref counted copy } /* * Destructor: close the cfitsio object */ FitsIO::~FitsIO() { if (fitsio_) { int status = 0; if (fits_close_file(fitsio_, &status) != 0) cfitsio_error(); fitsio_ = NULL; } } /* * Return a copy of this object that shares the data, but can have a different current HDU */ FitsIO* FitsIO::copy() { int status = 0; fitsfile* newFitsio; fits_reopen_file(fitsio_, &newFitsio, &status); if (status != 0) return NULL; return new FitsIO(width_, height_, bitpix_, bzero_, bscale_, header_, data_, newFitsio); } /* * initialize world coordinates (based on the image header) */ int FitsIO::wcsinit() { // if there are multiple HDUs, merge the primary header with // the extension header to get all of the WCS info // (requested by Andreas Wicenec ). if (getNumHDUs() > 1) { int length = header_.length() + primaryHeader_.length(); mergedHeader_ = Mem(length+1, 0); if (mergedHeader_.status() == 0) { strncpy((char*)mergedHeader_.ptr(), (char*)header_.ptr(), header_.length()); strncpy(((char*)mergedHeader_.ptr())+header_.length(), (char*)primaryHeader_.ptr(), primaryHeader_.length()); ((char*)mergedHeader_.ptr())[length] = '\0'; wcs_ = WCS(new SAOWCS((const char*)mergedHeader_.ptr(), length)); return wcs_.status(); } } wcs_ = WCS(new SAOWCS((const char*)header_.ptr(), header_.length())); return wcs_.status(); } /* * create and return a temporary file with a copy of stdin. * The argument is a char array large enough to hold the filename. */ static char* getFromStdin(char* filename) { sprintf(filename, "/tmp/fits%d", getpid()); FILE* f = fopen(filename, "w"); if (!f) { sys_error("could not create temp file: ", filename); return NULL; } char buf[1024]; size_t n; while((n = fread(buf, 1, sizeof(buf), stdin)) > 0) { if (fwrite(buf, 1, n, f) != n) { sys_error("error writing temp file: ", filename); return NULL; } } fclose(f); return filename; } /* * Check if the given file has a suffix that indicates a known * compression type, and if so, compress or decompress the file, * depending on the value of decompress_flag. * * The suffixes recognized correspond to the http Content-types: * * hfits: for H-Compress * gfits, gzfits, gz: for GZIP * cfits, Z: for UNIX compress. * * If istemp is true on entry, filename is overwritten with the * decompressed version. In any case, if any (de)compression is done, * the output is written to a temp file and "istemp" is set to 1. * * The return value is the name of the file, possibly after decompression. * The "buf" argument gives the space for the temporary filename, if * needed. The last argument is the value of "bitpix", if known, or * 0. This is used to check for the correct file type for h_compress, * which only works on 16 bit FITS files. */ const char* FitsIO::check_compress(const char* filename, char* buf, int bufsz, int& istemp, int decompress_flag, int bitpix) { // check the file extension for recognized compression types const char* suffix = strrchr(filename, '.'); if (suffix) suffix++; else suffix = ""; Compress::CompressType ctype = Compress::NO_COMPRESS; if (strcmp(suffix, "hfits") == 0) { if (bitpix && abs(bitpix) != 16) { error("H-compress is only allowed for 16 bit FITS images"); if (istemp) unlink(filename); return NULL; } ctype = Compress::H_COMPRESS; } else if (strcmp(suffix, "gfits") == 0 || strcmp(suffix, "gzfits") == 0 || strcmp(suffix, "gz") == 0) { ctype = Compress::GZIP_COMPRESS; } else if (strcmp(suffix, "cfits") == 0 || strcmp(suffix, "Z") == 0) { ctype = Compress::UNIX_COMPRESS; } if (ctype != Compress::NO_COMPRESS) { Compress c; char tmpfile[1024]; static int count = 0; // for unique filename int status = 0; if (decompress_flag) { // don't use file's dir when decompressing, since it might not be writable sprintf(tmpfile, "/tmp/fio-%s-%d.%d.fits", getenv("USER"), getpid(), count++); // unique filename status = c.decompress(filename, tmpfile, ctype); } else { // use file's dir when compressing, so that rename() is possible sprintf(tmpfile, "%s.tmp", filename); status = c.compress(filename, tmpfile, ctype); } if (istemp || status != 0) unlink(filename); if (status != 0) return NULL; istemp = 1; strncpy(buf, tmpfile, bufsz); return buf; } return filename; } /* * Check if FITS binary table extension contains a compressed image */ const char* FitsIO::check_cfitsio_compress(char* filename, char* buf, int bufsz, int& istemp) { fitsfile* fitsio = NULL; int num = 0, zimage = 0, status = 0; fits_open_file(&fitsio, filename, READONLY, &status); if (status != 0) { cfitsio_error(); return NULL; } if (fits_get_num_hdus(fitsio, &num, &status) != 0) { cfitsio_error(); fits_close_file(fitsio, &status); return NULL; } if (num < 2) { fits_close_file(fitsio, &status); return filename; // no binary table } if (fits_movrel_hdu(fitsio, 1, NULL, &status) != 0) { // move to next HDU cfitsio_error(); fits_close_file(fitsio, &status); return NULL; } fits_read_key(fitsio, TLOGICAL, (char *)"ZIMAGE", &zimage, NULL, &status); // check compressed image fits_close_file(fitsio, &status); if (!zimage) return filename; // no binary table char tmpfile[1024]; static int count = 0; // for unique filename sprintf(tmpfile, "/tmp/cfio-%s-%d.%d.fits", getenv("USER"), getpid(), count++); // unique filename unlink(tmpfile); if (imcopy((char *)filename, tmpfile) != 0) { unlink(tmpfile); return NULL; } istemp = 1; strncpy(buf, tmpfile, bufsz); return buf; } /* * Read a FITS file and return an initialized FitsIO object for it, * or NULL if there are errors. * * If filename is "-", stdin is read into a temp image file and used as the input. * * The Mem class is used to speed up loading the file. The optional mem_options * control whether the memory is mapped read-only or read/write (see class Mem). */ FitsIO* FitsIO::read(const char* filename, int mem_options) { char tmpfile[1024], tmpfile2[1024], cfile[1024]; int istemp = 0, istemp2 = 0; tmpfile[0] = '\0'; if (strcmp(filename, "-") == 0) { // use stdin // we have to use seek later, so copy to a temp file first filename = getFromStdin(tmpfile); if (filename == NULL) return NULL; istemp++; } // check the file extension for recognized compression types filename = check_compress(filename, tmpfile, (int)sizeof(tmpfile), istemp, 1, 0); if (filename == NULL) { if (istemp) unlink(tmpfile); return NULL; } // check if the file is internally tiled-image compressed (cfitsio) if (!istemp) strcpy(cfile, (char *)filename); else strcpy(cfile, tmpfile); filename = check_cfitsio_compress(cfile, tmpfile2, sizeof(tmpfile2), istemp2); if (filename == NULL) { if (istemp) unlink(tmpfile); if (istemp2) unlink(tmpfile2); return NULL; } // map image file to memory to speed up image loading if (mem_options == 0 && access(filename, W_OK) == 0) mem_options = Mem::FILE_RDWR; Mem header(filename, mem_options, 0); if (header.status() != 0) return NULL; if (istemp) { unlink(filename); // will be deleted by the OS later } if (istemp2) { unlink(tmpfile2); } if (header.status() != 0) return NULL; return initialize(header); } /* * Report a cfitsio error */ int FitsIO::cfitsio_error() { char buf[81]; ostringstream os; int i = 0; while (fits_read_errmsg(buf)) { os << buf << endl; i++; } fits_clear_errmsg(); if (i) { error("cfitsio: ", os.str().c_str()); } return ERROR; } /* * This static method is called by the cfitsio routines when the size of the file * has to be increased, such as when adding a new FITS block or table to the file. * Since a client data pointer is not part of the interface, we use the "current" * FitsIO object, set before any operations that could result in a call to this * method. */ void* FitsIO::reallocFile(void* p, size_t newsize) { if (!fits_) { if ( length_ != 0 && newsize > length_ ) { return NULL; } return p; } if (fits_->checkWritable() != 0) return NULL; // not a writable FITS file // OK, we have a writable FITS file. Extend the size, remap and // return the mmap pointer. Mem m = fits_->header_; m.offset(0); if (newsize <= m.size()) return p; m.unmap(); if (m.remap(m.options(), newsize) != 0) return NULL; // error return m.ptr(); } /* * This static method returns a cfitsio handle, given the Mem object for the * FITS header. */ fitsfile* FitsIO::openFitsMem(Mem& header) { // filename for error reporting const char* filename = header.filename(); int rw_flag = 0; // true if memory can be written to if (filename) { rw_flag = ((header.options() & Mem::FILE_RDWR) != 0); } else { filename = "FitsIO"; rw_flag++; } // use the cfitsio library routines to access the file in memory fitsfile* fitsio = NULL; int status = 0; // cfitsio wants to have (and save) pointers to the data pointer and size, // so we have to provide the address of these by accessing the internal // MemRep class in the header object. // XXX (make sure the values are not actually modified...) MemRep* mrep = (MemRep*)header.rep(); FitsIO::length_ = mrep->size; if (fits_open_memfile(&fitsio, filename, rw_flag, &mrep->ptr, &mrep->size, FITSBLOCK, FitsIO::reallocFile, &status) != 0) { FitsIO::length_ = 0; cfitsio_error(); return NULL; } FitsIO::length_ = 0; return fitsio; } /* * Copy a compressed input image to an uncompressed output image. * The code for this method was taken from imcopy.c (cfitsio) */ int FitsIO::imcopy(char *infile, char *outfile) { fitsfile *infptr, *outfptr; /* FITS file pointers defined in fitsio.h */ int status = 0, ii = 1, iteration = 0, hdupos, extend = 0; int hdutype, bitpix, bytepix, naxis = 0, nkeys, datatype = 0, anynul, num = 0; 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]; /* Open the input file and create output file */ fits_open_file(&infptr, infile, READONLY, &status); if (status != 0) { cfitsio_error(); return status; } fits_create_file(&outfptr, outfile, &status); if (status != 0) { cfitsio_error(); return status; } fits_get_num_hdus(infptr, &num, &status); fits_get_hdu_num(infptr, &hdupos); /* Get the current HDU position */ get(infptr, "NAXIS", naxis); get(infptr, "EXTEND", extend); if (naxis == 0 && extend && num == 2) { // check if image is contained in the 2'nd HDU fits_movrel_hdu(infptr, 1, NULL, &status); // move to next HDU } 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) { cfitsio_error(); 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 LONGLONG_IMG: datatype = TLONGLONG; 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); } 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 (status) cfitsio_error(); /* if error occurred, show error message */ return status; } /* * Check that this object represents a FITS file (and not just some kind of memory) * and return 0 if it does. If not, return an error message. */ int FitsIO::checkFitsFile() { // For now, only support extending headers in mmap'ed FITS files if (!fitsio_ || (! (header_.filename() && data_.filename() && strcmp(header_.filename(), data_.filename()) == 0))) { return error("FitsIO: Operation not allowed on memory image"); } return 0; } /* * This static method returns an allocated FitsIO object given a Mem object * containing the data for the file. (header points to the data for the entire * file...). */ FitsIO* FitsIO::initialize(Mem& header) { fitsfile* fitsio = openFitsMem(header); if (!fitsio) return NULL; LONGLONG headStart = 0, dataStart = 0, dataEnd = 0; int status = 0; if (fits_get_hduaddrll(fitsio, &headStart, &dataStart, &dataEnd, &status) != 0) { cfitsio_error(); return NULL; } if (header.length() < (dataEnd - headStart)) { const char* filename = header.filename(); if (filename) log_message("FITS file has the wrong size (too short): %s", filename); else log_message("FITS data has the wrong size (too short)"); // return NULL; } // The data part is the same mmap area as the header, with an offset Mem data(header); header.length(dataStart - headStart); // set usable length of header data.offset(dataStart); // set offset for data data.length(dataEnd-dataStart); return initialize(header, data, fitsio); } /* * This static method returns an allocated FitsIO object, given the cfitsio * handle. */ FitsIO* FitsIO::initialize(Mem& header, Mem& data, fitsfile* fitsio) { int bitpix = 0, width = 0, height = 0; double bzero = 0.0, bscale = 1.0; get(fitsio, "NAXIS1", width); get(fitsio, "NAXIS2", height); get(fitsio, "BITPIX", bitpix); get(fitsio, "BSCALE", bscale); get(fitsio, "BZERO", bzero); return new FitsIO(width, height, bitpix, bzero, bscale, header, data, fitsio); } /* * This static method returns an allocated FitsIO object given the * header and data. */ FitsIO* FitsIO::initialize(Mem& header, Mem& data) { fitsfile* fitsio = openFitsMem(header); if (!fitsio) return NULL; return initialize(header, data, fitsio); } /* * Generate a blank image with a FITS header based on the given fields. * The arguments are the position as ra, dec, equinox in double degrees, * the radius in arcmin, the width and height in pixels and the color * to use for the image (the color value for black, for example). * * If ra < 0, no world coordinate info is added to the header. This will * create just a blank image with no WCS. * */ FitsIO* FitsIO::blankImage(double ra, double dec, double equinox, double radius, int width, int height, unsigned long color0) { // generate the fits data if (width <= 0 || height <= 0) { error("width and height must be positive integers"); return NULL; } Mem data(width*height, 0); if (data.status() != 0) return NULL; char* d = (char*)data.ptr(); memset(d, color0, width*height); Mem header(FITSBLOCK, 0); // more than large enough to hold the fields below if (header.status() != 0) return NULL; ostringstream os; // generate the fits header double r = radius/60.0; // radius in degrees put_keyword(os, "SIMPLE", (char *)"T"); //FITS header put_keyword(os, "BITPIX", 8); // No.Bits per pixel put_keyword(os, "NAXIS ", 2); // No.dimensions put_keyword(os, "NAXIS1", width); // Length X axis put_keyword(os, "NAXIS2", height); // Length Y axis // this causes the pixels to appear black (if the colormap starts with black) put_keyword(os, "DATAMIN", int(color0)); // min color put_keyword(os, "DATAMAX", int(color0+256)); // (theoretical) max color if (ra >= 0) { double cdelt2 = sqrt((r*r)/2.0)/(width/2.0); double cdelt1 = -cdelt2; put_keyword(os, "CTYPE1", (char *)"RA---TAN"); // R.A. in tangent plane projection put_keyword(os, "CTYPE2", (char *)"DEC--TAN"); // DEC. in tangent plane projection put_keyword(os, "CRPIX1", width/2+0.5); // Refpix of first axis put_keyword(os, "CRPIX2", height/2+0.5); // Refpix of second axis put_keyword(os, "CRVAL1", ra); // RA at Ref pix in decimal degrees put_keyword(os, "CRVAL2", dec); // DEC at Ref pix in decimal degrees put_keyword(os, "CDELT1", cdelt1); // RA pixel step (deg) put_keyword(os, "CDELT2", cdelt2); // DEC pixel step (deg) put_keyword(os, "EQUINOX", 2000.0); // default equinox put_keyword(os, "RADECSYS", (char *)"FK5"); // J2000... } // add a keyword so we can determine this image is blank put_keyword(os, "OBJECT", (char *) "RTD_BLANK"); //put_keyword(os, "BLANK", (int)color0); // blank pixel value char buf[81]; sprintf(buf, "%-80s", "END"); // mark the end of the header os << buf; strncpy((char*)header.ptr(), os.str().c_str(), header.length()); // write to shared memory // generate the blank image return new FitsIO(width, height, BYTE_IMAGE, 0.0, 1.0, header, data); } /* * write the keyword/value pair to the given stream. * (char* value version) */ int FitsIO::put_keyword(ostream& os, const char* keyword, char* value) { char buf1[81], buf2[81]; sprintf(buf1, "%-8s= '%s'", keyword, value); sprintf(buf2, "%-80s", buf1); os << buf2; return 0; } /* * write the keyword/value pair to the given stream. * (char value version) */ int FitsIO::put_keyword(ostream& os, const char* keyword, char value) { char buf1[81], buf2[81]; sprintf(buf1, "%-8s= %20c", keyword, value); sprintf(buf2, "%-80s", buf1); os << buf2; return 0; } /* * write the keyword/value pair to the given stream. * (int value version) */ int FitsIO::put_keyword(ostream& os, const char* keyword, int value) { char buf1[81], buf2[81]; sprintf(buf1, "%-8s= %20d", keyword, value); sprintf(buf2, "%-80s", buf1); os << buf2; return 0; } /* * write the keyword/value pair to the given stream. * (double value version) */ int FitsIO::put_keyword(ostream& os, const char* keyword, double value) { char buf1[81], buf2[81]; sprintf(buf1, "%-8s= %20f", keyword, value); sprintf(buf2, "%-80s", buf1); os << buf2; return 0; } /* * write the keyword/value pair to the given open file descriptor. * (int value version) */ int FitsIO::put_keyword(FILE* f, const char* keyword, int value) { char buf[81]; sprintf(buf, "%-8s= %20d", keyword, value); fprintf(f, "%-80s", buf); return 0; } /* * write the keyword/value pair to the given open file descriptor. * (double value version) */ int FitsIO::put_keyword(FILE* f, const char* keyword, double value) { char buf[81]; sprintf(buf, "%-8s= %20f", keyword, value); fprintf(f, "%-80s", buf); return 0; } /* * write the keyword/value pair to the given open file descriptor. * (char* value version) */ int FitsIO::put_keyword(FILE* f, const char* keyword, const char* value) { char buf[81]; sprintf(buf, "%-8s= '%s'", keyword, value); fprintf(f, "%-80s", buf); return 0; } /* * write the keyword/value pair to the given open file descriptor. * (char value version) */ int FitsIO::put_keyword(FILE* f, const char* keyword, char value) { char buf[81]; sprintf(buf, "%-8s= %20c", keyword, value); fprintf(f, "%-80s", buf); return 0; } /* * round off the file size to the next FITS block. * (size is the current size) */ void FitsIO::padFile(FILE* f, int size) { int rest = (size + FITSBLOCK) % FITSBLOCK; if (rest) { while (rest < FITSBLOCK) { fputc(' ', f); rest++; } } } /* * write a fits file from the data and header, if present */ int FitsIO::write(const char *filename) { char tmpfilename[1024]; int istemp = 1; if (fitsio_) { // flush any changes done in a memory FITS file int status = 0; if (fits_flush_file(fitsio_, &status) != 0) return cfitsio_error(); } // if the file exists, rename it to make a backup and to avoid // crashing if we have the file mapped already if (access(filename, F_OK) == 0) { char backup[1024]; sprintf(backup, "%s.BAK", filename); if (rename(filename, backup) != 0) return sys_error("can't create backup file for ", filename); } FILE *f; f = fopen(filename,"w"); if (f == NULL) return error("can't create FITS file: ", filename); // if we have a FITS header, use it, otherwise create one from what we know // and add some "blank cards" at the end for application use int header_length = header_.length(); if ( header_length > 0 ) { char *nextrec = (char *)header_.ptr(); if ( getNumHDUs() > 1 && getHDUNum() != 1 ) { // Saving an image stored in an extension, so need to add // the "SIMPLE" keyword and remove the "XTENSION" one. put_keyword(f, "SIMPLE", 'T'); nextrec += 80; } fwrite((char *)nextrec, 1, header_length, f); padFile(f, header_length); } else { // create a FITS header int size = FITSBLOCK/80; // number of keyword lines in FITS header, including END // output keywords put_keyword(f, "SIMPLE", 'T'); size--; int bitpix = bitpix_; if (bitpix == -16) bitpix = 16; put_keyword(f, "BITPIX", bitpix); size--; put_keyword(f, "NAXIS", 2); size--; put_keyword(f, "NAXIS1", width_); size--; put_keyword(f, "NAXIS2", height_); size--; if (bitpix_ == -16) { put_keyword(f, "BZERO", (double)32768.0); size--; put_keyword(f, "BSCALE", (double)1.0); size--; } put_keyword(f, "COMMENT", "Generated by FitsIO::write"); size--; // add a timestamp char buf2[50]; time_t clock = time(0); strftime(buf2, sizeof(buf2), "%Y-%m-%dT%H:%M:%S", localtime(&clock)); put_keyword(f, "DATE", buf2); size--; // leave some "blank cards" for later modification by other applications char buf[10]; int i = 0; while (size > 1) { sprintf(buf, "BLANK%02d", ++i); put_keyword(f, buf, " "); size--; } fprintf(f, "%-80s", "END"); // ... no need for padding, since we filled up the FITS block } // now write the image data int tsize = abs(bitpix_)/8; // size of a pixel value switch(bitpix_) { case -8: // note: special non-fits format for a saved XImage case 8: case 16: case 32: case -32: case 64: case -64: fwriteNBO((char*)data_.ptr(), tsize, width_*height_, f); break; case -16: { // unsigned short needs to be converted (conversion taken from Midas) unsigned short *pu = (unsigned short *)data_.ptr(); int i = width_*height_; short *ps_new = new short[i]; short *ps = ps_new; if (ps_new == 0) { fclose(f); return error("Not enough memory"); } int nn; if (BIGENDIAN == usingNetBO()) { // native byte order? while (i--) { nn = (int)(*pu++) - 32768; *ps++ = (unsigned int) nn; } } else { while (i--) { nn = (int)(SWAP16(*pu)) - 32768; *ps = (unsigned int) SWAP16(nn); pu++; ps++; } } fwriteNBO((char*)ps_new, tsize, width_*height_, f); delete ps_new; } break; default: fclose(f); return error("unsupported image type"); } // round off file size padFile(f, width_*height_*tsize); fclose(f); // check the file extension for recognized compression types const char *tmpfile = check_compress(filename, tmpfilename, (int)sizeof(tmpfilename), istemp, 0, bitpix_); if (tmpfile == NULL) return ERROR; if (strcmp(tmpfile, filename) != 0) { if (rename(tmpfile, filename) != 0) return sys_error("cannot rename to file ", filename); } return OK; } /* * Write data to disk (network byte ordered, NBO). * Byte swap is only needed when data are in shm and not * in BIGENDIAN. * Since data are passed as char* there is no automatic type * conversion by gcc. */ int FitsIO::fwriteNBO(char *data, int tsize, int size, FILE *f) const { int status; int n = size; if (tsize == 1 || usingNetBO()) { return fwrite(data, tsize, size, f); } Mem dbuf(size * tsize, 0); if (dbuf.status() != 0) return 0; if (tsize == 2) { unsigned short *from = (unsigned short *) data; unsigned short *to = (unsigned short *) dbuf.ptr(); while (n--) { *to++ = SWAP16(*from); from++; } } else if (tsize == 4) { FITS_UINT *from = (FITS_UINT *) data; FITS_UINT *to = (FITS_UINT *) dbuf.ptr(); while (n--) { *to++ = SWAP32(*from); from++; } } else if (tsize == 8) { FITS_ULONG *from = (FITS_ULONG *) data; FITS_ULONG *to = (FITS_ULONG *) dbuf.ptr(); while (n--) { *to++ = SWAP64(*from); from++; } } status = fwrite(dbuf.ptr(), tsize, size, f); return status; } /* * write a (ASCII formatted) copy of the FITS header to the given stream. * (format it in 80 char lines and replace any NULL chars with blanks) */ int FitsIO::getFitsHeader(ostream& os) const { string s((char*)header_.ptr(), header_.length()); istringstream is(s); char buf[81]; while(is.read(buf, 80)) { for (int i = 0; i < 80; i++) if (!isascii(buf[i])) buf[i] = ' '; buf[80] = '\n'; os.write(buf, 81); if (strncmp(buf, "END ", 8) == 0) break; } return 0; } /* * Check if we are inserting a new keyword or updating an existing one. * If inserting, make sure there is enough space in the header and, * if not, try to make space by enlarging the header. * Returns 0 if OK. */ int FitsIO::checkKeywordSpace(const char* keyword) { // make sure the file was mapped with write permission if (checkWritable() != 0) return 1; // error if (!get(keyword)) { // keyword not found in header? // see if there is room in the header for more keys int keysExist = 0, moreKeys = 0, status = 0; if (fits_get_hdrspace(fitsio_, &keysExist, &moreKeys, &status) != 0) return cfitsio_error(); // if there is no more room, make some room // (Normally cfitsio would do this automatically, but since we // may be using mmap, it is more complicated. if (moreKeys == 0 && extendHeader() != 0) return 1; } return 0; } /* * flush any memory changes to the file */ int FitsIO::flush() { int status = 0; fits_ = this; // reallocFile() might be called fits_flush_file(fitsio_, &status); fits_ = NULL; if (status != 0) return cfitsio_error(); return 0; } /* * Insert the given FITS header card and return 0 if OK. * If there is not enough space in the header, the file size is * automatically increased. */ int FitsIO::putcard(const char* card) { // make sure there is enough space in the header if (checkKeywordSpace(card) != 0) return 1; int status = 0; if (fits_write_record(fitsio_, card, &status) != 0) return cfitsio_error(); return flush(); } int FitsIO::put(const char* keyword, float val, const char* comment) { // make sure there is enough space in the header if (checkKeywordSpace(keyword) != 0) return 1; int status = 0; if (fits_update_key(fitsio_, TFLOAT, (char*)keyword, &val, (char*)comment, &status) != 0) return cfitsio_error(); return flush(); } int FitsIO::put(const char* keyword, int val, const char* comment) { // make sure there is enough space in the header if (checkKeywordSpace(keyword) != 0) return 1; int status = 0; if (fits_update_key(fitsio_, TINT, (char*)keyword, &val, (char*)comment, &status) != 0) return cfitsio_error(); return flush(); } int FitsIO::put(const char* keyword, const char* val, const char* comment) { // make sure there is enough space in the header if (checkKeywordSpace(keyword) != 0) return 1; int status = 0; if (fits_update_key(fitsio_, TSTRING, (char*)keyword, (char*)val, (char*)comment, &status) != 0) return cfitsio_error(); return flush(); } /* * extend the size of the FITS header by one header block and if the * header is part of an mmap'ed file, rewrite the file with the * new enlarged header. */ int FitsIO::extendHeader() { // Make sure we have a writable FITS file if (checkWritable() != 0) return 1; // error int status = 0; if (fits_write_comment(fitsio_, "FitsIO: added 1 block to header", &status) != 0) return cfitsio_error(); // calling flush will cause reallocFile() to be called if (flush() != 0) return 1; // error return setHDU(getHDUNum()); // reset header/data mem offsets } /* * get value for the given FITS keyword and return 0 if OK (found) */ int FitsIO::get(const char* keyword, double& val) const { if (! fitsio_) return error(noHdrErrMsg); int status = 0; if (fits_read_key(fitsio_, TDOUBLE, (char*)keyword, &val, NULL, &status) != 0) return cfitsio_error(); return 0; } int FitsIO::get(const char* keyword, float& val) const { if (! fitsio_) return error(noHdrErrMsg); int status = 0; if (fits_read_key(fitsio_, TFLOAT, (char*)keyword, &val, NULL, &status) != 0) return cfitsio_error(); return 0; } int FitsIO::get(const char* keyword, int& val) const { if (! fitsio_) return error(noHdrErrMsg); int status = 0; if (fits_read_key(fitsio_, TINT, (char*)keyword, &val, NULL, &status) != 0) return cfitsio_error(); return 0; } int FitsIO::get(const char* keyword, long& val) const { if (! fitsio_) return error(noHdrErrMsg); int status = 0; if (fits_read_key(fitsio_, TLONG, (char*)keyword, &val, NULL, &status) != 0) return cfitsio_error(); return 0; } int FitsIO::get(const char* keyword, LONGLONG& val) const { if (! fitsio_) return error(noHdrErrMsg); int status = 0; if (fits_read_key(fitsio_, TLONGLONG, (char*)keyword, &val, NULL, &status) != 0) return cfitsio_error(); return 0; } int FitsIO::get(const char* keyword, unsigned char& val) const { if (! fitsio_) return error(noHdrErrMsg); int status = 0; if (fits_read_key(fitsio_, TBYTE, (char*)keyword, &val, NULL, &status) != 0) return cfitsio_error(); return 0; } int FitsIO::get(const char* keyword, short& val) const { if (! fitsio_) return error(noHdrErrMsg); int status = 0; if (fits_read_key(fitsio_, TSHORT, (char*)keyword, &val, NULL, &status) != 0) return cfitsio_error(); return 0; } int FitsIO::get(const char* keyword, unsigned short& val) const { if (! fitsio_) return error(noHdrErrMsg); int status = 0; if (fits_read_key(fitsio_, TUSHORT, (char*)keyword, &val, NULL, &status) != 0) return cfitsio_error(); return 0; } /* * find and return the value for the given FITS keyword, or NULL if not found * The returned value, if any, points to static data and should be saved by the * caller. */ char* FitsIO::get(const char* keyword) const { if (! fitsio_) { error(noHdrErrMsg); return NULL; } int status = 0; if (fits_read_key(fitsio_, TSTRING, (char*)keyword, buf_, NULL, &status) != 0) { cfitsio_error(); return NULL; } return buf_; } /* * find and return the comment for the given FITS keyword, or NULL if not found * The returned value, if any, points to static data and should be saved by the * caller. */ char* FitsIO::getComment(const char* keyword) const { if (! fitsio_) { error(noHdrErrMsg); return NULL; } int status = 0; char value[81]; if (fits_read_key(fitsio_, TSTRING, (char*)keyword, value, buf_, &status) != 0) { cfitsio_error(); return NULL; } return buf_; } /* * This is the same as get(const char*), but you supply the buffer to hold * the result, which is then an empty string, if not found. */ char* FitsIO::get(const char* keyword, char* buf, int bufsz) const { char* s = get(keyword); if (s) strncpy(buf, s, bufsz); else buf[0] = '\0'; return buf; } /* * these are static versions of the above */ int FitsIO::get(fitsfile* fitsio, const char* keyword, double& val) { if (! fitsio) return error(noHdrErrMsg); int status = 0; if (fits_read_key(fitsio, TDOUBLE, (char*)keyword, &val, NULL, &status) != 0) return cfitsio_error(); return 0; } int FitsIO::get(fitsfile* fitsio, const char* keyword, float& val) { if (! fitsio) return error(noHdrErrMsg); int status = 0; if (fits_read_key(fitsio, TFLOAT, (char*)keyword, &val, NULL, &status) != 0) return cfitsio_error(); return 0; } int FitsIO::get(fitsfile* fitsio, const char* keyword, int& val) { if (! fitsio) return error(noHdrErrMsg); int status = 0; if (fits_read_key(fitsio, TINT, (char*)keyword, &val, NULL, &status) != 0) return cfitsio_error(); return 0; } int FitsIO::get(fitsfile* fitsio, const char* keyword, long& val) { if (! fitsio) return error(noHdrErrMsg); int status = 0; if (fits_read_key(fitsio, TLONG, (char*)keyword, &val, NULL, &status) != 0) return cfitsio_error(); return 0; } int FitsIO::get(fitsfile* fitsio, const char* keyword, unsigned char& val) { if (! fitsio) return error(noHdrErrMsg); int status = 0; if (fits_read_key(fitsio, TBYTE, (char*)keyword, &val, NULL, &status) != 0) return cfitsio_error(); return 0; } int FitsIO::get(fitsfile* fitsio, const char* keyword, unsigned short& val) { if (! fitsio) return error(noHdrErrMsg); int status = 0; if (fits_read_key(fitsio, TUSHORT, (char*)keyword, &val, NULL, &status) != 0) return cfitsio_error(); return 0; } int FitsIO::get(fitsfile* fitsio, const char* keyword, short& val) { if (! fitsio) return error(noHdrErrMsg); int status = 0; if (fits_read_key(fitsio, TSHORT, (char*)keyword, &val, NULL, &status) != 0) return cfitsio_error(); return 0; } /* * Find and return the value for the given FITS keyword, or NULL if not found. * The returned value, if any, points to static data and should be saved by the * caller. */ char* FitsIO::get(fitsfile* fitsio, const char* keyword) { if (! fitsio) { error(noHdrErrMsg); return NULL; } int status = 0; if (fits_read_key(fitsio, TSTRING, (char*)keyword, buf_, NULL, &status) != 0) { cfitsio_error(); return NULL; } return buf_; } // -- HDU access -- /* * Return the total number of HDUs */ int FitsIO::getNumHDUs() { if (!fitsio_) return 0; // file might be only in memory int status = 0, num = 0; if (fits_get_num_hdus(fitsio_, &num, &status) != 0) { cfitsio_error(); return 0; } return num; } /* * Return the type of the current HDU as a string: "image", "ascii", * or "binary" or NULL if there was an error. * * PWD: return compressed images as a table. */ const char* FitsIO::getHDUType() { if (!fitsio_) { error(noFitsErrMsg); return NULL; } int status = 0, type = 0; if (fits_get_hdu_type(fitsio_, &type, &status) != 0) { cfitsio_error(); return NULL; } /* Check for a compressed image. */ if ( fits_is_compressed_image( fitsio_, &status ) ) { type = BINARY_TBL; } switch(type) { case IMAGE_HDU: return "image"; case ASCII_TBL: return "ascii"; case BINARY_TBL: return "binary"; } return NULL; } /* * Return the number of the current HDU */ int FitsIO::getHDUNum() { if (!fitsio_) return error(noFitsErrMsg); int num = 1; return fits_get_hdu_num(fitsio_, &num); } /* * Move to the specified HDU and make it the current one * (Note that "num" is one based, so the primary array is num = 1.) */ int FitsIO::setHDU(int num) { // PWD: this isn't necessary. // if (checkFitsFile() != 0) // return 1; // error int status = 0, type = 0; if (fits_movabs_hdu(fitsio_, num, &type, &status) != 0) return cfitsio_error(); LONGLONG headStart = 0, dataStart = 0, dataEnd = 0; if (fits_get_hduaddrll(fitsio_, &headStart, &dataStart, &dataEnd, &status) != 0) { return cfitsio_error(); } // update the header and data offsets to point to the new HDU header_.offset(headStart); header_.length(dataStart - headStart); data_.offset(dataStart); data_.length(dataEnd-dataStart); // update these inherited member variables width_ = height_ = bitpix_ = 0; bscale_ = 1.0; bzero_ = 0.0; get(fitsio_, "NAXIS1", width_); get(fitsio_, "NAXIS2", height_); get(fitsio_, "BITPIX", bitpix_); get(fitsio_, "BSCALE", bscale_); get(fitsio_, "BZERO", bzero_); return 0; } /* * Delete the given HDU. Any following HDUs are shifted to fill the gap. */ int FitsIO::deleteHDU(int num) { // make sure the file was mapped with write permission if (checkWritable() != 0) return 1; // error int curHDU = getHDUNum(); if (setHDU(num) != 0) return 1; // error int status = 0; if (fits_delete_hdu(fitsio_, NULL, &status) != 0) return cfitsio_error(); // reset to the original HDU if (curHDU <= getNumHDUs()) return setHDU(curHDU); return 0; } // -- Fits Tables -- /* * Get the dimensions of the current FITS table. */ int FitsIO::getTableDims(long& rows, int& cols) { if (!fitsio_) return error(noFitsErrMsg); int status = 0; if (fits_get_num_rows(fitsio_, &rows, &status) != 0 || fits_get_num_cols(fitsio_, &cols, &status) != 0) return cfitsio_error(); return 0; } /* * Return the table heading for the given column, or NULL if there is an * error. The return value points to static storage... */ char* FitsIO::getTableHead(int col) { if (col <= 0 || col > 999) { error("FITS table column index out of range"); return NULL; } char keyword[16]; sprintf(keyword, "TTYPE%d", col); return get(keyword); } /* * Get the contents of the given column as an array of doubles. * The caller should pass an array of numValues doubles. */ int FitsIO::getTableColumn(int col, double* values, int numValues) { if (!fitsio_) return error(noFitsErrMsg); int status = 0, anynull = 0; if (fits_read_col(fitsio_, TDOUBLE, col, 1, 1, numValues, NULL, values, &anynull, &status) != 0) return cfitsio_error(); return 0; } /* * Return the value in the current FITS table at the given row * and column, or NULL if there was an error. If the value is a * a floating point value it will be scaled (by scale, which defaults to 1.0). * (use this to convert value from radians to degrees). * The returned pointer points to static storage and will be overwritten * on the next call to this method or the get(keyword) methods. */ char* FitsIO::getTableValue(long row, int col, double scale) { if (!fitsio_) { error(noFitsErrMsg); return NULL; } buf_[0] = '\0'; int status = 0, typecode = 0, anynulls = 0; long repeat = 0, width = 0; if (fits_get_coltype(fitsio_, col, &typecode, &repeat, &width, &status) != 0) { cfitsio_error(); return NULL; } if (width > sizeof(buf_)-1) { fmt_error("FITS table value at row %d, col %d is too long", row, col); return NULL; } switch(typecode) { case TSTRING: char* p[1]; p[0] = buf_; if (fits_read_col(fitsio_, TSTRING, col, row, 1, 1, (char *)"", p, &anynulls, &status) != 0) { cfitsio_error(); return NULL; } break; case TBYTE: case TSHORT: case TINT: case TLONG: long l; if (fits_read_col(fitsio_, TLONG, col, row, 1, 1, NULL, &l, &anynulls, &status) != 0) { cfitsio_error(); return NULL; } sprintf(buf_, "%ld", l); break; case TLONGLONG: LONGLONG ll; if (fits_read_col(fitsio_, TLONGLONG, col, row, 1, 1, NULL, &ll, &anynulls, &status) != 0) { cfitsio_error(); return NULL; } /* Handle 64 bit integer printing for this platform. * Can be "long long" or "long", plus windows has "I64d" * format. */ #if _MSC_VER sprintf(buf_, "%I64d", ll); #elif USE_LL_SUFFIX sprintf(buf_, "%lld", ll); #else sprintf(buf_, "%ld", ll); #endif break; case TUSHORT: case TUINT: case TULONG: unsigned long ul; if (fits_read_col(fitsio_, TULONG, col, row, 1, 1, NULL, &ul, &anynulls, &status) != 0) { cfitsio_error(); return NULL; } sprintf(buf_, "%lu", ul); break; case TFLOAT: float f; if (fits_read_col(fitsio_, TFLOAT, col, row, 1, 1, NULL, &f, &anynulls, &status) != 0) { cfitsio_error(); return NULL; } /* Scaling may need more precision */ sprintf(buf_, "%.*g", DBL_DIG, (double)f * scale); break; case TDOUBLE: double d; if (fits_read_col(fitsio_, TDOUBLE, col, row, 1, 1, NULL, &d, &anynulls, &status) != 0) { cfitsio_error(); return NULL; } sprintf(buf_, "%.*g", DBL_DIG, d*scale); break; case TLOGICAL: char c; if (fits_read_col(fitsio_, TLOGICAL, col, row, 1, 1, NULL, &c, &anynulls, &status) != 0) { cfitsio_error(); return NULL; } buf_[0] = (c ? 'T' : 'F'); buf_[1] = '\0'; break; default: fmt_error("cfitsio data type (%d) not supported",typecode); return NULL; } return buf_; } /* * Create a FITS table and make it the current HDU * * extname gives the name of the table. * * The initial size will be rows x cols entries. * * tform is an array giving the FITS data type for each column * (For example: 16A, for a 16 char string, see FITS description.) * * If asciiFlag is 1, an ASCII table is created, otherwise a binary table. */ int FitsIO::createTable(const char* extname, long rows, int cols, char** headings, char** tform, int asciiFlag) { // make sure the file was mapped with write permission if (checkWritable() != 0) return 1; // error int status = 0; int tbltype = (asciiFlag ? ASCII_TBL : BINARY_TBL); fits_ = this; // reallocFile() might be called if (fits_create_tbl(fitsio_, tbltype, rows, cols, headings, tform, NULL, (char*)extname, &status) != 0) { fits_ = NULL; return cfitsio_error(); } fits_ = NULL; if (flush() != 0) return 1; // error flushing data if (fits_movnam_hdu(fitsio_, tbltype, (char*)extname, 0, &status) != 0) { return cfitsio_error(); } return setHDU(getHDUNum()); // remap after modifying file } /* * Set the value in the current FITS table at the given row and column * (For now, all data types are treated as strings) */ int FitsIO::setTableValue(long row, int col, const char* value) { // make sure the file was mapped with write permission if (checkWritable() != 0) return 1; // error if (row < 1) return fmt_error("FITS table row index %d out of range: should be >= 1", row); if (col < 1) return fmt_error("FITS table column index %d out of range: should be >= 1", col); // make sure the file was mapped with write permission if (checkWritable() != 0) return 1; // error int status = 0, typecode = 0; long repeat = 0, width = 0; if (fits_get_coltype(fitsio_, col, &typecode, &repeat, &width, &status) != 0) return cfitsio_error(); switch(typecode) { case TSTRING: if (fits_write_col(fitsio_, TSTRING, col, row, 1, 1, (char**)&value, &status) != 0) return cfitsio_error(); break; case TBYTE: case TSHORT: case TINT: case TLONG: long l; if (sscanf(value, "%ld", &l) != 1) return error("invalid int value: ", value); if (fits_write_col(fitsio_, TLONG, col, row, 1, 1, &l, &status) != 0) return cfitsio_error(); break; case TLONGLONG: LONGLONG ll; #if _MSC_VER if (sscanf(value, "%I64d", &ll) != 1) { #elif USE_LL_SUFFIX if (sscanf(value, "%lld", &ll) != 1) { #else if (sscanf(value, "%ld", &ll) != 1) { #endif return error("invalid long value: ", value); } if (fits_write_col(fitsio_, TLONGLONG, col, row, 1, 1, &ll, &status) != 0) return cfitsio_error(); break; case TUSHORT: case TUINT: case TULONG: unsigned long ul; if (sscanf(value, "%lu", &ul) != 1) return error("invalid unsigned value: ", value); if (fits_write_col(fitsio_, TULONG, col, row, 1, 1, &ul, &status) != 0) return cfitsio_error(); break; case TFLOAT: case TDOUBLE: double d; if (sscanf(value, "%lf", &d) != 1) return error("invalid floating point value: ", value); if (fits_write_col(fitsio_, TDOUBLE, col, row, 1, 1, &d, &status) != 0) return cfitsio_error(); break; case TLOGICAL: char c; if (fits_write_col(fitsio_, TLOGICAL, col, row, 1, 1, (char*)value, &status) != 0) return cfitsio_error(); break; default: return fmt_error("cfitsio data type (%d) not supported"); } return flush(); } /* * Make sure that this object represents a writable FITS file that was * also mapped with read/write permission. The default for FitsIO::read() * is to map the file read-only. If you plan to edit the file by * inserting keywords or tables, you must pass the read-write flag, for * example: * * FitsIO* fits = FitsIO::read(filename, Mem::FILE_RDWR); * * If this was not the case, this method attempts to remap the file read/write. * * The return value is 0 if the file was or could be mapped read-write, * otherwise 1. */ int FitsIO::checkWritable() { if (!fitsio_) return error(noFitsErrMsg); if (checkFitsFile() != 0) return 1; if (!(header_.options() & Mem::FILE_RDWR)) { if (access(header_.filename(), W_OK) != 0) return error("FitsIO: no write permission on file: ", header_.filename()); return header_.remap(Mem::FILE_RDWR); } return 0; } skycat-3.1.2-starlink-1b/astrotcl/generic/Fits_IO.h000066400000000000000000000251011215713201500220500ustar00rootroot00000000000000// -*-c++-*- #ifndef _FitsIO_h_ #define _FitsIO_h_ /* * E.S.O. - VLT project * * "@(#) $Id: Fits_IO.h,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $" * * Fits_IO.h - declarations for class FitsIO, a class representing the * contents of a FITS image file (or other image source) * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * Peter W. Draper 10/01/00 Added getFitsFile member to allow access * to fitsio file handle (used to access * HDUs in derived/related classes). * Peter W. Draper 04/02/00 Changed constness of write so that * non-const member can be used within this * member. * 15/08/00 Made write virtual so it can be overriden. * pbiereic 17/02/03 Revised byte-order issues * Peter W. Draper 13/06/05 Made setHDU virtual so it can be overriden. * 28/11/05 Made copy virtual so it can be overridden. * 14/12/05 Moved setHDU and copy to the ImageIORep base * class so that CompoundImageData does not * need knowledge of this class (so that other * ImageIORep implementations can be used in * CompoundImages). * 01/03/07 Added putcard member to write a header card * without decomposition to kvc. * pbiereic 17/02/03 Revised byte-order issues * abrighto 02/01/05 Renamed .h file to avoid conflict with cfitsio's * "fitsio.h" on case-ignoring file systems, such as * Mac OSX. * 16/03/09 Added getComment function. * Peter W. Draper 29/30/09 Added length_ to support check of opened file * length. * pbiereic 12/08/07 added support for data types double and long long int * pbiereic 07/09/07 added support for tiled-image compressed files */ #include #include #include "ImageIO.h" #include "fitsio.h" /* * This class manages reading and writing FITS files and storing the * image data. It is derived from ImageIORep rather than class ImageIO * for the sake of reference counting. */ class FitsIO : public ImageIORep { private: // set wcslib header length for searching static void set_header_length(const Mem& header); void set_header_length() const; // make sure there is enough space in the header to insert/update a keyword int checkKeywordSpace(const char* keyword); // extend the size of the FITS header by one header block int extendHeader(); static void* reallocFile(void* p, size_t newsize); protected: // PWD: Move here so that derived classes can manipulate (needed to get // at HDU functions from ther fitsfile* fitsio_; // handle to use for cfitsio C library routines static FitsIO* fits_; // current class ptr for reallocFile callback static size_t length_; // current mapped length for reallocFile callback Mem primaryHeader_; // the primary header, if there is more than one HDU Mem mergedHeader_; // the primary header merged with the current extension // header, if applicable (The primary header is appended // after the extension header). // Check that this object represents a FITS file (and not just some kind of memory) // and return 0 if it does. If not, return an error message. int checkFitsFile(); // return 0 if this object represents a FITS file that was mapped for read/write int checkWritable(); // write the keyword/value pair to the given open file descriptor. static int put_keyword(FILE* f, const char* keyword, int value); static int put_keyword(FILE* f, const char* keyword, double value); static int put_keyword(FILE* f, const char* keyword, const char* value); static int put_keyword(FILE* f, const char* keyword, char value); // write keyword/value pair to the given stream. static int put_keyword(ostream& os, const char* keyword, int value); static int put_keyword(ostream& os, const char* keyword, double value); static int put_keyword(ostream& os, const char* keyword, char* value); static int put_keyword(ostream& os, const char* keyword, char value); // round off file size static void padFile(FILE* f, int size); // Report a cfitsio error static int cfitsio_error(); // return a cfitsio handle, given the Mem object for the FITS header. static fitsfile* openFitsMem(Mem& header); // flush any memory changes to the file int flush(); // Return an allocated FitsIO object, given the Mem objects for the header and data // and the cfitsio handle to use to access the file. static FitsIO* initialize(Mem& header, Mem& data, fitsfile* fitsio); public: // constructor: init from given header and data and optional // cfitsio handle. FitsIO(int width, int height, int bitpix, double bzero, double bscale, const Mem& header, const Mem& data, fitsfile* fitsio = NULL); // destructor ~FitsIO(); // Return a copy of this object that shares the data, but can have a different current HDU virtual FitsIO* copy(); // initialize world coordinates (based on the image header) int wcsinit(); // return the class name as a string const char* classname() const {return "FitsIO";} // read a FITS file and return a pointer to an allocated FitsIO object // NULL if an error occurred static FitsIO* read(const char* filename, int memOptions = 0); // write the data to a FITS file int write(const char *filename); // compress or decompress the given file and return the new filename // see comments in source file for details. static const char* check_compress(const char* filename, char* buf, int bufsz, int& istemp, int decompress_flag = 1, int bitpix = 0); // check if FITS binary table extension contains a compressed image static const char* check_cfitsio_compress(char* filename, char* buf, int bufsz, int& istemp); // Copy a compressed input image to an uncompressed output image static int imcopy(char *infile, char *outfile); // Return an allocated FitsIO object, given the Mem object for the file header // (header.ptr() should point to the entire FITS file contents.) static FitsIO* initialize(Mem& header); // Return an allocated FitsIO object, given the Mem objects for the header and data. static FitsIO* initialize(Mem& header, Mem& data); // generate a blank image with a FITS header based on the given fields static FitsIO* blankImage(double ra, double dec, double equinox, double radius, int width, int height, unsigned long color0); // find and set value for the given FITS keyword and return 0 if OK (found) int get(const char* keyword, double& val) const; int get(const char* keyword, float& val) const; int get(const char* keyword, int& val) const; int get(const char* keyword, long& val) const; int get(const char* keyword, long long& val) const; int get(const char* keyword, unsigned char& val) const; int get(const char* keyword, unsigned short& val) const; int get(const char* keyword, short& val) const; // find and return the value for the given FITS keyword, or NULL if not found char* get(const char* keyword) const; // find and return the comment for the given FITS keyword, or NULL if not found char* getComment(const char* keyword) const; // same as get(const char*), but you supply the buffer to hold the result char* get(const char* keyword, char* buf, int bufsz) const; // these are static versions of the above that require the cfitsio handle static int get(fitsfile*, const char* keyword, double& val); static int get(fitsfile*, const char* keyword, float& val); static int get(fitsfile*, const char* keyword, int& val); static int get(fitsfile*, const char* keyword, long& val); static int get(fitsfile*, const char* keyword, unsigned char& val); static int get(fitsfile*, const char* keyword, unsigned short& val); static int get(fitsfile*, const char* keyword, short& val); // find and return the value for the given FITS keyword, or NULL if not found static char* get(fitsfile*, const char* keyword); // write a (ASCII formatted) copy of the FITS header to the given stream. int getFitsHeader(ostream& os) const; // write data to disk (network byte ordered, NBO) int fwriteNBO(char *data, int tsize, int size, FILE *f) const; // Insert the given FITS keyword and value and return 0 if OK // If there is not enough space in the header, the file size is // automatically increased. int put(const char* keyword, double val, const char* comment = NULL); int put(const char* keyword, float val, const char* comment = NULL); int put(const char* keyword, int val, const char* comment = NULL); int put(const char* keyword, const char* val, const char* comment = NULL); // Insert a formatted header card. int putcard(const char* card); // -- HDU access -- // Return the total number of HDUs int getNumHDUs(); // Return the type of the current HDU as a string: "image", "ascii", // or "binary" or NULL if there was as error. const char* getHDUType(); // Return the index of the current HDU int getHDUNum(); // Move to the specified HDU and make it the current one virtual int setHDU(int num); // Delete the given HDU int deleteHDU(int num); // -- Read Fits Tables -- // get the dimensions of the current FITS table int getTableDims(long& rows, int& cols); // return the table heading for the given column char* getTableHead(int col); // Return the value in the current FITS table at the given row and column char* getTableValue(long row, int col, double scale = 1.0); // get the contents of the given column as an array of doubles int getTableColumn(int col, double* values, int numValues); // -- Write Fits Tables -- // Create a FITS table and make it the current HDU int createTable(const char* extname, long rows, int cols, char** headings, char** tform, int asciiFlag = 0); // Set the value in the current FITS table at the given row and column // (For now, all data types are treated as strings) int setTableValue(long row, int col, const char* value); }; #endif /* _FitsIO_h_ */ skycat-3.1.2-starlink-1b/astrotcl/generic/HMS.C000066400000000000000000000104411215713201500211370ustar00rootroot00000000000000/* * E.S.O. - VLT project/ESO Archive * $Id: HMS.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ * * HMS.C - method definitions for class HMS * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 95 Created * Peter W. Draper 27 Jan 03 Added extra_precision flags for milli-arcsec * 08 Aug 08 Use libwcs dec2str and ra2str functions in the * print methods. Previous version wasn't careful * enough at the boundary conditions (given the * fraction part of the arcseconds value, which * can round up). */ static const char* const rcsId="@(#) $Id: HMS.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $"; #include #include #include #include "error.h" #include "HMS.h" #include "fitshead.h" // Default precision. int HMS::extra_precision = 0; /* * constructor - from H:M:S.sss, calculate double value * (note: hours is taken as double incase of "-00:mm:ss" */ HMS::HMS(double hours, int min, double sec) : hours_(int(hours)), min_(min), sec_(sec), show_sign_(0) { val_ = (sec/60.0 + min)/60.0; double z = -0.0; // check also for neg zero if (hours < 0.0 || memcmp(&z, &hours, sizeof(double)) == 0) { val_ = hours_ - val_; hours_ = -hours_; sign_ = '-'; } else { val_ = hours_ + val_; sign_ = '+'; } } /* * constructor - from decimal value, calculate H:M:S.sss */ HMS::HMS(double val) : val_(val), show_sign_(0) { double dd, md, v = val, z = -0.0; // check also for neg zero if (v < 0.0 || memcmp(&z, &v, sizeof(double)) == 0) { sign_ = '-'; v = -v; } else { sign_ = '+'; } if ( extra_precision ) { dd = v + 0.000000000001; } else { dd = v + 0.0000000001; } hours_ = (int)dd; md = (dd - hours_) * 60.; min_ = (int)md; sec_ = (md - min_) * 60.; } /* * constructor - from string value, in format H:M:S.sss, hh, d.ddd, or * H M S... * If hflag is 1 and the value is not in H:M:S and is not an * integer (has a decimal point) convert to hours by dividing by 15. * If dflag is specified, it is set to 1 if the value was divided by 15. */ HMS::HMS(const char* s, int hflag, int* dflag) : show_sign_(0) { if (!s) { val_ = sec_ = 0.; hours_ = min_ = 0; return; } double hours = 0; int min = 0; double sec = 0.0; double val = 0.0; int n = sscanf(s, "%lf%*[: ]%d%*[: ]%lf", &hours, &min, &sec); if (n >= 2) { // note: on HP, scanf on "-0.0" returns "0.0", on sun, "-0.0" if (hours == 0.0 && strchr(s, '-')) hours = -0.0; *this = HMS(hours, min, sec); } else if (n == 1) { if (sscanf(s, "%lf", &val) == 1) { if (hflag && strchr(s, '.')) { *this = HMS(val/15.); if (dflag) *dflag = 1; } else *this = HMS(val); } else { *this = HMS(hours, 0, 0); } } else { val_ = HMS_NULL; // error } } /* * print in the given buffer in H:M:S format */ void HMS::print(char* buf) const { if ( extra_precision ) { print_extra_precise_( buf ); } else { print_normal_precise_( buf ); } } // Show 2 digits prec for dec, 3 for ra void HMS::print_normal_precise_( char *buf ) const { char lbuf[32]; if ( show_sign_ ) { dec2str( lbuf, 32, val_, 2 ); } else { ra2str( lbuf, 32, val_ * 15.0, 3 ); } strncpy( buf, lbuf, 32 ); } // Show 4 digits prec for dec, 5 for ra void HMS::print_extra_precise_( char *buf ) const { char lbuf[32]; if ( show_sign_ ) { dec2str( lbuf, 32, val_, 4 ); } else { ra2str( lbuf, 32, val_ * 15.0, 5 ); } strncpy( buf, lbuf, 32 ); } /* * write this object to the given stream in the format * H:M:S.sss */ ostream& operator<<(ostream& os, const HMS& hms) { char buf[80]; hms.print(buf); os << buf; return os; } /* * read an HMS object from the given stream in the format * H:M:S.sss or H M S */ istream& operator>>(istream& is, HMS& hms) { char c; double hours = 0; int min = 0; double sec = 0.0; is >> hours >> c >> min >> c >> sec; hms = HMS(hours, min, sec); return is; } skycat-3.1.2-starlink-1b/astrotcl/generic/HMS.h000066400000000000000000000054231215713201500212100ustar00rootroot00000000000000// -*-c++-*- #ifndef _HMS_h_ #define _HMS_h_ /* * E.S.O. - VLT project * $Id: HMS.h,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ * * HMS.h - class representing a value of the form "hours:min:sec" * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 27 Sep 95 Created * pbiereic 17/02/03 Added 'using namespace std'. Removed ::std specs. */ #include #include using namespace std; const double HMS_NULL = HUGE_VAL; // null value for a double /* * Class HMS */ class HMS { protected: int hours_; // base 60 values H:M:S.sss int min_; double sec_; double val_; // value converted to decimal short show_sign_; // flag, if true, include sign (+/-) when printing char sign_; // '+' or '-' public: // constructors HMS() : hours_(0), min_(0), sec_(0.0), val_(HMS_NULL), show_sign_(0) {} HMS(double hours, int min, double sec); HMS(double val); HMS(const char* s, int hflag = 0, int* dflag = 0); // return true if this object has the null value int isNull() const {return val_ == HMS_NULL;} // set to the null value void setNull() {val_ = HMS_NULL;} // member access int hours() const {return hours_;} int min() const {return min_;} double sec() const {return sec_;} double val() const {return val_;} char sign() const {return sign_;} // set to true to cause << to print with leading sign even when positive void show_sign(int b) {show_sign_ = b;} // ... (add I/O and arithmetic operators here) ... // output operator friend ostream& operator<<(ostream&, const HMS&); friend istream& operator>>(istream&, HMS&); // print in the given buffer in H:M:S format void print(char* buf) const; int operator<(const HMS& hms) const { return val_ < hms.val_; } int operator<=(const HMS& hms) const { return val_ <= hms.val_; } int operator>(const HMS& hms) const { return val_ > hms.val_; } int operator>=(const HMS& hms) const { return val_ >= hms.val_; } int operator==(const HMS& hms) const { return fabs(val_ - hms.val_) <= 0.0000000001; } int operator!=(const HMS& hms) const { return fabs(val_ - hms.val_) >= 0.0000000001; } // return the difference between 2 HMS values friend double operator-(const HMS& a, const HMS& b) { return (a.val_ - b.val_); } // set how many decimal places to show for arc seconds, this is 2 // by default, setting this to 1 shows 3 (milli arcsec). static int extra_precision; protected: void print_normal_precise_( char *buf ) const; void print_extra_precise_( char *buf ) const; }; #endif /* _HMS_h_ */ skycat-3.1.2-starlink-1b/astrotcl/generic/ImageCoords.C000066400000000000000000000061721215713201500227120ustar00rootroot00000000000000/* * E.S.O. - VLT project/ESO Archive * $Id: ImageCoords.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ * * ImageCoords.C - method definitions for class ImageCoords * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 95 Created */ static const char* const rcsId="@(#) $Id: ImageCoords.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $"; #include #include #include #include #include "error.h" #include "ImageCoords.h" /* * constructor - takes x and y as strings */ ImageCoords::ImageCoords(const char* x_str, const char* y_str) : x_(IMAGE_COORD_NULL), y_(IMAGE_COORD_NULL), status_(0) { if (sscanf(x_str, "%lf", &x_) != 1 || sscanf(y_str, "%lf", &y_) != 1) status_ = fmt_error("bad image coords: (%s, %s)", x_str, y_str); } /* * Print the coordinates in the given buffers */ void ImageCoords::print(char* x_buf, char* y_buf) { sprintf(x_buf, "%g", x_); sprintf(y_buf, "%g", y_); } /* * Print the coordinates to the given stream. */ void ImageCoords::print(ostream& os) { os << *this; } /* * get x and y */ void ImageCoords::get(double& x, double& y) { x = x_; y = y_; } /* * output operator: ("" for null coords) */ ostream& operator<<(ostream& os, const ImageCoords& pos) { if (pos.isNull()) os << "\"\""; else os << pos.x_ << " " << pos.y_; return os; } /* * return the distance between this position and the given one * (in pixels) */ double ImageCoords::dist(ImageCoords& pos) const { return dist(x_, y_, pos.x_, pos.y_); } /* * static member to get the distance between 2 points in pixels */ double ImageCoords::dist(double x0, double y0, double x1, double y1) { double x = fabs(x1 - x0); double y = fabs(y1 - y0); return sqrt(x*x + y*y); } /* * Given a radius in pixels, set pos1 and pos2 to the 2 endpoints that form a box * with center at this position. */ int ImageCoords::box(double radius, ImageCoords& pos1, ImageCoords& pos2) const { double w = sqrt((radius * radius)/2.); double x0 = x_ - w; double y0 = y_ - w; double x1 = x_ + w; double y1 = y_ + w; pos1 = ImageCoords(x0, y0); pos2 = ImageCoords(x1, y1); return 0; } /* * Given the endpoints of a box (pos1, pos2), set width, height and radius in * pixels, and return the position at the center of the box */ ImageCoords ImageCoords::center(const ImageCoords& pos1, const ImageCoords& pos2, double& radius, double& width, double& height) { ImageCoords result; if (pos1.status() || pos2.status()) { error("invalid image position argument"); return result; } // get center pos double x1 = pos1.x_, y1 = pos1.y_; double x2 = pos2.x_, y2 = pos2.y_; double x = (x1 + x2)/2.0; double y = (y1 + y2)/2.0; result = ImageCoords(x, y); // get width and height of box width = dist(x1, y1, x2, y1); height = dist(x1, y1, x1, y2); // radius is half the distance from pos1 to pos2 radius = dist(x1, y1, x2, y2)/2.; return result; } skycat-3.1.2-starlink-1b/astrotcl/generic/ImageCoords.h000066400000000000000000000056251215713201500227610ustar00rootroot00000000000000// -*-c++-*- #ifndef _ImageCoords_h_ #define _ImageCoords_h_ /* * E.S.O. - VLT project * $Id: ImageCoords.h,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ * * ImageCoords.h - class representing image coordinates (x, y) * (see also class WorldCoords) * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 97 Created * pbiereic 17/02/03 Added 'using namespace std'. Removed ::std specs. */ using namespace std; #include #include #include const double IMAGE_COORD_NULL = HUGE_VAL; // null value for a double /* * Class ImageCoords */ class ImageCoords { protected: double x_, y_; // coordinates of a pixel int status_; // status for errors in constructor public: // constructor - initialize null coords ImageCoords() : x_(IMAGE_COORD_NULL), y_(IMAGE_COORD_NULL), status_(0) {} // constructor ImageCoords(double x, double y) : x_(x), y_(y), status_(0) {} // constructor - parse X and Y in string format ImageCoords(const char* x_str, const char* y_str); // return true if the coords are null int isNull() const {return x_ == IMAGE_COORD_NULL || y_ == IMAGE_COORD_NULL;} // set to the null value void setNull() {x_ = IMAGE_COORD_NULL; y_ = IMAGE_COORD_NULL;} // output operator: format: "x y" friend ostream& operator<<(ostream&, const ImageCoords& pos); // print coords to the given buffer void print(char* x_buf, char* y_buf); // print coords to the given stream void print(ostream& os); // get x and y void get(double& x, double& y); // check for equality int operator==(const ImageCoords& pos) const { return x_ == pos.x_ && y_ == pos.y_; } int operator!=(const ImageCoords& pos) const { return x_ != pos.x_ || y_ != pos.y_; } // return the difference between 2 image coord points friend ImageCoords operator-(const ImageCoords& a, const ImageCoords& b) { return ImageCoords(a.x_ - b.x_, a.y_ - b.y_); } // short cuts // return x and y double x() const {return x_;} double y() const {return y_;} // get distance between points double dist(ImageCoords& pos) const; // static member to get the distance between 2 points static double dist(double x0, double y0, double x1, double y1); // Given a radius, set pos1 and pos2 to the 2 endpoints that form a box // with center at this position. int box(double radius, ImageCoords& pos1, ImageCoords& pos2) const; // Given the endpoints of a box (pos1, pos2), set width, height and radius // and return the center position of the box. static ImageCoords center(const ImageCoords& pos1, const ImageCoords& pos2, double& radius, double& width, double& height); // member access int status() const {return status_;} }; #endif /* _ImageCoords_h_ */ skycat-3.1.2-starlink-1b/astrotcl/generic/ImageIO.C000066400000000000000000000103251215713201500217630ustar00rootroot00000000000000/* * E.S.O. - VLT project / ESO Archive * * "@(#) $Id: ImageIO.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $" * * ImageIO.C - method definitions for class ImageIO, for managing image * I/O and storage * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 07/03/96 Created * * 12/03/98 Remove dependency on FitsIO (delegated to * class FitsIO or other class derived from * ImageIORep. * Peter W. Draper 24/06/99 Changed to use FITS_LONG as type in byte * swapping. "long" is 8 bytes on alphas and 64 SUNs. * pbiereic 12/08/07 added support for data types double and long long int */ static const char* const rcsId="@(#) $Id: ImageIO.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $"; /* see Apple Developer Connection Tech Notes http://developer.apple.com/technotes/tn2002/tn2071.html */ #if ! ( defined(__APPLE__) && defined(__MACH__) ) #include #endif #include #include #include #if HAVE_CONFIG_H #include "config.h" #endif #include "define.h" #include "error.h" #include "ImageIO.h" #include "fitsio2.h" // The type "long" may have 64 bits. #if LONGSIZE == 64 #define FITS_LONG int #define FITS_LONGLONG long #else #define FITS_LONG long #define FITS_LONGLONG long long #endif /* * copy constructor - increment the reference count... */ ImageIO::ImageIO(const ImageIO& im) : rep_(im.rep_) { if (rep_) rep_->refcnt_++; } /* * destructor - delete if there are no more references. */ ImageIO::~ImageIO() { if (rep_ && --rep_->refcnt_ <= 0) delete rep_; } /* * assignment operator */ ImageIO& ImageIO::operator=(const ImageIO& im) { if (im.rep_) im.rep_->refcnt_++; // protect against "im = im" if (rep_ && --rep_->refcnt_ <= 0) delete rep_; rep_ = im.rep_; return *this; } // ----------------------------------------------------------------------- // ImageIORep: base class of internal representation // ----------------------------------------------------------------------- /* * replace header */ int ImageIORep::header(const Mem& m) { header_ = m; return 0; } /* * replace data with data of same size */ int ImageIORep::data(const Mem& m) { if (m.length() < width_* height_ * (abs(bitpix_)/8)) return error("image memory area is too small"); data_ = m; return 0; } /* * If byte swapping is needed for this machine and image, make a byte * swapped copy of the image data, otherwise, do nothing. * Returns 0 if all is OK. */ int ImageIORep::byteSwapData() { int dsize = abs(bitpix_)/8; FITS_LONG l = 1; if (ntohl(l) == l || dsize == 1) { // no byte swapping needed return 0; } // make a byte-swapped copy of the image in memory. // Note: if this causes problems with huge images, maybe we should // make a byte swapped file copy and mmap it. int n = width_ * height_; int datalen = n * dsize; Mem data(datalen, 0); if (data.status() != 0) return 1; // copy the data and swap bytes if (dsize == 2) { // copy shorts (could be an odd number of them...) unsigned short* from = (unsigned short*)data_.ptr(); unsigned short* to = (unsigned short*)data.ptr(); while(n--) { *to++ = ntohs(*from); // note: ntohs could be a macro that references its arg more than once... from++; } } else if (dsize == 4) { // copy longs unsigned FITS_LONG* from = (unsigned FITS_LONG*)data_.ptr(); unsigned FITS_LONG* to = (unsigned FITS_LONG*)data.ptr(); while(n--) { *to++ = ntohl(*from); from++; } } else if (dsize == 8) { // copy long longs (doubles) unsigned FITS_LONGLONG* from = (unsigned FITS_LONGLONG*)data_.ptr(); unsigned FITS_LONGLONG* to = (unsigned FITS_LONGLONG*)data.ptr(); while(n--) { *to++ = SWAP64(*from); from++; } } else { return fmt_error("ImageIO: unexpected value for bitpix: %d", bitpix_); } // replace the image data with the byte swapped data // (This deletes the old data Mem object and replaces it with the new one) data_ = data; return 0; } skycat-3.1.2-starlink-1b/astrotcl/generic/ImageIO.h000066400000000000000000000302301215713201500220250ustar00rootroot00000000000000// -*-c++-*- #ifndef _ImageIO_h_ #define _ImageIO_h_ /* * E.S.O. - VLT project / ESO Archive * * "@(#) $Id: ImageIO.h,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $" * * ImageIO.h - declarations for class ImageIO, an abstract base class * representing the contents of an image file (or other * image source) and managing the reading and writing of * image files. The image data is (optionally) kept in shared * memory so that it can be easily accessed by external * applications. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * * 12/03/98 Remove dependency on FitsIO (delegated to * class FitsIO or other class derived from * ImageIORep. * Added WCS class, for optional World Coords * support. * Peter W. Draper 04/02/00 Changed constness of write so that * non-const member can be used within this * member. * 30/05/01 Added DOUBLE_IMAGE enumeration. * Added copy() and setHDU pure virtual members * to support CompoundImageData not having access * to the FitsIO class. The actual effect * of the setHDU member is left to the * implementation (this switches HDU for FitsIO). * Peter W. Draper 08/01/07 Comment out isclear() methods. Not used and * no longer reflect how a blank image is detected * (if resurrected need to add and then check for * RTD_BLANK value in OBJECT card to match behaviour * in RTD, or add a member for blankness). * pbiereic 12/08/07 added support for data types double and long long int */ #include #include #include #include #include "WCSRep.h" #include "Mem.h" // types of image data (these mostly correspond to the FITS BITPIX values) enum ImageDataType { UNKNOWN_IMAGE = -1, // unknown type BYTE_IMAGE = 8, // 8 bit images X_IMAGE = -8, // special, already color scaled, X image data SHORT_IMAGE = 16, // 16 bit signed USHORT_IMAGE = -16, // 16 bit unsigned LONG_IMAGE = 32, // 32 bit integer FLOAT_IMAGE = -32, // 32 bit floating point LONGLONG_IMAGE = 64, // 64 bit integer DOUBLE_IMAGE = -64 // 64 bit double }; /* * This class is used internally for reference counting and subclassing. * The public interface is through the ImageIO class. */ class ImageIORep { friend class ImageIO; protected: int width_, height_; // image dimensions int bitpix_; // image data type double bzero_, bscale_; // image value = bzero + bscale * val Mem header_, data_; // header and data are kept in shared memory, // Format of header is FITS. WCS wcs_; // object used to manage World Coordinate conversion // (You can initialize wcs by calling the virtual method "wcsinit()".) int refcnt_; // reference count int status_; // status after constructor // constructor (derived classes call this) ImageIORep(int width, int height, int bitpix, double bzero, double bscale, const Mem& header, const Mem& data) : width_(width), height_(height), bitpix_(bitpix), bzero_(bzero), bscale_(bscale), header_(header), data_(data), refcnt_(1), status_(0), usingNetBO_(1) {} // FITS uses network byte order (=big Endian). int usingNetBO_; public: // destructor virtual ~ImageIORep() {} // the following methods must be defined in a derived class // initialize world coordinates (based on the image header) virtual int wcsinit() = 0; // If byte swapping is needed for this machine and image, make a byte // swapped copy of the image data, otherwise, do nothing. int byteSwapData(); // return the class name as a string virtual const char* classname() const = 0; // get the value for the given image header keyword and return 0 if found virtual int get(const char* keyword, double& val) const = 0; virtual int get(const char* keyword, float& val) const = 0; virtual int get(const char* keyword, int& val) const = 0; virtual int get(const char* keyword, long& val) const = 0; virtual int get(const char* keyword, long long& val) const = 0; virtual int get(const char* keyword, unsigned char& val) const = 0; virtual int get(const char* keyword, unsigned short& val) const = 0; virtual int get(const char* keyword, short& val) const = 0; // find and return the value for the given FITS keyword, or NULL if not found virtual char* get(const char* keyword) const = 0; // write a (ASCII formatted) copy of the FITS header to the given stream. virtual int getFitsHeader(ostream& os) const = 0; // write the data to an image file virtual int write(const char *filename) = 0; // apply bzero and bscale to the value double scaleValue(double d) const {return bzero_+d*bscale_;} // reverse the effect of bzero and bscale double unScaleValue(double d) const {return (d-bzero_)/bscale_;} // return the size in bytes of a raw image pixel int pixelSize() const {return abs(bitpix_)/8;} // member access int width() const {return width_;} int height() const {return height_;} int bitpix() const {return bitpix_;} double bscale() const {return bscale_;} void bscale(double d) {bscale_ = d;} double bzero() const {return bzero_;} void bzero(double d) {bzero_ = d;} Mem& header() {return header_;} Mem& data() {return data_;} int status() const {return status_;} void status(int s) {status_ = s;} // class uses network byte ordering (=big Endian) int usingNetBO() const {return usingNetBO_;} void usingNetBO(int bo) {usingNetBO_ = bo;} // return the object used to manage world coordinates WCS& wcs() const {return (WCS&)wcs_;} // set the object used to manage world coordinates void wcs(const WCS& newwcs) {wcs_ = newwcs;} // replace header int header(const Mem&); // replace data with data of same size int data(const Mem&); // Return true if no image is loaded (a 2x2 pixel or smaller // image is considered blank). // PWD: unsafe function. This is not true. //virtual int isclear() const {return width_ <= 2 && height_ <= 2;} // create a copy, as lightweight as possible. virtual ImageIORep *copy() = 0; // switch to another component of the implementation. virtual int setHDU(int num) = 0; }; /* * This class defines the public interface for image I/O. It uses reference * counting with the above class to make it easier to implement different * views of the same image data. */ class ImageIO { private: ImageIORep* rep_; // internal representation for reference counting public: // constructor, to create a null object (use assignment operator to set later) ImageIO() : rep_((ImageIORep*)NULL) {} // constructor, from a pointer to a subclass of ImageIORep (FitsIO, etc...). // rep should be allocated with new and will be deleted by this class when // there are no more references to it. ImageIO(ImageIORep* rep) : rep_(rep) {} // copy constructor ImageIO(const ImageIO&); // destructor ~ImageIO(); // assignment ImageIO& operator=(const ImageIO&); // write the data to an image file int write(const char *filename) const { return rep_->write(filename); } // initialize world coordinates (based on the image header) int wcsinit() { return rep_->wcsinit(); } // get the value for the given image header keyword and return 0 if found int get(const char* keyword, double& val) const { return rep_->get(keyword, val); } int get(const char* keyword, float& val) const { return rep_->get(keyword, val); } int get(const char* keyword, int& val) const { return rep_->get(keyword, val); } int get(const char* keyword, long& val) const { return rep_->get(keyword, val); } int get(const char* keyword, long long& val) const { return rep_->get(keyword, val); } int get(const char* keyword, unsigned char& val) const { return rep_->get(keyword, val); } int get(const char* keyword, unsigned short& val) const { return rep_->get(keyword, val); } int get(const char* keyword, short& val) const { return rep_->get(keyword, val); } // find and return the value for the given FITS keyword, or NULL if not found char* get(const char* keyword) const { return rep_->get(keyword); } // get the value for the given image header keyword or return the // supplied default value if not found int get(const char* keyword, double& val, double defVal) const { if (rep_->get(keyword, val) != 0) val = defVal; return 0; } int get(const char* keyword, float& val, float defVal) const { if (rep_->get(keyword, val) != 0) val = defVal; return 0; } int get(const char* keyword, int& val, int defVal) const { if (rep_->get(keyword, val) != 0) val = defVal; return 0; } int get(const char* keyword, long& val, long defVal) const { if (rep_->get(keyword, val) != 0) val = defVal; return 0; } int get(const char* keyword, long long& val, long defVal) const { if (rep_->get(keyword, val) != 0) val = defVal; return 0; } int get(const char* keyword, unsigned char& val, unsigned char defVal) const { if (rep_->get(keyword, val) != 0) val = defVal; return 0; } int get(const char* keyword, unsigned short& val, unsigned short defVal) const { if (rep_->get(keyword, val) != 0) val = defVal; return 0; } int get(const char* keyword, short& val, short defVal) const { if (rep_->get(keyword, val) != 0) val = defVal; return 0; } char* get(const char* keyword, const char* defVal) const { char* s = rep_->get(keyword); return (s != NULL) ? s : (char*)defVal; } // write a (ASCII formatted) copy of the FITS header to the given stream. int getFitsHeader(ostream& os) const { return rep_->getFitsHeader(os); } // apply bzero and bscale to the value double scaleValue(double d) const {return rep_->scaleValue(d);} // reverse the effect of bzero and bscale double unScaleValue(double d) const {return rep_->unScaleValue(d);} // return the size in bytes of a raw image pixel int pixelSize() const {return rep_->pixelSize();} // member access int width() const {return rep_->width();} int height() const {return rep_->height();} int bitpix() const {return rep_->bitpix();} double bscale() const {return rep_->bscale();} void bscale(double d) {rep_->bscale(d);} double bzero() const {return rep_->bzero();} void bzero(double d) {rep_->bzero(d);} const Mem& header() const {return rep_->header();} const Mem& data() const {return rep_->data();} int usingNetBO() const {return rep_->usingNetBO();} void usingNetBO(int bo) {rep_->usingNetBO(bo);} // return a reference to the object used to manage world coordinates WCS& wcs() const {return rep_->wcs();} // set the object used to manage world coordinates void wcs(const WCS& newwcs) {rep_->wcs(newwcs);} // replace header int header(const Mem& m) {return rep_->header(m);} // replace data with data of same size int data(const Mem& m) {return rep_->data(m);} // short cuts const char* headerPtr() const {return (const char*)rep_->header().ptr();} const void* dataPtr() const {return rep_->data().ptr();} // note: if status is non-zero, the other methods are undefined int status() const {return rep_ ? rep_->status() : 1;} // Return true if no image is loaded. // PWD: see ImageIORep. //int isclear() const {return rep_->isclear();} // return a pointer to the internal class ImageIORep* rep() const {return rep_;} }; #endif /* _ImageIO_h_ */ skycat-3.1.2-starlink-1b/astrotcl/generic/SAOWCS.C000066400000000000000000000203401215713201500215060ustar00rootroot00000000000000/* * E.S.O. - VLT project / ESO Archive * * "@(#) $Id: SAOWCS.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $" * * SAOWCS.C - method definitions for class SAOWCS, an implementation * of the abstract WCS (WCSRep) class interface based on * Doug Mink's (saoimage) WCS library. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 30 Sep 96 Created * * 09 Jan 98 Fixed problem with [xy]SecPix_ values for * some (HST) images (affects distance conversion * from WCS to pixel) * 17 Mar 98 Renamed from WSCRep, made WCSRep abstract, * to allow new implementations based on other * libraries. * pbiereic 11/10/99 Added deltset() */ static const char* const rcsId="@(#) $Id: SAOWCS.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $"; #include #include #include "error.h" #include "SAOWCS.h" /* * constructor: make an SAOWCS object from the FITS header string * and the length of the header string. */ SAOWCS::SAOWCS(const char* header, int headerLength) : WCSRep(), wcs_(NULL), equinox_(0.0), ra_(0.0), dec_(0.0), width_(0.0), height_(0.0), xSecPix_(0.0), ySecPix_(0.0) { equinoxStr_[0] = '\0'; if (header && headerLength) { // The wcssubs/hget routines depend on a static variable being set by hlength()... // (The header string is probably not null terminated, since mmap'ed) hlength((char*)header, headerLength); wcs_ = wcsninit(header, headerLength); if (isWcs()) { // get image center and dimensions wcsfull(wcs_, &ra_, &dec_, &width_, &height_); xSecPix_ = width_*3600./pixWidth(); ySecPix_ = height_*3600./pixHeight(); // set the equinox value and string setEquinox(); } } } /* * destructor */ SAOWCS::~SAOWCS() { if (wcs_) free(wcs_); } /* * util method to set the equinox value and string */ void SAOWCS::setEquinox() { // make sure equinox has a valid value equinox_ = wcs_->equinox; strcpy(equinoxStr_, wcs_->radecout); if (wcs_->sysout == WCS_B1950 || wcs_->sysout == WCS_J2000) sprintf(equinoxStr_, "%g", equinox_); else { strcpy(equinoxStr_, wcs_->radecout); } } /* * convert the given x,y image coordinates to world coordinates, if * possible, and write the result to the given buffer as a list of * the form "RA DEC EQUINOX". * If no conversion can be done, buf will contain an empty list. * * If hms_flag is 1, the result is always in H:M:S D:M:S, otherwise the * format is the one used in the pix2wcst routine (H:M:S for equatorial, * otherwise degrees). */ char* SAOWCS::pix2wcs(double x, double y, char* buf, int bufsz, int hms_flag) const { buf[0] = '\0'; if (isWcs() /* && x > 0 && y > 0 && x < pixWidth() && y < pixHeight()*/) { if (hms_flag == 0) { ::pix2wcst(wcs_, x, y, buf, bufsz); } else { double ra, dec; ::pix2wcs(wcs_, x, y, &ra, &dec); if ( ! (wcs_->offscl == 1)) { char rastr[32], decstr[32]; if (wcs_->degout == 0 || wcs_->sysout == WCS_J2000 || wcs_->sysout == WCS_B1950) ::ra2str(rastr, sizeof(rastr), ra, 3); else ::dec2str(rastr, sizeof(rastr), ra, 3); ::dec2str(decstr, sizeof(decstr), dec, 2); sprintf (buf, "%s %s %s", rastr, decstr, equinoxStr_); } } } return buf; } /* * convert the given x,y image coordinates to world coordinates, if * possible, and write the results to the arguments ra and dec as doubles * in degrees. If no conversion can be done, ra and dec are set to 0.0 * and 1 is returned, otherwise 0 is returned. */ int SAOWCS::pix2wcs(double x, double y, double& ra, double& dec) const { if (!isWcs()) return error("image does not support world coords"); if (x <= 0 || y <= 0 || x > pixWidth() || y > pixHeight()) return error("coordinates out of range"); // note: start at origin = (1,1) rather than (0,0) ra = dec = 0.0; ::pix2wcs(wcs_, x, y, &ra, &dec); if (wcs_->offscl) return error("can't convert world coordinates: out of range"); return 0; } /* * convert the given world coordinates (ra and dec, in degrees) to x,y * image coordinates and put the results in x and y. */ int SAOWCS::wcs2pix(double ra, double dec, double &x, double &y) const { x = y = 0.0; if (!isWcs()) return error("image does not support world coords"); int offscl = 0; // set to 1 if offscale ::wcs2pix(wcs_, ra, dec, &x, &y, &offscl); if (offscl == 1) return error("can't convert world coords: off scale"); return 0; } /* * convert the given world coordinates distance (ra and dec, in degrees) * to an x,y image coordinates distance and put the results in x and y. */ int SAOWCS::wcs2pixDist(double ra, double dec, double &x, double &y) const { // get degrees per pixel double xDegPix = xSecPix_/3600.; double yDegPix = ySecPix_/3600.; if (xDegPix == 0. || yDegPix == 0.) return error("can't convert world coordinate to image distance"); x = fabs(ra/xDegPix); y = fabs(dec/yDegPix); return 0; } /* * convert the given image coordinates distance (x,y) to a world coordinates * distance (ra and dec, in degrees J2000) and put the results in ra and dec. */ int SAOWCS::pix2wcsDist(double x, double y, double& ra, double& dec) const { double xDegPix = xSecPix_/3600.; double yDegPix = ySecPix_/3600.; if (xDegPix == 0. || yDegPix == 0.) return error("can't convert image to world coordinate distance"); ra = fabs(x*xDegPix); dec = fabs(y*yDegPix); return 0; } /* * return the radius of the image in world coordinate arc-minutes * (the distance from the center of the image to the origin) */ double SAOWCS::radius() const { if (!isWcs()) return 0.0; // convert to WCS double ra0 = 0.0, dec0 = 0.0, ra1 = 0.0, dec1 = 0.0; ::pix2wcs(wcs_, 0, 0, &ra0, &dec0); ::pix2wcs(wcs_, pixWidth()/2, pixHeight()/2, &ra1, &dec1); return ::wcsdist(ra0, dec0, ra1, dec1) * 60; } /* * reset the center of the WCS structure * * Args: * ra = New center right ascension in degrees * dec = New center declination in degrees * equinox = (must be 2000 or 1950) */ int SAOWCS::shift(double ra, double dec, double equinox) { char* coorsys; if (equinox == 2000.) coorsys = (char *)"FK5"; else if (equinox == 1950.) coorsys = (char *)"FK4"; else return error("expected equinox of 1950 or 2000"); ::wcsshift(wcs_, ra, dec, coorsys); ra_ = ra; dec_ = dec; return 0; } /* * Set rotation and scaling * * Args: * cdelt1 = scale in degrees/pixel (axis 1); degrees = arcsec/3600. * cdelt2 = scale in degrees/pixel (axis 2) * rotation = rotation angle in degrees */ int SAOWCS::deltset(double cdelt1, double cdelt2, double rotation) { if (!isWcs()) return error("image does not support world coords"); ::wcsdeltset(wcs_, cdelt1, cdelt2, rotation); return 0; } /* * set up the WCS structure from the given information about the image * * Args: * ra = Center right ascension in degrees * dec = Center declination in degrees * secpix = Number of arcseconds per pixel * xrefpix = Reference pixel X coordinate * yrefpix = Reference pixel Y coordinate * nxpix = Number of pixels along x-axis * nypix = Number of pixels along y-axis * rotate = Rotation angle (clockwise positive) in degrees * equinox = Equinox of coordinates, 1950 and 2000 supported * epoch = Epoch of coordinates, used for FK4/FK5 conversion no effect if 0 * proj = Projection */ int SAOWCS::set(double ra, double dec, double secpix, double xrefpix, double yrefpix, int nxpix, int nypix, double rotate, int equinox, double epoch, const char* proj) { if (wcs_) { free(wcs_); wcs_ = NULL; } wcs_ = ::wcsxinit(ra, dec, secpix, xrefpix, yrefpix, nxpix, nypix, rotate, equinox, epoch, (char*)proj); wcsfull(wcs_, &ra_, &dec_, &width_, &height_); xSecPix_ = ySecPix_ = secpix; setEquinox(); return 0; } /* * return the world coordinates of the image center */ WorldCoords SAOWCS::center() const { return WorldCoords(ra_, dec_, equinox()); } skycat-3.1.2-starlink-1b/astrotcl/generic/SAOWCS.h000066400000000000000000000116071215713201500215610ustar00rootroot00000000000000// -*-c++-*- #ifndef _SAOWCS_h_ #define _SAOWCS_h_ /* * E.S.O. - VLT project / ESO Archive * * "@(#) $Id: SAOWCS.h,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $" * * SAOWCS.h - declarations for class SAOWCS, an implementation class for * class WCS, which is a reference counted class that manages * a pointer to a class derived from WCSRep. * * This class is based on Doug Mink's (saoimage) WCS C library. * Other implementations of the WCS interface may be added by * Defining new subclasses of the abstract class WCSRep. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 30 Sep 96 Created * 17 Mar 98 Renamed from WSCRep, made WCSRep abstract, * to allow new implementations based on other * libraries. * pbiereic 11/10/99 Added deltset() */ #include "WCSRep.h" #include "WorldCoords.h" #include "wcs.h" /* * This class defines an interface to Doug Mink's (saoimage) WCS C library. * The public interface is through the WCS class. * * Usage: WCS wcs(new SAOWCS(fits_header)); * * The memory for the new object is managed by the WCS class with reference * counting (as long as you use normal assignment and not pointers). */ class SAOWCS : public WCSRep { protected: WorldCoor* wcs_; // C object to manage World Coordinates // The following are needed here because they are sometimes set to 0 // in the wcs_ object double equinox_; // equinox as 2000.0, 1950.0, ... char equinoxStr_[32]; // equinox string: "J2000", "B1950", ... double ra_, dec_; // coordinates of image center in deg double width_, height_; // image width and height in deg double xSecPix_, ySecPix_; // number of arcsecs per pixel void setEquinox(); // set equinox value and string public: // constructor (derived classes call this) SAOWCS(const char* header, int headerLength); // destructor virtual ~SAOWCS(); // return class name as a string virtual const char* classname() const {return "SAOWCS";} // Return 1 if WCS info is available, else 0 ("LINEAR" doesn't count) int isWcs() const {return (wcs_ && ::iswcs(wcs_) && strcmp(equinoxStr_, "LINEAR") != 0);} // return the world coordinates string for the given ximage coords char* pix2wcs(double x, double y, char* buf, int bufsz, int hms_flag = 1) const; // return the world coords (in degrees, as 2 doubles) for the ximage coords int pix2wcs(double x, double y, double& ra, double& dec) const; // get the image coordinates for the given world coords int wcs2pix(double ra, double dec, double &x, double &y) const; // get the image coordinates distance for the given world coords distance in deg int wcs2pixDist(double ra, double dec, double &x, double &y) const; // get the world coords distance in deg for the given image coordinates distance int pix2wcsDist(double x, double y, double& ra, double& dec) const; // set up the WCS structure from the given information about the image int set(double ra, double dec, double secpix, double xrefpix, double yrefpix, int nxpix, int nypix, double rotate, int equinox, double epoch, const char* proj); // reset the center of the WCS structure int shift(double ra, double dec, double equinox); // set rotation and scaling int deltset(double cdelt1, double cdelt2, double rotation); // Return the WCS equinox double equinox() const {return equinox_;} const char* equinoxStr() const {return equinoxStr_;} // return the WCS epoch double epoch() const {return wcs_->epoch;} // return the rotation angle in degrees double rotate() const {return wcs_->rot;} // return the width, height, radius of the image in arcmin double width() const {return width_*60.;} double height() const {return height_*60.;} double radius() const; // return the number of world coordinate arcsecs per pixel double secPix() const {return ySecPix_;} double xSecPix() const {return xSecPix_;} double ySecPix() const {return ySecPix_;} // return the world coordinates of the center of the image WorldCoords center() const; // return image dimensions int pixWidth() const {return int(wcs_->nxpix);} int pixHeight() const {return int(wcs_->nypix);} // Return the WCS distance between the 2 given WCS points in arcsec */ double dist(double ra0, double dec0, double ra1, double dec1) const { return ::wcsdist(ra0, dec0, ra1, dec1) * 60.0 * 60.0; } // return the x,y reference pixel values double xRefPix() const {return wcs_->xrefpix;} double yRefPix() const {return wcs_->yrefpix;} // return the projection type const char* projection() const {return wcs_->ptype;} }; #endif /* _SAOWCS_h_ */ skycat-3.1.2-starlink-1b/astrotcl/generic/TclWorldCoords.C000066400000000000000000000106451215713201500234220ustar00rootroot00000000000000/* * E.S.O. - VLT project/Archive * $Id: TclWorldCoords.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ * * TclWorldCoords.C - method definitions for class TclWorldCoords * (Tcl interface to the WorldCoords class) * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 09 Nov 95 Created * pbiereic 17/02/03 Added 'using namespace std'. Removed ::std specs. */ static const char* const rcsId="@(#) $Id: TclWorldCoords.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $"; using namespace std; #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "WorldCoords.h" #include "TclWorldCoords.h" /* * declare a table of tcl subcommands * format: name, min_args, max_args, method */ static class TclWorldCoordsSubCmds { public: char* name; // method name int (TclWorldCoords::*fptr)(int argc, char* argv[]); int min_args; // minimum number of args int max_args; // maximum number of args } subcmds_[] = { {(char *)"dtohms", &TclWorldCoords::dtohmsCmd, 1, 2}, {(char *)"hmstod", &TclWorldCoords::hmstodCmd, 1, 2} }; /* * Call the given method in this class with the given arguments */ int TclWorldCoords::call(const char* name, int len, int argc, char* argv[]) { for(unsigned int i = 0; i < (int)sizeof(subcmds_)/sizeof(*subcmds_); i++) { TclWorldCoordsSubCmds* t = &subcmds_[i]; if (strncmp(t->name, name, len) == 0) { if (check_args(name, argc, t->min_args, t->max_args) != TCL_OK) return TCL_ERROR; return (this->*t->fptr)(argc, argv); } } return TclCommand::call(name, len, argc, argv); } /* * A call to this function can be made from the tkAppInit file at startup * to install the starcat command */ extern "C" int TclWorldCoords_Init(Tcl_Interp* interp) { Tcl_CreateCommand(interp, "wcs", (Tcl_CmdProc*)TclWorldCoords::wcsCmd, NULL, NULL); return TCL_OK; } /* * Implementation of the tcl extended command "wcs" - * usage: see man page for more details */ int TclWorldCoords::wcsCmd(ClientData, Tcl_Interp* interp, int argc, char* argv[]) { if (argc != 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " instanceName\"", NULL); return TCL_ERROR; } TclWorldCoords* cmd = new TclWorldCoords(interp, argv[0], argv[1]); return cmd->status(); } /* * Constructor - * * Create an "wcs" object in tcl for accessing the contents of star * catalogs. * * Note that the tcl command for this object is created in the * parent class constructor. */ TclWorldCoords::TclWorldCoords(Tcl_Interp* interp, const char* cmdname, const char* instname) : TclCommand(interp, cmdname, instname) { } /* * return the given world coords in tcl in hh:mm:ss [+-]dd:mm:ss format */ int TclWorldCoords::set_wcs_result(const WorldCoords& wcs) { if (wcs.status() != 0) return TCL_ERROR; ostringstream os; os << wcs; return set_result(os.str().c_str()); } /* * return the given HMS value in tcl in hh:mm:ss format */ int TclWorldCoords::set_hms_result(const HMS& hms) { ostringstream os; os << hms; return set_result(os.str().c_str()); } /* * If 2 arguments are specified, convert ra and dec from degrees to * hh:mm:ss [+-]dd:mm:ss format. If only one argument is specified, * convert it from floating point format to hh:mm:ss. */ int TclWorldCoords::dtohmsCmd(int argc, char* argv[]) { if (argc == 2) { double ra, dec; if (Tcl_GetDouble(interp_, argv[0], &ra) != TCL_OK || Tcl_GetDouble(interp_, argv[1], &dec) != TCL_OK) { return TCL_ERROR; } return set_wcs_result(WorldCoords(ra, dec)); } double val; if (Tcl_GetDouble(interp_, argv[0], &val) != TCL_OK) return TCL_ERROR; return set_hms_result(HMS(val)); } /* * If 2 arguments are specified, convert ra and dec from hh:mm:ss [+-]dd:mm:ss * format to degrees. If 1 argument is specified, convert the value from * hh:mm:ss to floating point format. */ int TclWorldCoords::hmstodCmd(int argc, char* argv[]) { if (argc == 2) { WorldCoords wcs(argv[0], argv[1]); if (wcs.status()) return error("expected world coordinates in H:M:S [+-]D:M:S format"); return set_result(wcs.ra_deg(), wcs.dec_deg()); } HMS hms(argv[0]); return set_result(hms.val()); } skycat-3.1.2-starlink-1b/astrotcl/generic/TclWorldCoords.h000066400000000000000000000026151215713201500234650ustar00rootroot00000000000000// -*-c++-*- #ifndef _TclWorldCoords_h_ #define _TclWorldCoords_h_ /* * E.S.O. - VLT project/ESO Archive * $Id: TclWorldCoords.h,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ * * TclWorldCoords.h - Tcl interface to the WorldCoords C++ class for * manipulating world coordinates * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 07 Nov 95 Created */ #include "TclCommand.h" /* * This class declares the methods used to implement the Tcl WorldCoords * command */ class TclWorldCoords : public TclCommand { protected: // call a member function by name virtual int call(const char* name, int len, int argc, char* argv[]); // utility to return a world coordinate hh:mm:ss [+-]dd:mm:ss value in Tcl int set_wcs_result(const WorldCoords& wcs); // utility to return a hh:mm:ss value in Tcl int set_hms_result(const HMS& hms); public: // constructor TclWorldCoords(Tcl_Interp*, const char* cmdname, const char* instname); // entry point from Tcl static int wcsCmd(ClientData, Tcl_Interp* interp, int argc, char* argv[]); // -- tcl subcommands -- /* int resolveCmd(int argc, char* argv[]); */ int dtohmsCmd(int argc, char* argv[]); int hmstodCmd(int argc, char* argv[]); }; #endif /* _TclWorldCoords_h_ */ skycat-3.1.2-starlink-1b/astrotcl/generic/WCSRep.C000066400000000000000000000032061215713201500216140ustar00rootroot00000000000000/* * E.S.O. - VLT project / ESO Archive * * "@(#) $Id: WCSRep.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $" * * WCS.C - method definitions for class WCS, a reference counting * wrapper class for managing world coordinates for an image. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 30 Sep 96 Created * 17 Mar 98 Made WCSRep an abstract base class to allow * new implementations of WCS. Renamed old WCSRep * to SAOWCS (based on Doug Mink's saoimage version). * abrighto 02/01/06 Renamed WCS.C to WCSRep.C to avoid name conflict * with wcs.c on file systems that ignore case */ static const char* const rcsId="@(#) $Id: WCSRep.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $"; #include #include #include "error.h" #include "WCSRep.h" /* * constructor for internal representation */ WCSRep::WCSRep() : status_(0), refcnt_(1) { } /* * destructor for internal representation */ WCSRep::~WCSRep() { } /* * copy constructor - increment the reference count... */ WCS::WCS(const WCS& wcs) : rep_(wcs.rep_) { if (rep_) rep_->refcnt_++; } /* * destructor - delete if there are no more references. */ WCS::~WCS() { if (rep_ && --rep_->refcnt_ <= 0) delete rep_; } /* * assignment operator */ WCS& WCS::operator=(const WCS& wcs) { if (wcs.rep_) wcs.rep_->refcnt_++; // protect against "wcs = wcs" if (rep_ && --rep_->refcnt_ <= 0) delete rep_; rep_ = wcs.rep_; return *this; } skycat-3.1.2-starlink-1b/astrotcl/generic/WCSRep.h000066400000000000000000000203411215713201500216600ustar00rootroot00000000000000// -*-c++-*- #ifndef _WCS_h_ #define _WCS_h_ /* * E.S.O. - VLT project / ESO Archive * * "@(#) $Id: WCSRep.h,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $" * * WCSRep.h - declarations for class WCS, a reference counted wrapper class * for managing world coordinates for an image. The implementation * class is a subclass of the abstract WCSRep class. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 30 Sep 96 Created * 17 MAr 98 Made WCSRep an abstract class, to allow * new WCS implementations. The old WCSRep * class was renamed to SAOWCS. * pbiereic 11/10/99 Added deltset() * abrighto 02/01/06 Renamed WCS.h to WCSRep.h to avoid name conflict * with wcs.h on file systems that ignore case */ #include "WorldCoords.h" /* * This class is used internally for reference counting. * The public interface is through the WCS class. */ class WCSRep { friend class WCS; private: int refcnt_; // reference count int status_; // status after constructor public: // constructor WCSRep(); // destructor virtual ~WCSRep(); // return class name as a string virtual const char* classname() const = 0; // Return 1 if WCS info is available, else 0 virtual int isWcs() const = 0; // return the world coordinates as a string for the given ximage coords virtual char* pix2wcs(double x, double y, char* buf, int bufsz, int hms_flag = 1) const = 0; // return the world coords (in degrees, as 2 doubles) for the ximage coords virtual int pix2wcs(double x, double y, double& ra, double& dec) const = 0; // get the image coordinates for the given world coords virtual int wcs2pix(double ra, double dec, double &x, double &y) const = 0; // get the image coordinates distance for the given world coords distance in deg virtual int wcs2pixDist(double ra, double dec, double &x, double &y) const = 0; // get the world coords distance in deg for the given image coordinates distance virtual int pix2wcsDist(double x, double y, double& ra, double& dec) const = 0; // set up the WCS structure from the given information about the image virtual int set(double ra, double dec, double secpix, double xrefpix, double yrefpix, int nxpix, int nypix, double rotate, int equinox, double epoch, const char* proj) = 0; // set rotation and scaling virtual int deltset(double cdelt1, double cdelt2, double rotation) = 0; // reset the center of the WCS structure virtual int shift(double ra, double dec, double equinox) = 0; // Return the WCS equinox virtual double equinox() const = 0; // Return the WCS equinox as a string virtual const char* equinoxStr() const = 0; // return the WCS epoch virtual double epoch() const = 0; // return the rotation angle in degrees virtual double rotate() const = 0; // return the width, height, radius of the image in arcmin virtual double width() const = 0; virtual double height() const = 0; virtual double radius() const = 0; // return the number of world coordinate arcsecs per pixel virtual double secPix() const = 0; virtual double xSecPix() const = 0; virtual double ySecPix() const = 0; // return the world coordinates of the center of the image virtual WorldCoords center() const = 0; // return image dimensions virtual int pixWidth() const = 0; virtual int pixHeight() const = 0; // Return the WCS distance between the 2 given WCS points in arcsec */ virtual double dist(double ra0, double dec0, double ra1, double dec1) const = 0; // return the x,y reference pixel values virtual double xRefPix() const = 0; virtual double yRefPix() const = 0; // return the projection type virtual const char* projection() const = 0; // member access virtual int status() const {return status_;} virtual void status(int s) {status_ = s;} }; /* * This class defines the public interface. It uses reference * counting with the above class to make it easier to share copies * of this object. */ class WCS { private: WCSRep* rep_; // internal representation for reference counting public: // default constructor: initialize to null WCS() : rep_(NULL) {} // copy constructor WCS(const WCS&); // Constructor, from a pointer to a subclass of WCSRep. // The memory is managed by this class after this call. WCS(WCSRep* rep) : rep_(rep) {} // destructor ~WCS(); // assignment WCS& operator=(const WCS&); // Return 1 if WCS info is available, else 0 // (always check this before calling any other methods) int isWcs() const {return rep_ && rep_->isWcs();} // return the world coordinates string for the given ximage coords // member access int pixWidth() const {return rep_->pixWidth();} int pixHeight() const {return rep_->pixHeight();} // Return the WCS distance between the 2 given WCS points in arcsec */ double dist(double ra0, double dec0, double ra1, double dec1) const { return rep_->dist(ra0, dec0, ra1, dec1); } char* pix2wcs(double x, double y, char* buf, int bufsz, int hms_flag = 1) const { return rep_->pix2wcs(x, y, buf, bufsz, hms_flag); } // return the world coords (in degrees, as 2 doubles) for the ximage coords int pix2wcs(double x, double y, double& ra, double& dec) const { return rep_->pix2wcs(x, y, ra, dec); } // get the image coordinates for the given world coords int wcs2pix(double ra, double dec, double &x, double &y) const { return rep_->wcs2pix(ra, dec, x, y); } // get the image coordinates distance for the given world coords distance in deg int wcs2pixDist(double ra, double dec, double &x, double &y) const { return rep_->wcs2pixDist(ra, dec, x, y); } // get the world coords distance in deg for the given image coordinates distance int pix2wcsDist(double x, double y, double& ra, double& dec) const { return rep_->pix2wcsDist(x, y, ra, dec); } // set up the WCS structure from the given information about the image int set(double ra, double dec, double secpix, double xrefpix, double yrefpix, int nxpix, int nypix, double rotate, int equinox, double epoch, const char* proj) { return rep_->set(ra, dec, secpix, xrefpix, yrefpix, nxpix, nypix, rotate, equinox, epoch, proj); } // set rotation and scaling int deltset(double cdelt1, double cdelt2, double rotation) { return rep_->deltset(cdelt1, cdelt2, rotation); } // reset the center of the WCS structure int shift(double ra, double dec, double equinox) { return rep_->shift(ra, dec, equinox); } // Return the WCS equinox double equinox() const {return rep_->equinox();} const char* equinoxStr() const {return rep_->equinoxStr();} // return the WCS epoch double epoch() const {return rep_->epoch();} // return the rotation angle in degrees double rotate() const {return rep_->rotate();} // return the width, height, radius of the image in arcmin double width() const {return rep_->width();} double height() const {return rep_->height();} double radius() const {return rep_->radius();} // return the number of world coordinate arcsecs per pixel double secPix() const {return rep_->secPix();} double xSecPix() const {return rep_->xSecPix();} double ySecPix() const {return rep_->ySecPix();} // return the x,y reference pixel values double xRefPix() const {return rep_->xRefPix();} double yRefPix() const {return rep_->yRefPix();} // return the projection type const char* projection() const {return rep_->projection();} // return the world coordinates of the center of the image WorldCoords center() const {return rep_->center();} // note: if status is non-zero, the other methods are undefined int status() const {return rep_ ? rep_->status() : 1;} // return true if the WCS object has been initialized int initialized() const {return rep_ ? 1 : 0;} // return a pointer to the internal class WCSRep* rep() const {return rep_;} }; #endif /* _WCS_h_ */ skycat-3.1.2-starlink-1b/astrotcl/generic/WorldCoords.C000066400000000000000000000355711215713201500227640ustar00rootroot00000000000000/* * E.S.O. - VLT project/ESO Archive * $Id: WorldCoords.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ * * WorldCoords.C - method definitions for class WorldCoords * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 95 Created */ static const char* const rcsId="@(#) $Id: WorldCoords.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $"; #include #include #include #include #include "error.h" #include "wcs.h" #include "WorldCoords.h" // prototypes C routines used (the header files are not ANSI C or C++ compat...) extern "C" { // used to convert equinox int prej_q (double q0[2], // IN: ra+dec at equinox eq0 in degrees double q1[2], // OUT: precessed to equinox eq1 double eq0, // IN: Initial equinox (Julian Years) double eq1); // IN: Final equinox (Julian Years) } /* * check range of ra,dec values and return 0 if OK */ int WorldCoords::checkRange() { double ra = ra_.val(), dec = dec_.val(); if (ra < -0.001 || ra >= 25.0) return error("RA value out of range (0..24 hours)"); if (dec < -90. || dec > 90.) return error("DEC value out of range (-90..+90 deg)"); return 0; } /** Set the equinox from the string and return 0 if okay (defaults to 2000). */ static int getEquinox(const char* equinoxStr, double& equinox) { if (!equinoxStr || strcmp(equinoxStr, "J2000") == 0) { equinox = 2000.; return 0; } if (strcmp(equinoxStr, "B1950") == 0) { equinox = 1950.; return 0; } if (*equinoxStr == 'J' || *equinoxStr == 'B') equinoxStr++; if (sscanf(equinoxStr, "%lf", &equinox) == 1) { return 0; } return 1; } /* * convert from one equinox to another. */ int WorldCoords::convertEquinox(double from_equinox, double to_equinox) { if (from_equinox == to_equinox) return 0; double q0[2], q1[2]; q0[0] = ra_.val() * 15; // hours to degrees q0[1] = dec_.val(); if (prej_q(q0, q1, from_equinox, to_equinox)) { // was successful ra_ = HMS(q1[0]/15); // degrees to hours dec_ = HMS(q1[1]); dec_.show_sign(1); return 0; // OK } // error return char buf[126]; sprintf(buf, "could not convert equinox from %g to %g\n", from_equinox, to_equinox); return error(buf); } /* * Convert from one equinox (or named coordinate system) to another. * The first 2 parameters may be numbers, such as "2000" or "1950", or * coordinate system names, like "J2000", "FK5", "GALACTIC", "ECLIPTIC", ... * Epoch is the besselian epoch in years. * If dflag is 1, the ra value was converted to hours by dividing by 15 */ int WorldCoords::convertEquinox(const char* fromEquinoxStr, const char* toEquinoxStr, double epoch, int dflag) { // check for numerical equinox double from_equinox = 0.; double to_equinox = 0.; if (getEquinox(fromEquinoxStr, from_equinox) == 0 && getEquinox(toEquinoxStr, to_equinox) == 0) return convertEquinox(from_equinox, to_equinox); // convert from one system to another int sys1 = wcscsys((char*)fromEquinoxStr); if (sys1 == -1) return error("bad equinox value: ", fromEquinoxStr); int sys2 = wcscsys((char*)toEquinoxStr); if (sys2 == -1) return error("bad equinox value: ", toEquinoxStr); double dtheta = ra_.val(); if (dflag) dtheta *= 15; // hours to degrees double dphi = dec_.val(); wcscon(sys1, sys2, from_equinox, to_equinox, &dtheta, &dphi, epoch); if (sys2 == WCS_J2000 || sys2 == WCS_B1950) dtheta /= 15; // degrees to hours ra_ = HMS(dtheta); dec_ = HMS(dphi); dec_.show_sign(1); return 0; } /* * constructor: note that the ra arg is H:M:S, while dec is D:M:S */ WorldCoords::WorldCoords(const HMS& ra, const HMS& dec, double equinox) : ra_(ra), dec_(dec) { dec_.show_sign(1); status_ = checkRange() || convertEquinox(equinox); } /* * constructor: note that the ra arg is H:M:S, while dec is D:M:S. * EquinoxStr may be a number or the system name, such as "GALACTIC" or "ECLIPTIC". */ WorldCoords::WorldCoords(const HMS& ra, const HMS& dec, const char* equinoxStr) : ra_(ra), dec_(dec) { dec_.show_sign(1); status_ = convertEquinox(equinoxStr); } /* * constructor: note that the ra and dec args are both in degrees */ WorldCoords::WorldCoords(double ra, double dec, double equinox) : ra_(ra/15), dec_(dec) { dec_.show_sign(1); status_ = checkRange() || convertEquinox(equinox); } /* * constructor: note that the ra and dec args are both in degrees. * equinoxStr may be a number or the system name, such as "GALACTIC" or "ECLIPTIC". */ WorldCoords::WorldCoords(double ra, double dec, const char* equinoxStr) : ra_(ra/15), dec_(dec) { dec_.show_sign(1); status_ = convertEquinox(equinoxStr); } /* * constructor: note that r... is H:M:S, while d... is D:M:S */ WorldCoords::WorldCoords(double rh, int rm, double rs, double dd, int dm, double ds, double equinox) : ra_(rh, rm, rs), dec_(dd, dm, ds) { dec_.show_sign(1); status_ = checkRange() || convertEquinox(equinox); } /* * constructor: note that r... is H:M:S, while d... is D:M:S. * equinoxStr may be a number or the system name, such as "GALACTIC" or "ECLIPTIC". */ WorldCoords::WorldCoords(double rh, int rm, double rs, double dd, int dm, double ds, const char* equinoxStr) : ra_(rh, rm, rs), dec_(dd, dm, ds) { dec_.show_sign(1); status_ = convertEquinox(equinoxStr); } /* * constructor - parse a free format string assumed to contain RA and DEC * * Allowed formats of input string: * * hh mm ss.s +/-dd mm ss.s * or * d.ddd +/-d.dddd * * or * hh +/-d.dddd * * If hflag is 1 and the ra value is not in H:M:S and is not an integer, * convert to hours by dividing by 15. */ WorldCoords::WorldCoords(const char* ra_str, const char* dec_str, double equinox, int hflag) : status_(0), ra_(ra_str, hflag), dec_(dec_str) { if (ra_.isNull()) { status_ = 1; return; } if (dec_.isNull()) { status_ = 1; return; } dec_.show_sign(1); status_ = checkRange() || convertEquinox(equinox); } /* * constructor - parse coordinates in string format as above, except that * equinoxStr may be a number or the system name, such as "GALACTIC" or "ECLIPTIC". */ WorldCoords::WorldCoords(const char* ra_str, const char* dec_str, const char* equinoxStr, int hflag) : status_(0), dec_(dec_str) { int dflag = 0; // set to 1 if ra was divided by 15 ra_ = HMS(ra_str, hflag, &dflag); if (ra_.isNull()) { status_ = 1; return; } if (dec_.isNull()) { status_ = 1; return; } dec_.show_sign(1); double equinox = 2000.; if (getEquinox(equinoxStr, equinox) == 0) { status_ = checkRange() || convertEquinox(equinox); } else { // hack - need to know if the RA value is in hours or deg status_ = convertEquinox(equinoxStr, "J2000", 0., dflag); } } /* * Print the coordinates in the given buffers: * If hmsFlag is non-zero, in H:M:S [+-]D:M:S format, otherwise in decimal * degrees. */ void WorldCoords::print(char* ra_buf, char* dec_buf, double equinox, int hmsFlag) { if (equinox == 2000.0) { if (hmsFlag) { ra_.print(ra_buf); dec_.print(dec_buf); } else { sprintf(ra_buf, "%.17g", ra_deg()); sprintf(dec_buf, "%.17g", dec_deg()); } } else { // make tmp copy and convert equinox before printing WorldCoords tmp = *this; tmp.convertEquinox(2000.0, equinox); if (hmsFlag) { tmp.ra_.print(ra_buf); tmp.dec_.print(dec_buf); } else { sprintf(ra_buf, "%.17g", tmp.ra_deg()); sprintf(dec_buf, "%.17g", tmp.dec_deg()); } } } /* * Print the coordinates in the given buffers: * If hmsFlag is non-zero, in H:M:S [+-]D:M:S format, otherwise in decimal * degrees. * Here equinoxStr may be a number or the system name, such as "GALACTIC" or "ECLIPTIC". * The printed coordinates are converted to the given equinox (or system). */ void WorldCoords::print(char* ra_buf, char* dec_buf, const char* equinoxStr, int hmsFlag) { double equinox = 2000.; if (getEquinox(equinoxStr, equinox) == 0) { print(ra_buf, dec_buf, equinox, hmsFlag); } else { // make tmp copy and convert equinox before printing WorldCoords tmp = *this; tmp.convertEquinox("J2000", equinoxStr); if (hmsFlag) { tmp.ra_.print(ra_buf); tmp.dec_.print(dec_buf); } else { sprintf(ra_buf, "%.17g", tmp.ra_deg()); sprintf(dec_buf, "%.17g", tmp.dec_deg()); } } } /* * Print the coordinates to the given stream in the given equinox. */ void WorldCoords::print(ostream& os, double equinox) { if (equinox == 2000.0) { os << *this; } else { // make tmp copy and convert equinox before printing WorldCoords tmp = *this; tmp.convertEquinox(2000.0, equinox); os << tmp; } } /* * Print the coordinates to the given stream in the given equinox (or system). * Here equinoxStr may be a number or the system name, such as "GALACTIC" or "ECLIPTIC". */ void WorldCoords::print(ostream& os, const char* equinoxStr) { double equinox = 2000.; if (getEquinox(equinoxStr, equinox) == 0) { print(os, equinox); } else { // make tmp copy and convert equinox before printing WorldCoords tmp = *this; tmp.convertEquinox("J2000", equinoxStr); os << tmp; } } /* * get ra and dec in degrees in the given equinox */ void WorldCoords::get(double& ra, double& dec, double equinox) { if (equinox == 2000.0) { ra = ra_deg(); dec = dec_deg(); } else { // make tmp copy and convert equinox WorldCoords tmp = *this; tmp.convertEquinox(2000.0, equinox); ra = tmp.ra_deg(); dec = tmp.dec_deg(); } } /* * Get ra and dec in degrees in the given equinox. * Here equinoxStr may be a number or the system name, such as "GALACTIC" or "ECLIPTIC". */ void WorldCoords::get(double& ra, double& dec, const char* equinoxStr) { double equinox = 2000.; if (getEquinox(equinoxStr, equinox) == 0) { get(ra, dec, equinox); } else { // make tmp copy and convert equinox WorldCoords tmp = *this; tmp.convertEquinox("J2000", equinoxStr); ra = tmp.ra_.val(); dec = tmp.dec_.val(); } } /* * output operator: format: h:m:s[+-]d:m:s (J2000) or "" for null coords */ ostream& operator<<(ostream& os, const WorldCoords& pos) { if (pos.isNull()) os << "\"\""; else os << pos.ra_ << " " << pos.dec_; return os; } #if 0 /* * input operator: format: h:m:s[+-]d:m:s (J2000) */ istream& operator>>(istream& is, WorldCoords& pos) { is >> pos.ra_ >> pos.dec_; // XXX need to input equinox ? pos.dec_.show_sign(1); return is; } #endif /* * util: dispos computes distance and position angle solving a spherical * triangle (no approximations) * INPUT :coords in decimal degrees * OUTPUT :dist in arcmin, returns phi in degrees (East of North) * AUTHOR :a.p.martinez */ static double dispos(double dra0, // IN: center RA double decd0, // IN: center DEC double dra, // IN: point RA double decd, // IN: point DEC double& dist) // OUT: distance in arcmin { double alf,alf0,del,del0,phi; double sd,sd0,cd,cd0,cosda,cosd,sind,sinpa,cospa; const double radian=180./M_PI; // coo transformed in radiants alf = dra / radian ; alf0= dra0 / radian ; del = decd / radian; del0= decd0 / radian; sd0=sin(del0); sd =sin(del); cd0=cos(del0); cd =cos(del); cosda=cos(alf-alf0); cosd=sd0*sd+cd0*cd*cosda; dist=acos(cosd); phi=0.0; if(dist > 0.0000004) { sind=sin(dist); cospa=(sd*cd0 - cd*sd0*cosda)/sind; //if(cospa>1.0)cospa=1.0; if (abs(cospa) > 1.0) cospa=cospa/abs(cospa); // 2005-06-02: fix from awicenec@eso.org sinpa=cd*sin(alf-alf0)/sind; phi=acos(cospa)*radian; if(sinpa < 0.0)phi = 360.0-phi; } dist *=radian; dist *=60.0; if(decd0 == 90.) phi = 180.0; if(decd0 == -90.) phi = 0.0; return(phi); } /* * return the distance between this position and the given one in arcmin */ double WorldCoords::dist(WorldCoords& pos) const { double dist; dispos(ra_deg(), dec_deg(), pos.ra_deg(), pos.dec_deg(), dist); return dist; } /* * return the distance between this position and the given one in arcmin * and also set the position angle */ double WorldCoords::dist(WorldCoords& pos, double& pa) const { double dist; pa = dispos(ra_deg(), dec_deg(), pos.ra_deg(), pos.dec_deg(), dist); return dist; } /* * static member to get the distance between 2 points in arcmin */ double WorldCoords::dist(double ra0, double dec0, double ra1, double dec1) { double dist; dispos(ra0, dec0, ra1, dec1, dist); return dist; } // taken from starbase: search.c, used below #define X__PI 3.14159265358979323846 #define X_2PI ( 2 * X__PI ) #define X_R2D (X_2PI / 360.0) #define X_R2H (X_2PI / 24.0) #define X_H2D (360.0 / 24.0) #define r2h(r) ( (r) / X_R2H ) #define h2r(d) ( (d) * X_R2H ) #define r2d(r) ( (r) / X_R2D ) #define d2r(d) ( (d) * X_R2D ) #define h2d(r) ( (r) * X_H2D ) #define d2h(d) ( (d) / X_H2D ) /* * Given a radius in arcmin, set pos1 and pos2 to the 2 endpoints that form a box * with center at this position. */ int WorldCoords::box(double radius, WorldCoords& pos1, WorldCoords& pos2) const { // get units in degrees double ra = ra_.val(), dec = dec_.val(); radius /= 60.0; // get width of square double width = sqrt(2.0*radius*radius); double r1, r2, d1, d2; double cosdec; d1 = dec - width / 2.0; if ( d1 <= -90.0 ) { d1 = -90.0; d2 = dec + width / 2.0; r1 = 0.0; r2 = 24.0; } else { d2 = dec + width / 2.0; if ( d2 >= 90.0 ) { d1 = dec - width / 2.0; d2 = 90.0; r1 = 0.0; r2 = 24.0; } else { if ( dec > 0.0 ) cosdec = fabs(cos(d2r(d1))); else cosdec = fabs(cos(d2r(d2))); r1 = ra - d2h(width) / 2 / cosdec; r2 = ra + d2h(width) / 2 / cosdec; if ( r1 < 0.0 ) r1 += 24; if ( r2 > 24.0 ) r2 -= 24; } } pos1 = WorldCoords(h2d(r1), d1); pos2 = WorldCoords(h2d(r2), d2); return 0; } /* * Given the endpoints of a box (pos1, pos2), set width, height and radius in * arcmin, and return the position at the center of the box */ WorldCoords WorldCoords::center(const WorldCoords& pos1, const WorldCoords& pos2, double& radius, double& width, double& height) { WorldCoords result; if (pos1.status() || pos2.status()) { error("invalid WCS position argument"); return result; } // get center pos double ra1 = pos1.ra_deg(), dec1 = pos1.dec_deg(); double ra2 = pos2.ra_deg(), dec2 = pos2.dec_deg(); double ra = (ra1 + ra2)/2.0; double dec = (dec1 + dec2)/2.0; result = WorldCoords(ra, dec); // get width and height of box width = (wcsdist(ra1, dec1, ra2, dec1) * 60.); height = (wcsdist(ra1, dec1, ra1, dec2) * 60.); // radius is half the distance from pos1 to pos2 radius = (wcsdist(ra1, dec1, ra2, dec2) * 60.)/2.; return result; } skycat-3.1.2-starlink-1b/astrotcl/generic/WorldCoords.h000066400000000000000000000133071215713201500230220ustar00rootroot00000000000000// -*-c++-*- #ifndef _WorldCoords_h_ #define _WorldCoords_h_ /* * E.S.O. - VLT project * $Id: WorldCoords.h,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ * * WorldCoords.h - class representing world coordinates * (right-ascension, declination, stored as J2000 internally) * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 27 Sep 95 Created * Peter W. Draper 24 Mar 09 Made checkRange virtual for subclasses */ #include #include "HMS.h" const double WCS_NULL = HMS_NULL; // null value for double coordinate value /* * Class WorldCoords */ class WorldCoords { protected: HMS ra_, dec_; // right-ascension, declination int status_; // status for errors in constructor // convert from one equinox to another int convertEquinox(double from_equinox, double to_equinox = 2000.0); // convert from one equinox (or named coordinate system) to another (string version). // equinoxStr may be a numerical equinox value, or a coordinate system name, such as // "J2000", "FK5", "GALACTIC", "ECLIPTIC", etc. (upper or lower case, abbrieviations okay). // If dflag is 1, the ra value was converted to hours by dividing by 15 int convertEquinox(const char* from_equinox, const char* to_equinox = "J2000", double epoch = 0., int dflag = 1); // check range of ra,dec values virtual int checkRange(); public: // constructor - initialize null coords WorldCoords() : status_(0) {} // constructor: note that ra is H:M:S, while dec is D:M:S WorldCoords(const HMS& ra, const HMS& dec, double equinox = 2000.0); // constructor: note that ra is H:M:S, while dec is D:M:S WorldCoords(const HMS& ra, const HMS& dec, const char* equinoxStr); // constructor: note that ra and dec are both in degrees WorldCoords(double ra, double dec, double equinox = 2000.0); // constructor: note that ra and dec are both in degrees WorldCoords(double ra, double dec, const char* equinoxStr); // constructor: note that r... is H:M:S, while d... is D:M:S WorldCoords(double rh, int rm, double rs, double dd, int dm, double ds, double equinox = 2000.0); // constructor: note that r... is H:M:S, while d... is D:M:S WorldCoords(double rh, int rm, double rs, double dd, int dm, double ds, const char* equinoxStr); // constructor - parse RA and DEC in string format WorldCoords(const char* ra, const char* dec, double equinox = 2000.0, int hflag = 0); // constructor - parse coordinates in string format // Note: equinoxStr may be a number or the system name, such as "GALACTIC" or "ECLIPTIC" WorldCoords(const char* ra, const char* dec, const char* equinoxStr, int hflag = 0); // return true if the coords are null int isNull() const {return ra_.isNull() || dec_.isNull();} // set to the null value void setNull() {ra_.setNull(); dec_.setNull();} #if 0 // input operator: format: H:M:S[+-]D:M:S, J2000 friend istream& operator>>(istream&, WorldCoords& pos); #endif // output operator: format: H:M:S[+-]D:M:S, J2000 friend ostream& operator<<(ostream&, const WorldCoords& pos); // print coords to the given buffer with given equinox in the given format void print(char* ra_buf, char* dec_buf, double equinox = 2000.0, int hmsFlag=1); // print coords to the given buffer with given equinox in the given format // Note: equinoxStr may be a number or the system name, such as "GALACTIC" or "ECLIPTIC" void print(char* ra_buf, char* dec_buf, const char* equinoxStr, int hmsFlag=1); // print coords to the given stream with the given equinox in H:M:S format void print(ostream& os, double equinox = 2000.0); // print coords to the given stream with the given equinox (or system name) in H:M:S format void print(ostream& os, const char* equinoxStr); // get ra and dec in degrees in the given equinox void get(double& ra, double& dec, double equinox); // get ra and dec in degrees in the given equinox void get(double& ra, double& dec, const char* equinoxStr); // check for equality int operator==(const WorldCoords& pos) const { return ra_ == pos.ra_ && dec_ == pos.dec_; } int operator!=(const WorldCoords& pos) const { return ra_ != pos.ra_ || dec_ != pos.dec_; } // return the difference between 2 world coord points friend WorldCoords operator-(const WorldCoords& a, const WorldCoords& b) { return WorldCoords(a.ra_ - b.ra_, a.dec_ - b.dec_); } // short cuts // return ra and dec in degrees double ra_deg() const {return ra_.val()*15;} double dec_deg() const {return dec_.val();} // get distance in arcmin between points double dist(WorldCoords& pos) const; // get distance in arcmin and position angle between points double dist(WorldCoords& pos, double& pa) const; // static member to get the distance between 2 points (in deg) in arcmin static double dist(double ra0, double dec0, double ra1, double dec1); // Given a radius in arcmin, set pos1 and pos2 to the 2 endpoints that form a box // with center at this position. int box(double radius, WorldCoords& pos1, WorldCoords& pos2) const; // Given the endpoints of a box (pos1, pos2), set width, height and radius in // arcmin, and return the center position of the box. static WorldCoords center(const WorldCoords& pos1, const WorldCoords& pos2, double& radius, double& width, double& height); // member access const HMS& ra() const {return ra_;} const HMS& dec() const {return dec_;} int status() const {return status_;} }; #endif /* _WorldCoords_h_ */ skycat-3.1.2-starlink-1b/astrotcl/generic/WorldOrImageCoords.h000066400000000000000000000127301215713201500242650ustar00rootroot00000000000000// -*-c++-*- #ifndef _WorldOrImageCoords_h_ #define _WorldOrImageCoords_h_ /* * E.S.O. - VLT project * $Id: WorldOrImageCoords.h,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ * * WorldOrImageCoords.h - class representing either world (ra, dec, equinox) * or image (x, y) coordinates * (see also class WorldCoords, class ImageCoords) * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 97 Created */ #include "WorldCoords.h" #include "ImageCoords.h" /* * Class WorldOrImageCoords - This class is designed to be used in * situations where you might need to deal with either world coordinates * or image coordinates, but don't know ahead of time which. We could * use a common base class and virtual methods, but that would require * using pointers or references, while it is often more convenient to use * instances of these classes. Also, the methods in both classes have * slightly different signatures. */ class WorldOrImageCoords { protected: WorldCoords wc_; // used for world coords ImageCoords ic_; // used for image coords int isWcs_; // flag: true if using world coords public: // constructor - initialize null coords WorldOrImageCoords() : isWcs_(0) {} // constructor: initialize world coords WorldOrImageCoords(WorldCoords wc) : wc_(wc), isWcs_(1) {} // constructor: initialize image coords WorldOrImageCoords(ImageCoords ic) : ic_(ic), isWcs_(0) {} // return true if the coords are null int isNull() const {return isWcs_ ? wc_.isNull() : ic_.isNull();} // set to the null value void setNull() {if (isWcs_) wc_.setNull(); else ic_.setNull();} // output operator friend ostream& operator<<(ostream& os, const WorldOrImageCoords& pos) { if (pos.isWcs_) os << pos.wc_; else os << pos.ic_; return os; } // print coords to the given buffer in the given equinox void print(char* x_buf, char* y_buf, double equinox = 2000., int hmsFlag=1) { if (isWcs_) wc_.print(x_buf, y_buf, equinox, hmsFlag); else ic_.print(x_buf, y_buf); } // print coords to the given buffer in the given equinox (or system, such as "GALACTIC", "ECLIPTIC") void print(char* x_buf, char* y_buf, const char* equinoxStr, int hmsFlag=1) { if (isWcs_) wc_.print(x_buf, y_buf, equinoxStr, hmsFlag); else ic_.print(x_buf, y_buf); } // print coords to the given stream in the given equinox void print(ostream& os, double equinox = 2000.) { if (isWcs_) wc_.print(os, equinox); else ic_.print(os); } // print coords to the given stream in the given equinox (or system, such as "GALACTIC", "ECLIPTIC") void print(ostream& os, const char* equinoxStr) { if (isWcs_) wc_.print(os, equinoxStr); else ic_.print(os); } // get x and y void get(double& x, double& y, double equinox = 2000.) { if (isWcs_) wc_.get(x, y, equinox); else ic_.get(x, y); } // check for equality int operator==(const WorldOrImageCoords& pos) const { return isWcs_ ? (wc_ == pos.wc_) : (ic_ == pos.ic_); } int operator!=(const WorldOrImageCoords& pos) const { return isWcs_ ? (wc_ != pos.wc_) : (ic_ != pos.ic_); } // return the difference between 2 image coord points friend WorldOrImageCoords operator-(const WorldOrImageCoords& a, const WorldOrImageCoords& b) { if (a.isWcs_ && b.isWcs_) return WorldOrImageCoords(a.wc_ - b.wc_); return WorldOrImageCoords(a.ic_ - b.ic_); } // short cuts // return ra and dec in degrees double ra_deg() const {return wc_.ra_deg();} double dec_deg() const {return wc_.dec_deg();} // return the internal WorldCoords or ImageCoords class WorldCoords& wc() {return wc_;} ImageCoords& ic() {return ic_;} const WorldCoords& wc() const {return wc_;} const ImageCoords& ic() const {return ic_;} // get distance between points double dist(WorldOrImageCoords& pos, double& pa) const { return isWcs_ ? wc_.dist(pos.wc_, pa) : ic_.dist(pos.ic_); } // get distance between points double dist(WorldOrImageCoords& pos) const { return isWcs_ ? wc_.dist(pos.wc_) : ic_.dist(pos.ic_); } // Given a radius, set pos1 and pos2 to the 2 endpoints that form a box // with center at this position. int box(double radius, WorldOrImageCoords& pos1, WorldOrImageCoords& pos2) const { return (pos1.isWcs_ = pos2.isWcs_ = isWcs_) ? wc_.box(radius, pos1.wc_, pos2.wc_) : ic_.box(radius, pos1.ic_, pos2.ic_); } // Given the endpoints of a box (pos1, pos2), set width, height and radius // and return the center position of the box. static WorldOrImageCoords center(const WorldOrImageCoords& pos1, const WorldOrImageCoords& pos2, double& radius, double& width, double& height) { if (pos1.isWcs_ && pos2.isWcs_) return WorldOrImageCoords(WorldCoords::center(pos1.wc_, pos2.wc_, radius, width, height)); return WorldOrImageCoords(ImageCoords::center(pos1.ic_, pos2.ic_, radius, width, height)); } // member access const HMS& ra() const {return wc_.ra();} const HMS& dec() const {return wc_.dec();} double x() const {return ic_.x();} double y() const {return ic_.y();} // return true if using WorldCoords double isWcs() const {return isWcs_;} int status() const {return isWcs_ ? wc_.status() : ic_.status();} }; #endif /* _WorldOrImageCoords_h_ */ skycat-3.1.2-starlink-1b/astrotcl/generic/compiler.h000066400000000000000000000037221215713201500223730ustar00rootroot00000000000000/* static char sccsid[] = "@(#) ST-ECF os/h/compiler.h 4.1 10/16/92"; */ /* @(#)compiler.h 1.1.1.1 (ESO-IPG) 7/11/91 20:24:30 */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .TYPE Header .NAME compiler.h .LANGUAGE C .AUTHOR Francois Ochsenbein [ESO-IPG] .CATEGORY Compiler-specfic Definitions .COMMENTS This module includes constants depending on the compiler. .ENVIRONMENT .VERSION 1.0 Created file ------------------------------------------------------------*/ #ifndef COMPILER_DEF #define COMPILER_DEF 0 /*=========================================================================== * Define Here Your Specific Implementation *===========================================================================*/ #define _TEMPLATES_ 1 /* Function templates */ #if 0 /* Example */ #define CC_ENV _TURBOC #define _TEMPLATES_ 1 /* Function templates */ #endif /* End of Example */ /*=========================================================================== * Function Templates Facilities *===========================================================================*/ /*=========================================================================== * List of supported Compilers *===========================================================================*/ #define _TURBOC 1 #define CC_TURBOC (CC_ENV == _TURBOC) #ifndef CC_ENV /*=========================================================================== * Definition of Default Compiler *===========================================================================*/ #define CC_ENV 0 #endif #ifndef _TEMPLATES_ /*=========================================================================== * Definition of Allowed Function Templates *===========================================================================*/ # ifndef OSDEFOS_DEF #include "osdefos.h" # endif #if OS_VMS # define _TEMPLATES_ 1 #else # define _TEMPLATES_ 0 #endif #endif #endif skycat-3.1.2-starlink-1b/astrotcl/generic/cotr.c000066400000000000000000000227511215713201500215260ustar00rootroot00000000000000/* static char sccsid[] = "@(#) ST-ECF as/src/cotr.c 4.1 12/6/91"; */ /*++++++ .TYPE Module .IDENTIFICATION cotr.c .VERSION 1.0 26-Feb-1987: Creation . .VERSION 1.1 24-Oct-1988: Changed Names .VERSION 1.2 03-May-1989: Changed statics .Language C .AUTHOR Francois Ochsenbein [ESO-IPG] .KEYWORDS Spherical Coordinate transformations .ENV .COMMENTS The routines provided in this module all deal with coordinate transformations. All spherical coordinates are assumed to be expressed in DEGREES. No function is traced. \begin{TeX} The parameter mnemonics are: \begin{itemize} \item o = array $[\alpha,\delta]$ of spherical coordinates, expressed in degrees. \item R = $3 \times 3$ Rotation (orthogonal) matrix from old to new coordinate frame \item u = vector $[x,y,z]$ of Unit (cosine) direction $(x^2+y^2+z^2=1)$ \end{itemize} \end{TeX} -----------------------------------------------------------------------*/ #include "trigo.h" /* Definitions */ #include "ok.h" #define ra o[0] #define dec o[1] #define x u[0] #define y u[1] #define z u[2] #define X p[0] #define Y p[1] #define ze Euler_angles[0] #define theta Euler_angles[1] #define zeta Euler_angles[2] /*============================================================================*/ int tr_Euler (Euler_angles, R) /*+++ .PURPOSE Compute the rotation matrix from Euler angles .METHOD \begin{TeX} $(z, \theta, \zeta)$. This rotation matrix is actually defined by $$ R = R_z(-z) \cdot R_y(\theta) \cdot R_z(-\zeta)$$ (from old to new frame). \end{TeX} .RETURNS OK ---*/ double Euler_angles[3]; /* IN: Euler angles (z, theta, zeta) */ double R[3][3]; /* OUT: rotation matrix */ { double w; R[0][2] = cosd(ze); R[1][2] = sind(ze); R[2][0] = cosd(zeta); R[2][1] = sind(zeta); R[2][2] = cosd(theta); w = sind(theta); R[0][0] = R[2][0]*R[2][2]*R[0][2] - R[2][1]*R[1][2]; R[1][0] = R[2][0]*R[2][2]*R[1][2] + R[2][1]*R[0][2]; R[0][1] = -R[2][1]*R[2][2]*R[0][2] - R[2][0]*R[1][2]; R[1][1] = -R[2][1]*R[2][2]*R[1][2] + R[2][0]*R[0][2]; R[2][0] = R[2][0]*w; R[2][1] = -R[2][1]*w; R[0][2] = -w*R[0][2]; R[1][2] = -w*R[1][2]; return(OK); } /*============================================================================*/ int tr_oo( o , o2, R) /*+++ .PURPOSE Rotate polar coordinates, using a R rotation matrix (old to new frame) .METHOD Use unit vectors .RETURNS OK ---*/ double o[2]; /* IN: Original angles */ double o2[2]; /* OUT: rotated angles */ double R[3][3]; /* IN: Rotation matrix */ { double us[3]; tr_ou ( o, us); /* tranforms polar angles into dir cos */ tr_uu (us, us, R); /* rotates dir cos */ return(tr_uo(us, o2)); /* transform unit vector to angles */ } /*============================================================================*/ int tr_oo1( o , o2 , R) /*+++ .PURPOSE Rotate polar coordinates, using the inversed R matrix (new to old frame). .METHOD Use unit vectors .RETURNS Non-zero value ---*/ double o[2]; /* IN: original angles */ double o2[2]; /* OUT: rotated angles */ double R[3][3]; /* IN: rotation matrix */ { double us[3]; tr_ou ( o, us); /* tranforms polar angles into dir cos */ tr_uu1 (us, us, R); /* rotates dir cos */ return(tr_uo(us, o2)); /* transform unit vector to angles */ } /*============================================================================*/ int tr_oR ( o , R ) /*+++ .PURPOSE Creates the rotation matrix R[3][3] defined as \begin{TeX} \begin{itemize} \item R[0] (first row) = unit vector towards Zenith \item R[1] (second row) = unit vector towards East \item R[2] (third row) = unit vector towards North \end{itemize} The resulting $R$ matrix can then be used to get the components $\vec{v}_{loc}$ of a vector $\vec{v}$ in the local frame, as {\tt tr\_uu}($\vec{v}$, $\vec{v}_{loc}$, $R$). \end{TeX} .RETURNS OK ---*/ double o[2]; /* IN: original angles */ double R[3][3]; /* OUT: rotation matrix */ { R[2][2] = cosd(dec); R[0][2] = sind(dec); R[1][1] = cosd(ra); R[1][0] = -sind(ra); R[1][2] = 0.e0; R[0][0] = R[2][2] * R[1][1]; R[0][1] = -R[2][2] * R[1][0]; R[2][0] = -R[0][2] * R[1][1]; R[2][1] = R[0][2] * R[1][0]; return(OK); } /*============================================================================*/ int tr_ou (o , u) /*+++ .PURPOSE Transformation from polar coordinates to Unit vector .RETURNS OK ---*/ double o[2]; /* IN: angles ra + dec in degrees */ double u[3]; /* OUT: dir cosines */ { double cosdec; cosdec = cosd(dec); x = cosdec * cosd(ra); y = cosdec * sind(ra); z = sind(dec); return (OK); } /*============================================================================*/ int tr_uo (u,o) /*+++ .PURPOSE Computes angles from direction cosines .RETURNS OK / NOK (x=y=z=0) ---*/ double u[3]; /* IN: Dir cosines */ double o[2]; /* OUT: Angles ra + dec in degrees */ { double r2; /* sqrt(x*x+y*y) */ r2 = x*x + y*y; ra =0.e0; if (r2 == 0.e0) /* in case of poles */ { if (z == 0.e0) return(NOK); dec = ( z>0.e0 ? 90.e0 : -90.e0); return(OK); } dec = atand ( z / sqrt(r2)); ra = atan2d (y , x ); if (ra < 0.e0) ra += 360.e0; return (OK); } /*============================================================================*/ int tr_uR ( u , R ) /*+++ .PURPOSE Creates the rotation matrix R[3][3] with \begin{TeX} \begin{itemize} \item R[0] (first row) = unit vector towards Zenith \item R[1] (second row) = unit vector towards East \item R[2] (third row) = unit vector towards North \end{itemize} \end{TeX} .RETURNS OK .REMARKS For the poles, \begin{TeX} ($|z|=1$), the rotation axis is assumed be the $y$ axis, i.e. the right ascension is assumed to be 0. \end{TeX} ---*/ double u[3]; /* IN: Original direction */ double R[3][3]; /* OUT: Rotation matrix */ { R[0][0] = x; R[0][1] = y; R[0][2] = z; R[2][2] = hypot ( x , y ); R[1][0] = 0.e0; R[1][1] = 1.e0; /* These are defaults for poles */ R[1][2] = 0.e0; if (R[2][2] != 0.e0) { R[1][1] = x / R[2][2]; R[1][0] = -y / R[2][2]; } R[2][0] = -R[0][2] * R[1][1]; R[2][1] = R[0][2] * R[1][0]; return(OK); } /*============================================================================*/ int tr_uu( u1 , u2 , R ) /*+++ .PURPOSE Rotates the unit vector u1 to u2, as \begin{TeX} \quad $\vec{u_2} = R \cdot \vec{u_1}$ \quad (old to new frame) \end{TeX} .RETURNS OK ---*/ double u1[3]; /* IN: Unit vector */ double u2[3]; /* OUT: Resulting unit vector after rotation */ double R[3][3]; /* IN: rotation matrix (e.g. created by tr_oR)*/ { register int i,j; register double val; double u_stack[3]; /* allows same address for input/output */ for (i=0; i<3; i++) { val = 0.e0; for (j=0; j<3; j++) val += R[i][j]*u1[j]; u_stack[i] = val; } for (i=0; i<3; i++) u2[i] = u_stack[i]; /* copies to output */ return(OK); } /*============================================================================*/ int tr_uu1 ( u1 , u2 , R) /*+++ .PURPOSE Rotates the unit vector u1 to u2, as \begin{TeX} \quad $\vec{u_2} = R^{-1} \cdot \vec{u_1}$ \quad (new to old frame). \end{TeX} .RETURNS OK ---*/ double u1[3]; /* IN: Unit vector */ double u2[3]; /* OUT: Resulting unit vector after rotation */ double R[3][3]; /* IN: rotation matrix (e.g. created by tr_oR) */ { register int i,j; register double val; double u_stack[3]; /* allows same address for input/output */ for (i=0; i<3; i++) { for (j=0, val = 0.0e0; j<3; j++) val += R[j][i]*u1[j]; u_stack[i] = val; } for (i=0; i<3; i++) u2[i] = u_stack[i]; /* copies to output */ return(OK); } /*============================================================================*/ int tr_RR ( A , B , R) /*+++ .PURPOSE Product of orthogonal matrices \begin{TeX} \quad $B = R \cdot A$ \quad \end{TeX} .RETURNS OK ---*/ double A[3][3]; /* IN: First Matrix */ double B[3][3]; /* OUT: Result Matrix */ double R[3][3]; /* IN: Rotation Matrix */ { register int i, j, k; double val; double Rs[3][3]; /* Local copy */ for (i=0; i<3; i++) for (j=0; j<3; j++) { for (k=0, val=0.0e0; k<3; k++) val += R[i][k]*A[k][j]; Rs[i][j] = val; } for (i=0; i<3; i++) for (j=0; j<3; j++) B[i][j] = Rs[i][j]; return(OK); } /*============================================================================*/ int tr_RR1 ( A , B , R) /*+++ .PURPOSE Product of orthogonal matrices \begin{TeX} \quad $B = R^{-1} \cdot A$ \quad \end{TeX} .RETURNS OK ---*/ double A[3][3]; /* IN: First Matrix */ double B[3][3]; /* OUT: Result Matrix */ double R[3][3]; /* IN: Rotation Matrix */ { register int i, j, k; double val; double Rs[3][3]; /* Local copy */ for (i=0; i<3; i++) for (j=0; j<3; j++) { for (k=0, val=0.0e0; k<3; k++) val += R[k][i]*A[k][j]; Rs[i][j] = val; } for (i=0; i<3; i++) for (j=0; j<3; j++) B[i][j] = Rs[i][j]; return(OK); } skycat-3.1.2-starlink-1b/astrotcl/generic/jprec.c000066400000000000000000000154761215713201500216700ustar00rootroot00000000000000/* static char sccsid[] = "@(#) ST-ECF as/src/jprec.c 4.1 12/6/91"; */ /*+++++++++++++++ .TYPE Module .IDENTIFICATION jprec.c .VERSION 1.0 27-Feb-1987: Creation . .VERSION 1.1 26-Oct-1988: Cosmetic modifications .Language C .AUTHOR Francois Ochsenbein [ESO-IPG] .KEYWORDS Precession of Coordinates in new IAU system. .ENV .COMMENTS \begin{TeX} This module uses the new (IAU 76) precession constants, and assumes the FK5 system. Precession constants are taken from Lederl\'e and Schwan (Astron. Astrophys. {\bf 134}, 1, 1984), Liske J.H. (Astron. Astrophys. {\bf 73}, 282, 1979), Dates must be expressed in {\em Julian Years}. The precession may be applied on unit vectors (mnemonic {\tt u}), or on equatorial coordinates (mnemonic {\tt q}). \end{TeX} -----------------------------------------------------------------------*/ #include "trigo.h" #include "ok.h" #define ze Euler_angles[0] #define theta Euler_angles[1] #define zeta Euler_angles[2] /*============================================================================*/ int prej_R (R, eq0, eq1 ) /*+++ .PURPOSE Compute the precession matrix, using the new IAU constants. (IAU 1976). The resulting matrix is such that \begin{TeX} \quad $\vec{u}(t_1) = R \cdot \vec{u}(t_0)$ \quad (old to new frame). \end{TeX} .RETURNS OK ---*/ double R[3][3]; /* OUT: rotation matrix */ double eq0; /* IN: Initial equinox (Julian Years) */ double eq1; /* IN: Final equinox (Julian Years) */ { double t0, dt, w; double Euler_angles[3]; t0 = (eq0 - 2000.e0)/100.e0; /* Origin is J2000 */ dt = (eq1 - eq0)/100.e0; w = 2306.2181e0+(1.39656e0-0.000139e0*t0)*t0; /* Arc seconds */ zeta = (w + ( (0.30188e0-0.000344e0*t0) + 0.017998e0*dt) *dt) *dt/3600.e0; /* Degrees */ ze = (w + ( (1.09468e0+0.000066e0*t0) + 0.018203e0*dt) *dt) *dt/3600.e0; /* Degrees */ theta = ( (2004.3109e0 + (-0.85330e0-0.000217e0*t0)*t0) +( (-0.42665e0-0.000217e0*t0) - 0.041833e0*dt) *dt) *dt/3600.e0; /* Computation of rotation matrix */ return(tr_Euler(Euler_angles, R)); } /*============================================================================*/ int prej_q (q0, q1, eq0, eq1) /*+++ .PURPOSE Performs a complete precession between 2 equinoxes. Use the new IAU constants. .METHOD Compute the precession rotation matrix if necessary, then apply the rotation. .RETURNS OK ---*/ double q0[2]; /* IN: ra+dec at equinox eq0 in degrees */ double q1[2]; /* OUT: precessed to equinox eq1 */ double eq0; /* IN: Initial equinox (Julian Years) */ double eq1; /* IN: Final equinox (Julian Years) */ { double us[3]; if (eq0 == eq1) /* No precession at all, same equinox!!! */ { q1[0] = q0[0]; q1[1] = q0[1]; return(OK); } tr_ou(q0, us); /* Convert to unit vector... */ prej_u(us, us, eq0, eq1); /* precess on unit vectors... */ return (tr_uo ( us, q1)); /* And finally -> coordinates */ } /*============================================================================*/ int prej_u (u0, u1, eq0, eq1) /*+++ .PURPOSE Performs a complete precession between 2 equinoxes. Use the new IAU constants. .METHOD Compute the precession rotation matrix if necessary, then apply the rotation. .RETURNS OK ---*/ double u0[3]; /* IN: Unit vector at equinox eq0 */ double u1[3]; /* OUT: precessed to equinox eq1 */ double eq0; /* IN: Initial equinox (Julian Years) */ double eq1; /* IN: Final equinox (Julian Years) */ { static double _eq0 = 2000.e0; static double _eq1 = 2000.e0; static double _r[3][3] = { {1.e0, 0.e0, 0.e0}, {0.e0, 1.e0, 0.e0}, {0.e0, 0.e0, 1.e0}}; if (eq0 == eq1) /* No precession at all, same equinox!!! */ { u1[0] = u0[0]; u1[1] = u0[1]; u1[2] = u0[2]; return(OK); } if ( (_eq0 != eq0) || (_eq1 != eq1) ) { _eq0 = eq0; _eq1 = eq1; prej_R(_r, eq0, eq1); /* Compute precession matrix */ } return (tr_uu ( u0, u1, _r)); /* And finally rotate... */ } #if 0 /*============================================================================*/ int prej_qv (q0, v0, q1, v1, eq0, ep0, eq1, ep1) /*+++ .PURPOSE Performs a complete precession between (equinox0, epoch 0) to (equinox 1, epoch 1). Use the new IAU constants. .METHOD Unit vectors .RETURNS OK ---*/ double q0[2]; /* IN: Position at equinox eq0, epoch ep0 */ double v0[3]; /* IN: Velocity vector */ double q1[2]; /* OUT: precessed to equinox + epoch ep1 */ double v1[3]; /* OUT: Velocity vector */ double eq0; /* IN: Initial equinox (Julian Years) */ double ep0; /* IN: Initial epoch (Julian Years) */ double eq1; /* IN: Final equinox (Julian Years) */ double ep1; /* IN: Final epoch + equinox (Julian Years) */ { static double us[3]; tr_ou(q0, us); /* Convert to unit vector... */ prej_uv(us, v0, us, v1, eq0, ep0, eq1, ep1); /* precess on unit vectors... */ return (tr_uo ( us, q1)); /* And finally -> coordinates */ } /*============================================================================*/ int prej_uv (u0, v0, u1, v1, eq0, ep0, eq1, ep1) /*+++ .PURPOSE Performs a complete precession between (equinox0, epoch 0) to (equinox 1, epoch 1). Use the new IAU constants. .METHOD Apply the velocity corrections, then precess to new equinox. .RETURNS OK ---*/ double u0[3]; /* IN: Unit vector at equinox eq0, epoch ep0 */ double v0[3]; /* IN: Velocity vector ("/yr) */ double u1[3]; /* OUT: precessed to equinox eq1 and epoch ep1 */ double v1[3]; /* OUT: Velocity vector ("/yr) */ double eq0; /* IN: Initial equinox (Julian Years) */ double ep0; /* IN: Initial epoch (Julian Years) */ double eq1; /* IN: Final equinox (Julian Years) */ double ep1; /* IN: Final epoch + equinox (Julian Years) */ { static double _eq0 = 2000.e0; static double _eq1 = 2000.e0; static double _Rf[3][3] = { {1.e0, 0.e0, 0.e0}, /* Precession */ {0.e0, 1.e0, 0.e0}, {0.e0, 0.e0, 1.e0}}; double u[3], du[3], f; register int i; /* Express velocities in eq0 Frame */ tr_vw (v0, du, u0); /* Apply Proper Motion in eq0 Frame */ f = (ep1 - ep0)/3600.e0/DEG; for (i=0; i<3; i++) u[i] = u0[i] + f * v0[i]; /* Renormalize */ f = sqrt(u[0]*u[0] + u[1]*u[1] * u[2]*u[2]); for (i=0; i<3; i++) u[i] /= f; /* Precess position and velocity from eq0 to eq1 */ if (eq0 != eq1) { if ((_eq0 != eq0) || (_eq1 != eq1)) _eq0 = eq0, _eq1 = eq1, prej_R(_Rf, _eq0, _eq1); tr_uu( u, u, _Rf); tr_uu(du, du, _Rf); } /* Output the new position */ for (i=0; i<3; i++) u1[i] = u[i]; /* Compute new velocity vector */ tr_wv(du, v1, u1); /* to Local Frame */ return(OK); } #endif skycat-3.1.2-starlink-1b/astrotcl/generic/ok.h000066400000000000000000000020301215713201500211610ustar00rootroot00000000000000/* static char sccsid[] = "@(#) ST-ECF tc/h/ok.h 4.1 12/6/91"; */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .TYPE Header .NAME ok.h .LANGUAGE C .AUTHOR Francois Ochsenbein [ESO], Alan Richmond [ST-ECF]. .CATEGORY Status definitions .COMMENTS .ENVIRONMENT .VERSION 1.0 05-Mar-1987: Extracted from stesodef.h .VERSION 1.1 28-Mar-1990: Added COMMENT_CHAR ---------------------------*/ #ifndef OK_DEF #define OK_DEF 0 #define COMMENT_CHAR '!' /* Character used allover */ #define OK 1 /* no error */ #define NOK 0 /* not OK */ #define TRUE 1 /* ST-ScI standard */ #define FALSE 0 /* ST-ScI standard */ #define SUCCESS 1 /* ST-ScI standard */ #define FAILURE 0 /* ST-ScI standard */ #define NOT_FOUND (-1) /* mismatch */ #define MODE_INTERACTIVE 1 /* interactive mode */ #define MODE_BATCH 2 /* batch mode */ #define MODE_NETWORK 3 /* network mode */ #define MODE_OTHER 0 /* unknown mode */ #define RECORD_MODE 0400 /* Special option for opening files */ #endif skycat-3.1.2-starlink-1b/astrotcl/generic/osdefos.h000066400000000000000000000072651215713201500222310ustar00rootroot00000000000000/* static char sccsid[] = "@(#) ST-ECF os/h/osdefos.h 4.1 10/16/92"; */ /* @(#)osdefos.h 1.1.1.1 (ESO-IPG) 7/11/91 20:25:38 */ /*+++++++++++++++++++++ .TYPE Header .LANGUAGE C .IDENTIFICATION osdefos.h .AUTHOR BP [ESO-IPG], Francois Ochsenbein .KEYWORDS operating system, parameters, fortran compilers .ENVIRONMENT VMS ULTRIX MSDOS SYSTEM_FIVE SYSV_V2 BSD .COMMENTS This modules defines the OS #def's, and an option SW_LEVEL set to zero for minimizing the size of the generated programs. This version includes #def's keywords OS_VMS OS_ULTRIX OS_MSDOS OS_SYSV OS_SYSV_V2 OS_BSD and the memory classes EXTERN, etc... .VERSION 1.0 10-Mar-1987 Also set defines for standard calls BP .VERSION 1.1 11-Apr-1990 EXTERN is defined as extern for UNIX. CG --------------------------------------------------------------------------*/ #ifndef OSDEFOS_DEF #define OSDEFOS_DEF 0 /*=========================================================================== * List of supported Operating Systems *===========================================================================*/ #define _VMS 1 #define _ULTRIX 2 #define _MSDOS 3 #define _BSD 4 #define _SYSV 5 #define _SYSV_V2 6 #define OS_VMS (OS_ENV == _VMS) #define OS_ULTRIX (OS_ENV == _ULTRIX) #define OS_MSDOS (OS_ENV == _MSDOS) #define OS_BSD (OS_ENV == _BSD) #define OS_SYSV (OS_ENV == _SYSV) #define OS_SYSV_V2 (OS_ENV == _SYSV_V2) /*=========================================================================== * Define Here Your Specific Implementation *===========================================================================*/ #if 0 /* Example of minimal implementation for MicroComputer running MSDOS */ #define SW_LEVEL 0 #define OS_ENV _MSDOS #endif /* End of Example */ #ifndef OS_ENV /*=========================================================================== * Definition of Default Operating System *===========================================================================*/ #ifdef VMS #define OS_ENV _VMS #endif #ifndef OS_ENV #ifdef vms #define OS_ENV _VMS #endif #endif #ifdef ULTRIX #define OS_ENV _ULTRIX #endif #ifdef MSDOS #define OS_ENV _MSDOS #endif #ifdef __MSDOS_ #define OS_ENV _MSDOS #endif #ifdef SYSV_V2 #define OS_ENV _SYSV_V2 #endif #ifdef SYSV #define OS_ENV _SYSV #endif #ifdef BSD #define OS_ENV _BSD #endif #endif /* If no OS variable defined, choose among ULTRIX / SYSV / BSD */ #ifndef OS_ENV # ifdef vax # define OS_ENV _ULTRIX # else # ifdef sun # define OS_ENV _BSD # else # define OS_ENV _SYSV # endif # endif #endif /*=========================================================================== * Definition of Memory Classes (related to OS) *===========================================================================*/ #ifndef SW_LEVEL #define SW_LEVEL 9 #endif #define Rstatic RSTATIC #ifdef vax11c #define REGISTER register #define STATIC static noshare /* standard */ #define RSTATIC static readonly /* Added 13-Feb-1986 */ #define GLOBALDEF globaldef /* standard */ #define GLOBALREF globalref /* standard */ #define GLOBALVALUE globalvalue /* standard */ #define EXTERN globalref /* Mod. 13-Feb-1986 */ #define REXTERN globalref /* Added 13-Feb-1986 */ #define GLOBAL globaldef noshare /* Added 13-Feb-1986 */ #define RGLOBAL globaldef readonly /* Added 13-Feb-1986 */ #else /* gcc */ #define REGISTER register #define STATIC static #define RSTATIC static #define GLOBALDEF #define GLOBALREF extern #define GLOBALVALUE #define EXTERN extern #define REXTERN extern #define GLOBAL #define RGLOBAL #endif #endif skycat-3.1.2-starlink-1b/astrotcl/generic/slasubs.c000066400000000000000000000215671215713201500222370ustar00rootroot00000000000000/* File slasubs.c *** Starlink subroutines by Patrick Wallace used by wcscon.c subroutines *** April 13, 1998 */ #include #include #include /* slaDcs2c (a, b, v): Spherical coordinates to direction cosines. * slaDcc2s (v, a, b): Direction cosines to spherical coordinates. * slaDmxv (dm, va, vb): vector vb = matrix dm * vector va * slaImxv (rm, va, vb): vector vb = (inverse of matrix rm) * vector va * slaDranrm (angle): Normalize angle into range 0-2 pi. * slaDrange (angle): Normalize angle into range +/- pi. * slaDeuler (order, phi, theta, psi, rmat) * Form a rotation matrix from the Euler angles - three successive * rotations about specified Cartesian axes. */ void slaDcs2c (a, b, v) double a; /* Right ascension in radians */ double b; /* Declination in radians */ double *v; /* x,y,z unit vector (returned) */ /* ** slaDcs2c: Spherical coordinates to direction cosines. ** ** The spherical coordinates are longitude (+ve anticlockwise ** looking from the +ve latitude pole) and latitude. The ** Cartesian coordinates are right handed, with the x axis ** at zero longitude and latitude, and the z axis at the ** +ve latitude pole. ** ** P.T.Wallace Starlink 31 October 1993 */ { double cosb; cosb = cos ( b ); v[0] = cos ( a ) * cosb; v[1] = sin ( a ) * cosb; v[2] = sin ( b ); } void slaDcc2s (v, a, b) double *v; /* x,y,z vector */ double *a; /* Right ascension in radians */ double *b; /* Declination in radians */ /* ** slaDcc2s: ** Direction cosines to spherical coordinates. ** ** Returned: ** *a,*b double spherical coordinates in radians ** ** The spherical coordinates are longitude (+ve anticlockwise ** looking from the +ve latitude pole) and latitude. The ** Cartesian coordinates are right handed, with the x axis ** at zero longitude and latitude, and the z axis at the ** +ve latitude pole. ** ** If v is null, zero a and b are returned. ** At either pole, zero a is returned. ** ** P.T.Wallace Starlink 31 October 1993 */ { double x, y, z, r; x = v[0]; y = v[1]; z = v[2]; r = sqrt ( x * x + y * y ); *a = ( r != 0.0 ) ? atan2 ( y, x ) : 0.0; *b = ( z != 0.0 ) ? atan2 ( z, r ) : 0.0; } void slaDmxv (dm, va, vb) double (*dm)[3]; /* 3x3 Matrix */ double *va; /* Vector */ double *vb; /* Result vector (returned) */ /* ** slaDmxv: ** Performs the 3-d forward unitary transformation: ** vector vb = matrix dm * vector va ** ** P.T.Wallace Starlink 31 October 1993 */ { int i, j; double w, vw[3]; /* Matrix dm * vector va -> vector vw */ for ( j = 0; j < 3; j++ ) { w = 0.0; for ( i = 0; i < 3; i++ ) { w += dm[j][i] * va[i]; } vw[j] = w; } /* Vector vw -> vector vb */ for ( j = 0; j < 3; j++ ) { vb[j] = vw[j]; } } void slaDimxv (dm, va, vb) double (*dm)[3]; double *va; double *vb; /* ** - - - - - - - - - ** s l a D i m x v ** - - - - - - - - - ** ** Performs the 3-d backward unitary transformation: ** ** vector vb = (inverse of matrix dm) * vector va ** ** (double precision) ** ** (n.b. The matrix must be unitary, as this routine assumes that ** the inverse and transpose are identical) ** ** ** Given: ** dm double[3][3] matrix ** va double[3] vector ** ** Returned: ** vb double[3] result vector ** ** P.T.Wallace Starlink 31 October 1993 */ { long i, j; double w, vw[3]; /* Inverse of matrix dm * vector va -> vector vw */ for ( j = 0; j < 3; j++ ) { w = 0.0; for ( i = 0; i < 3; i++ ) { w += dm[i][j] * va[i]; } vw[j] = w; } /* Vector vw -> vector vb */ for ( j = 0; j < 3; j++ ) { vb[j] = vw[j]; } } /* 2pi */ #define D2PI 6.2831853071795864769252867665590057683943387987502 /* pi */ #define DPI 3.1415926535897932384626433832795028841971693993751 double slaDranrm (angle) double angle; /* angle in radians */ /* ** slaDranrm: ** Normalize angle into range 0-2 pi. ** The result is angle expressed in the range 0-2 pi (double). ** Defined in slamac.h: D2PI ** ** P.T.Wallace Starlink 30 October 1993 */ { double w; w = fmod ( angle, D2PI ); return ( w >= 0.0 ) ? w : w + D2PI; } #ifndef dsign #define dsign(A,B) ((B)<0.0?-(A):(A)) #endif double slaDrange (angle) double angle; /* ** - - - - - - - - - - ** s l a D r a n g e ** - - - - - - - - - - ** ** Normalize angle into range +/- pi. ** ** (double precision) ** ** Given: ** angle double the angle in radians ** ** The result is angle expressed in the +/- pi (double precision). ** ** Defined in slamac.h: DPI, D2PI ** ** P.T.Wallace Starlink 31 October 1993 */ { double w; w = fmod ( angle, D2PI ); return ( fabs ( w ) < DPI ) ? w : w - dsign ( D2PI, angle ); } void slaDeuler (order, phi, theta, psi, rmat) char *order; /* specifies about which axes the rotations occur */ double phi; /* 1st rotation (radians) */ double theta; /* 2nd rotation (radians) */ double psi; /* 3rd rotation (radians) */ double (*rmat)[3]; /* 3x3 Rotation matrix (returned) */ /* ** slaDeuler: ** Form a rotation matrix from the Euler angles - three successive ** rotations about specified Cartesian axes. ** ** A rotation is positive when the reference frame rotates ** anticlockwise as seen looking towards the origin from the ** positive region of the specified axis. ** ** The characters of order define which axes the three successive ** rotations are about. A typical value is 'zxz', indicating that ** rmat is to become the direction cosine matrix corresponding to ** rotations of the reference frame through phi radians about the ** old z-axis, followed by theta radians about the resulting x-axis, ** then psi radians about the resulting z-axis. ** ** The axis names can be any of the following, in any order or ** combination: x, y, z, uppercase or lowercase, 1, 2, 3. Normal ** axis labelling/numbering conventions apply; the xyz (=123) ** triad is right-handed. Thus, the 'zxz' example given above ** could be written 'zxz' or '313' (or even 'zxz' or '3xz'). Order ** is terminated by length or by the first unrecognised character. ** ** Fewer than three rotations are acceptable, in which case the later ** angle arguments are ignored. Zero rotations produces a unit rmat. ** ** P.T.Wallace Starlink 17 November 1993 */ { int j, i, l, n, k; double result[3][3], rotn[3][3], angle, s, c , w, wm[3][3]; char axis; /* Initialize result matrix */ for ( j = 0; j < 3; j++ ) { for ( i = 0; i < 3; i++ ) { result[i][j] = ( i == j ) ? 1.0 : 0.0; } } /* Establish length of axis string */ l = strlen ( order ); /* Look at each character of axis string until finished */ for ( n = 0; n < 3; n++ ) { if ( n <= l ) { /* Initialize rotation matrix for the current rotation */ for ( j = 0; j < 3; j++ ) { for ( i = 0; i < 3; i++ ) { rotn[i][j] = ( i == j ) ? 1.0 : 0.0; } } /* Pick up the appropriate Euler angle and take sine & cosine */ switch ( n ) { case 0 : angle = phi; break; case 1 : angle = theta; break; case 2 : angle = psi; break; } s = sin ( angle ); c = cos ( angle ); /* Identify the axis */ axis = order[n]; if ( ( axis == 'X' ) || ( axis == 'x' ) || ( axis == '1' ) ) { /* Matrix for x-rotation */ rotn[1][1] = c; rotn[1][2] = s; rotn[2][1] = -s; rotn[2][2] = c; } else if ( ( axis == 'Y' ) || ( axis == 'y' ) || ( axis == '2' ) ) { /* Matrix for y-rotation */ rotn[0][0] = c; rotn[0][2] = -s; rotn[2][0] = s; rotn[2][2] = c; } else if ( ( axis == 'Z' ) || ( axis == 'z' ) || ( axis == '3' ) ) { /* Matrix for z-rotation */ rotn[0][0] = c; rotn[0][1] = s; rotn[1][0] = -s; rotn[1][1] = c; } else { /* Unrecognized character - fake end of string */ l = 0; } /* Apply the current rotation (matrix rotn x matrix result) */ for ( i = 0; i < 3; i++ ) { for ( j = 0; j < 3; j++ ) { w = 0.0; for ( k = 0; k < 3; k++ ) { w += rotn[i][k] * result[k][j]; } wm[i][j] = w; } } for ( j = 0; j < 3; j++ ) { for ( i= 0; i < 3; i++ ) { result[i][j] = wm[i][j]; } } } } /* Copy the result */ for ( j = 0; j < 3; j++ ) { for ( i = 0; i < 3; i++ ) { rmat[i][j] = result[i][j]; } } } /* * Nov 4 1996 New file * * Apr 13 1998 Add list of subroutines to start of file */ skycat-3.1.2-starlink-1b/astrotcl/generic/slasubs.h000066400000000000000000000012371215713201500222340ustar00rootroot00000000000000#ifndef _slasubs_h_ #define _slasubs_h_ /* * E.S.O. - VLT project / ESO Archive * * "@(#) $Id: slasubs.h,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $" * * slasubs.h - #defines to change names in slasubs.c to avoid name conflicts * with sla libraries. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 16 Mar 98 Created */ #define slaDcs2c SAO__slaDcs2c #define slaDmxv SAO__slaDmxv #define slaDimxv SAO__slaDimxv #define slaDcc2s SAO__slaDcc2s #define slaDranrm SAO__slaDranrm #define slaDrange SAO__slaDrange #define slaDeuler SAO__slaDeuler #endif /* _slasubs_h_ */ skycat-3.1.2-starlink-1b/astrotcl/generic/trigo.h000066400000000000000000000076701215713201500217130ustar00rootroot00000000000000/* static char sccsid[] = "@(#) ST-ECF tc/h/trigo.h 4.1 12/6/91"; */ /*+++++++++ .Header trigo.h .LANGUAGE C .AUTHOR Francois Ochsenbein [ESO-IPG] .KEYWORDS Trigonometric mathematical functions .COMMENTS This header contains declarations for mathematical functions and macros for spherical/hyperbolic transformations. .VERSION 1.0 21-Oct-1985: Creation .VERSION 1.1 05-Dec-1988: Transformed some macros to functions ----------------*/ #ifndef TRIGO_DEF #define TRIGO_DEF 0 #include /* Use system Math Library */ #include "compiler.h" /* If function templates are allowed */ /* constants */ #undef PI #define PI 3.14159265358979325e0 #define DEG (180.e0/PI) /* radians to degrees */ /* =57.295779513082320e0 */ /*========================================================================= 1. Trigonometric functions *=========================================================================*/ /* Standard: sin(x) cos(x) tan(x) sinh(x) cosh(x) tanh(x) */ /* Argument in degrees: */ #if _TEMPLATES_ double cosd (double x); double sind (double x); double tand (double x); double acosd(double x); double asind(double x); double atand(double x); double atan2d(double x, double y); #else double acosd(), asind(), atand(), atan2d(); double cosd(), sind(), tand(); #endif /*========================================================================= 2. Spherical functions *=========================================================================*/ #if _TEMPLATES_ int tr_ou (double o[2] , double u[3]); int tr_uo (double u[3] , double o[2]); int tr_uu (double u1[3], double u2[3], double R[3][3]); int tr_uu1 (double u1[3], double u2[3], double R[3][3]); int tr_Euler(double Euler_angles[3], double R[3][3] ); int prej_u (double u0[3], double u1[3], double eq0, double eq1 ); /* Surface of a `rectangle' on the sphere */ double surf_o (double o1[2], double o2[2]); /* Pos. in degrees */ double surf_p (double p1[2], double p2[2]); /* On gnomonic proj. */ /* Distances between two points on the sphere (degrees) */ double s2d_u (double u1[3], double u2[3]); double s2d_o (double o1[2], double o2[2]); double s2d_p (double p1[2], double p2[2]); double dist_u (double u1[3], double u2[3]); double dist_o (double o1[2], double o2[2]); double dist_p (double p1[2], double p2[2]); #else double surf_o(), surf_p(); double s2d_o(), s2d_p(), s2d_u(); double dist_o(), dist_p(), dist_u(); #endif /*========================================================================= 3. Other standard Math Functions *=========================================================================*/ /* Standard: log(x) log10(x) exp(x) sqrt(x) */ /* Standard: hypoth(x,y)= sqrt(x*x + y*y) */ /* Standard: pow(x,y) = x**y */ #if _TEMPLATES_ double sinc (double x); /* sin(x)/x */ double asinc(double x); /* asin(x)/x */ double acosh(double x); double asinh(double x); double atanh(double x); #else double sinc(), asinc(); double acosh(), asinh(), atanh(); #endif /*========================================================================= 4. Arithmetic operations *=========================================================================*/ /* Standard: ceil(x) floor(x) fabs(x) */ /* Standard: fmod(x,y) = x%y, with same sign as x */ /* trigo functions in degrees*/ /*========================================================================= 5. Mantissa / Exponent Conversions *=========================================================================*/ /* Standard: m = frexp (x, &e) Returns m and e such that x = m * 2**e with |m| in range [0.5, 1[ */ /* Standard: y = ldexp (m, e) Returns y = m * 2**e */ /* Standard: f = modf (x, &E) Returns f and E (double) with x = E + f f = fractional part with same sign as x */ #endif skycat-3.1.2-starlink-1b/astrotcl/generic/trigod.c000066400000000000000000000101051215713201500220350ustar00rootroot00000000000000/* static char sccsid[] = "@(#) ST-ECF tc/src/trigod.c 4.1 12/6/91"; */ /*+++ Trigonometric Function in degrees .TYPE Module .IDENTIFICATION trigod.c .LANGUAGE C .AUTHOR Francois Ochsenbein [ESO-IPG] .CATEGORY Trigonometric Functions .COMMENTS Arguments in degrees .VERSION 1.0 21-Oct-1985: Creation .VERSION 1.1 05-Dec-1988: Added inverse functions. ________________________________________*/ #ifndef __hpux__ #include "trigo.h" #include "osdefos.h" STATIC double int_part; #define DOUBLE_MAX 1.7e38 /* max floating value */ /*========================================================================= * cosd *=========================================================================*/ double cosd (x) /*+++ .DES Computation of cosine (argument in degrees) .RET cosine (double) .REM ---*/ double x; /* argument in degrees */ { double argument; char sign; argument = modf (fabs(x)/360.e0, &int_part); sign = 0; if (argument > .5e0) argument = 1.e0 - argument; if (argument > .25e0) argument = .5e0 - argument, sign = 1; if (argument > .125e0) argument = sin( (PI*2) * (.25e0 - argument)); else argument = cos( (PI*2) * argument); if (sign) argument = -argument; return (argument); } /*========================================================================= * sind *=========================================================================*/ double sind(x) /*+++ .DES Computes the sine (argument in degrees) .RET sine of argument (double) .REM No tracing ---*/ double x; /* argument in degrees */ { double argument; char sign; sign = (x >= 0.e0 ? 0 : 1); argument = modf (fabs(x)/360.e0, &int_part); if (argument > .5e0) argument = 1.e0 - argument, sign ^= 1; if (argument > .25e0) argument = .5e0 - argument; if (argument > .125e0) argument = cos( (PI*2) * (.25e0 - argument)); else argument = sin( (PI*2) * argument); if (sign) argument = -argument; return (argument); } /*========================================================================= * tand *=========================================================================*/ double tand(x) /*+++ .DES Computes the tangent (argument in degrees) .RET tangent of argument (double) .REM For +90 degrees, DOUBLE_MAX is returned; For -90 degrees, -DOUBLE_MAX is returned .REM No tracing ---*/ double x; /* argument in degrees */ { double argument; argument = modf (fabs(x)/180.e0, &int_part); if (argument == .5e0) argument = DOUBLE_MAX; else argument = tan (PI*argument); return (x>0.e0 ? argument: -argument); } /*========================================================================= * Inverse functions *=========================================================================*/ double atand(x) /*+++ .DES Computes the Arc tan in degrees .RET Arc tangent of argument (double), in range [-90, 90] ---*/ double x; /* argument in degrees */ { return(DEG*atan(x)); } /*=========================================================================*/ double atan2d(x, y) /*+++ .DES Cartesian to polar .RET Angle in range ]-180, 180] ---*/ double x; /* argument in degrees */ double y; /* argument in degrees */ { return(DEG*atan2(x, y)); } /*=========================================================================*/ double acosd(x) /*+++ .DES Computes the Arc cos in degrees .RET Arc cosine of argument (double), in range [0, 180] .REM Range of argument [-1, +1] ---*/ double x; /* argument in degrees */ { return(DEG*acos(x)); } /*=========================================================================*/ double asind(x) /*+++ .DES Computes the Arc sine in degrees .RET Arc tangent of argument (double) in range [-90, 90] .REM Range of argument [-1, +1] ---*/ double x; /* argument in degrees */ { return(DEG*asin(x)); } /*=========================================================================*/ #endif /* HP_UX */ skycat-3.1.2-starlink-1b/astrotcl/generic/world_coords.C000066400000000000000000000050321215713201500232100ustar00rootroot00000000000000/* * E.S.O. - VLT project/ESO Archive * $Id: world_coords.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ * * worldCoords.C - C interface implementation for C++ class WorldCoords * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 13 Oct 95 Created * 02/01/06 Renamed worldCoords.C to world_coords.C to * avoid name conflict on file systems that ignore case */ static const char* const rcsId="@(#) $Id: world_coords.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $"; // include the C++ and C interfaces #include "WorldCoords.h" extern "C" { #include "world_coords.h" } /* * copy the C++ WorldCords class object to the C WC struct * and return a pointer to the C WC struct. */ static WC* wcCopy(const WorldCoords& wcs, WC* wc) { if (!wc) return NULL; wc->ra.hours = wcs.ra().hours(); wc->ra.min = wcs.ra().min(); wc->ra.sec = wcs.ra().sec(); wc->ra.val = wcs.ra().val(); wc->dec.hours = wcs.dec().hours(); wc->dec.min = wcs.dec().min(); wc->dec.sec = wcs.dec().sec(); wc->dec.val = wcs.dec().val(); return wc; } /* * initialize null world coordinates * and return a pointer to the WC struct. */ extern "C" WC* wcInitNull(WC* wc) { return wcCopy(WorldCoords(), wc); } /* * return true if the given coords are null */ extern "C" int wcIsNull(WC* wc) { return (wc->ra.val == WCS_NULL || wc->dec.val == WCS_NULL); } /* * initialize from RA, DEC in H:M:S D:M:S format * and return a pointer to the WC struct. */ extern "C" WC* wcInitFromHMS(WC* wc, int rh, int rm, double rs, int dd, int dm, double ds, double equinox) { return wcCopy(WorldCoords(rh, rm, rs, dd, dm, ds, equinox), wc); } /* * initialize from RA, DEC in degrees in floating pt format * and return a pointer to the WC struct. */ extern "C" WC* wcInitFromDeg(WC* wc, double ra, double dec, double equinox) { return wcCopy(WorldCoords(ra, dec, equinox), wc); } /* * initialize world coords from RA and DEC in string format "H:M:S", "D:M:S" */ extern "C" WC* wcInitFromStrings(WC* wc, char* ra, char* dec, double equinox) { return wcCopy(WorldCoords(ra, dec, equinox), wc); } /* * print RA and DEC to the given buffers in the given equinox */ void wcPrint(WC* wc, char* ra_buf, char* dec_buf, double equinox) { if (wc) { WorldCoords tmp(wc->ra.val*15, wc->dec.val); tmp.print(ra_buf, dec_buf, equinox); } } skycat-3.1.2-starlink-1b/astrotcl/generic/world_coords.h000066400000000000000000000031361215713201500232600ustar00rootroot00000000000000#ifndef _worldCoords_h_ #define _worldCoords_h_ /* * E.S.O. - VLT project * $Id: world_coords.h,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ * * world_coords.h - C interface to C++ class WorldCoords * * (Note: C applications must have at least a dummy C++ main and link * with C++) * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * 02/01/06 Renamed worldCoords.h to world_coords.h to * avoid name conflict on file systems that ignore case */ /* struct representing H:M:S.sss (or D:M:S) value */ typedef struct { int hours; int min; double sec; double val; /* value calculated in degrees */ } WC_HMS; /* struct representing world coordinates */ typedef struct { WC_HMS ra, dec; } WC; /* initialize null world coordinates */ WC* wcInitNull(WC*); /* return true if the given coords are null */ int wcIsNull(WC* wc); /* initialize world coords from RA and DEC in string format "H:M:S", "D:M:S" */ WC* wcInitFromStrings(WC*, char* ra, char* dec, double equinox); /* initialize from RA, DEC in H:M:S D:M:S format */ WC* wcInitFromHMS(WC*, int rh, int rm, double rs, int dd, int dm, double ds, double equinox); /* initialize from RA, DEC in degrees in floating pt format */ WC* wcInitFromDeg(WC*, double ra, double dec, double equinox); /* print RA and DEC to the given buffers in the given equinox */ void wcPrint(WC* wc, char* ra_buf, char* dec_buf, double equinox); #endif /* _worldCoords_h_ */ skycat-3.1.2-starlink-1b/astrotcl/install.sh000077500000000000000000000042121215713201500207740ustar00rootroot00000000000000#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5; it is not part of GNU. # # $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" instcmd="$mvprog" chmodcmd="" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; *) if [ x"$src" = x ] then src=$1 else dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` fi # Make a temp file name in the proper directory. dstdir=`dirname $dst` dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp # and set any options; do chmod last to preserve setuid bits if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi # Now rename the file to the real destination. $doit $rmcmd $dst $doit $mvcmd $dsttmp $dst exit 0 skycat-3.1.2-starlink-1b/astrotcl/library/000077500000000000000000000000001215713201500204345ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/astrotcl/library/AstrotclInit.tcl000066400000000000000000000010531215713201500235560ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: # # AstrotclInit.tcl # # script which is executed by AstrotclImage.C to initialize tcl # # who when what # -------- --------- ---------------------------------------------- # pbiereic 24/08/99 created # abrighto 21/12/05 updated for new version # We depend on. package require Tclutil package require Tclx if {![lcontain $auto_path $astrotcl_library]} { lappend auto_path $astrotcl_library } namespace eval astrotcl {namespace export *} namespace import -force astrotcl::* skycat-3.1.2-starlink-1b/astrotcl/library/mkIndex.tcl000077500000000000000000000002271215713201500225430ustar00rootroot00000000000000#! /bin/sh # -*-tcl-*- # The next line is executed by /bin/sh, but not Tcl \ exec tclsh $0 ${1+"$@"} package require Itcl auto_mkindex . *.tcl exit 0 skycat-3.1.2-starlink-1b/astrotcl/libwcs/000077500000000000000000000000001215713201500202535ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/astrotcl/libwcs/Files000066400000000000000000000171711215713201500212470ustar00rootroot00000000000000WCSTools libwcs Subroutines actread.c Return stars from the USNO ACT Reference Catalog binread.c Return stars from catalog files in the TDC binary catalog format catread.c Return stars from catalog files in the TDC ASCII catalog format catutil.c Subroutines for catalog identification and number range decoding cel.c WCSLIB spherical coordinate transformation drivers daoread.c Read x, y, and magnitude from DAOFIND output file and return x, y, and flux for use by IMSTAR or IMWCS. dateutil.c Subroutines for conversions between various date and time formats distort.c Subroutines for conversions between image pixel and focal plane coordinates dsspos.c dsspos() uses the WCS structure to compute sky coordinates given image pixel X and Y for images with Digitized Sky Survey plate solutions in their headers. dsspix() uses the WCS structure to compute image pixel X and Y given sky coordinates for DSS images. Algorithms from StSCI CASB. fileutil.c Subroutines for finding size and contents of ASCII files findstar.c findStars() gets the location and brightest pixel of stars in the given image. Included are subroutines to find and reject bright pixels and compute a star centroid. fitsfile.c FITS header and image reading and writing subroutines, including FITS table support. fitswcs.c GetWCSFITS() returns a WCS structure used by wcs.c subroutines from a FITS or IRAF .imh image, reading only the header. GetFITShead() returns a FITS header from a FITS or IRAF .imh image. DelWCS() delete the WCS keywords in a FITS header. fortcat.c Fortran wrapper subroutines for catalog reading subroutines ctgread() and ctgrnum() fortwcs.c Fortran wrapper subroutines for all useful subroutines in wcs.c and wcsinit.c gscread.c Return HST Guide Stars from standard CDROM format FITS table files for a given RA, Dec, and magnitude range or list of star numbers. gsc2read.c Return GSC II Stars using an HTTP query over the web for a given RA, Dec, and magnitude range or list of star numbers. hget.c Subroutines to extract values from FITS headers by keyword. Subroutines for parsing RA and Dec strings are included. hput.c Subroutines to implant values into FITS headers by keyword (and to delete headers). iget.c Subroutines to extract values from IRAF multi-keyword header parameters imhfile.c IRAF header and image reading and writing subroutines. IRAF headers are converted to FITS headers for use by other programs and can be derived from FITS headers for writing. imio.c Subroutines to get, put, and move pixels of various data types between images im memory and a program. imrotate.c RotFITS() rotates an image by 90, 180, or 270 degrees, with an optional left-right reflection before the rotation. imgetwcs.c GetWCSFITS() reads world coordinate system header information and returns the image center coordinates and size as well as the wcs data structure. imsetwcs.c SetWCSFITS() uses findStars to find the stars in an image, gscread to find the Guide Stars in the nominal image region, and findRegisration or findCoords to fit plate-tangent WCS to the image. lin.c WCSLIB linear transformation subroutines matchstar.c StarMatch() takes a list of reference star positions and a list of object coordinates from an image and finds the image pixels which correspond to each of the reference stars. It then uses these matches to get an image center, plate scale, and rotation. The actual fit is based on the amoeba subroutine in Numerical Recipes, and all necessary subroutines are included. platepos.c platepos() uses the WCS structure to compute sky coordinates given image pixel X and Y for images with polynomial plate solutions in their headers. platepix() uses the WCS structure to compute image pixel X and Y given sky coordinates for such images. Algorithms are based on those in dsspos.c, but go straight from pixels to angles without an intermediate plate coordinate. proj.c WCSLIB spherical map projection subroutines sdssread.c Return Sloan Digital Sky Survey Photometry Catalog sources using an HTTP query over the web for a given RA, Dec, and magnitude range. sortstars.c Subroutines to sort lists of stars by right ascension, magnitude, or flux sph.c WCSLIB spherical coordinate transformation subroutines tabread.c Return stars from a tab table format catalog file for a given RA, Dec, and magnitude range or list of star numbers. Based on John Roll's Starbase format. tmcread.c Return 2MASS Point Source Catalog stars from the catalog as ungzipped from the DVD into (or linked from) a common root directory for a given RA, Dec, and magnitude range or list of star numbers. Both IDR2 and All-Sky release formats are supported. tnxpos.c tnxpos() uses the WCS keywords set up for IRAF's TNX projection to compute sky coordinates given image pixel X and Y. tnxpix() uses the WCS structure to compute image pixel X and Y given sky coordinates for such images. The projection is a tangent plane with corrections between the rotation and scaling and the actual projection. uacread.c Return USNO A and SA Catalog stars from their standard CDROM format files for a given RA, Dec, and magnitude range or list of star numbers. ubcread.c Return USNO B Catalog stars from their standard format files for a given RA, Dec, and magnitude range or list of star numbers. ucacread.c Return USNO UCAC1 or UCAC2 Catalog stars from their standard format files for a given RA, Dec, and magnitude range or list of star numbers. ujcread.c Return USNO UJ Catalog stars from its standard CDROM format files for a given RA, Dec, and magnitude range or list of star numbers. wcs.c Subroutines for using FITS or IRAF header spatial world coordinate system information. wcsinit.c Subroutines to initialize WCS structure from a FITS header wcscon.c Subroutines for converting between B1950, J2000, and galactic coordinates, mostly based on Starlink SLA_LIB subroutines. webread.c Open Starbase files across the Internet using HTTP queries worldpos.c worldpos() uses the WCS structure to compute sky coordinates given image pixel X and Y for images with header information for any of 8 standard world coordinate systems. worldpix() uses the WCS structure to compute image pixel X and Y given sky coordinates for the same images. Mostly from NRAO. fitshead.h Declarations of FITS header access subroutines fitsfile.h Declarations of image access subroutines and FITS table data structure. imio.h Declarations of subroutines to convert binary formats of numbers lwcs.h Constants used by star-finding and WCS-setting subroutines wcscat.h Declarations for star catalog data structures wcs.h Declaration of WCS data structure and useful conversions. wcslib.h Declarations for WCSLIB high level driver subroutines, trig and inverse trig functions, spherical map projection subroutines, spherical coordinate transformation drivers, and linear transformation subroutines * Notes: slasubs.c contains unmodified subroutines from Pat Wallace's Starlink astrometry library and may be omitted if that library is being linked. WCSLIB subroutines were written by Mark Calabretta of CSIRO and have been modified in several ways: 1) His distributed wcs.h has been changed to wcslib.h, and 2) wcstrig.c subroutine names have been changed from d() to deg() to avoid name conflicts on some operating systems. 3) ifndef's at start of headers files have been named to reflect the names of the header files, i.e. wcslib_h_ in wcslib.h. 4) All header files have been combined into wcslib.h skycat-3.1.2-starlink-1b/astrotcl/libwcs/NEWS000066400000000000000000000333761215713201500207660ustar00rootroot00000000000000WCSTools subroutine release history July 21, 2005 - Release 3.6.2 (Doug Mink, SAO wcs.c: Fix wcsrange() to return correct range around RA=0 Clean up accumulated unused and misdeclared variables using lint April 13, 2005 - Release 3.6.1 (Doug Mink, SAO) Remove all sla_lib subroutines and calls thereto from wcscon.c, replacing them with local code. March 17, 2005 - Release 3.6.0 (Doug Mink, SAO) In wcs.c, fix bug in wcsrotset() so angles > 360 are set to angle - 360, not 360 Use unbuffered read() in isfits() in fitsfile.c November 01, 2004 - Release 3.5.8 (Doug Mink, SAO) In wcs.c, keep wcs->rot between 0 and 360 degrees (360.0 -> 0.0) September 21, 2004 - Release 3.5.7 (Doug Mink,SAO) In pix2wcs(), if spherical coordinate output, keep 0 < long/RA < 360 Fix bug in wcsfull() when wrapping around RA=0:00 In hput.c, add fixnegzero() to avoid putting -0.000 in header September 3, 2004 - Release 3.5.6 (Doug Mink, SAO) Modify FITS file reading software to get image size from file size if SIMPLE is F, so FITS headers with WCS can be used on arbitrary files. In hget.c, fix bug so comment is not pushed onto the next line if character value string lengthens (off by one bug). July 13, 2004 - Release 3.5.5 (Doug Mink, SAO) Add headshrink to hput.c to optionally keep blank lines after keywords are deleted. Read D, d, E, and e as exponent delimiters in floating point values in hget.c May 6, 2004 - Release 3.5.4 (Doug Mink, SAO) Add fitswexhead() to fitsfile.c to overwrite FITS extension headers April 16, 2004 - Release 3.5.3 (Doug Mink, SAO) Use strncsrch() in hget.c to get differently-cased keywords. February 3, 2004 - Release 3.5.2 (Doug Mink, SAO) In worldpix() in worldpos.c, allow ra/long. to exceed 180 if reference pixel is more than 180 degrees from image (1,1). December 12, 2003 - Release 3.5.1 (Doug Mink, SAO) Change p[0,1,2] initializations to p[1,2,3] in wcsinit.c to match proj.c (This affects constants for AZP,SIN,COP,COE,COD,COO,SZP,CEA,CYP,AIR,BON) Add wcs->naxes back into wcs structure for backward compatibility; it should always be equal to wcs->naxis. Fix bug in numdec() to return 0 if no digits after decimal point Fix call to setwcserr() with format in it November 17, 2003 - Release 3.5.0 (Doug Mink, SAO) Rename mgets() to mgetstr() in iget.c, wcsinit.c and fitshead.h Add numdec() to hget.c to return number of decimal places in numeric string Change wcs->naxes to wcs->naxis to prepare for WCSLIB 3.* In iraf2fits() and irafrimage(), use image, not physical, dimensions. In iraf2fits(), set NAXISi to image dimensions, NPAXISi to physical dimensions. Fix bugs in wcsfull() in wcs.c Move all distortion-related code to distort.c; include unistd.h Include stdlib.h instead of malloc.h in lin.c and drop malloc.h from matchstar.c August 22, 2003 - Release 3.4.2 (Doug Mink, SAO) Add fitsrfull() subroutine to read FITS files with more than 2 dimensions Modify fitswimage() to write FITS files with more than 2 dimensions July 11, 2003 - Release 3.4.1 (Doug Mink, SAO) Use strncmp to check for both stdin and stdout in fitsfile.c May 30, 2003 - Release 3.4.0 (Doug Mink, SAO) Add partial support for ZPX projection Fix bug reading COE and other projections when PROJPn coefficients were accidently reinitialized May 8, 2003 - Release 3.3.4 (Doug Mink, SAO) Add two missing semicolons in C++ declarations in wcs.h Read prj.p[0] from PROJP0 for ZPN projections, instead of ignoring it April 3, 2003 - Release 3.3.2 (Doug Mink, SAO) Add distortion conversion for SIRTF images March 27, 2003 - Release 3.3.1 (Doug Mink, SAO) Add conversions to and from Heliocentric Julian Dates to dateutil.c Open FITS and IMH files "rb" instead of "r" for Linux compatibility Add isimlistd() to fileutil.c to check for list of images in a specified directory Fix default center pixel computation in GetFITSWCS(); it was off by half a pixel January 30, 2003 - Release 3.3.0 (Doug Mink, SAO) Fix bug in dateutil.c ts2gst() sidereal time conversion. January 3, 2003 - Release 3.2.1 (Doug Mink, SAO) Fix bug in wcsinit() which failed to read PVi_0, and now initialize PVi_j in only once place. December 6, 2002 - Release 3.2.0 (Doug Mink, SAO) Add ET/TDT/TT and sidereal time conversion to dateutil.c Fix subroutine calls for radvel and latpole and correctly compute pixel at center of image for default CRPIX in wcsinit.c Add fitsrsect() to fitsfile.c to read a section of an image August 30, 2002 - Release 3.1.3 (Doug Mink, SAO) Fix bug in imio.c getvec() dealing with scaled images Add case-insensitive string search subroutines strcsrch() and strncsrch() Accept stdin as file in isfile() Add Ephemeris time conversions to dateutil() July 8, 2002 - Release 3.1.2 (Doug Mink, SAO) Fix bug in date utilities which always rounded to integer seconds of UT Fix bugs in date utilities to handle BC (negative) dates to JD 0. June 26, 2002 - Release 3.1.1 (Doug Mink, SAO) Fix bugs which caused TNX projection to fail Fix two bugs in wcsinit() which caused setting RADECSYS when an EQUINOX keyword is present. Write FITS error messages to string accessible by fitserr() Put SAO-written software under Gnu Lesser Public License April 12, 2002 - Release 3.1.0 (Doug Mink, SAO) Implement WCSLIB 2.9 Support PV entry of constants and PCi_j rotation matrices in wcsinit.c Support inversion (WCS->pix) of multiple dependent WCSs Add hgetri4c(), hgetr8c(), and hgetsc() for multiple WCS handling Fix bug in TNX projection software which caused an infinite loop during coefficient parsing. February 13, 2002 - Release 3.0.7 (Doug Mink, SAO) Fix bug in ecliptic coordinate conversion in wcscon.c Allow "stdin" to include extension and/or WCS selection in fitsfile.c Add a global switch to turn off scaling in imio.c Add ifdef to lin.c so it will compile under Mac OS/X December 4, 2001 - Release 3.0.6 (Doug Mink, SAO) In movepix(), add char to char move Always include stdlib.h in lin.c September 25, 2001 - Release 3.0.5 (Doug Mink, SAO) Implement WCSLIB version 2.7 Fix Makefile to include header files appropriately Accept FITS dates as yyyy/mm/dd Fix bug in str2dec() which misinterpreting strings with leading spaces Fix bug in isnum() which caused bad answer if trailing spaces Add fileutil.c, which includes various file info utilities September 7, 2001 - Release 3.0.3 (Doug Mink, SAO) Disallow files with = in their name in isfits() and isiraf() Set coordinate system from CTYPE if not equatorial July 12, 2001 - Release 3.0 (Doug Mink, SAO) Read PROJPn projection constants in wcsinit() ------------------------ March 30, 2001 - Release 2.9.4 (Doug Mink, SAO) Fix possible header length problem in hget.c March 22, 2001 - Release 2.9.3 (Doug Mink, SAO) Fix minor bugs in wcs.h, wcs.c, and wcsinit.c, wcslib.c, fitsfile.c, and cel.c found by gcc on Linux and possible memory leak in wcs.c March 9, 2001 - Release 2.9.2 (Doug Mink, SAO) In fitsfile.c, change multiple WCS separator in FITS file names from : to % and fix bug which failed to read multi-extension files if END was not preceded by a blank line in the extension's header. February 28, 2001 - Release 2.9.1 (Doug Mink, SAO) Fix major bug in wcsinit() which always set CRPIX2 the same as CRPIX1 February 23, 2001 - Release 2.9.0 (Doug Mink, SAO) FITS reading subroutines are fixed to ignore WCS name or character specified as :name or :character at end of filename. wcsinit() has new APIs which specify either a WCSNAME, wcsinitn(), or a WCS character, wcsinitc(), to allow use of multiple WCS's in a single FITS header. The WCSDEPx keyword has been added to indicate dependence on another WCS, though this feature has not been thoroughly debugged. fitscimage() is fixed so it doesn't overwrite data when overwriting a file An off-by-one bug was fixed for some polynomial types in tnxpos(). The WCSLIB subroutines were brought up to release 2.6 with very minor changes ------------------------ December 29, 2000 - Release 2.8.6 (Doug Mink, SAO) Fix handling of embedded + or - in isnum() in hget.c Default to 2000 for EQUINOX and EPOCH and FK5 for RADECSYS, if keywords not present. In wcscon.c, fk425() and fk524() algorithms were updated to include parallax and rv, proper motion is added by wcscon*() after fk425() or fk524() from system epoch, and proper motion units in fk524p() and fk425p() were fixed. In wcsinit.c, a bug initializing CD matrix was fixed. In cel.c, include string.h for strcmp(). September 29, 2000 - Release 2.8.5 (Doug Mink, SAO) wcsinit will now use a CD matrix if ANY CD keywords are present in header In getvec() in imio.c, move scaling outside of loop and make it conditional. Read .pix files in same directory as .imh file, if not otherwise found. August 1, 2000 - Release 2.8.3 (Doug Mink, SAO) Improve handling of 1-D WCS data. Fix numerous warning-generating bugs. Fix bug in ep2jd()/jd2ep() so both start year at 1/1 0:00 June 13, 2000 - Release 2.8.2 (Doug Mink, SAO) If imh pixel file has no directory, *always* use same as header file June 9, 2000 - Release 2.8.1 (Doug Mink, SAO) Read keyword values in hget.c even if no equal sign is present. June 2, 2000 - Release 2.8.0 (Doug Mink, SAO) Only a few minor changes due to running lint on everything ------------------------ May 10, 2000 - Release 2.7.4 (Doug Mink, SAO) In wcstype(), default to WCS_LIN, not error (after Bill Joye) May 1, 2000 - Release 2.7.3 (Doug Mink, SAO) Bug in hadd() fixed so new line is not overwritten. Pixel files whcih are in subdirectories of files where IRAF .imh header files reside are now dealt with correctly. All dates in the old FITS format (dd/mm/yy) where the year ranges from 0 to 999 have 1900 added to them: 01/05/100 becomes 2000-05-01. March 27, 2000 - Release 2.7.2 (Doug Mink, SAO) In hputs(), do not add quotes if writing COMMENT or HISTORY In fits2iraf(), in imhfile.c, minimize length of path in pixel file name Fix code to deal with .imh file paths longer than 67 characters. In platepix(), use inverse CD matrix to get better initial x,y value Change the maximum header string length in the hget header reading subroutines from 57600 to 256000 Replace oldsys with wcsproj in the WCS data structure so that more options are available, such as forcing use of AIPS or WCSLIB projection subroutines Add setdatedec() to set the number of decimal places in FITS date strings returned by dateutil subroutines Fix precession code to deal correctly with equinoxes other than J2000 and B1950. Move all date operations to dateutil.c, including current time used in imhfile.c February 23, 2000 - Release 2.7.0 (Doug Mink, SAO) Upgrade WCSLIB subroutines to WCSLIB 2.5 from 2.4 Add MJD and Besselian and Julian epoch conversion to dateutil.c Use WCSLIB CAR, COE, NCP projections if oldsys is 1, else use worldpos() Set CD matrix when using DSS projection Change oldwcs in wcs.h from switch to multi-value flag wcsproj, default is same Fix minor bug in fitsfile.c fitscimage error returns. ------------------------ January 11, 2000 - Release 2.6.12 (Doug Mink, SAO) Fix bug in dateutil() to get fractional year to date conversion right December 20, 1999 - Release 2.6.11 (Doug Mink, SAO) Fix bug in hgetdate() to get ISO minutes and seconds right Upgrade dateutil() to do many date conversions December 10, 1999 - Release 2.6.10 (Doug Mink, SAO) Fix bug which caused strings starting with d and e followed by numbers to be declared numeric even though they're not really numbers Fix bug in dateutil.c ts2jd() which does not affect SAOimage Fix bugs dealing with NOAO TNX projection November 17, 1999 - Release 2.6.9 (Doug Mink, SAO) Fix bug which caused loss of NCP projection November 5, 1999 - Release 2.6.8 (Doug Mink, SAO) Change release number to match WCSTools Clean up code in all subroutines using lint Add DATE-MOD to FITS header in iraf2fits() Added dateutil.c file for conversions between date formats (used by iraf2fits()) Return error code from hput*() subroutines if header buffer length exceeded. ------------------------ May 5, 1999 - Release 1.26 (Doug Mink, SAO hget.c, iget.c Use POSIX-compliant limits.h instead of values.h April 7, 1999 - Release 1.26 (Doug Mink, SAO) wcs.c Fix bug in dealing with EPOCHless non-equatorial coordinates wcsinit.c Add optional filename to printed error messages April 5, 1999 - Release 1.26 (Doug Mink, SAO) hget.c Check all string lengths before copying; ignore ^M at 80th character February 22, 1999 - Release 1.26 (Doug Mink, SAO) wcs.c Fix bug dealing with SPA and NPA coordinates Use faaces 0-5, not 1-6 for quad cube projections wcsinit.c Fix computed rotation angle for DSS projection February 9, 1999 - Release 1.26 (Doug Mink, SAO) fitsfile.c: Allow BITPIX=0 dataless images wcsinit.c: Fix bug initializing DSS image rotation wcs.c: Free lin.imgpix and lin.piximg in wcsfree() hput.c: Fix bug to avoid writing HISTORY or COMMENT lines past 80 chars ------------------------ December 8, 1998 - Release 1.25 (Doug Mink, SAO) fitsfile.c: Fix bug in fitsrhead() reading FITS table files caused by fix below November 30, 1998 - Release 1.25 (Doug Mink, SAO) fitsfile.c: Fix bug dealing with very large headers in fitsrhead() November 12, 1998 - Release 1.25 (Doug Mink, SAO) dsspos.c: Fix possible divide by zero problems fitsfile.c: Add isfits() which checks filename or first line of header imhfile.c: Add isiraf() which checks filename for .imh hget.c: Assume 2-digit year in hyphen-separated date means FITS, not ISO tnxpos.c: Fix multiple bugs wcscon.c: Add wcscstr() to get coordinate system as a character string wcscon.c: Add subroutine wcsconp() to convert coordinates + proper motions wcs.c: Add North and South Polar Angle coordinate systems wcs.c: Build WCS command initialization by getenv() into wcs*init() wcs.c: Fix bug in wcssize(); fix bug with rotated mirrored images wcslib.h: Add cel.h, lin.h, proj.h, and wcstrig.h to wcslib.h worldpos.c: Fix bug in inverse (sky to pixel) COE projection cel.c, lin.c, proj.c, sph.c, wcstrig.c: Include only wcslib.h skycat-3.1.2-starlink-1b/astrotcl/libwcs/Readme000066400000000000000000000013441215713201500213750ustar00rootroot00000000000000WCSTools libwcs.a These subroutines support the programs in the WCSTools package and include catalog search engines, image manipulation software, and fitting software. There use is documented on the World Wide Web at http://tdc-www.harvard.edu/software/wcstools/ Information about the individual files is in the Subroutines file. A self-contained subset of these programs which deal with image world coordinate systems is separately available and is used by the SAOimage, SAOtng, Skycat, and DS9 image display programs: cel.c dsspos.c fitshead.h fitsfile.c fitsfile.h hget.c hput.c iget.c imhfile.c imio.c lin.c platepos.c proj.c slasubs.c sph.c tnxpos.c wcs.c wcs.h wcscon.c wcslib.c wcslib.h wcstrig.c worldpos.c dateutil.c skycat-3.1.2-starlink-1b/astrotcl/libwcs/VERSION000066400000000000000000000000171215713201500213210ustar00rootroot00000000000000wcstools-4.3.0 skycat-3.1.2-starlink-1b/astrotcl/libwcs/cel.c000066400000000000000000000357271215713201500212000ustar00rootroot00000000000000/*============================================================================= * * WCSLIB - an implementation of the FITS WCS proposal. * Copyright (C) 1995-2002, Mark Calabretta * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Correspondence concerning WCSLIB may be directed to: * Internet email: mcalabre@atnf.csiro.au * Postal address: Dr. Mark Calabretta, * Australia Telescope National Facility, * P.O. Box 76, * Epping, NSW, 2121, * AUSTRALIA * *============================================================================= * * C routines which implement the FITS World Coordinate System (WCS) * convention. * * Summary of routines * ------------------- * These routines are provided as drivers for the lower level spherical * coordinate transformation and projection routines. There are separate * driver routines for the forward, celfwd(), and reverse, celrev(), * transformations. * * An initialization routine, celset(), computes intermediate values from * the transformation parameters but need not be called explicitly - see the * explanation of cel.flag below. * * * Initialization routine; celset() * -------------------------------- * Initializes members of a celprm data structure which hold intermediate * values. Note that this routine need not be called directly; it will be * invoked by celfwd() and celrev() if the "flag" structure member is * anything other than a predefined magic value. * * Given: * pcode[4] const char * WCS projection code (see below). * * Given and returned: * cel celprm* Spherical coordinate transformation parameters * (see below). * prj prjprm* Projection parameters (usage is described in the * prologue to "proj.c"). * * Function return value: * int Error status * 0: Success. * 1: Invalid coordinate transformation parameters. * 2: Ill-conditioned coordinate transformation * parameters. * * Forward transformation; celfwd() * -------------------------------- * Compute (x,y) coordinates in the plane of projection from celestial * coordinates (lng,lat). * * Given: * pcode[4] const char * WCS projection code (see below). * lng,lat const double * Celestial longitude and latitude of the projected * point, in degrees. * * Given and returned: * cel celprm* Spherical coordinate transformation parameters * (see below). * * Returned: * phi, double* Longitude and latitude in the native coordinate * theta system of the projection, in degrees. * * Given and returned: * prj prjprm* Projection parameters (usage is described in the * prologue to "proj.c"). * * Returned: * x,y double* Projected coordinates, "degrees". * * Function return value: * int Error status * 0: Success. * 1: Invalid coordinate transformation parameters. * 2: Invalid projection parameters. * 3: Invalid value of (lng,lat). * * Reverse transformation; celrev() * -------------------------------- * Compute the celestial coordinates (lng,lat) of the point with projected * coordinates (x,y). * * Given: * pcode[4] const char * WCS projection code (see below). * x,y const double * Projected coordinates, "degrees". * * Given and returned: * prj prjprm* Projection parameters (usage is described in the * prologue to "proj.c"). * * Returned: * phi, double* Longitude and latitude in the native coordinate * theta system of the projection, in degrees. * * Given and returned: * cel celprm* Spherical coordinate transformation parameters * (see below). * * Returned: * lng,lat double* Celestial longitude and latitude of the projected * point, in degrees. * * Function return value: * int Error status * 0: Success. * 1: Invalid coordinate transformation parameters. * 2: Invalid projection parameters. * 3: Invalid value of (x,y). * * Coordinate transformation parameters * ------------------------------------ * The celprm struct consists of the following: * * int flag * The celprm struct contains pointers to the forward and reverse * projection routines as well as intermediaries computed from the * reference coordinates (see below). Whenever the projection code * (pcode) or any of ref[4] are set or changed then this flag must be * set to zero to signal the initialization routine, celset(), to * redetermine the function pointers and recompute intermediaries. * Once this has been done pcode itself is ignored. * * double ref[4] * The first pair of values should be set to the celestial longitude * and latitude (usually right ascension and declination) of the * reference point of the projection. These are given by the CRVALn * keywords in FITS. * * The second pair of values are the native longitude of the celestial * pole and the celestial latitude of the native pole and correspond to * FITS keywords LONPOLE and LATPOLE. * * LONPOLE defaults to 0 degrees if the celestial latitude of the * reference point of the projection is greater than the native * latitude, otherwise 180 degrees. (This is the condition for the * celestial latitude to increase in the same direction as the native * latitude at the reference point.) ref[2] may be set to 999.0 to * indicate that the correct default should be substituted. * * In some circumstances the celestial latitude of the native pole may * be determined by the first three values only to within a sign and * LATPOLE is used to choose between the two solutions. LATPOLE is * set in ref[3] and the solution closest to this value is used to * reset ref[3]. It is therefore legitimate, for example, to set * ref[3] to 999.0 to choose the more northerly solution - the default * if the LATPOLE card is omitted from the FITS header. For the * special case where the reference point of the projection is at * native latitude zero, its celestial latitude is zero, and * LONPOLE = +/- 90 then the celestial latitude of the pole is not * determined by the first three reference values and LATPOLE * specifies it completely. * * The remaining members of the celprm struct are maintained by the * initialization routines and should not be modified. This is done for the * sake of efficiency and to allow an arbitrary number of contexts to be * maintained simultaneously. * * double euler[5] * Euler angles and associated intermediaries derived from the * coordinate reference values. * * * WCS projection codes * -------------------- * Zenithals/azimuthals: * AZP: zenithal/azimuthal perspective * TAN: gnomonic * STG: stereographic * SIN: synthesis (generalized orthographic) * ARC: zenithal/azimuthal equidistant * ZPN: zenithal/azimuthal polynomial * ZEA: zenithal/azimuthal equal area * AIR: Airy * * Cylindricals: * CYP: cylindrical perspective * CEA: cylindrical equal area * CAR: Cartesian * MER: Mercator * * Pseudo-cylindricals: * SFL: Sanson-Flamsteed * PAR: parabolic * MOL: Mollweide * * Conventional: * AIT: Hammer-Aitoff * * Conics: * COP: conic perspective * COD: conic equidistant * COE: conic equal area * COO: conic orthomorphic * * Polyconics: * BON: Bonne * PCO: polyconic * * Quad-cubes: * TSC: tangential spherical cube * CSC: COBE quadrilateralized spherical cube * QSC: quadrilateralized spherical cube * * Author: Mark Calabretta, Australia Telescope National Facility * $Id: cel.c,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ *===========================================================================*/ #include #include #include "wcslib.h" /* Map error number to error message for each function. */ const char *celset_errmsg[] = { 0, "Invalid coordinate transformation parameters", "Ill-conditioned coordinate transformation parameters"}; const char *celfwd_errmsg[] = { 0, "Invalid coordinate transformation parameters", "Invalid projection parameters", "Invalid value of (lng,lat)"}; const char *celrev_errmsg[] = { 0, "Invalid coordinate transformation parameters", "Invalid projection parameters", "Invalid value of (x,y)"}; int celset(pcode, cel, prj) const char pcode[4]; struct celprm *cel; struct prjprm *prj; { int dophip; const double tol = 1.0e-10; double clat0, cphip, cthe0, slat0, sphip, sthe0; double latp, latp1, latp2; double u, v, x, y, z; /* Initialize the projection driver routines. */ if (prjset(pcode, prj)) { return 1; } /* Set default for native longitude of the celestial pole? */ dophip = (cel->ref[2] == 999.0); /* Compute celestial coordinates of the native pole. */ if (prj->theta0 == 90.0) { /* Reference point is at the native pole. */ if (dophip) { /* Set default for longitude of the celestial pole. */ cel->ref[2] = 180.0; } latp = cel->ref[1]; cel->ref[3] = latp; cel->euler[0] = cel->ref[0]; cel->euler[1] = 90.0 - latp; } else { /* Reference point away from the native pole. */ /* Set default for longitude of the celestial pole. */ if (dophip) { cel->ref[2] = (cel->ref[1] < prj->theta0) ? 180.0 : 0.0; } clat0 = cosdeg (cel->ref[1]); slat0 = sindeg (cel->ref[1]); cphip = cosdeg (cel->ref[2]); sphip = sindeg (cel->ref[2]); cthe0 = cosdeg (prj->theta0); sthe0 = sindeg (prj->theta0); x = cthe0*cphip; y = sthe0; z = sqrt(x*x + y*y); if (z == 0.0) { if (slat0 != 0.0) { return 1; } /* latp determined by LATPOLE in this case. */ latp = cel->ref[3]; } else { if (fabs(slat0/z) > 1.0) { return 1; } u = atan2deg (y,x); v = acosdeg (slat0/z); latp1 = u + v; if (latp1 > 180.0) { latp1 -= 360.0; } else if (latp1 < -180.0) { latp1 += 360.0; } latp2 = u - v; if (latp2 > 180.0) { latp2 -= 360.0; } else if (latp2 < -180.0) { latp2 += 360.0; } if (fabs(cel->ref[3]-latp1) < fabs(cel->ref[3]-latp2)) { if (fabs(latp1) < 90.0+tol) { latp = latp1; } else { latp = latp2; } } else { if (fabs(latp2) < 90.0+tol) { latp = latp2; } else { latp = latp1; } } cel->ref[3] = latp; } cel->euler[1] = 90.0 - latp; z = cosdeg (latp)*clat0; if (fabs(z) < tol) { if (fabs(clat0) < tol) { /* Celestial pole at the reference point. */ cel->euler[0] = cel->ref[0]; cel->euler[1] = 90.0 - prj->theta0; } else if (latp > 0.0) { /* Celestial pole at the native north pole.*/ cel->euler[0] = cel->ref[0] + cel->ref[2] - 180.0; cel->euler[1] = 0.0; } else if (latp < 0.0) { /* Celestial pole at the native south pole. */ cel->euler[0] = cel->ref[0] - cel->ref[2]; cel->euler[1] = 180.0; } } else { x = (sthe0 - sindeg (latp)*slat0)/z; y = sphip*cthe0/clat0; if (x == 0.0 && y == 0.0) { return 1; } cel->euler[0] = cel->ref[0] - atan2deg (y,x); } /* Make euler[0] the same sign as ref[0]. */ if (cel->ref[0] >= 0.0) { if (cel->euler[0] < 0.0) cel->euler[0] += 360.0; } else { if (cel->euler[0] > 0.0) cel->euler[0] -= 360.0; } } cel->euler[2] = cel->ref[2]; cel->euler[3] = cosdeg (cel->euler[1]); cel->euler[4] = sindeg (cel->euler[1]); cel->flag = CELSET; /* Check for ill-conditioned parameters. */ if (fabs(latp) > 90.0+tol) { return 2; } return 0; } /*--------------------------------------------------------------------------*/ int celfwd(pcode, lng, lat, cel, phi, theta, prj, x, y) const char pcode[4]; const double lng, lat; struct celprm *cel; double *phi, *theta; struct prjprm *prj; double *x, *y; { int err; if (cel->flag != CELSET) { if (celset(pcode, cel, prj)) return 1; } /* Compute native coordinates. */ sphfwd(lng, lat, cel->euler, phi, theta); /* Apply forward projection. */ if ((err = prj->prjfwd(*phi, *theta, prj, x, y))) { return err == 1 ? 2 : 3; } return 0; } /*--------------------------------------------------------------------------*/ int celrev(pcode, x, y, prj, phi, theta, cel, lng, lat) const char pcode[4]; const double x, y; struct prjprm *prj; double *phi, *theta; struct celprm *cel; double *lng, *lat; { int err; if (cel->flag != CELSET) { if(celset(pcode, cel, prj)) return 1; } /* Apply reverse projection. */ if ((err = prj->prjrev(x, y, prj, phi, theta))) { return err == 1 ? 2 : 3; } /* Compute native coordinates. */ sphrev(*phi, *theta, cel->euler, lng, lat); return 0; } /* Dec 20 1999 Doug Mink - Change cosd() and sind() to cosdeg() and sindeg() * Dec 20 1999 Doug Mink - Include wcslib.h, which includes wcsmath.h and cel.h * * Dec 18 2000 Doug Mink - Include string.h for strcmp() * * Mar 20 2001 Doug Mink - Add () around err assignments in if statements * Sep 19 2001 Doug Mink - Add above changes to WCSLIB-2.7 cel.c * * Mar 12 2002 Doug Mink - Add changes to WCSLIB-2.8.2 cel.c */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/cel.h000066400000000000000000000024521215713201500211720ustar00rootroot00000000000000#ifndef cel_h_ #define cel_h_ #include "proj.h" #ifdef __cplusplus extern "C" { #endif extern int npcode; extern char pcodes[25][4]; struct celprm { int flag; double ref[4]; double euler[5]; #if __STDC__ || defined(__cplusplus) int (*prjfwd)(const double, const double, struct prjprm *, double *, double *); int (*prjrev)(const double, const double, struct prjprm *, double *, double *); #else int (*prjfwd)(); int (*prjrev)(); #endif }; #if __STDC__ || defined(__cplusplus) int celset(const char *, struct celprm *, struct prjprm *); int celfwd(const char *, const double, const double, struct celprm *, double *, double *, struct prjprm *, double *, double *); int celrev(const char *, const double, const double, struct prjprm *, double *, double *, struct celprm *, double *, double *); #else int celset(), celfwd(), celrev(); #endif extern const char *celset_errmsg[]; extern const char *celfwd_errmsg[]; extern const char *celrev_errmsg[]; #define CELSET 137 #ifdef __cplusplus } #endif #endif /* cel_h_ */ /* May 27 1998 ifndef CEL changed to ifndef cel_h_ */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/dateutil.c000066400000000000000000003231701215713201500222400ustar00rootroot00000000000000/*** File libwcs/dateutil.c *** January 8, 2007 *** By Doug Mink, dmink@cfa.harvard.edu *** Harvard-Smithsonian Center for Astrophysics *** Copyright (C) 1999-2007 *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Correspondence concerning WCSTools should be addressed as follows: Internet email: dmink@cfa.harvard.edu Postal address: Doug Mink Smithsonian Astrophysical Observatory 60 Garden St. Cambridge, MA 02138 USA */ /* Date and time conversion routines using the following conventions: doy = 2 floating point numbers: year and day, including fraction, of year *** First day of year is 1, not zero. dt = 2 floating point numbers: yyyy.mmdd, hh.mmssssss ep = fractional year, often epoch of a position including proper motion epb = Besselian epoch = 365.242198781-day years based on 1900.0 epj = Julian epoch = 365.25-day years based on 2000.0 fd = FITS date string which may be any of the following: yyyy.ffff (fractional year) dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard FITS use before 2000) yyyy-mm-dd (FITS standard after 1999) yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) jd = Julian Date lt = Local time mjd = modified Julian Date = JD - 2400000.5 ofd = FITS date string (dd/mm/yy before 2000, else no return) time = use fd2* with no date to convert time as hh:mm:ss.ss to sec, day, year ts = UT seconds since 1950-01-01T00:00 (used for ephemeris computations) tsi = local seconds since 1980-01-01T00:00 (used by IRAF as a time tag) tsu = UT seconds since 1970-01-01T00:00 (used as Unix system time) tsd = UT seconds of current day ut = Universal Time (UTC) et = Ephemeris Time (or TDB or TT) mst = Mean Greenwich Sidereal Time gst = Greenwich Sidereal Time (includes nutation) lst = Local Sidereal Time (includes nutation) (longitude must be set) hjd = Heliocentric Julian Date mhjd = modified Heliocentric Julian Date = HJD - 2400000.5 * doy2dt (year, doy, date, time) * Convert year and day of year to date as yyyy.ddmm and time as hh.mmsss * doy2ep, doy2epb, doy2epj (date, time) * Convert year and day of year to fractional year * doy2fd (year, doy) * Convert year and day of year to FITS date string * doy2mjd (year, doy) * Convert year and day of year to modified Julian date * * dt2doy (date, time, year, doy) * Convert date as yyyy.ddmm and time as hh.mmsss to year and day of year * dt2ep, dt2epb, dt2epj (date, time) * Convert date as yyyy.ddmm and time as hh.mmsss to fractional year * dt2fd (date, time) * Convert date as yyyy.ddmm and time as hh.mmsss to FITS date string * dt2i (date,time,iyr,imon,iday,ihr,imn,sec, ndsec) * Convert yyyy.mmdd hh.mmssss to year month day hours minutes seconds * dt2jd (date,time) * Convert date as yyyy.ddmm and time as hh.mmsss to Julian date * dt2mjd (date,time) * Convert date as yyyy.ddmm and time as hh.mmsss to modified Julian date * dt2ts (date,time) * Convert date (yyyy.ddmm) and time (hh.mmsss) to seconds since 1950-01-01 * dt2tsi (date,time) * Convert date (yyyy.ddmm) and time (hh.mmsss) to seconds since 1980-01-01 * dt2tsu (date,time) * Convert date (yyyy.ddmm) and time (hh.mmsss) to seconds since 1970-01-01 * * ep2dt, epb2dt, epj2dt (epoch,date, time) * Convert fractional year to date as yyyy.ddmm and time as hh.mmsss * ep2fd, epb2fd, epj2fd (epoch) * Convert epoch to FITS ISO date string * ep2i, epb2i, epj2i (epoch,iyr,imon,iday,ihr,imn,sec, ndsec) * Convert fractional year to year month day hours minutes seconds * ep2jd, epb2jd, epj2jd (epoch) * Convert fractional year as used in epoch to Julian date * ep2mjd, epb2mjd, epj2mjd (epoch) * Convert fractional year as used in epoch to modified Julian date * ep2ts, epb2ts, epj2ts (epoch) * Convert fractional year to seconds since 1950.0 * * et2fd (string) * Convert from ET (or TDT or TT) in FITS format to UT in FITS format * fd2et (string) * Convert from UT in FITS format to ET (or TDT or TT) in FITS format * jd2jed (dj) * Convert from Julian Date to Julian Ephemeris Date * jed2jd (dj) * Convert from Julian Ephemeris Date to Julian Date * dt2et (date, time) * Convert date (yyyy.ddmm) and time (hh.mmsss) to ephemeris time * edt2dt (date, time) * Convert ephemeris date (yyyy.ddmm) and time (hh.mmsss) to UT * ts2ets (tsec) * Convert from UT in seconds since 1950-01-01 to ET in same format * ets2ts (tsec) * Convert from ET in seconds since 1950-01-01 to UT in same format * * fd2ep, fd2epb, fd2epj (string) * Convert FITS date string to fractional year * Convert time alone to fraction of Besselian year * fd2doy (string, year, doy) * Convert FITS standard date string to year and day of year * fd2dt (string, date, time) * Convert FITS date string to date as yyyy.ddmm and time as hh.mmsss * Convert time alone to hh.mmssss with date set to 0.0 * fd2i (string,iyr,imon,iday,ihr,imn,sec, ndsec) * Convert FITS standard date string to year month day hours min sec * Convert time alone to hours min sec, year month day are zero * fd2jd (string) * Convert FITS standard date string to Julian date * Convert time alone to fraction of day * fd2mjd (string) * Convert FITS standard date string to modified Julian date * fd2ts (string) * Convert FITS standard date string to seconds since 1950.0 * Convert time alone to seconds of day * fd2fd (string) * Convert FITS standard date string to ISO FITS date string * fd2of (string) * Convert FITS standard date string to old-format FITS date and time * fd2ofd (string) * Convert FITS standard date string to old-format FITS date string * fd2oft (string) * Convert time part of FITS standard date string to FITS date string * * jd2doy (dj, year, doy) * Convert Julian date to year and day of year * jd2dt (dj,date,time) * Convert Julian date to date as yyyy.mmdd and time as hh.mmssss * jd2ep, jd2epb, jd2epj (dj) * Convert Julian date to fractional year as used in epoch * jd2fd (dj) * Convert Julian date to FITS ISO date string * jd2i (dj,iyr,imon,iday,ihr,imn,sec, ndsec) * Convert Julian date to year month day hours min sec * jd2mjd (dj) * Convert Julian date to modified Julian date * jd2ts (dj) * Convert Julian day to seconds since 1950.0 * * lt2dt() * Return local time as yyyy.mmdd and time as hh.mmssss * lt2fd() * Return local time as FITS ISO date string * lt2tsi() * Return local time as IRAF seconds since 1980-01-01 00:00 * lt2tsu() * Return local time as Unix seconds since 1970-01-01 00:00 * lt2ts() * Return local time as Unix seconds since 1950-01-01 00:00 * * mjd2doy (dj,year,doy) * Convert modified Julian date to date as year and day of year * mjd2dt (dj,date,time) * Convert modified Julian date to date as yyyy.mmdd and time as hh.mmssss * mjd2ep, mjd2epb, mjd2epj (dj) * Convert modified Julian date to fractional year as used in epoch * mjd2fd (dj) * Convert modified Julian date to FITS ISO date string * mjd2i (dj,iyr,imon,iday,ihr,imn,sec, ndsec) * Convert modified Julian date to year month day hours min sec * mjd2jd (dj) * Convert modified Julian date to Julian date * mjd2ts (dj) * Convert modified Julian day to seconds since 1950.0 * * ts2dt (tsec,date,time) * Convert seconds since 1950.0 to date as yyyy.ddmm and time as hh.mmsss * ts2ep, ts2epb, ts2epj (tsec) * Convert seconds since 1950.0 to fractional year * ts2fd (tsec) * Convert seconds since 1950.0 to FITS standard date string * ts2i (tsec,iyr,imon,iday,ihr,imn,sec, ndsec) * Convert sec since 1950.0 to year month day hours minutes seconds * ts2jd (tsec) * Convert seconds since 1950.0 to Julian date * ts2mjd (tsec) * Convert seconds since 1950.0 to modified Julian date * tsi2fd (tsec) * Convert seconds since 1980-01-01 to FITS standard date string * tsi2dt (tsec,date,time) * Convert seconds since 1980-01-01 to date as yyyy.ddmm, time as hh.mmsss * tsu2fd (tsec) * Convert seconds since 1970-01-01 to FITS standard date string * tsu2tsi (tsec) * Convert UT seconds since 1970-01-01 to local seconds since 1980-01-01 * tsu2dt (tsec,date,time) * Convert seconds since 1970-01-01 to date as yyyy.ddmm, time as hh.mmsss * * tsd2fd (tsec) * Convert seconds since start of day to FITS time, hh:mm:ss.ss * tsd2dt (tsec) * Convert seconds since start of day to hh.mmssss * * fd2gst (string) * convert from FITS date Greenwich Sidereal Time * dt2gst (date, time) * convert from UT as yyyy.mmdd hh.mmssss to Greenwich Sidereal Time * ts2gst (tsec) * Calculate Greenwich Sidereal Time given Universal Time * in seconds since 1951-01-01T0:00:00 * fd2mst (string) * convert from FITS UT date to Mean Sidereal Time * dt2gmt (date, time) * convert from UT as yyyy.mmdd hh.mmssss to Mean Sidereal Time * ts2mst (tsec) * Calculate Mean Sidereal Time given Universal Time * in seconds since 1951-01-01T0:00:00 * jd2mst (string) * convert from Julian Date to Mean Sidereal Time * mst2fd (string) * convert to current UT in FITS format given Greenwich Mean Sidereal Time * mst2jd (dj) * convert to current UT as Julian Date given Greenwich Mean Sidereal Time * jd2lst (dj) * Calculate Local Sidereal Time from Julian Date * ts2lst (tsec) * Calculate Local Sidereal Time given UT in seconds since 1951-01-01T0:00 * fd2lst (string) * Calculate Local Sidereal Time given Universal Time as FITS ISO date * lst2jd (dj, lst) * Calculate Julian Date given current Julian date and Local Sidereal Time * lst2fd (string, lst) * Calculate Julian Date given current UT date and Local Sidereal Time * gst2fd (string) * Calculate current UT given UT date and Greenwich Sidereal Time * gst2jd (dj) * Calculate current UT given UT date and Greenwich Sidereal Time as JD * * compnut (dj, dpsi, deps, eps0) * Compute the longitude and obliquity components of nutation and * mean obliquity from the IAU 1980 theory * * utdt (dj) * Compute difference between UT and dynamical time (ET-UT) * ut2dt (year, doy) * Current Universal Time to year and day of year * ut2dt (date, time) * Current Universal Time to date (yyyy.mmdd) and time (hh.mmsss) * ut2ep(), ut2epb(), ut2epj() * Current Universal Time to fractional year, Besselian, Julian epoch * ut2fd() * Current Universal Time to FITS ISO date string * ut2jd() * Current Universal Time to Julian Date * ut2mjd() * Current Universal Time to Modified Julian Date * ut2tsi() * Current Universal Time to IRAF seconds since 1980-01-01T00:00 * ut2tsu() * Current Universal Time to Unix seconds since 1970-01-01T00:00 * ut2ts() * Current Universal Time to seconds since 1950-01-01T00:00 * isdate (string) * Return 1 if string is a FITS date (old or ISO) * * Internally-used subroutines * * fixdate (iyr, imon, iday, ihr, imn, sec, ndsec) * Round seconds and make sure date and time numbers are within limits * caldays (year, month) * Calculate days in month 1-12 given year (Gregorian calendar only * dint (dnum) * Return integer part of floating point number * dmod (dnum) * Return Mod of floating point number */ #include #include #include #include #include #include #include "wcs.h" #include "fitsfile.h" static double suntl(); static void fixdate(); static int caldays(); static double dint(); static double dmod(); static double longitude = 0.0; /* longitude of observatory in degrees (+=west) */ void setlongitude (longitude0) double longitude0; { longitude = longitude0; return; } static int ndec = 3; void setdatedec (nd) int nd; { ndec = nd; return; } /* DT2FD-- convert vigesimal date and time to FITS date, yyyy-mm-ddThh:mm:ss.ss */ char * dt2fd (date, time) double date; /* Date as yyyy.mmdd yyyy = calendar year (e.g. 1973) mm = calendar month (e.g. 04 = april) dd = calendar day (e.g. 15) */ double time; /* Time as hh.mmssxxxx *if time<0, it is time as -(fraction of a day) hh = hour of day (0 .le. hh .le. 23) nn = minutes (0 .le. nn .le. 59) ss = seconds (0 .le. ss .le. 59) xxxx = tenths of milliseconds (0 .le. xxxx .le. 9999) */ { int iyr,imon,iday,ihr,imn; double sec; int nf; char *string; char tstring[32], dstring[32]; char outform[64]; dt2i (date, time, &iyr,&imon,&iday,&ihr,&imn,&sec, ndec); /* Convert to ISO date format */ string = (char *) calloc (32, sizeof (char)); /* Make time string */ if (time != 0.0 || ndec > 0) { if (ndec == 0) nf = 2; else nf = 3 + ndec; if (ndec > 0) { sprintf (outform, "%%02d:%%02d:%%0%d.%df", nf, ndec); sprintf (tstring, outform, ihr, imn, sec); } else { sprintf (outform, "%%02d:%%02d:%%0%dd", nf); sprintf (tstring, outform, ihr, imn, (int)(sec+0.5)); } } /* Make date string */ if (date != 0.0) sprintf (dstring, "%4d-%02d-%02d", iyr, imon, iday); /* Make FITS (ISO) date string */ if (date == 0.0) strcpy (string, tstring); else if (time == 0.0 && ndec < 1) strcpy (string, dstring); else sprintf (string, "%sT%s", dstring, tstring); return (string); } /* DT2JD-- convert from date as yyyy.mmdd and time as hh.mmsss to Julian Date * Return fractional days if date is zero */ double dt2jd (date,time) double date; /* Date as yyyy.mmdd yyyy = calendar year (e.g. 1973) mm = calendar month (e.g. 04 = april) dd = calendar day (e.g. 15) */ double time; /* Time as hh.mmssxxxx *if time<0, it is time as -(fraction of a day) hh = hour of day (0 .le. hh .le. 23) nn = minutes (0 .le. nn .le. 59) ss = seconds (0 .le. ss .le. 59) xxxx = tenths of milliseconds (0 .le. xxxx .le. 9999) */ { double dj; /* Julian date (returned) */ double tsec; /* seconds since 1950.0 */ tsec = dt2ts (date, time); if (date == 0.0) dj = tsec / 86400.0; else dj = ts2jd (tsec); return (dj); } /* DT2MJD-- convert from date yyyy.mmdd time hh.mmsss to modified Julian Date * Return fractional days if date is zero */ double dt2mjd (date,time) double date; /* Date as yyyy.mmdd yyyy = calendar year (e.g. 1973) mm = calendar month (e.g. 04 = april) dd = calendar day (e.g. 15) */ double time; /* Time as hh.mmssxxxx *if time<0, it is time as -(fraction of a day) hh = hour of day (0 .le. hh .le. 23) nn = minutes (0 .le. nn .le. 59) ss = seconds (0 .le. ss .le. 59) xxxx = tenths of milliseconds (0 .le. xxxx .le. 9999) */ { double dj; /* Modified Julian date (returned) */ double tsec; /* seconds since 1950.0 */ tsec = dt2ts (date, time); if (date == 0.0) dj = tsec / 86400.0; else dj = ts2jd (tsec); return (dj - 2400000.5); } /* HJD2JD-- convert Heliocentric Julian Date to (geocentric) Julian date */ double hjd2jd (dj, ra, dec, sys) double dj; /* Heliocentric Julian date */ double ra; /* Right ascension (degrees) */ double dec; /* Declination (degrees) */ int sys; /* J2000, B1950, GALACTIC, ECLIPTIC */ { double lt; /* Light travel difference to the Sun (days) */ lt = suntl (dj, ra, dec, sys); /* Return Heliocentric Julian Date */ return (dj - lt); } /* JD2HJD-- convert (geocentric) Julian date to Heliocentric Julian Date */ double jd2hjd (dj, ra, dec, sys) double dj; /* Julian date (geocentric) */ double ra; /* Right ascension (degrees) */ double dec; /* Declination (degrees) */ int sys; /* J2000, B1950, GALACTIC, ECLIPTIC */ { double lt; /* Light travel difference to the Sun (days) */ lt = suntl (dj, ra, dec, sys); /* Return Heliocentric Julian Date */ return (dj + lt); } /* MHJD2MJD-- convert modified Heliocentric Julian Date to modified geocentric Julian date */ double mhjd2mjd (mhjd, ra, dec, sys) double mhjd; /* Modified Heliocentric Julian date */ double ra; /* Right ascension (degrees) */ double dec; /* Declination (degrees) */ int sys; /* J2000, B1950, GALACTIC, ECLIPTIC */ { double lt; /* Light travel difference to the Sun (days) */ double hjd; /* Heliocentric Julian date */ hjd = mjd2jd (mhjd); lt = suntl (hjd, ra, dec, sys); /* Return Heliocentric Julian Date */ return (jd2mjd (hjd - lt)); } /* MJD2MHJD-- convert modified geocentric Julian date tp modified Heliocentric Julian Date */ double mjd2mhjd (mjd, ra, dec, sys) double mjd; /* Julian date (geocentric) */ double ra; /* Right ascension (degrees) */ double dec; /* Declination (degrees) */ int sys; /* J2000, B1950, GALACTIC, ECLIPTIC */ { double lt; /* Light travel difference to the Sun (days) */ double dj; /* Julian date (geocentric) */ dj = mjd2jd (mjd); lt = suntl (dj, ra, dec, sys); /* Return Heliocentric Julian Date */ return (jd2mjd (dj + lt)); } /* SUNTL-- compute light travel time to heliocentric correction in days */ /* Translated into C from IRAF SPP noao.astutils.asttools.asthjd.x */ static double suntl (dj, ra, dec, sys) double dj; /* Julian date (geocentric) */ double ra; /* Right ascension (degrees) */ double dec; /* Declination (degrees) */ int sys; /* J2000, B1950, GALACTIC, ECLIPTIC */ { double t; /* Number of Julian centuries since J1900 */ double manom; /* Mean anomaly of the Earth's orbit (degrees) */ double lperi; /* Mean longitude of perihelion (degrees) */ double oblq; /* Mean obliquity of the ecliptic (degrees) */ double eccen; /* Eccentricity of the Earth's orbit (dimensionless) */ double eccen2, eccen3; double tanom; /* True anomaly (approximate formula) (radians) */ double slong; /* True longitude of the Sun from the Earth (radians) */ double rs; /* Distance to the sun (AU) */ double lt; /* Light travel difference to the Sun (days) */ double l; /* Longitude of star in orbital plane of Earth (radians) */ double b; /* Latitude of star in orbital plane of Earth (radians) */ double epoch; /* Epoch of obervation */ double rs1,rs2; t = (dj - 2415020.0) / 36525.0; /* Compute earth orbital parameters */ manom = 358.47583 + (t * (35999.04975 - t * (0.000150 + t * 0.000003))); lperi = 101.22083 + (t * (1.7191733 + t * (0.000453 + t * 0.000003))); oblq = 23.452294 - (t * (0.0130125 + t * (0.00000164 - t * 0.000000503))); eccen = 0.01675104 - (t * (0.00004180 + t * 0.000000126)); eccen2 = eccen * eccen; eccen3 = eccen * eccen2; /* Convert to principle angles */ manom = manom - (360.0 * (dint) (manom / 360.0)); lperi = lperi - (360.0 * (dint) (lperi / 360.0)); /* Convert to radians */ manom = degrad (manom); lperi = degrad (lperi); oblq = degrad (oblq); /* True anomaly */ tanom = manom + (2 * eccen - 0.25 * eccen3) * sin (manom) + 1.25 * eccen2 * sin (2 * manom) + 13./12. * eccen3 * sin (3 * manom); /* Distance to the Sun */ rs1 = 1.0 - eccen2; rs2 = 1.0 + (eccen * cos (tanom)); rs = rs1 / rs2; /* True longitude of the Sun seen from the Earth */ slong = lperi + tanom + PI; /* Longitude and latitude of star in orbital plane of the Earth */ epoch = jd2ep (dj); wcscon (sys, WCS_ECLIPTIC, 0.0, 0.0, &ra, &dec, epoch); l = degrad (ra); b = degrad (dec); /* Light travel difference to the Sun */ lt = -0.005770 * rs * cos (b) * cos (l - slong); /* Return light travel difference */ return (lt); } /* JD2DT-- convert Julian date to date as yyyy.mmdd and time as hh.mmssss */ void jd2dt (dj,date,time) double dj; /* Julian date */ double *date; /* Date as yyyy.mmdd (returned) */ double *time; /* Time as hh.mmssxxxx (returned) */ { int iyr,imon,iday,ihr,imn; double sec; /* Convert Julian Date to date and time */ jd2i (dj, &iyr, &imon, &iday, &ihr, &imn, &sec, 4); /* Convert date to yyyy.mmdd */ if (iyr < 0) { *date = (double) (-iyr) + 0.01 * (double) imon + 0.0001 * (double) iday; *date = -(*date); } else *date = (double) iyr + 0.01 * (double) imon + 0.0001 * (double) iday; /* Convert time to hh.mmssssss */ *time = (double) ihr + 0.01 * (double) imn + 0.0001 * sec; return; } /* JD2I-- convert Julian date to date as year, month, and day, and time hours, minutes, and seconds */ /* after Fliegel and Van Flander, CACM 11, 657 (1968) */ void jd2i (dj, iyr, imon, iday, ihr, imn, sec, ndsec) double dj; /* Julian date */ int *iyr; /* year (returned) */ int *imon; /* month (returned) */ int *iday; /* day (returned) */ int *ihr; /* hours (returned) */ int *imn; /* minutes (returned) */ double *sec; /* seconds (returned) */ int ndsec; /* Number of decimal places in seconds (0=int) */ { double tsec; double frac, dts, ts, sday; int jd, l, n, i, j; tsec = jd2ts (dj); /* ts2i (tsec, iyr, imon, iday, ihr, imn, sec, ndsec); */ /* Round seconds to 0 - 4 decimal places */ if (tsec < 0.0) dts = -0.5; else dts = 0.5; if (ndsec < 1) ts = dint (tsec + dts); else if (ndsec < 2) ts = dint (tsec * 10.0 + dts) / 10.0; else if (ndsec < 3) ts = dint (tsec * 100.0 + dts) / 100.0; else if (ndsec < 4) ts = dint (tsec * 1000.0 + dts) / 1000.0; else ts = dint (tsec * 10000.0 + dts) / 10000.0; /* Convert back to Julian Date */ dj = ts2jd (ts); /* Compute time from fraction of a day */ frac = dmod (dj, 1.0); if (frac < 0.5) { jd = (int) (dj - frac); sday = (frac + 0.5) * 86400.0; } else { jd = (int) (dj - frac) + 1; sday = (frac - 0.5) * 86400.0; } *ihr = (int) (sday / 3600.0); sday = sday - (double) (*ihr * 3600); *imn = (int) (sday / 60.0); *sec = sday - (double) (*imn * 60); /* Compute day, month, year */ l = jd + 68569; n = (4 * l) / 146097; l = l - (146097 * n + 3) / 4; i = (4000 * (l + 1)) / 1461001; l = l - (1461 * i) / 4 + 31; j = (80 * l) / 2447; *iday = l - (2447 * j) / 80; l = j / 11; *imon = j + 2 - (12 * l); *iyr = 100 * (n - 49) + i + l; return; } /* JD2MJD-- convert Julian Date to Modified Julian Date */ double jd2mjd (dj) double dj; /* Julian Date */ { return (dj - 2400000.5); } /* JD2EP-- convert Julian date to fractional year as used in epoch */ double jd2ep (dj) double dj; /* Julian date */ { double date, time; jd2dt (dj, &date, &time); return (dt2ep (date, time)); } /* JD2EPB-- convert Julian date to Besselian epoch */ double jd2epb (dj) double dj; /* Julian date */ { return (1900.0 + (dj - 2415020.31352) / 365.242198781); } /* JD2EPJ-- convert Julian date to Julian epoch */ double jd2epj (dj) double dj; /* Julian date */ { return (2000.0 + (dj - 2451545.0) / 365.25); } /* LT2DT-- Return local time as yyyy.mmdd and time as hh.mmssss */ void lt2dt(date, time) double *date; /* Date as yyyy.mmdd (returned) */ double *time; /* Time as hh.mmssxxxx (returned) */ { time_t tsec; struct timeval tp; struct timezone tzp; struct tm *ts; gettimeofday (&tp,&tzp); tsec = tp.tv_sec; ts = localtime (&tsec); if (ts->tm_year < 1000) *date = (double) (ts->tm_year + 1900); else *date = (double) ts->tm_year; *date = *date + (0.01 * (double) (ts->tm_mon + 1)); *date = *date + (0.0001 * (double) ts->tm_mday); *time = (double) ts->tm_hour; *time = *time + (0.01 * (double) ts->tm_min); *time = *time + (0.0001 * (double) ts->tm_sec); return; } /* LT2FD-- Return current local time as FITS ISO date string */ char * lt2fd() { time_t tsec; struct tm *ts; struct timeval tp; struct timezone tzp; int month, day, year, hour, minute, second; char *isotime; gettimeofday (&tp,&tzp); tsec = tp.tv_sec; ts = localtime (&tsec); year = ts->tm_year; if (year < 1000) year = year + 1900; month = ts->tm_mon + 1; day = ts->tm_mday; hour = ts->tm_hour; minute = ts->tm_min; second = ts->tm_sec; isotime = (char *) calloc (32, sizeof (char)); sprintf (isotime, "%04d-%02d-%02dT%02d:%02d:%02d", year, month, day, hour, minute, second); return (isotime); } /* LT2TSI-- Return local time as IRAF seconds since 1980-01-01 00:00 */ int lt2tsi() { return ((int)(lt2ts() - 946684800.0)); } /* LT2TSU-- Return local time as Unix seconds since 1970-01-01 00:00 */ time_t lt2tsu() { return ((time_t)(lt2ts() - 631152000.0)); } /* LT2TS-- Return local time as Unix seconds since 1950-01-01 00:00 */ double lt2ts() { double tsec; char *datestring; datestring = lt2fd(); tsec = fd2ts (datestring); free (datestring); return (tsec); } /* MJD2DT-- convert Modified Julian Date to date (yyyy.mmdd) time (hh.mmssss) */ void mjd2dt (dj,date,time) double dj; /* Modified Julian Date */ double *date; /* Date as yyyy.mmdd (returned) yyyy = calendar year (e.g. 1973) mm = calendar month (e.g. 04 = april) dd = calendar day (e.g. 15) */ double *time; /* Time as hh.mmssxxxx (returned) *if time<0, it is time as -(fraction of a day) hh = hour of day (0 .le. hh .le. 23) nn = minutes (0 .le. nn .le. 59) ss = seconds (0 .le. ss .le. 59) xxxx = tenths of milliseconds (0 .le. xxxx .le. 9999) */ { double tsec; tsec = jd2ts (dj + 2400000.5); ts2dt (tsec, date, time); return; } /* MJD2I-- convert Modified Julian Date to date as year, month, day and time as hours, minutes, seconds */ void mjd2i (dj, iyr, imon, iday, ihr, imn, sec, ndsec) double dj; /* Modified Julian Date */ int *iyr; /* year (returned) */ int *imon; /* month (returned) */ int *iday; /* day (returned) */ int *ihr; /* hours (returned) */ int *imn; /* minutes (returned) */ double *sec; /* seconds (returned) */ int ndsec; /* Number of decimal places in seconds (0=int) */ { double tsec; tsec = jd2ts (dj + 2400000.5); ts2i (tsec, iyr, imon, iday, ihr, imn, sec, ndsec); return; } /* MJD2DOY-- convert Modified Julian Date to Year,Day-of-Year */ void mjd2doy (dj, year, doy) double dj; /* Modified Julian Date */ int *year; /* Year (returned) */ double *doy; /* Day of year with fraction (returned) */ { jd2doy (dj + 2400000.5, year, doy); return; } /* MJD2JD-- convert Modified Julian Date to Julian Date */ double mjd2jd (dj) double dj; /* Modified Julian Date */ { return (dj + 2400000.5); } /* MJD2EP-- convert Modified Julian Date to fractional year */ double mjd2ep (dj) double dj; /* Modified Julian Date */ { double date, time; jd2dt (dj + 2400000.5, &date, &time); return (dt2ep (date, time)); } /* MJD2EPB-- convert Modified Julian Date to Besselian epoch */ double mjd2epb (dj) double dj; /* Modified Julian Date */ { return (1900.0 + (dj - 15019.81352) / 365.242198781); } /* MJD2EPJ-- convert Modified Julian Date to Julian epoch */ double mjd2epj (dj) double dj; /* Modified Julian Date */ { return (2000.0 + (dj - 51544.5) / 365.25); } /* MJD2FD-- convert modified Julian date to FITS date, yyyy-mm-ddThh:mm:ss.ss */ char * mjd2fd (dj) double dj; /* Modified Julian date */ { return (jd2fd (dj + 2400000.5)); } /* MJD2TS-- convert modified Julian date to seconds since 1950.0 */ double mjd2ts (dj) double dj; /* Modified Julian date */ { return ((dj - 33282.0) * 86400.0); } /* EP2FD-- convert fractional year to FITS date, yyyy-mm-ddThh:mm:ss.ss */ char * ep2fd (epoch) double epoch; /* Date as fractional year */ { double tsec; /* seconds since 1950.0 (returned) */ tsec = ep2ts (epoch); return (ts2fd (tsec)); } /* EPB2FD-- convert Besselian epoch to FITS date, yyyy-mm-ddThh:mm:ss.ss */ char * epb2fd (epoch) double epoch; /* Besselian epoch (fractional 365.242198781-day years) */ { double dj; /* Julian Date */ dj = epb2jd (epoch); return (jd2fd (dj)); } /* EPJ2FD-- convert Julian epoch to FITS date, yyyy-mm-ddThh:mm:ss.ss */ char * epj2fd (epoch) double epoch; /* Julian epoch (fractional 365.25-day years) */ { double dj; /* Julian Date */ dj = epj2jd (epoch); return (jd2fd (dj)); } /* EP2TS-- convert fractional year to seconds since 1950.0 */ double ep2ts (epoch) double epoch; /* Date as fractional year */ { double dj; dj = ep2jd (epoch); return ((dj - 2433282.5) * 86400.0); } /* EPB2TS-- convert Besselian epoch to seconds since 1950.0 */ double epb2ts (epoch) double epoch; /* Besselian epoch (fractional 365.242198781-day years) */ { double dj; dj = epb2jd (epoch); return ((dj - 2433282.5) * 86400.0); } /* EPJ2TS-- convert Julian epoch to seconds since 1950.0 */ double epj2ts (epoch) double epoch; /* Julian epoch (fractional 365.25-day years) */ { double dj; dj = epj2jd (epoch); return ((dj - 2433282.5) * 86400.0); } /* EPB2EP-- convert Besselian epoch to fractional years */ double epb2ep (epoch) double epoch; /* Besselian epoch (fractional 365.242198781-day years) */ { double dj; dj = epb2jd (epoch); return (jd2ep (dj)); } /* EP2EPB-- convert fractional year to Besselian epoch */ double ep2epb (epoch) double epoch; /* Fractional year */ { double dj; dj = ep2jd (epoch); return (jd2epb (dj)); } /* EPJ2EP-- convert Julian epoch to fractional year */ double epj2ep (epoch) double epoch; /* Julian epoch (fractional 365.25-day years) */ { double dj; dj = epj2jd (epoch); return (jd2ep (dj)); } /* EP2EPJ-- convert fractional year to Julian epoch */ double ep2epj (epoch) double epoch; /* Fractional year */ { double dj; dj = ep2jd (epoch); return (jd2epj (dj)); } /* EP2I-- convert fractional year to year month day hours min sec */ void ep2i (epoch, iyr, imon, iday, ihr, imn, sec, ndsec) double epoch; /* Date as fractional year */ int *iyr; /* year (returned) */ int *imon; /* month (returned) */ int *iday; /* day (returned) */ int *ihr; /* hours (returned) */ int *imn; /* minutes (returned) */ double *sec; /* seconds (returned) */ int ndsec; /* Number of decimal places in seconds (0=int) */ { double date, time; ep2dt (epoch, &date, &time); dt2i (date, time, iyr,imon,iday,ihr,imn,sec, ndsec); return; } /* EPB2I-- convert Besselian epoch to year month day hours min sec */ void epb2i (epoch, iyr, imon, iday, ihr, imn, sec, ndsec) double epoch; /* Besselian epoch (fractional 365.242198781-day years) */ int *iyr; /* year (returned) */ int *imon; /* month (returned) */ int *iday; /* day (returned) */ int *ihr; /* hours (returned) */ int *imn; /* minutes (returned) */ double *sec; /* seconds (returned) */ int ndsec; /* Number of decimal places in seconds (0=int) */ { double date, time; epb2dt (epoch, &date, &time); dt2i (date, time, iyr,imon,iday,ihr,imn,sec, ndsec); return; } /* EPJ2I-- convert Julian epoch to year month day hours min sec */ void epj2i (epoch, iyr, imon, iday, ihr, imn, sec, ndsec) double epoch; /* Julian epoch (fractional 365.25-day years) */ int *iyr; /* year (returned) */ int *imon; /* month (returned) */ int *iday; /* day (returned) */ int *ihr; /* hours (returned) */ int *imn; /* minutes (returned) */ double *sec; /* seconds (returned) */ int ndsec; /* Number of decimal places in seconds (0=int) */ { double date, time; epj2dt (epoch, &date, &time); dt2i (date, time, iyr,imon,iday,ihr,imn,sec, ndsec); return; } /* EP2JD-- convert fractional year as used in epoch to Julian date */ double ep2jd (epoch) double epoch; /* Date as fractional year */ { double dj; /* Julian date (returned)*/ double date, time; ep2dt (epoch, &date, &time); dj = dt2jd (date, time); return (dj); } /* EPB2JD-- convert Besselian epoch to Julian Date */ double epb2jd (epoch) double epoch; /* Besselian epoch (fractional 365.242198781-day years) */ { return (2415020.31352 + ((epoch - 1900.0) * 365.242198781)); } /* EPJ2JD-- convert Julian epoch to Julian Date */ double epj2jd (epoch) double epoch; /* Julian epoch (fractional 365.25-day years) */ { return (2451545.0 + ((epoch - 2000.0) * 365.25)); } /* EP2MJD-- convert fractional year as used in epoch to modified Julian date */ double ep2mjd (epoch) double epoch; /* Date as fractional year */ { double dj; /* Julian date (returned)*/ double date, time; ep2dt (epoch, &date, &time); dj = dt2jd (date, time); return (dj - 2400000.5); } /* EPB2MJD-- convert Besselian epoch to modified Julian Date */ double epb2mjd (epoch) double epoch; /* Besselian epoch (fractional 365.242198781-day years) */ { return (15019.81352 + ((epoch - 1900.0) * 365.242198781)); } /* EPJ2MJD-- convert Julian epoch to modified Julian Date */ double epj2mjd (epoch) double epoch; /* Julian epoch (fractional 365.25-day years) */ { return (51544.5 + ((epoch - 2000.0) * 365.25)); } /* EPB2EPJ-- convert Besselian epoch to Julian epoch */ double epb2epj (epoch) double epoch; /* Besselian epoch (fractional 365.242198781-day years) */ { double dj; /* Julian date */ dj = epb2jd (epoch); return (jd2epj (dj)); } /* EPJ2EPB-- convert Julian epoch to Besselian epoch */ double epj2epb (epoch) double epoch; /* Julian epoch (fractional 365.25-day years) */ { double dj; /* Julian date */ dj = epj2jd (epoch); return (jd2epb (dj)); } /* JD2FD-- convert Julian date to FITS date, yyyy-mm-ddThh:mm:ss.ss */ char * jd2fd (dj) double dj; /* Julian date */ { double tsec; /* seconds since 1950.0 (returned) */ tsec = (dj - 2433282.5) * 86400.0; return (ts2fd (tsec)); } /* JD2TS-- convert Julian date to seconds since 1950.0 */ double jd2ts (dj) double dj; /* Julian date */ { return ((dj - 2433282.5) * 86400.0); } /* JD2TSI-- convert Julian date to IRAF seconds since 1980-01-01T0:00 */ int jd2tsi (dj) double dj; /* Julian date */ { double ts; ts = (dj - 2444239.5) * 86400.0; return ((int) ts); } /* JD2TSU-- convert Julian date to Unix seconds since 1970-01-01T0:00 */ time_t jd2tsu (dj) double dj; /* Julian date */ { return ((time_t)((dj - 2440587.5) * 86400.0)); } /* DT2DOY-- convert yyyy.mmdd hh.mmss to year and day of year */ void dt2doy (date, time, year, doy) double date; /* Date as yyyy.mmdd */ double time; /* Time as hh.mmssxxxx */ int *year; /* Year (returned) */ double *doy; /* Day of year with fraction (returned) */ { double dj; /* Julian date */ double dj0; /* Julian date on January 1 0:00 */ double date0; /* January first of date's year */ double dyear; dyear = floor (date); date0 = dyear + 0.0101; dj0 = dt2jd (date0, 0.0); dj = dt2jd (date, time); *year = (int) (dyear + 0.00000001); *doy = dj - dj0 + 1.0; return; } /* DOY2DT-- convert year and day of year to yyyy.mmdd hh.mmss */ void doy2dt (year, doy, date, time) int year; /* Year */ double doy; /* Day of year with fraction */ double *date; /* Date as yyyy.mmdd (returned) */ double *time; /* Time as hh.mmssxxxx (returned) */ { double dj; /* Julian date */ double dj0; /* Julian date on January 1 0:00 */ double date0; /* January first of date's year */ date0 = year + 0.0101; dj0 = dt2jd (date0, 0.0); dj = dj0 + doy - 1.0; jd2dt (dj, date, time); return; } /* DOY2EP-- convert year and day of year to fractional year as used in epoch */ double doy2ep (year, doy) int year; /* Year */ double doy; /* Day of year with fraction */ { double date, time; doy2dt (year, doy, &date, &time); return (dt2ep (date, time)); } /* DOY2EPB-- convert year and day of year to Besellian epoch */ double doy2epb (year, doy) int year; /* Year */ double doy; /* Day of year with fraction */ { double dj; dj = doy2jd (year, doy); return (jd2epb (dj)); } /* DOY2EPJ-- convert year and day of year to Julian epoch */ double doy2epj (year, doy) int year; /* Year */ double doy; /* Day of year with fraction */ { double dj; dj = doy2jd (year, doy); return (jd2epj (dj)); } /* DOY2FD-- convert year and day of year to FITS date */ char * doy2fd (year, doy) int year; /* Year */ double doy; /* Day of year with fraction */ { double dj; /* Julian date */ dj = doy2jd (year, doy); return (jd2fd (dj)); } /* DOY2JD-- convert year and day of year to Julian date */ double doy2jd (year, doy) int year; /* Year */ double doy; /* Day of year with fraction */ { double dj0; /* Julian date */ double date; /* Date as yyyy.mmdd (returned) */ double time; /* Time as hh.mmssxxxx (returned) */ date = (double) year + 0.0101; time = 0.0; dj0 = dt2jd (date, time); return (dj0 + doy - 1.0); } /* DOY2MJD-- convert year and day of year to Julian date */ double doy2mjd (year, doy) int year; /* Year */ double doy; /* Day of year with fraction */ { double dj0; /* Julian date */ double date; /* Date as yyyy.mmdd (returned) */ double time; /* Time as hh.mmssxxxx (returned) */ date = (double) year + 0.0101; time = 0.0; dj0 = dt2jd (date, time); return (dj0 + doy - 1.0 - 2400000.5); } /* DOY2TSU-- convert from FITS date to Unix seconds since 1970-01-01T0:00 */ time_t doy2tsu (year, doy) int year; /* Year */ double doy; /* Day of year with fraction */ { double dj; dj = doy2jd (year, doy); return ((time_t)jd2ts (dj)); } /* DOY2TSI-- convert from FITS date to IRAF seconds since 1980-01-01T0:00 */ int doy2tsi (year, doy) int year; /* Year */ double doy; /* Day of year with fraction */ { double dj; dj = doy2jd (year, doy); return ((int)jd2tsi (dj)); } /* DOY2TS-- convert year, day of year to seconds since 1950 */ double doy2ts (year, doy) int year; /* Year */ double doy; /* Day of year with fraction */ { double dj; dj = doy2jd (year, doy); return (jd2ts (dj)); } /* FD2DOY-- convert FITS date to year and day of year */ void fd2doy (string, year, doy) char *string; /* FITS date string, which may be: fractional year dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard use before 2000) yyyy-mm-dd (FITS standard after 1999) yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ int *year; /* Year (returned) */ double *doy; /* Day of year with fraction (returned) */ { double dj; /* Julian date */ dj = fd2jd (string); jd2doy (dj, year, doy); return; } /* JD2DOY-- convert Julian date to year and day of year */ void jd2doy (dj, year, doy) double dj; /* Julian date */ int *year; /* Year (returned) */ double *doy; /* Day of year with fraction (returned) */ { double date; /* Date as yyyy.mmdd (returned) */ double time; /* Time as hh.mmssxxxx (returned) */ double dj0; /* Julian date at 0:00 on 1/1 */ double dyear; jd2dt (dj, &date, &time); *year = (int) date; dyear = (double) *year; dj0 = dt2jd (dyear+0.0101, 0.0); *doy = dj - dj0 + 1.0; return; } /* TS2JD-- convert seconds since 1950.0 to Julian date */ double ts2jd (tsec) double tsec; /* seconds since 1950.0 */ { return (2433282.5 + (tsec / 86400.0)); } /* TS2MJD-- convert seconds since 1950.0 to modified Julian date */ double ts2mjd (tsec) double tsec; /* seconds since 1950.0 */ { return (33282.0 + (tsec / 86400.0)); } /* TS2EP-- convert seconds since 1950.0 to fractional year as used in epoch */ double ts2ep (tsec) double tsec; /* Seconds since 1950.0 */ { double date, time; ts2dt (tsec, &date, &time); return (dt2ep (date, time)); } /* TS2EPB-- convert seconds since 1950.0 to Besselian epoch */ double ts2epb (tsec) double tsec; /* Seconds since 1950.0 */ { double dj; /* Julian Date */ dj = ts2jd (tsec); return (jd2epb (dj)); } /* TS2EPB-- convert seconds since 1950.0 to Julian epoch */ double ts2epj (tsec) double tsec; /* Seconds since 1950.0 */ { double dj; /* Julian Date */ dj = ts2jd (tsec); return (jd2epj (dj)); } /* DT2EP-- convert from date, time as yyyy.mmdd hh.mmsss to fractional year */ double dt2ep (date, time) double date; /* Date as yyyy.mmdd yyyy = calendar year (e.g. 1973) mm = calendar month (e.g. 04 = april) dd = calendar day (e.g. 15) */ double time; /* Time as hh.mmssxxxx *if time<0, it is time as -(fraction of a day) hh = hour of day (0 .le. hh .le. 23) nn = minutes (0 .le. nn .le. 59) ss = seconds (0 .le. ss .le. 59) xxxx = tenths of milliseconds (0 .le. xxxx .le. 9999) */ { double epoch; /* Date as fractional year (returned) */ double dj, dj0, dj1, date0, time0, date1; dj = dt2jd (date, time); if (date == 0.0) epoch = dj / 365.2422; else { time0 = 0.0; date0 = dint (date) + 0.0101; date1 = dint (date) + 1.0101; dj0 = dt2jd (date0, time0); dj1 = dt2jd (date1, time0); epoch = dint (date) + ((dj - dj0) / (dj1 - dj0)); } return (epoch); } /* DT2EPB-- convert from date, time as yyyy.mmdd hh.mmsss to Besselian epoch */ double dt2epb (date, time) double date; /* Date as yyyy.mmdd yyyy = calendar year (e.g. 1973) mm = calendar month (e.g. 04 = april) dd = calendar day (e.g. 15) */ double time; /* Time as hh.mmssxxxx *if time<0, it is time as -(fraction of a day) hh = hour of day (0 .le. hh .le. 23) nn = minutes (0 .le. nn .le. 59) ss = seconds (0 .le. ss .le. 59) xxxx = tenths of milliseconds (0 .le. xxxx .le. 9999) */ { double dj; /* Julian date */ double epoch; /* Date as fractional year (returned) */ dj = dt2jd (date, time); if (date == 0.0) epoch = dj / 365.242198781; else epoch = jd2epb (dj); return (epoch); } /* DT2EPJ-- convert from date, time as yyyy.mmdd hh.mmsss to Julian epoch */ double dt2epj (date, time) double date; /* Date as yyyy.mmdd yyyy = calendar year (e.g. 1973) mm = calendar month (e.g. 04 = april) dd = calendar day (e.g. 15) */ double time; /* Time as hh.mmssxxxx *if time<0, it is time as -(fraction of a day) hh = hour of day (0 .le. hh .le. 23) nn = minutes (0 .le. nn .le. 59) ss = seconds (0 .le. ss .le. 59) xxxx = tenths of milliseconds (0 .le. xxxx .le. 9999) */ { double dj; /* Julian date */ double epoch; /* Date as fractional year (returned) */ dj = dt2jd (date, time); if (date == 0.0) epoch = dj / 365.25; else epoch = jd2epj (dj); return (epoch); } /* EP2DT-- convert from fractional year to date, time as yyyy.mmdd hh.mmsss */ void ep2dt (epoch, date, time) double epoch; /* Date as fractional year */ double *date; /* Date as yyyy.mmdd (returned) yyyy = calendar year (e.g. 1973) mm = calendar month (e.g. 04 = april) dd = calendar day (e.g. 15) */ double *time; /* Time as hh.mmssxxxx (returned) *if time<0, it is time as -(fraction of a day) hh = hour of day (0 .le. hh .le. 23) nn = minutes (0 .le. nn .le. 59) ss = seconds (0 .le. ss .le. 59) xxxx = tenths of milliseconds (0 .le. xxxx .le. 9999) */ { double dj, dj0, dj1, date0, time0, date1, epochi, epochf; time0 = 0.0; epochi = dint (epoch); epochf = epoch - epochi; date0 = epochi + 0.0101; date1 = epochi + 1.0101; dj0 = dt2jd (date0, time0); dj1 = dt2jd (date1, time0); dj = dj0 + epochf * (dj1 - dj0); jd2dt (dj, date, time); return; } /* EPB2DT-- convert from Besselian epoch to date, time as yyyy.mmdd hh.mmsss */ void epb2dt (epoch, date, time) double epoch; /* Besselian epoch (fractional 365.242198781-day years) */ double *date; /* Date as yyyy.mmdd (returned) yyyy = calendar year (e.g. 1973) mm = calendar month (e.g. 04 = april) dd = calendar day (e.g. 15) */ double *time; /* Time as hh.mmssxxxx (returned) *if time<0, it is time as -(fraction of a day) hh = hour of day (0 .le. hh .le. 23) nn = minutes (0 .le. nn .le. 59) ss = seconds (0 .le. ss .le. 59) xxxx = tenths of milliseconds (0 .le. xxxx .le. 9999) */ { double dj; /* Julian date */ dj = epb2jd (epoch); jd2dt (dj, date, time); } /* EPJ2DT-- convert from Julian epoch to date, time as yyyy.mmdd hh.mmsss */ void epj2dt (epoch, date, time) double epoch; /* Julian epoch (fractional 365.25-day years) */ double *date; /* Date as yyyy.mmdd (returned) yyyy = calendar year (e.g. 1973) mm = calendar month (e.g. 04 = april) dd = calendar day (e.g. 15) */ double *time; /* Time as hh.mmssxxxx (returned) *if time<0, it is time as -(fraction of a day) hh = hour of day (0 .le. hh .le. 23) nn = minutes (0 .le. nn .le. 59) ss = seconds (0 .le. ss .le. 59) xxxx = tenths of milliseconds (0 .le. xxxx .le. 9999) */ { double dj; /* Julian date */ dj = epj2jd (epoch); jd2dt (dj, date, time); } /* FD2JD-- convert FITS standard date to Julian date */ double fd2jd (string) char *string; /* FITS date string, which may be: fractional year dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard use before 2000) yyyy-mm-dd (FITS standard after 1999) yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ { double date, time; fd2dt (string, &date, &time); return (dt2jd (date, time)); } /* FD2MJD-- convert FITS standard date to modified Julian date */ double fd2mjd (string) char *string; /* FITS date string, which may be: fractional year dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard use before 2000) yyyy-mm-dd (FITS standard after 1999) yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ { return (fd2jd (string) - 2400000.5); } /* FD2TSU-- convert from FITS date to Unix seconds since 1970-01-01T0:00 */ time_t fd2tsu (string) char *string; /* FITS date string, which may be: fractional year dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard use before 2000) yyyy-mm-dd (FITS standard after 1999) yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ { double date, time; fd2dt (string, &date, &time); return (dt2tsu (date, time)); } /* FD2TSI-- convert from FITS date to IRAF seconds since 1980-01-01T0:00 */ int fd2tsi (string) char *string; /* FITS date string, which may be: fractional year dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard use before 2000) yyyy-mm-dd (FITS standard after 1999) yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ { double date, time; fd2dt (string, &date, &time); return (dt2tsi (date, time)); } /* FD2TS-- convert FITS standard date to seconds since 1950 */ double fd2ts (string) char *string; /* FITS date string, which may be: fractional year dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard use before 2000) yyyy-mm-dd (FITS standard after 1999) yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ { double date, time; fd2dt (string, &date, &time); return (dt2ts (date, time)); } /* FD2FD-- convert any FITS standard date to ISO FITS standard date */ char * fd2fd (string) char *string; /* FITS date string, which may be: fractional year dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard use before 2000) yyyy-mm-dd (FITS standard after 1999) yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ { double date, time; fd2dt (string, &date, &time); return (dt2fd (date, time)); } /* FD2OF-- convert any FITS standard date to old FITS standard date time */ char * fd2of (string) char *string; /* FITS date string, which may be: fractional year dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard use before 2000) yyyy-mm-dd (FITS standard after 1999) yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ { int iyr,imon,iday,ihr,imn; double sec; fd2i (string,&iyr,&imon,&iday,&ihr,&imn,&sec, 3); /* Convert to old FITS date format */ string = (char *) calloc (32, sizeof (char)); if (iyr < 1900) sprintf (string, "*** date out of range ***"); else if (iyr < 2000) sprintf (string, "%02d/%02d/%02d %02d:%02d:%06.3f", iday, imon, iyr-1900, ihr, imn, sec); else if (iyr < 2900.0) sprintf (string, "%02d/%02d/%3d %02d:%02d:%6.3f", iday, imon, iyr-1900, ihr, imn, sec); else sprintf (string, "*** date out of range ***"); return (string); } /* TAI-UTC from the U.S. Naval Observatory */ /* ftp://maia.usno.navy.mil/ser7/tai-utc.dat */ static double taijd[23]={2441317.5, 2441499.5, 2441683.5, 2442048.5, 2442413.5, 2442778.5, 2443144.5, 2443509.5, 2443874.5, 2444239.5, 2444786.5, 2445151.5, 2445516.5, 2446247.5, 2447161.5, 2447892.5, 2448257.5, 2448804.5, 2449169.5, 2449534.5, 2450083.5, 2450630.5, 2451179.5}; static double taidt[23]={10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0, 20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0}; static double dttab[173]={13.7,13.4,13.1,12.9,12.7,12.6,12.5,12.5,12.5,12.5, 12.5,12.5,12.5,12.5,12.5,12.5,12.5,12.4,12.3,12.2,12.0,11.7,11.4, 11.1,10.6,10.2, 9.6, 9.1, 8.6, 8.0, 7.5, 7.0, 6.6, 6.3, 6.0, 5.8, 5.7, 5.6, 5.6, 5.6, 5.7, 5.8, 5.9, 6.1, 6.2, 6.3, 6.5, 6.6, 6.8, 6.9, 7.1, 7.2, 7.3, 7.4, 7.5, 7.6, 7.7, 7.7, 7.8, 7.8,7.88,7.82, 7.54, 6.97, 6.40, 6.02, 5.41, 4.10, 2.92, 1.82, 1.61, 0.10,-1.02, -1.28,-2.69,-3.24,-3.64,-4.54,-4.71,-5.11,-5.40,-5.42,-5.20,-5.46, -5.46,-5.79,-5.63,-5.64,-5.80,-5.66,-5.87,-6.01,-6.19,-6.64,-6.44, -6.47,-6.09,-5.76,-4.66,-3.74,-2.72,-1.54,-0.02, 1.24, 2.64, 3.86, 5.37, 6.14, 7.75, 9.13,10.46,11.53,13.36,14.65,16.01,17.20,18.24, 19.06,20.25,20.95,21.16,22.25,22.41,23.03,23.49,23.62,23.86,24.49, 24.34,24.08,24.02,24.00,23.87,23.95,23.86,23.93,23.73,23.92,23.96, 24.02,24.33,24.83,25.30,25.70,26.24,26.77,27.28,27.78,28.25,28.71, 29.15,29.57,29.97,30.36,30.72,31.07,31.35,31.68,32.18,32.68,33.15, 33.59,34.00,34.47,35.03,35.73,36.54,37.43,38.29,39.20,40.18,41.17, 42.23}; /* ET2FD-- convert from ET (or TDT or TT) in FITS format to UT in FITS format */ char * et2fd (string) char *string; /* FITS date string, which may be: fractional year dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard use before 2000) yyyy-mm-dd (FITS standard after 1999) yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ { double dj0, dj, tsec, dt; dj0 = fd2jd (string); dt = utdt (dj0); dj = dj0 - (dt / 86400.0); dt = utdt (dj); tsec = fd2ts (string); tsec = tsec - dt; return (ts2fd (tsec)); } /* FD2ET-- convert from UT in FITS format to ET (or TDT or TT) in FITS format */ char * fd2et (string) char *string; /* FITS date string, which may be: fractional year dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard use before 2000) yyyy-mm-dd (FITS standard after 1999) yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ { double dj, tsec, dt; dj = fd2jd (string); dt = utdt (dj); tsec = fd2ts (string); tsec = tsec + dt; return (ts2fd (tsec)); } /* DT2ET-- convert from UT as yyyy.mmdd hh.mmssss to ET in same format */ void dt2et (date, time) double *date; /* Date as yyyy.mmdd */ double *time; /* Time as hh.mmssxxxx *if time<0, it is time as -(fraction of a day) */ { double dj, dt, tsec; dj = dt2jd (*date, *time); dt = utdt (dj); tsec = dt2ts (*date, *time); tsec = tsec + dt; ts2dt (tsec, date, time); return; } /* EDT2DT-- convert from ET as yyyy.mmdd hh.mmssss to UT in same format */ void edt2dt (date, time) double *date; /* Date as yyyy.mmdd */ double *time; /* Time as hh.mmssxxxx *if time<0, it is time as -(fraction of a day) */ { double dj, dt, tsec, tsec0; dj = dt2jd (*date, *time); dt = utdt (dj); tsec0 = dt2ts (*date, *time); tsec = tsec0 + dt; dj = ts2jd (tsec); dt = utdt (dj); tsec = tsec0 + dt; ts2dt (tsec, date, time); return; } /* JD2JED-- convert from Julian Date to Julian Ephemeris Date */ double jd2jed (dj) double dj; /* Julian Date */ { double dt; dt = utdt (dj); return (dj + (dt / 86400.0)); } /* JED2JD-- convert from Julian Ephemeris Date to Julian Date */ double jed2jd (dj) double dj; /* Julian Ephemeris Date */ { double dj0, dt; dj0 = dj; dt = utdt (dj); dj = dj0 - (dt / 86400.0); dt = utdt (dj); return (dj - (dt / 86400.0)); } /* TS2ETS-- convert from UT in seconds since 1950-01-01 to ET in same format */ double ts2ets (tsec) double tsec; { double dj, dt; dj = ts2jd (tsec); dt = utdt (dj); return (tsec + dt); } /* ETS2TS-- convert from ET in seconds since 1950-01-01 to UT in same format */ double ets2ts (tsec) double tsec; { double dj, dj0, dt; dj0 = ts2jd (tsec); dt = utdt (dj0); dj = dj0 - (dt / 86400.0); dt = utdt (dj); return (tsec - dt); } /* UTDT-- Compute difference between UT and dynamical time (ET-UT) */ double utdt (dj) double dj; /* Julian Date (UT) */ { double dt, date, time, ts, ts1, ts0, date0, yfrac, diff, cj; int i, iyr, iyear; /* If after 1972-01-01, use tabulated TAI-UT */ if (dj >= 2441317.5) { dt = 0.0; for (i = 22; i > 0; i--) { if (dj >= taijd[i]) dt = taidt[i]; } dt = dt + 32.84; } /* For 1800-01-01 to 1972-01-01, use table of ET-UT from AE */ else if (dj >= 2378496.5) { jd2dt (dj, &date, &time); ts = jd2ts (dj); iyear = (int) date; iyr = iyear - 1800; date0 = (double) iyear + 0.0101; ts0 = dt2ts (date0, 0.0); date0 = (double) (iyear + 1) + 0.0101; ts1 = dt2ts (date0, 0.0); yfrac = (ts - ts0) / (ts1 - ts0); diff = dttab[iyr+1] - dttab[iyr]; dt = dttab[iyr] + (diff * yfrac); } /* Compute back to 1600 using formula from McCarthy and Babcock (1986) */ else if (dj >= 2305447.5) { cj = (dj - 2378496.5) / 36525.0; dt = 5.156 + 13.3066 * (cj - 0.19) * (cj - 0.19); } /* Compute back to 948 using formula from Stephenson and Morrison (1984) */ else if (dj >= 2067309.5) { cj = (dj - 2378496.5) / 36525.0; dt = 25.5 * cj * cj; } /*Compute back to 390 BC using formula from Stephenson and Morrison (1984)*/ else if (dj >= 0.0) { cj = (dj = 2378496.5) / 36525.0; dt = 1360.0 + (320.0 * cj) + (44.3 * cj * cj); } else dt = 0.0; return (dt); } /* FD2OFD-- convert any FITS standard date to old FITS standard date */ char * fd2ofd (string) char *string; /* FITS date string, which may be: fractional year dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard use before 2000) yyyy-mm-dd (FITS standard after 1999) yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ { int iyr,imon,iday,ihr,imn; double sec; fd2i (string,&iyr,&imon,&iday,&ihr,&imn,&sec, 3); /* Convert to old FITS date format */ string = (char *) calloc (32, sizeof (char)); if (iyr < 1900) sprintf (string, "*** date out of range ***"); else if (iyr < 2000) sprintf (string, "%02d/%02d/%02d", iday, imon, iyr-1900); else if (iyr < 2900.0) sprintf (string, "%02d/%02d/%3d", iday, imon, iyr-1900); else sprintf (string, "*** date out of range ***"); return (string); } /* FD2OFT-- convert any FITS standard date to old FITS standard time */ char * fd2oft (string) char *string; /* FITS date string, which may be: fractional year dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard use before 2000) yyyy-mm-dd (FITS standard after 1999) yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ { int iyr,imon,iday,ihr,imn; double sec; fd2i (string,&iyr,&imon,&iday,&ihr,&imn,&sec, 3); /* Convert to old FITS date format */ string = (char *) calloc (32, sizeof (char)); sprintf (string, "%02d:%02d:%06.3f", ihr, imn, sec); return (string); } /* FD2DT-- convert FITS standard date to date, time as yyyy.mmdd hh.mmsss */ void fd2dt (string, date, time) char *string; /* FITS date string, which may be: fractional year dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard use before 2000) yyyy-mm-dd (FITS standard after 1999) yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ double *date; /* Date as yyyy.mmdd (returned) yyyy = calendar year (e.g. 1973) mm = calendar month (e.g. 04 = april) dd = calendar day (e.g. 15) */ double *time; /* Time as hh.mmssxxxx (returned) *if time<0, it is time as -(fraction of a day) hh = hour of day (0 .le. hh .le. 23) nn = minutes (0 .le. nn .le. 59) ss = seconds (0 .le. ss .le. 59) xxxx = tenths of milliseconds (0 .le. xxxx .le. 9999) */ { int iyr,imon,iday,ihr,imn; double sec; fd2i (string,&iyr,&imon,&iday,&ihr,&imn,&sec, 4); /* Convert date to yyyy.mmdd */ if (iyr < 0) { *date = (double) (-iyr) + 0.01 * (double) imon + 0.0001 * (double) iday; *date = -(*date); } else *date = (double) iyr + 0.01 * (double) imon + 0.0001 * (double) iday; /* Convert time to hh.mmssssss */ *time = (double) ihr + 0.01 * (double) imn + 0.0001 * sec; return; } /* FD2EP-- convert from FITS standard date to fractional year */ double fd2ep (string) char *string; /* FITS date string, which may be: yyyy.ffff (fractional year) dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard FITS use before 2000) yyyy-mm-dd (FITS standard after 1999) yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ { double dj; /* Julian date */ dj = fd2jd (string); if (dj < 1.0) return (dj / 365.2422); else return (jd2ep (dj)); } /* FD2EPB-- convert from FITS standard date to Besselian epoch */ double fd2epb (string) char *string; /* FITS date string, which may be: yyyy.ffff (fractional year) dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard FITS use before 2000) yyyy-mm-dd (FITS standard after 1999) yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ { double dj; /* Julian date */ dj = fd2jd (string); if (dj < 1.0) return (dj / 365.242198781); else return (jd2epb (dj)); } /* FD2EPJ-- convert from FITS standard date to Julian epoch */ double fd2epj (string) char *string; /* FITS date string, which may be: yyyy.ffff (fractional year) dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard FITS use before 2000) yyyy-mm-dd (FITS standard after 1999) yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ { double dj; /* Julian date */ dj = fd2jd (string); if (dj < 1.0) return (dj / 365.25); else return (jd2epj (dj)); } /* DT2TSU-- convert from date and time to Unix seconds since 1970-01-01T0:00 */ time_t dt2tsu (date,time) double date; /* Date as yyyy.mmdd */ double time; /* Time as hh.mmssxxxx *if time<0, it is time as -(fraction of a day) */ { return ((time_t)(dt2ts (date, time) - 631152000.0)); } /* DT2TSI-- convert from date and time to IRAF seconds since 1980-01-01T0:00 */ int dt2tsi (date,time) double date; /* Date as yyyy.mmdd */ double time; /* Time as hh.mmssxxxx *if time<0, it is time as -(fraction of a day) */ { return ((int)(dt2ts (date, time) - 946684800.0)); } /* DT2TS-- convert from date, time as yyyy.mmdd hh.mmsss to sec since 1950.0 */ double dt2ts (date,time) double date; /* Date as yyyy.mmdd yyyy = calendar year (e.g. 1973) mm = calendar month (e.g. 04 = april) dd = calendar day (e.g. 15) */ double time; /* Time as hh.mmssxxxx *if time<0, it is time as -(fraction of a day) hh = hour of day (0 .le. hh .le. 23) nn = minutes (0 .le. nn .le. 59) ss = seconds (0 .le. ss .le. 59) xxxx = tenths of milliseconds (0 .le. xxxx .le. 9999) */ { double tsec; /* Seconds past 1950.0 (returned) */ double dh,dm,dd; int iy,im,id; /* Calculate the number of full years, months, and days already * elapsed since 0h, March 1, -1 (up to most recent midnight). */ /* convert time of day to elapsed seconds */ /* If time is < 0, it is assumed to be a fractional day */ if (time < 0.0) tsec = time * -86400.0; else { dh = (int) (time + 0.0000000001); dm = (int) (((time - dh) * 100.0) + 0.0000000001); tsec = (time * 10000.0) - (dh * 10000.0) - (dm * 100.0); tsec = (int) (tsec * 100000.0 + 0.0001) / 100000.0; tsec = tsec + (dm * 60.0) + (dh * 3600.0); } /* Calculate the number of full months elapsed since * the current or most recent March */ if (date >= 0.0301) { iy = (int) (date + 0.0000000001); im = (int) (((date - (double) (iy)) * 10000.0) + 0.00000001); id = im % 100; im = (im / 100) + 9; if (im < 12) iy = iy - 1; im = im % 12; id = id - 1; /* starting with March as month 0 and ending with the following * February as month 11, the calculation of the number of days * per month reduces to a simple formula. the following statement * determines the number of whole days elapsed since 3/1/-1 and then * subtracts the 712163 days between then and 1/1/1950. it converts * the result to seconds and adds the accumulated seconds above. */ id = id + ((im+1+im/6+im/11)/2 * 31) + ((im-im/6-im/11)/2 * 30) + (iy / 4) - (iy / 100) + (iy / 400); dd = (double) id + (365.0 * (double) iy) - 712163.0; tsec = tsec + (dd * 86400.0); } return (tsec); } /* TS2DT-- convert seconds since 1950.0 to date, time as yyyy.mmdd hh.mmssss */ void ts2dt (tsec,date,time) double tsec; /* Seconds past 1950.0 */ double *date; /* Date as yyyy.mmdd (returned) yyyy = calendar year (e.g. 1973) mm = calendar month (e.g. 04 = april) dd = calendar day (e.g. 15) */ double *time; /* Time as hh.mmssxxxx (returned) *if time<0, it is time as -(fraction of a day) hh = hour of day (0 .le. hh .le. 23) nn = minutes (0 .le. nn .le. 59) ss = seconds (0 .le. ss .le. 59) xxxx = tenths of milliseconds (0 .le. xxxx .le. 9999) */ { int iyr,imon,iday,ihr,imn; double sec; ts2i (tsec,&iyr,&imon,&iday,&ihr,&imn,&sec, 4); /* Convert date to yyyy.mmdd */ if (iyr < 0) { *date = (double) (-iyr) + 0.01 * (double) imon + 0.0001 * (double) iday; *date = -(*date); } else *date = (double) iyr + 0.01 * (double) imon + 0.0001 * (double) iday; /* Convert time to hh.mmssssss */ *time = (double) ihr + 0.01 * (double) imn + 0.0001 * sec; return; } /* TSI2DT-- Convert seconds since 1980-01-01 to date yyyy.ddmm, time hh.mmsss */ void tsi2dt (isec,date,time) int isec; /* Seconds past 1980-01-01 */ double *date; /* Date as yyyy.mmdd (returned) */ double *time; /* Time as hh.mmssxxxx (returned) */ { ts2dt (tsi2ts (isec), date, time); } /* TSI2FD-- Convert seconds since 1980-01-01 to FITS standard date string */ char * tsi2fd (isec) int isec; /* Seconds past 1980-01-01 */ { return (ts2fd (tsi2ts (isec))); } /* TSI2TS-- Convert seconds since 1980-01-01 to seconds since 1950-01-01 */ double tsi2ts (isec) int isec; /* Seconds past 1980-01-01 */ { return ((double) isec + 946684800.0); } /* TSU2FD-- Convert seconds since 1970-01-01 to FITS standard date string */ char * tsu2fd (isec) time_t isec; /* Seconds past 1970-01-01 */ { return (ts2fd (tsu2ts (isec))); } /* TSU2DT-- Convert seconds since 1970-01-01 to date yyyy.ddmm, time hh.mmsss */ void tsu2dt (isec,date,time) time_t isec; /* Seconds past 1970-01-01 */ double *date; /* Date as yyyy.mmdd (returned) */ double *time; /* Time as hh.mmssxxxx (returned) */ { ts2dt (tsu2ts (isec), date, time); } /* TSU2TS-- Convert seconds since 1970-01-01 to seconds since 1950-01-01 */ double tsu2ts (isec) time_t isec; /* Seconds past 1970-01-01 */ { return ((double) isec + 631152000.0); } /* TSU2TSI-- UT seconds since 1970-01-01 to local seconds since 1980-01-01 */ int tsu2tsi (isec) time_t isec; /* Seconds past 1970-01-01 */ { double date, time; struct tm *ts; /* Get local time from UT seconds */ ts = localtime (&isec); if (ts->tm_year < 1000) date = (double) (ts->tm_year + 1900); else date = (double) ts->tm_year; date = date + (0.01 * (double) (ts->tm_mon + 1)); date = date + (0.0001 * (double) ts->tm_mday); time = (double) ts->tm_hour; time = time + (0.01 * (double) ts->tm_min); time = time + (0.0001 * (double) ts->tm_sec); return ((int)(dt2ts (date, time) - 631152000.0)); } /* TS2FD-- convert seconds since 1950.0 to FITS date, yyyy-mm-ddThh:mm:ss.ss */ char * ts2fd (tsec) double tsec; /* Seconds past 1950.0 */ { double date, time; ts2dt (tsec, &date, &time); return (dt2fd (date, time)); } /* TSD2FD-- convert seconds since start of day to FITS time, hh:mm:ss.ss */ char * tsd2fd (tsec) double tsec; /* Seconds since start of day */ { double date, time; char *thms, *fdate; int lfd, nbc; ts2dt (tsec, &date, &time); fdate = dt2fd (date, time); thms = (char *) calloc (16, 1); lfd = strlen (fdate); nbc = lfd - 11; strncpy (thms, fdate+11, nbc); return (thms); } /* TSD2DT-- convert seconds since start of day to hh.mmssss */ double tsd2dt (tsec) double tsec; /* Seconds since start of day */ { double date, time; ts2dt (tsec, &date, &time); return (time); } /* DT2I-- convert vigesimal date and time to year month day hours min sec */ void dt2i (date, time, iyr, imon, iday, ihr, imn, sec, ndsec) double date; /* Date as yyyy.mmdd (returned) yyyy = calendar year (e.g. 1973) mm = calendar month (e.g. 04 = april) dd = calendar day (e.g. 15) */ double time; /* Time as hh.mmssxxxx (returned) *if time<0, it is time as -(fraction of a day) hh = hour of day (0 .le. hh .le. 23) nn = minutes (0 .le. nn .le. 59) ss = seconds (0 .le. ss .le. 59) xxxx = tenths of milliseconds (0 .le. xxxx .le. 9999) */ int *iyr; /* year (returned) */ int *imon; /* month (returned) */ int *iday; /* day (returned) */ int *ihr; /* hours (returned) */ int *imn; /* minutes (returned) */ double *sec; /* seconds (returned) */ int ndsec; /* Number of decimal places in seconds (0=int) */ { double t,d; t = time; if (date < 0.0) d = -date; else d = date; /* Extract components of time */ *ihr = dint (t + 0.000000001); t = 100.0 * (t - (double) *ihr); *imn = dint (t + 0.0000001); *sec = 100.0 * (t - (double) *imn); /* Extract components of date */ *iyr = dint (d + 0.00001); d = 100.0 * (d - (double) *iyr); if (date < 0.0) *iyr = - *iyr; *imon = dint (d + 0.001); d = 100.0 * (d - (double) *imon); *iday = dint (d + 0.1); /* Make sure date and time are legal */ fixdate (iyr, imon, iday, ihr, imn, sec, ndsec); return; } /* FD2I-- convert from FITS standard date to year, mon, day, hours, min, sec */ void fd2i (string, iyr, imon, iday, ihr, imn, sec, ndsec) char *string; /* FITS date string, which may be: yyyy.ffff (fractional year) dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard FITS use before 2000) yyyy-mm-dd (FITS standard after 1999) yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ int *iyr; /* year (returned) */ int *imon; /* month (returned) */ int *iday; /* day (returned) */ int *ihr; /* hours (returned) */ int *imn; /* minutes (returned) */ double *sec; /* seconds (returned) */ int ndsec; /* Number of decimal places in seconds (0=int) */ { double tsec, fday, hr, mn; int i; char *sstr, *dstr, *tstr, *cstr, *nval, *fstr; /* Initialize all returned data to zero */ *iyr = 0; *imon = 0; *iday = 0; *ihr = 0; *imn = 0; *sec = 0.0; /* Return if no input string */ if (string == NULL) return; /* Check for various non-numeric characters */ sstr = strchr (string,'/'); dstr = strchr (string,'-'); if (dstr == string) dstr = strchr (string+1, '-'); fstr = strchr (string, '.'); tstr = strchr (string,'T'); if (tstr == NULL) tstr = strchr (string, 'Z'); if (tstr == NULL) tstr = strchr (string, 'S'); if (fstr != NULL && tstr != NULL && fstr > tstr) fstr = NULL; cstr = strchr (string,':'); /* Original FITS date format: dd/mm/yy */ if (sstr > string) { *sstr = '\0'; *iday = (int) atof (string); if (*iday > 31) { *iyr = *iday; if (*iyr >= 0 && *iyr <= 49) *iyr = *iyr + 2000; else if (*iyr < 1000) *iyr = *iyr + 1900; *sstr = '/'; nval = sstr + 1; sstr = strchr (nval,'/'); if (sstr > string) { *sstr = '\0'; *imon = (int) atof (nval); *sstr = '/'; nval = sstr + 1; *iday = (int) atof (nval); } } else { *sstr = '/'; nval = sstr + 1; sstr = strchr (nval,'/'); if (sstr == NULL) sstr = strchr (nval,'-'); if (sstr > string) { *sstr = '\0'; *imon = (int) atof (nval); *sstr = '/'; nval = sstr + 1; *iyr = (int) atof (nval); if (*iyr >= 0 && *iyr <= 49) *iyr = *iyr + 2000; else if (*iyr < 1000) *iyr = *iyr + 1900; } } tstr = strchr (string,'_'); if (tstr == NULL) return; } /* New FITS date format: yyyy-mm-ddThh:mm:ss[.sss] */ else if (dstr > string) { *dstr = '\0'; *iyr = (int) atof (string); *dstr = '-'; nval = dstr + 1; dstr = strchr (nval,'-'); *imon = 1; *iday = 1; /* Decode year, month, and day */ if (dstr > string) { *dstr = '\0'; *imon = (int) atof (nval); *dstr = '-'; nval = dstr + 1; if (tstr > string) *tstr = '\0'; *iday = (int) atof (nval); /* If fraction of a day is present, turn it into a time */ if (fstr != NULL) { fday = atof (fstr); hr = fday * 24.0; *ihr = (int) hr; mn = 60.0 * (hr - (double) *ihr); *imn = (int) mn; *sec = 60.0 * (mn - (double) *imn); } if (tstr > string) *tstr = 'T'; } /* If date is > 31, it is really year in old format */ if (*iday > 31) { i = *iyr; if (*iday < 100) *iyr = *iday + 1900; else *iyr = *iday; *iday = i; } } /* In rare cases, a FITS time is entered as an epoch */ else if (tstr == NULL && cstr == NULL && isnum (string)) { tsec = ep2ts (atof (string)); ts2i (tsec,iyr,imon,iday,ihr,imn,sec, ndsec); return; } /* Extract time, if it is present */ if (tstr > string || cstr > string) { if (tstr > string) nval = tstr + 1; else nval = string; cstr = strchr (nval,':'); if (cstr > string) { *cstr = '\0'; *ihr = (int) atof (nval); *cstr = ':'; nval = cstr + 1; cstr = strchr (nval,':'); if (cstr > string) { *cstr = '\0'; *imn = (int) atof (nval); *cstr = ':'; nval = cstr + 1; *sec = atof (nval); } else *imn = (int) atof (nval); } else *ihr = (int) atof (nval); } else ndsec = -1; /* Make sure date and time are legal */ fixdate (iyr, imon, iday, ihr, imn, sec, ndsec); return; } /* TS2I-- convert sec since 1950.0 to year month day hours minutes seconds */ void ts2i (tsec,iyr,imon,iday,ihr,imn,sec, ndsec) double tsec; /* seconds since 1/1/1950 0:00 */ int *iyr; /* year (returned) */ int *imon; /* month (returned) */ int *iday; /* day (returned) */ int *ihr; /* hours (returned) */ int *imn; /* minutes (returned) */ double *sec; /* seconds (returned) */ int ndsec; /* Number of decimal places in seconds (0=int) */ { double t,days, ts, dts; int nc,nc4,nly,ny,m,im; /* Round seconds to 0 - 4 decimal places */ ts = tsec + 61530883200.0; if (ts < 0.0) dts = -0.5; else dts = 0.5; if (ndsec < 1) t = dint (ts + dts) * 10000.0; else if (ndsec < 2) t = dint (ts * 10.0 + dts) * 1000.0; else if (ndsec < 3) t = dint (ts * 100.0 + dts) * 100.0; else if (ndsec < 4) t = dint (ts * 1000.0 + dts) * 10.0; else t = dint (ts * 10000.0 + dts); ts = t / 10000.0; /* Time of day (hours, minutes, seconds */ *ihr = (int) (dmod (ts/3600.0, 24.0)); *imn = (int) (dmod (ts/60.0, 60.0)); *sec = dmod (ts, 60.0); /* Number of days since 0 hr 0/0/0000 */ days = dint ((t / 864000000.0) + 0.000001); /* Number of leap centuries (400 years) */ nc4 = (int) ((days / 146097.0) + 0.00001); /* Number of centuries since last /400 */ days = days - (146097.0 * (double) (nc4)); nc = (int) ((days / 36524.0) + 0.000001); if (nc > 3) nc = 3; /* Number of leap years since last century */ days = days - (36524.0 * nc); nly = (int) ((days / 1461.0) + 0.0000000001); /* Number of years since last leap year */ days = days - (1461.0 * (double) nly); ny = (int) ((days / 365.0) + 0.00000001); if (ny > 3) ny = 3; /* Day of month */ days = days - (365.0 * (double) ny); if (days < 0) { m = 0; *iday = 29; } else { *iday = (int) (days + 0.00000001) + 1; for (m = 1; m <= 12; m++) { im = (m + ((m - 1) / 5)) % 2; /* fprintf (stderr,"%d %d %d %d\n", m, im, *iday, nc); */ if (*iday-1 < im+30) break; *iday = *iday - im - 30; } } /* Month */ *imon = ((m+1) % 12) + 1; /* Year */ *iyr = nc4*400 + nc*100 + nly*4 + ny + m/11; /* Make sure date and time are legal */ fixdate (iyr, imon, iday, ihr, imn, sec, ndsec); return; } /* UT2DOY-- Current Universal Time as year, day of year */ void ut2doy (year, doy) int *year; /* Year (returned) */ double *doy; /* Day of year (returned) */ { double date, time; ut2dt (&date, &time); dt2doy (date, time, year, doy); return; } /* UT2DT-- Current Universal Time as date (yyyy.mmdd) and time (hh.mmsss) */ void ut2dt(date, time) double *date; /* Date as yyyy.mmdd (returned) */ double *time; /* Time as hh.mmssxxxx (returned) */ { time_t tsec; struct timeval tp; struct timezone tzp; struct tm *ts; gettimeofday (&tp,&tzp); tsec = tp.tv_sec; ts = gmtime (&tsec); if (ts->tm_year < 1000) *date = (double) (ts->tm_year + 1900); else *date = (double) ts->tm_year; *date = *date + (0.01 * (double) (ts->tm_mon + 1)); *date = *date + (0.0001 * (double) ts->tm_mday); *time = (double) ts->tm_hour; *time = *time + (0.01 * (double) ts->tm_min); *time = *time + (0.0001 * (double) ts->tm_sec); return; } /* UT2EP-- Return current Universal Time as fractional year */ double ut2ep() { return (jd2ep (ut2jd())); } /* UT2EPB-- Return current Universal Time as Besselian epoch */ double ut2epb() { return (jd2epb (ut2jd())); } /* UT2EPJ-- Return current Universal Time as Julian epoch */ double ut2epj() { return (jd2epj (ut2jd())); } /* UT2FD-- Return current Universal Time as FITS ISO date string */ char * ut2fd() { int year, month, day, hour, minute, second; time_t tsec; struct timeval tp; struct timezone tzp; struct tm *ts; char *isotime; gettimeofday (&tp,&tzp); tsec = tp.tv_sec; ts = gmtime (&tsec); year = ts->tm_year; if (year < 1000) year = year + 1900; month = ts->tm_mon + 1; day = ts->tm_mday; hour = ts->tm_hour; minute = ts->tm_min; second = ts->tm_sec; isotime = (char *) calloc (32, sizeof (char)); sprintf (isotime, "%04d-%02d-%02dT%02d:%02d:%02d", year, month, day, hour, minute, second); return (isotime); } /* UT2JD-- Return current Universal Time as Julian Date */ double ut2jd() { return (fd2jd (ut2fd())); } /* UT2MJD-- convert current UT to Modified Julian Date */ double ut2mjd () { return (ut2jd() - 2400000.5); } /* UT2TS-- current Universal Time as IRAF seconds since 1950-01-01T00:00 */ double ut2ts() { double tsec; char *datestring; datestring = ut2fd(); tsec = fd2ts (datestring); free (datestring); return (tsec); } /* UT2TSI-- current Universal Time as IRAF seconds since 1980-01-01T00:00 */ int ut2tsi() { return ((int)(ut2ts() - 946684800.0)); } /* UT2TSU-- current Universal Time as IRAF seconds since 1970-01-01T00:00 */ time_t ut2tsu() { return ((time_t)(ut2ts () - 631152000.0)); } /* FD2GST-- convert from FITS date to Greenwich Sidereal Time */ char * fd2gst (string) char *string; /* FITS date string, which may be: fractional year dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard use before 2000) yyyy-mm-dd (FITS standard after 1999) yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ { double dj, gsec, date, time; dj = fd2jd (string); gsec = jd2gst (dj); ts2dt (gsec, &date, &time); date = 0.0; return (dt2fd (date, time)); } /* DT2GST-- convert from UT as yyyy.mmdd hh.mmssss to Greenwich Sidereal Time*/ void dt2gst (date, time) double *date; /* Date as yyyy.mmdd */ double *time; /* Time as hh.mmssxxxx *if time<0, it is time as -(fraction of a day) */ { double dj, gsec; dj = dt2ts (*date, *time); gsec = jd2gst (dj); ts2dt (gsec, date, time); *date = 0.0; return; } /* JD2LST - Local Sidereal Time in seconds from Julian Date */ double jd2lst (dj) double dj; /* Julian Date */ { double gst, lst; /* Compute Greenwich Sidereal Time at this epoch */ gst = jd2gst (dj); /* Subtract longitude (in seconds of time) */ lst = gst - 3600.0 * (longitude / 15.0); if (lst < 0.0) lst = lst + 86400.0; else if (lst > 86400.0) lst = lst - 86400.0; return (lst); } /* FD2LST - Local Sidereal Time as hh:mm:ss.ss from Universal Time as FITS ISO date */ char * fd2lst (string) char *string; /* FITS date string, which may be: fractional year dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard use before 2000) yyyy-mm-dd (FITS standard after 1999) */ { double dj, date, time, lst; dj = fd2jd (string); lst = jd2lst (dj); ts2dt (lst, &date, &time); date = 0.0; return (dt2fd (date, time)); } /* DT2LST - Local Sidereal Time as hh.mmssss from Universal Time as yyyy.mmdd hh.mmssss */ void dt2lst (date, time) double *date; /* Date as yyyy.mmdd */ double *time; /* Time as hh.mmssxxxx *if time<0, it is time as -(fraction of a day) */ { double dj, lst, date0; dj = dt2jd (*date, *time); lst = jd2lst (dj); date0 = 0.0; ts2dt (lst, &date0, time); return; } /* TS2LST - Local Sidereal Time in seconds of day * from Universal Time in seconds since 1951-01-01T0:00:00 */ double ts2lst (tsec) double tsec; /* time since 1950.0 in UT seconds */ { double gst; /* Greenwich Sidereal Time in seconds since 0:00 */ double lst; /* Local Sidereal Time in seconds since 0:00 */ double gsec, date; /* Greenwich Sidereal Time */ gsec = ts2gst (tsec); date = 0.0; ts2dt (gsec, &date, &gst); lst = gst - (longitude / 15.0); if (lst < 0.0) lst = lst + 86400.0; else if (lst > 86400.0) lst = lst - 86400.0; return (lst); } /* LST2FD - calculate current UT given Local Sidereal Time * plus date in FITS ISO format (yyyy-mm-dd) * Return UT date and time in FITS ISO format */ char * lst2fd (string) char *string; /* UT Date, LST as yyyy-mm-ddShh:mm:ss.ss */ { double sdj, dj; sdj = fd2jd (string); dj = lst2jd (sdj); return (jd2fd (dj)); } /* LST2JD - calculate current Julian Date given Local Sidereal Time * plus current Julian Date (0.5 at 0:00 UT) * Return UT date and time as Julian Date */ double lst2jd (sdj) double sdj; /* Julian Date of desired day at 0:00 UT + sidereal time */ { double gst; /* Greenwich Sidereal Time in seconds since 0:00 */ double lsd; /* Local Sidereal Time in seconds since 0:00 */ double gst0, tsd, dj1, dj0, eqnx; int idj; /* Julian date at 0:00 UT */ idj = (int) sdj; dj0 = (double) idj + 0.5; if (dj0 > sdj) dj0 = dj0 - 1.0; /* Greenwich Sidereal Time at 0:00 UT in seconds */ gst0 = jd2gst (dj0); /* Sidereal seconds since 0:00 */ lsd = (sdj - dj0) * 86400.0; /* Remove longitude for current Greenwich Sidereal Time in seconds */ /* (convert longitude from degrees to seconds of time) */ gst = lsd + (longitude * 240.0); /* Time since 0:00 UT */ tsd = (gst - gst0) / 1.0027379093; /* Julian Date (UT) */ dj1 = dj0 + (tsd / 86400.0); /* Equation of the equinoxes converted to UT seconds */ eqnx = eqeqnx (dj1) / 1.002739093; /* Remove equation of equinoxes */ dj1 = dj1 - (eqnx / 86400.0); if (dj1 < dj0) dj1 = dj1 + 1.0; return (dj1); } /* MST2FD - calculate current UT given Greenwich Mean Sidereal Time * plus date in FITS ISO format (yyyy-mm-ddShh:mm:ss.ss) * Return UT date and time in FITS ISO format */ char * mst2fd (string) char *string; /* UT Date, MST as yyyy-mm-ddShh:mm:ss.ss */ { double sdj, dj; sdj = fd2jd (string); dj = mst2jd (sdj); return (jd2fd (dj)); } /* MST2JD - calculate current UT given Greenwich Mean Sidereal Time * plus date in Julian Date (0:00 UT + Mean Sidereal Time) * Return UT date and time as Julian Date */ double mst2jd (sdj) double sdj; /* UT Date, MST as Julian Date */ { double tsd, djd, st0, dj0, dj; dj0 = (double) ((int) sdj) + 0.5; /* Greenwich Mean Sidereal Time at 0:00 UT in seconds */ st0 = jd2mst (dj0); /* Mean Sidereal Time in seconds */ tsd = (sdj - dj0) * 86400.0; if (tsd < 0.0) tsd = tsd + 86400.0; /* Convert to fraction of a day since 0:00 UT */ djd = ((tsd - st0) / 1.0027379093) / 86400.0; /* Julian Date */ dj = dj0 + djd; if (dj < dj0) dj = dj + (1.0 / 1.0027379093); return (dj); } /* GST2FD - calculate current UT given Greenwich Sidereal Time * plus date in FITS ISO format (yyyy-mm-ddShh:mm:ss.ss) * Return UT date and time in FITS ISO format */ char * gst2fd (string) char *string; /* UT Date, GST as yyyy-mm-ddShh:mm:ss.ss */ { double sdj, dj; sdj = fd2jd (string); dj = gst2jd (sdj); return (jd2fd (dj)); } /* GST2JD - calculate current UT given Greenwich Sidereal Time * plus date as Julian Date (JD at 0:00 UT + sidereal time) * Return UT date and time as Julian Date */ double gst2jd (sdj) double sdj; /* UT Date, GST as Julian Date */ { double dj, tsd, djd, st0, dj0, eqnx; dj0 = (double) ((int) sdj) + 0.5; /* Greenwich Mean Sidereal Time at 0:00 UT in seconds */ st0 = jd2mst (dj0); /* Mean Sidereal Time in seconds */ tsd = (sdj - dj0) * 86400.0; if (tsd < 0.0) tsd = tsd + 86400.0; /* Convert to fraction of a day since 0:00 UT */ djd = ((tsd - st0) / 1.0027379093) / 86400.0; /* Julian Date */ dj = dj0 + djd; /* Equation of the equinoxes (converted to UT seconds) */ eqnx = eqeqnx (dj) / 1.002737909; dj = dj - eqnx / 86400.0; if (dj < dj0) dj = dj + 1.0; return (dj); } /* LST2DT - calculate current UT given Local Sidereal Time as hh.mmsss * plus date as yyyy.mmdd * Return UT time as hh.mmssss */ double lst2dt (date0, time0) double date0; /* UT date as yyyy.mmdd */ double time0; /* LST as hh.mmssss */ { double gst; /* Greenwich Sidereal Time in seconds since 0:00 */ double lst; /* Local Sidereal Time in seconds since 0:00 */ double date1; /* UT date as yyyy.mmdd */ double time1; /* UT as hh.mmssss */ double tsec0, gst0, tsd, tsec; /* Greenwich Sidereal Time at 0:00 UT */ tsec0 = dt2ts (date0, 0.0); gst0 = ts2gst (tsec0); /* Current Greenwich Sidereal Time in seconds */ /* (convert longitude from degrees to seconds of time) */ lst = dt2ts (0.0, time0); gst = lst + (longitude * 240.0); /* Time since 0:00 UT */ tsd = (gst - gst0) / 1.0027379093; /* UT date and time */ tsec = tsec0 + tsd; ts2dt (tsec, &date1, &time1); return (time1); } /* TS2GST - calculate Greenwich Sidereal Time given Universal Time * in seconds since 1951-01-01T0:00:00 * Return sidereal time of day in seconds */ double ts2gst (tsec) double tsec; /* time since 1950.0 in UT seconds */ { double gst; /* Greenwich Sidereal Time in seconds since 0:00 */ double tsd, eqnx, dj; int its; /* Elapsed time as of 0:00 UT */ if (tsec >= 0.0) { its = (int) (tsec + 0.5); tsd = (double) (its % 86400); } else { its = (int) (-tsec + 0.5); tsd = (double) (86400 - (its % 86400)); } /* Mean sidereal time */ gst = ts2mst (tsec); /* Equation of the equinoxes */ dj = ts2jd (tsec); eqnx = eqeqnx (dj); /* Apparent sidereal time at 0:00 ut */ gst = gst + eqnx; /* Current sidereal time */ gst = gst + (tsd * 1.0027379093); gst = dmod (gst,86400.0); return (gst); } /* FD2MST-- convert from FITS date Mean Sidereal Time */ char * fd2mst (string) char *string; /* FITS date string, which may be: fractional year dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard use before 2000) yyyy-mm-dd (FITS standard after 1999) yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ { double gsec, date, time, dj; dj = fd2jd (string); gsec = jd2mst (dj); ts2dt (gsec, &date, &time); date = 0.0; return (dt2fd (date, time)); } /* DT2MST-- convert from UT as yyyy.mmdd hh.mmssss to Mean Sidereal Time in the same format */ void dt2mst (date, time) double *date; /* Date as yyyy.mmdd */ double *time; /* Time as hh.mmssxxxx *if time<0, it is time as -(fraction of a day) */ { double date0, gsec, dj; date0 = *date; dj = dt2jd (*date, *time); gsec = jd2mst (dj); ts2dt (gsec, date, time); *date = date0; return; } /* TS2MST - calculate Greenwich Mean Sidereal Time given Universal Time * in seconds since 1951-01-01T0:00:00 */ double ts2mst (tsec) double tsec; /* time since 1950.0 in UT seconds */ { double dj; dj = ts2jd (tsec); return (jd2mst (dj)); } /* JD2MST - Julian Date to Greenwich Mean Sidereal Time using IAU 2000 * Return sideral time in seconds of time * (from USNO NOVAS package * http://aa.usno.navy.mil/software/novas/novas_info.html */ double jd2mst2 (dj) double dj; /* Julian Date */ { double dt, t, t2, t3, mst, st; dt = dj - 2451545.0; t = dt / 36525.0; t2 = t * t; t3 = t2 * t; /* Compute Greenwich Mean Sidereal Time in seconds */ st = (8640184.812866 * t) + (3155760000.0 * t) - (0.0000062 * t3) + (0.093104 * t2) + 67310.54841; mst = dmod (st, 86400.0); if (mst < 0.0) mst = mst + 86400.0; return (mst); } /* MJD2MST - Modified Julian Date to Greenwich Mean Sidereal Time using IAU 2000 * Return sideral time in seconds of time * (from USNO NOVAS package * http://aa.usno.navy.mil/software/novas/novas_info.html */ double mjd2mst2 (dj) double dj; /* Modified Julian Date */ { double dt, t, t2, t3, mst, st; dt = dj - 51544.5; t = dt / 36525.0; t2 = t * t; t3 = t2 * t; /* Compute Greenwich Mean Sidereal Time in seconds */ st = (8640184.812866 * t) + (3155760000.0 * t) - (0.0000062 * t3) + (0.093104 * t2) + 67310.54841; mst = dmod (st, 86400.0); if (mst < 0.0) mst = mst + 86400.0; return (mst); } /* JD2GST - Julian Date to Greenwich Sideral Time * Return sideral time in seconds of time * (Jean Meeus, Astronomical Algorithms, Willmann-Bell, 1991, pp 83-84) */ double jd2gst (dj) double dj; /* Julian Date */ { double dj0, gmt, gst, tsd, eqnx; int ijd; /* Julian date at 0:00 UT */ ijd = (int) dj; dj0 = (double) ijd + 0.5; if (dj0 > dj) dj0 = dj0 - 1.0; /* UT seconds since 0:00 */ tsd = (dj - dj0) * 86400.0; /* Greenwich mean sidereal time at 0:00 UT in seconds */ gmt = jd2mst (dj0); /* Equation of the equinoxes */ eqnx = eqeqnx (dj); /* Apparent sidereal time at 0:00 ut */ gst = gmt + eqnx; /* Current sidereal time */ gst = gst + (tsd * 1.0027379093); gst = dmod (gst,86400.0); return (gst); } /* EQEQNX - Compute equation of the equinoxes for apparent sidereal time */ double eqeqnx (dj) double dj; /* Julian Date */ { double dt, edj, dpsi, deps, obl, eqnx; /* Convert UT to Ephemeris Time (TDB or TT)*/ dt = utdt (dj); edj = dj + dt / 86400.0; /* Nutation and obliquity */ compnut (edj, &dpsi, &deps, &obl); /* Correct obliquity for nutation */ obl = obl + deps; /* Equation of the equinoxes in seconds */ eqnx = (dpsi * cos (obl)) * 13750.98708; return (eqnx); } /* JD2MST - Julian Date to Mean Sideral Time * Return sideral time in seconds of time * (Jean Meeus, Astronomical Algorithms, Willmann-Bell, 1991, pp 83-84) */ double jd2mst (dj) double dj; /* Julian Date */ { double dt, t, mst; dt = dj - 2451545.0; t = dt / 36525.0; /* Compute Greenwich mean sidereal time in degrees (Meeus, page 84) */ mst = 280.46061837 + (360.98564736629 * dt) + (0.000387933 * t * t) - (t * t * t / 38710000.0); /* Keep degrees between 0 and 360 */ while (mst > 360.0) mst = mst - 360.0; while (mst < 0.0) mst = mst + 360.0; /* Convert to time in seconds (3600 / 15) */ mst = mst * 240.0; return (mst); } /* Compute the longitude and obliquity components of nutation and * mean obliquity from the IAU 1980 theory * References: * Final Report of the IAU Working Group on Nutation, * Chairman P.K.Seidelmann, 1980. * Kaplan,G.H., 1981, USNO Circular No. 163, pa3-6. * * From Fortran code by P.T. Wallace Starlink september 1987 */ void compnut (dj, dpsi, deps, eps0) double dj; /* TDB (loosely ET or TT) as Julian Date */ double *dpsi; /* Nutation in longitude in radians (returned) */ double *deps; /* Nutation in obliquity in radians (returned) */ double *eps0; /* Mean obliquity in radians (returned) */ { double t2as,as2r,u2r; double t,el,el2,el3; double elp,elp2; double f,f2,f4; double d,d2,d4; double om,om2; double dp,de; double a; /* Turns to arc seconds */ t2as = 1296000.0; /* Arc seconds to radians */ as2r = 0.000004848136811095359949; /* Units of 0.0001 arcsec to radians */ u2r = as2r / 10000.0; /* Basic epoch J2000.0 to current epoch in Julian Centuries */ t = (dj - 2400000.5 - 51544.5 ) / 36525.0; /* Fundamental arguments in the FK5 reference system */ /* mean longitude of the moon minus mean longitude of the moon's perigee */ el = as2r*(485866.733 + (1325.0 * t2as+715922.633 + (31.310 +0.064*t)*t)*t); /* mean longitude of the sun minus mean longitude of the sun's perigee */ elp = as2r*(1287099.804 + (99.0 * t2as+1292581.224 + (-0.577 -0.012*t)*t)*t); /* mean longitude of the moon minus mean longitude of the moon's node */ f = as2r*(335778.877 + (1342.0 * t2as+295263.137 + (-13.257 + 0.011*t)*t)*t); /* mean elongation of the moon from the sun */ d = as2r*(1072261.307 + (1236.0 * t2as+1105601.328 + (-6.891 + 0.019*t)*t)*t); /* longitude of the mean ascending node of the lunar orbit on the */ /* ecliptic, measured from the mean equinox of date */ om = as2r * (450160.280 + (-5.0 * t2as-482890.539 + (7.455 +0.008*t)*t)*t); /* Multiples of arguments */ el2 = el + el; el3 = el2 + el; elp2 = elp + elp; f2 = f + f; f4 = f2 + f2; d2 = d + d; d4 = d2 + d2; om2 = om + om; /* Series for the nutation */ dp = 0.0; de = 0.0; /* 106 */ dp = dp + sin (elp+d); /* 105 */ dp = dp - sin (f2 + d4 + om2); /* 104 */ dp = dp + sin (el2 + d2); /* 103 */ dp = dp - sin (el - f2 + d2); /* 102 */ dp = dp - sin (el + elp - d2 + om); /* 101 */ dp = dp - sin (-elp + f2 + om); /* 100 */ dp = dp - sin (el - f2 - d2); /* 99 */ dp = dp - sin (elp + d2); /* 98 */ dp = dp - sin (f2 - d + om2); /* 97 */ dp = dp - sin (-f2 + om); /* 96 */ dp = dp + sin (-el - elp + d2 + om); /* 95 */ dp = dp + sin (elp + f2 + om); /* 94 */ dp = dp - sin (el + f2 - d2); /* 93 */ dp = dp + sin(el3 + f2 - d2 + om2); /* 92 */ dp = dp + sin(f4 - d2 + om2); /* 91 */ dp = dp - sin(el + d2 + om); /* 90 */ dp = dp - sin(el2 + f2 + d2 + om2); /* 89 */ a = el2 + f2 - d2 + om; dp = dp + sin(a); de = de - cos(a); /* 88 */ dp = dp + (sin(el - elp - d2)); /* 87 */ dp = dp + (sin(-el + f4 + om2)); /* 86 */ a = -el2 + f2 + d4 + om2; dp = dp - sin(a); de = de + cos(a); /* 85 */ a = el + f2 + d2 + om; dp = dp - sin(a); de = de + cos(a); /* 84 */ a = el + elp + f2 - d2 + om2; dp = dp + sin(a); de = de - cos(a); /* 83 */ dp = dp - sin(el2 - d4); /* 82 */ a = -el + f2 + d4 + om2; dp = dp - (2.0 * sin(a)); de = de + cos(a); /* 81 */ a = -el2 + f2 + d2 + om2; dp = dp + sin(a); de = de - cos(a); /* 80 */ dp = dp - sin(el - d4); /* 79 */ a = -el + om2; dp = dp + sin(a); de = de - cos(a); /* 78 */ a = f2 + d + om2; dp = dp + (2.0 * sin(a)); de = de - cos(a); /* 77 */ dp = dp + (2.0 * sin(el3)); /* 76 */ a = el + om2; dp = dp - (2.0 * sin(a)); de = de + cos(a); /* 75 */ a = el2 + om; dp = dp + (2.0 * sin(a)); de = de - cos(a); /* 74 */ a = - el + f2 - d2 + om; dp = dp - (2.0 * sin(a)); de = de + cos(a); /* 73 */ a = el + elp + f2 + om2; dp = dp + (2.0 * sin(a)); de = de - cos(a); /* 72 */ a = -elp + f2 + d2 + om2; dp = dp - (3.0 * sin(a)); de = de + cos(a); /* 71 */ a = el3 + f2 + om2; dp = dp - (3.0 * sin(a)); de = de + cos(a); /* 70 */ a = -el2 + om; dp = dp - (2.0 * sin(a)); de = de + cos(a); /* 69 */ a = -el - elp + f2 + d2 + om2; dp = dp - (3.0 * sin(a)); de = de + cos(a); /* 68 */ a = el - elp + f2 + om2; dp = dp - (3.0 * sin(a)); de = de + cos(a); /* 67 */ dp = dp + (3.0 * sin(el + f2)); /* 66 */ dp = dp - (3.0 * sin(el + elp)); /* 65 */ dp = dp - (4.0 * sin(d)); /* 64 */ dp = dp + (4.0 * sin(el - f2)); /* 63 */ dp = dp - (4.0 * sin(elp - d2)); /* 62 */ a = el2 + f2 + om; dp = dp - (5.0 * sin(a)); de = de + (3.0 * cos(a)); /* 61 */ dp = dp + (5.0 * sin(el - elp)); /* 60 */ a = -d2 + om; dp = dp - (5.0 * sin(a)); de = de + (3.0 * cos(a)); /* 59 */ a = el + f2 - d2 + om; dp = dp + (6.0 * sin(a)); de = de - (3.0 * cos(a)); /* 58 */ a = f2 + d2 + om; dp = dp - (7.0 * sin(a)); de = de + (3.0 * cos(a)); /* 57 */ a = d2 + om; dp = dp - (6.0 * sin(a)); de = de + (3.0 * cos(a)); /* 56 */ a = el2 + f2 - d2 + om2; dp = dp + (6.0 * sin(a)); de = de - (3.0 * cos(a)); /* 55 */ dp = dp + (6.0 * sin(el + d2)); /* 54 */ a = el + f2 + d2 + om2; dp = dp - (8.0 * sin(a)); de = de + (3.0 * cos(a)); /* 53 */ a = -elp + f2 + om2; dp = dp - (7.0 * sin(a)); de = de + (3.0 * cos(a)); /* 52 */ a = elp + f2 + om2; dp = dp + (7.0 * sin(a)); de = de - (3.0 * cos(a)); /* 51 */ dp = dp - (7.0 * sin(el + elp - d2)); /* 50 */ a = -el + f2 + d2 + om; dp = dp - (10.0 * sin(a)); de = de + (5.0 * cos(a)); /* 49 */ a = el - d2 + om; dp = dp - (13.0 * sin(a)); de = de + (7.0 * cos(a)); /* 48 */ a = -el + d2 + om; dp = dp + (16.0 * sin(a)); de = de - (8.0 * cos(a)); /* 47 */ a = - el + f2 + om; dp = dp + (21.0 * sin(a)); de = de - (10.0 * cos(a)); /* 46 */ dp = dp + (26.0 * sin(f2)); de = de - cos(f2); /* 45 */ a = el2 + f2 + om2; dp = dp - (31.0 * sin(a)); de = de + (13.0 * cos(a)); /* 44 */ a = el + f2 - d2 + om2; dp = dp + (29.0 * sin(a)); de = de - (12.0 * cos(a)); /* 43 */ dp = dp + (29.0 * sin(el2)); de = de - cos(el2); /* 42 */ a = f2 + d2 + om2; dp = dp - (38.0 * sin(a)); de = de + (16.0 * cos(a)); /* 41 */ a = el + f2 + om; dp = dp - (51.0 * sin(a)); de = de + (27.0 * cos(a)); /* 40 */ a = -el + f2 + d2 + om2; dp = dp - (59.0 * sin(a)); de = de + (26.0 * cos(a)); /* 39 */ a = -el + om; dp = dp + ((-58.0 - 0.1 * t) * sin(a)); de = de + (32.0 * cos(a)); /* 38 */ a = el + om; dp = dp + ((63.0 + 0.1 * t) * sin(a)); de = de - (33.0 * cos(a)); /* 37 */ dp = dp + (63.0 * sin(d2)); de = de - (2.0 * cos(d2)); /* 36 */ a = -el + f2 + om2; dp = dp + (123.0 * sin(a)); de = de - (53.0 * cos(a)); /* 35 */ a = el - d2; dp = dp - (158.0 * sin(a)); de = de - cos(a); /* 34 */ a = el + f2 + om2; dp = dp - (301.0 * sin(a)); de = de + ((129.0 - 0.1 * t) * cos(a)); /* 33 */ a = f2 + om; dp = dp + ((-386.0 - 0.4 * t) * sin(a)); de = de + (200.0 * cos(a)); /* 32 */ dp = dp + ((712.0 + 0.1 * t) * sin(el)); de = de - (7.0 * cos(el)); /* 31 */ a = f2 + om2; dp = dp + ((-2274.0 - 0.2 * t) * sin(a)); de = de + ((977.0 - 0.5 * t) * cos(a)); /* 30 */ dp = dp - sin(elp + f2 - d2); /* 29 */ dp = dp + sin(-el + d + om); /* 28 */ dp = dp + sin(elp + om2); /* 27 */ dp = dp - sin(elp - f2 + d2); /* 26 */ dp = dp + sin(-f2 + d2 + om); /* 25 */ dp = dp + sin(el2 + elp - d2); /* 24 */ dp = dp - (4.0 * sin(el - d)); /* 23 */ a = elp + f2 - d2 + om; dp = dp + (4.0 * sin(a)); de = de - (2.0 * cos(a)); /* 22 */ a = el2 - d2 + om; dp = dp + (4.0 * sin(a)); de = de - (2.0 * cos(a)); /* 21 */ a = -elp + f2 - d2 + om; dp = dp - (5.0 * sin(a)); de = de + (3.0 * cos(a)); /* 20 */ a = -el2 + d2 + om; dp = dp - (6.0 * sin(a)); de = de + (3.0 * cos(a)); /* 19 */ a = -elp + om; dp = dp - (12.0 * sin(a)); de = de + (6.0 * cos(a)); /* 18 */ a = elp2 + f2 - d2 + om2; dp = dp + ((-16.0 + (0.1 * t)) * sin(a)); de = de + (7.0 * cos(a)); /* 17 */ a = elp + om; dp = dp - (15.0 * sin(a)); de = de + (9.0 * cos(a)); /* 16 */ dp = dp + ((17.0 - (0.1 * t)) * sin(elp2)); /* 15 */ dp = dp - (22.0 * sin(f2 - d2)); /* 14 */ a = el2 - d2; dp = dp + (48.0 * sin(a)); de = de + cos(a); /* 13 */ a = f2 - d2 + om; dp = dp + ((129.0 + (0.1 * t)) * sin(a)); de = de - (70.0 * cos(a)); /* 12 */ a = - elp + f2 - d2 + om2; dp = dp + ((217.0 - 0.5 * t) * sin(a)); de = de + ((-95.0 + 0.3 * t) * cos(a)); /* 11 */ a = elp + f2 - d2 + om2; dp = dp + ((-517.0 + (1.2 * t)) * sin(a)); de = de + ((224.0 - (0.6 * t)) * cos(a)); /* 10 */ dp = dp + ((1426.0 - (3.4 * t)) * sin(elp)); de = de + ((54.0 - (0.1 * t)) * cos(elp)); /* 9 */ a = f2 - d2 + om2; dp = dp + ((-13187.0 - (1.6 * t)) * sin(a)); de = de + ((5736.0 - (3.1 * t)) * cos(a)); /* 8 */ dp = dp + sin(el2 - f2 + om); /* 7 */ a = -elp2 + f2 - d2 + om; dp = dp - (2.0 * sin(a)); de = de + (1.0 * cos(a)); /* 6 */ dp = dp - (3.0 * sin(el - elp - d)); /* 5 */ a = - el2 + f2 + om2; dp = dp - (3.0 * sin(a)); de = de + (1.0 * cos(a)); /* 4 */ dp = dp + (11.0 * sin (el2 - f2)); /* 3 */ a = - el2 + f2 + om; dp = dp + (46.0 * sin(a)); de = de - (24.0 * cos(a)); /* 2 */ dp = dp + ((2062.0 + (0.2 * t)) * sin(om2)); de = de + ((-895.0 + (0.5 * t)) * cos(om2)); /* 1 */ dp = dp + ((-171996.0 - (174.2 * t)) * sin(om)); de = de + ((92025.0 + (8.9 * t)) * cos(om)); /* Convert results to radians */ *dpsi = dp * u2r; *deps = de * u2r; /* Mean Obliquity in radians */ *eps0 = as2r * (84381.448 + (-46.8150 + (-0.00059 + (0.001813*t)*t)*t)); return; } /* ISDATE - Return 1 if string is an old or ISO FITS standard date */ int isdate (string) char *string; /* Possible FITS date string, which may be: dd/mm/yy (FITS standard before 2000) dd-mm-yy (nonstandard FITS use before 2000) yyyy-mm-dd (FITS standard after 1999) yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ { int iyr = 0; /* year (returned) */ int imon = 0; /* month (returned) */ int iday = 0; /* day (returned) */ int i; char *sstr, *dstr, *tstr, *nval; /* Translate string from ASCII to binary */ if (string == NULL) return (0); sstr = strchr (string,'/'); dstr = strchr (string,'-'); if (dstr == string) dstr = strchr (string+1,'-'); tstr = strchr (string,'T'); /* Original FITS date format: dd/mm/yy */ if (sstr > string) { *sstr = '\0'; iday = (int) atof (string); *sstr = '/'; nval = sstr + 1; sstr = strchr (nval,'/'); if (sstr == NULL) sstr = strchr (nval,'-'); if (sstr > string) { *sstr = '\0'; imon = (int) atof (nval); *sstr = '/'; nval = sstr + 1; iyr = (int) atof (nval); if (iyr < 1000) iyr = iyr + 1900; } if (imon > 0 && iday > 0) return (1); else return (0); } /* New FITS date format: yyyy-mm-ddThh:mm:ss[.sss] */ else if (dstr > string) { *dstr = '\0'; iyr = (int) atof (string); nval = dstr + 1; *dstr = '-'; dstr = strchr (nval,'-'); imon = 0; iday = 0; /* Decode year, month, and day */ if (dstr > string) { *dstr = '\0'; imon = (int) atof (nval); *dstr = '-'; nval = dstr + 1; if (tstr > string) *tstr = '\0'; iday = (int) atof (nval); if (tstr > string) *tstr = 'T'; } /* If day is > 31, it is really year in old format */ if (iday > 31) { i = iyr; if (iday < 100) iyr = iday + 1900; else iyr = iday; iday = i; } if (imon > 0 && iday > 0) return (1); else return (0); } /* If FITS date is entered as an epoch, return 0 anyway */ else return (0); } /* Round seconds and make sure date and time numbers are within limits */ static void fixdate (iyr, imon, iday, ihr, imn, sec, ndsec) int *iyr; /* year (returned) */ int *imon; /* month (returned) */ int *iday; /* day (returned) */ int *ihr; /* hours (returned) */ int *imn; /* minutes (returned) */ double *sec; /* seconds (returned) */ int ndsec; /* Number of decimal places in seconds (0=int) */ { double days; /* Round seconds to 0 - 4 decimal places (no rounding if <0, >4) */ if (ndsec == 0) *sec = dint (*sec + 0.5); else if (ndsec < 2) *sec = dint (*sec * 10.0 + 0.5) / 10.0; else if (ndsec < 3) *sec = dint (*sec * 100.0 + 0.5) / 100.0; else if (ndsec < 4) *sec = dint (*sec * 1000.0 + 0.5) / 1000.0; else if (ndsec < 5) *sec = dint (*sec * 10000.0 + 0.5) / 10000.0; /* Adjust minutes and hours */ if (*sec > 60.0) { *sec = *sec - 60.0; *imn = *imn + 1; } if (*imn > 60) { *imn = *imn - 60; *ihr = *ihr + 1; } /* Return if no date */ if (*iyr == 0 && *imon == 0 && *iday == 0) return; /* Adjust date */ if (*ihr > 23) { *ihr = *ihr - 24; *iday = *iday + 1; } days = caldays (*iyr, *imon); if (*iday > days) { *iday = *iday - days; *imon = *imon + 1; } if (*iday < 1) { *imon = *imon - 1; if (*imon < 1) { *imon = *imon + 12; *iyr = *iyr - 1; } days = caldays (*iyr, *imon); *iday = *iday + days; } if (*imon < 1) { *imon = *imon + 12; *iyr = *iyr - 1; days = caldays (*iyr, *imon); if (*iday > days) { *iday = *iday - days; *imon = *imon + 1; } } if (*imon > 12) { *imon = *imon - 12; *iyr = *iyr + 1; } return; } /* Calculate days in month 1-12 given year (Gregorian calendar only) */ static int caldays (year, month) int year; /* 4-digit year */ int month; /* Month (1=January, 2=February, etc.) */ { if (month < 1) { month = month + 12; year = year + 1; } if (month > 12) { month = month - 12; year = year + 1; } switch (month) { case 1: return (31); case 2: if (year%400 == 0) return (29); else if (year%100 == 0) return (28); else if (year%4 == 0) return (29); else return (28); case 3: return (31); case 4: return (30); case 5: return (31); case 6: return (30); case 7: return (31); case 8: return (31); case 9: return (30); case 10: return (31); case 11: return (30); case 12: return (31); default: return (0); } } static double dint (dnum) double dnum; { double dn; if (dnum < 0.0) dn = -floor (-dnum); else dn = floor (dnum); return (dn); } static double dmod (dnum, dm) double dnum, dm; { double dnumx, dnumi, dnumf; if (dnum < 0.0) dnumx = -dnum; else dnumx = dnum; dnumi = dint (dnumx / dm); if (dnum < 0.0) dnumf = dnum + (dnumi * dm); else if (dnum > 0.0) dnumf = dnum - (dnumi * dm); else dnumf = 0.0; return (dnumf); } /* Jul 1 1999 New file, based on iolib/jcon.f and iolib/vcon.f and hgetdate() * Oct 21 1999 Fix declarations after lint * Oct 27 1999 Fix bug to return epoch if fractional year input * Dec 9 1999 Fix bug in ts2jd() found by Pete Ratzlaff (SAO) * Dec 17 1999 Add all unimplemented conversions * Dec 20 1999 Add isdate(); leave date, time strings unchanged in fd2i() * Dec 20 1999 Make all fd2*() subroutines deal with time alone * * Jan 3 2000 In old FITS format, year 100 is assumed to be 2000 * Jan 11 2000 Fix epoch to date conversion so .0 is 0:00, not 12:00 * Jan 21 2000 Add separate Besselian and Julian epoch computations * Jan 28 2000 Add Modified Julian Date conversions * Mar 2 2000 Implement decimal places for FITS date string * Mar 14 2000 Fix bug in dealing with 2000-02-29 in ts2i() * Mar 22 2000 Add lt2* and ut2* to get current time as local and UT * Mar 24 2000 Fix calloc() calls * Mar 24 2000 Add tsi2* and tsu2* to convert IRAF and Unix seconds * May 1 2000 In old FITS format, all years < 1000 get 1900 added to them * Aug 1 2000 Make ep2jd and jd2ep consistently starting at 1/1 0:00 * * Jan 11 2001 Print all messages to stderr * May 21 2001 Add day of year conversions * May 25 2001 Allow fraction of day in FITS date instead of time * * Apr 8 2002 Change all long declaration to time_t * May 13 2002 Fix bugs found by lint * Jul 5 2002 Fix bug in fixdate() so fractional seconds come out * Jul 8 2002 Fix rounding bug in t2i() * Jul 8 2002 Try Fliegel and Van Flandern's algorithm for JD to UT date * Jul 8 2002 If first character of string is -, check for other -'s in isdate * Sep 10 2002 Add ET/TDT/TT conversion from UT subroutines * Sep 10 2002 Add sidereal time conversions * * Jan 30 2003 Fix typo in ts2gst() * Mar 7 2003 Add conversions for heliocentric julian dates * May 20 2003 Declare nd in setdatedec() * Jul 18 2003 Add code to parse Las Campanas dates * * Mar 24 2004 If ndec > 0, add UT to FITS date even if it is 0:00:00 * * Oct 14 2005 Add tsd2fd() and tsd2dt() * * May 3 2006 Drop declaration of unused variables * Jun 20 2006 Initialized uninitialized variables * Aug 2 2006 Add local sidereal time * Sep 13 2006 Add more local sidereal time subroutines * Oct 2 2006 Add UT to old FITS date conversions * Oct 6 2006 Add eqeqnx() to compute equation of the equinoxes * * Jan 8 2007 Remove unused variables */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/distort.c000066400000000000000000000235051215713201500221140ustar00rootroot00000000000000/* * pbiereic 16.07.08 Added routine getfilesize() and system includes */ /*** File libwcs/distort.c *** January 4, 2007 *** By Doug Mink, dmink@cfa.harvard.edu, *** Based on code written by Jing Li, IPAC *** Harvard-Smithsonian Center for Astrophysics *** Copyright (C) 2004-2007 *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Correspondence concerning WCSTools should be addressed as follows: Internet email: dmink@cfa.harvard.edu Postal address: Doug Mink Smithsonian Astrophysical Observatory 60 Garden St. Cambridge, MA 02138 USA * Module: distort.c (World Coordinate Systems) * Purpose: Convert focal plane coordinates to pixels and vice versa: * Subroutine: distortinit (wcs, hstring) set distortion coefficients from FITS header * Subroutine: DelDistort (header, verbose) delete distortion coefficients in FITS header * Subroutine: pix2foc (wcs, x, y, u, v) pixel coordinates -> focal plane coordinates * Subroutine: foc2pix (wcs, u, v, x, y) focal plane coordinates -> pixel coordinates * Subroutine: setdistcode (wcs,ctype) sets distortion code from CTYPEi * Subroutine: getdistcode (wcs) returns distortion code string for CTYPEi */ #include #include #include #include #include #include #include #include "wcs.h" void distortinit (wcs, hstring) struct WorldCoor *wcs; /* World coordinate system structure */ const char *hstring; /* character string containing FITS header information in the format = [/ ] */ { int i, j, m; char keyword[12]; /* Read distortion coefficients, if present */ if (wcs->distcode == DISTORT_SIRTF) { if (wcs->wcsproj == WCS_OLD) { wcs->wcsproj = WCS_NEW; wcs->distort.a_order = 0; wcs->distort.b_order = 0; wcs->distort.ap_order = 0; wcs->distort.bp_order = 0; } else { if (!hgeti4 (hstring, "A_ORDER", &wcs->distort.a_order)) { setwcserr ("DISTINIT: Missing A_ORDER keyword for SIRTF distortion"); } else { m = wcs->distort.a_order; for (i = 0; i <= m; i++) { for (j = 0; j <= m; j++) { wcs->distort.a[i][j] = 0.0; } } for (i = 0; i <= m; i++) { for (j = 0; j <= m-i; j++) { sprintf (keyword, "A_%d_%d", i, j); hgetr8 (hstring, keyword, &wcs->distort.a[i][j]); } } } if (!hgeti4 (hstring, "B_ORDER", &wcs->distort.b_order)) { setwcserr ("DISTINIT: Missing B_ORDER keyword for SIRTF distortion"); } else { m = wcs->distort.b_order; for (i = 0; i <= m; i++) { for (j = 0; j <= m; j++) { wcs->distort.b[i][j] = 0.0; } } for (i = 0; i <= m; i++) { for (j = 0; j <= m-i; j++) { sprintf (keyword, "B_%d_%d", i, j); hgetr8 (hstring, keyword, &wcs->distort.b[i][j]); } } } if (!hgeti4 (hstring, "AP_ORDER", &wcs->distort.ap_order)) { setwcserr ("DISTINIT: Missing AP_ORDER keyword for SIRTF distortion"); } else { m = wcs->distort.ap_order; for (i = 0; i <= m; i++) { for (j = 0; j <= m; j++) { wcs->distort.ap[i][j] = 0.0; } } for (i = 0; i <= m; i++) { for (j = 0; j <= m-i; j++) { sprintf (keyword, "AP_%d_%d", i, j); hgetr8 (hstring, keyword, &wcs->distort.ap[i][j]); } } } if (!hgeti4 (hstring, "BP_ORDER", &wcs->distort.bp_order)) { setwcserr ("DISTINIT: Missing BP_ORDER keyword for SIRTF distortion"); } else { m = wcs->distort.bp_order; for (i = 0; i <= m; i++) { for (j = 0; j <= m; j++) { wcs->distort.bp[i][j] = 0.0; } } for (i = 0; i <= m; i++) { for (j = 0; j <= m-i; j++) { sprintf (keyword, "BP_%d_%d", i, j); hgetr8 (hstring, keyword, &wcs->distort.bp[i][j]); } } } } } return; } /* Delete all distortion-related fields. * return 0 if at least one such field is found, else -1. */ int DelDistort (header, verbose) char *header; int verbose; { char keyword[16]; char str[32]; int i, j, m; int lctype; int n; n = 0; if (hgeti4 (header, "A_ORDER", &m)) { for (i = 0; i <= m; i++) { for (j = 0; j <= m-i; j++) { sprintf (keyword, "A_%d_%d", i, j); hdel (header, keyword); n++; } } hdel (header, "A_ORDER"); n++; } if (hgeti4 (header, "AP_ORDER", &m)) { for (i = 0; i <= m; i++) { for (j = 0; j <= m-i; j++) { sprintf (keyword, "AP_%d_%d", i, j); hdel (header, keyword); n++; } } hdel (header, "AP_ORDER"); n++; } if (hgeti4 (header, "B_ORDER", &m)) { for (i = 0; i <= m; i++) { for (j = 0; j <= m-i; j++) { sprintf (keyword, "B_%d_%d", i, j); hdel (header, keyword); n++; } } hdel (header, "B_ORDER"); n++; } if (hgeti4 (header, "BP_ORDER", &m)) { for (i = 0; i <= m; i++) { for (j = 0; j <= m-i; j++) { sprintf (keyword, "BP_%d_%d", i, j); hdel (header, keyword); n++; } } hdel (header, "BP_ORDER"); n++; } if (n > 0 && verbose) fprintf (stderr,"%d keywords deleted\n", n); /* Remove WCS distortion code from CTYPEi in FITS header */ if (hgets (header, "CTYPE1", 31, str)) { lctype = strlen (str); if (lctype > 8) { str[8] = (char) 0; hputs (header, "CTYPE1", str); } } if (hgets (header, "CTYPE2", 31, str)) { lctype = strlen (str); if (lctype > 8) { str[8] = (char) 0; hputs (header, "CTYPE2", str); } } return (n); } void foc2pix (wcs, x, y, u, v) struct WorldCoor *wcs; /* World coordinate system structure */ double x, y; /* Focal plane coordinates */ double *u, *v; /* Image pixel coordinates (returned) */ { int m, n, i, j, k; double s[DISTMAX], sum; double temp_x, temp_y; /* SIRTF distortion */ if (wcs->distcode == DISTORT_SIRTF) { m = wcs->distort.ap_order; n = wcs->distort.bp_order; temp_x = x - wcs->xrefpix; temp_y = y - wcs->yrefpix; /* compute u */ for (j = 0; j <= m; j++) { s[j] = wcs->distort.ap[m-j][j]; for (k = j-1; k >= 0; k--) { s[j] = (temp_y * s[j]) + wcs->distort.ap[m-j][k]; } } sum = s[0]; for (i=m; i>=1; i--){ sum = (temp_x * sum) + s[m-i+1]; } *u = sum; /* compute v*/ for (j = 0; j <= n; j++) { s[j] = wcs->distort.bp[n-j][j]; for (k = j-1; k >= 0; k--) { s[j] = temp_y*s[j] + wcs->distort.bp[n-j][k]; } } sum = s[0]; for (i = n; i >= 1; i--) sum = temp_x * sum + s[n-i+1]; *v = sum; *u = x + *u; *v = y + *v; } /* If no distortion, return pixel positions unchanged */ else { *u = x; *v = y; } return; } void pix2foc (wcs, u, v, x, y) struct WorldCoor *wcs; /* World coordinate system structure */ double u, v; /* Image pixel coordinates */ double *x, *y; /* Focal plane coordinates (returned) */ { int m, n, i, j, k; double s[DISTMAX], sum; double temp_u, temp_v; /* SIRTF distortion */ if (wcs->distcode == DISTORT_SIRTF) { m = wcs->distort.a_order; n = wcs->distort.b_order; temp_u = u - wcs->xrefpix; temp_v = v - wcs->yrefpix; /* compute u */ for (j = 0; j <= m; j++) { s[j] = wcs->distort.a[m-j][j]; for (k = j-1; k >= 0; k--) { s[j] = (temp_v * s[j]) + wcs->distort.a[m-j][k]; } } sum = s[0]; for (i=m; i>=1; i--){ sum = temp_u*sum + s[m-i+1]; } *x = sum; /* compute v*/ for (j=0; j<=n; j++) { s[j] = wcs->distort.b[n-j][j]; for (k=j-1; k>=0; k--) { s[j] =temp_v*s[j] + wcs->distort.b[n-j][k]; } } sum = s[0]; for (i=n; i>=1; i--) sum = temp_u*sum + s[n-i+1]; *y = sum; *x = u + *x; *y = v + *y; /* *x = u + *x + coeff.crpix1; */ /* *y = v + *y + coeff.crpix2; */ } /* If no distortion, return pixel positions unchanged */ else { *x = u; *y = v; } return; } /* SETDISTCODE -- Set WCS distortion code from CTYPEi in FITS header */ void setdistcode (wcs, ctype) struct WorldCoor *wcs; /* World coordinate system structure */ char *ctype; /* Value of CTYPEi from FITS header */ { char *extension; int lctype; lctype = strlen (ctype); if (lctype < 9) wcs->distcode = DISTORT_NONE; else { extension = ctype + 8; if (!strncmp (extension, "-SIP", 4)) wcs->distcode = DISTORT_SIRTF; else wcs->distcode = DISTORT_NONE; } return; } /* GETDISTCODE -- Return NULL if no distortion or code from wcs.h */ char * getdistcode (wcs) struct WorldCoor *wcs; /* World coordinate system structure */ { char *dcode; /* Distortion string for CTYPEi */ if (wcs->distcode == DISTORT_SIRTF) { dcode = (char *) calloc (8, sizeof (char)); strcpy (dcode, "-SIP"); } else dcode = NULL; return (dcode); } int getfilesize (filename) char *filename; /* Name of file for which to find size */ { struct stat statbuff; if (stat (filename, &statbuff)) return (0); else return ((int) statbuff.st_size); } /* Apr 2 2003 New subroutines * Nov 3 2003 Add getdistcode to return distortion code string * Nov 10 2003 Include unistd.h to get definition of NULL * Nov 18 2003 Include string.h to get strlen() * * Jan 9 2004 Add DelDistort() to delete distortion keywords * * Jan 4 2007 Declare header const char* */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/dsspos.c000066400000000000000000000263261215713201500217430ustar00rootroot00000000000000/*** File saoimage/wcslib/dsspos.c *** October 21, 1999 *** By Doug Mink, dmink@cfa.harvard.edu *** Harvard-Smithsonian Center for Astrophysics *** Copyright (C) 1995-2002 *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Correspondence concerning WCSTools should be addressed as follows: Internet email: dmink@cfa.harvard.edu Postal address: Doug Mink Smithsonian Astrophysical Observatory 60 Garden St. Cambridge, MA 02138 USA * Module: dsspos.c (Plate solution WCS conversion) * Purpose: Compute WCS from Digital Sky Survey plate fit * Subroutine: dsspos() converts from pixel location to RA,Dec * Subroutine: dsspix() converts from RA,Dec to pixel location These functions are based on the astrmcal.c portion of GETIMAGE by J. Doggett and the documentation distributed with the Digital Sky Survey. */ #include #include #include #include "wcs.h" int dsspos (xpix, ypix, wcs, xpos, ypos) /* Routine to determine accurate position for pixel coordinates */ /* returns 0 if successful otherwise 1 = angle too large for projection; */ /* based on amdpos() from getimage */ /* Input: */ double xpix; /* x pixel number (RA or long without rotation) */ double ypix; /* y pixel number (dec or lat without rotation) */ struct WorldCoor *wcs; /* WCS parameter structure */ /* Output: */ double *xpos; /* Right ascension or longitude in degrees */ double *ypos; /* Declination or latitude in degrees */ { double x, y, xmm, ymm, xmm2, ymm2, xmm3, ymm3, x2y2; double xi, xir, eta, etar, raoff, ra, dec; double cond2r = 1.745329252e-2; double cons2r = 206264.8062470964; double twopi = 6.28318530717959; double ctan, ccos; /* Ignore magnitude and color terms double mag = 0.0; double color = 0.0; */ /* Convert from image pixels to plate pixels */ x = xpix + wcs->x_pixel_offset - 1.0 + 0.5; y = ypix + wcs->y_pixel_offset - 1.0 + 0.5; /* Convert from pixels to millimeters */ xmm = (wcs->ppo_coeff[2] - x * wcs->x_pixel_size) / 1000.0; ymm = (y * wcs->y_pixel_size - wcs->ppo_coeff[5]) / 1000.0; xmm2 = xmm * xmm; ymm2 = ymm * ymm; xmm3 = xmm * xmm2; ymm3 = ymm * ymm2; x2y2 = xmm2 + ymm2; /* Compute coordinates from x,y and plate model */ xi = wcs->x_coeff[ 0]*xmm + wcs->x_coeff[ 1]*ymm + wcs->x_coeff[ 2] + wcs->x_coeff[ 3]*xmm2 + wcs->x_coeff[ 4]*xmm*ymm + wcs->x_coeff[ 5]*ymm2 + wcs->x_coeff[ 6]*(x2y2) + wcs->x_coeff[ 7]*xmm3 + wcs->x_coeff[ 8]*xmm2*ymm + wcs->x_coeff[ 9]*xmm*ymm2 + wcs->x_coeff[10]*ymm3 + wcs->x_coeff[11]*xmm*(x2y2) + wcs->x_coeff[12]*xmm*x2y2*x2y2; /* Ignore magnitude and color terms + wcs->x_coeff[13]*mag + wcs->x_coeff[14]*mag*mag + wcs->x_coeff[15]*mag*mag*mag + wcs->x_coeff[16]*mag*xmm + wcs->x_coeff[17]*mag*x2y2 + wcs->x_coeff[18]*mag*xmm*x2y2 + wcs->x_coeff[19]*color; */ eta = wcs->y_coeff[ 0]*ymm + wcs->y_coeff[ 1]*xmm + wcs->y_coeff[ 2] + wcs->y_coeff[ 3]*ymm2 + wcs->y_coeff[ 4]*xmm*ymm + wcs->y_coeff[ 5]*xmm2 + wcs->y_coeff[ 6]*(x2y2) + wcs->y_coeff[ 7]*ymm3 + wcs->y_coeff[ 8]*ymm2*xmm + wcs->y_coeff[ 9]*ymm*xmm2 + wcs->y_coeff[10]*xmm3 + wcs->y_coeff[11]*ymm*(x2y2) + wcs->y_coeff[12]*ymm*x2y2*x2y2; /* Ignore magnitude and color terms + wcs->y_coeff[13]*mag + wcs->y_coeff[14]*mag*mag + wcs->y_coeff[15]*mag*mag*mag + wcs->y_coeff[16]*mag*ymm + wcs->y_coeff[17]*mag*x2y2) + wcs->y_coeff[18]*mag*ymm*x2y2 + wcs->y_coeff[19]*color; */ /* Convert to radians */ xir = xi / cons2r; etar = eta / cons2r; /* Convert to RA and Dec */ ctan = tan (wcs->plate_dec); ccos = cos (wcs->plate_dec); raoff = atan2 (xir / ccos, 1.0 - etar * ctan); ra = raoff + wcs->plate_ra; if (ra < 0.0) ra = ra + twopi; *xpos = ra / cond2r; dec = atan (cos (raoff) * ((etar + ctan) / (1.0 - (etar * ctan)))); *ypos = dec / cond2r; return 0; } int dsspix (xpos, ypos, wcs, xpix, ypix) /* Routine to determine pixel coordinates for sky position */ /* returns 0 if successful otherwise 1 = angle too large for projection; */ /* based on amdinv() from getimage */ /* Input: */ double xpos; /* Right ascension or longitude in degrees */ double ypos; /* Declination or latitude in degrees */ struct WorldCoor *wcs; /* WCS parameter structure */ /* Output: */ double *xpix; /* x pixel number (RA or long without rotation) */ double *ypix; /* y pixel number (dec or lat without rotation) */ { double div,xi,eta,x,y,xy,x2,y2,x2y,y2x,x3,y3,x4,y4,x2y2,cjunk,dx,dy; double sypos,cypos,syplate,cyplate,sxdiff,cxdiff; double f,fx,fy,g,gx,gy, xmm, ymm; double conr2s = 206264.8062470964; double tolerance = 0.0000005; int max_iterations = 50; int i; double xr, yr; /* position in radians */ *xpix = 0.0; *ypix = 0.0; /* Convert RA and Dec in radians to standard coordinates on a plate */ xr = degrad (xpos); yr = degrad (ypos); sypos = sin (yr); cypos = cos (yr); if (wcs->plate_dec == 0.0) wcs->plate_dec = degrad (wcs->yref); syplate = sin (wcs->plate_dec); cyplate = cos (wcs->plate_dec); if (wcs->plate_ra == 0.0) wcs->plate_ra = degrad (wcs->yref); sxdiff = sin (xr - wcs->plate_ra); cxdiff = cos (xr - wcs->plate_ra); div = (sypos * syplate) + (cypos * cyplate * cxdiff); if (div == 0.0) return (1); xi = cypos * sxdiff * conr2s / div; eta = ((sypos * cyplate) - (cypos * syplate * cxdiff)) * conr2s / div; /* Set initial value for x,y */ if (wcs->plate_scale == 0.0) return (1); xmm = xi / wcs->plate_scale; ymm = eta / wcs->plate_scale; /* Iterate by Newton's method */ for (i = 0; i < max_iterations; i++) { /* X plate model */ xy = xmm * ymm; x2 = xmm * xmm; y2 = ymm * ymm; x2y = x2 * ymm; y2x = y2 * xmm; x2y2 = x2 + y2; cjunk = x2y2 * x2y2; x3 = x2 * xmm; y3 = y2 * ymm; x4 = x2 * x2; y4 = y2 * y2; f = wcs->x_coeff[0]*xmm + wcs->x_coeff[1]*ymm + wcs->x_coeff[2] + wcs->x_coeff[3]*x2 + wcs->x_coeff[4]*xy + wcs->x_coeff[5]*y2 + wcs->x_coeff[6]*x2y2 + wcs->x_coeff[7]*x3 + wcs->x_coeff[8]*x2y + wcs->x_coeff[9]*y2x + wcs->x_coeff[10]*y3 + wcs->x_coeff[11]*xmm*x2y2 + wcs->x_coeff[12]*xmm*cjunk; /* magnitude and color terms ignored + wcs->x_coeff[13]*mag + wcs->x_coeff[14]*mag*mag + wcs->x_coeff[15]*mag*mag*mag + wcs->x_coeff[16]*mag*xmm + wcs->x_coeff[17]*mag*(x2+y2) + wcs->x_coeff[18]*mag*xmm*(x2+y2) + wcs->x_coeff[19]*color; */ /* Derivative of X model wrt x */ fx = wcs->x_coeff[0] + wcs->x_coeff[3]*2.0*xmm + wcs->x_coeff[4]*ymm + wcs->x_coeff[6]*2.0*xmm + wcs->x_coeff[7]*3.0*x2 + wcs->x_coeff[8]*2.0*xy + wcs->x_coeff[9]*y2 + wcs->x_coeff[11]*(3.0*x2+y2) + wcs->x_coeff[12]*(5.0*x4 +6.0*x2*y2+y4); /* magnitude and color terms ignored wcs->x_coeff[16]*mag + wcs->x_coeff[17]*mag*2.0*xmm + wcs->x_coeff[18]*mag*(3.0*x2+y2); */ /* Derivative of X model wrt y */ fy = wcs->x_coeff[1] + wcs->x_coeff[4]*xmm + wcs->x_coeff[5]*2.0*ymm + wcs->x_coeff[6]*2.0*ymm + wcs->x_coeff[8]*x2 + wcs->x_coeff[9]*2.0*xy + wcs->x_coeff[10]*3.0*y2 + wcs->x_coeff[11]*2.0*xy + wcs->x_coeff[12]*4.0*xy*x2y2; /* magnitude and color terms ignored wcs->x_coeff[17]*mag*2.0*ymm + wcs->x_coeff[18]*mag*2.0*xy; */ /* Y plate model */ g = wcs->y_coeff[0]*ymm + wcs->y_coeff[1]*xmm + wcs->y_coeff[2] + wcs->y_coeff[3]*y2 + wcs->y_coeff[4]*xy + wcs->y_coeff[5]*x2 + wcs->y_coeff[6]*x2y2 + wcs->y_coeff[7]*y3 + wcs->y_coeff[8]*y2x + wcs->y_coeff[9]*x2y + wcs->y_coeff[10]*x3 + wcs->y_coeff[11]*ymm*x2y2 + wcs->y_coeff[12]*ymm*cjunk; /* magnitude and color terms ignored wcs->y_coeff[13]*mag + wcs->y_coeff[14]*mag*mag + wcs->y_coeff[15]*mag*mag*mag + wcs->y_coeff[16]*mag*ymm + wcs->y_coeff[17]*mag*x2y2 + wcs->y_coeff[18]*mag*ymm*x2y2 + wcs->y_coeff[19]*color; */ /* Derivative of Y model wrt x */ gx = wcs->y_coeff[1] + wcs->y_coeff[4]*ymm + wcs->y_coeff[5]*2.0*xmm + wcs->y_coeff[6]*2.0*xmm + wcs->y_coeff[8]*y2 + wcs->y_coeff[9]*2.0*xy + wcs->y_coeff[10]*3.0*x2 + wcs->y_coeff[11]*2.0*xy + wcs->y_coeff[12]*4.0*xy*x2y2; /* magnitude and color terms ignored wcs->y_coeff[17]*mag*2.0*xmm + wcs->y_coeff[18]*mag*ymm*2.0*xmm; */ /* Derivative of Y model wrt y */ gy = wcs->y_coeff[0] + wcs->y_coeff[3]*2.0*ymm + wcs->y_coeff[4]*xmm + wcs->y_coeff[6]*2.0*ymm + wcs->y_coeff[7]*3.0*y2 + wcs->y_coeff[8]*2.0*xy + wcs->y_coeff[9]*x2 + wcs->y_coeff[11]*(x2+3.0*y2) + wcs->y_coeff[12]*(5.0*y4 + 6.0*x2*y2 + x4); /* magnitude and color terms ignored wcs->y_coeff[16]*mag + wcs->y_coeff[17]*mag*2.0*ymm + wcs->y_coeff[18]*mag*(x2+3.0*y2); */ f = f - xi; g = g - eta; dx = ((-f * gy) + (g * fy)) / ((fx * gy) - (fy * gx)); dy = ((-g * fx) + (f * gx)) / ((fx * gy) - (fy * gx)); xmm = xmm + dx; ymm = ymm + dy; if ((fabs(dx) < tolerance) && (fabs(dy) < tolerance)) break; } /* Convert mm from plate center to plate pixels */ if (wcs->x_pixel_size == 0.0 || wcs->y_pixel_size == 0.0) return (1); x = (wcs->ppo_coeff[2] - xmm*1000.0) / wcs->x_pixel_size; y = (wcs->ppo_coeff[5] + ymm*1000.0) / wcs->y_pixel_size; /* Convert from plate pixels to image pixels */ *xpix = x - wcs->x_pixel_offset + 1.0 - 0.5; *ypix = y - wcs->y_pixel_offset + 1.0 - 0.5; /* If position is off of the image, return offscale code */ if (*xpix < 0.5 || *xpix > wcs->nxpix+0.5) return -1; if (*ypix < 0.5 || *ypix > wcs->nypix+0.5) return -1; return 0; } /* Mar 6 1995 Original version of this code * May 4 1995 Fix eta cross terms which were all in y * Jun 21 1995 Add inverse routine * Oct 17 1995 Fix inverse routine (degrees -> radians) * Nov 7 1995 Add half pixel to image coordinates to get astrometric * plate coordinates * Feb 26 1996 Fix plate to image pixel conversion error * * Mar 23 1998 Change names from plate*() to dss*() * Apr 7 1998 Change amd_i_coeff to i_coeff * Sep 4 1998 Fix possible divide by zero in dsspos() from Allen Harris, SAO * Sep 10 1998 Fix possible divide by zero in dsspix() from Allen Harris, SAO * * Oct 21 1999 Drop declaration of cond2r in dsspix() */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/fitsfile.c000066400000000000000000001564141215713201500222370ustar00rootroot00000000000000/*** File libwcs/fitsfile.c *** April 30, 2007 *** By Doug Mink, dmink@cfa.harvard.edu *** Harvard-Smithsonian Center for Astrophysics *** Copyright (C) 1996-2007 *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Correspondence concerning WCSTools should be addressed as follows: Internet email: dmink@cfa.harvard.edu Postal address: Doug Mink Smithsonian Astrophysical Observatory 60 Garden St. Cambridge, MA 02138 USA * Module: fitsfile.c (FITS file reading and writing) * Purpose: Read and write FITS image and table files * fitsropen (inpath) * Open a FITS file for reading, returning a FILE pointer * fitsrhead (filename, lhead, nbhead) * Read FITS header and return it * fitsrtail (filename, lhead, nbhead) * Read appended FITS header and return it * fitsrsect (filename, nbhead, header, fd, x0, y0, nx, ny) * Read section of a FITS image, having already read the header * fitsrimage (filename, nbhead, header) * Read FITS image, having already ready the header * fitsrfull (filename, nbhead, header) * Read a FITS image of any dimension * fitsrtopen (inpath, nk, kw, nrows, nchar, nbhead) * Open a FITS table file for reading; return header information * fitsrthead (header, nk, kw, nrows, nchar, nbhead) * Extract FITS table information from a FITS header * fitsrtline (fd, nbhead, lbuff, tbuff, irow, nbline, line) * Read next line of FITS table file * ftgetr8 (entry, kw) * Extract column from FITS table line as double * ftgetr4 (entry, kw) * Extract column from FITS table line as float * ftgeti4 (entry, kw) * Extract column from FITS table line as int * ftgeti2 (entry, kw) * Extract column from FITS table line as short * ftgetc (entry, kw, string, maxchar) * Extract column from FITS table line as a character string * fitswimage (filename, header, image) * Write FITS header and image * fitswext (filename, header, image) * Write FITS header and image as extension to existing FITS file * fitswhdu (fd, filename, header, image) * Write FITS header and image as extension to file descriptor * fitscimage (filename, header, filename0) * Write FITS header and copy FITS image * fitswhead (filename, header) * Write FITS header and keep file open for further writing * fitswexhead (filename, header) * Write FITS header only to FITS extension without writing data * isfits (filename) * Return 1 if file is a FITS file, else 0 * fitsheadsize (header) * Return size of FITS header in bytes */ #include #ifndef VMS #include #endif #include #include #include #include #include #include "fitsfile.h" static int verbose=0; /* Print diagnostics */ static char fitserrmsg[80]; static int fitsinherit = 1; /* Append primary header to extension header */ void setfitsinherit (inh) int inh; {fitsinherit = inh; return;} static int ibhead = 0; /* Number of bytes read before header starts */ int getfitsskip() {return (ibhead);} /* FITSRHEAD -- Read a FITS header */ char * fitsrhead (filename, lhead, nbhead) char *filename; /* Name of FITS image file */ int *lhead; /* Allocated length of FITS header in bytes (returned) */ int *nbhead; /* Number of bytes before start of data (returned) */ /* This includes all skipped image extensions */ { int fd; char *header; /* FITS image header (filled) */ int extend; int nbytes,naxis, i; int ntry,nbr,irec,nrec, nbh, ipos, npos, nbprim, lprim, lext; int nax1, nax2, nax3, nax4, nbpix, ibpix, nblock, nbskip; char fitsbuf[2884]; char *headend; /* Pointer to last line of header */ char *headnext; /* Pointer to next line of header to be added */ int hdu; /* header/data unit counter */ int extnum; /* desired header data number (0=primary -1=first with data -2=use EXTNAME) */ char extname[32]; /* FITS extension name */ char extnam[32]; /* Desired FITS extension name */ char *ext; /* FITS extension name or number in header, if any */ char *pheader; /* Primary header (naxis is 0) */ char cext = 0; char *rbrac; /* Pointer to right bracket if present in file name */ char *mwcs; /* Pointer to WCS name separated by % */ char *newhead; /* New larger header */ int nbh0; /* Length of old too small header */ char *pheadend; int inherit = 1; /* Value of INHERIT keyword in FITS extension header */ int extfound = 0; /* Set to one if desired FITS extension is found */ pheader = NULL; lprim = 0; header = NULL; /* Check for FITS WCS specification and ignore for file opening */ mwcs = strchr (filename, '%'); if (mwcs != NULL) *mwcs = (char) 0; /* Check for FITS extension and ignore for file opening */ rbrac = NULL; ext = strchr (filename, ','); if (ext == NULL) { ext = strchr (filename, '['); if (ext != NULL) { rbrac = strchr (filename, ']'); if (rbrac != NULL) *rbrac = (char) 0; } } if (ext != NULL) { cext = *ext; *ext = (char) 0; } /* Open the image file and read the header */ if (strncasecmp (filename,"stdin",5)) { fd = -1; fd = fitsropen (filename); } #ifndef VMS else { fd = STDIN_FILENO; extnum = -1; } #endif if (ext != NULL) { if (isnum (ext+1)) extnum = atoi (ext+1); else { extnum = -2; strcpy (extnam, ext+1); } } else extnum = -1; /* Repair the damage done to the file-name string during parsing */ if (ext != NULL) *ext = cext; if (rbrac != NULL) *rbrac = ']'; if (mwcs != NULL) *mwcs = '%'; if (fd < 0) { fprintf (stderr,"FITSRHEAD: cannot read file %s\n", filename); return (NULL); } nbytes = FITSBLOCK; *nbhead = 0; headend = NULL; nbh = FITSBLOCK * 20 + 4; header = (char *) calloc ((unsigned int) nbh, 1); (void) hlength (header, nbh); headnext = header; nrec = 1; hdu = 0; ibhead = 0; /* Read FITS header from input file one FITS block at a time */ irec = 0; ibhead = 0; while (irec < 100) { nbytes = FITSBLOCK; for (ntry = 0; ntry < 10; ntry++) { for (i = 0; i < 2884; i++) fitsbuf[i] = 0; nbr = read (fd, fitsbuf, nbytes); /* Short records allowed only if they have the last header line */ if (nbr < nbytes) { headend = ksearch (fitsbuf,"END"); if (headend == NULL) { if (ntry < 9) { if (verbose) fprintf (stderr,"FITSRHEAD: %d / %d bytes read %d\n", nbr,nbytes,ntry); } else { snprintf(fitserrmsg,79,"FITSRHEAD: '%d / %d bytes of header read from %s\n" ,nbr,nbytes,filename); #ifndef VMS if (fd != STDIN_FILENO) #endif (void)close (fd); free (header); if (pheader != NULL) return (pheader); if (extnum != -1 && !extfound) { if (extnum < 0) fprintf (stderr, "FITSRHEAD: Extension %s not found in file %s\n",extnam, filename); else fprintf (stderr, "FITSRHEAD: Extension %d not found in file %s\n",extnum, filename); } else fprintf (stderr, "FITSRHEAD: No header found in file %s\n", filename); return (NULL); } } else break; } else break; } /* Move current FITS record into header string */ for (i = 0; i < 2880; i++) if (fitsbuf[i] < 32) fitsbuf[i] = 32; strncpy (headnext, fitsbuf, nbr); *nbhead = *nbhead + nbr; nrec = nrec + 1; *(headnext+nbr) = 0; ibhead = ibhead + 2880; /* Check to see if this is the final record in this header */ headend = ksearch (fitsbuf,"END"); if (headend == NULL) { /* Increase size of header buffer by 4 blocks if too small */ if (nrec * FITSBLOCK > nbh) { nbh0 = nbh; nbh = (nrec + 4) * FITSBLOCK + 4; newhead = (char *) calloc (1,(unsigned int) nbh); for (i = 0; i < nbh0; i++) newhead[i] = header[i]; free (header); header = newhead; (void) hlength (header, nbh); headnext = header + *nbhead - FITSBLOCK; } headnext = headnext + FITSBLOCK; } else { naxis = 0; hgeti4 (header,"NAXIS",&naxis); /* If header has no data, save it for appending to desired header */ if (naxis < 1) { nbprim = nrec * FITSBLOCK; headend = ksearch (header,"END"); lprim = headend + 80 - header; pheader = (char *) calloc ((unsigned int) nbprim, 1); for (i = 0; i < lprim; i++) pheader[i] = header[i]; strncpy (pheader, header, lprim); } /* If header has no data, start with the next record */ if (naxis < 1 && extnum == -1) { extend = 0; hgetl (header,"EXTEND",&extend); if (naxis == 0 && extend) { headnext = header; *headend = ' '; headend = NULL; /* nrec = 1; */ hdu = hdu + 1; } else break; } /* If this is the desired header data unit, keep it */ else if (extnum != -1) { if (extnum > -1 && hdu == extnum) { extfound = 1; break; } else if (extnum < 0) { extname[0] = 0; hgets (header, "EXTNAME", 32, extname); if (!strcmp (extnam,extname)) { extfound = 1; break; } } /* If this is not desired header data unit, skip over data */ hdu = hdu + 1; nblock = 0; ibhead = 0; if (naxis > 0) { ibpix = 0; hgeti4 (header,"BITPIX",&ibpix); if (ibpix < 0) nbpix = -ibpix / 8; else nbpix = ibpix / 8; nax1 = 1; hgeti4 (header,"NAXIS1",&nax1); nax2 = 1; if (naxis > 1) hgeti4 (header,"NAXIS2",&nax2); nax3 = 1; if (naxis > 2) hgeti4 (header,"NAXIS3",&nax3); nax4 = 1; if (naxis > 3) hgeti4 (header,"NAXIS4",&nax4); nbskip = nax1 * nax2 * nax3 * nax4 * nbpix; nblock = nbskip / 2880; if (nblock*2880 < nbskip) nblock = nblock + 1; } else nblock = 0; *nbhead = *nbhead + (nblock * 2880); /* Set file pointer to beginning of next header/data unit */ if (nblock > 0) { #ifndef VMS if (fd != STDIN_FILENO) { ipos = lseek (fd, *nbhead, SEEK_SET); npos = *nbhead; } else { #else { #endif ipos = 0; for (i = 0; i < nblock; i++) { nbytes = FITSBLOCK; nbr = read (fd, fitsbuf, nbytes); if (nbr < nbytes) { ipos = ipos + nbr; break; } else ipos = ipos + nbytes; } npos = nblock * 2880; } if (ipos < npos) { snprintf (fitserrmsg,79,"FITSRHEAD: %d / %d bytes skipped\n", ipos,npos); break; } } headnext = header; headend = NULL; nrec = 1; } else break; } } #ifndef VMS if (fd != STDIN_FILENO) (void)close (fd); #endif /* Print error message and return null if extension not found */ if (extnum != -1 && !extfound) { if (extnum < 0) fprintf (stderr, "FITSRHEAD: Extension %s not found in file %s\n",extnam, filename); else fprintf (stderr, "FITSRHEAD: Extension %d not found in file %s\n",extnum, filename); if (pheader != NULL) free (pheader); return (NULL); } /* Allocate an extra block for good measure */ *lhead = (nrec + 1) * FITSBLOCK; if (*lhead > nbh) { newhead = (char *) calloc (1,(unsigned int) *lhead); for (i = 0; i < nbh; i++) newhead[i] = header[i]; free (header); header = newhead; (void) hlength (header, *lhead); } else *lhead = nbh; /* If INHERIT keyword is FALSE, never append primary header */ if (hgetl (header, "INHERIT", &inherit)) { if (!inherit && fitsinherit) fitsinherit = 0; } /* Append primary data header to extension header */ if (pheader != NULL && extnum != 0 && fitsinherit) { extname[0] = 0; hgets (header, "XTENSION", 32, extname); if (!strcmp (extname,"IMAGE")) { strncpy (header, "SIMPLE ", 8); hputl (header, "SIMPLE", 1); } hputs (header,"COMMENT","-------------------------------------------"); hputs (header,"COMMENT","Information from Primary Header"); hputs (header,"COMMENT","-------------------------------------------"); headend = blsearch (header,"END"); if (headend == NULL) headend = ksearch (header, "END"); lext = headend - header; /* Update primary header for inclusion at end of extension header */ hchange (pheader, "SIMPLE", "ROOTHEAD"); hchange (pheader, "NEXTEND", "NUMEXT"); hdel (pheader, "BITPIX"); hdel (pheader, "NAXIS"); hdel (pheader, "EXTEND"); hputl (pheader, "ROOTEND",1); pheadend = ksearch (pheader,"END"); lprim = pheadend + 80 - pheader; if (lext + lprim > nbh) { nrec = (lext + lprim) / FITSBLOCK; if (FITSBLOCK*nrec < lext+lprim) nrec = nrec + 1; *lhead = (nrec+1) * FITSBLOCK; newhead = (char *) calloc (1,(unsigned int) *lhead); for (i = 0; i < nbh; i++) newhead[i] = header[i]; free (header); header = newhead; headend = header + lext; (void) hlength (header, *lhead); } pheader[lprim] = 0; strncpy (headend, pheader, lprim); free (pheader); } ibhead = *nbhead - ibhead; return (header); } /* FITSRTAIL -- Read FITS header appended to graphics file */ char * fitsrtail (filename, lhead, nbhead) char *filename; /* Name of image file */ int *lhead; /* Allocated length of FITS header in bytes (returned) */ int *nbhead; /* Number of bytes before start of data (returned) */ /* This includes all skipped image extensions */ { int fd; char *header; /* FITS image header (filled) */ int nbytes, i, ndiff; int nbr, irec, offset; char *mwcs; /* Pointer to WCS name separated by % */ char *headstart; char *newhead; header = NULL; /* Check for FITS WCS specification and ignore for file opening */ mwcs = strchr (filename, '%'); if (mwcs != NULL) *mwcs = (char) 0; /* Open the image file and read the header */ if (strncasecmp (filename,"stdin",5)) { fd = -1; fd = fitsropen (filename); } #ifndef VMS else { fd = STDIN_FILENO; } #endif /* Repair the damage done to the file-name string during parsing */ if (mwcs != NULL) *mwcs = '%'; if (fd < 0) { fprintf (stderr,"FITSRTAIL: cannot read file %s\n", filename); return (NULL); } nbytes = FITSBLOCK; *nbhead = 0; *lhead = 0; /* Read FITS header from end of input file one FITS block at a time */ irec = 0; while (irec < 100) { nbytes = FITSBLOCK * (irec + 2); header = (char *) calloc ((unsigned int) nbytes, 1); offset = lseek (fd, -nbytes, SEEK_END); if (offset < 0) { free (header); header = NULL; nbytes = 0; break; } for (i = 0; i < nbytes; i++) header[i] = 0; nbr = read (fd, header, nbytes); /* Check for SIMPLE at start of header */ for (i = 0; i < nbr; i++) if (header[i] < 32) header[i] = 32; if ((headstart = ksearch (header,"SIMPLE"))) { if (headstart != header) { ndiff = headstart - header; newhead = (char *) calloc ((unsigned int) nbytes, 1); for (i = 0; i < nbytes-ndiff; i++) newhead[i] = headstart[i]; free (header); header = newhead; } *lhead = nbytes; *nbhead = nbytes; break; } free (header); } (void) hlength (header, nbytes); #ifndef VMS if (fd != STDIN_FILENO) (void)close (fd); #endif return (header); } /* FITSRSECT -- Read a piece of a FITS image, having already read the header */ char * fitsrsect (filename, header, nbhead, x0, y0, nx, ny, nlog) char *filename; /* Name of FITS image file */ char *header; /* FITS header for image (previously read) */ int nbhead; /* Actual length of image header(s) in bytes */ int x0, y0; /* FITS image coordinate of first pixel */ int nx; /* Number of columns to read (less than NAXIS1) */ int ny; /* Number of rows to read (less than NAXIS2) */ int nlog; /* Note progress mod this rows */ { int fd; /* File descriptor */ int nbimage, naxis1, naxis2, bytepix, nbread; int bitpix, naxis, nblocks, nbytes, nbr; int x1, y1, nbline, impos, nblin, nyleft; char *image, *imline, *imlast; int ilog = 0; int row; /* Open the image file and read the header */ if (strncasecmp (filename,"stdin", 5)) { fd = -1; fd = fitsropen (filename); if (fd < 0) { snprintf (fitserrmsg,79, "FITSRSECT: cannot read file %s\n", filename); return (NULL); } /* Skip over FITS header and whatever else needs to be skipped */ if (lseek (fd, nbhead, SEEK_SET) < 0) { (void)close (fd); snprintf (fitserrmsg,79, "FITSRSECT: cannot skip header of file %s\n", filename); return (NULL); } } #ifndef VMS else fd = STDIN_FILENO; #endif /* Compute size of image in bytes using relevant header parameters */ naxis = 1; hgeti4 (header,"NAXIS",&naxis); naxis1 = 1; hgeti4 (header,"NAXIS1",&naxis1); naxis2 = 1; hgeti4 (header,"NAXIS2",&naxis2); bitpix = 0; hgeti4 (header,"BITPIX",&bitpix); if (bitpix == 0) { /* snprintf (fitserrmsg,79, "FITSRSECT: BITPIX is 0; image not read\n"); */ (void)close (fd); return (NULL); } bytepix = bitpix / 8; if (bytepix < 0) bytepix = -bytepix; /* Keep X coordinates within image limits */ if (x0 < 1) x0 = 1; else if (x0 > naxis1) x0 = naxis1; x1 = x0 + nx - 1; if (x1 < 1) x1 = 1; else if (x1 > naxis1) x1 = naxis1; nx = x1 - x0 + 1; /* Keep Y coordinates within image limits */ if (y0 < 1) y0 = 1; else if (y0 > naxis2) y0 = naxis2; y1 = y0 + ny - 1; if (y1 < 1) y1 = 1; else if (y1 > naxis2) y1 = naxis2; ny = y1 - y0 + 1; /* Number of bytes in output image */ nbline = nx * bytepix; nbimage = nbline * ny; /* Set number of bytes to integral number of 2880-byte blocks */ nblocks = nbimage / FITSBLOCK; if (nblocks * FITSBLOCK < nbimage) nblocks = nblocks + 1; nbytes = nblocks * FITSBLOCK; /* Allocate image section to be read */ image = (char *) malloc (nbytes); nyleft = ny; imline = image; nbr = 0; /* Computer pointer to first byte of input image to read */ nblin = naxis1 * bytepix; impos = ((y0 - 1) * nblin) + ((x0 - 1) * bytepix); row = y0 - 1; /* Read image section one line at a time */ while (nyleft-- > 0) { if (lseek (fd, impos, SEEK_CUR) >= 0) { nbread = read (fd, imline, nbline); nbr = nbr + nbread; impos = nblin - nbread; imline = imline + nbline; row++; if (++ilog == nlog) { ilog = 0; fprintf (stderr, "Row %5d extracted ", row); (void) putc (13,stderr); } } } if (nlog) fprintf (stderr, "\n"); /* Fill rest of image with zeroes */ imline = image + nbimage; imlast = image + nbytes; while (imline++ < imlast) *imline = (char) 0; /* Byte-reverse image, if necessary */ if (imswapped ()) imswap (bitpix, image, nbytes); return (image); } /* FITSRIMAGE -- Read a FITS image */ char * fitsrimage (filename, nbhead, header) char *filename; /* Name of FITS image file */ int nbhead; /* Actual length of image header(s) in bytes */ char *header; /* FITS header for image (previously read) */ { int fd; int nbimage, naxis1, naxis2, bytepix, nbread; int bitpix, naxis, nblocks, nbytes, nbleft, nbr; int simple; char *image, *imleft; /* Open the image file and read the header */ if (strncasecmp (filename,"stdin", 5)) { fd = -1; fd = fitsropen (filename); if (fd < 0) { snprintf (fitserrmsg,79, "FITSRIMAGE: cannot read file %s\n", filename); return (NULL); } /* Skip over FITS header and whatever else needs to be skipped */ if (lseek (fd, nbhead, SEEK_SET) < 0) { (void)close (fd); snprintf (fitserrmsg,79, "FITSRIMAGE: cannot skip header of file %s\n", filename); return (NULL); } } #ifndef VMS else fd = STDIN_FILENO; #endif /* If SIMPLE=F in header, simply put post-header part of file in buffer */ hgetl (header, "SIMPLE", &simple); if (!simple) { nbytes = getfilesize (filename) - nbhead; if ((image = (char *) malloc (nbytes + 1)) == NULL) { /* snprintf (fitserrmsg,79, "FITSRIMAGE: %d-byte image buffer cannot be allocated\n"); */ (void)close (fd); return (NULL); } hputi4 (header, "NBDATA", nbytes); nbread = read (fd, image, nbytes); return (image); } /* Compute size of image in bytes using relevant header parameters */ naxis = 1; hgeti4 (header,"NAXIS",&naxis); naxis1 = 1; hgeti4 (header,"NAXIS1",&naxis1); naxis2 = 1; hgeti4 (header,"NAXIS2",&naxis2); bitpix = 0; hgeti4 (header,"BITPIX",&bitpix); if (bitpix == 0) { /* snprintf (fitserrmsg,79, "FITSRIMAGE: BITPIX is 0; image not read\n"); */ (void)close (fd); return (NULL); } bytepix = bitpix / 8; if (bytepix < 0) bytepix = -bytepix; /* If either dimension is one and image is 3-D, read all three dimensions */ if (naxis == 3 && (naxis1 ==1 || naxis2 == 1)) { int naxis3; hgeti4 (header,"NAXIS3",&naxis3); nbimage = naxis1 * naxis2 * naxis3 * bytepix; } else nbimage = naxis1 * naxis2 * bytepix; /* Set number of bytes to integral number of 2880-byte blocks */ nblocks = nbimage / FITSBLOCK; if (nblocks * FITSBLOCK < nbimage) nblocks = nblocks + 1; nbytes = nblocks * FITSBLOCK; /* Allocate and read image */ image = (char *) malloc (nbytes); nbleft = nbytes; imleft = image; nbr = 0; while (nbleft > 0) { nbread = read (fd, imleft, nbleft); nbr = nbr + nbread; #ifndef VMS if (fd == STDIN_FILENO && nbread < nbleft && nbread > 0) { nbleft = nbleft - nbread; imleft = imleft + nbread; } else #endif nbleft = 0; } #ifndef VMS if (fd != STDIN_FILENO) (void)close (fd); #endif if (nbr < nbimage) { snprintf (fitserrmsg,79, "FITSRIMAGE: %d of %d bytes read from file %s\n", nbr, nbimage, filename); return (NULL); } /* Byte-reverse image, if necessary */ if (imswapped ()) imswap (bitpix, image, nbytes); return (image); } /* FITSRFULL -- Read a FITS image of any dimension */ char * fitsrfull (filename, nbhead, header) char *filename; /* Name of FITS image file */ int nbhead; /* Actual length of image header(s) in bytes */ char *header; /* FITS header for image (previously read) */ { int fd; int nbimage, naxisi, iaxis, bytepix, nbread; int bitpix, naxis, nblocks, nbytes, nbleft, nbr, simple; char keyword[16]; char *image, *imleft; /* Open the image file and read the header */ if (strncasecmp (filename,"stdin", 5)) { fd = -1; fd = fitsropen (filename); if (fd < 0) { snprintf (fitserrmsg,79, "FITSRFULL: cannot read file %s\n", filename); return (NULL); } /* Skip over FITS header and whatever else needs to be skipped */ if (lseek (fd, nbhead, SEEK_SET) < 0) { (void)close (fd); snprintf (fitserrmsg,79, "FITSRFULL: cannot skip header of file %s\n", filename); return (NULL); } } #ifndef VMS else fd = STDIN_FILENO; #endif /* If SIMPLE=F in header, simply put post-header part of file in buffer */ hgetl (header, "SIMPLE", &simple); if (!simple) { nbytes = getfilesize (filename) - nbhead; if ((image = (char *) malloc (nbytes + 1)) == NULL) { snprintf (fitserrmsg,79, "FITSRFULL: %d-byte image buffer cannot be allocated\n"); (void)close (fd); return (NULL); } hputi4 (header, "NBDATA", nbytes); nbread = read (fd, image, nbytes); return (image); } /* Find number of bytes per pixel */ bitpix = 0; hgeti4 (header,"BITPIX",&bitpix); if (bitpix == 0) { snprintf (fitserrmsg,79, "FITSRFULL: BITPIX is 0; image not read\n"); (void)close (fd); return (NULL); } bytepix = bitpix / 8; if (bytepix < 0) bytepix = -bytepix; nbimage = bytepix; /* Compute size of image in bytes using relevant header parameters */ naxis = 1; hgeti4 (header,"NAXIS",&naxis); for (iaxis = 1; iaxis <= naxis; iaxis++) { sprintf (keyword, "NAXIS%d", iaxis); naxisi = 1; hgeti4 (header,keyword,&naxisi); nbimage = nbimage * naxisi; } /* Set number of bytes to integral number of 2880-byte blocks */ nblocks = nbimage / FITSBLOCK; if (nblocks * FITSBLOCK < nbimage) nblocks = nblocks + 1; nbytes = nblocks * FITSBLOCK; /* Allocate and read image */ image = (char *) malloc (nbytes); nbleft = nbytes; imleft = image; nbr = 0; while (nbleft > 0) { nbread = read (fd, imleft, nbleft); nbr = nbr + nbread; #ifndef VMS if (fd == STDIN_FILENO && nbread < nbleft && nbread > 0) { nbleft = nbleft - nbread; imleft = imleft + nbread; } else #endif nbleft = 0; } #ifndef VMS if (fd != STDIN_FILENO) (void)close (fd); #endif if (nbr < nbimage) { snprintf (fitserrmsg,79, "FITSRFULL: %d of %d image bytes read from file %s\n", nbr, nbimage, filename); return (NULL); } /* Byte-reverse image, if necessary */ if (imswapped ()) imswap (bitpix, image, nbytes); return (image); } /* FITSROPEN -- Open a FITS file, returning the file descriptor */ int fitsropen (inpath) char *inpath; /* Pathname for FITS tables file to read */ { int ntry; int fd; /* file descriptor for FITS tables file (returned) */ char *ext; /* extension name or number */ char cext = 0; char *rbrac; char *mwcs; /* Pointer to WCS name separated by % */ /* Check for FITS WCS specification and ignore for file opening */ mwcs = strchr (inpath, '%'); /* Check for FITS extension and ignore for file opening */ ext = strchr (inpath, ','); rbrac = NULL; if (ext == NULL) { ext = strchr (inpath, '['); if (ext != NULL) { rbrac = strchr (inpath, ']'); } } /* Open input file */ for (ntry = 0; ntry < 3; ntry++) { if (ext != NULL) { cext = *ext; *ext = 0; } if (rbrac != NULL) *rbrac = (char) 0; if (mwcs != NULL) *mwcs = (char) 0; fd = open (inpath, O_RDONLY); if (ext != NULL) *ext = cext; if (rbrac != NULL) *rbrac = ']'; if (mwcs != NULL) *mwcs = '%'; if (fd >= 0) break; else if (ntry == 2) { snprintf (fitserrmsg,79, "FITSROPEN: cannot read file %s\n", inpath); return (-1); } } if (verbose) fprintf (stderr,"FITSROPEN: input file %s opened\n",inpath); return (fd); } static int offset1=0; static int offset2=0; /* FITSRTOPEN -- Open FITS table file and fill structure with * pointers to selected keywords * Return file descriptor (-1 if unsuccessful) */ int fitsrtopen (inpath, nk, kw, nrows, nchar, nbhead) char *inpath; /* Pathname for FITS tables file to read */ int *nk; /* Number of keywords to use */ struct Keyword **kw; /* Structure for desired entries */ int *nrows; /* Number of rows in table (returned) */ int *nchar; /* Number of characters in one table row (returned) */ int *nbhead; /* Number of characters before table starts */ { char temp[16]; int fd; int lhead; /* Maximum length in bytes of FITS header */ char *header; /* Header for FITS tables file to read */ /* Read FITS header from input file */ header = fitsrhead (inpath, &lhead, nbhead); if (!header) { snprintf (fitserrmsg,79,"FITSRTOPEN: %s is not a FITS file\n",inpath); return (0); } /* Make sure this file is really a FITS table file */ temp[0] = 0; (void) hgets (header,"XTENSION",16,temp); if (strncmp (temp, "TABLE", 5)) { snprintf (fitserrmsg,79, "FITSRTOPEN: %s is not a FITS table file\n",inpath); free ((void *) header); return (0); } /* If it is a FITS file, get table information from the header */ else { if (fitsrthead (header, nk, kw, nrows, nchar)) { snprintf (fitserrmsg,79, "FITSRTOPEN: Cannot read FITS table from %s\n",inpath); free ((void *) header); return (-1); } else { fd = fitsropen (inpath); offset1 = 0; offset2 = 0; free ((void *) header); return (fd); } } } static struct Keyword *pw; /* Structure for all entries */ static int *lpnam; /* length of name for each field */ static int bfields = 0; /* FITSRTHEAD -- From FITS table header, read pointers to selected keywords */ int fitsrthead (header, nk, kw, nrows, nchar) char *header; /* Header for FITS tables file to read */ int *nk; /* Number of keywords to use */ struct Keyword **kw; /* Structure for desired entries */ int *nrows; /* Number of rows in table (returned) */ int *nchar; /* Number of characters in one table row (returned) */ { struct Keyword *rw; /* Structure for desired entries */ int nfields; int ifield,ik,ln, i; char *h0, *h1, *tf1, *tf2; char tname[12]; char temp[16]; char tform[16]; int tverb; h0 = header; /* Make sure this is really a FITS table file header */ temp[0] = 0; hgets (header,"XTENSION",16,temp); if (strncmp (temp, "TABLE", 5) != 0) { snprintf (fitserrmsg,79, "FITSRTHEAD: Not a FITS table file\n"); free (temp); return (-1); } /* Get table size from FITS header */ *nchar = 0; hgeti4 (header,"NAXIS1",nchar); *nrows = 0; hgeti4 (header,"NAXIS2", nrows); if (*nrows <= 0 || *nchar <= 0) { snprintf (fitserrmsg,79, "FITSRTHEAD: cannot read %d x %d table\n", *nrows,*nchar); return (-1); } /* Set up table for access to individual fields */ nfields = 0; hgeti4 (header,"TFIELDS",&nfields); if (verbose) fprintf (stderr, "FITSRTHEAD: %d fields per table entry\n", nfields); if (nfields > bfields) { if (bfields > 0) free ((void *)pw); pw = (struct Keyword *) calloc (nfields, sizeof(struct Keyword)); if (pw == NULL) { snprintf (fitserrmsg,79,"FITSRTHEAD: cannot allocate table structure\n"); return (-1); } if (bfields > 0) free ((void *)lpnam); lpnam = (int *) calloc (nfields, sizeof(int)); if (lpnam == NULL) { snprintf (fitserrmsg,79,"FITSRTHEAD: cannot allocate length structure\n"); return (-1); } bfields = nfields; } tverb = verbose; verbose = 0; for (ifield = 0; ifield < nfields; ifield++) { /* First column of field */ for (i = 0; i < 12; i++) tname[i] = 0; sprintf (tname, "TBCOL%d", ifield+1); h1 = ksearch (h0,tname); pw[ifield].kf = 0; hgeti4 (h0,tname, &pw[ifield].kf); /* Length of field */ for (i = 0; i < 12; i++) tname[i] = 0; sprintf (tname, "TFORM%d", ifield+1);; tform[0] = 0; hgets (h0,tname,16,tform); tf1 = tform + 1; tf2 = strchr (tform,'.'); if (tf2 != NULL) *tf2 = ' '; pw[ifield].kl = atoi (tf1); /* Name of field */ for (i = 0; i < 12; i++) tname[i] = 0; sprintf (tname, "TTYPE%d", ifield+1);; temp[0] = 0; hgets (h0,tname,16,temp); strcpy (pw[ifield].kname,temp); lpnam[ifield] = strlen (pw[ifield].kname); h0 = h1; } /* Set up table for access to desired fields */ verbose = tverb; if (verbose) fprintf (stderr, "FITSRTHEAD: %d keywords read\n", *nk); /* If nk = 0, allocate and return structures for all table fields */ if (*nk <= 0) { *kw = pw; *nk = nfields; return (0); } else rw = *kw; /* Find each desired keyword in the header */ for (ik = 0; ik < *nk; ik++) { if (rw[ik].kn <= 0) { for (ifield = 0; ifield < nfields; ifield++) { ln = lpnam[ifield]; if (rw[ik].lname > ln) ln = rw[ik].lname; if (strncmp (pw[ifield].kname, rw[ik].kname, ln) == 0) { break; } } } else ifield = rw[ik].kn - 1; /* Set pointer, lentth, and name in returned array of structures */ rw[ik].kn = ifield + 1; rw[ik].kf = pw[ifield].kf - 1; rw[ik].kl = pw[ifield].kl; strcpy (rw[ik].kname, pw[ifield].kname); } return (0); } int fitsrtline (fd, nbhead, lbuff, tbuff, irow, nbline, line) int fd; /* File descriptor for FITS file */ int nbhead; /* Number of bytes in FITS header */ int lbuff; /* Number of bytes in table buffer */ char *tbuff; /* FITS table buffer */ int irow; /* Number of table row to read */ int nbline; /* Number of bytes to read for this line */ char *line; /* One line of FITS table (returned) */ { int nbuff, nlbuff; int nbr = 0; int offset, offend, ntry, ioff; char *tbuff1; offset = nbhead + (nbline * irow); offend = offset + nbline - 1; /* Read a new buffer of the FITS table into memory if needed */ if (offset < offset1 || offend > offset2) { nlbuff = lbuff / nbline; nbuff = nlbuff * nbline; for (ntry = 0; ntry < 3; ntry++) { ioff = lseek (fd, offset, SEEK_SET); if (ioff < offset) { if (ntry == 2) return (0); else continue; } nbr = read (fd, tbuff, nbuff); if (nbr < nbline) { if (verbose) fprintf (stderr, "FITSRTLINE: %d / %d bytes read %d\n", nbr,nbuff,ntry); if (ntry == 2) return (nbr); } else break; } offset1 = offset; offset2 = offset + nbr - 1; strncpy (line, tbuff, nbline); return (nbline); } else { tbuff1 = tbuff + (offset - offset1); strncpy (line, tbuff1, nbline); return (nbline); } } void fitsrtlset () { offset1 = 0; offset2 = 0; return; } /* FTGETI2 -- Extract n'th column from FITS table line as short */ short ftgeti2 (entry, kw) char *entry; /* Row or entry from table */ struct Keyword *kw; /* Table column information from FITS header */ { char temp[30]; if (ftgetc (entry, kw, temp, 30)) return ( (short) atof (temp) ); else return ((short) 0); } /* FTGETI4 -- Extract n'th column from FITS table line as int */ int ftgeti4 (entry, kw) char *entry; /* Row or entry from table */ struct Keyword *kw; /* Table column information from FITS header */ { char temp[30]; if (ftgetc (entry, kw, temp, 30)) return ( (int) atof (temp) ); else return (0); } /* FTGETR4 -- Extract n'th column from FITS table line as float */ float ftgetr4 (entry, kw) char *entry; /* Row or entry from table */ struct Keyword *kw; /* Table column information from FITS header */ { char temp[30]; if (ftgetc (entry, kw, temp, 30)) return ( (float) atof (temp) ); else return ((float) 0.0); } /* FTGETR8 -- Extract n'th column from FITS table line as double */ double ftgetr8 (entry, kw) char *entry; /* Row or entry from table */ struct Keyword *kw; /* Table column information from FITS header */ { char temp[30]; if (ftgetc (entry, kw, temp, 30)) return ( atof (temp) ); else return ((double) 0.0); } /* FTGETC -- Extract n'th column from FITS table line as character string */ int ftgetc (entry, kw, string, maxchar) char *entry; /* Row or entry from table */ struct Keyword *kw; /* Table column information from FITS header */ char *string; /* Returned string */ int maxchar; /* Maximum number of characters in returned string */ { int length = maxchar; if (kw->kl < length) length = kw->kl; if (length > 0) { strncpy (string, entry+kw->kf, length); string[length] = 0; return ( 1 ); } else return ( 0 ); } extern int errno; /*FITSWIMAGE -- Write FITS header and image */ int fitswimage (filename, header, image) char *filename; /* Name of FITS image file */ char *header; /* FITS image header */ char *image; /* FITS image pixels */ { int fd; /* Open the output file */ if (strcasecmp (filename,"stdout") ) { if (!access (filename, 0)) { fd = open (filename, O_WRONLY); if (fd < 3) { snprintf (fitserrmsg,79, "FITSWIMAGE: file %s not writeable\n", filename); return (0); } } else { fd = open (filename, O_RDWR+O_CREAT, 0666); if (fd < 3) { snprintf (fitserrmsg,79, "FITSWIMAGE: cannot create file %s\n", filename); return (0); } } } #ifndef VMS else fd = STDOUT_FILENO; #endif return (fitswhdu (fd, filename, header, image)); } /*FITSWEXT -- Write FITS header and image as extension to a file */ int fitswext (filename, header, image) char *filename; /* Name of IFTS image file */ char *header; /* FITS image header */ char *image; /* FITS image pixels */ { int fd; /* Open the output file */ if (strcasecmp (filename,"stdout") ) { if (!access (filename, 0)) { fd = open (filename, O_WRONLY); if (fd < 3) { snprintf (fitserrmsg,79, "FITSWEXT: file %s not writeable\n", filename); return (0); } } else { fd = open (filename, O_APPEND, 0666); if (fd < 3) { snprintf (fitserrmsg,79, "FITSWEXT: cannot append to file %s\n", filename); return (0); } } } #ifndef VMS else fd = STDOUT_FILENO; #endif return (fitswhdu (fd, filename, header, image)); } /* FITSWHDU -- Write FITS head and image as extension */ int fitswhdu (fd, filename, header, image) int fd; /* File descriptor */ char *filename; /* Name of IFTS image file */ char *header; /* FITS image header */ char *image; /* FITS image pixels */ { int nbhead, nbimage, nblocks, bytepix, i, nbhw; int bitpix, naxis, iaxis, naxisi, nbytes, nbw, nbpad, nbwp, simple; char *endhead, *padding; double bzero, bscale; char keyword[32]; /* Change BITPIX=-16 files to BITPIX=16 with BZERO and BSCALE */ bitpix = 0; hgeti4 (header,"BITPIX",&bitpix); if (bitpix == -16) { if (!hgetr8 (header, "BZERO", &bzero) && !hgetr8 (header, "BSCALE", &bscale)) { bitpix = 16; hputi4 (header, "BITPIX", bitpix); hputr8 (header, "BZERO", 32768.0); hputr8 (header, "BSCALE", 1.0); } } /* Write header to file */ endhead = ksearch (header,"END") + 80; nbhead = endhead - header; nbhw = write (fd, header, nbhead); if (nbhw < nbhead) { snprintf (fitserrmsg,79, "FITSWHDU: wrote %d / %d bytes of header to file %s\n", nbhw, nbhead, filename); (void)close (fd); return (0); } /* Write extra spaces to make an integral number of 2880-byte blocks */ nblocks = nbhead / FITSBLOCK; if (nblocks * FITSBLOCK < nbhead) nblocks = nblocks + 1; nbytes = nblocks * FITSBLOCK; nbpad = nbytes - nbhead; padding = (char *)calloc (1, nbpad); for (i = 0; i < nbpad; i++) padding[i] = ' '; nbwp = write (fd, padding, nbpad); if (nbwp < nbpad) { snprintf (fitserrmsg,79, "FITSWHDU: wrote %d / %d bytes of header padding to file %s\n", nbwp, nbpad, filename); (void)close (fd); return (0); } nbhw = nbhw + nbwp; free (padding); /* Return if file has no data */ if (bitpix == 0 || image == NULL) { /* snprintf (fitserrmsg,79, "FITSWHDU: BITPIX is 0; image not written\n"); */ (void)close (fd); return (0); } /* If SIMPLE=F in header, just write whatever is in the buffer */ hgetl (header, "SIMPLE", &simple); if (!simple) { hgeti4 (header, "NBDATA", &nbytes); nbimage = nbytes; } else { /* Compute size of pixel in bytes */ bytepix = bitpix / 8; if (bytepix < 0) bytepix = -bytepix; nbimage = bytepix; /* Compute size of image in bytes using relevant header parameters */ naxis = 1; hgeti4 (header,"NAXIS",&naxis); for (iaxis = 1; iaxis <= naxis; iaxis++) { sprintf (keyword, "NAXIS%d", iaxis); naxisi = 1; hgeti4 (header,keyword,&naxisi); nbimage = nbimage * naxisi; } /* Number of bytes to write is an integral number of FITS blocks */ nblocks = nbimage / FITSBLOCK; if (nblocks * FITSBLOCK < nbimage) nblocks = nblocks + 1; nbytes = nblocks * FITSBLOCK; /* Byte-reverse image before writing, if necessary */ if (imswapped ()) imswap (bitpix, image, nbimage); } /* Write image to file */ nbw = write (fd, image, nbimage); if (nbw < nbimage) { snprintf (fitserrmsg,79, "FITSWHDU: wrote %d / %d bytes of image to file %s\n", nbw, nbimage, filename); return (0); } /* Write extra zeroes to make an integral number of 2880-byte blocks */ nbpad = nbytes - nbimage; if (nbpad > 0) { padding = (char *)calloc (1, nbpad); nbwp = write (fd, padding, nbpad); if (nbwp < nbpad) { snprintf (fitserrmsg,79, "FITSWHDU: wrote %d / %d bytes of image padding to file %s\n", nbwp, nbpad, filename); (void)close (fd); return (0); } free (padding); } else nbwp = 0; (void)close (fd); /* Byte-reverse image after writing, if necessary */ if (imswapped ()) imswap (bitpix, image, nbimage); nbw = nbw + nbwp + nbhw; return (nbw); } /*FITSCIMAGE -- Write FITS header and copy FITS image Return number of bytes in output image, 0 if failure */ int fitscimage (filename, header, filename0) char *filename; /* Name of output FITS image file */ char *header; /* FITS image header */ char *filename0; /* Name of input FITS image file */ { int fdout, fdin; int nbhead, nbimage, nblocks, bytepix; int bitpix, naxis, naxis1, naxis2, nbytes, nbw, nbpad, nbwp; char *endhead, *lasthead, *padding; char *image; /* FITS image pixels */ char *oldhead; /* Input file image header */ int nbhead0; /* Length of input file image header */ int lhead0; int nbbuff, nbuff, ibuff, nbr, nbdata; /* Compute size of image in bytes using relevant header parameters */ naxis = 1; hgeti4 (header, "NAXIS", &naxis); naxis1 = 1; hgeti4 (header, "NAXIS1", &naxis1); naxis2 = 1; hgeti4 (header, "NAXIS2", &naxis2); hgeti4 (header, "BITPIX", &bitpix); bytepix = bitpix / 8; if (bytepix < 0) bytepix = -bytepix; /* If either dimension is one and image is 3-D, read all three dimensions */ if (naxis == 3 && (naxis1 ==1 || naxis2 == 1)) { int naxis3; hgeti4 (header,"NAXIS3",&naxis3); nbimage = naxis1 * naxis2 * naxis3 * bytepix; } else nbimage = naxis1 * naxis2 * bytepix; nblocks = nbimage / FITSBLOCK; if (nblocks * FITSBLOCK < nbimage) nblocks = nblocks + 1; nbytes = nblocks * FITSBLOCK; /* Allocate image buffer */ nbbuff = FITSBLOCK * 100; if (nbytes < nbbuff) nbbuff = nbytes; image = (char *) calloc (1, nbbuff); nbuff = nbytes / nbbuff; if (nbytes > nbuff * nbbuff) nbuff = nbuff + 1; /* Read input file header */ if ((oldhead = fitsrhead (filename0, &lhead0, &nbhead0)) == NULL) { snprintf (fitserrmsg, 79,"FITSCIMAGE: header of input file %s cannot be read\n", filename0); return (0); } /* Find size of output header */ nbhead = fitsheadsize (header); /* If overwriting, be more careful if new header is longer than old */ if (!strcmp (filename, filename0) && nbhead > nbhead0) { if ((image = fitsrimage (filename0, nbhead0, oldhead)) == NULL) { snprintf (fitserrmsg,79, "FITSCIMAGE: cannot read image from file %s\n", filename0); free (oldhead); return (0); } return (fitswimage (filename, header, image)); } free (oldhead); /* Open the input file and skip over the header */ if (strcasecmp (filename0,"stdin")) { fdin = -1; fdin = fitsropen (filename0); if (fdin < 0) { snprintf (fitserrmsg, 79,"FITSCIMAGE: cannot read file %s\n", filename0); return (0); } /* Skip over FITS header */ if (lseek (fdin, nbhead0, SEEK_SET) < 0) { (void)close (fdin); snprintf (fitserrmsg,79, "FITSCIMAGE: cannot skip header of file %s\n", filename0); return (0); } } #ifndef VMS else fdin = STDIN_FILENO; #endif /* Open the output file */ if (!access (filename, 0)) { fdout = open (filename, O_WRONLY); if (fdout < 3) { snprintf (fitserrmsg,79, "FITSCIMAGE: file %s not writeable\n", filename); return (0); } } else { fdout = open (filename, O_RDWR+O_CREAT, 0666); if (fdout < 3) { snprintf (fitserrmsg,79, "FITSCHEAD: cannot create file %s\n", filename); return (0); } } /* Pad header with spaces */ endhead = ksearch (header,"END") + 80; lasthead = header + nbhead; while (endhead < lasthead) *(endhead++) = ' '; /* Write header to file */ nbw = write (fdout, header, nbhead); if (nbw < nbhead) { snprintf (fitserrmsg, 79,"FITSCIMAGE: wrote %d / %d bytes of header to file %s\n", nbw, nbytes, filename); (void)close (fdout); (void)close (fdin); return (0); } /* Return if no data */ if (bitpix == 0) { (void)close (fdout); (void)close (fdin); return (nbhead); } nbdata = 0; for (ibuff = 0; ibuff < nbuff; ibuff++) { nbr = read (fdin, image, nbbuff); if (nbr > 0) { nbw = write (fdout, image, nbr); nbdata = nbdata + nbw; } } /* Write extra to make integral number of 2880-byte blocks */ nblocks = nbdata / FITSBLOCK; if (nblocks * FITSBLOCK < nbdata) nblocks = nblocks + 1; nbytes = nblocks * FITSBLOCK; nbpad = nbytes - nbdata; padding = (char *)calloc (1,nbpad); nbwp = write (fdout, padding, nbpad); nbw = nbdata + nbwp; free (padding); (void)close (fdout); (void)close (fdin); if (nbw < nbimage) { snprintf (fitserrmsg, 79, "FITSWIMAGE: wrote %d / %d bytes of image to file %s\n", nbw, nbimage, filename); return (0); } else return (nbw); } /* FITSWHEAD -- Write FITS header and keep file open for further writing */ int fitswhead (filename, header) char *filename; /* Name of IFTS image file */ char *header; /* FITS image header */ { int fd; int nbhead, nblocks; int nbytes, nbw; char *endhead, *lasthead; /* Open the output file */ if (!access (filename, 0)) { fd = open (filename, O_WRONLY); if (fd < 3) { snprintf (fitserrmsg, 79, "FITSWHEAD: file %s not writeable\n", filename); return (0); } } else { fd = open (filename, O_RDWR+O_CREAT, 0666); if (fd < 3) { snprintf (fitserrmsg, 79, "FITSWHEAD: cannot create file %s\n", filename); return (0); } } /* Write header to file */ endhead = ksearch (header,"END") + 80; nbhead = endhead - header; nblocks = nbhead / FITSBLOCK; if (nblocks * FITSBLOCK < nbhead) nblocks = nblocks + 1; nbytes = nblocks * FITSBLOCK; /* Pad header with spaces */ lasthead = header + nbytes; while (endhead < lasthead) *(endhead++) = ' '; nbw = write (fd, header, nbytes); if (nbw < nbhead) { fprintf (stderr, "FITSWHEAD: wrote %d / %d bytes of header to file %s\n", nbw, nbytes, filename); (void)close (fd); return (0); } return (fd); } /* FITSWEXHEAD -- Write FITS header in place */ int fitswexhead (filename, header) char *filename; /* Name of FITS image file with ,extension */ char *header; /* FITS image header */ { int fd; int nbhead, lhead; int nbw, nbnew, nbold; char *endhead, *lasthead, *oldheader; char *ext, cext; /* Compare size of existing header to size of new header */ fitsinherit = 0; oldheader = fitsrhead (filename, &lhead, &nbhead); if (oldheader == NULL) { fprintf (stderr, "FITSWEXHEAD: file %s cannot be read\n", filename); return (-1); } nbold = fitsheadsize (oldheader); nbnew = fitsheadsize (header); /* Return if the new header is bigger than the old header */ if (nbnew > nbold) { fprintf (stderr, "FITSWEXHEAD: old header %d bytes, new header %d bytes\n", nbold,nbnew); free (oldheader); oldheader = NULL; return (-1); } /* Add blank lines if new header is smaller than the old header */ else if (nbnew < nbold) { strcpy (oldheader, header); endhead = ksearch (oldheader,"END"); lasthead = oldheader + nbold; while (endhead < lasthead) *(endhead++) = ' '; strncpy (lasthead-80, "END", 3); } /* Pad header with spaces */ else { endhead = ksearch (header,"END") + 80; lasthead = header + nbnew; while (endhead < lasthead) *(endhead++) = ' '; strncpy (oldheader, header, nbnew); } /* Check for FITS extension and ignore for file opening */ ext = strchr (filename, ','); if (ext == NULL) ext = strchr (filename, '['); if (ext != NULL) { cext = *ext; *ext = (char) 0; } /* Open the output file */ fd = open (filename, O_WRONLY); if (ext != NULL) *ext = cext; if (fd < 3) { fprintf (stderr, "FITSWEXHEAD: file %s not writeable\n", filename); return (-1); } /* Skip to appropriate place in file */ (void) lseek (fd, ibhead, SEEK_SET); /* Write header to file */ nbw = write (fd, oldheader, nbold); (void)close (fd); free (oldheader); oldheader = NULL; if (nbw < nbhead) { fprintf (stderr, "FITSWHEAD: wrote %d / %d bytes of header to file %s\n", nbw, nbold, filename); return (-1); } return (0); } /* ISFITS -- Return 1 if FITS file, else 0 */ int isfits (filename) char *filename; /* Name of file for which to find size */ { int diskfile; char keyword[16]; int nbr; /* First check to see if this is an assignment */ if (strchr (filename, '=')) return (0); /* Then check file extension */ else if (strsrch (filename, ".fit") || strsrch (filename, ".fits") || strsrch (filename, ".fts")) return (1); /* Check for stdin (input from pipe) */ else if (!strcasecmp (filename,"stdin")) return (1); /* If no FITS file extension, try opening the file */ else { if ((diskfile = open (filename, O_RDONLY)) < 0) return (0); else { nbr = read (diskfile, keyword, 8); close (diskfile); if (nbr < 8) return (0); else if (!strncmp (keyword, "SIMPLE", 6)) return (1); else return (0); } } } /* FITSHEADSIZE -- Find size of FITS header */ int fitsheadsize (header) char *header; /* FITS header */ { char *endhead; int nbhead, nblocks; endhead = ksearch (header,"END") + 80; nbhead = endhead - header; nblocks = nbhead / FITSBLOCK; if (nblocks * FITSBLOCK < nbhead) nblocks = nblocks + 1; return (nblocks * FITSBLOCK); } /* Print error message */ void fitserr () { fprintf (stderr, "%s\n",fitserrmsg); return; } /* * Feb 8 1996 New subroutines * Apr 10 1996 Add subroutine list at start of file * Apr 17 1996 Print error message to stderr * May 2 1996 Write using stream IO * May 14 1996 If FITSRTOPEN NK is zero, return all keywords in header * May 17 1996 Make header internal to FITSRTOPEN * Jun 3 1996 Use stream I/O for input as well as output * Jun 10 1996 Remove unused variables after running lint * Jun 12 1996 Deal with byte-swapped images * Jul 11 1996 Rewrite code to separate header and data reading * Aug 6 1996 Fixed small defects after lint * Aug 6 1996 Drop unused NBHEAD argument from FITSRTHEAD * Aug 13 1996 If filename is stdin, read from standard input instead of file * Aug 30 1996 Use write for output, not fwrite * Sep 4 1996 Fix mode when file is created * Oct 15 1996 Drop column argument from FGET* subroutines * Oct 15 1996 Drop unused variable * Dec 17 1996 Add option to skip bytes in file before reading the header * Dec 27 1996 Turn nonprinting header characters into spaces * * Oct 9 1997 Add FITS extension support as filename,extension * Dec 15 1997 Fix minor bugs after lint * * Feb 23 1998 Do not append primary header if getting header for ext. 0 * Feb 23 1998 Accept either bracketed or comma extension * Feb 24 1998 Add SIMPLE keyword to start of extracted extension * Apr 30 1998 Fix error return if not table file after Allan Brighton * May 4 1998 Fix error in argument sequence in HGETS call * May 27 1998 Include fitsio.h and imio.h * Jun 1 1998 Add VMS fixes from Harry Payne at STScI * Jun 3 1998 Fix bug reading EXTNAME * Jun 11 1998 Initialize all header parameters before reading them * Jul 13 1998 Clarify argument definitions * Aug 6 1998 Rename fitsio.c to fitsfile.c to avoid conflict with CFITSIO * Aug 13 1998 Add FITSWHEAD to write only header * Sep 25 1998 Allow STDIN or stdin for standard input reading * Oct 5 1998 Add isfits() to decide whether a file is FITS * Oct 9 1998 Assume stdin and STDIN to be FITS files in isfits() * Nov 30 1998 Fix bug found by Andreas Wicenec when reading large headers * Dec 8 1998 Fix bug introduced by previous bug fix * * Jan 4 1999 Do not print error message if BITPIX is 0 * Jan 27 1999 Read and write all of 3D images if one dimension is 1 * Jan 27 1999 Pad out data to integral number of 2880-byte blocks * Apr 29 1999 Write BITPIX=-16 files as BITPIX=16 with BSCALE and BZERO * Apr 30 1999 Add % as alternative to , to denote sub-images * May 25 1999 Set buffer offsets to 0 when FITS table file is opened * Jul 14 1999 Do not try to write image data if BITPIX is 0 * Sep 27 1999 Add STDOUT as output filename option in fitswimage() * Oct 6 1999 Set header length global variable hget.lhead0 in fitsrhead() * Oct 14 1999 Update header length as it is changed in fitsrhead() * Oct 20 1999 Change | in if statements to || * Oct 25 1999 Change most malloc() calls to calloc() * Nov 24 1999 Add fitscimage() * * Feb 23 2000 Fix problem with some error returns in fitscimage() * Mar 17 2000 Drop unused variables after lint * Jul 20 2000 Drop BITPIX and NAXIS from primary header if extension printerd * Jul 20 2000 Start primary part of header with ROOTHEAD keyword * Jul 28 2000 Add loop to deal with buffered stdin * * Jan 11 2001 Print all messages to stderr * Jan 12 2001 Add extension back onto filename after fitsropen() (Guy Rixon) * Jan 18 2001 Drop EXTEND keyword when extracting an extension * Jan 18 2001 Add fitswext() to append HDU and fitswhdu() to do actual writing * Jan 22 2001 Ignore WCS name or letter following a : in file name in fitsrhead() * Jan 30 2001 Fix FITSCIMAGE so it doesn't overwrite data when overwriting a file * Feb 20 2001 Ignore WCS name or letter following a : in file name in fitsropen() * Feb 23 2001 Initialize rbrac in fitsropen() * Mar 8 2001 Use % instead of : for WCS specification in file name * Mar 9 2001 Fix bug so primary header is always appended to secondary header * Mar 9 2001 Change NEXTEND to NUMEXT in appended primary header * Mar 20 2001 Declare fitsheadsize() in fitschead() * Apr 24 2001 When matching column names, use longest length * Jun 27 2001 In fitsrthead(), allocate pw and lpnam only if more space needed * Aug 24 2001 In isfits(), return 0 if argument contains an equal sign * * Jan 28 2002 In fitsrhead(), allow stdin to include extension and/or WCS selection * Jun 18 2002 Save error messages as fitserrmsg and use fitserr() to print them * Oct 21 2002 Add fitsrsect() to read a section of an image * * Feb 4 2003 Open catalog file rb instead of r (Martin Ploner, Bern) * Apr 2 2003 Drop unused variable in fitsrsect() * Jul 11 2003 Use strcasecmp() to check for stdout and stdin * Aug 1 2003 If no other header, return root header from fitsrhead() * Aug 20 2003 Add fitsrfull() to read n-dimensional FITS images * Aug 21 2003 Modify fitswimage() to always write n-dimensional FITS images * Nov 18 2003 Fix minor bug in fitswhdu() * Dec 3 2003 Remove unused variable lasthead in fitswhdu() * * May 3 2004 Do not always append primary header to extension header * May 3 2004 Add ibhead as position of header read in file * May 19 2004 Do not reset ext if NULL in fitswexhead() * Jul 1 2004 Initialize INHERIT to 1 * Aug 30 2004 Move fitsheadsize() declaration to fitsfile.h * Aug 31 2004 If SIMPLE=F, put whatever is in file after header in image * * Mar 17 2005 Use unbuffered I/O in isfits() for robustness * Jun 27 2005 Drop unused variable nblocks in fitswexhead() * Aug 8 2005 Fix space-padding bug in fitswexhead() found by Armin Rest * Sep 30 2005 Fix fitsrsect() to position relatively, not absolutely * Oct 28 2005 Add error message if desired FITS extension is not found * Oct 28 2005 Fix initialization problem found by Sergey Koposov * * Feb 23 2006 Add fitsrtail() to read appended FITS headers * Feb 27 2006 Add file name to header-reading error messages * May 3 2006 Remove declarations of unused variables * Jun 20 2006 Initialize uninitialized variables * Nov 2 2006 Change all realloc() calls to calloc() * * Jan 5 2007 In fitsrtail(), change control characters in header to spaces * Apr 30 2007 Improve error reporting in FITSRFULL */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/fitsfile.h000066400000000000000000001731521215713201500222420ustar00rootroot00000000000000/*** File fitsfile.h FITS and IRAF file access subroutines *** June 11, 2007 *** By Doug Mink, dmink@cfa.harvard.edu *** Harvard-Smithsonian Center for Astrophysics *** Copyright (C) 1996-2007 *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Correspondence concerning WCSTools should be addressed as follows: Internet email: dmink@cfa.harvard.edu Postal address: Doug Mink Smithsonian Astrophysical Observatory 60 Garden St. Cambridge, MA 02138 USA */ #ifndef fitsfile_h_ #define fitsfile_h_ #include "fitshead.h" /* Declarations for subroutines in fitsfile.c, imhfile.c, imio.c, * fileutil.c, and dateutil.c */ #define FITSBLOCK 2880 /* FITS table keyword structure */ struct Keyword { char kname[10]; /* Keyword for table entry */ int lname; /* Length of keyword name */ int kn; /* Index of entry on line */ int kf; /* Index in line of first character of entry */ int kl; /* Length of entry value */ }; /* Structure for access to tokens within a string */ #define MAXTOKENS 1000 /* Maximum number of tokens to parse */ #define MAXWHITE 20 /* Maximum number of different whitespace characters */ struct Tokens { char *line; /* Line which has been parsed */ int lline; /* Number of characters in line */ int ntok; /* Number of tokens on line */ int nwhite; /* Number of whitespace characters */ char white[MAXWHITE]; /* Whitespace (separator) characters */ char *tok1[MAXTOKENS]; /* Pointers to start of tokens */ int ltok[MAXTOKENS]; /* Lengths of tokens */ int itok; /* Current token number */ }; #ifdef __cplusplus /* C++ prototypes */ extern "C" { #endif #ifdef __STDC__ /* Full ANSI prototypes */ /* Declarations for subroutines in fitsfile.c, imhfile.c, imio.c, * fileutil.c, and dateutil.c */ /* FITS file access subroutines in fitsfile.c */ int fitsropen( /* Open a FITS file for reading, returning a FILE pointer */ char *inpath); /* Pathname for FITS tables file to read */ char *fitsrhead( /* Read a FITS header */ char *filename, /* Name of FITS image file */ int *lhead, /* Allocated length of FITS header in bytes (returned) */ int *nbhead); /* Number of bytes before start of data (returned) */ char *fitsrtail( /* Read FITS header appended to graphics file */ char *filename, /* Name of FITS image file */ int *lhead, /* Allocated length of FITS header in bytes (returned) */ int *nbhead); /* Number of bytes before start of data (returned) */ char *fitsrimage( /* Read a FITS image */ char *filename, /* Name of FITS image file */ int nbhead, /* Actual length of image header(s) in bytes */ char *header); /* FITS header for image (previously read) */ char *fitsrfull( /* Read a FITS image of any dimension */ char *filename, /* Name of FITS image file */ int nbhead, /* Actual length of image header(s) in bytes */ char *header); /* FITS header for image (previously read) */ char *fitsrsect( /* Read a piece of a FITS image, header */ char *filename, /* Name of FITS image file */ char *header, /* FITS header for image (previously read) */ int nbhead, /* Actual length of image header(s) in bytes */ int x0, /* FITS image X coordinate of first pixel */ int y0, /* FITS image Y coordinate of first pixel */ int nx, /* Number of columns to read (less than NAXIS1) */ int ny, /* Number of rows to read (less than NAXIS2) */ int nlog); /* Note progress mod this rows */ int fitswhead( /* Write FITS header; keep file open for further writing */ char *filename, /* Name of FITS image file */ char *header); /* FITS header for image (previously read) */ int fitswexhead( /* Write FITS header in place */ char *filename, /* Name of FITS image file */ char *header); /* FITS header for image */ int fitswext( /* Write FITS header and image as extension to a file */ char *filename, /* Name of FITS image file */ char *header, /* FITS image header */ char *image); /* FITS image pixels */ int fitswhdu( /* Write FITS head and image as extension */ int fd, /* File descriptor */ char *filename, /* Name of FITS image file */ char *header, /* FITS image header */ char *image); /* FITS image pixels */ int fitswimage( /* Write FITS header and image */ char *filename, /* Name of FITS image file */ char *header, /* FITS image header */ char *image); /* FITS image pixels */ int fitscimage( /* Write FITS header and copy FITS image */ char *filename, /* Name of output FITS image file */ char *header, /* FITS image header */ char *filename0); /* Name of input FITS image file */ int isfits( /* Return 1 if file is a FITS file */ char *filename); /* Name of file to check */ void fitserr(); /* Print FITS error message to stderr */ void setfitsinherit( /* Set flag to append primary data header */ int inh); /* 1 to inherit primary data header, else 0 */ int fitsheadsize( /* Return size of fitsheader in bytes */ char *header); /* FITS image header */ /* FITS table file access subroutines in fitsfile.c */ int fitsrtopen( /* Open FITS table file and fill structure with * pointers to selected keywords * Return file descriptor (-1 if unsuccessful) */ char *inpath, /* Pathname for FITS tables file to read */ int *nk, /* Number of keywords to use */ struct Keyword **kw, /* Structure for desired entries */ int *nrows, /* Number of rows in table (returned) */ int *nchar, /* Number of characters in one table row (returned) */ int *nbhead); /* Number of characters before table starts */ int fitsrthead( /* Read pointers to selected keywords * from FITS table header */ char *header, /* Header for FITS tables file */ int *nk, /* Number of keywords to use */ struct Keyword **kw, /* Structure for desired entries */ int *nrows, /* Number of rows in table (returned) */ int *nchar); /* Number of characters in one table row (returned) */ void fitsrtlset(void); /* Reset FITS Table buffer limits from start of data */ int fitsrtline( /* Return specified line of FITS table */ int fd, /* File descriptor for FITS file */ int nbhead, /* Number of bytes in FITS header */ int lbuff, /* Number of bytes in table buffer */ char *tbuff, /* FITS table buffer */ int irow, /* Number of table row to read */ int nbline, /* Number of bytes to read for this line */ char *line); /* One line of FITS table (returned) */ short ftgeti2( /* Extract column for keyword from FITS table line * as short */ char *entry, /* Row or entry from table */ struct Keyword *kw); /* Table column information from FITS header */ int ftgeti4( /* Extract column for keyword from FITS table line * as int */ char *entry, /* Row or entry from table */ struct Keyword *kw); /* Table column information from FITS header */ float ftgetr4( /* Extract column for keyword from FITS table line * as float */ char *entry, /* Row or entry from table */ struct Keyword *kw); /* Table column information from FITS header */ double ftgetr8( /* Extract column for keyword from FITS table line * as double */ char *entry, /* Row or entry from table */ struct Keyword *kw); /* Table column information from FITS header */ int ftgetc( /* Extract column for keyword from FITS table line * as char string */ char *entry, /* Row or entry from table */ struct Keyword *kw, /* Table column information from FITS header */ char *string, /* Returned string */ int maxchar); /* Maximum number of characters in returned string */ /* IRAF file access subroutines in imhfile.c */ char *irafrhead( /* Read IRAF .imh header file and translate to FITS header */ char *filename, /* Name of IRAF header file */ int *lihead); /* Length of IRAF image header in bytes (returned) */ char *irafrimage( /* Read IRAF image pixels (call after irafrhead) */ char *fitsheader); /* FITS image header (filled) */ int irafwhead( /* Write IRAF .imh header file */ char *hdrname, /* Name of IRAF header file */ int lhead, /* Length of IRAF header */ char *irafheader, /* IRAF header */ char *fitsheader); /* FITS image header */ int irafwimage( /* Write IRAF .imh header file and .pix image file */ char *hdrname, /* Name of IRAF header file */ int lhead, /* Length of IRAF header */ char *irafheader, /* IRAF header */ char *fitsheader, /* FITS image header */ char *image); /* IRAF image */ int isiraf( /* return 1 if IRAF imh file, else 0 */ char *filename); /* Name of file to check */ char *iraf2fits( /* Convert IRAF image header to FITS image header, * returning FITS header */ char *hdrname, /* IRAF header file name (may be path) */ char *irafheader, /* IRAF image header */ int nbiraf, /* Number of bytes in IRAF header */ int *nbfits); /* Number of bytes in FITS header (returned) */ char *fits2iraf( /* Convert FITS image header to IRAF image header, * returning IRAF header */ char *fitsheader, /* FITS image header */ char *irafheader, /* IRAF image header (returned updated) */ int nbhead, /* Length of IRAF header */ int *nbiraf); /* Length of returned IRAF header */ /* Image pixel access subroutines in imio.c */ double getpix( /* Read one pixel from any data type 2-D array (0,0)*/ char *image, /* Image array as 1-D vector */ int bitpix, /* FITS bits per pixel * 16 = short, -16 = unsigned short, 32 = int * -32 = float, -64 = double */ int w, /* Image width in pixels */ int h, /* Image height in pixels */ double bzero, /* Zero point for pixel scaling */ double bscale, /* Scale factor for pixel scaling */ int x, /* Zero-based horizontal pixel number */ int y); /* Zero-based vertical pixel number */ double getpix1( /* Read one pixel from any data type 2-D array (1,1)*/ char *image, /* Image array as 1-D vector */ int bitpix, /* FITS bits per pixel */ int w, /* Image width in pixels */ int h, /* Image height in pixels */ double bzero, /* Zero point for pixel scaling */ double bscale, /* Scale factor for pixel scaling */ int x, /* One-based horizontal pixel number */ int y); /* One-based vertical pixel number */ double maxvec( /* Get maximum value in vector from a image */ char *image, /* Image array from which to extract vector */ int bitpix, /* Number of bits per pixel in image */ double bzero, /* Zero point for pixel scaling */ double bscale, /* Scale factor for pixel scaling */ int pix1, /* Offset of first pixel to extract */ int npix); /* Number of pixels to extract */ double minvec( /* Get minimum value in vector from a image */ char *image, /* Image array from which to extract vector */ int bitpix, /* Number of bits per pixel in image */ double bzero, /* Zero point for pixel scaling */ double bscale, /* Scale factor for pixel scaling */ int pix1, /* Offset of first pixel to extract */ int npix); /* Number of pixels to extract */ void putpix( /* Write one pixel to any data type 2-D array (0,0)*/ char *image, /* Image array as 1-D vector */ int bitpix, /* FITS bits per pixel */ int w, /* Image width in pixels */ int h, /* Image height in pixels */ double bzero, /* Zero point for pixel scaling */ double bscale, /* Scale factor for pixel scaling */ int x, /* Zero-based horizontal pixel number */ int y, /* Zero-based vertical pixel number */ double dpix); /* Value to put into image pixel */ void putpix1( /* Write one pixel to any data type 2-D array (1,1) */ char *image, /* Image array as 1-D vector */ int bitpix, /* FITS bits per pixel */ int w, /* Image width in pixels */ int h, /* Image height in pixels */ double bzero, /* Zero point for pixel scaling */ double bscale, /* Scale factor for pixel scaling */ int x, /* One-based horizontal pixel number */ int y, /* One-based vertical pixel number */ double dpix); /* Value to put into image pixel */ void addpix( /* Add to one pixel in any data type 2-D array (0,0)*/ char *image, /* Image array as 1-D vector */ int bitpix, /* FITS bits per pixel */ int w, /* Image width in pixels */ int h, /* Image height in pixels */ double bzero, /* Zero point for pixel scaling */ double bscale, /* Scale factor for pixel scaling */ int x, /* Zero-based horizontal pixel number */ int y, /* Zero-based vertical pixel number */ double dpix); /* Value to add to image pixel */ void addpix1( /* Add to one pixel in any data type 2-D array (1,1)*/ char *image, /* Image array as 1-D vector */ int bitpix, /* FITS bits per pixel */ int w, /* Image width in pixels */ int h, /* Image height in pixels */ double bzero, /* Zero point for pixel scaling */ double bscale, /* Scale factor for pixel scaling */ int x, /* One-based horizontal pixel number */ int y, /* One-based vertical pixel number */ double dpix); /* Value to add to image pixel */ void movepix( /* Move one pixel value between two 2-D arrays (0,0) */ char *image1, /* Pointer to first pixel in input image */ int bitpix1, /* Bits per input pixel (FITS codes) */ int w1, /* Number of horizontal pixels in input image */ int x1, /* Zero-based row for input pixel */ int y1, /* Zero-based column for input pixel */ char *image2, /* Pointer to first pixel in output image */ int bitpix2, /* Bits per output pixel (FITS codes) */ int w2, /* Number of horizontal pixels in output image */ int x2, /* Zero-based row for output pixel */ int y2); /* Zero-based column for output pixel */ void movepix1( /* Move one pixel value between two 2-D arrays (1,1) */ char *image1, /* Pointer to first pixel in input image */ int bitpix1, /* Bits per input pixel (FITS codes) */ int w1, /* Number of horizontal pixels in input image */ int x1, /* One-based row for input pixel */ int y1, /* One-based column for input pixel */ char *image2, /* Pointer to first pixel in output image */ int bitpix2, /* Bits per output pixel (FITS codes) */ int w2, /* Number of horizontal pixels in output image */ int x2, /* One-based row for output pixel */ int y2); /* One-based column for output pixel */ /* Image vector processing subroutines in imio.c */ void addvec( /* Add constant to vector from 2-D array */ char *image, /* Image array as 1-D vector */ int bitpix, /* FITS bits per pixel */ double bzero, /* Zero point for pixel scaling */ double bscale, /* Scale factor for pixel scaling */ int pix1, /* Offset of first pixel to which to add */ int npix, /* Number of pixels to which to add */ double dpix); /* Value to add to pixels */ void multvec( /* Multiply vector from 2-D array by a constant */ char *image, /* Image array as 1-D vector */ int bitpix, /* FITS bits per pixel */ double bzero, /* Zero point for pixel scaling */ double bscale, /* Scale factor for pixel scaling */ int pix1, /* Offset of first pixel to multiply */ int npix, /* Number of pixels to multiply */ double dpix); /* Value to add to pixels */ void getvec( /* Read vector from 2-D array */ char *image, /* Image array as 1-D vector */ int bitpix, /* FITS bits per pixel */ double bzero, /* Zero point for pixel scaling */ double bscale, /* Scale factor for pixel scaling */ int pix1, /* Offset of first pixel to extract */ int npix, /* Number of pixels to extract */ double *dvec0); /* Vector of pixels (returned) */ void putvec( /* Write vector into 2-D array */ char *image, /* Image array as 1-D vector */ int bitpix, /* FITS bits per pixel */ double bzero, /* Zero point for pixel scaling */ double bscale, /* Scale factor for pixel scaling */ int pix1, /* Offset of first pixel to insert */ int npix, /* Number of pixels to insert */ double *dvec0); /* Vector of pixels to insert */ void fillvec( /* Write constant into a vector */ char *image, /* Image array as 1-D vector */ int bitpix, /* FITS bits per pixel */ double bzero, /* Zero point for pixel scaling */ double bscale, /* Scale factor for pixel scaling */ int pix1, /* Zero-based offset of first pixel to multiply */ int npix, /* Number of pixels to multiply */ double dpix); /* Value to which to set pixels */ void fillvec1( /* Write constant into a vector */ char *image, /* Image array as 1-D vector */ int bitpix, /* FITS bits per pixel */ double bzero, /* Zero point for pixel scaling */ double bscale, /* Scale factor for pixel scaling */ int pix1, /* One-based offset of first pixel to multiply */ int npix, /* Number of pixels to multiply */ double dpix); /* Value to which to set pixels */ /* Image pixel byte-swapping subroutines in imio.c */ void imswap( /* Swap alternating bytes in a vector */ int bitpix, /* Number of bits per pixel */ char *string, /* Address of starting point of bytes to swap */ int nbytes); /* Number of bytes to swap */ void imswap2( /* Swap bytes in a vector of 2-byte (short) integers */ char *string, /* Address of starting point of bytes to swap */ int nbytes); /* Number of bytes to swap */ void imswap4( /* Reverse bytes in a vector of 4-byte numbers */ char *string, /* Address of starting point of bytes to swap */ int nbytes); /* Number of bytes to swap */ void imswap8( /* Reverse bytes in a vector of 8-byte numbers */ char *string, /* Address of starting point of bytes to swap */ int nbytes); /* Number of bytes to swap */ int imswapped(void); /* Return 1 if machine byte order is not FITS order */ /* File utilities from fileutil.c */ int getfilelines( /* Return number of lines in an ASCII file */ char *filename); /* Name of file to check */ char *getfilebuff( /* Return entire file contents in a character string */ char *filename); /* Name of file to read */ int getfilesize( /* Return size of a binary or ASCII file */ char *filename); /* Name of file to check */ int isimlist( /* Return 1 if file is list of FITS or IRAF image files, else 0 */ char *filename); /* Name of file to check */ int isimlistd( /* Return 1 if file is list of FITS or IRAF image files, else 0 */ char *filename, /* Name of file to check */ char *rootdir); /* Name of root directory for files in list */ int isfilelist( /* Return 1 if list of readable files, else 0 */ char *filename, /* Name of file to check */ char *rootdir); /* Name of root directory for files in list */ int isfile( /* Return 1 if file is a readable file, else 0 */ char *filename); /* Name of file to check */ int istiff( /* Return 1 if TIFF image file, else 0 */ char *filename); /* Name of file to check */ int isjpeg( /* Return 1 if JPEG image file, else 0 */ char *filename); /* Name of file to check */ int isgif( /* Return 1 if GIF image file, else 0 */ char *filename); /* Name of file to check */ int first_token( /* Return first token from the next line of an ASCII file */ FILE *diskfile, /* File descriptor for ASCII file */ int ncmax, /* Maximum number of characters returned */ char *token); /* First token on next line (returned) */ int stc2s ( /* Replace character in string with space */ char *spchar, /* Character to replace with spaces */ char *string); /* Character string to process */ int sts2c ( /* Replace spaces in string with character */ char *spchar, /* Character with which to replace spaces */ char *string); /* Character string to process */ /* Subroutines for access to tokens within a string from fileutil.c */ int setoken( /* Tokenize a string for easy decoding */ struct Tokens *tokens, /* Token structure returned */ char *string, /* character string to tokenize */ char *cwhite); /* additional whitespace characters * if = tab, disallow spaces and commas */ int nextoken( /* Get next token from tokenized string */ struct Tokens *tokens, /* Token structure returned */ char *token, /* token (returned) */ int maxchars); /* Maximum length of token */ int getoken( /* Get specified token from tokenized string */ struct Tokens *tokens, /* Token structure returned */ int itok, /* token sequence number of token * if <0, get whole string after token -itok * if =0, get whole string */ char *token, /* token (returned) */ int maxchars); /* Maximum length of token */ /* Subroutines for translating dates and times in dateutil.c */ /* Subroutines to convert from year and day of year */ void doy2dt( /* Year and day of year to yyyy.mmdd hh.mmss */ int year, /* Year */ double doy, /* Day of year with fraction */ double *date, /* Date as yyyy.mmdd (returned) */ double *time); /* Time as hh.mmssxxxx (returned) */ double doy2ep( /* Year and day of year to fractional year (epoch) */ int year, /* Year */ double doy); /* Day of year with fraction */ double doy2epb( /* year and day of year to Besselian epoch */ int year, /* Year */ double doy); /* Day of year with fraction */ double doy2epj( /* year and day of year to Julian epoch */ int year, /* Year */ double doy); /* Day of year with fraction */ char *doy2fd( /* year and day of year to FITS date */ int year, /* Year */ double doy); /* Day of year with fraction */ double doy2jd( /* year and day of year to Julian Day */ int year, /* Year */ double doy); /* Day of year with fraction */ double doy2mjd( /* year and day of year to Modified Julian Day */ int year, /* Year */ double doy); /* Day of year with fraction */ double doy2ts( /* year and day of year to seconds since 1950.0 */ int year, /* Year */ double doy); /* Day of year with fraction */ int doy2tsi( /* year and day of year to IRAF seconds since 1980-01-01 */ int year, /* Year */ double doy); /* Day of year with fraction */ time_t doy2tsu( /* year and day of year to Unix seconds since 1970-01-01 */ int year, /* Year */ double doy); /* Day of year with fraction */ /* Subroutines to convert from date and time */ void dt2doy( /* yyyy.mmdd hh.mmss to year and day of year */ double date, /* Date as yyyy.mmdd * yyyy = calendar year (e.g. 1973) * mm = calendar month (e.g. 04 = april) * dd = calendar day (e.g. 15) */ double time, /* Time as hh.mmssxxxx * if time<0, it is time as -(fraction of a day) * hh = hour of day (0 .le. hh .le. 23) * nn = minutes (0 .le. nn .le. 59) * ss = seconds (0 .le. ss .le. 59) * xxxx = tenths of milliseconds (0 .le. xxxx .le. 9999) */ int *year, /* Year (returned) */ double *doy); /* Day of year with fraction (returned) */ double dt2ep( /* yyyy.ddmm and hh.mmsss to fractional year (epoch) */ double date, /* Date as yyyy.mmdd */ double time); /* Time as hh.mmssxxxx */ double dt2epb( /* yyyy.ddmm and hh.mmsss to Besselian epoch */ double date, /* Date as yyyy.mmdd */ double time); /* Time as hh.mmssxxxx */ double dt2epj( /* yyyy.ddmm and hh.mmsss to Julian epoch */ double date, /* Date as yyyy.mmdd */ double time); /* Time as hh.mmssxxxx */ char *dt2fd( /* yyyy.ddmm and hh.mmsss to FITS date string */ double date, /* Date as yyyy.mmdd */ double time); /* Time as hh.mmssxxxx */ void dt2i( /* yyyy.ddmm and hh.mmsss to year, month, day, hrs, min, sec */ double date, /* Date as yyyy.mmdd */ double time, /* Time as hh.mmssxxxx */ int *iyr, /* year (returned) */ int *imon, /* month (returned) */ int *iday, /* day (returned) */ int *ihr, /* hours (returned) */ int *imn, /* minutes (returned) */ double *sec, /* seconds (returned) */ int ndsec); /* Number of decimal places in seconds (0=int) */ double dt2jd( /* yyyy.ddmm and hh.mmsss to Julian Day */ double date, /* Date as yyyy.mmdd */ double time); /* Time as hh.mmssxxxx */ double dt2mjd( /* yyyy.ddmm and hh.mmsss to Modified Julian Day */ double date, /* Date as yyyy.mmdd */ double time); /* Time as hh.mmssxxxx */ double dt2ts( /* yyyy.ddmm and hh.mmsss to seconds since 1950.0 */ double date, /* Date as yyyy.mmdd */ double time); /* Time as hh.mmssxxxx */ int dt2tsi( /* yyyy.ddmm and hh.mmsss to IRAF seconds since 1980-01-01 */ double date, /* Date as yyyy.mmdd */ double time); /* Time as hh.mmssxxxx */ time_t dt2tsu( /* yyyy.ddmm and hh.mmsss to Unix seconds since 1970-01-01 */ double date, /* Date as yyyy.mmdd */ double time); /* Time as hh.mmssxxxx */ /* Subroutines to convert from epoch (various types of fractional year) */ void ep2dt( /* Fractional year to yyyy.mmdd hh.mmssss */ double epoch, /* Date as fractional year */ double *date, /* Date as yyyy.mmdd (returned) */ double *time); /* Time as hh.mmssxxxx (returned) */ void epb2dt( /* Besselian epoch to yyyy.mmdd hh.mmssss */ double epoch, /* Besselian epoch (fractional 365.242198781-day years) */ double *date, /* Date as yyyy.mmdd (returned) */ double *time); /* Time as hh.mmssxxxx (returned) */ void epj2dt( /* Julian epoch to yyyy.mmdd hh.mmssss */ double epoch, /* Julian epoch (fractional 365.25-day years) */ double *date, /* Date as yyyy.mmdd (returned)*/ double *time); /* Time as hh.mmssxxxx (returned) */ char *ep2fd( /* Fractional year to FITS date string yyyy-mm-ddThh:mm:ss.ss */ double epoch); /* Date as fractional year */ char *epb2fd( /* Besselian epoch to FITS date string yyyy-mm-ddThh:mm:ss.ss */ double epoch); /* Besselian epoch (fractional 365.242198781-day years) */ char *epj2fd( /* Julian epoch to FITS date string yyyy-mm-ddThh:mm:ss.ss */ double epoch); /* Julian epoch (fractional 365.25-day years) */ void ep2i( /* Fractional year to year, month, day, hours, min., sec. */ double epoch, /* Date as fractional year */ int *iyr, /* year (returned) */ int *imon, /* month (returned) */ int *iday, /* day (returned) */ int *ihr, /* hours (returned) */ int *imn, /* minutes (returned) */ double *sec, /* seconds (returned) */ int ndsec); /* Number of decimal places in seconds (0=int) */ void epb2i( /* Besselian epoch to year, month, day, hours, min., sec. */ double epoch, /* Besselian epoch (fractional 365.242198781-day years) */ int *iyr, /* year (returned) */ int *imon, /* month (returned) */ int *iday, /* day (returned) */ int *ihr, /* hours (returned) */ int *imn, /* minutes (returned) */ double *sec, /* seconds (returned) */ int ndsec); /* Number of decimal places in seconds (0=int) */ void epj2i( /* Julian epoch to year, month, day, hours, min., sec. */ double epoch, /* Julian epoch (fractional 365.25-day years) */ int *iyr, /* year (returned) */ int *imon, /* month (returned) */ int *iday, /* day (returned) */ int *ihr, /* hours (returned) */ int *imn, /* minutes (returned) */ double *sec, /* seconds (returned) */ int ndsec); /* Number of decimal places in seconds (0=int) */ double ep2jd( /* Fractional year to Julian Date */ double epoch); /* Date as fractional year */ double epb2jd( /* Besselian epoch to Julian Date */ double epoch); /* Besselian epoch (fractional 365.242198781-day years) */ double epj2jd( /* Julian epoch to Julian Date */ double epoch); /* Julian epoch (fractional 365.25-day years) */ double ep2mjd( /* Fractional year to Modified Julian Date */ double epoch); /* Date as fractional year */ double epb2mjd( /* Besselian epoch to Modified Julian Date */ double epoch); /* Besselian epoch (fractional 365.242198781-day years) */ double epj2mjd( /* Julian epoch to Modified Julian Date */ double epoch); /* Julian epoch (fractional 365.25-day years) */ double ep2epb( /* Fractional year to Besselian epoch */ double epoch); /* Date as fractional year */ double ep2epj( /* Fractional year to Julian epoch */ double epoch); /* Date as fractional year */ double epb2epj( /* Besselian epoch to Julian epoch */ double epoch); /* Besselian epoch (fractional 365.242198781-day years) */ double epj2epb( /* Julian epoch to Besselian epoch */ double epoch); /* Julian epoch (fractional 365.25-day years) */ double epb2ep( /* Besselian epoch to fractional year */ double epoch); /* Besselian epoch (fractional 365.242198781-day years) */ double epj2ep( /* Julian epoch to fractional year */ double epoch); /* Julian epoch (fractional 365.25-day years) */ double ep2ts( /* Fractional year to seconds since 1950.0 */ double epoch); /* Date as fractional year */ double epb2ts( /* Besselian epoch to seconds since 1950.0 */ double epoch); /* Besselian epoch (fractional 365.242198781-day years) */ double epj2ts( /* Julian epoch to seconds since 1950.0 */ double epoch); /* Julian epoch (fractional 365.25-day years) */ /* Convert from FITS standard date string */ void fd2dt( /* FITS standard date string to date and time */ char *string, /* FITS date string, which may be: * fractional year * dd/mm/yy (FITS standard before 2000) * dd-mm-yy (nonstandard use before 2000) * yyyy-mm-dd (FITS standard after 1999) * yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ double *date, /* Date as yyyy.mmdd (returned)*/ double *time); /* Time as hh.mmssxxxx (returned) */ void fd2doy( /* FITS standard date string to year, day of year */ char *string, /* FITS date string */ int *year, /* Year (returned) */ double *doy); /* Day of year with fraction (returned) */ double fd2ep( /* FITS standard date string to fractional year (epoch) */ char *string); /* FITS date string */ double fd2epb( /* FITS standard date string to Besselian epoch */ char *string); /* FITS date string */ double fd2epj( /* FITS standard date string to Julian epoch */ char *string); /* FITS date string */ char *fd2fd( /* Any FITS standard date string to ISO FITS date string */ char *string); /* FITS date string */ char *fd2of( /* Any FITS standard date string to old FITS date and time */ char *string); /* FITS date string */ char *fd2ofd( /* Any FITS standard date string to old FITS date string */ char *string); /* FITS date string */ char *fd2oft( /* Any FITS standard date string to old FITS time string */ char *string); /* FITS date string */ void fd2i( /* FITS standard date string to year, mon, day, hrs, min, sec */ char *string, /* FITS date string */ int *iyr, /* year (returned) */ int *imon, /* month (returned) */ int *iday, /* day (returned) */ int *ihr, /* hours (returned) */ int *imn, /* minutes (returned) */ double *sec, /* seconds (returned) */ int ndsec); /* Number of decimal places in seconds (0=int) */ double fd2jd( /* FITS standard date string to Julian Day */ char *string); /* FITS date string */ double fd2mjd( /* FITS standard date string to Modified Julian Day */ char *string); /* FITS date string */ double fd2ts( /* FITS standard date to seconds since 1950-01-01 */ char *string); /* FITS date string */ int fd2tsi( /* FITS standard date to IRAF seconds since 1980-01-01 */ char *string); /* FITS date string */ time_t fd2tsu( /* FITS standard date to Unix seconds since 1970-01-01 */ char *string); /* FITS date string */ /* Convert from Julian Day */ void jd2doy( /* Julian Day to year and day of year */ double dj, /* Julian Day */ int *year, /* Year (returned) */ double *doy); /* Day of year with fraction (returned) */ void jd2dt( /* Julian Day to yyyy.mmdd hh.mmssss */ double dj, /* Julian Day */ double *date, /* Date as yyyy.mmdd (returned)*/ double *time); /* Time as hh.mmssxxxx (returned) */ double jd2ep( /* Julian Day to fractional year */ double dj); /* Julian Day */ double jd2epb( /* Julian Day to Besselian epoch */ double dj); /* Julian Day */ double jd2epj( /* Julian Day to Julian epoch */ double dj); /* Julian Day */ char *jd2fd( /* Julian Day to FITS date string yyyy-mm-ddThh:mm:ss.ss */ double dj); /* Julian Day */ void jd2i( /* Julian Day to year, month, day, hours, min., sec. */ double dj, /* Julian Day */ int *iyr, /* year (returned) */ int *imon, /* month (returned) */ int *iday, /* day (returned) */ int *ihr, /* hours (returned) */ int *imn, /* minutes (returned) */ double *sec, /* seconds (returned) */ int ndsec); /* Number of decimal places in seconds (0=int) */ double jd2mjd( /* Julian Day to Modified Julian day */ double dj); /* Julian Day */ double jd2ts( /* Julian Day to seconds since 1950.0 */ double dj); /* Julian Day */ time_t jd2tsu( /* Julian Day to Unix seconds since 1970-01-01T00:00 */ double dj); /* Julian Day */ int jd2tsi( /* Julian Day to IRAF seconds since 1980-01-01T00:00 */ double dj); /* Julian Day */ /* Convert current local time to various formats */ void lt2dt( /* Current local time to date (yyyy.mmdd), time (hh.mmsss) */ double *date, /* Date as yyyy.mmdd (returned) */ double *time); /* Time as hh.mmssxxxx (returned) */ char *lt2fd(void); /* Current local time to FITS ISO date string */ int lt2tsi(void); /* Current local time to IRAF seconds since 1980-01-01T00:00 */ time_t lt2tsu(void); /* Current local time to Unix seconds since 1970-01-01T00:00 */ double lt2ts(void); /* Current local time to IRAF seconds since 1950-01-01T00:00 */ /* Convert from Modified Julian Day (JD - 2400000.5) */ void mjd2doy( /* Modified Julian Day to year and day of year */ double dj, /* Modified Julian Day */ int *year, /* Year (returned) */ double *doy); /* Day of year with fraction (returned) */ void mjd2dt( /* Modified Julian Day to yyyy.mmdd hh.mmssss */ double dj, /* Modified Julian Date */ double *date, /* Date as yyyy.mmdd (returned)*/ double *time); /* Time as hh.mmssxxxx (returned) */ double mjd2ep( /* Modified Julian Day to fractional year */ double dj); /* Modified Julian Date */ double mjd2epb( /* Modified Julian Day to Besselian epoch */ double dj); /* Modified Julian Date */ double mjd2epj( /* Modified Julian Day to Julian epoch */ double dj); /* Modified Julian Date */ char *mjd2fd( /* Modified Julian Day to FITS date yyyy-mm-ddThh:mm:ss.ss */ double dj); /* Modified Julian Date */ void mjd2i( /* Modified Julian Day to year, month, day, hours, min, sec */ double dj, /* Modified Julian Date */ int *iyr, /* year (returned) */ int *imon, /* month (returned) */ int *iday, /* day (returned) */ int *ihr, /* hours (returned) */ int *imn, /* minutes (returned) */ double *sec, /* seconds (returned) */ int ndsec); /* Number of decimal places in seconds (0=int) */ double mjd2jd( /* Modified Julian Day to Julian day */ double dj); /* Modified Julian Date */ double mjd2ts( /* Modified Julian Day to seconds since 1950.0 */ double dj); /* Modified Julian Date */ /* Convert from seconds since 1950-01-01 0:00 (JPL Ephemeris time) */ void ts2dt( /* Seconds since 1950.0 to yyyy.mmdd hh.mmssss */ double tsec, /* seconds since 1950.0 */ double *date, /* Date as yyyy.mmdd (returned)*/ double *time); /* Time as hh.mmssxxxx (returned) */ double ts2ep( /* Seconds since 1950.0 to fractional year */ double tsec); /* seconds since 1950.0 */ double ts2epb( /* Seconds since 1950.0 to Besselian epoch */ double tsec); /* seconds since 1950.0 */ double ts2epj( /* Seconds since 1950.0 to Julian epoch */ double tsec); /* seconds since 1950.0 */ char *ts2fd( /* Seconds since 1950.0 to FITS date, yyyy-mm-ddT00:00:00.000 */ double tsec); /* seconds since 1950.0 */ void ts2i( /* Seconds since 1950.0 to year, month, day, hours, min, sec */ double tsec, /* seconds since 1950.0 */ int *iyr, /* year (returned) */ int *imon, /* month (returned) */ int *iday, /* day (returned) */ int *ihr, /* hours (returned) */ int *imn, /* minutes (returned) */ double *sec, /* seconds (returned) */ int ndsec); /* Number of decimal places in seconds (0=int) */ double ts2jd( /* Seconds since 1950.0 to Julian Day */ double tsec); /* seconds since 1950.0 */ double ts2mjd( /* Seconds since 1950.0 to Modified Julian Day */ double tsec); /* seconds since 1950.0 */ /* Convert from IRAF time (seconds since 1980-01-01 0:00 UT) */ char *tsi2fd( /* Seconds since 1980-01-01 to FITS standard date string */ int isec); /* Seconds past 1980-01-01 */ double tsi2ts( /* Seconds since 1980-01-01 to seconds since 1950-01-01 */ int isec); /* Seconds past 1980-01-01 */ void tsi2dt( /* Seconds since 1980-01-01 to date yyyy.mmdd, time hh.mmssss */ int isec, /* Seconds past 1980-01-01 */ double *date, /* Date as yyyy.mmdd (returned) */ double *time); /* Time as hh.mmssxxxx (returned) */ /* Convert from Unix time (seconds since 1970-01-01 0:00 UT) */ void tsu2dt( /* Seconds since 1970-01-01 to date yyyy.ddmm, time hh.mmsss */ time_t isec, /* Seconds past 1970-01-01 */ double *date, /* Date as yyyy.mmdd (returned) */ double *time); /* Time as hh.mmssxxxx (returned) */ char *tsu2fd( /* Seconds since 1970-01-01 to FITS standard date string */ time_t isec); /* Seconds past 1970-01-01 */ double tsu2ts( /* Seconds since 1970-01-01 to seconds since 1950-01-01 */ time_t isec); /* Seconds past 1970-01-01 */ int tsu2tsi( /* Seconds since 1970-01-01 to local seconds since 1980-01-01 */ time_t isec); /* Seconds past 1970-01-01 */ /* Convert times within a day */ char *tsd2fd( /* Seconds since start of day to FITS standard time string */ double tsec); /* Seconds since start of day */ double tsd2dt( /* Seconds since start of day to hh.mmsssss */ double tsec); /* Seconds since start of day */ /* Convert from current Universal Time */ void ut2dt( /* Current Universal Time to date (yyyy.mmdd), time (hh.mmsss) */ double *date, /* Date as yyyy.mmdd (returned) */ double *time); /* Time as hh.mmssxxxx (returned) */ void ut2doy( /* Current Universal Time to year, day of year */ int *year, /* Year (returned) */ double *doy); /* Day of year (returned) */ double ut2ep(void); /* Current Universal Time to fractional year */ double ut2epb(void); /* Current Universal Time to Besselian Epoch */ double ut2epj(void); /* Current Universal Time to Julian Epoch */ char *ut2fd(void); /* Current Universal Time to FITS ISO date string */ double ut2jd(void); /* Current Universal Time to Julian Date */ double ut2mjd(void); /* Current Universal Time to Modified Julian Date */ int ut2tsi(void); /* Current UT to IRAF seconds since 1980-01-01T00:00 */ time_t ut2tsu(void); /* Current UT to Unix seconds since 1970-01-01T00:00 */ double ut2ts(void); /* Current UT to seconds since 1950-01-01T00:00 */ int isdate( /* Return 1 if string is FITS old or ISO date */ char *string); /* Possible FITS date string, which may be: * dd/mm/yy (FITS standard before 2000) * dd-mm-yy (nonstandard FITS use before 2000) * yyyy-mm-dd (FITS standard after 1999) * yyyy-mm-ddThh:mm:ss.ss (FITS standard after 1999) */ /* Ephemeris time conversions (ET, TT, and TDT) */ char *et2fd( /* ET (or TDT or TT) in FITS format to UT in FITS format */ char *string); /* Ephemeris Time as FITS date string (E not T) */ char *fd2et( /* UT in FITS format to ET (or TDT or TT) in FITS format */ char *string); /* FITS date string */ void dt2et( /* yyyy.ddmm and hh.mmsss to Ephemeris Time */ double *date, /* Date as yyyy.mmdd */ double *time); /* Time as hh.mmssxxxx *if time<0, it is time as -(fraction of a day) */ double jd2jed( /* Convert from Julian Date to Julian Ephemeris Date */ double dj); /* Julian Date */ double jed2jd( /* Convert from Julian Ephemeris Date to Julian Date */ double dj); /* Julian Ephemeris Date */ double ets2ts( /* ET in seconds since 1950-01-01 to UT in same format */ double tsec); /* ET in seconds since 1950-01-01 */ double ts2ets( /* UT in seconds since 1950-01-01 to ET in same format */ double tsec); /* UT in seconds since 1950-01-01 */ void edt2dt( /* yyyy.ddmm and hh.mmsss Ephemeris Time to UT */ double *date, /* Date as yyyy.mmdd */ double *time); /* Time as hh.mmssxxxx * If time<0, it is time as -(fraction of a day) */ double utdt( /* Compute difference between UT and dynamical time (ET-UT) */ double dj); /* Julian Date (UT) */ /* Sidereal Time conversions */ char *fd2gst( /* Convert from FITS UT date to Greenwich Sidereal Time */ char *string); /* FITS date string */ void dt2gst( /* Convert from UT as yyyy.mmdd hh.mmssss to Greenwich Sidereal Time */ double *date, /* Date as yyyy.mmdd */ double *time); /* Time as hh.mmssxxxx * If time<0, it is time as -(fraction of a day) */ double jd2gst( /* Calculate Greenwich Sidereal Time given Julian Date */ double dj); /* Julian Date (UT) */ double ts2gst( /* Calculate Greenwich Sidereal Time given Universal Time */ double tsec); /* Time since 1950.0 in UT seconds */ char *fd2lst( /* Convert from FITS UT date to Local Sidereal Time */ char *string); /* FITS date string */ void dt2lst( /* Convert from UT as yyyy.mmdd hh.mmssss to Local Sidereal Time */ double *date, /* Date as yyyy.mmdd */ double *time); /* Time as hh.mmssxxxx * If time<0, it is time as -(fraction of a day) */ double ts2lst( /* Calculate Local Sidereal Time given Universal Time */ double tsec); /* Time since 1950.0 in UT seconds */ double jd2lst( /* Calculate Local Sidereal Time given Julian Date */ double dj); /* Julian Date (UT) */ double eqeqnx( /* Compute equation of eqinoxes from Julian Date */ double dj); /* Julian Date (UT) */ char *fd2mst( /* Convert from FITS UT date to Mean Sidereal Time */ char *string); /* FITS date string */ double jd2mst( /* Convert from Julian Date to Mean Sidereal Time */ double dj); /* Julian Date (UT) */ double jd2mst2( /* Convert from Julian Date to Mean Sidereal Time */ double dj); /* Julian Date (UT) */ void dt2mst( /* Convert from UT as yyyy.mmdd hh.mmssss to Mean Sidereal Time */ double *date, /* Date as yyyy.mmdd */ double *time); /* Time as hh.mmssxxxx * If time<0, it is time as -(fraction of a day) */ double lst2dt( /* Calculate UT as hh.mmsss given UT date and * Local Sidereal Time */ double date0, /* UT date as yyyy.mmdd */ double time0); /* LST as hh.mmssss */ double lst2jd( /* Calculate UT as Julian Date given UT date and * Local Sidereal Time */ double sdj); /* Julian Date of desired day at 0:00 UT + sidereal time */ char *lst2fd( /* Calculate FITS UT date and time given UT date and * Local Sidereal Time */ char *string); /* UT Date, LST as yyyy-mm-ddShh:mm:ss.ss */ char *gst2fd( /* Calculate FITS UT date and time given Greenwich Sidereal Time */ char *string); /* UT Date, GST as yyyy-mm-ddShh:mm:ss.ss */ double gst2jd( /* Calculate FITS UT Julian Date given Greenwich Sidereal Time */ double sdj); /* UT Date, GST as Julian Date */ char *mst2fd( /* Calculate FITS UT date and time given Mean Sidereal Time */ char *string); /* UT Date, MST as yyyy-mm-ddShh:mm:ss.ss */ double mst2jd( /* Calculate FITS UT Julian Date given Mean Sidereal Time */ double sdj); /* UT Date, MST as Julian Date */ double ts2mst( /* Calculate Mean Sidereal Time given Universal Time */ double tsec); /* time since 1950.0 in UT seconds */ void setlongitude( /* Longitude for sidereal time in or out */ double longitude); /* longitude of observatory in degrees (+=west) */ void compnut( /* Compute nutation in longitude and obliquity and mean obliquity*/ double dj, /* TDB (loosely ET or TT) as Julian Date */ double *dpsi, /* Nutation in longitude in radians (returned) */ double *deps, /* Nutation in obliquity in radians (returned) */ double *eps0); /* Mean obliquity in radians (returned) */ /* Heliocentric Julian Date conversions */ double mjd2mhjd( /* Convert from Modified Julian Date to Heliocentric MJD */ double mjd, /* Julian date (geocentric) */ double ra, /* Right ascension (degrees) */ double dec, /* Declination (degrees) */ int sys); /* J2000, B1950, GALACTIC, ECLIPTIC */ double mjd2hjd( /* Convert from Modified Julian Date to Heliocentric JD */ double mjd, /* Julian date (geocentric) */ double ra, /* Right ascension (degrees) */ double dec, /* Declination (degrees) */ int sys); /* J2000, B1950, GALACTIC, ECLIPTIC */ double mhjd2mjd( /* Convert from Heliocentric Modified Julian Date to MJD */ double mhjd, /* Modified Heliocentric Julian date */ double ra, /* Right ascension (degrees) */ double dec, /* Declination (degrees) */ int sys); /* J2000, B1950, GALACTIC, ECLIPTIC */ double jd2hjd( /* Convert from Julian Date to Heliocentric Julian Date */ double dj, /* Julian date (geocentric) */ double ra, /* Right ascension (degrees) */ double dec, /* Declination (degrees) */ int sys); /* J2000, B1950, GALACTIC, ECLIPTIC */ double hjd2jd( /* Convert from Heliocentric Julian Date to Julian Date */ double dj, /* Heliocentric Julian date */ double ra, /* Right ascension (degrees) */ double dec, /* Declination (degrees) */ int sys); /* J2000, B1950, GALACTIC, ECLIPTIC */ void setdatedec( /* Set number of decimal places in FITS dates */ int nd); /* Number of decimal places in FITS dates */ #else /* K&R prototypes */ /* FITS file access subroutines in fitsfile.c */ extern int fitsropen(); extern char *fitsrhead(); extern char *fitsrtail(); extern char *fitsrimage(); extern char *fitsrfull(); extern char *fitsrsect(); extern int fitswhead(); extern int fitswexhead(); extern int fitswext(); extern int fitswhdu(); extern int fitswimage(); extern int fitscimage(); extern int isfits(); /* Return 1 if file is a FITS file */ extern void fitserr(); /* Print FITS error message to stderr */ extern void setfitsinherit(); /* Set flag to append primary data header */ extern int fitsheadsize(); /* Return size of fitsheader in bytes */ /* FITS table file access subroutines in fitsfile.c */ extern int fitsrtopen(); extern int fitsrthead(); extern void fitsrtlset(); extern int fitsrtline(); extern short ftgeti2(); extern int ftgeti4(); extern float ftgetr4(); extern double ftgetr8(); extern int ftgetc(); /* IRAF file access subroutines in imhfile.c */ extern char *irafrhead(); extern char *irafrimage(); extern int irafwhead(); extern int irafwimage(); extern int isiraf(); extern char *iraf2fits(); extern char *fits2iraf(); /* Image pixel access subroutines in imio.c */ extern double getpix(); /* Read one pixel from any data type 2-D array (0,0)*/ extern double getpix1(); /* Read one pixel from any data type 2-D array (1,1)*/ extern double maxvec(); /* Get maximum value in vector from a image */ extern double minvec(); /* Get minimum value in vector from a image */ extern void putpix(); /* Write one pixel to any data type 2-D array (0,0)*/ extern void putpix1(); /* Write one pixel to any data type 2-D array (1,1) */ extern void addpix(); /* Add to one pixel in any data type 2-D array (0,0)*/ extern void addpix1(); /* Add to one pixel in any data type 2-D array (1,1)*/ extern void movepix(); /* Move one pixel value between two 2-D arrays (0,0) */ extern void movepix1(); /* Move one pixel value between two 2-D arrays (1,1) */ extern void addvec(); /* Add constant to vector from 2-D array */ extern void multvec(); /* Multiply vector from 2-D array by a constant */ extern void getvec(); /* Read vector from 2-D array */ extern void putvec(); /* Write vector into 2-D array */ extern void fillvec(); /* Write constant into a vector */ extern void fillvec1(); /* Write constant into a vector */ extern void imswap(); /* Swap alternating bytes in a vector */ extern void imswap2(); /* Swap bytes in a vector of 2-byte (short) integers */ extern void imswap4(); /* Reverse bytes in a vector of 4-byte numbers */ extern void imswap8(); /* Reverse bytes in a vector of 8-byte numbers */ extern int imswapped(); /* Return 1 if machine byte order is not FITS order */ /* File utilities from fileutil.c */ extern int getfilelines(); extern char *getfilebuff(); extern int getfilesize(); extern int isimlist(); extern int isimlistd(); extern int isfilelist(); extern int isfile(); extern int istiff(); extern int isjpeg(); extern int isgif(); extern int first_token(); /* Subroutines for access to tokens within a string from fileutil.c */ int setoken(); /* Tokenize a string for easy decoding */ int nextoken(); /* Get next token from tokenized string */ int getoken(); /* Get specified token from tokenized string */ /* Subroutines for translating dates and times in dateutil.c */ void doy2dt(); /* year and day of year to yyyy.mmdd hh.mmss */ double doy2ep(); /* year and day of year to fractional year (epoch) */ double doy2epb(); /* year and day of year to Besselian epoch */ double doy2epj(); /* year and day of year to Julian epoch */ char *doy2fd(); /* year and day of year to FITS date */ double doy2jd(); /* year and day of year to Julian date */ double doy2mjd(); /* year and day of year to modified Julian date */ double doy2ts(); /* year and day of year to seconds since 1950.0 */ int doy2tsi(); /* year and day of year to IRAF seconds since 1980-01-01 */ time_t doy2tsu(); /* year and day of year to Unix seconds since 1970-01-01 */ void dt2doy(); /* yyyy.mmdd hh.mmss to year and day of year */ double dt2ep(); /* yyyy.ddmm and hh.mmsss to fractional year (epoch) */ double dt2epb(); /* yyyy.ddmm and hh.mmsss to Besselian epoch */ double dt2epj(); /* yyyy.ddmm and hh.mmsss to Julian epoch */ char *dt2fd(); /* yyyy.ddmm and hh.mmsss to FITS date string */ void dt2i(); /* yyyy.ddmm and hh.mmsss to year, month, day, hrs, min, sec */ double dt2jd(); /* yyyy.ddmm and hh.mmsss to Julian date */ double dt2mjd(); /* yyyy.ddmm and hh.mmsss to modified Julian date */ double dt2ts(); /* yyyy.ddmm and hh.mmsss to seconds since 1950.0 */ int dt2tsi(); /* yyyy.ddmm and hh.mmsss to IRAF seconds since 1980-01-01 */ time_t dt2tsu(); /* yyyy.ddmm and hh.mmsss to Unix seconds since 1970-01-01 */ void ep2dt(); /* Fractional year to yyyy.mmdd hh.mmssss */ void epb2dt(); /* Besselian epoch to yyyy.mmdd hh.mmssss */ void epj2dt(); /* Julian epoch to yyyy.mmdd hh.mmssss */ char *ep2fd(); /* Fractional year to FITS date string yyyy-mm-ddThh:mm:ss.ss */ char *epb2fd(); /* Besselian epoch to FITS date string yyyy-mm-ddThh:mm:ss.ss */ char *epj2fd(); /* Julian epoch to FITS date string yyyy-mm-ddThh:mm:ss.ss */ void ep2i(); /* Fractional year to year, month, day, hours, min., sec. */ void epb2i(); /* Besselian epoch to year, month, day, hours, min., sec. */ void epj2i(); /* Julian epoch to year, month, day, hours, min., sec. */ double ep2jd(); /* Fractional year to Julian Date */ double epb2jd(); /* Besselian epoch to Julian Date */ double epj2jd(); /* Julian epoch to Julian Date */ double ep2mjd(); /* Fractional year to modified Julian Date */ double epb2mjd(); /* Besselian epoch to modified Julian Date */ double epj2mjd(); /* Julian epoch to modified Julian Date */ double ep2epb(); /* Fractional year to Besselian epoch */ double ep2epj(); /* Fractional year to Julian epoch */ double epb2epj(); /* Besselian epoch to Julian epoch */ double epj2epb(); /* Julian epoch to Besselian epoch */ double epb2ep(); /* Besselian epoch to fractional year */ double epj2ep(); /* Julian epoch to fractional year */ double ep2ts(); /* Fractional year to seconds since 1950.0 */ double epb2ts(); /* Besselian epoch to seconds since 1950.0 */ double epj2ts(); /* Julian epoch to seconds since 1950.0 */ void fd2dt(); /* FITS standard date string to Julian date */ void fd2doy(); /* FITS standard date string to year, day of year */ double fd2ep(); /* FITS standard date string to fractional year (epoch) */ double fd2epb(); /* FITS standard date string to Besselian epoch */ double fd2epj(); /* FITS standard date string to Julian epoch */ char *fd2fd(); /* Any FITS standard date string to ISO FITS date string */ char *fd2of(); /* Any FITS standard date string to old FITS date and time */ char *fd2ofd(); /* Any FITS standard date string to old FITS date string */ char *fd2oft(); /* Any FITS standard date string to old FITS time string */ void fd2i(); /* FITS standard date string to year, mon, day, hrs, min, sec */ double fd2jd(); /* FITS standard date string to Julian date */ double fd2mjd(); /* FITS standard date string to modified Julian date */ double fd2ts(); /* FITS standard date to seconds since 1950-01-01 */ int fd2tsi(); /* FITS standard date to IRAF seconds since 1980-01-01 */ time_t fd2tsu(); /* FITS standard date to Unix seconds since 1970-01-01 */ void jd2doy(); /* Julian date to year and day of year */ void jd2dt(); /* Julian date to yyyy.mmdd hh.mmssss */ double jd2ep(); /* Julian date to fractional year */ double jd2epb(); /* Julian date to Besselian epoch */ double jd2epj(); /* Julian date to Julian epoch */ char *jd2fd(); /* Julian date to FITS date string yyyy-mm-ddThh:mm:ss.ss */ void jd2i(); /* Julian date to year, month, day, hours, min., sec. */ double jd2mjd(); /* Julian date to modified Julian date */ double jd2ts(); /* Julian date to seconds since 1950.0 */ time_t jd2tsu(); /* Julian date to Unix seconds since 1970-01-01T00:00 */ int jd2tsi(); /* Julian date to IRAF seconds since 1980-01-01T00:00 */ void lt2dt(); /* Current local time to date (yyyy.mmdd), time (hh.mmsss) */ char *lt2fd(); /* Current local time to FITS ISO date string */ int lt2tsi(); /* Current local time to IRAF seconds since 1980-01-01T00:00 */ time_t lt2tsu(); /* Current local time to Unix seconds since 1970-01-01T00:00 */ double lt2ts(); /* Current local time to IRAF seconds since 1950-01-01T00:00 */ void mjd2doy(); /* Convert from Modified Julian Date to Day of Year */ void mjd2dt(); /* Modified Julian date to yyyy.mmdd hh.mmssss */ double mjd2ep(); /* Modified Julian date to fractional year */ double mjd2epb(); /* Modified Julian date to Besselian epoch */ double mjd2epj(); /* Modified Julian date to Julian epoch */ char *mjd2fd(); /* Modified Julian date to FITS date yyyy-mm-ddThh:mm:ss.ss */ void mjd2i(); /* Modified Julian date to year, month, day, hours, min, sec */ double mjd2jd(); /* Modified Julian date to Julian date */ double mjd2ts(); /* Modified Julian date to seconds since 1950.0 */ void ts2dt(); /* Seconds since 1950.0 to yyyy.mmdd hh.mmssss */ double ts2ep(); /* Seconds since 1950.0 to fractional year */ double ts2epb(); /* Seconds since 1950.0 to Besselian epoch */ double ts2epj(); /* Seconds since 1950.0 to Julian epoch */ char *ts2fd(); /* Seconds since 1950.0 to FITS date, yyyy-mm-ddT00:00:00.000 */ void ts2i(); /* Seconds since 1950.0 to year, month, day, hours, min, sec */ double ts2jd(); /* Seconds since 1950.0 to Julian date */ double ts2mjd(); /* Seconds since 1950.0 to modified Julian date */ char *tsi2fd(); /* Seconds since 1980-01-01 to FITS standard date string */ double tsi2ts(); /* Seconds since 1980-01-01 to seconds since 1950-01-01 */ double tsi2ts(); /* Seconds since 1980-01-01 to seconds since 1950-01-01 */ void tsi2dt(); /* Seconds since 1980-01-01 to date yyyy.mmdd, time hh.mmssss */ void tsu2dt(); /* Seconds since 1970-01-01 to date yyyy.ddmm, time hh.mmsss */ char *tsu2fd(); /* Seconds since 1970-01-01 to FITS standard date string */ char *tsd2fd(); /* Seconds since start of day to FITS standard time string */ double tsd2dt(); /* Seconds since start of day to hh.mmsssss */ double tsu2ts(); /* Seconds since 1970-01-01 to seconds since 1950-01-01 */ int tsu2tsi(); /* Seconds since 1970-01-01 to local seconds since 1980-01-01 */ int isdate(); /* Return 1 if string is FITS old or ISO date */ void ut2dt(); /* Current Universal Time to date (yyyy.mmdd), time (hh.mmsss) */ void ut2doy(); /* Current Universal Time to year, day of year */ double ut2ep(); /* Current Universal Time to fractional year */ double ut2epb(); /* Current Universal Time to Besselian Epoch */ double ut2epj(); /* Current Universal Time to Julian Epoch */ char *ut2fd(); /* Current Universal Time to FITS ISO date string */ double ut2jd(); /* Current Universal Time to Julian Date */ double ut2mjd(); /* Current Universal Time to Modified Julian Date */ int ut2tsi(); /* Current UT to IRAF seconds since 1980-01-01T00:00 */ time_t ut2tsu(); /* Current UT to Unix seconds since 1970-01-01T00:00 */ double ut2ts(); /* Current UT to IRAF seconds since 1950-01-01T00:00 */ int sts2c(); /* Replaces spaces in a string with a specified character */ int stc2s(); /* Replaces a specified character in a string with spaces */ char *et2fd(); /* ET (or TDT or TT) in FITS format to UT in FITS format */ char *fd2et(); /* UT in FITS format to ET (or TDT or TT) in FITS format */ double jd2jed(); /* Convert from Julian Date to Julian Ephemeris Date */ double jed2jd(); /* Convert from Julian Ephemeris Date to Julian Date */ double ets2ts(); /* ET in seconds since 1950-01-01 to UT in same format */ double ts2ets(); /* UT in seconds since 1950-01-01 to ET in same format */ void dt2et(); /* yyyy.ddmm and hh.mmsss to Ephemeris Time */ void edt2dt(); /* yyyy.ddmm and hh.mmsss Ephemeris Time to UT */ double utdt(); /* Compute difference between UT and dynamical time (ET-UT) */ char *fd2gst(); /* Convert from FITS UT date to Greenwich Sidereal Time */ void dt2gst(); /* Convert from UT as yyyy.mmdd hh.mmssss to Greenwich Sidereal Time */ double jd2gst(); /* Calculate Greenwich Sidereal Time given Julian Date */ double ts2gst(); /* Calculate Greenwich Sidereal Time given Universal Time */ char *fd2lst(); /* Convert from FITS UT date to Local Sidereal Time */ void dt2lst(); /* Convert from UT as yyyy.mmdd hh.mmssss to Local Sidereal Time */ double ts2lst(); /* Calculate Local Sidereal Time given Universal Time */ double jd2lst(); /* Calculate Local Sidereal Time given Julian Date */ double eqeqnx(); /* Compute equation of eqinoxes from Julian Date */ char *fd2mst(); /* Convert from FITS UT date to Mean Sidereal Time */ double jd2mst(); /* Convert from Julian Date to Mean Sidereal Time */ double jd2mst2(); /* Convert from Julian Date to Mean Sidereal Time */ void dt2mst(); /* Convert from UT as yyyy.mmdd hh.mmssss to Mean Sidereal Time */ double lst2ts(); /* Calculate Universal Time given Local Sidereal Time */ double lst2dt(); /* Calculate UT as yyyy.mmdd hh.mmsss given UT date and Local Sidereal Time */ double lst2jd(); /* Calculate UT as Julian Date given UT date and Local Sidereal Time */ char *lst2fd(); /* Calculate FITS UT date and time given UT date and Local Sidereal Time */ char *gst2fd(); /* Calculate FITS UT date and time given Greenwich Sidereal Time */ double gst2jd(); /* Calculate FITS UT Julian Date given Greenwich Sidereal Time */ char *mst2fd(); /* Calculate FITS UT date and time given Mean Sidereal Time */ double mst2jd(); /* Calculate FITS UT Julian Date given Mean Sidereal Time */ char *fd2mst(); /* Convert from FITS UT date to Mean Sidereal Time */ void dt2mst(); /* Convert from UT as yyyy.mmdd hh.mmssss to Mean Sidereal Time */ double ts2mst(); /* Calculate Mean Sidereal Time given Universal Time */ double mjd2mhjd(); /* Convert from Modified Julian Date to Heliocentric MJD */ double mjd2hjd(); /* Convert from Modified Julian Date to Heliocentric JD */ double mhjd2mjd(); /* Convert from Heliocentric Modified Julian Date to MJD */ double jd2hjd(); /* Convert from Julian Date to Heliocentric Julian Date */ double jd2mhjd(); /* Convert from Julian Date to Modified Heliocentric JD */ double hjd2jd(); /* Convert from Heliocentric Julian Date to Julian Date */ double hjd2mjd(); /* Convert from Heliocentric Julian Date to Modified JD */ double hjd2mhjd(); /* Convert from Heliocentric Julian Date to Modified HJD */ void setdatedec(); /* Set number of decimal places in FITS dates */ void setlongitude(); /* Longitude for sidereal time in or out */ void compnut(); /* Compute nutation in longitude and obliquity and mean obliquity*/ #endif /* __STDC__ */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* fitsfile_h_ */ /* May 31 1996 Use stream I/O for reading as well as writing * Jun 12 1996 Add byte-swapping subroutines * Jul 10 1996 FITS header now allocated in subroutines * Jul 17 1996 Add FITS table column extraction subroutines * Aug 6 1996 Add MOVEPIX, HDEL and HCHANGE declarations * * Oct 10 1997 FITS file opening subroutines now return int instead of FILE * * * May 27 1998 Split off fitsio and imhio subroutines to fitsio.h * Jun 4 1998 Change fits2iraf from int to int * * Jul 24 1998 Make IRAF header char instead of int * Aug 18 1998 Change name to fitsfile.h from fitsio.h * Oct 5 1998 Add isiraf() and isfits() * Oct 7 1998 Note separation of imhfile.c into two files * * Jul 15 1999 Add fileutil.c subroutines * Sep 28 1999 Add (1,1)-based image access subroutines * Oct 21 1999 Add fitswhead() * Nov 2 1999 Add date utilities from wcscat.h * Nov 23 1999 Add fitscimage() * Dec 15 1999 Fix misdeclaration of *2fd() subroutines, add fd2i(), dt2i() * Dec 20 1999 Add isdate() * * Jan 20 2000 Add conversions to and from Besselian and Julian epochs * Jan 21 2000 Add conversions to old FITS date and time * Jan 26 2000 Add conversion to modified Julian date (JD - 2400000.5 * Mar 22 2000 Add lt2* and ut2* to get current time as local and UT * Mar 24 2000 Add tsi2* and tsu2* to convert IRAF and Unix seconds * Sep 8 2000 Improve comments * * Apr 24 2001 Add length of column name to column data structure * May 22 2001 Add day of year date conversion subroutines * Sep 25 2001 Add isfilelist() and isfile() * * Jan 8 2002 Add sts2c() and stc2s() * Apr 8 2002 Change all long declarations to time_t for compatibility * Jun 18 2002 Add fitserr() to print error messages * Aug 30 2002 Add Ephemeris Time date conversions * Sep 10 2002 Add Sidereal Time conversions * Oct 21 2002 Add fitsrsect() to read sections of FITS images * * Mar 5 2003 Add isimlistd() to check image lists with root directory * Aug 20 2003 Add fitsrfull() to read n-dimensional simple FITS images * * Feb 27 2004 Add fillvec() and fillvec1() * May 3 2004 Add setfitsinherit() * May 6 2004 Add fitswexhead() * Aug 27 2004 Add fitsheadsize() * * Oct 14 2005 Add tsd2fd(), tsd2dt(), epj2ep(), epb2ep(), tsi2dt() * * Feb 23 2006 Add fitsrtail() to read appended FITS header * Feb 23 2006 Add istiff(), isjpeg(), isgif() to check TIFF, JPEG, GIF files * Sep 6 2006 Add heliocentric time conversions * Oct 5 2006 Add local sidereal time conversions * * Jan 9 2007 Add ANSI prototypes * Jan 11 2007 Add token subroutines from catutil.c/wcscat.h to fileutil.c * Jun 11 2007 Add minvec() subroutine in imio.c */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/fitshead.h000066400000000000000000000473511215713201500222250ustar00rootroot00000000000000/*** File fitshead.h FITS header access subroutines *** January 9, 2007 *** By Doug Mink, dmink@cfa.harvard.edu *** Harvard-Smithsonian Center for Astrophysics *** Copyright (C) 1996-2007 *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Correspondence concerning WCSTools should be addressed as follows: Internet email: dmink@cfa.harvard.edu Postal address: Doug Mink Smithsonian Astrophysical Observatory 60 Garden St. Cambridge, MA 02138 USA */ /* Declarations for subroutines in hget.c, hput.c, and iget.c */ #ifndef _fitshead_h_ #define _fitshead_h_ #include #ifdef __cplusplus /* C++ prototypes */ extern "C" { #endif #ifdef __STDC__ /* Full ANSI prototypes */ /* Subroutines in hget.c */ int hgeti2( /* Extract short value from FITS header */ const char* hstring, /* FITS header string */ const char* keyword, /* FITS keyword */ short* val); /* short integer value (returned) */ int hgeti4c( /* Extract int value from FITS header */ const char* hstring, /* FITS header string */ const char* keyword, /* FITS keyword */ const char* wchar, /* WCS to use (A-Z or null) */ int* val); /* integer value (returned) */ int hgeti4( /* Extract int value from FITS header */ const char* hstring, /* FITS header string */ const char* keyword, /* FITS keyword */ int* val); /* integer value (returned) */ int hgetr4( /* Extract float value from FITS header */ const char* hstring, /* FITS header string */ const char* keyword, /* FITS keyword */ float* val); /* float value (returned) */ int hgetr8c( /* Extract double value from FITS header */ const char* hstring, /* FITS header string */ const char* keyword, /* FITS keyword */ const char* wchar, /* WCS to use (A-Z or null) */ double* val); /* double value (returned) */ int hgetr8( /* Extract double value from FITS header */ const char* hstring, /* FITS header string */ const char* keyword, /* FITS keyword */ double* val); /* double value (returned) */ int hgetra( /* Extract right ascension from FITS header */ const char* hstring, /* FITS header string */ const char* keyword, /* FITS keyword */ double* ra); /* RA in degrees (returned) */ int hgetdec( /* Extract declination from FITS header */ const char* hstring, /* FITS header string */ const char* keyword, /* FITS keyword */ double* dec); /* Dec in degrees (returned) */ int hgetdate( /* Extract date from FITS header */ const char* hstring, /* FITS header string */ const char* keyword, /* FITS keyword */ double* date); /* Date in fractional years (returned) */ int hgetl( /* Extract boolean value from FITS header */ const char* hstring, /* FITS header string */ const char* keyword, /* FITS keyword */ int* lval); /* 1 if T, 0 if F (returned) */ int hgetsc( /* Extract string value from FITS header */ const char* hstring, /* FITS header string */ const char* keyword, /* FITS keyword */ const char* wchar, /* WCS to use (A-Z or null) */ const int lstr, /* maximum length of returned string */ char* string); /* null-terminated string value (returned) */ int hgets( /* Extract string value from FITS header */ const char* hstring, /* FITS header string */ const char* keyword, /* FITS keyword */ const int lstr, /* maximum length of returned string */ char* string); /* null-terminated string value (returned) */ int hgetm ( /* Extract string from multiple keywords */ const char* hstring, /* FITS header string */ const char* keyword, /* FITS keyword */ const int lstr, /* maximum length of returned string */ char* string); /* null-terminated string value (returned) */ int hgetndec( /* Find number of decimal places in FITS value*/ const char* hstring, /* FITS header string */ const char* keyword, /* FITS keyword */ int* ndec); /* number of decimal places (returned) */ char* hgetc( /* Return pointer to value for FITS keyword */ const char* hstring, /* FITS header string */ const char* keyword); /* FITS keyword */ char* ksearch( /* Return pointer to keyword in FITS header */ const char* hstring, /* FITS header string */ const char* keyword); /* FITS keyword */ char *blsearch ( const char* hstring, /* FITS header string */ const char* keyword); /* FITS keyword */ char *strsrch ( /* Find string s2 within string s1 */ const char* s1, /* String to search */ const char* s2); /* String to look for */ char *strnsrch ( /* Find string s2 within string s1 */ const char* s1, /* String to search */ const char* s2, /* String to look for */ const int ls1); /* Length of string being searched */ char *strcsrch ( /* Find string s2 within string s1 (no case) */ const char* s1, /* String to search */ const char* s2); /* String to look for */ char *strncsrch ( /* Find string s2 within string s1 (no case) */ const char* s1, /* String to search */ const char* s2, /* String to look for */ const int ls1); /* Length of string being searched */ int hlength( /* Set length of unterminated FITS header */ const char *header, /* FITS header */ const int lhead); /* Allocated length of FITS header */ int gethlength( /* Get length of current FITS header */ char* header); /* FITS header */ double str2ra( /* Return RA in degrees from string */ const char* in); /* Character string (hh:mm:ss.sss or dd.dddd) */ double str2dec( /* Return Dec in degrees from string */ const char* in); /* Character string (dd:mm:ss.sss or dd.dddd) */ int isnum( /* Return 1 if number, else 0 */ const char* string); /* Character string which may be a number */ int notnum( /* Return 0 if number, else 1 */ const char* string); /* Character string which may be a number */ int numdec( /* Return number of decimal places in number */ const char* string); /* Character string which may be a number */ void strfix( /* Clean up extraneous characters in string */ char* string, /* Character string which may be a number */ int fillblank, /* If 1, blanks are replaced by underscores */ int dropzero); /* If 1, drop trailing zeroes from string */ char *getltime(void); /* Return current local time in ISO format */ char *getutime(void); /* Return current UT as an ISO-format string */ /* Subroutines in iget.c */ int mgetstr( /* Extract string from multiline FITS keyword */ const char* hstring, /* FITS header string */ const char* mkey, /* FITS keyword root _n added for extra lines */ const char* keyword, /* IRAF keyword */ const int lstr, /* maximum length of returned string */ char* string); /* null-terminated string value (returned) */ int mgeti4( /* Extract int from multiline FITS keyword */ const char* hstring, /* FITS header string */ const char* mkey, /* FITS keyword root _n added for extra lines */ const char* keyword, /* IRAF keyword */ int* ival); /* int keyword value (returned) */ int mgetr8( /* Extract double from multiline FITS keyword */ const char* hstring, /* FITS header string */ const char* mkey, /* FITS keyword root _n added for extra lines */ const char* keyword, /* IRAF keyword */ double* dval); /* double keyword value (returned) */ int igeti4( /* Extract int from IRAF keyword string */ const char* hstring, /* Multiline IRAF keyword string value */ const char* keyword, /* IRAF keyword */ int* val); /* int value (returned) */ int igetr4( /* Extract float from IRAF keyword string */ const char* hstring, /* Multiline IRAF keyword string value */ const char* keyword, /* IRAF keyword */ float* val); /* float value (returned) */ int igetr8( /* Extract double from IRAF keyword string */ const char* hstring, /* Multiline IRAF keyword string value */ const char* keyword, /* IRAF keyword */ double* val); /* double value (returned) */ int igets( /* Extract string from IRAF keyword string */ const char* hstring, /* Multiline IRAF keyword string value */ const char* keyword, /* IRAF keyword */ const int lstr, /* maximum length of returned string */ char* string); /* null-terminated string value (returned) */ char *igetc( /* Extract string from IRAF keyword string */ const char* hstring, /* Multiline IRAF keyword string value */ const char* keyword); /* IRAF keyword */ /* Subroutines in hput.c */ /* All hput* routines return 0 if successful, else -1 */ int hputi2( /* Implant short value into FITS header */ char* hstring, /* FITS header string (modified) */ const char* keyword, /* FITS keyword */ short ival); /* short value */ int hputi4( /* Implant int value into FITS header */ char* hstring, /* FITS header string (modified) */ const char* keyword, /* FITS keyword */ const int ival); /* int value */ int hputr4( /* Implant float value into FITS header */ char* hstring, /* FITS header string (modified) */ const char* keyword, /* FITS keyword */ const float* rval); /* float (4 byte) value */ int hputr8( /* Implant short into FITS header */ char* hstring, /* FITS header string (modified) */ const char* keyword, /* FITS keyword */ const double dval); /* double value */ int hputnr8( /* double with specified number of decimal places */ char* hstring, /* FITS header string (modified) */ const char* keyword, /* FITS keyword */ const int ndec, /* Number of decimal places in keyword value */ const double dval); /* double value */ int hputs( /* Quoted character string into FITS header */ char* hstring, /* FITS header string (modified) */ const char* keyword, /* FITS keyword */ const char* cval); /* Character string value */ int hputm( /* Quoted character string, mutiple keywords */ char* hstring, /* FITS header string (modified) */ const char* keyword, /* FITS keyword */ const char* cval); /* Character string value */ int hputcom( /* Add comment to keyword line in FITS header */ char* hstring, /* FITS header string (modified) */ const char* keyword, /* FITS keyword */ const char* comment); /* Comment string */ int hputra( /* Right ascension in degrees into hh:mm:ss.sss */ char* hstring, /* FITS header string (modified) */ const char* keyword, /* FITS keyword */ const double ra); /* Right ascension in degrees */ int hputdec( /* Declination in degrees into dd:mm:ss.ss */ char* hstring, /* FITS header string (modified) */ const char* keyword, /* FITS keyword */ const double dec); /* Declination in degrees */ int hputl( /* Implant boolean value into FITS header */ char* hstring, /* FITS header string (modified) */ const char* keyword, /* FITS keyword */ const int lval); /* 0->F, else ->T */ int hputc( /* Implant character string without quotes */ char* hstring, /* FITS header string (modified) */ const char* keyword, /* FITS keyword */ const char* cval); /* Character string value */ int hdel( /* Delete a keyword line from a FITS header */ char* hstring, /* FITS header string (modified) */ const char* keyword); /* FITS keyword to delete */ int hadd( /* Add a keyword line from a FITS header */ char* hplace, /* Location in FITS header string (modified) */ const char* keyword); /* FITS keyword to add */ int hchange( /* Change a keyword name in a FITS header */ char* hstring, /* FITS header string (modified) */ const char* keyword1, /* Current FITS keyword name */ const char* keyword2); /* New FITS keyword name */ void ra2str( /* Convert degrees to hh:mm:ss.ss */ char *string, /* Character string (returned) */ int lstr, /* Length of string */ const double ra, /* Right ascension in degrees */ const int ndec); /* Number of decimal places in seconds */ void dec2str( /* Convert degrees to dd:mm:ss.ss */ char *string, /* Character string (returned) */ int lstr, /* Length of string */ const double dec, /* Declination in degrees */ const int ndec); /* Number of decimal places in arcseconds */ void deg2str( /* Format angle into decimal degrees string */ char *string, /* Character string (returned) */ int lstr, /* Length of string */ const double deg, /* Angle in degrees */ const int ndec); /* Number of decimal places in degrees */ void num2str( /* Format number into string */ char *string, /* Character string (returned) */ const double num, /* Number */ const int field, /* Total field size in characters */ const int ndec); /* Number of decimal places */ void setheadshrink( /* 0 to keep blank line when keyword deleted */ const int hsh); /* 1 to shrink header by one line */ void setleaveblank( /* 1 to keep blank line where keyword deleted */ const int hsh); /* 0 to shrink header by one line */ #else /* K&R prototypes */ /* Subroutines in hget.c */ /* Extract a value from a FITS header for given keyword */ extern int hgeti4(); /* int (Multiple WCS) */ extern int hgeti4c(); /* int */ extern int hgeti2(); /* short */ extern int hgetr4(); /* float */ extern int hgetr8(); /* double */ extern int hgetr8c(); /* double (Multiple WCS) */ extern int hgetra(); /* Right ascension in degrees from string */ extern int hgetdec(); /* Declination in degrees from string */ extern int hgetdate(); /* Date in years from FITS date string */ extern int hgetl(); /* T->1, F->0 from FITS logical entry */ extern int hgets(); /* Previously allocated string */ extern int hgetsc(); /* Previously allocated string (Multiple WCS) */ extern int hgetm(); /* Previously allocated string from multiple keywords */ extern char *hgetc(); /* Return pointer to string */ extern int hgetndec(); /* Number of decimal places in keyword value */ /* Subroutines to convert strings to RA and Dec in degrees */ extern double str2ra(); extern double str2dec(); /* Check to see whether a string is a number or not */ extern int isnum(); extern int notnum(); extern int decnum(); /* Find given keyword entry in FITS header */ extern char *ksearch(); /* Find beginning of fillable blank line before FITS header keyword */ extern char *blsearch(); /* Search for substring s2 within string s1 */ extern char *strsrch (); /* s1 null-terminated */ extern char *strnsrch (); /* s1 ls1 characters long */ extern char *strcsrch (); /* s1 null-terminated (case-insensitive) */ extern char *strncsrch (); /* s1 ls1 characters long (case-insensitive) */ extern void strfix(); /* Drop or change extraneous characters in string */ /* Set length of header which is not null-terminated */ extern int hlength(); /* Get length of current FITS header */ extern int gethlength(); /* Subroutines in iget.c */ extern int mgetstr(); /* Previously allocated string from multiline keyword */ extern int mgetr8(); /* double from multiline keyword */ extern int mgeti4(); /* int from multiline keyword */ extern int igeti4(); /* long integer from IRAF compound keyword value */ extern int igetr4(); /* real from IRAF compound keyword value */ extern int igetr8(); /* double from IRAF compound keyword value */ extern int igets(); /* character string from IRAF compound keyword value */ extern char *igetc(); /* Extract string from IRAF keyword string */ /* Subroutines in hput.c */ /* Implant a value into a FITS header for given keyword */ extern int hputi4(); /* int */ extern int hputi2(); /* short */ extern int hputr4(); /* float */ extern int hputr8(); /* double */ extern int hputnr8(); /* double with specified number of decimal places */ extern int hputra(); /* Right ascension in degrees into hh:mm:ss.sss */ extern int hputdec(); /* Declination in degrees into dd:mm:ss.ss */ extern int hputl(); /* 0 -> F, else T FITS logical entry */ extern int hputs(); /* Quoted character string */ extern int hputm(); /* Quoted character string into mutiple keywords */ extern int hputc(); /* Character string without quotes (returns 0 if OK) */ extern int hputcom(); /* Comment after keyword=value (returns 0 if OK) */ extern int hdel(); /* Delete a keyword line from a FITS header */ extern int hadd(); /* Add a keyword line to a FITS header */ extern int hchange(); /* Change a keyword name in a FITS header */ extern void setheadshrink(); /* Set flag for deleted keyword space disposition*/ extern void setleaveblank(); /* Set flag for deleted keyword space disposition*/ /* Subroutines to convert RA and Dec in degrees to strings */ extern void ra2str(); extern void dec2str(); extern void deg2str(); extern void num2str(); extern int numdec(); /* Return number of decimal places in number */ extern char *getltime(); /* Return current local time in ISO format */ extern char *getutime(); /* Return current UT as an ISO-format string */ #endif /* __STDC__ */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* fitshead_h_ */ /* Apr 26 1996 Add HGETDATE to get year from date string * May 22 1996 Return double from STR2RA and STR2DEC * May 31 1996 Use stream I/O for reading as well as writing * Jun 12 1996 Add byte-swapping subroutines * Jul 10 1996 FITS header now allocated in subroutines * Jul 17 1996 Add FITS table column extraction subroutines * Jul 19 1996 Add declarations for header implanting subroutines * Aug 5 1996 Add HLENGTH for FITS headers which are not null-terminated * Aug 5 1996 Add STRNSRCH for FITS headers which are not null-terminated * Aug 6 1996 Add HPUTNR8 to save a specified number of decimal places * Aug 6 1996 Add MOVEPIX, HDEL and HCHANGE declarations * Nov 1 1996 Add DEG2STR * Dec 12 1996 Add ISNUM * * Oct 10 1997 FITS file opening subroutines now return int instead of FILE * * * Mar 12 1998 Add NOTNUM * Apr 30 1998 Clean up declarations and add more comments * May 12 1998 Add MGETS, MGETR8, MGETI4 for IRAF multi-line keywords * May 26 1998 Add HGETNDEC for number of decimal places in keyword value * May 27 1998 Add BLSEARCH to find usable blank lines in header * May 27 1998 Split off fitsio and imhio subroutines to fitsio.h * May 27 1998 Add all subroutines in hget.c, hput.c, and iget.c to C++ dec. * Jun 24 1998 Add string lengths to ra2str(), dec2str, and deg2str() calls * Jun 25 1998 Fix other C++ declarations with added string lengths * Aug 31 1998 Add current date subroutines getltime() and getutime() * Oct 28 1998 Add missing hgetc() to non c++ declarations * * Oct 6 1999 Add gethlength() to return current size of header * Oct 14 1999 All HPUT subroutines now return an error code, 0 if OK, else -1 * Oct 15 1999 Add hputcom() declaration * Oct 21 1999 Add hgetm() declaration * * Mar 22 2000 Add int to iget*() declarations * Mar 27 2000 Add hputm() declaration * * Apr 3 2002 Add hgeti4c(), hgetr8c(), and hgetsc() * Apr 8 2002 Include sys/types.h * Aug 30 2002 Add strcsrch() and strncsrch() * * Sep 23 2003 Change mgets() to mgetstr() to avoid name collision at UCO Lick * Oct 20 2003 Add numdec() to return the number of decimal places in a string * * Feb 26 2004 Add igetc(), formerly internal to iget.c * Jul 1 2004 Add setheadshrink() for hdel() * Aug 30 2004 Add numdec() to non-C++ declarations * * May 22 2006 Add setleaveblank() to leave blank line where keyword is deleted * Jun 28 2006 Add strfix() to clean up characters in strings * Nov 29 2006 Drop semicolon at end of C++ ifdef * * Jan 9 2007 Fix declarations so ANSI prototypes are not just for C++ */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/hget.c000066400000000000000000001467231215713201500213630ustar00rootroot00000000000000/* * pbiereic 16.07.08 Fixes for gcc version 4.2.4 * pbiereic 16.07.08 Included original ksearch routine (instead of using findit()) */ /*** File libwcs/hget.c *** August 22, 2007 *** By Doug Mink, dmink@cfa.harvard.edu *** Harvard-Smithsonian Center for Astrophysics *** Copyright (C) 1994-2007 *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Correspondence concerning WCSTools should be addressed as follows: Internet email: dmink@cfa.harvard.edu Postal address: Doug Mink Smithsonian Astrophysical Observatory 60 Garden St. Cambridge, MA 02138 USA * Module: hget.c (Get FITS Header parameter values) * Purpose: Extract values for variables from FITS header string * Subroutine: hgeti2 (hstring,keyword,ival) returns short integer * Subroutine: hgeti4c (hstring,keyword,wchar,ival) returns long integer * Subroutine: hgeti4 (hstring,keyword,ival) returns long integer * Subroutine: hgetr4 (hstring,keyword,rval) returns real * Subroutine: hgetra (hstring,keyword,ra) returns double RA in degrees * Subroutine: hgetdec (hstring,keyword,dec) returns double Dec in degrees * Subroutine: hgetr8c (hstring,keyword,wchar,dval) returns double * Subroutine: hgetr8 (hstring,keyword,dval) returns double * Subroutine: hgetl (hstring,keyword,lval) returns logical int (0=F, 1=T) * Subroutine: hgetsc (hstring,keyword,wchar,lstr,str) returns character string * Subroutine: hgets (hstring,keyword, lstr, str) returns character string * Subroutine: hgetm (hstring,keyword, lstr, str) returns multi-keyword string * Subroutine: hgetdate (hstring,keyword,date) returns date as fractional year * Subroutine: hgetndec (hstring, keyword, ndec) returns number of dec. places * Subroutine: hgetc (hstring,keyword) returns character string * Subroutine: blsearch (hstring,keyword) returns pointer to blank lines before keyword * Subroutine: ksearch (hstring,keyword) returns pointer to header string entry * Subroutine: str2ra (in) converts string to right ascension in degrees * Subroutine: str2dec (in) converts string to declination in degrees * Subroutine: strsrch (s1, s2) finds string s2 in null-terminated string s1 * Subroutine: strnsrch (s1, s2, ls1) finds string s2 in ls1-byte string s1 * Subroutine: hlength (header,lhead) sets length of FITS header for searching * Subroutine: isnum (string) returns 1 if integer, 2 if fp number, else 0 * Subroutine: notnum (string) returns 0 if number, else 1 * Subroutine: numdec (string) returns number of decimal places in numeric string * Subroutine: strfix (string,blankfill,zerodrop) removes extraneous characters */ #include /* NULL, strlen, strstr, strcpy */ #include #include "fitshead.h" /* FITS header extraction subroutines */ #include #ifndef VMS #include #else #define INT_MAX 2147483647 /* Biggest number that can fit in long */ #define SHRT_MAX 32767 #endif #define VLENGTH 81 #ifdef USE_SAOLIB static int use_saolib=0; #endif char *hgetc (); static char val[VLENGTH+1]; static int multiline = 0; static int lhead0 = 0; /* Length of header string */ /* Set the length of the header string, if not terminated by NULL */ int hlength (header, lhead) const char *header; /* FITS header */ int lhead; /* Maximum length of FITS header */ { char *hend; if (lhead > 0) lhead0 = lhead; else { lhead0 = 0; hend = ksearch (header,"END"); lhead0 = hend + 80 - header; } return (lhead0); } /* Return the length of the header string, computing it if lhead0 not set */ int gethlength (header) char *header; /* FITS header */ { if (lhead0 > 0) return (lhead0); else return (hlength (header, 0)); } /* Extract Integer*4 value for variable from FITS header string */ int hgeti4c (hstring,keyword,wchar,ival) const char *hstring; /* character string containing FITS header information in the format = {/ } */ const char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ const char *wchar; /* Character of multiple WCS header; =0 if unused */ int *ival; /* Keyword value returned */ { char keyword1[16]; int lkey; if (wchar[0] < (char) 64) return (hgeti4 (hstring, keyword, ival)); else { strcpy (keyword1, keyword); lkey = strlen (keyword); keyword1[lkey] = wchar[0]; keyword1[lkey+1] = (char) 0; return (hgeti4 (hstring, keyword1, ival)); } } /* Extract long value for variable from FITS header string */ int hgeti4 (hstring,keyword,ival) const char *hstring; /* character string containing FITS header information in the format = {/ } */ const char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ int *ival; { char *value; double dval; int minint; int lval; char *dchar; /* Get value and comment from header string */ value = hgetc (hstring,keyword); /* Translate value from ASCII to binary */ if (value != NULL) { if (value[0] == '#') value++; minint = -INT_MAX - 1; lval = strlen (value); if (lval > VLENGTH) { strncpy (val, value, VLENGTH); val[VLENGTH] = (char) 0; } else strcpy (val, value); if (isnum (val) == 2) { if ((dchar = strchr (val, 'D'))) *dchar = 'e'; if ((dchar = strchr (val, 'd'))) *dchar = 'e'; if ((dchar = strchr (val, 'E'))) *dchar = 'e'; } dval = atof (val); if (dval+0.001 > INT_MAX) *ival = INT_MAX; else if (dval >= 0) *ival = (int) (dval + 0.001); else if (dval-0.001 < minint) *ival = minint; else *ival = (int) (dval - 0.001); return (1); } else { return (0); } } /* Extract integer*2 value for variable from fits header string */ int hgeti2 (hstring,keyword,ival) const char *hstring; /* character string containing FITS header information in the format = {/ } */ const char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ short *ival; { char *value; double dval; int minshort; int lval; char *dchar; /* Get value and comment from header string */ value = hgetc (hstring,keyword); /* Translate value from ASCII to binary */ if (value != NULL) { if (value[0] == '#') value++; lval = strlen (value); if (lval > VLENGTH) { strncpy (val, value, VLENGTH); val[VLENGTH] = (char) 0; } else strcpy (val, value); if (isnum (val) == 2) { if ((dchar = strchr (val, 'D'))) *dchar = 'e'; if ((dchar = strchr (val, 'd'))) *dchar = 'e'; if ((dchar = strchr (val, 'E'))) *dchar = 'e'; } dval = atof (val); minshort = -SHRT_MAX - 1; if (dval+0.001 > SHRT_MAX) *ival = SHRT_MAX; else if (dval >= 0) *ival = (short) (dval + 0.001); else if (dval-0.001 < minshort) *ival = minshort; else *ival = (short) (dval - 0.001); return (1); } else { return (0); } } /* Extract real value for variable from FITS header string */ int hgetr4 (hstring,keyword,rval) const char *hstring; /* character string containing FITS header information in the format = {/ } */ const char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ float *rval; { char *value; int lval; char *dchar; /* Get value and comment from header string */ value = hgetc (hstring,keyword); /* translate value from ASCII to binary */ if (value != NULL) { if (value[0] == '#') value++; lval = strlen (value); if (lval > VLENGTH) { strncpy (val, value, VLENGTH); val[VLENGTH] = (char) 0; } else strcpy (val, value); if (isnum (val) == 2) { if ((dchar = strchr (val, 'D'))) *dchar = 'e'; if ((dchar = strchr (val, 'd'))) *dchar = 'e'; if ((dchar = strchr (val, 'E'))) *dchar = 'e'; } *rval = (float) atof (val); return (1); } else { return (0); } } /* Extract real*8 right ascension in degrees from FITS header string */ int hgetra (hstring,keyword,dval) const char *hstring; /* character string containing FITS header information in the format = {/ } */ const char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ double *dval; /* Right ascension in degrees (returned) */ { char *value; /* Get value from header string */ value = hgetc (hstring,keyword); /* Translate value from ASCII colon-delimited string to binary */ if (value != NULL) { *dval = str2ra (value); return (1); } else return (0); } /* Extract real*8 declination in degrees from FITS header string */ int hgetdec (hstring,keyword,dval) const char *hstring; /* character string containing FITS header information in the format = {/ } */ const char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ double *dval; /* Right ascension in degrees (returned) */ { char *value; /* Get value from header string */ value = hgetc (hstring,keyword); /* Translate value from ASCII colon-delimited string to binary */ if (value != NULL) { *dval = str2dec (value); return (1); } else return (0); } /* Extract real*8 value for variable from FITS header string */ int hgetr8c (hstring,keyword,wchar,dval) const char *hstring; /* character string containing FITS header information in the format = {/ } */ const char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ const char *wchar; /* Character of multiple WCS header; =0 if unused */ double *dval; /* Keyword value returned */ { char keyword1[16]; int lkey; if (wchar[0] < (char) 64) return (hgetr8 (hstring, keyword, dval)); else { strcpy (keyword1, keyword); lkey = strlen (keyword); keyword1[lkey] = wchar[0]; keyword1[lkey+1] = (char) 0; return (hgetr8 (hstring, keyword1, dval)); } } /* Extract real*8 value for variable from FITS header string */ int hgetr8 (hstring,keyword,dval) const char *hstring; /* character string containing FITS header information in the format = {/ } */ const char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ double *dval; { char *value; int lval; char *dchar; /* Get value and comment from header string */ value = hgetc (hstring,keyword); /* Translate value from ASCII to binary */ if (value != NULL) { if (value[0] == '#') value++; lval = strlen (value); if (lval > VLENGTH) { strncpy (val, value, VLENGTH); val[VLENGTH] = (char) 0; } else strcpy (val, value); if (isnum (val) == 2) { if ((dchar = strchr (val, 'D'))) *dchar = 'e'; if ((dchar = strchr (val, 'd'))) *dchar = 'e'; if ((dchar = strchr (val, 'E'))) *dchar = 'e'; } *dval = atof (val); return (1); } else { return (0); } } /* Extract logical value for variable from FITS header string */ int hgetl (hstring,keyword,ival) const char *hstring; /* character string containing FITS header information in the format = {/ } */ const char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ int *ival; { char *value; char newval; int lval; /* Get value and comment from header string */ value = hgetc (hstring,keyword); /* Translate value from ASCII to binary */ if (value != NULL) { lval = strlen (value); if (lval > VLENGTH) { strncpy (val, value, VLENGTH); val[VLENGTH] = (char) 0; } else strcpy (val, value); newval = val[0]; if (newval == 't' || newval == 'T') *ival = 1; else *ival = 0; return (1); } else { return (0); } } /* Extract real*8 date from FITS header string (dd/mm/yy or dd-mm-yy) */ int hgetdate (hstring,keyword,dval) const char *hstring; /* character string containing FITS header information in the format = {/ } */ const char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ double *dval; { double yeardays, seconds, fday; char *value,*sstr, *dstr, *tstr, *cstr, *nval; int year, month, day, yday, i, hours, minutes; static int mday[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; /* Get value and comment from header string */ value = hgetc (hstring,keyword); /* Translate value from ASCII to binary */ if (value != NULL) { sstr = strchr (value,'/'); dstr = strchr (value,'-'); /* Original FITS date format: dd/mm/yy */ if (sstr > value) { *sstr = '\0'; day = (int) atof (value); *sstr = '/'; nval = sstr + 1; sstr = strchr (nval,'/'); if (sstr == NULL) sstr = strchr (nval,'-'); if (sstr > value) { *sstr = '\0'; month = (int) atof (nval); *sstr = '/'; nval = sstr + 1; year = (int) atof (nval); if (day > 31) { yday = year; year = day; day = yday; } if (year >= 0 && year <= 49) year = year + 2000; else if (year < 100) year = year + 1900; if ((year % 4) == 0) mday[1] = 29; else mday[1] = 28; if ((year % 100) == 0 && (year % 400) != 0) mday[1] = 28; if (day > mday[month-1]) day = mday[month-1]; else if (day < 1) day = 1; if (mday[1] == 28) yeardays = 365.0; else yeardays = 366.0; yday = day - 1; for (i = 0; i < month-1; i++) yday = yday + mday[i]; *dval = (double) year + ((double)yday / yeardays); return (1); } else return (0); } /* New FITS date format: yyyy-mm-ddThh:mm:ss[.sss] */ else if (dstr > value) { *dstr = '\0'; year = (int) atof (value); *dstr = '-'; nval = dstr + 1; dstr = strchr (nval,'-'); month = 1; day = 1; tstr = NULL; if (dstr > value) { *dstr = '\0'; month = (int) atof (nval); *dstr = '-'; nval = dstr + 1; tstr = strchr (nval,'T'); if (tstr > value) *tstr = '\0'; day = (int) atof (nval); if (tstr > value) *tstr = 'T'; } /* If year is < 32, it is really day of month in old format */ if (year < 32) { i = year; year = day + 1900; day = i; } if ((year % 4) == 0) mday[1] = 29; else mday[1] = 28; if ((year % 100) == 0 && (year % 400) != 0) mday[1] = 28; if (day > mday[month-1]) day = mday[month-1]; else if (day < 1) day = 1; if (mday[1] == 28) yeardays = 365.0; else yeardays = 366.0; yday = day - 1; for (i = 0; i < month-1; i++) yday = yday + mday[i]; *dval = (double) year + ((double)yday / yeardays); /* Extract time, if it is present */ if (tstr > value) { nval = tstr + 1; hours = 0.0; minutes = 0.0; seconds = 0.0; cstr = strchr (nval,':'); if (cstr > value) { *cstr = '\0'; hours = (int) atof (nval); *cstr = ':'; nval = cstr + 1; cstr = strchr (nval,':'); if (cstr > value) { *cstr = '\0'; minutes = (int) atof (nval); *cstr = ':'; nval = cstr + 1; seconds = atof (nval); } else { minutes = (int) atof (nval); seconds = 0.0; } } fday = ((3.6e3 * (double)hours) + (6.e1 * (double)minutes) + seconds) / 8.64e4; *dval = *dval + (fday / yeardays); } return (1); } else return (0); } else return (0); } /* Extract IRAF multiple-keyword string value from FITS header string */ int hgetm (hstring, keyword, lstr, str) const char *hstring; /* character string containing FITS header information in the format = {/ } */ const char *keyword; /* character string containing the root name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ const int lstr; /* Size of str in characters */ char *str; /* String (returned) */ { char *value; char *stri; char keywordi[16]; int lval, lstri, ikey; char keyform[8]; stri = str; lstri = lstr; sprintf (keywordi, "%s_1", keyword); if (ksearch (hstring, keywordi)) strcpy (keyform, "%s_%d"); else { sprintf (keywordi, "%s_01", keyword); if (ksearch (hstring, keywordi)) strcpy (keyform, "%s_%02d"); else { sprintf (keywordi, "%s_001", keyword); if (ksearch (hstring, keywordi)) strcpy (keyform, "%s_%03d"); else return (0); } } /* Loop through sequentially-named keywords */ multiline = 1; for (ikey = 1; ikey < 500; ikey++) { sprintf (keywordi, keyform, keyword, ikey); /* Get value for this keyword */ value = hgetc (hstring, keywordi); if (value != NULL) { lval = strlen (value); if (lval < lstri) strcpy (stri, value); else if (lstri > 1) { strncpy (stri, value, lstri-1); stri[lstri] = (char) 0; break; } else { str[0] = value[0]; break; } } else break; stri = stri + lval; lstri = lstri - lval; } multiline = 0; /* Return 1 if any keyword found, else 0 */ if (ikey > 1) return (1); else return (0); } /* Extract string value for variable from FITS header string */ int hgetsc (hstring,keyword,wchar,lstr,str) const char *hstring; /* character string containing FITS header information in the format = {/ } */ const char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ const char *wchar; /* Character of multiple WCS header; =0 if unused */ const int lstr; /* Size of str in characters */ char *str; /* String (returned) */ { char keyword1[16]; int lkey; if (wchar[0] < (char) 64) return (hgets (hstring, keyword, lstr, str)); else { strcpy (keyword1, keyword); lkey = strlen (keyword); keyword1[lkey] = wchar[0]; keyword1[lkey+1] = (char) 0; return (hgets (hstring, keyword1, lstr, str)); } } /* Extract string value for variable from FITS header string */ int hgets (hstring, keyword, lstr, str) const char *hstring; /* character string containing FITS header information in the format = {/ } */ const char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ const int lstr; /* Size of str in characters */ char *str; /* String (returned) */ { char *value; int lval; /* Get value and comment from header string */ value = hgetc (hstring,keyword); if (value != NULL) { lval = strlen (value); if (lval < lstr) strcpy (str, value); else if (lstr > 1) strncpy (str, value, lstr-1); else str[0] = value[0]; return (1); } else return (0); } /* Extract number of decimal places for value in FITS header string */ int hgetndec (hstring, keyword, ndec) const char *hstring; /* character string containing FITS header information in the format = {/ } */ const char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ int *ndec; /* Number of decimal places in keyword value */ { char *value; int i, nchar; /* Get value and comment from header string */ value = hgetc (hstring,keyword); /* Find end of string and count backward to decimal point */ *ndec = 0; if (value != NULL) { nchar = strlen (value); for (i = nchar-1; i >= 0; i--) { if (value[i] == '.') return (1); *ndec = *ndec + 1; } return (1); } else return (0); } /* Extract character value for variable from FITS header string */ char * hgetc (hstring,keyword0) const char *hstring; /* character string containing FITS header information in the format = {/ } */ const char *keyword0; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ { static char cval[80]; char *value; char cwhite[2]; char squot[2], dquot[2], lbracket[2], rbracket[2], slash[2], comma[2]; char space; char keyword[81]; /* large for ESO hierarchical keywords */ char line[100]; char *vpos, *cpar; char *q1, *q2, *v1, *v2, *c1, *brack1, *brack2; int ipar, i, lkey; #ifdef USE_SAOLIB int iel=1, ip=1, nel, np, ier; char *get_fits_head_str(); if( !use_saolib ){ #endif squot[0] = (char) 39; squot[1] = (char) 0; dquot[0] = (char) 34; dquot[1] = (char) 0; lbracket[0] = (char) 91; lbracket[1] = (char) 0; comma[0] = (char) 44; comma[1] = (char) 0; rbracket[0] = (char) 93; rbracket[1] = (char) 0; slash[0] = (char) 47; slash[1] = (char) 0; space = (char) 32; /* Find length of variable name */ strncpy (keyword,keyword0, sizeof(keyword)-1); brack1 = strsrch (keyword,lbracket); if (brack1 == NULL) brack1 = strsrch (keyword,comma); if (brack1 != NULL) { *brack1 = '\0'; brack1++; } /* Search header string for variable name */ vpos = ksearch (hstring,keyword); /* Exit if not found */ if (vpos == NULL) { return (NULL); } /* Initialize line to nulls */ for (i = 0; i < 100; i++) line[i] = 0; /* In standard FITS, data lasts until 80th character */ /* Extract entry for this variable from the header */ strncpy (line,vpos,80); /* Check for quoted value */ q1 = strsrch (line,squot); c1 = strsrch (line,slash); if (q1 != NULL) { if (c1 != NULL && q1 < c1) { q2 = strsrch (q1+1,squot); if (q2 == NULL) { q2 = c1 - 1; while (*q2 == space) q2--; q2++; } else if (c1 < q2) c1 = strsrch (q2,slash); } else if (c1 == NULL) { q2 = strsrch (q1+1,squot); if (q2 == NULL) { q2 = line + 79; while (*q2 == space) q2--; q2++; } } else q1 = NULL; } else { q1 = strsrch (line,dquot); if (q1 != NULL) { if (c1 != NULL && q1 < c1) { q2 = strsrch (q1+1,dquot); if (q2 == NULL) { q2 = c1 - 1; while (*q2 == space) q2--; q2++; } else if (c1 < q2) c1 = strsrch (q2,slash); } else if (c1 == NULL) { q2 = strsrch (q1+1,dquot); if (q2 == NULL) { q2 = line + 79; while (*q2 == space) q2--; q2++; } } else q1 = NULL; } else { q1 = NULL; q2 = line + 10; } } /* Extract value and remove excess spaces */ if (q1 != NULL) { v1 = q1 + 1; v2 = q2; } else { v1 = strsrch (line,"="); if (v1 == NULL) v1 = line + 9; else v1 = v1 + 1; c1 = strsrch (line,"/"); if (c1 != NULL) v2 = c1; else v2 = line + 79; } /* Ignore leading spaces if not multiline */ if (!multiline) { while (*v1 == ' ' && v1 < v2) { v1++; } } /* Drop trailing spaces */ *v2 = '\0'; if (!multiline) { v2--; while ((*v2 == ' ' || *v2 == (char) 13) && v2 > v1) { *v2 = '\0'; v2--; } } /* Convert -zero to just plain 0 */ if (!strcmp (v1, "-0")) v1++; strcpy (cval,v1); value = cval; /* If keyword has brackets, extract appropriate token from value */ if (brack1 != NULL) { brack2 = strsrch (brack1,rbracket); if (brack2 != NULL) *brack2 = '\0'; if (isnum (brack1)) { ipar = atoi (brack1); cwhite[0] = ' '; cwhite[1] = '\0'; if (ipar > 0) { for (i = 1; i <= ipar; i++) { cpar = strtok (v1,cwhite); v1 = NULL; } if (cpar != NULL) { strcpy (cval,cpar); value = cval; } else value = NULL; } /* If token counter is negative, include rest of value */ else if (ipar < 0) { for (i = 1; i < -ipar; i++) { v1 = strchr (v1, ' '); if (v1 == NULL) break; else v1 = v1 + 1; } if (v1 != NULL) { strcpy (cval, v1); value = cval; } else value = NULL; } } else { lkey = strlen (brack1); for (i = 0; i < lkey; i++) { if (brack1[i] > 64 && brack1[i] < 91) brack1[i] = brack1[i] + 32; } v1 = igetc (cval, brack1); if (v1) { strcpy (cval,v1); value = cval; } else value = NULL; } } return (value); #ifdef USE_SAOLIB } else { return(get_fits_head_str(keyword0, iel, ip, &nel, &np, &ier, hstring)); } #endif } /* Find beginning of fillable blank line before FITS header keyword line */ char * blsearch (hstring,keyword) /* Find entry for keyword keyword in FITS header string hstring. (the keyword may have a maximum of eight letters) NULL is returned if the keyword is not found */ const char *hstring; /* character string containing fits-style header information in the format = {/ } the default is that each entry is 80 characters long; however, lines may be of arbitrary length terminated by nulls, carriage returns or linefeeds, if packed is true. */ const char *keyword; /* character string containing the name of the variable to be returned. ksearch searches for a line beginning with this string. The string may be a character literal or a character variable terminated by a null or '$'. it is truncated to 8 characters. */ { const char *headlast; char *loc, *headnext, *pval, *lc, *line; char *bval; int icol, nextchar, lkey, nleft, lhstr; pval = 0; /* Search header string for variable name */ if (lhead0) lhstr = lhead0; else { lhstr = 0; while (lhstr < 256000 && hstring[lhstr] != 0) lhstr++; } headlast = hstring + lhstr; headnext = (char *) hstring; pval = NULL; while (headnext < headlast) { nleft = headlast - headnext; loc = strncsrch (headnext, keyword, nleft); /* Exit if keyword is not found */ if (loc == NULL) { break; } icol = (loc - hstring) % 80; lkey = strlen (keyword); nextchar = (int) *(loc + lkey); /* If this is not in the first 8 characters of a line, keep searching */ if (icol > 7) headnext = loc + 1; /* If parameter name in header is longer, keep searching */ else if (nextchar != 61 && nextchar > 32 && nextchar < 127) headnext = loc + 1; /* If preceeding characters in line are not blanks, keep searching */ else { line = loc - icol; for (lc = line; lc < loc; lc++) { if (*lc != ' ') headnext = loc + 1; } /* Return pointer to start of line if match */ if (loc >= headnext) { pval = line; break; } } } /* Return NULL to calling program if keyword is not found */ if (pval == NULL) return (pval); /* Return NULL if keyword is found at start of FITS header string */ if (pval == hstring) return (NULL); /* Find last nonblank in FITS header string line before requested keyword */ bval = pval - 80; while (!strncmp (bval," ",8) && bval >= hstring) bval = bval - 80; bval = bval + 80; /* Return pointer to calling program if blank lines found */ if (bval < pval && bval >= hstring) return (bval); else return (NULL); } /* Find FITS header line containing specified keyword */ char * ksearch (hstring,keyword) /* Find entry for keyword keyword in FITS header string hstring. (the keyword may have a maximum of eight letters) NULL is returned if the keyword is not found */ const char *hstring; /* character string containing fits-style header information in the format = {/ } the default is that each entry is 80 characters long; however, lines may be of arbitrary length terminated by nulls, carriage returns or linefeeds, if packed is true. */ const char *keyword; /* character string containing the name of the variable to be returned. ksearch searches for a line beginning with this string. The string may be a character literal or a character variable terminated by a null or '$'. it is truncated to 8 characters. */ { char *loc, *headnext, *headlast, *pval, *lc, *line; int icol, nextchar, lkey, nleft, lhstr, lhead; #ifdef USE_SAOLIB int iel=1, ip=1, nel, np, ier; char *get_fits_head_str(); if( !use_saolib ){ #endif pval = 0; /* Search header string for variable name */ if (lhead0) lhead = lhead0; else { lhead = 0; while (lhead < 256000 && hstring[lhead] != 0) lhead++; } /* XXX allan: causes core dump on solaris, with mmapped header lhstr = strlen (hstring); if (lhstr < lhead) lhead = lhstr; XXX */ headlast = (char *)(hstring + lhead); headnext = (char *)(hstring); pval = NULL; while (headnext < headlast) { nleft = headlast - headnext; loc = strnsrch (headnext, keyword, nleft); /* Exit if keyword is not found */ if (loc == NULL) { break; } icol = (loc - hstring) % 80; lkey = strlen (keyword); nextchar = (int) *(loc + lkey); /* If this is not in the first 8 characters of a line, keep searching */ if (icol > 7) headnext = loc + 1; /* If parameter name in header is longer, keep searching */ else if (nextchar != 61 && nextchar > 32 && nextchar < 127) headnext = loc + 1; /* If preceeding characters in line are not blanks, keep searching */ else { line = loc - icol; for (lc = line; lc < loc; lc++) { if (*lc != ' ') headnext = loc + 1; } /* Return pointer to start of line if match */ if (loc >= headnext) { pval = line; break; } } } /* Return pointer to calling program */ return (pval); #ifdef USE_SAOLIB } else { if (get_fits_head_str(keyword,iel,ip,&nel,&np,&ier,hstring) != NULL) return(hstring); else return(NULL); } #endif } char * ksearchh (hstring,keyword) /*** waj ***/ /* Find entry for keyword keyword in FITS header string hstring. (the keyword may have a maximum of eight letters) NULL is returned if the keyword is not found */ const char *hstring; /* character string containing fits-style header information in the format = {/ } the default is that each entry is 80 characters long; however, lines may be of arbitrary length terminated by nulls, carriage returns or linefeeds, if packed is true. */ const char *keyword; /* character string containing the name of the variable to be returned. ksearch searches for a line beginning with this string. The string may be a character literal or a character variable terminated by a null or '$'. it is truncated to 8 characters. */ { const char *headlast; char *loc, *headnext, *pval, *lc, *line; int icol, nextchar, lkey, nleft, lhead, lmax; #ifdef USE_SAOLIB int iel=1, ip=1, nel, np, ier; char *get_fits_head_str(); if( !use_saolib ){ #endif pval = 0; /* Find current length of header string */ if (lhead0) lmax = lhead0; else lmax = 256000; for (lhead = 0; lhead < lmax; lhead++) { if (hstring[lhead] == (char) 0) break; } /* Search header string for variable name */ headlast = hstring + lhead; headnext = (char *) hstring; pval = NULL; while (headnext < headlast) { nleft = headlast - headnext; loc = strncsrch (headnext, keyword, nleft); /* Exit if keyword is not found */ if (loc == NULL) { break; } icol = (loc - hstring) % 80; lkey = strlen (keyword); nextchar = (int) *(loc + lkey); /* If this is not in the first 8 characters of a line, keep searching */ if (icol > 7) headnext = loc + 1; /* If parameter name in header is longer, keep searching */ else if (nextchar != 61 && nextchar > 32 && nextchar < 127) headnext = loc + 1; /* If preceeding characters in line are not blanks, keep searching */ else { line = loc - icol; for (lc = line; lc < loc; lc++) { if (*lc != ' ') headnext = loc + 1; } /* Return pointer to start of line if match */ if (loc >= headnext) { pval = line; break; } } } /* Return pointer to calling program */ return (pval); #ifdef USE_SAOLIB } else { if (get_fits_head_str(keyword,iel,ip,&nel,&np,&ier,hstring) != NULL) return(hstring); else return(NULL); } #endif } /* Return the right ascension in degrees from sexagesimal hours or decimal degrees */ double str2ra (in) const char *in; /* Character string of sexigesimal hours or decimal degrees */ { double ra; /* Right ascension in degrees (returned) */ ra = str2dec (in); if (strsrch (in,":")) ra = ra * 15.0; return (ra); } /* Return the declination in degrees from sexagesimal or decimal degrees */ double str2dec (in) const char *in; /* Character string of sexigesimal or decimal degrees */ { double dec; /* Declination in degrees (returned) */ double deg, min, sec, sign; char *value, *c1, *c2; int lval; char *dchar; dec = 0.0; /* Return 0.0 if string is null */ if (in == NULL) return (dec); /* Translate value from ASCII colon-delimited string to binary */ if (in[0]) { value = (char *) in; /* Remove leading spaces */ while (*value == ' ') value++; /* Save sign */ if (*value == '-') { sign = -1.0; value++; } else if (*value == '+') { sign = 1.0; value++; } else sign = 1.0; /* Remove trailing spaces */ lval = strlen (value); while (value[lval-1] == ' ') lval--; if ((c1 = strsrch (value,":")) == NULL) c1 = strnsrch (value," ",lval); if (c1 != NULL) { *c1 = 0; deg = (double) atoi (value); *c1 = ':'; value = c1 + 1; if ((c2 = strsrch (value,":")) == NULL) c2 = strsrch (value," "); if (c2 != NULL) { *c2 = 0; min = (double) atoi (value); *c2 = ':'; value = c2 + 1; sec = atof (value); } else { sec = 0.0; if ((c1 = strsrch (value,".")) != NULL) min = atof (value); if (strlen (value) > 0) min = (double) atoi (value); } dec = sign * (deg + (min / 60.0) + (sec / 3600.0)); } else if (isnum (value) == 2) { if ((dchar = strchr (value, 'D'))) *dchar = 'e'; if ((dchar = strchr (value, 'd'))) *dchar = 'e'; if ((dchar = strchr (value, 'E'))) *dchar = 'e'; dec = sign * atof (value); } else dec = sign * (double) atoi (value); } return (dec); } /* Find string s2 within null-terminated string s1 */ char * strsrch (s1, s2) const char *s1; /* String to search */ const char *s2; /* String to look for */ { int ls1; ls1 = strlen (s1); return (strnsrch (s1, s2, ls1)); } /* Find string s2 within string s1 */ char * strnsrch (s1, s2, ls1) const char *s1; /* String to search */ const char *s2; /* String to look for */ const int ls1; /* Length of string being searched */ { char *s,*s1e; char cfirst,clast; int i,ls2; /* Return null string if either pointer is NULL */ if (s1 == NULL || s2 == NULL) return (NULL); /* A zero-length pattern is found in any string */ ls2 = strlen (s2); if (ls2 ==0) return ((char *) s1); /* Only a zero-length string can be found in a zero-length string */ if (ls1 ==0) return (NULL); cfirst = (char) s2[0]; clast = (char) s2[ls2-1]; s1e = (char *) s1 + (int) ls1 - ls2 + 1; s = (char *) s1; while (s < s1e) { /* Search for first character in pattern string */ if (*s == cfirst) { /* If single character search, return */ if (ls2 == 1) return (s); /* Search for last character in pattern string if first found */ if (s[ls2-1] == clast) { /* If two-character search, return */ if (ls2 == 2) return (s); /* If 3 or more characters, check for rest of search string */ i = 1; while (i < ls2 && s[i] == s2[i]) i++; /* If entire string matches, return */ if (i >= ls2) return (s); } } s++; } return (NULL); } /* Find string s2 within null-terminated string s1 (case-free search) */ char * strcsrch (s1, s2) const char *s1; /* String to search */ const char *s2; /* String to look for */ { int ls1; ls1 = strlen ((char *) s1); return (strncsrch (s1, s2, ls1)); } /* Find string s2 within string s1 (case-free search) */ char * strncsrch (s1, s2, ls1) const char *s1; /* String to search */ const char *s2; /* String to look for */ const int ls1; /* Length of string being searched */ { char *s,*s1e, sl, *os2; char cfirst,ocfirst; char clast = ' '; char oclast = ' '; int i,ls2; /* Return null string if either pointer is NULL */ if (s1 == NULL || s2 == NULL) return (NULL); /* A zero-length pattern is found in any string */ ls2 = strlen (s2); if (ls2 ==0) return ((char *) s1); /* Only a zero-length string can be found in a zero-length string */ os2 = NULL; if (ls1 ==0) return (NULL); /* For one or two characters, set opposite case first and last letters */ if (ls2 < 3) { cfirst = (char) s2[0]; if (cfirst > 96 && cfirst < 123) ocfirst = cfirst - 32; else if (cfirst > 64 && cfirst < 91) ocfirst = cfirst + 32; else ocfirst = cfirst; if (ls2 > 1) { clast = s2[1]; if (clast > 96 && clast < 123) oclast = clast - 32; else if (clast > 64 && clast < 91) oclast = clast + 32; else oclast = clast; } } /* Else duplicate string with opposite case letters for comparison */ else { os2 = (char *) calloc (ls2, 1); for (i = 0; i < ls2; i++) { if (s2[i] > 96 && s2[i] < 123) os2[i] = s2[i] - 32; else if (s2[i] > 64 && s2[i] < 91) os2[i] = s2[i] + 32; else os2[i] = s2[i]; } cfirst = s2[0]; ocfirst = os2[0]; clast = s2[ls2-1]; oclast = os2[ls2-1]; } /* Loop through input string, character by character */ s = (char *) s1; s1e = s + (int) ls1 - ls2 + 1; while (s < s1e) { /* Search for first character in pattern string */ if (*s == cfirst || *s == ocfirst) { /* If single character search, return */ if (ls2 == 1) return (s); /* Search for last character in pattern string if first found */ sl = s[ls2-1]; if (sl == clast || sl == oclast) { /* If two-character search, return */ if (ls2 == 2) return (s); /* If 3 or more characters, check for rest of search string */ i = 1; while (i < ls2 && (s[i] == (char) s2[i] || s[i] == os2[i])) i++; /* If entire string matches, return */ if (i >= ls2) { free (os2); return (s); } } } s++; } if (os2 != NULL) free (os2); return (NULL); } int notnum (string) const char *string; /* Character string */ { if (isnum (string)) return (0); else return (1); } /* ISNUM-- Return 1 if string is an integer number, 2 if floating point, 3 if sexigesimal, with or without decimal point else 0 */ int isnum (string) const char *string; /* Character string */ { int lstr, i, nd, cl; char cstr, cstr1; int fpcode; /* Return 0 if string is NULL */ if (string == NULL) return (0); lstr = strlen (string); nd = 0; cl = 0; fpcode = 1; /* Return 0 if string starts with a D or E */ cstr = string[0]; if (cstr == 'D' || cstr == 'd' || cstr == 'E' || cstr == 'e') { return (0); } /* Remove trailing spaces */ while (string[lstr-1] == ' ') lstr--; /* Numeric strings contain 0123456789-+ and d or e for exponents */ for (i = 0; i < lstr; i++) { cstr = string[i]; if (cstr == '\n') break; /* Ignore leading spaces */ if (cstr == ' ' && nd == 0) continue; if ((cstr < 48 || cstr > 57) && cstr != '+' && cstr != '-' && cstr != 'D' && cstr != 'd' && cstr != 'E' && cstr != 'e' && cstr != ':' && cstr != '.') return (0); else if (cstr == '+' || cstr == '-') { if (string[i+1] == '-' || string[i+1] == '+') return (0); else if (i > 0) { cstr1 = string[i-1]; if (cstr1 != 'D' && cstr1 != 'd' && cstr1 != 'E' && cstr1 != 'e' && cstr1 != ':' && cstr1 != ' ') return (0); } } else if (cstr >= 47 && cstr <= 57) nd++; /* Check for colon */ else if (cstr == 58) cl++; if (cstr=='.' || cstr=='d' || cstr=='e' || cstr=='d' || cstr=='e') fpcode = 2; } if (nd > 0) { if (cl) fpcode = 3; return (fpcode); } else return (0); } /* NUMDEC -- Return number of decimal places in numeric string (-1 if not number) */ int numdec (string) const char *string; /* Numeric string */ { char *cdot; int lstr; if (notnum (string) && !strchr (string, ':')) return (-1); else { lstr = strlen (string); if ((cdot = strchr (string, '.')) == NULL) return (0); else return (lstr - (cdot - string) - 1); } } #ifdef USE_SAOLIB int set_saolib(hstring) void *hstring; { if( *((int *)hstring) == 142857 ) use_saolib = 1; else use_saolib = 0; } #endif /* Remove exponent, leading #, and/or trailing zeroes, if reasonable */ void strfix (string, fillblank, dropzero) char *string; /* String to modify */ int fillblank; /* If nonzero, fill blanks with underscores */ int dropzero; /* If nonzero, drop trailing zeroes */ { char *sdot, *s, *strend, *str, ctemp, *slast; int ndek, lstr, i; /* If number, ignore leading # and remove trailing non-numeric character */ if (string[0] == '#') { strend = string + strlen (string); str = string + 1; strend = str + strlen (str) - 1; ctemp = *strend; if (!isnum (strend)) *strend = (char) 0; if (isnum (str)) { strend = string + strlen (string); for (str = string; str < strend; str++) *str = *(str + 1); } else *strend = ctemp; } /* Remove positive exponent if there are enough digits given */ if (isnum (string) > 1 && strsrch (string, "E+") != NULL) { lstr = strlen (string); ndek = (int) (string[lstr-1] - 48); ndek = ndek + (10 * ((int) (string[lstr-2] - 48))); if (ndek < lstr - 7) { lstr = lstr - 4; string[lstr] = (char) 0; string[lstr+1] = (char) 0; string[lstr+2] = (char) 0; string[lstr+3] = (char) 0; sdot = strchr (string, '.'); if (ndek > 0 && sdot != NULL) { for (i = 1; i <= ndek; i++) { *sdot = *(sdot+1); sdot++; *sdot = '.'; } } } } /* Remove trailing zeroes if they are not significant */ if (dropzero) { if (isnum (string) > 1 && strchr (string, '.') != NULL && strsrch (string, "E-") == NULL && strsrch (string, "E+") == NULL && strsrch (string, "e-") == NULL && strsrch (string, "e+") == NULL) { lstr = strlen (string); s = string + lstr - 1; while (*s == '0' && lstr > 1) { if (*(s - 1) != '.') { *s = (char) 0; lstr --; } s--; } } } /* Remove trailing decimal point */ lstr = strlen (string); s = string + lstr - 1; if (*s == '.') *s = (char) 0; /* Replace embedded blanks with underscores, if requested to */ if (fillblank) { lstr = strlen (string); slast = string + lstr; for (s = string; s < slast; s++) { if (*s == ' ') *s = '_'; } } return; } /* Oct 28 1994 New program * * Mar 1 1995 Search for / after second quote, not first one * May 2 1995 Initialize line in HGETC; deal with logicals in HGETL better * May 4 1995 Declare STRSRCH in KSEARCH * Aug 7 1995 Fix line initialization in HGETC * Dec 22 1995 Add HGETRA and HGETDEC to get degrees from xx:xx:xx.xxx string * * Jan 26 1996 Fix HGETL to not crash when parameter is not present * Feb 1 1996 Fix HGETC to deal with quotes correctly * Feb 1 1996 Fix HGETDEG to deal with sign correctly * Feb 6 1996 Add HGETS to update character strings * Feb 8 1996 Fix STRSRCH to find final characters in string * Feb 23 1996 Add string to degree conversions * Apr 26 1996 Add HGETDATE to get fractional year from date string * May 22 1996 Fix documentation; return double from STR2RA and STR2DEC * May 28 1996 Fix string translation of RA and Dec when no seconds * Jun 10 1996 Remove unused variables after running lint * Jun 17 1996 Fix bug which failed to return single character strings * Jul 1 1996 Skip sign when reading declination after testing for it * Jul 19 1996 Do not divide by 15 if RA header value is already in degrees * Aug 5 1996 Add STRNSRCH to search strings which are not null-terminated * Aug 6 1996 Make minor changes after lint * Aug 8 1996 Fix ksearch bug which finds wrong keywords * Aug 13 1996 Fix sign bug in STR2DEC for degrees * Aug 26 1996 Drop unused variables ICOL0, NLINE, PREVCHAR from KSEARCH * Sep 10 1996 Fix header length setting code * Oct 15 1996 Clean up loops and fix ICOL assignment * Nov 13 1996 Handle integer degrees correctly in STR2DEC * Nov 21 1996 Make changes for Linux thanks to Sidik Isani * Dec 12 1996 Add ISNUM to check to see whether strings are numbers * * Jan 22 1997 Add ifdefs for Eric Mandel (SAOtng) * Jan 27 1997 Convert to integer through ATOF so exponents are recognized * Jul 25 1997 Implement FITS version of ISO date format * * Feb 24 1998 Implement code to return IRAF multiple-keyword strings * Mar 12 1998 Add subroutine NOTNUM * Mar 27 1998 Add changes to match SKYCAT version * Apr 30 1998 Add BLSEARCH() to find blank lines before END * May 27 1998 Add HGETNDEC() to get number of decimal places in entry * Jun 1 1998 Add VMS patch from Harry Payne at StSci * Jun 18 1998 Fix code which extracts tokens from string values * Jul 21 1998 Drop minus sign for values of -0 * Sep 29 1998 Treat hyphen-separated date as old format if 2-digit year * Oct 7 1998 Clean up search for last blank line * * Apr 5 1999 Check lengths of strings before copying them * May 5 1999 values.h -> POSIX limits.h: MAXINT->INT_MAX, MAXSHORT->SHRT_MAX * Jul 15 1999 Add hgetm() options of 1- or 2-digit keyword extensions * Oct 6 1999 Add gethlength() to return header length * Oct 14 1999 In ksearch(), search only to null not to end of buffer * Oct 15 1999 Return 1 from hgetndec() if successful * Oct 20 1999 Drop unused variable after lint (val in hgetndec) * Dec 3 1999 Fix isnum() to reject strings starting with a d or e * Dec 20 1999 Update hgetdate() to get minutes and seconds right * * Feb 10 2000 Parse RA and Dec with spaces as well as colons as separators * Feb 11 2000 Add null at end of multi-line keyword value character string * Feb 25 2000 Change max search string length from 57600 to 256000 * Mar 15 2000 Deal with missing second quotes in string values * Mar 17 2000 Return 2 from isnum() if number is floating point (.de) * Mar 17 2000 Ignore leading # for numeric values in header * Mar 21 2000 Implement -n to get string value starting with nth token * Apr 5 2000 Reject +- in isnum() * Jun 9 2000 Read keyword values even if no equal sign is present * Sep 20 2000 Ignore linefeed at end of number in isnum() * Oct 23 2000 Fix handling of embedded + or - in isnum() * * Jan 19 2000 Return 0 from isnum(), str2ra(), and str2dec() if string is null * Mar 30 2001 Fix header length finding algorithm in ksearch() * Jul 13 2001 Make val[] static int instead of int; drop unused variables * Sep 12 2001 Read yyyy/mm/dd dates as well as dd/mm/yyyy * Sep 20 2001 Ignore leading spaces in str2dec() * Sep 20 2001 Ignore trailing spaces in isnum() * * Apr 3 2002 Add hgetr8c(), hgeti4c(), and hgetsc() for multiple WCS handling * Apr 26 2002 Fix bug in hgetsc(), hgeti4c(), and hgetr8c() found by Bill Joye * Jun 26 2002 Do not drop leading or trailing spaces in multi-line values * Aug 6 2002 Add strcsrch() and strncsrch() for case-insensitive searches * Aug 30 2002 Fix bug so strcsrch() really is case-insensitive * Oct 20 2003 Add numdec() to return number of decimal places in a string * Dec 9 2003 Fix numdec() to return 0 if no digits after decimal point * * Feb 26 2004 Extract value from keyword=value strings within a keyword value * Apr 9 2004 Use strncsrch() in ksearch() to find differently-cased keywords * Apr 28 2004 Free os2 in strncsrch() only if it is allocated * Jul 13 2004 Accept D, d, E, or e as exponent delimiter in floating points * Aug 30 2004 Change numdec() to accept sexigesimal numbers (:'s) * * Jun 27 2005 Drop unused variables * Aug 30 2005 Adjust code in hlength() * * Jun 20 2006 Initialize uninitialized variables in strnsrch() * Jun 29 2006 Add new subroutine strfix() to clean strings for other uses * Jul 13 2006 Increase maximum number of multiline keywords from 20 to 500 * * Jan 4 2007 Declare header, keyword to be const * Jan 4 2007 Change WCS letter from char to char* * Feb 28 2007 If header length is not set in hlength, set it to 0 * May 31 2007 Add return value of 3 to isnum() if string has colon(s) * Aug 22 2007 If closing quote not found, make one up */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/hput.c000066400000000000000000000770601215713201500214110ustar00rootroot00000000000000/*** File libwcs/hput.c *** August 22, 2007 *** By Doug Mink, dmink@cfa.harvard.edu *** Harvard-Smithsonian Center for Astrophysics *** Copyright (C) 1995-2007 *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Correspondence concerning WCSTools should be addressed as follows: Internet email: dmink@cfa.harvard.edu Postal address: Doug Mink Smithsonian Astrophysical Observatory 60 Garden St. Cambridge, MA 02138 USA * Module: hput.c (Put FITS Header parameter values) * Purpose: Implant values for parameters into FITS header string * Subroutine: hputi4 (hstring,keyword,ival) sets int ival * Subroutine: hputr4 (hstring,keyword,rval) sets real*4 rval * Subroutine: hputr8 (hstring,keyword,dval) sets real*8 dval * Subroutine: hputnr8 (hstring,keyword,ndec,dval) sets real*8 dval * Subroutine: hputra (hstring,keyword,lval) sets right ascension as string * Subroutine: hputdec (hstring,keyword,lval) sets declination as string * Subroutine: hputl (hstring,keyword,lval) sets logical lval * Subroutine: hputs (hstring,keyword,cval) sets character string adding '' * Subroutine: hputm (hstring,keyword,cval) sets multi-line character string * Subroutine: hputc (hstring,keyword,cval) sets character string cval * Subroutine: hdel (hstring,keyword) deletes entry for keyword keyword * Subroutine: hadd (hplace,keyword) adds entry for keyword at hplace * Subroutine: hchange (hstring,keyword1,keyword2) changes keyword for entry * Subroutine: hputcom (hstring,keyword,comment) sets comment for parameter keyword * Subroutine: ra2str (out, lstr, ra, ndec) converts RA from degrees to string * Subroutine: dec2str (out, lstr, dec, ndec) converts Dec from degrees to string * Subroutine: deg2str (out, lstr, deg, ndec) converts degrees to string * Subroutine: num2str (out, num, field, ndec) converts number to string * Subroutine: getltime () returns current local time as ISO-style string * Subroutine: getutime () returns current UT as ISO-style string */ #include #include /* NULL, strlen, strstr, strcpy */ #include #include #include #include "fitshead.h" static int verbose=0; /* Set to 1 to print error messages and other info */ static void fixnegzero(); /* HPUTI4 - Set int keyword = ival in FITS header string */ int hputi4 (hstring,keyword,ival) char *hstring; /* FITS-style header information in the format = {/ } each entry is padded with spaces to 80 characters */ const char *keyword; /* Name of the variable in header to be returned. If no line begins with this string, one is created. The first 8 characters of keyword must be unique. */ int ival; /* int number */ { char value[30]; /* Translate value from binary to ASCII */ sprintf (value,"%d",ival); /* Put value into header string */ return (hputc (hstring,keyword,value)); } /* HPUTR4 - Set float keyword = rval in FITS header string */ int hputr4 (hstring, keyword, rval) char *hstring; /* FITS header string */ const char *keyword; /* Keyword name */ const float *rval; /* float number */ { char value[30]; /* Translate value from binary to ASCII */ sprintf (value, "%f", *rval); /* Remove sign if string is -0 or extension thereof */ fixnegzero (value); /* Put value into header string */ return (hputc (hstring, keyword, value)); } /* HPUTR8 - Set double keyword = dval in FITS header string */ int hputr8 (hstring, keyword, dval) char *hstring; /* FITS header string */ const char *keyword; /* Keyword name */ const double dval; /* double number */ { char value[30]; /* Translate value from binary to ASCII */ sprintf (value, "%g", dval); /* Remove sign if string is -0 or extension thereof */ fixnegzero (value); /* Put value into header string */ return (hputc (hstring, keyword, value)); } /* HPUTNR8 - Set double keyword = dval in FITS header string */ int hputnr8 (hstring, keyword, ndec, dval) char *hstring; /* FITS header string */ const char *keyword; /* Keyword name */ const int ndec; /* Number of decimal places to print */ const double dval; /* double number */ { char value[30]; char format[8]; int i, lval; /* Translate value from binary to ASCII */ if (ndec < 0) { sprintf (format, "%%.%dg", -ndec); sprintf (value, format, dval); lval = (int) strlen (value); for (i = 0; i < lval; i++) if (value[i] == 'e') value[i] = 'E'; } else { sprintf (format, "%%.%df", ndec); sprintf (value, format, dval); } /* Remove sign if string is -0 or extension thereof */ fixnegzero (value); /* Put value into header string */ return (hputc (hstring, keyword, value)); } /* HPUTRA - Set double keyword = hh:mm:ss.sss in FITS header string */ int hputra (hstring, keyword, ra) char *hstring; /* FITS header string */ const char *keyword; /* Keyword name */ const double ra; /* Right ascension in degrees */ { char value[30]; /* Translate value from binary to ASCII */ ra2str (value, 30, ra, 3); /* Remove sign if string is -0 or extension thereof */ fixnegzero (value); /* Put value into header string */ return (hputs (hstring, keyword, value)); } /* HPUTDEC - Set double keyword = dd:mm:ss.sss in FITS header string */ int hputdec (hstring, keyword, dec) char *hstring; /* FITS header string */ const char *keyword; /* Keyword name */ const double dec; /* Declination in degrees */ { char value[30]; /* Translate value from binary to ASCII */ dec2str (value, 30, dec, 2); /* Remove sign if string is -0 or extension thereof */ fixnegzero (value); /* Put value into header string */ return (hputs (hstring, keyword, value)); } /* FIXNEGZERO -- Drop - sign from beginning of any string which is all zeros */ static void fixnegzero (string) char *string; { int i, lstr; if (string[0] != '-') return; /* Drop out if any non-zero digits in this string */ lstr = (int) strlen (string); for (i = 1; i < lstr; i++) { if (string[i] > '0' && string[i] <= '9') return; if (string[i] == 'd' || string[i] == 'e' || string[i] == ' ') break; } /* Drop - from start of string; overwrite string in place */ for (i = 1; i < lstr; i++) string[i-1] = string[i]; string[lstr-1] = (char) 0; return; } /* HPUTL - Set keyword = F if lval=0, else T, in FITS header string */ int hputl (hstring, keyword,lval) char *hstring; /* FITS header */ const char *keyword; /* Keyword name */ const int lval; /* logical variable (0=false, else true) */ { char value[8]; /* Translate value from binary to ASCII */ if (lval) strcpy (value, "T"); else strcpy (value, "F"); /* Put value into header string */ return (hputc (hstring,keyword,value)); } /* HPUTM - Set multi-line character string in FITS header string */ /* return number of keywords written */ int hputm (hstring,keyword,cval) char *hstring; /* FITS header */ const char *keyword; /* Keyword name root (6 characters or less) */ const char *cval; /* character string containing the value for variable keyword. trailing and leading blanks are removed. */ { int lroot, lcv, i, ii, nkw, lkw, lval; int comment = 0; const char *v; char keyroot[8], newkey[12], value[80]; char squot = 39; /* If COMMENT or HISTORY, use the same keyword on every line */ lkw = (int) strlen (keyword); if (lkw == 7 && (strncmp (keyword,"COMMENT",7) == 0 || strncmp (keyword,"HISTORY",7) == 0)) comment = 1; /* Set up keyword root, shortening it to 6 characters, if necessary */ else { comment = 0; strcpy (keyroot, keyword); lroot = (int) strlen (keyroot); if (lroot > 6) { keyroot[6] = (char) 0; lroot = 6; } } /* Write keyword value one line of up to 67 characters at a time */ ii = '1'; nkw = 0; lcv = (int) strlen (cval); if (!comment) { strcpy (newkey, keyroot); strcat (newkey, "_"); newkey[lroot+2] = (char) 0; } v = cval; while (lcv > 0) { if (lcv > 67) lval = 67; else lval = lcv; value[0] = squot; for (i = 1; i <= lval; i++) value[i] = *v++; /* Pad short strings to 8 characters */ if (lval < 8) { for (i = lval+1; i < 9; i++) value[i] = ' '; lval = 8; } value[lval+1] = squot; value[lval+2] = (char) 0; /* Add this line to the header */ if (comment) i = hputc (hstring, keyroot, value); else { newkey[lroot+1] = ii; ii++; i = hputc (hstring, newkey, value); } if (i != 0) return (i); nkw++; if (lcv > 67) lcv = lcv - 67; else break; } return (nkw); } /* HPUTS - Set character string keyword = 'cval' in FITS header string */ int hputs (hstring,keyword,cval) char *hstring; /* FITS header */ const char *keyword; /* Keyword name */ const char *cval; /* character string containing the value for variable keyword. trailing and leading blanks are removed. */ { char squot = 39; char value[80]; int lcval, i, lkeyword; /* If COMMENT or HISTORY, just add it as is */ lkeyword = (int) strlen (keyword); if (lkeyword == 7 && (strncmp (keyword,"COMMENT",7) == 0 || strncmp (keyword,"HISTORY",7) == 0)) return (hputc (hstring,keyword,cval)); /* find length of variable string */ lcval = (int) strlen (cval); if (lcval > 67) lcval = 67; /* Put single quote at start of string */ value[0] = squot; strncpy (&value[1],cval,lcval); /* If string is less than eight characters, pad it with spaces */ if (lcval < 8) { for (i = lcval; i < 8; i++) { value[i+1] = ' '; } lcval = 8; } /* Add single quote and null to end of string */ value[lcval+1] = squot; value[lcval+2] = (char) 0; /* Put value into header string */ return (hputc (hstring,keyword,value)); } /* HPUTC - Set character string keyword = value in FITS header string */ /* Return -1 if error, 0 if OK */ int hputc (hstring,keyword,value) char *hstring; const char *keyword; const char *value; /* character string containing the value for variable keyword. trailing and leading blanks are removed. */ { char squot = 39; char line[100]; char newcom[50]; char *vp, *v1, *v2, *q1, *q2, *c1, *ve; int lkeyword, lcom, lval, lc, lv1, lhead, lblank, ln, nc, i; /* Find length of keyword, value, and header */ lkeyword = (int) strlen (keyword); lval = (int) strlen (value); lhead = gethlength (hstring); /* If COMMENT or HISTORY, always add it just before the END */ if (lkeyword == 7 && (strncmp (keyword,"COMMENT",7) == 0 || strncmp (keyword,"HISTORY",7) == 0)) { /* First look for blank lines before END */ v1 = blsearch (hstring, "END"); /* Otherwise, create a space for it at the end of the header */ if (v1 == NULL) { /* Find end of header */ v1 = ksearch (hstring,"END"); /* Align pointer at start of 80-character line */ lc = v1 - hstring; ln = lc / 80; nc = ln * 80; v1 = hstring + nc; v2 = v1 + 80; /* If header length is exceeded, return error code */ if (v2 - hstring > lhead) { return (-1); } /* Move END down 80 characters */ strncpy (v2, v1, 80); } else v2 = v1 + 80; /* Insert keyword */ strncpy (v1,keyword,7); /* Pad with spaces */ for (vp = v1+lkeyword; vp < v2; vp++) *vp = ' '; if (lval > 71) lv1 = 71; else lv1 = lval; /* Insert comment */ strncpy (v1+9,value,lv1); return (0); } /* Otherwise search for keyword */ else v1 = ksearch (hstring,keyword); /* If parameter is not found, find a place to put it */ if (v1 == NULL) { /* First look for blank lines before END */ v1 = blsearch (hstring, "END"); /* Otherwise, create a space for it at the end of the header */ if (v1 == NULL) { ve = ksearch (hstring,"END"); v1 = ve; /* Align pointer at start of 80-character line */ lc = v1 - hstring; ln = lc / 80; nc = ln * 80; v1 = hstring + nc; v2 = v1 + 80; /* If header length is exceeded, return error code */ if (v2 - hstring > lhead) { return (-1); } strncpy (v2, ve, 80); } else v2 = v1 + 80; lcom = 0; newcom[0] = 0; } /* Otherwise, extract the entry for this keyword from the header */ else { /* Align pointer at start of 80-character line */ lc = v1 - hstring; ln = lc / 80; nc = ln * 80; v1 = hstring + nc; v2 = v1 + 80; strncpy (line, v1, 80); line[80] = 0; v2 = v1 + 80; /* check for quoted value */ q1 = strchr (line, squot); if (q1 != NULL) { q2 = strchr (q1+1,squot); if (q2 != NULL) c1 = strchr (q2,'/'); else c1 = strrchr (line+79,'/'); } else c1 = strchr (line,'/'); /* extract comment and discount trailing spaces */ if (c1 != NULL) { lcom = 80 - (c1 + 2 - line); strncpy (newcom, c1+2, lcom); vp = newcom + lcom - 1; while (vp-- > newcom && *vp == ' ') lcom--; } else { newcom[0] = 0; lcom = 0; } } /* Fill new entry with spaces */ for (vp = v1; vp < v2; vp++) *vp = ' '; /* Copy keyword to new entry */ strncpy (v1, keyword, lkeyword); /* Add parameter value in the appropriate place */ vp = v1 + 8; *vp = '='; vp = v1 + 9; *vp = ' '; vp = vp + 1; if (*value == squot) { strncpy (vp, value, lval); if (lval+12 > 31) lc = lval + 12; else lc = 30; } else { vp = v1 + 30 - lval; strncpy (vp, value, lval); lc = 30; } /* Add comment in the appropriate place */ if (lcom > 0) { if (lc+2+lcom > 80) lcom = 77 - lc; vp = v1 + lc; /* Jul 16 1997: was vp = v1 + lc * 2 */ *vp++ = ' '; *vp++ = '/'; *vp++ = ' '; lblank = v2 - vp; for (i = 0; i < lblank; i++) vp[i] = ' '; if (lcom > lblank) lcom = lblank; strncpy (vp, newcom, lcom); } if (verbose) { if (lcom > 0) fprintf (stderr,"HPUT: %s = %s / %s\n",keyword, value, newcom); else fprintf (stderr,"HPUT: %s = %s\n",keyword, value); } return (0); } /* HPUTCOM - Set comment for keyword or on line in FITS header string */ int hputcom (hstring,keyword,comment) char *hstring; const char *keyword; const char *comment; { char squot, slash, space; char line[100]; int lkeyword, lcom, lhead, i, lblank, ln, nc, lc; char *vp, *v1, *v2, *c0, *c1, *q1, *q2; squot = (char) 39; slash = (char) 47; space = (char) 32; /* Find length of variable name */ lkeyword = (int) strlen (keyword); lhead = gethlength (hstring); lcom = (int) strlen (comment); /* If COMMENT or HISTORY, always add it just before the END */ if (lkeyword == 7 && (strncmp (keyword,"COMMENT",7) == 0 || strncmp (keyword,"HISTORY",7) == 0)) { /* Find end of header */ v1 = ksearch (hstring,"END"); /* Align pointer at start of 80-character line */ lc = v1 - hstring; ln = lc / 80; nc = ln * 80; v1 = hstring + nc; v2 = v1 + 80; /* If header length is exceeded, return error code */ if (v2 - hstring > lhead) { return (-1); } /* Move END down 80 characters */ strncpy (v2, v1, 80); /* blank out new line and insert keyword */ for (vp = v1; vp < v2; vp++) *vp = ' '; strncpy (v1, keyword, lkeyword); c0 = v1 + lkeyword; } /* Search header string for variable name */ else { v1 = ksearch (hstring,keyword); /* If parameter is not found, return without doing anything */ if (v1 == NULL) { if (verbose) fprintf (stderr,"HPUTCOM: %s not found\n",keyword); return (-1); } /* Align pointer at start of 80-character line */ lc = v1 - hstring; ln = lc / 80; nc = ln * 80; v1 = hstring + nc; v2 = v1 + 80; /* Extract entry for this variable from the header */ strncpy (line, v1, 80); line[80] = '\0'; /* Null-terminate line before strchr call */ /* check for quoted value */ q1 = strchr (line,squot); c1 = strchr (line,slash); if (q1 != NULL) { if (c1 != NULL && q1 < c1) { q2 = strchr (q1+1, squot); if (q2 == NULL) { q2 = c1 - 1; while (*q2 == space) q2--; q2++; } else if (c1 < q2) c1 = strchr (q2, slash); } else if (c1 == NULL) { q2 = strchr (q1+1, squot); if (q2 == NULL) { q2 = line + 79; while (*q2 == space) q2--; q2++; } } else q1 = NULL; } else q2 = NULL; if (c1 != NULL) c0 = v1 + (c1 - line) - 1; else if (q2 == NULL || q2-line < 30) c0 = v1 + 30; else c0 = v1 + (q2 - line) + 1; /* allan: 1997-09-30, was c0=q2+2 */ /* If comment will not fit at all, return */ if (c0 - v1 > 77) return (-1); strncpy (c0, " / ",3); } /* Create new entry */ if (lcom > 0) { c1 = c0 + 3; lblank = v1 + 79 - c1; if (lcom > lblank) lcom = lblank; for (i = 0; i < lblank; i++) c1[i] = ' '; strncpy (c1, comment, lcom); } if (verbose) { fprintf (stderr,"HPUTCOM: %s / %s\n",keyword,comment); } return (0); } static int leaveblank = 0; /* If 1, leave blank line when deleting */ void setleaveblank (lb) int lb; { leaveblank = lb; return; } static int headshrink=1; /* Set to 1 to drop line after deleting keyword */ void setheadshrink (hsh) int hsh; {headshrink = hsh; return;} /* HDEL - Set character string keyword = value in FITS header string * returns 1 if entry deleted, else 0 */ int hdel (hstring,keyword) char *hstring; /* FITS header */ const char *keyword; /* Keyword of entry to be deleted */ { char *v, *v1, *v2, *ve; /* Search for keyword */ v1 = ksearch (hstring,keyword); /* If keyword is not found, return header unchanged */ if (v1 == NULL) { return (0); } /* Find end of header */ ve = ksearch (hstring,"END"); /* If headshrink is 0, leave END where it is */ if (!leaveblank && !headshrink) ve = ve - 80; /* Cover deleted keyword line with spaces */ if (leaveblank) { v2 = v1 + 80; for (v = ve; v < v2; v++) *v = ' '; } /* Shift rest of header up one line */ else { for (v = v1; v < ve; v = v + 80) { v2 = v + 80; strncpy (v, v2, 80); } /* Cover former last line with spaces */ v2 = ve + 80; for (v = ve; v < v2; v++) *v = ' '; } return (1); } /* HADD - Add character string keyword = value to FITS header string * returns 1 if entry added, else 0 * Call hputx() to put value into entry */ int hadd (hplace, keyword) char *hplace; /* FITS header position for new keyword */ const char *keyword; /* Keyword of entry to be deleted */ { char *v, *v1, *v2, *ve; int i, lkey; /* Find end of header */ ve = ksearch (hplace,"END"); /* If END is not found, return header unchanged */ if (ve == NULL) { return (0); } v1 = hplace; /* Shift rest of header down one line */ /* limit bug found by Paolo Montegriffo fixed 2000-04-19 */ for (v = ve; v >= v1; v = v - 80) { v2 = v + 80; strncpy (v2, v, 80); } /* Cover former first line with new keyword */ lkey = (int) strlen (keyword); strncpy (hplace, keyword, lkey); if (lkey < 8) { for (i = lkey; i < 8; i++) hplace[i] = ' '; hplace[8] = '='; } for (i = 9; i < 80; i++) hplace[i] = ' '; return (1); } /* HCHANGE - Changes keyword for entry from keyword1 to keyword2 in FITS header string * returns 1 if entry changed, else 0 */ int hchange (hstring, keyword1, keyword2) char *hstring; /* FITS header */ const char *keyword1; /* Keyword to be changed */ const char *keyword2; /* New keyword name */ { char *v, *v1; const char *v2; int lv2, i; /* Search for keyword */ v1 = ksearch (hstring,keyword1); /* If keyword is not found, return header unchanged */ if (!v1) return (0); else { lv2 = (int) strlen (keyword2); v = v1; v2 = keyword2; for (i = 0; i < 8; i++) { if (i < lv2) v[i] = v2[i]; else v[i] = ' '; } } return (1); } /* Write the right ascension ra in sexagesimal format into string*/ void ra2str (string, lstr, ra, ndec) char *string; /* Character string (returned) */ int lstr; /* Maximum number of characters in string */ double ra; /* Right ascension in degrees */ int ndec; /* Number of decimal places in seconds */ { double a,b; double seconds; char tstring[64]; int hours; int minutes; int isec, ltstr; double dsgn; /* Keep RA between 0 and 360 */ if (ra < 0.0 ) { ra = -ra; dsgn = -1.0; } else dsgn = 1.0; ra = fmod(ra, 360.0); ra *= dsgn; if (ra < 0.0) ra = ra + 360.0; a = ra / 15.0; /* Convert to hours */ hours = (int) a; /* Compute minutes */ b = (a - (double)hours) * 60.0; minutes = (int) b; /* Compute seconds */ seconds = (b - (double)minutes) * 60.0; if (ndec > 5) { if (seconds > 59.999999) { seconds = 0.0; minutes = minutes + 1; } if (minutes > 59) { minutes = 0; hours = hours + 1; } hours = hours % 24; (void) sprintf (tstring,"%02d:%02d:%09.6f",hours,minutes,seconds); } else if (ndec > 4) { if (seconds > 59.99999) { seconds = 0.0; minutes = minutes + 1; } if (minutes > 59) { minutes = 0; hours = hours + 1; } hours = hours % 24; (void) sprintf (tstring,"%02d:%02d:%08.5f",hours,minutes,seconds); } else if (ndec > 3) { if (seconds > 59.9999) { seconds = 0.0; minutes = minutes + 1; } if (minutes > 59) { minutes = 0; hours = hours + 1; } hours = hours % 24; (void) sprintf (tstring,"%02d:%02d:%07.4f",hours,minutes,seconds); } else if (ndec > 2) { if (seconds > 59.999) { seconds = 0.0; minutes = minutes + 1; } if (minutes > 59) { minutes = 0; hours = hours + 1; } hours = hours % 24; (void) sprintf (tstring,"%02d:%02d:%06.3f",hours,minutes,seconds); } else if (ndec > 1) { if (seconds > 59.99) { seconds = 0.0; minutes = minutes + 1; } if (minutes > 59) { minutes = 0; hours = hours + 1; } hours = hours % 24; (void) sprintf (tstring,"%02d:%02d:%05.2f",hours,minutes,seconds); } else if (ndec > 0) { if (seconds > 59.9) { seconds = 0.0; minutes = minutes + 1; } if (minutes > 59) { minutes = 0; hours = hours + 1; } hours = hours % 24; (void) sprintf (tstring,"%02d:%02d:%04.1f",hours,minutes,seconds); } else { isec = (int)(seconds + 0.5); if (isec > 59) { isec = 0; minutes = minutes + 1; } if (minutes > 59) { minutes = 0; hours = hours + 1; } hours = hours % 24; (void) sprintf (tstring,"%02d:%02d:%02d",hours,minutes,isec); } /* Move formatted string to returned string */ ltstr = (int) strlen (tstring); if (ltstr < lstr-1) strcpy (string, tstring); else { strncpy (string, tstring, lstr-1); string[lstr-1] = 0; } return; } /* Write the variable a in sexagesimal format into string */ void dec2str (string, lstr, dec, ndec) char *string; /* Character string (returned) */ int lstr; /* Maximum number of characters in string */ double dec; /* Declination in degrees */ int ndec; /* Number of decimal places in arcseconds */ { double a, b, dsgn, deg1; double seconds; char sign; int degrees; int minutes; int isec, ltstr; char tstring[64]; /* Keep angle between -180 and 360 degrees */ deg1 = dec; if (deg1 < 0.0 ) { deg1 = -deg1; dsgn = -1.0; } else dsgn = 1.0; deg1 = fmod(deg1, 360.0); deg1 *= dsgn; if (deg1 <= -180.0) deg1 = deg1 + 360.0; a = deg1; /* Set sign and do all the rest with a positive */ if (a < 0) { sign = '-'; a = -a; } else sign = '+'; /* Convert to degrees */ degrees = (int) a; /* Compute minutes */ b = (a - (double)degrees) * 60.0; minutes = (int) b; /* Compute seconds */ seconds = (b - (double)minutes) * 60.0; if (ndec > 5) { if (seconds > 59.999999) { seconds = 0.0; minutes = minutes + 1; } if (minutes > 59) { minutes = 0; degrees = degrees + 1; } (void) sprintf (tstring,"%c%02d:%02d:%09.6f",sign,degrees,minutes,seconds); } else if (ndec > 4) { if (seconds > 59.99999) { seconds = 0.0; minutes = minutes + 1; } if (minutes > 59) { minutes = 0; degrees = degrees + 1; } (void) sprintf (tstring,"%c%02d:%02d:%08.5f",sign,degrees,minutes,seconds); } else if (ndec > 3) { if (seconds > 59.9999) { seconds = 0.0; minutes = minutes + 1; } if (minutes > 59) { minutes = 0; degrees = degrees + 1; } (void) sprintf (tstring,"%c%02d:%02d:%07.4f",sign,degrees,minutes,seconds); } else if (ndec > 2) { if (seconds > 59.999) { seconds = 0.0; minutes = minutes + 1; } if (minutes > 59) { minutes = 0; degrees = degrees + 1; } (void) sprintf (tstring,"%c%02d:%02d:%06.3f",sign,degrees,minutes,seconds); } else if (ndec > 1) { if (seconds > 59.99) { seconds = 0.0; minutes = minutes + 1; } if (minutes > 59) { minutes = 0; degrees = degrees + 1; } (void) sprintf (tstring,"%c%02d:%02d:%05.2f",sign,degrees,minutes,seconds); } else if (ndec > 0) { if (seconds > 59.9) { seconds = 0.0; minutes = minutes + 1; } if (minutes > 59) { minutes = 0; degrees = degrees + 1; } (void) sprintf (tstring,"%c%02d:%02d:%04.1f",sign,degrees,minutes,seconds); } else { isec = (int)(seconds + 0.5); if (isec > 59) { isec = 0; minutes = minutes + 1; } if (minutes > 59) { minutes = 0; degrees = degrees + 1; } (void) sprintf (tstring,"%c%02d:%02d:%02d",sign,degrees,minutes,isec); } /* Move formatted string to returned string */ ltstr = (int) strlen (tstring); if (ltstr < lstr-1) strcpy (string, tstring); else { strncpy (string, tstring, lstr-1); string[lstr-1] = 0; } return; } /* Write the angle a in decimal format into string */ void deg2str (string, lstr, deg, ndec) char *string; /* Character string (returned) */ int lstr; /* Maximum number of characters in string */ double deg; /* Angle in degrees */ int ndec; /* Number of decimal places in degree string */ { char degform[8]; int field, ltstr; char tstring[64]; double deg1; double dsgn; /* Keep angle between -180 and 360 degrees */ deg1 = deg; if (deg1 < 0.0 ) { deg1 = -deg1; dsgn = -1.0; } else dsgn = 1.0; deg1 = fmod(deg1, 360.0); deg1 *= dsgn; if (deg1 <= -180.0) deg1 = deg1 + 360.0; /* Write angle to string, adding 4 digits to number of decimal places */ field = ndec + 4; if (ndec > 0) { sprintf (degform, "%%%d.%df", field, ndec); sprintf (tstring, degform, deg1); } else { sprintf (degform, "%%%4d", field); sprintf (tstring, degform, (int)deg1); } /* Move formatted string to returned string */ ltstr = (int) strlen (tstring); if (ltstr < lstr-1) strcpy (string, tstring); else { strncpy (string, tstring, lstr-1); string[lstr-1] = 0; } return; } /* Write the variable a in decimal format into field-character string */ void num2str (string, num, field, ndec) char *string; /* Character string (returned) */ double num; /* Number */ int field; /* Number of characters in output field (0=any) */ int ndec; /* Number of decimal places in degree string */ { char numform[8]; if (field > 0) { if (ndec > 0) { sprintf (numform, "%%%d.%df", field, ndec); sprintf (string, numform, num); } else { sprintf (numform, "%%%dd", field); sprintf (string, numform, (int)num); } } else { if (ndec > 0) { sprintf (numform, "%%.%df", ndec); sprintf (string, numform, num); } else { sprintf (string, "%d", (int)num); } } return; } /* Dec 14 1995 Original subroutines * Feb 5 1996 Added HDEL to delete keyword entry from FITS header * Feb 7 1996 Add EOS to LINE in HPUTC * Feb 21 1996 Add RA2STR and DEC2STR string routines * Jul 19 1996 Add HPUTRA and HPUTDEC * Jul 22 1996 Add HCHANGE to change keywords * Aug 5 1996 Add HPUTNR8 to save specific number of decimal places * Oct 15 1996 Fix spelling * Nov 1 1996 Add DEG2STR to set specific number of decimal places * Nov 1 1996 Allow DEC2STR to handle upt to 6 decimal places * * Mar 20 1997 Fix format error in DEG2STR * Jul 7 1997 Fix 2 errors in HPUTCOM found by Allan Brighton * Jul 16 1997 Fix error in HPUTC found by Allan Brighton * Jul 17 1997 Fix error in HPUTC found by Allan Brighton * Sep 30 1997 Fix error in HPUTCOM found by Allan Brighton * Dec 15 1997 Fix minor bugs after lint * Dec 31 1997 Always put two hour digits in RA2STR * * Feb 25 1998 Add HADD to insert keywords at specific locations * Mar 27 1998 If n is negative, write g format in HPUTNR8() * Apr 24 1998 Add NUM2STR() for easy output formatting * Apr 30 1998 Use BLSEARCH() to overwrite blank lines before END * May 27 1998 Keep Dec between -90 and +90 in DEC2STR() * May 28 1998 Keep RA between 0 and 360 in RA2STR() * Jun 2 1998 Fix bug when filling in blank lines before END * Jun 24 1998 Add string length to ra2str(), dec2str(), and deg2str() * Jun 25 1998 Make string converstion subroutines more robust * Aug 31 1998 Add getltime() and getutime() * Sep 28 1998 Null-terminate comment in HPUTCOM (Allan Brighton) * Oct 1 1998 Change clock declaration in getltime() from int (Allan Brighton) * * Jan 28 1999 Fix bug to avoid writing HISTORY or COMMENT past 80 characters * Jul 14 1999 Pad string in hputs() to minimum of 8 characters * Aug 16 1999 Keep angle between -180 and +360 in dec2str() * Oct 6 1999 Reallocate header buffer if it is too small in hputc() * Oct 14 1999 Do not reallocate header; return error if not successful * * Mar 2 2000 Do not add quotes if adding HISTORY or COMMENT with hputs() * Mar 22 2000 Move getutime() and getltime() to dateutil.c * Mar 27 2000 Add hputm() for muti-line keywords * Mar 27 2000 Fix bug testing for space to fit comment in hputcom() * Apr 19 2000 Fix bug in hadd() which overwrote line * Jun 2 2000 Dropped unused variable lv in hputm() after lint * Jul 20 2000 Drop unused variables blank and i in hputc() * * Jan 11 2001 Print all messages to stderr * Jan 18 2001 Drop declaration of blsearch(); it is in fitshead.h * * Jan 4 2002 Fix placement of comments * * Jul 1 2004 Add headshrink to optionally keep blank lines in header * Sep 3 2004 Fix bug so comments are not pushed onto next line if long value * Sep 16 2004 Add fixnegzero() to avoid putting signed zero values in header * * May 22 2006 Add option to leave blank line when deleting a keyword * Jun 15 2006 Fix comment alignment in hputc() and hputcom() * Jun 20 2006 Initialized uninitialized variables in hputm() and hputcom() * * Jan 4 2007 Declare keyword to be const * Jan 4 2007 Drop unused subroutine hputi2() * Jan 5 2007 Drop ksearch() declarations; it is now in fitshead.h * Jan 16 2007 Fix bugs in ra2str() and dec2str() so ndec=0 works * Aug 20 2007 Fix bug so comments after quoted keywords work * Aug 22 2007 If closing quote not found, make one up */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/iget.c000066400000000000000000000353401215713201500213540ustar00rootroot00000000000000/*** File libwcs/iget.c *** January 4, 2007 *** By Doug Mink, dmink@cfa.harvard.edu *** Harvard-Smithsonian Center for Astrophysics *** Copyright (C) 1998-2007 *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Correspondence concerning WCSTools should be addressed as follows: Internet email: dmink@cfa.harvard.edu Postal address: Doug Mink Smithsonian Astrophysical Observatory 60 Garden St. Cambridge, MA 02138 USA * Module: iget.c (Get IRAF FITS Header parameter values) * Purpose: Extract values for variables from IRAF keyword value string * Subroutine: mgeti4 (hstring,mkey,keyword,ival) returns long integer * Subroutine: mgetr8 (hstring,mkey,keyword,dval) returns double * Subroutine: mgetstr (hstring,mkey,keyword,lstr,str) returns character string * Subroutine: igeti4 (hstring,keyword,ival) returns long integer * Subroutine: igetr4 (hstring,keyword,rval) returns real * Subroutine: igetr8 (hstring,keyword,dval) returns double * Subroutine: igets (hstring,keyword,lstr,str) returns character string * Subroutine: igetc (hstring,keyword) returns character string * Subroutine: isearch (hstring,keyword) returns pointer to header string entry */ #include /* NULL, strlen, strstr, strcpy */ #include #include "fitshead.h" /* FITS header extraction subroutines */ #include #ifndef VMS #include #else #define INT_MAX 2147483647 /* Biggest number that can fit in long */ #define SHRT_MAX 32767 #endif #define MAX_LVAL 2000 static char *isearch(); static char val[30]; /* Extract long value for variable from IRAF multiline keyword value */ int mgeti4 (hstring, mkey, keyword, ival) const char *hstring; /* Character string containing FITS or IRAF header information in the format = ... */ const char *mkey; /* Character string containing the name of the multi-line keyword, the string value of which contains the desired keyword, the value of which is returned. */ const char *keyword; /* Character string containing the name of the keyword within the multiline IRAF keyword */ int *ival; /* Integer value returned */ { char *mstring; mstring = malloc (MAX_LVAL); if (hgetm (hstring, mkey, MAX_LVAL, mstring)) { if (igeti4 (mstring, keyword, ival)) { free (mstring); return (1); } else { free (mstring); return (0); } } else { free (mstring); return (0); } } /* Extract double value for variable from IRAF multiline keyword value */ int mgetr8 (hstring, mkey, keyword, dval) const char *hstring; /* Character string containing FITS or IRAF header information in the format = ... */ const char *mkey; /* Character string containing the name of the multi-line keyword, the string value of which contains the desired keyword, the value of which is returned. */ const char *keyword; /* Character string containing the name of the keyword within the multiline IRAF keyword */ double *dval; /* Integer value returned */ { char *mstring; mstring = malloc (MAX_LVAL); if (hgetm (hstring, mkey, MAX_LVAL, mstring)) { if (igetr8 (mstring, keyword, dval)) { free (mstring); return (1); } else { free (mstring); return (0); } } else { free (mstring); return (0); } } /* Extract string value for variable from IRAF keyword value string */ int mgetstr (hstring, mkey, keyword, lstr, str) const char *hstring; /* character string containing FITS header information in the format = {/ } */ const char *mkey; /* Character string containing the name of the multi-line keyword, the string value of which contains the desired keyword, the value of which is returned. */ const char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ const int lstr; /* Size of str in characters */ char *str; /* String (returned) */ { char *mstring; mstring = malloc (MAX_LVAL); if (hgetm (hstring, mkey, MAX_LVAL, mstring)) { if (igets (mstring, keyword, lstr, str)) { free (mstring); return (1); } else { free (mstring); return (0); } } else { free (mstring); return (0); } } /* Extract long value for variable from IRAF keyword value string */ int igeti4 (hstring, keyword, ival) const char *hstring; /* character string containing IRAF header information in the format = ... */ const char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ int *ival; /* Integer value returned */ { char *value; double dval; int minint; /* Get value from header string */ value = igetc (hstring,keyword); /* Translate value from ASCII to binary */ if (value != NULL) { minint = -INT_MAX - 1; strcpy (val, value); dval = atof (val); if (dval+0.001 > INT_MAX) *ival = INT_MAX; else if (dval >= 0) *ival = (int) (dval + 0.001); else if (dval-0.001 < minint) *ival = minint; else *ival = (int) (dval - 0.001); return (1); } else { return (0); } } /* Extract integer*2 value for variable from IRAF keyword value string */ int igeti2 (hstring,keyword,ival) const char *hstring; /* character string containing FITS header information in the format = {/ } */ const char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ short *ival; { char *value; double dval; int minshort; /* Get value from header string */ value = igetc (hstring,keyword); /* Translate value from ASCII to binary */ if (value != NULL) { strcpy (val, value); dval = atof (val); minshort = -SHRT_MAX - 1; if (dval+0.001 > SHRT_MAX) *ival = SHRT_MAX; else if (dval >= 0) *ival = (short) (dval + 0.001); else if (dval-0.001 < minshort) *ival = minshort; else *ival = (short) (dval - 0.001); return (1); } else { return (0); } } /* Extract real value for variable from IRAF keyword value string */ int igetr4 (hstring,keyword,rval) const char *hstring; /* character string containing FITS header information in the format = {/ } */ const char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ float *rval; { char *value; /* Get value from header string */ value = igetc (hstring,keyword); /* Translate value from ASCII to binary */ if (value != NULL) { strcpy (val, value); *rval = (float) atof (val); return (1); } else { return (0); } } /* Extract real*8 value for variable from IRAF keyword value string */ int igetr8 (hstring,keyword,dval) const char *hstring; /* character string containing FITS header information in the format = {/ } */ const char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ double *dval; { char *value,val[30]; /* Get value from header string */ value = igetc (hstring,keyword); /* Translate value from ASCII to binary */ if (value != NULL) { strcpy (val, value); *dval = atof (val); return (1); } else { return (0); } } /* Extract string value for variable from IRAF keyword value string */ int igets (hstring, keyword, lstr, str) const char *hstring; /* character string containing FITS header information in the format = {/ } */ const char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ const int lstr; /* Size of str in characters */ char *str; /* String (returned) */ { char *value; int lval; /* Get value from header string */ value = igetc (hstring,keyword); if (value != NULL) { lval = strlen (value); if (lval < lstr) strcpy (str, value); else if (lstr > 1) strncpy (str, value, lstr-1); else str[0] = value[0]; return (1); } else return (0); } /* Extract character value for variable from IRAF keyword value string */ char * igetc (hstring,keyword0) const char *hstring; /* character string containing IRAF keyword value string in the format = {/ } */ const char *keyword0; /* character string containing the name of the keyword the value of which is returned. iget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ { static char cval[MAX_LVAL]; char *value; char cwhite[8]; char lbracket[2],rbracket[2]; char keyword[16]; char line[MAX_LVAL]; char *vpos,*cpar; char *c1, *brack1, *brack2; int ipar, i; lbracket[0] = 91; lbracket[1] = 0; rbracket[0] = 93; rbracket[1] = 0; /* Find length of variable name */ strcpy (keyword,keyword0); brack1 = strsrch (keyword,lbracket); if (brack1 != NULL) *brack1 = '\0'; /* Search header string for variable name */ vpos = isearch (hstring,keyword); /* Exit if not found */ if (vpos == NULL) { return (NULL); } /* Initialize returned value to nulls */ for (i = 0; i < MAX_LVAL; i++) line[i] = 0; /* If quoted value, copy until second quote is reached */ i = 0; if (*vpos == '"') { vpos++; while (*vpos && *vpos != '"' && i < MAX_LVAL) line[i++] = *vpos++; } /* Otherwise copy until next space or tab */ else { while (*vpos != ' ' && *vpos != (char)9 && *vpos > 0 && i < MAX_LVAL) line[i++] = *vpos++; } /* If keyword has brackets, extract appropriate token from value */ if (brack1 != NULL) { c1 = (char *) (brack1 + 1); brack2 = strsrch (c1, rbracket); if (brack2 != NULL) { *brack2 = '\0'; ipar = atoi (c1); if (ipar > 0) { cwhite[0] = ' '; cwhite[1] = ','; cwhite[2] = '\0'; cpar = strtok (line, cwhite); for (i = 1; i < ipar; i++) { cpar = strtok (NULL, cwhite); } if (cpar != NULL) { strcpy (cval,cpar); } else value = NULL; } } } else strcpy (cval, line); value = cval; return (value); } /* Find value for specified IRAF keyword */ static char * isearch (hstring,keyword) /* Find entry for keyword keyword in IRAF keyword value string hstring. NULL is returned if the keyword is not found */ const char *hstring; /* character string containing fits-style header information in the format = {/ } the default is that each entry is 80 characters long; however, lines may be of arbitrary length terminated by nulls, carriage returns or linefeeds, if packed is true. */ const char *keyword; /* character string containing the name of the variable to be returned. isearch searches for a line beginning with this string. The string may be a character literal or a character variable terminated by a null or '$'. it is truncated to 8 characters. */ { char *loc, *headnext, *headlast, *pval; int lastchar, nextchar, lkey, nleft, lhstr; /* Search header string for variable name */ lhstr = 0; while (lhstr < 57600 && hstring[lhstr] != 0) lhstr++; headlast = (char *) hstring + lhstr; headnext = (char *) hstring; pval = NULL; lkey = strlen (keyword); while (headnext < headlast) { nleft = headlast - headnext; loc = strnsrch (headnext, keyword, nleft); /* Exit if keyword is not found */ if (loc == NULL) { break; } nextchar = (int) *(loc + lkey); lastchar = (int) *(loc - 1); /* If parameter name in header is longer, keep searching */ if (nextchar != 61 && nextchar > 32 && nextchar < 127) headnext = loc + 1; /* If start of string, keep it */ else if (loc == hstring) { pval = loc; break; } /* If preceeded by a blank or tab, keep it */ else if (lastchar == 32 || lastchar == 9) { pval = loc; break; } else headnext = loc + 1; } /* Find start of value string for this keyword */ if (pval != NULL) { pval = pval + lkey; while (*pval == ' ' || *pval == '=') pval++; } /* Return pointer to calling program */ return (pval); } /* Mar 12 1998 New subroutines * Apr 15 1998 Set IGET() and ISEARCH() static when defined * Apr 24 1998 Add MGETI4(), MGETR8(), and MGETS() for single step IRAF ext. * Jun 1 1998 Add VMS patch from Harry Payne at STScI * Jul 9 1998 Fix bracket token extraction after Paul Sydney * May 5 1999 values.h -> POSIX limits.h: MAXINT->INT_MAX, MAXSHORT->SHRT_MAX * Oct 21 1999 Fix declarations after lint * * Feb 11 2000 Stop search for end of quoted keyword if more than 500 chars * Jul 20 2000 Drop unused variables squot, dquot, and slash in igetc() * * Jun 26 2002 Change maximum string length from 600 to 2000; use MAX_LVAL * Jun 26 2002 Stop search for end of quoted keyword if > MAX_LVAL chars * * Sep 23 2003 Change mgets() to mgetstr() to avoid name collision at UCO Lick * * Feb 26 2004 Make igetc() accessible from outside this file * * Jan 4 2007 Declare header, keyword to be const */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/imhfile.c000066400000000000000000001473121215713201500220440ustar00rootroot00000000000000/*** File imhfile.c *** January 8, 2007 *** By Doug Mink, dmink@cfa.harvard.edu *** Harvard-Smithsonian Center for Astrophysics *** Copyright (C) 1996-2007 *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Correspondence concerning WCSTools should be addressed as follows: Internet email: dmink@cfa.harvard.edu Postal address: Doug Mink Smithsonian Astrophysical Observatory 60 Garden St. Cambridge, MA 02138 USA * Module: imhfile.c (IRAF .imh image file reading and writing) * Purpose: Read and write IRAF image files (and translate headers) * Subroutine: check_immagic (irafheader, teststring ) * Verify that file is valid IRAF imhdr or impix * Subroutine: irafrhead (filename, lfhead, fitsheader, lihead) * Read IRAF image header * Subroutine: irafrimage (fitsheader) * Read IRAF image pixels (call after irafrhead) * Subroutine: same_path (pixname, hdrname) * Put filename and header path together * Subroutine: iraf2fits (hdrname, irafheader, nbiraf, nbfits) * Convert IRAF image header to FITS image header * Subroutine: irafwhead (hdrname, irafheader, fitsheader) * Write IRAF header file * Subroutine: irafwimage (hdrname, irafheader, fitsheader, image ) * Write IRAF image and header files * Subroutine: fits2iraf (fitsheader, irafheader) * Convert FITS image header to IRAF image header * Subroutine: irafgeti4 (irafheader, offset) * Get 4-byte integer from arbitrary part of IRAF header * Subroutine: irafgetc2 (irafheader, offset) * Get character string from arbitrary part of IRAF v.1 header * Subroutine: irafgetc (irafheader, offset) * Get character string from arbitrary part of IRAF header * Subroutine: iraf2str (irafstring, nchar) * Convert 2-byte/char IRAF string to 1-byte/char string * Subroutine: str2iraf (string, irafstring, nchar) * Convert 1-byte/char string to IRAF 2-byte/char string * Subroutine: irafswap (bitpix,string,nbytes) * Swap bytes in string in place, with FITS bits/pixel code * Subroutine: irafswap2 (string,nbytes) * Swap bytes in string in place * Subroutine irafswap4 (string,nbytes) * Reverse bytes of Integer*4 or Real*4 vector in place * Subroutine irafswap8 (string,nbytes) * Reverse bytes of Real*8 vector in place * Subroutine irafsize (filename) * Return length of file in bytes * Subroutine isiraf (filename) * Return 1 if IRAF .imh file, else 0 * Copyright: 2000 Smithsonian Astrophysical Observatory * You may do anything you like with this file except remove * this copyright. The Smithsonian Astrophysical Observatory * makes no representations about the suitability of this * software for any purpose. It is provided "as is" without * express or implied warranty. */ #include /* define stderr, FD, and NULL */ #include #include #include #include #include #include #include "fitsfile.h" /* Parameters from iraf/lib/imhdr.h for IRAF version 1 images */ #define SZ_IMPIXFILE 79 /* name of pixel storage file */ #define SZ_IMHDRFILE 79 /* length of header storage file */ #define SZ_IMTITLE 79 /* image title string */ #define LEN_IMHDR 2052 /* length of std header */ /* Parameters from iraf/lib/imhdr.h for IRAF version 2 images */ #define SZ_IM2PIXFILE 255 /* name of pixel storage file */ #define SZ_IM2HDRFILE 255 /* name of header storage file */ #define SZ_IM2TITLE 383 /* image title string */ #define LEN_IM2HDR 2046 /* length of std header */ /* Offsets into header in bytes for parameters in IRAF version 1 images */ #define IM_HDRLEN 12 /* Length of header in 4-byte ints */ #define IM_PIXTYPE 16 /* Datatype of the pixels */ #define IM_NDIM 20 /* Number of dimensions */ #define IM_LEN 24 /* Length (as stored) */ #define IM_PHYSLEN 52 /* Physical length (as stored) */ #define IM_PIXOFF 88 /* Offset of the pixels */ #define IM_CTIME 108 /* Time of image creation */ #define IM_MTIME 112 /* Time of last modification */ #define IM_LIMTIME 116 /* Time of min,max computation */ #define IM_MAX 120 /* Maximum pixel value */ #define IM_MIN 124 /* Maximum pixel value */ #define IM_PIXFILE 412 /* Name of pixel storage file */ #define IM_HDRFILE 572 /* Name of header storage file */ #define IM_TITLE 732 /* Image name string */ /* Offsets into header in bytes for parameters in IRAF version 2 images */ #define IM2_HDRLEN 6 /* Length of header in 4-byte ints */ #define IM2_PIXTYPE 10 /* Datatype of the pixels */ #define IM2_SWAPPED 14 /* Pixels are byte swapped */ #define IM2_NDIM 18 /* Number of dimensions */ #define IM2_LEN 22 /* Length (as stored) */ #define IM2_PHYSLEN 50 /* Physical length (as stored) */ #define IM2_PIXOFF 86 /* Offset of the pixels */ #define IM2_CTIME 106 /* Time of image creation */ #define IM2_MTIME 110 /* Time of last modification */ #define IM2_LIMTIME 114 /* Time of min,max computation */ #define IM2_MAX 118 /* Maximum pixel value */ #define IM2_MIN 122 /* Maximum pixel value */ #define IM2_PIXFILE 126 /* Name of pixel storage file */ #define IM2_HDRFILE 382 /* Name of header storage file */ #define IM2_TITLE 638 /* Image name string */ /* Codes from iraf/unix/hlib/iraf.h */ #define TY_CHAR 2 #define TY_SHORT 3 #define TY_INT 4 #define TY_LONG 5 #define TY_REAL 6 #define TY_DOUBLE 7 #define TY_COMPLEX 8 #define TY_POINTER 9 #define TY_STRUCT 10 #define TY_USHORT 11 #define TY_UBYTE 12 #define LEN_IRAFHDR 25000 #define LEN_PIXHDR 1024 #define LEN_FITSHDR 11520 int check_immagic(); int irafgeti4(); float irafgetr4(); char *irafgetc2(); char *irafgetc(); char *iraf2str(); static char *same_path(); static void irafputr4(); static void irafputi4(); static void irafputc2(); static void irafputc(); static void str2iraf(); static int headswap=-1; /* =1 to swap data bytes of foreign IRAF file */ static void irafswap(); static void irafswap2(); static void irafswap4(); static void irafswap8(); int head_version (); int pix_version (); int irafncmp (); static int machswap(); static int irafsize(); #define SECONDS_1970_TO_1980 315532800L /* Subroutine: irafrhead * Purpose: Open and read the iraf .imh file, translating it to FITS, too. * Returns: NULL if failure, else pointer to IRAF .imh image header * Notes: The imhdr format is defined in iraf/lib/imhdr.h, some of * which defines or mimicked, above. */ char * irafrhead (filename, lihead) char *filename; /* Name of IRAF header file */ int *lihead; /* Length of IRAF image header in bytes (returned) */ { FILE *fd; int nbr; char *irafheader; int nbhead, nbytes; int imhver; headswap = -1; *lihead = 0; /* open the image header file */ fd = fopen (filename, "rb"); if (fd == NULL) { fprintf (stderr, "IRAFRHEAD: cannot open file %s to read\n", filename); return (NULL); } /* Find size of image header file */ if ((nbhead = irafsize (fd)) <= 0) { fprintf (stderr, "IRAFRHEAD: cannot read file %s, size = %d\n", filename, nbhead); return (NULL); } /* allocate initial sized buffer */ nbytes = nbhead + 5000; irafheader = (char *) calloc (nbytes/4, 4); if (irafheader == NULL) { (void)fprintf(stderr, "IRAFRHEAD Cannot allocate %d-byte header\n", nbytes); return (NULL); } *lihead = nbytes; /* Read IRAF header */ nbr = fread (irafheader, 1, nbhead, fd); fclose (fd); /* Reject if header less than minimum length */ if (nbr < LEN_PIXHDR) { (void)fprintf(stderr, "IRAFRHEAD header file %s: %d / %d bytes read.\n", filename,nbr,LEN_PIXHDR); free (irafheader); return (NULL); } /* Check header magic word */ imhver = head_version (irafheader); if (imhver < 1) { free (irafheader); (void)fprintf(stderr, "IRAFRHEAD: %s is not a valid IRAF image header\n", filename); return(NULL); } /* check number of image dimensions if (imhver == 2) ndim = irafgeti4 (irafheader, IM2_NDIM]) else ndim = irafgeti4 (irafheader, IM_NDIM]) if (ndim < 2) { free (irafheader); (void)fprintf(stderr, "File %s does not contain 2d image\n", filename); return (NULL); } */ return (irafheader); } char * irafrimage (fitsheader) char *fitsheader; /* FITS image header (filled) */ { FILE *fd; char *bang; int naxis, naxis1, naxis2, naxis3, npaxis1, npaxis2,bitpix, bytepix, pixswap, i; char *image; int nbr, nbimage, nbaxis, nbl, nbdiff, lpname; char *pixheader; char *linebuff, *pixchar; int imhver, lpixhead, len; char pixname[SZ_IM2PIXFILE+1]; char newpixname[SZ_IM2HDRFILE+1]; /* Convert pixel file name to character string */ hgetm (fitsheader, "PIXFIL", SZ_IM2PIXFILE, pixname); /* Drop trailing spaces */ lpname = strlen (pixname); pixchar = pixname + lpname - 1; while (*pixchar == ' ') *pixchar = (char) 0; hgeti4 (fitsheader, "PIXOFF", &lpixhead); /* Open pixel file, ignoring machine name if present */ if ((bang = strchr (pixname, '!')) != NULL ) fd = fopen (bang + 1, "rb"); else fd = fopen (pixname, "rb"); /* If not at pathname in header, try same directory as header file */ if (!fd) { hgetm (fitsheader, "IMHFIL", SZ_IM2HDRFILE, newpixname); len = strlen (newpixname); newpixname[len-3] = 'p'; newpixname[len-2] = 'i'; newpixname[len-1] = 'x'; fd = fopen (newpixname, "rb"); } /* Print error message and exit if pixel file is not found */ if (!fd) { (void)fprintf(stderr, "IRAFRIMAGE: Cannot open IRAF pixel file %s\n", pixname); return (NULL); } /* Read pixel header */ pixheader = (char *) calloc (lpixhead/4, 4); if (pixheader == NULL) { (void)fprintf(stderr, "IRAFRIMAGE Cannot allocate %d-byte pixel header\n", lpixhead); return (NULL); } nbr = fread (pixheader, 1, lpixhead, fd); /* Check size of pixel header */ if (nbr < lpixhead) { (void)fprintf(stderr, "IRAF pixel file %s: %d / %d bytes read.\n", pixname,nbr,LEN_PIXHDR); free (pixheader); fclose (fd); return (NULL); } /* check pixel header magic word */ imhver = pix_version (pixheader); if (imhver < 1) { (void)fprintf(stderr, "File %s not valid IRAF pixel file.\n", pixname); free (pixheader); fclose (fd); return(NULL); } free (pixheader); /* Find number of bytes to read */ hgeti4 (fitsheader,"NAXIS",&naxis); hgeti4 (fitsheader,"NAXIS1",&naxis1); hgeti4 (fitsheader,"NAXIS2",&naxis2); hgeti4 (fitsheader,"NPAXIS1",&npaxis1); hgeti4 (fitsheader,"NPAXIS2",&npaxis2); hgeti4 (fitsheader,"BITPIX",&bitpix); if (bitpix < 0) bytepix = -bitpix / 8; else bytepix = bitpix / 8; /* If either dimension is one and image is 3-D, read all three dimensions */ if (naxis == 3 && ((naxis1 == 1) | (naxis2 == 1))) { hgeti4 (fitsheader,"NAXIS3",&naxis3); nbimage = naxis1 * naxis2 * naxis3 * bytepix; } else { nbimage = naxis1 * naxis2 * bytepix; naxis3 = 1; } if (bytepix > 4) image = (char *) calloc (nbimage/8, 8); else if (bytepix > 2) image = (char *) calloc (nbimage/4, 4); else if (bytepix > 1) image = (char *) calloc (nbimage/2, 2); else image = (char *) calloc (nbimage, 1); if (image == NULL) { (void)fprintf(stderr, "IRAFRIMAGE Cannot allocate %d-byte image buffer\n", nbimage); return (NULL); } /* Read IRAF image all at once if physical and image dimensions are the same */ if (npaxis1 == naxis1) nbr = fread (image, 1, nbimage, fd); /* Read IRAF image one line at a time if physical and image dimensions differ */ else { nbdiff = (npaxis1 - naxis1) * bytepix; nbaxis = naxis1 * bytepix; linebuff = image; nbr = 0; if (naxis2 == 1 && naxis3 > 1) naxis2 = naxis3; for (i = 0; i < naxis2; i++) { nbl = fread (linebuff, 1, nbaxis, fd); nbr = nbr + nbl; (void) fseek (fd, nbdiff, SEEK_CUR); linebuff = linebuff + nbaxis; } } fclose (fd); /* Check size of image */ if (nbr < nbimage) { (void)fprintf(stderr, "IRAF pixel file %s: %d / %d bytes read.\n", pixname,nbr,nbimage); free (image); return (NULL); } /* Byte-reverse image, if necessary */ pixswap = 0; hgetl (fitsheader, "PIXSWAP", &pixswap); if (pixswap) irafswap (bitpix, image, nbimage); return (image); } /* Return IRAF image format version number from magic word in IRAF header*/ int head_version (irafheader) char *irafheader; /* IRAF image header from file */ { /* Check header file magic word */ if (irafncmp (irafheader, "imhdr", 5) != 0 ) { if (strncmp (irafheader, "imhv2", 5) != 0) return (0); else return (2); } else return (1); } /* Return IRAF image format version number from magic word in IRAF pixel file */ int pix_version (irafheader) char *irafheader; /* IRAF image header from file */ { /* Check pixel file header magic word */ if (irafncmp (irafheader, "impix", 5) != 0) { if (strncmp (irafheader, "impv2", 5) != 0) return (0); else return (2); } else return (1); } /* Verify that file is valid IRAF imhdr or impix by checking first 5 chars * Returns: 0 on success, 1 on failure */ int irafncmp (irafheader, teststring, nc) char *irafheader; /* IRAF image header from file */ char *teststring; /* C character string to compare */ int nc; /* Number of characters to compate */ { char *line; headswap = -1; if ((line = iraf2str (irafheader, nc)) == NULL) return (1); if (strncmp (line, teststring, nc) == 0) { free (line); return (0); } else { free (line); return (1); } } /* Convert IRAF image header to FITS image header, returning FITS header */ char * iraf2fits (hdrname, irafheader, nbiraf, nbfits) char *hdrname; /* IRAF header file name (may be path) */ char *irafheader; /* IRAF image header */ int nbiraf; /* Number of bytes in IRAF header */ int *nbfits; /* Number of bytes in FITS header (returned) */ { char *objname; /* object name from FITS file */ int lstr, i, j, k, ib, nax, nbits, nl; int lname = 0; char *pixname, *newpixname, *bang, *chead; char *fitsheader; int nblock, nlines; char *fhead, *fhead1, *fp, endline[81]; char irafchar; char fitsline[81]; char *dstring; int pixtype; int imhver, n, imu, pixoff, impixoff, immax, immin, imtime; int imndim, imlen, imphyslen, impixtype, pixswap, hpixswap, mtime; float rmax, rmin; headswap = -1; /* Set up last line of FITS header */ (void)strncpy (endline,"END", 3); for (i = 3; i < 80; i++) endline[i] = ' '; endline[80] = 0; /* Check header magic word */ imhver = head_version (irafheader); if (imhver < 1) { (void)fprintf(stderr, "File %s not valid IRAF image header\n", hdrname); return(NULL); } if (imhver == 2) { nlines = 24 + ((nbiraf - LEN_IM2HDR) / 81); imndim = IM2_NDIM; imlen = IM2_LEN; imphyslen = IM2_PHYSLEN; impixtype = IM2_PIXTYPE; impixoff = IM2_PIXOFF; imtime = IM2_MTIME; immax = IM2_MAX; immin = IM2_MIN; } else { nlines = 24 + ((nbiraf - LEN_IMHDR) / 162); imndim = IM_NDIM; imlen = IM_LEN; imphyslen = IM_PHYSLEN; impixtype = IM_PIXTYPE; impixoff = IM_PIXOFF; imtime = IM_MTIME; immax = IM_MAX; immin = IM_MIN; } /* Initialize FITS header */ nblock = (nlines * 80) / 2880; *nbfits = (nblock + 5) * 2880 + 4; fitsheader = (char *) calloc (*nbfits, 1); if (fitsheader == NULL) { (void)fprintf(stderr, "IRAF2FITS Cannot allocate %d-byte FITS header\n", *nbfits); return (NULL); } hlength (fitsheader, *nbfits); fhead = fitsheader; (void)strncpy (fitsheader, endline, 80); hputl (fitsheader, "SIMPLE", 1); fhead = fhead + 80; /* Set pixel size in FITS header */ pixtype = irafgeti4 (irafheader, impixtype); switch (pixtype) { case TY_CHAR: nbits = 8; break; case TY_UBYTE: nbits = 8; break; case TY_SHORT: nbits = 16; break; case TY_USHORT: nbits = -16; break; case TY_INT: case TY_LONG: nbits = 32; break; case TY_REAL: nbits = -32; break; case TY_DOUBLE: nbits = -64; break; default: (void)fprintf(stderr,"Unsupported data type: %d\n", pixtype); return (NULL); } hputi4 (fitsheader,"BITPIX",nbits); hputcom (fitsheader,"BITPIX", "IRAF .imh pixel type"); fhead = fhead + 80; /* Set image dimensions in FITS header */ nax = irafgeti4 (irafheader, imndim); hputi4 (fitsheader,"NAXIS",nax); hputcom (fitsheader,"NAXIS", "IRAF .imh naxis"); fhead = fhead + 80; n = irafgeti4 (irafheader, imlen); hputi4 (fitsheader, "NAXIS1", n); hputcom (fitsheader,"NAXIS1", "IRAF .imh image naxis[1]"); fhead = fhead + 80; if (nax > 1) { n = irafgeti4 (irafheader, imlen+4); hputi4 (fitsheader, "NAXIS2", n); hputcom (fitsheader,"NAXIS2", "IRAF .imh image naxis[2]"); } else hputi4 (fitsheader, "NAXIS2", 1); hputcom (fitsheader,"NAXIS2", "IRAF .imh naxis[2]"); fhead = fhead + 80; if (nax > 2) { n = irafgeti4 (irafheader, imlen+8); hputi4 (fitsheader, "NAXIS3", n); hputcom (fitsheader,"NAXIS3", "IRAF .imh image naxis[3]"); fhead = fhead + 80; } if (nax > 3) { n = irafgeti4 (irafheader, imlen+12); hputi4 (fitsheader, "NAXIS4", n); hputcom (fitsheader,"NAXIS4", "IRAF .imh image naxis[4]"); fhead = fhead + 80; } /* Set object name in FITS header */ if (imhver == 2) objname = irafgetc (irafheader, IM2_TITLE, SZ_IM2TITLE); else objname = irafgetc2 (irafheader, IM_TITLE, SZ_IMTITLE); if ((lstr = strlen (objname)) < 8) { for (i = lstr; i < 8; i++) objname[i] = ' '; objname[8] = 0; } hputs (fitsheader,"OBJECT",objname); hputcom (fitsheader,"OBJECT", "IRAF .imh title"); free (objname); fhead = fhead + 80; /* Save physical axis lengths so image file can be read */ n = irafgeti4 (irafheader, imphyslen); hputi4 (fitsheader, "NPAXIS1", n); hputcom (fitsheader,"NPAXIS1", "IRAF .imh physical naxis[1]"); fhead = fhead + 80; if (nax > 1) { n = irafgeti4 (irafheader, imphyslen+4); hputi4 (fitsheader, "NPAXIS2", n); hputcom (fitsheader,"NPAXIS2", "IRAF .imh physical naxis[2]"); fhead = fhead + 80; } if (nax > 2) { n = irafgeti4 (irafheader, imphyslen+8); hputi4 (fitsheader, "NPAXIS3", n); hputcom (fitsheader,"NPAXIS3", "IRAF .imh physical naxis[3]"); fhead = fhead + 80; } if (nax > 3) { n = irafgeti4 (irafheader, imphyslen+12); hputi4 (fitsheader, "NPAXIS4", n); hputcom (fitsheader,"NPAXIS4", "IRAF .imh physical naxis[4]"); fhead = fhead + 80; } /* Save image minimum and maximum in header */ rmax = irafgetr4 (irafheader, immax); rmin = irafgetr4 (irafheader, immin); if (rmin != rmax) { hputr4 (fitsheader, "IRAFMIN", &rmin); fhead = fhead + 80; hputcom (fitsheader,"IRAFMIN", "IRAF .imh minimum"); hputr4 (fitsheader, "IRAFMAX", &rmax); hputcom (fitsheader,"IRAFMAX", "IRAF .imh maximum"); fhead = fhead + 80; } /* Save image header filename in header */ nl = hputm (fitsheader,"IMHFIL",hdrname); if (nl > 0) { lname = strlen (hdrname); strcpy (fitsline, "IRAF header file name"); if (lname < 43) hputcom (fitsheader,"IMHFIL_1", fitsline); else if (lname > 67 && lname < 110) hputcom (fitsheader,"IMHFIL_2", fitsline); else if (lname > 134 && lname < 177) hputcom (fitsheader,"IMHFIL_3", fitsline); } if (nl > 0) fhead = fhead + (nl * 80); /* Save image pixel file pathname in header */ if (imhver == 2) pixname = irafgetc (irafheader, IM2_PIXFILE, SZ_IM2PIXFILE); else pixname = irafgetc2 (irafheader, IM_PIXFILE, SZ_IMPIXFILE); if (strncmp(pixname, "HDR", 3) == 0 ) { newpixname = same_path (pixname, hdrname); free (pixname); pixname = newpixname; } if (strchr (pixname, '/') == NULL && strchr (pixname, '$') == NULL) { newpixname = same_path (pixname, hdrname); free (pixname); pixname = newpixname; } if ((bang = strchr (pixname, '!')) != NULL ) nl = hputm (fitsheader,"PIXFIL",bang+1); else nl = hputm (fitsheader,"PIXFIL",pixname); free (pixname); if (nl > 0) { strcpy (fitsline, "IRAF .pix pixel file"); if (lname < 43) hputcom (fitsheader,"PIXFIL_1", fitsline); else if (lname > 67 && lname < 110) hputcom (fitsheader,"PIXFIL_2", fitsline); else if (lname > 134 && lname < 177) hputcom (fitsheader,"PIXFIL_3", fitsline); } if (nl > 0) fhead = fhead + (nl * 80); /* Save image offset from star of pixel file */ pixoff = irafgeti4 (irafheader, impixoff); pixoff = (pixoff - 1) * 2; hputi4 (fitsheader, "PIXOFF", pixoff); hputcom (fitsheader,"PIXOFF", "IRAF .pix pixel offset (Do not change!)"); fhead = fhead + 80; /* Save IRAF file format version in header */ hputi4 (fitsheader,"IMHVER",imhver); hputcom (fitsheader,"IMHVER", "IRAF .imh format version (1 or 2)"); fhead = fhead + 80; /* Set flag if header numbers are byte-reversed on this machine */ if (machswap() != headswap) hputl (fitsheader, "HEADSWAP", 1); else hputl (fitsheader, "HEADSWAP", 0); hputcom (fitsheader,"HEADSWAP", "IRAF header, FITS byte orders differ if T"); fhead = fhead + 80; /* Set flag if image pixels are byte-reversed on this machine */ if (imhver == 2) { hpixswap = irafgeti4 (irafheader, IM2_SWAPPED); if (headswap && !hpixswap) pixswap = 1; else if (!headswap && hpixswap) pixswap = 1; else pixswap = 0; } else pixswap = headswap; if (machswap() != pixswap) hputl (fitsheader, "PIXSWAP", 1); else hputl (fitsheader, "PIXSWAP", 0); hputcom (fitsheader,"PIXSWAP", "IRAF pixels, FITS byte orders differ if T"); fhead = fhead + 80; /* Read modification time */ mtime = irafgeti4 (irafheader, imtime); if (mtime == 0) dstring = lt2fd (); else dstring = tsi2fd (mtime); hputs (fitsheader, "DATE-MOD", dstring); hputcom (fitsheader,"DATE-MOD", "Date of latest file modification"); free (dstring); fhead = fhead + 80; /* Add user portion of IRAF header to FITS header */ fitsline[80] = 0; if (imhver == 2) { imu = LEN_IM2HDR; chead = irafheader; j = 0; for (k = 0; k < 80; k++) fitsline[k] = ' '; for (i = imu; i < nbiraf; i++) { irafchar = chead[i]; if (irafchar == 0) break; else if (irafchar == 10) { (void)strncpy (fhead, fitsline, 80); /* fprintf (stderr,"%80s\n",fitsline); */ if (strncmp (fitsline, "OBJECT ", 7) != 0) { fhead = fhead + 80; } for (k = 0; k < 80; k++) fitsline[k] = ' '; j = 0; } else { if (j > 80) { if (strncmp (fitsline, "OBJECT ", 7) != 0) { (void)strncpy (fhead, fitsline, 80); /* fprintf (stderr,"%80s\n",fitsline); */ j = 9; fhead = fhead + 80; } for (k = 0; k < 80; k++) fitsline[k] = ' '; } if (irafchar > 32 && irafchar < 127) fitsline[j] = irafchar; j++; } } } else { imu = LEN_IMHDR; chead = irafheader; if (headswap == 1) ib = 0; else ib = 1; for (k = 0; k < 80; k++) fitsline[k] = ' '; j = 0; for (i = imu; i < nbiraf; i=i+2) { irafchar = chead[i+ib]; if (irafchar == 0) break; else if (irafchar == 10) { if (strncmp (fitsline, "OBJECT ", 7) != 0) { (void)strncpy (fhead, fitsline, 80); fhead = fhead + 80; } /* fprintf (stderr,"%80s\n",fitsline); */ j = 0; for (k = 0; k < 80; k++) fitsline[k] = ' '; } else { if (j > 80) { if (strncmp (fitsline, "OBJECT ", 7) != 0) { (void)strncpy (fhead, fitsline, 80); j = 9; fhead = fhead + 80; } /* fprintf (stderr,"%80s\n",fitsline); */ for (k = 0; k < 80; k++) fitsline[k] = ' '; } if (irafchar > 32 && irafchar < 127) fitsline[j] = irafchar; j++; } } } /* Add END to last line */ (void)strncpy (fhead, endline, 80); /* Find end of last 2880-byte block of header */ fhead = ksearch (fitsheader, "END") + 80; nblock = *nbfits / 2880; fhead1 = fitsheader + (nblock * 2880); /* Pad rest of header with spaces */ strncpy (endline," ",3); for (fp = fhead; fp < fhead1; fp = fp + 80) { (void)strncpy (fp, endline,80); } return (fitsheader); } int irafwhead (hdrname, lhead, irafheader, fitsheader) char *hdrname; /* Name of IRAF header file */ int lhead; /* Length of IRAF header */ char *irafheader; /* IRAF header */ char *fitsheader; /* FITS image header */ { int fd; int nbw, nbhead, lphead, pixswap; /* Get rid of redundant header information */ hgeti4 (fitsheader, "PIXOFF", &lphead); hgeti4 (fitsheader, "PIXSWAP", &pixswap); /* Write IRAF header file */ /* Convert FITS header to IRAF header */ irafheader = fits2iraf (fitsheader, irafheader, lhead, &nbhead); if (irafheader == NULL) { fprintf (stderr, "IRAFWIMAGE: file %s header error\n", hdrname); return (-1); } /* Open the output file */ if (!access (hdrname, 0)) { fd = open (hdrname, O_WRONLY); if (fd < 3) { fprintf (stderr, "IRAFWIMAGE: file %s not writeable\n", hdrname); return (0); } } else { fd = open (hdrname, O_RDWR+O_CREAT, 0666); if (fd < 3) { fprintf (stderr, "IRAFWIMAGE: cannot create file %s\n", hdrname); return (0); } } /* Write IRAF header to disk file */ nbw = write (fd, irafheader, nbhead); (void) ftruncate (fd, nbhead); close (fd); if (nbw < nbhead) { (void)fprintf(stderr, "IRAF header file %s: %d / %d bytes written.\n", hdrname, nbw, nbhead); return (-1); } return (nbw); } /* IRAFWIMAGE -- write IRAF .imh header file and .pix image file * No matter what the input, this always writes in the local byte order */ int irafwimage (hdrname, lhead, irafheader, fitsheader, image ) char *hdrname; /* Name of IRAF header file */ int lhead; /* Length of IRAF header */ char *irafheader; /* IRAF header */ char *fitsheader; /* FITS image header */ char *image; /* IRAF image */ { int fd; char *bang; int nbw, bytepix, bitpix, naxis, naxis1, naxis2, nbimage, lphead; char *pixn, *newpixname; char pixname[SZ_IM2PIXFILE+1]; int imhver, pixswap; hgeti4 (fitsheader, "IMHVER", &imhver); if (!hgetm (fitsheader, "PIXFIL", SZ_IM2PIXFILE, pixname)) { if (imhver == 2) pixn = irafgetc (irafheader, IM2_PIXFILE, SZ_IM2PIXFILE); else pixn = irafgetc2 (irafheader, IM_PIXFILE, SZ_IMPIXFILE); if (strncmp(pixn, "HDR", 3) == 0 ) { newpixname = same_path (pixn, hdrname); strcpy (pixname, newpixname); } else { if ((bang = strchr (pixn, '!')) != NULL ) strcpy (pixname, bang+1); else strcpy (pixname, pixn); } free (pixn); } /* Find number of bytes to write */ hgeti4 (fitsheader,"NAXIS",&naxis); hgeti4 (fitsheader,"NAXIS1",&naxis1); hgeti4 (fitsheader,"NAXIS2",&naxis2); hgeti4 (fitsheader,"BITPIX",&bitpix); if (bitpix < 0) bytepix = -bitpix / 8; else bytepix = bitpix / 8; /* If either dimension is one and image is 3-D, read all three dimensions */ if (naxis == 3 && ((naxis1 == 1) | (naxis2 == 1))) { int naxis3; hgeti4 (fitsheader,"NAXIS3",&naxis3); nbimage = naxis1 * naxis2 * naxis3 * bytepix; } else nbimage = naxis1 * naxis2 * bytepix; /* Read information about pixel file from header */ hgeti4 (fitsheader, "PIXOFF", &lphead); hgeti4 (fitsheader, "PIXSWAP", &pixswap); /* Write IRAF header file */ if (irafwhead (hdrname, lhead, irafheader, fitsheader)) return (0); /* Open the output file */ if (!access (pixname, 0)) { fd = open (pixname, O_WRONLY); if (fd < 3) { fprintf (stderr, "IRAFWIMAGE: file %s not writeable\n", pixname); return (0); } } else { fd = open (pixname, O_RDWR+O_CREAT, 0666); if (fd < 3) { fprintf (stderr, "IRAFWIMAGE: cannot create file %s\n", pixname); return (0); } } /* Write header to IRAF pixel file */ if (imhver == 2) irafputc ("impv2", irafheader, 0, 5); else irafputc2 ("impix", irafheader, 0, 5); nbw = write (fd, irafheader, lphead); /* Byte-reverse image, if necessary */ if (pixswap) irafswap (bitpix, image, nbimage); /* Write data to IRAF pixel file */ nbw = write (fd, image, nbimage); close (fd); free (pixname); return (nbw); } /* Put filename and header path together */ static char * same_path (pixname, hdrname) char *pixname; /* IRAF pixel file pathname */ char *hdrname; /* IRAF image header file pathname */ { int len; char *newpixname; newpixname = (char *) calloc (SZ_IM2PIXFILE, 1); /* Pixel file is in same directory as header */ if (strncmp(pixname, "HDR$", 4) == 0 ) { (void)strncpy (newpixname, hdrname, SZ_IM2PIXFILE); /* find the end of the pathname */ len = strlen (newpixname); #ifndef VMS while( (len > 0) && (newpixname[len-1] != '/') ) #else while( (len > 0) && (newpixname[len-1] != ']') && (newpixname[len-1] != ':') ) #endif len--; /* add name */ newpixname[len] = '\0'; (void)strncat (newpixname, &pixname[4], SZ_IM2PIXFILE); } /* Bare pixel file with no path is assumed to be same as HDR$filename */ else if (strchr (pixname, '/') == NULL && strchr (pixname, '$') == NULL) { (void)strncpy (newpixname, hdrname, SZ_IM2PIXFILE); /* find the end of the pathname */ len = strlen (newpixname); #ifndef VMS while( (len > 0) && (newpixname[len-1] != '/') ) #else while( (len > 0) && (newpixname[len-1] != ']') && (newpixname[len-1] != ':') ) #endif len--; /* add name */ newpixname[len] = '\0'; (void)strncat (newpixname, pixname, SZ_IM2PIXFILE); } /* Pixel file has same name as header file, but with .pix extension */ else if (strncmp (pixname, "HDR", 3) == 0) { /* load entire header name string into name buffer */ (void)strncpy (newpixname, hdrname, SZ_IM2PIXFILE); len = strlen (newpixname); newpixname[len-3] = 'p'; newpixname[len-2] = 'i'; newpixname[len-1] = 'x'; } return (newpixname); } /* Convert FITS image header to IRAF image header, returning IRAF header */ /* No matter what the input, this always writes in the local byte order */ char * fits2iraf (fitsheader, irafheader, nbhead, nbiraf) char *fitsheader; /* FITS image header */ char *irafheader; /* IRAF image header (returned updated) */ int nbhead; /* Length of IRAF header */ int *nbiraf; /* Length of returned IRAF header */ { int i, n, pixoff, lhdrdir; short *irafp, *irafs, *irafu; char *iraf2u, *iraf2p, *filename, *hdrdir; char *fitsend, *fitsp, pixfile[SZ_IM2PIXFILE], hdrfile[SZ_IM2HDRFILE]; char title[SZ_IM2TITLE], temp[80]; int nax, nlfits, imhver, nbits, pixtype, hdrlength, mtime; int imndim, imlen, imphyslen, impixtype, imhlen, imtime, immax, immin; float rmax, rmin; hgeti4 (fitsheader, "IMHVER", &imhver); hdel (fitsheader, "IMHVER"); hdel (fitsheader, "IMHVER"); hgetl (fitsheader, "HEADSWAP", &headswap); hdel (fitsheader, "HEADSWAP"); hdel (fitsheader, "HEADSWAP"); if (imhver == 2) { imhlen = IM2_HDRLEN; imndim = IM2_NDIM; imlen = IM2_LEN; imtime = IM2_MTIME; imphyslen = IM2_PHYSLEN; impixtype = IM2_PIXTYPE; immax = IM2_MAX; immin = IM2_MIN; } else { imhlen = IM_HDRLEN; imndim = IM_NDIM; imlen = IM_LEN; imtime = IM_MTIME; imphyslen = IM_PHYSLEN; impixtype = IM_PIXTYPE; immax = IM_MAX; immin = IM_MIN; } /* Delete FITS header keyword not needed by IRAF */ hdel (fitsheader,"SIMPLE"); /* Set IRAF image data type */ hgeti4 (fitsheader,"BITPIX", &nbits); switch (nbits) { case 8: pixtype = TY_CHAR; break; case -8: pixtype = TY_UBYTE; break; case 16: pixtype = TY_SHORT; break; case -16: pixtype = TY_USHORT; break; case 32: pixtype = TY_INT; break; case -32: pixtype = TY_REAL; break; case -64: pixtype = TY_DOUBLE; break; default: (void)fprintf(stderr,"Unsupported data type: %d\n", nbits); return (NULL); } irafputi4 (irafheader, impixtype, pixtype); hdel (fitsheader,"BITPIX"); /* Set IRAF image dimensions */ hgeti4 (fitsheader,"NAXIS",&nax); irafputi4 (irafheader, imndim, nax); hdel (fitsheader,"NAXIS"); hgeti4 (fitsheader, "NAXIS1", &n); irafputi4 (irafheader, imlen, n); irafputi4 (irafheader, imphyslen, n); hdel (fitsheader,"NAXIS1"); hgeti4 (fitsheader,"NAXIS2",&n); irafputi4 (irafheader, imlen+4, n); irafputi4 (irafheader, imphyslen+4, n); hdel (fitsheader,"NAXIS2"); if (nax > 2) { hgeti4 (fitsheader,"NAXIS3",&n); irafputi4 (irafheader, imlen+8, n); irafputi4 (irafheader, imphyslen+8, n); hdel (fitsheader,"NAXIS3"); } if (nax > 3) { hgeti4 (fitsheader,"NAXIS4",&n); irafputi4 (irafheader, imlen+12, n); irafputi4 (irafheader, imphyslen+12, n); hdel (fitsheader,"NAXIS4"); } /* Set image pixel value limits */ rmin = 0.0; hgetr4 (fitsheader, "IRAFMIN", &rmin); rmax = 0.0; hgetr4 (fitsheader, "IRAFMAX", &rmax); if (rmin != rmax) { irafputr4 (irafheader, immax, rmax); irafputr4 (irafheader, immin, rmin); } hdel (fitsheader, "IRAFMIN"); hdel (fitsheader, "IRAFMAX"); /* Replace pixel file name, if it is in the FITS header */ if (hgetm (fitsheader, "PIXFIL", SZ_IM2PIXFILE, pixfile)) { if (strchr (pixfile, '/')) { if (hgetm (fitsheader, "IMHFIL", SZ_IM2HDRFILE, hdrfile)) { hdrdir = strrchr (hdrfile, '/'); if (hdrdir != NULL) { lhdrdir = hdrdir - hdrfile + 1; if (!strncmp (pixfile, hdrfile, lhdrdir)) { filename = pixfile + lhdrdir; strcpy (temp, "HDR$"); strcat (temp,filename); strcpy (pixfile, temp); } } if (pixfile[0] != '/' && pixfile[0] != 'H') { strcpy (temp, "HDR$"); strcat (temp,pixfile); strcpy (pixfile, temp); } } } if (imhver == 2) irafputc (pixfile, irafheader, IM2_PIXFILE, SZ_IM2PIXFILE); else irafputc2 (pixfile, irafheader, IM_PIXFILE, SZ_IMPIXFILE); hdel (fitsheader,"PIXFIL_1"); hdel (fitsheader,"PIXFIL_2"); hdel (fitsheader,"PIXFIL_3"); hdel (fitsheader,"PIXFIL_4"); } /* Replace header file name, if it is in the FITS header */ if (hgetm (fitsheader, "IMHFIL", SZ_IM2HDRFILE, pixfile)) { if (!strchr (pixfile,'/') && !strchr (pixfile,'$')) { strcpy (temp, "HDR$"); strcat (temp,pixfile); strcpy (pixfile, temp); } if (imhver == 2) irafputc (pixfile, irafheader, IM2_HDRFILE, SZ_IM2HDRFILE); else irafputc2 (pixfile, irafheader, IM_HDRFILE, SZ_IMHDRFILE); hdel (fitsheader, "IMHFIL_1"); hdel (fitsheader, "IMHFIL_2"); hdel (fitsheader, "IMHFIL_3"); hdel (fitsheader, "IMHFIL_4"); } /* Replace image title, if it is in the FITS header */ if (hgets (fitsheader, "OBJECT", SZ_IM2TITLE, title)) { if (imhver == 2) irafputc (title, irafheader, IM2_TITLE, SZ_IM2TITLE); else irafputc2 (title, irafheader, IM_TITLE, SZ_IMTITLE); hdel (fitsheader, "OBJECT"); } hgeti4 (fitsheader, "PIXOFF", &pixoff); hdel (fitsheader, "PIXOFF"); hdel (fitsheader, "PIXOFF"); hdel (fitsheader, "PIXSWAP"); hdel (fitsheader, "PIXSWAP"); hdel (fitsheader, "DATE-MOD"); hdel (fitsheader, "DATE-MOD"); fitsend = ksearch (fitsheader,"END"); /* Find length of FITS header */ fitsend = ksearch (fitsheader,"END"); nlfits = ((fitsend - fitsheader) / 80); /* Find new length of IRAF header */ if (imhver == 2) *nbiraf = LEN_IM2HDR + (81 * nlfits); else *nbiraf = LEN_IMHDR + (162 * nlfits); if (*nbiraf > nbhead) irafheader = realloc (irafheader, *nbiraf); /* Reset modification time */ mtime = lt2tsi (); irafputi4 (irafheader, imtime, mtime); /* Replace user portion of IRAF header with remaining FITS header */ if (imhver == 2) { iraf2u = irafheader + LEN_IM2HDR; iraf2p = iraf2u; for (fitsp = fitsheader; fitsp < fitsend; fitsp = fitsp + 80) { for (i = 0; i < 80; i++) *iraf2p++ = fitsp[i]; *iraf2p++ = 10; } *iraf2p++ = 0; *nbiraf = iraf2p - irafheader; hdrlength = 1 + *nbiraf / 2; } else { irafs = (short *)irafheader; irafu = irafs + (LEN_IMHDR / 2); irafp = irafu; for (fitsp = fitsheader; fitsp < fitsend; fitsp = fitsp + 80) { for (i = 0; i < 80; i++) *irafp++ = (short) fitsp[i]; *irafp++ = 10; } *irafp++ = 0; *irafp++ = 32; *nbiraf = 2 * (irafp - irafs); hdrlength = *nbiraf / 4; } /* Length of header file */ irafputi4 (irafheader, imhlen, hdrlength); /* Offset in .pix file to first pixel data hputi4 (fitsheader, "PIXOFF", pixoff); */ /* Return number of bytes in new IRAF header */ return (irafheader); } int irafgeti4 (irafheader, offset) char *irafheader; /* IRAF image header */ int offset; /* Number of bytes to skip before number */ { char *ctemp, *cheader; int temp; cheader = irafheader; ctemp = (char *) &temp; /* If header swap flag not set, set it now */ if (headswap < 0) { if (cheader[offset] > 0) headswap = 1; else headswap = 0; } if (machswap() != headswap) { ctemp[3] = cheader[offset]; ctemp[2] = cheader[offset+1]; ctemp[1] = cheader[offset+2]; ctemp[0] = cheader[offset+3]; } else { ctemp[0] = cheader[offset]; ctemp[1] = cheader[offset+1]; ctemp[2] = cheader[offset+2]; ctemp[3] = cheader[offset+3]; } return (temp); } float irafgetr4 (irafheader, offset) char *irafheader; /* IRAF image header */ int offset; /* Number of bytes to skip before number */ { char *ctemp, *cheader; float temp; cheader = irafheader; ctemp = (char *) &temp; /* If header swap flag not set, set it now */ if (headswap < 0) { if (cheader[offset] > 0) headswap = 1; else headswap = 0; } if (machswap() != headswap) { ctemp[3] = cheader[offset]; ctemp[2] = cheader[offset+1]; ctemp[1] = cheader[offset+2]; ctemp[0] = cheader[offset+3]; } else { ctemp[0] = cheader[offset]; ctemp[1] = cheader[offset+1]; ctemp[2] = cheader[offset+2]; ctemp[3] = cheader[offset+3]; } return (temp); } /* IRAFGETC2 -- Get character string from arbitrary part of v.1 IRAF header */ char * irafgetc2 (irafheader, offset, nc) char *irafheader; /* IRAF image header */ int offset; /* Number of bytes to skip before string */ int nc; /* Maximum number of characters in string */ { char *irafstring, *string; irafstring = irafgetc (irafheader, offset, 2*(nc+1)); string = iraf2str (irafstring, nc); free (irafstring); return (string); } /* IRAFGETC -- Get character string from arbitrary part of IRAF header */ char * irafgetc (irafheader, offset, nc) char *irafheader; /* IRAF image header */ int offset; /* Number of bytes to skip before string */ int nc; /* Maximum number of characters in string */ { char *ctemp, *cheader; int i; cheader = irafheader; ctemp = (char *) calloc (nc+1, 1); if (ctemp == NULL) { (void)fprintf(stderr, "IRAFGETC Cannot allocate %d-byte variable\n", nc+1); return (NULL); } for (i = 0; i < nc; i++) { ctemp[i] = cheader[offset+i]; if (ctemp[i] > 0 && ctemp[i] < 32) ctemp[i] = ' '; } return (ctemp); } /* Convert IRAF 2-byte/char string to 1-byte/char string */ char * iraf2str (irafstring, nchar) char *irafstring; /* IRAF 2-byte/character string */ int nchar; /* Number of characters in string */ { char *string; int i, j; /* Set swap flag according to position of nulls in 2-byte characters */ if (headswap < 0) { if (irafstring[0] != 0 && irafstring[1] == 0) headswap = 1; else if (irafstring[0] == 0 && irafstring[1] != 0) headswap = 0; else return (NULL); } string = (char *) calloc (nchar+1, 1); if (string == NULL) { (void)fprintf(stderr, "IRAF2STR Cannot allocate %d-byte variable\n", nchar+1); return (NULL); } /* Swap bytes, if requested */ if (headswap) j = 0; else j = 1; /* Convert appropriate byte of input to output character */ for (i = 0; i < nchar; i++) { string[i] = irafstring[j]; j = j + 2; } return (string); } /* IRAFPUTI4 -- Insert 4-byte integer into arbitrary part of IRAF header */ static void irafputi4 (irafheader, offset, inum) char *irafheader; /* IRAF image header */ int offset; /* Number of bytes to skip before number */ int inum; /* Number to put into header */ { char *cn, *chead; chead = irafheader; cn = (char *) &inum; if (headswap < 0) headswap = 0; if (headswap != machswap()) { chead[offset+3] = cn[0]; chead[offset+2] = cn[1]; chead[offset+1] = cn[2]; chead[offset] = cn[3]; } else { chead[offset] = cn[0]; chead[offset+1] = cn[1]; chead[offset+2] = cn[2]; chead[offset+3] = cn[3]; } return; } /* IRAFPUTR4 -- Insert 4-byte real number into arbitrary part of IRAF header */ static void irafputr4 (irafheader, offset, rnum) char *irafheader; /* IRAF image header */ int offset; /* Number of bytes to skip before number */ float rnum; /* Number to put into header */ { char *cn, *chead; chead = irafheader; cn = (char *) &rnum; if (headswap < 0) headswap = 0; if (headswap != machswap()) { chead[offset+3] = cn[0]; chead[offset+2] = cn[1]; chead[offset+1] = cn[2]; chead[offset] = cn[3]; } else { chead[offset] = cn[0]; chead[offset+1] = cn[1]; chead[offset+2] = cn[2]; chead[offset+3] = cn[3]; } return; } /* IRAFPUTC2 -- Insert character string into arbitrary part of v.1 IRAF header */ static void irafputc2 (string, irafheader, offset, nc) char *string; /* String to insert into header */ char *irafheader; /* IRAF image header */ int offset; /* Number of bytes to skip before string */ int nc; /* Maximum number of characters in string */ { char *irafstring; irafstring = (char *) calloc (2 * nc, 1); if (irafstring == NULL) { (void)fprintf(stderr, "IRAFPUTC2 Cannot allocate %d-byte variable\n", 2 * nc); } str2iraf (string, irafstring, nc); irafputc (irafstring, irafheader, offset, 2*nc); return; } /* IRAFPUTC -- Insert character string into arbitrary part of IRAF header */ static void irafputc (string, irafheader, offset, nc) char *string; /* String to insert into header */ char *irafheader; /* IRAF image header */ int offset; /* Number of bytes to skip before string */ int nc; /* Maximum number of characters in string */ { char *chead; int i; chead = irafheader; for (i = 0; i < nc; i++) chead[offset+i] = string[i]; return; } /* STR2IRAF -- Convert 1-byte/char string to IRAF 2-byte/char string */ static void str2iraf (string, irafstring, nchar) char *string; /* 1-byte/character string */ char *irafstring; /* IRAF 2-byte/character string */ int nchar; /* Maximum number of characters in IRAF string */ { int i, j, nc, nbytes; nc = strlen (string); /* Fill output string with zeroes */ nbytes = nchar * 2; for (i = 0; i < nbytes; i++) irafstring[i] = 0; /* If swapped, start with first byte of 2-byte characters */ if (headswap) j = 0; else j = 1; /* Move input characters to appropriate bytes of output */ for (i = 0; i < nchar; i++) { if (i > nc) irafstring[j] = 0; else irafstring[j] = string[i]; j = j + 2; } return; } /* IRAFSWAP -- Reverse bytes of any type of vector in place */ static void irafswap (bitpix, string, nbytes) int bitpix; /* Number of bits per pixel */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ char *string; /* Address of starting point of bytes to swap */ int nbytes; /* Number of bytes to swap */ { switch (bitpix) { case 16: if (nbytes < 2) return; irafswap2 (string,nbytes); break; case 32: if (nbytes < 4) return; irafswap4 (string,nbytes); break; case -16: if (nbytes < 2) return; irafswap2 (string,nbytes); break; case -32: if (nbytes < 4) return; irafswap4 (string,nbytes); break; case -64: if (nbytes < 8) return; irafswap8 (string,nbytes); break; } return; } /* IRAFSWAP2 -- Swap bytes in string in place */ static void irafswap2 (string,nbytes) char *string; /* Address of starting point of bytes to swap */ int nbytes; /* Number of bytes to swap */ { char *sbyte, temp, *slast; slast = string + nbytes; sbyte = string; while (sbyte < slast) { temp = sbyte[0]; sbyte[0] = sbyte[1]; sbyte[1] = temp; sbyte= sbyte + 2; } return; } /* IRAFSWAP4 -- Reverse bytes of Integer*4 or Real*4 vector in place */ static void irafswap4 (string,nbytes) char *string; /* Address of Integer*4 or Real*4 vector */ int nbytes; /* Number of bytes to reverse */ { char *sbyte, *slast; char temp0, temp1, temp2, temp3; slast = string + nbytes; sbyte = string; while (sbyte < slast) { temp3 = sbyte[0]; temp2 = sbyte[1]; temp1 = sbyte[2]; temp0 = sbyte[3]; sbyte[0] = temp0; sbyte[1] = temp1; sbyte[2] = temp2; sbyte[3] = temp3; sbyte = sbyte + 4; } return; } /* IRAFSWAP8 -- Reverse bytes of Real*8 vector in place */ static void irafswap8 (string,nbytes) char *string; /* Address of Real*8 vector */ int nbytes; /* Number of bytes to reverse */ { char *sbyte, *slast; char temp[8]; slast = string + nbytes; sbyte = string; while (sbyte < slast) { temp[7] = sbyte[0]; temp[6] = sbyte[1]; temp[5] = sbyte[2]; temp[4] = sbyte[3]; temp[3] = sbyte[4]; temp[2] = sbyte[5]; temp[1] = sbyte[6]; temp[0] = sbyte[7]; sbyte[0] = temp[0]; sbyte[1] = temp[1]; sbyte[2] = temp[2]; sbyte[3] = temp[3]; sbyte[4] = temp[4]; sbyte[5] = temp[5]; sbyte[6] = temp[6]; sbyte[7] = temp[7]; sbyte = sbyte + 8; } return; } /* Set flag if machine on which program is executing is not FITS byte order * ( i.e., if it is an Alpha or PC instead of a Sun ) */ static int machswap () { char *ctest; int itest; itest = 1; ctest = (char *)&itest; if (*ctest) return (1); else return (0); } /* ISIRAF -- return 1 if IRAF imh file, else 0 */ int isiraf (filename) char *filename; /* Name of file for which to find size */ { if (strchr (filename, '=')) return (0); else if (strsrch (filename, ".imh")) return (1); else return (0); } /* IRAFSIZE -- return size of file in bytes */ static int irafsize (diskfile) FILE *diskfile; /* Descriptor of file for which to find size */ { long filesize; long offset; offset = (long) 0; /* Move to end of the file */ if (fseek (diskfile, offset, SEEK_END) == 0) { /* Position is the size of the file */ filesize = ftell (diskfile); /* Move file pointer back tot he start of the file */ fseek (diskfile, offset, SEEK_SET); } else filesize = -1; return (filesize); } /* Feb 15 1996 New file * Apr 10 1996 Add more documentation * Apr 17 1996 Print error message on open failure * Jun 5 1996 Add byte swapping (reversal); use streams * Jun 10 1996 Make fixes after running lint * Jun 12 1996 Use IMSWAP subroutines instead of local ones * Jul 3 1996 Go back to using local IRAFSWAP subroutines * Jul 3 1996 Write to pixel file from FITS header * Jul 10 1996 Allocate all headers * Aug 13 1996 Add unistd.h to include list * Aug 26 1996 Allow 1-d images; fix comments; fix arguments after lint * Aug 26 1996 Add IRAF header lingth argument to IRAFWIMAGE and IRAFWHEAD * Aug 28 1996 Clean up code in IRAF2FITS * Aug 30 1996 Use write instead of fwrite * Sep 4 1996 Fix write mode bug * Oct 15 1996 Drop unused variables * Oct 17 1996 Minor fix after lint; cast arguments to STR2IRAF * * May 15 1997 Fix returned header length in IRAF2FITS * Dec 19 1997 Add IRAF version 2 .imh files * * Jan 2 1998 Allow uneven length of user parameter lines in IRAF headers * Jan 6 1998 Fix output of imh2 headers; allow newlines in imh1 headers * Jan 14 1998 Handle byte reversing correctly * Apr 17 1998 Add new IRAF data types unsigned char and unsigned short * Apr 30 1998 Fix error return if illegal data type after Allan Brighton * May 15 1998 Delete header keywords used for IRAF binary values * May 15 1998 Fix bug so FITS OBJECT is put into IRAF title * May 26 1998 Fix bug in fits2iraf keeping track of end of header * May 27 1998 Include fitsio.h instead of fitshead.h * Jun 4 1998 Write comments into header for converted IRAF binary values * Jun 4 1998 Pad FITS strings to 8 character minimum * Jul 24 1998 Write header file length to IRAF header file * Jul 27 1998 Print error messages to stderr for all failed malloc's * Jul 27 1998 Fix bug padding FITS header with spaces in iraf2fits * Jul 27 1998 Write modification time to IRAF header file * Aug 6 1998 Change fitsio.h to fitsfile.h; imhio.c to imhfile.c * Oct 1 1998 Set irafswap flag only once per file * Oct 5 1998 Add subroutines irafsize() and isiraf() * Nov 16 1998 Fix byte-swap checking * * Jan 27 1999 Read and write all of 3D image if one dimension is =1 * Jul 13 1999 Improve error messages; change irafsize() argument to fd * Sep 22 1999 Don't copy OBJECT keyword from .imh file; use binary title * Oct 14 1999 Set FITS header length * Oct 20 1999 Allocate 5000 extra bytes for IRAF header * Nov 2 1999 Fix getclocktime() to use only time.h subroutines * Nov 2 1999 Add modification date and time to FITS header in iraf2fits() * Nov 24 1999 Delete HEADSWAP, IMHVER, DATE-MOD from header before writing * Nov 29 1999 Delete PIXSWAP, IRAF-MIN, IRAF-MAX from header before writing * * Jan 13 2000 Fix bug which dropped characters in iraf2fits() * Feb 3 2000 Declare timezone long, not time_t; drop unused variable * Mar 7 2000 Add more code to keep pixel file path short * Mar 10 2000 Fix bugs when writing .imh file headers * Mar 21 2000 Change computation of IRAF time tags to use only data structure * Mar 22 2000 Move IRAF time tag computation to lt2tsi() in dateutil.c * Mar 24 2000 Use Unix file update time if none in header * Mar 27 2000 Use hputm() to save file paths up to 256 characters * Mar 27 2000 Write filename comments after 1st keyword with short value * Mar 27 2000 Allocate pixel file name in same_path to imh2 length * Mar 29 2000 Add space after last linefeed of header in fits2iraf() * Apr 28 2000 Dimension pixname in irafwimage() * May 1 2000 Fix code for updating pixel file name with HDR$ in fits2iraf() * Jun 2 2000 Drop unused variables in fits2iraf() after lint * Jun 12 2000 If pixel filename has no / or $, use same path as header file * Sep 6 2000 Use header directory if pixel file not found at its pathname * * Jan 11 2001 Print all messages to stderr * Aug 24 2001 In isiraf(), return 0 if argument contains an equal sign * * Apr 8 2002 Fix bug in error message for unidentified nbits in fits2iraf() * * Feb 4 2003 Open catalog file rb instead of r (Martin Ploner, Bern) * Oct 31 2003 Read image only in irafrimage() if physical dimension > image dim. * Nov 3 2003 Set NAXISi to image, not physical dimensions in iraf2fits() * * Jun 13 2005 Drop trailing spaces on pixel file name * * Jun 20 2006 Initialize uninitialized variables * * Jan 4 2007 Change hputr4() calls to send pointer to value * Jan 8 2007 Drop unused variable nbx in irafrimage() * Jan 8 2006 Align header and image buffers properly by 4 and by BITPIX */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/imio.c000066400000000000000000001107151215713201500213610ustar00rootroot00000000000000/*** File wcslib/imio.c *** June 11, 2007 *** By Doug Mink, dmink@cfa.harvard.edu *** Harvard-Smithsonian Center for Astrophysics *** Copyright (C) 1996-2007 *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Correspondence concerning WCSTools should be addressed as follows: Internet email: dmink@cfa.harvard.edu Postal address: Doug Mink Smithsonian Astrophysical Observatory 60 Garden St. Cambridge, MA 02138 USA * Module: imio.c (image pixel manipulation) * Purpose: Read and write pixels from arbitrary data type 2D arrays * Subroutine: getpix (image, bitpix, w, h, bz, bs, x, y) * Read pixel from 2D image of any numeric type (0,0 lower left) * Subroutine: getpix1 (image, bitpix, w, h, bz, bs, x, y) * Read pixel from 2D image of any numeric type (1,1 lower left) * Subroutine: putpix (image, bitpix, w, h, bz, bs, x, y, dpix) * Write pixel into 2D image of any numeric type (0,0 lower left) * Subroutine: putpix1 (image, bitpix, w, h, bz, bs, x, y, dpix) * Write pixel into 2D image of any numeric type (1,1 lower left) * Subroutine: addpix (image, bitpix, w, h, bz, bs, x, y, dpix) * Copy pixel into 2D image of any numeric type (0,0 lower left) * Subroutine: addpix1 (image, bitpix, w, h, bz, bs, x, y, dpix) * Add pixel into 2D image of any numeric type (1,1 lower left) * Subroutine: maxvec (image, bitpix, bz, bs, pix1, npix) * Get maximum of vector from 2D image of any numeric type * Subroutine: minvec (image, bitpix, bz, bs, pix1, npix) * Get minimum of vector from 2D image of any numeric type * Subroutine: getvec (image, bitpix, bz, bs, pix1, npix, dvec) * Get vector from 2D image of any numeric type * Subroutine: putvec (image, bitpix, bz, bs, pix1, npix, dvec) * Copy pixel vector into a vector of any numeric type * Subroutine: addvec (image, bitpix, bz, bs, pix1, npix, dpix) * Add constant to pixel values in a vector * Subroutine: multvec (image, bitpix, bz, bs, pix1, npix, dpix) * Multiply pixel values in a vector by a constant * Subroutine: fillvec (image, bitpix, bz, bs, pix1, npix, dpix) * Copy pixel value in a vector of any numeric type * Subroutine: fillvec1 (image, bitpix, bz, bs, pix1, npix, dpix) * Copy pixel value int a vector of any numeric type * Subroutine: movepix (image1, bitpix, w1, x1, y1, image2, w2, x2, y2) * Copy pixel from one image location to another * Subroutine: imswap (bitpix,string,nbytes) * Swap bytes in string in place, with FITS bits/pixel code * Subroutine: imswap2 (string,nbytes) * Swap bytes in string in place * Subroutine imswap4 (string,nbytes) * Reverse bytes of Integer*4 or Real*4 vector in place * Subroutine imswap8 (string,nbytes) * Reverse bytes of Real*8 vector in place * Subroutine imswapped () * Return 1 if PC/DEC byte order, else 0 */ #include #include #include "fitsfile.h" static int scale = 1; /* If 0, skip scaling step */ void setscale (scale0) int scale0; {scale = scale0; return;} /* GETPIX1 -- Get pixel from 2D FITS image of any numeric type */ double getpix1 (image, bitpix, w, h, bzero, bscale, x, y) char *image; /* Image array as 1-D vector */ int bitpix; /* FITS bits per pixel */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ int w; /* Image width in pixels */ int h; /* Image height in pixels */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int x; /* One-based horizontal pixel number */ int y; /* One-based vertical pixel number */ { return (getpix (image, bitpix, w, h, bzero, bscale, x-1, y-1)); } /* GETPIX -- Get pixel from 2D image of any numeric type */ double getpix (image, bitpix, w, h, bzero, bscale, x, y) char *image; /* Image array as 1-D vector */ int bitpix; /* FITS bits per pixel */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ int w; /* Image width in pixels */ int h; /* Image height in pixels */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int x; /* Zero-based horizontal pixel number */ int y; /* Zero-based vertical pixel number */ { short *im2; int *im4; unsigned short *imu; float *imr; double *imd; double dpix; /* Return 0 if coordinates are not inside image */ if (x < 0 || x >= w) return (0.0); if (y < 0 || y >= h) return (0.0); /* Extract pixel from appropriate type of array */ switch (bitpix) { case 8: dpix = (double) image[(y*w) + x]; break; case 16: im2 = (short *)image; dpix = (double) im2[(y*w) + x]; break; case 32: im4 = (int *)image; dpix = (double) im4[(y*w) + x]; break; case -16: imu = (unsigned short *)image; dpix = (double) imu[(y*w) + x]; break; case -32: imr = (float *)image; dpix = (double) imr[(y*w) + x]; break; case -64: imd = (double *)image; dpix = imd[(y*w) + x]; break; default: dpix = 0.0; } if (scale) return (bzero + (bscale * dpix)); else return (dpix); } /* PUTPIX1 -- Copy pixel into 2D FITS image of any numeric type */ void putpix1 (image, bitpix, w, h, bzero, bscale, x, y, dpix) char *image; int bitpix; /* Number of bits per pixel */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ int w; /* Image width in pixels */ int h; /* Image height in pixels */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int x; /* One-based horizontal pixel number */ int y; /* One-based vertical pixel number */ double dpix; { putpix (image, bitpix, w, h, bzero, bscale, x-1, y-1, dpix); return; } /* PUTPIX -- Copy pixel into 2D image of any numeric type */ void putpix (image, bitpix, w, h, bzero, bscale, x, y, dpix) char *image; int bitpix; /* Number of bits per pixel */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ int w; /* Image width in pixels */ int h; /* Image height in pixels */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int x; int y; double dpix; { short *im2; int *im4; unsigned short *imu; float *imr; double *imd; /* Return if coordinates are not inside image */ if (x < 0 || x >= w) return; if (y < 0 || y >= h) return; if (scale) dpix = (dpix - bzero) / bscale; switch (bitpix) { case 8: if (dpix < 0) image[(y*w) + x] = (char) (dpix - 0.5); else image[(y*w) + x] = (char) (dpix + 0.5); break; case 16: im2 = (short *)image; if (dpix < 0) im2[(y*w) + x] = (short) (dpix - 0.5); else im2[(y*w) + x] = (short) (dpix + 0.5); break; case 32: im4 = (int *)image; if (dpix < 0) im4[(y*w) + x] = (int) (dpix - 0.5); else im4[(y*w) + x] = (int) (dpix + 0.5); break; case -16: imu = (unsigned short *)image; if (dpix < 0) imu[(y*w) + x] = (unsigned short) 0; else imu[(y*w) + x] = (unsigned short) (dpix + 0.5); break; case -32: imr = (float *)image; imr[(y*w) + x] = (float) dpix; break; case -64: imd = (double *)image; imd[(y*w) + x] = dpix; break; } return; } /* ADDPIX1 -- Add pixel value into 2D FITS image of any numeric type */ void addpix1 (image, bitpix, w, h, bzero, bscale, x, y, dpix) char *image; int bitpix; /* Number of bits per pixel */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ int w; /* Image width in pixels */ int h; /* Image height in pixels */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int x; /* One-based horizontal pixel number */ int y; /* One-based vertical pixel number */ double dpix; /* Value to add to pixel */ { addpix (image, bitpix, w, h, bzero, bscale, x-1, y-1, dpix); return; } /* ADDPIX -- Add constant to pixel values in 2D image of any numeric type */ void addpix (image, bitpix, w, h, bzero, bscale, x, y, dpix) char *image; int bitpix; /* Number of bits per pixel */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ int w; /* Image width in pixels */ int h; /* Image height in pixels */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int x; /* Zero-based horizontal pixel number */ int y; /* Zero-based vertical pixel number */ double dpix; /* Value to add to pixel */ { short *im2; int *im4; unsigned short *imu; float *imr; double *imd; int ipix; /* Return if coordinates are not inside image */ if (x < 0 || x >= w) return; if (y < 0 || y >= h) return; if (scale) dpix = (dpix - bzero) / bscale; ipix = (y * w) + x; switch (bitpix) { case 8: if (dpix < 0) image[ipix] = image[ipix] + (char) (dpix - 0.5); else image[ipix] = image[ipix] + (char) (dpix + 0.5); break; case 16: im2 = (short *)image; if (dpix < 0) im2[ipix] = im2[ipix] + (short) (dpix - 0.5); else im2[ipix] = im2[ipix] + (short) (dpix + 0.5); break; case 32: im4 = (int *)image; if (dpix < 0) im4[ipix] = im4[ipix] + (int) (dpix - 0.5); else im4[ipix] = im4[ipix] + (int) (dpix + 0.5); break; case -16: imu = (unsigned short *)image; if (dpix > 0) imu[ipix] = imu[ipix] + (unsigned short) (dpix + 0.5); break; case -32: imr = (float *)image; imr[ipix] = imr[ipix] + (float) dpix; break; case -64: imd = (double *)image; imd[ipix] = imd[ipix] + dpix; break; } return; } /* MOVEPIX -- Copy pixel between images */ void movepix (image1, bitpix1, w1, x1, y1, image2, bitpix2, w2, x2, y2) char *image1; /* Pointer to first pixel in input image */ int bitpix1; /* Bits per input pixel (FITS codes) */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ int w1; /* Number of horizontal pixels in input image */ int x1, y1; /* Row and column for input pixel */ char *image2; /* Pointer to first pixel in output image */ int bitpix2; /* Bits per output pixel (FITS codes) */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ int w2; /* Number of horizontal pixels in output image */ int x2, y2; /* Row and column for output pixel */ { short *ims1, *ims2; int *imi1, *imi2; unsigned short *imu1, *imu2; float rpix, *imr1, *imr2; double dpix, *imd1, *imd2; if (x1 < 0 || x2 < 0 || x1 >= w1 || x2 >= w2) return; if (y1 < 0 || y2 < 0) return; switch (bitpix1) { case 8: switch (bitpix2) { case 8: image2[(y2*w2) + x2] = image1[(y1*w1) + x1]; break; case 16: ims2 = (short *)image2; ims2[(y2*w2) + x2] = image1[(y1*w1) + x1]; break; case 32: imi2 = (int *)image2; imi2[(y2*w2) + x2] = (int) image1[(y1*w1) + x1]; break; case -16: imu2 = (unsigned short *)image2; imu2[(y2*w2) + x2] = (unsigned short) image1[(y1*w1) + x1]; break; case -32: imr2 = (float *)image2; imr2[(y2*w2) + x2] = (float) image1[(y1*w1) + x1]; break; case -64: imd2 = (double *)image2; imd2[(y2*w2) + x2] = (double) image1[(y1*w1) + x1]; break; } break; case 16: switch (bitpix2) { case 8: ims1 = (short *)image1; image2[(y2*w2) + x2] = (char) ims1[(y1*w1) + x1]; break; case 16: ims1 = (short *)image1; ims2 = (short *)image2; ims2[(y2*w2) + x2] = ims1[(y1*w1) + x1]; break; case 32: ims1 = (short *)image1; imi2 = (int *)image2; imi2[(y2*w2) + x2] = (int) ims1[(y1*w1) + x1]; break; case -16: ims1 = (short *)image1; imu2 = (unsigned short *)image2; imu2[(y2*w2) + x2] = (unsigned short) ims1[(y1*w1) + x1]; break; case -32: ims1 = (short *)image1; imr2 = (float *)image2; imr2[(y2*w2) + x2] = (float) ims1[(y1*w1) + x1]; break; case -64: ims1 = (short *)image1; imd2 = (double *)image2; imd2[(y2*w2) + x2] = (double) ims1[(y1*w1) + x1]; break; } break; case 32: switch (bitpix2) { case 8: imi1 = (int *)image1; image2[(y2*w2) + x2] = (char) imi1[(y1*w1) + x1]; break; case 16: imi1 = (int *)image1; ims2 = (short *)image2; ims2[(y2*w2) + x2] = (short) imi1[(y1*w1) + x1]; break; case 32: imi1 = (int *)image1; imi2 = (int *)image2; imi2[(y2*w2) + x2] = imi1[(y1*w1) + x1]; break; case -16: imi1 = (int *)image1; imu2 = (unsigned short *)image2; imu2[(y2*w2) + x2] = (unsigned short) imi1[(y1*w1) + x1]; break; case -32: imi1 = (int *)image1; imr2 = (float *)image2; imr2[(y2*w2) + x2] = (float) imi1[(y1*w1) + x1]; break; case -64: imi1 = (int *)image1; imd2 = (double *)image2; imd2[(y2*w2) + x2] = (double) imi1[(y1*w1) + x1]; break; } break; case -16: switch (bitpix2) { case 8: imu1 = (unsigned short *)image1; image2[(y2*w2) + x2] = (char) imu1[(y1*w1) + x1]; break; case 16: imu1 = (unsigned short *)image1; ims2 = (short *)image2; ims2[(y2*w2) + x2] = (short) imu1[(y1*w1) + x1]; break; case 32: imu1 = (unsigned short *)image1; imi2 = (int *)image2; imi2[(y2*w2) + x2] = (int) imu1[(y1*w1) + x1]; break; case -16: imu1 = (unsigned short *)image1; imu2 = (unsigned short *)image2; imu2[(y2*w2) + x2] = imu1[(y1*w1) + x1]; break; case -32: imu1 = (unsigned short *)image1; imr2 = (float *)image2; imr2[(y2*w2) + x2] = (float) imu1[(y1*w1) + x1]; break; case -64: imu1 = (unsigned short *)image1; imd2 = (double *)image2; imd2[(y2*w2) + x2] = (double) imu1[(y1*w1) + x1]; break; } break; case -32: imr1 = (float *)image1; rpix = imr1[(y1*w1) + x1]; switch (bitpix2) { case 8: if (rpix < 0.0) image2[(y2*w2) + x2] = (char) (rpix - 0.5); else image2[(y2*w2) + x2] = (char) (rpix + 0.5); break; case 16: ims2 = (short *)image2; if (rpix < 0.0) ims2[(y2*w2) + x2] = (short) (rpix - 0.5); else ims2[(y2*w2) + x2] = (short) (rpix + 0.5); break; case 32: imi2 = (int *)image2; if (rpix < 0.0) imi2[(y2*w2) + x2] = (int) (rpix - 0.5); else imi2[(y2*w2) + x2] = (int) (rpix + 0.5); break; case -16: imu2 = (unsigned short *)image2; if (rpix < 0.0) imu2[(y2*w2) + x2] = (unsigned short) 0; else imu2[(y2*w2) + x2] = (unsigned short) (rpix + 0.5); break; case -32: imr2 = (float *)image2; imr2[(y2*w2) + x2] = rpix; break; case -64: imd2 = (double *)image2; imd2[(y2*w2) + x2] = (double) rpix; break; } break; case -64: imd1 = (double *)image1; dpix = imd1[(y1*w1) + x1]; switch (bitpix2) { case 8: imd1 = (double *)image1; if (dpix < 0.0) image2[(y2*w2) + x2] = (char) (dpix - 0.5); else image2[(y2*w2) + x2] = (char) (dpix + 0.5); break; case 16: ims2 = (short *)image2; if (dpix < 0.0) ims2[(y2*w2) + x2] = (short) (dpix - 0.5); else ims2[(y2*w2) + x2] = (short) (dpix + 0.5); break; case 32: imi2 = (int *)image2; if (dpix < 0.0) imi2[(y2*w2) + x2] = (int) (dpix - 0.5); else imi2[(y2*w2) + x2] = (int) (dpix + 0.5); break; case -16: imu2 = (unsigned short *)image2; if (dpix < 0.0) imu2[(y2*w2) + x2] = (unsigned short) 0; else imu2[(y2*w2) + x2] = (unsigned short) (dpix + 0.5); break; case -32: imr2 = (float *)image2; imr2[(y2*w2) + x2] = (float) dpix; break; case -64: imd2 = (double *)image2; imd2[(y2*w2) + x2] = dpix; break; } break; } return; } /* MAXVEC -- Get maximum value in vector from 2D image of any numeric type */ double maxvec (image, bitpix, bzero, bscale, pix1, npix) char *image; /* Image array from which to read vector */ int bitpix; /* Number of bits per pixel in image */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int pix1; /* Offset of first pixel to check */ int npix; /* Number of pixels to check */ { short *im2, imax2, ip2; int *im4, imax4, ip4; unsigned short *imu, imaxu, ipu; float *imr, imaxr, ipr; double *imd; double dmax = 0.0; double ipd; int ipix, pix2; char imaxc, ipc; pix2 = pix1 + npix; switch (bitpix) { case 8: imaxc = *(image + pix1); for (ipix = pix1; ipix < pix2; ipix++) { ipc = *(image + ipix); if (ipc > imaxc) imaxc = ipc; } dmax = (double) imaxc; break; case 16: im2 = (short *)image; imax2 = *(im2 + pix1); for (ipix = pix1; ipix < pix2; ipix++) { ip2 = *(im2 + ipix); if (ip2 > imax2) imax2 = ip2; } dmax = (double) imax2; break; case 32: im4 = (int *)image; imax4 = *(im4 + pix1); for (ipix = pix1; ipix < pix2; ipix++) { ip4 = *(im4 + ipix); if (ip4 > imax4) imax4 = ip4; } dmax = (double) imax4; break; case -16: imu = (unsigned short *)image; imaxu = *(imu + pix1); for (ipix = pix1; ipix < pix2; ipix++) { ipu = *(imu + ipix); if (ipu > imaxu) imaxu = ipu; } dmax = (double) imaxu; break; case -32: imr = (float *)image; imaxr = *(imr + pix1); for (ipix = pix1; ipix < pix2; ipix++) { ipr = *(imr + ipix); if (ipr > imaxr) imax2 = ipr; } dmax = (double) imaxr; break; case -64: imd = (double *)image; dmax = *(imd + pix1); for (ipix = pix1; ipix < pix2; ipix++) { ipd = *(imd + ipix); if (ipd > dmax) dmax = ipd; } break; } /* Scale data if either BZERO or BSCALE keyword has been set */ if (scale && (bzero != 0.0 || bscale != 1.0)) dmax = (dmax * bscale) + bzero; return (dmax); } /* MINVEC -- Get minimum value in vector from 2D image of any numeric type */ double minvec (image, bitpix, bzero, bscale, pix1, npix) char *image; /* Image array from which to read vector */ int bitpix; /* Number of bits per pixel in image */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int pix1; /* Offset of first pixel to check */ int npix; /* Number of pixels to check */ { short *im2, imin2, *ip2, *il2; int *im4, imin4, ip4; unsigned short *imu, iminu, ipu; float *imr, iminr, ipr; double *imd, ipd; double dmin = 0.0; int ipix, pix2; char cmin, cp; pix2 = pix1 + npix; switch (bitpix) { case 8: cmin = *(image + pix1); for (ipix = pix1; ipix < pix2; ipix++) { cp = *(image + ipix); if (cp < cmin) cmin = cp; } dmin = (double) cmin; break; case 16: im2 = (short *)image + pix1; imin2 = *im2; il2 = im2 + npix; ip2 = im2; while (ip2 < il2) { if (*ip2 < imin2) imin2 = *ip2; ip2++; } dmin = (double) imin2; break; case 32: im4 = (int *)image; imin4 = *(im4 + pix1); for (ipix = pix1; ipix < pix2; ipix++) { ip4 = *(im4 + ipix); if (ip4 < imin4) imin4 = ip4; } dmin = (double) imin4; break; case -16: imu = (unsigned short *)image; iminu = *(imu + pix1); for (ipix = pix1; ipix < pix2; ipix++) { ipu = *(imu + ipix); if (ipu < iminu) iminu = ipu; } dmin = (double) iminu; break; case -32: imr = (float *)image; iminr = *(imr + pix1); for (ipix = pix1; ipix < pix2; ipix++) { ipr = *(imr + ipix); if (ipr < iminr) iminr = ipr; } dmin = (double) iminr; break; case -64: imd = (double *)image; dmin = *(imd + pix1); for (ipix = pix1; ipix < pix2; ipix++) { ipd = *(imd + ipix); if (ipd < dmin) dmin = ipd; } break; } /* Scale data if either BZERO or BSCALE keyword has been set */ if (scale && (bzero != 0.0 || bscale != 1.0)) dmin = (dmin * bscale) + bzero; return (dmin); } /* ADDVEC -- Add constant to pixel values in 2D image of any numeric type */ void addvec (image, bitpix, bzero, bscale, pix1, npix, dpix) char *image; /* Image array from which to extract vector */ int bitpix; /* Number of bits per pixel in image */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int pix1; /* Offset of first pixel to extract */ int npix; /* Number of pixels to extract */ double dpix; /* Value to add to pixels */ { char *imc, ccon; short *im2, jcon; int *im4, icon; unsigned short *imu, ucon; float *imr, rcon; double *imd; int ipix, pix2; pix2 = pix1 + npix; if (scale) dpix = (dpix - bzero) / bscale; switch (bitpix) { case 8: imc = image + pix1; if (dpix < 0) ccon = (char) (dpix - 0.5); else ccon = (char) (dpix + 0.5); for (ipix = pix1; ipix < pix2; ipix++) *imc++ += ccon; break; case 16: im2 = (short *) (image + pix1); if (dpix < 0) jcon = (short) (dpix - 0.5); else jcon = (short) (dpix + 0.5); for (ipix = pix1; ipix < pix2; ipix++) *im2++ += jcon; break; case 32: im4 = (int *) (image + pix1); if (dpix < 0) icon = (int) (dpix - 0.5); else icon = (int) (dpix + 0.5); for (ipix = pix1; ipix < pix2; ipix++) *im4++ += icon; break; case -16: imu = (unsigned short *) (image + pix1); if (dpix > 0) { ucon = (unsigned short) (dpix + 0.5); imu = (unsigned short *) (image + pix1); for (ipix = pix1; ipix < pix2; ipix++) *imu++ += ucon; } else { icon = (int) (dpix - 0.5); imu = (unsigned short *) (image + pix1); for (ipix = pix1; ipix < pix2; ipix++) { unsigned short tmp = (icon + (int) *imu); *imu++ += tmp; } } break; case -32: rcon = (float) dpix; imr = (float *) (image + pix1); for (ipix = pix1; ipix < pix2; ipix++) *imr++ += rcon; break; case -64: imd = (double *) (image + pix1); for (ipix = pix1; ipix < pix2; ipix++) *imd++ += dpix; break; } return; } /* MULTVEC -- Multiply pixel values in place in 2D image of any numeric type */ void multvec (image, bitpix, bzero, bscale, pix1, npix, dpix) char *image; /* Image array from which to extract vector */ int bitpix; /* Number of bits per pixel in image */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int pix1; /* Offset of first pixel to extract */ int npix; /* Number of pixels to extract */ double dpix; /* Value by which to multiply pixels */ { char *imc, ccon; short *im2, jcon; int *im4, icon, isint; unsigned short *imu, ucon; float *imr, rcon; double *imd, dcon, dval; int ipix, pix2; pix2 = pix1 + npix; if (scale) dpix = (dpix - bzero) / bscale; ipix = (int) dpix; dcon = (double) ipix; if (dcon == dpix) isint = 1; else isint = 0; switch (bitpix) { case 8: imc = image + pix1; if (isint) { if (dpix < 0) ccon = (char) (dpix - 0.5); else ccon = (char) (dpix + 0.5); for (ipix = pix1; ipix < pix2; ipix++) *imc++ *= ccon; } else { for (ipix = pix1; ipix < pix2; ipix++) { dval = ((double) *imc) * dpix; if (dval < 256.0) *imc++ = (char) dval; else *imc++ = (char) 255; } } break; case 16: im2 = (short *) (image + pix1); if (isint) { im2 = (short *)image; if (dpix < 0) jcon = (short) (dpix - 0.5); else jcon = (short) (dpix + 0.5); for (ipix = pix1; ipix < pix2; ipix++) *im2++ *= jcon; } else { for (ipix = pix1; ipix < pix2; ipix++) { dval = ((double) *im2) * dpix; if (dval < 32768.0) *im2++ = (short) dval; else *im2++ = (short) 32767; } } break; case 32: im4 = (int *) (image + pix1); if (isint) { if (dpix < 0) icon = (int) (dpix - 0.5); else icon = (int) (dpix + 0.5); for (ipix = pix1; ipix < pix2; ipix++) *im4++ *= icon; } else { for (ipix = pix1; ipix < pix2; ipix++) { dval = ((double) *im4) * dpix; if (dval < 32768.0) *im4++ = (int) dval; else *im4++ = (int) 32767; } } break; case -16: imu = (unsigned short *) (image + pix1); if (dpix > 0) { ucon = (unsigned short) (dpix + 0.5); imu = (unsigned short *) (image + pix1); for (ipix = pix1; ipix < pix2; ipix++) *imu++ *= ucon; } break; case -32: rcon = (float) dpix; imr = (float *) (image + pix1); for (ipix = pix1; ipix < pix2; ipix++) *imr++ *= rcon; break; case -64: imd = (double *) (image + pix1); for (ipix = pix1; ipix < pix2; ipix++) *imd++ *= dpix; break; } return; } /* GETVEC -- Get vector from 2D image of any numeric type */ void getvec (image, bitpix, bzero, bscale, pix1, npix, dvec0) char *image; /* Image array from which to extract vector */ int bitpix; /* Number of bits per pixel in image */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int pix1; /* Offset of first pixel to extract */ int npix; /* Number of pixels to extract */ double *dvec0; /* Vector of pixels (returned) */ { short *im2; int *im4; unsigned short *imu; float *imr; double *imd; double *dvec; int ipix, pix2; pix2 = pix1 + npix; dvec = dvec0; switch (bitpix) { case 8: for (ipix = pix1; ipix < pix2; ipix++) *dvec++ = (double) *(image + ipix); break; case 16: im2 = (short *)image; for (ipix = pix1; ipix < pix2; ipix++) *dvec++ = (double) *(im2 + ipix); break; case 32: im4 = (int *)image; for (ipix = pix1; ipix < pix2; ipix++) *dvec++ = (double) *(im4 + ipix); break; case -16: imu = (unsigned short *)image; for (ipix = pix1; ipix < pix2; ipix++) *dvec++ = (double) *(imu + ipix); break; case -32: imr = (float *)image; for (ipix = pix1; ipix < pix2; ipix++) *dvec++ = (double) *(imr + ipix); break; case -64: imd = (double *)image; for (ipix = pix1; ipix < pix2; ipix++) *dvec++ = (double) *(imd + ipix); break; } /* Scale data if either BZERO or BSCALE keyword has been set */ if (scale && (bzero != 0.0 || bscale != 1.0)) { dvec = dvec0; for (ipix = pix1; ipix < pix2; ipix++) { *dvec = (*dvec * bscale) + bzero; dvec++; } } return; } /* PUTVEC -- Copy pixel vector into 2D image of any numeric type */ void putvec (image, bitpix, bzero, bscale, pix1, npix, dvec) char *image; /* Image into which to copy vector */ int bitpix; /* Number of bits per pixel im image */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int pix1; /* Offset of first pixel of vector in image */ int npix; /* Number of pixels to copy */ double *dvec; /* Vector of pixels to copy */ { short *im2; int *im4; unsigned short *imu; float *imr; double *imd; int ipix, pix2; double *dp = dvec; pix2 = pix1 + npix; /* Scale data if either BZERO or BSCALE keyword has been set */ if (scale && (bzero != 0.0 || bscale != 1.0)) { for (ipix = pix1; ipix < pix2; ipix++) { *dp = (*dp - bzero) / bscale; dp++; } dp = dvec; } switch (bitpix) { case 8: for (ipix = pix1; ipix < pix2; ipix++) *(image+ipix) = (char) *dp++; break; case 16: im2 = (short *)image; for (ipix = pix1; ipix < pix2; ipix++) { if (*dp < 0.0) *(im2+ipix) = (short) (*dp++ - 0.5); else *(im2+ipix) = (short) (*dp++ + 0.5); } break; case 32: im4 = (int *)image; for (ipix = pix1; ipix < pix2; ipix++) { if (*dp < 0.0) *(im4+ipix) = (int) (*dp++ - 0.5); else *(im4+ipix) = (int) (*dp++ + 0.5); } break; case -16: imu = (unsigned short *)image; for (ipix = pix1; ipix < pix2; ipix++) { if (*dp < 0.0) *(imu+ipix) = (unsigned short) 0; else *(imu+ipix) = (unsigned short) (*dp++ + 0.5); } break; case -32: imr = (float *)image; for (ipix = pix1; ipix < pix2; ipix++) *(imr+ipix) = (float) *dp++; break; case -64: imd = (double *)image; for (ipix = pix1; ipix < pix2; ipix++) *(imd+ipix) = (double) *dp++; break; } return; } /* FILLVEC1 -- Copy single value into a vector of any numeric type */ void fillvec1 (image, bitpix, bzero, bscale, pix1, npix, dpix) char *image; /* Vector to fill */ int bitpix; /* Number of bits per pixel im image */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int pix1; /* First pixel to fill */ int npix; /* Number of pixels to fill */ double dpix; /* Value with which to fill pixels */ { fillvec (image, bitpix, bzero, bscale, pix1-1, npix, dpix); return; } /* FILLVEC -- Copy single value into a vector of any numeric type */ void fillvec (image, bitpix, bzero, bscale, pix1, npix, dpix) char *image; /* Vector to fill */ int bitpix; /* Number of bits per pixel im image */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int pix1; /* First pixel to fill */ int npix; /* Number of pixels to fill */ double dpix; /* Value with which to fill pixels */ { char ipc; short *im2, ip2; int *im4, ip4; unsigned short *imu, ipu; float *imr, ipr; double *imd; int ipix, pix2; double dp; pix2 = pix1 + npix; /* Scale data if either BZERO or BSCALE keyword has been set */ dp = dpix; if (scale && (bzero != 0.0 || bscale != 1.0)) dp = (dp - bzero) / bscale; switch (bitpix) { case 8: if (dp < 0.0) ipc = (char) (dp - 0.5); else ipc = (char) (dp + 0.5); for (ipix = pix1; ipix < pix2; ipix++) image[ipix] = ipc; break; case 16: im2 = (short *)image; if (dp < 0.0) ip2 = (short) (dp - 0.5); else ip2 = (short) (dp + 0.5); for (ipix = pix1; ipix < pix2; ipix++) im2[ipix] = ip2; break; case 32: im4 = (int *)image; if (dp < 0.0) ip4 = (int) (dp - 0.5); else ip4 = (int) (dp + 0.5); for (ipix = pix1; ipix < pix2; ipix++) im4[ipix] = ip4; break; case -16: imu = (unsigned short *)image; if (dp < 0.0) ipu = (unsigned short) (dp - 0.5); else ipu = (unsigned short) (dp + 0.5); for (ipix = pix1; ipix < pix2; ipix++) imu[ipix] = ipu; break; case -32: imr = (float *)image; ipr = (float) dp; for (ipix = pix1; ipix < pix2; ipix++) imr[ipix] = ipr; break; case -64: imd = (double *)image; for (ipix = pix1; ipix < pix2; ipix++) imd[ipix] = dp; break; } return; } /* IMSWAP -- Reverse bytes of any type of vector in place */ void imswap (bitpix, string, nbytes) int bitpix; /* Number of bits per pixel */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ char *string; /* Address of starting point of bytes to swap */ int nbytes; /* Number of bytes to swap */ { switch (bitpix) { case 8: break; case 16: if (nbytes < 2) return; imswap2 (string,nbytes); break; case 32: if (nbytes < 4) return; imswap4 (string,nbytes); break; case -16: if (nbytes < 2) return; imswap2 (string,nbytes); break; case -32: if (nbytes < 4) return; imswap4 (string,nbytes); break; case -64: if (nbytes < 8) return; imswap8 (string,nbytes); break; } return; } /* IMSWAP2 -- Swap bytes in string in place */ void imswap2 (string,nbytes) char *string; /* Address of starting point of bytes to swap */ int nbytes; /* Number of bytes to swap */ { char *sbyte, temp, *slast; slast = string + nbytes; sbyte = string; while (sbyte < slast) { temp = sbyte[0]; sbyte[0] = sbyte[1]; sbyte[1] = temp; sbyte= sbyte + 2; } return; } /* IMSWAP4 -- Reverse bytes of Integer*4 or Real*4 vector in place */ void imswap4 (string,nbytes) char *string; /* Address of Integer*4 or Real*4 vector */ int nbytes; /* Number of bytes to reverse */ { char *sbyte, *slast; char temp0, temp1, temp2, temp3; slast = string + nbytes; sbyte = string; while (sbyte < slast) { temp3 = sbyte[0]; temp2 = sbyte[1]; temp1 = sbyte[2]; temp0 = sbyte[3]; sbyte[0] = temp0; sbyte[1] = temp1; sbyte[2] = temp2; sbyte[3] = temp3; sbyte = sbyte + 4; } return; } /* IMSWAP8 -- Reverse bytes of Real*8 vector in place */ void imswap8 (string,nbytes) char *string; /* Address of Real*8 vector */ int nbytes; /* Number of bytes to reverse */ { char *sbyte, *slast; char temp[8]; slast = string + nbytes; sbyte = string; while (sbyte < slast) { temp[7] = sbyte[0]; temp[6] = sbyte[1]; temp[5] = sbyte[2]; temp[4] = sbyte[3]; temp[3] = sbyte[4]; temp[2] = sbyte[5]; temp[1] = sbyte[6]; temp[0] = sbyte[7]; sbyte[0] = temp[0]; sbyte[1] = temp[1]; sbyte[2] = temp[2]; sbyte[3] = temp[3]; sbyte[4] = temp[4]; sbyte[5] = temp[5]; sbyte[6] = temp[6]; sbyte[7] = temp[7]; sbyte = sbyte + 8; } return; } /* IMSWAPPED -- Returns 0 if big-endian (Sun,Mac), 1 if little-endian(PC,Alpha) */ int imswapped () { char *ctest; int itest; itest = 1; ctest = (char *)&itest; if (*ctest) return (1); else return (0); } /* Apr 17 1996 New file * May 22 1996 Add H so that PUTPIX and GETPIX can check coordinates * Jun 11 1996 Simplify NEWIMAGE subroutine * Jun 12 1996 Add byte-swapping subroutines * * Jul 24 1997 Add 8-bit option to subroutines * * May 27 1998 Include imio.h instead of fitshead.h * Jun 17 1998 Fix bug, changing all unsigned int's to unsigned short's * * Apr 29 1999 Add scaling to getpix, putpix, getvec, and putvec * Apr 29 1999 Fix bug in getvec in dealing with 1-byte data * Sep 14 1999 Change dp incrementing so it works on Alpha compiler * Sep 27 1999 Add interface for 1-based (FITS) image access * Sep 27 1999 Add addpix() and addpix1() * Dec 14 1999 In putpix(), addpix(), putvec(), round when output is integer * * Sep 20 2000 In getvec(), scale only if necessary * * Nov 27 2001 In movepix(), add char to char move * * Jan 23 2002 Add global scale switch to turn off scaling * Jun 4 2002 In getvec() and putvec(), change dpix to dvec * Jun 4 2002 Add addvec() to add to a vector * Jul 19 2002 Fix getvec() bug rescaling scaled numbers * * May 20 2003 Declare scale0 in setscale() * * Jan 28 2004 Add image limit check to movepix() * Feb 27 2004 Add fillvec() and fillvec1() to set vector to a constant * * Jun 27 2005 Fix major bug in fillvec(); pass value dpix in fillvec1(), too * Aug 18 2005 Add maxvec(), addvec(), and multvec() * * Mar 1 2006 Fix bug of occasional double application of bscale in getvec() * Apr 3 2006 Fix bad cast in unisigned int section of addvec() * May 3 2006 Code fixes in addpix and multpix suggested by Robert Lupton * Jun 8 2006 Drop erroneous second im2 assignment without offset in addvec() * Jun 20 2006 Fix typos masquerading as unitialized variables * * Jan 8 2007 Include fitsfile.h instead of imio.h * Jun 11 2007 Add minvec() and speed up maxvec() */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/imio.h000066400000000000000000000032071215713201500213630ustar00rootroot00000000000000/* imio.h memory access subroutines * September 27, 1999 * By Doug Mink, Harvard-Smithsonian Center for Astrophysics */ #ifndef imio_h_ #define imio_h_ /* Image pixel access subroutines in imio.c */ extern double getpix(); /* Read one pixel from any data type 2-D array (0,0)*/ extern double getpix1(); /* Read one pixel from any data type 2-D array (1,1)*/ extern void putpix(); /* Write one pixel to any data type 2-D array (0,0)*/ extern void putpix1(); /* Write one pixel to any data type 2-D array (1,1) */ extern void addpix(); /* Add to one pixel in any data type 2-D array (0,0)*/ extern void addpix1(); /* Add to one pixel in any data type 2-D array (1,1)*/ extern void movepix(); /* Move one pixel value between two 2-D arrays (0,0) */ extern void movepix1(); /* Move one pixel value between two 2-D arrays (1,1) */ extern void getvec(); /* Read vector from 2-D array */ extern void putvec(); /* Write vector into 2-D array */ extern void imswap(); /* Swap alternating bytes in a vector */ extern void imswap2(); /* Swap bytes in a vector of 2-byte (short) integers */ extern void imswap4(); /* Reverse bytes in a vector of 4-byte numbers */ extern void imswap8(); /* Reverse bytes in a vector of 8-byte numbers */ extern int imswapped(); /* Return 1 if machine byte order is not FITS order */ #endif /* imio_h_ */ /* May 31 1996 Use stream I/O for reading as well as writing * Jun 12 1996 Add byte-swapping subroutines * Aug 6 1996 Add MOVEPIX, HDEL and HCHANGE declarations * * May 27 1998 Split off imio subroutines to imio.h * Sep 27 1999 Add Fortran-indexed (1,1), not (0,0) image access *1() * Sep 28 1999 Add addpix() */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/lin.c000066400000000000000000000304271215713201500212070ustar00rootroot00000000000000/*============================================================================= * * WCSLIB - an implementation of the FITS WCS proposal. * Copyright (C) 1995-2002, Mark Calabretta * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Correspondence concerning WCSLIB may be directed to: * Internet email: mcalabre@atnf.csiro.au * Postal address: Dr. Mark Calabretta, * Australia Telescope National Facility, * P.O. Box 76, * Epping, NSW, 2121, * AUSTRALIA * *============================================================================= * * C routines which implement the FITS World Coordinate System (WCS) * convention. * * Summary of routines * ------------------- * These utility routines apply the linear transformation defined by the WCS * FITS header cards. There are separate routines for the image-to-pixel, * linfwd(), and pixel-to-image, linrev(), transformations. * * An initialization routine, linset(), computes intermediate values from * the transformation parameters but need not be called explicitly - see the * explanation of lin.flag below. * * An auxiliary matrix inversion routine, matinv(), is included. It uses * LU-triangular factorization with scaled partial pivoting. * * * Initialization routine; linset() * -------------------------------- * Initializes members of a linprm data structure which hold intermediate * values. Note that this routine need not be called directly; it will be * invoked by linfwd() and linrev() if the "flag" structure member is * anything other than a predefined magic value. * * Given and/or returned: * lin linprm* Linear transformation parameters (see below). * * Function return value: * int Error status * 0: Success. * 1: Memory allocation error. * 2: PC matrix is singular. * * Forward transformation; linfwd() * -------------------------------- * Compute pixel coordinates from image coordinates. Note that where * celestial coordinate systems are concerned the image coordinates * correspond to (x,y) in the plane of projection, not celestial (lng,lat). * * Given: * imgcrd const double[] * Image (world) coordinate. * * Given and returned: * lin linprm* Linear transformation parameters (see below). * * Returned: * pixcrd d[] Pixel coordinate. * * Function return value: * int Error status * 0: Success. * 1: The transformation is not invertible. * * Reverse transformation; linrev() * -------------------------------- * Compute image coordinates from pixel coordinates. Note that where * celestial coordinate systems are concerned the image coordinates * correspond to (x,y) in the plane of projection, not celestial (lng,lat). * * Given: * pixcrd const double[] * Pixel coordinate. * * Given and/or returned: * lin linprm* Linear transformation parameters (see below). * * Returned: * imgcrd d[] Image (world) coordinate. * * Function return value: * int Error status * 0: Success. * 1: Error. * * Linear transformation parameters * -------------------------------- * The linprm struct consists of the following: * * int flag * This flag must be set to zero whenever any of the following members * are set or modified. This signals the initialization routine, * linset(), to recompute intermediaries. * int naxis * Number of image axes. * double *crpix * Pointer to the first element of an array of double containing the * coordinate reference pixel, CRPIXn. * double *pc * Pointer to the first element of the PC (pixel coordinate) * transformation matrix. The expected order is * * lin.pc = {PC1_1, PC1_2, PC2_1, PC2_2}; * * This may be conveniently constructed from a two-dimensional array * via * * double m[2][2] = {{PC1_1, PC1_2}, * {PC2_1, PC2_2}}; * * which is equivalent to, * * double m[2][2]; * m[0][0] = PC1_1; * m[0][1] = PC1_2; * m[1][0] = PC2_1; * m[1][1] = PC2_2; * * for which the storage order is * * PC1_1, PC1_2, PC2_1, PC2_2 * * so it would be legitimate to set lin.pc = *m. * double *cdelt * Pointer to the first element of an array of double containing the * coordinate increments, CDELTn. * * The remaining members of the linprm struct are maintained by the * initialization routine and should not be modified. * * double *piximg * Pointer to the first element of the matrix containing the product * of the CDELTn diagonal matrix and the PC matrix. * double *imgpix * Pointer to the first element of the inverse of the piximg matrix. * * linset allocates storage for the above arrays using malloc(). Note, * however, that these routines do not free this storage so if a linprm * variable has itself been malloc'd then these structure members must be * explicitly freed before the linprm variable is free'd otherwise a memory * leak will result. * * Author: Mark Calabretta, Australia Telescope National Facility * $Id: lin.c,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ *===========================================================================*/ #include #include #include "wcslib.h" /* Map error number to error message for each function. */ const char *linset_errmsg[] = { 0, "Memory allocation error", "PC matrix is singular"}; const char *linfwd_errmsg[] = { 0, "Memory allocation error", "PC matrix is singular"}; const char *linrev_errmsg[] = { 0, "Memory allocation error", "PC matrix is singular"}; int linset(lin) struct linprm *lin; { int i, ij, j, mem, n; n = lin->naxis; /* Allocate memory for internal arrays. */ mem = n * n * sizeof(double); lin->piximg = (double*)malloc(mem); if (lin->piximg == (double*)0) return 1; lin->imgpix = (double*)malloc(mem); if (lin->imgpix == (double*)0) { free(lin->piximg); return 1; } /* Compute the pixel-to-image transformation matrix. */ for (i = 0, ij = 0; i < n; i++) { for (j = 0; j < n; j++, ij++) { lin->piximg[ij] = lin->cdelt[i] * lin->pc[ij]; } } /* Compute the image-to-pixel transformation matrix. */ if (matinv(n, lin->piximg, lin->imgpix)) return 2; lin->flag = LINSET; return 0; } /*--------------------------------------------------------------------------*/ int linfwd(imgcrd, lin, pixcrd) const double imgcrd[]; struct linprm *lin; double pixcrd[]; { int i, ij, j, n; n = lin->naxis; if (lin->flag != LINSET) { if (linset(lin)) return 1; } for (i = 0, ij = 0; i < n; i++) { pixcrd[i] = 0.0; for (j = 0; j < n; j++, ij++) { pixcrd[i] += lin->imgpix[ij] * imgcrd[j]; } } for (j = 0; j < n; j++) { pixcrd[j] += lin->crpix[j]; } return 0; } /*--------------------------------------------------------------------------*/ int linrev(pixcrd, lin, imgcrd) const double pixcrd[]; struct linprm *lin; double imgcrd[]; { int i, ij, j, n; double temp; n = lin->naxis; if (lin->flag != LINSET) { if (linset(lin)) return 1; } for (i = 0; i < n; i++) { imgcrd[i] = 0.0; } for (j = 0; j < n; j++) { temp = pixcrd[j] - lin->crpix[j]; for (i = 0, ij = j; i < n; i++, ij+=n) { imgcrd[i] += lin->piximg[ij] * temp; } } return 0; } /*--------------------------------------------------------------------------*/ int matinv(n, mat, inv) const int n; const double mat[]; double inv[]; { register int i, ij, ik, j, k, kj, pj; int itemp, mem, *mxl, *lxm, pivot; double colmax, *lu, *rowmax, dtemp; /* Allocate memory for internal arrays. */ mem = n * sizeof(int); if ((mxl = (int*)malloc(mem)) == (int*)0) return 1; if ((lxm = (int*)malloc(mem)) == (int*)0) { free(mxl); return 1; } mem = n * sizeof(double); if ((rowmax = (double*)malloc(mem)) == (double*)0) { free(mxl); free(lxm); return 1; } mem *= n; if ((lu = (double*)malloc(mem)) == (double*)0) { free(mxl); free(lxm); free(rowmax); return 1; } /* Initialize arrays. */ for (i = 0, ij = 0; i < n; i++) { /* Vector which records row interchanges. */ mxl[i] = i; rowmax[i] = 0.0; for (j = 0; j < n; j++, ij++) { dtemp = fabs(mat[ij]); if (dtemp > rowmax[i]) rowmax[i] = dtemp; lu[ij] = mat[ij]; } /* A row of zeroes indicates a singular matrix. */ if (rowmax[i] == 0.0) { free(mxl); free(lxm); free(rowmax); free(lu); return 2; } } /* Form the LU triangular factorization using scaled partial pivoting. */ for (k = 0; k < n; k++) { /* Decide whether to pivot. */ colmax = fabs(lu[k*n+k]) / rowmax[k]; pivot = k; for (i = k+1; i < n; i++) { ik = i*n + k; dtemp = fabs(lu[ik]) / rowmax[i]; if (dtemp > colmax) { colmax = dtemp; pivot = i; } } if (pivot > k) { /* We must pivot, interchange the rows of the design matrix. */ for (j = 0, pj = pivot*n, kj = k*n; j < n; j++, pj++, kj++) { dtemp = lu[pj]; lu[pj] = lu[kj]; lu[kj] = dtemp; } /* Amend the vector of row maxima. */ dtemp = rowmax[pivot]; rowmax[pivot] = rowmax[k]; rowmax[k] = dtemp; /* Record the interchange for later use. */ itemp = mxl[pivot]; mxl[pivot] = mxl[k]; mxl[k] = itemp; } /* Gaussian elimination. */ for (i = k+1; i < n; i++) { ik = i*n + k; /* Nothing to do if lu[ik] is zero. */ if (lu[ik] != 0.0) { /* Save the scaling factor. */ lu[ik] /= lu[k*n+k]; /* Subtract rows. */ for (j = k+1; j < n; j++) { lu[i*n+j] -= lu[ik]*lu[k*n+j]; } } } } /* mxl[i] records which row of mat corresponds to row i of lu. */ /* lxm[i] records which row of lu corresponds to row i of mat. */ for (i = 0; i < n; i++) { lxm[mxl[i]] = i; } /* Determine the inverse matrix. */ for (i = 0, ij = 0; i < n; i++) { for (j = 0; j < n; j++, ij++) { inv[ij] = 0.0; } } for (k = 0; k < n; k++) { inv[lxm[k]*n+k] = 1.0; /* Forward substitution. */ for (i = lxm[k]+1; i < n; i++) { for (j = lxm[k]; j < i; j++) { inv[i*n+k] -= lu[i*n+j]*inv[j*n+k]; } } /* Backward substitution. */ for (i = n-1; i >= 0; i--) { for (j = i+1; j < n; j++) { inv[i*n+k] -= lu[i*n+j]*inv[j*n+k]; } inv[i*n+k] /= lu[i*n+i]; } } free(mxl); free(lxm); free(rowmax); free(lu); return 0; } /* Dec 20 1999 Doug Mink - Include wcslib.h, which includes lin.h * * Feb 15 2001 Doug Mink - Add comments for WCSLIB 2.6; no code changes * Sep 19 2001 Doug Mink - Add above change to WCSLIB 2.7 code * Nov 20 2001 Doug Mink - Always include stdlib.h * * Jan 15 2002 Bill Joye - Add ifdef so this compiles on MacOS/X * * Nov 18 2003 Doug Mink - Include stdlib.h instead of malloc.h */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/lin.h000066400000000000000000000015331215713201500212100ustar00rootroot00000000000000#ifndef lin_h_ #define lin_h_ #ifdef __cplusplus extern "C" { #endif #if !defined(__STDC__) && !defined(__cplusplus) #ifndef const #define const #endif #endif struct linprm { int flag; int naxis; double *crpix; double *pc; double *cdelt; /* Intermediates. */ double *piximg; double *imgpix; }; #if __STDC__ || defined(__cplusplus) int linset(struct linprm *); int linfwd(const double[], struct linprm *, double[]); int linrev(const double[], struct linprm *, double[]); int matinv(const int, const double [], double []); #else int linset(), linfwd(), linrev(), matinv(); #endif extern const char *linset_errmsg[]; extern const char *linfwd_errmsg[]; extern const char *linrev_errmsg[]; #define LINSET 137 #ifdef __cplusplus }; #endif #endif /* lin_h_ */ /* May 27 1998 ifndef LIN changed to ifndef lin_h_ */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/platepos.c000066400000000000000000000253721215713201500222570ustar00rootroot00000000000000/*** File saoimage/wcslib/platepos.c *** February 29, 2000 *** By Doug Mink, dmink@cfa.harvard.edu *** Harvard-Smithsonian Center for Astrophysics *** Copyright (C) 1998-2002 *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Correspondence concerning WCSTools should be addressed as follows: Internet email: dmink@cfa.harvard.edu Postal address: Doug Mink Smithsonian Astrophysical Observatory 60 Garden St. Cambridge, MA 02138 USA * Module: platepos.c (Plate solution WCS conversion * Purpose: Compute WCS from plate fit * Subroutine: platepos() converts from pixel location to RA,Dec * Subroutine: platepix() converts from RA,Dec to pixel location These functions are based on the astrmcal.c portion of GETIMAGE by J. Doggett and the documentation distributed with the Digital Sky Survey. */ #include #include #include #include "wcs.h" int platepos (xpix, ypix, wcs, xpos, ypos) /* Routine to determine accurate position for pixel coordinates */ /* returns 0 if successful otherwise 1 = angle too large for projection; */ /* based on amdpos() from getimage */ /* Input: */ double xpix; /* x pixel number (RA or long without rotation) */ double ypix; /* y pixel number (dec or lat without rotation) */ struct WorldCoor *wcs; /* WCS parameter structure */ /* Output: */ double *xpos; /* Right ascension or longitude in degrees */ double *ypos; /* Declination or latitude in degrees */ { double x, y, x2, y2, x3, y3, r2; double xi, xir, eta, etar, raoff, ra, dec, ra0, dec0; double twopi = 6.28318530717959; double ctan, ccos; int ncoeff1 = wcs->ncoeff1; int ncoeff2 = wcs->ncoeff2; /* Ignore magnitude and color terms double mag = 0.0; double color = 0.0; */ /* Convert from pixels to millimeters */ x = xpix - wcs->crpix[0]; y = ypix - wcs->crpix[1]; x2 = x * x; y2 = y * y; x3 = x * x2; y3 = y * y2; r2 = x2 + y2; /* Compute xi,eta coordinates in degrees from x,y and plate model */ xi = wcs->x_coeff[ 0] + wcs->x_coeff[ 1]*x + wcs->x_coeff[ 2]*y + wcs->x_coeff[ 3]*x2 + wcs->x_coeff[ 4]*y2 + wcs->x_coeff[ 5]*x*y; if (ncoeff1 > 6) xi = xi + wcs->x_coeff[ 6]*x3 + wcs->x_coeff[ 7]*y3; if (ncoeff1 > 8) { xi = xi + wcs->x_coeff[ 8]*x2*y + wcs->x_coeff[ 9]*x*y2 + wcs->x_coeff[10]*(r2) + wcs->x_coeff[11]*x*r2 + wcs->x_coeff[12]*y*r2; } eta = wcs->y_coeff[ 0] + wcs->y_coeff[ 1]*x + wcs->y_coeff[ 2]*y + wcs->y_coeff[ 3]*x2 + wcs->y_coeff[ 4]*y2 + wcs->y_coeff[ 5]*x*y; if (ncoeff2 > 6) eta = eta + wcs->y_coeff[ 6]*x3 + wcs->y_coeff[ 7]*y3; if (ncoeff2 > 8) { eta = eta + wcs->y_coeff[ 8]*x2*y + wcs->y_coeff[ 9]*y2*x + wcs->y_coeff[10]*r2 + wcs->y_coeff[11]*x*r2 + wcs->y_coeff[12]*y*r2; } /* Convert to radians */ xir = degrad (xi); etar = degrad (eta); /* Convert to RA and Dec */ ra0 = degrad (wcs->crval[0]); dec0 = degrad (wcs->crval[1]); ctan = tan (dec0); ccos = cos (dec0); raoff = atan2 (xir / ccos, 1.0 - etar * ctan); ra = raoff + ra0; if (ra < 0.0) ra = ra + twopi; *xpos = raddeg (ra); dec = atan (cos (raoff) / ((1.0 - (etar * ctan)) / (etar + ctan))); *ypos = raddeg (dec); return 0; } int platepix (xpos, ypos, wcs, xpix, ypix) /* Routine to determine pixel coordinates for sky position */ /* returns 0 if successful otherwise 1 = angle too large for projection; */ /* based on amdinv() from getimage */ /* Input: */ double xpos; /* Right ascension or longitude in degrees */ double ypos; /* Declination or latitude in degrees */ struct WorldCoor *wcs; /* WCS parameter structure */ /* Output: */ double *xpix; /* x pixel number (RA or long without rotation) */ double *ypix; /* y pixel number (dec or lat without rotation) */ { double xi,eta,x,y,xy,x2,y2,x2y,y2x,x3,y3,r2,dx,dy; double tdec,ctan,ccos,traoff, craoff, etar, xir; double f,fx,fy,g,gx,gy; double ra0, dec0, ra, dec; double tolerance = 0.0000005; int max_iterations = 50; int i; int ncoeff1 = wcs->ncoeff1; int ncoeff2 = wcs->ncoeff2; /* Convert RA and Dec in radians to standard coordinates on a plate */ ra = degrad (xpos); dec = degrad (ypos); tdec = tan (dec); ra0 = degrad (wcs->crval[0]); dec0 = degrad (wcs->crval[1]); ctan = tan (dec0); ccos = cos (dec0); traoff = tan (ra - ra0); craoff = cos (ra - ra0); etar = (1.0 - ctan * craoff / tdec) / (ctan + (craoff / tdec)); xir = traoff * ccos * (1.0 - (etar * ctan)); xi = raddeg (xir); eta = raddeg (etar); /* Set initial value for x,y */ x = xi * wcs->dc[0] + eta * wcs->dc[1]; y = xi * wcs->dc[2] + eta * wcs->dc[3]; /* if (wcs->x_coeff[1] == 0.0) x = xi - wcs->x_coeff[0]; else x = (xi - wcs->x_coeff[0]) / wcs->x_coeff[1]; if (wcs->y_coeff[2] == 0.0) y = eta - wcs->y_coeff[0]; else y = (eta - wcs->y_coeff[0]) / wcs->y_coeff[2]; */ /* Iterate by Newton's method */ for (i = 0; i < max_iterations; i++) { /* X plate model */ xy = x * y; x2 = x * x; y2 = y * y; x3 = x2 * x; y3 = y2 * y; x2y = x2 * y; y2x = y2 * x; r2 = x2 + y2; f = wcs->x_coeff[0] + wcs->x_coeff[1]*x + wcs->x_coeff[2]*y + wcs->x_coeff[3]*x2 + wcs->x_coeff[4]*y2 + wcs->x_coeff[5]*xy; /* Derivative of X model wrt x */ fx = wcs->x_coeff[1] + wcs->x_coeff[3]*2.0*x + wcs->x_coeff[5]*y; /* Derivative of X model wrt y */ fy = wcs->x_coeff[2] + wcs->x_coeff[4]*2.0*y + wcs->x_coeff[5]*x; if (ncoeff1 > 6) { f = f + wcs->x_coeff[6]*x3 + wcs->x_coeff[7]*y3; fx = fx + wcs->x_coeff[6]*3.0*x2; fy = fy + wcs->x_coeff[7]*3.0*y2; } if (ncoeff1 > 8) { f = f + wcs->x_coeff[8]*x2y + wcs->x_coeff[9]*y2x + wcs->x_coeff[10]*r2 + wcs->x_coeff[11]*x*r2 + wcs->x_coeff[12]*y*r2; fx = fx + wcs->x_coeff[8]*2.0*xy + wcs->x_coeff[9]*y2 + wcs->x_coeff[10]*2.0*x + wcs->x_coeff[11]*(3.0*x2+y2) + wcs->x_coeff[12]*2.0*xy; fy = fy + wcs->x_coeff[8]*x2 + wcs->x_coeff[9]*2.0*xy + wcs->x_coeff[10]*2.0*y + wcs->x_coeff[11]*2.0*xy + wcs->x_coeff[12]*(3.0*y2+x2); } /* Y plate model */ g = wcs->y_coeff[0] + wcs->y_coeff[1]*x + wcs->y_coeff[2]*y + wcs->y_coeff[3]*x2 + wcs->y_coeff[4]*y2 + wcs->y_coeff[5]*xy; /* Derivative of Y model wrt x */ gx = wcs->y_coeff[1] + wcs->y_coeff[3]*2.0*x + wcs->y_coeff[5]*y; /* Derivative of Y model wrt y */ gy = wcs->y_coeff[2] + wcs->y_coeff[4]*2.0*y + wcs->y_coeff[5]*x; if (ncoeff2 > 6) { g = g + wcs->y_coeff[6]*x3 + wcs->y_coeff[7]*y3; gx = gx + wcs->y_coeff[6]*3.0*x2; gy = gy + wcs->y_coeff[7]*3.0*y2; } if (ncoeff2 > 8) { g = g + wcs->y_coeff[8]*x2y + wcs->y_coeff[9]*y2x + wcs->y_coeff[10]*r2 + wcs->y_coeff[11]*x*r2 + wcs->y_coeff[12]*y*r2; gx = gx + wcs->y_coeff[8]*2.0*xy + wcs->y_coeff[9]*y2 + wcs->y_coeff[10]*2.0*x + wcs->y_coeff[11]*(3.0*x2+y2) + wcs->y_coeff[12]*2.0*xy; gy = gy + wcs->y_coeff[8]*x2 + wcs->y_coeff[9]*2.0*xy + wcs->y_coeff[10]*2.0*y + wcs->y_coeff[11]*2.0*xy + wcs->y_coeff[12]*(3.0*y2+x2); } f = f - xi; g = g - eta; dx = ((-f * gy) + (g * fy)) / ((fx * gy) - (fy * gx)); dy = ((-g * fx) + (f * gx)) / ((fx * gy) - (fy * gx)); x = x + dx; y = y + dy; if ((fabs(dx) < tolerance) && (fabs(dy) < tolerance)) break; } /* Convert from plate pixels to image pixels */ *xpix = x + wcs->crpix[0]; *ypix = y + wcs->crpix[1]; /* If position is off of the image, return offscale code */ if (*xpix < 0.5 || *xpix > wcs->nxpix+0.5) return -1; if (*ypix < 0.5 || *ypix > wcs->nypix+0.5) return -1; return 0; } /* Set plate fit coefficients in structure from arguments */ int SetPlate (wcs, ncoeff1, ncoeff2, coeff) struct WorldCoor *wcs; /* World coordinate system structure */ int ncoeff1; /* Number of coefficients for x */ int ncoeff2; /* Number of coefficients for y */ double *coeff; /* Plate fit coefficients */ { int i; if (nowcs (wcs) || (ncoeff1 < 1 && ncoeff2 < 1)) return 1; wcs->ncoeff1 = ncoeff1; wcs->ncoeff2 = ncoeff2; wcs->prjcode = WCS_PLT; for (i = 0; i < 20; i++) { if (i < ncoeff1) wcs->x_coeff[i] = coeff[i]; else wcs->x_coeff[i] = 0.0; } for (i = 0; i < 20; i++) { if (i < ncoeff2) wcs->y_coeff[i] = coeff[ncoeff1+i]; else wcs->y_coeff[i] = 0.0; } return 0; } /* Return plate fit coefficients from structure in arguments */ int GetPlate (wcs, ncoeff1, ncoeff2, coeff) struct WorldCoor *wcs; /* World coordinate system structure */ int *ncoeff1; /* Number of coefficients for x */ int *ncoeff2; /* Number of coefficients for y) */ double *coeff; /* Plate fit coefficients */ { int i; if (nowcs (wcs)) return 1; *ncoeff1 = wcs->ncoeff1; *ncoeff2 = wcs->ncoeff2; for (i = 0; i < *ncoeff1; i++) coeff[i] = wcs->x_coeff[i]; for (i = 0; i < *ncoeff2; i++) coeff[*ncoeff1+i] = wcs->y_coeff[i]; return 0; } /* Set FITS header plate fit coefficients from structure */ void SetFITSPlate (header, wcs) char *header; /* Image FITS header */ struct WorldCoor *wcs; /* WCS structure */ { char keyword[16]; int i; for (i = 0; i < wcs->ncoeff1; i++) { sprintf (keyword,"CO1_%d",i+1); hputnr8 (header, keyword, -15, wcs->x_coeff[i]); } for (i = 0; i < wcs->ncoeff2; i++) { sprintf (keyword,"CO2_%d",i+1); hputnr8 (header, keyword, -15, wcs->y_coeff[i]); } return; } /* Mar 27 1998 New subroutines for direct image pixel <-> sky polynomials * Apr 10 1998 Make terms identical for both x and y polynomials * Apr 10 1998 Allow different numbers of coefficients for x and y * Apr 16 1998 Drom NCOEFF header parameter * Apr 28 1998 Change projection flags to WCS_* * Sep 10 1998 Check for xc1 and yc2 divide by zero after Allen Harris, SAO * * Oct 21 1999 Drop unused variables after lint * * Feb 29 2000 Use inverse CD matrix to get initial X,Y in platepix() * as suggested by Paolo Montegriffo from Bologna Ast. Obs. */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/proj.c000066400000000000000000002757361215713201500214150ustar00rootroot00000000000000/*============================================================================ * * WCSLIB - an implementation of the FITS WCS proposal. * Copyright (C) 1995-2002, Mark Calabretta * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Correspondence concerning WCSLIB may be directed to: * Internet email: mcalabre@atnf.csiro.au * Postal address: Dr. Mark Calabretta, * Australia Telescope National Facility, * P.O. Box 76, * Epping, NSW, 2121, * AUSTRALIA * *============================================================================= * * C implementation of the spherical map projections recognized by the FITS * "World Coordinate System" (WCS) convention. * * Summary of routines * ------------------- * Each projection is implemented via separate functions for the forward, * *fwd(), and reverse, *rev(), transformation. * * Initialization routines, *set(), compute intermediate values from the * projection parameters but need not be called explicitly - see the * explanation of prj.flag below. * * prjset prjfwd prjrev Driver routines (see below). * * azpset azpfwd azprev AZP: zenithal/azimuthal perspective * szpset szpfwd szprev SZP: slant zenithal perspective * tanset tanfwd tanrev TAN: gnomonic * stgset stgfwd stgrev STG: stereographic * sinset sinfwd sinrev SIN: orthographic/synthesis * arcset arcfwd arcrev ARC: zenithal/azimuthal equidistant * zpnset zpnfwd zpnrev ZPN: zenithal/azimuthal polynomial * zeaset zeafwd zearev ZEA: zenithal/azimuthal equal area * airset airfwd airrev AIR: Airy * cypset cypfwd cyprev CYP: cylindrical perspective * ceaset ceafwd cearev CEA: cylindrical equal area * carset carfwd carrev CAR: Cartesian * merset merfwd merrev MER: Mercator * sflset sflfwd sflrev SFL: Sanson-Flamsteed * parset parfwd parrev PAR: parabolic * molset molfwd molrev MOL: Mollweide * aitset aitfwd aitrev AIT: Hammer-Aitoff * copset copfwd coprev COP: conic perspective * coeset coefwd coerev COE: conic equal area * codset codfwd codrev COD: conic equidistant * cooset coofwd coorev COO: conic orthomorphic * bonset bonfwd bonrev BON: Bonne * pcoset pcofwd pcorev PCO: polyconic * tscset tscfwd tscrev TSC: tangential spherical cube * cscset cscfwd cscrev CSC: COBE quadrilateralized spherical cube * qscset qscfwd qscrev QSC: quadrilateralized spherical cube * * * Driver routines; prjset(), prjfwd() & prjrev() * ---------------------------------------------- * A set of driver routines are available for use as a generic interface to * the specific projection routines. The interfaces to prjfwd() and prjrev() * are the same as those of the forward and reverse transformation routines * for the specific projections (see below). * * The interface to prjset() differs slightly from that of the initialization * routines for the specific projections and unlike them it must be invoked * explicitly to use prjfwd() and prjrev(). * * Given: * pcode[4] const char * WCS projection code. * * Given and/or returned: * prj prjprm* Projection parameters (see below). * * Function return value: * int Error status * 0: Success. * * * Initialization routine; *set() * ------------------------------ * Initializes members of a prjprm data structure which hold intermediate * values. Note that this routine need not be called directly; it will be * invoked by prjfwd() and prjrev() if the "flag" structure member is * anything other than a predefined magic value. * * Given and/or returned: * prj prjprm* Projection parameters (see below). * * Function return value: * int Error status * 0: Success. * 1: Invalid projection parameters. * * Forward transformation; *fwd() * ----------------------------- * Compute (x,y) coordinates in the plane of projection from native spherical * coordinates (phi,theta). * * Given: * phi, const double * theta Longitude and latitude of the projected point in * native spherical coordinates, in degrees. * * Given and returned: * prj prjprm* Projection parameters (see below). * * Returned: * x,y double* Projected coordinates. * * Function return value: * int Error status * 0: Success. * 1: Invalid projection parameters. * 2: Invalid value of (phi,theta). * * Reverse transformation; *rev() * ----------------------------- * Compute native spherical coordinates (phi,theta) from (x,y) coordinates in * the plane of projection. * * Given: * x,y const double * Projected coordinates. * * Given and returned: * prj prjprm* Projection parameters (see below). * * Returned: * phi, double* Longitude and latitude of the projected point in * theta native spherical coordinates, in degrees. * * Function return value: * int Error status * 0: Success. * 1: Invalid projection parameters. * 2: Invalid value of (x,y). * 1: Invalid projection parameters. * * Projection parameters * --------------------- * The prjprm struct consists of the following: * * int flag * This flag must be set to zero whenever any of p[10] or r0 are set * or changed. This signals the initialization routine to recompute * intermediaries. flag may also be set to -1 to disable strict bounds * checking for the AZP, SZP, TAN, SIN, ZPN, and COP projections. * * double r0 * r0; The radius of the generating sphere for the projection, a linear * scaling parameter. If this is zero, it will be reset to the default * value of 180/pi (the value for FITS WCS). * * double p[10] * The first 10 elements contain projection parameters which correspond * to the PROJPn keywords in FITS, so p[0] is PROJP0, and p[9] is * PROJP9. Many projections use p[1] (PROJP1) and some also use p[2] * (PROJP2). ZPN is the only projection which uses any of the others. * * The remaining members of the prjprm struct are maintained by the * initialization routines and should not be modified. This is done for the * sake of efficiency and to allow an arbitrary number of contexts to be * maintained simultaneously. * * char code[4] * Three-letter projection code. * * double phi0, theta0 * Native longitude and latitude of the reference point, in degrees. * * double w[10] * int n * Intermediate values derived from the projection parameters. * * int (*prjfwd)() * int (*prjrev)() * Pointers to the forward and reverse projection routines. * * Usage of the p[] array as it applies to each projection is described in * the prologue to each trio of projection routines. * * Argument checking * ----------------- * Forward routines: * * The values of phi and theta (the native longitude and latitude) * normally lie in the range [-180,180] for phi, and [-90,90] for theta. * However, all forward projections will accept any value of phi and will * not normalize it. * * The forward projection routines do not explicitly check that theta lies * within the range [-90,90]. They do check for any value of theta which * produces an invalid argument to the projection equations (e.g. leading * to division by zero). The forward routines for AZP, SZP, TAN, SIN, * ZPN, and COP also return error 2 if (phi,theta) corresponds to the * overlapped (far) side of the projection but also return the * corresponding value of (x,y). This strict bounds checking may be * relaxed by setting prj->flag to -1 (rather than 0) when these * projections are initialized. * * Reverse routines: * * Error checking on the projected coordinates (x,y) is limited to that * required to ascertain whether a solution exists. Where a solution does * exist no check is made that the value of phi and theta obtained lie * within the ranges [-180,180] for phi, and [-90,90] for theta. * * Accuracy * -------- * Closure to a precision of at least 1E-10 degree of longitude and latitude * has been verified for typical projection parameters on the 1 degree grid * of native longitude and latitude (to within 5 degrees of any latitude * where the projection may diverge). * * Author: Mark Calabretta, Australia Telescope National Facility * $Id: proj.c,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ *===========================================================================*/ #include #include #include #include "wcslib.h" int npcode = 26; char pcodes[26][4] = {"AZP", "SZP", "TAN", "STG", "SIN", "ARC", "ZPN", "ZEA", "AIR", "CYP", "CEA", "CAR", "MER", "COP", "COE", "COD", "COO", "SFL", "PAR", "MOL", "AIT", "BON", "PCO", "TSC", "CSC", "QSC"}; const int AZP = 101; const int SZP = 102; const int TAN = 103; const int STG = 104; const int SIN = 105; const int ARC = 106; const int ZPN = 107; const int ZEA = 108; const int AIR = 109; const int CYP = 201; const int CEA = 202; const int CAR = 203; const int MER = 204; const int SFL = 301; const int PAR = 302; const int MOL = 303; const int AIT = 401; const int COP = 501; const int COE = 502; const int COD = 503; const int COO = 504; const int BON = 601; const int PCO = 602; const int TSC = 701; const int CSC = 702; const int QSC = 703; /* Map error number to error message for each function. */ const char *prjset_errmsg[] = { 0, "Invalid projection parameters"}; const char *prjfwd_errmsg[] = { 0, "Invalid projection parameters", "Invalid value of (phi,theta)"}; const char *prjrev_errmsg[] = { 0, "Invalid projection parameters", "Invalid value of (x,y)"}; #define copysgn(X, Y) ((Y) < 0.0 ? -fabs(X) : fabs(X)) #define copysgni(X, Y) ((Y) < 0 ? -abs(X) : abs(X)) /*==========================================================================*/ int prjset(pcode, prj) const char pcode[4]; struct prjprm *prj; { /* Set pointers to the forward and reverse projection routines. */ if (strcmp(pcode, "AZP") == 0) { azpset(prj); } else if (strcmp(pcode, "SZP") == 0) { szpset(prj); } else if (strcmp(pcode, "TAN") == 0) { tanset(prj); } else if (strcmp(pcode, "STG") == 0) { stgset(prj); } else if (strcmp(pcode, "SIN") == 0) { sinset(prj); } else if (strcmp(pcode, "ARC") == 0) { arcset(prj); } else if (strcmp(pcode, "ZPN") == 0) { zpnset(prj); } else if (strcmp(pcode, "ZEA") == 0) { zeaset(prj); } else if (strcmp(pcode, "AIR") == 0) { airset(prj); } else if (strcmp(pcode, "CYP") == 0) { cypset(prj); } else if (strcmp(pcode, "CEA") == 0) { ceaset(prj); } else if (strcmp(pcode, "CAR") == 0) { carset(prj); } else if (strcmp(pcode, "MER") == 0) { merset(prj); } else if (strcmp(pcode, "SFL") == 0) { sflset(prj); } else if (strcmp(pcode, "PAR") == 0) { parset(prj); } else if (strcmp(pcode, "MOL") == 0) { molset(prj); } else if (strcmp(pcode, "AIT") == 0) { aitset(prj); } else if (strcmp(pcode, "COP") == 0) { copset(prj); } else if (strcmp(pcode, "COE") == 0) { coeset(prj); } else if (strcmp(pcode, "COD") == 0) { codset(prj); } else if (strcmp(pcode, "COO") == 0) { cooset(prj); } else if (strcmp(pcode, "BON") == 0) { bonset(prj); } else if (strcmp(pcode, "PCO") == 0) { pcoset(prj); } else if (strcmp(pcode, "TSC") == 0) { tscset(prj); } else if (strcmp(pcode, "CSC") == 0) { cscset(prj); } else if (strcmp(pcode, "QSC") == 0) { qscset(prj); } else { /* Unrecognized projection code. */ return 1; } return 0; } /*--------------------------------------------------------------------------*/ int prjfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { return prj->prjfwd(phi, theta, prj, x, y); } /*--------------------------------------------------------------------------*/ int prjrev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { return prj->prjrev(x, y, prj, phi, theta); } /*============================================================================ * AZP: zenithal/azimuthal perspective projection. * * Given: * prj->p[1] Distance parameter, mu in units of r0. * prj->p[2] Tilt angle, gamma in degrees. * * Given and/or returned: * prj->flag AZP, or -AZP if prj->flag is given < 0. * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "AZP" * prj->phi0 0.0 * prj->theta0 90.0 * prj->w[0] r0*(mu+1) * prj->w[1] tan(gamma) * prj->w[2] sec(gamma) * prj->w[3] cos(gamma) * prj->w[4] sin(gamma) * prj->w[5] asin(-1/mu) for |mu| >= 1, -90 otherwise * prj->w[6] mu*cos(gamma) * prj->w[7] 1 if |mu*cos(gamma)| < 1, 0 otherwise * prj->prjfwd Pointer to azpfwd(). * prj->prjrev Pointer to azprev(). *===========================================================================*/ int azpset(prj) struct prjprm *prj; { strcpy(prj->code, "AZP"); prj->flag = copysgni (AZP, prj->flag); prj->phi0 = 0.0; prj->theta0 = 90.0; if (prj->r0 == 0.0) prj->r0 = R2D; prj->w[0] = prj->r0*(prj->p[1] + 1.0); if (prj->w[0] == 0.0) { return 1; } prj->w[3] = cosdeg (prj->p[2]); if (prj->w[3] == 0.0) { return 1; } prj->w[2] = 1.0/prj->w[3]; prj->w[4] = sindeg (prj->p[2]); prj->w[1] = prj->w[4] / prj->w[3]; if (fabs(prj->p[1]) > 1.0) { prj->w[5] = asindeg (-1.0/prj->p[1]); } else { prj->w[5] = -90.0; } prj->w[6] = prj->p[1] * prj->w[3]; prj->w[7] = (fabs(prj->w[6]) < 1.0) ? 1.0 : 0.0; prj->prjfwd = azpfwd; prj->prjrev = azprev; return 0; } /*--------------------------------------------------------------------------*/ int azpfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { double a, b, cphi, cthe, r, s, t; if (abs(prj->flag) != AZP) { if (azpset(prj)) return 1; } cphi = cosdeg (phi); cthe = cosdeg (theta); s = prj->w[1]*cphi; t = (prj->p[1] + sindeg (theta)) + cthe*s; if (t == 0.0) { return 2; } r = prj->w[0]*cthe/t; *x = r*sindeg (phi); *y = -r*cphi*prj->w[2]; /* Bounds checking. */ if (prj->flag > 0) { /* Overlap. */ if (theta < prj->w[5]) { return 2; } /* Divergence. */ if (prj->w[7] > 0.0) { t = prj->p[1] / sqrt(1.0 + s*s); if (fabs(t) <= 1.0) { s = atandeg (-s); t = asindeg (t); a = s - t; b = s + t + 180.0; if (a > 90.0) a -= 360.0; if (b > 90.0) b -= 360.0; if (theta < ((a > b) ? a : b)) { return 2; } } } } return 0; } /*--------------------------------------------------------------------------*/ int azprev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { double a, b, r, s, t, ycosg; const double tol = 1.0e-13; if (abs(prj->flag) != AZP) { if (azpset(prj)) return 1; } ycosg = y*prj->w[3]; r = sqrt(x*x + ycosg*ycosg); if (r == 0.0) { *phi = 0.0; *theta = 90.0; } else { *phi = atan2deg (x, -ycosg); s = r / (prj->w[0] + y*prj->w[4]); t = s*prj->p[1]/sqrt(s*s + 1.0); s = atan2deg (1.0, s); if (fabs(t) > 1.0) { t = copysgn (90.0,t); if (fabs(t) > 1.0+tol) { return 2; } } else { t = asindeg (t); } a = s - t; b = s + t + 180.0; if (a > 90.0) a -= 360.0; if (b > 90.0) b -= 360.0; *theta = (a > b) ? a : b; } return 0; } /*============================================================================ * SZP: slant zenithal perspective projection. * * Given: * prj->p[1] Distance of the point of projection from the centre of the * generating sphere, mu in units of r0. * prj->p[2] Native longitude, phi_c, and ... * prj->p[3] Native latitude, theta_c, on the planewards side of the * intersection of the line through the point of projection * and the centre of the generating sphere, phi_c in degrees. * * Given and/or returned: * prj->flag SZP, or -SZP if prj->flag is given < 0. * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "SZP" * prj->phi0 0.0 * prj->theta0 90.0 * prj->w[0] 1/r0 * prj->w[1] xp = -mu*cos(theta_c)*sin(phi_c) * prj->w[2] yp = mu*cos(theta_c)*cos(phi_c) * prj->w[3] zp = mu*sin(theta_c) + 1 * prj->w[4] r0*xp * prj->w[5] r0*yp * prj->w[6] r0*zp * prj->w[7] (zp - 1)^2 * prj->w[8] asin(1-zp) if |1 - zp| < 1, -90 otherwise * prj->prjfwd Pointer to szpfwd(). * prj->prjrev Pointer to szprev(). *===========================================================================*/ int szpset(prj) struct prjprm *prj; { strcpy(prj->code, "SZP"); prj->flag = copysgni (SZP, prj->flag); prj->phi0 = 0.0; prj->theta0 = 90.0; if (prj->r0 == 0.0) prj->r0 = R2D; prj->w[0] = 1.0/prj->r0; prj->w[3] = prj->p[1] * sindeg (prj->p[3]) + 1.0; if (prj->w[3] == 0.0) { return 1; } prj->w[1] = -prj->p[1] * cosdeg (prj->p[3]) * sindeg (prj->p[2]); prj->w[2] = prj->p[1] * cosdeg (prj->p[3]) * cosdeg (prj->p[2]); prj->w[4] = prj->r0 * prj->w[1]; prj->w[5] = prj->r0 * prj->w[2]; prj->w[6] = prj->r0 * prj->w[3]; prj->w[7] = (prj->w[3] - 1.0) * prj->w[3] - 1.0; if (fabs(prj->w[3] - 1.0) < 1.0) { prj->w[8] = asindeg (1.0 - prj->w[3]); } else { prj->w[8] = -90.0; } prj->prjfwd = szpfwd; prj->prjrev = szprev; return 0; } /*--------------------------------------------------------------------------*/ int szpfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { double a, b, cphi, cthe, s, sphi, t; if (abs(prj->flag) != SZP) { if (szpset(prj)) return 1; } cphi = cosdeg (phi); sphi = sindeg (phi); cthe = cosdeg (theta); s = 1.0 - sindeg (theta); t = prj->w[3] - s; if (t == 0.0) { return 2; } *x = (prj->w[6]*cthe*sphi - prj->w[4]*s)/t; *y = -(prj->w[6]*cthe*cphi + prj->w[5]*s)/t; /* Bounds checking. */ if (prj->flag > 0) { /* Divergence. */ if (theta < prj->w[8]) { return 2; } /* Overlap. */ if (fabs(prj->p[1]) > 1.0) { s = prj->w[1]*sphi - prj->w[2]*cphi; t = 1.0/sqrt(prj->w[7] + s*s); if (fabs(t) <= 1.0) { s = atan2deg (s, prj->w[3] - 1.0); t = asindeg (t); a = s - t; b = s + t + 180.0; if (a > 90.0) a -= 360.0; if (b > 90.0) b -= 360.0; if (theta < ((a > b) ? a : b)) { return 2; } } } } return 0; } /*--------------------------------------------------------------------------*/ int szprev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { double a, b, c, d, r2, sth1, sth2, sthe, sxy, t, x1, xp, y1, yp, z; const double tol = 1.0e-13; if (abs(prj->flag) != SZP) { if (szpset(prj)) return 1; } xp = x*prj->w[0]; yp = y*prj->w[0]; r2 = xp*xp + yp*yp; x1 = (xp - prj->w[1])/prj->w[3]; y1 = (yp - prj->w[2])/prj->w[3]; sxy = xp*x1 + yp*y1; if (r2 < 1.0e-10) { /* Use small angle formula. */ z = r2/2.0; *theta = 90.0 - R2D*sqrt(r2/(1.0 + sxy)); } else { t = x1*x1 + y1*y1; a = t + 1.0; b = sxy - t; c = r2 - sxy - sxy + t - 1.0; d = b*b - a*c; /* Check for a solution. */ if (d < 0.0) { return 2; } d = sqrt(d); /* Choose solution closest to pole. */ sth1 = (-b + d)/a; sth2 = (-b - d)/a; sthe = (sth1 > sth2) ? sth1 : sth2; if (sthe > 1.0) { if (sthe-1.0 < tol) { sthe = 1.0; } else { sthe = (sth1 < sth2) ? sth1 : sth2; } } if (sthe < -1.0) { if (sthe+1.0 > -tol) { sthe = -1.0; } } if (sthe > 1.0 || sthe < -1.0) { return 2; } *theta = asindeg (sthe); z = 1.0 - sthe; } *phi = atan2deg (xp - x1*z, -(yp - y1*z)); return 0; } /*============================================================================ * TAN: gnomonic projection. * * Given and/or returned: * prj->flag TAN, or -TAN if prj->flag is given < 0. * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "TAN" * prj->phi0 0.0 * prj->theta0 90.0 * prj->prjfwd Pointer to tanfwd(). * prj->prjrev Pointer to tanrev(). *===========================================================================*/ int tanset(prj) struct prjprm *prj; { strcpy(prj->code, "TAN"); prj->flag = copysgni (TAN, prj->flag); prj->phi0 = 0.0; prj->theta0 = 90.0; if (prj->r0 == 0.0) prj->r0 = R2D; prj->prjfwd = tanfwd; prj->prjrev = tanrev; return 0; } /*--------------------------------------------------------------------------*/ int tanfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { double r, s; if (abs(prj->flag) != TAN) { if(tanset(prj)) return 1; } s = sindeg (theta); if (s <= 0.0) { return 2; } r = prj->r0*cosdeg (theta)/s; *x = r*sindeg (phi); *y = -r*cosdeg (phi); if (prj->flag > 0 && s < 0.0) { return 2; } return 0; } /*--------------------------------------------------------------------------*/ int tanrev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { double r; if (abs(prj->flag) != TAN) { if (tanset(prj)) return 1; } r = sqrt(x*x + y*y); if (r == 0.0) { *phi = 0.0; } else { *phi = atan2deg (x, -y); } *theta = atan2deg (prj->r0, r); return 0; } /*============================================================================ * STG: stereographic projection. * * Given and/or returned: * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "STG" * prj->flag STG * prj->phi0 0.0 * prj->theta0 90.0 * prj->w[0] 2*r0 * prj->w[1] 1/(2*r0) * prj->prjfwd Pointer to stgfwd(). * prj->prjrev Pointer to stgrev(). *===========================================================================*/ int stgset(prj) struct prjprm *prj; { strcpy(prj->code, "STG"); prj->flag = STG; prj->phi0 = 0.0; prj->theta0 = 90.0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 360.0/PI; prj->w[1] = PI/360.0; } else { prj->w[0] = 2.0*prj->r0; prj->w[1] = 1.0/prj->w[0]; } prj->prjfwd = stgfwd; prj->prjrev = stgrev; return 0; } /*--------------------------------------------------------------------------*/ int stgfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { double r, s; if (prj->flag != STG) { if (stgset(prj)) return 1; } s = 1.0 + sindeg (theta); if (s == 0.0) { return 2; } r = prj->w[0]*cosdeg (theta)/s; *x = r*sindeg (phi); *y = -r*cosdeg (phi); return 0; } /*--------------------------------------------------------------------------*/ int stgrev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { double r; if (prj->flag != STG) { if (stgset(prj)) return 1; } r = sqrt(x*x + y*y); if (r == 0.0) { *phi = 0.0; } else { *phi = atan2deg (x, -y); } *theta = 90.0 - 2.0*atandeg (r*prj->w[1]); return 0; } /*============================================================================ * SIN: orthographic/synthesis projection. * * Given: * prj->p[1:2] Obliqueness parameters, xi and eta. * * Given and/or returned: * prj->flag SIN, or -SIN if prj->flag is given < 0. * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "SIN" * prj->phi0 0.0 * prj->theta0 90.0 * prj->w[0] 1/r0 * prj->w[1] xi**2 + eta**2 * prj->w[2] xi**2 + eta**2 + 1 * prj->w[3] xi**2 + eta**2 - 1 * prj->prjfwd Pointer to sinfwd(). * prj->prjrev Pointer to sinrev(). *===========================================================================*/ int sinset(prj) struct prjprm *prj; { strcpy(prj->code, "SIN"); prj->flag = copysgni (SIN, prj->flag); prj->phi0 = 0.0; prj->theta0 = 90.0; if (prj->r0 == 0.0) prj->r0 = R2D; prj->w[0] = 1.0/prj->r0; prj->w[1] = prj->p[1]*prj->p[1] + prj->p[2]*prj->p[2]; prj->w[2] = prj->w[1] + 1.0; prj->w[3] = prj->w[1] - 1.0; prj->prjfwd = sinfwd; prj->prjrev = sinrev; return 0; } /*--------------------------------------------------------------------------*/ int sinfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { double cphi, cthe, sphi, t, z; if (abs(prj->flag) != SIN) { if (sinset(prj)) return 1; } t = (90.0 - fabs(theta))*D2R; if (t < 1.0e-5) { if (theta > 0.0) { z = t*t/2.0; } else { z = 2.0 - t*t/2.0; } cthe = t; } else { z = 1.0 - sindeg (theta); cthe = cosdeg (theta); } cphi = cosdeg (phi); sphi = sindeg (phi); *x = prj->r0*(cthe*sphi + prj->p[1]*z); *y = -prj->r0*(cthe*cphi - prj->p[2]*z); /* Validate this solution. */ if (prj->flag > 0) { if (prj->w[1] == 0.0) { /* Orthographic projection. */ if (theta < 0.0) { return 2; } } else { /* "Synthesis" projection. */ t = -atandeg (prj->p[1]*sphi - prj->p[2]*cphi); if (theta < t) { return 2; } } } return 0; } /*--------------------------------------------------------------------------*/ int sinrev (x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { const double tol = 1.0e-13; double a, b, c, d, r2, sth1, sth2, sthe, sxy, x0, x1, xp, y0, y1, yp, z; if (abs(prj->flag) != SIN) { if (sinset(prj)) return 1; } /* Compute intermediaries. */ x0 = x*prj->w[0]; y0 = y*prj->w[0]; r2 = x0*x0 + y0*y0; if (prj->w[1] == 0.0) { /* Orthographic projection. */ if (r2 != 0.0) { *phi = atan2deg (x0, -y0); } else { *phi = 0.0; } if (r2 < 0.5) { *theta = acosdeg (sqrt(r2)); } else if (r2 <= 1.0) { *theta = asindeg (sqrt(1.0 - r2)); } else { return 2; } } else { /* "Synthesis" projection. */ x1 = prj->p[1]; y1 = prj->p[2]; sxy = x0*x1 + y0*y1; if (r2 < 1.0e-10) { /* Use small angle formula. */ z = r2/2.0; *theta = 90.0 - R2D*sqrt(r2/(1.0 + sxy)); } else { a = prj->w[2]; b = sxy - prj->w[1]; c = r2 - sxy - sxy + prj->w[3]; d = b*b - a*c; /* Check for a solution. */ if (d < 0.0) { return 2; } d = sqrt(d); /* Choose solution closest to pole. */ sth1 = (-b + d)/a; sth2 = (-b - d)/a; sthe = (sth1 > sth2) ? sth1 : sth2; if (sthe > 1.0) { if (sthe-1.0 < tol) { sthe = 1.0; } else { sthe = (sth1 < sth2) ? sth1 : sth2; } } if (sthe < -1.0) { if (sthe+1.0 > -tol) { sthe = -1.0; } } if (sthe > 1.0 || sthe < -1.0) { return 2; } *theta = asindeg (sthe); z = 1.0 - sthe; } xp = -y0 + prj->p[2]*z; yp = x0 - prj->p[1]*z; if (xp == 0.0 && yp == 0.0) { *phi = 0.0; } else { *phi = atan2deg (yp,xp); } } return 0; } /*============================================================================ * ARC: zenithal/azimuthal equidistant projection. * * Given and/or returned: * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "ARC" * prj->flag ARC * prj->phi0 0.0 * prj->theta0 90.0 * prj->w[0] r0*(pi/180) * prj->w[1] (180/pi)/r0 * prj->prjfwd Pointer to arcfwd(). * prj->prjrev Pointer to arcrev(). *===========================================================================*/ int arcset(prj) struct prjprm *prj; { strcpy(prj->code, "ARC"); prj->flag = ARC; prj->phi0 = 0.0; prj->theta0 = 90.0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 1.0; prj->w[1] = 1.0; } else { prj->w[0] = prj->r0*D2R; prj->w[1] = 1.0/prj->w[0]; } prj->prjfwd = arcfwd; prj->prjrev = arcrev; return 0; } /*--------------------------------------------------------------------------*/ int arcfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { double r; if (prj->flag != ARC) { if (arcset(prj)) return 1; } r = prj->w[0]*(90.0 - theta); *x = r*sindeg (phi); *y = -r*cosdeg (phi); return 0; } /*--------------------------------------------------------------------------*/ int arcrev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { double r; if (prj->flag != ARC) { if (arcset(prj)) return 1; } r = sqrt(x*x + y*y); if (r == 0.0) { *phi = 0.0; } else { *phi = atan2deg (x, -y); } *theta = 90.0 - r*prj->w[1]; return 0; } /*============================================================================ * ZPN: zenithal/azimuthal polynomial projection. * * Given: * prj->p[0:9] Polynomial coefficients. * * Given and/or returned: * prj->flag ZPN, or -ZPN if prj->flag is given < 0. * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "ZPN" * prj->phi0 0.0 * prj->theta0 90.0 * prj->n Degree of the polynomial, N. * prj->w[0] Co-latitude of the first point of inflection (N > 2). * prj->w[1] Radius of the first point of inflection (N > 2). * prj->prjfwd Pointer to zpnfwd(). * prj->prjrev Pointer to zpnrev(). *===========================================================================*/ int zpnset(prj) struct prjprm *prj; { int i, j, k; double d, d1, d2, r, zd, zd1, zd2; const double tol = 1.0e-13; strcpy(prj->code, "ZPN"); prj->flag = copysgni (ZPN, prj->flag); prj->phi0 = 0.0; prj->theta0 = 90.0; if (prj->r0 == 0.0) prj->r0 = R2D; /* Find the highest non-zero coefficient. */ for (k = 9; k >= 0 && prj->p[k] == 0.0; k--); if (k < 0) return 1; prj->n = k; if (k >= 3) { /* Find the point of inflection closest to the pole. */ zd1 = 0.0; d1 = prj->p[1]; if (d1 <= 0.0) { return 1; } /* Find the point where the derivative first goes negative. */ for (i = 0; i < 180; i++) { zd2 = i*D2R; d2 = 0.0; for (j = k; j > 0; j--) { d2 = d2*zd2 + j*prj->p[j]; } if (d2 <= 0.0) break; zd1 = zd2; d1 = d2; } if (i == 180) { /* No negative derivative -> no point of inflection. */ zd = PI; } else { /* Find where the derivative is zero. */ for (i = 1; i <= 10; i++) { zd = zd1 - d1*(zd2-zd1)/(d2-d1); d = 0.0; for (j = k; j > 0; j--) { d = d*zd + j*prj->p[j]; } if (fabs(d) < tol) break; if (d < 0.0) { zd2 = zd; d2 = d; } else { zd1 = zd; d1 = d; } } } r = 0.0; for (j = k; j >= 0; j--) { r = r*zd + prj->p[j]; } prj->w[0] = zd; prj->w[1] = r; } prj->prjfwd = zpnfwd; prj->prjrev = zpnrev; return 0; } /*--------------------------------------------------------------------------*/ int zpnfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { int j; double r, s; if (abs(prj->flag) != ZPN) { if (zpnset(prj)) return 1; } s = (90.0 - theta)*D2R; r = 0.0; for (j = 9; j >= 0; j--) { r = r*s + prj->p[j]; } r = prj->r0*r; *x = r*sindeg (phi); *y = -r*cosdeg (phi); if (prj->flag > 0 && s > prj->w[0]) { return 2; } return 0; } /*--------------------------------------------------------------------------*/ int zpnrev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { int i, j, k; double a, b, c, d, lambda, r, r1, r2, rt, zd, zd1, zd2; const double tol = 1.0e-13; if (abs(prj->flag) != ZPN) { if (zpnset(prj)) return 1; } k = prj->n; r = sqrt(x*x + y*y)/prj->r0; if (k < 1) { /* Constant - no solution. */ return 1; } else if (k == 1) { /* Linear. */ zd = (r - prj->p[0])/prj->p[1]; } else if (k == 2) { /* Quadratic. */ a = prj->p[2]; b = prj->p[1]; c = prj->p[0] - r; d = b*b - 4.0*a*c; if (d < 0.0) { return 2; } d = sqrt(d); /* Choose solution closest to pole. */ zd1 = (-b + d)/(2.0*a); zd2 = (-b - d)/(2.0*a); zd = (zd1zd2) ? zd1 : zd2; if (zd < 0.0) { if (zd < -tol) { return 2; } zd = 0.0; } else if (zd > PI) { if (zd > PI+tol) { return 2; } zd = PI; } } else { /* Higher order - solve iteratively. */ zd1 = 0.0; r1 = prj->p[0]; zd2 = prj->w[0]; r2 = prj->w[1]; if (r < r1) { if (r < r1-tol) { return 2; } zd = zd1; } else if (r > r2) { if (r > r2+tol) { return 2; } zd = zd2; } else { /* Disect the interval. */ for (j = 0; j < 100; j++) { lambda = (r2 - r)/(r2 - r1); if (lambda < 0.1) { lambda = 0.1; } else if (lambda > 0.9) { lambda = 0.9; } zd = zd2 - lambda*(zd2 - zd1); rt = 0.0; for (i = k; i >= 0; i--) { rt = (rt * zd) + prj->p[i]; } if (rt < r) { if (r-rt < tol) break; r1 = rt; zd1 = zd; } else { if (rt-r < tol) break; r2 = rt; zd2 = zd; } if (fabs(zd2-zd1) < tol) break; } } } if (r == 0.0) { *phi = 0.0; } else { *phi = atan2deg (x, -y); } *theta = 90.0 - zd*R2D; return 0; } /*============================================================================ * ZEA: zenithal/azimuthal equal area projection. * * Given and/or returned: * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "ZEA" * prj->flag ZEA * prj->phi0 0.0 * prj->theta0 90.0 * prj->w[0] 2*r0 * prj->w[1] 1/(2*r0) * prj->prjfwd Pointer to zeafwd(). * prj->prjrev Pointer to zearev(). *===========================================================================*/ int zeaset(prj) struct prjprm *prj; { strcpy(prj->code, "ZEA"); prj->flag = ZEA; prj->phi0 = 0.0; prj->theta0 = 90.0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 360.0/PI; prj->w[1] = PI/360.0; } else { prj->w[0] = 2.0*prj->r0; prj->w[1] = 1.0/prj->w[0]; } prj->prjfwd = zeafwd; prj->prjrev = zearev; return 0; } /*--------------------------------------------------------------------------*/ int zeafwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { double r; if (prj->flag != ZEA) { if (zeaset(prj)) return 1; } r = prj->w[0]*sindeg ((90.0 - theta)/2.0); *x = r*sindeg (phi); *y = -r*cosdeg (phi); return 0; } /*--------------------------------------------------------------------------*/ int zearev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { double r, s; const double tol = 1.0e-12; if (prj->flag != ZEA) { if (zeaset(prj)) return 1; } r = sqrt(x*x + y*y); if (r == 0.0) { *phi = 0.0; } else { *phi = atan2deg (x, -y); } s = r*prj->w[1]; if (fabs(s) > 1.0) { if (fabs(r - prj->w[0]) < tol) { *theta = -90.0; } else { return 2; } } else { *theta = 90.0 - 2.0*asindeg (s); } return 0; } /*============================================================================ * AIR: Airy's projection. * * Given: * prj->p[1] Latitude theta_b within which the error is minimized, in * degrees. * * Given and/or returned: * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "AIR" * prj->flag AIR * prj->phi0 0.0 * prj->theta0 90.0 * prj->w[0] 2*r0 * prj->w[1] ln(cos(xi_b))/tan(xi_b)**2, where xi_b = (90-theta_b)/2 * prj->w[2] 1/2 - prj->w[1] * prj->w[3] 2*r0*prj->w[2] * prj->w[4] tol, cutoff for using small angle approximation, in * radians. * prj->w[5] prj->w[2]*tol * prj->w[6] (180/pi)/prj->w[2] * prj->prjfwd Pointer to airfwd(). * prj->prjrev Pointer to airrev(). *===========================================================================*/ int airset(prj) struct prjprm *prj; { const double tol = 1.0e-4; double cxi; strcpy(prj->code, "AIR"); prj->flag = AIR; prj->phi0 = 0.0; prj->theta0 = 90.0; if (prj->r0 == 0.0) prj->r0 = R2D; prj->w[0] = 2.0*prj->r0; if (prj->p[1] == 90.0) { prj->w[1] = -0.5; prj->w[2] = 1.0; } else if (prj->p[1] > -90.0) { cxi = cosdeg ((90.0 - prj->p[1])/2.0); prj->w[1] = log(cxi)*(cxi*cxi)/(1.0-cxi*cxi); prj->w[2] = 0.5 - prj->w[1]; } else { return 1; } prj->w[3] = prj->w[0] * prj->w[2]; prj->w[4] = tol; prj->w[5] = prj->w[2]*tol; prj->w[6] = R2D/prj->w[2]; prj->prjfwd = airfwd; prj->prjrev = airrev; return 0; } /*--------------------------------------------------------------------------*/ int airfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { double cxi, r, txi, xi; if (prj->flag != AIR) { if (airset(prj)) return 1; } if (theta == 90.0) { r = 0.0; } else if (theta > -90.0) { xi = D2R*(90.0 - theta)/2.0; if (xi < prj->w[4]) { r = xi*prj->w[3]; } else { cxi = cosdeg ((90.0 - theta)/2.0); txi = sqrt(1.0-cxi*cxi)/cxi; r = -prj->w[0]*(log(cxi)/txi + prj->w[1]*txi); } } else { return 2; } *x = r*sindeg (phi); *y = -r*cosdeg (phi); return 0; } /*--------------------------------------------------------------------------*/ int airrev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { int j; double cxi, lambda, r, r1, r2, rt, txi, x1, x2, xi; const double tol = 1.0e-12; if (prj->flag != AIR) { if (airset(prj)) return 1; } r = sqrt(x*x + y*y)/prj->w[0]; if (r == 0.0) { xi = 0.0; } else if (r < prj->w[5]) { xi = r*prj->w[6]; } else { /* Find a solution interval. */ x1 = 1.0; r1 = 0.0; for (j = 0; j < 30; j++) { x2 = x1/2.0; txi = sqrt(1.0-x2*x2)/x2; r2 = -(log(x2)/txi + prj->w[1]*txi); if (r2 >= r) break; x1 = x2; r1 = r2; } if (j == 30) return 2; for (j = 0; j < 100; j++) { /* Weighted division of the interval. */ lambda = (r2-r)/(r2-r1); if (lambda < 0.1) { lambda = 0.1; } else if (lambda > 0.9) { lambda = 0.9; } cxi = x2 - lambda*(x2-x1); txi = sqrt(1.0-cxi*cxi)/cxi; rt = -(log(cxi)/txi + prj->w[1]*txi); if (rt < r) { if (r-rt < tol) break; r1 = rt; x1 = cxi; } else { if (rt-r < tol) break; r2 = rt; x2 = cxi; } } if (j == 100) return 2; xi = acosdeg (cxi); } if (r == 0.0) { *phi = 0.0; } else { *phi = atan2deg (x, -y); } *theta = 90.0 - 2.0*xi; return 0; } /*============================================================================ * CYP: cylindrical perspective projection. * * Given: * prj->p[1] Distance of point of projection from the centre of the * generating sphere, mu, in units of r0. * prj->p[2] Radius of the cylinder of projection, lambda, in units of * r0. * * Given and/or returned: * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "CYP" * prj->flag CYP * prj->phi0 0.0 * prj->theta0 0.0 * prj->w[0] r0*lambda*(pi/180) * prj->w[1] (180/pi)/(r0*lambda) * prj->w[2] r0*(mu + lambda) * prj->w[3] 1/(r0*(mu + lambda)) * prj->prjfwd Pointer to cypfwd(). * prj->prjrev Pointer to cyprev(). *===========================================================================*/ int cypset(prj) struct prjprm *prj; { strcpy(prj->code, "CYP"); prj->flag = CYP; prj->phi0 = 0.0; prj->theta0 = 0.0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = prj->p[2]; if (prj->w[0] == 0.0) { return 1; } prj->w[1] = 1.0/prj->w[0]; prj->w[2] = R2D*(prj->p[1] + prj->p[2]); if (prj->w[2] == 0.0) { return 1; } prj->w[3] = 1.0/prj->w[2]; } else { prj->w[0] = prj->r0*prj->p[2]*D2R; if (prj->w[0] == 0.0) { return 1; } prj->w[1] = 1.0/prj->w[0]; prj->w[2] = prj->r0*(prj->p[1] + prj->p[2]); if (prj->w[2] == 0.0) { return 1; } prj->w[3] = 1.0/prj->w[2]; } prj->prjfwd = cypfwd; prj->prjrev = cyprev; return 0; } /*--------------------------------------------------------------------------*/ int cypfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { double s; if (prj->flag != CYP) { if (cypset(prj)) return 1; } s = prj->p[1] + cosdeg (theta); if (s == 0.0) { return 2; } *x = prj->w[0]*phi; *y = prj->w[2]*sindeg (theta)/s; return 0; } /*--------------------------------------------------------------------------*/ int cyprev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { double eta; if (prj->flag != CYP) { if (cypset(prj)) return 1; } *phi = x*prj->w[1]; eta = y*prj->w[3]; *theta = atan2deg (eta,1.0) + asindeg (eta*prj->p[1]/sqrt(eta*eta+1.0)); return 0; } /*============================================================================ * CEA: cylindrical equal area projection. * * Given: * prj->p[1] Square of the cosine of the latitude at which the * projection is conformal, lambda. * * Given and/or returned: * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "CEA" * prj->flag CEA * prj->phi0 0.0 * prj->theta0 0.0 * prj->w[0] r0*(pi/180) * prj->w[1] (180/pi)/r0 * prj->w[2] r0/lambda * prj->w[3] lambda/r0 * prj->prjfwd Pointer to ceafwd(). * prj->prjrev Pointer to cearev(). *===========================================================================*/ int ceaset(prj) struct prjprm *prj; { strcpy(prj->code, "CEA"); prj->flag = CEA; prj->phi0 = 0.0; prj->theta0 = 0.0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 1.0; prj->w[1] = 1.0; if (prj->p[1] <= 0.0 || prj->p[1] > 1.0) { return 1; } prj->w[2] = prj->r0/prj->p[1]; prj->w[3] = prj->p[1]/prj->r0; } else { prj->w[0] = prj->r0*D2R; prj->w[1] = R2D/prj->r0; if (prj->p[1] <= 0.0 || prj->p[1] > 1.0) { return 1; } prj->w[2] = prj->r0/prj->p[1]; prj->w[3] = prj->p[1]/prj->r0; } prj->prjfwd = ceafwd; prj->prjrev = cearev; return 0; } /*--------------------------------------------------------------------------*/ int ceafwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { if (prj->flag != CEA) { if (ceaset(prj)) return 1; } *x = prj->w[0]*phi; *y = prj->w[2]*sindeg (theta); return 0; } /*--------------------------------------------------------------------------*/ int cearev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { double s; const double tol = 1.0e-13; if (prj->flag != CEA) { if (ceaset(prj)) return 1; } s = y*prj->w[3]; if (fabs(s) > 1.0) { if (fabs(s) > 1.0+tol) { return 2; } s = copysgn (1.0,s); } *phi = x*prj->w[1]; *theta = asindeg (s); return 0; } /*============================================================================ * CAR: Cartesian projection. * * Given and/or returned: * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "CAR" * prj->flag CAR * prj->phi0 0.0 * prj->theta0 0.0 * prj->w[0] r0*(pi/180) * prj->w[1] (180/pi)/r0 * prj->prjfwd Pointer to carfwd(). * prj->prjrev Pointer to carrev(). *===========================================================================*/ int carset(prj) struct prjprm *prj; { strcpy(prj->code, "CAR"); prj->flag = CAR; prj->phi0 = 0.0; prj->theta0 = 0.0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 1.0; prj->w[1] = 1.0; } else { prj->w[0] = prj->r0*D2R; prj->w[1] = 1.0/prj->w[0]; } prj->prjfwd = carfwd; prj->prjrev = carrev; return 0; } /*--------------------------------------------------------------------------*/ int carfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { if (prj->flag != CAR) { if (carset(prj)) return 1; } *x = prj->w[0]*phi; *y = prj->w[0]*theta; return 0; } /*--------------------------------------------------------------------------*/ int carrev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { if (prj->flag != CAR) { if (carset(prj)) return 1; } *phi = prj->w[1]*x; *theta = prj->w[1]*y; return 0; } /*============================================================================ * MER: Mercator's projection. * * Given and/or returned: * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "MER" * prj->flag MER * prj->phi0 0.0 * prj->theta0 0.0 * prj->w[0] r0*(pi/180) * prj->w[1] (180/pi)/r0 * prj->prjfwd Pointer to merfwd(). * prj->prjrev Pointer to merrev(). *===========================================================================*/ int merset(prj) struct prjprm *prj; { strcpy(prj->code, "MER"); prj->flag = MER; prj->phi0 = 0.0; prj->theta0 = 0.0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 1.0; prj->w[1] = 1.0; } else { prj->w[0] = prj->r0*D2R; prj->w[1] = 1.0/prj->w[0]; } prj->prjfwd = merfwd; prj->prjrev = merrev; return 0; } /*--------------------------------------------------------------------------*/ int merfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { if (prj->flag != MER) { if (merset(prj)) return 1; } if (theta <= -90.0 || theta >= 90.0) { return 2; } *x = prj->w[0]*phi; *y = prj->r0*log(tandeg ((90.0+theta)/2.0)); return 0; } /*--------------------------------------------------------------------------*/ int merrev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { if (prj->flag != MER) { if (merset(prj)) return 1; } *phi = x*prj->w[1]; *theta = 2.0*atandeg (exp(y/prj->r0)) - 90.0; return 0; } /*============================================================================ * SFL: Sanson-Flamsteed ("global sinusoid") projection. * * Given and/or returned: * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "SFL" * prj->flag SFL * prj->phi0 0.0 * prj->theta0 0.0 * prj->w[0] r0*(pi/180) * prj->w[1] (180/pi)/r0 * prj->prjfwd Pointer to sflfwd(). * prj->prjrev Pointer to sflrev(). *===========================================================================*/ int sflset(prj) struct prjprm *prj; { strcpy(prj->code, "SFL"); prj->flag = SFL; prj->phi0 = 0.0; prj->theta0 = 0.0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 1.0; prj->w[1] = 1.0; } else { prj->w[0] = prj->r0*D2R; prj->w[1] = 1.0/prj->w[0]; } prj->prjfwd = sflfwd; prj->prjrev = sflrev; return 0; } /*--------------------------------------------------------------------------*/ int sflfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { if (prj->flag != SFL) { if (sflset(prj)) return 1; } *x = prj->w[0]*phi*cosdeg (theta); *y = prj->w[0]*theta; return 0; } /*--------------------------------------------------------------------------*/ int sflrev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { double w; if (prj->flag != SFL) { if (sflset(prj)) return 1; } w = cos(y/prj->r0); if (w == 0.0) { *phi = 0.0; } else { *phi = x*prj->w[1]/cos(y/prj->r0); } *theta = y*prj->w[1]; return 0; } /*============================================================================ * PAR: parabolic projection. * * Given and/or returned: * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "PAR" * prj->flag PAR * prj->phi0 0.0 * prj->theta0 0.0 * prj->w[0] r0*(pi/180) * prj->w[1] (180/pi)/r0 * prj->w[2] pi*r0 * prj->w[3] 1/(pi*r0) * prj->prjfwd Pointer to parfwd(). * prj->prjrev Pointer to parrev(). *===========================================================================*/ int parset(prj) struct prjprm *prj; { strcpy(prj->code, "PAR"); prj->flag = PAR; prj->phi0 = 0.0; prj->theta0 = 0.0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 1.0; prj->w[1] = 1.0; prj->w[2] = 180.0; prj->w[3] = 1.0/prj->w[2]; } else { prj->w[0] = prj->r0*D2R; prj->w[1] = 1.0/prj->w[0]; prj->w[2] = PI*prj->r0; prj->w[3] = 1.0/prj->w[2]; } prj->prjfwd = parfwd; prj->prjrev = parrev; return 0; } /*--------------------------------------------------------------------------*/ int parfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { double s; if (prj->flag != PAR) { if (parset(prj)) return 1; } s = sindeg (theta/3.0); *x = prj->w[0]*phi*(1.0 - 4.0*s*s); *y = prj->w[2]*s; return 0; } /*--------------------------------------------------------------------------*/ int parrev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { double s, t; if (prj->flag != PAR) { if (parset(prj)) return 1; } s = y*prj->w[3]; if (s > 1.0 || s < -1.0) { return 2; } t = 1.0 - 4.0*s*s; if (t == 0.0) { if (x == 0.0) { *phi = 0.0; } else { return 2; } } else { *phi = prj->w[1]*x/t; } *theta = 3.0*asindeg (s); return 0; } /*============================================================================ * MOL: Mollweide's projection. * * Given and/or returned: * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "MOL" * prj->flag MOL * prj->phi0 0.0 * prj->theta0 0.0 * prj->w[0] sqrt(2)*r0 * prj->w[1] sqrt(2)*r0/90 * prj->w[2] 1/(sqrt(2)*r0) * prj->w[3] 90/r0 * prj->prjfwd Pointer to molfwd(). * prj->prjrev Pointer to molrev(). *===========================================================================*/ int molset(prj) struct prjprm *prj; { strcpy(prj->code, "MOL"); prj->flag = MOL; prj->phi0 = 0.0; prj->theta0 = 0.0; if (prj->r0 == 0.0) prj->r0 = R2D; prj->w[0] = SQRT2*prj->r0; prj->w[1] = prj->w[0]/90.0; prj->w[2] = 1.0/prj->w[0]; prj->w[3] = 90.0/prj->r0; prj->w[4] = 2.0/PI; prj->prjfwd = molfwd; prj->prjrev = molrev; return 0; } /*--------------------------------------------------------------------------*/ int molfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { int j; double gamma, resid, u, v, v0, v1; const double tol = 1.0e-13; if (prj->flag != MOL) { if (molset(prj)) return 1; } if (fabs(theta) == 90.0) { *x = 0.0; *y = copysgn (prj->w[0],theta); } else if (theta == 0.0) { *x = prj->w[1]*phi; *y = 0.0; } else { u = PI*sindeg (theta); v0 = -PI; v1 = PI; v = u; for (j = 0; j < 100; j++) { resid = (v - u) + sin(v); if (resid < 0.0) { if (resid > -tol) break; v0 = v; } else { if (resid < tol) break; v1 = v; } v = (v0 + v1)/2.0; } gamma = v/2.0; *x = prj->w[1]*phi*cos(gamma); *y = prj->w[0]*sin(gamma); } return 0; } /*--------------------------------------------------------------------------*/ int molrev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { double s, y0, z; const double tol = 1.0e-12; if (prj->flag != MOL) { if (molset(prj)) return 1; } y0 = y/prj->r0; s = 2.0 - y0*y0; if (s <= tol) { if (s < -tol) { return 2; } s = 0.0; if (fabs(x) > tol) { return 2; } *phi = 0.0; } else { s = sqrt(s); *phi = prj->w[3]*x/s; } z = y*prj->w[2]; if (fabs(z) > 1.0) { if (fabs(z) > 1.0+tol) { return 2; } z = copysgn (1.0,z) + y0*s/PI; } else { z = asin(z)*prj->w[4] + y0*s/PI; } if (fabs(z) > 1.0) { if (fabs(z) > 1.0+tol) { return 2; } z = copysgn (1.0,z); } *theta = asindeg (z); return 0; } /*============================================================================ * AIT: Hammer-Aitoff projection. * * Given and/or returned: * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "AIT" * prj->flag AIT * prj->phi0 0.0 * prj->theta0 0.0 * prj->w[0] 2*r0**2 * prj->w[1] 1/(2*r0)**2 * prj->w[2] 1/(4*r0)**2 * prj->w[3] 1/(2*r0) * prj->prjfwd Pointer to aitfwd(). * prj->prjrev Pointer to aitrev(). *===========================================================================*/ int aitset(prj) struct prjprm *prj; { strcpy(prj->code, "AIT"); prj->flag = AIT; prj->phi0 = 0.0; prj->theta0 = 0.0; if (prj->r0 == 0.0) prj->r0 = R2D; prj->w[0] = 2.0*prj->r0*prj->r0; prj->w[1] = 1.0/(2.0*prj->w[0]); prj->w[2] = prj->w[1]/4.0; prj->w[3] = 1.0/(2.0*prj->r0); prj->prjfwd = aitfwd; prj->prjrev = aitrev; return 0; } /*--------------------------------------------------------------------------*/ int aitfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { double cthe, w; if (prj->flag != AIT) { if (aitset(prj)) return 1; } cthe = cosdeg (theta); w = sqrt(prj->w[0]/(1.0 + cthe*cosdeg (phi/2.0))); *x = 2.0*w*cthe*sindeg (phi/2.0); *y = w*sindeg (theta); return 0; } /*--------------------------------------------------------------------------*/ int aitrev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { double s, u, xp, yp, z; const double tol = 1.0e-13; if (prj->flag != AIT) { if (aitset(prj)) return 1; } u = 1.0 - x*x*prj->w[2] - y*y*prj->w[1]; if (u < 0.0) { if (u < -tol) { return 2; } u = 0.0; } z = sqrt(u); s = z*y/prj->r0; if (fabs(s) > 1.0) { if (fabs(s) > 1.0+tol) { return 2; } s = copysgn (1.0,s); } xp = 2.0*z*z - 1.0; yp = z*x*prj->w[3]; if (xp == 0.0 && yp == 0.0) { *phi = 0.0; } else { *phi = 2.0*atan2deg (yp, xp); } *theta = asindeg (s); return 0; } /*============================================================================ * COP: conic perspective projection. * * Given: * prj->p[1] sigma = (theta2+theta1)/2 * prj->p[2] delta = (theta2-theta1)/2, where theta1 and theta2 are the * latitudes of the standard parallels, in degrees. * * Given and/or returned: * prj->flag COP, or -COP if prj->flag is given < 0. * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "COP" * prj->phi0 0.0 * prj->theta0 sigma * prj->w[0] C = sin(sigma) * prj->w[1] 1/C * prj->w[2] Y0 = r0*cos(delta)*cot(sigma) * prj->w[3] r0*cos(delta) * prj->w[4] 1/(r0*cos(delta) * prj->w[5] cot(sigma) * prj->prjfwd Pointer to copfwd(). * prj->prjrev Pointer to coprev(). *===========================================================================*/ int copset(prj) struct prjprm *prj; { strcpy(prj->code, "COP"); prj->flag = copysgni (COP, prj->flag); prj->phi0 = 0.0; prj->theta0 = prj->p[1]; if (prj->r0 == 0.0) prj->r0 = R2D; prj->w[0] = sindeg (prj->p[1]); if (prj->w[0] == 0.0) { return 1; } prj->w[1] = 1.0/prj->w[0]; prj->w[3] = prj->r0*cosdeg (prj->p[2]); if (prj->w[3] == 0.0) { return 1; } prj->w[4] = 1.0/prj->w[3]; prj->w[5] = 1.0/tandeg (prj->p[1]); prj->w[2] = prj->w[3]*prj->w[5]; prj->prjfwd = copfwd; prj->prjrev = coprev; return 0; } /*--------------------------------------------------------------------------*/ int copfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { double a, r, s, t; if (abs(prj->flag) != COP) { if (copset(prj)) return 1; } t = theta - prj->p[1]; s = cosdeg (t); if (s == 0.0) { return 2; } a = prj->w[0]*phi; r = prj->w[2] - prj->w[3]*sindeg (t)/s; *x = r*sindeg (a); *y = prj->w[2] - r*cosdeg (a); if (prj->flag > 0 && r*prj->w[0] < 0.0) { return 2; } return 0; } /*--------------------------------------------------------------------------*/ int coprev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { double a, dy, r; if (abs(prj->flag) != COP) { if (copset(prj)) return 1; } dy = prj->w[2] - y; r = sqrt(x*x + dy*dy); if (prj->p[1] < 0.0) r = -r; if (r == 0.0) { a = 0.0; } else { a = atan2deg (x/r, dy/r); } *phi = a*prj->w[1]; *theta = prj->p[1] + atandeg (prj->w[5] - r*prj->w[4]); return 0; } /*============================================================================ * COE: conic equal area projection. * * Given: * prj->p[1] sigma = (theta2+theta1)/2 * prj->p[2] delta = (theta2-theta1)/2, where theta1 and theta2 are the * latitudes of the standard parallels, in degrees. * * Given and/or returned: * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "COE" * prj->flag COE * prj->phi0 0.0 * prj->theta0 sigma * prj->w[0] C = (sin(theta1) + sin(theta2))/2 * prj->w[1] 1/C * prj->w[2] Y0 = chi*sqrt(psi - 2C*sindeg (sigma)) * prj->w[3] chi = r0/C * prj->w[4] psi = 1 + sin(theta1)*sin(theta2) * prj->w[5] 2C * prj->w[6] (1 + sin(theta1)*sin(theta2))*(r0/C)**2 * prj->w[7] C/(2*r0**2) * prj->w[8] chi*sqrt(psi + 2C) * prj->prjfwd Pointer to coefwd(). * prj->prjrev Pointer to coerev(). *===========================================================================*/ int coeset(prj) struct prjprm *prj; { double theta1, theta2; strcpy(prj->code, "COE"); prj->flag = COE; prj->phi0 = 0.0; prj->theta0 = prj->p[1]; if (prj->r0 == 0.0) prj->r0 = R2D; theta1 = prj->p[1] - prj->p[2]; theta2 = prj->p[1] + prj->p[2]; prj->w[0] = (sindeg (theta1) + sindeg (theta2))/2.0; if (prj->w[0] == 0.0) { return 1; } prj->w[1] = 1.0/prj->w[0]; prj->w[3] = prj->r0/prj->w[0]; prj->w[4] = 1.0 + sindeg (theta1)*sindeg (theta2); prj->w[5] = 2.0*prj->w[0]; prj->w[6] = prj->w[3]*prj->w[3]*prj->w[4]; prj->w[7] = 1.0/(2.0*prj->r0*prj->w[3]); prj->w[8] = prj->w[3]*sqrt(prj->w[4] + prj->w[5]); prj->w[2] = prj->w[3]*sqrt(prj->w[4] - prj->w[5]*sindeg (prj->p[1])); prj->prjfwd = coefwd; prj->prjrev = coerev; return 0; } /*--------------------------------------------------------------------------*/ int coefwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { double a, r; if (prj->flag != COE) { if (coeset(prj)) return 1; } a = phi*prj->w[0]; if (theta == -90.0) { r = prj->w[8]; } else { r = prj->w[3]*sqrt(prj->w[4] - prj->w[5]*sindeg (theta)); } *x = r*sindeg (a); *y = prj->w[2] - r*cosdeg (a); return 0; } /*--------------------------------------------------------------------------*/ int coerev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { double a, dy, r, w; const double tol = 1.0e-12; if (prj->flag != COE) { if (coeset(prj)) return 1; } dy = prj->w[2] - y; r = sqrt(x*x + dy*dy); if (prj->p[1] < 0.0) r = -r; if (r == 0.0) { a = 0.0; } else { a = atan2deg (x/r, dy/r); } *phi = a*prj->w[1]; if (fabs(r - prj->w[8]) < tol) { *theta = -90.0; } else { w = (prj->w[6] - r*r)*prj->w[7]; if (fabs(w) > 1.0) { if (fabs(w-1.0) < tol) { *theta = 90.0; } else if (fabs(w+1.0) < tol) { *theta = -90.0; } else { return 2; } } else { *theta = asindeg (w); } } return 0; } /*============================================================================ * COD: conic equidistant projection. * * Given: * prj->p[1] sigma = (theta2+theta1)/2 * prj->p[2] delta = (theta2-theta1)/2, where theta1 and theta2 are the * latitudes of the standard parallels, in degrees. * * Given and/or returned: * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "COD" * prj->flag COD * prj->phi0 0.0 * prj->theta0 sigma * prj->w[0] C = r0*sin(sigma)*sin(delta)/delta * prj->w[1] 1/C * prj->w[2] Y0 = delta*cot(delta)*cot(sigma) * prj->w[3] Y0 + sigma * prj->prjfwd Pointer to codfwd(). * prj->prjrev Pointer to codrev(). *===========================================================================*/ int codset(prj) struct prjprm *prj; { strcpy(prj->code, "COD"); prj->flag = COD; prj->phi0 = 0.0; prj->theta0 = prj->p[1]; if (prj->r0 == 0.0) prj->r0 = R2D; if (prj->p[2] == 0.0) { prj->w[0] = prj->r0*sindeg (prj->p[1])*D2R; } else { prj->w[0] = prj->r0*sindeg (prj->p[1])*sindeg (prj->p[2])/prj->p[2]; } if (prj->w[0] == 0.0) { return 1; } prj->w[1] = 1.0/prj->w[0]; prj->w[2] = prj->r0*cosdeg (prj->p[2])*cosdeg (prj->p[1])/prj->w[0]; prj->w[3] = prj->w[2] + prj->p[1]; prj->prjfwd = codfwd; prj->prjrev = codrev; return 0; } /*--------------------------------------------------------------------------*/ int codfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { double a, r; if (prj->flag != COD) { if (codset(prj)) return 1; } a = prj->w[0]*phi; r = prj->w[3] - theta; *x = r*sindeg (a); *y = prj->w[2] - r*cosdeg (a); return 0; } /*--------------------------------------------------------------------------*/ int codrev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { double a, dy, r; if (prj->flag != COD) { if (codset(prj)) return 1; } dy = prj->w[2] - y; r = sqrt(x*x + dy*dy); if (prj->p[1] < 0.0) r = -r; if (r == 0.0) { a = 0.0; } else { a = atan2deg (x/r, dy/r); } *phi = a*prj->w[1]; *theta = prj->w[3] - r; return 0; } /*============================================================================ * COO: conic orthomorphic projection. * * Given: * prj->p[1] sigma = (theta2+theta1)/2 * prj->p[2] delta = (theta2-theta1)/2, where theta1 and theta2 are the * latitudes of the standard parallels, in degrees. * * Given and/or returned: * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "COO" * prj->flag COO * prj->phi0 0.0 * prj->theta0 sigma * prj->w[0] C = ln(cos(theta2)/cos(theta1))/ln(tan(tau2)/tan(tau1)) * where tau1 = (90 - theta1)/2 * tau2 = (90 - theta2)/2 * prj->w[1] 1/C * prj->w[2] Y0 = psi*tan((90-sigma)/2)**C * prj->w[3] psi = (r0*cos(theta1)/C)/tan(tau1)**C * prj->w[4] 1/psi * prj->prjfwd Pointer to coofwd(). * prj->prjrev Pointer to coorev(). *===========================================================================*/ int cooset(prj) struct prjprm *prj; { double cos1, cos2, tan1, tan2, theta1, theta2; strcpy(prj->code, "COO"); prj->flag = COO; prj->phi0 = 0.0; prj->theta0 = prj->p[1]; if (prj->r0 == 0.0) prj->r0 = R2D; theta1 = prj->p[1] - prj->p[2]; theta2 = prj->p[1] + prj->p[2]; tan1 = tandeg ((90.0 - theta1)/2.0); cos1 = cosdeg (theta1); if (theta1 == theta2) { prj->w[0] = sindeg (theta1); } else { tan2 = tandeg ((90.0 - theta2)/2.0); cos2 = cosdeg (theta2); prj->w[0] = log(cos2/cos1)/log(tan2/tan1); } if (prj->w[0] == 0.0) { return 1; } prj->w[1] = 1.0/prj->w[0]; prj->w[3] = prj->r0*(cos1/prj->w[0])/pow(tan1,prj->w[0]); if (prj->w[3] == 0.0) { return 1; } prj->w[2] = prj->w[3]*pow(tandeg ((90.0 - prj->p[1])/2.0),prj->w[0]); prj->w[4] = 1.0/prj->w[3]; prj->prjfwd = coofwd; prj->prjrev = coorev; return 0; } /*--------------------------------------------------------------------------*/ int coofwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { double a, r; if (prj->flag != COO) { if (cooset(prj)) return 1; } a = prj->w[0]*phi; if (theta == -90.0) { if (prj->w[0] < 0.0) { r = 0.0; } else { return 2; } } else { r = prj->w[3]*pow(tandeg ((90.0 - theta)/2.0),prj->w[0]); } *x = r*sindeg (a); *y = prj->w[2] - r*cosdeg (a); return 0; } /*--------------------------------------------------------------------------*/ int coorev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { double a, dy, r; if (prj->flag != COO) { if (cooset(prj)) return 1; } dy = prj->w[2] - y; r = sqrt(x*x + dy*dy); if (prj->p[1] < 0.0) r = -r; if (r == 0.0) { a = 0.0; } else { a = atan2deg (x/r, dy/r); } *phi = a*prj->w[1]; if (r == 0.0) { if (prj->w[0] < 0.0) { *theta = -90.0; } else { return 2; } } else { *theta = 90.0 - 2.0*atandeg (pow(r*prj->w[4],prj->w[1])); } return 0; } /*============================================================================ * BON: Bonne's projection. * * Given: * prj->p[1] Bonne conformal latitude, theta1, in degrees. * * Given and/or returned: * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "BON" * prj->flag BON * prj->phi0 0.0 * prj->theta0 0.0 * prj->w[1] r0*pi/180 * prj->w[2] Y0 = r0*(cot(theta1) + theta1*pi/180) * prj->prjfwd Pointer to bonfwd(). * prj->prjrev Pointer to bonrev(). *===========================================================================*/ int bonset(prj) struct prjprm *prj; { strcpy(prj->code, "BON"); prj->flag = BON; prj->phi0 = 0.0; prj->theta0 = 0.0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[1] = 1.0; prj->w[2] = prj->r0*cosdeg (prj->p[1])/sindeg (prj->p[1]) + prj->p[1]; } else { prj->w[1] = prj->r0*D2R; prj->w[2] = prj->r0*(cosdeg (prj->p[1])/sindeg (prj->p[1]) + prj->p[1]*D2R); } prj->prjfwd = bonfwd; prj->prjrev = bonrev; return 0; } /*--------------------------------------------------------------------------*/ int bonfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { double a, r; if (prj->p[1] == 0.0) { /* Sanson-Flamsteed. */ return sflfwd(phi, theta, prj, x, y); } if (prj->flag != BON) { if (bonset(prj)) return 1; } r = prj->w[2] - theta*prj->w[1]; a = prj->r0*phi*cosdeg (theta)/r; *x = r*sindeg (a); *y = prj->w[2] - r*cosdeg (a); return 0; } /*--------------------------------------------------------------------------*/ int bonrev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { double a, cthe, dy, r; if (prj->p[1] == 0.0) { /* Sanson-Flamsteed. */ return sflrev(x, y, prj, phi, theta); } if (prj->flag != BON) { if (bonset(prj)) return 1; } dy = prj->w[2] - y; r = sqrt(x*x + dy*dy); if (prj->p[1] < 0.0) r = -r; if (r == 0.0) { a = 0.0; } else { a = atan2deg (x/r, dy/r); } *theta = (prj->w[2] - r)/prj->w[1]; cthe = cosdeg (*theta); if (cthe == 0.0) { *phi = 0.0; } else { *phi = a*(r/prj->r0)/cthe; } return 0; } /*============================================================================ * PCO: polyconic projection. * * Given and/or returned: * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "PCO" * prj->flag PCO * prj->phi0 0.0 * prj->theta0 0.0 * prj->w[0] r0*(pi/180) * prj->w[1] 1/r0 * prj->w[2] 2*r0 * prj->prjfwd Pointer to pcofwd(). * prj->prjrev Pointer to pcorev(). *===========================================================================*/ int pcoset(prj) struct prjprm *prj; { strcpy(prj->code, "PCO"); prj->flag = PCO; prj->phi0 = 0.0; prj->theta0 = 0.0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 1.0; prj->w[1] = 1.0; prj->w[2] = 360.0/PI; } else { prj->w[0] = prj->r0*D2R; prj->w[1] = 1.0/prj->w[0]; prj->w[2] = 2.0*prj->r0; } prj->prjfwd = pcofwd; prj->prjrev = pcorev; return 0; } /*--------------------------------------------------------------------------*/ int pcofwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { double a, cthe, cotthe, sthe; if (prj->flag != PCO) { if (pcoset(prj)) return 1; } cthe = cosdeg (theta); sthe = sindeg (theta); a = phi*sthe; if (sthe == 0.0) { *x = prj->w[0]*phi; *y = 0.0; } else { cotthe = cthe/sthe; *x = prj->r0*cotthe*sindeg (a); *y = prj->r0*(cotthe*(1.0 - cosdeg (a)) + theta*D2R); } return 0; } /*--------------------------------------------------------------------------*/ int pcorev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { int j; double f, fneg, fpos, lambda, tanthe, theneg, thepos, w, xp, xx, ymthe, yp; const double tol = 1.0e-12; if (prj->flag != PCO) { if (pcoset(prj)) return 1; } w = fabs(y*prj->w[1]); if (w < tol) { *phi = x*prj->w[1]; *theta = 0.0; } else if (fabs(w-90.0) < tol) { *phi = 0.0; *theta = copysgni (90.0,y); } else { /* Iterative solution using weighted division of the interval. */ if (y > 0.0) { thepos = 90.0; } else { thepos = -90.0; } theneg = 0.0; xx = x*x; ymthe = y - prj->w[0]*thepos; fpos = xx + ymthe*ymthe; fneg = -999.0; for (j = 0; j < 64; j++) { if (fneg < -100.0) { /* Equal division of the interval. */ *theta = (thepos+theneg)/2.0; } else { /* Weighted division of the interval. */ lambda = fpos/(fpos-fneg); if (lambda < 0.1) { lambda = 0.1; } else if (lambda > 0.9) { lambda = 0.9; } *theta = thepos - lambda*(thepos-theneg); } /* Compute the residue. */ ymthe = y - prj->w[0]*(*theta); tanthe = tandeg (*theta); f = xx + ymthe*(ymthe - prj->w[2]/tanthe); /* Check for convergence. */ if (fabs(f) < tol) break; if (fabs(thepos-theneg) < tol) break; /* Redefine the interval. */ if (f > 0.0) { thepos = *theta; fpos = f; } else { theneg = *theta; fneg = f; } } xp = prj->r0 - ymthe*tanthe; yp = x*tanthe; if (xp == 0.0 && yp == 0.0) { *phi = 0.0; } else { *phi = atan2deg (yp, xp)/sindeg (*theta); } } return 0; } /*============================================================================ * TSC: tangential spherical cube projection. * * Given and/or returned: * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "TSC" * prj->flag TSC * prj->phi0 0.0 * prj->theta0 0.0 * prj->w[0] r0*(pi/4) * prj->w[1] (4/pi)/r0 * prj->prjfwd Pointer to tscfwd(). * prj->prjrev Pointer to tscrev(). *===========================================================================*/ int tscset(prj) struct prjprm *prj; { strcpy(prj->code, "TSC"); prj->flag = TSC; prj->phi0 = 0.0; prj->theta0 = 0.0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 45.0; prj->w[1] = 1.0/45.0; } else { prj->w[0] = prj->r0*PI/4.0; prj->w[1] = 1.0/prj->w[0]; } prj->prjfwd = tscfwd; prj->prjrev = tscrev; return 0; } /*--------------------------------------------------------------------------*/ int tscfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { int face; double cthe, l, m, n, rho; double x0 = 0.0; double y0 = 0.0; double xf = 0.0; double yf = 0.0; const double tol = 1.0e-12; if (prj->flag != TSC) { if (tscset(prj)) return 1; } cthe = cosdeg (theta); l = cthe*cosdeg (phi); m = cthe*sindeg (phi); n = sindeg (theta); face = 0; rho = n; if (l > rho) { face = 1; rho = l; } if (m > rho) { face = 2; rho = m; } if (-l > rho) { face = 3; rho = -l; } if (-m > rho) { face = 4; rho = -m; } if (-n > rho) { face = 5; rho = -n; } if (face == 0) { xf = m/rho; yf = -l/rho; x0 = 0.0; y0 = 2.0; } else if (face == 1) { xf = m/rho; yf = n/rho; x0 = 0.0; y0 = 0.0; } else if (face == 2) { xf = -l/rho; yf = n/rho; x0 = 2.0; y0 = 0.0; } else if (face == 3) { xf = -m/rho; yf = n/rho; x0 = 4.0; y0 = 0.0; } else if (face == 4) { xf = l/rho; yf = n/rho; x0 = 6.0; y0 = 0.0; } else if (face == 5) { xf = m/rho; yf = l/rho; x0 = 0.0; y0 = -2.0; } if (fabs(xf) > 1.0) { if (fabs(xf) > 1.0+tol) { return 2; } xf = copysgn (1.0,xf); } if (fabs(yf) > 1.0) { if (fabs(yf) > 1.0+tol) { return 2; } yf = copysgn (1.0,yf); } *x = prj->w[0]*(xf + x0); *y = prj->w[0]*(yf + y0); return 0; } /*--------------------------------------------------------------------------*/ int tscrev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { double l, m, n, xf, yf; if (prj->flag != TSC) { if (tscset(prj)) return 1; } xf = x*prj->w[1]; yf = y*prj->w[1]; /* Check bounds. */ if (fabs(xf) <= 1.0) { if (fabs(yf) > 3.0) return 2; } else { if (fabs(xf) > 7.0) return 2; if (fabs(yf) > 1.0) return 2; } /* Map negative faces to the other side. */ if (xf < -1.0) xf += 8.0; /* Determine the face. */ if (xf > 5.0) { /* face = 4 */ xf = xf - 6.0; m = -1.0/sqrt(1.0 + xf*xf + yf*yf); l = -m*xf; n = -m*yf; } else if (xf > 3.0) { /* face = 3 */ xf = xf - 4.0; l = -1.0/sqrt(1.0 + xf*xf + yf*yf); m = l*xf; n = -l*yf; } else if (xf > 1.0) { /* face = 2 */ xf = xf - 2.0; m = 1.0/sqrt(1.0 + xf*xf + yf*yf); l = -m*xf; n = m*yf; } else if (yf > 1.0) { /* face = 0 */ yf = yf - 2.0; n = 1.0/sqrt(1.0 + xf*xf + yf*yf); l = -n*yf; m = n*xf; } else if (yf < -1.0) { /* face = 5 */ yf = yf + 2.0; n = -1.0/sqrt(1.0 + xf*xf + yf*yf); l = -n*yf; m = -n*xf; } else { /* face = 1 */ l = 1.0/sqrt(1.0 + xf*xf + yf*yf); m = l*xf; n = l*yf; } if (l == 0.0 && m == 0.0) { *phi = 0.0; } else { *phi = atan2deg (m, l); } *theta = asindeg (n); return 0; } /*============================================================================ * CSC: COBE quadrilateralized spherical cube projection. * * Given and/or returned: * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "CSC" * prj->flag CSC * prj->phi0 0.0 * prj->theta0 0.0 * prj->w[0] r0*(pi/4) * prj->w[1] (4/pi)/r0 * prj->prjfwd Pointer to cscfwd(). * prj->prjrev Pointer to cscrev(). *===========================================================================*/ int cscset(prj) struct prjprm *prj; { strcpy(prj->code, "CSC"); prj->flag = CSC; prj->phi0 = 0.0; prj->theta0 = 0.0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 45.0; prj->w[1] = 1.0/45.0; } else { prj->w[0] = prj->r0*PI/4.0; prj->w[1] = 1.0/prj->w[0]; } prj->prjfwd = cscfwd; prj->prjrev = cscrev; return 0; } /*--------------------------------------------------------------------------*/ int cscfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { int face; double cthe, eta, l, m, n, rho, xi; const float tol = 1.0e-7; float a, a2, a2b2, a4, ab, b, b2, b4, ca2, cb2; float x0 = 0.0; float y0 = 0.0; float xf = 0.0; float yf = 0.0; const float gstar = 1.37484847732; const float mm = 0.004869491981; const float gamma = -0.13161671474; const float omega1 = -0.159596235474; const float d0 = 0.0759196200467; const float d1 = -0.0217762490699; const float c00 = 0.141189631152; const float c10 = 0.0809701286525; const float c01 = -0.281528535557; const float c11 = 0.15384112876; const float c20 = -0.178251207466; const float c02 = 0.106959469314; if (prj->flag != CSC) { if (cscset(prj)) return 1; } cthe = cosdeg (theta); l = cthe*cosdeg (phi); m = cthe*sindeg (phi); n = sindeg (theta); face = 0; rho = n; if (l > rho) { face = 1; rho = l; } if (m > rho) { face = 2; rho = m; } if (-l > rho) { face = 3; rho = -l; } if (-m > rho) { face = 4; rho = -m; } if (-n > rho) { face = 5; rho = -n; } if (face == 0) { xi = m; eta = -l; x0 = 0.0; y0 = 2.0; } else if (face == 1) { xi = m; eta = n; x0 = 0.0; y0 = 0.0; } else if (face == 2) { xi = -l; eta = n; x0 = 2.0; y0 = 0.0; } else if (face == 3) { xi = -m; eta = n; x0 = 4.0; y0 = 0.0; } else if (face == 4) { xi = l; eta = n; x0 = 6.0; y0 = 0.0; } else if (face == 5) { xi = m; eta = l; x0 = 0.0; y0 = -2.0; } a = xi/rho; b = eta/rho; a2 = a*a; b2 = b*b; ca2 = 1.0 - a2; cb2 = 1.0 - b2; /* Avoid floating underflows. */ ab = fabs(a*b); a4 = (a2 > 1.0e-16) ? a2*a2 : 0.0; b4 = (b2 > 1.0e-16) ? b2*b2 : 0.0; a2b2 = (ab > 1.0e-16) ? a2*b2 : 0.0; xf = a*(a2 + ca2*(gstar + b2*(gamma*ca2 + mm*a2 + cb2*(c00 + c10*a2 + c01*b2 + c11*a2b2 + c20*a4 + c02*b4)) + a2*(omega1 - ca2*(d0 + d1*a2)))); yf = b*(b2 + cb2*(gstar + a2*(gamma*cb2 + mm*b2 + ca2*(c00 + c10*b2 + c01*a2 + c11*a2b2 + c20*b4 + c02*a4)) + b2*(omega1 - cb2*(d0 + d1*b2)))); if (fabs(xf) > 1.0) { if (fabs(xf) > 1.0+tol) { return 2; } xf = copysgn (1.0,xf); } if (fabs(yf) > 1.0) { if (fabs(yf) > 1.0+tol) { return 2; } yf = copysgn (1.0,yf); } *x = prj->w[0]*(x0 + xf); *y = prj->w[0]*(y0 + yf); return 0; } /*--------------------------------------------------------------------------*/ int cscrev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { int face; double l = 0.0; double m = 0.0; double n = 0.0; float a, b, xf, xx, yf, yy, z0, z1, z2, z3, z4, z5, z6; const float p00 = -0.27292696; const float p10 = -0.07629969; const float p20 = -0.22797056; const float p30 = 0.54852384; const float p40 = -0.62930065; const float p50 = 0.25795794; const float p60 = 0.02584375; const float p01 = -0.02819452; const float p11 = -0.01471565; const float p21 = 0.48051509; const float p31 = -1.74114454; const float p41 = 1.71547508; const float p51 = -0.53022337; const float p02 = 0.27058160; const float p12 = -0.56800938; const float p22 = 0.30803317; const float p32 = 0.98938102; const float p42 = -0.83180469; const float p03 = -0.60441560; const float p13 = 1.50880086; const float p23 = -0.93678576; const float p33 = 0.08693841; const float p04 = 0.93412077; const float p14 = -1.41601920; const float p24 = 0.33887446; const float p05 = -0.63915306; const float p15 = 0.52032238; const float p06 = 0.14381585; if (prj->flag != CSC) { if (cscset(prj)) return 1; } xf = x*prj->w[1]; yf = y*prj->w[1]; /* Check bounds. */ if (fabs(xf) <= 1.0) { if (fabs(yf) > 3.0) return 2; } else { if (fabs(xf) > 7.0) return 2; if (fabs(yf) > 1.0) return 2; } /* Map negative faces to the other side. */ if (xf < -1.0) xf += 8.0; /* Determine the face. */ if (xf > 5.0) { face = 4; xf = xf - 6.0; } else if (xf > 3.0) { face = 3; xf = xf - 4.0; } else if (xf > 1.0) { face = 2; xf = xf - 2.0; } else if (yf > 1.0) { face = 0; yf = yf - 2.0; } else if (yf < -1.0) { face = 5; yf = yf + 2.0; } else { face = 1; } xx = xf*xf; yy = yf*yf; z0 = p00 + xx*(p10 + xx*(p20 + xx*(p30 + xx*(p40 + xx*(p50 + xx*(p60)))))); z1 = p01 + xx*(p11 + xx*(p21 + xx*(p31 + xx*(p41 + xx*(p51))))); z2 = p02 + xx*(p12 + xx*(p22 + xx*(p32 + xx*(p42)))); z3 = p03 + xx*(p13 + xx*(p23 + xx*(p33))); z4 = p04 + xx*(p14 + xx*(p24)); z5 = p05 + xx*(p15); z6 = p06; a = z0 + yy*(z1 + yy*(z2 + yy*(z3 + yy*(z4 + yy*(z5 + yy*z6))))); a = xf + xf*(1.0 - xx)*a; z0 = p00 + yy*(p10 + yy*(p20 + yy*(p30 + yy*(p40 + yy*(p50 + yy*(p60)))))); z1 = p01 + yy*(p11 + yy*(p21 + yy*(p31 + yy*(p41 + yy*(p51))))); z2 = p02 + yy*(p12 + yy*(p22 + yy*(p32 + yy*(p42)))); z3 = p03 + yy*(p13 + yy*(p23 + yy*(p33))); z4 = p04 + yy*(p14 + yy*(p24)); z5 = p05 + yy*(p15); z6 = p06; b = z0 + xx*(z1 + xx*(z2 + xx*(z3 + xx*(z4 + xx*(z5 + xx*z6))))); b = yf + yf*(1.0 - yy)*b; if (face == 0) { n = 1.0/sqrt(a*a + b*b + 1.0); l = -b*n; m = a*n; } else if (face == 1) { l = 1.0/sqrt(a*a + b*b + 1.0); m = a*l; n = b*l; } else if (face == 2) { m = 1.0/sqrt(a*a + b*b + 1.0); l = -a*m; n = b*m; } else if (face == 3) { l = -1.0/sqrt(a*a + b*b + 1.0); m = a*l; n = -b*l; } else if (face == 4) { m = -1.0/sqrt(a*a + b*b + 1.0); l = -a*m; n = -b*m; } else if (face == 5) { n = -1.0/sqrt(a*a + b*b + 1.0); l = -b*n; m = -a*n; } if (l == 0.0 && m == 0.0) { *phi = 0.0; } else { *phi = atan2deg (m, l); } *theta = asindeg (n); return 0; } /*============================================================================ * QSC: quadrilaterilized spherical cube projection. * * Given and/or returned: * prj->r0 r0; reset to 180/pi if 0. * * Returned: * prj->code "QSC" * prj->flag QSC * prj->phi0 0.0 * prj->theta0 0.0 * prj->w[0] r0*(pi/4) * prj->w[1] (4/pi)/r0 * prj->prjfwd Pointer to qscfwd(). * prj->prjrev Pointer to qscrev(). *===========================================================================*/ int qscset(prj) struct prjprm *prj; { strcpy(prj->code, "QSC"); prj->flag = QSC; prj->phi0 = 0.0; prj->theta0 = 0.0; if (prj->r0 == 0.0) { prj->r0 = R2D; prj->w[0] = 45.0; prj->w[1] = 1.0/45.0; } else { prj->w[0] = prj->r0*PI/4.0; prj->w[1] = 1.0/prj->w[0]; } prj->prjfwd = qscfwd; prj->prjrev = qscrev; return 0; } /*--------------------------------------------------------------------------*/ int qscfwd(phi, theta, prj, x, y) const double phi, theta; struct prjprm *prj; double *x, *y; { int face; double cthe, l, m, n, omega, p, rho, rhu, t, tau; double xi = 0.0; double eta = 0.0; double x0 = 0.0; double y0 = 0.0; double xf = 0.0; double yf = 0.0; const double tol = 1.0e-12; if (prj->flag != QSC) { if (qscset(prj)) return 1; } if (fabs(theta) == 90.0) { *x = 0.0; *y = copysgn (2.0*prj->w[0],theta); return 0; } cthe = cosdeg (theta); l = cthe*cosdeg (phi); m = cthe*sindeg (phi); n = sindeg (theta); face = 0; rho = n; if (l > rho) { face = 1; rho = l; } if (m > rho) { face = 2; rho = m; } if (-l > rho) { face = 3; rho = -l; } if (-m > rho) { face = 4; rho = -m; } if (-n > rho) { face = 5; rho = -n; } rhu = 1.0 - rho; if (face == 0) { xi = m; eta = -l; if (rhu < 1.0e-8) { /* Small angle formula. */ t = (90.0 - theta)*D2R; rhu = t*t/2.0; } x0 = 0.0; y0 = 2.0; } else if (face == 1) { xi = m; eta = n; if (rhu < 1.0e-8) { /* Small angle formula. */ t = theta*D2R; p = fmod(phi,360.0); if (p < -180.0) p += 360.0; if (p > 180.0) p -= 360.0; p *= D2R; rhu = (p*p + t*t)/2.0; } x0 = 0.0; y0 = 0.0; } else if (face == 2) { xi = -l; eta = n; if (rhu < 1.0e-8) { /* Small angle formula. */ t = theta*D2R; p = fmod(phi,360.0); if (p < -180.0) p += 360.0; p = (90.0 - p)*D2R; rhu = (p*p + t*t)/2.0; } x0 = 2.0; y0 = 0.0; } else if (face == 3) { xi = -m; eta = n; if (rhu < 1.0e-8) { /* Small angle formula. */ t = theta*D2R; p = fmod(phi,360.0); if (p < 0.0) p += 360.0; p = (180.0 - p)*D2R; rhu = (p*p + t*t)/2.0; } x0 = 4.0; y0 = 0.0; } else if (face == 4) { xi = l; eta = n; if (rhu < 1.0e-8) { /* Small angle formula. */ t = theta*D2R; p = fmod(phi,360.0); if (p > 180.0) p -= 360.0; p *= (90.0 + p)*D2R; rhu = (p*p + t*t)/2.0; } x0 = 6; y0 = 0.0; } else if (face == 5) { xi = m; eta = l; if (rhu < 1.0e-8) { /* Small angle formula. */ t = (90.0 + theta)*D2R; rhu = t*t/2.0; } x0 = 0.0; y0 = -2; } if (xi == 0.0 && eta == 0.0) { xf = 0.0; yf = 0.0; } else if (-xi >= fabs(eta)) { omega = eta/xi; tau = 1.0 + omega*omega; xf = -sqrt(rhu/(1.0-1.0/sqrt(1.0+tau))); yf = (xf/15.0)*(atandeg (omega) - asindeg (omega/sqrt(tau+tau))); } else if (xi >= fabs(eta)) { omega = eta/xi; tau = 1.0 + omega*omega; xf = sqrt(rhu/(1.0-1.0/sqrt(1.0+tau))); yf = (xf/15.0)*(atandeg (omega) - asindeg (omega/sqrt(tau+tau))); } else if (-eta > fabs(xi)) { omega = xi/eta; tau = 1.0 + omega*omega; yf = -sqrt(rhu/(1.0-1.0/sqrt(1.0+tau))); xf = (yf/15.0)*(atandeg (omega) - asindeg (omega/sqrt(tau+tau))); } else if (eta > fabs(xi)) { omega = xi/eta; tau = 1.0 + omega*omega; yf = sqrt(rhu/(1.0-1.0/sqrt(1.0+tau))); xf = (yf/15.0)*(atandeg (omega) - asindeg (omega/sqrt(tau+tau))); } if (fabs(xf) > 1.0) { if (fabs(xf) > 1.0+tol) { return 2; } xf = copysgn (1.0,xf); } if (fabs(yf) > 1.0) { if (fabs(yf) > 1.0+tol) { return 2; } yf = copysgn (1.0,yf); } *x = prj->w[0]*(xf + x0); *y = prj->w[0]*(yf + y0); return 0; } /*--------------------------------------------------------------------------*/ int qscrev(x, y, prj, phi, theta) const double x, y; struct prjprm *prj; double *phi, *theta; { int direct, face; double omega, rho, rhu, tau, xf, yf, w; double l = 0.0; double m = 0.0; double n = 0.0; const double tol = 1.0e-12; if (prj->flag != QSC) { if (qscset(prj)) return 1; } xf = x*prj->w[1]; yf = y*prj->w[1]; /* Check bounds. */ if (fabs(xf) <= 1.0) { if (fabs(yf) > 3.0) return 2; } else { if (fabs(xf) > 7.0) return 2; if (fabs(yf) > 1.0) return 2; } /* Map negative faces to the other side. */ if (xf < -1.0) xf += 8.0; /* Determine the face. */ if (xf > 5.0) { face = 4; xf = xf - 6.0; } else if (xf > 3.0) { face = 3; xf = xf - 4.0; } else if (xf > 1.0) { face = 2; xf = xf - 2.0; } else if (yf > 1.0) { face = 0; yf = yf - 2.0; } else if (yf < -1.0) { face = 5; yf = yf + 2.0; } else { face = 1; } direct = (fabs(xf) > fabs(yf)); if (direct) { if (xf == 0.0) { omega = 0.0; tau = 1.0; rho = 1.0; rhu = 0.0; } else { w = 15.0*yf/xf; omega = sindeg (w)/(cosdeg (w) - SQRT2INV); tau = 1.0 + omega*omega; rhu = xf*xf*(1.0 - 1.0/sqrt(1.0 + tau)); rho = 1.0 - rhu; } } else { if (yf == 0.0) { omega = 0.0; tau = 1.0; rho = 1.0; rhu = 0.0; } else { w = 15.0*xf/yf; omega = sindeg (w)/(cosdeg (w) - SQRT2INV); tau = 1.0 + omega*omega; rhu = yf*yf*(1.0 - 1.0/sqrt(1.0 + tau)); rho = 1.0 - rhu; } } if (rho < -1.0) { if (rho < -1.0-tol) { return 2; } rho = -1.0; rhu = 2.0; w = 0.0; } else { w = sqrt(rhu*(2.0-rhu)/tau); } if (face == 0) { n = rho; if (direct) { m = w; if (xf < 0.0) m = -m; l = -m*omega; } else { l = w; if (yf > 0.0) l = -l; m = -l*omega; } } else if (face == 1) { l = rho; if (direct) { m = w; if (xf < 0.0) m = -m; n = m*omega; } else { n = w; if (yf < 0.0) n = -n; m = n*omega; } } else if (face == 2) { m = rho; if (direct) { l = w; if (xf > 0.0) l = -l; n = -l*omega; } else { n = w; if (yf < 0.0) n = -n; l = -n*omega; } } else if (face == 3) { l = -rho; if (direct) { m = w; if (xf > 0.0) m = -m; n = -m*omega; } else { n = w; if (yf < 0.0) n = -n; m = -n*omega; } } else if (face == 4) { m = -rho; if (direct) { l = w; if (xf < 0.0) l = -l; n = l*omega; } else { n = w; if (yf < 0.0) n = -n; l = n*omega; } } else if (face == 5) { n = -rho; if (direct) { m = w; if (xf < 0.0) m = -m; l = m*omega; } else { l = w; if (yf < 0.0) l = -l; m = l*omega; } } if (l == 0.0 && m == 0.0) { *phi = 0.0; } else { *phi = atan2deg (m, l); } *theta = asindeg (n); return 0; } /* Dec 20 1999 Doug Mink - Change cosd() and sind() to cosdeg() and sindeg() * Dec 20 1999 Doug Mink - Include wcslib.h, which includes proj.h, wcsmath.h * Dec 20 1999 Doug Mink - Define copysign only if it is not defined * Dec 20 1999 Doug Mink - tanfwd() returns error if s<=0.0, not only if s==0.0 * * Jun 2 2000 Doug Mink - include stdlib.h to get abs() * * Feb 15 2001 Doug Mink - update zearev() for WCSLIB 2.6 * Sep 19 2001 Doug Mink - Make above changes for WCSLIB 2.7 * * Mar 15 2002 Doug Mink - Make above changes for WCSLIB 2.8.2 * * Feb 3 2003 Doug Mink - Use locally defined copysgn() and copysgni(), * not copysign() * Apr 1 2003 Doug Mink - include string.h for strcpy() and strcmp() */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/proj.h000066400000000000000000000143451215713201500214050ustar00rootroot00000000000000#ifndef proj_h_ #define proj_h_ #include "wcstrig.h" #ifdef __cplusplus extern "C" { #endif struct prjprm { int flag; int n; double r0; double p[10]; double w[10]; }; #if __STDC__ || defined(__cplusplus) int azpset(struct prjprm *); int azpfwd(const double, const double, struct prjprm *, double *, double *); int azprev(const double, const double, struct prjprm *, double *, double *); int tanset(struct prjprm *); int tanfwd(const double, const double, struct prjprm *, double *, double *); int tanrev(const double, const double, struct prjprm *, double *, double *); int sinset(struct prjprm *); int sinfwd(const double, const double, struct prjprm *, double *, double *); int sinrev(const double, const double, struct prjprm *, double *, double *); int stgset(struct prjprm *); int stgfwd(const double, const double, struct prjprm *, double *, double *); int stgrev(const double, const double, struct prjprm *, double *, double *); int arcset(struct prjprm *); int arcfwd(const double, const double, struct prjprm *, double *, double *); int arcrev(const double, const double, struct prjprm *, double *, double *); int zpnset(struct prjprm *); int zpnfwd(const double, const double, struct prjprm *, double *, double *); int zpnrev(const double, const double, struct prjprm *, double *, double *); int zeaset(struct prjprm *); int zeafwd(const double, const double, struct prjprm *, double *, double *); int zearev(const double, const double, struct prjprm *, double *, double *); int airset(struct prjprm *); int airfwd(const double, const double, struct prjprm *, double *, double *); int airrev(const double, const double, struct prjprm *, double *, double *); int cypset(struct prjprm *); int cypfwd(const double, const double, struct prjprm *, double *, double *); int cyprev(const double, const double, struct prjprm *, double *, double *); int carset(struct prjprm *); int carfwd(const double, const double, struct prjprm *, double *, double *); int carrev(const double, const double, struct prjprm *, double *, double *); int merset(struct prjprm *); int merfwd(const double, const double, struct prjprm *, double *, double *); int merrev(const double, const double, struct prjprm *, double *, double *); int ceaset(struct prjprm *); int ceafwd(const double, const double, struct prjprm *, double *, double *); int cearev(const double, const double, struct prjprm *, double *, double *); int copset(struct prjprm *); int copfwd(const double, const double, struct prjprm *, double *, double *); int coprev(const double, const double, struct prjprm *, double *, double *); int codset(struct prjprm *); int codfwd(const double, const double, struct prjprm *, double *, double *); int codrev(const double, const double, struct prjprm *, double *, double *); int coeset(struct prjprm *); int coefwd(const double, const double, struct prjprm *, double *, double *); int coerev(const double, const double, struct prjprm *, double *, double *); int cooset(struct prjprm *); int coofwd(const double, const double, struct prjprm *, double *, double *); int coorev(const double, const double, struct prjprm *, double *, double *); int bonset(struct prjprm *); int bonfwd(const double, const double, struct prjprm *, double *, double *); int bonrev(const double, const double, struct prjprm *, double *, double *); int pcoset(struct prjprm *); int pcofwd(const double, const double, struct prjprm *, double *, double *); int pcorev(const double, const double, struct prjprm *, double *, double *); int glsset(struct prjprm *); int glsfwd(const double, const double, struct prjprm *, double *, double *); int glsrev(const double, const double, struct prjprm *, double *, double *); int parset(struct prjprm *); int parfwd(const double, const double, struct prjprm *, double *, double *); int parrev(const double, const double, struct prjprm *, double *, double *); int aitset(struct prjprm *); int aitfwd(const double, const double, struct prjprm *, double *, double *); int aitrev(const double, const double, struct prjprm *, double *, double *); int molset(struct prjprm *); int molfwd(const double, const double, struct prjprm *, double *, double *); int molrev(const double, const double, struct prjprm *, double *, double *); int cscset(struct prjprm *); int cscfwd(const double, const double, struct prjprm *, double *, double *); int cscrev(const double, const double, struct prjprm *, double *, double *); int qscset(struct prjprm *); int qscfwd(const double, const double, struct prjprm *, double *, double *); int qscrev(const double, const double, struct prjprm *, double *, double *); int tscset(struct prjprm *); int tscfwd(const double, const double, struct prjprm *, double *, double *); int tscrev(const double, const double, struct prjprm *, double *, double *); #else int azpset(), azpfwd(), azprev(); int tanset(), tanfwd(), tanrev(); int sinset(), sinfwd(), sinrev(); int stgset(), stgfwd(), stgrev(); int arcset(), arcfwd(), arcrev(); int zpnset(), zpnfwd(), zpnrev(); int zeaset(), zeafwd(), zearev(); int airset(), airfwd(), airrev(); int cypset(), cypfwd(), cyprev(); int carset(), carfwd(), carrev(); int merset(), merfwd(), merrev(); int ceaset(), ceafwd(), cearev(); int copset(), copfwd(), coprev(); int codset(), codfwd(), codrev(); int coeset(), coefwd(), coerev(); int cooset(), coofwd(), coorev(); int bonset(), bonfwd(), bonrev(); int pcoset(), pcofwd(), pcorev(); int glsset(), glsfwd(), glsrev(); int parset(), parfwd(), parrev(); int aitset(), aitfwd(), aitrev(); int molset(), molfwd(), molrev(); int cscset(), cscfwd(), cscrev(); int qscset(), qscfwd(), qscrev(); int tscset(), tscfwd(), tscrev(); #endif extern const char *prjset_errmsg[]; extern const char *prjfwd_errmsg[]; extern const char *prjrev_errmsg[]; #ifndef PI #define PI 3.141592653589793238462643 #endif #define D2R PI/180.0 #define R2D 180.0/PI #define SQRT2 1.4142135623730950488 #define SQRT2INV 1.0/SQRT2 #define PRJSET 137 #ifdef __cplusplus }; #endif #endif /* proj_h_ */ /* May 27 1998 ifndef WCSTRIG changed to ifndef wcstrig_h_ */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/sph.c000066400000000000000000000164341215713201500212210ustar00rootroot00000000000000/*============================================================================ * * WCSLIB - an implementation of the FITS WCS proposal. * Copyright (C) 1995-2002, Mark Calabretta * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Correspondence concerning WCSLIB may be directed to: * Internet email: mcalabre@atnf.csiro.au * Postal address: Dr. Mark Calabretta, * Australia Telescope National Facility, * P.O. Box 76, * Epping, NSW, 2121, * AUSTRALIA * *============================================================================= * * C routines for the spherical coordinate transformations used by the FITS * "World Coordinate System" (WCS) convention. * * Summary of routines * ------------------- * The spherical coordinate transformations are implemented via separate * functions for the transformation in each direction. * * Forward transformation; sphfwd() * -------------------------------- * Transform celestial coordinates to the native coordinates of a projection. * * Given: * lng,lat double Celestial longitude and latitude, in degrees. * eul[5] double Euler angles for the transformation: * 0: Celestial longitude of the native pole, in * degrees. * 1: Celestial colatitude of the native pole, or * native colatitude of the celestial pole, in * degrees. * 2: Native longitude of the celestial pole, in * degrees. * 3: cos(eul[1]) * 4: sin(eul[1]) * * Returned: * phi, double Longitude and latitude in the native coordinate * theta system of the projection, in degrees. * * Function return value: * int Error status * 0: Success. * * Reverse transformation; sphrev() * -------------------------------- * Transform native coordinates of a projection to celestial coordinates. * * Given: * phi, double Longitude and latitude in the native coordinate * theta system of the projection, in degrees. * eul[5] double Euler angles for the transformation: * 0: Celestial longitude of the native pole, in * degrees. * 1: Celestial colatitude of the native pole, or * native colatitude of the celestial pole, in * degrees. * 2: Native longitude of the celestial pole, in * degrees. * 3: cos(eul[1]) * 4: sin(eul[1]) * * Returned: * lng,lat double Celestial longitude and latitude, in degrees. * * Function return value: * int Error status * 0: Success. * * Author: Mark Calabretta, Australia Telescope National Facility * $Id: sph.c,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ *===========================================================================*/ #include #include "wcslib.h" #ifndef __STDC__ #ifndef const #define const #endif #endif const double tol = 1.0e-5; int sphfwd (lng, lat, eul, phi, theta) const double lat, lng, eul[5]; double *phi, *theta; { double coslat, coslng, dlng, dphi, sinlat, sinlng, x, y, z; coslat = cosdeg (lat); sinlat = sindeg (lat); dlng = lng - eul[0]; coslng = cosdeg (dlng); sinlng = sindeg (dlng); /* Compute the native longitude. */ x = sinlat*eul[4] - coslat*eul[3]*coslng; if (fabs(x) < tol) { /* Rearrange formula to reduce roundoff errors. */ x = -cosdeg (lat+eul[1]) + coslat*eul[3]*(1.0 - coslng); } y = -coslat*sinlng; if (x != 0.0 || y != 0.0) { dphi = atan2deg (y, x); } else { /* Change of origin of longitude. */ dphi = dlng - 180.0; } *phi = eul[2] + dphi; /* Normalize the native longitude. */ if (*phi > 180.0) { *phi -= 360.0; } else if (*phi < -180.0) { *phi += 360.0; } /* Compute the native latitude. */ if (fmod(dlng,180.0) == 0.0) { *theta = lat + coslng*eul[1]; if (*theta > 90.0) *theta = 180.0 - *theta; if (*theta < -90.0) *theta = -180.0 - *theta; } else { z = sinlat*eul[3] + coslat*eul[4]*coslng; /* Use an alternative formula for greater numerical accuracy. */ if (fabs(z) > 0.99) { if (z < 0) *theta = -acosdeg (sqrt(x*x+y*y)); else *theta = acosdeg (sqrt(x*x+y*y)); } else { *theta = asindeg (z); } } return 0; } /*-----------------------------------------------------------------------*/ int sphrev (phi, theta, eul, lng, lat) const double phi, theta, eul[5]; double *lng, *lat; { double cosphi, costhe, dlng, dphi, sinphi, sinthe, x, y, z; costhe = cosdeg (theta); sinthe = sindeg (theta); dphi = phi - eul[2]; cosphi = cosdeg (dphi); sinphi = sindeg (dphi); /* Compute the celestial longitude. */ x = sinthe*eul[4] - costhe*eul[3]*cosphi; if (fabs(x) < tol) { /* Rearrange formula to reduce roundoff errors. */ x = -cosdeg (theta+eul[1]) + costhe*eul[3]*(1.0 - cosphi); } y = -costhe*sinphi; if (x != 0.0 || y != 0.0) { dlng = atan2deg (y, x); } else { /* Change of origin of longitude. */ dlng = dphi + 180.0; } *lng = eul[0] + dlng; /* Normalize the celestial longitude. */ if (eul[0] >= 0.0) { if (*lng < 0.0) *lng += 360.0; } else { if (*lng > 0.0) *lng -= 360.0; } if (*lng > 360.0) { *lng -= 360.0; } else if (*lng < -360.0) { *lng += 360.0; } /* Compute the celestial latitude. */ if (fmod(dphi,180.0) == 0.0) { *lat = theta + cosphi*eul[1]; if (*lat > 90.0) *lat = 180.0 - *lat; if (*lat < -90.0) *lat = -180.0 - *lat; } else { z = sinthe*eul[3] + costhe*eul[4]*cosphi; /* Use an alternative formula for greater numerical accuracy. */ if (fabs(z) > 0.99) { if (z < 0) *lat = -acosdeg (sqrt(x*x+y*y)); else *lat = acosdeg (sqrt(x*x+y*y)); } else { *lat = asindeg (z); } } return 0; } /* Dec 20 1999 Doug Mink - Change cosd() and sind() to cosdeg() and sindeg() * Dec 20 1999 Doug Mink - Include wcslib.h, which includes wcstrig.h, sph.h * Dec 20 1999 Doug Mink - Define copysign only if it is not already defined * * Jan 5 2000 Doug Mink - Drop copysign * * Sep 19 2001 Doug Mink - No change for WCSLIB 2.7 */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/tnxpos.c000066400000000000000000000777731215713201500217770ustar00rootroot00000000000000/*** File wcslib/tnxpos.c *** April 3, 2007 *** By Doug Mink, dmink@cfa.harvard.edu *** Harvard-Smithsonian Center for Astrophysics *** After IRAF mwcs/wftnx.x and mwcs/wfgsurfit.x *** Copyright (C) 1998-2007 *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Correspondence concerning WCSTools should be addressed as follows: Internet email: dmink@cfa.harvard.edu Postal address: Doug Mink Smithsonian Astrophysical Observatory 60 Garden St. Cambridge, MA 02138 USA */ #include #include #include #include "wcs.h" #define SPHTOL 0.00001 #define BADCVAL 0.0 #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define MIN(a,b) (((a) < (b)) ? (a) : (b)) /* wftnx -- wcs function driver for the gnomonic projection with correction. * tnxinit (header, wcs) * tnxclose (wcs) * tnxfwd (xpix, ypix, wcs, xpos, ypos) Pixels to WCS * tnxrev (xpos, ypos, wcs, xpix, ypix) WCS to pixels */ #define max_niter 500 #define SZ_ATSTRING 2000 static void wf_gsclose(); static void wf_gsb1pol(); static void wf_gsb1leg(); static void wf_gsb1cheb(); /* tnxinit -- initialize the gnomonic forward or inverse transform. * initialization for this transformation consists of, determining which * axis is ra / lon and which is dec / lat, computing the celestial longitude * and colatitude of the native pole, reading in the the native longitude * of the pole of the celestial coordinate system longpole from the attribute * list, precomputing euler angles and various intermediaries derived from the * coordinate reference values, and reading in the projection parameter ro * from the attribute list. if longpole is undefined then a value of 180.0 * degrees is assumed. if ro is undefined a value of 180.0 / pi is assumed. * the tan projection is equivalent to the azp projection with mu set to 0.0. * in order to determine the axis order, the parameter "axtype={ra|dec} * {xlon|glat}{xlon|elat}" must have been set in the attribute list for the * function. the longpole and ro parameters may be set in either or both of * the axes attribute lists, but the value in the ra axis attribute list takes * precedence. */ int tnxinit (header, wcs) const char *header; /* FITS header */ struct WorldCoor *wcs; /* pointer to WCS structure */ { struct IRAFsurface *wf_gsopen(); char *str1, *str2, *lngstr, *latstr; extern void wcsrotset(); /* allocate space for the attribute strings */ str1 = malloc (SZ_ATSTRING); str2 = malloc (SZ_ATSTRING); hgetm (header, "WAT1", SZ_ATSTRING, str1); hgetm (header, "WAT2", SZ_ATSTRING, str2); lngstr = malloc (SZ_ATSTRING); latstr = malloc (SZ_ATSTRING); /* determine the native longitude of the pole of the celestial coordinate system corresponding to the FITS keyword longpole. this number has no default and should normally be set to 180 degrees. search both axes for this quantity. */ if (wcs->longpole > 360.0) { if (!igetr8 (str1, "longpole", &wcs->longpole)) { if (!igetr8 (str2, "longpole", &wcs->longpole)) wcs->longpole = 180.0; } } /* Fetch the ro projection parameter which is the radius of the generating sphere for the projection. if ro is absent which is the usual case set it to 180 / pi. search both axes for this quantity. */ if (!igetr8 (str1, "ro", &wcs->rodeg)) { if (!igetr8 (str2, "ro", &wcs->rodeg)) wcs->rodeg = 180.0 / PI; } /* Fetch the longitude correction surface. note that the attribute string may be of any length so the length of atvalue may have to be adjusted. */ if (!igets (str1, "lngcor", SZ_ATSTRING, lngstr)) { if (!igets (str2, "lngcor", SZ_ATSTRING, lngstr)) wcs->lngcor = NULL; else wcs->lngcor = wf_gsopen (lngstr); } else wcs->lngcor = wf_gsopen (lngstr); /* Fetch the latitude correction surface. note that the attribute string may be of any length so the length of atvalue may have to be adjusted. */ if (!igets (str2, "latcor", SZ_ATSTRING, latstr)) { if (!igets (str1, "latcor", SZ_ATSTRING, latstr)) wcs->latcor = NULL; else wcs->latcor = wf_gsopen (latstr); } else wcs->latcor = wf_gsopen (latstr); /* Compute image rotation */ wcsrotset (wcs); /* free working space. */ free (str1); free (str2); free (lngstr); free (latstr); /* Return 1 if there are no correction coefficients */ if (wcs->latcor == NULL && wcs->lngcor == NULL) return (1); else return (0); } /* tnxpos -- forward transform (physical to world) gnomonic projection. */ int tnxpos (xpix, ypix, wcs, xpos, ypos) double xpix, ypix; /*i physical coordinates (x, y) */ struct WorldCoor *wcs; /*i pointer to WCS descriptor */ double *xpos, *ypos; /*o world coordinates (ra, dec) */ { int ira, idec; double x, y, r, phi, theta, costhe, sinthe, dphi, cosphi, sinphi, dlng, z; double colatp, coslatp, sinlatp, longp; double xs, ys, ra, dec; double wf_gseval(); /* Convert from pixels to image coordinates */ xpix = xpix - wcs->crpix[0]; ypix = ypix - wcs->crpix[1]; /* Scale and rotate using CD matrix */ if (wcs->rotmat) { x = xpix * wcs->cd[0] + ypix * wcs->cd[1]; y = xpix * wcs->cd[2] + ypix * wcs->cd[3]; } else { /* Check axis increments - bail out if either 0 */ if (wcs->cdelt[0] == 0.0 || wcs->cdelt[1] == 0.0) { *xpos = 0.0; *ypos = 0.0; return 2; } /* Scale using CDELT */ xs = xpix * wcs->cdelt[0]; ys = ypix * wcs->cdelt[1]; /* Take out rotation from CROTA */ if (wcs->rot != 0.0) { double cosr = cos (degrad (wcs->rot)); double sinr = sin (degrad (wcs->rot)); x = xs * cosr - ys * sinr; y = xs * sinr + ys * cosr; } else { x = xs; y = ys; } } /* get the axis numbers */ if (wcs->coorflip) { ira = 1; idec = 0; } else { ira = 0; idec = 1; } colatp = degrad (90.0 - wcs->crval[idec]); coslatp = cos(colatp); sinlatp = sin(colatp); longp = degrad(wcs->longpole); /* Compute native spherical coordinates phi and theta in degrees from the projected coordinates. this is the projection part of the computation */ if (wcs->lngcor != NULL) x = x + wf_gseval (wcs->lngcor, x, y); if (wcs->latcor != NULL) y = y + wf_gseval (wcs->latcor, x, y); r = sqrt (x * x + y * y); /* Compute phi */ if (r == 0.0) phi = 0.0; else phi = atan2 (x, -y); /* Compute theta */ theta = atan2 (wcs->rodeg, r); /* Compute the celestial coordinates ra and dec from the native coordinates phi and theta. this is the spherical geometry part of the computation */ costhe = cos (theta); sinthe = sin (theta); dphi = phi - longp; cosphi = cos (dphi); sinphi = sin (dphi); /* Compute the ra */ x = sinthe * sinlatp - costhe * coslatp * cosphi; if (fabs (x) < SPHTOL) x = -cos (theta + colatp) + costhe * coslatp * (1.0 - cosphi); y = -costhe * sinphi; if (x != 0.0 || y != 0.0) dlng = atan2 (y, x); else dlng = dphi + PI ; ra = wcs->crval[ira] + raddeg(dlng); /* normalize ra */ if (wcs->crval[ira] >= 0.0) { if (ra < 0.0) ra = ra + 360.0; } else { if (ra > 0.0) ra = ra - 360.0; } if (ra > 360.0) ra = ra - 360.0; else if (ra < -360.0) ra = ra + 360.0; /* compute the dec */ if (fmod (dphi, PI) == 0.0) { dec = raddeg(theta + cosphi * colatp); if (dec > 90.0) dec = 180.0 - dec; if (dec < -90.0) dec = -180.0 - dec; } else { z = sinthe * coslatp + costhe * sinlatp * cosphi; if (fabs(z) > 0.99) { if (z >= 0.0) dec = raddeg(acos (sqrt(x * x + y * y))); else dec = raddeg(-acos (sqrt(x * x + y * y))); } else dec = raddeg(asin (z)); } /* store the results */ *xpos = ra; *ypos = dec; return (0); } /* tnxpix -- inverse transform (world to physical) gnomonic projection */ int tnxpix (xpos, ypos, wcs, xpix, ypix) double xpos, ypos; /*i world coordinates (ra, dec) */ struct WorldCoor *wcs; /*i pointer to WCS descriptor */ double *xpix, *ypix; /*o physical coordinates (x, y) */ { int ira, idec, niter; double ra, dec, cosdec, sindec, cosra, sinra, x, y, phi, theta; double s, r, dphi, z, dpi, dhalfpi, twopi, tx; double xm, ym, f, fx, fy, g, gx, gy, denom, dx, dy; double colatp, coslatp, sinlatp, longp, sphtol; double wf_gseval(), wf_gsder(); /* get the axis numbers */ if (wcs->coorflip) { ira = 1; idec = 0; } else { ira = 0; idec = 1; } /* Compute the transformation from celestial coordinates ra and dec to native coordinates phi and theta. this is the spherical geometry part of the transformation */ ra = degrad (xpos - wcs->crval[ira]); dec = degrad (ypos); cosra = cos (ra); sinra = sin (ra); cosdec = cos (dec); sindec = sin (dec); colatp = degrad (90.0 - wcs->crval[idec]); coslatp = cos (colatp); sinlatp = sin (colatp); if (wcs->longpole == 999.0) longp = degrad (180.0); else longp = degrad(wcs->longpole); dpi = PI; dhalfpi = dpi * 0.5; twopi = PI + PI; sphtol = SPHTOL; /* Compute phi */ x = sindec * sinlatp - cosdec * coslatp * cosra; if (fabs(x) < sphtol) x = -cos (dec + colatp) + cosdec * coslatp * (1.0 - cosra); y = -cosdec * sinra; if (x != 0.0 || y != 0.0) dphi = atan2 (y, x); else dphi = ra - dpi; phi = longp + dphi; if (phi > dpi) phi = phi - twopi; else if (phi < -dpi) phi = phi + twopi; /* Compute theta */ if (fmod (ra, dpi) == 0.0) { theta = dec + cosra * colatp; if (theta > dhalfpi) theta = dpi - theta; if (theta < -dhalfpi) theta = -dpi - theta; } else { z = sindec * coslatp + cosdec * sinlatp * cosra; if (fabs (z) > 0.99) { if (z >= 0.0) theta = acos (sqrt(x * x + y * y)); else theta = -acos (sqrt(x * x + y * y)); } else theta = asin (z); } /* Compute the transformation from native coordinates phi and theta to projected coordinates x and y */ s = sin (theta); if (s == 0.0) { x = BADCVAL; y = BADCVAL; } else { r = wcs->rodeg * cos (theta) / s; if (wcs->lngcor == NULL && wcs->latcor == NULL) { if (wcs->coorflip) { y = r * sin (phi); x = -r * cos (phi); } else { x = r * sin (phi); y = -r * cos (phi); } } else { xm = r * sin (phi); ym = -r * cos (phi); x = xm; y = ym; niter = 0; while (niter < max_niter) { if (wcs->lngcor != NULL) { f = x + wf_gseval (wcs->lngcor, x, y) - xm; fx = wf_gsder (wcs->lngcor, x, y, 1, 0); fx = 1.0 + fx; fy = wf_gsder (wcs->lngcor, x, y, 0, 1); } else { f = x - xm; fx = 1.0 ; fy = 0.0; } if (wcs->latcor != NULL) { g = y + wf_gseval (wcs->latcor, x, y) - ym; gx = wf_gsder (wcs->latcor, x, y, 1, 0); gy = wf_gsder (wcs->latcor, x, y, 0, 1); gy = 1.0 + gy; } else { g = y - ym; gx = 0.0 ; gy = 1.0; } denom = fx * gy - fy * gx; if (denom == 0.0) break; dx = (-f * gy + g * fy) / denom; dy = (-g * fx + f * gx) / denom; x = x + dx; y = y + dy; if (MAX(MAX(fabs(dx),fabs(dy)),MAX(fabs(f),fabs(g))) < 2.80e-8) break; niter = niter + 1; } /* Reverse x and y if axes flipped */ if (wcs->coorflip) { tx = x; x = y; y = tx; } } } /* Scale and rotate using CD matrix */ if (wcs->rotmat) { *xpix = x * wcs->dc[0] + y * wcs->dc[1]; *ypix = x * wcs->dc[2] + y * wcs->dc[3]; } else { /* Correct for rotation */ if (wcs->rot!=0.0) { double cosr = cos (degrad (wcs->rot)); double sinr = sin (degrad (wcs->rot)); *xpix = x * cosr + y * sinr; *ypix = y * cosr - x * sinr; } else { *xpix = x; *ypix = y; } /* Scale using CDELT */ if (wcs->xinc != 0.) *xpix = *xpix / wcs->xinc; if (wcs->yinc != 0.) *ypix = *ypix / wcs->yinc; } /* Convert to pixels */ *xpix = *xpix + wcs->xrefpix; *ypix = *ypix + wcs->yrefpix; return (0); } /* TNXCLOSE -- free up the distortion surface pointers */ void tnxclose (wcs) struct WorldCoor *wcs; /* pointer to the WCS descriptor */ { if (wcs->lngcor != NULL) wf_gsclose (wcs->lngcor); if (wcs->latcor != NULL) wf_gsclose (wcs->latcor); return; } /* copyright(c) 1986 association of universities for research in astronomy inc. * wfgsurfit.x -- surface fitting package used by wcs function drivers. * Translated to C from SPP by Doug Mink, SAO, May 26, 1998 * * the following routines are used by the experimental function drivers tnx * and zpx to decode polynomial fits stored in the image header in the form * of a list of parameters and coefficients into surface descriptors in * ra / dec or longitude latitude. the polynomial surfaces so encoded consist * of corrections to function drivers tan and zpn. the package routines are * modelled after the equivalent gsurfit routines and are consistent with them. * the routines are: * * sf = wf_gsopen (wattstr) * wf_gsclose (sf) * * z = wf_gseval (sf, x, y) * ncoeff = wf_gscoeff (sf, coeff) * zder = wf_gsder (sf, x, y, nxder, nyder) * * wf_gsopen is used to open a surface fit encoded in a wcs attribute, returning * the sf surface fitting descriptor. wf_gsclose should be called later to free * the descriptor. wf_gseval is called to evaluate the surface at a point. */ #define SZ_GSCOEFFBUF 20 /* define the structure elements for the wf_gsrestore task */ #define TNX_SAVETYPE 0 #define TNX_SAVEXORDER 1 #define TNX_SAVEYORDER 2 #define TNX_SAVEXTERMS 3 #define TNX_SAVEXMIN 4 #define TNX_SAVEXMAX 5 #define TNX_SAVEYMIN 6 #define TNX_SAVEYMAX 7 #define TNX_SAVECOEFF 8 /* wf_gsopen -- decode the longitude / latitude or ra / dec mwcs attribute * and return a gsurfit compatible surface descriptor. */ struct IRAFsurface * wf_gsopen (astr) char *astr; /* the input mwcs attribute string */ { double dval; char *estr; int npar, szcoeff; double *coeff; struct IRAFsurface *gs; struct IRAFsurface *wf_gsrestore(); if (astr[1] == 0) return (NULL); gs = NULL; npar = 0; szcoeff = SZ_GSCOEFFBUF; coeff = (double *) malloc (szcoeff * sizeof (double)); estr = astr; while (*estr != (char) 0) { dval = strtod (astr, &estr); if (*estr == '.') estr++; if (*estr != (char) 0) { npar++; if (npar >= szcoeff) { szcoeff = szcoeff + SZ_GSCOEFFBUF; coeff = (double *) realloc (coeff, (szcoeff * sizeof (double))); } coeff[npar-1] = dval; astr = estr; while (*astr == ' ') astr++; } } gs = wf_gsrestore (coeff); free (coeff); if (npar == 0) return (NULL); else return (gs); } /* wf_gsclose -- procedure to free the surface descriptor */ static void wf_gsclose (sf) struct IRAFsurface *sf; /* the surface descriptor */ { if (sf != NULL) { if (sf->xbasis != NULL) free (sf->xbasis); if (sf->ybasis != NULL) free (sf->ybasis); if (sf->coeff != NULL) free (sf->coeff); free (sf); } return; } /* wf_gseval -- procedure to evaluate the fitted surface at a single point. * the wf->ncoeff coefficients are stored in the vector pointed to by sf->coeff. */ double wf_gseval (sf, x, y) struct IRAFsurface *sf; /* pointer to surface descriptor structure */ double x; /* x value */ double y; /* y value */ { double sum, accum; int i, ii, k, maxorder, xorder; /* Calculate the basis functions */ switch (sf->type) { case TNX_CHEBYSHEV: wf_gsb1cheb (x, sf->xorder, sf->xmaxmin, sf->xrange, sf->xbasis); wf_gsb1cheb (y, sf->yorder, sf->ymaxmin, sf->yrange, sf->ybasis); break; case TNX_LEGENDRE: wf_gsb1leg (x, sf->xorder, sf->xmaxmin, sf->xrange, sf->xbasis); wf_gsb1leg (y, sf->yorder, sf->ymaxmin, sf->yrange, sf->ybasis); break; case TNX_POLYNOMIAL: wf_gsb1pol (x, sf->xorder, sf->xbasis); wf_gsb1pol (y, sf->yorder, sf->ybasis); break; default: fprintf (stderr,"TNX_GSEVAL: unknown surface type\n"); return (0.0); } /* Initialize accumulator basis functions */ sum = 0.0; /* Loop over y basis functions */ if (sf->xorder > sf->yorder) maxorder = sf->xorder + 1; else maxorder = sf->yorder + 1; xorder = sf->xorder; ii = 0; for (i = 0; i < sf->yorder; i++) { /* Loop over the x basis functions */ accum = 0.0; for (k = 0; k < xorder; k++) { accum = accum + sf->coeff[ii] * sf->xbasis[k]; ii = ii + 1; } accum = accum * sf->ybasis[i]; sum = sum + accum; /* Elements of the coefficient vector where neither k = 1 or i = 1 are not calculated if sf->xterms = no. */ if (sf->xterms == TNX_XNONE) xorder = 1; else if (sf->xterms == TNX_XHALF) { if ((i + 1 + sf->xorder + 1) > maxorder) xorder = xorder - 1; } } return (sum); } /* TNX_GSCOEFF -- procedure to fetch the number and magnitude of the coefficients * if the sf->xterms = wf_xbi (yes) then the number of coefficients will be * (sf->xorder * sf->yorder); if wf_xterms is wf_xtri then the number * of coefficients will be (sf->xorder * sf->yorder - order * * (order - 1) / 2) where order is the minimum of the x and yorders; if * sf->xterms = TNX_XNONE then the number of coefficients will be * (sf->xorder + sf->yorder - 1). */ int wf_gscoeff (sf, coeff) struct IRAFsurface *sf; /* pointer to the surface fitting descriptor */ double *coeff; /* the coefficients of the fit */ { int ncoeff; /* the number of coefficients */ int i; /* Exctract coefficients from data structure and calculate their number */ ncoeff = sf->ncoeff; for (i = 0; i < ncoeff; i++) coeff[i] = sf->coeff[i]; return (ncoeff); } static double *coeff = NULL; static int nbcoeff = 0; /* wf_gsder -- procedure to calculate a new surface which is a derivative of * the input surface. */ double wf_gsder (sf1, x, y, nxd, nyd) struct IRAFsurface *sf1; /* pointer to the previous surface */ double x; /* x values */ double y; /* y values */ int nxd, nyd; /* order of the derivatives in x and y */ { int nxder, nyder, i, j, k, nbytes; int order, maxorder1, maxorder2, nmove1, nmove2; struct IRAFsurface *sf2 = 0; double *ptr1, *ptr2; double zfit, norm; double wf_gseval(); if (sf1 == NULL) return (0.0); if (nxd < 0 || nyd < 0) { fprintf (stderr, "TNX_GSDER: order of derivatives cannot be < 0\n"); return (0.0); } if (nxd == 0 && nyd == 0) { zfit = wf_gseval (sf1, x, y); return (zfit); } /* Allocate space for new surface */ sf2 = (struct IRAFsurface *) malloc (sizeof (struct IRAFsurface)); /* Check the order of the derivatives */ nxder = MIN (nxd, sf1->xorder - 1); nyder = MIN (nyd, sf1->yorder - 1); /* Set up new surface */ sf2->type = sf1->type; /* Set the derivative surface parameters */ if (sf2->type == TNX_LEGENDRE || sf2->type == TNX_CHEBYSHEV || sf2->type == TNX_POLYNOMIAL) { sf2->xterms = sf1->xterms; /* Find the order of the new surface */ switch (sf2->xterms) { case TNX_XNONE: if (nxder > 0 && nyder > 0) { sf2->xorder = 1; sf2->yorder = 1; sf2->ncoeff = 1; } else if (nxder > 0) { sf2->xorder = MAX (1, sf1->xorder - nxder); sf2->yorder = 1; sf2->ncoeff = sf2->xorder; } else if (nyder > 0) { sf2->xorder = 1; sf2->yorder = MAX (1, sf1->yorder - nyder); sf2->ncoeff = sf2->yorder; } break; case TNX_XHALF: maxorder1 = MAX (sf1->xorder+1, sf1->yorder+1); order = MAX(1, MIN(maxorder1-1-nyder-nxder,sf1->xorder-nxder)); sf2->xorder = order; order = MAX(1, MIN(maxorder1-1-nyder-nxder,sf1->yorder-nyder)); sf2->yorder = order; order = MIN (sf2->xorder, sf2->yorder); sf2->ncoeff = sf2->xorder * sf2->yorder - (order*(order-1)/2); break; default: sf2->xorder = MAX (1, sf1->xorder - nxder); sf2->yorder = MAX (1, sf1->yorder - nyder); sf2->ncoeff = sf2->xorder * sf2->yorder; } /* define the data limits */ sf2->xrange = sf1->xrange; sf2->xmaxmin = sf1->xmaxmin; sf2->yrange = sf1->yrange; sf2->ymaxmin = sf1->ymaxmin; } else { fprintf (stderr, "TNX_GSDER: unknown surface type %d\n", sf2->type); return (0.0); } /* Allocate space for coefficients and basis functions */ nbytes = sf2->ncoeff * sizeof(double); sf2->coeff = (double *) malloc (nbytes); nbytes = sf2->xorder * sizeof(double); sf2->xbasis = (double *) malloc (nbytes); nbytes = sf2->yorder * sizeof(double); sf2->ybasis = (double *) malloc (nbytes); /* Get coefficients */ nbytes = sf1->ncoeff * sizeof(double); if (nbytes > nbcoeff) { if (nbcoeff > 0) coeff = (double *) realloc (coeff, nbytes); else coeff = (double *) malloc (nbytes); nbcoeff = nbytes; } (void) wf_gscoeff (sf1, coeff); /* Compute the new coefficients */ switch (sf2->xterms) { case TNX_XFULL: ptr2 = sf2->coeff + (sf2->yorder - 1) * sf2->xorder; ptr1 = coeff + (sf1->yorder - 1) * sf1->xorder; for (i = sf1->yorder - 1; i >= nyder+1; i--) { for (j = i; j >= i-nyder+1; j--) { for (k = 0; k < sf2->xorder; k++) ptr1[nxder+k] = ptr1[nxder+k] * (double)(j-1); } for (j = sf1->xorder; j >= nxder+1; j--) { for (k = j; k >= j-nxder+1; k--) ptr1[j-1] = ptr1[j-1] * (double)(k - 1); } for (j = 0; j < sf2->xorder; j++) ptr2[j] = ptr1[nxder+j]; ptr2 = ptr2 - sf2->xorder; ptr1 = ptr1 - sf1->xorder; } break; case TNX_XHALF: maxorder1 = MAX (sf1->xorder + 1, sf1->yorder + 1); maxorder2 = MAX (sf2->xorder + 1, sf2->yorder + 1); ptr2 = sf2->coeff + sf2->ncoeff; ptr1 = coeff + sf1->ncoeff; for (i = sf1->yorder; i >= nyder+1; i--) { nmove1 = MAX (0, MIN (maxorder1 - i, sf1->xorder)); nmove2 = MAX (0, MIN (maxorder2 - i + nyder, sf2->xorder)); ptr1 = ptr1 - nmove1; ptr2 = ptr2 - nmove2; for (j = i; j > i - nyder + 1; j--) { for (k = 0; k < nmove2; k++) ptr1[nxder+k] = ptr1[nxder+k] * (double)(j-1); } for (j = nmove1; j >= nxder+1; j--) { for (k = j; k >= j-nxder+1; k--) ptr1[j-1] = ptr1[j-1] * (double)(k - 1); } for (j = 0; j < nmove2; j++) ptr2[j] = ptr1[nxder+j]; } break; default: if (nxder > 0 && nyder > 0) sf2->coeff[0] = 0.0; else if (nxder > 0) { ptr1 = coeff; ptr2 = sf2->coeff + sf2->ncoeff - 1; for (j = sf1->xorder; j >= nxder+1; j--) { for (k = j; k >= j - nxder + 1; k--) ptr1[j-1] = ptr1[j-1] * (double)(k - 1); ptr2[0] = ptr1[j-1]; ptr2 = ptr2 - 1; } } else if (nyder > 0) { ptr1 = coeff + sf1->ncoeff - 1; ptr2 = sf2->coeff; for (i = sf1->yorder; i >= nyder + 1; i--) { for (j = i; j >= i - nyder + 1; j--) *ptr1 = *ptr1 * (double)(j - 1); ptr1 = ptr1 - 1; } for (i = 0; i < sf2->ncoeff; i++) ptr2[i] = ptr1[i+1]; } } /* evaluate the derivatives */ zfit = wf_gseval (sf2, x, y); /* normalize */ if (sf2->type != TNX_POLYNOMIAL) { norm = pow (sf2->xrange, (double)nxder) * pow (sf2->yrange, (double)nyder); zfit = norm * zfit; } /* free the space */ wf_gsclose (sf2); return (zfit); } /* wf_gsrestore -- procedure to restore the surface fit encoded in the image header as a list of double precision parameters and coefficients to the surface descriptor for use by the evaluating routines. the surface parameters, surface type, xorder (or number of polynomial terms in x), yorder (or number of polynomial terms in y), xterms, xmin, xmax and ymin and ymax, are stored in the first eight elements of the double array fit, followed by the wf->ncoeff surface coefficients. */ struct IRAFsurface * wf_gsrestore (fit) double *fit; /* array containing the surface parameters and coefficients */ { struct IRAFsurface *sf; /* surface descriptor */ int surface_type, xorder, yorder, order, i; double xmin, xmax, ymin, ymax; xorder = (int) (fit[TNX_SAVEXORDER] + 0.5); if (xorder < 1) { fprintf (stderr, "wf_gsrestore: illegal x order %d\n", xorder); return (NULL); } yorder = (int) (fit[TNX_SAVEYORDER] + 0.5); if (yorder < 1) { fprintf (stderr, "wf_gsrestore: illegal y order %d\n", yorder); return (NULL); } xmin = fit[TNX_SAVEXMIN]; xmax = fit[TNX_SAVEXMAX]; if (xmax <= xmin) { fprintf (stderr, "wf_gsrestore: illegal x range %f-%f\n",xmin,xmax); return (NULL); } ymin = fit[TNX_SAVEYMIN]; ymax = fit[TNX_SAVEYMAX]; if (ymax <= ymin) { fprintf (stderr, "wf_gsrestore: illegal y range %f-%f\n",ymin,ymax); return (NULL); } /* Set surface type dependent surface descriptor parameters */ surface_type = (int) (fit[TNX_SAVETYPE] + 0.5); if (surface_type == TNX_LEGENDRE || surface_type == TNX_CHEBYSHEV || surface_type == TNX_POLYNOMIAL) { /* allocate space for the surface descriptor */ sf = (struct IRAFsurface *) malloc (sizeof (struct IRAFsurface)); sf->xorder = xorder; sf->xrange = 2.0 / (xmax - xmin); sf->xmaxmin = - (xmax + xmin) / 2.0; sf->yorder = yorder; sf->yrange = 2.0 / (ymax - ymin); sf->ymaxmin = - (ymax + ymin) / 2.0; sf->xterms = fit[TNX_SAVEXTERMS]; switch (sf->xterms) { case TNX_XNONE: sf->ncoeff = sf->xorder + sf->yorder - 1; break; case TNX_XHALF: order = MIN (xorder, yorder); sf->ncoeff = sf->xorder * sf->yorder - order * (order-1) / 2; break; case TNX_XFULL: sf->ncoeff = sf->xorder * sf->yorder; break; } } else { fprintf (stderr, "wf_gsrestore: unknown surface type %d\n", surface_type); return (NULL); } /* Set remaining curve parameters */ sf->type = surface_type; /* Restore coefficient array */ sf->coeff = (double *) malloc (sf->ncoeff*sizeof (double)); for (i = 0; i < sf->ncoeff; i++) sf->coeff[i] = fit[TNX_SAVECOEFF+i]; /* Allocate space for basis vectors */ sf->xbasis = (double *) malloc (sf->xorder*sizeof (double)); sf->ybasis = (double *) malloc (sf->yorder*sizeof (double)); return (sf); } /* wf_gsb1pol -- procedure to evaluate all the non-zero polynomial functions for a single point and given order. */ static void wf_gsb1pol (x, order, basis) double x; /*i data point */ int order; /*i order of polynomial, order = 1, constant */ double *basis; /*o basis functions */ { int i; basis[0] = 1.0; if (order == 1) return; basis[1] = x; if (order == 2) return; for (i = 2; i < order; i++) basis[i] = x * basis[i-1]; return; } /* wf_gsb1leg -- procedure to evaluate all the non-zero legendre functions for a single point and given order. */ static void wf_gsb1leg (x, order, k1, k2, basis) double x; /*i data point */ int order; /*i order of polynomial, order = 1, constant */ double k1, k2; /*i normalizing constants */ double *basis; /*o basis functions */ { int i; double ri, xnorm; basis[0] = 1.0; if (order == 1) return; xnorm = (x + k1) * k2 ; basis[1] = xnorm; if (order == 2) return; for (i = 2; i < order; i++) { ri = i; basis[i] = ((2.0 * ri - 1.0) * xnorm * basis[i-1] - (ri - 1.0) * basis[i-2]) / ri; } return; } /* wf_gsb1cheb -- procedure to evaluate all the non-zero chebyshev function coefficients for a given x and order. */ static void wf_gsb1cheb (x, order, k1, k2, basis) double x; /*i number of data points */ int order; /*i order of polynomial, 1 is a constant */ double k1, k2; /*i normalizing constants */ double *basis; /*o array of basis functions */ { int i; double xnorm; basis[0] = 1.0; if (order == 1) return; xnorm = (x + k1) * k2; basis[1] = xnorm; if (order == 2) return; for (i = 2; i < order; i++) basis[i] = 2. * xnorm * basis[i-1] - basis[i-2]; return; } /* Set surface polynomial from arguments */ int tnxpset (wcs, xorder, yorder, xterms, coeff) struct WorldCoor *wcs; /* World coordinate system structure */ int xorder; /* Number of x coefficients (same for x and y) */ int yorder; /* Number of y coefficients (same for x and y) */ int xterms; /* Number of xy coefficients (same for x and y) */ double *coeff; /* Plate fit coefficients */ { double *ycoeff; struct IRAFsurface *wf_gspset (); wcs->prjcode = WCS_TNX; wcs->lngcor = wf_gspset (xorder, yorder, xterms, coeff); ycoeff = coeff + wcs->lngcor->ncoeff; wcs->latcor = wf_gspset (xorder, yorder, xterms, ycoeff); return 0; } /* wf_gspset -- procedure to set the surface descriptor for use by the evaluating routines. from arguments. The surface parameters are surface type, xorder (number of polynomial terms in x), yorder (number of polynomial terms in y), xterms, and the surface coefficients. */ struct IRAFsurface * wf_gspset (xorder, yorder, xterms, coeff) int xorder; int yorder; int xterms; double *coeff; { struct IRAFsurface *sf; /* surface descriptor */ int surface_type, order, i; double xmin, xmax; double ymin, ymax; surface_type = TNX_POLYNOMIAL; xmin = 0.0; xmax = 0.0; ymin = 0.0; ymax = 0.0; if (surface_type == TNX_LEGENDRE || surface_type == TNX_CHEBYSHEV || surface_type == TNX_POLYNOMIAL) { /* allocate space for the surface descriptor */ sf = (struct IRAFsurface *) malloc (sizeof (struct IRAFsurface)); sf->xorder = xorder; sf->xrange = 2.0 / (xmax - xmin); sf->xmaxmin = -(xmax + xmin) / 2.0; sf->yorder = yorder; sf->yrange = 2.0 / (ymax - ymin); sf->ymaxmin = - (ymax + ymin) / 2.0; sf->xterms = xterms; switch (sf->xterms) { case TNX_XNONE: sf->ncoeff = sf->xorder + sf->yorder - 1; break; case TNX_XHALF: order = MIN (xorder, yorder); sf->ncoeff = sf->xorder * sf->yorder - order * (order-1) / 2; break; case TNX_XFULL: sf->ncoeff = sf->xorder * sf->yorder; break; } } else { fprintf (stderr, "TNX_GSSET: unknown surface type %d\n", surface_type); return (NULL); } /* Set remaining curve parameters */ sf->type = surface_type; /* Restore coefficient array */ sf->coeff = (double *) malloc (sf->ncoeff*sizeof (double)); for (i = 0; i < sf->ncoeff; i++) sf->coeff[i] = coeff[i]; /* Allocate space for basis vectors */ sf->xbasis = (double *) malloc (sf->xorder*sizeof (double)); sf->ybasis = (double *) malloc (sf->yorder*sizeof (double)); return (sf); } /* Mar 26 1998 New subroutines, translated from SPP * Apr 28 1998 Change all local flags to TNX_* and projection flag to WCS_TNX * May 11 1998 Fix use of pole longitude default * Sep 4 1998 Fix missed assignment in tnxpos from Allen Harris, SAO * Sep 10 1998 Fix bugs in tnxpix() * Sep 10 1998 Fix missed assignment in tnxpix from Allen Harris, SAO * * Oct 22 1999 Drop unused variables, fix case statements after lint * Dec 10 1999 Fix bug in gsder() which failed to allocate enough memory * Dec 10 1999 Compute wcs->rot using wcsrotset() in tnxinit() * * Feb 14 2001 Fixed off-by-one bug in legendre evaluation (Mike Jarvis) * * Apr 11 2002 Fix bug when .-terminated substring in wf_gsopen() * Apr 29 2002 Clean up code * Jun 26 2002 Increase size of WAT strings from 500 to 2000 * * Jun 27 2005 Drop unused arguments k1 and k2 from wf_gsb1pol() * * Jan 8 2007 Drop unused variable ncoeff in wf_gsder() * Jan 9 2007 Declare header const char in tnxinit() * Apr 3 2007 Fix offsets to hit last cooefficient in wf_gsder() */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/wcs.c000066400000000000000000002467401215713201500212300ustar00rootroot00000000000000/*** File libwcs/wcs.c *** July 25, 2007 *** By Doug Mink, dmink@cfa.harvard.edu *** Harvard-Smithsonian Center for Astrophysics *** Copyright (C) 1994-2007 *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Correspondence concerning WCSTools should be addressed as follows: Internet email: dmink@cfa.harvard.edu Postal address: Doug Mink Smithsonian Astrophysical Observatory 60 Garden St. Cambridge, MA 02138 USA * Module: wcs.c (World Coordinate Systems) * Purpose: Convert FITS WCS to pixels and vice versa: * Subroutine: wcsxinit (cra,cdec,secpix,xrpix,yrpix,nxpix,nypix,rotate,equinox,epoch,proj) * sets a WCS structure from arguments * Subroutine: wcskinit (nxpix,nypix,ctype1,ctype2,crpix1,crpix2,crval1,crval2, cd,cdelt1,cdelt2,crota,equinox,epoch) * sets a WCS structure from keyword-based arguments * Subroutine: wcsreset (wcs,crpix1,crpix2,crval1,crval2,cdelt1,cdelt2,crota,cd, equinox) * resets an existing WCS structure from arguments * Subroutine: wcsdeltset (wcs,cdelt1,cdelt2,crota) sets rotation and scaling * Subroutine: wcscdset (wcs, cd) sets rotation and scaling from a CD matrix * Subroutine: wcspcset (wcs,cdelt1,cdelt2,pc) sets rotation and scaling * Subroutine: wcseqset (wcs, equinox) resets an existing WCS structure to new equinox * Subroutine: iswcs(wcs) returns 1 if WCS structure is filled, else 0 * Subroutine: nowcs(wcs) returns 0 if WCS structure is filled, else 1 * Subroutine: wcscent (wcs) prints the image center and size in WCS units * Subroutine: wcssize (wcs, cra, cdec, dra, ddec) returns image center and size * Subroutine: wcsfull (wcs, cra, cdec, width, height) returns image center and size * Subroutine: wcsrange (wcs, ra1, ra2, dec1, dec2) returns image coordinate limits * Subroutine: wcsshift (wcs,cra,cdec) resets the center of a WCS structure * Subroutine: wcsdist (x1,y1,x2,y2) compute angular distance between ra/dec or lat/long * Subroutine: wcsdiff (x1,y1,x2,y2) compute angular distance between ra/dec or lat/long * Subroutine: wcscominit (wcs,command) sets up a command format for execution by wcscom * Subroutine: wcsoutinit (wcs,coor) sets up the coordinate system used by pix2wcs * Subroutine: getwcsout (wcs) returns current output coordinate system used by pix2wcs * Subroutine: wcsininit (wcs,coor) sets up the coordinate system used by wcs2pix * Subroutine: getwcsin (wcs) returns current input coordinate system used by wcs2pix * Subroutine: setwcsdeg(wcs, new) sets WCS output in degrees or hh:mm:ss * Subroutine: getradecsys(wcs) returns current coordinate system type * Subroutine: wcscom (wcs,file,x,y,wcstr) executes a command using the current world coordinates * Subroutine: setwcslin (wcs, mode) sets output string mode for LINEAR * Subroutine: pix2wcst (wcs,xpix,ypix,wcstring,lstr) pixels -> sky coordinate string * Subroutine: pix2wcs (wcs,xpix,ypix,xpos,ypos) pixel coordinates -> sky coordinates * Subroutine: wcsc2pix (wcs,xpos,ypos,coorsys,xpix,ypix,offscl) sky coordinates -> pixel coordinates * Subroutine: wcs2pix (wcs,xpos,ypos,xpix,ypix,offscl) sky coordinates -> pixel coordinates * Subroutine: wcszin (izpix) sets third dimension for pix2wcs() and pix2wcst() * Subroutine: wcszout (wcs) returns third dimension from wcs2pix() * Subroutine: setwcsfile (filename) Set file name for error messages * Subroutine: setwcserr (errmsg) Set error message * Subroutine: wcserr() Print error message * Subroutine: setdefwcs (wcsproj) Set flag to choose AIPS or WCSLIB WCS subroutines * Subroutine: getdefwcs() Get flag to switch between AIPS and WCSLIB subroutines * Subroutine: savewcscoor (wcscoor) * Subroutine: getwcscoor() Return preset output default coordinate system * Subroutine: savewcscom (i, wcscom) Save specified WCS command * Subroutine: setwcscom (wcs) Initialize WCS commands * Subroutine: getwcscom (i) Return specified WCS command * Subroutine: wcsfree (wcs) Free storage used by WCS structure * Subroutine: freewcscom (wcs) Free storage used by WCS commands * Subroutine: cpwcs (&header, cwcs) */ #include /* strstr, NULL */ #include /* stderr */ #include #include "wcs.h" #ifndef VMS #include #endif static char wcserrmsg[80]; static char wcsfile[256]={""}; static void wcslibrot(); void wcsrotset(); static int wcsproj0 = 0; static int izpix = 0; static double zpix = 0.0; void wcsfree (wcs) struct WorldCoor *wcs; /* WCS structure */ { if (nowcs (wcs)) { /* Free WCS structure if allocated but not filled */ if (wcs) free (wcs); return; } freewcscom (wcs); if (wcs->wcsname != NULL) free (wcs->wcsname); if (wcs->lin.imgpix != NULL) free (wcs->lin.imgpix); if (wcs->lin.piximg != NULL) free (wcs->lin.piximg); free (wcs); return; } /* Set up a WCS structure from subroutine arguments */ struct WorldCoor * wcsxinit (cra,cdec,secpix,xrpix,yrpix,nxpix,nypix,rotate,equinox,epoch,proj) double cra; /* Center right ascension in degrees */ double cdec; /* Center declination in degrees */ double secpix; /* Number of arcseconds per pixel */ double xrpix; /* Reference pixel X coordinate */ double yrpix; /* Reference pixel X coordinate */ int nxpix; /* Number of pixels along x-axis */ int nypix; /* Number of pixels along y-axis */ double rotate; /* Rotation angle (clockwise positive) in degrees */ int equinox; /* Equinox of coordinates, 1950 and 2000 supported */ double epoch; /* Epoch of coordinates, used for FK4/FK5 conversion * no effect if 0 */ char *proj; /* Projection */ { struct WorldCoor *wcs; double cdelt1, cdelt2; wcs = (struct WorldCoor *) calloc (1, sizeof(struct WorldCoor)); /* Set WCSLIB flags so that structures will be reinitialized */ wcs->cel.flag = 0; wcs->lin.flag = 0; wcs->wcsl.flag = 0; /* Image dimensions */ wcs->naxis = 2; wcs->naxes = 2; wcs->lin.naxis = 2; wcs->nxpix = nxpix; wcs->nypix = nypix; wcs->wcsproj = wcsproj0; wcs->crpix[0] = xrpix; wcs->crpix[1] = yrpix; wcs->xrefpix = wcs->crpix[0]; wcs->yrefpix = wcs->crpix[1]; wcs->lin.crpix = wcs->crpix; wcs->crval[0] = cra; wcs->crval[1] = cdec; wcs->xref = wcs->crval[0]; wcs->yref = wcs->crval[1]; wcs->cel.ref[0] = wcs->crval[0]; wcs->cel.ref[1] = wcs->crval[1]; wcs->cel.ref[2] = 999.0; strcpy (wcs->c1type,"RA"); strcpy (wcs->c2type,"DEC"); /* Allan Brighton: 28.4.98: for backward compat., remove leading "--" */ while (proj && *proj == '-') proj++; strcpy (wcs->ptype,proj); strcpy (wcs->ctype[0],"RA---"); strcpy (wcs->ctype[1],"DEC--"); strcat (wcs->ctype[0],proj); strcat (wcs->ctype[1],proj); if (wcstype (wcs, wcs->ctype[0], wcs->ctype[1])) { wcsfree (wcs); return (NULL); } /* Approximate world coordinate system from a known plate scale */ cdelt1 = -secpix / 3600.0; cdelt2 = secpix / 3600.0; wcsdeltset (wcs, cdelt1, cdelt2, rotate); wcs->lin.cdelt = wcs->cdelt; wcs->lin.pc = wcs->pc; /* Coordinate reference frame and equinox */ wcs->equinox = (double) equinox; if (equinox > 1980) strcpy (wcs->radecsys,"FK5"); else strcpy (wcs->radecsys,"FK4"); if (epoch > 0) wcs->epoch = epoch; else wcs->epoch = 0.0; wcs->wcson = 1; wcs->syswcs = wcscsys (wcs->radecsys); wcsoutinit (wcs, wcs->radecsys); wcsininit (wcs, wcs->radecsys); wcs->eqout = 0.0; wcs->printsys = 1; wcs->tabsys = 0; /* Initialize special WCS commands */ setwcscom (wcs); return (wcs); } /* Set up a WCS structure from subroutine arguments based on FITS keywords */ struct WorldCoor * wcskinit (naxis1, naxis2, ctype1, ctype2, crpix1, crpix2, crval1, crval2, cd, cdelt1, cdelt2, crota, equinox, epoch) int naxis1; /* Number of pixels along x-axis */ int naxis2; /* Number of pixels along y-axis */ char *ctype1; /* FITS WCS projection for axis 1 */ char *ctype2; /* FITS WCS projection for axis 2 */ double crpix1, crpix2; /* Reference pixel coordinates */ double crval1, crval2; /* Coordinates at reference pixel in degrees */ double *cd; /* Rotation matrix, used if not NULL */ double cdelt1, cdelt2; /* scale in degrees/pixel, ignored if cd is not NULL */ double crota; /* Rotation angle in degrees, ignored if cd is not NULL */ int equinox; /* Equinox of coordinates, 1950 and 2000 supported */ double epoch; /* Epoch of coordinates, used for FK4/FK5 conversion * no effect if 0 */ { struct WorldCoor *wcs; wcs = (struct WorldCoor *) calloc (1, sizeof(struct WorldCoor)); /* Set WCSLIB flags so that structures will be reinitialized */ wcs->cel.flag = 0; wcs->lin.flag = 0; wcs->wcsl.flag = 0; /* Image dimensions */ wcs->naxis = 2; wcs->naxes = 2; wcs->lin.naxis = 2; wcs->nxpix = naxis1; wcs->nypix = naxis2; wcs->wcsproj = wcsproj0; wcs->crpix[0] = crpix1; wcs->crpix[1] = crpix2; wcs->xrefpix = wcs->crpix[0]; wcs->yrefpix = wcs->crpix[1]; wcs->lin.crpix = wcs->crpix; if (wcstype (wcs, ctype1, ctype2)) { wcsfree (wcs); return (NULL); } if (wcs->latbase == 90) crval2 = 90.0 - crval2; else if (wcs->latbase == -90) crval2 = crval2 - 90.0; wcs->crval[0] = crval1; wcs->crval[1] = crval2; wcs->xref = wcs->crval[0]; wcs->yref = wcs->crval[1]; wcs->cel.ref[0] = wcs->crval[0]; wcs->cel.ref[1] = wcs->crval[1]; wcs->cel.ref[2] = 999.0; if (cd != NULL) wcscdset (wcs, cd); else if (cdelt1 != 0.0) wcsdeltset (wcs, cdelt1, cdelt2, crota); else { wcsdeltset (wcs, 1.0, 1.0, crota); setwcserr ("WCSRESET: setting CDELT to 1"); } wcs->lin.cdelt = wcs->cdelt; wcs->lin.pc = wcs->pc; /* Coordinate reference frame and equinox */ wcs->equinox = (double) equinox; if (equinox > 1980) strcpy (wcs->radecsys,"FK5"); else strcpy (wcs->radecsys,"FK4"); if (epoch > 0) wcs->epoch = epoch; else wcs->epoch = 0.0; wcs->wcson = 1; strcpy (wcs->radecout, wcs->radecsys); wcs->syswcs = wcscsys (wcs->radecsys); wcsoutinit (wcs, wcs->radecsys); wcsininit (wcs, wcs->radecsys); wcs->eqout = 0.0; wcs->printsys = 1; wcs->tabsys = 0; /* Initialize special WCS commands */ setwcscom (wcs); return (wcs); } /* Set projection in WCS structure from FITS keyword values */ int wcstype (wcs, ctype1, ctype2) struct WorldCoor *wcs; /* World coordinate system structure */ char *ctype1; /* FITS WCS projection for axis 1 */ char *ctype2; /* FITS WCS projection for axis 2 */ { int i, iproj; int nctype = 32; char ctypes[32][4]; char dtypes[10][4]; /* Initialize projection types */ strcpy (ctypes[0], "LIN"); strcpy (ctypes[1], "AZP"); strcpy (ctypes[2], "SZP"); strcpy (ctypes[3], "TAN"); strcpy (ctypes[4], "SIN"); strcpy (ctypes[5], "STG"); strcpy (ctypes[6], "ARC"); strcpy (ctypes[7], "ZPN"); strcpy (ctypes[8], "ZEA"); strcpy (ctypes[9], "AIR"); strcpy (ctypes[10], "CYP"); strcpy (ctypes[11], "CAR"); strcpy (ctypes[12], "MER"); strcpy (ctypes[13], "CEA"); strcpy (ctypes[14], "COP"); strcpy (ctypes[15], "COD"); strcpy (ctypes[16], "COE"); strcpy (ctypes[17], "COO"); strcpy (ctypes[18], "BON"); strcpy (ctypes[19], "PCO"); strcpy (ctypes[20], "SFL"); strcpy (ctypes[21], "PAR"); strcpy (ctypes[22], "AIT"); strcpy (ctypes[23], "MOL"); strcpy (ctypes[24], "CSC"); strcpy (ctypes[25], "QSC"); strcpy (ctypes[26], "TSC"); strcpy (ctypes[27], "NCP"); strcpy (ctypes[28], "GLS"); strcpy (ctypes[29], "DSS"); strcpy (ctypes[30], "PLT"); strcpy (ctypes[31], "TNX"); /* Initialize distortion types */ strcpy (dtypes[1], "SIP"); if (!strncmp (ctype1, "LONG",4)) strncpy (ctype1, "XLON",4); strcpy (wcs->ctype[0], ctype1); strcpy (wcs->c1type, ctype1); strcpy (wcs->ptype, ctype1); /* Linear coordinates */ if (!strncmp (ctype1,"LINEAR",6)) wcs->prjcode = WCS_LIN; /* Pixel coordinates */ else if (!strncmp (ctype1,"PIXEL",6)) wcs->prjcode = WCS_PIX; /*Detector pixel coordinates */ else if (strsrch (ctype1,"DET")) wcs->prjcode = WCS_PIX; /* Set up right ascension, declination, latitude, or longitude */ else if (ctype1[0] == 'R' || ctype1[0] == 'D' || ctype1[0] == 'A' || ctype1[1] == 'L') { wcs->c1type[0] = ctype1[0]; wcs->c1type[1] = ctype1[1]; if (ctype1[2] == '-') { wcs->c1type[2] = 0; iproj = 3; } else { wcs->c1type[2] = ctype1[2]; iproj = 4; if (ctype1[3] == '-') { wcs->c1type[3] = 0; } else { wcs->c1type[3] = ctype1[3]; wcs->c1type[4] = 0; } } if (ctype1[iproj] == '-') iproj = iproj + 1; if (ctype1[iproj] == '-') iproj = iproj + 1; if (ctype1[iproj] == '-') iproj = iproj + 1; if (ctype1[iproj] == '-') iproj = iproj + 1; wcs->ptype[0] = ctype1[iproj]; wcs->ptype[1] = ctype1[iproj+1]; wcs->ptype[2] = ctype1[iproj+2]; wcs->ptype[3] = 0; sprintf (wcs->ctype[0],"%-4s%4s",wcs->c1type,wcs->ptype); for (i = 0; i < 8; i++) if (wcs->ctype[0][i] == ' ') wcs->ctype[0][i] = '-'; /* Find projection type */ wcs->prjcode = 0; /* default type is linear */ for (i = 1; i < nctype; i++) { if (!strncmp(wcs->ptype, ctypes[i], 3)) wcs->prjcode = i; } /* Handle "obsolete" NCP projection (now WCSLIB should be OK) if (wcs->prjcode == WCS_NCP) { if (wcs->wcsproj == WCS_BEST) wcs->wcsproj = WCS_OLD; else if (wcs->wcsproj == WCS_ALT) wcs->wcsproj = WCS_NEW; } */ /* Work around bug in WCSLIB handling of CAR projection else if (wcs->prjcode == WCS_CAR) { if (wcs->wcsproj == WCS_BEST) wcs->wcsproj = WCS_OLD; else if (wcs->wcsproj == WCS_ALT) wcs->wcsproj = WCS_NEW; } */ /* Work around bug in WCSLIB handling of COE projection else if (wcs->prjcode == WCS_COE) { if (wcs->wcsproj == WCS_BEST) wcs->wcsproj = WCS_OLD; else if (wcs->wcsproj == WCS_ALT) wcs->wcsproj = WCS_NEW; } else if (wcs->wcsproj == WCS_BEST) */ if (wcs->wcsproj == WCS_BEST) wcs->wcsproj = WCS_NEW; else if (wcs->wcsproj == WCS_ALT) wcs->wcsproj = WCS_OLD; /* if (wcs->wcsproj == WCS_OLD && ( wcs->prjcode != WCS_STG && wcs->prjcode != WCS_AIT && wcs->prjcode != WCS_MER && wcs->prjcode != WCS_GLS && wcs->prjcode != WCS_ARC && wcs->prjcode != WCS_TAN && wcs->prjcode != WCS_TNX && wcs->prjcode != WCS_SIN && wcs->prjcode != WCS_PIX && wcs->prjcode != WCS_LIN && wcs->prjcode != WCS_CAR && wcs->prjcode != WCS_COE && wcs->prjcode != WCS_NCP)) wcs->wcsproj = WCS_NEW; */ /* Handle NOAO corrected TNX as uncorrected TAN if oldwcs is set */ if (wcs->wcsproj == WCS_OLD && wcs->prjcode == WCS_TNX) { wcs->ctype[0][6] = 'A'; wcs->ctype[0][7] = 'N'; wcs->prjcode = WCS_TAN; } } /* If not sky coordinates, assume linear */ else { wcs->prjcode = WCS_LIN; return (0); } /* Second coordinate type */ if (!strncmp (ctype2, "NPOL",4)) { ctype2[0] = ctype1[0]; strncpy (ctype2+1, "LAT",3); wcs->latbase = 90; strcpy (wcs->radecsys,"NPOLE"); wcs->syswcs = WCS_NPOLE; } else if (!strncmp (ctype2, "SPA-",4)) { ctype2[0] = ctype1[0]; strncpy (ctype2+1, "LAT",3); wcs->latbase = -90; strcpy (wcs->radecsys,"SPA"); wcs->syswcs = WCS_SPA; } else wcs->latbase = 0; strcpy (wcs->ctype[1], ctype2); strcpy (wcs->c2type, ctype2); /* Linear coordinates */ if (!strncmp (ctype2,"LINEAR",6)) wcs->prjcode = WCS_LIN; /* Pixel coordinates */ else if (!strncmp (ctype2,"PIXEL",6)) wcs->prjcode = WCS_PIX; /* Set up right ascension, declination, latitude, or longitude */ else if (ctype2[0] == 'R' || ctype2[0] == 'D' || ctype2[0] == 'A' || ctype2[1] == 'L') { wcs->c2type[0] = ctype2[0]; wcs->c2type[1] = ctype2[1]; if (ctype2[2] == '-') { wcs->c2type[2] = 0; iproj = 3; } else { wcs->c2type[2] = ctype2[2]; iproj = 4; if (ctype2[3] == '-') { wcs->c2type[3] = 0; } else { wcs->c2type[3] = ctype2[3]; wcs->c2type[4] = 0; } } if (ctype2[iproj] == '-') iproj = iproj + 1; if (ctype2[iproj] == '-') iproj = iproj + 1; if (ctype2[iproj] == '-') iproj = iproj + 1; if (ctype2[iproj] == '-') iproj = iproj + 1; wcs->ptype[0] = ctype2[iproj]; wcs->ptype[1] = ctype2[iproj+1]; wcs->ptype[2] = ctype2[iproj+2]; wcs->ptype[3] = 0; if (!strncmp (ctype1, "DEC", 3) || !strncmp (ctype1+1, "LAT", 3)) wcs->coorflip = 1; else wcs->coorflip = 0; if (ctype2[1] == 'L' || ctype2[0] == 'A') { wcs->degout = 1; wcs->ndec = 5; } else { wcs->degout = 0; wcs->ndec = 3; } sprintf (wcs->ctype[1],"%-4s%4s",wcs->c2type,wcs->ptype); for (i = 0; i < 8; i++) if (wcs->ctype[1][i] == ' ') wcs->ctype[1][i] = '-'; } /* If not sky coordinates, assume linear */ else { wcs->prjcode = WCS_LIN; } /* Set distortion code from CTYPE1 extension */ setdistcode (wcs, ctype1); return (0); } int wcsreset (wcs, crpix1, crpix2, crval1, crval2, cdelt1, cdelt2, crota, cd) struct WorldCoor *wcs; /* World coordinate system data structure */ double crpix1, crpix2; /* Reference pixel coordinates */ double crval1, crval2; /* Coordinates at reference pixel in degrees */ double cdelt1, cdelt2; /* scale in degrees/pixel, ignored if cd is not NULL */ double crota; /* Rotation angle in degrees, ignored if cd is not NULL */ double *cd; /* Rotation matrix, used if not NULL */ { if (nowcs (wcs)) return (-1); /* Set WCSLIB flags so that structures will be reinitialized */ wcs->cel.flag = 0; wcs->lin.flag = 0; wcs->wcsl.flag = 0; /* Reference pixel coordinates and WCS value */ wcs->crpix[0] = crpix1; wcs->crpix[1] = crpix2; wcs->xrefpix = wcs->crpix[0]; wcs->yrefpix = wcs->crpix[1]; wcs->lin.crpix = wcs->crpix; wcs->crval[0] = crval1; wcs->crval[1] = crval2; wcs->xref = wcs->crval[0]; wcs->yref = wcs->crval[1]; if (wcs->coorflip) { wcs->cel.ref[1] = wcs->crval[0]; wcs->cel.ref[0] = wcs->crval[1]; } else { wcs->cel.ref[0] = wcs->crval[0]; wcs->cel.ref[1] = wcs->crval[1]; } /* Keep ref[2] and ref[3] from input */ /* Initialize to no plate fit */ wcs->ncoeff1 = 0; wcs->ncoeff2 = 0; if (cd != NULL) wcscdset (wcs, cd); else if (cdelt1 != 0.0) wcsdeltset (wcs, cdelt1, cdelt2, crota); else { wcs->xinc = 1.0; wcs->yinc = 1.0; setwcserr ("WCSRESET: setting CDELT to 1"); } /* Coordinate reference frame, equinox, and epoch */ if (!strncmp (wcs->ptype,"LINEAR",6) || !strncmp (wcs->ptype,"PIXEL",5)) wcs->degout = -1; wcs->wcson = 1; return (0); } void wcseqset (wcs, equinox) struct WorldCoor *wcs; /* World coordinate system data structure */ double equinox; /* Desired equinox as fractional year */ { if (nowcs (wcs)) return; /* Leave WCS alone if already at desired equinox */ if (wcs->equinox == equinox) return; /* Convert center from B1950 (FK4) to J2000 (FK5) */ if (equinox == 2000.0 && wcs->equinox == 1950.0) { if (wcs->coorflip) { fk425e (&wcs->crval[1], &wcs->crval[0], wcs->epoch); wcs->cel.ref[1] = wcs->crval[0]; wcs->cel.ref[0] = wcs->crval[1]; } else { fk425e (&wcs->crval[0], &wcs->crval[1], wcs->epoch); wcs->cel.ref[0] = wcs->crval[0]; wcs->cel.ref[1] = wcs->crval[1]; } wcs->xref = wcs->crval[0]; wcs->yref = wcs->crval[1]; wcs->equinox = 2000.0; strcpy (wcs->radecsys, "FK5"); wcs->syswcs = WCS_J2000; wcs->cel.flag = 0; wcs->wcsl.flag = 0; } /* Convert center from J2000 (FK5) to B1950 (FK4) */ else if (equinox == 1950.0 && wcs->equinox == 2000.0) { if (wcs->coorflip) { fk524e (&wcs->crval[1], &wcs->crval[0], wcs->epoch); wcs->cel.ref[1] = wcs->crval[0]; wcs->cel.ref[0] = wcs->crval[1]; } else { fk524e (&wcs->crval[0], &wcs->crval[1], wcs->epoch); wcs->cel.ref[0] = wcs->crval[0]; wcs->cel.ref[1] = wcs->crval[1]; } wcs->xref = wcs->crval[0]; wcs->yref = wcs->crval[1]; wcs->equinox = 1950.0; strcpy (wcs->radecsys, "FK4"); wcs->syswcs = WCS_B1950; wcs->cel.flag = 0; wcs->wcsl.flag = 0; } wcsoutinit (wcs, wcs->radecsys); wcsininit (wcs, wcs->radecsys); return; } /* Set scale and rotation in WCS structure */ void wcscdset (wcs, cd) struct WorldCoor *wcs; /* World coordinate system structure */ double *cd; /* CD matrix, ignored if NULL */ { double tcd; if (cd == NULL) return; wcs->rotmat = 1; wcs->cd[0] = cd[0]; wcs->cd[1] = cd[1]; wcs->cd[2] = cd[2]; wcs->cd[3] = cd[3]; (void) matinv (2, wcs->cd, wcs->dc); /* Compute scale */ wcs->xinc = sqrt (cd[0]*cd[0] + cd[2]*cd[2]); wcs->yinc = sqrt (cd[1]*cd[1] + cd[3]*cd[3]); /* Deal with x=Dec/y=RA case */ if (wcs->coorflip) { tcd = cd[1]; cd[1] = -cd[2]; cd[2] = -tcd; } wcslibrot (wcs); wcs->wcson = 1; /* Compute image rotation */ wcsrotset (wcs); wcs->cdelt[0] = wcs->xinc; wcs->cdelt[1] = wcs->yinc; return; } /* Set scale and rotation in WCS structure from axis scale and rotation */ void wcsdeltset (wcs, cdelt1, cdelt2, crota) struct WorldCoor *wcs; /* World coordinate system structure */ double cdelt1; /* degrees/pixel in first axis (or both axes) */ double cdelt2; /* degrees/pixel in second axis if nonzero */ double crota; /* Rotation counterclockwise in degrees */ { double *pci; double crot, srot; int i, j, naxes; naxes = wcs->naxis; if (naxes > 2) naxes = 2; wcs->cdelt[0] = cdelt1; if (cdelt2 != 0.0) wcs->cdelt[1] = cdelt2; else wcs->cdelt[1] = cdelt1; wcs->xinc = wcs->cdelt[0]; wcs->yinc = wcs->cdelt[1]; pci = wcs->pc; for (i = 0; i < naxes; i++) { for (j = 0; j < naxes; j++) { if (i ==j) *pci = 1.0; else *pci = 0.0; pci++; } } wcs->rotmat = 0; /* If image is reversed, value of CROTA is flipped, too */ wcs->rot = crota; if (wcs->rot < 0.0) wcs->rot = wcs->rot + 360.0; if (wcs->rot >= 360.0) wcs->rot = wcs->rot - 360.0; crot = cos (degrad(wcs->rot)); if (cdelt1 * cdelt2 > 0) srot = sin (-degrad(wcs->rot)); else srot = sin (degrad(wcs->rot)); /* Set CD matrix */ wcs->cd[0] = wcs->cdelt[0] * crot; if (wcs->cdelt[0] < 0) wcs->cd[1] = -fabs (wcs->cdelt[1]) * srot; else wcs->cd[1] = fabs (wcs->cdelt[1]) * srot; if (wcs->cdelt[1] < 0) wcs->cd[2] = fabs (wcs->cdelt[0]) * srot; else wcs->cd[2] = -fabs (wcs->cdelt[0]) * srot; wcs->cd[3] = wcs->cdelt[1] * crot; (void) matinv (2, wcs->cd, wcs->dc); /* Set rotation matrix */ wcslibrot (wcs); /* Set image rotation and mirroring */ if (wcs->coorflip) { if (wcs->cdelt[0] < 0 && wcs->cdelt[1] > 0) { wcs->imflip = 1; wcs->imrot = wcs->rot - 90.0; if (wcs->imrot < -180.0) wcs->imrot = wcs->imrot + 360.0; wcs->pa_north = wcs->rot; wcs->pa_east = wcs->rot - 90.0; if (wcs->pa_east < -180.0) wcs->pa_east = wcs->pa_east + 360.0; } else if (wcs->cdelt[0] > 0 && wcs->cdelt[1] < 0) { wcs->imflip = 1; wcs->imrot = wcs->rot + 90.0; if (wcs->imrot > 180.0) wcs->imrot = wcs->imrot - 360.0; wcs->pa_north = wcs->rot; wcs->pa_east = wcs->rot - 90.0; if (wcs->pa_east < -180.0) wcs->pa_east = wcs->pa_east + 360.0; } else if (wcs->cdelt[0] > 0 && wcs->cdelt[1] > 0) { wcs->imflip = 0; wcs->imrot = wcs->rot + 90.0; if (wcs->imrot > 180.0) wcs->imrot = wcs->imrot - 360.0; wcs->pa_north = wcs->imrot; wcs->pa_east = wcs->rot + 90.0; if (wcs->pa_east > 180.0) wcs->pa_east = wcs->pa_east - 360.0; } else if (wcs->cdelt[0] < 0 && wcs->cdelt[1] < 0) { wcs->imflip = 0; wcs->imrot = wcs->rot - 90.0; if (wcs->imrot < -180.0) wcs->imrot = wcs->imrot + 360.0; wcs->pa_north = wcs->imrot; wcs->pa_east = wcs->rot + 90.0; if (wcs->pa_east > 180.0) wcs->pa_east = wcs->pa_east - 360.0; } } else { if (wcs->cdelt[0] < 0 && wcs->cdelt[1] > 0) { wcs->imflip = 0; wcs->imrot = wcs->rot; wcs->pa_north = wcs->rot + 90.0; if (wcs->pa_north > 180.0) wcs->pa_north = wcs->pa_north - 360.0; wcs->pa_east = wcs->rot + 180.0; if (wcs->pa_east > 180.0) wcs->pa_east = wcs->pa_east - 360.0; } else if (wcs->cdelt[0] > 0 && wcs->cdelt[1] < 0) { wcs->imflip = 0; wcs->imrot = wcs->rot + 180.0; if (wcs->imrot > 180.0) wcs->imrot = wcs->imrot - 360.0; wcs->pa_north = wcs->imrot + 90.0; if (wcs->pa_north > 180.0) wcs->pa_north = wcs->pa_north - 360.0; wcs->pa_east = wcs->imrot + 180.0; if (wcs->pa_east > 180.0) wcs->pa_east = wcs->pa_east - 360.0; } else if (wcs->cdelt[0] > 0 && wcs->cdelt[1] > 0) { wcs->imflip = 1; wcs->imrot = -wcs->rot; wcs->pa_north = wcs->imrot + 90.0; if (wcs->pa_north > 180.0) wcs->pa_north = wcs->pa_north - 360.0; wcs->pa_east = wcs->rot; } else if (wcs->cdelt[0] < 0 && wcs->cdelt[1] < 0) { wcs->imflip = 1; wcs->imrot = wcs->rot + 180.0; if (wcs->imrot > 180.0) wcs->imrot = wcs->imrot - 360.0; wcs->pa_north = wcs->imrot + 90.0; if (wcs->pa_north > 180.0) wcs->pa_north = wcs->pa_north - 360.0; wcs->pa_east = wcs->rot + 90.0; if (wcs->pa_east > 180.0) wcs->pa_east = wcs->pa_east - 360.0; } } return; } /* Set scale and rotation in WCS structure */ void wcspcset (wcs, cdelt1, cdelt2, pc) struct WorldCoor *wcs; /* World coordinate system structure */ double cdelt1; /* degrees/pixel in first axis (or both axes) */ double cdelt2; /* degrees/pixel in second axis if nonzero */ double *pc; /* Rotation matrix, ignored if NULL */ { double *pci, *pc0i; int i, j, naxes; if (pc == NULL) return; naxes = wcs->naxis; /* if (naxes > 2) naxes = 2; */ if (naxes < 1 || naxes > 9) { naxes = wcs->naxes; wcs->naxis = naxes; } wcs->cdelt[0] = cdelt1; if (cdelt2 != 0.0) wcs->cdelt[1] = cdelt2; else wcs->cdelt[1] = cdelt1; wcs->xinc = wcs->cdelt[0]; wcs->yinc = wcs->cdelt[1]; /* Set rotation matrix */ pci = wcs->pc; pc0i = pc; for (i = 0; i < naxes; i++) { for (j = 0; j < naxes; j++) { *pci = *pc0i; pci++; pc0i++; } } /* Set CD matrix */ if (naxes > 1) { wcs->cd[0] = pc[0] * wcs->cdelt[0]; wcs->cd[1] = pc[1] * wcs->cdelt[0]; wcs->cd[2] = pc[naxes] * wcs->cdelt[1]; wcs->cd[3] = pc[naxes+1] * wcs->cdelt[1]; } else { wcs->cd[0] = pc[0] * wcs->cdelt[0]; wcs->cd[1] = 0.0; wcs->cd[2] = 0.0; wcs->cd[3] = 1.0; } (void) matinv (2, wcs->cd, wcs->dc); wcs->rotmat = 1; (void)linset (&wcs->lin); wcs->wcson = 1; wcsrotset (wcs); return; } /* Set up rotation matrix for WCSLIB projection subroutines */ static void wcslibrot (wcs) struct WorldCoor *wcs; /* World coordinate system structure */ { int i, mem, naxes; naxes = wcs->naxis; if (naxes > 2) naxes = 2; if (naxes < 1 || naxes > 9) { naxes = wcs->naxes; wcs->naxis = naxes; } mem = naxes * naxes * sizeof(double); if (wcs->lin.piximg == NULL) wcs->lin.piximg = (double*)malloc(mem); if (wcs->lin.piximg != NULL) { if (wcs->lin.imgpix == NULL) wcs->lin.imgpix = (double*)malloc(mem); if (wcs->lin.imgpix != NULL) { wcs->lin.flag = LINSET; if (naxes == 2) { for (i = 0; i < 4; i++) { wcs->lin.piximg[i] = wcs->cd[i]; } } else if (naxes == 3) { for (i = 0; i < 9; i++) wcs->lin.piximg[i] = 0.0; wcs->lin.piximg[0] = wcs->cd[0]; wcs->lin.piximg[1] = wcs->cd[1]; wcs->lin.piximg[3] = wcs->cd[2]; wcs->lin.piximg[4] = wcs->cd[3]; wcs->lin.piximg[8] = 1.0; } else if (naxes == 4) { for (i = 0; i < 16; i++) wcs->lin.piximg[i] = 0.0; wcs->lin.piximg[0] = wcs->cd[0]; wcs->lin.piximg[1] = wcs->cd[1]; wcs->lin.piximg[4] = wcs->cd[2]; wcs->lin.piximg[5] = wcs->cd[3]; wcs->lin.piximg[10] = 1.0; wcs->lin.piximg[15] = 1.0; } (void) matinv (naxes, wcs->lin.piximg, wcs->lin.imgpix); wcs->lin.crpix = wcs->crpix; wcs->lin.cdelt = wcs->cdelt; wcs->lin.pc = wcs->pc; wcs->lin.flag = LINSET; } } return; } /* Compute image rotation */ void wcsrotset (wcs) struct WorldCoor *wcs; /* World coordinate system structure */ { int off; double cra, cdec, xc, xn, xe, yc, yn, ye; /* If image is one-dimensional, leave rotation angle alone */ if (wcs->nxpix < 1.5 || wcs->nypix < 1.5) { wcs->imrot = wcs->rot; wcs->pa_north = wcs->rot + 90.0; wcs->pa_east = wcs->rot + 180.0; return; } /* Do not try anything if image is LINEAR (not Cartesian projection) */ if (wcs->syswcs == WCS_LINEAR) return; wcs->xinc = fabs (wcs->xinc); wcs->yinc = fabs (wcs->yinc); /* Compute position angles of North and East in image */ xc = wcs->xrefpix; yc = wcs->yrefpix; pix2wcs (wcs, xc, yc, &cra, &cdec); if (wcs->coorflip) { wcs2pix (wcs, cra+wcs->yinc, cdec, &xe, &ye, &off); wcs2pix (wcs, cra, cdec+wcs->xinc, &xn, &yn, &off); } else { wcs2pix (wcs, cra+wcs->xinc, cdec, &xe, &ye, &off); wcs2pix (wcs, cra, cdec+wcs->yinc, &xn, &yn, &off); } wcs->pa_north = raddeg (atan2 (yn-yc, xn-xc)); if (wcs->pa_north < -90.0) wcs->pa_north = wcs->pa_north + 360.0; wcs->pa_east = raddeg (atan2 (ye-yc, xe-xc)); if (wcs->pa_east < -90.0) wcs->pa_east = wcs->pa_east + 360.0; /* Compute image rotation angle from North */ if (wcs->pa_north < -90.0) wcs->imrot = 270.0 + wcs->pa_north; else wcs->imrot = wcs->pa_north - 90.0; /* Compute CROTA */ if (wcs->coorflip) { wcs->rot = wcs->imrot + 90.0; if (wcs->rot < 0.0) wcs->rot = wcs->rot + 360.0; } else wcs->rot = wcs->imrot; if (wcs->rot < 0.0) wcs->rot = wcs->rot + 360.0; if (wcs->rot >= 360.0) wcs->rot = wcs->rot - 360.0; /* Set image mirror flag based on axis orientation */ wcs->imflip = 0; if (wcs->pa_east - wcs->pa_north < -80.0 && wcs->pa_east - wcs->pa_north > -100.0) wcs->imflip = 1; if (wcs->pa_east - wcs->pa_north < 280.0 && wcs->pa_east - wcs->pa_north > 260.0) wcs->imflip = 1; if (wcs->pa_north - wcs->pa_east > 80.0 && wcs->pa_north - wcs->pa_east < 100.0) wcs->imflip = 1; if (wcs->coorflip) { if (wcs->imflip) wcs->yinc = -wcs->yinc; } else { if (!wcs->imflip) wcs->xinc = -wcs->xinc; } return; } /* Return 1 if WCS structure is filled, else 0 */ int iswcs (wcs) struct WorldCoor *wcs; /* World coordinate system structure */ { if (wcs == NULL) return (0); else return (wcs->wcson); } /* Return 0 if WCS structure is filled, else 1 */ int nowcs (wcs) struct WorldCoor *wcs; /* World coordinate system structure */ { if (wcs == NULL) return (1); else return (!wcs->wcson); } /* Reset the center of a WCS structure */ void wcsshift (wcs,rra,rdec,coorsys) struct WorldCoor *wcs; /* World coordinate system structure */ double rra; /* Reference pixel right ascension in degrees */ double rdec; /* Reference pixel declination in degrees */ char *coorsys; /* FK4 or FK5 coordinates (1950 or 2000) */ { if (nowcs (wcs)) return; /* Approximate world coordinate system from a known plate scale */ wcs->crval[0] = rra; wcs->crval[1] = rdec; wcs->xref = wcs->crval[0]; wcs->yref = wcs->crval[1]; /* Coordinate reference frame */ strcpy (wcs->radecsys,coorsys); wcs->syswcs = wcscsys (coorsys); if (wcs->syswcs == WCS_B1950) wcs->equinox = 1950.0; else wcs->equinox = 2000.0; return; } /* Print position of WCS center, if WCS is set */ void wcscent (wcs) struct WorldCoor *wcs; /* World coordinate system structure */ { double xpix,ypix, xpos1, xpos2, ypos1, ypos2; char wcstring[32]; double width, height, secpix, secpixh, secpixw; int lstr = 32; if (nowcs (wcs)) (void)fprintf (stderr,"No WCS information available\n"); else { if (wcs->prjcode == WCS_DSS) (void)fprintf (stderr,"WCS plate center %s\n", wcs->center); xpix = 0.5 * wcs->nxpix; ypix = 0.5 * wcs->nypix; (void) pix2wcst (wcs,xpix,ypix,wcstring, lstr); (void)fprintf (stderr,"WCS center %s %s %s %s at pixel (%.2f,%.2f)\n", wcs->ctype[0],wcs->ctype[1],wcstring,wcs->ptype,xpix,ypix); /* Image width */ (void) pix2wcs (wcs,1.0,ypix,&xpos1,&ypos1); (void) pix2wcs (wcs,wcs->nxpix,ypix,&xpos2,&ypos2); if (wcs->syswcs == WCS_LINEAR) { width = xpos2 - xpos1; if (width < 100.0) (void)fprintf (stderr, "WCS width = %.5f %s ",width, wcs->units[0]); else (void)fprintf (stderr, "WCS width = %.3f %s ",width, wcs->units[0]); } else { width = wcsdist (xpos1,ypos1,xpos2,ypos2); if (width < 1/60.0) (void)fprintf (stderr, "WCS width = %.2f arcsec ",width*3600.0); else if (width < 1.0) (void)fprintf (stderr, "WCS width = %.2f arcmin ",width*60.0); else (void)fprintf (stderr, "WCS width = %.3f degrees ",width); } secpixw = width / (wcs->nxpix - 1.0); /* Image height */ (void) pix2wcs (wcs,xpix,1.0,&xpos1,&ypos1); (void) pix2wcs (wcs,xpix,wcs->nypix,&xpos2,&ypos2); if (wcs->syswcs == WCS_LINEAR) { height = ypos2 - ypos1; if (height < 100.0) (void)fprintf (stderr, " height = %.5f %s ",height, wcs->units[1]); else (void)fprintf (stderr, " height = %.3f %s ",height, wcs->units[1]); } else { height = wcsdist (xpos1,ypos1,xpos2,ypos2); if (height < 1/60.0) (void) fprintf (stderr, " height = %.2f arcsec",height*3600.0); else if (height < 1.0) (void) fprintf (stderr, " height = %.2f arcmin",height*60.0); else (void) fprintf (stderr, " height = %.3f degrees",height); } secpixh = height / (wcs->nypix - 1.0); /* Image scale */ if (wcs->syswcs == WCS_LINEAR) { (void) fprintf (stderr,"\n"); (void) fprintf (stderr,"WCS %.5f %s/pixel, %.5f %s/pixel\n", wcs->xinc,wcs->units[0],wcs->yinc,wcs->units[1]); } else { if (wcs->xinc != 0.0 && wcs->yinc != 0.0) secpix = (fabs(wcs->xinc) + fabs(wcs->yinc)) * 0.5 * 3600.0; else if (secpixh > 0.0 && secpixw > 0.0) secpix = (secpixw + secpixh) * 0.5 * 3600.0; else if (wcs->xinc != 0.0 || wcs->yinc != 0.0) secpix = (fabs(wcs->xinc) + fabs(wcs->yinc)) * 3600.0; else secpix = (secpixw + secpixh) * 3600.0; if (secpix < 100.0) (void) fprintf (stderr, " %.3f arcsec/pixel\n",secpix); else if (secpix < 3600.0) (void) fprintf (stderr, " %.3f arcmin/pixel\n",secpix/60.0); else (void) fprintf (stderr, " %.3f degrees/pixel\n",secpix/3600.0); } } return; } /* Return RA and Dec of image center, plus size in RA and Dec */ void wcssize (wcs, cra, cdec, dra, ddec) struct WorldCoor *wcs; /* World coordinate system structure */ double *cra; /* Right ascension of image center (deg) (returned) */ double *cdec; /* Declination of image center (deg) (returned) */ double *dra; /* Half-width in right ascension (deg) (returned) */ double *ddec; /* Half-width in declination (deg) (returned) */ { double width, height; /* Find right ascension and declination of coordinates */ if (iswcs(wcs)) { wcsfull (wcs, cra, cdec, &width, &height); *dra = 0.5 * width / cos (degrad (*cdec)); *ddec = 0.5 * height; } else { *cra = 0.0; *cdec = 0.0; *dra = 0.0; *ddec = 0.0; } return; } /* Return RA and Dec of image center, plus size in degrees */ void wcsfull (wcs, cra, cdec, width, height) struct WorldCoor *wcs; /* World coordinate system structure */ double *cra; /* Right ascension of image center (deg) (returned) */ double *cdec; /* Declination of image center (deg) (returned) */ double *width; /* Width in degrees (returned) */ double *height; /* Height in degrees (returned) */ { double xpix, ypix, xpos1, xpos2, ypos1, ypos2, xcpix, ycpix; double xcent, ycent; /* Find right ascension and declination of coordinates */ if (iswcs(wcs)) { xcpix = (0.5 * wcs->nxpix) + 0.5; ycpix = (0.5 * wcs->nypix) + 0.5; (void) pix2wcs (wcs,xcpix,ycpix,&xcent, &ycent); *cra = xcent; *cdec = ycent; /* Compute image width in degrees */ xpix = 0.500001; (void) pix2wcs (wcs,xpix,ycpix,&xpos1,&ypos1); xpix = wcs->nxpix + 0.499999; (void) pix2wcs (wcs,xpix,ycpix,&xpos2,&ypos2); if (strncmp (wcs->ptype,"LINEAR",6) && strncmp (wcs->ptype,"PIXEL",5)) { *width = wcsdist (xpos1,ypos1,xpos2,ypos2); } else *width = sqrt (((ypos2-ypos1) * (ypos2-ypos1)) + ((xpos2-xpos1) * (xpos2-xpos1))); /* Compute image height in degrees */ ypix = 0.5; (void) pix2wcs (wcs,xcpix,ypix,&xpos1,&ypos1); ypix = wcs->nypix + 0.5; (void) pix2wcs (wcs,xcpix,ypix,&xpos2,&ypos2); if (strncmp (wcs->ptype,"LINEAR",6) && strncmp (wcs->ptype,"PIXEL",5)) *height = wcsdist (xpos1,ypos1,xpos2,ypos2); else *height = sqrt (((ypos2-ypos1) * (ypos2-ypos1)) + ((xpos2-xpos1) * (xpos2-xpos1))); } else { *cra = 0.0; *cdec = 0.0; *width = 0.0; *height = 0.0; } return; } /* Return minimum and maximum RA and Dec of image in degrees */ void wcsrange (wcs, ra1, ra2, dec1, dec2) struct WorldCoor *wcs; /* World coordinate system structure */ double *ra1; /* Minimum right ascension of image (deg) (returned) */ double *ra2; /* Maximum right ascension of image (deg) (returned) */ double *dec1; /* Minimum declination of image (deg) (returned) */ double *dec2; /* Maximum declination of image (deg) (returned) */ { double xpos1, xpos2, xpos3, xpos4, ypos1, ypos2, ypos3, ypos4, temp; if (iswcs(wcs)) { /* Compute image corner coordinates in degrees */ (void) pix2wcs (wcs,1.0,1.0,&xpos1,&ypos1); (void) pix2wcs (wcs,1.0,wcs->nypix,&xpos2,&ypos2); (void) pix2wcs (wcs,wcs->nxpix,1.0,&xpos3,&ypos3); (void) pix2wcs (wcs,wcs->nxpix,wcs->nypix,&xpos4,&ypos4); /* Find minimum right ascension or longitude */ *ra1 = xpos1; if (xpos2 < *ra1) *ra1 = xpos2; if (xpos3 < *ra1) *ra1 = xpos3; if (xpos4 < *ra1) *ra1 = xpos4; /* Find maximum right ascension or longitude */ *ra2 = xpos1; if (xpos2 > *ra2) *ra2 = xpos2; if (xpos3 > *ra2) *ra2 = xpos3; if (xpos4 > *ra2) *ra2 = xpos4; if (wcs->syswcs != WCS_LINEAR && wcs->syswcs != WCS_XY) { if (*ra2 - *ra1 > 180.0) { temp = *ra1; *ra1 = *ra2; *ra2 = temp; } } /* Find minimum declination or latitude */ *dec1 = ypos1; if (ypos2 < *dec1) *dec1 = ypos2; if (ypos3 < *dec1) *dec1 = ypos3; if (ypos4 < *dec1) *dec1 = ypos4; /* Find maximum declination or latitude */ *dec2 = ypos1; if (ypos2 > *dec2) *dec2 = ypos2; if (ypos3 > *dec2) *dec2 = ypos3; if (ypos4 > *dec2) *dec2 = ypos4; } else { *ra1 = 0.0; *ra2 = 0.0; *dec1 = 0.0; *dec2 = 0.0; } return; } /* Compute distance in degrees between two sky coordinates */ double wcsdist (x1,y1,x2,y2) double x1,y1; /* (RA,Dec) or (Long,Lat) in degrees */ double x2,y2; /* (RA,Dec) or (Long,Lat) in degrees */ { double xr1, xr2, yr1, yr2, r, diffi; double pos1[3], pos2[3], w, diff, cosb; int i; /* Convert two vectors to direction cosines */ r = 1.0; d2v3 (x1, y1, r, pos1); d2v3 (x2, y2, r, pos2); /* Modulus squared of half the difference vector */ w = 0.0; for (i = 0; i < 3; i++) { diffi = pos1[i] - pos2[i]; w = w + (diffi * diffi); } w = w / 4.0; if (w > 1.0) w = 1.0; /* Angle beween the vectors */ diff = 2.0 * atan2 (sqrt (w), sqrt (1.0 - w)); diff = raddeg (diff); return (diff); } /* Compute distance in degrees between two sky coordinates away from pole */ double wcsdiff (x1,y1,x2,y2) double x1,y1; /* (RA,Dec) or (Long,Lat) in degrees */ double x2,y2; /* (RA,Dec) or (Long,Lat) in degrees */ { double xdiff, ydiff, ycos, diff; ycos = cos (degrad ((y2 + y1) / 2.0)); xdiff = x2 - x1; if (xdiff > 180.0) xdiff = xdiff - 360.0; if (xdiff < -180.0) xdiff = xdiff + 360.0; xdiff = xdiff / ycos; ydiff = (y2 - y1); diff = sqrt ((xdiff * xdiff) + (ydiff * ydiff)); return (diff); } /* Initialize catalog search command set by -wcscom */ void wcscominit (wcs, i, command) struct WorldCoor *wcs; /* World coordinate system structure */ int i; /* Number of command (0-9) to initialize */ char *command; /* command with %s where coordinates will go */ { int lcom,icom; if (iswcs(wcs)) { lcom = strlen (command); if (lcom > 0) { if (wcs->command_format[i] != NULL) free (wcs->command_format[i]); wcs->command_format[i] = (char *) calloc (lcom+2, 1); if (wcs->command_format[i] == NULL) return; for (icom = 0; icom < lcom; icom++) { if (command[icom] == '_') wcs->command_format[i][icom] = ' '; else wcs->command_format[i][icom] = command[icom]; } wcs->command_format[i][lcom] = 0; } } return; } /* Execute Unix command with world coordinates (from x,y) and/or filename */ void wcscom ( wcs, i, filename, xfile, yfile, wcstring ) struct WorldCoor *wcs; /* World coordinate system structure */ int i; /* Number of command (0-9) to execute */ char *filename; /* Image file name */ double xfile,yfile; /* Image pixel coordinates for WCS command */ char *wcstring; /* WCS String from pix2wcst() */ { char command[120]; char comform[120]; char xystring[32]; char *fileform, *posform, *imform; int ier; if (nowcs (wcs)) { (void)fprintf(stderr,"WCSCOM: no WCS\n"); return; } if (wcs->command_format[i] != NULL) strcpy (comform, wcs->command_format[i]); else strcpy (comform, "sgsc -ah %s"); if (comform[0] > 0) { /* Create and execute search command */ fileform = strsrch (comform,"%f"); imform = strsrch (comform,"%x"); posform = strsrch (comform,"%s"); if (imform != NULL) { *(imform+1) = 's'; (void)sprintf (xystring, "%.2f %.2f", xfile, yfile); if (fileform != NULL) { *(fileform+1) = 's'; if (posform == NULL) { if (imform < fileform) (void)sprintf(command, comform, xystring, filename); else (void)sprintf(command, comform, filename, xystring); } else if (fileform < posform) { if (imform < fileform) (void)sprintf(command, comform, xystring, filename, wcstring); else if (imform < posform) (void)sprintf(command, comform, filename, xystring, wcstring); else (void)sprintf(command, comform, filename, wcstring, xystring); } else if (imform < posform) (void)sprintf(command, comform, xystring, wcstring, filename); else if (imform < fileform) (void)sprintf(command, comform, wcstring, xystring, filename); else (void)sprintf(command, comform, wcstring, filename, xystring); } else if (posform == NULL) (void)sprintf(command, comform, xystring); else if (imform < posform) (void)sprintf(command, comform, xystring, wcstring); else (void)sprintf(command, comform, wcstring, xystring); } else if (fileform != NULL) { *(fileform+1) = 's'; if (posform == NULL) (void)sprintf(command, comform, filename); else if (fileform < posform) (void)sprintf(command, comform, filename, wcstring); else (void)sprintf(command, comform, wcstring, filename); } else (void)sprintf(command, comform, wcstring); ier = system (command); if (ier) (void)fprintf(stderr,"WCSCOM: %s failed %d\n",command,ier); } return; } /* Initialize WCS output coordinate system for use by PIX2WCS() */ void wcsoutinit (wcs, coorsys) struct WorldCoor *wcs; /* World coordinate system structure */ char *coorsys; /* Input world coordinate system: FK4, FK5, B1950, J2000, GALACTIC, ECLIPTIC fk4, fk5, b1950, j2000, galactic, ecliptic */ { int sysout, i; if (nowcs (wcs)) return; /* If argument is null, set to image system and equinox */ if (coorsys == NULL || strlen (coorsys) < 1 || !strcmp(coorsys,"IMSYS") || !strcmp(coorsys,"imsys")) { sysout = wcs->syswcs; strcpy (wcs->radecout, wcs->radecsys); wcs->eqout = wcs->equinox; if (sysout == WCS_B1950) { if (wcs->eqout != 1950.0) { wcs->radecout[0] = 'B'; sprintf (wcs->radecout+1,"%.4f", wcs->equinox); i = strlen(wcs->radecout) - 1; if (wcs->radecout[i] == '0') wcs->radecout[i] = (char)0; i = strlen(wcs->radecout) - 1; if (wcs->radecout[i] == '0') wcs->radecout[i] = (char)0; i = strlen(wcs->radecout) - 1; if (wcs->radecout[i] == '0') wcs->radecout[i] = (char)0; } else strcpy (wcs->radecout, "B1950"); } else if (sysout == WCS_J2000) { if (wcs->eqout != 2000.0) { wcs->radecout[0] = 'J'; sprintf (wcs->radecout+1,"%.4f", wcs->equinox); i = strlen(wcs->radecout) - 1; if (wcs->radecout[i] == '0') wcs->radecout[i] = (char)0; i = strlen(wcs->radecout) - 1; if (wcs->radecout[i] == '0') wcs->radecout[i] = (char)0; i = strlen(wcs->radecout) - 1; if (wcs->radecout[i] == '0') wcs->radecout[i] = (char)0; } else strcpy (wcs->radecout, "J2000"); } } /* Ignore new coordinate system if it is not supported */ else { if ((sysout = wcscsys (coorsys)) < 0) return; /* Do not try to convert linear or alt-az coordinates */ if (sysout != wcs->syswcs && (wcs->syswcs == WCS_LINEAR || wcs->syswcs == WCS_ALTAZ)) return; strcpy (wcs->radecout, coorsys); wcs->eqout = wcsceq (coorsys); } wcs->sysout = sysout; if (wcs->wcson) { /* Set output in degrees flag and number of decimal places */ if (wcs->sysout == WCS_GALACTIC || wcs->sysout == WCS_ECLIPTIC || wcs->sysout == WCS_PLANET) { wcs->degout = 1; wcs->ndec = 5; } else if (wcs->sysout == WCS_ALTAZ) { wcs->degout = 1; wcs->ndec = 5; } else if (wcs->sysout == WCS_NPOLE || wcs->sysout == WCS_SPA) { wcs->degout = 1; wcs->ndec = 5; } else { wcs->degout = 0; wcs->ndec = 3; } } return; } /* Return current value of WCS output coordinate system set by -wcsout */ char * getwcsout(wcs) struct WorldCoor *wcs; /* World coordinate system structure */ { if (nowcs (wcs)) return (NULL); else return(wcs->radecout); } /* Initialize WCS input coordinate system for use by WCS2PIX() */ void wcsininit (wcs, coorsys) struct WorldCoor *wcs; /* World coordinate system structure */ char *coorsys; /* Input world coordinate system: FK4, FK5, B1950, J2000, GALACTIC, ECLIPTIC fk4, fk5, b1950, j2000, galactic, ecliptic */ { int sysin, i; if (nowcs (wcs)) return; /* If argument is null, set to image system and equinox */ if (coorsys == NULL || strlen (coorsys) < 1) { wcs->sysin = wcs->syswcs; strcpy (wcs->radecin, wcs->radecsys); wcs->eqin = wcs->equinox; if (wcs->sysin == WCS_B1950) { if (wcs->eqin != 1950.0) { wcs->radecin[0] = 'B'; sprintf (wcs->radecin+1,"%.4f", wcs->equinox); i = strlen(wcs->radecin) - 1; if (wcs->radecin[i] == '0') wcs->radecin[i] = (char)0; i = strlen(wcs->radecin) - 1; if (wcs->radecin[i] == '0') wcs->radecin[i] = (char)0; i = strlen(wcs->radecin) - 1; if (wcs->radecin[i] == '0') wcs->radecin[i] = (char)0; } else strcpy (wcs->radecin, "B1950"); } else if (wcs->sysin == WCS_J2000) { if (wcs->eqin != 2000.0) { wcs->radecin[0] = 'J'; sprintf (wcs->radecin+1,"%.4f", wcs->equinox); i = strlen(wcs->radecin) - 1; if (wcs->radecin[i] == '0') wcs->radecin[i] = (char)0; i = strlen(wcs->radecin) - 1; if (wcs->radecin[i] == '0') wcs->radecin[i] = (char)0; i = strlen(wcs->radecin) - 1; if (wcs->radecin[i] == '0') wcs->radecin[i] = (char)0; } else strcpy (wcs->radecin, "J2000"); } } /* Ignore new coordinate system if it is not supported */ if ((sysin = wcscsys (coorsys)) < 0) return; wcs->sysin = sysin; wcs->eqin = wcsceq (coorsys); strcpy (wcs->radecin, coorsys); return; } /* Return current value of WCS input coordinate system set by wcsininit */ char * getwcsin (wcs) struct WorldCoor *wcs; /* World coordinate system structure */ { if (nowcs (wcs)) return (NULL); else return (wcs->radecin); } /* Set WCS output in degrees or hh:mm:ss dd:mm:ss, returning old flag value */ int setwcsdeg(wcs, new) struct WorldCoor *wcs; /* World coordinate system structure */ int new; /* 1: degrees, 0: h:m:s d:m:s */ { int old; if (nowcs (wcs)) return (0); old = wcs->degout; wcs->degout = new; if (new == 1 && old == 0 && wcs->ndec == 3) wcs->ndec = 6; if (new == 0 && old == 1 && wcs->ndec == 5) wcs->ndec = 3; return(old); } /* Set number of decimal places in pix2wcst output string */ int wcsndec (wcs, ndec) struct WorldCoor *wcs; /* World coordinate system structure */ int ndec; /* Number of decimal places in output string */ /* If < 0, return current unchanged value */ { if (nowcs (wcs)) return (0); else if (ndec >= 0) wcs->ndec = ndec; return (wcs->ndec); } /* Return current value of coordinate system */ char * getradecsys(wcs) struct WorldCoor *wcs; /* World coordinate system structure */ { if (nowcs (wcs)) return (NULL); else return (wcs->radecsys); } /* Set output string mode for LINEAR coordinates */ void setwcslin (wcs, mode) struct WorldCoor *wcs; /* World coordinate system structure */ int mode; /* mode = 0: x y linear mode = 1: x units x units mode = 2: x y linear units */ { if (iswcs (wcs)) wcs->linmode = mode; return; } /* Convert pixel coordinates to World Coordinate string */ int pix2wcst (wcs, xpix, ypix, wcstring, lstr) struct WorldCoor *wcs; /* World coordinate system structure */ double xpix,ypix; /* Image coordinates in pixels */ char *wcstring; /* World coordinate string (returned) */ int lstr; /* Length of world coordinate string (returned) */ { double xpos,ypos; char rastr[32], decstr[32]; int minlength, lunits, lstring; if (nowcs (wcs)) { if (lstr > 0) wcstring[0] = 0; return(0); } pix2wcs (wcs,xpix,ypix,&xpos,&ypos); /* If point is off scale, set string accordingly */ if (wcs->offscl) { (void)sprintf (wcstring,"Off map"); return (1); } /* Print coordinates in degrees */ else if (wcs->degout == 1) { minlength = 9 + (2 * wcs->ndec); if (lstr > minlength) { deg2str (rastr, 32, xpos, wcs->ndec); deg2str (decstr, 32, ypos, wcs->ndec); if (wcs->tabsys) (void)sprintf (wcstring,"%s %s", rastr, decstr); else (void)sprintf (wcstring,"%s %s", rastr, decstr); lstr = lstr - minlength; } else { if (wcs->tabsys) strncpy (wcstring,"********* **********",lstr); else strncpy (wcstring,"*******************",lstr); lstr = 0; } } /* print coordinates in sexagesimal notation */ else if (wcs->degout == 0) { minlength = 18 + (2 * wcs->ndec); if (lstr > minlength) { if (wcs->sysout == WCS_J2000 || wcs->sysout == WCS_B1950) { ra2str (rastr, 32, xpos, wcs->ndec); dec2str (decstr, 32, ypos, wcs->ndec-1); } else { dec2str (rastr, 32, xpos, wcs->ndec); dec2str (decstr, 32, ypos, wcs->ndec); } if (wcs->tabsys) { (void)sprintf (wcstring,"%s %s", rastr, decstr); } else { (void)sprintf (wcstring,"%s %s", rastr, decstr); } lstr = lstr - minlength; } else { if (wcs->tabsys) { strncpy (wcstring,"************* *************",lstr); } else { strncpy (wcstring,"**************************",lstr); } lstr = 0; } } /* Label galactic coordinates */ if (wcs->sysout == WCS_GALACTIC) { if (lstr > 9 && wcs->printsys) { if (wcs->tabsys) strcat (wcstring," galactic"); else strcat (wcstring," galactic"); } } /* Label ecliptic coordinates */ else if (wcs->sysout == WCS_ECLIPTIC) { if (lstr > 9 && wcs->printsys) { if (wcs->tabsys) strcat (wcstring," ecliptic"); else strcat (wcstring," ecliptic"); } } /* Label planet coordinates */ else if (wcs->sysout == WCS_PLANET) { if (lstr > 9 && wcs->printsys) { if (wcs->tabsys) strcat (wcstring," planet"); else strcat (wcstring," planet"); } } /* Label alt-az coordinates */ else if (wcs->sysout == WCS_ALTAZ) { if (lstr > 7 && wcs->printsys) { if (wcs->tabsys) strcat (wcstring," alt-az"); else strcat (wcstring," alt-az"); } } /* Label north pole angle coordinates */ else if (wcs->sysout == WCS_NPOLE) { if (lstr > 7 && wcs->printsys) { if (wcs->tabsys) strcat (wcstring," long-npa"); else strcat (wcstring," long-npa"); } } /* Label south pole angle coordinates */ else if (wcs->sysout == WCS_SPA) { if (lstr > 7 && wcs->printsys) { if (wcs->tabsys) strcat (wcstring," long-spa"); else strcat (wcstring," long-spa"); } } /* Label equatorial coordinates */ else if (wcs->sysout==WCS_B1950 || wcs->sysout==WCS_J2000) { if (lstr > (int) strlen(wcs->radecout)+1 && wcs->printsys) { if (wcs->tabsys) strcat (wcstring," "); else strcat (wcstring," "); strcat (wcstring, wcs->radecout); } } /* Output linear coordinates */ else { num2str (rastr, xpos, 0, wcs->ndec); num2str (decstr, ypos, 0, wcs->ndec); lstring = strlen (rastr) + strlen (decstr) + 1; lunits = strlen (wcs->units[0]) + strlen (wcs->units[1]) + 2; if (wcs->syswcs == WCS_LINEAR && wcs->linmode == 1) { if (lstr > lstring + lunits) { if (strlen (wcs->units[0]) > 0) { strcat (rastr, " "); strcat (rastr, wcs->units[0]); } if (strlen (wcs->units[1]) > 0) { strcat (decstr, " "); strcat (decstr, wcs->units[1]); } lstring = lstring + lunits; } } if (lstr > lstring) { if (wcs->tabsys) (void)sprintf (wcstring,"%s %s", rastr, decstr); else (void)sprintf (wcstring,"%s %s", rastr, decstr); } else { if (wcs->tabsys) strncpy (wcstring,"********** *********",lstr); else strncpy (wcstring,"*******************",lstr); } if (wcs->syswcs == WCS_LINEAR && wcs->linmode != 1 && lstr > lstring + 7) strcat (wcstring, " linear"); if (wcs->syswcs == WCS_LINEAR && wcs->linmode == 2 && lstr > lstring + lunits + 7) { if (strlen (wcs->units[0]) > 0) { strcat (wcstring, " "); strcat (wcstring, wcs->units[0]); } if (strlen (wcs->units[1]) > 0) { strcat (wcstring, " "); strcat (wcstring, wcs->units[1]); } } } return (1); } /* Convert pixel coordinates to World Coordinates */ void pix2wcs (wcs,xpix,ypix,xpos,ypos) struct WorldCoor *wcs; /* World coordinate system structure */ double xpix,ypix; /* x and y image coordinates in pixels */ double *xpos,*ypos; /* RA and Dec in degrees (returned) */ { double xpi, ypi, xp, yp; double eqin, eqout; int wcspos(); if (nowcs (wcs)) return; wcs->xpix = xpix; wcs->ypix = ypix; wcs->zpix = zpix; wcs->offscl = 0; /* If this WCS is converted from another WCS rather than pixels, convert now */ if (wcs->wcs != NULL) { pix2wcs (wcs->wcs, xpix, ypix, &xpi, &ypi); } else { pix2foc (wcs, xpix, ypix, &xpi, &ypi); } /* Convert image coordinates to sky coordinates */ /* Use Digitized Sky Survey plate fit */ if (wcs->prjcode == WCS_DSS) { if (dsspos (xpi, ypi, wcs, &xp, &yp)) wcs->offscl = 1; } /* Use SAO plate fit */ else if (wcs->prjcode == WCS_PLT) { if (platepos (xpi, ypi, wcs, &xp, &yp)) wcs->offscl = 1; } /* Use NOAO IRAF corrected plane tangent projection */ else if (wcs->prjcode == WCS_TNX) { if (tnxpos (xpi, ypi, wcs, &xp, &yp)) wcs->offscl = 1; } /* Use Classic AIPS projections */ else if (wcs->wcsproj == WCS_OLD || wcs->prjcode <= 0) { if (worldpos (xpi, ypi, wcs, &xp, &yp)) wcs->offscl = 1; } /* Use Mark Calabretta's WCSLIB projections */ else if (wcspos (xpi, ypi, wcs, &xp, &yp)) wcs->offscl = 1; /* Do not change coordinates if offscale */ if (wcs->offscl) { *xpos = 0.0; *ypos = 0.0; } else { /* Convert coordinates to output system, if not LINEAR */ if (wcs->prjcode > 0) { /* Convert coordinates to desired output system */ eqin = wcs->equinox; eqout = wcs->eqout; wcscon (wcs->syswcs,wcs->sysout,eqin,eqout,&xp,&yp,wcs->epoch); } if (wcs->latbase == 90) yp = 90.0 - yp; else if (wcs->latbase == -90) yp = yp - 90.0; wcs->xpos = xp; wcs->ypos = yp; *xpos = xp; *ypos = yp; } /* Keep RA/longitude within range if spherical coordinate output (Not LINEAR or XY) */ if (wcs->sysout > 0 && wcs->sysout != 6 && wcs->sysout != 10) { if (*xpos < 0.0) *xpos = *xpos + 360.0; else if (*xpos > 360.0) *xpos = *xpos - 360.0; } return; } /* Convert World Coordinates to pixel coordinates */ void wcs2pix (wcs, xpos, ypos, xpix, ypix, offscl) struct WorldCoor *wcs; /* World coordinate system structure */ double xpos,ypos; /* World coordinates in degrees */ double *xpix,*ypix; /* Image coordinates in pixels */ int *offscl; /* 0 if within bounds, else off scale */ { wcsc2pix (wcs, xpos, ypos, wcs->radecin, xpix, ypix, offscl); return; } /* Convert World Coordinates to pixel coordinates */ void wcsc2pix (wcs, xpos, ypos, coorsys, xpix, ypix, offscl) struct WorldCoor *wcs; /* World coordinate system structure */ double xpos,ypos; /* World coordinates in degrees */ char *coorsys; /* Input world coordinate system: FK4, FK5, B1950, J2000, GALACTIC, ECLIPTIC fk4, fk5, b1950, j2000, galactic, ecliptic * If NULL, use image WCS */ double *xpix,*ypix; /* Image coordinates in pixels */ int *offscl; /* 0 if within bounds, else off scale */ { struct WorldCoor *depwcs; /* Dependent WCS structure */ double xp, yp, xpi, ypi; double eqin, eqout; int sysin; int wcspix(); if (nowcs (wcs)) return; *offscl = 0; xp = xpos; yp = ypos; if (wcs->latbase == 90) yp = 90.0 - yp; else if (wcs->latbase == -90) yp = yp - 90.0; if (coorsys == NULL) { sysin = wcs->syswcs; eqin = wcs->equinox; } else { sysin = wcscsys (coorsys); eqin = wcsceq (coorsys); } wcs->zpix = 1.0; /* Convert coordinates to same system as image */ if (sysin > 0 && sysin != 6 && sysin != 10) { eqout = wcs->equinox; wcscon (sysin, wcs->syswcs, eqin, eqout, &xp, &yp, wcs->epoch); } /* Convert sky coordinates to image coordinates */ /* Use Digitized Sky Survey plate fit */ if (wcs->prjcode == WCS_DSS) { if (dsspix (xp, yp, wcs, &xpi, &ypi)) *offscl = 1; } /* Use SAO polynomial plate fit */ else if (wcs->prjcode == WCS_PLT) { if (platepix (xp, yp, wcs, &xpi, &ypi)) *offscl = 1; } /* Use NOAO IRAF corrected plane tangent projection */ else if (wcs->prjcode == WCS_TNX) { if (tnxpix (xp, yp, wcs, &xpi, &ypi)) *offscl = 1; } /* Use Classic AIPS projections */ else if (wcs->wcsproj == WCS_OLD || wcs->prjcode <= 0) { if (worldpix (xp, yp, wcs, &xpi, &ypi)) *offscl = 1; } /* Use Mark Calabretta's WCSLIB projections */ else if (wcspix (xp, yp, wcs, &xpi, &ypi)) { *offscl = 1; } /* If this WCS is converted from another WCS rather than pixels, convert now */ if (wcs->wcs != NULL) { wcsc2pix (wcs->wcs, xpi, ypi, NULL, xpix, ypix, offscl); } else { foc2pix (wcs, xpi, ypi, xpix, ypix); /* Set off-scale flag to 2 if off image but within bounds of projection */ if (!*offscl) { if (*xpix < 0.5 || *ypix < 0.5) *offscl = 2; else if (*xpix > wcs->nxpix + 0.5 || *ypix > wcs->nypix + 0.5) *offscl = 2; } } wcs->offscl = *offscl; wcs->xpos = xpos; wcs->ypos = ypos; wcs->xpix = *xpix; wcs->ypix = *ypix; /* If this WCS is converted to another WCS rather than pixels, convert now */ if (wcs->wcsdep != NULL) { xpos = *xpix; ypos = *ypix; depwcs = wcs->wcsdep; wcsc2pix (wcs->wcsdep, xpos, ypos, depwcs->radecin, xpix, ypix, offscl); } return; } int wcspos (xpix, ypix, wcs, xpos, ypos) /* Input: */ double xpix; /* x pixel number (RA or long without rotation) */ double ypix; /* y pixel number (dec or lat without rotation) */ struct WorldCoor *wcs; /* WCS parameter structure */ /* Output: */ double *xpos; /* x (RA) coordinate (deg) */ double *ypos; /* y (dec) coordinate (deg) */ { int offscl; int i; int wcsrev(); double wcscrd[4], imgcrd[4], pixcrd[4]; double phi, theta; *xpos = 0.0; *ypos = 0.0; pixcrd[0] = xpix; pixcrd[1] = ypix; if (wcs->prjcode == WCS_CSC || wcs->prjcode == WCS_QSC || wcs->prjcode == WCS_TSC) pixcrd[2] = (double) (izpix + 1); else pixcrd[2] = zpix; pixcrd[3] = 1.0; for (i = 0; i < 4; i++) imgcrd[i] = 0.0; offscl = wcsrev ((void *)&wcs->ctype, &wcs->wcsl, pixcrd, &wcs->lin, imgcrd, &wcs->prj, &phi, &theta, wcs->crval, &wcs->cel, wcscrd); if (offscl == 0) { *xpos = wcscrd[wcs->wcsl.lng]; *ypos = wcscrd[wcs->wcsl.lat]; } return (offscl); } int wcspix (xpos, ypos, wcs, xpix, ypix) /* Input: */ double xpos; /* x (RA) coordinate (deg) */ double ypos; /* y (dec) coordinate (deg) */ struct WorldCoor *wcs; /* WCS parameter structure */ /* Output: */ double *xpix; /* x pixel number (RA or long without rotation) */ double *ypix; /* y pixel number (dec or lat without rotation) */ { int offscl; int wcsfwd(); double wcscrd[4], imgcrd[4], pixcrd[4]; double phi, theta; *xpix = 0.0; *ypix = 0.0; if (wcs->wcsl.flag != WCSSET) { if (wcsset (wcs->lin.naxis, (void *)&wcs->ctype, &wcs->wcsl) ) return (1); } /* Set input for WCSLIB subroutines */ wcscrd[0] = 0.0; wcscrd[1] = 0.0; wcscrd[2] = 0.0; wcscrd[3] = 0.0; wcscrd[wcs->wcsl.lng] = xpos; wcscrd[wcs->wcsl.lat] = ypos; /* Initialize output for WCSLIB subroutines */ pixcrd[0] = 0.0; pixcrd[1] = 0.0; pixcrd[2] = 1.0; pixcrd[3] = 1.0; imgcrd[0] = 0.0; imgcrd[1] = 0.0; imgcrd[2] = 1.0; imgcrd[3] = 1.0; /* Invoke WCSLIB subroutines for coordinate conversion */ offscl = wcsfwd ((void *)&wcs->ctype, &wcs->wcsl, wcscrd, wcs->crval, &wcs->cel, &phi, &theta, &wcs->prj, imgcrd, &wcs->lin, pixcrd); if (!offscl) { *xpix = pixcrd[0]; *ypix = pixcrd[1]; if (wcs->prjcode == WCS_CSC || wcs->prjcode == WCS_QSC || wcs->prjcode == WCS_TSC) wcs->zpix = pixcrd[2] - 1.0; else wcs->zpix = pixcrd[2]; } return (offscl); } /* Set third dimension for cube projections */ int wcszin (izpix0) int izpix0; /* coordinate in third dimension (if < 0, return current value without changing it */ { if (izpix0 > -1) { izpix = izpix0; zpix = (double) izpix0; } return (izpix); } /* Return third dimension for cube projections */ int wcszout (wcs) struct WorldCoor *wcs; /* WCS parameter structure */ { return ((int) wcs->zpix); } /* Set file name for error messages */ void setwcsfile (filename) char *filename; /* FITS or IRAF file with WCS */ { if (strlen (filename) < 256) strcpy (wcsfile, filename); else strncpy (wcsfile, filename, 255); return; } /* Set error message */ void setwcserr (errmsg) char *errmsg; /* Error mesage < 80 char */ { strcpy (wcserrmsg, errmsg); return; } /* Print error message */ void wcserr () { if (strlen (wcsfile) > 0) fprintf (stderr, "%s in file %s\n",wcserrmsg, wcsfile); else fprintf (stderr, "%s\n",wcserrmsg); return; } /* Flag to use AIPS WCS subroutines instead of WCSLIB */ void setdefwcs (wp) int wp; { wcsproj0 = wp; return; } int getdefwcs () { return (wcsproj0); } /* Save output default coordinate system */ static char wcscoor0[16]; void savewcscoor (wcscoor) char *wcscoor; { strcpy (wcscoor0, wcscoor); return; } /* Return preset output default coordinate system */ char * getwcscoor () { return (wcscoor0); } /* Save default commands */ static char *wcscom0[10]; void savewcscom (i, wcscom) int i; char *wcscom; { int lcom; if (i < 0) i = 0; else if (i > 9) i = 9; lcom = strlen (wcscom) + 2; wcscom0[i] = (char *) calloc (lcom, 1); if (wcscom0[i] != NULL) strcpy (wcscom0[i], wcscom); return; } void setwcscom (wcs) struct WorldCoor *wcs; /* WCS parameter structure */ { char envar[16]; int i; char *str; if (nowcs(wcs)) return; for (i = 0; i < 10; i++) { if (i == 0) strcpy (envar, "WCS_COMMAND"); else sprintf (envar, "WCS_COMMAND%d", i); if (wcscom0[i] != NULL) wcscominit (wcs, i, wcscom0[i]); else if ((str = getenv (envar)) != NULL) wcscominit (wcs, i, str); else if (i == 1) wcscominit (wcs, i, "sua2 -ah %s"); /* F1= Search USNO-A2.0 Catalog */ else if (i == 2) wcscominit (wcs, i, "sgsc -ah %s"); /* F2= Search HST GSC */ else if (i == 3) wcscominit (wcs, i, "sty2 -ah %s"); /* F3= Search Tycho-2 Catalog */ else if (i == 4) wcscominit (wcs, i, "sppm -ah %s"); /* F4= Search PPM Catalog */ else if (i == 5) wcscominit (wcs, i, "ssao -ah %s"); /* F5= Search SAO Catalog */ else wcs->command_format[i] = NULL; } return; } char * getwcscom (i) int i; { return (wcscom0[i]); } void freewcscom (wcs) struct WorldCoor *wcs; /* WCS parameter structure */ { int i; for (i = 0; i < 10; i++) { if (wcscom0[i] != NULL) { free (wcscom0[i]); wcscom0[i] = NULL; } } if (iswcs (wcs)) { for (i = 0; i < 10; i++) { if (wcs->command_format[i] != NULL) { free (wcs->command_format[i]); } } } return; } int cpwcs (header, cwcs) char **header; /* Pointer to start of FITS header */ char *cwcs; /* Keyword suffix character for output WCS */ { double tnum; int dkwd[100]; int i, maxnkwd, ikwd, nleft, lbuff, lhead, nkwd, nbytes; int nkwdw; char **kwd; char *newhead, *oldhead; char kwdc[16], keyword[16]; char tstr[80]; /* Allocate array of keywords to be transferred */ maxnkwd = 100; kwd = (char **)calloc (maxnkwd, sizeof(char *)); for (ikwd = 0; ikwd < maxnkwd; ikwd++) kwd[ikwd] = (char *) calloc (16, 1); /* Make list of all possible keywords to be transferred */ nkwd = 0; strcpy (kwd[++nkwd], "EPOCH"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "EQUINOX"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "RADECSYS"); dkwd[nkwd] = 0; strcpy (kwd[++nkwd], "CTYPE1"); dkwd[nkwd] = 0; strcpy (kwd[++nkwd], "CTYPE2"); dkwd[nkwd] = 0; strcpy (kwd[++nkwd], "CRVAL1"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "CRVAL2"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "CDELT1"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "CDELT2"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "CRPIX1"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "CRPIX2"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "CROTA1"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "CROTA2"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "CD1_1"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "CD1_2"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "CD2_1"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "CD2_2"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "PC1_1"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "PC1_2"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "PC2_1"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "PC2_2"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "PC001001"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "PC001002"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "PC002001"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "PC002002"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "LATPOLE"); dkwd[nkwd] = 1; strcpy (kwd[++nkwd], "LONPOLE"); dkwd[nkwd] = 1; for (i = 1; i < 13; i++) { sprintf (keyword,"CO1_%d", i); strcpy (kwd[++nkwd], keyword); dkwd[nkwd] = 1; } for (i = 1; i < 13; i++) { sprintf (keyword,"CO2_%d", i); strcpy (kwd[++nkwd], keyword); dkwd[nkwd] = 1; } for (i = 0; i < 10; i++) { sprintf (keyword,"PROJP%d", i); strcpy (kwd[++nkwd], keyword); dkwd[nkwd] = 1; } for (i = 0; i < 10; i++) { sprintf (keyword,"PV1_%d", i); strcpy (kwd[++nkwd], keyword); dkwd[nkwd] = 1; } for (i = 0; i < 10; i++) { sprintf (keyword,"PV2_%d", i); strcpy (kwd[++nkwd], keyword); dkwd[nkwd] = 1; } /* Allocate new header buffer if needed */ lhead = (ksearch (*header, "END") - *header) + 80; lbuff = gethlength (*header); nleft = (lbuff - lhead) / 80; if (nleft < nkwd) { nbytes = lhead + (nkwd * 80) + 400; newhead = (char *) calloc (1, nbytes); strncpy (newhead, *header, lhead); oldhead = *header; header = &newhead; free (oldhead); } /* Copy keywords to new WCS ID in header */ nkwdw = 0; for (i = 0; i < nkwd; i++) { if (dkwd[i]) { if (hgetr8 (*header, kwd[i], &tnum)) { nkwdw++; if (!strncmp (kwd[i], "PC0", 3)) { if (!strcmp (kwd[i], "PC001001")) strcpy (kwdc, "PC1_1"); else if (!strcmp (kwd[i], "PC001002")) strcpy (kwdc, "PC1_2"); else if (!strcmp (kwd[i], "PC002001")) strcpy (kwdc, "PC2_1"); else strcpy (kwdc, "PC2_2"); } else strcpy (kwdc, kwd[i]); strncat (kwdc, cwcs, 1); (void)hputr8 (*header, kwdc, tnum); } } else { if (hgets (*header, kwd[i], 80, tstr)) { nkwdw++; if (!strncmp (kwd[i], "RADECSYS", 8)) strcpy (kwdc, "RADECSY"); else strcpy (kwdc, kwd[i]); strncat (kwdc, cwcs, 1); hputs (*header, kwdc, tstr); } } } /* Free keyword list array */ for (ikwd = 0; ikwd < maxnkwd; ikwd++) free (kwd[ikwd]); free (kwd); kwd = NULL; return (nkwdw); } /* Oct 28 1994 new program * Dec 21 1994 Implement CD rotation matrix * Dec 22 1994 Allow RA and DEC to be either x,y or y,x * * Mar 6 1995 Add Digital Sky Survey plate fit * May 2 1995 Add prototype of PIX2WCST to WCSCOM * May 25 1995 Print leading zero for hours and degrees * Jun 21 1995 Add WCS2PIX to get pixels from WCS * Jun 21 1995 Read plate scale from FITS header for plate solution * Jul 6 1995 Pass WCS structure as argument; malloc it in WCSINIT * Jul 6 1995 Check string lengths in PIX2WCST * Aug 16 1995 Add galactic coordinate conversion to PIX2WCST * Aug 17 1995 Return 0 from iswcs if wcs structure is not yet set * Sep 8 1995 Do not include malloc.h if VMS * Sep 8 1995 Check for legal WCS before trying anything * Sep 8 1995 Do not try to set WCS if missing key keywords * Oct 18 1995 Add WCSCENT and WCSDIST to print center and size of image * Nov 6 1995 Include stdlib.h instead of malloc.h * Dec 6 1995 Fix format statement in PIX2WCST * Dec 19 1995 Change MALLOC to CALLOC to initialize array to zeroes * Dec 19 1995 Explicitly initialize rotation matrix and yinc * Dec 22 1995 If SECPIX is set, use approximate WCS * Dec 22 1995 Always print coordinate system * * Jan 12 1996 Use plane-tangent, not linear, projection if SECPIX is set * Jan 12 1996 Add WCSSET to set WCS without an image * Feb 15 1996 Replace all calls to HGETC with HGETS * Feb 20 1996 Add tab table output from PIX2WCST * Apr 2 1996 Convert all equinoxes to B1950 or J2000 * Apr 26 1996 Get and use image epoch for accurate FK4/FK5 conversions * May 16 1996 Clean up internal documentation * May 17 1996 Return width in right ascension degrees, not sky degrees * May 24 1996 Remove extraneous print command from WCSSIZE * May 28 1996 Add NOWCS and WCSSHIFT subroutines * Jun 11 1996 Drop unused variables after running lint * Jun 12 1996 Set equinox as well as system in WCSSHIFT * Jun 14 1996 Make DSS keyword searches more robust * Jul 1 1996 Allow for SECPIX1 and SECPIX2 keywords * Jul 2 1996 Test for CTYPE1 instead of CRVAL1 * Jul 5 1996 Declare all subroutines in wcs.h * Jul 19 1996 Add subroutine WCSFULL to return real image size * Aug 12 1996 Allow systemless coordinates which cannot be converted * Aug 15 1996 Allow LINEAR WCS to pass numbers through transparently * Aug 15 1996 Add WCSERR to print error message under calling program control * Aug 16 1996 Add latitude and longitude as image coordinate types * Aug 26 1996 Fix arguments to HLENGTH in WCSNINIT * Aug 28 1996 Explicitly set OFFSCL in WCS2PIX if coordinates outside image * Sep 3 1996 Return computed pixel values even if they are offscale * Sep 6 1996 Allow filename to be passed by WCSCOM * Oct 8 1996 Default to 2000 for EQUINOX and EPOCH and FK5 for RADECSYS * Oct 8 1996 If EPOCH is 0 and EQUINOX is not set, default to 1950 and FK4 * Oct 15 1996 Add comparison when testing an assignment * Oct 16 1996 Allow PIXEL CTYPE which means WCS is same as image coordinates * Oct 21 1996 Add WCS_COMMAND environment variable * Oct 25 1996 Add image scale to WCSCENT * Oct 30 1996 Fix bugs in WCS2PIX * Oct 31 1996 Fix CD matrix rotation angle computation * Oct 31 1996 Use inline degree <-> radian conversion functions * Nov 1 1996 Add option to change number of decimal places in PIX2WCST * Nov 5 1996 Set wcs->crot to 1 if rotation matrix is used * Dec 2 1996 Add altitide/azimuth coordinates * Dec 13 1996 Fix search format setting from environment * * Jan 22 1997 Add ifdef for Eric Mandel (SAOtng) * Feb 5 1997 Add wcsout for Eric Mandel * Mar 20 1997 Drop unused variable STR in WCSCOM * May 21 1997 Do not make pixel coordinates mod 360 in PIX2WCST * May 22 1997 Add PIXEL prjcode = -1; * Jul 11 1997 Get center pixel x and y from header even if no WCS * Aug 7 1997 Add NOAO PIXSCALi keywords for default WCS * Oct 15 1997 Do not reset reference pixel in WCSSHIFT * Oct 20 1997 Set chip rotation * Oct 24 1997 Keep longitudes between 0 and 360, not -180 and +180 * Nov 5 1997 Do no compute crot and srot; they are now computed in worldpos * Dec 16 1997 Set rotation and axis increments from CD matrix * * Jan 6 1998 Deal with J2000 and B1950 as EQUINOX values (from ST) * Jan 7 1998 Read INSTRUME and DETECTOR header keywords * Jan 7 1998 Fix tab-separated output * Jan 9 1998 Precess coordinates if either FITS projection or *DSS plate* * Jan 16 1998 Change PTYPE to not include initial hyphen * Jan 16 1998 Change WCSSET to WCSXINIT to avoid conflict with Calabretta * Jan 23 1998 Change PCODE to PRJCODE to avoid conflict with Calabretta * Jan 27 1998 Add LATPOLE and LONGPOLE for Calabretta projections * Feb 5 1998 Make cd and dc into vectors; use matinv() to invert cd * Feb 5 1998 In wcsoutinit(), check that corsys is a valid pointer * Feb 18 1998 Fix bugs for Calabretta projections * Feb 19 1998 Add wcs structure access subroutines from Eric Mandel * Feb 19 1998 Add wcsreset() to make sure derived values are reset * Feb 19 1998 Always set oldwcs to 1 if NCP projection * Feb 19 1998 Add subroutine to set oldwcs default * Feb 20 1998 Initialize projection types one at a time for SunOS C * Feb 23 1998 Add TNX projection from NOAO; treat it as TAN * Feb 23 1998 Compute size based on max and min coordinates, not sides * Feb 26 1998 Add code to set center pixel if part of detector array * Mar 6 1998 Write 8-character values to RADECSYS * Mar 9 1998 Add naxis to WCS structure * Mar 16 1998 Use separate subroutine for IRAF TNX projection * Mar 20 1998 Set PC matrix if more than two axes and it's not in header * Mar 20 1998 Reset lin flag in WCSRESET if CDELTn * Mar 20 1998 Set CD matrix with CDELTs and CROTA in wcsinit and wcsreset * Mar 20 1998 Allow initialization of rotation angle alone * Mar 23 1998 Use dsspos() and dsspix() instead of platepos() and platepix() * Mar 24 1998 Set up PLT/PLATE plate polynomial fit using platepos() and platepix() * Mar 25 1998 Read plate fit coefficients from header in getwcscoeffs() * Mar 27 1998 Check for FITS WCS before DSS WCS * Mar 27 1998 Compute scale from edges if xinc and yinc not set in wcscent() * Apr 6 1998 Change plate coefficient keywords from PLTij to COi_j * Apr 6 1998 Read all coefficients in line instead of with subroutine * Apr 7 1998 Change amd_i_coeff to i_coeff * Apr 8 1998 Add wcseqset to change equinox after wcs has been set * Apr 10 1998 Use separate counters for x and y polynomial coefficients * Apr 13 1998 Use CD/CDELT+CDROTA if oldwcs is set * Apr 14 1998 Use codes instead of strings for various coordinate systems * Apr 14 1998 Separate input coordinate conversion from output conversion * Apr 14 1998 Use wcscon() for most coordinate conversion * Apr 17 1998 Always compute cdelt[] * Apr 17 1998 Deal with reversed axis more correctly * Apr 17 1998 Compute rotation angle and approximate CDELTn for polynomial * Apr 23 1998 Deprecate xref/yref in favor of crval[] * Apr 23 1998 Deprecate xrefpix/yrefpix in favor of crpix[] * Apr 23 1998 Add LINEAR to coordinate system types * Apr 23 1998 Always use AIPS subroutines for LINEAR or PIXEL * Apr 24 1998 Format linear coordinates better * Apr 28 1998 Change coordinate system flags to WCS_* * Apr 28 1998 Change projection flags to WCS_* * Apr 28 1998 Add subroutine wcsc2pix for coordinates to pixels with system * Apr 28 1998 Add setlinmode() to set output string mode for LINEAR coordinates * Apr 30 1998 Fix bug by setting degree flag for lat and long in wcsinit() * Apr 30 1998 Allow leading "-"s in projecting in wcsxinit() * May 1 1998 Assign new output coordinate system only if legitimate system * May 1 1998 Do not allow oldwcs=1 unless allowed projection * May 4 1998 Fix bug in units reading for LINEAR coordinates * May 6 1998 Initialize to no CD matrix * May 6 1998 Use TAN instead of TNX if oldwcs * May 12 1998 Set 3rd and 4th coordinates in wcspos() * May 12 1998 Return *xpos and *ypos = 0 in pix2wcs() if offscale * May 12 1998 Declare undeclared external subroutines after lint * May 13 1998 Add equinox conversion to specified output equinox * May 13 1998 Set output or input system to image with null argument * May 15 1998 Return reference pixel, cdelts, and rotation for DSS * May 20 1998 Fix bad bug so setlinmode() is no-op if wcs not set * May 20 1998 Fix bug so getwcsout() returns null pointer if wcs not set * May 27 1998 Change WCS_LPR back to WCS_LIN; allow CAR in oldwcs * May 28 1998 Go back to old WCSFULL, computing height and width from center * May 29 1998 Add wcskinit() to initialize WCS from arguments * May 29 1998 Add wcstype() to set projection from arguments * May 29 1998 Add wcscdset(), and wcsdeltset() to set scale from arguments * Jun 1 1998 In wcstype(), reconstruct ctype for WCS structure * Jun 11 1998 Split off header-dependent subroutines to wcsinit.c * Jun 18 1998 Add wcspcset() for PC matrix initialization * Jun 24 1998 Add string lengths to ra2str(), dec2str, and deg2str() calls * Jun 25 1998 Use AIPS software for CAR projection * Jun 25 1998 Add wcsndec to set number of decimal places in output string * Jul 6 1998 Add wcszin() and wcszout() to use third dimension of images * Jul 7 1998 Change setlinmode() to setwcslin(); setdegout() to setwcsdeg() * Jul 10 1998 Initialize matrices correctly for naxis > 2 in wcs<>set() * Jul 16 1998 Initialize coordinates to be returned in wcspos() * Jul 17 1998 Link lin structure arrays to wcs structure arrays * Jul 20 1998 In wcscdset() compute sign of xinc and yinc from CD1_1, CD 2_2 * Jul 20 1998 In wcscdset() compute sign of rotation based on CD1_1, CD 1_2 * Jul 22 1998 Add wcslibrot() to compute lin() rotation matrix * Jul 30 1998 Set wcs->naxes and lin.naxis in wcsxinit() and wcskinit() * Aug 5 1998 Use old WCS subroutines to deal with COE projection (for ESO) * Aug 14 1998 Add option to print image coordinates with wcscom() * Aug 14 1998 Add multiple command options to wcscom*() * Aug 31 1998 Declare undeclared arguments to wcspcset() * Sep 3 1998 Set CD rotation and cdelts from sky axis position angles * Sep 16 1998 Add option to use North Polar Angle instead of Latitude * Sep 29 1998 Initialize additional WCS commands from the environment * Oct 14 1998 Fix bug in wcssize() which didn't divide dra by cos(dec) * Nov 12 1998 Fix sign of CROTA when either axis is reflected * Dec 2 1998 Fix non-arcsecond scale factors in wcscent() * Dec 2 1998 Add PLANET coordinate system to pix2wcst() * Jan 20 1999 Free lin.imgpix and lin.piximg in wcsfree() * Feb 22 1999 Fix bug setting latitude reference value of latbase != 0 * Feb 22 1999 Fix bug so that quad cube faces are 0-5, not 1-6 * Mar 16 1999 Always initialize all 4 imgcrds and pixcrds in wcspix() * Mar 16 1999 Always return (0,0) from wcs2pix if offscale * Apr 7 1999 Add code to put file name in error messages * Apr 7 1999 Document utility subroutines at end of file * May 6 1999 Fix bug printing height of LINEAR image * Jun 16 1999 Add wcsrange() to return image RA and Dec limits * Jul 8 1999 Always use FK5 and FK4 instead of J2000 and B1950 in RADECSYS * Aug 16 1999 Print dd:mm:ss dd:mm:ss if not J2000 or B1950 output * Aug 20 1999 Add WCS string argument to wcscom(); don't compute it there * Aug 20 1999 Change F3 WCS command default from Tycho to ACT * Oct 15 1999 Free wcs using wcsfree() * Oct 21 1999 Drop declarations of unused functions after lint * Oct 25 1999 Drop out of wcsfree() if wcs is null pointer * Nov 17 1999 Fix bug which caused software to miss NCP projection * * Jan 24 2000 Default to AIPS for NCP, CAR, and COE proj.; if -z use WCSLIB * Feb 24 2000 If coorsys is null in wcsc2pix, wcs->radecin is assumed * May 10 2000 In wcstype(), default to WCS_LIN, not error (after Bill Joye) * Jun 22 2000 In wcsrotset(), leave rotation angle alone in 1-d image * Jul 3 2000 Initialize wcscrd[] to zero in wcspix() * * Feb 20 2001 Add recursion to wcs2pix() and pix2wcs() for dependent WCS's * Mar 20 2001 Add braces to avoid ambiguity in if/else groupings * Mar 22 2001 Free WCS structure in wcsfree even if it is not filled * Sep 12 2001 Fix bug which omitted tab in pix2wcst() galactic coord output * * Mar 7 2002 Fix bug which gave wrong pa's and rotation for reflected RA * (but correct WCS conversions!) * Mar 28 2002 Add SZP projection * Apr 3 2002 Synchronize projection types with other subroutines * Apr 3 2002 Drop special cases of projections * Apr 9 2002 Implement inversion of multiple WCSs in wcsc2pix() * Apr 25 2002 Use Tycho-2 catalog instead of ACT in setwcscom() * May 13 2002 Free WCSNAME in wcsfree() * * Mar 31 2003 Add distcode to wcstype() * Apr 1 2003 Add calls to foc2pix() in wcs2pix() and pix2foc() in pix2wcs() * May 20 2003 Declare argument i in savewcscom() * Sep 29 2003 Fix bug to compute width and height correctly in wcsfull() * Sep 29 2003 Fix bug to deal with all-sky images orrectly in wcsfull() * Oct 1 2003 Rename wcs->naxes to wcs->naxis to match WCSLIB 3.2 * Nov 3 2003 Set distortion code by calling setdistcode() in wcstype() * Dec 3 2003 Add back wcs->naxes for compatibility * Dec 3 2003 Add braces in if...else in pix2wcst() * * Sep 17 2004 If spherical coordinate output, keep 0 < long/RA < 360 * Sep 17 2004 Fix bug in wcsfull() when wrapping around RA=0:00 * Nov 1 2004 Keep wcs->rot between 0 and 360 * * Mar 9 2005 Fix bug in wcsrotset() which set rot > 360 to 360 * Jun 27 2005 Fix ctype in calls to wcs subroutines * Jul 21 2005 Fix bug in wcsrange() at RA ~= 0.0 * * Apr 24 2006 Always set inverse CD matrix to 2 dimensions in wcspcset() * May 3 2006 (void *) pointers so arguments match type, from Robert Lupton * Jun 30 2006 Set only 2-dimensional PC matrix; that is all lin* can deal with * Oct 30 2006 In pix2wcs(), do not limit x to between 0 and 360 if XY or LINEAR * Oct 30 2006 In wcsc2pix(), do not precess LINEAR or XY coordinates * Dec 21 2006 Add cpwcs() to copy WCS keywords to new suffix * * Jan 4 2007 Fix pointer to header in cpwcs() * Jan 5 2007 Drop declarations of wcscon(); it is in wcs.h * Jan 9 2006 Drop declarations of fk425e() and fk524e(); moved to wcs.h * Jan 9 2006 Drop *pix() and *pos() external declarations; moved to wcs.h * Jan 9 2006 Drop matinv() external declaration; it is already in wcslib.h * Feb 15 2007 If CTYPEi contains DET, set to WCS_PIX projection * Feb 23 2007 Fix bug when checking for "DET" in CTYPEi * Apr 2 2007 Fix PC to CD matrix conversion * Jul 25 2007 Compute distance between two coordinates using d2v3() */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/wcs.h000066400000000000000000001340041215713201500212220ustar00rootroot00000000000000/*** File libwcs/wcs.h *** July 25, 2007 *** By Doug Mink, dmink@cfa.harvard.edu *** Harvard-Smithsonian Center for Astrophysics *** Copyright (C) 1994-2007 *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Correspondence concerning WCSTools should be addressed as follows: Internet email: dmink@cfa.harvard.edu Postal address: Doug Mink Smithsonian Astrophysical Observatory 60 Garden St. Cambridge, MA 02138 USA */ #ifndef _wcs_h_ #define _wcs_h_ #include "wcslib.h" #include "fitshead.h" /* SIRTF distortion matrix coefficients */ #define DISTMAX 10 struct Distort { int a_order; /* max power for the 1st dimension */ double a[DISTMAX][DISTMAX]; /* coefficient array of 1st dimension */ int b_order; /* max power for 1st dimension */ double b[DISTMAX][DISTMAX]; /* coefficient array of 2nd dimension */ int ap_order; /* max power for the 1st dimension */ double ap[DISTMAX][DISTMAX]; /* coefficient array of 1st dimension */ int bp_order; /* max power for 1st dimension */ double bp[DISTMAX][DISTMAX]; /* coefficient array of 2nd dimension */ }; struct WorldCoor { double xref; /* X reference coordinate value (deg) */ double yref; /* Y reference coordinate value (deg) */ double xrefpix; /* X reference pixel */ double yrefpix; /* Y reference pixel */ double xinc; /* X coordinate increment (deg) */ double yinc; /* Y coordinate increment (deg) */ double rot; /* rotation around axis (deg) (N through E) */ double cd[4]; /* rotation matrix */ double dc[4]; /* inverse rotation matrix */ double equinox; /* Equinox of coordinates default to 1950.0 */ double epoch; /* Epoch of coordinates default to equinox */ double nxpix; /* Number of pixels in X-dimension of image */ double nypix; /* Number of pixels in Y-dimension of image */ double plate_ra; /* Right ascension of plate center */ double plate_dec; /* Declination of plate center */ double plate_scale; /* Plate scale in arcsec/mm */ double x_pixel_offset; /* X pixel offset of image lower right */ double y_pixel_offset; /* Y pixel offset of image lower right */ double x_pixel_size; /* X pixel_size */ double y_pixel_size; /* Y pixel_size */ double ppo_coeff[6]; /* pixel to plate coefficients for DSS */ double x_coeff[20]; /* X coefficients for plate model */ double y_coeff[20]; /* Y coefficients for plate model */ double xpix; /* X (RA) coordinate (pixels) */ double ypix; /* Y (dec) coordinate (pixels) */ double zpix; /* Z (face) coordinate (pixels) */ double xpos; /* X (RA) coordinate (deg) */ double ypos; /* Y (dec) coordinate (deg) */ double crpix[9]; /* Values of CRPIXn keywords */ double crval[9]; /* Values of CRVALn keywords */ double cdelt[9]; /* Values of CDELTn keywords */ double pc[81]; /* Values of PCiiijjj keywords */ double projp[10]; /* Constants for various projections */ double longpole; /* Longitude of North Pole in degrees */ double latpole; /* Latitude of North Pole in degrees */ double rodeg; /* Radius of the projection generating sphere */ double imrot; /* Rotation angle of north pole */ double pa_north; /* Position angle of north (0=horizontal) */ double pa_east; /* Position angle of east (0=horizontal) */ double radvel; /* Radial velocity (km/sec away from observer)*/ double zvel; /* Radial velocity (v/c away from observer)*/ int imflip; /* If not 0, image is reflected around axis */ int prjcode; /* projection code (-1-32) */ int latbase; /* Latitude base 90 (NPA), 0 (LAT), -90 (SPA) */ int ncoeff1; /* Number of x-axis plate fit coefficients */ int ncoeff2; /* Number of y-axis plate fit coefficients */ int changesys; /* 1 for FK4->FK5, 2 for FK5->FK4 */ /* 3 for FK4->galactic, 4 for FK5->galactic */ int printsys; /* 1 to print coordinate system, else 0 */ int ndec; /* Number of decimal places in PIX2WCST */ int degout; /* 1 to always print degrees in PIX2WCST */ int tabsys; /* 1 to put tab between RA & Dec, else 0 */ int rotmat; /* 0 if CDELT, CROTA; 1 if CD */ int coorflip; /* 0 if x=RA, y=Dec; 1 if x=Dec, y=RA */ int offscl; /* 0 if OK, 1 if offscale */ int wcson; /* 1 if WCS is set, else 0 */ int naxis; /* Number of axes in image (for WCSLIB 3.0) */ int naxes; /* Number of axes in image */ int wcsproj; /* WCS_OLD: AIPS worldpos() and worldpix() WCS_NEW: Mark Calabretta's WCSLIB subroutines WCS_BEST: WCSLIB for all but CAR,COE,NCP WCS_ALT: AIPS for all but CAR,COE,NCP */ int linmode; /* 0=system only, 1=units, 2=system+units */ int detector; /* Instrument detector number */ char instrument[32]; /* Instrument name */ char ctype[9][9]; /* Values of CTYPEn keywords */ char c1type[9]; /* 1st coordinate type code: RA--, GLON, ELON */ char c2type[9]; /* 2nd coordinate type code: DEC-, GLAT, ELAT */ char ptype[9]; /* projection type code: SIN, TAN, ARC, NCP, GLS, MER, AIT, etc */ char units[9][32]; /* Units if LINEAR */ char radecsys[32]; /* Reference frame: FK4, FK4-NO-E, FK5, GAPPT*/ char radecout[32]; /* Output reference frame: FK4,FK5,GAL,ECL */ char radecin[32]; /* Input reference frame: FK4,FK5,GAL,ECL */ double eqin; /* Input equinox (match sysin if 0.0) */ double eqout; /* Output equinox (match sysout if 0.0) */ int sysin; /* Input coordinate system code */ int syswcs; /* WCS coordinate system code */ int sysout; /* Output coordinate system code */ /* WCS_B1950, WCS_J2000, WCS_ICRS, WCS_GALACTIC, * WCS_ECLIPTIC, WCS_LINEAR, WCS_ALTAZ */ char center[32]; /* Center coordinates (with frame) */ struct wcsprm wcsl; /* WCSLIB main projection parameters */ struct linprm lin; /* WCSLIB image/pixel conversion parameters */ struct celprm cel; /* WCSLIB projection type */ struct prjprm prj; /* WCSLIB projection parameters */ struct IRAFsurface *lngcor; /* RA/longitude correction structure */ struct IRAFsurface *latcor; /* Dec/latitude correction structure */ int distcode; /* Distortion code 0=none 1=SIRTF */ struct Distort distort; /* SIRTF distortion coefficients */ char *command_format[10]; /* WCS command formats */ /* where %s is replaced by WCS coordinates */ /* where %f is replaced by the image filename */ /* where %x is replaced by image coordinates */ double ltm[4]; /* Image rotation matrix */ double ltv[2]; /* Image offset */ int idpix[2]; /* First pixel to use in image (x, y) */ int ndpix[2]; /* Number of pixels to use in image (x, y) */ struct WorldCoor *wcs; /* WCS upon which this WCS depends */ struct WorldCoor *wcsdep; /* WCS depending on this WCS */ char *wcsname; /* WCS name (defaults to NULL pointer) */ char wcschar; /* WCS character (A-Z, null, space) */ int logwcs; /* 1 if DC-FLAG is set for log wavelength */ }; /* Projections (1-26 are WCSLIB) (values for wcs->prjcode) */ #define WCS_PIX -1 /* Pixel WCS */ #define WCS_LIN 0 /* Linear projection */ #define WCS_AZP 1 /* Zenithal/Azimuthal Perspective */ #define WCS_SZP 2 /* Zenithal/Azimuthal Perspective */ #define WCS_TAN 3 /* Gnomonic = Tangent Plane */ #define WCS_SIN 4 /* Orthographic/synthesis */ #define WCS_STG 5 /* Stereographic */ #define WCS_ARC 6 /* Zenithal/azimuthal equidistant */ #define WCS_ZPN 7 /* Zenithal/azimuthal PolyNomial */ #define WCS_ZEA 8 /* Zenithal/azimuthal Equal Area */ #define WCS_AIR 9 /* Airy */ #define WCS_CYP 10 /* CYlindrical Perspective */ #define WCS_CAR 11 /* Cartesian */ #define WCS_MER 12 /* Mercator */ #define WCS_CEA 13 /* Cylindrical Equal Area */ #define WCS_COP 14 /* Conic PerSpective (COP) */ #define WCS_COD 15 /* COnic equiDistant */ #define WCS_COE 16 /* COnic Equal area */ #define WCS_COO 17 /* COnic Orthomorphic */ #define WCS_BON 18 /* Bonne */ #define WCS_PCO 19 /* Polyconic */ #define WCS_SFL 20 /* Sanson-Flamsteed (GLobal Sinusoidal) */ #define WCS_PAR 21 /* Parabolic */ #define WCS_AIT 22 /* Hammer-Aitoff */ #define WCS_MOL 23 /* Mollweide */ #define WCS_CSC 24 /* COBE quadrilateralized Spherical Cube */ #define WCS_QSC 25 /* Quadrilateralized Spherical Cube */ #define WCS_TSC 26 /* Tangential Spherical Cube */ #define WCS_NCP 27 /* Special case of SIN */ #define WCS_GLS 28 /* Same as SFL */ #define WCS_DSS 29 /* Digitized Sky Survey plate solution */ #define WCS_PLT 30 /* Plate fit polynomials (SAO) */ #define WCS_TNX 31 /* Gnomonic = Tangent Plane (NOAO with corrections) */ /* Coordinate systems */ #define WCS_J2000 1 /* J2000(FK5) right ascension and declination */ #define WCS_B1950 2 /* B1950(FK4) right ascension and declination */ #define WCS_GALACTIC 3 /* Galactic longitude and latitude */ #define WCS_ECLIPTIC 4 /* Ecliptic longitude and latitude */ #define WCS_ALTAZ 5 /* Azimuth and altitude/elevation */ #define WCS_LINEAR 6 /* Linear with optional units */ #define WCS_NPOLE 7 /* Longitude and north polar angle */ #define WCS_SPA 8 /* Longitude and south polar angle */ #define WCS_PLANET 9 /* Longitude and latitude on planet */ #define WCS_XY 10 /* X-Y Cartesian coordinates */ #define WCS_ICRS 11 /* ICRS right ascension and declination */ /* Method to use */ #define WCS_BEST 0 /* Use best WCS projections */ #define WCS_ALT 1 /* Use not best WCS projections */ #define WCS_OLD 2 /* Use AIPS WCS projections */ #define WCS_NEW 3 /* Use WCSLIB 2.5 WCS projections */ /* Distortion codes (values for wcs->distcode) */ #define DISTORT_NONE 0 /* No distortion coefficients */ #define DISTORT_SIRTF 1 /* SIRTF distortion matrix */ #ifndef PI #define PI 3.141592653589793238462643 #endif /* pi/(180*3600): arcseconds to radians */ #define AS2R 4.8481368110953e-6 /* Conversions among hours of RA, degrees and radians. */ #define degrad(x) ((x)*PI/180.) #define raddeg(x) ((x)*180./PI) #define hrdeg(x) ((x)*15.) #define deghr(x) ((x)/15.) #define hrrad(x) degrad(hrdeg(x)) #define radhr(x) deghr(raddeg(x)) #define secrad(x) ((x)*AS2R) /* TNX surface fitting structure and flags */ struct IRAFsurface { double xrange; /* 2. / (xmax - xmin), polynomials */ double xmaxmin; /* - (xmax + xmin) / 2., polynomials */ double yrange; /* 2. / (ymax - ymin), polynomials */ double ymaxmin; /* - (ymax + ymin) / 2., polynomials */ int type; /* type of curve to be fitted */ int xorder; /* order of the fit in x */ int yorder; /* order of the fit in y */ int xterms; /* cross terms for polynomials */ int ncoeff; /* total number of coefficients */ double *coeff; /* pointer to coefficient vector */ double *xbasis; /* pointer to basis functions (all x) */ double *ybasis; /* pointer to basis functions (all y) */ }; /* TNX permitted types of surfaces */ #define TNX_CHEBYSHEV 1 #define TNX_LEGENDRE 2 #define TNX_POLYNOMIAL 3 /* TNX cross-terms flags */ #define TNX_XNONE 0 /* no x-terms (old no) */ #define TNX_XFULL 1 /* full x-terms (new yes) */ #define TNX_XHALF 2 /* half x-terms (new) */ #ifdef __cplusplus /* C++ prototypes */ extern "C" { #endif #ifdef __STDC__ /* Full ANSI prototypes */ /* WCS data structure initialization subroutines in wcsinit.c */ struct WorldCoor *wcsinit ( /* set up WCS structure from a FITS image header */ const char* hstring); struct WorldCoor *wcsninit ( /* set up WCS structure from a FITS image header */ const char* hstring, /* FITS header */ int len); /* Length of FITS header */ struct WorldCoor *wcsinitn ( /* set up WCS structure from a FITS image header */ const char* hstring, /* FITS header */ const char* wcsname); /* WCS name */ struct WorldCoor *wcsninitn ( /* set up WCS structure from a FITS image header */ const char* hstring, /* FITS header */ int len, /* Length of FITS header */ const char* wcsname); /* WCS name */ struct WorldCoor *wcsinitc ( /* set up WCS structure from a FITS image header */ const char* hstring, /* FITS header */ char *wcschar); /* WCS character (A-Z) */ struct WorldCoor *wcsninitc ( /* set up WCS structure from a FITS image header */ const char* hstring, /* FITS header */ int len, /* Length of FITS header */ char *wcschar); /* WCS character (A-Z) */ /* WCS subroutines in wcs.c */ void wcsfree ( /* Free a WCS structure and its contents */ struct WorldCoor *wcs); /* World coordinate system structure */ int wcstype( /* Set projection type from header CTYPEs */ struct WorldCoor *wcs, /* World coordinate system structure */ char *ctype1, /* FITS WCS projection for axis 1 */ char *ctype2); /* FITS WCS projection for axis 2 */ int iswcs( /* Returns 1 if wcs structure set, else 0 */ struct WorldCoor *wcs); /* World coordinate system structure */ int nowcs( /* Returns 0 if wcs structure set, else 1 */ struct WorldCoor *wcs); /* World coordinate system structure */ int pix2wcst ( /* Convert pixel coordinates to World Coordinate string */ struct WorldCoor *wcs, /* World coordinate system structure */ double xpix, /* Image horizontal coordinate in pixels */ double ypix, /* Image vertical coordinate in pixels */ char *wcstring, /* World coordinate string (returned) */ int lstr); /* Length of world coordinate string (returned) */ void pix2wcs ( /* Convert pixel coordinates to World Coordinates */ struct WorldCoor *wcs, /* World coordinate system structure */ double xpix, /* Image horizontal coordinate in pixels */ double ypix, /* Image vertical coordinate in pixels */ double *xpos, /* Longitude/Right Ascension in degrees (returned) */ double *ypos); /* Latitude/Declination in degrees (returned) */ void wcsc2pix ( /* Convert World Coordinates to pixel coordinates */ struct WorldCoor *wcs, /* World coordinate system structure */ double xpos, /* Longitude/Right Ascension in degrees */ double ypos, /* Latitude/Declination in degrees */ char *coorsys, /* Coordinate system (B1950, J2000, etc) */ double *xpix, /* Image horizontal coordinate in pixels (returned) */ double *ypix, /* Image vertical coordinate in pixels (returned) */ int *offscl); void wcs2pix ( /* Convert World Coordinates to pixel coordinates */ struct WorldCoor *wcs, /* World coordinate system structure */ double xpos, /* Longitude/Right Ascension in degrees */ double ypos, /* Latitude/Declination in degrees */ double *xpix, /* Image horizontal coordinate in pixels (returned) */ double *ypix, /* Image vertical coordinate in pixels (returned) */ int *offscl); double wcsdist( /* Compute angular distance between 2 sky positions */ double ra1, /* First longitude/right ascension in degrees */ double dec1, /* First latitude/declination in degrees */ double ra2, /* Second longitude/right ascension in degrees */ double dec2); /* Second latitude/declination in degrees */ double wcsdiff( /* Compute angular distance between 2 sky positions */ double ra1, /* First longitude/right ascension in degrees */ double dec1, /* First latitude/declination in degrees */ double ra2, /* Second longitude/right ascension in degrees */ double dec2); /* Second latitude/declination in degrees */ struct WorldCoor* wcsxinit( /* set up a WCS structure from arguments */ double cra, /* Center right ascension in degrees */ double cdec, /* Center declination in degrees */ double secpix, /* Number of arcseconds per pixel */ double xrpix, /* Reference pixel X coordinate */ double yrpix, /* Reference pixel X coordinate */ int nxpix, /* Number of pixels along x-axis */ int nypix, /* Number of pixels along y-axis */ double rotate, /* Rotation angle (clockwise positive) in degrees */ int equinox, /* Equinox of coordinates, 1950 and 2000 supported */ double epoch, /* Epoch of coordinates, used for FK4/FK5 conversion * no effect if 0 */ char *proj); /* Projection */ struct WorldCoor* wcskinit( /* set up WCS structure from keyword values */ int naxis1, /* Number of pixels along x-axis */ int naxis2, /* Number of pixels along y-axis */ char *ctype1, /* FITS WCS projection for axis 1 */ char *ctype2, /* FITS WCS projection for axis 2 */ double crpix1, /* Reference pixel coordinates */ double crpix2, /* Reference pixel coordinates */ double crval1, /* Coordinate at reference pixel in degrees */ double crval2, /* Coordinate at reference pixel in degrees */ double *cd, /* Rotation matrix, used if not NULL */ double cdelt1, /* scale in degrees/pixel, if cd is NULL */ double cdelt2, /* scale in degrees/pixel, if cd is NULL */ double crota, /* Rotation angle in degrees, if cd is NULL */ int equinox, /* Equinox of coordinates, 1950 and 2000 supported */ double epoch); /* Epoch of coordinates, for FK4/FK5 conversion */ void wcsshift( /* Change center of WCS */ struct WorldCoor *wcs, /* World coordinate system structure */ double cra, /* New center right ascension in degrees */ double cdec, /* New center declination in degrees */ char *coorsys); /* FK4 or FK5 coordinates (1950 or 2000) */ void wcsfull( /* Return RA and Dec of image center, size in degrees */ struct WorldCoor *wcs, /* World coordinate system structure */ double *cra, /* Right ascension of image center (deg) (returned) */ double *cdec, /* Declination of image center (deg) (returned) */ double *width, /* Width in degrees (returned) */ double *height); /* Height in degrees (returned) */ void wcscent( /* Print the image center and size in WCS units */ struct WorldCoor *wcs); /* World coordinate system structure */ void wcssize( /* Return image center and size in RA and Dec */ struct WorldCoor *wcs, /* World coordinate system structure */ double *cra, /* Right ascension of image center (deg) (returned) */ double *cdec, /* Declination of image center (deg) (returned) */ double *dra, /* Half-width in right ascension (deg) (returned) */ double *ddec); /* Half-width in declination (deg) (returned) */ void wcsrange( /* Return min and max RA and Dec of image in degrees */ struct WorldCoor *wcs, /* World coordinate system structure */ double *ra1, /* Min. right ascension of image (deg) (returned) */ double *ra2, /* Max. right ascension of image (deg) (returned) */ double *dec1, /* Min. declination of image (deg) (returned) */ double *dec2); /* Max. declination of image (deg) (returned) */ void wcscdset( /* Set scaling and rotation from CD matrix */ struct WorldCoor *wcs, /* World coordinate system structure */ double *cd); /* CD matrix, ignored if NULL */ void wcsdeltset( /* set scaling, rotation from CDELTi, CROTA2 */ struct WorldCoor *wcs, /* World coordinate system structure */ double cdelt1, /* degrees/pixel in first axis (or both axes) */ double cdelt2, /* degrees/pixel in second axis if nonzero */ double crota); /* Rotation counterclockwise in degrees */ void wcspcset( /* set scaling, rotation from CDELTs and PC matrix */ struct WorldCoor *wcs, /* World coordinate system structure */ double cdelt1, /* degrees/pixel in first axis (or both axes) */ double cdelt2, /* degrees/pixel in second axis if nonzero */ double *pc); /* Rotation matrix, ignored if NULL */ void setwcserr( /* Set WCS error message for later printing */ char *errmsg); /* Error mesage < 80 char */ void wcserr(void); /* Print WCS error message to stderr */ void setdefwcs( /* Set flag to use AIPS WCS instead of WCSLIB */ int oldwcs); /* 1 for AIPS WCS subroutines, else WCSLIB */ int getdefwcs(void); /* Return flag for AIPS WCS set by setdefwcs */ char *getradecsys( /* Return name of image coordinate system */ struct WorldCoor *wcs); /* World coordinate system structure */ void wcsoutinit( /* Set output coordinate system for pix2wcs */ struct WorldCoor *wcs, /* World coordinate system structure */ char *coorsys); /* Coordinate system (B1950, J2000, etc) */ char *getwcsout( /* Return current output coordinate system */ struct WorldCoor *wcs); /* World coordinate system structure */ void wcsininit( /* Set input coordinate system for wcs2pix */ struct WorldCoor *wcs, /* World coordinate system structure */ char *coorsys); /* Coordinate system (B1950, J2000, etc) */ char *getwcsin( /* Return current input coordinate system */ struct WorldCoor *wcs); /* World coordinate system structure */ int setwcsdeg( /* Set WCS coordinate output format */ struct WorldCoor *wcs, /* World coordinate system structure */ int degout); /* 1= degrees, 0= hh:mm:ss dd:mm:ss */ int wcsndec( /* Set or get number of output decimal places */ struct WorldCoor *wcs, /* World coordinate system structure */ int ndec); /* Number of decimal places in output string if < 0, return current ndec unchanged */ int wcsreset( /* Change WCS using arguments */ struct WorldCoor *wcs, /* World coordinate system data structure */ double crpix1, /* Horizontal reference pixel */ double crpix2, /* Vertical reference pixel */ double crval1, /* Reference pixel horizontal coordinate in degrees */ double crval2, /* Reference pixel vertical coordinate in degrees */ double cdelt1, /* Horizontal scale in degrees/pixel, ignored if cd is not NULL */ double cdelt2, /* Vertical scale in degrees/pixel, ignored if cd is not NULL */ double crota, /* Rotation angle in degrees, ignored if cd is not NULL */ double *cd); /* Rotation matrix, used if not NULL */ void wcseqset( /* Change equinox of reference pixel coordinates in WCS */ struct WorldCoor *wcs, /* World coordinate system data structure */ double equinox); /* Desired equinox as fractional year */ void setwcslin( /* Set pix2wcst() mode for LINEAR coordinates */ struct WorldCoor *wcs, /* World coordinate system structure */ int mode); /* 0: x y linear, 1: x units x units 2: x y linear units */ int wcszin( /* Set third dimension for cube projections */ int izpix); /* Set coordinate in third dimension (face) */ int wcszout ( /* Return coordinate in third dimension */ struct WorldCoor *wcs); /* World coordinate system structure */ void wcscominit( /* Initialize catalog search command set by -wcscom */ struct WorldCoor *wcs, /* World coordinate system structure */ int i, /* Number of command (0-9) to initialize */ char *command); /* command with %s where coordinates will go */ void wcscom( /* Execute catalog search command set by -wcscom */ struct WorldCoor *wcs, /* World coordinate system structure */ int i, /* Number of command (0-9) to execute */ char *filename, /* Image file name */ double xfile, /* Horizontal image pixel coordinates for WCS command */ double yfile, /* Vertical image pixel coordinates for WCS command */ char *wcstring); /* WCS String from pix2wcst() */ void savewcscom( /* Save WCS shell command */ int i, /* i of 10 possible shell commands */ char *wcscom); /* Shell command using output WCS string */ char *getwcscom( /* Return WCS shell command */ int i); /* i of 10 possible shell commands */ void setwcscom( /* Set WCS shell commands from stored values */ struct WorldCoor *wcs); /* World coordinate system structure */ void freewcscom( /* Free memory storing WCS shell commands */ struct WorldCoor *wcs); /* World coordinate system structure */ void setwcsfile( /* Set filename for WCS error message */ char *filename); /* FITS or IRAF file name */ int cpwcs ( /* Copy WCS keywords with no suffix to ones with suffix */ char **header, /* Pointer to start of FITS header */ char *cwcs); /* Keyword suffix character for output WCS */ void savewcscoor( /* Save output coordinate system */ char *wcscoor); /* coordinate system (J2000, B1950, galactic) */ char *getwcscoor(void); /* Return output coordinate system */ /* Coordinate conversion subroutines in wcscon.c */ void wcsconv( /* Convert between coordinate systems and equinoxes */ int sys1, /* Input coordinate system (J2000, B1950, ECLIPTIC, GALACTIC */ int sys2, /* Output coordinate system (J2000, B1950, ECLIPTIC, G ALACTIC */ double eq1, /* Input equinox (default of sys1 if 0.0) */ double eq2, /* Output equinox (default of sys2 if 0.0) */ double ep1, /* Input Besselian epoch in years */ double ep2, /* Output Besselian epoch in years */ double *dtheta, /* Longitude or right ascension in degrees Input in sys1, returned in sys2 */ double *dphi, /* Latitude or declination in degrees Input in sys1, returned in sys2 */ double *ptheta, /* Longitude or right ascension proper motion in deg/year Input in sys1, returned in sys2 */ double *pphi, /* Latitude or declination proper motion in deg/year */ double *px, /* Parallax in arcseconds */ double *rv); /* Radial velocity in km/sec */ void wcsconp( /* Convert between coordinate systems and equinoxes */ int sys1, /* Input coordinate system (J2000, B1950, ECLIPTIC, GALACTIC */ int sys2, /* Output coordinate system (J2000, B1950, ECLIPTIC, G ALACTIC */ double eq1, /* Input equinox (default of sys1 if 0.0) */ double eq2, /* Output equinox (default of sys2 if 0.0) */ double ep1, /* Input Besselian epoch in years */ double ep2, /* Output Besselian epoch in years */ double *dtheta, /* Longitude or right ascension in degrees Input in sys1, returned in sys2 */ double *dphi, /* Latitude or declination in degrees Input in sys1, returned in sys2 */ double *ptheta, /* Longitude or right ascension proper motion in degrees/year Input in sys1, returned in sys2 */ double *pphi); /* Latitude or declination proper motion in degrees/year Input in sys1, returned in sys2 */ void wcscon( /* Convert between coordinate systems and equinoxes */ int sys1, /* Input coordinate system (J2000, B1950, ECLIPTIC, GALACTIC */ int sys2, /* Output coordinate system (J2000, B1950, ECLIPTIC, G ALACTIC */ double eq1, /* Input equinox (default of sys1 if 0.0) */ double eq2, /* Output equinox (default of sys2 if 0.0) */ double *dtheta, /* Longitude or right ascension in degrees Input in sys1, returned in sys2 */ double *dphi, /* Latitude or declination in degrees Input in sys1, returned in sys2 */ double epoch); /* Besselian epoch in years */ void fk425e ( /* Convert B1950(FK4) to J2000(FK5) coordinates */ double *ra, /* Right ascension in degrees (B1950 in, J2000 out) */ double *dec, /* Declination in degrees (B1950 in, J2000 out) */ double epoch); /* Besselian epoch in years */ void fk524e ( /* Convert J2000(FK5) to B1950(FK4) coordinates */ double *ra, /* Right ascension in degrees (J2000 in, B1950 out) */ double *dec, /* Declination in degrees (J2000 in, B1950 out) */ double epoch); /* Besselian epoch in years */ int wcscsys( /* Return code for coordinate system in string */ char *coorsys); /* Coordinate system (B1950, J2000, etc) */ double wcsceq ( /* Set equinox from string (return 0.0 if not obvious) */ char *wcstring); /* Coordinate system (B1950, J2000, etc) */ void wcscstr ( /* Set coordinate system type string from system and equinox */ char *cstr, /* Coordinate system string (returned) */ int syswcs, /* Coordinate system code */ double equinox, /* Equinox of coordinate system */ double epoch); /* Epoch of coordinate system */ void d2v3 ( /* Convert RA and Dec in degrees and distance to vector */ double rra, /* Right ascension in degrees */ double rdec, /* Declination in degrees */ double r, /* Distance to object in same units as pos */ double pos[3]); /* x,y,z geocentric equatorial position of object (returned) */ void s2v3 ( /* Convert RA and Dec in radians and distance to vector */ double rra, /* Right ascension in radians */ double rdec, /* Declination in radians */ double r, /* Distance to object in same units as pos */ double pos[3]); /* x,y,z geocentric equatorial position of object (returned) */ void v2d3 ( /* Convert vector to RA and Dec in degrees and distance */ double pos[3], /* x,y,z geocentric equatorial position of object */ double *rra, /* Right ascension in degrees (returned) */ double *rdec, /* Declination in degrees (returned) */ double *r); /* Distance to object in same units as pos (returned) */ void v2s3 ( /* Convert vector to RA and Dec in radians and distance */ double pos[3], /* x,y,z geocentric equatorial position of object */ double *rra, /* Right ascension in radians (returned) */ double *rdec, /* Declination in radians (returned) */ double *r); /* Distance to object in same units as pos (returned) */ /* Distortion model subroutines in distort.c */ void distortinit ( /* Set distortion coefficients from FITS header */ struct WorldCoor *wcs, /* World coordinate system structure */ const char* hstring); /* FITS header */ void setdistcode ( /* Set WCS distortion code string from CTYPEi value */ struct WorldCoor *wcs, /* World coordinate system structure */ char *ctype); /* CTYPE value from FITS header */ char *getdistcode ( /* Return distortion code string for CTYPEi */ struct WorldCoor *wcs); /* World coordinate system structure */ int DelDistort ( /* Delete all distortion-related fields */ char *header, /* FITS header */ int verbose); /* If !=0, print keywords as deleted */ void pix2foc ( /* Convert pixel to focal plane coordinates */ struct WorldCoor *wcs, /* World coordinate system structure */ double x, /* Image pixel horizontal coordinate */ double y, /* Image pixel vertical coordinate */ double *u, /* Focal plane horizontal coordinate(returned) */ double *v); /* Focal plane vertical coordinate (returned) */ void foc2pix ( /* Convert focal plane to pixel coordinates */ struct WorldCoor *wcs, /* World coordinate system structure */ double u, /* Focal plane horizontal coordinate */ double v, /* Focal plane vertical coordinate */ double *x, /* Image pixel horizontal coordinate(returned) */ double *y); /* Image pixel vertical coordinate (returned) */ /* Other projection subroutines */ /* 8 projections using AIPS algorithms (worldpos.c) */ int worldpos ( /* Convert from pixel location to RA,Dec */ double xpix, /* x pixel number (RA or long without rotation) */ double ypix, /* y pixel number (Dec or lat without rotation) */ struct WorldCoor *wcs, /* WCS parameter structure */ double *xpos, /* x (RA) coordinate (deg) (returned) */ double *ypos); /* y (dec) coordinate (deg) (returned) */ int worldpix ( /* Convert from RA,Dec to pixel location */ double xpos, /* x (RA) coordinate (deg) */ double ypos, /* y (dec) coordinate (deg) */ struct WorldCoor *wcs, /* WCS parameter structure */ double *xpix, /* x pixel number (RA or long without rotation) */ double *ypix); /* y pixel number (dec or lat without rotation) */ /* Digital Sky Survey projection (dsspos.c) */ int dsspos ( /* Convert from pixel location to RA,Dec */ double xpix, /* x pixel number (RA or long without rotation) */ double ypix, /* y pixel number (Dec or lat without rotation) */ struct WorldCoor *wcs, /* WCS parameter structure */ double *xpos, /* x (RA) coordinate (deg) (returned) */ double *ypos); /* y (dec) coordinate (deg) (returned) */ int dsspix ( /* Convert from RA,Dec to pixel location */ double xpos, /* x (RA) coordinate (deg) */ double ypos, /* y (dec) coordinate (deg) */ struct WorldCoor *wcs, /* WCS parameter structure */ double *xpix, /* x pixel number (RA or long without rotation) */ double *ypix); /* y pixel number (dec or lat without rotation) */ /* SAO TDC TAN projection with higher order terms (platepos.c) */ int platepos ( /* Convert from pixel location to RA,Dec */ double xpix, /* x pixel number (RA or long without rotation) */ double ypix, /* y pixel number (Dec or lat without rotation) */ struct WorldCoor *wcs, /* WCS parameter structure */ double *xpos, /* x (RA) coordinate (deg) (returned) */ double *ypos); /* y (dec) coordinate (deg) (returned) */ int platepix ( /* Convert from RA,Dec to pixel location */ double xpos, /* x (RA) coordinate (deg) */ double ypos, /* y (dec) coordinate (deg) */ struct WorldCoor *wcs, /* WCS parameter structure */ double *xpix, /* x pixel number (RA or long without rotation) */ double *ypix); /* y pixel number (dec or lat without rotation) */ void SetFITSPlate ( /* Set FITS header plate fit coefficients from structure */ char *header, /* Image FITS header */ struct WorldCoor *wcs); /* WCS structure */ int SetPlate ( /* Set plate fit coefficients in structure from arguments */ struct WorldCoor *wcs, /* World coordinate system structure */ int ncoeff1, /* Number of coefficients for x */ int ncoeff2, /* Number of coefficients for y */ double *coeff); /* Plate fit coefficients */ int GetPlate ( /* Return plate fit coefficients from structure in arguments */ struct WorldCoor *wcs, /* World coordinate system structure */ int *ncoeff1, /* Number of coefficients for x */ int *ncoeff2, /* Number of coefficients for y) */ double *coeff); /* Plate fit coefficients */ /* IRAF TAN projection with higher order terms (tnxpos.c) */ int tnxinit ( /* initialize the gnomonic forward or inverse transform */ const char *header, /* FITS header */ struct WorldCoor *wcs); /* pointer to WCS structure */ int tnxpos ( /* forward transform (physical to world) gnomonic projection. */ double xpix, /* Image X coordinate */ double ypix, /* Image Y coordinate */ struct WorldCoor *wcs, /* pointer to WCS descriptor */ double *xpos, /* Right ascension (returned) */ double *ypos); /* Declination (returned) */ int tnxpix ( /* Inverse transform (world to physical) gnomonic projection */ double xpos, /* Right ascension */ double ypos, /* Declination */ struct WorldCoor *wcs, /* Pointer to WCS descriptor */ double *xpix, /* Image X coordinate (returned) */ double *ypix); /* Image Y coordinate (returned) */ #else /* K&R prototypes */ /* WCS subroutines in wcs.c */ struct WorldCoor *wcsinit(); /* set up a WCS structure from a FITS image header */ struct WorldCoor *wcsninit(); /* set up a WCS structure from a FITS image header */ struct WorldCoor *wcsinitn(); /* set up a WCS structure from a FITS image header */ struct WorldCoor *wcsninitn(); /* set up a WCS structure from a FITS image header */ struct WorldCoor *wcsinitc(); /* set up a WCS structure from a FITS image header */ struct WorldCoor *wcsninitc(); /* set up a WCS structure from a FITS image header */ struct WorldCoor *wcsxinit(); /* set up a WCS structure from arguments */ struct WorldCoor *wcskinit(); /* set up a WCS structure from keyword values */ void wcsfree(void); /* Free a WCS structure and its contents */ int wcstype(); /* Set projection type from header CTYPEs */ void wcscdset(); /* Set scaling and rotation from CD matrix */ void wcsdeltset(); /* set scaling and rotation from CDELTs and CROTA2 */ void wcspcset(); /* set scaling and rotation from CDELTs and PC matrix */ int iswcs(); /* Return 1 if WCS structure is filled, else 0 */ int nowcs(); /* Return 0 if WCS structure is filled, else 1 */ void wcsshift(); /* Reset the center of a WCS structure */ void wcscent(); /* Print the image center and size in WCS units */ void wcssize(); /* Return RA and Dec of image center, size in RA and Dec */ void wcsfull(); /* Return RA and Dec of image center, size in degrees */ void wcsrange(); /* Return min and max RA and Dec of image in degrees */ double wcsdist(); /* Distance in degrees between two sky coordinates */ double wcsdiff(); /* Distance in degrees between two sky coordinates */ void wcscominit(); /* Initialize catalog search command set by -wcscom */ void wcscom(); /* Execute catalog search command set by -wcscom */ char *getradecsys(); /* Return current value of coordinate system */ void wcsoutinit(); /* Initialize WCS output coordinate system for use by pix2wcs */ char *getwcsout(); /* Return current value of WCS output coordinate system */ void wcsininit(); /* Initialize WCS input coordinate system for use by wcs2pix */ char *getwcsin(); /* Return current value of WCS input coordinate system */ int setwcsdeg(); /* Set WCS output in degrees (1) or hh:mm:ss dd:mm:ss (0) */ int wcsndec(); /* Set or get number of output decimal places */ int wcsreset(); /* Change WCS using arguments */ void wcseqset(); /* Change equinox of reference pixel coordinates in WCS */ void wcscstr(); /* Return system string from system code, equinox, epoch */ void setwcslin(); /* Set output string mode for LINEAR coordinates */ int pix2wcst(); /* Convert pixel coordinates to World Coordinate string */ void pix2wcs(); /* Convert pixel coordinates to World Coordinates */ void wcsc2pix(); /* Convert World Coordinates to pixel coordinates */ void wcs2pix(); /* Convert World Coordinates to pixel coordinates */ void setdefwcs(); /* Call to use AIPS classic WCS (also not PLT or TNX */ int getdefwcs(); /* Call to get flag for AIPS classic WCS */ int wcszin(); /* Set coordinate in third dimension (face) */ int wcszout(); /* Return coordinate in third dimension */ void wcserr(); /* Print WCS error message to stderr */ void setwcserr(); /* Set WCS error message for later printing */ void savewcscoor(); /* Save output coordinate system */ char *getwcscoor(); /* Return output coordinate system */ void savewcscom(); /* Save WCS shell command */ char *getwcscom(); /* Return WCS shell command */ void setwcscom(); /* Set WCS shell commands from stored values */ void freewcscom(); /* Free memory used to store WCS shell commands */ void setwcsfile(); /* Set filename for WCS error message */ int cpwcs(); /* Copy WCS keywords with no suffix to ones with suffix */ /* Coordinate conversion subroutines in wcscon.c */ void wcscon(); /* Convert between coordinate systems and equinoxes */ void wcsconp(); /* Convert between coordinate systems and equinoxes */ void wcsconv(); /* Convert between coordinate systems and equinoxes */ void fk425e(); /* Convert B1950(FK4) to J2000(FK5) coordinates */ void fk524e(); /* Convert J2000(FK5) to B1950(FK4) coordinates */ int wcscsys(); /* Set coordinate system from string */ double wcsceq(); /* Set equinox from string (return 0.0 if not obvious) */ void d2v3(); /* Convert RA and Dec in degrees and distance to vector */ void s2v3(); /* Convert RA and Dec in radians and distance to vector */ void v2d3(); /* Convert vector to RA and Dec in degrees and distance */ void v2s3(); /* Convert vector to RA and Dec in radians and distance */ /* Distortion model subroutines in distort.c */ void distortinit(); /* Set distortion coefficients from FITS header */ void setdistcode(); /* Set WCS distortion code string from CTYPEi value */ char *getdistcode(); /* Return distortion code string for CTYPEi */ int DelDistort(); /* Delete all distortion-related fields */ void pix2foc(); /* pixel coordinates -> focal plane coordinates */ void foc2pix(); /* focal plane coordinates -> pixel coordinates */ /* Other projection subroutines */ /* 8 projections using AIPS algorithms (worldpos.c) */ extern int worldpos(); /* Convert from pixel location to RA,Dec */ extern int worldpix(); /* Convert from RA,Dec to pixel location */ /* Digital Sky Survey projection (dsspos.c) */ extern int dsspos(); /* Convert from pixel location to RA,Dec */ extern int dsspix(); /* Convert from RA,Dec to pixel location */ /* SAO TDC TAN projection with higher order terms (platepos.c) */ extern int platepos(); /* Convert from pixel location to RA,Dec */ extern int platepix(); /* Convert from RA,Dec to pixel location */ extern void SetFITSPlate(); /* Set FITS header plate fit coefficients from structure */ extern int SetPlate(); /* Set plate fit coefficients in structure from arguments */ extern int GetPlate(); /* Return plate fit coefficients from structure in arguments */ /* IRAF TAN projection with higher order terms (tnxpos.c) */ extern int tnxinit(); /* initialize the gnomonic forward or inverse transform */ extern int tnxpos(); /* forward transform (physical to world) gnomonic projection. */ extern int tnxpix(); /* Inverse transform (world to physical) gnomonic projection */ #endif /* __STDC__ */ #ifdef __cplusplus } #endif #endif /* _wcs_h_ */ /* Oct 26 1994 New file * Dec 21 1994 Add rotation matrix * Dec 22 1994 Add flag for coordinate reversal * Mar 6 1995 Add parameters for Digital Sky Survey plate fit * Jun 8 1995 Add parameters for coordinate system change * Jun 21 1995 Add parameter for plate scale * Jul 6 1995 Add parameter to note whether WCS is set * Aug 8 1995 Add parameter to note whether to print coordinate system * Oct 16 1995 Add parameters to save image dimensions and center coordinates * Feb 15 1996 Add coordinate conversion functions * Feb 20 1996 Add flag for tab tables * Apr 26 1996 Add epoch of positions (actual date of image) * Jul 5 1996 Add subroutine declarations * Jul 19 1996 Add WCSFULL declaration * Aug 5 1996 Add WCSNINIT to initialize WCS for non-terminated header * Oct 31 1996 Add DCnn inverse rotation matrix * Nov 1 1996 Add NDEC number of decimal places in output * * May 22 1997 Change range of pcode from 1-8 to -1-8 for linear transform * Sep 12 1997 Add chip rotation MROT, XMPIX, YMPIX * * Jan 7 1998 Add INSTRUME and DETECTOR for HST metric correction * Jan 16 1998 Add Mark Calabretta's WCSLIB data structures * Jan 16 1998 Add LONGPOLE, LATPOLE, and PROJP constants for Calabretta * Jan 22 1998 Add ctype[], crpix[], crval[], and cdelt[] for Calabretta * Jan 23 1998 Change wcsset() to wcsxinit() and pcode to prjcode * Jan 23 1998 Define projection type flags * Jan 26 1998 Remove chip rotation * Jan 26 1998 Add chip correction polynomial * Feb 3 1998 Add number of coefficients for residual fit * Feb 5 1998 Make cd and dc matrices vectors, not individual elements * Feb 19 1998 Add projection names * Feb 23 1998 Add TNX projection from NOAO * Mar 3 1998 Add NOAO plate fit and residual fit * Mar 12 1998 Add variables for TNX correction surface * Mar 23 1998 Add PLT plate fit polynomial projection; reassign DSS * Mar 23 1998 Drop plate_fit flag from structure * Mar 25 1998 Add npcoeff to wcs structure for new plate fit WCS * Apr 7 1998 Change amd_i_coeff to i_coeff * Apr 8 1998 Add wcseqset() and wcsreset() subroutine declarations * Apr 10 1998 Rearrange order of nonstandard WCS types * Apr 13 1998 Add setdefwcs() subroutine declaration * Apr 14 1998 Add coordinate systems and wcscoor() * Apr 24 1998 Add units * Apr 28 1998 Change coordinate system flags to WCS_* * Apr 28 1998 Change projection flags to WCS_* * Apr 28 1998 Add wcsc2pix() * May 7 1998 Add C++ declarations * May 13 1998 Add eqin and eqout for conversions to and from equinoxes * May 14 1998 Add declarations for coordinate conversion subroutines * May 27 1998 Add blsearch() * May 27 1998 Change linear projection back to WCS_LIN from WCS_LPR * May 27 1998 Move hget.c and hput.c C++ declarations to fitshead.h * May 27 1998 Include fitshead.h * May 29 1998 Add wcskinit() * Jun 1 1998 Add wcserr() * Jun 11 1998 Add initialization support subroutines * Jun 18 1998 Add wcspcset() * Jun 25 1998 Add wcsndec() * Jul 6 1998 Add wcszin() and wcszout() to use third dimension of images * Jul 7 1998 Change setdegout() to setwcsdeg(); setlinmode() to setwcslin() * Jul 17 1998 Add savewcscoor(), getwcscoor(), savewcscom(), and getwcscom() * Aug 14 1998 Add freewcscom(), setwcscom(), and multiple WCS commands * Sep 3 1998 Add pa_north, pa_east, imrot and imflip to wcs structure * Sep 14 1998 Add latbase for AXAF North Polar angle (NPOL not LAT-) * Sep 16 1998 Make WCS_system start at 1; add NPOLE * Sep 17 1998 Add wcscstr() * Sep 21 1998 Add wcsconp() to convert proper motions, too. * Dec 2 1998 Add WCS type for planet surface * Jan 20 1999 Add declaration of wcsfree() * Jun 16 1999 Add declaration of wcsrange() * Oct 21 1999 Add declaration of setwcsfile() * * Jan 28 2000 Add flags for choice of WCS projection subroutines * Jun 26 2000 Add XY coordinate system * Nov 2 2000 Add wcsconv() to convert coordinates when parallax or rv known * * Jan 17 2001 Add idpix and ndpix for trim section, ltm for readout rotation * Jan 31 2001 Add wcsinitn(), wcsninitn(), wcsinitc(), and wcsninitc() * Feb 20 2001 Add wcs->wcs to main data structure * Mar 20 2001 Close unclosed comment in wcsconv() argument list * * Apr 3 2002 Add SZP and second GLS/SFL projection * Apr 9 2002 Add wcs->wcsdep for pointer to WCS depending on this WCS * Apr 26 2002 Add wcs->wcsname and wcs->wcschar to identify WCS structure * May 9 2002 Add wcs->radvel and wcs->zvel for radial velocity in km/sec * * Apr 1 2003 Add wcs->distort Distort structure for distortion correction * Apr 1 2003 Add foc2pix() and pix2foc() subroutines for distortion correction * May 1 2003 Add missing semicolons after C++ declarations of previous two functions * Oct 1 2003 Rename wcs->naxes to wcs->naxis to match WCSLIB 3.2 * Nov 3 2003 Add distinit(), setdistcode(), and getdistcode() to distort.c * Dec 3 2003 Add back wcs->naxes for backward compatibility * * Aug 30 2004 Add DelDistort() * * Nov 1 2005 Add WCS_ICRS * * Jan 5 2006 Add secrad() * Apr 21 2006 Increase maximum number of axes from 4 to 8 * Apr 24 2006 Increase maximum number of axes to 9 * Nov 29 2006 Drop semicolon at end of C++ ifdef * Dec 21 2006 Add cpwcs() * * Jan 4 2007 Drop extra declaration of wcscstr() * Jan 4 2007 Fix declarations so ANSI prototypes are not just for C++ * Jan 9 2007 Add fk425e() and fk524e() subroutines * Jan 9 2007 Add worldpos.c, dsspos.c, platepos.c, and tnxpos.c subroutines * Jan 10 2007 Add ANSI prototypes for all subroutines * Feb 1 2007 Add wcs.wcslog for log wavelength * Jul 25 2007 Add v2s3(), s2v3(), d2v3(), v2d3() for coordinate-vector conversion */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/wcscon.c000066400000000000000000002030461215713201500217200ustar00rootroot00000000000000/*** File wcscon.c *** August 15, 2007 *** Doug Mink, Harvard-Smithsonian Center for Astrophysics *** Some subroutines are based on Starlink subroutines by Patrick Wallace *** Copyright (C) 1995-2007 *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Correspondence concerning WCSTools should be addressed as follows: Internet email: dmink@cfa.harvard.edu Postal address: Doug Mink Smithsonian Astrophysical Observatory 60 Garden St. Cambridge, MA 02138 USA * Module: wcscon.c (World Coordinate System conversion) * Purpose: Convert between various sky coordinate systems * Subroutine: wcscon (sys1,sys2,eq1,eq2,theta,phi,epoch) * convert between coordinate systems * Subroutine: wcsconp (sys1,sys2,eq1,eq2,ep1,ep2,dtheta,dphi,ptheta,pphi) * convert coordinates and proper motion between coordinate systems * Subroutine: wcsconv (sys1,sys2,eq1,eq2,ep1,ep2,dtheta,dphi,ptheta,pphi,px,rv) * convert coordinates and proper motion between coordinate systems * Subroutine: wcscsys (cstring) returns code for coordinate system in string * Subroutine: wcsceq (wcstring) returns equinox in years from system string * Subroutine: wcscstr (sys,equinox,epoch) returns system string from equinox * Subroutine: fk524 (ra,dec) Convert J2000(FK5) to B1950(FK4) coordinates * Subroutine: fk524e (ra, dec, epoch) (more accurate for known position epoch) * Subroutine: fk524m (ra,dec,rapm,decpm) exact * Subroutine: fk524pv (ra,dec,rapm,decpm,parallax,rv) more exact * Subroutine: fk425 (ra,dec) Convert B1950(FK4) to J2000(FK5) coordinates * Subroutine: fk425e (ra, dec, epoch) (more accurate for known position epoch) * Subroutine: fk425m (ra, dec, rapm, decpm) exact * Subroutine: fk425pv (ra,dec,rapm,decpm,parallax,rv) more exact * Subroutine: fk42gal (dtheta,dphi) Convert B1950(FK4) to galactic coordinates * Subroutine: fk52gal (dtheta,dphi) Convert J2000(FK5) to galactic coordinates * Subroutine: gal2fk4 (dtheta,dphi) Convert galactic coordinates to B1950(FK4) * Subroutine: gal2fk5 (dtheta,dphi) Convert galactic coordinates to J2000 #ifndef VMS #include #endif #include /* for fprintf() and sprintf() */ #include #include #include "wcs.h" void fk524(), fk524e(), fk524m(), fk524pv(); void fk425(), fk425e(), fk425m(), fk425pv(); void fk42gal(), fk52gal(), gal2fk4(), gal2fk5(); void fk42ecl(), fk52ecl(), ecl2fk4(), ecl2fk5(); /* Convert from coordinate system sys1 to coordinate system sys2, converting proper motions, too, and adding them if an epoch is specified */ void wcsconp (sys1, sys2, eq1, eq2, ep1, ep2, dtheta, dphi, ptheta, pphi) int sys1; /* Input coordinate system (J2000, B1950, ECLIPTIC, GALACTIC */ int sys2; /* Output coordinate system (J2000, B1950, ECLIPTIC, GALACTIC */ double eq1; /* Input equinox (default of sys1 if 0.0) */ double eq2; /* Output equinox (default of sys2 if 0.0) */ double ep1; /* Input Besselian epoch in years (for proper motion) */ double ep2; /* Output Besselian epoch in years (for proper motion) */ double *dtheta; /* Longitude or right ascension in degrees Input in sys1, returned in sys2 */ double *dphi; /* Latitude or declination in degrees Input in sys1, returned in sys2 */ double *ptheta; /* Longitude or right ascension proper motion in degrees/year Input in sys1, returned in sys2 */ double *pphi; /* Latitude or declination proper motion in degrees/year Input in sys1, returned in sys2 */ { void fk5prec(), fk4prec(); /* Set equinoxes if 0.0 */ if (eq1 == 0.0) { if (sys1 == WCS_B1950) eq1 = 1950.0; else eq1 = 2000.0; } if (eq2 == 0.0) { if (sys2 == WCS_B1950) eq2 = 1950.0; else eq2 = 2000.0; } /* Set epochs if 0.0 */ if (ep1 == 0.0) { if (sys1 == WCS_B1950) ep1 = 1950.0; else ep1 = 2000.0; } if (ep2 == 0.0) { if (sys2 == WCS_B1950) ep2 = 1950.0; else ep2 = 2000.0; } if (sys1 == WCS_ICRS && sys2 == WCS_ICRS) eq2 = eq1; if (sys1 == WCS_J2000 && sys2 == WCS_ICRS && eq1 == 2000.0) { eq2 = eq1; sys1 = sys2; } /* Set systems and equinoxes so that ICRS coordinates are not precessed */ if (sys1 == WCS_ICRS && sys2 == WCS_J2000 && eq2 == 2000.0) { eq1 = eq2; sys1 = sys2; } /* If systems and equinoxes are the same, add proper motion and return */ if (sys2 == sys1 && eq1 == eq2) { if (ep1 != ep2) { if (sys1 == WCS_J2000) { *dtheta = *dtheta + ((ep2 - ep1) * *ptheta); *dphi = *dphi + ((ep2 - ep1) * *pphi); } else if (sys1 == WCS_B1950) { *dtheta = *dtheta + ((ep2 - ep1) * *ptheta); *dphi = *dphi + ((ep2 - ep1) * *pphi); } } if (eq1 != eq2) { if (sys1 == WCS_B1950) fk4prec (eq1, eq2, dtheta, dphi); if (sys1 == WCS_J2000) fk5prec (eq1, 2000.0, dtheta, dphi); } return; } /* Precess from input equinox to input system equinox, if necessary */ if (sys1 == WCS_B1950 && eq1 != 1950.0) fk4prec (eq1, 1950.0, dtheta, dphi); if (sys1 == WCS_J2000 && eq1 != 2000.0) fk5prec (eq1, 2000.0, dtheta, dphi); /* Convert to B1950 FK4 */ if (sys2 == WCS_B1950) { if (sys1 == WCS_J2000) { if (*ptheta != 0.0 || *pphi != 0.0) { fk524m (dtheta, dphi, ptheta, pphi); if (ep1 == 2000.0) ep1 = 1950.0; if (ep2 != 1950.0) { *dtheta = *dtheta + ((ep2 - 1950.0) * *ptheta); *dphi = *dphi + ((ep2 - 1950.0) * *pphi); } } else if (ep2 != 1950.0) fk524e (dtheta, dphi, ep2); else fk524 (dtheta, dphi); } else if (sys1 == WCS_GALACTIC) gal2fk4 (dtheta, dphi); else if (sys1 == WCS_ECLIPTIC) ecl2fk4 (dtheta, dphi, ep2); } else if (sys2 == WCS_J2000) { if (sys1 == WCS_B1950) { if (*ptheta != 0.0 || *pphi != 0.0) { fk425m (dtheta, dphi, ptheta, pphi); if (ep2 != 2000.0) { *dtheta = *dtheta + ((ep2 - 2000.0) * *ptheta); *dphi = *dphi + ((ep2 - 2000.0) * *pphi); } } else if (ep2 > 0.0) fk425e (dtheta, dphi, ep2); else fk425 (dtheta, dphi); } else if (sys1 == WCS_GALACTIC) gal2fk5 (dtheta, dphi); else if (sys1 == WCS_ECLIPTIC) ecl2fk5 (dtheta, dphi, ep2); } else if (sys2 == WCS_GALACTIC) { if (sys1 == WCS_B1950) { if (ep2 != 0.0 && (*ptheta != 0.0 || *pphi != 0.0)) { *dtheta = *dtheta + (*ptheta * (ep2 - ep1)); *dphi = *dphi + (*pphi * (ep2 - ep1)); } fk42gal (dtheta, dphi); } else if (sys1 == WCS_J2000) { if (ep2 != 0.0 && (*ptheta != 0.0 || *pphi != 0.0)) { *dtheta = *dtheta + (*ptheta * (ep2 - ep1)); *dphi = *dphi + (*pphi * (ep2 - ep1)); } fk52gal (dtheta, dphi); } else if (sys1 == WCS_ECLIPTIC) { ecl2fk5 (dtheta, dphi, ep2); fk52gal (dtheta, dphi); } } else if (sys2 == WCS_ECLIPTIC) { if (sys1 == WCS_B1950) { if (ep2 != 0.0 && (*ptheta != 0.0 || *pphi != 0.0)) { *dtheta = *dtheta + (*ptheta * (ep2 - ep1)); *dphi = *dphi + (*pphi * (ep2 - ep1)); } if (ep2 > 0.0) fk42ecl (dtheta, dphi, ep2); else fk42ecl (dtheta, dphi, 1950.0); } else if (sys1 == WCS_J2000) { if (ep2 != 0.0 && (*ptheta != 0.0 || *pphi != 0.0)) { *dtheta = *dtheta + (*ptheta * (ep2 - ep1)); *dphi = *dphi + (*pphi * (ep2 - ep1)); } fk52ecl (dtheta, dphi, ep2); } else if (sys1 == WCS_GALACTIC) { gal2fk5 (dtheta, dphi); fk52ecl (dtheta, dphi, ep2); } } /* Precess to desired equinox, if necessary */ if (sys2 == WCS_B1950 && eq2 != 1950.0) fk4prec (1950.0, eq2, dtheta, dphi); if (sys2 == WCS_J2000 && eq2 != 2000.0) fk5prec (2000.0, eq2, dtheta, dphi); /* Keep latitude/declination between +90 and -90 degrees */ if (*dphi > 90.0) { *dphi = 180.0 - *dphi; *dtheta = *dtheta + 180.0; } else if (*dphi < -90.0) { *dphi = -180.0 - *dphi; *dtheta = *dtheta + 180.0; } /* Keep longitude/right ascension between 0 and 360 degrees */ if (*dtheta > 360.0) *dtheta = *dtheta - 360.0; else if (*dtheta < 0.0) *dtheta = *dtheta + 360.0; return; } /* Convert from coordinate system sys1 to coordinate system sys2, converting proper motions, too, and adding them if an epoch is specified */ void wcsconv (sys1, sys2, eq1, eq2, ep1, ep2, dtheta, dphi, ptheta, pphi, px, rv) int sys1; /* Input coordinate system (J2000, B1950, ECLIPTIC, GALACTIC */ int sys2; /* Output coordinate system (J2000, B1950, ECLIPTIC, GALACTIC */ double eq1; /* Input equinox (default of sys1 if 0.0) */ double eq2; /* Output equinox (default of sys2 if 0.0) */ double ep1; /* Input Besselian epoch in years (for proper motion) */ double ep2; /* Output Besselian epoch in years (for proper motion) */ double *dtheta; /* Longitude or right ascension in degrees Input in sys1, returned in sys2 */ double *dphi; /* Latitude or declination in degrees Input in sys1, returned in sys2 */ double *ptheta; /* Longitude or right ascension proper motion in degrees/year Input in sys1, returned in sys2 */ double *pphi; /* Latitude or declination proper motion in degrees/year Input in sys1, returned in sys2 */ double *px; /* Parallax in arcseconds */ double *rv; /* Radial velocity in km/sec */ { void fk5prec(), fk4prec(); /* Set equinoxes if 0.0 */ if (eq1 == 0.0) { if (sys1 == WCS_B1950) eq1 = 1950.0; else eq1 = 2000.0; } if (eq2 == 0.0) { if (sys2 == WCS_B1950) eq2 = 1950.0; else eq2 = 2000.0; } /* Set epochs if 0.0 */ if (ep1 == 0.0) { if (sys1 == WCS_B1950) ep1 = 1950.0; else ep1 = 2000.0; } if (ep2 == 0.0) { if (sys2 == WCS_B1950) ep2 = 1950.0; else ep2 = 2000.0; } /* Set systems and equinoxes so that ICRS coordinates are not precessed */ if (sys1 == WCS_ICRS && sys2 == WCS_ICRS) eq2 = eq1; if (sys1 == WCS_J2000 && sys2 == WCS_ICRS && eq1 == 2000.0) { eq2 = eq1; sys1 = sys2; } if (sys1 == WCS_ICRS && sys2 == WCS_J2000 && eq2 == 2000.0) { eq1 = eq2; sys1 = sys2; } /* If systems and equinoxes are the same, add proper motion and return */ if (sys2 == sys1 && eq1 == eq2) { if (ep1 != ep2) { if (sys1 == WCS_J2000) { *dtheta = *dtheta + ((ep2 - ep1) * *ptheta); *dphi = *dphi + ((ep2 - ep1) * *pphi); } else if (sys1 == WCS_B1950) { *dtheta = *dtheta + ((ep2 - ep1) * *ptheta); *dphi = *dphi + ((ep2 - ep1) * *pphi); } } return; } /* Precess from input equinox to input system equinox, if necessary */ if (eq1 != eq2) { if (sys1 == WCS_B1950 && eq1 != 1950.0) fk4prec (eq1, 1950.0, dtheta, dphi); if (sys1 == WCS_J2000 && eq1 != 2000.0) fk5prec (eq1, 2000.0, dtheta, dphi); } /* Convert to B1950 FK4 */ if (sys2 == WCS_B1950) { if (sys1 == WCS_J2000) { if (*ptheta != 0.0 || *pphi != 0.0) { if (*px != 0.0 || *rv != 0.0) fk524pv (dtheta, dphi, ptheta, pphi, px, rv); else fk524m (dtheta, dphi, ptheta, pphi); if (ep1 == 2000.0) ep1 = 1950.0; if (ep2 != 1950.0) { *dtheta = *dtheta + ((ep2 - 1950.0) * *ptheta); *dphi = *dphi + ((ep2 - 1950.0) * *pphi); } } else if (ep2 != 1950.0) fk524e (dtheta, dphi, ep2); else fk524 (dtheta, dphi); } else if (sys1 == WCS_GALACTIC) gal2fk4 (dtheta, dphi); else if (sys1 == WCS_ECLIPTIC) ecl2fk4 (dtheta, dphi, ep2); } else if (sys2 == WCS_J2000) { if (sys1 == WCS_B1950) { if (*ptheta != 0.0 || *pphi != 0.0) { if (*px != 0.0 || *rv != 0.0) fk425pv (dtheta, dphi, ptheta, pphi, px, rv); else fk425m (dtheta, dphi, ptheta, pphi); if (ep2 != 2000.0) { *dtheta = *dtheta + ((ep2 - 2000.0) * *ptheta); *dphi = *dphi + ((ep2 - 2000.0) * *pphi); } } else if (ep2 > 0.0) fk425e (dtheta, dphi, ep2); else fk425 (dtheta, dphi); } else if (sys1 == WCS_GALACTIC) gal2fk5 (dtheta, dphi); else if (sys1 == WCS_ECLIPTIC) ecl2fk5 (dtheta, dphi, ep2); } else if (sys2 == WCS_GALACTIC) { if (sys1 == WCS_B1950) { if (ep2 != 0.0 && (*ptheta != 0.0 || *pphi != 0.0)) { *dtheta = *dtheta + (*ptheta * (ep2 - ep1)); *dphi = *dphi + (*pphi * (ep2 - ep1)); } fk42gal (dtheta, dphi); } else if (sys1 == WCS_J2000) { if (ep2 != 0.0 && (*ptheta != 0.0 || *pphi != 0.0)) { *dtheta = *dtheta + (*ptheta * (ep2 - ep1)); *dphi = *dphi + (*pphi * (ep2 - ep1)); } fk52gal (dtheta, dphi); } else if (sys1 == WCS_ECLIPTIC) { ecl2fk5 (dtheta, dphi, ep2); fk52gal (dtheta, dphi); } } else if (sys2 == WCS_ECLIPTIC) { if (sys1 == WCS_B1950) { if (ep2 != 0.0 && (*ptheta != 0.0 || *pphi != 0.0)) { *dtheta = *dtheta + (*ptheta * (ep2 - ep1)); *dphi = *dphi + (*pphi * (ep2 - ep1)); } if (ep2 > 0.0) fk42ecl (dtheta, dphi, ep2); else fk42ecl (dtheta, dphi, 1950.0); } else if (sys1 == WCS_J2000) { if (ep2 != 0.0 && (*ptheta != 0.0 || *pphi != 0.0)) { *dtheta = *dtheta + (*ptheta * (ep2 - ep1)); *dphi = *dphi + (*pphi * (ep2 - ep1)); } fk52ecl (dtheta, dphi, ep2); } else if (sys1 == WCS_GALACTIC) { gal2fk5 (dtheta, dphi); fk52ecl (dtheta, dphi, ep2); } } /* Precess to desired equinox, if necessary */ if (eq1 != eq2) { if (sys2 == WCS_B1950 && eq2 != 1950.0) fk4prec (1950.0, eq2, dtheta, dphi); if (sys2 == WCS_J2000 && eq2 != 2000.0) fk5prec (2000.0, eq2, dtheta, dphi); } /* Keep latitude/declination between +90 and -90 degrees */ if (*dphi > 90.0) { *dphi = 180.0 - *dphi; *dtheta = *dtheta + 180.0; } else if (*dphi < -90.0) { *dphi = -180.0 - *dphi; *dtheta = *dtheta + 180.0; } /* Keep longitude/right ascension between 0 and 360 degrees */ if (*dtheta > 360.0) *dtheta = *dtheta - 360.0; else if (*dtheta < 0.0) *dtheta = *dtheta + 360.0; return; } /* Convert from coordinate system sys1 to coordinate system sys2 */ void wcscon (sys1, sys2, eq1, eq2, dtheta, dphi, epoch) int sys1; /* Input coordinate system (J2000, B1950, ECLIPTIC, GALACTIC */ int sys2; /* Output coordinate system (J2000, B1950, ECLIPTIC, GALACTIC */ double eq1; /* Input equinox (default of sys1 if 0.0) */ double eq2; /* Output equinox (default of sys2 if 0.0) */ double *dtheta; /* Longitude or right ascension in degrees Input in sys1, returned in sys2 */ double *dphi; /* Latitude or declination in degrees Input in sys1, returned in sys2 */ double epoch; /* Besselian epoch in years */ { void fk5prec(), fk4prec(); /* Set equinoxes if 0.0 */ if (eq1 == 0.0) { if (sys1 == WCS_B1950) eq1 = 1950.0; else eq1 = 2000.0; } if (eq2 == 0.0) { if (sys2 == WCS_B1950) eq2 = 1950.0; else eq2 = 2000.0; } /* Set systems and equinoxes so that ICRS coordinates are not precessed */ if (sys1 == WCS_ICRS && sys2 == WCS_ICRS) eq2 = eq1; if (sys1 == WCS_J2000 && sys2 == WCS_ICRS && eq1 == 2000.0) { eq2 = eq1; sys1 = sys2; } if (sys1 == WCS_ICRS && sys2 == WCS_J2000 && eq2 == 2000.0) { eq1 = eq2; sys1 = sys2; } /* If systems and equinoxes are the same, return */ if (sys2 == sys1 && eq1 == eq2) return; /* Precess from input equinox, if necessary */ if (eq1 != eq2) { if (sys1 == WCS_B1950 && eq1 != 1950.0) fk4prec (eq1, 1950.0, dtheta, dphi); if (sys1 == WCS_J2000 && eq1 != 2000.0) fk5prec (eq1, 2000.0, dtheta, dphi); } /* Convert to B1950 FK4 */ if (sys2 == WCS_B1950) { if (sys1 == WCS_J2000) { if (epoch > 0) fk524e (dtheta, dphi, epoch); else fk524 (dtheta, dphi); } else if (sys1 == WCS_GALACTIC) gal2fk4 (dtheta, dphi); else if (sys1 == WCS_ECLIPTIC) { if (epoch > 0) ecl2fk4 (dtheta, dphi, epoch); else ecl2fk4 (dtheta, dphi, 1950.0); } } else if (sys2 == WCS_J2000) { if (sys1 == WCS_B1950) { if (epoch > 0) fk425e (dtheta, dphi, epoch); else fk425 (dtheta, dphi); } else if (sys1 == WCS_GALACTIC) gal2fk5 (dtheta, dphi); else if (sys1 == WCS_ECLIPTIC) { if (epoch > 0) ecl2fk5 (dtheta, dphi, epoch); else ecl2fk5 (dtheta, dphi, 2000.0); } } else if (sys2 == WCS_GALACTIC) { if (sys1 == WCS_B1950) fk42gal (dtheta, dphi); else if (sys1 == WCS_J2000) fk52gal (dtheta, dphi); else if (sys1 == WCS_ECLIPTIC) { if (epoch > 0) ecl2fk5 (dtheta, dphi, epoch); else ecl2fk5 (dtheta, dphi, 2000.0); fk52gal (dtheta, dphi); } } else if (sys2 == WCS_ECLIPTIC) { if (sys1 == WCS_B1950) { if (epoch > 0) fk42ecl (dtheta, dphi, epoch); else fk42ecl (dtheta, dphi, 1950.0); } else if (sys1 == WCS_J2000) { if (epoch > 0) fk52ecl (dtheta, dphi, epoch); else fk52ecl (dtheta, dphi, 2000.0); } else if (sys1 == WCS_GALACTIC) { gal2fk5 (dtheta, dphi); if (epoch > 0) fk52ecl (dtheta, dphi, epoch); else fk52ecl (dtheta, dphi, 2000.0); } } /* Precess to desired equinox, if necessary */ if (eq1 != eq2) { if (sys2 == WCS_B1950 && eq2 != 1950.0) fk4prec (1950.0, eq2, dtheta, dphi); if (sys2 == WCS_J2000 && eq2 != 2000.0) fk5prec (2000.0, eq2, dtheta, dphi); } /* Keep latitude/declination between +90 and -90 degrees */ if (*dphi > 90.0) { *dphi = 180.0 - *dphi; *dtheta = *dtheta + 180.0; } else if (*dphi < -90.0) { *dphi = -180.0 - *dphi; *dtheta = *dtheta + 180.0; } /* Keep longitude/right ascension between 0 and 360 degrees */ if (*dtheta > 360.0) *dtheta = *dtheta - 360.0; else if (*dtheta < 0.0) *dtheta = *dtheta + 360.0; return; } /* Set coordinate system from string */ int wcscsys (wcstring) char *wcstring; /* Name of coordinate system */ { double equinox; if (wcstring[0] == 'J' || wcstring[0] == 'j' || !strcmp (wcstring,"2000") || !strcmp (wcstring, "2000.0") || !strcmp (wcstring,"ICRS") || !strcmp (wcstring, "icrs") || !strncmp (wcstring,"FK5",3) || !strncmp (wcstring, "fk5",3)) return WCS_J2000; if (wcstring[0] == 'B' || wcstring[0] == 'b' || !strcmp (wcstring,"1950") || !strcmp (wcstring, "1950.0") || !strncmp (wcstring,"FK4",3) || !strncmp (wcstring, "fk4",3)) return WCS_B1950; else if (wcstring[0] == 'I' || wcstring[0] == 'i' ) return WCS_ICRS; else if (wcstring[0] == 'G' || wcstring[0] == 'g' ) return WCS_GALACTIC; else if (wcstring[0] == 'E' || wcstring[0] == 'e' ) return WCS_ECLIPTIC; else if (wcstring[0] == 'A' || wcstring[0] == 'a' ) return WCS_ALTAZ; else if (wcstring[0] == 'N' || wcstring[0] == 'n' ) return WCS_NPOLE; else if (wcstring[0] == 'L' || wcstring[0] == 'l' ) return WCS_LINEAR; else if (!strncasecmp (wcstring, "pixel", 5)) return WCS_XY; else if (wcstring[0] == 'P' || wcstring[0] == 'p' ) return WCS_PLANET; else if (isnum (wcstring)) { equinox = atof (wcstring); if (equinox > 1980.0) return WCS_J2000; else if (equinox > 1900.0) return WCS_B1950; else return -1; } else return -1; } /* Set equinox from string (return 0.0 if not obvious) */ double wcsceq (wcstring) char *wcstring; /* Name of coordinate system */ { if (wcstring[0] == 'J' || wcstring[0] == 'j' || wcstring[0] == 'B' || wcstring[0] == 'b') return (atof (wcstring+1)); else if (!strncmp (wcstring, "FK4",3) || !strncmp (wcstring, "fk4",3)) return (1950.0); else if (!strncmp (wcstring, "FK5",3) || !strncmp (wcstring, "fk5",3)) return (2000.0); else if (!strncmp (wcstring, "ICRS",4) || !strncmp (wcstring, "icrs",4)) return (2000.0); else if (wcstring[0] == '1' || wcstring[0] == '2') return (atof (wcstring)); else return (0.0); } /* Set coordinate system type string from system and equinox */ void wcscstr (cstr, syswcs, equinox, epoch) char *cstr; /* Coordinate system string (returned) */ int syswcs; /* Coordinate system code */ double equinox; /* Equinox of coordinate system */ double epoch; /* Epoch of coordinate system */ { char *estr; if (syswcs == WCS_XY) { strcpy (cstr, "XY"); return; } /* Try to figure out coordinate system if it is not set */ if (epoch == 0.0) epoch = equinox; if (syswcs < 0) { if (equinox > 0.0) { if (equinox == 2000.0) syswcs = WCS_J2000; else if (equinox == 1950.0) syswcs = WCS_B1950; } else if (epoch > 0.0) { if (epoch > 1980.0) { syswcs = WCS_J2000; equinox = 2000.0; } else { syswcs = WCS_B1950; equinox = 1950.0; } } else syswcs = WCS_J2000; } /* Set coordinate system string from system flag and epoch */ if (syswcs == WCS_B1950) { if (epoch == 1950.0 || epoch == 0.0) strcpy (cstr, "B1950"); else sprintf (cstr, "B%7.2f", equinox); if ((estr = strsrch (cstr,".00")) != NULL) { estr[0] = (char) 0; estr[1] = (char) 0; estr[2] = (char) 0; } } else if (syswcs == WCS_GALACTIC) strcpy (cstr, "galactic"); else if (syswcs == WCS_ECLIPTIC) strcpy (cstr, "ecliptic"); else if (syswcs == WCS_J2000) { if (epoch == 2000.0 || epoch == 0.0) strcpy (cstr, "J2000"); else sprintf (cstr, "J%7.2f", equinox); if ((estr = strsrch (cstr,".00")) != NULL) { estr[0] = (char) 0; estr[1] = (char) 0; estr[2] = (char) 0; } } else if (syswcs == WCS_ICRS) { strcpy (cstr, "ICRS"); } else if (syswcs == WCS_PLANET) { strcpy (cstr, "PLANET"); } else if (syswcs == WCS_LINEAR || syswcs == WCS_XY) { strcpy (cstr, "LINEAR"); } return; } /* Constant vector and matrix (by columns) These values were obtained by inverting C.Hohenkerk's forward matrix (private communication), which agrees with the one given in reference 2 but which has one additional decimal place. */ static double a[3] = {-1.62557e-6, -0.31919e-6, -0.13843e-6}; static double ad[3] = {1.245e-3, -1.580e-3, -0.659e-3}; static double d2pi = 6.283185307179586476925287; /* two PI */ static double tiny = 1.e-30; /* small number to avoid arithmetic problems */ /* FK524 convert J2000 FK5 star data to B1950 FK4 based on Starlink sla_fk524 by P.T.Wallace 27 October 1987 */ static double emi[6][6] = { { 0.9999256795, /* emi[0][0] */ 0.0111814828, /* emi[0][1] */ 0.0048590039, /* emi[0][2] */ -0.00000242389840, /* emi[0][3] */ -0.00000002710544, /* emi[0][4] */ -0.00000001177742 }, /* emi[0][5] */ { -0.0111814828, /* emi[1][0] */ 0.9999374849, /* emi[1][1] */ -0.0000271771, /* emi[1][2] */ 0.00000002710544, /* emi[1][3] */ -0.00000242392702, /* emi[1][4] */ 0.00000000006585 }, /* emi[1][5] */ { -0.0048590040, /* emi[2][0] */ -0.0000271557, /* emi[2][1] */ 0.9999881946, /* emi[2][2] */ 0.00000001177742, /* emi[2][3] */ 0.00000000006585, /* emi[2][4] */ -0.00000242404995 }, /* emi[2][5] */ { -0.000551, /* emi[3][0] */ 0.238509, /* emi[3][1] */ -0.435614, /* emi[3][2] */ 0.99990432, /* emi[3][3] */ 0.01118145, /* emi[3][4] */ 0.00485852 }, /* emi[3][5] */ { -0.238560, /* emi[4][0] */ -0.002667, /* emi[4][1] */ 0.012254, /* emi[4][2] */ -0.01118145, /* emi[4][3] */ 0.99991613, /* emi[4][4] */ -0.00002717 }, /* emi[4][5] */ { 0.435730, /* emi[5][0] */ -0.008541, /* emi[5][1] */ 0.002117, /* emi[5][2] */ -0.00485852, /* emi[5][3] */ -0.00002716, /* emi[5][4] */ 0.99996684 } /* emi[5][5] */ }; void fk524 (ra,dec) double *ra; /* Right ascension in degrees (J2000 in, B1950 out) */ double *dec; /* Declination in degrees (J2000 in, B1950 out) */ { double rapm; /* Proper motion in right ascension */ double decpm; /* Proper motion in declination */ /* In: deg/jul.yr. Out: deg/trop.yr. */ rapm = (double) 0.0; decpm = (double) 0.0; fk524m (ra, dec, &rapm, &decpm); return; } void fk524e (ra, dec, epoch) double *ra; /* Right ascension in degrees (J2000 in, B1950 out) */ double *dec; /* Declination in degrees (J2000 in, B1950 out) */ double epoch; /* Besselian epoch in years */ { double rapm; /* Proper motion in right ascension */ double decpm; /* Proper motion in declination */ /* In: deg/jul.yr. Out: deg/trop.yr. */ rapm = (double) 0.0; decpm = (double) 0.0; fk524m (ra, dec, &rapm, &decpm); *ra = *ra + (rapm * (epoch - 1950.0)); *dec = *dec + (decpm * (epoch - 1950.0)); return; } void fk524m (ra,dec,rapm,decpm) double *ra; /* Right ascension in degrees (J2000 in, B1950 out) */ double *dec; /* Declination in degrees (J2000 in, B1950 out) */ double *rapm; /* Proper motion in right ascension */ double *decpm; /* Proper motion in declination */ /* In: ra/dec deg/jul.yr. Out: ra/dec deg/trop.yr. */ { double parallax = 0.0; double rv = 0.0; fk524pv (ra, dec, rapm, decpm, ¶llax, &rv); return; } void fk524pv (ra,dec,rapm,decpm, parallax, rv) double *ra; /* Right ascension in degrees (J2000 in, B1950 out) */ double *dec; /* Declination in degrees (J2000 in, B1950 out) */ double *rapm; /* Proper motion in right ascension */ double *decpm; /* Proper motion in declination * In: ra/dec degrees/Julian year (not ra*cos(dec)) * Out: ra/dec degrees/tropical year */ double *parallax; /* Parallax (arcsec) */ double *rv; /* Rradial velocity (km/s, +ve = moving away) */ /* This routine converts stars from the IAU 1976 FK5 Fricke system, to the old Bessel-Newcomb FK4 system, using Yallop's implementation (see ref 2) of a matrix method due to Standish (see ref 3). The numerical values of ref 2 are used canonically. * Conversion from other than Julian epoch 2000.0 to other than Besselian epoch 1950.0 will require use of the appropriate precession, proper motion, and e-terms routines before and/or after fk524 is called. * In the FK4 catalogue the proper motions of stars within 10 degrees of the poles do not embody the differential e-term effect and should, strictly speaking, be handled in a different manner from stars outside these regions. however, given the general lack of homogeneity of the star data available for routine astrometry, the difficulties of handling positions that may have been determined from astrometric fields spanning the polar and non-polar regions, the likelihood that the differential e-terms effect was not taken into account when allowing for proper motion in past astrometry, and the undesirability of a discontinuity in the algorithm, the decision has been made in this routine to include the effect of differential e-terms on the proper motions for all stars, whether polar or not, at epoch 2000, and measuring on the sky rather than in terms of dra, the errors resulting from this simplification are less than 1 milliarcsecond in position and 1 milliarcsecond per century in proper motion. References: 1 "Mean and apparent place computations in the new IAU System. I. The transformation of astrometric catalog systems to the equinox J2000.0." Smith, C.A.; Kaplan, G.H.; Hughes, J.A.; Seidelmann, P.K.; Yallop, B.D.; Hohenkerk, C.Y. Astronomical Journal vol. 97, Jan. 1989, p. 265-273. 2 "Mean and apparent place computations in the new IAU System. II. Transformation of mean star places from FK4 B1950.0 to FK5 J2000.0 using matrices in 6-space." Yallop, B.D.; Hohenkerk, C.Y.; Smith, C.A.; Kaplan, G.H.; Hughes, J.A.; Seidelmann, P.K.; Astronomical Journal vol. 97, Jan. 1989, p. 274-279. 3 Seidelmann, P.K. (ed), 1992. "Explanatory Supplement to the Astronomical Almanac", ISBN 0-935702-68-7. 4 "Conversion of positions and proper motions from B1950.0 to the IAU system at J2000.0", Standish, E.M. Astronomy and Astrophysics, vol. 115, no. 1, Nov. 1982, p. 20-22. P.T.Wallace Starlink 19 December 1993 Doug Mink Smithsonian Astrophysical Observatory 1 November 2000 */ { double r2000,d2000; /* J2000.0 ra,dec (radians) */ double r1950,d1950; /* B1950.0 ra,dec (rad) */ /* Miscellaneous */ double ur,ud; double sr, cr, sd, cd, x, y, z, w, wd; double v1[6],v2[6]; double xd,yd,zd; double rxyz, rxysq, rxy; double dra,ddec; int i,j; int diag = 0; /* Constants */ double zero = (double) 0.0; double vf = 21.095; /* Km per sec to AU per tropical century */ /* = 86400 * 36524.2198782 / 149597870 */ /* Convert J2000 RA and Dec from degrees to radians */ r2000 = degrad (*ra); d2000 = degrad (*dec); /* Convert J2000 RA and Dec proper motion from degrees/year to arcsec/tc */ ur = *rapm * 360000.0; ud = *decpm * 360000.0; /* Spherical to Cartesian */ sr = sin (r2000); cr = cos (r2000); sd = sin (d2000); cd = cos (d2000); x = cr * cd; y = sr * cd; z = sd; v1[0] = x; v1[1] = y; v1[2] = z; if (ur != zero || ud != zero) { v1[3] = -(ur*y) - (cr*sd*ud); v1[4] = (ur*x) - (sr*sd*ud); v1[5] = (cd*ud); } else { v1[3] = zero; v1[4] = zero; v1[5] = zero; } /* Convert position + velocity vector to bn system */ for (i = 0; i < 6; i++) { w = zero; for (j = 0; j < 6; j++) { w = w + emi[i][j] * v1[j]; } v2[i] = w; } /* Vector components */ x = v2[0]; y = v2[1]; z = v2[2]; rxyz = sqrt (x*x + y*y + z*z); /* Magnitude of position vector */ rxyz = sqrt (x*x + y*y + z*z); /* Apply e-terms to position */ w = (x * a[0]) + (y * a[1]) + (z * a[2]); x = x + (a[0] * rxyz) - (w * x); y = y + (a[1] * rxyz) - (w * z); z = z + (a[2] * rxyz) - (w * z); /* Recompute magnitude of position vector */ rxyz = sqrt (x*x + y*y + z*z); /* Apply e-terms to position and velocity */ x = v2[0]; y = v2[1]; z = v2[2]; w = (x * a[0]) + (y * a[1]) + (z * a[2]); wd = (x * ad[0]) + (y * ad[1]) + (z * ad[2]); x = x + (a[0] * rxyz) - (w * x); y = y + (a[1] * rxyz) - (w * y); z = z + (a[2] * rxyz) - (w * z); xd = v2[3] + (ad[0] * rxyz) - (wd * x); yd = v2[4] + (ad[1] * rxyz) - (wd * y); zd = v2[5] + (ad[2] * rxyz) - (wd * z); /* Convert to spherical */ rxysq = (x * x) + (y * y); rxy = sqrt (rxysq); /* Convert back to spherical coordinates */ if (x == zero && y == zero) r1950 = zero; else { r1950 = atan2 (y,x); if (r1950 < zero) r1950 = r1950 + d2pi; } d1950 = atan2 (z,rxy); if (rxy > tiny) { ur = (x*yd - y*xd) / rxysq; ud = (zd*rxysq - z * (x*xd + y*yd)) / ((rxysq + z*z) * rxy); } if (*parallax > tiny) { *rv = ((x * xd) + (y * yd) + (z * zd)) / (*parallax * vf * rxyz); *parallax = *parallax / rxyz; } /* Return results */ *ra = raddeg (r1950); *dec = raddeg (d1950); *rapm = ur / 360000.0; *decpm = ud / 360000.0; if (diag) { dra = 240.0 * raddeg (r1950 - r2000); ddec = 3600.0 * raddeg (d1950 - d2000); fprintf(stderr,"B1950-J2000: dra= %11.5f sec ddec= %f11.5f arcsec\n", dra, ddec); } return; } /* Convert B1950.0 FK4 star data to J2000.0 FK5 */ static double em[6][6] = { { 0.9999256782, /* em[0][0] */ -0.0111820611, /* em[0][1] */ -0.0048579477, /* em[0][2] */ 0.00000242395018, /* em[0][3] */ -0.00000002710663, /* em[0][4] */ -0.00000001177656 }, /* em[0][5] */ { 0.0111820610, /* em[1][0] */ 0.9999374784, /* em[1][1] */ -0.0000271765, /* em[1][2] */ 0.00000002710663, /* em[1][3] */ 0.00000242397878, /* em[1][4] */ -0.00000000006587 }, /* em[1][5] */ { 0.0048579479, /* em[2][0] */ -0.0000271474, /* em[2][1] */ 0.9999881997, /* em[2][2] */ 0.00000001177656, /* em[2][3] */ -0.00000000006582, /* em[2][4] */ 0.00000242410173 }, /* em[2][5] */ { -0.000551, /* em[3][0] */ -0.238565, /* em[3][1] */ 0.435739, /* em[3][2] */ 0.99994704, /* em[3][3] */ -0.01118251, /* em[3][4] */ -0.00485767 }, /* em[3][5] */ { 0.238514, /* em[4][0] */ -0.002667, /* em[4][1] */ -0.008541, /* em[4][2] */ 0.01118251, /* em[4][3] */ 0.99995883, /* em[4][4] */ -0.00002718 }, /* em[4][5] */ { -0.435623, /* em[5][0] */ 0.012254, /* em[5][1] */ 0.002117, /* em[5][2] */ 0.00485767, /* em[5][3] */ -0.00002714, /* em[5][4] */ 1.00000956 } /* em[5][5] */ }; void fk425 (ra, dec) double *ra; /* Right ascension in degrees (B1950 in, J2000 out) */ double *dec; /* Declination in degrees (B1950 in, J2000 out) */ { double rapm; /* Proper motion in right ascension */ double decpm; /* Proper motion in declination */ /* In: rad/trop.yr. Out: rad/jul.yr. */ rapm = (double) 0.0; decpm = (double) 0.0; fk425m (ra, dec, &rapm, &decpm); return; } void fk425e (ra, dec, epoch) double *ra; /* Right ascension in degrees (B1950 in, J2000 out) */ double *dec; /* Declination in degrees (B1950 in, J2000 out) */ double epoch; /* Besselian epoch in years */ { double rapm; /* Proper motion in right ascension */ double decpm; /* Proper motion in declination */ /* In: rad/trop.yr. Out: rad/jul.yr. */ rapm = (double) 0.0; decpm = (double) 0.0; fk425m (ra, dec, &rapm, &decpm); *ra = *ra + (rapm * (epoch - 2000.0)); *dec = *dec + (decpm * (epoch - 2000.0)); return; } void fk425m (ra, dec, rapm, decpm) double *ra, *dec; /* Right ascension and declination in degrees input: B1950.0,FK4 returned: J2000.0,FK5 */ double *rapm, *decpm; /* Proper motion in right ascension and declination input: B1950.0,FK4 returned: J2000.0,FK5 ra/dec deg/trop.yr. ra/dec deg/jul.yr. */ { double parallax = 0.0; double rv = 0.0; fk425pv (ra, dec, rapm, decpm, ¶llax, &rv); return; } void fk425pv (ra,dec,rapm,decpm, parallax, rv) double *ra; /* Right ascension in degrees (J2000 in, B1950 out) */ double *dec; /* Declination in degrees (J2000 in, B1950 out) */ double *rapm; /* Proper motion in right ascension */ double *decpm; /* Proper motion in declination * In: ra/dec degrees/Julian year (not ra*cos(dec)) * Out: ra/dec degrees/tropical year */ double *parallax; /* Parallax (arcsec) */ double *rv; /* Rradial velocity (km/s, +ve = moving away) */ /* This routine converts stars from the old Bessel-Newcomb FK4 system to the IAU 1976 FK5 Fricke system, using Yallop's implementation (see ref 2) of a matrix method due to Standish (see ref 3). The numerical values of ref 2 are used canonically. * Conversion from other than Besselian epoch 1950.0 to other than Julian epoch 2000.0 will require use of the appropriate precession, proper motion, and e-terms routines before and/or after fk425 is called. * In the FK4 catalogue the proper motions of stars within 10 degrees of the poles do not embody the differential e-term effect and should, strictly speaking, be handled in a different manner from stars outside these regions. however, given the general lack of homogeneity of the star data available for routine astrometry, the difficulties of handling positions that may have been determined from astrometric fields spanning the polar and non-polar regions, the likelihood that the differential e-terms effect was not taken into account when allowing for proper motion in past astrometry, and the undesirability of a discontinuity in the algorithm, the decision has been made in this routine to include the effect of differential e-terms on the proper motions for all stars, whether polar or not, at epoch 2000, and measuring on the sky rather than in terms of dra, the errors resulting from this simplification are less than 1 milliarcsecond in position and 1 milliarcsecond per century in proper motion. References: 1 "Mean and apparent place computations in the new IAU System. I. The transformation of astrometric catalog systems to the equinox J2000.0." Smith, C.A.; Kaplan, G.H.; Hughes, J.A.; Seidelmann, P.K.; Yallop, B.D.; Hohenkerk, C.Y. Astronomical Journal vol. 97, Jan. 1989, p. 265-273. 2 "Mean and apparent place computations in the new IAU System. II. Transformation of mean star places from FK4 B1950.0 to FK5 J2000.0 using matrices in 6-space." Yallop, B.D.; Hohenkerk, C.Y.; Smith, C.A.; Kaplan, G.H.; Hughes, J.A.; Seidelmann, P.K.; Astronomical Journal vol. 97, Jan. 1989, p. 274-279. 3 "Conversion of positions and proper motions from B1950.0 to the IAU system at J2000.0", Standish, E.M. Astronomy and Astrophysics, vol. 115, no. 1, Nov. 1982, p. 20-22. P.T.Wallace Starlink 20 December 1993 Doug Mink Smithsonian Astrophysical Observatory 7 June 1995 */ { double r1950,d1950; /* B1950.0 ra,dec (rad) */ double r2000,d2000; /* J2000.0 ra,dec (rad) */ /* Miscellaneous */ double ur,ud,sr,cr,sd,cd,w,wd; double x,y,z,xd,yd,zd, dra,ddec; double rxyz, rxysq, rxy, rxyzsq, spxy, spxyz; int i,j; int diag = 0; double r0[3],rd0[3]; /* star position and velocity vectors */ double v1[6],v2[6]; /* combined position and velocity vectors */ /* Constants */ double zero = (double) 0.0; double vf = 21.095; /* Km per sec to AU per tropical century */ /* = 86400 * 36524.2198782 / 149597870 */ /* Convert B1950 RA and Dec from degrees to radians */ r1950 = degrad (*ra); d1950 = degrad (*dec); /* Convert B1950 RA and Dec proper motion from degrees/year to arcsec/tc */ ur = *rapm * 360000.0; ud = *decpm * 360000.0; /* Convert direction to Cartesian */ sr = sin (r1950); cr = cos (r1950); sd = sin (d1950); cd = cos (d1950); r0[0] = cr * cd; r0[1] = sr * cd; r0[2] = sd; /* Convert motion to Cartesian */ w = vf * *rv * *parallax; if (ur != zero || ud != zero || (*rv != zero && *parallax != zero)) { rd0[0] = (-sr * cd * ur) - (cr * sd * ud) + (w * r0[0]); rd0[1] = (cr * cd * ur) - (sr * sd * ud) + (w * r0[1]); rd0[2] = (cd * ud) + (w * r0[2]); } else { rd0[0] = zero; rd0[1] = zero; rd0[2] = zero; } /* Remove e-terms from position and express as position+velocity 6-vector */ w = (r0[0] * a[0]) + (r0[1] * a[1]) + (r0[2] * a[2]); for (i = 0; i < 3; i++) v1[i] = r0[i] - a[i] + (w * r0[i]); /* Remove e-terms from proper motion and express as 6-vector */ wd = (r0[0] * ad[0]) + (r0[1] * ad[1]) + (r0[2] * ad[2]); for (i = 0; i < 3; i++) v1[i+3] = rd0[i] - ad[i] + (wd * r0[i]); /* Alternately: Put proper motion in 6-vector without adding e-terms for (i = 0; i < 3; i++) v1[i+3] = rd0[i]; */ /* Convert position + velocity vector to FK5 system */ for (i = 0; i < 6; i++) { w = zero; for (j = 0; j < 6; j++) { w += em[i][j] * v1[j]; } v2[i] = w; } /* Vector components */ x = v2[0]; y = v2[1]; z = v2[2]; xd = v2[3]; yd = v2[4]; zd = v2[5]; /* Magnitude of position vector */ rxysq = x*x + y*y; rxy = sqrt (rxysq); rxyzsq = rxysq + z*z; rxyz = sqrt (rxyzsq); spxy = (x * xd) + (y * yd); spxyz = spxy + (z * zd); /* Convert back to spherical coordinates */ if (x == zero && y == zero) r2000 = zero; else { r2000 = atan2 (y,x); if (r2000 < zero) r2000 = r2000 + d2pi; } d2000 = atan2 (z,rxy); if (rxy > tiny) { ur = ((x * yd) - (y * xd)) / rxysq; ud = ((zd * rxysq) - (z * spxy)) / (rxyzsq * rxy); } if (*parallax > tiny) { *rv = spxyz / (*parallax * rxyz * vf); *parallax = *parallax / rxyz; } /* Return results */ *ra = raddeg (r2000); *dec = raddeg (d2000); *rapm = ur / 360000.0; *decpm = ud / 360000.0; if (diag) { dra = 240.0 * raddeg (r2000 - r1950); ddec = 3600.0 * raddeg (d2000 - d1950); fprintf(stderr,"J2000-B1950: dra= %11.5f sec ddec= %f11.5f arcsec\n", dra, ddec); } return; } int idg=0; /* l2,b2 system of galactic coordinates * p = 192.25 ra of galactic north pole (mean b1950.0) * q = 62.6 inclination of galactic to mean b1950.0 equator * r = 33 longitude of ascending node * p,q,r are degrees * Equatorial to galactic rotation matrix (The Eulerian angles are p, q, 90-r) +cp.cq.sr-sp.cr +sp.cq.sr+cp.cr -sq.sr -cp.cq.cr-sp.sr -sp.cq.cr+cp.sr +sq.cr cp.sq +sp.sq +cq */ static double bgal[3][3] = {{-0.066988739415,-0.872755765852,-0.483538914632}, {0.492728466075,-0.450346958020, 0.744584633283}, {-0.867600811151,-0.188374601723, 0.460199784784}}; /*--- Transform B1950.0 FK4 equatorial coordinates to * IAU 1958 galactic coordinates */ void fk42gal (dtheta,dphi) double *dtheta; /* B1950.0 FK4 right ascension in degrees Galactic longitude (l2) in degrees (returned) */ double *dphi; /* B1950.0 FK4 declination in degrees Galactic latitude (b2) in degrees (returned) */ /* Input equatorial coordinates are B1950 FK4. Use fk52gal() to convert from j2000.0 coordinates. Reference: Blaauw et al, MNRAS,121,123 (1960) */ { double pos[3],pos1[3],r,dl,db,rl,rb,rra,rdec,dra,ddec; void v2s3(),s2v3(); int i; char *eqcoor, *eqstrn(); dra = *dtheta; ddec = *dphi; rra = degrad (dra); rdec = degrad (ddec); /* remove e-terms */ /* call jpabe (rra,rdec,-1,idg) */ /* Spherical to Cartesian */ r = 1.; s2v3 (rra,rdec,r,pos); /* rotate to galactic */ for (i = 0; i<3; i++) { pos1[i] = pos[0]*bgal[i][0] + pos[1]*bgal[i][1] + pos[2]*bgal[i][2]; } /* Cartesian to spherical */ v2s3 (pos1,&rl,&rb,&r); dl = raddeg (rl); db = raddeg (rb); *dtheta = dl; *dphi = db; /* Print result if in diagnostic mode */ if (idg) { eqcoor = eqstrn (dra,ddec); fprintf (stderr,"FK42GAL: B1950 RA,Dec= %s\n",eqcoor); fprintf (stderr,"FK42GAL: long = %.5f lat = %.5f\n",dl,db); free (eqcoor); } return; } /*--- Transform IAU 1958 galactic coordinates to B1950.0 'FK4' * equatorial coordinates */ void gal2fk4 (dtheta,dphi) double *dtheta; /* Galactic longitude (l2) in degrees B1950 FK4 RA in degrees (returned) */ double *dphi; /* Galactic latitude (b2) in degrees B1950 FK4 Dec in degrees (returned) */ /* Output equatorial coordinates are B1950.0 FK4. Use gal2fk5() to convert to J2000 coordinates. Reference: Blaauw et al, MNRAS,121,123 (1960) */ { double pos[3],pos1[3],r,dl,db,rl,rb,rra,rdec,dra,ddec; void v2s3(),s2v3(); char *eqcoor, *eqstrn(); int i; /* spherical to cartesian */ dl = *dtheta; db = *dphi; rl = degrad (dl); rb = degrad (db); r = 1.0; s2v3 (rl,rb,r,pos); /* rotate to equatorial coordinates */ for (i = 0; i < 3; i++) { pos1[i] = pos[0]*bgal[0][i] + pos[1]*bgal[1][i] + pos[2]*bgal[2][i]; } /* cartesian to spherical */ v2s3 (pos1,&rra,&rdec,&r); /* introduce e-terms */ /* jpabe (rra,rdec,-1,idg); */ dra = raddeg (rra); ddec = raddeg (rdec); *dtheta = dra; *dphi = ddec; /* print result if in diagnostic mode */ if (idg) { fprintf (stderr,"GAL2FK4: long = %.5f lat = %.5f\n",dl,db); eqcoor = eqstrn (dra,ddec); fprintf (stderr,"GAL2FK4: B1950 RA,Dec= %s\n",eqcoor); free (eqcoor); } return; } /* l2,b2 system of galactic coordinates p = 192.25 ra of galactic north pole (mean b1950.0) q = 62.6 inclination of galactic to mean b1950.0 equator r = 33 longitude of ascending node p,q,r are degrees */ /* Equatorial to galactic rotation matrix The eulerian angles are p, q, 90-r +cp.cq.sr-sp.cr +sp.cq.sr+cp.cr -sq.sr -cp.cq.cr-sp.sr -sp.cq.cr+cp.sr +sq.cr +cp.sq +sp.sq +cq */ static double jgal[3][3] = {{-0.054875539726,-0.873437108010,-0.483834985808}, {0.494109453312,-0.444829589425, 0.746982251810}, {-0.867666135858,-0.198076386122, 0.455983795705}}; /* Transform J2000 equatorial coordinates to IAU 1958 galactic coordinates */ void fk52gal (dtheta,dphi) double *dtheta; /* J2000 right ascension in degrees Galactic longitude (l2) in degrees (returned) */ double *dphi; /* J2000 declination in degrees Galactic latitude (b2) in degrees (returned) */ /* Rotation matrices by P.T.Wallace, Starlink eqgal and galeq, March 1986 */ /* Input equatorial coordinates are J2000 FK5. Use gal2fk4() if converting from B1950 FK4 coordinates. Reference: Blaauw et al, MNRAS,121,123 (1960) */ { double pos[3],pos1[3],r,dl,db,rl,rb,rra,rdec,dra,ddec; void v2s3(),s2v3(); char *eqcoor, *eqstrn(); int i; /* Spherical to cartesian */ dra = *dtheta; ddec = *dphi; rra = degrad (dra); rdec = degrad (ddec); r = 1.0; (void)s2v3 (rra,rdec,r,pos); /* Rotate to galactic */ for (i = 0; i < 3; i++) { pos1[i] = pos[0]*jgal[i][0] + pos[1]*jgal[i][1] + pos[2]*jgal[i][2]; } /* Cartesian to spherical */ v2s3 (pos1,&rl,&rb,&r); dl = raddeg (rl); db = raddeg (rb); *dtheta = dl; *dphi = db; /* Print result if in diagnostic mode */ if (idg) { eqcoor = eqstrn (dra,ddec); fprintf (stderr,"FK52GAL: J2000 RA,Dec= %s\n",eqcoor); fprintf (stderr,"FK52GAL: long = %.5f lat = %.5f\n",dl,db); free (eqcoor); } return; } /*--- Transform IAU 1958 galactic coordinates to J2000 equatorial coordinates */ void gal2fk5 (dtheta,dphi) double *dtheta; /* Galactic longitude (l2) in degrees J2000.0 ra in degrees (returned) */ double *dphi; /* Galactic latitude (b2) in degrees J2000.0 dec in degrees (returned) */ /* Output equatorial coordinates are J2000. Use gal2fk4() to convert to B1950 coordinates. Reference: Blaauw et al, MNRAS,121,123 (1960) */ { double pos[3],pos1[3],r,dl,db,rl,rb,rra,rdec,dra,ddec; void v2s3(),s2v3(); int i; char *eqcoor, *eqstrn(); /* Spherical to Cartesian */ dl = *dtheta; db = *dphi; rl = degrad (dl); rb = degrad (db); r = 1.0; s2v3 (rl,rb,r,pos); /* Rotate to equatorial coordinates */ for (i = 0; i < 3; i++) { pos1[i] = pos[0]*jgal[0][i] + pos[1]*jgal[1][i] + pos[2]*jgal[2][i]; } /* Cartesian to Spherical */ v2s3 (pos1,&rra,&rdec,&r); dra = raddeg (rra); ddec = raddeg (rdec); *dtheta = dra; *dphi = ddec; /* Print result if in diagnostic mode */ if (idg) { fprintf (stderr,"GAL2FK5: long = %.5f lat = %.5f\n",dl,db); eqcoor = eqstrn (dra,ddec); fprintf (stderr,"GAL2FK5: J2000 RA,Dec= %s\n",eqcoor); free (eqcoor); } return; } /* Return string with right ascension in hours and declination in degrees */ char *eqstrn (dra, ddec) double dra; /* Right ascension in degrees */ double ddec; /* Declination in degrees */ { char *eqcoor; /* ASCII character string of position (returned) */ char decp; int rah,irm,decd,decm; double xpos,ypos,xp,yp,ras,decs; /* Right ascension to hours, minutes, and seconds */ xpos = dra / 15.0; rah = (int) xpos; xp = (double) 60.0 * (xpos - (double) rah); irm = (int) xp; ras = (double) 60.0 * (xp - (double) irm); /* Declination to degrees, minutes, seconds */ if (ddec < 0) { ypos = -ddec; decp = '-'; } else { decp = '+'; ypos = ddec; } decd = (int) ypos; yp = (double) 60.0 * (ypos - (double) decd); decm = (int) yp; decs = (double) 60.0 * (yp - (double) decm); eqcoor = malloc (32); (void)sprintf (eqcoor,"%02d:%02d:%06.3f %c%02d:%02d:%05.2f", rah,irm,ras,decp,decd,decm,decs); if (eqcoor[6] == ' ') eqcoor[6] = '0'; if (eqcoor[20] == ' ') eqcoor[20] = '0'; return (eqcoor); } /* Convert geocentric equatorial rectangular coordinates to right ascension and declination, and distance */ /* These routines are based on similar ones in Pat Wallace's slalib package */ /* Convert B1950 right ascension and declination to ecliptic coordinates */ void fk42ecl (dtheta, dphi, epoch) double *dtheta; /* B1950 right ascension in degrees Galactic longitude (l2) in degrees (returned) */ double *dphi; /* B1950 declination in degrees Galactic latitude (b2) in degrees (returned) */ double epoch; /* Besselian epoch in years */ { void fk425e(), fk52ecl(); /* Convert from B1950 to J2000 coordinates */ fk425e (dtheta, dphi, epoch); /* Convert from J2000 to ecliptic coordinates */ fk52ecl (dtheta, dphi, epoch); return; } /* Convert J2000 right ascension and declination to ecliptic coordinates */ void fk52ecl (dtheta, dphi, epoch) double *dtheta; /* J2000 right ascension in degrees Galactic longitude (l2) in degrees (returned) */ double *dphi; /* J2000 declination in degrees Galactic latitude (b2) in degrees (returned) */ double epoch; /* Besselian epoch in years */ { int i, j; double t, eps0, rphi, rtheta; double v1[3], v2[3], r; double rmat[9], *rmati; /* Rotation matrix */ void rotmat(), v2s3(), s2v3(), fk5prec(); /* Precess coordinates from J2000 to epoch */ if (epoch != 2000.0) fk5prec (2000.0, epoch, dtheta, dphi); /* Convert from degrees to radians */ rtheta = degrad (*dtheta); rphi = degrad (*dphi); /* Convert RA,Dec to x,y,z */ r = 1.0; s2v3 (rtheta, rphi, r, v1); /* Interval between basic epoch J2000.0 and current epoch (JC) in centuries*/ t = (epoch - 2000.0) * 0.01; /* Mean obliquity */ eps0 = secrad ((84381.448 + (-46.8150 + (-0.00059 + 0.001813*t) * t) * t)); /* Form the equatorial to ecliptic rotation matrix (IAU 1980 theory). * References: Murray, C.A., Vectorial Astrometry, section 4.3. * The matrix is in the sense v[ecl] = rmat * v[equ]; the * equator, equinox and ecliptic are mean of date. */ rotmat (1, eps0, 0.0, 0.0, rmat); /* Multiply position vector by equatoria to eccliptic rotation matrix */ rmati = rmat; for (i = 0; i < 3; i++) { v2[i] = 0; for (j = 0; j < 3; j++) v2[i] = v2[i] + (*rmati++ * v1[j]); } /* Convert x,y,z to latitude, longitude */ v2s3 (v2, &rtheta, &rphi, &r); /* Convert from radians to degrees */ *dtheta = raddeg (rtheta); *dphi = raddeg (rphi); } /* Convert ecliptic coordinates to B1950 right ascension and declination */ void ecl2fk4 (dtheta, dphi, epoch) double *dtheta; /* Galactic longitude (l2) in degrees B1950 right ascension in degrees (returned) */ double *dphi; /* Galactic latitude (b2) in degrees B1950 declination in degrees (returned) */ double epoch; /* Besselian epoch in years */ { void ecl2fk5(), fk524e(); /* Convert from ecliptic to J2000 coordinates */ ecl2fk5 (dtheta, dphi, epoch); /* Convert from J2000 to B1950 coordinates */ fk524e (dtheta, dphi, epoch); return; } /* Convert ecliptic coordinates to J2000 right ascension and declination */ void ecl2fk5 (dtheta, dphi, epoch) double *dtheta; /* Galactic longitude (l2) in degrees J2000 right ascension in degrees (returned) */ double *dphi; /* Galactic latitude (b2) in degrees J2000 declination in degrees (returned) */ double epoch; /* Besselian epoch in years */ { int i, j; double rtheta, rphi, v1[3], v2[3]; double t, eps0, r; double rmat[9]; /* Rotation matrix */ void v2s3(),s2v3(), fk5prec(), rotmat(); rtheta = degrad (*dtheta); rphi = degrad (*dphi); /* Convert RA,Dec to x,y,z */ r = 1.0; s2v3 (rtheta, rphi, r, v1); /* Interval between basic epoch J2000.0 and current epoch (JC) in centuries*/ t = (epoch - 2000.0) * 0.01; /* Mean obliquity */ eps0 = secrad ((84381.448 + (-46.8150 + (-0.00059 + 0.001813*t) * t) * t)); /* Form the equatorial to ecliptic rotation matrix (IAU 1980 theory). * References: Murray, C.A., Vectorial Astrometry, section 4.3. * The matrix is in the sense v[ecl] = rmat * v[equ]; the * equator, equinox and ecliptic are mean of date. */ rotmat (1, eps0, 0.0, 0.0, rmat); /* Multiply position vector by ecliptic to equatorial rotation matrix */ for (i = 0; i < 3; i++) { v2[i] = 0; for (j = 0; j < 3; j++) v2[i] = v2[i] + (rmat[3*j + i] * v1[j]); } /* Cartesian to spherical */ v2s3 (v2, &rtheta, &rphi, &r); /* Convert from radians to degrees */ *dtheta = raddeg (rtheta); *dphi = raddeg (rphi); if (epoch != 2000.0) fk5prec (epoch, 2000.0, dtheta, dphi); } /* The following routines are modified from Patrick Wallace's SLALIB */ /* Precess coordinates between epochs in FK4 */ void fk4prec (ep0, ep1, ra, dec) double ep0; /* Starting Besselian epoch */ double ep1; /* Ending Besselian epoch */ double *ra; /* RA in degrees mean equator & equinox of epoch ep0 mean equator & equinox of epoch ep1 (returned) */ double *dec; /* Dec in degrees mean equator & equinox of epoch ep0 mean equator & equinox of epoch ep1 (returned) */ /* ** Precession - FK4 (Bessel-Newcomb, pre-IAU1976) ** ** This routine will not correctly convert between FK4 and FK5 ** For output in FK5, precess to 1950.0 and use fk425() on result. ** ** Based on slaPreces(), P.T.Wallace Starlink 22 December 1993 */ { int i, j; double pm[9], *pmi, v1[3], v2[3], rra, rdec, r; void v2s3(),s2v3(), mprecfk4(); rra = degrad (*ra); rdec = degrad (*dec); r = 1.0; /* Generate appropriate precession matrix */ mprecfk4 ( ep0, ep1, pm ); /* Convert RA,Dec to x,y,z */ s2v3 (rra, rdec, r, v1); /* Multiply position vector by precession matrix */ pmi = pm; for (i = 0; i < 3; i++) { v2[i] = 0; for (j = 0; j < 3; j++) v2[i] = v2[i] + (*pmi++ * v1[j]); } /* Back to RA,Dec */ v2s3 (v2, &rra, &rdec, &r); /* Convert from radians to degrees */ *ra = raddeg (rra); *dec = raddeg (rdec); } void fk5prec (ep0, ep1, ra, dec) double ep0; /* Starting epoch */ double ep1; /* Ending epoch */ double *ra; /* RA in degrees mean equator & equinox of epoch ep0 mean equator & equinox of epoch ep1 (returned) */ double *dec; /* Dec in degrees mean equator & equinox of epoch ep0 mean equator & equinox of epoch ep1 (returned) */ /* ** Precession - FK5 (Fricke, post-IAU1976) ** ** This routine will not correctly convert between FK5 and FK4. ** For output in FK4, precess to 2000.0 and use fk524() on result. ** ** Based on slaPreces(), P.T.Wallace Starlink 22 December 1993 */ { int i, j; double pm[9], *pmi, v1[3], v2[3], rra, rdec, r; void v2s3(),s2v3(), mprecfk5(); rra = degrad (*ra); rdec = degrad (*dec); r = 1.0; /* Generate appropriate precession matrix */ mprecfk5 (ep0, ep1, pm); /* Convert RA,Dec to x,y,z */ s2v3 (rra, rdec, r, v1); /* Multiply position vector by precession matrix */ pmi = pm; for (i = 0; i < 3; i++) { v2[i] = 0; for (j = 0; j < 3; j++) v2[i] = v2[i] + ( v1[j] * *pmi++ ); } /* Back to RA,Dec */ v2s3 (v2, &rra, &rdec, &r); /* Convert from radians to degrees */ *ra = raddeg (rra); *dec = raddeg (rdec); return; } void mprecfk4 (bep0, bep1, rmatp) double bep0; /* Beginning Besselian epoch */ double bep1; /* Ending Besselian epoch */ double rmatp[9]; /* 3x3 Precession matrix (returned) */ /* ** Generate the matrix of precession between two epochs, ** using the old, pre-IAU1976, Bessel-Newcomb model, using ** Kinoshita's formulation (double precision) ** ** The matrix is in the sense v(bep1) = rmatp * v(bep0) ** ** Reference: ** Kinoshita, H. (1975) 'Formulas for precession', SAO Special ** Report No. 364, Smithsonian Institution Astrophysical ** Observatory, Cambridge, Massachusetts. ** ** Based on slaPrebn() by P.T.Wallace Starlink 30 October 1993 */ { double bigt, t, tas2r, w, zeta, z, theta; void rotmat(); /* Interval between basic epoch B1850.0 and beginning epoch in TC */ bigt = ( bep0 - 1850.0 ) / 100.0; /* Interval over which precession required, in tropical centuries */ t = ( bep1 - bep0 ) / 100.0; /* Euler angles */ tas2r = secrad (t); w = 2303.5548 + ( 1.39720 + 0.000059 * bigt ) * bigt; zeta = (w + ( 0.30242 - 0.000269 * bigt + 0.017996 * t ) * t ) * tas2r; z = (w + ( 1.09478 + 0.000387 * bigt + 0.018324 * t ) * t ) * tas2r; theta = ( 2005.1125 + ( - 0.85294 - 0.000365* bigt ) * bigt + ( - 0.42647 - 0.000365 * bigt - 0.041802 * t ) * t ) * tas2r; /* Rotation matrix */ rotmat (323, -zeta, theta, -z, rmatp); return; } void mprecfk5 (ep0, ep1, rmatp) double ep0; /* Beginning epoch */ double ep1; /* Ending epoch */ double rmatp[9]; /* 3x3 Precession matrix (returned) */ /* ** Form the matrix of precession between two epochs (IAU 1976, FK5). ** Notes: ** 1) The epochs are TDB (loosely ET) Julian epochs. ** 2) The matrix is in the sense v(ep1) = rmatp * v(ep0) . ** ** References: ** Lieske,J.H., 1979. Astron. Astrophys.,73,282. ** equations (6) & (7), p283. ** Kaplan,G.H., 1981. USNO circular no. 163, pa2. ** ** Based on slaPrec(), P.T.Wallace Starlink 31 October 1993 */ { double t0, t, tas2r, w, zeta, z, theta; void rotmat(); /* Interval between basic epoch J2000.0 and beginning epoch (JC) */ t0 = ( ep0 - 2000.0 ) / 100.0; /* Interval over which precession required (JC) */ t = ( ep1 - ep0 ) / 100.0; /* Euler angles */ tas2r = secrad (t); w = 2306.2181 + ( ( 1.39656 - ( 0.000139 * t0 ) ) * t0 ); zeta = (w + ( ( 0.30188 - 0.000344 * t0 ) + 0.017998 * t ) * t ) * tas2r; z = (w + ( ( 1.09468 + 0.000066 * t0 ) + 0.018203 * t ) * t ) * tas2r; theta = ( ( 2004.3109 + ( - 0.85330 - 0.000217 * t0 ) * t0 ) + ( ( -0.42665 - 0.000217 * t0 ) - 0.041833 * t ) * t ) * tas2r; /* Rotation matrix */ rotmat (323, -zeta, theta, -z, rmatp); return; } /* Make 3-D rotation matrix from up to three rotations */ void rotmat (axes, rot1, rot2, rot3, matrix) int axes; /* Axes about which coordinates are rotated (1=x, 2=y, 3=z) */ double rot1; /* First rotation in degrees */ double rot2; /* Second rotation in degrees */ double rot3; /* Third rotation in degrees */ double *matrix; /* 3x3 rotation matrix (returned) */ { int i, j, k, naxis, iaxes, iaxis; double rot[3], srot, crot, *mati, w, wm[9], *wmi, matn[9]; int axis[3]; /* Initial final rotation matrix */ mati = matrix; for (i = 0; i < 3; i++) { for (j=0; j < 3; j++) { if (i == j) *mati++ = 1.0; else *mati++ = 0.0; } } /* Separate digits of rotation axis string and count rotations */ naxis = 0; iaxes = axes; axis[0] = iaxes / 100; if (axis[0] > 0) { naxis++; iaxes = iaxes - (100 * axis[0]); } axis[naxis] = iaxes / 10; if (axis[naxis] > 0) { iaxes = iaxes - (10 * axis[naxis]); naxis++; } axis[naxis] = iaxes; if (axis[naxis] > 0) naxis++; /* Set up rotation angles */ rot[0] = rot1; rot[1] = rot2; rot[2] = rot3; /* For each digit of axis string, set up matrix */ for (iaxis = 0; iaxis < naxis; iaxis++) { /* Initialize current rotation matrix */ mati = matn; for (i = 0; i < 3; i++) { for (j=0; j < 3; j++) { if (i == j) *mati++ = 1.0; else *mati++ = 0.0; } } srot = sin (rot[iaxis]); crot = cos (rot[iaxis]); /* Matrix for rotation in X */ if (axis[iaxis] == 1) { matn[4] = crot; matn[5] = srot; matn[7] = -srot; matn[8] = crot; } /* Matrix for rotation in Y */ else if (axis[iaxis] == 2) { matn[0] = crot; matn[2] = -srot; matn[6] = srot; matn[8] = crot; } /* Matrix for rotation in Z */ else { matn[0] = crot; matn[1] = srot; matn[3] = -srot; matn[4] = crot; } /* Multiply existing rotation matrix by new rotation matrix */ for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { w = 0.0; for (k = 0; k < 3; k++) w+= matn[3*i + k] * matrix[3*k + j]; wm[3*i + j] = w; } } /* Update output matrix */ mati = matrix; wmi = wm; for (i = 0; i < 9; i++) { *mati++ = *wmi++; } } return; } /* The following routines are from Doug Mink's Fortran ephemeris library */ /* Convert right ascensiona and declination in degrees and distance to geocentric equatorial rectangular coordinates */ void d2v3 (rra,rdec,r,pos) double rra; /* Right ascension in degrees */ double rdec; /* Declination in degrees */ double r; /* Distance to object in same units as pos */ double pos[3]; /* x,y,z geocentric equatorial position of object (returned) */ { s2v3 (degrad (rra), degrad (rdec), r, pos); return; } /* Convert right ascension, declination, and distance to geocentric equatorial rectangular coordinates */ void s2v3 (rra,rdec,r,pos) double rra; /* Right ascension in radians */ double rdec; /* Declination in radians */ double r; /* Distance to object in same units as pos */ double pos[3]; /* x,y,z geocentric equatorial position of object (returned) */ { pos[0] = r * cos (rra) * cos (rdec); pos[1] = r * sin (rra) * cos (rdec); pos[2] = r * sin (rdec); return; } /* Convert geocentric equatorial rectangular coordinates to right ascension and declination in degrees and distance */ void v2d3 (pos,rra,rdec,r) double pos[3]; /* x,y,z geocentric equatorial position of object */ double *rra; /* Right ascension in degrees (returned) */ double *rdec; /* Declination in degrees (returned) */ double *r; /* Distance to object in same units as pos (returned) */ { v2s3 (pos, rra, rdec, r); *rra = raddeg (*rra); *rdec = raddeg (*rdec); return; } /* Convert geocentric equatorial rectangular coordinates to right ascension, declination, and distance */ void v2s3 (pos,rra,rdec,r) double pos[3]; /* x,y,z geocentric equatorial position of object */ double *rra; /* Right ascension in radians (returned) */ double *rdec; /* Declination in radians (returned) */ double *r; /* Distance to object in same units as pos (returned) */ { double x,y,z,rxy,rxy2,z2; x = pos[0]; y = pos[1]; z = pos[2]; *rra = atan2 (y, x); /* Keep RA within 0 to 2pi range */ if (*rra < 0.0) *rra = *rra + (2.0 * PI); if (*rra > 2.0 * PI) *rra = *rra - (2.0 * PI); rxy2 = x*x + y*y; rxy = sqrt (rxy2); *rdec = atan2 (z, rxy); z2 = z * z; *r = sqrt (rxy2 + z2); return; } /* * Nov 6 1995 Include stdlib.h instead of malloc.h * Apr 1 1996 Add arbitrary epoch precession * Apr 26 1996 Add FK4 <-> FK5 subroutines for use when epoch is known * Aug 6 1996 Clean up after lint * Nov 4 1996 Break SLA subroutines into separate file slasubs.c * Dec 9 1996 Change arguments to degrees in FK4 and FK5 precession programs * Dec 10 1996 All subroutine arguments are degrees except vector conversions * * Mar 20 1997 Drop unused variables after lint * * Apr 14 1998 Add ecliptic coordinate conversions and general conversion routines * Apr 23 1998 Add LINEAR coordinate system * Apr 28 1998 Change coordinate system flags to WCS_* * Apr 28 1998 Return -1 from wcscsys if not a legal coordinate system * May 7 1998 Keep theta within 0 to 2pi in ecl2fk5() * May 13 1998 Add wcsceq() * May 13 1998 Add equinox arguments to wcscon() * Jun 24 1998 Set J2000 from ICRS in wcscsys() * Jul 9 1998 Include stdio.h for fprintf() and sprintf() declarations * Sep 17 1998 Add wcscstr() to get coordinate string * Sep 21 1998 Fix bug in wcscstr() which returned B2000 instead of J2000 * Sep 21 1998 Add subroutine to convert proper motions, too. * Oct 21 1998 In wcscstr(), drop .00 from returned string * Nov 18 1998 Rename jpcop() v2s3() and jpcon() s2v3() (spherical to vector) * Dec 2 1998 Add PLANET coordinate system to wcscsys() and wcscstr() * * Mar 10 2000 Precess coordinates correctly from other than 1950.0 and 2000.0 * Mar 10 2000 Set coordinate system to J2000 or B1950 if string is numeric * Mar 14 2000 Clean up code in fk524m() and fk425m() * May 31 2000 Add proper motion correctly if proper motion precessed * Jun 26 2000 Add some support for WCS_XY image coordinates * Sep 14 2000 Return -1 from wcscsys if equinox is less than 1900.0 * Oct 31 2000 Add proper motion after fk425 or fk524 from system epoch * Oct 31 2000 Fix proper motion units in fk524p() and fk425p() * Nov 6 2000 Update fk425 and fk524 algorithms to include parallax and rv * * Jan 11 2001 Print all messages to stderr * Mar 21 2001 Move braces around bgal[] and jgal[] matrix initialization * * Feb 13 2002 Fix precession units problem in ecl2fk5() and fk52ecl() * * Apr 13 2005 Replace all sla_lib calls with local code * Nov 1 2005 Add WCS_ICRS, and unprecessable system * * Jan 5 2006 Fix bugs in precession subroutines mprecxxx() * May 3 2006 Drop declarations of unused variables suggested by Robert Lupton * Oct 6 2006 If pixel coordinates, set system to WCS_XY in wcscsys() * Oct 30 2006 Add LINEAR and ICRS to wcscstr() returns * * Aug 15 2007 Clean up code in rotmat() */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/wcsinit.c000066400000000000000000001221771215713201500221110ustar00rootroot00000000000000/*** File libwcs/wcsinit.c *** April 27, 2007 *** By Doug Mink, dmink@cfa.harvard.edu *** Harvard-Smithsonian Center for Astrophysics *** Copyright (C) 1998-2007 *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Correspondence concerning WCSTools should be addressed as follows: Internet email: dmink@cfa.harvard.edu Postal address: Doug Mink Smithsonian Astrophysical Observatory 60 Garden St. Cambridge, MA 02138 USA * Module: wcsinit.c (World Coordinate Systems) * Purpose: Convert FITS WCS to pixels and vice versa: * Subroutine: wcsinit (hstring) sets a WCS structure from an image header * Subroutine: wcsninit (hstring,lh) sets a WCS structure from fixed-length header * Subroutine: wcsinitn (hstring, name) sets a WCS structure for specified WCS * Subroutine: wcsninitn (hstring,lh, name) sets a WCS structure for specified WCS * Subroutine: wcsinitc (hstring, mchar) sets a WCS structure if multiple * Subroutine: wcsninitc (hstring,lh,mchar) sets a WCS structure if multiple * Subroutine: wcschar (hstring, name) returns suffix for specifed WCS * Subroutine: wcseq (hstring, wcs) set radecsys and equinox from image header * Subroutine: wcseqm (hstring, wcs, mchar) set radecsys and equinox if multiple */ #include /* strstr, NULL */ #include /* stderr */ #include #include "wcs.h" #ifndef VMS #include #endif static void wcseq(); static void wcseqm(); static void wcsioset(); void wcsrotset(); char wcschar(); /* set up a WCS structure from a FITS image header lhstring bytes long * for a specified WCS name */ struct WorldCoor * wcsninitn (hstring, lhstring, name) const char *hstring; /* character string containing FITS header information in the format = [/ ] */ int lhstring; /* Length of FITS header in bytes */ const char *name; /* character string with identifying name of WCS */ { hlength (hstring, lhstring); return (wcsinitn (hstring, name)); } /* set up a WCS structure from a FITS image header for specified WCSNAME */ struct WorldCoor * wcsinitn (hstring, name) const char *hstring; /* character string containing FITS header information in the format = [/ ] */ const char *name; /* character string with identifying name of WCS */ { char mchar; /* Suffix character for one of multiple WCS */ mchar = wcschar (hstring, name); if (mchar == '_') { fprintf (stderr, "WCSINITN: WCS name %s not matched in FITS header\n", name); return (NULL); } return (wcsinitc (hstring, &mchar)); } /* WCSCHAR -- Find the letter for a specific WCS conversion */ char wcschar (hstring, name) const char *hstring; /* character string containing FITS header information in the format = [/ ] */ const char *name; /* Name of WCS conversion to be matched (case-independent) */ { char *upname, *uppercase(); char cwcs, charwcs; int iwcs; char keyword[12]; char *upval, value[72]; /* If no WCS character, return 0 */ if (name == NULL) return ((char) 0); /* Convert input name to upper case */ upname = uppercase (name); /* If single character name, return that character */ if (strlen (upname) == 1) return (upname[0]); /* Try to match input name to available WCSNAME names in header */ strcpy (keyword, "WCSNAME"); keyword[8] = (char) 0; charwcs = '_'; for (iwcs = 0; iwcs < 27; iwcs++) { if (iwcs > 0) cwcs = (char) (64 + iwcs); else cwcs = (char) 0; keyword[7] = cwcs; if (hgets (hstring, keyword, 72, value)) { upval = uppercase (value); if (!strcmp (upval, upname)) charwcs = cwcs; free (upval); } } free (upname); return (charwcs); } /* Make string of arbitrary case all uppercase */ char * uppercase (string) char *string; { int lstring, i; char *upstring; lstring = strlen (string); upstring = (char *) calloc (1,lstring+1); for (i = 0; i < lstring; i++) { if (string[i] > 96 && string[i] < 123) upstring[i] = string[i] - 32; else upstring[i] = string[i]; } upstring[lstring] = (char) 0; return (upstring); } /* set up a WCS structure from a FITS image header lhstring bytes long */ struct WorldCoor * wcsninit (hstring, lhstring) const char *hstring; /* character string containing FITS header information in the format = [/ ] */ int lhstring; /* Length of FITS header in bytes */ { char mchar; /* Suffix character for one of multiple WCS */ mchar = (char) 0; hlength (hstring, lhstring); return (wcsinitc (hstring, &mchar)); } /* set up a WCS structure from a FITS image header lhstring bytes long */ struct WorldCoor * wcsninitc (hstring, lhstring, mchar) const char *hstring; /* character string containing FITS header information in the format = [/ ] */ int lhstring; /* Length of FITS header in bytes */ char *mchar; /* Suffix character for one of multiple WCS */ { hlength (hstring, lhstring); if (mchar[0] == ' ') mchar[0] = (char) 0; return (wcsinitc (hstring, mchar)); } /* set up a WCS structure from a FITS image header */ struct WorldCoor * wcsinit (hstring) const char *hstring; /* character string containing FITS header information in the format = [/ ] */ { char mchar; /* Suffix character for one of multiple WCS */ mchar = (char) 0; return (wcsinitc (hstring, &mchar)); } /* set up a WCS structure from a FITS image header for specified suffix */ struct WorldCoor * wcsinitc (hstring, wchar) const char *hstring; /* character string containing FITS header information in the format = [/ ] */ char *wchar; /* Suffix character for one of multiple WCS */ { struct WorldCoor *wcs, *depwcs; char ctype1[32], ctype2[32], tstring[32]; char pvkey1[8],pvkey2[8],pvkey3[8]; char *hcoeff; /* pointer to first coeff's in header */ char decsign; double rah,ram,ras, dsign,decd,decm,decs; double dec_deg,ra_hours, secpix, ra0, ra1, dec0, dec1, cvel; double cdelt1, cdelt2, cd[4], pc[81]; char keyword[16]; int ieq, i, j, k, naxes, cd11p, cd12p, cd21p, cd22p; int ilat; /* coordinate for latitude or declination */ /* int ix1, ix2, iy1, iy2, idx1, idx2, idy1, idy2; double dxrefpix, dyrefpix; */ char temp[80]; char wcsname[64]; /* Name of WCS depended on by current WCS */ char mchar; char cspace = (char) ' '; char cnull = (char) 0; double mjd; double rot; double ut; int nax; int twod; int iszpx = 0; extern int tnxinit(); extern int platepos(); extern int dsspos(); wcs = (struct WorldCoor *) calloc (1, sizeof(struct WorldCoor)); /* Set WCS character and name in structure */ mchar = wchar[0]; if (mchar == ' ') mchar = cnull; wcs->wcschar = mchar; if (hgetsc (hstring, "WCSNAME", &mchar, 63, wcsname)) { wcs->wcsname = (char *) calloc (strlen (wcsname)+2, 1); strcpy (wcs->wcsname, wcsname); } /* Set WCSLIB flags so that structures will be reinitialized */ wcs->cel.flag = 0; wcs->lin.flag = 0; wcs->wcsl.flag = 0; wcs->wcsl.cubeface = -1; /* Initialize to no plate fit */ wcs->ncoeff1 = 0; wcs->ncoeff2 = 0; /* Initialize to no CD matrix */ cdelt1 = 0.0; cdelt2 = 0.0; cd[0] = 0.0; cd[1] = 0.0; cd[2] = 0.0; cd[3] = 0.0; pc[0] = 0.0; wcs->rotmat = 0; wcs->rot = 0.0; /* Header parameters independent of projection */ naxes = 0; hgeti4c (hstring, "WCSAXES", &mchar, &naxes); if (naxes == 0) hgeti4 (hstring, "WCSAXES", &naxes); if (naxes == 0) hgeti4 (hstring, "NAXIS", &naxes); if (naxes == 0) hgeti4 (hstring, "WCSDIM", &naxes); if (naxes < 1) { setwcserr ("WCSINIT: No WCSAXES, NAXIS, or WCSDIM keyword"); wcsfree (wcs); return (NULL); } if (naxes > 2) naxes = 2; wcs->naxis = naxes; wcs->naxes = naxes; wcs->lin.naxis = naxes; wcs->nxpix = 0; hgetr8 (hstring, "NAXIS1", &wcs->nxpix); if (wcs->nxpix < 1) { setwcserr ("WCSINIT: No NAXIS1 keyword"); wcsfree (wcs); return (NULL); } wcs->nypix = 0; hgetr8 (hstring, "NAXIS2", &wcs->nypix); /* Reset number of axes to only those with dimension greater than one */ nax = 0; for (i = 0; i < naxes; i++) { /* Check for number of pixels in axis more than one */ strcpy (keyword, "NAXIS"); sprintf (temp, "%d", i+1); strcat (keyword, temp); if (!hgeti4 (hstring, keyword, &j)) fprintf (stderr,"WCSINIT: Missing keyword %s assumed 1\n",keyword); /* Check for TAB WCS in axis */ strcpy (keyword, "CTYPE"); strcat (keyword, temp); if (hgets (hstring, keyword, 16, temp)) { if (strsrch (temp, "-TAB")) j = 0; } if (j > 1) nax = nax + 1; } naxes = nax; wcs->naxes = nax; wcs->naxis = nax; hgets (hstring, "INSTRUME", 16, wcs->instrument); hgeti4 (hstring, "DETECTOR", &wcs->detector); wcs->wcsproj = getdefwcs(); wcs->logwcs = 0; hgeti4 (hstring, "DC-FLAG", &wcs->logwcs); /* Initialize rotation matrices */ for (i = 0; i < 81; i++) wcs->pc[i] = 0.0; for (i = 0; i < 81; i++) pc[i] = 0.0; for (i = 0; i < naxes; i++) wcs->pc[(i*naxes)+i] = 1.0; for (i = 0; i < naxes; i++) pc[(i*naxes)+i] = 1.0; for (i = 0; i < 9; i++) wcs->cdelt[i] = 0.0; for (i = 0; i < naxes; i++) wcs->cdelt[i] = 1.0; /* If the current world coordinate system depends on another, set it now */ if (hgetsc (hstring, "WCSDEP",&mchar, 63, wcsname)) { if ((wcs->wcs = wcsinitn (hstring, wcsname)) == NULL) { setwcserr ("WCSINIT: depended on WCS could not be set"); wcsfree (wcs); return (NULL); } depwcs = wcs->wcs; depwcs->wcsdep = wcs; } else wcs->wcs = NULL; /* Read radial velocity from image header */ wcs->radvel = 0.0; wcs->zvel = 0.0; cvel = 299792.5; if (hgetr8c (hstring, "VSOURCE", &mchar, &wcs->radvel)) wcs->zvel = wcs->radvel / cvel; else if (hgetr8c (hstring, "ZSOURCE", &mchar, &wcs->zvel)) wcs->radvel = wcs->zvel * cvel; else if (hgetr8 (hstring, "VELOCITY", &wcs->radvel)) wcs->zvel = wcs->radvel / cvel; for (i = 0; i < 10; i++) { wcs->prj.p[i] = 0.0; } /* World coordinate system reference coordinate information */ if (hgetsc (hstring, "CTYPE1", &mchar, 16, ctype1)) { if (!strncmp (ctype1+5,"ZPX", 3)) { iszpx = 1; ctype1[7] = 'N'; /* IRAF ZPX parameters for ZPN projection */ for (i = 0; i < 10; i++) { sprintf (keyword,"projp%d",i); mgetr8 (hstring, "WAT1",keyword, &wcs->prj.p[i]); } } else iszpx = 0; /* Read second coordinate type */ strcpy (ctype2, ctype1); if (!hgetsc (hstring, "CTYPE2", &mchar, 16, ctype2)) twod = 0; else { twod = 1; if (!strncmp (ctype2+5,"ZPX", 3)) { iszpx = 1; ctype2[7] = 'N'; } } strcpy (wcs->ctype[0], ctype1); strcpy (wcs->ctype[1], ctype2); if (strsrch (ctype2, "LAT") || strsrch (ctype2, "DEC")) ilat = 2; else ilat = 1; /* Read third and fourth coordinate types, if present */ strcpy (wcs->ctype[2], ""); hgetsc (hstring, "CTYPE3", &mchar, 9, wcs->ctype[2]); strcpy (wcs->ctype[3], ""); hgetsc (hstring, "CTYPE4", &mchar, 9, wcs->ctype[3]); /* Set projection type in WCS data structure */ if (wcstype (wcs, ctype1, ctype2)) { wcsfree (wcs); return (NULL); } /* Get units, if present, for linear coordinates */ if (wcs->prjcode == WCS_LIN) { if (!hgetsc (hstring, "CUNIT1", &mchar, 16, wcs->units[0])) { if (!mgetstr (hstring, "WAT1", "units", 16, wcs->units[0])) { wcs->units[0][0] = 0; } } if (!strcmp (wcs->units[0], "pixel")) wcs->prjcode = WCS_PIX; if (twod) { if (!hgetsc (hstring, "CUNIT2", &mchar, 16, wcs->units[1])) { if (!mgetstr (hstring, "WAT2", "units", 16, wcs->units[1])) { wcs->units[1][0] = 0; } } if (!strcmp (wcs->units[0], "pixel")) wcs->prjcode = WCS_PIX; } } /* Reference pixel coordinates and WCS value */ wcs->crpix[0] = 1.0; hgetr8c (hstring, "CRPIX1", &mchar, &wcs->crpix[0]); wcs->crpix[1] = 1.0; hgetr8c (hstring, "CRPIX2", &mchar, &wcs->crpix[1]); wcs->xrefpix = wcs->crpix[0]; wcs->yrefpix = wcs->crpix[1]; wcs->crval[0] = 0.0; hgetr8c (hstring, "CRVAL1", &mchar, &wcs->crval[0]); wcs->crval[1] = 0.0; hgetr8c (hstring, "CRVAL2", &mchar, &wcs->crval[1]); if (wcs->syswcs == WCS_NPOLE) wcs->crval[1] = 90.0 - wcs->crval[1]; if (wcs->syswcs == WCS_SPA) wcs->crval[1] = wcs->crval[1] - 90.0; wcs->xref = wcs->crval[0]; wcs->yref = wcs->crval[1]; if (wcs->coorflip) { wcs->cel.ref[0] = wcs->crval[1]; wcs->cel.ref[1] = wcs->crval[0]; } else { wcs->cel.ref[0] = wcs->crval[0]; wcs->cel.ref[1] = wcs->crval[1]; } wcs->longpole = 999.0; hgetr8c (hstring, "LONPOLE", &mchar, &wcs->longpole); wcs->cel.ref[2] = wcs->longpole; wcs->latpole = 999.0; hgetr8c (hstring, "LATPOLE", &mchar, &wcs->latpole); wcs->cel.ref[3] = wcs->latpole; wcs->lin.crpix = wcs->crpix; wcs->lin.cdelt = wcs->cdelt; wcs->lin.pc = wcs->pc; /* Projection constants (this should be projection-dependent */ wcs->prj.r0 = 0.0; hgetr8c (hstring, "PROJR0", &mchar, &wcs->prj.r0); /* FITS WCS interim proposal projection constants */ for (i = 0; i < 10; i++) { sprintf (keyword,"PROJP%d",i); hgetr8c (hstring, keyword, &mchar, &wcs->prj.p[i]); } sprintf (pvkey1, "PV%d_1", ilat); sprintf (pvkey2, "PV%d_2", ilat); sprintf (pvkey3, "PV%d_3", ilat); /* FITS WCS standard projection constants (projection-dependent) */ if (wcs->prjcode == WCS_AZP || wcs->prjcode == WCS_SIN || wcs->prjcode == WCS_COP || wcs->prjcode == WCS_COE || wcs->prjcode == WCS_COD || wcs->prjcode == WCS_COO) { hgetr8c (hstring, pvkey1, &mchar, &wcs->prj.p[1]); hgetr8c (hstring, pvkey2, &mchar, &wcs->prj.p[2]); } else if (wcs->prjcode == WCS_SZP) { hgetr8c (hstring, pvkey1, &mchar, &wcs->prj.p[1]); hgetr8c (hstring, pvkey2, &mchar, &wcs->prj.p[2]); if (wcs->prj.p[3] == 0.0) wcs->prj.p[3] = 90.0; hgetr8c (hstring, pvkey3, &mchar, &wcs->prj.p[3]); } else if (wcs->prjcode == WCS_CEA) { if (wcs->prj.p[1] == 0.0) wcs->prj.p[1] = 1.0; hgetr8c (hstring, pvkey1, &mchar, &wcs->prj.p[1]); } else if (wcs->prjcode == WCS_CYP) { if (wcs->prj.p[1] == 0.0) wcs->prj.p[1] = 1.0; hgetr8c (hstring, pvkey1, &mchar, &wcs->prj.p[1]); if (wcs->prj.p[2] == 0.0) wcs->prj.p[2] = 1.0; hgetr8c (hstring, pvkey2, &mchar, &wcs->prj.p[2]); } else if (wcs->prjcode == WCS_AIR) { if (wcs->prj.p[1] == 0.0) wcs->prj.p[1] = 90.0; hgetr8c (hstring, pvkey1, &mchar, &wcs->prj.p[1]); } else if (wcs->prjcode == WCS_BON) { hgetr8c (hstring, pvkey1, &mchar, &wcs->prj.p[1]); } else if (wcs->prjcode == WCS_ZPN) { for (i = 0; i < 10; i++) { sprintf (keyword,"PV%d_%d", ilat, i); hgetr8c (hstring, keyword, &mchar, &wcs->prj.p[i]); } } /* If ZPX, read coefficients from WATi keyword */ if (iszpx) { char mkey[8]; sprintf (mkey,"WAT%d", ilat); for (i = 0; i < 10; i++) { wcs->prj.p[i] = 0.0; sprintf (keyword,"projp%d",i); mgetr8 (hstring, mkey, keyword, &wcs->prj.p[i]); } } /* Coordinate reference frame, equinox, and epoch */ if (wcs->wcsproj > 0) wcseqm (hstring, wcs, &mchar); wcsioset (wcs); /* Read distortion coefficients, if present */ distortinit (wcs, hstring); /* Use polynomial fit instead of projection, if present */ wcs->ncoeff1 = 0; wcs->ncoeff2 = 0; cd11p = hgetr8c (hstring, "CD1_1", &mchar, &cd[0]); cd12p = hgetr8c (hstring, "CD1_2", &mchar, &cd[1]); cd21p = hgetr8c (hstring, "CD2_1", &mchar, &cd[2]); cd22p = hgetr8c (hstring, "CD2_2", &mchar, &cd[3]); if (wcs->wcsproj != WCS_OLD && (hcoeff = ksearch (hstring,"CO1_1")) != NULL) { wcs->prjcode = WCS_PLT; (void)strcpy (wcs->ptype, "PLATE"); for (i = 0; i < 20; i++) { sprintf (keyword,"CO1_%d", i+1); wcs->x_coeff[i] = 0.0; if (hgetr8 (hcoeff, keyword, &wcs->x_coeff[i])) wcs->ncoeff1 = i + 1; } hcoeff = ksearch (hstring,"CO2_1"); for (i = 0; i < 20; i++) { sprintf (keyword,"CO2_%d",i+1); wcs->y_coeff[i] = 0.0; if (hgetr8 (hcoeff, keyword, &wcs->y_coeff[i])) wcs->ncoeff2 = i + 1; } /* Compute a nominal scale factor */ platepos (wcs->crpix[0], wcs->crpix[1], wcs, &ra0, &dec0); platepos (wcs->crpix[0], wcs->crpix[1]+1.0, wcs, &ra1, &dec1); wcs->yinc = dec1 - dec0; wcs->xinc = -wcs->yinc; /* Compute image rotation angle */ wcs->wcson = 1; wcsrotset (wcs); rot = degrad (wcs->rot); /* Compute scale at reference pixel */ platepos (wcs->crpix[0], wcs->crpix[1], wcs, &ra0, &dec0); platepos (wcs->crpix[0]+cos(rot), wcs->crpix[1]+sin(rot), wcs, &ra1, &dec1); wcs->cdelt[0] = -wcsdist (ra0, dec0, ra1, dec1); wcs->xinc = wcs->cdelt[0]; platepos (wcs->crpix[0]+sin(rot), wcs->crpix[1]+cos(rot), wcs, &ra1, &dec1); wcs->cdelt[1] = wcsdist (ra0, dec0, ra1, dec1); wcs->yinc = wcs->cdelt[1]; /* Set CD matrix from header */ wcs->cd[0] = cd[0]; wcs->cd[1] = cd[1]; wcs->cd[2] = cd[2]; wcs->cd[3] = cd[3]; (void) matinv (2, wcs->cd, wcs->dc); } /* Else use CD matrix, if present */ else if (cd11p || cd12p || cd21p || cd22p) { wcs->rotmat = 1; wcscdset (wcs, cd); } /* Else get scaling from CDELT1 and CDELT2 */ else if (hgetr8c (hstring, "CDELT1", &mchar, &cdelt1) != 0) { hgetr8c (hstring, "CDELT2", &mchar, &cdelt2); /* If CDELT1 or CDELT2 is 0 or missing */ if (cdelt1 == 0.0 || (wcs->nypix > 1 && cdelt2 == 0.0)) { if (ksearch (hstring,"SECPIX") != NULL || ksearch (hstring,"PIXSCALE") != NULL || ksearch (hstring,"PIXSCAL1") != NULL || ksearch (hstring,"XPIXSIZE") != NULL || ksearch (hstring,"SECPIX1") != NULL) { secpix = 0.0; hgetr8 (hstring,"SECPIX",&secpix); if (secpix == 0.0) hgetr8 (hstring,"PIXSCALE",&secpix); if (secpix == 0.0) { hgetr8 (hstring,"SECPIX1",&secpix); if (secpix != 0.0) { if (cdelt1 == 0.0) cdelt1 = -secpix / 3600.0; if (cdelt2 == 0.0) { hgetr8 (hstring,"SECPIX2",&secpix); cdelt2 = secpix / 3600.0; } } else { hgetr8 (hstring,"XPIXSIZE",&secpix); if (secpix != 0.0) { if (cdelt1 == 0.0) cdelt1 = -secpix / 3600.0; if (cdelt2 == 0.0) { hgetr8 (hstring,"YPIXSIZE",&secpix); cdelt2 = secpix / 3600.0; } } else { hgetr8 (hstring,"PIXSCAL1",&secpix); if (secpix != 0.0 && cdelt1 == 0.0) cdelt1 = -secpix / 3600.0; if (cdelt2 == 0.0) { hgetr8 (hstring,"PIXSCAL2",&secpix); cdelt2 = secpix / 3600.0; } } } } else { if (cdelt1 == 0.0) cdelt1 = -secpix / 3600.0; if (cdelt2 == 0.0) cdelt2 = secpix / 3600.0; } } } if (cdelt2 == 0.0 && wcs->nypix > 1) cdelt2 = -cdelt1; wcs->cdelt[2] = 1.0; wcs->cdelt[3] = 1.0; /* Initialize rotation matrix */ for (i = 0; i < 81; i++) { pc[i] = 0.0; wcs->pc[i] = 0.0; } for (i = 0; i < naxes; i++) pc[(i*naxes)+i] = 1.0; /* Read FITS WCS interim rotation matrix */ if (!mchar && hgetr8 (hstring,"PC001001",&pc[0]) != 0) { k = 0; for (i = 0; i < naxes; i++) { for (j = 0; j < naxes; j++) { if (i == j) pc[k] = 1.0; else pc[k] = 0.0; sprintf (keyword, "PC00%1d00%1d", i+1, j+1); hgetr8 (hstring, keyword, &pc[k++]); } } wcspcset (wcs, cdelt1, cdelt2, pc); } /* Read FITS WCS standard rotation matrix */ else if (hgetr8c (hstring, "PC1_1", &mchar, &pc[0]) != 0) { k = 0; for (i = 0; i < naxes; i++) { for (j = 0; j < naxes; j++) { if (i == j) pc[k] = 1.0; else pc[k] = 0.0; sprintf (keyword, "PC%1d_%1d", i+1, j+1); hgetr8c (hstring, keyword, &mchar, &pc[k++]); } } wcspcset (wcs, cdelt1, cdelt2, pc); } /* Otherwise, use CROTAn */ else { rot = 0.0; if (ilat == 2) hgetr8c (hstring, "CROTA2", &mchar, &rot); else hgetr8c (hstring,"CROTA1", &mchar, &rot); wcsdeltset (wcs, cdelt1, cdelt2, rot); } } /* If no scaling is present, set to 1 per pixel, no rotation */ else { wcs->xinc = 1.0; wcs->yinc = 1.0; wcs->cdelt[0] = 1.0; wcs->cdelt[1] = 1.0; wcs->rot = 0.0; wcs->rotmat = 0; setwcserr ("WCSINIT: setting CDELT to 1"); } /* Initialize TNX, defaulting to TAN if there is a problem */ if (wcs->prjcode == WCS_TNX) { if (tnxinit (hstring, wcs)) { wcs->ctype[0][6] = 'A'; wcs->ctype[0][7] = 'N'; wcs->ctype[1][6] = 'A'; wcs->ctype[1][7] = 'N'; wcs->prjcode = WCS_TAN; } } /* If linear or pixel WCS, print "degrees" */ if (!strncmp (wcs->ptype,"LINEAR",6) || !strncmp (wcs->ptype,"PIXEL",5)) { wcs->degout = -1; wcs->ndec = 5; } /* Epoch of image (from observation date, if possible) */ if (hgetr8 (hstring, "MJD-OBS", &mjd)) wcs->epoch = 1900.0 + (mjd - 15019.81352) / 365.242198781; else if (!hgetdate (hstring,"DATE-OBS",&wcs->epoch)) { if (!hgetdate (hstring,"DATE",&wcs->epoch)) { if (!hgetr8 (hstring,"EPOCH",&wcs->epoch)) wcs->epoch = wcs->equinox; } } /* Add time of day if not part of DATE-OBS string */ else { hgets (hstring,"DATE-OBS",32,tstring); if (!strchr (tstring,'T')) { if (hgetr8 (hstring, "UT",&ut)) wcs->epoch = wcs->epoch + (ut / (24.0 * 365.242198781)); else if (hgetr8 (hstring, "UTMID",&ut)) wcs->epoch = wcs->epoch + (ut / (24.0 * 365.242198781)); } } wcs->wcson = 1; } else if (mchar != cnull && mchar != cspace) { (void) sprintf (temp, "WCSINITC: No image scale for WCS %c", mchar); setwcserr (temp); wcsfree (wcs); return (NULL); } /* Plate solution coefficients */ else if (ksearch (hstring,"PLTRAH") != NULL) { wcs->prjcode = WCS_DSS; hcoeff = ksearch (hstring,"PLTRAH"); hgetr8 (hcoeff,"PLTRAH",&rah); hgetr8 (hcoeff,"PLTRAM",&ram); hgetr8 (hcoeff,"PLTRAS",&ras); ra_hours = rah + (ram / (double)60.0) + (ras / (double)3600.0); wcs->plate_ra = hrrad (ra_hours); decsign = '+'; hgets (hcoeff,"PLTDECSN", 1, &decsign); if (decsign == '-') dsign = -1.; else dsign = 1.; hgetr8 (hcoeff,"PLTDECD",&decd); hgetr8 (hcoeff,"PLTDECM",&decm); hgetr8 (hcoeff,"PLTDECS",&decs); dec_deg = dsign * (decd+(decm/(double)60.0)+(decs/(double)3600.0)); wcs->plate_dec = degrad (dec_deg); hgetr8 (hstring,"EQUINOX",&wcs->equinox); hgeti4 (hstring,"EQUINOX",&ieq); if (ieq == 1950) strcpy (wcs->radecsys,"FK4"); else strcpy (wcs->radecsys,"FK5"); wcs->epoch = wcs->equinox; hgetr8 (hstring,"EPOCH",&wcs->epoch); (void)sprintf (wcs->center,"%2.0f:%2.0f:%5.3f %c%2.0f:%2.0f:%5.3f %s", rah,ram,ras,decsign,decd,decm,decs,wcs->radecsys); hgetr8 (hstring,"PLTSCALE",&wcs->plate_scale); hgetr8 (hstring,"XPIXELSZ",&wcs->x_pixel_size); hgetr8 (hstring,"YPIXELSZ",&wcs->y_pixel_size); hgetr8 (hstring,"CNPIX1",&wcs->x_pixel_offset); hgetr8 (hstring,"CNPIX2",&wcs->y_pixel_offset); hcoeff = ksearch (hstring,"PPO1"); for (i = 0; i < 6; i++) { sprintf (keyword,"PPO%d", i+1); wcs->ppo_coeff[i] = 0.0; hgetr8 (hcoeff,keyword,&wcs->ppo_coeff[i]); } hcoeff = ksearch (hstring,"AMDX1"); for (i = 0; i < 20; i++) { sprintf (keyword,"AMDX%d", i+1); wcs->x_coeff[i] = 0.0; hgetr8 (hcoeff, keyword, &wcs->x_coeff[i]); } hcoeff = ksearch (hstring,"AMDY1"); for (i = 0; i < 20; i++) { sprintf (keyword,"AMDY%d",i+1); wcs->y_coeff[i] = 0.0; hgetr8 (hcoeff, keyword, &wcs->y_coeff[i]); } wcs->wcson = 1; (void)strcpy (wcs->c1type, "RA"); (void)strcpy (wcs->c2type, "DEC"); (void)strcpy (wcs->ptype, "DSS"); wcs->degout = 0; wcs->ndec = 3; /* Compute a nominal reference pixel at the image center */ strcpy (wcs->ctype[0], "RA---DSS"); strcpy (wcs->ctype[1], "DEC--DSS"); wcs->crpix[0] = 0.5 * wcs->nxpix; wcs->crpix[1] = 0.5 * wcs->nypix; wcs->xrefpix = wcs->crpix[0]; wcs->yrefpix = wcs->crpix[1]; dsspos (wcs->crpix[0], wcs->crpix[1], wcs, &ra0, &dec0); wcs->crval[0] = ra0; wcs->crval[1] = dec0; wcs->xref = wcs->crval[0]; wcs->yref = wcs->crval[1]; /* Compute a nominal scale factor */ dsspos (wcs->crpix[0], wcs->crpix[1]+1.0, wcs, &ra1, &dec1); wcs->yinc = dec1 - dec0; wcs->xinc = -wcs->yinc; wcsioset (wcs); /* Compute image rotation angle */ wcs->wcson = 1; wcsrotset (wcs); rot = degrad (wcs->rot); /* Compute image scale at center */ dsspos (wcs->crpix[0]+cos(rot), wcs->crpix[1]+sin(rot), wcs, &ra1, &dec1); wcs->cdelt[0] = -wcsdist (ra0, dec0, ra1, dec1); dsspos (wcs->crpix[0]+sin(rot), wcs->crpix[1]+cos(rot), wcs, &ra1, &dec1); wcs->cdelt[1] = wcsdist (ra0, dec0, ra1, dec1); /* Set all other image scale parameters */ wcsdeltset (wcs, wcs->cdelt[0], wcs->cdelt[1], wcs->rot); } /* Approximate world coordinate system if plate scale is known */ else if ((ksearch (hstring,"SECPIX") != NULL || ksearch (hstring,"PIXSCALE") != NULL || ksearch (hstring,"PIXSCAL1") != NULL || ksearch (hstring,"XPIXSIZE") != NULL || ksearch (hstring,"SECPIX1") != NULL)) { secpix = 0.0; hgetr8 (hstring,"SECPIX",&secpix); if (secpix == 0.0) hgetr8 (hstring,"PIXSCALE",&secpix); if (secpix == 0.0) { hgetr8 (hstring,"SECPIX1",&secpix); if (secpix != 0.0) { cdelt1 = -secpix / 3600.0; hgetr8 (hstring,"SECPIX2",&secpix); cdelt2 = secpix / 3600.0; } else { hgetr8 (hstring,"XPIXSIZE",&secpix); if (secpix != 0.0) { cdelt1 = -secpix / 3600.0; hgetr8 (hstring,"YPIXSIZE",&secpix); cdelt2 = secpix / 3600.0; } else { hgetr8 (hstring,"PIXSCAL1",&secpix); cdelt1 = -secpix / 3600.0; hgetr8 (hstring,"PIXSCAL2",&secpix); cdelt2 = secpix / 3600.0; } } } else { cdelt2 = secpix / 3600.0; cdelt1 = -cdelt2; } /* Get rotation angle from the header, if it's there */ rot = 0.0; hgetr8 (hstring,"CROTA1", &rot); if (wcs->rot == 0.) hgetr8 (hstring,"CROTA2", &rot); /* Set CD and PC matrices */ wcsdeltset (wcs, cdelt1, cdelt2, rot); /* By default, set reference pixel to center of image */ wcs->crpix[0] = 0.5 + (wcs->nxpix * 0.5); wcs->crpix[1] = 0.5 + (wcs->nypix * 0.5); /* Get reference pixel from the header, if it's there */ if (ksearch (hstring,"CRPIX1") != NULL) { hgetr8 (hstring,"CRPIX1",&wcs->crpix[0]); hgetr8 (hstring,"CRPIX2",&wcs->crpix[1]); } /* Use center of detector array as reference pixel else if (ksearch (hstring,"DETSIZE") != NULL || ksearch (hstring,"DETSEC") != NULL) { char *ic; hgets (hstring, "DETSIZE", 32, temp); ic = strchr (temp, ':'); if (ic != NULL) *ic = ' '; ic = strchr (temp, ','); if (ic != NULL) *ic = ' '; ic = strchr (temp, ':'); if (ic != NULL) *ic = ' '; ic = strchr (temp, ']'); if (ic != NULL) *ic = cnull; sscanf (temp, "%d %d %d %d", &idx1, &idx2, &idy1, &idy2); dxrefpix = 0.5 * (double) (idx1 + idx2 - 1); dyrefpix = 0.5 * (double) (idy1 + idy2 - 1); hgets (hstring, "DETSEC", 32, temp); ic = strchr (temp, ':'); if (ic != NULL) *ic = ' '; ic = strchr (temp, ','); if (ic != NULL) *ic = ' '; ic = strchr (temp, ':'); if (ic != NULL) *ic = ' '; ic = strchr (temp, ']'); if (ic != NULL) *ic = cnull; sscanf (temp, "%d %d %d %d", &ix1, &ix2, &iy1, &iy2); wcs->crpix[0] = dxrefpix - (double) (ix1 - 1); wcs->crpix[1] = dyrefpix - (double) (iy1 - 1); } */ wcs->xrefpix = wcs->crpix[0]; wcs->yrefpix = wcs->crpix[1]; wcs->crval[0] = -999.0; if (!hgetra (hstring,"RA",&wcs->crval[0])) { setwcserr ("WCSINIT: No RA with SECPIX, no WCS"); wcsfree (wcs); return (NULL); } wcs->crval[1] = -999.0; if (!hgetdec (hstring,"DEC",&wcs->crval[1])) { setwcserr ("WCSINIT No DEC with SECPIX, no WCS"); wcsfree (wcs); return (NULL); } wcs->xref = wcs->crval[0]; wcs->yref = wcs->crval[1]; wcs->coorflip = 0; wcs->cel.ref[0] = wcs->crval[0]; wcs->cel.ref[1] = wcs->crval[1]; wcs->cel.ref[2] = 999.0; if (!hgetr8 (hstring,"LONPOLE",&wcs->cel.ref[2])) hgetr8 (hstring,"LONGPOLE",&wcs->cel.ref[2]); wcs->cel.ref[3] = 999.0; hgetr8 (hstring,"LATPOLE",&wcs->cel.ref[3]); /* Epoch of image (from observation date, if possible) */ if (hgetr8 (hstring, "MJD-OBS", &mjd)) wcs->epoch = 1900.0 + (mjd - 15019.81352) / 365.242198781; else if (!hgetdate (hstring,"DATE-OBS",&wcs->epoch)) { if (!hgetdate (hstring,"DATE",&wcs->epoch)) { if (!hgetr8 (hstring,"EPOCH",&wcs->epoch)) wcs->epoch = wcs->equinox; } } /* Add time of day if not part of DATE-OBS string */ else { hgets (hstring,"DATE-OBS",32,tstring); if (!strchr (tstring,'T')) { if (hgetr8 (hstring, "UT",&ut)) wcs->epoch = wcs->epoch + (ut / (24.0 * 365.242198781)); else if (hgetr8 (hstring, "UTMID",&ut)) wcs->epoch = wcs->epoch + (ut / (24.0 * 365.242198781)); } } /* Coordinate reference frame and equinox */ (void) wcstype (wcs, "RA---TAN", "DEC--TAN"); wcs->coorflip = 0; wcseq (hstring,wcs); wcsioset (wcs); wcs->degout = 0; wcs->ndec = 3; wcs->wcson = 1; } else { setwcserr ("WCSINIT: No image scale"); wcsfree (wcs); return (NULL); } wcs->lin.crpix = wcs->crpix; wcs->lin.cdelt = wcs->cdelt; wcs->lin.pc = wcs->pc; wcs->printsys = 1; wcs->tabsys = 0; wcs->linmode = 0; /* Initialize special WCS commands */ setwcscom (wcs); return (wcs); } /* Set coordinate system of image, input, and output */ static void wcsioset (wcs) struct WorldCoor *wcs; { if (strlen (wcs->radecsys) == 0 || wcs->prjcode == WCS_LIN) strcpy (wcs->radecsys, "LINEAR"); if (wcs->prjcode == WCS_PIX) strcpy (wcs->radecsys, "PIXEL"); wcs->syswcs = wcscsys (wcs->radecsys); if (wcs->syswcs == WCS_B1950) strcpy (wcs->radecout, "FK4"); else if (wcs->syswcs == WCS_J2000) strcpy (wcs->radecout, "FK5"); else strcpy (wcs->radecout, wcs->radecsys); wcs->sysout = wcscsys (wcs->radecout); wcs->eqout = wcs->equinox; strcpy (wcs->radecin, wcs->radecsys); wcs->sysin = wcscsys (wcs->radecin); wcs->eqin = wcs->equinox; return; } static void wcseq (hstring, wcs) const char *hstring; /* character string containing FITS header information in the format = [/ ] */ struct WorldCoor *wcs; /* World coordinate system data structure */ { char mchar; /* Suffix character for one of multiple WCS */ mchar = (char) 0; wcseqm (hstring, wcs, &mchar); return; } static void wcseqm (hstring, wcs, mchar) char *hstring; /* character string containing FITS header information in the format = [/ ] */ struct WorldCoor *wcs; /* World coordinate system data structure */ char *mchar; /* Suffix character for one of multiple WCS */ { int ieq = 0; int eqhead = 0; char systring[32], eqstring[32]; char radeckey[16], eqkey[16]; char tstring[32]; double ut; /* Set equinox from EQUINOX, EPOCH, or RADECSYS; default to 2000 */ systring[0] = 0; eqstring[0] = 0; if (mchar[0]) { sprintf (eqkey, "EQUINOX%c", mchar[0]); sprintf (radeckey, "RADECSYS%c", mchar[0]); } else { strcpy (eqkey, "EQUINOX"); sprintf (radeckey, "RADECSYS"); } if (!hgets (hstring, eqkey, 31, eqstring)) { if (hgets (hstring, "EQUINOX", 31, eqstring)) strcpy (eqkey, "EQUINOX"); } if (!hgets (hstring, radeckey, 31, systring)) { if (hgets (hstring, "RADECSYS", 31, systring)) sprintf (radeckey, "RADECSYS"); } if (eqstring[0] == 'J') { wcs->equinox = atof (eqstring+1); ieq = atoi (eqstring+1); strcpy (systring, "FK5"); } else if (eqstring[0] == 'B') { wcs->equinox = atof (eqstring+1); ieq = (int) atof (eqstring+1); strcpy (systring, "FK4"); } else if (hgeti4 (hstring, eqkey, &ieq)) { hgetr8 (hstring, eqkey, &wcs->equinox); eqhead = 1; } else if (hgeti4 (hstring,"EPOCH",&ieq)) { if (ieq == 0) { ieq = 1950; wcs->equinox = 1950.0; } else { hgetr8 (hstring,"EPOCH",&wcs->equinox); eqhead = 1; } } else if (systring[0] != (char)0) { if (!strncmp (systring,"FK4",3)) { wcs->equinox = 1950.0; ieq = 1950; } else if (!strncmp (systring,"ICRS",4)) { wcs->equinox = 2000.0; ieq = 2000; } else if (!strncmp (systring,"FK5",3)) { wcs->equinox = 2000.0; ieq = 2000; } else if (!strncmp (systring,"GAL",3)) { wcs->equinox = 2000.0; ieq = 2000; } else if (!strncmp (systring,"ECL",3)) { wcs->equinox = 2000.0; ieq = 2000; } } if (ieq == 0) { wcs->equinox = 2000.0; ieq = 2000; if (!strncmp (wcs->c1type, "RA",2) || !strncmp (wcs->c1type,"DEC",3)) strcpy (systring,"FK5"); } /* Epoch of image (from observation date, if possible) */ if (!hgetdate (hstring,"DATE-OBS",&wcs->epoch)) { if (!hgetdate (hstring,"DATE",&wcs->epoch)) { if (!hgetr8 (hstring,"EPOCH",&wcs->epoch)) wcs->epoch = wcs->equinox; } } /* Add time of day if not part of DATE-OBS string */ else { hgets (hstring,"DATE-OBS",32,tstring); if (!strchr (tstring,'T')) { if (hgetr8 (hstring, "UT",&ut)) wcs->epoch = wcs->epoch + (ut / (24.0 * 365.242198781)); else if (hgetr8 (hstring, "UTMID",&ut)) wcs->epoch = wcs->epoch + (ut / (24.0 * 365.242198781)); } } if (wcs->epoch == 0.0) wcs->epoch = wcs->equinox; /* Set coordinate system from keyword, if it is present */ if (systring[0] == (char) 0) hgets (hstring, radeckey, 31, systring); if (systring[0] != (char) 0) { strcpy (wcs->radecsys,systring); if (!eqhead) { if (!strncmp (wcs->radecsys,"FK4",3)) wcs->equinox = 1950.0; else if (!strncmp (wcs->radecsys,"FK5",3)) wcs->equinox = 2000.0; else if (!strncmp (wcs->radecsys,"ICRS",4)) wcs->equinox = 2000.0; else if (!strncmp (wcs->radecsys,"GAL",3) && ieq == 0) wcs->equinox = 2000.0; } } /* Otherwise set coordinate system from equinox */ /* Systemless coordinates cannot be translated using b, j, or g commands */ else if (wcs->syswcs != WCS_NPOLE) { if (ieq > 1980) strcpy (wcs->radecsys,"FK5"); else strcpy (wcs->radecsys,"FK4"); } /* Set galactic coordinates if GLON or GLAT are in C1TYPE */ if (wcs->c1type[0] == 'G') strcpy (wcs->radecsys,"GALACTIC"); else if (wcs->c1type[0] == 'E') strcpy (wcs->radecsys,"ECLIPTIC"); else if (wcs->c1type[0] == 'S') strcpy (wcs->radecsys,"SGALACTC"); else if (wcs->c1type[0] == 'H') strcpy (wcs->radecsys,"HELIOECL"); else if (wcs->c1type[0] == 'A') strcpy (wcs->radecsys,"ALTAZ"); else if (wcs->c1type[0] == 'L') strcpy (wcs->radecsys,"LINEAR"); wcs->syswcs = wcscsys (wcs->radecsys); return; } /* Jun 11 1998 Split off header-dependent WCS initialization from other subs * Jun 15 1998 Fix major bug in wcsinit() when synthesizing WCS from header * Jun 18 1998 Fix bug in CD initialization; split PC initialization off * Jun 18 1998 Split PC initialization off into subroutine wcspcset() * Jun 24 1998 Set equinox from RADECSYS only if EQUINOX and EPOCH not present * Jul 6 1998 Read third and fourth axis CTYPEs * Jul 7 1998 Initialize eqin and eqout to equinox, * Jul 9 1998 Initialize rotation matrices correctly * Jul 13 1998 Initialize rotation, scale for polynomial and DSS projections * Aug 6 1998 Fix CROTA computation for DSS projection * Sep 4 1998 Fix CROTA, CDELT computation for DSS and polynomial projections * Sep 14 1998 If DATE-OBS not found, check for DATE * Sep 14 1998 If B or J present in EQUINOX, use that info to set system * Sep 29 1998 Initialize additional WCS commands from the environment * Sep 29 1998 Fix bug which read DATE as number rather than formatted date * Dec 2 1998 Read projection constants from header (bug fix) * * Feb 9 1999 Set rotation angle correctly when using DSS projection * Feb 19 1999 Fill in CDELTs from scale keyword if absent or zero * Feb 19 1999 Add PIXSCALE as possible default arcseconds per pixel * Apr 7 1999 Add error checking for NAXIS and NAXIS1 keywords * Apr 7 1999 Do not set systring if epoch is 0 and not RA/Dec * Jul 8 1999 In RADECSYS, use FK5 and FK4 instead of J2000 and B1950 * Oct 15 1999 Free wcs using wcsfree() * Oct 20 1999 Add multiple WCS support using new subroutine names * Oct 21 1999 Delete unused variables after lint; declare dsspos() * Nov 9 1999 Add wcschar() to check WCSNAME keywords for desired WCS * Nov 9 1999 Check WCSPREx keyword to find out if chained WCS's * * Jan 6 1999 Add wcsinitn() to initialize from specific WCSNAME * Jan 24 2000 Set CD matrix from header even if using polynomial * Jan 27 2000 Fix MJD to epoch conversion for when MJD-OBS is the only date * Jan 28 2000 Set CD matrix for DSS projection, too * Jan 28 2000 Use wcsproj instead of oldwcs * Dec 18 2000 Fix error in hgets() call in wcschar() * Dec 29 2000 Compute inverse CD matrix even if polynomial solution * Dec 29 2000 Add PROJR0 keyword for WCSLIB projections * Dec 29 2000 Use CDi_j matrix if any elements are present * * Jan 31 2001 Fix to allow 1D WCS * Jan 31 2001 Treat single character WCS name as WCS character * Feb 20 2001 Implement WCSDEPx nested WCS's * Feb 23 2001 Initialize all 4 terms of CD matrix * Feb 28 2001 Fix bug which read CRPIX1 into CRPIX2 * Mar 20 2001 Compare mchar to (char)0, not null * Mar 21 2001 Move ic declaration into commented out code * Jul 12 2001 Read PROJPn constants into proj.p array instead of PVn * Sep 7 2001 Set system to galactic or ecliptic based on CTYPE, not RADECSYS * Oct 11 2001 Set ctype[0] as well as ctype[1] to TAN for TNX projections * Oct 19 2001 WCSDIM keyword overrides zero value of NAXIS * * Feb 19 2002 Add XPIXSIZE/YPIXSIZE (KPNO) as default image scale keywords * Mar 12 2002 Add LONPOLE as well as LONGPOLE for WCSLIB 2.8 * Apr 3 2002 Implement hget8c() and hgetsc() to simplify code * Apr 3 2002 Add PVj_n projection constants in addition to PROJPn * Apr 19 2002 Increase numeric keyword value length from 16 to 31 * Apr 19 2002 Fix bug which didn't set radecsys keyword name * Apr 24 2002 If no WCS present for specified letter, return null * Apr 26 2002 Implement WCSAXESa keyword as first choice for number of axes * Apr 26 2002 Add wcschar and wcsname to WCS structure * May 9 2002 Add radvel and zvel to WCS structure * May 13 2002 Free everything which is allocated * May 28 2002 Read 10 prj.p instead of maximum of 100 * May 31 2002 Fix bugs with PV reading * May 31 2002 Initialize syswcs, sysin, sysout in wcsioset() * Sep 25 2002 Fix subroutine calls for radvel and latpole * Dec 6 2002 Correctly compute pixel at center of image for default CRPIX * * Jan 2 2002 Do not reinitialize projection vector for PV input * Jan 3 2002 For ZPN, read PVi_0 to PVi_9, not PVi_1 to PVi_10 * Mar 27 2003 Clean up default center computation * Apr 3 2003 Add input for SIRTF distortion coefficients * May 8 2003 Change PROJP reading to start with 0 instead of 1 * May 22 2003 Add ZPX approximation, reading projpn from WATi * May 28 2003 Avoid reinitializing coefficients set by PROJP * Jun 26 2003 Initialize xref and yref to -999.0 * Sep 23 2003 Change mgets() to mgetstr() to avoid name collision at UCO Lick * Oct 1 2003 Rename wcs->naxes to wcs->naxis to match WCSLIB 3.2 * Nov 3 2003 Initialize distortion coefficients in distortinit() in distort.c * Dec 1 2003 Change p[0,1,2] initializations to p[1,2,3] * Dec 3 2003 Add back wcs->naxes for backward compatibility * Dec 3 2003 Remove unused variables j,m in wcsinitc() * Dec 12 2003 Fix call to setwcserr() with format in it * * Feb 26 2004 Add parameters for ZPX projection * * Jun 22 2005 Drop declaration of variable wcserrmsg which is not used * Nov 9 2005 Use CROTA1 if CTYPE1 is LAT/DEC, CROTA2 if CTYPE2 is LAT/DEC * * Mar 9 2006 Get Epoch of observation from MJD-OBS or DATE-OBS/UT unless DSS * Apr 24 2006 Initialize rotation matrices * Apr 25 2006 Ignore axes with dimension of one * May 19 2006 Initialize all of 9x9 PC matrix; read in loops * Aug 21 2006 Limit naxes to 2 everywhere; RA and DEC should always be 1st * Oct 6 2006 If units are pixels, projection type is PIXEL * Oct 30 2006 Initialize cube face to -1, not a cube projection * * Jan 4 2007 Drop declarations of wcsinitc() and wcsinitn() already in wcs.h * Jan 8 2007 Change WCS letter from char to char* * Feb 1 2007 Read IRAF log wavelength flag DC-FLAG to wcs.logwcs * Feb 15 2007 Check for wcs->wcsproj > 0 instead of CTYPEi != LINEAR or PIXEL * Mar 13 2007 Try for RA, DEC, SECPIX if WCS character is space or null * Apr 27 2007 Ignore axes with TAB WCS for now */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/wcslib.c000066400000000000000000001262161215713201500217120ustar00rootroot00000000000000/*============================================================================= * * WCSLIB - an implementation of the FITS WCS proposal. * Copyright (C) 1995-2002, Mark Calabretta * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Correspondence concerning WCSLIB may be directed to: * Internet email: mcalabre@atnf.csiro.au * Postal address: Dr. Mark Calabretta, * Australia Telescope National Facility, * P.O. Box 76, * Epping, NSW, 2121, * AUSTRALIA * *============================================================================= * * C routines which implement the FITS World Coordinate System (WCS) * convention. * * Summary of routines * ------------------- * wcsfwd() and wcsrev() are high level driver routines for the WCS linear * transformation, spherical coordinate transformation, and spherical * projection routines. * * Given either the celestial longitude or latitude plus an element of the * pixel coordinate a hybrid routine, wcsmix(), iteratively solves for the * unknown elements. * * An initialization routine, wcsset(), computes indices from the ctype * array but need not be called explicitly - see the explanation of * wcs.flag below. * * * Initialization routine; wcsset() * -------------------------------- * Initializes elements of a wcsprm data structure which holds indices into * the coordinate arrays. Note that this routine need not be called directly; * it will be invoked by wcsfwd() and wcsrev() if the "flag" structure member * is anything other than a predefined magic value. * * Given: * naxis const int * Number of image axes. * ctype[][9] * const char * Coordinate axis types corresponding to the FITS * CTYPEn header cards. * * Returned: * wcs wcsprm* Indices for the celestial coordinates obtained * by parsing the ctype[] array (see below). * * Function return value: * int Error status * 0: Success. * 1: Inconsistent or unrecognized coordinate axis * types. * * * Forward transformation; wcsfwd() * -------------------------------- * Compute the pixel coordinate for given world coordinates. * * Given: * ctype[][9] * const char * Coordinate axis types corresponding to the FITS * CTYPEn header cards. * * Given or returned: * wcs wcsprm* Indices for the celestial coordinates obtained * by parsing the ctype[] array (see below). * * Given: * world const double[] * World coordinates. world[wcs->lng] and * world[wcs->lat] are the celestial longitude and * latitude, in degrees. * * Given: * crval const double[] * Coordinate reference values corresponding to the FITS * CRVALn header cards (see note 2). * * Given and returned: * cel celprm* Spherical coordinate transformation parameters (usage * is described in the prologue to "cel.c"). * * Returned: * phi, double* Longitude and latitude in the native coordinate * theta system of the projection, in degrees. * * Given and returned: * prj prjprm* Projection parameters (usage is described in the * prologue to "proj.c"). * * Returned: * imgcrd double[] Image coordinate. imgcrd[wcs->lng] and * imgcrd[wcs->lat] are the projected x-, and * y-coordinates, in "degrees". For quadcube * projections with a CUBEFACE axis the face number is * also returned in imgcrd[wcs->cubeface]. * * Given and returned: * lin linprm* Linear transformation parameters (usage is described * in the prologue to "lin.c"). * * Returned: * pixcrd double[] Pixel coordinate. * * Function return value: * int Error status * 0: Success. * 1: Invalid coordinate transformation parameters. * 2: Invalid projection parameters. * 3: Invalid world coordinate. * 4: Invalid linear transformation parameters. * * * Reverse transformation; wcsrev() * -------------------------------- * Compute world coordinates for a given pixel coordinate. * * Given: * ctype[][9] * const char * Coordinate axis types corresponding to the FITS * CTYPEn header cards. * * Given or returned: * wcs wcsprm* Indices for the celestial coordinates obtained * by parsing the ctype[] array (see below). * * Given: * pixcrd const double[] * Pixel coordinate. * * Given and returned: * lin linprm* Linear transformation parameters (usage is described * in the prologue to "lin.c"). * * Returned: * imgcrd double[] Image coordinate. imgcrd[wcs->lng] and * imgcrd[wcs->lat] are the projected x-, and * y-coordinates, in "degrees". * * Given and returned: * prj prjprm* Projection parameters (usage is described in the * prologue to "proj.c"). * * Returned: * phi, double* Longitude and latitude in the native coordinate * theta system of the projection, in degrees. * * Given: * crval const double[] * Coordinate reference values corresponding to the FITS * CRVALn header cards (see note 2). * * Given and returned: * cel celprm* Spherical coordinate transformation parameters * (usage is described in the prologue to "cel.c"). * * Returned: * world double[] World coordinates. world[wcs->lng] and * world[wcs->lat] are the celestial longitude and * latitude, in degrees. * * Function return value: * int Error status * 0: Success. * 1: Invalid coordinate transformation parameters. * 2: Invalid projection parameters. * 3: Invalid pixel coordinate. * 4: Invalid linear transformation parameters. * * * Hybrid transformation; wcsmix() * ------------------------------- * Given either the celestial longitude or latitude plus an element of the * pixel coordinate solve for the remaining elements by iterating on the * unknown celestial coordinate element using wcsfwd(). * * Given: * ctype[][9] * const char * Coordinate axis types corresponding to the FITS * CTYPEn header cards. * * Given or returned: * wcs wcsprm* Indices for the celestial coordinates obtained * by parsing the ctype[] array (see below). * * Given: * mixpix const int * Which element of the pixel coordinate is given. * mixcel const int * Which element of the celestial coordinate is * given: * 1: Celestial longitude is given in * world[wcs->lng], latitude returned in * world[wcs->lat]. * 2: Celestial latitude is given in * world[wcs->lat], longitude returned in * world[wcs->lng]. * vspan[2] const double * Solution interval for the celestial coordinate, in * degrees. The ordering of the two limits is * irrelevant. Longitude ranges may be specified with * any convenient normalization, for example [-120,+120] * is the same as [240,480], except that the solution * will be returned with the same normalization, i.e. * lie within the interval specified. * vstep const double * Step size for solution search, in degrees. If zero, * a sensible, although perhaps non-optimal default will * be used. * viter int * If a solution is not found then the step size will be * halved and the search recommenced. viter controls * how many times the step size is halved. The allowed * range is 5 - 10. * * Given and returned: * world double[] World coordinates. world[wcs->lng] and * world[wcs->lat] are the celestial longitude and * latitude, in degrees. Which is given and which * returned depends on the value of mixcel. All other * elements are given. * * Given: * crval const double[] * Coordinate reference values corresponding to the FITS * CRVALn header cards (see note 2). * * Given and returned: * cel celprm* Spherical coordinate transformation parameters * (usage is described in the prologue to "cel.c"). * * Returned: * phi, double* Longitude and latitude in the native coordinate * theta system of the projection, in degrees. * * Given and returned: * prj prjprm* Projection parameters (usage is described in the * prologue to "proj.c"). * * Returned: * imgcrd double[] Image coordinate. imgcrd[wcs->lng] and * imgcrd[wcs->lat] are the projected x-, and * y-coordinates, in "degrees". * * Given and returned: * lin linprm* Linear transformation parameters (usage is described * in the prologue to "lin.c"). * * Given and returned: * pixcrd double[] Pixel coordinate. The element indicated by mixpix is * given and the remaining elements are returned. * * Function return value: * int Error status * 0: Success. * 1: Invalid coordinate transformation parameters. * 2: Invalid projection parameters. * 3: Coordinate transformation error. * 4: Invalid linear transformation parameters. * 5: No solution found in the specified interval. * * * Notes * ----- * 1) The CTYPEn must in be upper case and there must be 0 or 1 pair of * matched celestial axis types. The ctype[][9] should be padded with * blanks on the right and null-terminated. * * 2) Elements of the crval[] array which correspond to celestial axes are * ignored, the reference coordinate values in cel->ref[0] and * cel->ref[1] are the ones used. * * 3) These functions recognize the NCP projection and convert it to the * equivalent SIN projection. * * They also recognize GLS as a synonym for SFL. * * 4) The quadcube projections (TSC, CSC, QSC) may be represented in FITS in * either of two ways: * * a) The six faces may be laid out in one plane and numbered as * follows: * * 0 * * 4 3 2 1 4 3 2 * * 5 * * Faces 2, 3 and 4 may appear on one side or the other (or both). * The forward routines map faces 2, 3 and 4 to the left but the * inverse routines accept them on either side. * * b) The "COBE" convention in which the six faces are stored in a * three-dimensional structure using a "CUBEFACE" axis indexed from * 0 to 5 as above. * * These routines support both methods; wcsset() determines which is * being used by the presence or absence of a CUBEFACE axis in ctype[]. * wcsfwd() and wcsrev() translate the CUBEFACE axis representation to * the single plane representation understood by the lower-level WCSLIB * projection routines. * * * WCS indexing parameters * ----------------------- * The wcsprm struct consists of the following: * * int flag * The wcsprm struct contains indexes and other information derived * from the CTYPEn. Whenever any of the ctype[] are set or changed * this flag must be set to zero to signal the initialization routine, * wcsset() to redetermine the indices. The flag is set to 999 if * there is no celestial axis pair in the CTYPEn. * * char pcode[4] * The WCS projection code. * * char lngtyp[5], lattyp[5] * WCS celestial axis types. * * int lng,lat * Indices into the imgcrd[], and world[] arrays as described above. * These may also serve as indices for the celestial longitude and * latitude axes in the pixcrd[] array provided that the PC matrix * does not transpose axes. * * int cubeface * Index into the pixcrd[] array for the CUBEFACE axis. This is * optionally used for the quadcube projections where each cube face is * stored on a separate axis. * * * wcsmix() algorithm * ------------------ * Initially the specified solution interval is checked to see if it's a * "crossing" interval. If it isn't, a search is made for a crossing * solution by iterating on the unknown celestial coordinate starting at * the upper limit of the solution interval and decrementing by the * specified step size. A crossing is indicated if the trial value of the * pixel coordinate steps through the value specified. If a crossing * interval is found then the solution is determined by a modified form of * "regula falsi" division of the crossing interval. If no crossing * interval was found within the specified solution interval then a search * is made for a "non-crossing" solution as may arise from a point of * tangency. The process is complicated by having to make allowance for * the discontinuities that occur in all map projections. * * Once one solution has been determined others may be found by subsequent * invokations of wcsmix() with suitably restricted solution intervals. * * Note the circumstance which arises when the solution point lies at a * native pole of a projection in which the pole is represented as a * finite curve, for example the zenithals and conics. In such cases two * or more valid solutions may exist but WCSMIX only ever returns one. * * Because of its generality wcsmix() is very compute-intensive. For * compute-limited applications more efficient special-case solvers could * be written for simple projections, for example non-oblique cylindrical * projections. * * Author: Mark Calabretta, Australia Telescope National Facility * $Id: wcslib.c,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ *===========================================================================*/ #include #include #include #include #include "wcslib.h" /* Map error number to error message for each function. */ const char *wcsset_errmsg[] = { 0, "Inconsistent or unrecognized coordinate axis types"}; const char *wcsfwd_errmsg[] = { 0, "Invalid coordinate transformation parameters", "Invalid projection parameters", "Invalid world coordinate", "Invalid linear transformation parameters"}; const char *wcsrev_errmsg[] = { 0, "Invalid coordinate transformation parameters", "Invalid projection parameters", "Invalid pixel coordinate", "Invalid linear transformation parameters"}; const char *wcsmix_errmsg[] = { 0, "Invalid coordinate transformation parameters", "Invalid projection parameters", "Coordinate transformation error", "Invalid linear transformation parameters", "No solution found in the specified interval"}; #define signb(X) ((X) < 0.0 ? 1 : 0) int wcsset (naxis, ctype, wcs) const int naxis; const char ctype[][9]; struct wcsprm *wcs; { int nalias = 2; char aliases [2][4] = {"NCP", "GLS"}; int j, k; int *ndx = NULL; char requir[9]; strcpy(wcs->pcode, ""); strcpy(requir, ""); wcs->lng = -1; wcs->lat = -1; wcs->cubeface = -1; for (j = 0; j < naxis; j++) { if (ctype[j][4] != '-') { if (strcmp(ctype[j], "CUBEFACE") == 0) { if (wcs->cubeface == -1) { wcs->cubeface = j; } else { /* Multiple CUBEFACE axes! */ return 1; } } continue; } /* Got an axis qualifier, is it a recognized WCS projection? */ for (k = 0; k < npcode; k++) { if (strncmp(&ctype[j][5], pcodes[k], 3) == 0) break; } if (k == npcode) { /* Maybe it's a projection alias. */ for (k = 0; k < nalias; k++) { if (strncmp(&ctype[j][5], aliases[k], 3) == 0) break; } /* Not recognized. */ if (k == nalias) { continue; } } /* Parse the celestial axis type. */ if (strcmp(wcs->pcode, "") == 0) { sprintf(wcs->pcode, "%.3s", &ctype[j][5]); if (strncmp(ctype[j], "RA--", 4) == 0) { wcs->lng = j; strcpy(wcs->lngtyp, "RA"); strcpy(wcs->lattyp, "DEC"); ndx = &wcs->lat; sprintf(requir, "DEC--%s", wcs->pcode); } else if (strncmp(ctype[j], "DEC-", 4) == 0) { wcs->lat = j; strcpy(wcs->lngtyp, "RA"); strcpy(wcs->lattyp, "DEC"); ndx = &wcs->lng; sprintf(requir, "RA---%s", wcs->pcode); } else if (strncmp(&ctype[j][1], "LON", 3) == 0) { wcs->lng = j; sprintf(wcs->lngtyp, "%cLON", ctype[j][0]); sprintf(wcs->lattyp, "%cLAT", ctype[j][0]); ndx = &wcs->lat; sprintf(requir, "%s-%s", wcs->lattyp, wcs->pcode); } else if (strncmp(&ctype[j][1], "LAT", 3) == 0) { wcs->lat = j; sprintf(wcs->lngtyp, "%cLON", ctype[j][0]); sprintf(wcs->lattyp, "%cLAT", ctype[j][0]); ndx = &wcs->lng; sprintf(requir, "%s-%s", wcs->lngtyp, wcs->pcode); } else if (strncmp(&ctype[j][2], "LN", 2) == 0) { wcs->lng = j; sprintf(wcs->lngtyp, "%c%cLN", ctype[j][0], ctype[j][1]); sprintf(wcs->lattyp, "%c%cLT", ctype[j][0], ctype[j][1]); ndx = &wcs->lat; sprintf(requir, "%s-%s", wcs->lattyp, wcs->pcode); } else if (strncmp(&ctype[j][2], "LT", 2) == 0) { wcs->lat = j; sprintf(wcs->lngtyp, "%c%cLN", ctype[j][0], ctype[j][1]); sprintf(wcs->lattyp, "%c%cLT", ctype[j][0], ctype[j][1]); ndx = &wcs->lng; sprintf(requir, "%s-%s", wcs->lngtyp, wcs->pcode); } else { /* Unrecognized celestial type. */ return 1; } } else { if (strncmp(ctype[j], requir, 8) != 0) { /* Inconsistent projection types. */ return 1; } if (ndx == NULL) return 1; *ndx = j; strcpy(requir, ""); } } if (strcmp(requir, "")) { /* Unmatched celestial axis. */ return 1; } /* Do simple alias translations. */ if (strncmp(wcs->pcode, "GLS", 3) == 0) { strcpy(wcs->pcode, "SFL"); } if (strcmp(wcs->pcode, "")) { wcs->flag = WCSSET; } else { /* Signal for no celestial axis pair. */ wcs->flag = 999; } return 0; } /*--------------------------------------------------------------------------*/ int wcsfwd(ctype, wcs, world, crval, cel, phi, theta, prj, imgcrd, lin, pixcrd) const char ctype[][9]; struct wcsprm* wcs; const double world[]; const double crval[]; struct celprm *cel; double *phi, *theta; struct prjprm *prj; double imgcrd[]; struct linprm *lin; double pixcrd[]; { int err, j; double offset; /* Initialize if required. */ if (wcs->flag != WCSSET) { if (wcsset(lin->naxis, ctype, wcs)) return 1; } /* Convert to relative physical coordinates. */ for (j = 0; j < lin->naxis; j++) { if (j == wcs->lng) continue; if (j == wcs->lat) continue; imgcrd[j] = world[j] - crval[j]; } if (wcs->flag != 999) { /* Compute projected coordinates. */ if (strcmp(wcs->pcode, "NCP") == 0) { /* Convert NCP to SIN. */ if (cel->ref[1] == 0.0) { return 2; } strcpy(wcs->pcode, "SIN"); prj->p[1] = 0.0; prj->p[2] = cosdeg (cel->ref[1])/sindeg (cel->ref[1]); prj->flag = (prj->flag < 0) ? -1 : 0; } if ((err = celfwd(wcs->pcode, world[wcs->lng], world[wcs->lat], cel, phi, theta, prj, &imgcrd[wcs->lng], &imgcrd[wcs->lat]))) { return err; } /* Do we have a CUBEFACE axis? */ if (wcs->cubeface != -1) { /* Separation between faces. */ if (prj->r0 == 0.0) { offset = 90.0; } else { offset = prj->r0*PI/2.0; } /* Stack faces in a cube. */ if (imgcrd[wcs->lat] < -0.5*offset) { imgcrd[wcs->lat] += offset; imgcrd[wcs->cubeface] = 5.0; } else if (imgcrd[wcs->lat] > 0.5*offset) { imgcrd[wcs->lat] -= offset; imgcrd[wcs->cubeface] = 0.0; } else if (imgcrd[wcs->lng] > 2.5*offset) { imgcrd[wcs->lng] -= 3.0*offset; imgcrd[wcs->cubeface] = 4.0; } else if (imgcrd[wcs->lng] > 1.5*offset) { imgcrd[wcs->lng] -= 2.0*offset; imgcrd[wcs->cubeface] = 3.0; } else if (imgcrd[wcs->lng] > 0.5*offset) { imgcrd[wcs->lng] -= offset; imgcrd[wcs->cubeface] = 2.0; } else { imgcrd[wcs->cubeface] = 1.0; } } } /* Apply forward linear transformation. */ if (linfwd(imgcrd, lin, pixcrd)) { return 4; } return 0; } /*--------------------------------------------------------------------------*/ int wcsrev(ctype, wcs, pixcrd, lin, imgcrd, prj, phi, theta, crval, cel, world) const char ctype[][9]; struct wcsprm *wcs; const double pixcrd[]; struct linprm *lin; double imgcrd[]; struct prjprm *prj; double *phi, *theta; const double crval[]; struct celprm *cel; double world[]; { int err, face, j; double offset; /* Initialize if required. */ if (wcs->flag != WCSSET) { if (wcsset(lin->naxis, ctype, wcs)) return 1; } /* Apply reverse linear transformation. */ if (linrev(pixcrd, lin, imgcrd)) { return 4; } /* Convert to world coordinates. */ for (j = 0; j < lin->naxis; j++) { if (j == wcs->lng) continue; if (j == wcs->lat) continue; world[j] = imgcrd[j] + crval[j]; } if (wcs->flag != 999) { /* Do we have a CUBEFACE axis? */ if (wcs->cubeface != -1) { face = (int)(imgcrd[wcs->cubeface] + 0.5); if (fabs(imgcrd[wcs->cubeface]-face) > 1e-10) { return 3; } /* Separation between faces. */ if (prj->r0 == 0.0) { offset = 90.0; } else { offset = prj->r0*PI/2.0; } /* Lay out faces in a plane. */ switch (face) { case 0: imgcrd[wcs->lat] += offset; break; case 1: break; case 2: imgcrd[wcs->lng] += offset; break; case 3: imgcrd[wcs->lng] += offset*2; break; case 4: imgcrd[wcs->lng] += offset*3; break; case 5: imgcrd[wcs->lat] -= offset; break; default: return 3; } } /* Compute celestial coordinates. */ if (strcmp(wcs->pcode, "NCP") == 0) { /* Convert NCP to SIN. */ if (cel->ref[1] == 0.0) { return 2; } strcpy(wcs->pcode, "SIN"); prj->p[1] = 0.0; prj->p[2] = cosdeg (cel->ref[1])/sindeg (cel->ref[1]); prj->flag = (prj->flag < 0) ? -1 : 0; } if ((err = celrev(wcs->pcode, imgcrd[wcs->lng], imgcrd[wcs->lat], prj, phi, theta, cel, &world[wcs->lng], &world[wcs->lat]))) { return err; } } return 0; } /*--------------------------------------------------------------------------*/ int wcsmix(ctype, wcs, mixpix, mixcel, vspan, vstep, viter, world, crval, cel, phi, theta, prj, imgcrd, lin, pixcrd) const char ctype[][9]; struct wcsprm *wcs; const int mixpix, mixcel; const double vspan[2], vstep; int viter; double world[]; const double crval[]; struct celprm *cel; double *phi, *theta; struct prjprm *prj; double imgcrd[]; struct linprm *lin; double pixcrd[]; { const int niter = 60; int crossed, err, istep, iter, j, k, nstep, retry; const double tol = 1.0e-10; const double tol2 = 100.0*tol; double lambda, span[2], step; double pixmix; double dlng, lng, lng0, lng0m, lng1, lng1m; double dlat, lat, lat0, lat0m, lat1, lat1m; double d, d0, d0m, d1, d1m; double dx = 0.0; double dabs, dmin, lmin; double dphi, phi0, phi1; struct celprm cel0; /* Initialize if required. */ if (wcs->flag != WCSSET) { if (wcsset(lin->naxis, ctype, wcs)) return 1; } /* Check vspan. */ if (vspan[0] <= vspan[1]) { span[0] = vspan[0]; span[1] = vspan[1]; } else { /* Swap them. */ span[0] = vspan[1]; span[1] = vspan[0]; } /* Check vstep. */ step = fabs(vstep); if (step == 0.0) { step = (span[1] - span[0])/10.0; if (step > 1.0 || step == 0.0) step = 1.0; } /* Check viter. */ nstep = viter; if (nstep < 5) { nstep = 5; } else if (nstep > 10) { nstep = 10; } /* Given pixel element. */ pixmix = pixcrd[mixpix]; /* Iterate on the step size. */ for (istep = 0; istep <= nstep; istep++) { if (istep) step /= 2.0; /* Iterate on the sky coordinate between the specified range. */ if (mixcel == 1) { /* Celestial longitude is given. */ /* Check whether the solution interval is a crossing interval. */ lat0 = span[0]; world[wcs->lat] = lat0; if ((err = wcsfwd(ctype, wcs, world, crval, cel, phi, theta, prj, imgcrd, lin, pixcrd))) { return err; } d0 = pixcrd[mixpix] - pixmix; dabs = fabs(d0); if (dabs < tol) return 0; lat1 = span[1]; world[wcs->lat] = lat1; if ((err = wcsfwd(ctype, wcs, world, crval, cel, phi, theta, prj, imgcrd, lin, pixcrd))) { return err; } d1 = pixcrd[mixpix] - pixmix; dabs = fabs(d1); if (dabs < tol) return 0; lmin = lat1; dmin = dabs; /* Check for a crossing point. */ if (signb(d0) != signb(d1)) { crossed = 1; dx = d1; } else { crossed = 0; lat0 = span[1]; } for (retry = 0; retry < 4; retry++) { /* Refine the solution interval. */ while (lat0 > span[0]) { lat0 -= step; if (lat0 < span[0]) lat0 = span[0]; world[wcs->lat] = lat0; if ((err = wcsfwd(ctype, wcs, world, crval, cel, phi, theta, prj, imgcrd, lin, pixcrd))) { return err; } d0 = pixcrd[mixpix] - pixmix; /* Check for a solution. */ dabs = fabs(d0); if (dabs < tol) return 0; /* Record the point of closest approach. */ if (dabs < dmin) { lmin = lat0; dmin = dabs; } /* Check for a crossing point. */ if (signb(d0) != signb(d1)) { crossed = 2; dx = d0; break; } /* Advance to the next subinterval. */ lat1 = lat0; d1 = d0; } if (crossed) { /* A crossing point was found. */ for (iter = 0; iter < niter; iter++) { /* Use regula falsi division of the interval. */ lambda = d0/(d0-d1); if (lambda < 0.1) { lambda = 0.1; } else if (lambda > 0.9) { lambda = 0.9; } dlat = lat1 - lat0; lat = lat0 + lambda*dlat; world[wcs->lat] = lat; if ((err = wcsfwd(ctype, wcs, world, crval, cel, phi, theta, prj, imgcrd, lin, pixcrd))) { return err; } /* Check for a solution. */ d = pixcrd[mixpix] - pixmix; dabs = fabs(d); if (dabs < tol) return 0; if (dlat < tol) { /* An artifact of numerical imprecision. */ if (dabs < tol2) return 0; /* Must be a discontinuity. */ break; } /* Record the point of closest approach. */ if (dabs < dmin) { lmin = lat; dmin = dabs; } if (signb(d0) == signb(d)) { lat0 = lat; d0 = d; } else { lat1 = lat; d1 = d; } } /* No convergence, must have been a discontinuity. */ if (crossed == 1) lat0 = span[1]; lat1 = lat0; d1 = dx; crossed = 0; } else { /* No crossing point; look for a tangent point. */ if (lmin == span[0]) break; if (lmin == span[1]) break; lat = lmin; lat0 = lat - step; if (lat0 < span[0]) lat0 = span[0]; lat1 = lat + step; if (lat1 > span[1]) lat1 = span[1]; world[wcs->lat] = lat0; if ((err = wcsfwd(ctype, wcs, world, crval, cel, phi, theta, prj, imgcrd, lin, pixcrd))) { return err; } d0 = fabs(pixcrd[mixpix] - pixmix); d = dmin; world[wcs->lat] = lat1; if ((err = wcsfwd(ctype, wcs, world, crval, cel, phi, theta, prj, imgcrd, lin, pixcrd))) { return err; } d1 = fabs(pixcrd[mixpix] - pixmix); for (iter = 0; iter < niter; iter++) { lat0m = (lat0 + lat)/2.0; world[wcs->lat] = lat0m; if ((err = wcsfwd(ctype, wcs, world, crval, cel, phi, theta, prj, imgcrd, lin, pixcrd))) { return err; } d0m = fabs(pixcrd[mixpix] - pixmix); if (d0m < tol) return 0; lat1m = (lat1 + lat)/2.0; world[wcs->lat] = lat1m; if ((err = wcsfwd(ctype, wcs, world, crval, cel, phi, theta, prj, imgcrd, lin, pixcrd))) { return err; } d1m = fabs(pixcrd[mixpix] - pixmix); if (d1m < tol) return 0; if (d0m < d && d0m <= d1m) { lat1 = lat; d1 = d; lat = lat0m; d = d0m; } else if (d1m < d) { lat0 = lat; d0 = d; lat = lat1m; d = d1m; } else { lat0 = lat0m; d0 = d0m; lat1 = lat1m; d1 = d1m; } } } } } else { /* Celestial latitude is given. */ /* Check whether the solution interval is a crossing interval. */ lng0 = span[0]; world[wcs->lng] = lng0; if ((err = wcsfwd(ctype, wcs, world, crval, cel, phi, theta, prj, imgcrd, lin, pixcrd))) { return err; } d0 = pixcrd[mixpix] - pixmix; dabs = fabs(d0); if (dabs < tol) return 0; lng1 = span[1]; world[wcs->lng] = lng1; if ((err = wcsfwd(ctype, wcs, world, crval, cel, phi, theta, prj, imgcrd, lin, pixcrd))) { return err; } d1 = pixcrd[mixpix] - pixmix; dabs = fabs(d1); if (dabs < tol) return 0; lmin = lng1; dmin = dabs; /* Check for a crossing point. */ if (signb(d0) != signb(d1)) { crossed = 1; dx = d1; } else { crossed = 0; lng0 = span[1]; } for (retry = 0; retry < 4; retry++) { /* Refine the solution interval. */ while (lng0 > span[0]) { lng0 -= step; if (lng0 < span[0]) lng0 = span[0]; world[wcs->lng] = lng0; if ((err = wcsfwd(ctype, wcs, world, crval, cel, phi, theta, prj, imgcrd, lin, pixcrd))) { return err; } d0 = pixcrd[mixpix] - pixmix; /* Check for a solution. */ dabs = fabs(d0); if (dabs < tol) return 0; /* Record the point of closest approach. */ if (dabs < dmin) { lmin = lng0; dmin = dabs; } /* Check for a crossing point. */ if (signb(d0) != signb(d1)) { crossed = 2; dx = d0; break; } /* Advance to the next subinterval. */ lng1 = lng0; d1 = d0; } if (crossed) { /* A crossing point was found. */ for (iter = 0; iter < niter; iter++) { /* Use regula falsi division of the interval. */ lambda = d0/(d0-d1); if (lambda < 0.1) { lambda = 0.1; } else if (lambda > 0.9) { lambda = 0.9; } dlng = lng1 - lng0; lng = lng0 + lambda*dlng; world[wcs->lng] = lng; if ((err = wcsfwd(ctype, wcs, world, crval, cel, phi, theta, prj, imgcrd, lin, pixcrd))) { return err; } /* Check for a solution. */ d = pixcrd[mixpix] - pixmix; dabs = fabs(d); if (dabs < tol) return 0; if (dlng < tol) { /* An artifact of numerical imprecision. */ if (dabs < tol2) return 0; /* Must be a discontinuity. */ break; } /* Record the point of closest approach. */ if (dabs < dmin) { lmin = lng; dmin = dabs; } if (signb(d0) == signb(d)) { lng0 = lng; d0 = d; } else { lng1 = lng; d1 = d; } } /* No convergence, must have been a discontinuity. */ if (crossed == 1) lng0 = span[1]; lng1 = lng0; d1 = dx; crossed = 0; } else { /* No crossing point; look for a tangent point. */ if (lmin == span[0]) break; if (lmin == span[1]) break; lng = lmin; lng0 = lng - step; if (lng0 < span[0]) lng0 = span[0]; lng1 = lng + step; if (lng1 > span[1]) lng1 = span[1]; world[wcs->lng] = lng0; if ((err = wcsfwd(ctype, wcs, world, crval, cel, phi, theta, prj, imgcrd, lin, pixcrd))) { return err; } d0 = fabs(pixcrd[mixpix] - pixmix); d = dmin; world[wcs->lng] = lng1; if ((err = wcsfwd(ctype, wcs, world, crval, cel, phi, theta, prj, imgcrd, lin, pixcrd))) { return err; } d1 = fabs(pixcrd[mixpix] - pixmix); for (iter = 0; iter < niter; iter++) { lng0m = (lng0 + lng)/2.0; world[wcs->lng] = lng0m; if ((err = wcsfwd(ctype, wcs, world, crval, cel, phi, theta, prj, imgcrd, lin, pixcrd))) { return err; } d0m = fabs(pixcrd[mixpix] - pixmix); if (d0m < tol) return 0; lng1m = (lng1 + lng)/2.0; world[wcs->lng] = lng1m; if ((err = wcsfwd(ctype, wcs, world, crval, cel, phi, theta, prj, imgcrd, lin, pixcrd))) { return err; } d1m = fabs(pixcrd[mixpix] - pixmix); if (d1m < tol) return 0; if (d0m < d && d0m <= d1m) { lng1 = lng; d1 = d; lng = lng0m; d = d0m; } else if (d1m < d) { lng0 = lng; d0 = d; lng = lng1m; d = d1m; } else { lng0 = lng0m; d0 = d0m; lng1 = lng1m; d1 = d1m; } } } } } } /* Set cel0 to the unity transformation. */ cel0.flag = CELSET; cel0.ref[0] = cel->ref[0]; cel0.ref[1] = cel->ref[1]; cel0.ref[2] = cel->ref[2]; cel0.ref[3] = cel->ref[3]; cel0.euler[0] = -90.0; cel0.euler[1] = 0.0; cel0.euler[2] = 90.0; cel0.euler[3] = 1.0; cel0.euler[4] = 0.0; /* No convergence, check for aberrant behaviour at a native pole. */ *theta = -90.0; for (j = 1; j <= 2; j++) { /* Could the celestial coordinate element map to a native pole? */ *theta = -*theta; err = sphrev(0.0, *theta, cel->euler, &lng, &lat); if (mixcel == 1) { if (fabs(fmod(world[wcs->lng]-lng,360.0)) > tol) continue; if (lat < span[0]) continue; if (lat > span[1]) continue; world[wcs->lat] = lat; } else { if (fabs(world[wcs->lat]-lat) > tol) continue; if (lng < span[0]) lng += 360.0; if (lng > span[1]) lng -= 360.0; if (lng < span[0]) continue; if (lng > span[1]) continue; world[wcs->lng] = lng; } /* Is there a solution for the given pixel coordinate element? */ lng = world[wcs->lng]; lat = world[wcs->lat]; /* Feed native coordinates to wcsfwd() with cel0 set to unity. */ world[wcs->lng] = -180.0; world[wcs->lat] = *theta; if ((err = wcsfwd(ctype, wcs, world, crval, &cel0, phi, theta, prj, imgcrd, lin, pixcrd))) { return err; } d0 = pixcrd[mixpix] - pixmix; /* Check for a solution. */ if (fabs(d0) < tol) { /* Recall saved world coordinates. */ world[wcs->lng] = lng; world[wcs->lat] = lat; return 0; } /* Search for a crossing interval. */ phi0 = -180.0; for (k = -179; k <= 180; k++) { phi1 = (double) k; world[wcs->lng] = phi1; if ((err = wcsfwd(ctype, wcs, world, crval, &cel0, phi, theta, prj, imgcrd, lin, pixcrd))) { return err; } d1 = pixcrd[mixpix] - pixmix; /* Check for a solution. */ dabs = fabs(d1); if (dabs < tol) { /* Recall saved world coordinates. */ world[wcs->lng] = lng; world[wcs->lat] = lat; return 0; } /* Is it a crossing interval? */ if (signb(d0) != signb(d1)) break; phi0 = phi1; d0 = d1; } for (iter = 1; iter <= niter; iter++) { /* Use regula falsi division of the interval. */ lambda = d0/(d0-d1); if (lambda < 0.1) { lambda = 0.1; } else if (lambda > 0.9) { lambda = 0.9; } dphi = phi1 - phi0; world[wcs->lng] = phi0 + lambda*dphi; if ((err = wcsfwd(ctype, wcs, world, crval, &cel0, phi, theta, prj, imgcrd, lin, pixcrd))) { return err; } /* Check for a solution. */ d = pixcrd[mixpix] - pixmix; dabs = fabs(d); if (dabs < tol || (dphi < tol && dabs < tol2)) { /* Recall saved world coordinates. */ world[wcs->lng] = lng; world[wcs->lat] = lat; return 0; } if (signb(d0) == signb(d)) { phi0 = world[wcs->lng]; d0 = d; } else { phi1 = world[wcs->lng]; d1 = d; } } } /* No solution. */ return 5; } /* Dec 20 1999 Doug Mink - Change signbit() to signb() and always define it * Dec 20 1999 Doug Mink - Include wcslib.h, which includes wcs.h, wcstrig.h * * Mar 20 2001 Doug Mink - Include stdio.h for sprintf() * Mar 20 2001 Doug Mink - Add () around err assignments in if statements * Sep 19 2001 Doug Mink - Add above changes to WCSLIB-2.7 version * * Mar 15 2002 Doug Mink - Add above changes to WCSLIB-2.8.2 * Apr 3 2002 Mark Calabretta - Fix bug in code checking section * * Jun 20 2006 Doug Mink - Initialized uninitialized variables */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/wcslib.h000066400000000000000000000314571215713201500217210ustar00rootroot00000000000000#ifndef wcslib_h_ #define wcslib_h_ /*============================================================================= * * WCSLIB - an implementation of the FITS WCS proposal. * Copyright (C) 1995-2002, Mark Calabretta * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Correspondence concerning WCSLIB may be directed to: * Internet email: mcalabre@atnf.csiro.au * Postal address: Dr. Mark Calabretta, * Australia Telescope National Facility, * P.O. Box 76, * Epping, NSW, 2121, * AUSTRALIA * * Author: Mark Calabretta, Australia Telescope National Facility * $Id: wcslib.h,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ *===========================================================================*/ #ifdef __cplusplus extern "C" { #endif #if !defined(__STDC__) && !defined(__cplusplus) #ifndef const #define const #endif #endif extern int npcode; extern char pcodes[26][4]; struct prjprm { char code[4]; int flag; double phi0, theta0; double r0; double p[10]; double w[20]; int n; #if __STDC__ || defined(__cplusplus) int (*prjfwd)(const double, const double, struct prjprm *, double *, double *); int (*prjrev)(const double, const double, struct prjprm *, double *, double *); #else int (*prjfwd)(); int (*prjrev)(); #endif }; #if __STDC__ || defined(__cplusplus) int prjset(const char [], struct prjprm *); int prjfwd(const double, const double, struct prjprm *, double *, double *); int prjrev(const double, const double, struct prjprm *, double *, double *); int azpset(struct prjprm *); int azpfwd(const double, const double, struct prjprm *, double *, double *); int azprev(const double, const double, struct prjprm *, double *, double *); int szpset(struct prjprm *); int szpfwd(const double, const double, struct prjprm *, double *, double *); int szprev(const double, const double, struct prjprm *, double *, double *); int tanset(struct prjprm *); int tanfwd(const double, const double, struct prjprm *, double *, double *); int tanrev(const double, const double, struct prjprm *, double *, double *); int stgset(struct prjprm *); int stgfwd(const double, const double, struct prjprm *, double *, double *); int stgrev(const double, const double, struct prjprm *, double *, double *); int sinset(struct prjprm *); int sinfwd(const double, const double, struct prjprm *, double *, double *); int sinrev(const double, const double, struct prjprm *, double *, double *); int arcset(struct prjprm *); int arcfwd(const double, const double, struct prjprm *, double *, double *); int arcrev(const double, const double, struct prjprm *, double *, double *); int zpnset(struct prjprm *); int zpnfwd(const double, const double, struct prjprm *, double *, double *); int zpnrev(const double, const double, struct prjprm *, double *, double *); int zeaset(struct prjprm *); int zeafwd(const double, const double, struct prjprm *, double *, double *); int zearev(const double, const double, struct prjprm *, double *, double *); int airset(struct prjprm *); int airfwd(const double, const double, struct prjprm *, double *, double *); int airrev(const double, const double, struct prjprm *, double *, double *); int cypset(struct prjprm *); int cypfwd(const double, const double, struct prjprm *, double *, double *); int cyprev(const double, const double, struct prjprm *, double *, double *); int ceaset(struct prjprm *); int ceafwd(const double, const double, struct prjprm *, double *, double *); int cearev(const double, const double, struct prjprm *, double *, double *); int carset(struct prjprm *); int carfwd(const double, const double, struct prjprm *, double *, double *); int carrev(const double, const double, struct prjprm *, double *, double *); int merset(struct prjprm *); int merfwd(const double, const double, struct prjprm *, double *, double *); int merrev(const double, const double, struct prjprm *, double *, double *); int sflset(struct prjprm *); int sflfwd(const double, const double, struct prjprm *, double *, double *); int sflrev(const double, const double, struct prjprm *, double *, double *); int parset(struct prjprm *); int parfwd(const double, const double, struct prjprm *, double *, double *); int parrev(const double, const double, struct prjprm *, double *, double *); int molset(struct prjprm *); int molfwd(const double, const double, struct prjprm *, double *, double *); int molrev(const double, const double, struct prjprm *, double *, double *); int aitset(struct prjprm *); int aitfwd(const double, const double, struct prjprm *, double *, double *); int aitrev(const double, const double, struct prjprm *, double *, double *); int copset(struct prjprm *); int copfwd(const double, const double, struct prjprm *, double *, double *); int coprev(const double, const double, struct prjprm *, double *, double *); int coeset(struct prjprm *); int coefwd(const double, const double, struct prjprm *, double *, double *); int coerev(const double, const double, struct prjprm *, double *, double *); int codset(struct prjprm *); int codfwd(const double, const double, struct prjprm *, double *, double *); int codrev(const double, const double, struct prjprm *, double *, double *); int cooset(struct prjprm *); int coofwd(const double, const double, struct prjprm *, double *, double *); int coorev(const double, const double, struct prjprm *, double *, double *); int bonset(struct prjprm *); int bonfwd(const double, const double, struct prjprm *, double *, double *); int bonrev(const double, const double, struct prjprm *, double *, double *); int pcoset(struct prjprm *); int pcofwd(const double, const double, struct prjprm *, double *, double *); int pcorev(const double, const double, struct prjprm *, double *, double *); int tscset(struct prjprm *); int tscfwd(const double, const double, struct prjprm *, double *, double *); int tscrev(const double, const double, struct prjprm *, double *, double *); int cscset(struct prjprm *); int cscfwd(const double, const double, struct prjprm *, double *, double *); int cscrev(const double, const double, struct prjprm *, double *, double *); int qscset(struct prjprm *); int qscfwd(const double, const double, struct prjprm *, double *, double *); int qscrev(const double, const double, struct prjprm *, double *, double *); #else int prjset(), prjfwd(), prjrev(); int azpset(), azpfwd(), azprev(); int szpset(), szpfwd(), szprev(); int tanset(), tanfwd(), tanrev(); int stgset(), stgfwd(), stgrev(); int sinset(), sinfwd(), sinrev(); int arcset(), arcfwd(), arcrev(); int zpnset(), zpnfwd(), zpnrev(); int zeaset(), zeafwd(), zearev(); int airset(), airfwd(), airrev(); int cypset(), cypfwd(), cyprev(); int ceaset(), ceafwd(), cearev(); int carset(), carfwd(), carrev(); int merset(), merfwd(), merrev(); int sflset(), sflfwd(), sflrev(); int parset(), parfwd(), parrev(); int molset(), molfwd(), molrev(); int aitset(), aitfwd(), aitrev(); int copset(), copfwd(), coprev(); int coeset(), coefwd(), coerev(); int codset(), codfwd(), codrev(); int cooset(), coofwd(), coorev(); int bonset(), bonfwd(), bonrev(); int pcoset(), pcofwd(), pcorev(); int tscset(), tscfwd(), tscrev(); int cscset(), cscfwd(), cscrev(); int qscset(), qscfwd(), qscrev(); #endif extern const char *prjset_errmsg[]; extern const char *prjfwd_errmsg[]; extern const char *prjrev_errmsg[]; #define PRJSET 137 struct celprm { int flag; double ref[4]; double euler[5]; }; #if __STDC__ || defined(__cplusplus) int celset(const char *, struct celprm *, struct prjprm *); int celfwd(const char *, const double, const double, struct celprm *, double *, double *, struct prjprm *, double *, double *); int celrev(const char *, const double, const double, struct prjprm *, double *, double *, struct celprm *, double *, double *); #else int celset(), celfwd(), celrev(); #endif extern const char *celset_errmsg[]; extern const char *celfwd_errmsg[]; extern const char *celrev_errmsg[]; #define CELSET 137 struct linprm { int flag; int naxis; double *crpix; double *pc; double *cdelt; /* Intermediates. */ double *piximg; double *imgpix; }; #if __STDC__ || defined(__cplusplus) int linset(struct linprm *); int linfwd(const double[], struct linprm *, double[]); int linrev(const double[], struct linprm *, double[]); int matinv(const int, const double [], double []); #else int linset(), linfwd(), linrev(), matinv(); #endif extern const char *linset_errmsg[]; extern const char *linfwd_errmsg[]; extern const char *linrev_errmsg[]; #define LINSET 137 struct wcsprm { int flag; char pcode[4]; char lngtyp[5], lattyp[5]; int lng, lat; int cubeface; }; #if __STDC__ || defined(__cplusplus) int wcsset(const int, const char[][9], struct wcsprm *); int wcsfwd(const char[][9], struct wcsprm *, const double[], const double[], struct celprm *, double *, double *, struct prjprm *, double[], struct linprm *, double[]); int wcsrev(const char[][9], struct wcsprm *, const double[], struct linprm *, double[], struct prjprm *, double *, double *, const double[], struct celprm *, double[]); int wcsmix(const char[][9], struct wcsprm *, const int, const int, const double[], const double, int, double[], const double[], struct celprm *, double *, double *, struct prjprm *, double[], struct linprm *, double[]); #else int wcsset(), wcsfwd(), wcsrev(), wcsmix(); #endif extern const char *wcsset_errmsg[]; extern const char *wcsfwd_errmsg[]; extern const char *wcsrev_errmsg[]; extern const char *wcsmix_errmsg[]; #define WCSSET 137 #if __STDC__ || defined(__cplusplus) int sphfwd(const double, const double, const double [], double *, double *); int sphrev(const double, const double, const double [], double *, double *); #else int sphfwd(), sphrev(); #endif #ifdef PI #undef PI #endif #ifdef D2R #undef D2R #endif #ifdef R2D #undef R2D #endif #ifdef SQRT2 #undef SQRT2 #endif #ifdef SQRT2INV #undef SQRT2INV #endif #define PI 3.141592653589793238462643 #define D2R PI/180.0 #define R2D 180.0/PI #define SQRT2 1.4142135623730950488 #define SQRT2INV 1.0/SQRT2 #if !defined(__STDC__) && !defined(__cplusplus) #ifndef const #define const #endif #endif #if __STDC__ || defined(__cplusplus) double cosdeg(const double); double sindeg(const double); double tandeg(const double); double acosdeg(const double); double asindeg(const double); double atandeg(const double); double atan2deg(const double, const double); #else double cosdeg(); double sindeg(); double tandeg(); double acosdeg(); double asindeg(); double atandeg(); double atan2deg(); #endif /* Domain tolerance for asin and acos functions. */ #define WCSTRIG_TOL 1e-10 #ifdef __cplusplus } #endif #endif /* wcslib_h_ */ /* Feb 3 2000 Doug Mink - Make cplusplus ifdefs for braces all-inclusive * * Feb 15 2001 Doug Mink - Undefine math constants if already defined * Sep 19 2001 Doug Mink - Update for WCSLIB 2.7, especially proj.h and cel.h * * Mar 12 2002 Doug Mink - Update for WCSLIB 2.8.2, especially proj.h * Nov 29 2006 Doug Mink - Drop semicolon at end of C++ ifdef * Jan 4 2007 Doug Mink - Drop extra declarations of SZP subroutines */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/wcstrig.c000066400000000000000000000106261215713201500221060ustar00rootroot00000000000000/*============================================================================ * * WCSLIB - an implementation of the FITS WCS proposal. * Copyright (C) 1995-2002, Mark Calabretta * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Correspondence concerning WCSLIB may be directed to: * Internet email: mcalabre@atnf.csiro.au * Postal address: Dr. Mark Calabretta, * Australia Telescope National Facility, * P.O. Box 76, * Epping, NSW, 2121, * AUSTRALIA * *============================================================================= * * The functions defined herein are trigonometric or inverse trigonometric * functions which take or return angular arguments in decimal degrees. * * $Id: wcstrig.c,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ *---------------------------------------------------------------------------*/ #include #include "wcslib.h" const double d2r = PI / 180.0; const double r2d = 180.0 / PI; double cosdeg (angle) const double angle; { double resid; resid = fabs(fmod(angle,360.0)); if (resid == 0.0) { return 1.0; } else if (resid == 90.0) { return 0.0; } else if (resid == 180.0) { return -1.0; } else if (resid == 270.0) { return 0.0; } return cos(angle*d2r); } /*--------------------------------------------------------------------------*/ double sindeg (angle) const double angle; { double resid; resid = fmod(angle-90.0,360.0); if (resid == 0.0) { return 1.0; } else if (resid == 90.0) { return 0.0; } else if (resid == 180.0) { return -1.0; } else if (resid == 270.0) { return 0.0; } return sin(angle*d2r); } /*--------------------------------------------------------------------------*/ double tandeg (angle) const double angle; { double resid; resid = fmod(angle,360.0); if (resid == 0.0 || fabs(resid) == 180.0) { return 0.0; } else if (resid == 45.0 || resid == 225.0) { return 1.0; } else if (resid == -135.0 || resid == -315.0) { return -1.0; } return tan(angle*d2r); } /*--------------------------------------------------------------------------*/ double acosdeg(v) const double v; { if (v >= 1.0) { if (v-1.0 < WCSTRIG_TOL) return 0.0; } else if (v == 0.0) { return 90.0; } else if (v <= -1.0) { if (v+1.0 > -WCSTRIG_TOL) return 180.0; } return acos(v)*r2d; } /*--------------------------------------------------------------------------*/ double asindeg (v) const double v; { if (v <= -1.0) { if (v+1.0 > -WCSTRIG_TOL) return -90.0; } else if (v == 0.0) { return 0.0; } else if (v >= 1.0) { if (v-1.0 < WCSTRIG_TOL) return 90.0; } return asin(v)*r2d; } /*--------------------------------------------------------------------------*/ double atandeg (v) const double v; { if (v == -1.0) { return -45.0; } else if (v == 0.0) { return 0.0; } else if (v == 1.0) { return 45.0; } return atan(v)*r2d; } /*--------------------------------------------------------------------------*/ double atan2deg (y, x) const double x, y; { if (y == 0.0) { if (x >= 0.0) { return 0.0; } else if (x < 0.0) { return 180.0; } } else if (x == 0.0) { if (y > 0.0) { return 90.0; } else if (y < 0.0) { return -90.0; } } return atan2(y,x)*r2d; } /* Dec 20 1999 Doug Mink - Change cosd() and sind() to cosdeg() and sindeg() * Dec 20 1999 Doug Mink - Include wcslib.h, which includes wcstrig.h * Dec 20 1999 Doug Mink - Use PI from wcslib.h, not locally defined * * Sep 19 2001 Doug Mink - No change for WCSLIB 2.7 */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/wcstrig.h000066400000000000000000000016761215713201500221200ustar00rootroot00000000000000#ifndef wcstrig_h_ #define wcstrig_h_ #include #ifdef __cplusplus extern "C" { #endif #if !defined(__STDC__) && !defined(__cplusplus) #ifndef const #define const #endif #endif #ifdef TRIGD #include #else /* not TRIGD */ #if __STDC__ || defined(__cplusplus) double cosdeg(const double); double sindeg(const double); double tandeg(const double); double acosdeg(const double); double asindeg(const double); double atandeg(const double); double atan2deg(const double, const double); #else double cosdeg(); double sindeg(); double tandeg(); double acosdeg(); double asindeg(); double atandeg(); double atan2deg(); #endif /* Domain tolerance for asin and acos functions. */ #define WCSTRIG_TOL 1e-10 #endif /* TRIGD */ #ifdef __cplusplus }; #endif #endif /* wcstrig_h_ */ /* Apr 15 1998 "deg" added to function names by Doug Mink, SAO * May 27 1998 ifndef WCSTRIG changed to ifndef wcstrig_h_ */ skycat-3.1.2-starlink-1b/astrotcl/libwcs/worldpos.c000066400000000000000000000501341215713201500222730ustar00rootroot00000000000000/* worldpos.c -- WCS Algorithms from Classic AIPS. * June 20, 2006 * Copyright (C) 1994-2006 * Associated Universities, Inc. Washington DC, USA. * With code added by Doug Mink, Smithsonian Astrophysical Observatory * and Allan Brighton and Andreas Wicenec, ESO * Module: worldpos.c * Purpose: Perform forward and reverse WCS computations for 8 projections * Subroutine: worldpos() converts from pixel location to RA,Dec * Subroutine: worldpix() converts from RA,Dec to pixel location -=-=-=-=-=-=- This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Correspondence concerning AIPS should be addressed as follows: Internet email: aipsmail@nrao.edu Postal address: AIPS Group National Radio Astronomy Observatory 520 Edgemont Road Charlottesville, VA 22903-2475 USA -=-=-=-=-=-=- These two ANSI C functions, worldpos() and worldpix(), perform forward and reverse WCS computations for 8 types of projective geometries ("-SIN", "-TAN", "-ARC", "-NCP", "-GLS" or "-SFL", "-MER", "-AIT", "-STG", "CAR", and "COE"): worldpos() converts from pixel location to RA,Dec worldpix() converts from RA,Dec to pixel location where "(RA,Dec)" are more generically (long,lat). These functions are based on the WCS implementation of Classic AIPS, an implementation which has been in production use for more than ten years. See the two memos by Eric Greisen ftp://fits.cv.nrao.edu/fits/documents/wcs/aips27.ps.Z ftp://fits.cv.nrao.edu/fits/documents/wcs/aips46.ps.Z for descriptions of the 8 projective geometries and the algorithms. Footnotes in these two documents describe the differences between these algorithms and the 1993-94 WCS draft proposal (see URL below). In particular, these algorithms support ordinary field rotation, but not skew geometries (CD or PC matrix cases). Also, the MER and AIT algorithms work correctly only for CRVALi=(0,0). Users should note that GLS projections with yref!=0 will behave differently in this code than in the draft WCS proposal. The NCP projection is now obsolete (it is a special case of SIN). WCS syntax and semantics for various advanced features is discussed in the draft WCS proposal by Greisen and Calabretta at: ftp://fits.cv.nrao.edu/fits/documents/wcs/wcs.all.ps.Z -=-=-=- The original version of this code was Emailed to D.Wells on Friday, 23 September by Bill Cotton , who described it as a "..more or less.. exact translation from the AIPSish..". Changes were made by Don Wells during the period October 11-13, 1994: 1) added GNU license and header comments 2) added testpos.c program to perform extensive circularity tests 3) changed float-->double to get more than 7 significant figures 4) testpos.c circularity test failed on MER and AIT. B.Cotton found that "..there were a couple of lines of code [in] the wrong place as a result of merging several Fortran routines." 5) testpos.c found 0h wraparound in worldpix() and worldpos(). 6) E.Greisen recommended removal of various redundant if-statements, and addition of a 360d difference test to MER case of worldpos(). 7) D.Mink changed input to data structure and implemented rotation matrix. */ #include #include #include #include "wcs.h" int worldpos (xpix, ypix, wcs, xpos, ypos) /* Routine to determine accurate position for pixel coordinates */ /* returns 0 if successful otherwise 1 = angle too large for projection; */ /* does: -SIN, -TAN, -ARC, -NCP, -GLS or -SFL, -MER, -AIT projections */ /* anything else is linear */ /* Input: */ double xpix; /* x pixel number (RA or long without rotation) */ double ypix; /* y pixel number (Dec or lat without rotation) */ struct WorldCoor *wcs; /* WCS parameter structure */ /* Output: */ double *xpos; /* x (RA) coordinate (deg) */ double *ypos; /* y (dec) coordinate (deg) */ { double cosr, sinr, dx, dy, dz, tx; double sins, coss, dt, l, m, mg, da, dd, cos0, sin0; double rat = 0.0; double dect = 0.0; double mt, a, y0, td, r2; /* allan: for COE */ double dec0, ra0, decout, raout; double geo1, geo2, geo3; double cond2r=1.745329252e-2; double twopi = 6.28318530717959; double deps = 1.0e-5; /* Structure elements */ double xref; /* X reference coordinate value (deg) */ double yref; /* Y reference coordinate value (deg) */ double xrefpix; /* X reference pixel */ double yrefpix; /* Y reference pixel */ double xinc; /* X coordinate increment (deg) */ double yinc; /* Y coordinate increment (deg) */ double rot; /* Optical axis rotation (deg) (N through E) */ int itype = wcs->prjcode; /* Set local projection parameters */ xref = wcs->xref; yref = wcs->yref; xrefpix = wcs->xrefpix; yrefpix = wcs->yrefpix; xinc = wcs->xinc; yinc = wcs->yinc; rot = degrad (wcs->rot); cosr = cos (rot); sinr = sin (rot); /* Offset from ref pixel */ dx = xpix - xrefpix; dy = ypix - yrefpix; /* Scale and rotate using CD matrix */ if (wcs->rotmat) { tx = dx * wcs->cd[0] + dy * wcs->cd[1]; dy = dx * wcs->cd[2] + dy * wcs->cd[3]; dx = tx; } /* Scale and rotate using CDELTn and CROTA2 */ else { /* Check axis increments - bail out if either 0 */ if ((xinc==0.0) || (yinc==0.0)) { *xpos=0.0; *ypos=0.0; return 2; } /* Scale using CDELT */ dx = dx * xinc; dy = dy * yinc; /* Take out rotation from CROTA */ if (rot != 0.0) { tx = dx * cosr - dy * sinr; dy = dx * sinr + dy * cosr; dx = tx; } } /* Flip coordinates if necessary */ if (wcs->coorflip) { tx = dx; dx = dy; dy = tx; } /* Default, linear result for error or pixel return */ *xpos = xref + dx; *ypos = yref + dy; if (itype <= 0) return 0; /* Convert to radians */ if (wcs->coorflip) { dec0 = degrad (xref); ra0 = degrad (yref); } else { ra0 = degrad (xref); dec0 = degrad (yref); } l = degrad (dx); m = degrad (dy); sins = l*l + m*m; decout = 0.0; raout = 0.0; cos0 = cos (dec0); sin0 = sin (dec0); /* Process by case */ switch (itype) { case WCS_CAR: /* -CAR Cartesian (was WCS_PIX pixel and WCS_LIN linear) */ rat = ra0 + l; dect = dec0 + m; break; case WCS_SIN: /* -SIN sin*/ if (sins>1.0) return 1; coss = sqrt (1.0 - sins); dt = sin0 * coss + cos0 * m; if ((dt>1.0) || (dt<-1.0)) return 1; dect = asin (dt); rat = cos0 * coss - sin0 * m; if ((rat==0.0) && (l==0.0)) return 1; rat = atan2 (l, rat) + ra0; break; case WCS_TAN: /* -TAN tan */ case WCS_TNX: /* -TNX tan with polynomial correction */ if (sins>1.0) return 1; dect = cos0 - m * sin0; if (dect==0.0) return 1; rat = ra0 + atan2 (l, dect); dect = atan (cos(rat-ra0) * (m * cos0 + sin0) / dect); break; case WCS_ARC: /* -ARC Arc*/ if (sins>=twopi*twopi/4.0) return 1; sins = sqrt(sins); coss = cos (sins); if (sins!=0.0) sins = sin (sins) / sins; else sins = 1.0; dt = m * cos0 * sins + sin0 * coss; if ((dt>1.0) || (dt<-1.0)) return 1; dect = asin (dt); da = coss - dt * sin0; dt = l * sins * cos0; if ((da==0.0) && (dt==0.0)) return 1; rat = ra0 + atan2 (dt, da); break; case WCS_NCP: /* -NCP North celestial pole*/ dect = cos0 - m * sin0; if (dect==0.0) return 1; rat = ra0 + atan2 (l, dect); dt = cos (rat-ra0); if (dt==0.0) return 1; dect = dect / dt; if ((dect>1.0) || (dect<-1.0)) return 1; dect = acos (dect); if (dec0<0.0) dect = -dect; break; case WCS_GLS: /* -GLS global sinusoid */ case WCS_SFL: /* -SFL Samson-Flamsteed */ dect = dec0 + m; if (fabs(dect)>twopi/4.0) return 1; coss = cos (dect); if (fabs(l)>twopi*coss/2.0) return 1; rat = ra0; if (coss>deps) rat = rat + l / coss; break; case WCS_MER: /* -MER mercator*/ dt = yinc * cosr + xinc * sinr; if (dt==0.0) dt = 1.0; dy = degrad (yref/2.0 + 45.0); dx = dy + dt / 2.0 * cond2r; dy = log (tan (dy)); dx = log (tan (dx)); geo2 = degrad (dt) / (dx - dy); geo3 = geo2 * dy; geo1 = cos (degrad (yref)); if (geo1<=0.0) geo1 = 1.0; rat = l / geo1 + ra0; if (fabs(rat - ra0) > twopi) return 1; /* added 10/13/94 DCW/EWG */ dt = 0.0; if (geo2!=0.0) dt = (m + geo3) / geo2; dt = exp (dt); dect = 2.0 * atan (dt) - twopi / 4.0; break; case WCS_AIT: /* -AIT Aitoff*/ dt = yinc*cosr + xinc*sinr; if (dt==0.0) dt = 1.0; dt = degrad (dt); dy = degrad (yref); dx = sin(dy+dt)/sqrt((1.0+cos(dy+dt))/2.0) - sin(dy)/sqrt((1.0+cos(dy))/2.0); if (dx==0.0) dx = 1.0; geo2 = dt / dx; dt = xinc*cosr - yinc* sinr; if (dt==0.0) dt = 1.0; dt = degrad (dt); dx = 2.0 * cos(dy) * sin(dt/2.0); if (dx==0.0) dx = 1.0; geo1 = dt * sqrt((1.0+cos(dy)*cos(dt/2.0))/2.0) / dx; geo3 = geo2 * sin(dy) / sqrt((1.0+cos(dy))/2.0); rat = ra0; dect = dec0; if ((l==0.0) && (m==0.0)) break; dz = 4.0 - l*l/(4.0*geo1*geo1) - ((m+geo3)/geo2)*((m+geo3)/geo2) ; if ((dz>4.0) || (dz<2.0)) return 1;; dz = 0.5 * sqrt (dz); dd = (m+geo3) * dz / geo2; if (fabs(dd)>1.0) return 1;; dd = asin (dd); if (fabs(cos(dd))1.0) return 1;; da = asin (da); rat = ra0 + 2.0 * da; dect = dd; break; case WCS_STG: /* -STG Sterographic*/ dz = (4.0 - sins) / (4.0 + sins); if (fabs(dz)>1.0) return 1; dect = dz * sin0 + m * cos0 * (1.0+dz) / 2.0; if (fabs(dect)>1.0) return 1; dect = asin (dect); rat = cos(dect); if (fabs(rat)1.0) return 1; rat = asin (rat); mg = 1.0 + sin(dect) * sin0 + cos(dect) * cos0 * cos(rat); if (fabs(mg)deps) rat = twopi/2.0 - rat; rat = ra0 + rat; break; case WCS_COE: /* COE projection code from Andreas Wicenic, ESO */ td = tan (dec0); y0 = 1.0 / td; mt = y0 - m; if (dec0 < 0.) a = atan2 (l,-mt); else a = atan2 (l, mt); rat = ra0 - (a / sin0); r2 = (l * l) + (mt * mt); dect = asin (1.0 / (sin0 * 2.0) * (1.0 + sin0*sin0 * (1.0 - r2))); break; } /* Return RA in range */ raout = rat; decout = dect; if (raout-ra0>twopi/2.0) raout = raout - twopi; if (raout-ra0<-twopi/2.0) raout = raout + twopi; if (raout < 0.0) raout += twopi; /* added by DCW 10/12/94 */ /* Convert units back to degrees */ *xpos = raddeg (raout); *ypos = raddeg (decout); return 0; } /* End of worldpos */ int worldpix (xpos, ypos, wcs, xpix, ypix) /*-----------------------------------------------------------------------*/ /* routine to determine accurate pixel coordinates for an RA and Dec */ /* returns 0 if successful otherwise: */ /* 1 = angle too large for projection; */ /* 2 = bad values */ /* does: SIN, TAN, ARC, NCP, GLS or SFL, MER, AIT, STG, CAR, COE projections */ /* anything else is linear */ /* Input: */ double xpos; /* x (RA) coordinate (deg) */ double ypos; /* y (dec) coordinate (deg) */ struct WorldCoor *wcs; /* WCS parameter structure */ /* Output: */ double *xpix; /* x pixel number (RA or long without rotation) */ double *ypix; /* y pixel number (dec or lat without rotation) */ { double dx, dy, ra0, dec0, ra, dec, coss, sins, dt, da, dd, sint; double l, m, geo1, geo2, geo3, sinr, cosr, tx, x, a2, a3, a4; double rthea,gamby2,a,b,c,phi,an,rap,v,tthea,co1,co2,co3,co4,ansq; /* COE */ double cond2r=1.745329252e-2, deps=1.0e-5, twopi=6.28318530717959; /* Structure elements */ double xref; /* x reference coordinate value (deg) */ double yref; /* y reference coordinate value (deg) */ double xrefpix; /* x reference pixel */ double yrefpix; /* y reference pixel */ double xinc; /* x coordinate increment (deg) */ double yinc; /* y coordinate increment (deg) */ double rot; /* Optical axis rotation (deg) (from N through E) */ int itype; /* Set local projection parameters */ xref = wcs->xref; yref = wcs->yref; xrefpix = wcs->xrefpix; yrefpix = wcs->yrefpix; xinc = wcs->xinc; yinc = wcs->yinc; rot = degrad (wcs->rot); cosr = cos (rot); sinr = sin (rot); /* Projection type */ itype = wcs->prjcode; /* Nonlinear position */ if (itype > 0) { if (wcs->coorflip) { dec0 = degrad (xref); ra0 = degrad (yref); dt = xpos - yref; } else { ra0 = degrad (xref); dec0 = degrad (yref); dt = xpos - xref; } /* 0h wrap-around tests added by D.Wells 10/12/1994: */ /* Modified to exclude weird reference pixels by D.Mink 2/3/2004 */ if (xrefpix*xinc > 180.0 || xrefpix*xinc < -180.0) { if (dt > 360.0) xpos -= 360.0; if (dt < 0.0) xpos += 360.0; } else { if (dt > 180.0) xpos -= 360.0; if (dt < -180.0) xpos += 360.0; } /* NOTE: changing input argument xpos is OK (call-by-value in C!) */ ra = degrad (xpos); dec = degrad (ypos); /* Compute direction cosine */ coss = cos (dec); sins = sin (dec); l = sin(ra-ra0) * coss; sint = sins * sin(dec0) + coss * cos(dec0) * cos(ra-ra0); } else { l = 0.0; sint = 0.0; sins = 0.0; coss = 0.0; ra = 0.0; dec = 0.0; ra0 = 0.0; dec0 = 0.0; m = 0.0; } /* Process by case */ switch (itype) { case WCS_CAR: /* -CAR Cartesian */ l = ra - ra0; m = dec - dec0; break; case WCS_SIN: /* -SIN sin*/ if (sint<0.0) return 1; m = sins * cos(dec0) - coss * sin(dec0) * cos(ra-ra0); break; case WCS_TAN: /* -TAN tan */ if (sint<=0.0) return 1; m = sins * sin(dec0) + coss * cos(dec0) * cos(ra-ra0); l = l / m; m = (sins * cos(dec0) - coss * sin(dec0) * cos(ra-ra0)) / m; break; case WCS_ARC: /* -ARC Arc*/ m = sins * sin(dec0) + coss * cos(dec0) * cos(ra-ra0); if (m<-1.0) m = -1.0; if (m>1.0) m = 1.0; m = acos (m); if (m!=0) m = m / sin(m); else m = 1.0; l = l * m; m = (sins * cos(dec0) - coss * sin(dec0) * cos(ra-ra0)) * m; break; case WCS_NCP: /* -NCP North celestial pole*/ if (dec0==0.0) return 1; /* can't stand the equator */ else m = (cos(dec0) - coss * cos(ra-ra0)) / sin(dec0); break; case WCS_GLS: /* -GLS global sinusoid */ case WCS_SFL: /* -SFL Samson-Flamsteed */ dt = ra - ra0; if (fabs(dec)>twopi/4.0) return 1; if (fabs(dec0)>twopi/4.0) return 1; m = dec - dec0; l = dt * coss; break; case WCS_MER: /* -MER mercator*/ dt = yinc * cosr + xinc * sinr; if (dt==0.0) dt = 1.0; dy = degrad (yref/2.0 + 45.0); dx = dy + dt / 2.0 * cond2r; dy = log (tan (dy)); dx = log (tan (dx)); geo2 = degrad (dt) / (dx - dy); geo3 = geo2 * dy; geo1 = cos (degrad (yref)); if (geo1<=0.0) geo1 = 1.0; dt = ra - ra0; l = geo1 * dt; dt = dec / 2.0 + twopi / 8.0; dt = tan (dt); if (dttwopi/4.0) return 1; dt = yinc*cosr + xinc*sinr; if (dt==0.0) dt = 1.0; dt = degrad (dt); dy = degrad (yref); dx = sin(dy+dt)/sqrt((1.0+cos(dy+dt))/2.0) - sin(dy)/sqrt((1.0+cos(dy))/2.0); if (dx==0.0) dx = 1.0; geo2 = dt / dx; dt = xinc*cosr - yinc* sinr; if (dt==0.0) dt = 1.0; dt = degrad (dt); dx = 2.0 * cos(dy) * sin(dt/2.0); if (dx==0.0) dx = 1.0; geo1 = dt * sqrt((1.0+cos(dy)*cos(dt/2.0))/2.0) / dx; geo3 = geo2 * sin(dy) / sqrt((1.0+cos(dy))/2.0); dt = sqrt ((1.0 + cos(dec) * cos(da))/2.0); if (fabs(dt)twopi/4.0) return 1; dd = 1.0 + sins * sin(dec0) + coss * cos(dec0) * cos(da); if (fabs(dd)rotmat) l = rap * an * (1.0 - ansq/6.0) * (wcs->cd[0] / fabs(wcs->cd[0])); else l = rap * an * (1.0 - ansq/6.0) * (xinc / fabs(xinc)); m = rthea - (rap * (1.0 - ansq/2.0)); break; } /* end of itype switch */ /* Convert back to degrees */ if (itype > 0) { dx = raddeg (l); dy = raddeg (m); } /* For linear or pixel projection */ else { dx = xpos - xref; dy = ypos - yref; } if (wcs->coorflip) { tx = dx; dx = dy; dy = tx; } /* Scale and rotate using CD matrix */ if (wcs->rotmat) { tx = dx * wcs->dc[0] + dy * wcs->dc[1]; dy = dx * wcs->dc[2] + dy * wcs->dc[3]; dx = tx; } /* Scale and rotate using CDELTn and CROTA2 */ else { /* Correct for rotation */ if (rot!=0.0) { tx = dx*cosr + dy*sinr; dy = dy*cosr - dx*sinr; dx = tx; } /* Scale using CDELT */ if (xinc != 0.) dx = dx / xinc; if (yinc != 0.) dy = dy / yinc; } /* Convert to pixels */ *xpix = dx + xrefpix; if (itype == WCS_CAR) { if (*xpix > wcs->nxpix) { x = *xpix - (360.0 / xinc); if (x > 0.0) *xpix = x; } else if (*xpix < 0) { x = *xpix + (360.0 / xinc); if (x <= wcs->nxpix) *xpix = x; } } *ypix = dy + yrefpix; return 0; } /* end worldpix */ /* Oct 26 1995 Fix bug which interchanged RA and Dec twice when coorflip * * Oct 31 1996 Fix CD matrix use in WORLDPIX * Nov 4 1996 Eliminate extra code for linear projection in WORLDPIX * Nov 5 1996 Add coordinate flip in WORLDPIX * * May 22 1997 Avoid angle wraparound when CTYPE is pixel * Jun 4 1997 Return without angle conversion from worldpos if type is PIXEL * * Oct 20 1997 Add chip rotation; compute rotation angle trig functions * Jan 23 1998 Change PCODE to PRJCODE * Jan 26 1998 Remove chip rotation code * Feb 5 1998 Make cd[] and dc[] vectors; use xinc, yinc, rot from init * Feb 23 1998 Add NOAO TNX projection as TAN * Apr 28 1998 Change projection flags to WCS_* * May 27 1998 Skip limit checking for linear projection * Jun 25 1998 Fix inverse for CAR projection * Aug 5 1998 Allan Brighton: Added COE projection (code from A. Wicenec, ESO) * Sep 30 1998 Fix bug in COE inverse code to get sign correct * * Oct 21 1999 Drop unused y from worldpix() * * Apr 3 2002 Use GLS and SFL interchangeably * * Feb 3 2004 Let ra be >180 in worldpix() if ref pixel is >180 deg away * * Jun 20 2006 Initialize uninitialized variables */ skycat-3.1.2-starlink-1b/astrotcl/man/000077500000000000000000000000001215713201500175435ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/astrotcl/man/Compress.man3000066400000000000000000000077541215713201500221330ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: Compress.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 15 Jan 98 Created # NAME Compress - utility class for compressing/decompressing FITS files SYNOPSIS class Compress { protected: public: enum CompressType { NO_COMPRESS, // no compression UNIX_COMPRESS, // Compressed FITS file (UNIX) H_COMPRESS, // Hcompressed FITS file ULDA_COMPRESS, // ULDA compressed FITS file GZIP_COMPRESS // GZIPed FITS file }; Compress(); int compress(int read_fd, int write_fd, CompressType type, int compress_flag = 1); int decompress(int read_fd, int write_fd, CompressType type); int compress(const char* infile, const char* outfile, CompressType type, int compress_flag = 1, int mmap_flag = 1); int decompress(const char* infile, const char* outfile, CompressType type, int mmap_flag = 1); int compress(const char* file, CompressType type, int compress_flag = 1, int mmap_flag = 1); int decompress(const char* file, CompressType type, int mmap_flag = 1); int compress(const char* inbuf, int inbufsz, char*& outbuf, int& outbufsz, CompressType ctype, int compress_flag = 1); int decompress(const char* inbuf, int inbufsz, char*& outbuf, int& outbufsz, CompressType ctype); }; DESCRIPTION This class is a C++ wrapper around the CADC "press" routines for FITS image compression. The methods all do the same thing: compress or decompress an image. Some methods take file names as arguments, others pointers to memory areas. The type of compression is specified as an enum value "CompressType". The methods called "compress" all take an optional flag argument that indicates compression or decompression. The methods called "decompress" are shortcut, inline methods that call compress with the decompress flag on. CONSTRUCTORS Compress() Initialize the object. METHODS compress(read_fd, write_fd, type, compress_flag) Compress (or decompress), reading from the given read file descriptor and writing the results to the given write fd. If compress_flag is true, compress, otherwise decompress the file. decompress(read_fd, write_fd, type) Decompress, reading from the given read file descriptor and writing the results to the given write fd. compress(infile, outfile, type, compress_flag, mmap_flag) Compress (or decompress) the given input file and put the result in outfile. If compress_flag is true, compress, otherwise decompress the file. If mmap_flag is true, use mmap to map the file to memory. Note: we can just open the file and use the fd, but the "press" C routines do unbuffered I/O on each char, which is slow. We can mmap the file to memory and use the "mem to mem" version to improve speed somewhat. decompress(infile, outfile, type, mmap_flag) Decompress the given input file and put the result in outfile. compress(file, type, compress_flag, mmap_flag) Compress (decompress) the file in place using the given compress type. If compress_flag is true, compress, otherwise decompress the file. decompress(file, type, mmap_flag) Decompress the file in place. compress(inbuf, inbufsz, outbuf, outbufsz, ctype, compress_flag) Compress (or decompress) the contents of inbuf using the given compress type and allocate the results to outbuf. inbufsz is the size of the input buffer. outbufsz is an estimate of the outbuf size on input and the actual size on output. If compress_flag is true, compress, otherwise decompress the file. It is the caller's responsibility to free() the outbuf when no longer needed. decompress(inbuf, inbufsz, outbuf, outbufsz, ctype) Decompress inbuf and allocate results in outbuf. ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/astrotcl/man/FitsIO.man3000066400000000000000000000224721215713201500214670ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: FitsIO.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 21 Feb 96 Created # NAME FitsIO - C++ Class for Reading, Writing and Managing FITS Images SYNOPSIS #include "FitsIO.h" class FitsIO : public ImageIORep { ... public: FitsIO(int width, int height, int bitpix, double bzero, double bscale, const Mem& header, const Mem& data, fitsfile* fitsio = NULL); ~FitsIO(); int wcsinit(); int usingNetBO() const; const char* classname() const; static FitsIO* read(const char* filename, int memOptions = 0); int write(const char *filename) const; static const char* check_compress(const char* filename, char* buf, int bufsz, int& istemp, int decompress_flag = 1, int bitpix = 0); static FitsIO* initialize(Mem& header); static FitsIO* initialize(Mem& header, Mem& data); static FitsIO* blankImage(double ra, double dec, double equinox, double radius, int width, int height, unsigned long color0); int get(const char* keyword, double& val) const; int get(const char* keyword, float& val) const; int get(const char* keyword, int& val) const; int get(const char* keyword, long& val) const; int get(const char* keyword, unsigned char& val) const; int get(const char* keyword, unsigned short& val) const; int get(const char* keyword, short& val) const; char* get(const char* keyword) const; char* get(const char* keyword, char* buf, int bufsz) const; static int get(fitsfile*, const char* keyword, double& val); static int get(fitsfile*, const char* keyword, float& val); static int get(fitsfile*, const char* keyword, int& val); static int get(fitsfile*, const char* keyword, long& val); static int get(fitsfile*, const char* keyword, unsigned char& val); static int get(fitsfile*, const char* keyword, unsigned short& val); static int get(fitsfile*, const char* keyword, short& val); static char* get(fitsfile*, const char* keyword); int getFitsHeader(ostream& os) const; int put(const char* keyword, double val, const char* comment = NULL); int put(const char* keyword, float val, const char* comment = NULL); int put(const char* keyword, int val, const char* comment = NULL); int put(const char* keyword, const char* val, const char* comment = NULL); int getNumHDUs(); const char* getHDUType(); int getHDUNum(); int setHDU(int num); int deleteHDU(int num); int getTableDims(long& rows, int& cols); char* getTableHead(int col); char* getTableValue(long row, int col); int getTableColumn(int col, double* values, int numValues); int createTable(const char* extname, long rows, int cols, int setTableValue(long row, int col, const char* value); }; DESCRIPTION This class manages the reading and writing of FITS images, including ASCII and binary tables, FITS headers and keywords. FITS file access is based on William Pence's CFITSIO package. World coordinates support is based on Doug Mink's WCSSUBS package (also used by saoimage). The sources from both packages are included in this package. This class is a subclass of ImageIORep, which is the internal class used by class ImageIO for reference counting. The public interface is generally through the ImageIO class, although class FitsIO may be used directly in cases where you know that the image is already in FITS format or you are creating a new image in FITS format. Besides reading and writing FITS images, this class can be used to create a FITS image from data in memory and to create a "blank" image with World Coordinate information for plotting astronomical objects. CREATING A FITSIO OBJECT To create a FitsIO object from a FITS file, use the read method, which returns a pointer to an allocated FitsIO object given the file name. If you have the image data in memory, you can use one of the constructors to create the object. You can pass a pointer to a FitsIO object to the ImageIO constructor to create a reference counted ImageIO object, for example: ImageIO imio = FitsIO::read(filename); or ImageIO imio = new FitsIO(w, h, type, bzero, bscale, header, data); COMPRESSION Images are compressed and decompressed automatically by the read and write methods based on the file name suffix: ".hfits" for H-compress, ".gzfits" or ".gfits" for gzip compression, and ".cfits" for UNIX compression. See Compress for details. IMAGE EXTENSIONS Methods are provided to query the number of FITS HDUs (header data units) and switch to a given HDU. You can iterate through a FITS table by first switching to the HDU containing the table and then calling one of the HDU methods described below. When switching HDUs, make sure that the image display code is not still accessing a different HDU. It might be necessary to save the current HDU number before reading a FITS table and then restore the HDU settings afterwards in this case. FITS TABLES Reading and writing of FITS ASCII and binary tables is supported. FITS tables may also be created and deleted. (Note this class does not support the full functionality of the cfitsio library (yet), but only the features that we needed so far.) WRITING FITS IMAGES Care must be taken when modifying FITS image files used with the FitsIO class, since the files are memory mapped. When using the "put()" method to insert FITS keywords, the FitsIO class automatically handles adding new FITS blocks as needed and remapping the file. This may change the starting location of the FITS image data or extensions. METHODS FitsIO(width, height, bitpix, bzero, bscale, header, data) This constructor is called by the static "read" method once the FITS file has been read. The parameters are based on values read from the FITS header. The header and data arguments are instances of class Mem, which uses reference counting to manage shared and unshared memory. read(filename, int memOptions = 0) Read a FITS file and return an initialized FitsIO object for it, or NULL if there are errors. If filename is "-", stdin is read into a temp image file and used as the input. The Mem class is used to speed up loading the file. The optional mem_options argument controls whether the memory is mapped read-only or read/write. See class Mem for the available options. write(filename) Write the data to a FITS file. blankImage(ra, dec, equinox, radius, width, height, color0) Generate a blank image with a FITS header based on the given fields and including support for World Coordinates. RA and DEC are specified in degrees. Width and Height are in pixels. "color0" is the value to use for the image pixels (usually the value for "black"). get(keyword, val) Find and set the value for the given FITS keyword and return 0 if OK (found). This method is overloaded for various data types. get(keyword) Find and return the string value for the given FITS keyword, or NULL if not found. getFitsHeader(os) Write an ASCII formatted copy of the FITS header to the given stream, format it in 80 char lines and replace any NULL chars with blanks. put(keyword, val, comment) Insert the given FITS keyword and value with the given comment in the FITS header and return 0 if all is OK. If there is not enough space in the FITS header, extend the size of the FITS header by one header block and if the header is part of an mmap'ed file, rewrite the file with the new enlarged header. getNumHDUs() Return the total number of HDUs (FITS header/data units). getHDUType() Return the type of the current HDU as a string: "image", "ascii", or "binary" or NULL if there was as error. getHDUNum() Return the index of the current HDU. setHDU(num) Move to the specified HDU and make it the current one. deleteHDU(num); Delete the given HDU. All following HDUs are moved to fill the space. getTableDims(rows, cols) Get the dimensions of the current FITS table. getTableHead(col); Return the table heading for the given column, or NULL if there is an error. The return value points to static storage. getTableValue(row, col) Return the value in the current FITS table at the given row and column, or NULL if there was an error. The returned pointer points to static storage and will be overwritten on the next call to this method or one of the get(keyword) methods. getTableColumn(col, values, numValues) Get the contents of the given column as an array of doubles. The caller should pass an array of numValues doubles. createTable(extname, rows, cols, headings, tform, asciiFlag) Create a FITS table and make it the current HDU extname gives the name of the table. The initial size will be rows x cols entries. tform is an array giving the FITS data type for each column (For example: 16A, for a 16 char string, see FITS description.) If asciiFlag is 1, an ASCII table is created, otherwise a binary table. setTableValue(row, col, value) Set the value in the current FITS table at the given row and column (For now, all data types are treated as strings) SEE ALSO ImageIO(3++), ImageData, Mem(3C++), Compress(3C++) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/astrotcl/man/HMS.man3000066400000000000000000000040221215713201500207500ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: HMS.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 16 Oct 95 Created # NAME HMS - C++ class for working with H:M:S (hours minutes seconds) values SYNOPSIS #include "HMS.h" class HMS { public: HMS(); HMS(int hours, int min, double sec); HMS(double val); int isNull() const; int hours() const; int min() const; double sec() const; double val() const; friend ostream& operator<<(ostream&, const HMS&); friend istream& operator>>(istream&, HMS&); friend int operator< (const HMS& a, const HMS& b); friend int operator<=(const HMS& a, const HMS& b); friend int operator> (const HMS& a, const HMS& b); friend int operator>=(const HMS& a, const HMS& b); friend int operator==(const HMS& a, const HMS& b); friend int operator!=(const HMS& a, const HMS& b); }; DESCRIPTION HMS is a simple class for representing values in Hours:Minutes:Seconds format or in degrees, converting back and forth and comparing. CONSTRUCTORS HMS() Initialize a NULL H:M:S value (see isNull() method). HMS(hours, min, sec) Initialize from hours, minutes and seconds. HMS(val) Initialize from a value in degrees. METHODS isNull() Return true if the HMS object has the NULL value (created with default constructor). hours() min() sec() val() Return the parts of the H:M:S value or the value (val) in degrees. operator<<(ostream, hms) operator>>(istream, hms) I/O operators - using format H:M:S.sss. operator< (a, b); operator<=(a, b); operator> (a, b); operator>=(a, b); operator==(a, b); operator!=(a, b); Comparison operators - compare two H:M:S values. SEE ALSO WorldCoords ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/astrotcl/man/ImageCoords.man3000066400000000000000000000056521215713201500225270ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: ImageCoords.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 15 Jan 98 Created # NAME ImageCoords - class representing image coordinates (x, y) SYNOPSIS #include "ImageCoords.h" class ImageCoords { ... public: ImageCoords(); ImageCoords(double x, double y); ImageCoords(const char* x_str, const char* y_str); isNull() const; void setNull(); friend ostream& operator<<(ostream&, const ImageCoords& pos); void print(char* x_buf, char* y_buf); void print(ostream& os); void get(double& x, double& y); int operator==(const ImageCoords& pos) const; int operator!=(const ImageCoords& pos) const; friend ImageCoords operator-(const ImageCoords& a, const ImageCoords& b); double x() const; double y() const; double dist(ImageCoords& pos) const; static double dist(double x0, double y0, double x1, double y1); int box(double radius, ImageCoords& pos1, ImageCoords& pos2) const; static ImageCoords center(const ImageCoords& pos1, const ImageCoords& pos2, double& radius, double& width, double& height); int status() const; }; DESCRIPTION This class is used to represent image pixel coordinates (x, y). It has an interface similar to the WorldCoords class, and is used by the WorldOrImageCoords class to represent image coordinates. CONSTRUCTORS ImageCoords() Initialize null coordinates. ImageCoords(x, y) Initialize coordinates with (x, y) ImageCoords(x_str, y_str) Parse X and Y in string format. METHODS isNull() Return true if the coordinates are null. setNull() Set to the null value. ostream& operator<<(os, pos) Output operator: format: "x y" print(x_buf, y_buf) Print the coordinates to the given buffers. print(os) Print coordinates to the given stream. get(x, y) Get the values of x and y. operator==(pos) Check for equality. operator!=(pos) Check for inequality. operator-(a, b) { Return the difference between two points. x() return the value of x. y() return the value of y. dist(pos) Get distance between this point and the given one. dist(x0, y0, x1, y1) Static member to get the distance between two points. box(radius, Ipos1, pos2) Given a radius, set pos1 and pos2 to the two endpoints that form a box with center at this position. center(pos1, const pos2, radius, width, height) Given the endpoints of a box (pos1, pos2), set width, height and radius and return the center position of the box. status() Return the status ater the constructor (0 is OK). SEE ALSO WorldCoords, WorldOrImageCoords(3C++) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/astrotcl/man/ImageIO.man3000066400000000000000000000151361215713201500216030ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: ImageIO.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 10 Apr 96 Created # NAME ImageIO - Reference Counted C++ Class for Reading and Writing Images SYNOPSIS #include "ImageIO.h" // types of image data (these mostly correspond to the FITS BITPIX values) enum ImageDataType { UNKNOWN_IMAGE = -1, // unknown type BYTE_IMAGE = 8, // 8 bit images X_IMAGE = -8, // special, color scaled, X image data SHORT_IMAGE = 16, // 16 bit signed USHORT_IMAGE = -16, // 16 bit unsigned LONG_IMAGE = 32, // 32 bit integer FLOAT_IMAGE = -32 // 32 bit floating point }; class ImageIORep { ... }; class FitsIO : public ImageIORep { ... }; class ImageIO; ... public: ImageIO(); ImageIO(ImageIORep* rep); ImageIO(const ImageIO&); ~ImageIO(); ImageIO& operator=(const ImageIO&); int usingNetBO() const; int write(const char *filename) const; int wcsinit(); int get(const char* keyword, double& val) const; int get(const char* keyword, float& val) const; int get(const char* keyword, int& val) const; int get(const char* keyword, long& val) const; int get(const char* keyword, unsigned char& val) const; int get(const char* keyword, unsigned short& val) const; int get(const char* keyword, short& val) const; char* get(const char* keyword) const; int getFitsHeader(ostream& os) const; double scaleValue(double d) const; double unScaleValue(double d) const; int pixelSize() const; int width() const; int height() const; int bitpix() const; double bscale() const; double bzero() const; const Mem& header() const; const Mem& data() const; WCS& wcs(); void wcs(const WCS& newwcs); int header(const Mem& m); int data(const Mem& m); const char* headerPtr() const; const void* dataPtr() const; int status() const; ImageIORep* rep() const; }; DESCRIPTION Class ImageIO is used to read, write and manage the memory for astronomical images of various formats. The image header and data may be optionally kept in shared memory (mmap or shm), so they can be accessed by external processes that may want to do image processing or other operations. Regardless of the original image format and derived class, the header and data are always kept in FITS format. Other image types are converted to FITS format by the derived classes (see below). Subclasses of ImageIORep can, however, specify via a virtual method whether the image data is in network or in native byte order (see below). CLASS STRUCTURE Class ImageIO uses reference counting to make it easier to share objects of this type for displaying in multiple windows. The actual (abstract) base class is ImageIORep. An ImageIO object contains a pointer to an ImageIORep object, which may be shared by multiple ImageIO objects. To add new image types, to the ImageIO class, classes are derived from ImageIORep. WORLD COORDINATES SUPPORT This class offers optional support of world coordinates for the image, which can be initialized by calling the wcsinit() method, which must be defined in a derived class, such as FitsIO. Normally wcsinit() will get the necessary information from the image header, which is normally assumed to be in FITS format. METHODS ImageIO() Default constructor, creates a null object (use assignment operator to set later); ImageIO(ImageIORep* rep) Constructor, from a pointer to a subclass of ImageIORep (FitsIO, for example). "rep" should be allocated with the "new" operator and will be deleted by this class when there are no more references to it. Note that this constructors enables automatic conversion from a pointer to a subclass of ImageIORep to class ImageIO. Examples: // create an ImageIO object from a FITS file ImageIO imio1 = FitsIO::read(filename); // create an ImageIO object from FITS data and header in memory Mem header(...), data(...); ImageIO imio2 = new FitsIO(w, h, type, bzero, bscale, header, data); ImageIO(const ImageIO&) Copy constructor: only copies the internal pointer and raises the reference count. ~ImageIO() Destructor, lowers the reference count and frees the memory, if there are no more references. ImageIO& operator=(const ImageIO&) Assignment operator: reference counted. usingNetBO() Return true if the ImageIORep subclass uses native byte ordering. FITS files and most other image formats are in network byte order, however, the derived class may want to byte swap the data first, if needed, so that it is easier to work with. This virtual method is checked by classes that use this object to determine if byte-swapping may need to be done. write(filename) Write the image header and data to a file in a format defined in the derived class. get(keyword, val) Find and set the value for the given FITS keyword and return 0 if OK (found). This method is overloaded for various data types. get(keyword) Find and return the string value for the given FITS keyword, or NULL if not found. scaleValue(d) Apply the FITS keyword values for BZERO and BSCALE to the given value (d = BZERO+d*BSCALE) unScaleValue(d) Reverse the effect of BZERO and BSCALE (d = (d-BZERO)/BSCALE) width() Return the width of the image in pixels. height() Return the height of the image in pixels. bitpix() Return the value of the BITPIX keyword (data type of image). bscale() Return value for the BSCALE keyword. bzero() Return the value for the BZERO keyword. header() Return a reference to the FITS header (class Mem). data() Return a reference to the FITS image data (class Mem). header(const Mem& newheader) Replace teh image header. data(const Mem& newdata) Replace the image data with new data of same size. WCS& wcs() Return a reference to the object used to manage world coordinates. Note that this object is reference counted in the same way as the ImageIO class. void wcs(const WCS& newwcs) Set the WCS object used to manage world coordinates. Since the WCS class is also a reference counted wrapper around an abstract base class (WCSRep), you can define subclasses of class WCSRep that redefines the behavior and implementation of the WCS object. SEE ALSO FitsIO, ImageData(3C++), Mem(3C++) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/astrotcl/man/WCS.man3000066400000000000000000000130751215713201500207650ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: WCS.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 30 Sep 96 Created # NAME WCS - Reference counted C++ wrapper class for managing World Coordinates SYNOPSIS #include "WCS.h" class WCSRep; class SAOWCS : public WCSRep {...}; class WCS { ... public: WCS(); WCS(const WCS&); WCS(WCSRep* rep); ~WCS(); WCS& operator=(const WCS&); int isWcs() const; int pixWidth() const; int pixHeight() const; double dist(double ra0, double dec0, double ra1, double dec1) const; char* pix2wcs(double x, double y, char* buf, int bufsz, int hms_flag = 1) const; int pix2wcs(double x, double y, double& ra, double& dec) const; int wcs2pix(double ra, double dec, double &x, double &y) const; int set(double ra, double dec, double secpix, double xrefpix, double yrefpix, int nxpix, int nypix, double rotate, int equinox, double epoch, const char* proj); int shift(double ra, double dec, double equinox); double equinox() const; char* equinoxStr() const; double epoch() const; double rotate() const; double width() const; double height() const; double radius() const; double secPix() const; WorldCoords center() const; int initialized() const; int status() const; }; DESCRIPTION Class WCS is a reference counted wrapper class for managing world coordinates for a given image. This class does not do anything itself, but manages a pointer to a class derived from class WCSRep, which is an abstract base class. Packages can add their own WCS implementations by deriving new subclasses from WCSRep that meet the required interface, which includes the same methods as class WCS. Since class WCS uses reference counting, you do not normally have to worry about allocating and deleting it. You can jsut create an instance and copy it. When the last copy goes out of scope or is deleted, the memory is released. The astrotcl package provides one implementation subclass of WCSRep, class SAOWCS, which is based on Doug Mink's (saoimage) WCS C library (Note: a Starlink based version is also available, see the GAIA plugin for Skycat). The constructor for SAOWCS takes a pointer to a FITS image header and uses that to set up world coordinates for the image. Methods are implemented to convert between image pixel and world coordinates and to set world coordinates when there is no FITS header. See the HTML documentation in http://tdc-www.harvard.edu/software/wcstools.html for information about the underlying C library used by SAOWCS. The latest version of the wcs C library can be found under: ftp://cfa-ftp.harvard.edu/pub/gsc/WCS/. METHODS WCS() WCS(WCSRep* rep) The default constructor creates a null WCS object. If you pass the constructor a pointer to an object of a class derived from WCSRep (SAOWCS, for example), the object is initialized from it. isWcs() Returns nozero if the image supports world coordinates (has the necessary FITS keywords in the image header or from some other source). Note that if this method returns 0, none of the other methods should be called. pix2wcs(int x, int y, char* buf) Return the world coordinates string for the given image coords. pix2wcs(int x, int y, double& ra, double& dec) Return the world coords (in degrees, as 2 doubles) for the image coords. wcs2pix(double ra, double dec, int &x, int &y) Get the image coordinates for the given world coords. dist(double ra0, double dec0, double ra1, double dec1) Return the WCS distance between the 2 given WCS points in arcmin. width() height() radius() Return the width, height, radius of the image in arc-minutes. set(double ra, double dec, double secpix, double xrefpix, double yrefpix, int nxpix, int nypix, double rotate, int equinox, double epoch, const char* proj); Set up the WCS structure from the given information about the image. This method can be used to add world coordinate support to an image even if the image doesn't have it in the header. Arguments: ra = Center right ascension in degrees dec = Center declination in degrees secpix = Number of arcseconds per pixel xrefpix = Reference pixel X coordinate yrefpix = Reference pixel Y coordinate nxpix = Number of pixels along x-axis nypix = Number of pixels along y-axis rotate = Rotation angle (clockwise positive) in degrees equinox = Equinox of coordinates, 1950 and 2000 supported epoch = Epoch of coordinates, used for FK4/FK5 conversion no effect if 0 proj = Projection shift(double ra, double dec, double equinox) Reset the center of the WCS structure. equinox() equinoxStr() Return the WCS equinox as a double (1) or a string (2). epoch() Return the WCS epoch as a double. rotate() Return the rotation angle in degrees. secPix() Return the number of world coordinate arcseconds per pixel. center() Return the world coordinates of the center of the image. pixWidth() const pixHeight() Return image dimensions in pixels. initialized() Returns true if WCS has been initialized (with a FITS header). status() status(int s) Get/set the status of the object (0 is OK). SEE ALSO ImageData, RtdImage(3C++), WorldCoords(3C++), FitsIO(3C++), ImageIO ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/astrotcl/man/WorldCoords.man3000066400000000000000000000113261215713201500225670ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: WorldCoords.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 16 Oct 95 Created # NAME WorldCoords - C++ class for working with world coordinates SYNOPSIS #include "WorldCoords.h" class WorldCoords { ... public: WorldCoords(); WorldCoords(const HMS& ra, const HMS& dec, double equinox = 2000.0); WorldCoords(double ra_deg, double dec_deg, double equinox = 2000.0); WorldCoords(int rh, int rm, double rs, int dd, int dm, float ds, double equinox = 2000.0); WorldCoords(const char* ra_str, const char* dec_str, double equinox = 2000.0); isNull() const; void setNull(); void print(char* ra_buf, char* dec_buf, double equinox = 2000.0); friend istream& operator>>(istream&, WorldCoords& pos); friend ostream& operator<<(ostream&, const WorldCoords& pos); friend int operator==(const WorldCoords& a, const WorldCoords& b); friend int operator!=(const WorldCoords& a, const WorldCoords& b); friend WorldCoords operator-(const WorldCoords& a, const WorldCoords& b); const HMS& ra() const; const HMS& dec() const; int status(); }; DESCRIPTION This class is used to represent world coordinates and to convert between different representations of world coordinates. The member variables in the class are always kept internally in both H:M:S format and as floating point values in the default equinox J2000. For example, for a given WorldCoords object "pos", the coordinates in H:M:S[+-]D:M:S format are given by: (pos.ra(), pos.dec()) ra() and dec() both return a reference to an HMS object, which is used to represent values in hours, minutes and seconds (see HMS). The coordinates in decimal degrees are given by (pos.ra().val()*15, pos.dec().val()). The ra value must be multiplied by 15 to convert from hours to degrees. CONSTRUCTORS WorldCoords() Initialize null world coordinates. (Null coordinates are useful in some cases where you have an optional second position for an area instead of a single point). WorldCoords(ra, dec, equinox) Initialize the world coordinates from RA, DEC in H:M:S D:M:S format. Arguments: ra (in) - RA in H:M:S dec (in) - DEC in D:M:S equinox (in) - optional epoch (2000.0, 1950.0, ...) WorldCoords(rh, rm, rs, dd, dm, ds, equinox) Initialize the world coordinates from H M S D M S as separate values. Arguments: rh (in) - RA hours rm (in) - RA minutes rs (in) - RA seconds dd (in) - DEC degrees dm (in) - DEC minutes ds (in) - DEC seconds equinox (in) - optional epoch (2000.0, 1950.0, ...) WorldCoords(ra_deg, dec_deg, equinox) Initialize the world coordinates from RA, DEC in degrees in floating point format. Arguments: ra (in) - right ascension dec (in) - declination equinox (in) - epoch (2000.0, 1950.0, ...) WorldCoords(ra_str, dec_str, equinox); Initialize the world coordinates from RA and DEC in string format. Allowed formats of input strings: hh mm ss.s +/-dd mm ss.s hh:mm:ss.s +/-dd:mm:ss.s h.hhhh +/-d.dddd Arguments: ra (in) - String containing right ascension dec (in) - String containing declination equinox (in) - epoch (2000.0, 1950.0, ...) METHODS isNull() Return true if the given coords are null (this is true if they were created with the default constructor - i.e.: with no arguments). setNull() Set to the null value. print(ra_buf, dec_buf, equinox) Print the coordinates in the given buffers in H:M:S format in given equinox. operator>>(istream, pos) Input operator: format: H:M:S[+-]D:M:S - reads the position from the given istream. operator<<(ostream, pos) Output operator: format: H:M:S[+-]D:M:S - writes the position to the given ostream. operator==(pos1, pos2) operator!=(pos1, pos2) Comparison operators - check for equality/inequality. ra() Return the RA part of the coordinates (class HMS). ra().val()*15 is the value in degrees, ra.hours(), ra().min() and ra().sec() give the H:M:S values. dec() Return the DEC part of the coordinates (class HMS). dec().val() is the value in degrees, dec.hours(), dec().min() and dec().sec() give the H:M:S values. status() Return the status after the constructor is done (0 is OK, 1 for errors). SEE ALSO HMS ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/astrotcl/man/WorldOrImageCoords.man3000066400000000000000000000110421215713201500240260ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: WorldOrImageCoords.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 15 Jan 98 Created # NAME WorldOrImageCoords - class representing either world or image coordinates SYNOPSIS #include "WorldOrImageCoords.h" class WorldOrImageCoords { ... public: WorldOrImageCoords(); WorldOrImageCoords(WorldCoords wc); WorldOrImageCoords(ImageCoords ic); isNull() const; void setNull(); friend ostream& operator<<(ostream& os, const WorldOrImageCoords& pos); void print(char* x_buf, char* y_buf, double equinox = 2000., int hmsFlag=1); void print(ostream& os, double equinox = 2000.); void get(double& x, double& y, double equinox = 2000.); int operator==(const WorldOrImageCoords& pos) const; int operator!=(const WorldOrImageCoords& pos) const; friend WorldOrImageCoords operator-(const WorldOrImageCoords& a, const WorldOrImageCoords& b); double ra_deg() const; double dec_deg() const; WorldCoords& wc(); ImageCoords& ic(); const WorldCoords& wc() const const ImageCoords& ic() const; double dist(WorldOrImageCoords& pos, double& pa) const; double dist(WorldOrImageCoords& pos) const; int box(double radius, WorldOrImageCoords& pos1, WorldOrImageCoords& pos2) const; static WorldOrImageCoords center(const WorldOrImageCoords& pos1, const WorldOrImageCoords& pos2, double& radius, double& width, double& height); const HMS& ra() const; const HMS& dec() const; double x() const; double y() const; double isWcs() const; int status() const; }; DESCRIPTION Class WorldOrImageCoords is designed to be used in situations where you might need to deal with either world coordinates or image coordinates, but don't know ahead of time which. We could use a common base class and virtual methods, but that would require using pointers or references, while it is often more convenient to use instances of these classes. Also, the methods in both classes have slightly different signatures. After initializing the class with with a WorldCoords(n) object or an ImageCoords(n) object, you can use the isWcs() method to check which one it is, if you don't know. Otherwise, most of the methods work transparently, independent of the coordinate type. However, you should not attempt, for example, to fetch the value of "ra" and "dec" without being sure that the object represents world coordinates. CONSTRUCTORS WorldOrImageCoords() Initialize null coordinates. WorldOrImageCoords(wc) Initialize world coordinates. WorldOrImageCoords(ic) Initialize image coordinates. METHODS isNull(); Return true if the coordinates are null setNull() Set to the null value. operator<<(os, pos) Output operator, prints world coordinates as hh:mm:ss dd:mm:ss, image coordinates as x y. print(x_buf, y_buf, equinox, hmsFlag) Print the coordinates to the given buffer. For world coordinates, if hmsFlag is non-zero, prints in H:M:S [+-]D:M:S format, otherwise in decimal degrees. print(os, equinox) Print the coordinates to the given stream. get(x, y, equinox) Get teh valules of x and y in the given equinox. operator==(pos) Check for equality. operator!=(pos) Check for inequality. operator-(a, b) Return the difference between two points. ra_deg() Return ra in degrees. dec_deg() Return dec in degrees. wc() Return the internal WorldCoords class. ic() Return the internal ImageCoords class. dist(pos, pa) Get distance and pa angle between the given point and this point. dist(pos) Get distance between between the given point and this point. box(radius, pos1, pos2) Given a radius, set pos1 and pos2 to the 2 endpoints that form a box with center at this position. center(pos1, pos2, radius, width, height) { Given the endpoints of a box (pos1, pos2), set width, height and radius and return the center position of the box. ra() Return the value of ra. dec() Return the value of dec. x() Return the value of the x coordinate. y() Return the value of the y coordinate. isWcs() Return true if this class represents world coordinates. status() Return the status after the constructor (0 is OK). SEE ALSO WorldCoords, ImageCoords(3C++) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/astrotcl/man/world_coords.man3000066400000000000000000000070451215713201500230310ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: world_coords.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 16 Oct 95 Created # NAME worldCoords - C utility routine for working with world coordinates SYNOPSIS #include "worldCoords.h" typedef struct { int hours; int min; double sec; double val; /* value calculated in degrees */ } WC_HMS; typedef struct { WC_HMS ra, dec; } WC; WC* wcInitNull(WC*); int wcIsNull(WC* wc); WC* wcInitFromHMS(WC*, int rh, int rm, double rs, int dd, int dm, int ds, double equinox); WC* wcInitFromDeg(WC*, double ra, double dec, double equinox); WC* wcInitFromStrings(WC*, char* ra, char* dec, double equinox); void wcPrint(WC* wc, char* ra_buf, char* dec_buf, double equinox); DESCRIPTION The routines described here present a C interface to the C++ WorldCoords class and are used to convert between different representations of world coordinates. The values in the struct are always kept in both H:M:S[+-]D:M:S format (members: hours, min, sec) and as floating point values in hours (member: val) in the default equinox of J2000. C ROUTINES wcInitNull Initialize null world coordinates and return the argument. (Null coordinates are useful in some cases where you have an optional second position for an area instead of a single point). Arguments: wc (in/out) - pointer to WC struct to be filled in Return value: pointer to wc argument. wcIsNull Return true if the given coords are null. Arguments: wc (in) - pointer to initialized WC struct Return value: boolean value wcInitFromHMS Initialize the world coordinates from RA, DEC in H:M:S D:M:S format and return the first parameter. Arguments: wc (in/out) - pointer to WC struct to fill out rh (in) - RA hours rm (in) - RA minutes rs (in) - RA seconds dd (in) - DEC degrees dm (in) - DEC minutes ds (in) - DEC seconds equinox (in) - epoch (2000.0, 1950.0, ...) Return value: pointer to wc argument wcInitFromDeg Initialize the world coordinates from RA, DEC in degrees in floating point format and return the first parameter. Arguments: wc (in/out) - pointer to WC struct to fill out ra (in) - right ascension dec (in) - declination equinox (in) - epoch (2000.0, 1950.0, ...) Return value: pointer to wc argument wcInitFromStrings Initialize the world coordinates from RA, DEC in the format "H:M:S.sss", "[+-]D:M:S.sss" and return the first parameter. The minutes and seconds are optional, so the formats "H.hhh", "[+-]D.ddd" and "H:M", "D:M" are also supported. Arguments: wc (in/out) - pointer to WC struct to fill out ra (in) - right ascention dec (in) - declination equinox (in) - epoch (2000.0, 1950.0, ...) Return value: pointer to wc argument wcPrint Print RA and DEC to the given buffers in the given equinox. Arguments: wc (in) - pointer to WC struct ra_buf (in) - buffer to contain RA in H:M:S dec_buf (in) - buffer to contain DEC in D:M:S equinox (in) - desired epoch (2000.0, 1950.0, ...) Return value: none. SEE ALSO WorldCoords ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/astrotcl/pkgIndex.tcl.in000066400000000000000000000002271215713201500216530ustar00rootroot00000000000000# Tcl package index file, version 1.0 package ifneeded Astrotcl @PACKAGE_VERSION@ [list load [file join [file dirname $dir] @PKG_LIB_FILE@] Astrotcl] skycat-3.1.2-starlink-1b/astrotcl/press/000077500000000000000000000000001215713201500201245ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/astrotcl/press/digitize.c000066400000000000000000000005321215713201500221000ustar00rootroot00000000000000/* digitize.c digitize H-transform * * Programmer: R. White Date: 11 March 1991 */ #include extern void digitize(a,nx,ny,scale) int a[]; int nx,ny; int scale; { int d, *p; /* * round to multiple of scale */ if (scale <= 1) return; d=(scale+1)/2-1; for (p=a; p <= &a[nx*ny-1]; p++) *p = ((*p>0) ? (*p+d) : (*p-d))/scale; } skycat-3.1.2-starlink-1b/astrotcl/press/gen_msg.h000066400000000000000000000017321215713201500217170ustar00rootroot00000000000000/*+ ************************************************************************ **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** * * Include File Name: gen/h/gen_msg.h * * Purpose: * Defines the message structure. * * Date : Aug 23, 1991 * * SCCS data : @(#) * Module Name : gen_msg.h * Version Number : 1.3 * Release Number : 1 * Last Updated : 8/12/92 * * Programmer : Severin Gaudet * * Modification History: * **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** ************************************************************************ -*/ /* * A huge negative number is required for the MSG_ERRNO value. */ #define MSG_ERRNO (-9999) /* * Define the maximum message size. */ #define MSG_MAX_LEN 2048 typedef struct msg { int m_status; char *m_format; } MSG; extern void msg_append(); extern void msg_clear(); extern void msg_format(char *buffer, char *prefix, int num_msgs, MSG *msgs, int status, ...); skycat-3.1.2-starlink-1b/astrotcl/press/gen_str.h000066400000000000000000000025021215713201500217350ustar00rootroot00000000000000/*+ ************************************************************************ **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** * * Include File Name: gen/h/gen_str.h * * Purpose: * Contains defines and declarations for string manipulation. * * Date : Dec 10, 1990 * * SCCS data : @(#) * Module Name : gen_str.h * Version Number : 1.8 * Release Number : 1 * Last Updated : 12/16/92 * * Programmer : Severin Gaudet * * Modification History: * 92/03/02 Norman Hill - Added strnsav. * **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** ************************************************************************ -*/ /* * Standard include file. */ #include /* * Definitions. */ #ifndef STRSIZ #define STRSIZ 256 #endif #define streq(s1,s2) (strcmp(s1,s2) == 0) #define strne(s1,s2) (strcmp(s1,s2) != 0) /* * External function declarations. */ extern boolean str2float(); extern boolean str2int(); extern void str2lower(); extern void str2upper(); extern char *strapp(); extern char *strext(); extern char *strfit(); extern boolean strfloat(); extern void strhead(); extern boolean strint(); extern char *strnapp(); extern char *strnsav(); extern boolean strpattern(); extern void strroot(); extern char *strsav(); extern char *strtail(); extern void strtokens(); skycat-3.1.2-starlink-1b/astrotcl/press/gen_types.h000066400000000000000000000055341215713201500223010ustar00rootroot00000000000000/*+ ************************************************************************ **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** * * Include File Name: gen/h/gen_types.h * * Purpose: * General constants and macros. * * Date : Dec 10, 1990 * * SCCS data : @(#) * Module Name : gen_types.h * Version Number : 1.5 * Release Number : 1 * Last Updated : 2/17/94 * * Programmer : Severin Gaudet * * Modification History: * **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** ************************************************************************ -*/ /* * Standard include files. */ #include #include /* * Data structures */ typedef int boolean; typedef unsigned char byte; typedef boolean (*pfb)(); typedef int (*pfi)(); typedef float (*pff)(); typedef void (*pfv)(); typedef void *pointer; /* * Constant definitions */ #ifndef FALSE #define FALSE 0 #define TRUE 1 #endif /* * Memory allocation macro definitions. */ #define gen_alloc(n) (malloc((unsigned)(n))) #define gen_calloc(n,s) (calloc((unsigned)(n),(unsigned)(s))) #define gen_free(p) ((void) free((pointer) (p))) #define gen_realloc(p,n) (realloc((pointer)(p),(unsigned)(n))) #define gen_zero(p,n) (memset((pointer)(p),0,(int)(n))) #define boolean_alloc(n) (boolean *)(gen_alloc(((n)*sizeof(boolean)))) #define byte_alloc(n) (byte *)(gen_alloc(((n) * sizeof(byte)))) #define char_alloc(n) (gen_alloc((n) * sizeof(char))) #define double_alloc(n) (double *)gen_alloc((n)*sizeof(double)) #define float_alloc(n) (float *)gen_alloc((n)*sizeof(float)) #define int_alloc(n) ((int *)gen_alloc((n)*sizeof(int))) #define ptr_alloc(n) ((pointer *)gen_alloc((n)*sizeof(pointer))) #define short_alloc(n) ((short *)gen_alloc((n)*sizeof(short))) /* * General macro definitions. */ #ifdef ABS #undef ABS #endif #define ABS(a) ((a) < 0 ? -(a) : (a)) #define EPSILON 0.00001 #define EVEN(x) ((0x01 & x) ? FALSE : TRUE) #define FEQ(a,b) (ABS((a)-(b)) <= EPSILON) /* Equal */ #define FLE(a,b) (FLT(a,b) || FEQ(a,b)) /* Less than or equal */ #define FLT(a,b) ((b)-(a) > EPSILON) /* Less than */ #define FGE(a,b) (FGT(a,b) || FEQ(a,b)) /* Greater than or equal*/ #define FGT(a,b) ((a)-(b) > EPSILON) /* Greater than */ #define FNE(a,b) (!(FEQ(a,b))) /* Not equal */ #define INRANGE(x,lo,hi) ((x)>=(lo) && (x)<=(hi)) #define INBOX(x,y,l,r,b,t) (INRANGE(x,l,r) && INRANGE(y,b,t)) #ifdef MAX #undef MAX #endif #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #ifdef MIN #undef MIN #endif #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #ifndef NULL #define NULL 0 #endif #define ROUND(x) ((x) + 0.5) #define SIGN(x) (((x) < (0)) ? (FEQ((x),0.0) ? 1 : (-1)) : 1) #define SWAP(a,b) {float swpv; swpv=(a);(a)=(b);(b)=swpv;} #define XOR(a,b) (((a) || (b)) && !((a) && (b))) skycat-3.1.2-starlink-1b/astrotcl/press/gzip.c000066400000000000000000000173651215713201500212550ustar00rootroot00000000000000/*+ ************************************************************************ **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** * * Module Name: press/src/gzip.c * * Purpose: * decompress files in gzip format. * Copyright (C) 1992-1993 Jean-loup Gailly * This is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License, see the file COPYING. * This version can extract files in gzip format. * * The code in this file is derived from the file funzip.c written * and put in the public domain by Mark Adler. * * Routines: * int gzip_comp : Uncompresses gzipped data. * int unzip : Compress data into gzip format. * * Date : June 21, 1993 * * SCCS data : @(#) * Module Name : gzip.c * Version Number : 1.8 * Release Number : 1 * Last Updated : 07/16/97 * * Programmer : Norman Hill * * Modification History: * 97/07/02 SEC : Bring up to ANSI C. * **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** ************************************************************************ -*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef HAVE_SYS_FILIO_H #include #endif #include #include #include #if ! defined( _SOL ) && ! defined( lint ) #include #endif /* allan: 2.8.96, changed #ifdef for configure */ #ifdef HAVE_VFORK_H #include #endif #include "gen_types.h" #include "gen_msg.h" #include "press.h" #include "local_press.h" #include "gzip.h" /* allan: 15-03-99: moved globals to here from gzip.h to avoid linker warning */ unsigned short *dbuf; /* buffer for distances, see trees.c */ unsigned char *swindow; /* Sliding window and suffix table (unlzw) */ unsigned short *tab_prefix; /* prefix code (see unlzw.c) */ unsigned inptr; /* Index of next byte to be processed */ /* in inbuf. */ unsigned insize; /* valid bytes in inbuf */ pfi char_in; /* Function to read bytes. */ pfi char_out; /* Function to write bytes. */ long bytes_out; /* The number of output bytes. */ #define EXTHDR 16 /* Size of extend local header. */ /*+ ************************************************************************ * * Synopsis: * int gzip_comp( char_in, char_out ) * * Purpose: * Statement of purpose. * * Parameters: * int (*char_in)() : (in) Function to get data from input. * int (*char_out)() : (in) Function to write data to output. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_IO : Error during io. * ************************************************************************ -*/ int gzip_comp ( pfi char_in, /* (in) Func. to get data from input. */ pfi char_out /* (in) Func. to put data to output. */ ) { /* void pr_format_message(); */ byte out_buffer[4096]; byte in_buffer[4096]; byte *buf_ptr; int in_pipe[2]; int bytes_left; int bytes_read; int bytes_written; int out_pipe[2]; int tmp_stdin; int tmp_stdout; int status; tmp_stdin = dup( 0 ); tmp_stdout = dup( 1 ); PR_CHECK_IO( pipe( in_pipe ), "in pipe" ); PR_CHECK_IO( pipe( out_pipe ), "out pipe" ); (void) dup2( in_pipe[1], 1 ); (void) dup2( out_pipe[0], 0 ); if ( ( status = vfork() ) == 0 ) { (void) close( in_pipe[0] ); (void) close( out_pipe[1] ); (void) execlp( "gzip", "gzip", "-c", NULL ); pr_format_message( MSG_ERRNO, "gzip" ); _exit( 999 ); } PR_CHECK_IO( status, "vfork" ); (void) close( in_pipe[1] ); (void) close( out_pipe[0] ); (void) dup2( tmp_stdin, 0 ); (void) dup2( tmp_stdout, 1 ); (void) close( tmp_stdin ); (void) close( tmp_stdout ); PR_CHECK_IO( fcntl( out_pipe[1], F_SETFL, O_NDELAY | O_WRONLY ), "fcntl" ); PR_CHECK_IO( fcntl( in_pipe[0], F_SETFL, O_NDELAY ), "fcntl" ); while ( ( bytes_left = char_in( out_buffer, 4096 ) ) != PR_E_EOI ) { buf_ptr = out_buffer; do { bytes_written = write( out_pipe[1], buf_ptr, bytes_left ); if ( bytes_written < 0 ) { bytes_written = 0; } do { bytes_read = read( in_pipe[0], in_buffer, 4096 ); if ( bytes_read > 0 ) { PR_CHECK( char_out( in_buffer, bytes_read ) ); } } while ( bytes_read > 0 ); if ( bytes_read <= 0 && bytes_written <= 0 ) { /* sleep( 1 ); allan: 22.3.98: commented out: very bad for performance... */ } buf_ptr += bytes_written; bytes_left -= bytes_written; } while ( bytes_left > 0 ); } close( out_pipe[1] ); PR_CHECK_IO( fcntl( in_pipe[0], F_SETFL, O_RDONLY ), "fcntl" ); do { bytes_read = read( in_pipe[0], in_buffer, 4096 ); if ( bytes_read > 0 ) { PR_CHECK( char_out( in_buffer, bytes_read ) ); } } while ( bytes_read > 0 ); close( in_pipe[0] ); return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * int unzip( p_char_in, p_char_out ) * * Purpose: * Function to uncompress gzip files. * * Parameters: * int (*p_char_in)() : (in) Function to get the next input * character. * int (*p_char_out)() : (in) Function to send data to the output. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_EOI : End of input detected. * int PR_E_MAGIC : Invalid magic number. * int PR_E_METHOD : Unknown compression method. * ************************************************************************ -*/ int gzip_uncomp ( pfi p_char_in, /* (in) Func. to get char from input. */ pfi p_char_out /* (in) Func. to put char to output. */ ) { /* void pr_format_message(); */ unsigned char buff[EXTHDR]; /* extended local header */ char c; byte dummy[6]; byte flags; /* Compression flags. */ byte magic[2]; /* The magic number. */ byte method; /* The compress */ unsigned long orig_crc; /* original crc */ unsigned long orig_len; /* original uncompressed length */ char_in = p_char_in; char_out = p_char_out; orig_crc = 0; orig_len = 0; /* * Check the magic number and compression type. */ PR_CHECK( char_in( magic, 2 ) ); if ( memcmp( magic, GZIP_MAGIC, 2 ) != 0 ) { pr_format_message( PR_E_MAGIC ); return( PR_E_MAGIC ); } PR_CHECK( char_in( &method, 1 ) ); if ( method != DEFLATED ) { pr_format_message( PR_E_METHOD, method ); return( PR_E_METHOD ); } PR_CHECK( char_in( &flags, 1 ) ); if ( flags & ENCRYPTED || flags & CONTINUATION || flags & RESERVED ) { pr_format_message( PR_E_UNSUPPORT, "" ); return( PR_E_UNSUPPORT ); } /* * Skip over time stamp, extra flags, and os. */ PR_CHECK( char_in( dummy, 6 ) ); if ( ( flags & EXTRA_FIELD ) != 0 ) { /* * Skip the file length. */ PR_CHECK( char_in( dummy, 2 ) ); } /* * Skip over the original file name. */ if ( ( flags & ORIG_NAME ) != 0 ) { do { PR_CHECK( char_in( &c, 1 ) ); } while ( c != '\0' ); } /* * skip over the comment. */ if ( ( flags & COMMENT ) != 0 ) { do { PR_CHECK( char_in( &c, 1 ) ); } while ( c != '\0' ); } /* * initialize crc */ (void) updcrc(NULL, 0); /* * Decompress */ PR_CHECK( gzip_inflate() ); /* * Get the crc and original length */ /* * crc32 (see algorithm.doc) * uncompressed input size modulo 2^32 */ PR_CHECK( char_in( buff, 8 ) ); orig_crc = LG(buff); orig_len = LG(buff+4); /* * Validate decompression */ #ifdef OMIT if ( orig_crc != updcrc(buff, 0)) { pr_format_message( PR_E_CRC ); } #endif if (orig_len != bytes_out) { pr_format_message( PR_E_SIZE ); } return( PR_SUCCESS ); } skycat-3.1.2-starlink-1b/astrotcl/press/gzip.h000066400000000000000000000121471215713201500212530ustar00rootroot00000000000000/*+ ************************************************************************ **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** * * Include File Name: press/h/gzip.h * * Purpose: * Common declarations for all gzip modules * Copyright (C) 1992-1993 Jean-loup Gailly. * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License, see the file * COPYING. * * Date : June 22, 1993 * * SCCS data : @(#) * Module Name : gzip.h * Version Number : 1.2 * Release Number : 1 * Last Updated : 07/04/97 * * Programmer : Norman Hill * * Modification History: * 97/07/02 SEC : Added function prototype for flush_window(). * 98/10/16 ESO : Allan Brighton: changed global names to avoid clash * with cfitsio and tclpro, which also use gzip sources. * Changed "window" to "swindow", "prev" to "sprev". * **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** ************************************************************************ -*/ #ifdef __STDC__ typedef void *voidp; #else typedef char *voidp; #endif # define memzero(s, n) memset ((voidp)(s), 0, (n)) /* * Compression methods (see algorithm.doc) */ #define DEFLATED 8 #define MAX_METHODS 9 #define DIST_BUFSIZE 0x8000 /* buffer for distances, see trees.c */ /* allan: 15-03-99: added "extern" to avoid linker warning */ extern unsigned short *dbuf; /* buffer for distances, see trees.c */ extern unsigned char *swindow; /* Sliding window and suffix table (unlzw) */ #define tab_suffix swindow #define tab_prefix sprev /* hash link (see deflate.c) */ #define head (sprev+WSIZE) /* hash head (see deflate.c) */ extern unsigned short *tab_prefix; /* prefix code (see unlzw.c) */ extern unsigned insize; /* valid bytes in inbuf */ extern unsigned inptr; /* index of next byte to be processed in inbuf */ extern unsigned outcnt; /* bytes in output buffer */ extern long bytes_in; /* number of input bytes */ extern long bytes_out; /* number of output bytes */ extern long header_bytes;/* number of bytes in gzip header */ #define isize bytes_in /* for compatibility with old zip sources (to be cleaned) */ extern long time_stamp; /* original time stamp (modification time) */ extern long ifile_size; /* input file size, -1 for devices (debug only) */ typedef int file_t; /* Do not use stdio */ #define NO_FILE (-1) /* in memory compression */ #define GZIP_MAGIC "\037\213" /* Magic header for gzip files, 1F 8B */ /* * gzip flag byte */ #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ #define COMMENT 0x10 /* bit 4 set: file comment present */ #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ #define RESERVED 0xC0 /* bit 6,7: reserved */ /* internal file attribute */ #define UNKNOWN 0xffff #define BINARY 0 #define ASCII 1 #ifndef WSIZE # define WSIZE 0x8000 /* window size--must be a power of two, and */ #endif /* at least 32K for zip's deflate method */ #define MIN_MATCH 3 #define MAX_MATCH 258 /* The minimum and maximum match lengths */ #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) /* Minimum amount of lookahead, except at the end of the input file. * See deflate.c for comments about the MIN_MATCH+1. */ #define MAX_DIST (WSIZE-MIN_LOOKAHEAD) /* In order to simplify the code, particularly on 16 bit machines, match * distances are limited to MAX_DIST instead of WSIZE. */ extern int decrypt; /* flag to turn on decryption */ extern int exit_code; /* program exit code */ extern int verbose; /* be verbose (-v) */ extern int quiet; /* be quiet (-q) */ extern int level; /* compression level */ extern int test; /* check .z file integrity */ extern int to_stdout; /* output to stdout (-c) */ extern int save_orig_name; /* set if original name must be saved */ extern pfi char_in; /* Function to read bytes. */ extern pfi char_out; /* function to write bytes. */ /* put_byte is used for the compressed output, put_ubyte for the * uncompressed output. However unlzw() uses window for its * suffix table instead of its output buffer, so it does not use put_ubyte * (to be cleaned up). */ /* Output a 16 bit value, lsb first */ #define seekable() 0 /* force sequential output */ #define translate_eol 0 /* no option -a yet */ #define tolow(c) (isupper(c) ? (c)-'A'+'a' : (c)) /* force to lower case */ /* Macros for getting two-byte and four-byte header values */ #define SH(p) ((unsigned short)(byte)((p)[0]) | \ ((unsigned short)(byte)((p)[1]) << 8)) #define LG(p) ((unsigned long)(SH(p)) | ((unsigned long)(SH((p)+2)) << 16)) #ifdef XXXDEBUG # define Tracevv(x) {if (verbose>1) fprintf x ;} # define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} #else # define Tracevv(x) # define Tracecv(c,x) #endif /* * Function prototypes. */ extern int flush_window( void ); skycat-3.1.2-starlink-1b/astrotcl/press/gzip_inflate.c000066400000000000000000001045251215713201500227520ustar00rootroot00000000000000/*+ ************************************************************************ **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** * * Module Name: press/src/gzip_inflate.c * * Purpose: * Contains the gzip_inflate routine for gzip. * * gzip_inflate.c -- Not copyrighted 1992 by Mark Adler * version c10p1, 10 January 1993 * * You can do whatever you like with this source file, though I would * prefer that if you modify it and redistribute it that you include * comments to that effect with your name and the date. Thank you. * [The history has been moved to the file ChangeLog.] * * * Inflate deflated (PKZIP's method 8 compressed) data. The compression * method searches for as much of the current string of bytes (up to a * length of 258) in the previous 32K bytes. If it doesn't find any * matches (of at least length 3), it codes the next byte. Otherwise, it * codes the length of the matched string and its distance backwards from * the current position. There is a single Huffman code that codes both * single bytes (called "literals") and match lengths. A second Huffman * code codes the distance information, which follows a length code. Each * length or distance code actually represents a base value and a number * of "extra" (sometimes zero) bits to get to add to the base value. At * the end of each deflated block is a special end-of-block (EOB) literal/ * length code. The decoding process is basically: get a literal/length * code; if EOB then done; if a literal, emit the decoded byte; if a * length then get the distance and emit the referred-to bytes from the * sliding window of previously emitted data. * * There are (currently) three kinds of inflate blocks: stored, fixed, and * dynamic. The compressor deals with some chunk of data at a time, and * decides which method to use on a chunk-by-chunk basis. A chunk might * typically be 32K or 64K. If the chunk is uncompressible, then the * "stored" method is used. In this case, the bytes are simply stored as * is, eight bits per byte, with none of the above coding. The bytes are * preceded by a count, since there is no longer an EOB code. * * If the data is compressible, then either the fixed or dynamic methods * are used. In the dynamic method, the compressed data is preceded by * an encoding of the literal/length and distance Huffman codes that are * to be used to decode this block. The representation is itself Huffman * coded, and so is preceded by a description of that code. These code * descriptions take up a little space, and so for small blocks, there is * a predefined set of codes, called the fixed codes. The fixed method is * used if the block codes up smaller that way (usually for quite small * chunks), otherwise the dynamic method is used. In the latter case, the * codes are customized to the probabilities in the current block, and so * can code it much better than the pre-determined fixed codes. * * The Huffman codes themselves are decoded using a mutli-level table * lookup, in order to maximize the speed of decoding plus the speed of * building the decoding tables. See the comments below that precede the * lbits and dbits tuning parameters. * * * Notes beyond the 1.93a appnote.txt: * * 1. Distance pointers never point before the beginning of the output * stream. * 2. Distance pointers can point back across blocks, up to 32k away. * 3. There is an implied maximum of 7 bits for the bit length table and * 15 bits for the actual data. * 4. If only one code exists, then it is encoded using one bit. (Zero * would be more efficient, but perhaps a little confusing.) If two * codes exist, they are coded using one bit each (0 and 1). * 5. There is no way of sending zero distance codes--a dummy must be * sent if there are none. (History: a pre 2.0 version of PKZIP would * store blocks with no distance codes, but this was discovered to be * too harsh a criterion.) Valid only for 1.93a. 2.04c does allow * zero distance codes, which is sent as one code of zero bits in * length. * 6. There are up to 286 literal/length codes. Code 256 represents the * end-of-block. Note however that the static length tree defines * 288 codes just to fill out the Huffman codes. Codes 286 and 287 * cannot be used though, since there is no length base or extra bits * defined for them. Similarly, there are up to 30 distance codes. * However, static trees define 32 codes (all 5 bits) to fill out the * Huffman codes, but the last two had better not show up in the data. * 7. Unzip can check dynamic Huffman blocks for complete code sets. * The exception is that a single code would not be complete (see #4). * 8. The five bits following the block type is really the number of * literal codes sent minus 257. * 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits * (1+6+6). Therefore, to output three times the length, you output * three codes (1+1+1), whereas to output four times the same length, * you only need two codes (1+3). Hmm. * 10. In the tree reconstruction algorithm, Code = Code + Increment * only if BitLength(i) is not zero. (Pretty obvious.) * 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) * 12. Note: length code 284 can represent 227-258, but length code 285 * really is 258. The last length deserves its own, short code * since it gets used a lot in very redundant files. The length * 258 is special since 258 - 3 (the min match length) is 255. * 13. The literal/length and distance code bit lengths are read as a * single stream of lengths. It is possible (and advantageous) for * a repeat code (16, 17, or 18) to go across the boundary between * the two sets of lengths. * * Routines: * type routine : Brief description. * type routine : Brief description. * type routine : Brief description. * * Date : mmm dd, 1993 * * SCCS data : @(#) * Module Name : gzip_inflate.c * Version Number : 1.5 * Release Number : 1 * Last Updated : 08/29/97 * * Programmer : your name * * Modification History: * 97/07/02 SEC : Bring up to ANSI Standard. * 97/08/29 SEC : Free window buffer in gzip_inflate(). * 98/10/29 ESO : Added "static" keywords to avoid conflict with tclpro libs * **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** ************************************************************************ -*/ #include #include #include "gen_types.h" #include "press.h" #include "local_press.h" #include "gzip.h" static int huft_free(HUFT *t); /* allan: added proto */ /* * The inflate algorithm uses a sliding 32K byte window on the uncompressed * stream to find repeated byte strings. This is implemented here as a * circular buffer. The index is updated simply by incrementing and then * and'ing with 0x7fff (32K-1). */ /* byte *swindow; (allan: was already defined in gzip.h) */ unsigned outcnt; /* current position in window */ #define flush_output(w) (outcnt=(w),flush_window()) /* * Tables for deflate from PKZIP's appnote.txt. */ static unsigned border[] = { /* Order of the bit length code lengths */ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; static unsigned short cplens[] = {/* Copy lengths for literal codes 257..285 */ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; /* note: see note #13 above about the 258 in this list. */ static unsigned short cplext[] = {/* Extra bits for literal codes 257..285 */ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */ static unsigned short cpdist[] = {/* Copy offsets for distance codes 0..29 */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; static unsigned short cpdext[] = {/* Extra bits for distance codes */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; /* * Macros for gzip_inflate() bit peeking and grabbing. * The usage is: * * NEEDBITS(j) * x = b & mask_bits[j]; * DUMPBITS(j) * * where NEEDBITS makes sure that b has at least j bits in it, and * DUMPBITS removes the bits from b. The macros use the variable k * for the number of bits in b. Normally, b and k are register * variables for speed, and are initialized at the beginning of a * routine that uses these macros from a global bit buffer and count. * * If we assume that EOB will be the longest code, then we will never * ask for bits with NEEDBITS that are beyond the end of the stream. * So, NEEDBITS should not read any more bytes than are needed to * meet the request. Then no bytes need to be "returned" to the buffer * at the end of the last block. * * However, this assumption is not true for fixed blocks--the EOB code * is 7 bits, but the other literal/length codes can be 8 or 9 bits. * (The EOB code is shorter than other codes because fixed blocks are * generally short. So, while a block always has an EOB, many other * literal/length codes have a significantly lower probability of * showing up at all.) However, by making the first table have a * lookup of seven bits, the EOB code will be found in that first * lookup, and so will not require that too many bits be pulled from * the stream. */ static unsigned long bb; /* bit buffer */ static unsigned bk; /* bits in bit buffer */ static unsigned short mask_bits[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff }; #define NEXTBYTE() (byte)get_byte() #define NEEDBITS(n) {while(k<(n)){b|=((unsigned long)NEXTBYTE())<>=(n);k-=(n);} /* * Huffman code decoding is performed using a multi-level table lookup. * The fastest way to decode is to simply build a lookup table whose * size is determined by the longest code. However, the time it takes * to build this table can also be a factor if the data being decoded * is not very long. The most common codes are necessarily the * shortest codes, so those codes dominate the decoding time, and hence * the speed. The idea is you can have a shorter table that decodes the * shorter, more probable codes, and then point to subsidiary tables for * the longer codes. The time it costs to decode the longer codes is * then traded against the time it takes to make longer tables. * * This results of this trade are in the variables lbits and dbits * below. lbits is the number of bits the first level table for literal/ * length codes can decode in one step, and dbits is the same thing for * the distance codes. Subsequent tables are also less than or equal to * those sizes. These values may be adjusted either when all of the * codes are shorter than that, in which case the longest code length in * bits is used, or when the shortest code is *longer* than the requested * table size, in which case the length of the shortest code in bits is * used. * * There are two different values for the two tables, since they code a * different number of possibilities each. The literal/length table * codes 286 possible values, or in a flat code, a little over eight * bits. The distance table codes 30 possible values, or a little less * than five bits, flat. The optimum values for speed end up being * about one bit more than those, so lbits is 8+1 and dbits is 5+1. * The optimum values may differ though from machine to machine, and * possibly even between compilers. Your mileage may vary. */ static int lbits = 9; /* bits in base literal/length lookup table */ static int dbits = 6; /* bits in base distance lookup table */ /* * If BMAX needs to be larger than 16, then h and x[] should be ulg. */ #define BMAX 16 /* maximum bit length of any code (16 for explode) */ #define N_MAX 288 /* maximum number of codes in any set */ static unsigned hufts; /* track memory usage */ /*+ ************************************************************************ * * Synopsis: * int huft_build( b, n, s, d, e, t, m ) * * Purpose: * Given a list of code lengths and a maximum table size, make a set of * tables to decode that set of codes. Return zero on success, one if * the given code set is incomplete (the tables are still built in this * case), two if the input is invalid (all zero length codes or an * oversubscribed set of lengths), and three if not enough memory. * * Parameters: * unsigned *b : (mod) code lengths in bits (all assumed * <= BMAX) * unsigned n : (in) Number of codes (assumed <= N_MAX) * unsigned s : (in) number of simple-valued codes (0..s-1) * unsigned short *d : (mod) list of base values for non-simple codes * unsigned short *e : (mod) list of extra bits for non-simple codes * struct huft **t : (out) result: starting table. * int *m : (mod) maximum lookup bits, returns actual. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_INC_LIT : Code set is incomplete (the tables are * still built in this case) * int PR_E_DATA : The input is invalid (all zero length * codes or an oversubscribed set of lengths) * int PR_E_MEMORY : Memory allocation failure. * ************************************************************************ -*/ static int huft_build ( unsigned *b, /* (???) */ unsigned n, /* (???) */ unsigned s, /* (???) */ unsigned short *d, /* (???) */ unsigned short *e, /* (???) */ HUFT **t, /* (???) */ int *m /* (???) */ ) { /* void pr_format_message(); */ unsigned a; /* counter for codes of length k */ unsigned c[BMAX+1]; /* bit length count table */ unsigned f; /* i repeats in table every f entries */ int g; /* maximum code length */ int h; /* table level */ unsigned i; /* counter, current code */ unsigned j; /* counter */ int k; /* number of bits in current code */ int l; /* bits per table (returned in m) */ unsigned *p; /* pointer into c[], b[], or v[] */ HUFT *q; /* points to current table */ HUFT r; /* table entry for structure assignment */ HUFT *u[BMAX]; /* table stack */ unsigned v[N_MAX]; /* values in order of bit length */ int w; /* bits before this table == (l * h) */ unsigned x[BMAX+1]; /* bit offsets, then code stack */ unsigned *xp; /* pointer into x */ int y; /* number of dummy codes added */ unsigned z; /* number of entries in current table */ /* * Generate counts for each bit length */ (void) memzero(c, sizeof(c)); p = b; i = n; do { Tracecv(*p, (stderr, (n-i >= ' ' && n-i <= '~' ? "%c %d\n" : "0x%x %d\n"), n-i, *p)); c[*p++]++; /* assume all entries <= BMAX */ } while (--i); if (c[0] == n) /* null input--all zero length codes */ { *t = (HUFT *) NULL; *m = 0; return( PR_SUCCESS ); } /* * Find minimum and maximum length, bound *m by those */ l = *m; for (j = 1; j <= BMAX; j++) { if (c[j]) { break; } } k = j; /* minimum code length */ if ((unsigned)l < j) { l = j; } for (i = BMAX; i; i--) { if (c[i]) { break; } } g = i; /* maximum code length */ if ((unsigned)l > i) { l = i; } *m = l; /* * Adjust last length count to fill out codes, if needed */ for (y = 1 << j; j < i; j++, y <<= 1) { if ((y -= c[j]) < 0) { pr_format_message( PR_E_DATA ); return( PR_E_DATA ); /* bad input: more codes than bits */ } } if ((y -= c[i]) < 0) { pr_format_message( PR_E_DATA ); return( PR_E_DATA ); /* bad input: more codes than bits */ } c[i] += y; /* * Generate starting offsets into the value table for each length */ x[1] = j = 0; p = c + 1; xp = x + 2; while (--i) /* note that i == g from above */ { *xp++ = (j += *p++); } /* Make a table of values in order of bit lengths */ p = b; i = 0; do { if ((j = *p++) != 0) { v[x[j]++] = i; } } while (++i < n); /* * Generate the Huffman codes and for each, make the table entries */ x[0] = i = 0; /* first Huffman code is zero */ p = v; /* grab values in bit order */ h = -1; /* no tables yet--level -1 */ w = -l; /* bits decoded == (l * h) */ u[0] = (HUFT *) NULL; /* just to keep compilers happy */ q = (HUFT *) NULL; /* ditto */ z = 0; /* ditto */ /* * go through the bit lengths (k already is bits in shortest code) */ for (; k <= g; k++) { a = c[k]; while (a--) { /* * here i is the Huffman code of length k bits for value *p * make tables up to required level */ while (k > w + l) { h++; w += l; /* previous table always l bits */ /* * compute minimum size table less than or equal to l bits */ /* upper limit on table size */ z = (z = g - w) > (unsigned)l ? l : z; /* try a k-w bit table */ if ((f = 1 << (j = k - w)) > a + 1) { /* too few codes for k-w bit table */ f -= a + 1; /* deduct codes from patterns left */ xp = c + k; while (++j < z) /* try smaller tables up to z bits */ { if ((f <<= 1) <= *++xp) { break; /* enough codes to use up j bits */ } f -= *xp; /* else deduct codes from patterns */ } } z = 1 << j; /* table entries for j-bit table */ /* * allocate and link in new table */ if ((q = (HUFT *) malloc((z + 1)*sizeof( HUFT ))) == (HUFT *)NULL) { if (h) { PR_CHECK( huft_free(u[0])); } pr_format_message( PR_E_MEMORY ); return( PR_E_MEMORY ); /* not enough memory */ } hufts += z + 1; /* track memory usage */ *t = q + 1; /* link to list for huft_free() */ *(t = &(q->v.t)) = (HUFT *) NULL; u[h] = ++q; /* table starts after link */ /* * connect to last table, if there is one */ if (h) { x[h] = i; /* save pattern for backing up */ r.b = (byte)l; /* bits to dump before this table */ r.e = (byte)(16 + j);/* bits in this table */ r.v.t = q; /* pointer to this table */ j = i >> (w - l); /* (get around Turbo C bug) */ u[h-1][j] = r; /* connect to last table */ } } /* * set up table entry in r */ r.b = (byte)(k - w); if (p >= v + n) { r.e = 99; /* out of values--invalid code */ } else if (*p < s) { r.e = (byte)(*p < 256 ? 16 : 15);/* 256 is end-of-block code */ r.v.n = (byte)(*p); /* simple code is just the value */ p++; /* one compiler does not like *p++ */ } else { r.e = (byte)e[*p - s]; /* non-simple--look up in lists */ r.v.n = d[*p++ - s]; } /* * fill code-like entries with r */ f = 1 << (k - w); for (j = i >> w; j < z; j += f) { q[j] = r; } /* * backwards increment the k-bit code i */ for (j = 1 << (k - 1); i & j; j >>= 1) { i ^= j; } i ^= j; /* * backup over finished tables */ while ((i & ((1 << w) - 1)) != x[h]) { h--; /* don't need to update q */ w -= l; } } } /* * Return true PR_E_INC_LIT if we were given an incomplete table */ if ( y != 0 && g != 1 ) { pr_format_message( PR_E_INC_LIT ); return( PR_E_INC_LIT ); } else { return( PR_SUCCESS ); } } /*+ ************************************************************************ * * Synopsis: * int huft_free( t ) * * Purpose: * Free the malloc'ed tables built by huft_build(), which makes a linked * list of the tables it made, with the links in a dummy first entry of * each table. * * Parameters: * struct huft *t : (in) Table to free. * * Values Returned: * int PR_SUCCESS : Normal completion. * ************************************************************************ -*/ static int huft_free ( HUFT *t /* ( ??? ) */ ) { HUFT *p; HUFT *q; /* * Go through linked list, freeing from the malloced (t[-1]) address. */ p = t; while (p != (HUFT *) NULL) { q = (--p)->v.t; free((char*)p); p = q; } return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * int inflate_codes( tl, td, bl, bd ) * * Purpose: * gzip_inflate (decompress) the codes in a deflated (compressed) block. * * Parameters: * struct huft *tl : (in) literal/length decoder table. * struct huft *td : (in) distance decoder table. * int bl : (in) Number of bits decoded by tl. * int bd : (in) Number of bits decoded by td. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_DATA : Data is undecodable. * ************************************************************************ -*/ static int inflate_codes ( HUFT *tl, /* ( ??? ) */ HUFT *td, /* ( ??? ) */ int bl, /* ( ??? ) */ int bd /* ( ??? ) */ ) { unsigned e; /* table entry flag/number of extra bits*/ unsigned n, d; /* length and index for copy */ unsigned w; /* current window position */ HUFT *t; /* pointer to table entry */ unsigned ml, md; /* masks for bl and bd bits */ unsigned long b; /* bit buffer */ unsigned k; /* number of bits in bit buffer */ /* * make local copies of globals */ b = bb; /* initialize bit buffer */ k = bk; w = outcnt; /* initialize window position */ /* * inflate the coded data */ ml = mask_bits[bl]; /* precompute masks for speed */ md = mask_bits[bd]; for (;;) /* do until end of block */ { NEEDBITS((unsigned)bl) if ((e = (t = tl + ((unsigned)b & ml))->e) > 16) { do { if (e == 99) { pr_format_message( PR_E_DATA ); return( PR_E_DATA ); } DUMPBITS(t->b) e -= 16; NEEDBITS(e) } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16); } DUMPBITS(t->b) if (e == 16) /* then it's a literal */ { swindow[w++] = (byte)t->v.n; Tracevv((stderr, "%c", swindow[w-1])); if (w == WSIZE) { PR_CHECK( flush_output(w) ); w = 0; } } else /* it's an EOB or a length */ { /* exit if end of block */ if (e == 15) { break; } /* * get length of block to copy */ NEEDBITS(e) n = t->v.n + ((unsigned)b & mask_bits[e]); DUMPBITS(e); /* * decode distance of block to copy */ NEEDBITS((unsigned)bd) if ((e = (t = td + ((unsigned)b & md))->e) > 16) { do { if (e == 99) { pr_format_message( PR_E_DATA ); return( PR_E_DATA ); } DUMPBITS(t->b) e -= 16; NEEDBITS(e) } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16); } DUMPBITS(t->b) NEEDBITS(e) d = w - t->v.n - ((unsigned)b & mask_bits[e]); DUMPBITS(e) Tracevv((stderr,"\\[%d,%d]", w-d, n)); /* * do the copy */ do { n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); #if !defined(NOMEMCPY) && !defined(DEBUG) if (w - d >= e) /* (this test assumes unsigned comparison) */ { memcpy(swindow + w, swindow + d, e); w += e; d += e; } else /* do it slow to avoid memcpy() overlap */ #endif /* !NOMEMCPY */ { do { swindow[w++] = swindow[d++]; Tracevv((stderr, "%c", swindow[w-1])); } while (--e); } if (w == WSIZE) { PR_CHECK( flush_output(w) ); w = 0; } } while (n); } } /* * restore the globals from the locals */ outcnt = w; /* restore global window pointer */ bb = b; /* restore global bit buffer */ bk = k; /* * done */ return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * int inflate_stored( ) * * Purpose: * "decompress" an inflated type 0 (stored) block. * * Parameters: * void * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_DATA : An error occured in the data. * ************************************************************************ -*/ static int inflate_stored ( void ) { /* void pr_format_message(); */ unsigned n; /* number of bytes in block */ unsigned w; /* current window position */ unsigned long b; /* bit buffer */ unsigned k; /* number of bits in bit buffer */ /* * make local copies of globals */ b = bb; /* initialize bit buffer */ k = bk; w = outcnt; /* initialize window position */ /* * go to byte boundary */ n = k & 7; DUMPBITS(n); /* * get the length and its complement */ NEEDBITS(16) n = ((unsigned)b & 0xffff); DUMPBITS(16) NEEDBITS(16) if ( n != (unsigned)( ( ~b ) & 0xffff ) ) { /* * An error in the compressed data. */ pr_format_message( PR_E_DATA ); return( PR_E_DATA ); } DUMPBITS(16) /* * read and output the compressed data */ while (n--) { NEEDBITS(8) swindow[w++] = (byte)b; if (w == WSIZE) { PR_CHECK( flush_output( w ) ); w = 0; } DUMPBITS(8) } /* * restore the globals from the locals */ outcnt = w; /* restore global window pointer */ bb = b; /* restore global bit buffer */ bk = k; return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * int inflate_fixed() * * Purpose: * decompress an inflated type 1 (fixed Huffman codes) block. We should * either replace this with a custom decoder, or at least precompute the * Huffman tables. * * Parameters: * void * * Values Returned: * int PR_SUCCESS : Normal completion. * ************************************************************************ -*/ static int inflate_fixed ( void ) { int i; /* temporary variable */ HUFT *tl; /* literal/length code table */ HUFT *td; /* distance code table */ int bl; /* lookup bits for tl */ int bd; /* lookup bits for td */ unsigned l[288]; /* length list for huft_build */ /* * set up literal table */ for (i = 0; i < 144; i++) { l[i] = 8; } for (; i < 256; i++) { l[i] = 9; } for (; i < 280; i++) { l[i] = 7; } for (; i < 288; i++) /* make a complete, but wrong code set */ { l[i] = 8; } bl = 7; PR_CHECK( huft_build(l, 288, 257, cplens, cplext, &tl, &bl)); /* * set up distance table */ for (i = 0; i < 30; i++) /* make an incomplete code set */ { l[i] = 5; } bd = 5; i = huft_build( l, 30, 0, cpdist, cpdext, &td, &bd ); if ( i != PR_SUCCESS && i != PR_E_INC_LIT ) { PR_CHECK( huft_free(tl) ); return i; } /* * decompress until an end-of-block code */ PR_CHECK( inflate_codes(tl, td, bl, bd)); /* * free the decoding tables, return */ PR_CHECK( huft_free(tl) ); PR_CHECK( huft_free(td) ); return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * int inflate_dynamic() * * Purpose: * decompress an inflated type 2 (dynamic Huffman codes) block. * * Parameters: * void * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_DATA : Data could not be decompressed. * ************************************************************************ -*/ static int inflate_dynamic ( void ) { /* void pr_format_message(); */ int i; /* temporary variables */ unsigned j; unsigned l; /* last length */ unsigned m; /* mask for bit lengths table */ unsigned n; /* number of lengths to get */ HUFT *tl; /* literal/length code table */ HUFT *td; /* distance code table */ int bl; /* lookup bits for tl */ int bd; /* lookup bits for td */ unsigned nb; /* number of bit length codes */ unsigned nl; /* number of literal/length codes */ unsigned nd; /* number of distance codes */ #ifdef PKZIP_BUG_WORKAROUND unsigned ll[288+32]; /* literal/length and distance code lengths */ #else unsigned ll[286+30]; /* literal/length and distance code lengths */ #endif unsigned long b; /* bit buffer */ unsigned k; /* number of bits in bit buffer */ /* * make local bit buffer */ b = bb; k = bk; /* * read in table lengths */ NEEDBITS(5) nl = 257 + ((unsigned)b & 0x1f); /* number of literal/length codes */ DUMPBITS(5) NEEDBITS(5) nd = 1 + ((unsigned)b & 0x1f); /* number of distance codes */ DUMPBITS(5) NEEDBITS(4) nb = 4 + ((unsigned)b & 0xf); /* number of bit length codes */ DUMPBITS(4) #ifdef PKZIP_BUG_WORKAROUND if (nl > 288 || nd > 32) #else if (nl > 286 || nd > 30) #endif { /* * Bad lengths. */ pr_format_message( PR_E_DATA ); return( PR_E_DATA ); } /* * read in bit-length-code lengths */ for (j = 0; j < nb; j++) { NEEDBITS(3) ll[border[j]] = (unsigned)b & 7; DUMPBITS(3) } for (; j < 19; j++) { ll[border[j]] = 0; } /* * build decoding table for trees--single level, 7 bit lookup */ bl = 7; if ( ( i = huft_build( ll, 19, 19, NULL, NULL, &tl, &bl ) ) != PR_SUCCESS ) { if ( i == PR_E_INC_LIT ) { PR_CHECK( huft_free(tl) ); } return i; /* incomplete code set */ } /* * read in literal and distance code lengths */ n = nl + nd; m = mask_bits[bl]; i = l = 0; while ( (unsigned) i < n ) { NEEDBITS((unsigned)bl) j = (td = tl + ((unsigned)b & m))->b; DUMPBITS(j) j = td->v.n; if (j < 16) /* length of code in bits (0..15) */ { ll[i++] = l = j; /* save last length in l */ } else if (j == 16) /* repeat last length 3 to 6 times */ { NEEDBITS(2) j = 3 + ((unsigned)b & 3); DUMPBITS(2) if ((unsigned)i + j > n) { pr_format_message( PR_E_DATA ); return( PR_E_DATA ); } while (j--) { ll[i++] = l; } } else if (j == 17) /* 3 to 10 zero length codes */ { NEEDBITS(3) j = 3 + ((unsigned)b & 7); DUMPBITS(3) if ((unsigned)i + j > n) { pr_format_message( PR_E_DATA ); return( PR_E_DATA ); } while (j--) { ll[i++] = 0; } l = 0; } else /* j == 18: 11 to 138 zero length codes */ { NEEDBITS(7) j = 11 + ((unsigned)b & 0x7f); DUMPBITS(7) if ((unsigned)i + j > n) { pr_format_message( PR_E_DATA ); return( PR_E_DATA ); } while (j--) { ll[i++] = 0; } l = 0; } } /* * free decoding table for trees */ PR_CHECK( huft_free(tl) ); /* * restore the global bit buffer */ bb = b; bk = k; /* * build the decoding tables for literal/length and distance codes */ bl = lbits; if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != PR_SUCCESS) { if ( i == PR_E_INC_LIT ) { PR_CHECK( huft_free(tl) ); } return i; /* incomplete code set */ } bd = dbits; if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != PR_SUCCESS) { if (i == PR_E_INC_LIT ) { #ifdef PKZIP_BUG_WORKAROUND i = 0; } #else PR_CHECK( huft_free(td) ); } PR_CHECK( huft_free(tl) ); return( i ); /* incomplete code set */ #endif } /* * decompress until an end-of-block code */ PR_CHECK( inflate_codes(tl, td, bl, bd)); /* * free the decoding tables, return */ PR_CHECK( huft_free(tl) ); PR_CHECK( huft_free(td) ); return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * static int inflate_block( e ) * * Purpose: * decompress an inflated block * * Parameters: * boolean e : (out) End flag. * * Values Returned: * int PR_SUCCESS : Normal completion. * ************************************************************************ -*/ static int inflate_block ( boolean *e /* (???) */ ) { unsigned t; /* block type */ unsigned long b; /* bit buffer */ unsigned k; /* number of bits in bit buffer */ /* * make local bit buffer */ b = bb; k = bk; /* * read in last block bit */ NEEDBITS(1) *e = (int)b & 1; DUMPBITS(1) /* * read in block type */ NEEDBITS(2) t = (unsigned)b & 3; DUMPBITS(2) /* * restore the global bit buffer */ bb = b; bk = k; /* * inflate that block type */ if ( t == 2 ) { return( inflate_dynamic() ); } else if ( t == 0 ) { return( inflate_stored() ); } else if ( t == 1 ) { return( inflate_fixed() ); } /* * bad block type */ pr_format_message( PR_E_BLOCK, t ); return( PR_E_BLOCK ); } /*+ ************************************************************************ * * Synopsis: * int gzip_inflate() * * Purpose: * Decompress an inflated entry. * * Parameters: * void * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_MEMORY : Memory alloation failure. * ************************************************************************ -*/ int gzip_inflate ( void ) { /* static int inflate_block(); */ boolean e; /* last block flag */ unsigned h; /* maximum struct huft's malloc'ed */ /* * initialize window, bit buffer */ outcnt = 0; bk = 0; bb = 0; PR_CHECK_NULL(swindow = byte_alloc( WSIZE ) ); /* * decompress until the last block */ h = 0; do { hufts = 0; PR_CHECK( inflate_block( &e ) ); if (hufts > h) { h = hufts; } } while ( !e ); /* * Undo too much lookahead. The next read will be byte aligned so we * can discard unused bits in the last meaningful byte. */ while ( bk >= 8 ) { bk -= 8; inptr--; } /* * flush out window, free memory allocated to window. */ PR_CHECK( flush_output( outcnt ) ); gen_free( swindow ); return( PR_SUCCESS ); } skycat-3.1.2-starlink-1b/astrotcl/press/gzip_util.c000066400000000000000000000372221215713201500223040ustar00rootroot00000000000000/*+ ************************************************************************ **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** * * Module Name: press/src/gzip_util.c * * Purpose: * Contains utility routines for gzip. * * Routines: * type routine : Brief description. * type routine : Brief description. * type routine : Brief description. * * Date : mmm dd, 1993 * * SCCS data : @(#) * Module Name : gzip_util.c * Version Number : 1.2 * Release Number : 1 * Last Updated : 07/04/97 * * Programmer : your name * * Modification History: * 97/07/02 SEC : Bring up to ANSI standard. * **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** ************************************************************************ -*/ #include "gen_types.h" #include "press.h" #include "local_press.h" #include "gzip.h" /* ======================================================================== * Table of CRC-32's of all single-byte values (made by makecrc.c) */ static unsigned long crc_32_tab[] = { 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, 0x2d02ef8dUL }; int get_byte ( void ) { byte c; int s; s = char_in( &c, 1 ); return( (int) c ); } #ifdef omit /* util.c -- utility functions for gzip support * Copyright (C) 1992-1993 Jean-loup Gailly * This is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, see the file COPYING. */ #include #include #include x#include "tailor.h" #include #include x#include "gzip.h" x#include "crypt.h" /* =========================================================================== * Copy input to output unchanged: zcat == cat with --force. * IN assertion: insize bytes have already been read in inbuf. */ int copy ( int in, /* Input file descriptor. */ int out /* Output file descriptor. */ ) { errno = 0; while (insize != 0 && (int)insize != EOF) { write_buf(out, (char*)inbuf, insize); bytes_out += insize; insize = read(in, (char*)inbuf, INBUFSIZ); } if ((int)insize == EOF && errno != 0) { read_error(); } bytes_in = bytes_out; return OK; } #endif /* omit */ /* =========================================================================== * Run a set of bytes through the crc shift register. If s is a NULL * pointer, then initialize the crc shift register contents instead. * Return the current crc in either case. */ unsigned long updcrc ( byte *s, /* pointer to bytes to pump through. */ unsigned n /* number of bytes in s[]. */ ) { unsigned long c; /* temporary variable. */ static unsigned long crc = 0xffffffffUL; /* shift register contents. */ if (s == NULL) { c = 0xffffffffUL; } else { c = crc; for ( ; n > (unsigned) 0 ; n-- ) { c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8); } } crc = c; return ( c ^ 0xffffffffUL ); /* (instead of ~c for 64-bit machines) */ } #ifdef omit /* =========================================================================== * Clear input and output buffers */ void clear_bufs ( void ) { outcnt = 0; insize = inptr = 0; bytes_in = bytes_out = 0L; } /* =========================================================================== * Fill the input buffer. This is called only when the buffer is empty. */ int fill_inbuf ( int eof_ok /* set if EOF acceptable as a result. */ ) { /* void pr_format_message(); */ int len; /* Read as much as possible */ insize = 0; errno = 0; do { len = char_in((char*)inbuf+insize, INBUFSIZ-insize); if (len == 0 || len == PR_E_EOI ) break; insize += len; } while (insize < INBUFSIZ); if (insize == 0) { if (eof_ok) return(PR_E_EOI); pr_format_message( PR_E_EOI ); } bytes_in += (unsigned long)insize; inptr = 1; return inbuf[0]; } /* =========================================================================== * Write the output buffer outbuf[0..outcnt-1] and update bytes_out. * (used for the compressed data only) */ void flush_outbuf ( void ) { if (outcnt == 0) return; write_buf(ofd, (char *)outbuf, outcnt); bytes_out += (ulg)outcnt; outcnt = 0; } #endif /* omit */ /*+ ************************************************************************ * * Synopsis: * int flush_window() * * Purpose: * Write the output window window[0..outcnt-1] and update crc and * bytes_out. (Used for the decompressed data only.) * * Parameters: * type arg1 : (in) What it is * type arg2 : (mod) What it is * type argn : (out) What it is * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_IO : Io error. * ************************************************************************ -*/ int flush_window ( void ) { if (outcnt == 0) { return( PR_SUCCESS ); } updcrc(swindow, outcnt); PR_CHECK( char_out( swindow, outcnt ) ); bytes_out += (unsigned long) outcnt; outcnt = 0; return( PR_SUCCESS ); } #ifdef omit /* ======================================================================== * Put string s in lower case, return s. */ char *strlwr ( char *s /* (mod) string to mod to lower case. */ ) { char *t; /* pointer into string. */ for (t = s; *t; t++) *t = tolow(*t); return s; } /* ======================================================================== * Return the base name of a file (remove any directory prefix and * any version suffix). For systems with file names that are not * case sensitive, force the base name to lower case. */ char *basename ( char *fname /* (mod) Filename to get base name of. */ ) { char *p; /* pointer into filename string. */ if ((p = strrchr(fname, PATH_SEP)) != NULL) fname = p+1; #ifdef PATH_SEP2 if ((p = strrchr(fname, PATH_SEP2)) != NULL) fname = p+1; #endif #ifdef PATH_SEP3 if ((p = strrchr(fname, PATH_SEP3)) != NULL) fname = p+1; #endif #ifdef SUFFIX_SEP if ((p = strrchr(fname, SUFFIX_SEP)) != NULL) *p = '\0'; #endif if (casemap('A') == 'a') strlwr(fname); return fname; } /* ======================================================================== * Make a file name legal for file systems not allowing file names with * multiple dots or starting with a dot (such as MSDOS), by changing * all dots except the last one into underlines. A target dependent * function can be used instead of this simple function by defining the macro * MAKE_LEGAL_NAME in tailor.h and providing the function in a target * dependent module. */ void make_simple_name ( char *name /* (mod) filename to make legal. */ ) { char *p = strrchr(name, '.'); /* pointer into filename string. */ if (p == NULL) return; if (p == name) p++; do { if (*--p == '.') *p = '_'; } while (p != name); } #if defined(NO_STRING_H) && !defined(STDC_HEADERS) /* Provide missing strspn and strcspn functions. */ # ifndef __STDC__ # define const # endif int strspn OF((const char *s, const char *accept)); int strcspn OF((const char *s, const char *reject)); /* ======================================================================== * Return the length of the maximum initial segment * of s which contains only characters in accept. */ int strspn ( const char *s, /* (in) String to search for chars in. */ const char *accept /* (in) String of chars to search for. */ ) { register const char *p; /* Pointer into string s. */ register const char *a; /* Pointer into string a. */ register int count = 0; /* Counter. */ for (p = s; *p != '\0'; ++p) { for (a = accept; *a != '\0'; ++a) { if (*p == *a) break; } if (*a == '\0') return count; ++count; } return count; } /* ======================================================================== * Return the length of the maximum inital segment of s * which contains no characters from reject. */ int strcspn ( const char *s, /* (in) String to search for chars in. */ const char *reject /* (in) String of chars to search for. */ ) { register int count = 0; /* Counter. */ while (*s != '\0') { if (strchr(reject, *s++) != NULL) return count; ++count; } return count; } #endif /* NO_STRING_H */ /* ======================================================================== * Add an environment variable (if any) before argv, and update argc. * Return the expanded environment variable to be freed later, or NULL * if no options were added to argv. */ #define SEPARATOR " \t" /* separators in env variable */ char *add_envopt ( int *argcp, /* pointer to argc */ char ***argvp, /* pointer to argv */ char *env /* name of environment variable */ ) { char *p; /* running pointer through env variable */ char **oargv; /* runs through old argv array */ char **nargv; /* runs through new argv array */ int oargc = *argcp; /* old argc */ int nargc = 0; /* number of arguments in env variable */ env = (char*)getenv(env); if (env == NULL) return NULL; p = (char*)xmalloc(strlen(env)+1); env = strcpy(p, env); /* keep env variable intact */ for (p = env; *p; nargc++ ) { /* move through env */ p += strspn(p, SEPARATOR); /* skip leading separators */ if (*p == '\0') break; p += strcspn(p, SEPARATOR); /* find end of word */ if (*p) *p++ = '\0'; /* mark it */ } if (nargc == 0) { free(env); env = NULL; return NULL; } *argcp += nargc; /* Allocate the new argv array, with an extra element just in case * the original arg list did not end with a NULL. */ nargv = (char**)calloc(*argcp+1, sizeof(char *)); if (nargv == NULL) error("out of memory"); oargv = *argvp; *argvp = nargv; /* Copy the program name first */ if (oargc-- < 0) error("argc<=0"); *(nargv++) = *(oargv++); /* Then copy the environment args */ for (p = env; nargc > 0; nargc--) { p += strspn(p, SEPARATOR); /* skip separators */ *(nargv++) = p; /* store start */ while (*p++) ; /* skip over word */ } /* Finally copy the old args and add a NULL (usual convention) */ while (oargc--) *(nargv++) = *(oargv++); *nargv = NULL; return env; } /* ======================================================================== * Error handlers. */ void error ( char *m /* (in) Message to print. */ ) { fprintf(stderr, "\n%s: %s: %s\n", progname, ifname, m); abort_gzip(); } void warn ( char *a, /* message string juxtaposed in output */ char *b /* message string juxtaposed in output */ ) { WARN((stderr, "%s: %s: warning: %s%s\n", progname, ifname, a, b)); } void read_error ( void ) { fprintf(stderr, "\n%s: ", progname); if (errno != 0) { perror(ifname); } else { fprintf(stderr, "%s: unexpected end of file\n", ifname); } abort_gzip(); } void write_error ( void ) { fprintf(stderr, "\n%s: ", progname); perror(ofname); abort_gzip(); } /* ======================================================================== * Display compression ratio on the given stream on 6 characters. */ void display_ratio ( long num; long den; FILE *file; ) { long ratio; /* 1000 times the compression ratio. */ if (den == 0) { ratio = 0; /* no compression */ } else if (den < 2147483L) { /* (2**31 -1)/1000 */ ratio = 1000L*num/den; } else { ratio = num/(den/1000L); } if (ratio < 0) { putc('-', file); ratio = -ratio; } else { putc(' ', file); } fprintf(file, "%2ld.%1ld%%", ratio / 10L, ratio % 10L); } /* ======================================================================== * Semi-safe malloc -- never returns NULL. */ voidp i xmalloc ( unsigned size; /* (in) Size to malloc. */ ) { voidp cp = (voidp)malloc (size); /* pointer to malloced memory. */ if (cp == NULL) error("out of memory"); return cp; } #endif skycat-3.1.2-starlink-1b/astrotcl/press/h_comp.h000066400000000000000000000016131215713201500215430ustar00rootroot00000000000000/*+ ************************************************************************ **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** * * Include File Name: press/h/h_comp.h * * Purpose: * Header file for the h compress routines. * * Date : Mar 15, 1993 * * SCCS data : @(#) * Module Name : h_comp.h * Version Number : 1.3 * Release Number : 1 * Last Updated : 30 Mar 1993 * * Programmer : Norman Hill * * Modification History: * **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** ************************************************************************ -*/ static unsigned char code_magic[2] = { 0xDD, 0x99 }; /* allan: see h_decomp.c for routine */ /* #define read_int( char_in, data ) char_in( (byte *) data, sizeof( int ) ) */ /* allan: see h_press.c for routine */ /*#define write_int( char_out, data ) char_out( (byte *) data, sizeof( int ) )*/ skycat-3.1.2-starlink-1b/astrotcl/press/h_decomp.c000066400000000000000000000723501215713201500220550ustar00rootroot00000000000000/*+ ************************************************************************ **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** * * Module Name: press/src/h_uncomp.c * * Purpose: * Countains routines to decompress hcompressed data. * * Routines: * static int decode : Decode hcompressed data. * static int dodecode : Do the decode. * static int fitspass : Pass fits header from input to output. * int h_uncomp : Uncompresses hcompressed data. * static int input_bit : Gets a single bit from the input. * static int input_huffman : Huffman decoding for fixed codes. * static int input_nbits : Get a specified number of bits from * the input. * static int makefits : Write a simple fits header for a * 2-d image. * static void qtree_bitins : * static void qtree_copy : * static int qtree_decode : Turn a stream of bits into a * bitplanes. * static int qtree_expand : Do one quadtree expansion step. * static int read_bdirect : Reads an image packed 4 bits per * byte. * static void start_inputing_bits : Initializes the bit input functions. * * Date : Mar 15, 1993 * * SCCS data : @(#) * Module Name : h_decomp.c * Version Number : 1.7 * Release Number : 1 * Last Updated : 07/04/97 * * Programmer : Norman Hill * * Modification History: * 97/07/02 SEC : Bring up to ANSI standard. * **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** ************************************************************************ -*/ #include #include #include #include #include #include "gen_types.h" #include "gen_str.h" #include "gen_msg.h" #include "press.h" #include "local_press.h" #include "h_comp.h" #define input_nybble(char_in) input_nbits(char_in,4) /* THE BIT BUFFER */ static int buffer; /* Bits waiting to be input */ static int bits_to_go; /* Number of bits still in buffer */ /* * Static function prototypes. */ static int decode( ); static int dodecode( pfi, int *, int, int, byte * ); static int fitspass( pfi, boolean, pfi ); static int makefits( pfi, int, int, int, char * ); static int input_bit( pfi ); static int input_nbits( pfi, int ); static int qtree_decode( pfi, int *, int, int, int, int ); static void start_inputing_bits( void ); static int input_huffman( pfi ); static void qtree_bitins( byte *, int, int, int *, int, int ); static void qtree_copy( byte *, int, int, byte *, int ); static int qtree_expand ( pfi, byte *, int, int, byte * ); static int read_bdirect ( pfi, int *, int, int, int, byte *, int ); /* * allan: 17.12.97: replaced a non-portable #define with this routine */ int read_int(pfi char_in, int* i) { int status = char_in((byte *)i, sizeof(int)); *i = ntohl(*i); return status; } /*+ ************************************************************************ * * Synopsis: * static int decode( char_in, char_out, a, nx, ny, scale, format ) * * Purpose: * Reads codes from an hcompressed file and creates an array. * * Parameters: * int (*char_in)() : (in) Function to read data. * int (*char_out)() : (in) Function to write data. * int **a : (out) Address of output array. * int *nx : (out) Size on x axis. * int *ny : (out) Size on y axis. * int *scale : (out) Scale factor of digitization. * char **format : (mod) A string indicating the output type. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_FORMAT : Data format was incorrect. * int PR_E_IO : Error during io. * int PR_E_MEMORY : Memory allocation failure. * ************************************************************************ -*/ static int decode ( pfi char_in, /* (in) Function to read data. */ pfi char_out, /* (in) Function to write data. */ int **a, /* (out) Address of output array. */ int *nx, /* (out) Size on x axis. */ int *ny, /* (out) Size on y axis. */ int *scale, /* (out) Scale factor of digitization. */ char **format /* (mod) String of the output type. */ ) { /* int dodecode(); */ /* static int fitspass(); */ /* static int makefits(); */ /* void pr_format_message(); */ int nel; int sumall; int newfits = 0; byte nbitplanes[3]; char tmagic[2]; char line[81]; /* * File starts either with special 2-byte magic code or with * FITS keyword "SIMPLE =" */ PR_CHECK( char_in( tmagic, sizeof( tmagic ) ) ); /* * Check for FITS */ if ( strncmp( tmagic, "SI", 2 ) == 0 ) { /* * read rest of line and make sure the whole keyword is correct */ (void) strncpy( line, "SI", 2 ); if ( char_in( line + 2, 78 ) != 78 ) { pr_format_message( PR_E_FORMAT ); return( PR_E_FORMAT ); } line[80] = '\0'; if ( strncmp( line, "SIMPLE =", 9) != 0 ) { pr_format_message( PR_E_FORMAT ); return( PR_E_FORMAT ); } /* * set output format to default "fits" if it is empty */ if ( ( *format )[0] == '\0' ) { *format = "fits"; } /* * if fits output format and outfile != NULL, write this line to * outfile and then copy rest of FITS header; else just read past * FITS header. */ if ( strcmp( *format, "fits" ) == 0 ) { char_out( line, 80 ); PR_CHECK( fitspass( char_in, TRUE, char_out ) ); } else { PR_CHECK( fitspass( char_in, FALSE, char_out) ); } /* * now read the next two characters -- this time they * MUST be the magic code! */ PR_CHECK( char_in( tmagic, sizeof( tmagic ) ) ); } else { /* * set default format to raw if it is not specified */ if( ( *format )[0] == '\0' ) { *format = "raw"; } /* * if input format is not FITS but output format is FITS, set * a flag so we generate a FITS header once we know how big * the image must be. */ if ( strcmp( *format, "fits" ) == 0) { newfits = 1; } } /* * check for correct magic code value */ if ( memcmp( tmagic, code_magic, sizeof( code_magic ) ) != 0) { pr_format_message( PR_E_FORMAT ); return( PR_E_FORMAT ); } /* * Read the size of the image and the scale factor for digitization. */ PR_CHECK( read_int( char_in, nx ) ); PR_CHECK( read_int( char_in, ny ) ); PR_CHECK( read_int( char_in, scale ) ); /* * write the new fits header to outfile if needed */ if ( newfits ) { PR_CHECK( makefits( char_out, *nx, *ny, 16, "INTEGER*2" ) ); } /* * allocate memory for array */ nel = (*nx) * (*ny); PR_CHECK_NULL( *a = int_alloc( nel ) ); /* * Read the sum of all pixels */ PR_CHECK( read_int( char_in, &sumall ) ); /* * Read the number of bits in quadrants. */ PR_CHECK( char_in( nbitplanes, sizeof( nbitplanes ) ) ); PR_CHECK( dodecode( char_in, *a, *nx, *ny, nbitplanes ) ); /* * put sum of all pixels back into pixel 0 */ (*a)[0] = sumall; return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * static int dodecode( char_in, a, nx, ny, nbitplanes ) * * Purpose: * Decode stream of characters and return array * This version encodes the different quadrants separately * * Parameters: * int (*char_in)() : (in) Function to get the next data. * int a[] : (in) Array to be created. * int nx : (in) X axis dimension. * int ny : (in) Y axis dimension. * int nbitplanes : (in) Number of bitplanes in quadrants. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_BITPLANE: Bad bit plane. * int PR_E_CODE : Bad format code. * int PR_E_IO : Error during io. * int PR_E_MEMORY : Memory allocation failure. * * References: * Copied from function dodecode from the hcompress program. * Programmer: R. White Date: 9 May 1991 * ************************************************************************ -*/ static int dodecode ( pfi char_in, int a[], int nx, int ny, byte nbitplanes[3] ) { /* static int input_bit(); */ /* static int input_nbits(); */ /* static int qtree_decode(); */ /* static void start_inputing_bits(); */ byte bit; /* The value of a bit. */ int i; int nel; int nx2; int ny2; nel = nx*ny; nx2 = (nx+1)/2; ny2 = (ny+1)/2; /* * initialize a to zero */ for ( i = 0; i < nel; i++ ) { a[i] = 0; } /* * Initialize bit input */ start_inputing_bits(); /* * read bit planes for each quadrant */ PR_CHECK( qtree_decode( char_in, &a[0], ny, nx2, ny2, nbitplanes[0] ) ); PR_CHECK( qtree_decode( char_in, &a[ny2], ny, nx2, ny/2, nbitplanes[1] ) ); PR_CHECK( qtree_decode( char_in, &a[ny*nx2], ny, nx/2, ny2, nbitplanes[1] ) ); PR_CHECK( qtree_decode( char_in, &a[ny*nx2+ny2], ny, nx/2, ny/2, nbitplanes[2] ) ); /* * make sure there is an EOF symbol (nybble=0) at end */ if ( input_nybble( char_in ) != 0 ) { pr_format_message( PR_E_BITPLANE ); return( PR_E_BITPLANE ); } /* * now get the sign bits * Re-initialize bit input */ start_inputing_bits(); for ( i = 0; i < nel; i++) { if ( a[i] != 0 ) { PR_CHECK( bit = input_bit( char_in ) ); if ( bit != 0 ) { a[i] = -a[i]; } } } return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * static int fitspass( char_in, passthru, char_out ) * * Purpose: * Skip over the fits header in the input, and optionaly copy it to * the output. * * Parameters: * int (*char_in)() : (in) Function to get data from the input. * boolean passthru : (in) True if the header should be written * to the output. * int (*char_out)() : (in) Function to write data to the output. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_IO : Error during io. * int PR_E_EOI : End of input. * * References: * Copied from function dodecode from the hcompress program. * Programmer: R. White Date: 16 April 1992 * ************************************************************************ -*/ static int fitspass ( pfi char_in, boolean passthru, pfi char_out ) { char line[81]; int i; int j; /* * Note that the SIMPLE line has already been stripped off and * written to outfile for FITS files, so we start at i=1 */ for ( i = 1;; i++ ) { PR_CHECK( char_in( line, 80 ) ); if ( passthru ) { PR_CHECK( char_out( line, 80 ) ); } if ( strncmp(line, "END ", 4) == 0) { break; } } /* * write blank lines to make a multiple of 36 lines in header * number of lines written so far is i+1 */ if ( passthru ) { for ( j = 0; j < 80; j++ ) { line[j] = ' '; } line[80] = '\0'; for ( i = 35 - ( i % 36 ); i > 0; i-- ) { PR_CHECK( char_out( line, 80 ) ); } } return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * int h_uncomp( char_in, char_out ) * * Purpose: * Uncompresses h compressed data. * * Parameters: * byte (*char_in)() : (in) Function to get data from input. * byte (*char_out)() : (in) Function to write data to output. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_FORMAT : Data format was incorrect. * int PR_E_IO : Error during io. * int PR_E_MEMORY : Memory allocation failure. * ************************************************************************ -*/ int h_uncomp ( pfi char_in, pfi char_out ) { /* static int decode(); */ int h_put_data(); void hinv(); /* void pr_format_message(); */ void undigitize(); int *a; /* Pointer to the image array. */ int nx; /* Size in x axis. */ int ny; /* Size in y axis. */ int scale; /* Scale factor of compression. */ int status; /* Function return status. */ PR_CHECK( decode( char_in, char_out, &a, &nx, &ny, &scale, &( local_press.lp_format ) ) ); undigitize( a, nx, ny, scale ); /* * Inverse H-tranform */ hinv( a, nx, ny, local_press.lp_smooth, scale ); /* * Write the data. */ status = h_put_data( char_out, a, nx, ny, local_press.lp_format ); free( a ); PR_CHECK( status ); if ( local_press.lp_verbose ) { pr_format_message( PR_HDECOMP_INFO, local_press.lp_smooth, nx, ny, scale, local_press.lp_format ); } return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * static int input_bit( char_in ) * * Purpose: * input a bit. * * Parameters: * int (*char_in)() : (in) Gets data from input. * * Values Returned: * int value : if value > 0, the bit value. * int PR_E_IO : Error during io. * int PR_E_EOI : End of input. * ************************************************************************ -*/ static int input_bit ( pfi char_in ) { byte b; if ( bits_to_go == 0 ) { /* * Read the next byte if no */ PR_CHECK( char_in( &b, 1 ) ); buffer = b; bits_to_go = 8; } /* * Return the next bit */ bits_to_go -= 1; return ( ( buffer >> bits_to_go ) & 1 ); } /*+ ************************************************************************ * * Synopsis: * static int input_huffman( char_in ) * * Purpose: * Huffman decoding for fixed codes * * Coded values range from 0-15 * * Huffman code values ( hex ): * * 3e, 00, 01, 08, 02, 09, 1a, 1b, * 03, 1c, 0a, 1d, 0b, 1e, 3f, 0c * * and number of bits in each code: * * 6, 3, 3, 4, 3, 4, 5, 5, * 3, 5, 4, 5, 4, 5, 6, 4 * Statement of purpose. * * Parameters: * int (*char_in)() : (in) Function to read data from input. * * Values Returned: * int code : if value > 0. * int PR_E_IO : Error during io. * * References: * Copied from the hcompress function input_huffman. * Programmer: R. White Date: 7 May 1991 * ************************************************************************ -*/ static int input_huffman ( pfi char_in ) { /* static int input_bit(); */ int b; int c; /* * get first 3 bits to start */ PR_CHECK( c = input_nbits( char_in, 3 ) ); if ( c < 4 ) { /* * this is all we need return 1,2,4,8 for c=0,1,2,3 */ return ( 1 << c ); } /* * get the next bit */ PR_CHECK( b = input_bit( char_in ) ); c = b | ( c << 1 ); if ( c < 13 ) { /* * OK, 4 bits is enough */ switch ( c ) { case 8: return ( 3 ); case 9: return ( 5 ); case 10: return ( 10 ); case 11: return ( 12 ); case 12: return ( 15 ); } } /* * get yet another bit */ PR_CHECK( b = input_bit( char_in ) ); c = b | ( c << 1 ); if ( c < 31 ) { /* * OK, 5 bits is enough */ switch ( c ) { case 26: return ( 6 ); case 27: return ( 7 ); case 28: return ( 9 ); case 29: return ( 11 ); case 30: return ( 13 ); } } /* * need the 6th bit */ PR_CHECK( b = input_bit( char_in ) ); c = b | ( c << 1 ); if ( c == 62 ) { return ( 0 ); } else { return ( 14 ); } } /*+ ************************************************************************ * * Synopsis: * static int input_nbits( char_in, n ) * * Purpose: * Input n bits, n <= 8. * * Parameters: * int (*char_in)() : (in) Function to read data from input. * int n : (in) Number of bytes to read. * * Values Returned: * int value : if > 0, value of the bits * int PR_E_EOI : End of input detected. * int PR_E_IO : Error during io. * ************************************************************************ -*/ static int input_nbits ( pfi char_in, int n ) { byte c; if ( bits_to_go < n ) { /* * need another byte's worth of bits */ buffer <<= 8; PR_CHECK( char_in( &c, 1 ) ); buffer |= c; bits_to_go += 8; } /* * now pick off the first n bits */ bits_to_go -= n; return ( ( buffer >> bits_to_go ) & ( ( 1 << n ) - 1 ) ); } /*+ ************************************************************************ * * Synopsis: * static int makefits( char_out, nx, ny, bitpix, datatype ) * * Purpose: * Writes a simple fits header for a 2-d image. * example of header: * lines must be exactly 80 characters, with no newline at the end * 0123456789 123456789 123456789 123456789 SIMPLE = T /Standard FITS format BITPIX = 16 / NAXIS = 2 /Number of axes NAXIS1 = 256 / NAXIS2 = 256 / DATATYPE= 'INTEGER*2' / END * * Parameters: * type arg1 : (in) What it is * type arg2 : (mod) What it is * type argn : (out) What it is * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_IO : IO error. * * References: * Copied from function makefits from the hcompress program. * Programmer: R. White Date: 24 April 1992 * ************************************************************************ -*/ static int makefits ( pfi char_out, int nx, int ny, int bitpix, char *datatype ) { char line[81]; int i; (void) sprintf( line, "%-80.80s", "SIMPLE = T /Standard FITS format" ); PR_CHECK( char_out( line, 80 ) ); (void) sprintf( line, "%10.10s%10d%-60.60s", "BITPIX =", bitpix, " /Bits per pixel." ); PR_CHECK( char_out( line, 80 ) ); (void) sprintf( line, "%-80.80s", "NAXIS = 2 /Number of axes"); PR_CHECK( char_out( line, 80 ) ); (void) sprintf( line, "%10.10s%10d%-60.60s", "NAXIS1 =", ny, " /" ); PR_CHECK( char_out( line, 80 ) ); (void) sprintf( line, "%10.10s%10d%-60.60s", "NAXIS2 =", nx, " /" ); PR_CHECK( char_out( line, 80 ) ); (void) sprintf( line, "%10.10s'%*.*s'%*s%48s", "DATATYPE=", (int)strlen( datatype), (int)strlen( datatype ), datatype, 22-(int)strlen( datatype), "/", "" ); PR_CHECK( char_out( line, 80 ) ); (void) sprintf( line, "%-80.80s", "END" ); PR_CHECK( char_out( line, 80 ) ); /* * pad with blank lines to get multiple of 36 (2880 bytes) */ for ( i = 0; i < 80; i++ ) { line[i] = ' '; } line[80] = '\0'; for ( i = 7; i < 36; i++) { PR_CHECK( char_out( line, 80 ) ); } return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * static void qtree_bitins( a, nx, ny, b, n, bit ) * * Purpose: * Copy 4-bit values from a[( nx+1 )/2,( ny+1 )/2] to b[nx,ny], expanding * each value to 2x2 pixels and inserting into bitplane BIT of B. * A,B may NOT be same array ( it wouldn't make sense to be inserting * bits into the same array anyway. ) * * Parameters: * byte a[] : (in) Input array. * int nx : (in) X dimension. * int ny : (in) Y dimension. * int b[] : (out) Output array. * int n : (in) Declare y dimension of b. * int bit : (in) * * Values Returned: * void * * References: * Copied from the hcompress function qtree_bitins. * Programmer: R. White Date: 7 May 1991 * ************************************************************************ -*/ static void qtree_bitins ( byte a[], int nx, int ny, int b[], int n, int bit ) { int i; int j; int *ptr_b00; int *ptr_b10; byte *ptr_k; int tmp; int mask; mask = 1 << bit; /* * expand each 2x2 block */ ptr_k = a; /* ptr_k is index of a[i/2,j/2] */ for ( i = 0; i < nx - 1; i += 2 ) { for ( ptr_b00 = b + n * i, ptr_b10 = ptr_b00 + n; ptr_b00 < b + n * i + ny - 1 ; ptr_b00 += 2, ptr_b10 += 2 ) { tmp = *ptr_k << bit; *( ptr_b10 + 1 ) |= tmp & mask; *ptr_b10 |= ( tmp >> 1 ) & mask; *( ptr_b00 + 1 ) |= ( tmp >> 2 ) & mask; *ptr_b00 |= ( tmp >> 3 ) & mask; ptr_k ++; } if ( ptr_b00 < b + n * i + ny ) /* if ( j < ny )*/ { /* * row size is odd, do last element in row s00+1, s10+1 are * off edge */ *ptr_b10 |= ( ( *ptr_k >> 1 ) & 1 ) << bit; *ptr_b00 |= ( ( *ptr_k >> 3 ) & 1 ) << bit; ptr_k ++; } } if ( i < nx ) { /* * column size is odd, do last row s10, s10+1 are off edge */ ptr_b00 = b + n * i; for ( j = 0; j < ny - 1; j += 2 ) { *( ptr_b00 + 1 ) |= ( ( *ptr_k >> 2 ) & 1 ) << bit; * ptr_b00 |= ( ( *ptr_k >> 3 ) & 1 ) << bit; ptr_b00 += 2; ptr_k ++; } if ( j < ny ) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ *ptr_b00 |= ( ( *ptr_k >> 3 ) & 1 ) << bit; *ptr_k ++; } } } /*+ ************************************************************************ * * Synopsis: * static void qtree_copy( a, nx, ny, b, n ) * * Purpose: * copy 4-bit values from a[( nx+1 )/2,( ny+1 )/2] to b[nx,ny], expanding * each value to 2x2 pixels * a,b may be same array * * Parameters: * byte a[] : (in) Source array * int nx : (in) X dimension of destination. * int ny : (in) Y dimension of destination. * byte b[] : (out) Destination array. * int n : (in) Declared y dimension of b. * * Values Returned: * void * * References: * Copied from the hcompress function qtree_copy. * Programmer: R. White Date: 7 May 1991 * ************************************************************************ -*/ static void qtree_copy ( byte a[], int nx, int ny, byte b[], int n ) { int i; int j; int k; int nx2; int ny2; int s00; int s10; /* * first copy 4-bit values to b start at end in case a,b are same * array */ nx2 = ( nx + 1 ) / 2; ny2 = ( ny + 1 ) / 2; k = ny2 * ( nx2 - 1 ) + ny2 - 1; /* k is index of a[i,j] */ for ( i = nx2 - 1; i >= 0; i-- ) { s00 = 2 * ( n * i + ny2 - 1 ); /* s00 is index of b[2*i,2*j] */ for ( j = ny2 - 1; j >= 0; j-- ) { b[s00] = a[k]; k -= 1; s00 -= 2; } } /* * now expand each 2x2 block */ for ( i = 0; i < nx - 1; i += 2 ) { s00 = n * i; /* s00 is index of b[i,j] */ s10 = s00 + n; /* s10 is index of b[i+1,j] */ for ( j = 0; j < ny - 1; j += 2 ) { b[s10 + 1] = b[s00] & (byte) 1; b[s10] = ( b[s00] >> 1 ) & 1; b[s00 + 1] = ( b[s00] >> 2 ) & 1; b[s00] = ( b[s00] >> 3 ) & 1; s00 += 2; s10 += 2; } if ( j < ny ) { /* * row size is odd, do last element in row s00+1, s10+1 are * off edge */ b[s10] = ( b[s00] >> 1 ) & 1; b[s00] = ( b[s00] >> 3 ) & 1; } } if ( i < nx ) { /* * column size is odd, do last row s10, s10+1 are off edge */ s00 = n * i; for ( j = 0; j < ny - 1; j += 2 ) { b[s00 + 1] = ( b[s00] >> 2 ) & 1; b[s00] = ( b[s00] >> 3 ) & 1; s00 += 2; } if ( j < ny ) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ b[s00] = ( b[s00] >> 3 ) & 1; } } } /*+ ************************************************************************ * * Synopsis: * static int qtree_decode( char_in, a, n, nqx, nqy, nbitplanes ) * * Purpose: * Read stream of codes from char_in and construct bit planes * in quadrant of 2-D array using binary quadtree coding * * Parameters: * int (*char_in)() : (in) Function to get the next byte. * int a[] : (out) Array to fill. * int n : (in) Declared y dimension of a. * int nqx : (in) Partial length of row to decode. * int nqy : (in) Partial length of column to decode. * int nbitplanes : (in) Number of bitplanes to decode. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_CODE : Bad format code. * int PR_E_IO : Error during io. * int PR_E_MEMORY : Memory allocation failure. * * References: * Copied from the hcompress function qtree_decode. * Programmer: R. White Date: 7 May 1991 * ************************************************************************ -*/ static int qtree_decode ( pfi char_in, int a[], int n, int nqx, int nqy, int nbitplanes ) { /* static int input_bit(); */ /* static int input_huffman(); */ /* static int input_nbits(); */ /* void pr_format_message(); */ /* static int qtree_expand(); */ /* static void qtree_bitins(); */ /* static int read_bdirect(); */ int log2n; int k; int bit; int b; int nqmax; int nx; int ny; int nfx; int nfy; int c; int nqx2; int nqy2; byte *scratch; /* * log2n is log2 of max(nqx,nqy) rounded up to next power of 2 */ nqmax = ( nqx > nqy ) ? nqx : nqy; log2n = log( (float) nqmax ) / log( 2.0 ) + 0.5; if ( nqmax > ( 1 << log2n ) ) { log2n += 1; } /* * allocate scratch array for working space */ nqx2 = ( nqx + 1 ) / 2; nqy2 = ( nqy + 1 ) / 2; PR_CHECK_NULL( scratch = byte_alloc( nqx2 * nqy2 ) ); /* * now decode each bit plane, starting at the top A is assumed to * be initialized to zero */ for ( bit = nbitplanes - 1; bit >= 0; bit-- ) { /* * Was bitplane was quadtree-coded or written directly? */ b = input_nybble( char_in ); if ( b == 0 ) { /* * bit map was written directly */ PR_CHECK( read_bdirect( char_in, a, n, nqx, nqy, scratch, bit ) ); } else if ( b != 0xf ) { pr_format_message( PR_E_CODE, b ); return ( PR_E_CODE ); } else { /* * bitmap was quadtree-coded, do log2n expansions * * read first code */ PR_CHECK( scratch[0] = input_huffman( char_in ) ); /* * now do log2n expansions, reading codes from file as * necessary */ nx = 1; ny = 1; nfx = nqx; nfy = nqy; c = 1 << log2n; for ( k = 1; k < log2n; k++ ) { /* * this somewhat cryptic code generates the sequence * n[k-1] = ( n[k]+1 )/2 where n[log2n]=nqx or nqy */ c = c >> 1; nx = nx << 1; ny = ny << 1; if ( nfx <= c ) { nx -= 1; } else { nfx -= c; } if ( nfy <= c ) { ny -= 1; } else { nfy -= c; } PR_CHECK( qtree_expand( char_in, scratch, nx, ny, scratch ) ); } /* * now copy last set of 4-bit codes to bitplane bit of * array a */ qtree_bitins( scratch, nqx, nqy, a, n, bit ); } } free( scratch ); return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * static int qtree_expand( char_in, a, nx, ny, b ) * * Purpose: * do one quadtree expansion step on array a[( nqx+1 )/2,( nqy+1 )/2] * results put into b[nqx,nqy] ( which may be the same as a ) * * Parameters: * int (*char_in)() : (in) Function to read data from input * byte a[] : (in) Array of data to expand. * int nx : (in) X dimension of a. * int ny : (in) Y dimension of a. * byte b[] : (out) Expanded data. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_IO : Error during io. * * References: * Copied from the hcompress function qtree_expand. * Programmer: R. White Date: 7 May 1991 * ************************************************************************ -*/ static int qtree_expand ( pfi char_in, byte a[], int nx, int ny, byte b[] ) { /* static int input_huffman(); */ /* static void qtree_copy(); */ int i; /* * first copy a to b, expanding each 4-bit value */ qtree_copy( a, nx, ny, b, ny ); /* * now read new 4-bit values into b for each non-zero element */ for ( i = nx * ny - 1; i >= 0; i-- ) { if ( b[i] != 0 ) { PR_CHECK( b[i] = input_huffman( char_in ) ); } } return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * static int read_bdirect( char_in, a, n, nqx, nqy, scratch, bit ) * * Purpose: * Reads an image packed 4 bits per byte. * * Parameters: * int (*char_in)() : (in) Function to read data. * int a[] : (out) * int n : (in) Declared y dimension of a. * int nqx : (in) X dimension of a. * int nqy : (in) Y dimension of a. * byte scratch[] : (in) * int bit : (in) * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_IO : Error during io. * * References: * Copied from the hcompress function qtree_bdirect. * Programmer: R. White Date: 7 May 1991 * ************************************************************************ -*/ static int read_bdirect ( pfi char_in, int a[], int n, int nqx, int nqy, byte scratch[], int bit ) { /* static void qtree_bitins(); */ int i; /* * read bit image packed 4 pixels/nybble */ for ( i = 0; i < ( ( nqx + 1 ) / 2 ) * ( ( nqy + 1 ) / 2 ); i++ ) { PR_CHECK( scratch[i] = input_nybble( char_in ) ); } /* * insert in bitplane BIT of image A */ qtree_bitins( scratch, nqx, nqy, a, n, bit ); return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * static void start_inputing_bits() * * Purpose: * Initialize bit input. * * Parameters: * void * * Values Returned: * void * ************************************************************************ -*/ static void start_inputing_bits ( void ) { /* * Buffer starts out with no bits in it */ bits_to_go = 0; } skycat-3.1.2-starlink-1b/astrotcl/press/h_press.c000066400000000000000000000775111215713201500217460ustar00rootroot00000000000000/*+ ************************************************************************ **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** * * Module Name: press/src/hpress.c * * Purpose: * Funciton to hcompress image data. * * Routines: * static int bufcopy : Copy non-zero code from array to * buffer. * static int doencode : Encode 2-D array and write stream * of characters to outfile. * static int done_outputing_bits: Flush out the last bits in the * bit buffer. * static int encode : Encode H-transform and write to * output. * static int fitsread : Reads fits header and optionally * passes it to the output. * static int get_data : Gets data from input. * static int get_fits : Gets fits data from input. * static int get_raw : Gets raw data from input. * int h_comp : Does hcompress. * static int output_nbits : Writes a specified number of bits to * the output. * static int qtree_encode : Encode the image using quadtree. * static void qtree_onebit : Do first quadtree reduction step. * static void qtree_reduce : Do one quadtree reduction step. * static void start_outputing_bits: Initializes the bit output * functions. * static int write_bdirect : * * Date : Mar 01, 1993 * * SCCS data : @(#) * Module Name : h_press.c * Version Number : 1.6 * Release Number : 1 * Last Updated : 07/04/97 * * Programmer : Norman Hill * * Modification History: * 97/07/02 SEC : Bring up to ANSI standard. * **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** ************************************************************************ -*/ #include #include #include #include #include #include "gen_types.h" #include "gen_msg.h" #include "press.h" #include "h_comp.h" #include "local_press.h" static int bitcount; static int bo_buffer; /* The bit buffer. */ static int bo_bits_to_go; static int qt_bitbuffer; /* Buffer for qtree_encode. */ static int qt_bits_to_go; /* * Huffman code values and number of bits in each code */ static int code[16] = { 0x3e, 0x00, 0x01, 0x08, 0x02, 0x09, 0x1a, 0x1b, 0x03, 0x1c, 0x0a, 0x1d, 0x0b, 0x1e, 0x3f, 0x0c }; static int ncode[16] = { 6, 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 6, 4 }; #define output_nybble(char_out,c) output_nbits(char_out,c,4) #define output_huffman(char_out,c) output_nbits(char_out,code[c],ncode[c]) /* * Static function prototypes. */ static int bufcopy( byte[], int, byte[], int *, int ); static int doencode( pfi, int[], int, int, byte[3] ); static int done_outputing_bits( pfi ); static int encode( pfi, int[], int, int, int ); static int fitsread( pfi, pfi, int *, int *, int, int ); static int get_data( pfi, pfi, int **, int *, int *, char * ); static int get_fits( pfi, pfi, int **, int *, int * ); static int get_raw( pfi, int **, int, int, int ); static int output_nbits( pfi, int, int ); static int qtree_encode( pfi, int[], int, int, int, int ); static void qtree_onebit( int[], int, int, int, byte[], int ); static void qtree_reduce( byte[], int, int, int, byte[] ); static void start_outputing_bits( void ); static int write_bdirect( pfi, int[], int, int, int, byte[], int ); /* * allan: 17.12.97: replaced a non-portable #define with this routine */ int write_int(pfi char_out, int* i) { int n = htonl(*i); return char_out((byte *)&n, sizeof(int)); } /*+ ************************************************************************ * * Synopsis: * static int bufcopy( a, n, buffer, b, bmax ) * * Purpose: * copy non-zero codes from array to buffer * * Parameters: * byte a[] : (in) array to copy from. * int n : (in) size of array a. * byte buffer : (in) Output buffer. * int b : (out) Num. bytes in buffer. * int bmax : (in) Size of buffer. * * Values Returned: * int 1 : Buffer is full. * int 0 : Buffer is not full. * * References: * Copied from hcompress fitsread function. * Programmer: R. White Date: 15 May 1991 * ************************************************************************ -*/ static int bufcopy ( byte a[], int n, byte buffer[], int *b, int bmax ) { int i; for (i = 0; i < n; i++) { if (a[i] != 0) { /* * add Huffman code for a[i] to buffer */ qt_bitbuffer |= code[a[i]] << qt_bits_to_go; qt_bits_to_go += ncode[a[i]]; if (qt_bits_to_go >= 8) { buffer[*b] = qt_bitbuffer & 0xFF; *b += 1; /* * return warning code if we fill buffer */ if (*b >= bmax) return (1); qt_bitbuffer >>= 8; qt_bits_to_go -= 8; } } } return (0); } /*+ ************************************************************************ * * Synopsis: * static int doencode( char_out, a, nx, ny, nbitplanes ) * * Purpose: * Encode 2-D array and write stream of characters to outfile. * * Parameters: * int (*char_out)() : (in) Function to write data to output. * int a[] : (in) Image to encode. * int nx : (in) X dimension of the image. * int ny : (in) Y dimension of the image. * byte nbitplanes : (in) Number of bit planes in quadrants. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_IO : Error durring io. * int PR_E_MEMORY : Memory allocation failure. * * References: * Copied from hcompress fitsread function. * Programmer: R. White Date: 24 April 1992 * ************************************************************************ -*/ static int doencode ( pfi char_out, int a[], int nx, int ny, byte nbitplanes[3] ) { /* static int qtree_encode(); */ /* static void start_outputing_bits(); */ /* static int done_outputing_bits(); */ /* static int output_nbits(); */ int nx2; int ny2; nx2 = (nx+1)/2; ny2 = (ny+1)/2; /* * Initialize bit output */ start_outputing_bits(); /* * write out the bit planes for each quadrant */ PR_CHECK( qtree_encode( char_out, &a[0], ny, nx2, ny2, nbitplanes[0] ) ); PR_CHECK( qtree_encode( char_out, &a[ny2], ny, nx2, ny/2, nbitplanes[1] ) ); PR_CHECK( qtree_encode( char_out, &a[ny*nx2], ny, nx/2, ny2, nbitplanes[1] ) ); PR_CHECK( qtree_encode( char_out, &a[ny*nx2+ny2], ny, nx/2, ny/2, nbitplanes[2] ) ); /* * Add zero as an EOF symbol */ PR_CHECK( output_nybble( char_out, 0 ) ); done_outputing_bits( char_out ); return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * static int done_outputing_bits( char_out ) * * Purpose: * Flush the last bits in the bit buffer. * * Parameters: * int (*char_out)() : (in) Function to write data to the output. * * Values Returned: * int PR_SUCCESS : Normal completion * int PR_E_IO : Error during io. * int PR_E_MEMORY : Memory allocation failure. * * References: * Copied from hcompress done_outputing_bits function. * Programmer: R. White * ************************************************************************ -*/ static int done_outputing_bits ( pfi char_out ) { byte b; if ( bo_bits_to_go < 8 ) { b = bo_buffer< 0) { /* * positive element, put zero at end of buffer */ signbits[nsign] <<= 1; bits_to_go -= 1; } else if (a[i] < 0) { /* * negative element, shift in a one */ signbits[nsign] <<= 1; signbits[nsign] |= 1; bits_to_go -= 1; /* * replace a by absolute value */ a[i] = -a[i]; } if (bits_to_go == 0) { /* * filled up this byte, go to the next one */ bits_to_go = 8; nsign += 1; signbits[nsign] = 0; } } if (bits_to_go != 8) { /* * some bits in last element move bits in last byte to bottom * and increment nsign */ signbits[nsign] <<= bits_to_go; nsign += 1; } /* * calculate number of bit planes for 3 quadrants * * quadrant 0=bottom left, 1=bottom right or top left, 2=top right, */ for (q = 0; q < 3; q++) { vmax[q] = 0; } /* * get maximum absolute value in each quadrant */ nx2 = (nx + 1) / 2; ny2 = (ny + 1) / 2; j = 0; /* column counter */ k = 0; /* row counter */ for (i = 0; i < nel; i++) { q = (j >= ny2) + (k >= nx2); if (vmax[q] < a[i]) vmax[q] = a[i]; if (++j >= ny) { j = 0; k += 1; } } /* * now calculate number of bits for each quadrant */ for (q = 0; q < 3; q++) { nbitplanes[q] = log((float) (vmax[q] + 1)) / log(2.0) + 0.5; if ((vmax[q] + 1) > (1 << nbitplanes[q])) { nbitplanes[q] += 1; } } /* * write nbitplanes */ PR_CHECK( char_out( nbitplanes, sizeof( nbitplanes ) ) ); /* * write coded array */ PR_CHECK( doencode( char_out, a, nx, ny, nbitplanes ) ); /* * write sign bits */ if (nsign > 0) { PR_CHECK( char_out( signbits, nsign ) ); } if ( local_press.lp_verbose ) { /* * total number of bits written to file */ i = bitcount + 8 * (nsign + sizeof(code_magic) + sizeof(nbitplanes) + 4 * sizeof(int)); pr_format_message( PR_HCOMP_INFO, ( (float) i) / nel, 16.0 * nel / ( (float) i ) ); } free(signbits); return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * static int fitsread( char_in, char_out, nx, ny, passthru, * padded ) * * Purpose: * Read FITS header from char_in and optionally pass it to char_out. * nx and ny are found in the header. * * Parameters: * int (*char_in)() : (in) Function to get data from input. * int (*char_out)() : (in) Function to write data to the output. * int *nx : (out) X dimension of the image. * int *ny : (out) Y dimension of the image. * int passthru : (in) Non-zero if copy header to char_out. * int padded : (in) Non-zero if header is padded to 2880. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_FITS : Fits header read error. * int PR_E_IO : Error during io. * int PR_E_MEMORY : Memory allocation failure. * * References: * Copied from hcompress fitsread function. * Programmer: R. White Date: 16 April 1992 * ************************************************************************ -*/ static int fitsread ( pfi char_in, pfi char_out, int *nx, int *ny, int passthru, int padded ) { /* void pr_format_message(); */ int i; int j; char line[82]; int naxis1; int naxis2; int nline; int noend; int status; /* Function return status. */ int val; /* * make sure we find NAXIS1 and NAXIS2 */ naxis1 = 0; naxis2 = 0; noend = 1; nline = 81; while (noend) { /* * continue looping until we've read END statement or until * we've read a multiple of 36 lines past END (if padded != 0) */ for (i = 0; (i < 36) && (noend || padded); i++) { if ( ( status = char_in( line, nline-1 ) ) == PR_E_EOI ) { pr_format_message( PR_E_FITS_INC ); return( PR_E_FITS ); } PR_CHECK( status ); line[80] = '\0'; /* Replace line of nulls with line of blanks. */ if (strlen(line) != 80) { for (j = strlen(line); j < 80; j++) line[j] = ' '; } /* * copy to outfile if passthru != 0 and we have not reached * END */ if ( passthru && noend ) { PR_CHECK( char_out( line, 80 ) ); } if (strncmp(line, "END ", 4) == 0) { noend = 0; } else if (strncmp(line, "NAXIS1 =", 9) == 0) { if (sscanf(&line[10], " %d", &naxis1) != 1) { pr_format_message( PR_E_FITS, line ); return( PR_E_FITS ); } } else if (strncmp(line, "NAXIS2 =", 9) == 0) { if (sscanf(&line[10], " %d", &naxis2) != 1) { pr_format_message( PR_E_FITS, line ); return( PR_E_FITS ); } } else if (strncmp(line, "NAXIS =", 9) == 0) { if (sscanf(&line[10], " %d", &val) != 1) { pr_format_message( PR_E_FITS, line ); return( PR_E_FITS ); } if (val != 2) { pr_format_message( PR_E_FITS_DIM ); return( PR_E_FITS ); } } else if (strncmp(line, "DATATYPE=", 9) == 0) { if (strncmp(&line[11], "INTEGER*2", 9) != 0) { pr_format_message( PR_E_FITS_TYPE, "INTEGER*2" ); return( PR_E_FITS ); } } else if (strncmp(line, "PSIZE =", 9) == 0) { /* * check PSIZE == 0 */ if (sscanf(&line[10], " %d", &val) != 1) { pr_format_message( PR_E_FITS, line ); return( PR_E_FITS ); } if (val != 0) { pr_format_message( PR_E_FITS_GRP ); return( PR_E_FITS ); } } else if (strncmp(line, "GCOUNT =", 9) == 0) { /* * check for GCOUNT > 1 */ if (sscanf(&line[10], " %d", &val) != 1) { pr_format_message( PR_E_FITS, line ); return( PR_E_FITS ); } if (val > 1) { pr_format_message( PR_E_FITS_GRP ); return( PR_E_FITS ); } } } } if (naxis1 <= 0 || naxis2 <= 0) { pr_format_message( PR_E_NAXIS ); return( PR_E_FITS ); } *ny = naxis1; *nx = naxis2; return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * static int get_data( char_in, char_out, a, nx, ny, format ) * * Purpose: * Reads data from the input into an array. * * Parameters: * int (*char_in)() : (in) Function to read data from input. * int (*char_out)() : (in) Function to write data to output. * int **a : (out) Image array. * int *nx : (out) X dimension of the image. * int *ny : (out) X dimension of the image. * char *format : (in) Format of input file. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_EOI : Unexpected end of input. * int PR_E_FITS : Fits header read error. * int PR_E_IO : Error during io. * int PR_E_MEMORY : Memory allocation failure. * * References: * Copied from hcompress get_data function. * Programmer: R. White Date: 17 April 1992 * ************************************************************************ -*/ static int get_data ( pfi char_in, pfi char_out, int **a, int *nx, int *ny, char *format ) { /* int get_raw(); */ /* int get_fits(); */ /* void pr_format_message(); */ if (strcmp(format, "raw") == 0) { PR_CHECK( get_raw(char_in, a, *nx, *ny, 0) ); } else if (strcmp(format, "net") == 0) { PR_CHECK( get_raw(char_in, a, *nx, *ny, 1) ); } else if (strcmp(format, "fits") == 0) { PR_CHECK( get_fits(char_in, char_out, a, nx, ny) ); } else { pr_format_message( PR_E_FORMAT ); return( PR_E_FORMAT ); } return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * static int get_fits( char_in, char_out, a, nx, ny ) * * Purpose: * Reads a fits file into a buffer. * * Parameters: * int (*char_in)() : (in) Function to read data from input. * int (*char_out)() : (in) Function to write data to output. * int **a : (out) Pointer to allocated image array. * int *nx : (out) X dimension of image. * int *ny : (out) Y dimension of image. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_EOI : Unexpected end of input. * int PR_E_FITS : Fits header read error. * int PR_E_IO : Error during io. * int PR_E_MEMORY : Memory allocation failure. * * References: * Copied from hcompress get_fits function. * Programmer: R. White Date: 17 April 1992 * ************************************************************************ -*/ static int get_fits ( pfi char_in, pfi char_out, int **a, int *nx, int *ny ) { /* int fitsread(); */ /* int get_raw(); */ /* * 1: pass lines through to outfile 1: header is multiple of * 2880 bytes 0: lines are not terminated by newline */ PR_CHECK( fitsread( char_in, char_out, nx, ny, 1, 1 ) ); /* * read raw pixel data with byte swapping */ PR_CHECK( get_raw( char_in, a, *nx, *ny, 1 ) ); return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * static int get_raw( char_in, a, nx, ny, swap ) * * Purpose: * Reads raw data from the input. * * Parameters: * int (*char_in)() : (in) Function to read data from input. * int (*char_out)() : (in) Function to write data to output. * int **a : (out) Image array. * int nx : (in) X dimension of the image. * int ny : (in) X dimension of the image. * int swap : (in) Should bytes be swapped? * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_EOI : Unexpected end of input. * int PR_E_IO : Error during io. * int PR_E_MEMORY : Memory allocation failure. * * References: * Copied from hcompress get_raw function. * Programmer: R. White Date: 17 April 1992 * ************************************************************************ -*/ static int get_raw ( pfi char_in, int **a, int nx, int ny, int swap ) { boolean test_swap(); void h_swap_bytes(); /* void pr_format_message(); */ int i; int j; int k; short *sa; int tswap; PR_CHECK_NULL( *a = (int *) malloc(nx * ny * sizeof(int)) ); /* * read a row at a time to minimize page faulting problems */ PR_CHECK_NULL( sa = (short *) malloc(ny * sizeof(short)) ); /* * see if byte swapping will be needed */ if (swap) { tswap = test_swap(); } else { tswap = 0; } /* * read rows */ for (i = 0; i < nx; i++) { if ( char_in( sa, ny * sizeof( short ) ) != ny * sizeof( short ) ) { pr_format_message( PR_E_EOI ); return( PR_E_EOI ); } /* * swap if necessary */ if (tswap) { h_swap_bytes(sa, ny * sizeof(short)); } /* * copy to array A, converting to int */ k = i * ny; for (j = 0; j < ny; j++) { (*a)[k++] = sa[j]; } } free(sa); return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * int h_comp( char_in, char_out ) * * Purpose: * Executes the hcomp program. * * Parameters: * int (*char_in)() : (in) Function to get the next character * from the input. * int (*char_out)() : (in) Function to get the next character * from the output. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_IO : Error during io. * ************************************************************************ -*/ int h_comp ( pfi char_in, pfi char_out ) { void digitize(); /* int encode(); */ /* int get_data(); */ void htrans(); /* void pr_format_message(); */ int *a; /* Image array. */ int nx; /* X dimension of image. */ int ny; /* Y dimension of image. */ nx = local_press.lp_nx; ny = local_press.lp_ny; /* * Read the data. */ PR_CHECK( get_data( char_in, char_out, &a, &nx, &ny, local_press.lp_format ) ); /* * H-transform the data. */ htrans( a, nx, ny ); /* * Digitize the data. */ digitize( a, nx, ny, local_press.lp_scale ); /* * Encode and write to stdout. */ PR_CHECK( encode( char_out, a, nx, ny, local_press.lp_scale ) ); free( a ); return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * static int output_nbites( char_out, bits, n ) * * Purpose: * Writes n bits to the output. * * Parameters: * int (*char_out)() : (in) Function to write bytes to output. * int bits : (in) Int containing bits to write. * int n : (in) Number of bits to write. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_IO : Error durring io. * int PR_E_MEMORY : Memory allocation failure. * * References: * Copied from hcompress output_nbites function. * Programmer: R. White * ************************************************************************ -*/ static int output_nbits ( pfi char_out, int bits, int n ) { byte b; /* * Insert bits at the end of the buffer. */ bo_buffer <<= n; bo_buffer |= ( bits & ( ( 1 << n ) - 1 ) ); bo_bits_to_go -= n; if ( bo_bits_to_go <= 0 ) { /* * The buffer is full, write the top 8 bits. */ b = (bo_buffer >> (-bo_bits_to_go)) & 0xff; PR_CHECK( char_out( &b, 1 ) ); bo_bits_to_go += 8; } bitcount += n; return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * static int qtree_encode( char_out, a, n, nqx, nqy, nbitplanes ) * * Purpose: * Encode values in quadrant of 2-D array using binary quadtree coding * for each bit plane. Assumes array is positive. * * Parameters: * int (*char_out)() : (in) Function to write data to output. * int a[] : (in) Array to output. * int n : (in) Plysical dimension of rows in a. * int nqx : (in) Length of row. * int nqy : (in) Length of column. * int nbitplanes : (in) Number of bit planes to output. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_IO : Error during io. * int PR_E_MEMORY : Memory allocation failure. * * References: * Copied from hcompress get_raw function. * Programmer: R. White Date: 15 May 1991 * ************************************************************************ -*/ static int qtree_encode ( pfi char_out, int a[], int n, int nqx, int nqy, int nbitplanes ) { /* static int bufcopy(); */ /* static int output_nbits(); */ /* void pr_format_message(); */ /* static void qtree_onebit(); */ /* static void qtree_reduce(); */ /* static int write_bdirect(); */ int log2n; int i; int k; int bit; int b; int bmax; int nqmax; int nqx2; int nqy2; int nx; int ny; byte *scratch; byte *buffer; /* * log2n is log2 of max(nqx,nqy) rounded up to next power of 2 */ nqmax = (nqx > nqy) ? nqx : nqy; log2n = log((float) nqmax) / log(2.0) + 0.5; if (nqmax > (1 << log2n)) { log2n += 1; } /* * initialize buffer point, max buffer size */ nqx2 = (nqx + 1) / 2; nqy2 = (nqy + 1) / 2; bmax = (nqx2 * nqy2 + 1) / 2; /* * We're indexing A as a 2-D array with dimensions (nqx,nqy). * Scratch is 2-D with dimensions (nqx/2,nqy/2) rounded up. Buffer * is used to store string of codes for output. */ PR_CHECK_NULL( scratch = (byte *) malloc(2 * bmax) ); PR_CHECK_NULL( buffer = (byte *) malloc(bmax) ); /* * now encode each bit plane, starting with the top */ for (bit = nbitplanes - 1; bit >= 0; bit--) { /* * initial bit buffer */ b = 0; qt_bitbuffer = 0; qt_bits_to_go = 0; /* * on first pass copy A to scratch array */ qtree_onebit(a, n, nqx, nqy, scratch, bit); nx = (nqx + 1) >> 1; ny = (nqy + 1) >> 1; /* * copy non-zero values to output buffer, which will be written * in reverse order */ if (bufcopy(scratch, nx * ny, buffer, &b, bmax)) { /* * quadtree is expanding data, change warning code and just * fill buffer with bit-map */ PR_CHECK( write_bdirect( char_out, a, n, nqx, nqy, scratch, bit ) ); goto bitplane_done; } /* * do log2n reductions */ for (k = 1; k < log2n; k++) { qtree_reduce(scratch, ny, nx, ny, scratch); nx = (nx + 1) >> 1; ny = (ny + 1) >> 1; if (bufcopy(scratch, nx * ny, buffer, &b, bmax)) { PR_CHECK( write_bdirect( char_out, a, n, nqx, nqy, scratch, bit ) ); goto bitplane_done; } } /* * OK, we've got the code in buffer Write quadtree warning * code, then write buffer in reverse order */ PR_CHECK( output_nybble(char_out, 0xF) ); if (b == 0) { if (qt_bits_to_go > 0) { /* * put out the last few bits */ PR_CHECK( output_nbits( char_out, qt_bitbuffer & ((1 << qt_bits_to_go) - 1), qt_bits_to_go) ); } else { /* * have to write a zero nybble if there are no 1's in * array */ PR_CHECK( output_huffman(char_out, 0) ); } } else { if (qt_bits_to_go > 0) { /* * put out the last few bits */ PR_CHECK( output_nbits(char_out, qt_bitbuffer & ((1 << qt_bits_to_go) - 1), qt_bits_to_go ) ); } for (i = b - 1; i >= 0; i--) { PR_CHECK( output_nbits( char_out, buffer[i], 8 ) ); } } bitplane_done:; } free(buffer); free(scratch); return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * static void qtree_onebit( a, n, nx, ny, b, bit ) * * Purpose: * Do first quadtree reduction step on bit BIT of array A. * Results put into b. * * Parameters: * int a[] : * int n : * int nx : * int ny : * byte b : * int bit : * * Values Returned: * void * * References: * Copied from hcompress write_bdirect function. * Programmer: R. White Date: 15 May 1991 * ************************************************************************ -*/ static void qtree_onebit ( int a[], int n, int nx, int ny, byte b[], int bit ) { int i; int j; int k; int b0; int b1; int b2; int b3; int s10; int s00; /* * use selected bit to get amount to shift */ b0 = 1 << bit; b1 = b0 << 1; b2 = b0 << 2; b3 = b0 << 3; k = 0; /* k is index of b[i/2,j/2] */ for (i = 0; i < nx - 1; i += 2) { s00 = n * i; /* s00 is index of a[i,j] */ s10 = s00 + n; /* s10 is index of a[i+1,j] */ for (j = 0; j < ny - 1; j += 2) { b[k] = ((a[s10 + 1] & b0) | ((a[s10] << 1) & b1) | ((a[s00 + 1] << 2) & b2) | ((a[s00] << 3) & b3)) >> bit; k += 1; s00 += 2; s10 += 2; } if (j < ny) { /* * row size is odd, do last element in row s00+1,s10+1 are * off edge */ b[k] = (((a[s10] << 1) & b1) | ((a[s00] << 3) & b3)) >> bit; k += 1; } } if (i < nx) { /* * column size is odd, do last row s10,s10+1 are off edge */ s00 = n * i; for (j = 0; j < ny - 1; j += 2) { b[k] = (((a[s00 + 1] << 2) & b2) | ((a[s00] << 3) & b3)) >> bit; k += 1; s00 += 2; } if (j < ny) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ b[k] = (((a[s00] << 3) & b3)) >> bit; k += 1; } } } /*+ ************************************************************************ * * Synopsis: * static void qtree_reduce( a, n, nx, ny, b ) * * Purpose: * Do one quadtree reduction step on array a results put into b * (which may be the same as a) * * Parameters: * byte a[] : * int n : * int nx : * int ny : * * Values Returned: * void * * References: * Copied from hcompress write_bdirect function. * Programmer: R. White Date: 15 May 1991 * ************************************************************************ -*/ static void qtree_reduce ( byte a[], int n, int nx, int ny, byte b[] ) { int i; int j; int k; int s10; int s00; k = 0; /* k is index of b[i/2,j/2] */ for (i = 0; i < nx - 1; i += 2) { s00 = n * i; /* s00 is index of a[i,j] */ s10 = s00 + n; /* s10 is index of a[i+1,j] */ for (j = 0; j < ny - 1; j += 2) { b[k] = (a[s10 + 1] != 0) | ((a[s10] != 0) << 1) | ((a[s00 + 1] != 0) << 2) | ((a[s00] != 0) << 3); k += 1; s00 += 2; s10 += 2; } if (j < ny) { /* * row size is odd, do last element in row s00+1,s10+1 are * off edge */ b[k] = ((a[s10] != 0) << 1) | ((a[s00] != 0) << 3); k += 1; } } if (i < nx) { /* * column size is odd, do last row s10,s10+1 are off edge */ s00 = n * i; for (j = 0; j < ny - 1; j += 2) { b[k] = ((a[s00 + 1] != 0) << 2) | ((a[s00] != 0) << 3); k += 1; s00 += 2; } if (j < ny) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ b[k] = ((a[s00] != 0) << 3); k += 1; } } } /*+ ************************************************************************ * * Synopsis: * static void start_outputing_bits() * * Purpose: * Initializes the bit output functions. * * Parameters: * void * * Values Returned: * void * * References: * Copied from hcompress start_outputing_bits function. * Programmer: R. White * ************************************************************************ -*/ static void start_outputing_bits ( void ) { bo_buffer = 0; bo_bits_to_go = 8; bitcount = 0; } /*+ ************************************************************************ * * Synopsis: * static int write_bdirect( char_out, a, n, nqx, nqy, scratch, bit ) * * Purpose: * * Parameters: * int (*char_out)() : (in) Function to output data. * int a[] : (in) * int n : (in) * int nqx : (in) * int nqy : (in) * byte scratch : (in) * int bit : (in) * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_IO : Error during io. * int PR_E_MEMORY : Memory allocation failure. * * References: * Copied from hcompress write_bdirect function. * Programmer: R. White Date: 15 May 1991 * ************************************************************************ -*/ static int write_bdirect ( pfi char_out, int a[], int n, int nqx, int nqy, byte scratch[], int bit ) { int i; /* * Write the direct bitmap warning code */ PR_CHECK( output_nybble( char_out, 0x0 ) ); /* * Copy A to scratch array (again!), packing 4 bits/nybble */ qtree_onebit(a, n, nqx, nqy, scratch, bit); /* * write to outfile */ for (i = 0; i < ((nqx + 1) / 2) * ((nqy + 1) / 2); i++) { PR_CHECK( output_nybble( char_out, scratch[i] ) ); } return( PR_SUCCESS ); } skycat-3.1.2-starlink-1b/astrotcl/press/hcomp.c000066400000000000000000000160451215713201500214040ustar00rootroot00000000000000/*+ ************************************************************************ **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** * * Module Name: press/src/hcomp.c * * Purpose: * Contains the hcompress routines shared by both hcompress and * hdecompress. * * Routines: * int h_put_data : Writes data to output. * static int put_raw : Writes raw data to output. * static int put_fits : Writes fits data to output. * void h_swap_bytes : Swaps bytes in an array. * boolean test_swap : Check to see if swaping is necessary. * * Date : Mar 15, 1993 * * SCCS data : @(#) * Module Name : hcomp.c * Version Number : 1.7 * Release Number : 1 * Last Updated : 03/20/98 * * Programmer : Norman Hill * * Modification History: * 97/07/02 SEC : Bring up to ANSI standard. * **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** ************************************************************************ -*/ #include "gen_types.h" #include "gen_str.h" #include "press.h" #include "local_press.h" #include "h_comp.h" /* * Static function prototypes. */ static int put_raw( pfi, int[], int, int, boolean ); static int put_fits( pfi, int[], int, int ); /*+ ************************************************************************ * * Synopsis: * int h_put_data( char_out, a, nx, ny, format ) * * Purpose: * Write the data image swaping bytes if required. * * Parameters: * int (*char_out)() : (in) Function to write characters. * int a[] : (in) Data array to write. * int nx : (in) X dimension of the array. * int ny : (in) Y dimension of the array. * char *format : (in) Output format to use. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_FORMAT : Output format is unknown. * int PR_E_IO : Error during io. * int PR_E_MEMORY : Memory allocation failure. * * References: * Copied from the hcompress put_data routine. * Programmer: R. White Date: 17 April 1992 * ************************************************************************ -*/ int h_put_data ( pfi char_out, int a[], int nx, int ny, char *format ) { /* void pr_format_message(); */ /* static int put_raw(); */ /* static int put_fits(); */ if ( streq( format, "raw" ) || streq( format, "hhh" ) ) { PR_CHECK( put_raw( char_out, a, nx, ny, FALSE ) ); } else if ( streq( format, "net") ) { PR_CHECK( put_raw( char_out, a, nx, ny, TRUE ) ); } else if (streq( format, "fits" ) ) { PR_CHECK( put_fits( char_out, a, nx, ny ) ); } else { pr_format_message( PR_E_FORMAT ); return( PR_E_FORMAT ); } return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * static int put_raw( char_out, a, nx, ny, swap ) * * Purpose: * Statement of purpose. * * Parameters: * int (*char_out)() : (in) Function to write bytes. * int a[] : (in) Array to write. * int nx : (in) Size of x axis. * int ny : (in) Size of y axis. * boolean swap : (in) If true, bytes will be swaped if * necesary. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_IO : Error during io. * int PR_E_MEMORY : Memory allocation failure. * * References: * Copied from the hcompress put_raw routine. * Programmer: R. White Date: 17 April 1992 * ************************************************************************ -*/ static int put_raw ( pfi char_out, int a[], int nx, int ny, boolean swap ) { void h_swap_bytes(); boolean test_swap(); int i; int j; int k; short *sa; /* Working array for swaped data. */ boolean tswap; /* is byte swaping required? */ int v; /* * see if byte-swapping will be needed */ if (swap) { tswap = test_swap(); } else { tswap = 0; } /* * write a row at a time to minimize page faulting problems */ PR_CHECK_NULL( sa = short_alloc( ny ) ); for ( i = 0; i < nx ; i++ ) { k = i * ny; for ( j = 0; j < ny; j++) { /* * force value into 16-bit integer range */ v = a[k++]; if (v < -32768) { sa[j] = -32768; } else if (v > 32767) { sa[j] = 32767; } else { sa[j] = v; } } if ( tswap ) { h_swap_bytes( sa, ny * sizeof( short ) ); } PR_CHECK( char_out( sa, ny * sizeof( short ) ) ); } gen_free(sa); return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * static int PUT_FITS( char_out, a, nx, ny ) * * Purpose: * Writes fits data to the output. * * Parameters: * int (*char_out)() : (in) Function to write data. * int a[] : (in) Array to be written. * int nx : (in) X dimension. * int ny : (in) Y dimension. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_IO : Error during io. * int PR_E_MEMORY : Memory allocation failure. * * References: * Copied from the hcompress put_fits routine. * Programmer: R. White Date: 17 April 1992 * ************************************************************************ -*/ static int put_fits ( pfi char_out, int a[], int nx, int ny ) { void pr_foramt_message(); int n; short *sa; int status; /* * write data with swapping */ PR_CHECK( put_raw( char_out, a, nx, ny, TRUE) ); /* * add zeroes to get up to multiple of 2880 bytes * number of padding short ints to write is between 0 and 1439 */ n = 1439 - ( ( nx * ny - 1 ) % 1440 ); status = PR_SUCCESS; if ( n > 0 ) { /* * allocate a block of zeros */ PR_CHECK_NULL( sa = (short *) calloc( n , sizeof( short ) ) ); status = char_out( sa, n * sizeof( short ) ); gen_free( sa ); } return( status ); } /*+ ************************************************************************ * * Synopsis: * void h_swap_bytes( a, n ) * * Purpose: * Swaps the bytes in a. * * Parameters: * byte a[] : (in) An array of bytes to swap. * int n : (in) The size of the array. * * Values Returned: * void * * References: * Copied from the hcompress h_swap_bytes routine. * Programmer: R. White Date: 17 April 1992 * ************************************************************************ -*/ void h_swap_bytes ( byte a[], int n ) { int i; byte tmp; for (i = 0; i < n - 1; i += 2) { tmp = a[i]; a[i] = a[i+1]; a[i+1] = tmp; } } /*+ ************************************************************************ * * Synopsis: * boolean test_swap() * * Purpose: * Test to see if byte swapping is necessary on this machine. * * Parameters: * void * * Values Returned: * boolean TRUE : Byte swapping is necesary. * boolean FALSE : Byte swapping is not necessary. * * References: * Copied from the hcompress test_swap routine. * Programmer: R. White Date: 17 April 1992 * ************************************************************************ -*/ boolean test_swap ( void ) { union { short s; char c[2]; } u; u.c[0] = 0; u.c[1] = 1; return (u.s != 1); } skycat-3.1.2-starlink-1b/astrotcl/press/hinv.c000066400000000000000000000135331215713201500212410ustar00rootroot00000000000000/* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* hinv.c Inverse H-transform of NX x NY integer image * * Programmer: R. White Date: 23 July 1993 */ #include #include #include static void unshuffle(); extern void hsmooth(); extern void hinv(a,nx,ny,smooth,scale) int a[]; int nx,ny; int smooth; /* 0 for no smoothing, else smooth during inversion */ int scale; /* used if smoothing is specified */ { int nmax, log2n, i, j, k; int nxtop,nytop,nxf,nyf,c; int oddx,oddy; int shift, bit0, bit1, bit2, mask0, mask1, mask2, prnd0, prnd1, prnd2, nrnd0, nrnd1, nrnd2, lowbit0, lowbit1; int h0, hx, hy, hc; int s10, s00; int *tmp; /* * log2n is log2 of max(nx,ny) rounded up to next power of 2 */ nmax = (nx>ny) ? nx : ny; log2n = log((float) nmax)/log(2.0)+0.5; if ( nmax > (1<> 1; prnd1 = bit1 >> 1; prnd2 = bit2 >> 1; nrnd0 = prnd0 - 1; nrnd1 = prnd1 - 1; nrnd2 = prnd2 - 1; /* * round h0 to multiple of bit2 */ a[0] = (a[0] + ((a[0] >= 0) ? prnd2 : nrnd2)) & mask2; /* * do log2n expansions * * We're indexing a as a 2-D array with dimensions (nx,ny). */ nxtop = 1; nytop = 1; nxf = nx; nyf = ny; c = 1<=0; k--) { /* * this somewhat cryptic code generates the sequence * ntop[k-1] = (ntop[k]+1)/2, where ntop[log2n] = n */ c = c>>1; nxtop = nxtop<<1; nytop = nytop<<1; if (nxf <= c) { nxtop -= 1; } else { nxf -= c; } if (nyf <= c) { nytop -= 1; } else { nyf -= c; } /* * double shift and fix nrnd0 (because prnd0=0) on last pass */ if (k == 0) { nrnd0 = 0; shift = 2; } /* * unshuffle in each dimension to interleave coefficients */ for (i = 0; i= 0) ? prnd1 : nrnd1)) & mask1; hy = (hy + ((hy >= 0) ? prnd1 : nrnd1)) & mask1; hc = (hc + ((hc >= 0) ? prnd0 : nrnd0)) & mask0; /* * propagate bit0 of hc to hx,hy */ lowbit0 = hc & bit0; hx = (hx >= 0) ? (hx - lowbit0) : (hx + lowbit0); hy = (hy >= 0) ? (hy - lowbit0) : (hy + lowbit0); /* * Propagate bits 0 and 1 of hc,hx,hy to h0. * This could be simplified if we assume h0>0, but then * the inversion would not be lossless for images with * negative pixels. */ lowbit1 = (hc ^ hx ^ hy) & bit1; h0 = (h0 >= 0) ? (h0 + lowbit0 - lowbit1) : (h0 + ((lowbit0 == 0) ? lowbit1 : (lowbit0-lowbit1))); /* * Divide sums by 2 (4 last time) */ a[s10+1] = (h0 + hx + hy + hc) >> shift; a[s10 ] = (h0 + hx - hy - hc) >> shift; a[s00+1] = (h0 - hx + hy - hc) >> shift; a[s00 ] = (h0 - hx - hy + hc) >> shift; s00 += 2; s10 += 2; } if (oddy) { /* * do last element in row if row length is odd * s00+1, s10+1 are off edge */ h0 = a[s00 ]; hx = a[s10 ]; hx = ((hx >= 0) ? (hx+prnd1) : (hx+nrnd1)) & mask1; lowbit1 = hx & bit1; h0 = (h0 >= 0) ? (h0 - lowbit1) : (h0 + lowbit1); a[s10 ] = (h0 + hx) >> shift; a[s00 ] = (h0 - hx) >> shift; } } if (oddx) { /* * do last row if column length is odd * s10, s10+1 are off edge */ s00 = ny*i; for (j = 0; j= 0) ? (hy+prnd1) : (hy+nrnd1)) & mask1; lowbit1 = hy & bit1; h0 = (h0 >= 0) ? (h0 - lowbit1) : (h0 + lowbit1); a[s00+1] = (h0 + hy) >> shift; a[s00 ] = (h0 - hy) >> shift; s00 += 2; } if (oddy) { /* * do corner element if both row and column lengths are odd * s00+1, s10, s10+1 are off edge */ h0 = a[s00 ]; a[s00 ] = h0 >> shift; } } /* * divide all the masks and rounding values by 2 */ bit2 = bit1; bit1 = bit0; bit0 = bit0 >> 1; mask1 = mask0; mask0 = mask0 >> 1; prnd1 = prnd0; prnd0 = prnd0 >> 1; nrnd1 = nrnd0; nrnd0 = prnd0 - 1; } free(tmp); } static void unshuffle(a,n,n2,tmp) int a[]; /* array to shuffle */ int n; /* number of elements to shuffle */ int n2; /* second dimension */ int tmp[]; /* scratch storage */ { int i; int nhalf; int *p1, *p2, *pt; /* * copy 2nd half of array to tmp */ nhalf = (n+1)>>1; pt = tmp; p1 = &a[n2*nhalf]; /* pointer to a[i] */ for (i=nhalf; i= 0; i--) { *p1 = *p2; p2 -= n2; p1 -= (n2+n2); } /* * now distribute 2nd half of array (in tmp) to odd elements */ pt = tmp; p1 = &a[n2]; /* pointer to a[i] */ for (i=1; i #include #define min(a,b) (((a)<(b)) ? (a) : (b)) #define max(a,b) (((a)>(b)) ? (a) : (b)) extern void hsmooth(a,nxtop,nytop,ny,scale) int a[]; /* array of H-transform coefficients */ int nxtop,nytop; /* size of coefficient block to use */ int ny; /* actual 1st dimension of array */ int scale; /* truncation scale factor that was used */ { int i, j; int ny2, s10, s00, diff, dmax, dmin, s, smax; int hm, h0, hp, hmm, hpm, hmp, hpp, hx2, hy2; int m1,m2; /* * Maximum change in coefficients is determined by scale factor. * Since we rounded during division (see digitize.c), the biggest * permitted change is scale/2. */ smax = (scale >> 1); if (smax <= 0) return; ny2 = ny << 1; /* * We're indexing a as a 2-D array with dimensions (nxtop,ny) of which * only (nxtop,nytop) are used. The coefficients on the edge of the * array are not adjusted (which is why the loops below start at 2 * instead of 0 and end at nxtop-2 instead of nxtop.) */ /* * Adjust x difference hx */ for (i = 2; i=0, dmin<=0. */ if (dmin < dmax) { diff = max( min(diff, dmax), dmin); /* * Compute change in slope limited to range +/- smax. * Careful with rounding negative numbers when using * shift for divide by 8. */ s = diff-(a[s10]<<3); s = (s>=0) ? (s>>3) : ((s+7)>>3) ; s = max( min(s, smax), -smax); a[s10] = a[s10]+s; } s00 += 2; s10 += 2; } } /* * Adjust y difference hy */ for (i = 0; i=0) ? (s>>3) : ((s+7)>>3) ; s = max( min(s, smax), -smax); a[s00+1] = a[s00+1]+s; } s00 += 2; s10 += 2; } } /* * Adjust curvature difference hc */ for (i = 2; i=0, dmin<=0. */ if (dmin < dmax) { diff = max( min(diff, dmax), dmin); /* * Compute change in slope limited to range +/- smax. * Careful with rounding negative numbers when using * shift for divide by 64. */ s = diff-(a[s10+1]<<6); s = (s>=0) ? (s>>6) : ((s+63)>>6) ; s = max( min(s, smax), -smax); a[s10+1] = a[s10+1]+s; } s00 += 2; s10 += 2; } } } skycat-3.1.2-starlink-1b/astrotcl/press/htrans.c000066400000000000000000000101161215713201500215660ustar00rootroot00000000000000/* htrans.c H-transform of NX x NY integer image * * Programmer: R. White Date: 11 May 1992 */ #include #include #include static void shuffle(); extern void htrans(a,nx,ny) int a[]; int nx, ny; { int nmax, log2n, h0, hx, hy, hc, nxtop, nytop, i, j, k; int oddx, oddy; int shift, mask, mask2, prnd, prnd2, nrnd2; int s10, s00; int *tmp; /* * log2n is log2 of max(nx,ny) rounded up to next power of 2 */ nmax = (nx>ny) ? nx : ny; log2n = log((float) nmax)/log(2.0)+0.5; if ( nmax > (1<> shift; hx = (a[s10+1] + a[s10] - a[s00+1] - a[s00]) >> shift; hy = (a[s10+1] - a[s10] + a[s00+1] - a[s00]) >> shift; hc = (a[s10+1] - a[s10] - a[s00+1] + a[s00]) >> shift; /* * Throw away the 2 bottom bits of h0, bottom bit of hx,hy. * To get rounding to be same for positive and negative * numbers, nrnd2 = prnd2 - 1. */ a[s10+1] = hc; a[s10 ] = ( (hx>=0) ? (hx+prnd) : hx ) & mask ; a[s00+1] = ( (hy>=0) ? (hy+prnd) : hy ) & mask ; a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; s00 += 2; s10 += 2; } if (oddy) { /* * do last element in row if row length is odd * s00+1, s10+1 are off edge */ h0 = (a[s10] + a[s00]) << (1-shift); hx = (a[s10] - a[s00]) << (1-shift); a[s10 ] = ( (hx>=0) ? (hx+prnd) : hx ) & mask ; a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; s00 += 1; s10 += 1; } } if (oddx) { /* * do last row if column length is odd * s10, s10+1 are off edge */ s00 = i*ny; for (j = 0; j=0) ? (hy+prnd) : hy ) & mask ; a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; s00 += 2; } if (oddy) { /* * do corner element if both row and column lengths are odd * s00+1, s10, s10+1 are off edge */ h0 = a[s00] << (2-shift); a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; } } /* * now shuffle in each dimension to group coefficients by order */ for (i = 0; i>1; nytop = (nytop+1)>>1; /* * divisor doubles after first reduction */ shift = 1; /* * masks, rounding values double after each iteration */ mask = mask2; prnd = prnd2; mask2 = mask2 << 1; prnd2 = prnd2 << 1; nrnd2 = prnd2 - 1; } free(tmp); } static void shuffle(a,n,n2,tmp) int a[]; /* array to shuffle */ int n; /* number of elements to shuffle */ int n2; /* second dimension */ int tmp[]; /* scratch storage */ { int i; int *p1, *p2, *pt; /* * copy odd elements to tmp */ pt = tmp; p1 = &a[n2]; for (i=1; i < n; i += 2) { *pt = *p1; pt += 1; p1 += (n2+n2); } /* * compress even elements into first half of A */ p1 = &a[n2]; p2 = &a[n2+n2]; for (i=2; i #include #include #include #include "gen_types.h" #include "gen_str.h" #include "gen_msg.h" #include "press.h" #include "local_press.h" /*+ ************************************************************************ * * Function: press * * Purpose: * Generic compression function. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_UNSUPPORT : Unsuported compression type. * ************************************************************************ -*/ int press ( pfi char_in, /* (in) Function to get input data. */ pfi char_out, /* (in) Function to write output data. */ char *type /* (in) Compresion type. */ ) { if ( streq( type, PR_UNIX ) ) { PR_CHECK( ux_comp( char_in, char_out ) ); } else if ( streq( type, PR_HCOMP ) ) { PR_CHECK( h_comp( char_in, char_out ) ); } else if ( streq( type, PR_GZIP ) ) { PR_CHECK( gzip_comp( char_in, char_out ) ); } else if ( streq( type, PR_NONE ) ) { PR_CHECK( none_comp( char_in, char_out ) ); } else { pr_format_message( PR_E_UNSUPPORT, type ); return( PR_E_UNSUPPORT ); } return( PR_SUCCESS ); } /*+ ************************************************************************ * * Function: press_buffer_in * * Purpose: * Copies a string of characters from in input buffer. * * Values Returned: * int len : The number of bytes transfered. * int PR_E_EOI : End of file detected. * ************************************************************************ -*/ int press_buffer_in ( byte *buffer, /* (in) Place to put the characters. */ int length /* (in) The size of buffer. */ ) { int len; if ( local_press.lp_in_buf_pos >= local_press.lp_in_buf_size ) { return( PR_E_EOI ); } else { len = MIN( length, local_press.lp_in_buf_size - local_press.lp_in_buf_pos ); (void) memcpy( buffer, local_press.lp_in_buf + local_press.lp_in_buf_pos, len ); local_press.lp_in_buf_pos += len; return( len ); } } /*+ ************************************************************************ * * Function: press_buffer_out * * Purpose: * Copies a string of characters to the output buffer. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_MEMORY : Memory allocation failure. * ************************************************************************ -*/ int press_buffer_out ( byte *buffer, /* (in) Buffer to write. */ int length /* (in) Number of characters to copy. */ ) { if ( local_press.lp_out_buf_pos + length > local_press.lp_out_buf_size ) { PR_CHECK_NULL( local_press.lp_out_buf = (byte *) gen_realloc( local_press.lp_out_buf, MAX( local_press.lp_out_buf_size + local_press.lp_out_buf_inc, local_press.lp_out_buf_pos + length ) ) ); local_press.lp_out_buf_size += local_press.lp_out_buf_inc; } (void) memcpy( local_press.lp_out_buf + local_press.lp_out_buf_pos, buffer, length ); local_press.lp_out_buf_pos += length; return( PR_SUCCESS ); } /*+ ************************************************************************ * * Function: press_file_in * * Purpose: * Gets a string of characters from an input file. * * Values Returned: * int length : The number of characters read. * int PR_E_EOI : End of file detected. * ************************************************************************ -*/ int press_file_in ( byte *buffer, /* (in) The buffer to fill. */ int length /* (in) Number of characters to get. */ ) { int len; len = read( local_press.lp_infile, buffer, length ); if ( len <= 0 ) { return( PR_E_EOI ); } else { return( len ); } } /*+ ************************************************************************ * * Function: press_file_out * * Purpose: * Writes a character to the output file. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_IO : Io error detected. * ************************************************************************ -*/ int press_file_out ( byte *buffer, /* (in) Buffer to write. */ int length /* (in) Number of bytes to write. */ ) { PR_CHECK_IO( write( local_press.lp_outfile, buffer, length ), "output file" ); return( PR_SUCCESS ); } /*+ ************************************************************************ * * Function: unpress * * Purpose: * Generic decompression function. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_UNSUPPORT : Unsupported compression type. * ************************************************************************ -*/ int unpress ( pfi char_in, /* (in) Function to read characters. */ pfi char_out, /* (in) Function to write characters. */ char *type /* (in) Compression type. */ ) { if ( streq( type, PR_UNIX ) ) { PR_CHECK( ux_uncomp( char_in, char_out ) ); } else if ( streq( type, PR_HCOMP ) ) { PR_CHECK( h_uncomp( char_in, char_out ) ) } else if ( streq( type, PR_ULDA ) ) { PR_CHECK( ulda_uncomp( char_in, char_out ) ) } else if ( streq( type, PR_GZIP ) ) { PR_CHECK( gzip_uncomp( char_in, char_out ) ) } else if ( streq( type, PR_NONE ) ) { PR_CHECK( none_uncomp( char_in, char_out ) ) } else { pr_format_message( PR_E_UNSUPPORT, type ); return( PR_E_UNSUPPORT ); } return( PR_SUCCESS ); } skycat-3.1.2-starlink-1b/astrotcl/press/local_press.h000066400000000000000000000074411215713201500226110ustar00rootroot00000000000000/*+ ************************************************************************ **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** * * Include File Name: press/h/local_press.h * * Purpose: * Contains the local symbol definitions for the press library. * * Date : Feb 24, 1993 * * SCCS data : @(#) * Module Name : local_press.h * Version Number : 1.6 * Release Number : 1 * Last Updated : 07/04/97 * * Programmer : Norman Hill * * Modification History: * 97/07/02 SEC : Added function prototypes. * **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** ************************************************************************ -*/ #define PR_CHECK( s ) { int estatus; \ if ( ( estatus = ( s ) ) < 0 ) { \ return( estatus ); } } #define PR_CHECK_IO( s, name ) { if ( ( s ) < 0 ) {\ pr_format_message( MSG_ERRNO, (name) );\ return( PR_E_IO ); } } #define PR_CHECK_NULL( s ) { if ( ( s ) == NULL ) {\ pr_format_message( PR_E_MEMORY );\ return( PR_E_MEMORY ); } } typedef struct local_press { char *lp_format; /* Format of hcompress data: raw | fits */ /* | net | hhh */ int lp_nx; /* X dimension of the image. */ int lp_ny; /* Y dimension of the image. */ int lp_smooth; /* Do smoothing after hdecompress? */ boolean lp_verbose; /* Run in verbose mode? */ int lp_scale; /* Scale factor for hcompress and gzip. */ int lp_infile; /* Input file descriptor. */ int lp_outfile; /* Output file descriptor. */ byte *lp_in_buf; /* Pointer to input buffer. */ int lp_in_buf_size; /* Size of the input buffer. */ int lp_in_buf_pos; /* Position in the input buffer. */ byte *lp_out_buf; /* Pointer to output buffer. */ int lp_out_buf_size;/* Size of the output buffer. */ int lp_out_buf_pos; /* Position in the ouput buffer. */ int lp_out_buf_inc; /* Ouput buffer size increment. */ } LOCAL_PRESS; /* * Huffman code lookup table entry--this entry is four bytes for machines * that have 16-bit pointers (e.g. PC's in the small or medium model). * Valid extra bits are 0..13. e == 15 is EOB (end of block), e == 16 * means that v is a literal, 16 < e < 32 means that v is a pointer to * the next table, which codes e - 16 bits, and lastly e == 99 indicates * an unused code. If a code with e == 99 is looked up, this implies an * error in the data. */ typedef struct huft_struct { byte e; /* number of extra bits or operation */ byte b; /* number of bits in this code or subcode */ union { unsigned short n; /* literal, length base, or distance base */ struct huft_struct *t; /* pointer to next level of table */ } v; } HUFT; /* * Globals variable declarations. */ extern LOCAL_PRESS local_press; /* * ANSI C Function Prototypes for local functions. */ extern int get_byte( void ); #if 0 /* allan */ extern int huft_build( unsigned *, unsigned, unsigned, unsigned short *, unsigned short *, HUFT **, int * ); extern int huft_free( HUFT * ); #endif extern int gzip_inflate( void ); /* allan: changed name from "inflate()" to avoid name clash with tclpro */ extern unsigned long updcrc( byte *, unsigned ); extern int h_comp( pfi, pfi ); extern int h_uncomp( pfi, pfi ); extern int gzip_comp( pfi, pfi ); extern int gzip_uncomp( pfi, pfi ); extern int none_comp( pfi, pfi ); extern int none_uncomp( pfi, pfi ); extern void pr_format_message( int, ... ); extern int press( pfi, pfi, char *); extern int unpress( pfi, pfi, char * ); extern int press_buffer_in( byte *, int ); extern int press_buffer_out( byte *, int ); extern int press_file_in( byte *, int ); extern int press_file_out( byte *, int ); extern int ulda_uncomp( pfi, pfi ); extern int ux_comp( pfi, pfi ); extern int ux_uncomp( pfi, pfi ); skycat-3.1.2-starlink-1b/astrotcl/press/msg.c000066400000000000000000000155101215713201500210600ustar00rootroot00000000000000/*+ ************************************************************************ **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** * * Module Name: gen/src/msg.c * * Purpose: * Message handling routines. When more than one message is * found in the string, the delimiting character is a newline * character. * * Routines: * static int compare_status : Compare function for bsearch. * void msg_append : Appends a message to another. * void msg_clear : Clears the message string. * static char *msg_find : Returns the format string. * void msg_format : Formats and appends the message. * * Date : Aug 23, 1991 * * SCCS data : @(#) * Module Name : msg.c * Version Number : 1.10 * Release Number : 1 * Last Updated : 2/12/93 * * Programmer : Severin Gaudet * : Peter W. Draper * * Modification History: * 92/08/11 nrh - Added check for vms specific errors to * msg_format. * 98/02/09 pwd - modifed to use strerror on UNIX calls. * **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** ************************************************************************ -*/ #include #include #include #ifdef VMS #include #endif #include #include "gen_types.h" #include "gen_str.h" #include "gen_msg.h" int errno; #define MSG_NOT_FOUND "Message not found." /*+ ************************************************************************ * * Synopsis: * static int compare_status( p, q ) * * Purpose: * Compares the status values in 2 msg structures. This function * is used be bsearch(). * * Parameters: * char *p : (in) Item to be compared. * char *q : (in) Item to be compared. * * Values Returned: * int 0 : Same status value. * int < 0 : p is greater than q. * int > 0 : q is greater than p. * ************************************************************************ -*/ static int compare_status( p, q ) const void *p; const void *q; { MSG *m1; MSG *m2; m1 = (MSG *) p; m2 = (MSG *) q; return( m2->m_status - m1->m_status ); } /*+ ************************************************************************ * * Synopsis: * void msg_append( msg1, msg2 ) * * Purpose: * Appends msg2 to msg1. This is useful for concatenating messages * from different sources. Make sure that the total length will * not exceed the maximum message length. A newline character is * used as the delimiter between messages. * * Parameters: * char *msg1 : (mod) Message to be appended to. * char *msg2 : (in) Message to be added. * * Values Returned: * None. * ************************************************************************ -*/ void msg_append( msg1, msg2 ) char *msg1; char *msg2; { int len1; int len2; len1 = strlen( msg1 ) + 1; len2 = strlen( msg2 ); len2 = MIN( len2, ( MSG_MAX_LEN - len1 ) ); if ( len2 > 0 ) { if ( len1 == 1 ) { (void) strcpy( msg1, msg2 ); } else { (void) strcat( msg1, "\n" ); (void) strncat( msg1, msg2, len2 ); } } } /*+ ************************************************************************ * * Synopsis: * void msg_clear( msg ) * * Purpose: * Clears the message string by setting the first character to * the end-of-string character. * * Parameters: * char *msg : (mod) String to be cleared. * * Values Returned: * None. * ************************************************************************ -*/ void msg_clear( msg ) char *msg; { msg[0] = '\0'; } /*+ ************************************************************************ * * Synopsis: * static char *msg_find( status, msgs, num_msgs ) * * Purpose: * Returns the format string of the message corresponding to the * given status. * * Parameters: * int status : (in) Status searching for. * MSG *msgs : (in) Array of message structures. * int num_msgs : (in) Number of messages in array. * * Values Returned: * char *format : Format string. * ************************************************************************ -*/ static char *msg_find( status, msgs, num_msgs ) int status; MSG *msgs; int num_msgs; { MSG *m; MSG temp_m; temp_m.m_status = status; m = (MSG *) bsearch( (char *)(&temp_m), (char *) msgs, (unsigned) num_msgs, sizeof( MSG ), compare_status ); if ( m == NULL ) { return( MSG_NOT_FOUND ); } else { return( m->m_format ); } } /*+ ************************************************************************ * * Synopsis: * void msg_format( buffer, prefix, num_msgs, msgs, status, args ) * * Purpose: * Formats the buffer according to the status using the message * array and arguments provided. * * Parameters: * va_list : (in) Variable length arguments. * * Values Returned: * None. * ************************************************************************ -*/ void msg_format(char *buffer, char *prefix, int num_msgs, MSG *msgs, int status, ...) /* XXX allan: 12.11.03: changed from vararg to stdarg */ { void msg_append(); char *msg_find(); char *errno_arg; char *format; int i; int indent_size; char *t1; char *t2; char temp_buffer1[MSG_MAX_LEN]; char temp_buffer2[MSG_MAX_LEN]; va_list args; va_start( args, status ); if ( status == MSG_ERRNO ) { /* * Errno message will be used and then reset to 0. * The '+' character is used to separate the prefix from * the error number. */ errno_arg = va_arg( args, char * ); #ifdef VMS if ( vaxc$errno != 0 ) { (void) sprintf( temp_buffer2, "(%s+%d) %s: %s", prefix, errno, errno_arg, strerror( EVMSERR, vaxc$errno ) ); } else if ( errno != 0 ) { (void) sprintf( temp_buffer2, "(%s+%d) %s: %s", prefix, errno, errno_arg, strerror( errno ) ); } vaxc$errno = 0; errno = 0; #else /* VMS */ if ( errno != 0 ) { (void) sprintf( temp_buffer2, "(%s+%d) %s: %s", prefix, errno, errno_arg, strerror( errno ) ); errno = 0; } #endif /* VMS */ } else { /* * Message array will be used and the prefix-number * separator will be a '-' (implicit since the number * is negative). Since this is a programmer generated * message, parse it for newline characters and indent * accordingly. */ format = msg_find( status, msgs, num_msgs ); (void) vsprintf( temp_buffer1, format, args ); if ( strchr( temp_buffer1, '\n' ) == NULL ) { (void) sprintf( temp_buffer2, "(%s%d) %s", prefix, status, temp_buffer1 ); } else { (void) sprintf( temp_buffer2, "(%s%d) ", prefix, status ); indent_size = strlen( temp_buffer2 ); t1 = temp_buffer1; t2 = temp_buffer2 + indent_size; for ( ; *t1; t1++ ) { *t2++ = *t1; if ( *t1 == '\n' ) { for ( i = 0; i < indent_size; i++ ) { *t2++ = ' '; } } } *t2 = '\0'; } } msg_append( buffer, temp_buffer2 ); } skycat-3.1.2-starlink-1b/astrotcl/press/none.c000066400000000000000000000064231215713201500212340ustar00rootroot00000000000000/*+ ************************************************************************ **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** * * (c) 1995 (c) 1995. * National Research Council Conseil national de recherches * Ottawa, Canada, K1A 0R6 Ottawa, Canada, K1A 0R6 * All rights reserved Tous droits reserves * * NRC disclaims any warranties, Le CNRC denie toute garantie * expressed, implied, or statu- enoncee, implicite ou legale, * tory, of any kind with respect de quelque nature que se soit, * to the software, including concernant le logiciel, y com- * without limitation any war- pris sans restriction toute * ranty of merchantability or garantie de valeur marchande * fitness for a particular pur- ou de pertinence pour un usage * pose. NRC shall not be liable particulier. Le CNRC ne * in any event for any damages, pourra en aucun cas etre tenu * whether direct or indirect, responsable de tout dommage, * special or general, consequen- direct ou indirect, particul- * tial or incidental, arising ier ou general, accessoire ou * from the use of the software. fortuit, resultant de l'utili- * sation du logiciel. * ************************************************************************ * * Module Name: press/src/none.c * * Purpose: * Whatever * * Routines: * type routine : Brief description. * type routine : Brief description. * type routine : Brief description. * * Date : Nov 16, 1995 * * SCCS data : @(#) * Module Name : none.c * Version Number : 1.1 * Release Number : 1 * Last Updated : 03/07/96 * * Programmer : Norm Hill * * Modification History: * **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** ************************************************************************ -*/ #include "gen_types.h" #include "press.h" #include "local_press.h" /*+ ************************************************************************ * * Function: name * * Purpose: * Statement of purpose. * * Values Returned: * type name : Meaning *** delete if void function *** * type name : Meaning *** delete if void function *** * * References: * *** delete if not applicable *** * ************************************************************************ -*/ int none_comp ( pfi char_in, /* (in) Function to get data. */ pfi char_out /* (in) Function to write data. */ ) { byte buffer[4096]; int bytes_left; while ( ( bytes_left = char_in( buffer, sizeof( buffer ) ) ) != PR_E_EOI ) { PR_CHECK( char_out( buffer, bytes_left ) ); } return( PR_SUCCESS ); } /*+ ************************************************************************ * * Function: name * * Purpose: * Statement of purpose. * * Values Returned: * type name : Meaning *** delete if void function *** * type name : Meaning *** delete if void function *** * * References: * *** delete if not applicable *** * ************************************************************************ -*/ int none_uncomp ( pfi char_in, /* (in) Function to get data. */ pfi char_out /* (in) Function to write data. */ ) { byte buffer[4096]; int bytes_left; while ( ( bytes_left = char_in( buffer, sizeof( buffer ) ) ) != PR_E_EOI ) { PR_CHECK( char_out( buffer, bytes_left ) ); } return( PR_SUCCESS ); } skycat-3.1.2-starlink-1b/astrotcl/press/pr_msg.c000066400000000000000000000055711215713201500215670ustar00rootroot00000000000000/*+ ************************************************************************ **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** * * Module Name: press/src/pr_msg.c * * Purpose: * Formats messge for the press library. * * Routines: * void pr_format_message : Formats a message. * * Date : Feb 23, 1993 * * SCCS data : @(#) * Module Name : pr_msg.c * Version Number : 1.8 * Release Number : 1 * Last Updated : 07/04/97 * * Programmer : Norman Hill * * Modification History: * 97/07/02 SEC : Bring up to ANSI standard. * **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** ************************************************************************ -*/ #include #include "gen_types.h" #include "gen_str.h" #include "gen_msg.h" #include "press.h" #define PR_PREFIX "pr" char pr_msg[MSG_MAX_LEN]; MSG pr_msgs[] = { { PR_HCOMP_INFO, "%6.4f bits/pixel, compression factor %5.1f." }, { PR_HDECOMP_INFO, " Smoothing: %d, image size: %dx%d, scale: %d, output format: %s." }, { PR_E_BITPLANE, " bit plane in hdecompress." }, { PR_E_BITS, "Only codes up to '%d' bits are supported." }, { PR_E_BLOCK, " block type '%d'." }, { PR_E_CODE, " code %d in hdecompress qtree decode." }, { PR_E_CRC, "The CRC stored in the file does not match the data." }, { PR_E_DATA, "Data could not be decompressed." }, { PR_E_EOI, "Unexpected end of input detected." }, { PR_E_FITS, "Error reading fits header line:\n%s" }, { PR_E_FITS_DIM, "The image is not 2 dimensional." }, { PR_E_FITS_GRP, "The fits file contains groups, and cannot be compressed." }, { PR_E_FITS_INC, "The fits header is incomplete." }, { PR_E_FITS_TYPE, "The type of the image data is not '%s'." }, { PR_E_FORMAT, "Hcompress output format is not supported." }, { PR_E_INC_LIT, "Incomplete literal tree." }, { PR_E_MAGIC, "The magic number of the compressed data is wrong." }, { PR_E_MEMORY, "Memory allocation failure." }, { PR_E_METHOD, "Compression method '%s' is not supported." }, { PR_E_NAXIS, "hcompress only supports 2 axis fits files." }, { PR_E_SIZE, "The size of the data is not the expected size." }, { PR_E_UNSUPPORT, "Compression type '%s' is not supported." }, }; int pr_num_msgs = sizeof( pr_msgs ) / sizeof( MSG ); /*+ ************************************************************************ * * Synopsis: * void pr_format_message( va_alist ) * * Purpose: * Formats a message from the contents of the va_alist. * * Parameters: * va_list : (in) Variable length arguments. * * Values Returned: * None. * ************************************************************************ -*/ void pr_format_message ( int status, ... ) { va_list args; va_start( args, status ); msg_format( pr_msg, PR_PREFIX, pr_num_msgs, pr_msgs, status, args ); va_end( args ); } skycat-3.1.2-starlink-1b/astrotcl/press/press.c000066400000000000000000000372501215713201500214330ustar00rootroot00000000000000/*+ ************************************************************************ **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** * * Module Name: press/src/press.c * * Purpose: * Contains the user interface routines to the press library. * * Routines: * int press_f2f : Compress file to file. * int press_f2m : Compress file to memory. * int press_m2f : Compress memory to file. * int press_m2m : Compress memory to memory. * int press_setopt : Set compression/decompression options. * int unpress_f2f : Uncompress file to file. * int unpress_f2m : Uncompress file to memory. * int unpress_fsize : Returns uncompressed file size. * int unpress_m2f : Uncompress memory to file. * int unpress_m2m : Uncompress memory to memory. * int unpress_msize : Returns uncompressed memory size. * * Date : Feb 24, 1993 * * SCCS data : @(#) * Module Name : press.c * Version Number : 1.12 * Release Number : 1 * Last Updated : 07/04/97 * * Programmer : Norman Hill * * Modification History: * 97/07/02 SEC : Bring up to ANSI standard, added new functions * unpress_fsize and unpress_msize. * 98/03/22 Allan : changed varargs.h to stdarg.h and fixed * va_start call. * **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** ************************************************************************ -*/ #include #include /* allan: 22.03.98: was varargs.h */ #include #include #include #include "gen_types.h" #include "gen_msg.h" #include "gen_str.h" #include "press.h" #include "local_press.h" #define SH(p) ((unsigned short)(byte)((p)[0]) | \ ((unsigned short)(byte)((p)[1]) << 8)) #define LG(p) ((unsigned long)(SH(p)) | ((unsigned long)(SH((p)+2)) << 16)) /* allan: changed from "FITS" to "fits" */ LOCAL_PRESS local_press = { "fits", 512, 512, 0, FALSE, 10}; /* * An array of functions to call for each compression type. */ /*+ ************************************************************************ * * Function: press_f2f * * Purpose: * Compresses an input file opened on fd_in to an output file opened * on fd_out. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_UNSUPPORT : Unsupported compression type. * ************************************************************************ -*/ int press_f2f ( int fd_in, /* (in) Input file descriptor. */ int fd_out, /* (in) Output file descriptor. */ char *type /* (in) Compression type of the file. */ ) { local_press.lp_infile = fd_in; local_press.lp_outfile = fd_out; PR_CHECK( press( press_file_in, press_file_out, type ) ); return( PR_SUCCESS ); } /*+ ************************************************************************ * * Function: press_f2m * * Purpose: * Compresses an input file opened on fd_in to memory buffer * buffer_out. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_MEMORY : Memory allocation failure. * int PR_E_UNSUPPORT : Unsupported compression type. * ************************************************************************ -*/ int press_f2m ( int fd_in, /* (in) Input file descriptor. */ byte **o_buf, /* (out) Output memory buffer. */ int *o_buf_size, /* (mod) Estimated output buf size on input, actual buffer size on output. */ char *type /* (in) Compression type of the file. */ ) { local_press.lp_infile = fd_in; local_press.lp_out_buf_size = MAX( *o_buf_size, 1024 ); PR_CHECK_NULL( local_press.lp_out_buf = byte_alloc( local_press.lp_out_buf_size ) ); local_press.lp_out_buf_pos = 0; local_press.lp_out_buf_inc = local_press.lp_out_buf_size; PR_CHECK( press( press_file_in, press_buffer_out, type ) ); /* * Set the returned buffer pointer and length. */ *o_buf = local_press.lp_out_buf; *o_buf_size = local_press.lp_out_buf_pos; return( PR_SUCCESS ); } /*+ ************************************************************************ * * Function: press_m2f * * Purpose: * Compress the data in ibuf and write the data to the file opened * on file descriptor fd_out. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_UNSUPPORT : Unsupported compression type. * ************************************************************************ -*/ int press_m2f ( byte *i_buf, /* (in) Input memory buffer. */ int i_buf_size, /* (in) Input buffer size. */ int fd_out, /* (in) Output file descriptor. */ char *type /* (in) Compression type of the file. */ ) { local_press.lp_in_buf = i_buf; local_press.lp_in_buf_size = i_buf_size; local_press.lp_in_buf_pos = 0; local_press.lp_outfile = fd_out; PR_CHECK( press( press_buffer_in, press_file_out, type ) ); return( PR_SUCCESS ); } /*+ ************************************************************************ * * Function: press_m2m * * Purpose: * Compress the data in ibuf and return the result in a buffer * pointed to by obuf. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_MEMORY : Memory allocation failure. * int PR_E_UNSUPPORT : Unsupported compression type. * ************************************************************************ -*/ int press_m2m ( byte *i_buf, /* (in) Input memory buffer. */ int i_buf_size, /* (in) Input buffer size. */ byte **o_buf, /* (out) Output memory buffer. */ int *o_buf_size, /* (mod) Estimated output buf size on input, actual buffer size on output. */ char *type /* (in) Compression type of the file. */ ) { local_press.lp_out_buf_size = MAX( *o_buf_size, 1024 ); PR_CHECK_NULL( local_press.lp_out_buf = byte_alloc( local_press.lp_out_buf_size ) ); local_press.lp_out_buf_pos = 0; local_press.lp_out_buf_inc = local_press.lp_out_buf_size; local_press.lp_in_buf = i_buf; local_press.lp_in_buf_size = i_buf_size; local_press.lp_in_buf_pos = 0; PR_CHECK( press( press_buffer_in, press_buffer_out, type ) ); /* * Set the returned buffer pointer and length. */ *o_buf = local_press.lp_out_buf; *o_buf_size = local_press.lp_out_buf_pos; return( PR_SUCCESS ); } /*+ ************************************************************************ * * Function: press_setopt * * Purpose: * This function set the compression options. The options depend * on the compression type. * * * For unix compression: * int press_setopt( PR_UNIX, verbose ) * * Parameters: * char *type : (in) The type of compression: PR_UNIX * boolean verbose : (in) Should run in verbose mode? * * For gzip: * int press_setopt( PR_GZIP, verbose, scale ); * * Parameter: * char *type : (in) The type of compression: PR_GZIP * boolean verbose : (in) Should run in verboase mode? * int scale : (in) Scale factor for scaling: ( 1 - 9 ) * * * For hcompress: * int press_setopt( PR_HCOMP, verbose, smoothing, scale, format, * nx, ny ) * * Parameters: * char *type : (in) The type of compression: PR_HCOMP * boolean verbose : (in) Should run in verbose mode? * boolean smoothing : (in) Should hdecompress use smoothing * int scale : (in) Scale factor to use for hcompress. * char *format : (in) Format to use (fits | raw | net ) * int nx : (in) X dimension of the image. * int ny : (in) Y dimension of teh image. * * Note that nx and ny are required for raw and net files, but ignored for * fits files. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_UNSUPPORTED: Unsupported compression type. * ************************************************************************ -*/ int press_setopt ( char *type, ... ) { va_list args; va_start( args, type ); /* allan: 22.3.98: added type arg */ if ( streq( type, PR_UNIX ) ) { /* local_press.lp_verbose = va_arg( args, boolean ); allan: XXX error with gcc-2.96 */ local_press.lp_verbose = va_arg( args, int ); va_end( args ); } else if ( streq( type, PR_HCOMP ) ) { local_press.lp_verbose = (boolean) va_arg( args, int ); local_press.lp_smooth = va_arg( args, int ); local_press.lp_scale = va_arg( args, int ); local_press.lp_format = va_arg( args, char *); local_press.lp_nx = va_arg( args, int ); local_press.lp_ny = va_arg( args, int ); va_end( args ); } else if ( streq( type, PR_GZIP ) ) { local_press.lp_verbose = (boolean) va_arg( args, int ); local_press.lp_scale = va_arg( args, int ); va_end( args ); } else if ( streq( type, PR_NONE ) ) { /** local_press.lp_verbose = va_arg( args, boolean ); XXX allan: error with gcc-2.96 */ local_press.lp_verbose = va_arg( args, int ); va_end( args ); } else { va_end( args ); pr_format_message( PR_E_UNSUPPORT, type ); return( PR_E_UNSUPPORT ); } return( PR_SUCCESS ); } /*+ ************************************************************************ * * Function: unpress_f2f * * Purpose: * Uncompresses an input file opened on fd_in to an output file opened * on fd_out. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_UNSUPPORT : Unsupported compression type. * ************************************************************************ -*/ int unpress_f2f ( int fd_in, /* (in) Input file descriptor. */ int fd_out, /* (in) Output file descriptor. */ char *type /* (in) Compression type of the file. */ ) { local_press.lp_infile = fd_in; local_press.lp_outfile = fd_out; PR_CHECK( unpress( press_file_in, press_file_out, type ) ); return( PR_SUCCESS ); } /*+ ************************************************************************ * * Function: unpress_f2m * * Purpose: * Uncompresses an input file opened on fd_in to memory buffer * buffer_out. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_MEMORY : Memory allocation failure. * int PR_E_UNSUPPORT : Unsupported compression type. * ************************************************************************ -*/ int unpress_f2m ( int fd_in, /* (in) Input file descriptor. */ byte **o_buf, /* (out) Output memory buffer. */ int *o_buf_size, /* (mod) Estimated output buf size on input, actual buffer size on output. */ char *type /* (in) Compression type of the file. */ ) { local_press.lp_infile = fd_in; local_press.lp_out_buf_size = MAX( *o_buf_size, 1024 ); PR_CHECK_NULL( local_press.lp_out_buf = byte_alloc( local_press.lp_out_buf_size ) ); local_press.lp_out_buf_pos = 0; local_press.lp_out_buf_inc = local_press.lp_out_buf_size; PR_CHECK( unpress( press_file_in, press_buffer_out, type ) ); /* * Set the returned buffer pointer and length. */ *o_buf = local_press.lp_out_buf; *o_buf_size = local_press.lp_out_buf_pos; return( PR_SUCCESS ); } /*+ ************************************************************************ * * Function: unpress_fsize * * Purpose: * Get the uncompressed size of a compressed file. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_IO : Error during io. * int PR_E_UNSUPPORT : Unsupported compression type. * ************************************************************************ -*/ int unpress_fsize ( int fd_in, /* (in) Input file descriptor. */ int *osize, /* (mod) The uncompressed size. */ char *type /* (in) Compression type of the file. */ ) { char buf[4]; if ( streq( type, PR_GZIP ) ) { PR_CHECK_IO( lseek( fd_in, -4, SEEK_END ), "lseek" ); PR_CHECK_IO( read( fd_in, (char *) buf, sizeof(buf) ), "read" ); *osize = LG( buf ); } else { local_press.lp_infile = fd_in; local_press.lp_out_buf_size = MAX( *osize, 1024 ); PR_CHECK_NULL( local_press.lp_out_buf = byte_alloc( local_press.lp_out_buf_size ) ); local_press.lp_out_buf_pos = 0; local_press.lp_out_buf_inc = local_press.lp_out_buf_size; PR_CHECK( unpress( press_file_in, press_buffer_out, type ) ); gen_free( local_press.lp_out_buf ); *osize = local_press.lp_out_buf_pos; } return( PR_SUCCESS ); } /*+ ************************************************************************ * * Function: unpress_m2f * * Purpose: * Uncompress the data in ibuf and write the result to the file * descriptor fd_out. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_UNSUPPORT : Unsupported compression type. * ************************************************************************ -*/ int unpress_m2f ( byte *i_buf, /* (in) Input memory buffer. */ int i_buf_size, /* (in) Input buffer size. */ int fd_out, /* (in) Output file descriptor. */ char *type /* (in) Compression type of the file. */ ) { local_press.lp_in_buf = i_buf; local_press.lp_in_buf_size = i_buf_size; local_press.lp_in_buf_pos = 0; local_press.lp_outfile = fd_out; PR_CHECK( unpress( press_buffer_in, press_file_out, type ) ); return( PR_SUCCESS ); } /*+ ************************************************************************ * * Function: unpress_m2m * * Purpose: * Uncompress the data in ibuf and return the result in a buffer * pointed to by obuf. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_MEMORY : Memory allocation failure. * int PR_E_UNSUPPORT : Unsupported compression type. * ************************************************************************ -*/ int unpress_m2m ( byte *i_buf, /* (in) Input memory buffer. */ int i_buf_size, /* (in) Input buffer size. */ byte **o_buf, /* (out) Output memory buffer. */ int *o_buf_size, /* (mod) Estimated output buf size on input, actual buffer size on output. */ char *type /* (in) Compression type of the file. */ ) { local_press.lp_out_buf_size = MAX( *o_buf_size, i_buf_size ); local_press.lp_out_buf_size = MAX( local_press.lp_out_buf_size, 1024 ); PR_CHECK_NULL( local_press.lp_out_buf = byte_alloc( local_press.lp_out_buf_size ) ); local_press.lp_out_buf_pos = 0; local_press.lp_out_buf_inc = local_press.lp_out_buf_size; local_press.lp_in_buf = i_buf; local_press.lp_in_buf_size = i_buf_size; local_press.lp_in_buf_pos = 0; PR_CHECK( unpress( press_buffer_in, press_buffer_out, type ) ); /* * Set the returned buffer pointer and length. */ *o_buf = local_press.lp_out_buf; *o_buf_size = local_press.lp_out_buf_pos; return( PR_SUCCESS ); } /*+ ************************************************************************ * * Function: unpress_msize * * Purpose: * Get the uncompressed size of a compressed file in a memory buffer. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_IO : Error during io. * int PR_E_UNSUPPORT : Unsupported compression type. * ************************************************************************ -*/ int unpress_msize ( byte *i_buf, /* (in) Input memory buffer. */ int i_buf_size, /* (in) The buffer length. */ int *osize, /* (mod) The uncompressed size. */ char *type /* (in) Compression type of the file. */ ) { byte *ptr; if ( streq( type, PR_GZIP ) ) { ptr = &( i_buf[i_buf_size-4] ); *osize = LG( ptr ); } else { local_press.lp_out_buf_size = MAX( *osize, i_buf_size ); local_press.lp_out_buf_size = MAX( local_press.lp_out_buf_size, 1024 ); PR_CHECK_NULL( local_press.lp_out_buf = byte_alloc( local_press.lp_out_buf_size ) ); local_press.lp_out_buf_pos = 0; local_press.lp_out_buf_inc = local_press.lp_out_buf_size; local_press.lp_in_buf = i_buf; local_press.lp_in_buf_size = i_buf_size; local_press.lp_in_buf_pos = 0; PR_CHECK( unpress( press_buffer_in, press_buffer_out, type ) ); gen_free( local_press.lp_out_buf ); *osize = local_press.lp_out_buf_pos; } return( PR_SUCCESS ); } skycat-3.1.2-starlink-1b/astrotcl/press/press.h000066400000000000000000000062511215713201500214350ustar00rootroot00000000000000/*+ ************************************************************************ **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** * * Include File Name: press/h/press.h * * Purpose: * Public header file for the compress routines. * Whatever * * Date : Feb 23, 1993 * * SCCS data : @(#) * Module Name : press.h * Version Number : 1.11 * Release Number : 1 * Last Updated : 07/04/97 * * Programmer : Norman Hill * * Modification History: * 97/06/06 JSD : Changed extern definitions. * 97/07/02 SEC : Mod'ed func prototypes for up-to-ANSI standard. * **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** ************************************************************************ -*/ /* * Status codes. */ #define PR_HCOMP_INFO 2 /* Print h-compress information. */ #define PR_HDECOMP_INFO 1 /* Print h-decompress information. */ #define PR_SUCCESS 0 #define PR_E_BITPLANE (-1) /* Bad bit plane in decoded data. */ #define PR_E_BITS (-2) /* Code size is larger than 16 bits. */ #define PR_E_BLOCK (-3) /* Bad block type in gzip data. */ #define PR_E_CODE (-4) /* Bad code during decode. */ #define PR_E_CRC (-5) /* CRC does not match data. */ #define PR_E_DATA (-6) /* Data had bad format. */ #define PR_E_EOI (-7) /* End of input stream reached. */ #define PR_E_FITS (-8) /* Bad fits header format. */ #define PR_E_FITS_DIM (-9) /* Dimension of image is not 2. */ #define PR_E_FITS_GRP (-10) /* Fits file contains groups. */ #define PR_E_FITS_INC (-11) /* Fits header was incomplete. */ #define PR_E_FITS_TYPE (-12) /* Fits image data type is not INTEGER*2*/ #define PR_E_FORMAT (-13) /* Data has a fromat. */ #define PR_E_INC_LIT (-14) /* Incomplete literal set. */ #define PR_E_IO (-15) /* Error durring io. */ #define PR_E_MAGIC (-16) /* Magic number was not found. */ #define PR_E_MEMORY (-17) /* Memory allocation failure. */ #define PR_E_METHOD (-18) /* Compression method is unknown. */ #define PR_E_NAXIS (-19) /* Image dimensions not in fits header. */ #define PR_E_NO_SAVE (-20) /* Compressed data got larger. */ #define PR_E_SIZE (-21) /* File size is wrong. */ #define PR_E_UNSUPPORT (-22) /* Unsupported compression algorithm. */ /* * Compression types supported. */ #define PR_UNIX "UCMP" #define PR_HCOMP "HCMP" #define PR_ULDA "ULDA" #define PR_GZIP "GZIP" #define PR_NONE "NONE" /* * The following #ifdef makes the interface to C++ cleaner. */ #ifdef __cplusplus extern "C" { #endif /* * Function prototypes and external declarations. */ extern int press_f2f( int, int, char * ); extern int press_f2m( int, byte **, int *, char * ); extern int press_m2f( byte *, int, int, char * ); extern int press_m2m( byte *, int, byte **, int *, char * ); extern int press_setopt( char *, ... ); extern int unpress_f2f( int, int, char * ); extern int unpress_f2m( int, byte **, int *, char * ); extern int unpress_m2f( byte *, int, int, char * ); extern int unpress_m2m( byte *, int, byte **, int *, char * ); extern int unpress_fsize( int, int *, char * ); extern int unpress_msize( byte *, int, int *, char * ); extern char pr_msg[]; /* * Ending the C++ compatibility from above. */ #ifdef __cplusplus } #endif skycat-3.1.2-starlink-1b/astrotcl/press/ulda.c000066400000000000000000000237151215713201500212250ustar00rootroot00000000000000/*+ ************************************************************************ **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** * * Module Name: press/src/ulda.c * * Purpose: * Function to uncompress ulda data into a fits file. * * Routines: * int ulda_uncomp : Function to uncompress ulda data. * * Date : Apr 05, 1993 * * SCCS data : @(#) * Module Name : ulda.c * Version Number : 1.3 * Release Number : 1 * Last Updated : 07/04/97 * * Programmer : Norman Hill * * Modification History: * 97/07/02 SEC : Mod'ed for clean compile. * **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** ************************************************************************ -*/ #include #include #include "gen_types.h" #include "press.h" #include "local_press.h" typedef struct ulda_header { int uh_recno; double uh_lamzer; /* Starting wavelength. */ double uh_lamstp; /* Wavelength step. */ double uh_bscale; /* Scale factor. */ double uh_bzero; /* Scale offset. */ double uh_exp_time; /* Exposure time in seconds. */ long uh_ra; /* Right asscension. */ long uh_dec; /* Declination. */ long uh_numlam; /* Number of data points. */ long uh_num_epsilon; /* Number of encoded epsilon values. */ char uh_dubious[81]; /* Dubious comments. */ char uh_id[17]; /* Homogeneous object id. */ char uh_obs_date[10];/* Observation date. */ char uh_imno[6]; /* Image number. */ char uh_cam[4]; /* Camera id. */ char uh_exp_code[4]; /* Exposure code. */ char uh_ap; /* Aperture id. */ char uh_usage; /* Set to 'U' if the data has been used*/ byte uh_obj_class; /* Object class. */ } ULDA_HEADER; typedef char ULDA_DATA[5]; /*+ ************************************************************************ * * Synopsis: * int ulda_uncomp( char_in, char_out ) * * Purpose: * Uncompresses a ulda spectrum into a fits file. * * Parameters: * int (*char_in)() : (in) Function to read data. * int (*char_out)() : (in) Function to write data. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_IO : Error during io. * int PR_E_MEMORY : Memory allocaiton failure. * ************************************************************************ -*/ int ulda_uncomp ( pfi char_in, pfi char_out ) { ULDA_HEADER header; ULDA_DATA *data; byte line[81]; int line_count; static char *fmt1 = "%-8.8s= %-30.30s/ %-38.38s"; static char *fmt2 = "%-8.8s= %-10d / %-38.38s"; static char *fmt3 = "%-8.8s= %-13.10E / %-38.38s"; static char *fmt4 = "%-8.8s= '%-28.28s'/ %-38.38s"; static char *fmt5 = "%-8.8s= '%c ' / %-38.38s"; int i; int j; byte val; int run_length; byte e_value; int band; short tmp; /* * Read the header part of the data. */ PR_CHECK( char_in( (byte *) &header, 189 ) ); /* * Write the fits header. */ line_count = 0; (void) sprintf( (char *) line, fmt1, "SIMPLE", "T", "Standard FITS format" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt2, "BITPIX", 8, "8 bits per pixel." ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt2, "NAXIS", 0, "" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt1, "EXTEND", "T", "There is a binary table extension." ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt2, "RA", header.uh_ra, "" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt2, "DEC", header.uh_dec, "" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt4, "CAMERA", header.uh_cam, "Camera idenifier" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt1, "IMAGE", header.uh_imno, "Image number" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt5, "APERTURE", header.uh_ap, "Aperture id" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt4, "DISPERSN", "LOW", "Camera idenifier" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt4, "DATE", header.uh_obs_date, "Observation date" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt3, "EXPOSURE", header.uh_exp_time, "Exposure time (sec)" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt4, "EXPCODE", header.uh_exp_code, "Exposure code" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt4, "OBJECT", header.uh_id, "Object id" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt5, "CLASS", header.uh_obj_class, "Aperture id" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; header.uh_dubious[72] = '\0'; (void) sprintf( (char *) line, "COMMENT %-72.72s", header.uh_dubious ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, "%-80.80s", "END" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; /* * Fill in the rest of the header block with spaces. */ (void) memset( line, ' ', 80 ); for ( i = ( line_count - 1 ) % 36 + 1; i < 36; i ++ ) { PR_CHECK( char_out( line, 80 ) ); } /* * Write the extension header. */ line_count = 0; (void) sprintf( (char *) line, fmt1, "XTENSION", "'BINTABLE'", "Binary table extension" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt2, "BITPIX", 8, "8 bits per pixel" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt2, "NAXIS", 2, "" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt2, "NAXIS1", 5, "" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt2, "NAXIS2", header.uh_numlam, "Number of spectral bands" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt2, "PCOUNT", 0, "" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt2, "GCOUNT", 1, "" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt2, "TFIELDS", 3, "" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt1, "TFORM1", "'I '", "Wavelength" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt4, "TTYPE1", "Wavelength", "Wavelength" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt4, "TUNIT1", "Angstroms", "Wavelength" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt3, "TZERO1", header.uh_lamzer, "Starting Wavelength" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt3, "TSCAL1", header.uh_lamstp, "Wavelength increment" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt1, "TFORM2", "'I '", "Flux" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt4, "TTYPE2", "Flux", "Flux" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt3, "TZERO2", header.uh_bzero, "Flux offset" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt3, "TSCAL2", header.uh_bscale, "Flux increment" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt1, "TFORM3", "'B '", "Epsilon" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, fmt4, "TTYPE3", "Epsilon", "Epsilon" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; (void) sprintf( (char *) line, "%-80.80s", "END" ); PR_CHECK( char_out( line, 80 ) ); line_count ++; /* * Fill in the rest of the header block with spaces. */ (void) memset( line, ' ', 80 ); for ( i = ( line_count - 1 ) % 36 + 1; i < 36; i ++ ) { PR_CHECK( char_out( line, 80 ) ); } PR_CHECK_NULL( data = (ULDA_DATA *) gen_alloc( header.uh_numlam * 5 ) ); /* * Write the data to the output. */ for ( tmp = 0; tmp < header.uh_numlam; tmp++ ) { memcpy( data[tmp], &tmp, 2 ); PR_CHECK( char_in( (byte *) data[tmp] + 2, 2 ) ); } /* * Decode the epsilon values. */ for( band = 0, i = 0; i < header.uh_num_epsilon; i++ ) { PR_CHECK( char_in( &val, 1 ) ); run_length = val >> 3; e_value = val & 0x07; for ( j = 0; j < run_length && band < header.uh_numlam ; j ++, band ++ ) { data[band][4] = e_value; } } /* * write the data to the output */ PR_CHECK( char_out( (byte *) data, header.uh_numlam * 5 ) ); gen_free( data ); /* * Fill in the remainder of the last 2880 block with nulls. */ for ( i = ( ( ( header.uh_numlam * 5 ) - 1 ) % 2880 ) + 1 ; i < 2880; i++ ) { PR_CHECK( char_out( "\0", 1 ) ); } return( PR_SUCCESS ); } skycat-3.1.2-starlink-1b/astrotcl/press/undigitize.c000066400000000000000000000004521215713201500224440ustar00rootroot00000000000000/* undigitize.c undigitize H-transform * * Programmer: R. White Date: 9 May 1991 */ #include extern void undigitize(a,nx,ny,scale) int a[]; int nx,ny; int scale; { int *p; /* * multiply by scale */ if (scale <= 1) return; for (p=a; p <= &a[nx*ny-1]; p++) *p = (*p)*scale; } skycat-3.1.2-starlink-1b/astrotcl/press/ux_press.c000066400000000000000000000344321215713201500221460ustar00rootroot00000000000000/*+ ************************************************************************ **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** * * Module Name: press/src/ux_press.c * * Purpose: * Contains routines to do compression and decompression using the * unix compress algorithm. These routines are taken from * version 4.1 of the compress program. * * Routines: * int ux_comp : Compresses using teh unix compress * algorithm. * int ux_uncomp : Uncompress using the unix compress * algorithm. * * Date : Feb 26, 1993 * * SCCS data : @(#) * Module Name : ux_press.c * Version Number : 1.4 * Release Number : 1 * Last Updated : 07/04/97 * * Programmer : Norman Hill * Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas) * Jim McKie (decvax!mcvax!jim) * Steve Davies (decvax!vax135!petsd!peora!srd) * Ken Turkowski (decvax!decwrl!turtlevax!ken) * James A. Woods (decvax!ihnp4!ames!jaw) * Joe Orost (decvax!vax135!petsd!joe) * Dave Mack (csu@alembic.acs.com) * * Modification History: * 97/07/02 SEC : Bring up to ANSI standard. * **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** ************************************************************************ -*/ #include #include #include "gen_types.h" #include "press.h" #include "local_press.h" #include "ux_press.h" static long bytes_out; static int (*g_char_in)(); static int (*g_char_out)(); static count_int checkpoint; static int clear_flg; static unsigned short codetab [HSIZE]; static code_int free_ent; /* First unused entry. */ static count_int htab [HSIZE]; static long in_count; static byte lmask[9] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00}; static byte magic_header[] = { "\037\235" }; /* 1F 9D */ static int maxbits; static code_int maxcode; static code_int maxmaxcode; static int n_bits; static int offset; static long out_count; static int r_off; static int ratio; static byte rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; /* * Static function prototypes. */ static int cl_block( void ); static int cl_hash( count_int ); static code_int getcode( void ); static int output( code_int ); /*+ ************************************************************************ * * Synopsis: * static int cl_block( void ) * * Purpose: * * Parameters: * void * * Values Returned: * int PR_SUCCESS : Normal completion. * ************************************************************************ -*/ static int cl_block ( void ) { long rat; checkpoint = in_count + CHECK_GAP; if(in_count > 0x007fffff) { /* * shift will overflow */ rat = bytes_out >> 8; if(rat == 0) { /* * Don't divide by zero */ rat = 0x7fffffff; } else { rat = in_count / rat; } } else { rat = (in_count << 8) / bytes_out; /* 8 fractional bits */ } if ( rat > ratio ) { ratio = rat; } else { ratio = 0; cl_hash( (count_int) HSIZE ); free_ent = FIRST; clear_flg = 1; PR_CHECK( output( (code_int) CLEAR ) ); } return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * static int cl_hash( hsize ) * * Purpose: * Clears the hash table. * * Parameters: * count_int hsize : (in) The size of the hash table. * * Values Returned: * int PR_SUCCESS : Normal completion. * ************************************************************************ -*/ static int cl_hash ( count_int hsize ) { memset( htab, (byte) 0xff, hsize * sizeof( count_int ) ); return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * static code_int getcode() * * Purpose: * Gets the next code from the input stream. * * Parameters: * int (*char_in)() : (in) Function to get the next character * from the input stream. * * Values Returned: * int code : Next code in the input stream. * int PR_E_EOI : End of input detected. * ************************************************************************ -*/ static code_int getcode ( void ) { byte *bp; int bits; static byte buf[BITS]; code_int code; static int offset = 0; static int size = 0; bp = buf; if ( clear_flg > 0 || offset >= size || free_ent > maxcode ) { /* * If the next entry will be too big for the current code * size, then we must increase the size. This implies reading * a new buffer full, too. */ if ( free_ent > maxcode ) { n_bits++; if ( n_bits == maxbits ) { maxcode = maxmaxcode; /* won't get any bigger now */ } else { maxcode = MAXCODE(n_bits); } } if ( clear_flg > 0) { maxcode = MAXCODE (n_bits = INIT_BITS); clear_flg = 0; } offset = 0; if ( ( size = g_char_in( buf, n_bits ) ) <= 0 ) { size = 0; return( PR_E_EOI ); } /* Round size down to integral number of codes */ size = (size << 3) - (n_bits - 1); } r_off = offset; bits = n_bits; /* * Get to the first byte. */ bp += (r_off >> 3); r_off &= 7; /* * Get first part (low order bits) */ code = (*bp++ >> r_off); bits -= (8 - r_off); r_off = 8 - r_off; /* now, offset into code word */ /* * Get any 8 bit parts in the middle (<=1 for up to 16 bits). */ if ( bits >= 8 ) { code |= *bp++ << r_off; r_off += 8; bits -= 8; } /* * high order bits. */ code |= (*bp & rmask[bits]) << r_off; offset += n_bits; return( code ); } /*+ ************************************************************************ * * Synopsis: * int output( code ) * * Purpose: * outputs a code. * * Parameters: * code_int code : (in) Code to output. * * Values Returned: * int PR_SUCCESS : Normal completion. * ************************************************************************ -*/ int output ( code_int code ) { int bits; byte *bp; static byte buf[BITS]; int r_off; bp = buf; bits = n_bits; r_off = offset; if ( code >= 0 ) { /* * Get to the first byte. */ bp += (r_off >> 3); r_off &= 7; /* * Since code is always >= 8 bits, only need to mask the first * hunk on the left. */ *bp = ( *bp & rmask[ r_off ] ) | ( code << r_off ) & lmask[ r_off ]; bp++; bits -= ( 8 - r_off ); code >>= 8 - r_off; /* * Get any 8 bit parts in the middle (<=1 for up to 16 bits). */ if ( bits >= 8 ) { *bp++ = code; code >>= 8; bits -= 8; } /* * Last bits. */ if(bits) { *bp = code; } offset += n_bits; if ( offset == ( n_bits << 3 ) ) { bp = buf; bits = n_bits; bytes_out += bits; PR_CHECK( g_char_out( bp, bits ) ); bits = 0; offset = 0; } /* * If the next entry is going to be too big for the code size, * then increase it, if possible. */ if ( free_ent > maxcode || ( clear_flg > 0 ) ) { /* * Write the whole buffer, because the input side won't * discover the size increase until after it has read it. */ if ( offset > 0 ) { PR_CHECK( g_char_out( buf, n_bits ) ); } offset = 0; if ( clear_flg ) { maxcode = MAXCODE( n_bits = INIT_BITS ); clear_flg = 0; } else { n_bits++; if ( n_bits == maxbits ) { maxcode = maxmaxcode; } else { maxcode = MAXCODE( n_bits ); } } } } else { /* * At EOF, write the rest of the buffer. */ if ( offset > 0 ) { PR_CHECK( g_char_out( buf, (offset + 7) / 8 ) ); } bytes_out += (offset + 7) / 8; offset = 0; } return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * int ux_comp( char_in, char_out ) * * Purpose: * Compresses data using the unix compress algorithm. * Algorithm: use open addressing double hashing (no chaining) on the * prefix code / next character combination. We do a variant of Knuth's * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime * secondary probe. Here, the modular division first probe is gives way * to a faster exclusive-or manipulation. Also do block compression with * an adaptive reset, whereby the code table is cleared when the compression * ratio decreases, but after the table fills. The variable-length output * codes are re-sized at this point, and a special CLEAR code is generated * for the decompressor. Late addition: construct the table according to * file size for noticeable speed improvement on small files. Please direct * questions about this implementation to ames!jaw. * * Parameters: * int (*char_in)() : (in) Function to get the next input * character. * int (*char_out)() : (in) Function to write the next output * character. * * Values Returned: * int PR_SUCCESS : Normal completion. * ************************************************************************ -*/ int ux_comp ( pfi char_in, pfi char_out ) { int block_compress; int c; byte chr; int disp; code_int ent; long fcode; int hshift; code_int i = 0; g_char_in = char_in; g_char_out = char_out; /* * write the magic number. */ PR_CHECK( char_out( magic_header, 2 ) ); block_compress = BLOCK_MASK; chr = (byte) ( BITS | BLOCK_MASK ); PR_CHECK( char_out( &chr, 1 ) ); offset = 0; bytes_out = 3; /* includes 3-byte header mojo */ out_count = 0; clear_flg = 0; ratio = 0; in_count = 1; maxbits = BITS; maxmaxcode = 1 << maxbits; checkpoint = CHECK_GAP; maxcode = MAXCODE( n_bits = INIT_BITS ); free_ent = ( ( block_compress ) ? FIRST : 256 ); PR_CHECK( char_in( &chr, 1 ) ); ent = (code_int) chr; hshift = 0; for ( fcode = (long) HSIZE; fcode < 65536L; fcode *= 2L ) { hshift++; } /* * set hash code range bound */ hshift = 8 - hshift; /* * clear hash table. */ cl_hash( (count_int) HSIZE); while ( char_in( &chr, 1 ) == 1 ) { c = (int) chr; in_count++; fcode = (long) ( ( (long) c << maxbits) + ent); i = ( ( c << hshift ) ^ ent ); /* xor hashing */ if ( htabof( i ) == fcode ) { ent = codetabof( i ); continue; } else if ( (long)htabof( i ) < 0 ) /* empty slot */ { goto nomatch; } disp = HSIZE - i; /* secondary hash (after G. Knott) */ if ( i == 0 ) { disp = 1; } probe: if ( (i -= disp) < 0 ) { i += HSIZE; } if ( htabof( i ) == fcode ) { ent = codetabof( i ); continue; } if ( (long)htabof( i ) > 0 ) { goto probe; } nomatch: PR_CHECK( output( ent ) ); out_count++; ent = c; if ( free_ent < maxmaxcode ) { codetabof( i ) = free_ent++; /* code -> hashtable */ htabof( i ) = fcode; } else if ( (count_int)in_count >= checkpoint && block_compress ) { cl_block(); } } /* * Put out the final code. */ PR_CHECK( output( ent ) ); out_count++; PR_CHECK( output( -1 ) ); return( PR_SUCCESS ); } /*+ ************************************************************************ * * Synopsis: * int ux_uncomp( char_in, char_out ) * * Purpose: * Decompresses a memory buffer into a second buffer. * Statement of purpose. * * Parameters: * int (*char_in)() : (in) Function to get a compressed char. * int (*char_out)() : (in) Function to put an uncompressed char. * * Values Returned: * int PR_SUCCESS : Normal completion. * int PR_E_BITS : More bits than can be handled. * int PR_E_MAGIC : Incorrect magic number. * * References: * Compress compresses files using a heavily modified version of the * LZW algorithm as described in IEEE Computer, June 1984. * ************************************************************************ -*/ int ux_uncomp ( pfi char_in, pfi char_out ) { int block_compress; byte buffer[2]; byte chr; code_int code; int finchar; code_int incode; code_int oldcode; /* The previous code. */ byte *stackp; g_char_in = char_in; g_char_out = char_out; free_ent = 0; /* * Check to see if the magic number is correct. */ if ( char_in( buffer, 2 ) != 2 || memcmp( magic_header, buffer, 2 ) != 0 ) { pr_format_message( PR_E_MAGIC ); return( PR_E_MAGIC ); } PR_CHECK( char_in( buffer, 1 ) ); maxbits = (int) buffer[0]; block_compress = maxbits & BLOCK_MASK; maxbits &= BIT_MASK; maxmaxcode = 1 << maxbits; if ( maxbits > BITS ) { pr_format_message( PR_E_BITS, BITS ); return( PR_E_BITS ); } /* * As above, initialize the first 256 entries in the table. */ maxcode = MAXCODE(n_bits = INIT_BITS); for ( code = 255; code >= 0; code-- ) { tab_prefixof(code) = 0; tab_suffixof(code) = (byte)code; } free_ent = ((block_compress) ? FIRST : 256 ); finchar = oldcode = getcode(); /* * Check for EOF. */ if( oldcode == PR_E_EOI ) { return( PR_SUCCESS ); } /* * Write the first character. */ chr = (byte) finchar; PR_CHECK( char_out( &chr, 1 ) ); stackp = de_stack; while ( ( code = getcode() ) > -1 ) { if ( ( code == CLEAR ) && block_compress ) { for ( code = 255; code >= 0; code-- ) { tab_prefixof( code ) = 0; } clear_flg = 1; free_ent = FIRST - 1; if ( ( code = getcode () ) == PR_E_EOI ) { /* * O, untimely death! */ break; } } incode = code; /* * Special case for KwKwK string. */ if ( code >= free_ent ) { *stackp++ = finchar; code = oldcode; } /* * Generate output characters in reverse order */ while ( code >= 256 ) { *stackp++ = tab_suffixof(code); code = tab_prefixof(code); } *stackp++ = finchar = tab_suffixof(code); /* * And put them out in forward order */ do { PR_CHECK( char_out ( --stackp, 1 ) ); } while ( stackp > de_stack ); /* * Generate the new entry. */ if ( ( code=free_ent ) < maxmaxcode ) { tab_prefixof( code ) = (unsigned short) oldcode; tab_suffixof( code) = finchar; free_ent = code+1; } /* * Remember previous code. */ oldcode = incode; } return( PR_SUCCESS ); } skycat-3.1.2-starlink-1b/astrotcl/press/ux_press.h000066400000000000000000000035321215713201500221500ustar00rootroot00000000000000/*+ ************************************************************************ **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** * * Include File Name: press/h/ux_press.h * * Purpose: * Private header for the unix compress routines. * * Date : Feb 23, 1993 * * SCCS data : @(#) * Module Name : ux_press.h * Version Number : 1.1 * Release Number : 1 * Last Updated : 03/01/93 * * Programmer : Norman Hill * * Modification History: * **** C A N A D I A N A S T R O N O M Y D A T A C E N T R E ***** ************************************************************************ -*/ #include typedef int code_int; typedef long int count_int; /* * Define the bits for the third byte in the header. */ #define BLOCK_MASK 0x80 #define BIT_MASK 0x1f #define CHECK_GAP 50000 /* * the next two codes should not be changed lightly, as they must not * lie within the contiguous general code space. */ #define FIRST 257 /* first free entry */ #define CLEAR 256 /* table clear output code */ #define BITS 16 /* Maximum number of bits. */ #define INIT_BITS 9 /* Initial number of bits/code. */ #define HSIZE 69001 /* Hash table size. */ #define htabof(i) htab[i] #define codetabof(i) codetab[i] /* * To save much memory, we overlay the table used by compress() with those * used by decompress(). The tab_prefix table is the same size and type * as the codetab. The tab_suffix table needs 2**BITS characters. We * get this from the beginning of htab. The output stack uses the rest * of htab, and contains characters. There is plenty of room for any * possible stack (stack used to be 8000 characters). */ #define tab_prefixof(i) codetabof(i) #define tab_suffixof(i) ((byte *)(htab))[i] #define de_stack ((byte *)&tab_suffixof(1< #include #include #include "error.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" #include "Mem.h" #include "DCompress.h" #define TTEST(x) {if (!(x)){printf("%s: line %d: Test failed\n", __FILE__, __LINE__); exit(1);}} #ifdef TIME_TESTS #define TEST(x) TIMECALL("x", TTEST(x)) #else #define TEST(x) TTEST(x) #endif main() { char buf[3*1024]; // errors will be printed on stderr automatically set_error_handler(print_error); // compress and decompress the FITS file "test.fits" Compress c; // compress/decompress H_COMPRESS printf("compressing test.fits (H_COMPRESS):\n"); TEST(c.compress("test.fits", "test.fits.hfits", Compress::H_COMPRESS) == 0); printf("decompressing (H_COMPRESS):\n"); TEST(c.decompress("test.fits.hfits", "test.fits.h_decompress", Compress::H_COMPRESS) == 0); // compress/decompress GZIP printf("compressing test.fits (GZIP):\n"); TEST(c.compress("test.fits", "test.fits.gzfits", Compress::GZIP_COMPRESS) == 0); printf("decompressing (GZIP):\n"); TEST(c.decompress("test.fits.gzfits", "test.fits.gzip_decompress", Compress::GZIP_COMPRESS) == 0); printf("comparing results (GZIP):\n"); sprintf(buf, "cmp %s %s", "test.fits", "test.fits.gzip_decompress"); TEST(system(buf) == 0); // compress/decompress UNIX printf("compressing test.fits (UNIX):\n"); TEST(c.compress("test.fits", "test.fits.cfits", Compress::UNIX_COMPRESS) == 0); printf("decompressing (UNIX):\n"); TEST(c.decompress("test.fits.cfits", "test.fits.unix_decompress", Compress::UNIX_COMPRESS) == 0); printf("comparing results (UNIX):\n"); sprintf(buf, "cmp %s %s", "test.fits", "test.fits.unix_decompress"); TEST(system(buf) == 0); #if 0 // memory compress/decompress printf("\ntesting compression of memory (using mmap of FITS file):\n"); Mem m("test.fits"); char* inbuf = (char*)m.ptr(); char* outbuf; int inbufsz = m.size(), outbufsz = m.size()/3; int i; printf("compressing test.fits in memory (GZIP):\n"); TEST(c.compress(inbuf, inbufsz, outbuf, outbufsz, Compress::GZIP_COMPRESS) == 0); printf("decompressing (GZIP) in memory:\n"); TEST(c.decompress(outbuf, outbufsz, inbuf, inbufsz, Compress::GZIP_COMPRESS) == 0); if (inbufsz < m.size()) { printf("decompressed size (%s) does not match expected (%d)\n", inbufsz, m.size()); exit(1); } if ((i = memcmp(inbuf, (char*)m.ptr(), m.size())) != 0) { printf("memcmp of results with original returned %d\n", i); exit(1); } outbufsz = m.size()/2; printf("compressing test.fits in memory (UNIX):\n"); TEST(c.compress(inbuf, inbufsz, outbuf, outbufsz, Compress::UNIX_COMPRESS) == 0); printf("decompressing (UNIX) in memory:\n"); TEST(c.decompress(outbuf, outbufsz, inbuf, inbufsz, Compress::UNIX_COMPRESS) == 0); if (inbufsz < m.size()) { printf("decompressed size (%s) does not match expected (%d)\n", inbufsz, m.size()); exit(1); } if ((i = memcmp(inbuf, (char*)m.ptr(), m.size())) != 0) { printf("memcmp of results with original returned %d\n", i); exit(1); } #endif printf("All tests passed\n"); return(0); } skycat-3.1.2-starlink-1b/astrotcl/tests/tCompress.ok000066400000000000000000000003551215713201500224470ustar00rootroot00000000000000compressing test.fits (H_COMPRESS): decompressing (H_COMPRESS): compressing test.fits (GZIP): decompressing (GZIP): comparing results (GZIP): compressing test.fits (UNIX): decompressing (UNIX): comparing results (UNIX): All tests passed skycat-3.1.2-starlink-1b/astrotcl/tests/tFitsIO.C000066400000000000000000000114751215713201500215670ustar00rootroot00000000000000/* * E.S.O. - VLT project * $Id: tFitsIO.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ * * tFitsIO.C - test cases for class FitsIO * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 08 Oct 97 Created */ #include #include #include #include #include "error.h" #include "Fits_IO.h" #define TEST(x) {if (!(x)){printf("%s: line %d: Test failed\n", __FILE__, __LINE__); exit(1) ;}} main(int argc, char** argv) { // errors will be printed on stderr automatically set_error_handler(print_error); // default test file is test.fits, or the first cmd line argument char* filename = "test.fits"; if (argc > 1) filename = argv[1]; char cmd[1024]; sprintf(cmd, "cp %s tmp.fits", filename); if (system(cmd) != 0) return fmt_error("error copying %s to tmp.fits", filename); if (system("chmod 777 tmp.fits") != 0) return error("error changing perms on tmp.fits"); FitsIO* fits = FitsIO::read("tmp.fits", Mem::FILE_RDWR); if (! fits) return error("error reading tmp.fits"); // test reading a normal FITS keyword double d; TEST(fits->get("BSCALE", d) == 0); TEST(d == 1.0); // yesy reading it as a string char* bscaleStr = fits->get("BSCALE"); TEST(bscaleStr && sscanf(bscaleStr, "%lf", &d) == 1.0); // test modifying a normal FITS keyword TEST(fits->put("BSCALE", 2.0) == 0); TEST(fits->get("BSCALE", d) == 0); TEST(d == 2.0); // test inserting a normal FITS keyword TEST(fits->put("ARCFILE", "TS1.1998-03-19T01:17:23.199.fits", "Archive File Name") == 0); // test reading an ESO extended FITS keyword char* p = fits->get("HIERARCH ESO DET CHIP1 ID"); TEST(p != NULL); TEST(strcmp(p, "TK2048EB4-1 1604") == 0); // test modifying an ESO extended FITS keyword TEST (fits->put("HIERARCH ESO DET CHIP1 ID", "CHANGED") == 0); p = fits->get("HIERARCH ESO DET CHIP1 ID"); TEST(p != NULL); TEST(strcmp(p, "CHANGED") == 0); // test inserting keywords and extending the file size char keyword[80], comment[80]; for (int i = 0; i < 244; i++) { sprintf(keyword, "TEST_%d", i); sprintf(comment, "test insert of keyword %d", i); if (fits->put(keyword, i, comment) != 0) return error("error inserting keyword: ", keyword); } delete fits; fits = FitsIO::read("tmp.fits", Mem::FILE_RDWR); if (! fits) return error("error re-reading tmp.fits after iniserting keywords"); long rows = 0; int cols = 0; #if 0 // test HDU/Table access TEST(fits->getNumHDUs() == 2); TEST(fits->setHDU(2) == 0); TEST(strcmp(fits->getHDUType(), "binary") == 0); TEST(fits->getTableDims(rows, cols) == 0); TEST(rows == 100); TEST(cols == 3); for(int i = 1; i <= rows; i++) { for(int j = 1; j <= cols; j++) { char* p = fits->getTableValue(i, j); TEST(p != NULL); printf("table(%d,%d) == %s\n", i, j, p); } } #endif #if 0 // test FITS table creation rows = 4; cols = 3; static char* tform[] = {"1J", "32A", "1D"}; static char* headings[] = {"int", "string", "double"}; TEST(fits->createTable("TESTTAB", rows, cols, headings, tform) == 0); TEST(fits->setTableValue(1, 1, "25") == 0); TEST(fits->setTableValue(1, 2, "hello") == 0); TEST(fits->setTableValue(1, 3, "3.14") == 0); TEST(fits->setTableValue(2, 1, "50") == 0); TEST(fits->setTableValue(2, 2, "good bye") == 0); TEST(fits->setTableValue(2, 3, "1.58") == 0); TEST(fits->setTableValue(3, 1, "75") == 0); TEST(fits->setTableValue(3, 2, "test test test test") == 0); TEST(fits->setTableValue(3, 3, "-0.0001") == 0); TEST(fits->setTableValue(4, 1, "100") == 0); TEST(fits->setTableValue(4, 2, "passed") == 0); TEST(fits->setTableValue(4, 3, "0.0001") == 0); #endif delete fits; #if 0 // ----------------------------------------------------------- // See what happens if you try to insert keywords in a decompressed // file (should fail eventually, since using a temp file and can't // increase the size after it is unlinked). if (system("gzip < test.fits > tmp.fits.gz") != 0) return error("error compressing test.fits to tmp.fits.gz"); fits = FitsIO::read("tmp.fits.gz", Mem::FILE_RDWR); if (! fits) return error("error reading tmp.fits.gz"); for (int i = 0; i < 256; i++) { sprintf(keyword, "TEST_%d", i); sprintf(value, "%d", i); sprintf(comment, "test insert of keyword %d", i); if (fits->put(keyword, value, comment) != 0) { error("error inserting keyword in decompressed file (as expected): ", keyword); break; } } delete fits; // ----------------------------------------------------------- #endif printf("All tests passed\n"); // unlink("tmp.fits"); return 0; } skycat-3.1.2-starlink-1b/astrotcl/tests/tFitsIO.ok000066400000000000000000000000211215713201500217770ustar00rootroot00000000000000All tests passed skycat-3.1.2-starlink-1b/astrotcl/tests/tHMS.C000066400000000000000000000041021215713201500210460ustar00rootroot00000000000000/* * E.S.O. - VLT project * $Id: tHMS.C,v 1.1.1.1 2009/03/31 14:11:53 cguirao Exp $ * * tHMS.C - test cases for class HMS * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 95 Created * pbiereic 17/02/03 Added 'using namespace std'. Removed ::std specs. */ using namespace std; #include #include #include #include #include "error.h" #include "HMS.h" main() { // errors will be printed on stderr automatically set_error_handler(print_error); //cout << setprecision(17); cout << "test 1" << endl; HMS h(3, 19, 48.23); cout << h << " HMS = " << h.val()*15 << " = " << HMS(h.val()) << endl; if (h != HMS(h.val())) cout << "Equality test failed: " << h << " != " << HMS(h.val()) << endl; h = HMS(41, 30, 42.2); cout << h << " DMS = " << h.val() << " = " << HMS(h.val()) << endl; h = HMS(-41, 30, 42.2); cout << h << " DMS = " << h.val() << " = " << HMS(h.val()) << endl; h = HMS(-0, 15, 33.3333); cout << h << " DMS = " << h.val() << " = " << HMS(h.val()) << endl; h = HMS(-0.0001); cout << h << " DMS = " << h.val() << " = " << HMS(h.val()) << endl; cout << "\ntest 2" << endl; h = HMS(121.39583332/15.); cout << h << " HMS = " << h.val()*15 << " = " << HMS(h.val()) << endl; cout << "\ntest 3" << endl; h = HMS(121.09583332/15.); cout << h << " HMS = " << h.val()*15 << " = " << HMS(h.val()) << endl; cout << "\ntest 4" << endl; h = HMS(-121.39583332/15.); cout << h << " HMS = " << h.val()*15 << " = " << HMS(h.val()) << endl; cout << "\ntest 5" << endl; h = HMS(-121.09583332/15.); cout << h << " HMS = " << h.val()*15 << " = " << HMS(h.val()) << endl; cout << "\ntest 6" << endl; h = HMS("-08:05:35"); cout << h << " HMS = " << h.val()*15 << " = " << HMS(h.val()) << endl; cout << "\ntest 7" << endl; h = HMS("-08:04:23"); cout << h << " HMS = " << h.val()*15 << " = " << HMS(h.val()) << endl; return(0); } skycat-3.1.2-starlink-1b/astrotcl/tests/tHMS.ok000066400000000000000000000010261215713201500212770ustar00rootroot00000000000000test 1 03:19:48.230 HMS = 49.951 = 03:19:48.230 41:30:42.200 DMS = 41.5117 = 41:30:42.200 -41:30:42.200 DMS = -41.5117 = -41:30:42.200 00:15:33.333 DMS = 0.259259 = 00:15:33.333 -00:00:00.360 DMS = -0.0001 = -00:00:00.360 test 2 08:05:35.000 HMS = 121.396 = 08:05:35.000 test 3 08:04:23.000 HMS = 121.096 = 08:04:23.000 test 4 -08:05:35.000 HMS = -121.396 = -08:05:35.000 test 5 -08:04:23.000 HMS = -121.096 = -08:04:23.000 test 6 -08:05:35.000 HMS = -121.396 = -08:05:35.000 test 7 -08:04:23.000 HMS = -121.096 = -08:04:23.000 skycat-3.1.2-starlink-1b/astrotcl/tests/tHMS.result000066400000000000000000000010261215713201500222040ustar00rootroot00000000000000test 1 03:19:48.230 HMS = 49.951 = 03:19:48.230 41:30:42.200 DMS = 41.5117 = 41:30:42.200 -41:30:42.200 DMS = -41.5117 = -41:30:42.200 00:15:33.333 DMS = 0.259259 = 00:15:33.333 -00:00:00.360 DMS = -0.0001 = -00:00:00.360 test 2 08:05:35.000 HMS = 121.396 = 08:05:35.000 test 3 08:04:23.000 HMS = 121.096 = 08:04:23.000 test 4 -08:05:35.000 HMS = -121.396 = -08:05:35.000 test 5 -08:04:23.000 HMS = -121.096 = -08:04:23.000 test 6 -08:05:35.000 HMS = -121.396 = -08:05:35.000 test 7 -08:04:23.000 HMS = -121.096 = -08:04:23.000 skycat-3.1.2-starlink-1b/astrotcl/tests/tImageCoords.C000066400000000000000000000020151215713201500226140ustar00rootroot00000000000000/* * E.S.O. - VLT project * $Id: tImageCoords.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * tImageCoords.C - test cases for class ImageCoords * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 97 Created * pbiereic 17/02/03 Added 'using namespace std'. Removed ::std specs. */ using namespace std; #include #include #include #include "error.h" #include "ImageCoords.h" main() { // errors will be printed on stderr automatically set_error_handler(print_error); ImageCoords c1(123.456, 654.321); ImageCoords c2("123.456.", "654.321."); cout << "these coords should be the same (or very close):" << endl << c1 << endl << c2 << endl; // test the "box" method (get 2 points given a radius) ImageCoords c3(100., 200.), c4, c5; c3.box(10., c4, c5); cout << "\nbox of radius 10 with center at (100, 200) ==> (" << c4 << "), (" << c5 << ")\n"; return(0); } skycat-3.1.2-starlink-1b/astrotcl/tests/tImageCoords.ok000066400000000000000000000002461215713201500230470ustar00rootroot00000000000000these coords should be the same (or very close): 123.456 654.321 123.456 654.321 box of radius 10 with center at (100, 200) ==> (92.9289 192.929), (107.071 207.071) skycat-3.1.2-starlink-1b/astrotcl/tests/tWorldCoords.C000066400000000000000000000066361215713201500226760ustar00rootroot00000000000000/* * E.S.O. - VLT project * $Id: tWorldCoords.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * tWorldCoords.C - test cases for class WorldCoords * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 95 Created * pbiereic 17/02/03 Added 'using namespace std'. Removed ::std specs. */ using namespace std; #include #include #include #include "error.h" #include "WorldCoords.h" main() { // errors will be printed on stderr automatically set_error_handler(print_error); WorldCoords c1(49.95096, 41.51173); WorldCoords c2(3, 19, 48.2304, 41, 30, 42.228); WorldCoords c3(HMS(3, 19, 48.2304), HMS(41, 30, 42.228)); WorldCoords c4(HMS(c1.ra()), HMS(c1.dec())); WorldCoords c5("3 19 48.2304", "+41 30 42.228", 2000.0); WorldCoords c6("3:19:48.2304", "+41:30:42.228", 2000.0); char buf[80]; sprintf(buf, "%f", 49.95096/15); WorldCoords c7(buf, "41.51173", 2000.0); cout << "these coords should all be the same (or very close):" << endl << c1 << endl << c2 << endl << c3 << endl << c4 << endl << c5 << endl << c6 << endl << c7 << endl; c1 = WorldCoords(49.95096, -41.51173); c2 = WorldCoords(3, 19, 48.2304, -41, 30, 42.228); c3 = WorldCoords(HMS(3, 19, 48.2304), HMS(-41, 30, 42.228)); c4 = WorldCoords(HMS(c1.ra()), HMS(c1.dec())); c5 = WorldCoords("3 19 48.2304", "-41 30 42.228", 2000.0); c6 = WorldCoords("3:19:48.2304", "-41:30:42.228", 2000.0); c7 = WorldCoords(buf, "-41.51173", 2000.0); cout << "Here is the same with negative dec:" << endl << c1 << endl << c2 << endl << c3 << endl << c4 << endl << c5 << endl << c6 << endl << c7 << endl; WorldCoords c8("3:19", "+41:30", 2000.0); WorldCoords c9("3", "+41", 2000.0); cout << "And with missing minutes, ... seconds, ..." << endl << c8 << endl << c9 << endl; // test the "box" method (get 2 points given a radius) WorldCoords c10("03:19:48.243", "+41:30:40.31"), c11, c12; c10.box(7.05, c11, c12); cout << "\nbox of radius 7.05 with center at (03:19:48.243, +41:30:40.31) ==> (" << c11 << "), (" << c12 << ")\n"; // test values at or near 0,0 WorldCoords c13("0", "+41:30:40.31"); cout << "\nWith ra = 0.0: " << c13 << ", vals = " << c13.ra().val() << ", " << c13.dec().val() << endl; WorldCoords c14("0.0", "-0.0"); cout << "\nWith ra = 0.0, dec = -0.0: " << c14 << ", vals = " << c14.ra().val() << ", " << c14.dec().val() << endl; WorldCoords c15("0:0:1", "-0:1:1"); cout << "\nWith ra = 0:0:1, dec = -0:1:1: " << c15 << ", vals = " << c15.ra().val() << ", " << c15.dec().val() << endl; // test conversion between h:m:s and deg and back WorldCoords c16("22:45:22.74", "-39:34:14.63"); cout << "\ntest conversion between h:m:s and deg and back\n"; cout << "22:45:22.74 -39:34:14.63 == " << c16 << endl; char ra_buf[80], dec_buf[80]; c16.print(ra_buf, dec_buf, 2000., 0); cout << " == " << ra_buf << " " << dec_buf << endl; double ra = atof(ra_buf), dec = atof(dec_buf); WorldCoords c17(ra, dec); cout << " == " << c17 << endl; // test reported problem when using equinox J2000.0 (with extra ".0") cout << "\ntest use of equinox J2000.0 (with extra .0)\n"; WorldCoords c18("22:45:22.74", "-39:34:14.63", "J2000.0"); cout << " == " << c18 << endl; return(0); } skycat-3.1.2-starlink-1b/astrotcl/tests/tWorldCoords.ok000066400000000000000000000021661215713201500231170ustar00rootroot00000000000000these coords should all be the same (or very close): 03:19:48.230 +41:30:42.23 03:19:48.230 +41:30:42.23 03:19:48.230 +41:30:42.23 03:19:48.230 +41:30:42.23 03:19:48.230 +41:30:42.23 03:19:48.230 +41:30:42.23 03:19:48.230 +41:30:42.23 Here is the same with negative dec: 03:19:48.230 -41:30:42.23 03:19:48.230 -41:30:42.23 03:19:48.230 -41:30:42.23 03:19:48.230 -41:30:42.23 03:19:48.230 -41:30:42.23 03:19:48.230 -41:30:42.23 03:19:48.230 -41:30:42.23 And with missing minutes, ... seconds, ... 03:19:00.000 +41:30:00.00 03:00:00.000 +41:00:00.00 box of radius 7.05 with center at (03:19:48.243, +41:30:40.31) ==> (03:19:21.648 +41:25:41.20), (03:20:14.838 +41:35:39.42) With ra = 0.0: 00:00:00.000 +41:30:40.31, vals = 0, 41.5112 With ra = 0.0, dec = -0.0: 00:00:00.000 -00:00:00.00, vals = 0, -0 With ra = 0:0:1, dec = -0:1:1: 00:00:01.000 -00:01:01.00, vals = 0.000277778, -0.0169444 test conversion between h:m:s and deg and back 22:45:22.74 -39:34:14.63 == 22:45:22.740 -39:34:14.63 == 341.34474999999998 -39.570730555555556 == 22:45:22.740 -39:34:14.63 test use of equinox J2000.0 (with extra .0) == 22:45:22.740 -39:34:14.63 skycat-3.1.2-starlink-1b/astrotcl/tests/tWorldOrImageCoords.C000066400000000000000000000101161215713201500241260ustar00rootroot00000000000000/* * E.S.O. - VLT project * $Id: tWorldOrImageCoords.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * tWorldOrImageCoords.C - test cases for class WorldOrImageCoords * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 97 Created * pbiereic 17/02/03 Added 'using namespace std'. Removed ::std specs. */ using namespace std; #include #include #include #include "error.h" #include "WorldOrImageCoords.h" // test automatic conversion static void print_coords(const ImageCoords& ic, const WorldCoords& wc) { cout << "\nconversion test: image coords: " << ic << ", world coords: " << wc << endl; } main() { // errors will be printed on stderr automatically set_error_handler(print_error); // test image coords WorldOrImageCoords ic1(ImageCoords(123.456, 654.321)); WorldOrImageCoords ic2(ImageCoords("123.456.", "654.321.")); cout << "these coords should be the same (or very close):" << endl << ic1 << endl << ic2 << endl; // test the "box" method (get 2 points given a radius) WorldOrImageCoords ic3(ImageCoords(100., 200.)), ic4, ic5; ic3.box(10., ic4, ic5); cout << "\nbox of radius 10 with center at (100, 200) ==> (" << ic4 << "), (" << ic5 << ")\n"; // test world coords WorldOrImageCoords c1(WorldCoords(49.95096, 41.51173)); WorldOrImageCoords c2(WorldCoords(3, 19, 48.2304, 41, 30, 42.228)); WorldOrImageCoords c3(WorldCoords(HMS(3, 19, 48.2304), HMS(41, 30, 42.228))); WorldOrImageCoords c4(WorldCoords(HMS(c1.ra()), HMS(c1.dec()))); WorldOrImageCoords c5(WorldCoords("3 19 48.2304", "+41 30 42.228", 2000.0)); WorldOrImageCoords c6(WorldCoords("3:19:48.2304", "+41:30:42.228", 2000.0)); char buf[80]; sprintf(buf, "%f", 49.95096/15); WorldOrImageCoords c7(WorldCoords(buf, "41.51173", 2000.0)); cout << "these coords should all be the same (or very close):" << endl << c1 << endl << c2 << endl << c3 << endl << c4 << endl << c5 << endl << c6 << endl << c7 << endl; c1 = WorldOrImageCoords(WorldCoords(49.95096, -41.51173)); c2 = WorldOrImageCoords(WorldCoords(3, 19, 48.2304, -41, 30, 42.228)); c3 = WorldOrImageCoords(WorldCoords(HMS(3, 19, 48.2304), HMS(-41, 30, 42.228))); c4 = WorldOrImageCoords(WorldCoords(HMS(c1.ra()), HMS(c1.dec()))); c5 = WorldOrImageCoords(WorldCoords("3 19 48.2304", "-41 30 42.228", 2000.0)); c6 = WorldOrImageCoords(WorldCoords("3:19:48.2304", "-41:30:42.228", 2000.0)); c7 = WorldOrImageCoords(WorldCoords(buf, "-41.51173", 2000.0)); cout << "Here is the same with negative dec:" << endl << c1 << endl << c2 << endl << c3 << endl << c4 << endl << c5 << endl << c6 << endl << c7 << endl; WorldOrImageCoords c8(WorldCoords("3:19", "+41:30", 2000.0)); WorldOrImageCoords c9(WorldCoords("3", "+41", 2000.0)); cout << "And with missing minutes, ... seconds, ..." << endl << c8 << endl << c9 << endl; // test the "box" method (get 2 points given a radius) WorldOrImageCoords c10(WorldCoords("03:19:48.243", "+41:30:40.31")), c11, c12; c10.box(7.05, c11, c12); cout << "\nbox of radius 7.05 with center at (03:19:48.243, +41:30:40.31) ==> (" << c11 << "), (" << c12 << ")\n"; // test values at or near 0,0 WorldOrImageCoords c13(WorldCoords("0", "+41:30:40.31")); cout << "\nWith ra = 0.0: " << c13 << ", vals = " << c13.ra().val() << ", " << c13.dec().val() << endl; WorldOrImageCoords c14(WorldCoords("0.0", "-0.0")); cout << "\nWith ra = 0.0, dec = -0.0: " << c14 << ", vals = " << c14.ra().val() << ", " << c14.dec().val() << endl; WorldOrImageCoords c15(WorldCoords("0:0:1", "-0:1:1")); cout << "\nWith ra = 0:0:1, dec = -0:1:1: " << c15 << ", vals = " << c15.ra().val() << ", " << c15.dec().val() << endl; // test automatic conversion print_coords(ImageCoords(10., 20.), WorldCoords(10., 20.)); // test assignment c1 = WorldCoords(10., 20.); ic1 = ImageCoords(10., 20.); print_coords(ImageCoords(10., 20.), WorldCoords(10., 20.)); return(0); } skycat-3.1.2-starlink-1b/astrotcl/tests/tWorldOrImageCoords.ok000066400000000000000000000023001215713201500243510ustar00rootroot00000000000000these coords should be the same (or very close): 123.456 654.321 123.456 654.321 box of radius 10 with center at (100, 200) ==> (92.9289 192.929), (107.071 207.071) these coords should all be the same (or very close): 03:19:48.230 +41:30:42.23 03:19:48.230 +41:30:42.23 03:19:48.230 +41:30:42.23 03:19:48.230 +41:30:42.23 03:19:48.230 +41:30:42.23 03:19:48.230 +41:30:42.23 03:19:48.230 +41:30:42.23 Here is the same with negative dec: 03:19:48.230 -41:30:42.23 03:19:48.230 -41:30:42.23 03:19:48.230 -41:30:42.23 03:19:48.230 -41:30:42.23 03:19:48.230 -41:30:42.23 03:19:48.230 -41:30:42.23 03:19:48.230 -41:30:42.23 And with missing minutes, ... seconds, ... 03:19:00.000 +41:30:00.00 03:00:00.000 +41:00:00.00 box of radius 7.05 with center at (03:19:48.243, +41:30:40.31) ==> (03:19:21.648 +41:25:41.20), (03:20:14.838 +41:35:39.42) With ra = 0.0: 00:00:00.000 +41:30:40.31, vals = 0, 41.5112 With ra = 0.0, dec = -0.0: 00:00:00.000 -00:00:00.00, vals = 0, -0 With ra = 0:0:1, dec = -0:1:1: 00:00:01.000 -00:01:01.00, vals = 0.000277778, -0.0169444 conversion test: image coords: 10 20, world coords: 00:40:00.000 +20:00:00.00 conversion test: image coords: 10 20, world coords: 00:40:00.000 +20:00:00.00 skycat-3.1.2-starlink-1b/astrotcl/tests/test.fits000066400000000000000000015213001215713201500220020ustar00rootroot00000000000000SIMPLE = T / Standard FITS format (NOST-100.0) BITPIX = 16 / # of bits storing pix values NAXIS = 2 / # of axes in frame NAXIS1 = 25 / Length X axis NAXIS2 = 31 / Length Y axis ORIGIN = 'ESO ' / European Southern Observatory DATE = '1998-03-18T16:30:23.415' / UT date when this file was written PC001001 = 0.866025403 / PC002002 = 0.866025403 / CRVAL1 = 5.98364046269628E+00 / RA at Ref pix in decimal degrees CRPIX1 = 1.25000000000000E+01 / Refpix of first axis CDELT1 = 1.0E-4 / SS per pixel in RA CTYPE1 = 'RA---TAN' / Pixel coordinate system PC001002= 0.5 PC002001= -0.5 CRVAL2 = -7.19991314321991E+01 / DEC at Ref pix in decimal degrees CRPIX2 = 1.55000000000000E+01 / Refpix of second axis CDELT2 = 1.0E-4 / SS arcsec per pixel in DEC CTYPE2 = 'DEC--TAN' / Pixel coordinate system EQUINOX = 2000.000 / BSCALE = 1.0 / pixel=FITS*BSCALE+BZERO BZERO = 32768.0 / pixel=FITS*BSCALE+BZERO MJD-OBS = 50890.68722293 / MJD start (1998-03-18T16:29:36.061) EXPTIME = 4.9973 / Total integration time EXTEND = F / Extension may be present OBSERVER= 'FORS observer' / Name of observer OBJECT = 'Objectname' / Target designation INSTRUME= 'FORS1 ' / Instrument used HIERARCH ESO TPL EXPNO = 0 / Exposure number within template HIERARCH ESO INS MODE = 'FREE ' / Instrument mode used HIERARCH ESO INS COLL ID = '+1 ' / Collimator unique ID HIERARCH ESO INS COLL NAME = 'COLL_SR ' / Collimator name HIERARCH ESO INS PIXSCALE = 0.200 / pixel scale in arcsec/pixel HIERARCH ESO INS FILT1 ID = '+35 ' / Filter unique ID HIERARCH ESO INS FILT1 NAME = 'V_BESS ' / Filter i name HIERARCH ESO INS FOCU POS = -0.00002500 / Focus position in cm HIERARCH ESO INS OPTI2 NAME = 'MOS ' / Name of long slit or polarimetric HIERARCH ESO INS OPTI2 ID = ' ' / Id of long slit or polarimetric maHIERARCH ESO INS OPTI2 TYPE = 'MOS ' / Element type HIERARCH ESO INS OPTI3 NAME = 'COLL_SR ' / Name of collimator HIERARCH ESO INS OPTI3 ID = '+1 ' / Identification of collimator HIERARCH ESO INS OPTI3 TYPE = 'COLL ' / Element type HIERARCH ESO INS OPTI4 NAME = 'free ' / Name of retarder plate HIERARCH ESO INS OPTI4 ID = ' ' / Id of retarder plate HIERARCH ESO INS OPTI4 TYPE = ' ' / Element type HIERARCH ESO INS OPTI5 NAME = 'free ' / element name in wheel 1 (WollastonHIERARCH ESO INS OPTI5 ID = ' ' / element id in wheel 1 (Wollaston) HIERARCH ESO INS OPTI5 TYPE = ' ' / Element type HIERARCH ESO INS OPTI6 NAME = 'free ' / element name in wheel2 (grism) HIERARCH ESO INS OPTI6 ID = ' ' / element id in wheel2 (grism) HIERARCH ESO INS OPTI6 TYPE = ' ' / Element type HIERARCH ESO INS OPTI7 NAME = 'V_BESS ' / element name in wheel3 (parallel bHIERARCH ESO INS OPTI7 ID = '+35 ' / element id in wheel3 (parallel beaHIERARCH ESO INS OPTI7 TYPE = 'FILT ' / Element type HIERARCH ESO INS OPTI8 NAME = 'CAMERA ' / camera name HIERARCH ESO INS OPTI8 ID = '+3 ' / camera id HIERARCH ESO INS OPTI8 TYPE = 'CAMERA ' / Element type HIERARCH ESO INS OPTI9 NAME = 'free ' / element name in wheel 4 (interfereHIERARCH ESO INS OPTI9 ID = ' ' / element id in wheel 4 (interferencHIERARCH ESO INS OPTI9 TYPE = ' ' / Element type HIERARCH ESO INS OPTI10 NAME = 'free ' / Element name in wheel 5 (interf. 2HIERARCH ESO INS OPTI10 ID = ' ' / Element id in wheel 5 (interf. 2) HIERARCH ESO INS OPTI10 TYPE = ' ' / Element type HIERARCH ESO DET ID = 'fors - Rev 2.12' / Detector system Id HIERARCH ESO DET NAME = 'fors camera' / Name of detector system HIERARCH ESO DET DATE = '28/01/98' / Installation date HIERARCH ESO DET DID = 'ESO-VLT-DIC.CCDDCS,ESO-VLT-DIC.FCDDCS' / DdictioHIERARCH ESO DET BITS = 16 / Bits per pixel readout HIERARCH ESO DET RA = 0.00000000 / Apparent 00:00:00.0 RA at start HIERARCH ESO DET DEC = 0.00000000 / Apparent 00:00:00.0 DEC at start HIERARCH ESO DET SOFW MODE = 'Normal ' / CCD sw operational mode HIERARCH ESO DET CHIPS = 1 / # of chips in detector array HIERARCH ESO DET CHIP1 ID = 'TK2048EB4-1 1604' / Detector chip identificationHIERARCH ESO DET CHIP1 NAME = ' ' / Detector chip name HIERARCH ESO DET CHIP1 DATE = '28/01/98' / Date of installation [YYYY-MM-DD] HIERARCH ESO DET CHIP1 X = 1 / X location in array HIERARCH ESO DET CHIP1 Y = 1 / Y location in array HIERARCH ESO DET CHIP1 NX = 2048 / # of pixels along X HIERARCH ESO DET CHIP1 NY = 2049 / # of pixels along Y HIERARCH ESO DET CHIP1 PSZX = 24.0 / Size of pixel in X HIERARCH ESO DET CHIP1 PSZY = 24.0 / Size of pixel in Y HIERARCH ESO DET EXP ID = 6471 / Unique exposure ID number HIERARCH ESO DET EXP TYPE = 'Normal ' / Exposure type HIERARCH ESO DET EXP DUMDIT = 0 / # of dummy readouts HIERARCH ESO DET EXP RDTTIME = 89.753 / image readout time HIERARCH ESO DET EXP XFERTIM = 89.680 / image transfer time HIERARCH ESO DET READ MODE = 'normal ' / Readout method HIERARCH ESO DET READ SPEED = 'normal ' / Readout speed HIERARCH ESO DET READ CLOCK = 'Readout A (low gnorm' / Readout clock pattern usHIERARCH ESO DET OUTPUTS = 1 / # of outputs HIERARCH ESO DET OUTREF = 0 / reference output HIERARCH ESO DET OUT1 ID = 'A ' / Output ID as from manufacturer HIERARCH ESO DET OUT1 NAME = ' ' / Description of output HIERARCH ESO DET OUT1 CHIP = 1 / index of chip it belongs to HIERARCH ESO DET OUT1 X = 1 / X location of output HIERARCH ESO DET OUT1 Y = 1 / Y location of output HIERARCH ESO DET OUT1 NX = 0 / valid pixels along X HIERARCH ESO DET OUT1 NY = 0 / valid pixels along Y HIERARCH ESO DET OUT1 PRSCX = 19 / Prescan region in X HIERARCH ESO DET OUT1 OVSCX = 19 / Overscan region in X HIERARCH ESO DET OUT1 CONAD = 1.50 / Conversion from electrons to ADUs HIERARCH ESO DET OUT1 GAIN = 0.00 / Gain for output HIERARCH ESO DET FRAM ID = 1 / Image sequencial number HIERARCH ESO DET FRAM TYPE = 'Normal ' / Type of frame HIERARCH ESO DET WINDOWS = 1 / # of windows readout HIERARCH ESO DET WIN1 STRX = 1 / Lower left pixel in X HIERARCH ESO DET WIN1 STRY = 1 / Lower left pixel in Y HIERARCH ESO DET WIN1 NX = 2080 / # of pixels along X HIERARCH ESO DET WIN1 NY = 2048 / # of pixels along Y HIERARCH ESO DET WIN1 BINX = 1 / Binning factor along X HIERARCH ESO DET WIN1 BINY = 1 / Binning factor along Y HIERARCH ESO DET WIN1 NDIT = 1 / # of subintegrations HIERARCH ESO DET WIN1 UIT1 = 5.000 / user defined subintegration time HIERARCH ESO DET WIN1 DIT1 = 4.9973 / actual subintegration time HIERARCH ESO DET WIN1 DKTM = 5.1346 / Dark current time HIERARCH ESO DET SHUT TYPE = 'Iris ' / type of shutter HIERARCH ESO DET SHUT ID = 'fors shutter' / Shutter unique identifier HIERARCH ESO DET SHUT TMOPEN = 0.235 / Time taken to open shutter HIERARCH ESO DET SHUT TMCLOS = 0.230 / Time taken to close shutter HIERARCH ESO INS MOS1 RA = 6.17962900 / RA of slit in deg HIERARCH ESO INS MOS1 DEC = -72.02527900 / DEC of slit in deg HIERARCH ESO INS MOS1 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS1 LEN = 22.37 / MOSi slit length in arcsec HIERARCH ESO INS MOS1 POSANG = 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS2 RA = 6.14554800 / RA of slit in deg HIERARCH ESO INS MOS2 DEC = -72.03162100 / DEC of slit in deg HIERARCH ESO INS MOS2 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS2 LEN = 20.09 / MOSi slit length in arcsec HIERARCH ESO INS MOS2 POSANG = 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS3 RA = 6.14558900 / RA of slit in deg HIERARCH ESO INS MOS3 DEC = -72.03793900 / DEC of slit in deg HIERARCH ESO INS MOS3 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS3 LEN = 22.37 / MOSi slit length in arcsec HIERARCH ESO INS MOS3 POSANG = 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS4 RA = 6.12855100 / RA of slit in deg HIERARCH ESO INS MOS4 DEC = -72.04426600 / DEC of slit in deg HIERARCH ESO INS MOS4 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS4 LEN = 20.09 / MOSi slit length in arcsec HIERARCH ESO INS MOS4 POSANG = 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS5 RA = 6.11150200 / RA of slit in deg HIERARCH ESO INS MOS5 DEC = -72.05059200 / DEC of slit in deg HIERARCH ESO INS MOS5 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS5 LEN = 22.37 / MOSi slit length in arcsec HIERARCH ESO INS MOS5 POSANG = 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS6 RA = 6.09444200 / RA of slit in deg HIERARCH ESO INS MOS6 DEC = -72.05691700 / DEC of slit in deg HIERARCH ESO INS MOS6 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS6 LEN = 20.09 / MOSi slit length in arcsec HIERARCH ESO INS MOS6 POSANG = 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS7 RA = 6.07737000 / RA of slit in deg HIERARCH ESO INS MOS7 DEC = -72.06324000 / DEC of slit in deg HIERARCH ESO INS MOS7 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS7 LEN = 22.37 / MOSi slit length in arcsec HIERARCH ESO INS MOS7 POSANG = 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS8 RA = 6.06028600 / RA of slit in deg HIERARCH ESO INS MOS8 DEC = -72.06956100 / DEC of slit in deg HIERARCH ESO INS MOS8 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS8 LEN = 20.09 / MOSi slit length in arcsec HIERARCH ESO INS MOS8 POSANG = 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS9 RA = 6.04319000 / RA of slit in deg HIERARCH ESO INS MOS9 DEC = -72.07588100 / DEC of slit in deg HIERARCH ESO INS MOS9 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS9 LEN = 22.37 / MOSi slit length in arcsec HIERARCH ESO INS MOS9 POSANG = 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS10 RA = 6.02608300 / RA of slit in deg HIERARCH ESO INS MOS10 DEC = -72.08220000 / DEC of slit in deg HIERARCH ESO INS MOS10 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS10 LEN = 20.09 / MOSi slit length in arcsec HIERARCH ESO INS MOS10 POSANG= 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS11 RA = 6.00896500 / RA of slit in deg HIERARCH ESO INS MOS11 DEC = -72.08851700 / DEC of slit in deg HIERARCH ESO INS MOS11 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS11 LEN = 22.37 / MOSi slit length in arcsec HIERARCH ESO INS MOS11 POSANG= 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS12 RA = 5.99183400 / RA of slit in deg HIERARCH ESO INS MOS12 DEC = -72.09483300 / DEC of slit in deg HIERARCH ESO INS MOS12 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS12 LEN = 20.09 / MOSi slit length in arcsec HIERARCH ESO INS MOS12 POSANG= 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS13 RA = 5.97469100 / RA of slit in deg HIERARCH ESO INS MOS13 DEC = -72.10114700 / DEC of slit in deg HIERARCH ESO INS MOS13 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS13 LEN = 22.37 / MOSi slit length in arcsec HIERARCH ESO INS MOS13 POSANG= 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS14 RA = 5.95753800 / RA of slit in deg HIERARCH ESO INS MOS14 DEC = -72.10745900 / DEC of slit in deg HIERARCH ESO INS MOS14 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS14 LEN = 20.09 / MOSi slit length in arcsec HIERARCH ESO INS MOS14 POSANG= 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS15 RA = 5.94037200 / RA of slit in deg HIERARCH ESO INS MOS15 DEC = -72.11377000 / DEC of slit in deg HIERARCH ESO INS MOS15 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS15 LEN = 22.37 / MOSi slit length in arcsec HIERARCH ESO INS MOS15 POSANG= 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS16 RA = 5.92319600 / RA of slit in deg HIERARCH ESO INS MOS16 DEC = -72.12008000 / DEC of slit in deg HIERARCH ESO INS MOS16 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS16 LEN = 20.09 / MOSi slit length in arcsec HIERARCH ESO INS MOS16 POSANG= 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS17 RA = 5.90600600 / RA of slit in deg HIERARCH ESO INS MOS17 DEC = -72.12638800 / DEC of slit in deg HIERARCH ESO INS MOS17 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS17 LEN = 22.37 / MOSi slit length in arcsec HIERARCH ESO INS MOS17 POSANG= 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS18 RA = 5.88880500 / RA of slit in deg HIERARCH ESO INS MOS18 DEC = -72.13269500 / DEC of slit in deg HIERARCH ESO INS MOS18 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS18 LEN = 20.09 / MOSi slit length in arcsec HIERARCH ESO INS MOS18 POSANG= 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS19 RA = 5.87159200 / RA of slit in deg HIERARCH ESO INS MOS19 DEC = -72.13900000 / DEC of slit in deg HIERARCH ESO INS MOS19 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS19 LEN = 22.37 / MOSi slit length in arcsec HIERARCH ESO INS MOS19 POSANG= 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS LAMP10 NAME = 'FlatRed+2' / Name of the lamp switched on HIERARCH ESO INS LAMP10 TIME = 5.000 / Lamp ilumination time in sec. HIERARCH ESO INS MOS1 POS = 9.000003e+01 / Position of the slit 1 in mm. HIERARCH ESO INS MOS1 WIDTH = 2.999450e-01 / Width of the MOS slit 1 in mm. HIERARCH ESO INS MOS2 POS = 6.999967e+01 / Position of the slit 2 in mm. HIERARCH ESO INS MOS2 WIDTH = 2.996540e-01 / Width of the MOS slit 2 in mm. HIERARCH ESO INS MOS3 POS = 6.999992e+01 / Position of the slit 3 in mm. HIERARCH ESO INS MOS3 WIDTH = 3.001540e-01 / Width of the MOS slit 3 in mm. HIERARCH ESO INS MOS4 POS = 5.999997e+01 / Position of the slit 4 in mm. HIERARCH ESO INS MOS4 WIDTH = 2.990500e-01 / Width of the MOS slit 4 in mm. HIERARCH ESO INS MOS5 POS = 4.999995e+01 / Position of the slit 5 in mm. HIERARCH ESO INS MOS5 WIDTH = 3.001060e-01 / Width of the MOS slit 5 in mm. HIERARCH ESO INS MOS6 POS = 4.000011e+01 / Position of the slit 6 in mm. HIERARCH ESO INS MOS6 WIDTH = 2.997830e-01 / Width of the MOS slit 6 in mm. HIERARCH ESO INS MOS7 POS = 2.999997e+01 / Position of the slit 7 in mm. HIERARCH ESO INS MOS7 WIDTH = 3.000600e-01 / Width of the MOS slit 7 in mm. HIERARCH ESO INS MOS8 POS = 1.999998e+01 / Position of the slit 8 in mm. HIERARCH ESO INS MOS8 WIDTH = 3.000320e-01 / Width of the MOS slit 8 in mm. HIERARCH ESO INS MOS9 POS = 9.999977e+00 / Position of the slit 9 in mm. HIERARCH ESO INS MOS9 WIDTH = 3.000470e-01 / Width of the MOS slit 9 in mm. HIERARCH ESO INS MOS10 POS = 2.000000e-06 / Position of the slit 10 in mm. HIERARCH ESO INS MOS10 WIDTH = 2.999960e-01 / Width of the MOS slit 10 in mm. HIERARCH ESO INS MOS11 POS = -9.999966e+00 / Position of the slit 11 in mm. HIERARCH ESO INS MOS11 WIDTH = 2.999320e-01 / Width of the MOS slit 11 in mm. HIERARCH ESO INS MOS12 POS = -2.000025e+01 / Position of the slit 12 in mm. HIERARCH ESO INS MOS12 WIDTH = 2.995010e-01 / Width of the MOS slit 12 in mm. HIERARCH ESO INS MOS13 POS = -3.000037e+01 / Position of the slit 13 in mm. HIERARCH ESO INS MOS13 WIDTH = 2.997380e-01 / Width of the MOS slit 13 in mm. HIERARCH ESO INS MOS14 POS = -4.000010e+01 / Position of the slit 14 in mm. HIERARCH ESO INS MOS14 WIDTH = 3.001890e-01 / Width of the MOS slit 14 in mm. HIERARCH ESO INS MOS15 POS = -4.999995e+01 / Position of the slit 15 in mm. HIERARCH ESO INS MOS15 WIDTH = 2.998980e-01 / Width of the MOS slit 15 in mm. HIERARCH ESO INS MOS16 POS = -5.999965e+01 / Position of the slit 16 in mm. HIERARCH ESO INS MOS16 WIDTH = 2.992920e-01 / Width of the MOS slit 16 in mm. HIERARCH ESO INS MOS17 POS = -7.000008e+01 / Position of the slit 17 in mm. HIERARCH ESO INS MOS17 WIDTH = 3.001660e-01 / Width of the MOS slit 17 in mm. HIERARCH ESO INS MOS18 POS = -8.000004e+01 / Position of the slit 18 in mm. HIERARCH ESO INS MOS18 WIDTH = 3.000790e-01 / Width of the MOS slit 18 in mm. HIERARCH ESO INS MOS19 POS = -9.000012e+01 / Position of the slit 19 in mm. HIERARCH ESO INS MOS19 WIDTH = 3.002380e-01 / Width of the MOS slit 19 in mm. HISTORY SETHEAD 2.4 1998-09-04 14:49 PC001002 and PC002001 updated END €¾€¼€½€Â€Ã€»€Â€Ê€× …ÁwÈTµ(…1€ü€Ì€Æ€Ä€¿€Á€Â€Ã€Á€»€½€½€½€Ä€Á€Á€È€ÓtÁ,ÈÚ´r…M€ú€Ñ€Ë€¾€Á€Ä€¹€¹€¿€¾€¼€¹€¿€¿€Å€Æ€Ç€Ò €Á"ȉ´í…€ï€Õ€È€Å€¿€Ã€½€½€Å€½€¾€¿€¿€Ä€Ã€Å€È€Ñ~Á²È¦´Ä…7€ù€Ò€Ä€Á€Å€¿€Â€¾€À€½€¿€¿€Â€½€Á€É€É€Ó ŽÂÈY´ƒ…"€ï€Ö€Ê€É€Â€Æ€»€Ã€À€¾€»€¾€¾€¿€¿€Å€Ì€ÒJÁ‹È±´Ç…@€å€Ô€Í€Æ€Á€Â€À€¿€À€·€º€»€Á€½€À€Æ€Ì€Õ5ÁÈm´Ì…@€ò€Í€Â€Á€Æ€Â€Ç€½€½€¹€½€½€¹€º€Ä€½€Í€ÓAÀÜÈ7´Q…=€ð€Ï€Ç€Å€¿€Ä€»€À€À€¼€Â€¾€Â€¿€Â€À€Ë€Ô MÀàȯ´/…€ô€Ø€Æ€È€À€Á€¾€¿€À€º€¸€¾€À€¼€Ã€Á€È€ÚZÁÈf´\„ý€ô€Ð€Ç€½€Ã€¿€¾€Ã€Ä€·€»€½€¾€¼€½€È€È€Ê7ÁWÇì´…€ù€Ë€É€Æ€Ã€À€¼€½€¾€Á€¼€¼€Á€À€½€Â€Æ€Õ„ÁÈg´(…#€ñ€Ï€Æ€À€Á€»€¾€Á€½€¾€»€¾€¾€À€¾€Æ€Æ€ÕFÁ@Èâ´…:€í€Ï€Ë€À€Ç€Á€¼€½€½€¿€½€½€À€À€¾€Ä€É€ÓvÁ"ÈÔ´W… €î€Ñ€Å€Ä€Å€Â€Á€¿€º€½€Â€»€¾€½€¿€È€É€Ñ ?À¶Èt´ …€ó€Ú€Ë€Á€À€Â€¿€À€½€¿€½€º€½€Á€¿€À€Ç€ÛZÁmȯ³Ý… €ë€Î€¿€É€¾€¿€¿€¿€¾€Â€»€Á€¼€½€¿€Â€Ì€Õ"Â-Ȱ³±…€ø€Ì€Â€À€¾€À€¼€Ä€¹€À€»€Á€Á€½€À€Ê€Æ€Ñ ƒÁÈö³ä…,€ó€Ó€Æ€Á€Æ€¿€Á€½€º€¸€¼€¼€Á€Ä€½€Æ€É€ÍNÁ­Èí´%…&€ñ€Ê€È€¾€À€À€½€½€¿€½€À€¾€Ã€Å€Â€Å€Â€Õ DÁéÈÙµ …<€ô€Ë€Ê€À€À€Â€À€º€»€½€Á€º€Ã€¼€Â€Æ€È€Î;À«È…´w…C€ï€Ë€È€Æ€½€À€½€Á€¾€¾€¾€½€½€½€¿€Ç€Í€ÓŒÝÁ˜È<´E…;€ë€Ë€Â€Ä€»€È€Ä€½€½€¹€¹€¾€¹€Ä€Æ€À€Å€ÕIÀàÈÏ´Q…#€ð€Ï€Æ€Æ€À€Á€Â€º€Å€½€¼€º€¿€Á€¿€Á€Ë€ÕvÁÈ¿´m…*€ð€Õ€Å€Å€À€À€½€¿€¾€¼€»€½€¾€¼€Æ€É€×€û¦ŽRÁæÉ´º…€ö€Ï€È€Á€Ã€Ã€¹€Â€½€½€¾€À€»€º€½€Ü„¯î©WÆÉ@¶Ê‡e¤€í€Ë€Ç€Á€Á€½€¿€¼€½€À€»€º€Ä€Ã€Ï7‰Ü¦ÀÚÈFȘÀhŸ7ˆ2K€Õ€Á€Á€Â€º€Á€»€¾€¼€¸€½€À€·€È‰s¢„¶Õ¼³¼<¶ß¡ê‰b€Ô€Æ€¼€¼€¾€¹€¸€º€¼€¸€»€¾€½€É€òƒNŠ>Ò‘Ö‘Ÿ„‰ªƒ9€Ë€Å€Â€¼€º€¿€¹€¼€½€º€Â€À€¼€Â€Ç;‚„ƒ·„„ƒ‚E0€×€Ã€¾€¹€¿€À€¼€¾€¼€·€½€Á€¹€¼€»€É€à7ƒ·Ì¿€Ö€Â€Å€Á€½€½€º€À€»XTENSION= 'BINTABLE' / binary table extension BITPIX = 8 / 8-bit bytes NAXIS = 2 / 2-dimensional binary table NAXIS1 = 4021 / width of table in bytes NAXIS2 = 100 / number of rows in table PCOUNT = 0 / size of special data area GCOUNT = 1 / one data group (required keyword) TFIELDS = 3 / number of fields in each row TTYPE1 = 'Avalue ' / label for field 1 TFORM1 = '20A ' / data format of field: ASCII Character TTYPE2 = 'Lvalue ' / label for field 2 TFORM2 = '1L ' / data format of field: 1-byte LOGICAL TUNIT2 = 'm**2 ' / physical unit of field TTYPE3 = 'Evalue ' / label for field 3 TFORM3 = '1000E ' / data format of field: 4-byte REAL TUNIT3 = 'cm ' / physical unit of field EXTNAME = 'iter_test' / name of this binary table extension END changed to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fskycat-3.1.2-starlink-1b/astrotcl/tests/tmp.fits000077500000000000000000015631001215713201500216320ustar00rootroot00000000000000SIMPLE = T / Standard FITS format (NOST-100.0) BITPIX = 16 / # of bits storing pix values NAXIS = 2 / # of axes in frame NAXIS1 = 25 / Length X axis NAXIS2 = 31 / Length Y axis ORIGIN = 'ESO ' / European Southern Observatory DATE = '1998-03-18T16:30:23.415' / UT date when this file was written PC001001 = 0.866025403 / PC002002 = 0.866025403 / CRVAL1 = 5.98364046269628E+00 / RA at Ref pix in decimal degrees CRPIX1 = 1.25000000000000E+01 / Refpix of first axis CDELT1 = 1.0E-4 / SS per pixel in RA CTYPE1 = 'RA---TAN' / Pixel coordinate system PC001002= 0.5 PC002001= -0.5 CRVAL2 = -7.19991314321991E+01 / DEC at Ref pix in decimal degrees CRPIX2 = 1.55000000000000E+01 / Refpix of second axis CDELT2 = 1.0E-4 / SS arcsec per pixel in DEC CTYPE2 = 'DEC--TAN' / Pixel coordinate system EQUINOX = 2000.000 / BSCALE = 2. / pixel=FITS*BSCALE+BZERO BZERO = 32768.0 / pixel=FITS*BSCALE+BZERO MJD-OBS = 50890.68722293 / MJD start (1998-03-18T16:29:36.061) EXPTIME = 4.9973 / Total integration time EXTEND = F / Extension may be present OBSERVER= 'FORS observer' / Name of observer OBJECT = 'Objectname' / Target designation INSTRUME= 'FORS1 ' / Instrument used HIERARCH ESO TPL EXPNO = 0 / Exposure number within template HIERARCH ESO INS MODE = 'FREE ' / Instrument mode used HIERARCH ESO INS COLL ID = '+1 ' / Collimator unique ID HIERARCH ESO INS COLL NAME = 'COLL_SR ' / Collimator name HIERARCH ESO INS PIXSCALE = 0.200 / pixel scale in arcsec/pixel HIERARCH ESO INS FILT1 ID = '+35 ' / Filter unique ID HIERARCH ESO INS FILT1 NAME = 'V_BESS ' / Filter i name HIERARCH ESO INS FOCU POS = -0.00002500 / Focus position in cm HIERARCH ESO INS OPTI2 NAME = 'MOS ' / Name of long slit or polarimetric HIERARCH ESO INS OPTI2 ID = ' ' / Id of long slit or polarimetric maHIERARCH ESO INS OPTI2 TYPE = 'MOS ' / Element type HIERARCH ESO INS OPTI3 NAME = 'COLL_SR ' / Name of collimator HIERARCH ESO INS OPTI3 ID = '+1 ' / Identification of collimator HIERARCH ESO INS OPTI3 TYPE = 'COLL ' / Element type HIERARCH ESO INS OPTI4 NAME = 'free ' / Name of retarder plate HIERARCH ESO INS OPTI4 ID = ' ' / Id of retarder plate HIERARCH ESO INS OPTI4 TYPE = ' ' / Element type HIERARCH ESO INS OPTI5 NAME = 'free ' / element name in wheel 1 (WollastonHIERARCH ESO INS OPTI5 ID = ' ' / element id in wheel 1 (Wollaston) HIERARCH ESO INS OPTI5 TYPE = ' ' / Element type HIERARCH ESO INS OPTI6 NAME = 'free ' / element name in wheel2 (grism) HIERARCH ESO INS OPTI6 ID = ' ' / element id in wheel2 (grism) HIERARCH ESO INS OPTI6 TYPE = ' ' / Element type HIERARCH ESO INS OPTI7 NAME = 'V_BESS ' / element name in wheel3 (parallel bHIERARCH ESO INS OPTI7 ID = '+35 ' / element id in wheel3 (parallel beaHIERARCH ESO INS OPTI7 TYPE = 'FILT ' / Element type HIERARCH ESO INS OPTI8 NAME = 'CAMERA ' / camera name HIERARCH ESO INS OPTI8 ID = '+3 ' / camera id HIERARCH ESO INS OPTI8 TYPE = 'CAMERA ' / Element type HIERARCH ESO INS OPTI9 NAME = 'free ' / element name in wheel 4 (interfereHIERARCH ESO INS OPTI9 ID = ' ' / element id in wheel 4 (interferencHIERARCH ESO INS OPTI9 TYPE = ' ' / Element type HIERARCH ESO INS OPTI10 NAME = 'free ' / Element name in wheel 5 (interf. 2HIERARCH ESO INS OPTI10 ID = ' ' / Element id in wheel 5 (interf. 2) HIERARCH ESO INS OPTI10 TYPE = ' ' / Element type HIERARCH ESO DET ID = 'fors - Rev 2.12' / Detector system Id HIERARCH ESO DET NAME = 'fors camera' / Name of detector system HIERARCH ESO DET DATE = '28/01/98' / Installation date HIERARCH ESO DET DID = 'ESO-VLT-DIC.CCDDCS,ESO-VLT-DIC.FCDDCS' / DdictioHIERARCH ESO DET BITS = 16 / Bits per pixel readout HIERARCH ESO DET RA = 0.00000000 / Apparent 00:00:00.0 RA at start HIERARCH ESO DET DEC = 0.00000000 / Apparent 00:00:00.0 DEC at start HIERARCH ESO DET SOFW MODE = 'Normal ' / CCD sw operational mode HIERARCH ESO DET CHIPS = 1 / # of chips in detector array HIERARCH ESO DET CHIP1 ID = 'CHANGED ' / Detector chip identification HIERARCH ESO DET CHIP1 NAME = ' ' / Detector chip name HIERARCH ESO DET CHIP1 DATE = '28/01/98' / Date of installation [YYYY-MM-DD] HIERARCH ESO DET CHIP1 X = 1 / X location in array HIERARCH ESO DET CHIP1 Y = 1 / Y location in array HIERARCH ESO DET CHIP1 NX = 2048 / # of pixels along X HIERARCH ESO DET CHIP1 NY = 2049 / # of pixels along Y HIERARCH ESO DET CHIP1 PSZX = 24.0 / Size of pixel in X HIERARCH ESO DET CHIP1 PSZY = 24.0 / Size of pixel in Y HIERARCH ESO DET EXP ID = 6471 / Unique exposure ID number HIERARCH ESO DET EXP TYPE = 'Normal ' / Exposure type HIERARCH ESO DET EXP DUMDIT = 0 / # of dummy readouts HIERARCH ESO DET EXP RDTTIME = 89.753 / image readout time HIERARCH ESO DET EXP XFERTIM = 89.680 / image transfer time HIERARCH ESO DET READ MODE = 'normal ' / Readout method HIERARCH ESO DET READ SPEED = 'normal ' / Readout speed HIERARCH ESO DET READ CLOCK = 'Readout A (low gnorm' / Readout clock pattern usHIERARCH ESO DET OUTPUTS = 1 / # of outputs HIERARCH ESO DET OUTREF = 0 / reference output HIERARCH ESO DET OUT1 ID = 'A ' / Output ID as from manufacturer HIERARCH ESO DET OUT1 NAME = ' ' / Description of output HIERARCH ESO DET OUT1 CHIP = 1 / index of chip it belongs to HIERARCH ESO DET OUT1 X = 1 / X location of output HIERARCH ESO DET OUT1 Y = 1 / Y location of output HIERARCH ESO DET OUT1 NX = 0 / valid pixels along X HIERARCH ESO DET OUT1 NY = 0 / valid pixels along Y HIERARCH ESO DET OUT1 PRSCX = 19 / Prescan region in X HIERARCH ESO DET OUT1 OVSCX = 19 / Overscan region in X HIERARCH ESO DET OUT1 CONAD = 1.50 / Conversion from electrons to ADUs HIERARCH ESO DET OUT1 GAIN = 0.00 / Gain for output HIERARCH ESO DET FRAM ID = 1 / Image sequencial number HIERARCH ESO DET FRAM TYPE = 'Normal ' / Type of frame HIERARCH ESO DET WINDOWS = 1 / # of windows readout HIERARCH ESO DET WIN1 STRX = 1 / Lower left pixel in X HIERARCH ESO DET WIN1 STRY = 1 / Lower left pixel in Y HIERARCH ESO DET WIN1 NX = 2080 / # of pixels along X HIERARCH ESO DET WIN1 NY = 2048 / # of pixels along Y HIERARCH ESO DET WIN1 BINX = 1 / Binning factor along X HIERARCH ESO DET WIN1 BINY = 1 / Binning factor along Y HIERARCH ESO DET WIN1 NDIT = 1 / # of subintegrations HIERARCH ESO DET WIN1 UIT1 = 5.000 / user defined subintegration time HIERARCH ESO DET WIN1 DIT1 = 4.9973 / actual subintegration time HIERARCH ESO DET WIN1 DKTM = 5.1346 / Dark current time HIERARCH ESO DET SHUT TYPE = 'Iris ' / type of shutter HIERARCH ESO DET SHUT ID = 'fors shutter' / Shutter unique identifier HIERARCH ESO DET SHUT TMOPEN = 0.235 / Time taken to open shutter HIERARCH ESO DET SHUT TMCLOS = 0.230 / Time taken to close shutter HIERARCH ESO INS MOS1 RA = 6.17962900 / RA of slit in deg HIERARCH ESO INS MOS1 DEC = -72.02527900 / DEC of slit in deg HIERARCH ESO INS MOS1 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS1 LEN = 22.37 / MOSi slit length in arcsec HIERARCH ESO INS MOS1 POSANG = 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS2 RA = 6.14554800 / RA of slit in deg HIERARCH ESO INS MOS2 DEC = -72.03162100 / DEC of slit in deg HIERARCH ESO INS MOS2 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS2 LEN = 20.09 / MOSi slit length in arcsec HIERARCH ESO INS MOS2 POSANG = 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS3 RA = 6.14558900 / RA of slit in deg HIERARCH ESO INS MOS3 DEC = -72.03793900 / DEC of slit in deg HIERARCH ESO INS MOS3 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS3 LEN = 22.37 / MOSi slit length in arcsec HIERARCH ESO INS MOS3 POSANG = 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS4 RA = 6.12855100 / RA of slit in deg HIERARCH ESO INS MOS4 DEC = -72.04426600 / DEC of slit in deg HIERARCH ESO INS MOS4 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS4 LEN = 20.09 / MOSi slit length in arcsec HIERARCH ESO INS MOS4 POSANG = 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS5 RA = 6.11150200 / RA of slit in deg HIERARCH ESO INS MOS5 DEC = -72.05059200 / DEC of slit in deg HIERARCH ESO INS MOS5 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS5 LEN = 22.37 / MOSi slit length in arcsec HIERARCH ESO INS MOS5 POSANG = 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS6 RA = 6.09444200 / RA of slit in deg HIERARCH ESO INS MOS6 DEC = -72.05691700 / DEC of slit in deg HIERARCH ESO INS MOS6 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS6 LEN = 20.09 / MOSi slit length in arcsec HIERARCH ESO INS MOS6 POSANG = 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS7 RA = 6.07737000 / RA of slit in deg HIERARCH ESO INS MOS7 DEC = -72.06324000 / DEC of slit in deg HIERARCH ESO INS MOS7 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS7 LEN = 22.37 / MOSi slit length in arcsec HIERARCH ESO INS MOS7 POSANG = 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS8 RA = 6.06028600 / RA of slit in deg HIERARCH ESO INS MOS8 DEC = -72.06956100 / DEC of slit in deg HIERARCH ESO INS MOS8 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS8 LEN = 20.09 / MOSi slit length in arcsec HIERARCH ESO INS MOS8 POSANG = 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS9 RA = 6.04319000 / RA of slit in deg HIERARCH ESO INS MOS9 DEC = -72.07588100 / DEC of slit in deg HIERARCH ESO INS MOS9 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS9 LEN = 22.37 / MOSi slit length in arcsec HIERARCH ESO INS MOS9 POSANG = 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS10 RA = 6.02608300 / RA of slit in deg HIERARCH ESO INS MOS10 DEC = -72.08220000 / DEC of slit in deg HIERARCH ESO INS MOS10 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS10 LEN = 20.09 / MOSi slit length in arcsec HIERARCH ESO INS MOS10 POSANG= 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS11 RA = 6.00896500 / RA of slit in deg HIERARCH ESO INS MOS11 DEC = -72.08851700 / DEC of slit in deg HIERARCH ESO INS MOS11 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS11 LEN = 22.37 / MOSi slit length in arcsec HIERARCH ESO INS MOS11 POSANG= 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS12 RA = 5.99183400 / RA of slit in deg HIERARCH ESO INS MOS12 DEC = -72.09483300 / DEC of slit in deg HIERARCH ESO INS MOS12 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS12 LEN = 20.09 / MOSi slit length in arcsec HIERARCH ESO INS MOS12 POSANG= 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS13 RA = 5.97469100 / RA of slit in deg HIERARCH ESO INS MOS13 DEC = -72.10114700 / DEC of slit in deg HIERARCH ESO INS MOS13 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS13 LEN = 22.37 / MOSi slit length in arcsec HIERARCH ESO INS MOS13 POSANG= 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS14 RA = 5.95753800 / RA of slit in deg HIERARCH ESO INS MOS14 DEC = -72.10745900 / DEC of slit in deg HIERARCH ESO INS MOS14 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS14 LEN = 20.09 / MOSi slit length in arcsec HIERARCH ESO INS MOS14 POSANG= 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS15 RA = 5.94037200 / RA of slit in deg HIERARCH ESO INS MOS15 DEC = -72.11377000 / DEC of slit in deg HIERARCH ESO INS MOS15 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS15 LEN = 22.37 / MOSi slit length in arcsec HIERARCH ESO INS MOS15 POSANG= 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS16 RA = 5.92319600 / RA of slit in deg HIERARCH ESO INS MOS16 DEC = -72.12008000 / DEC of slit in deg HIERARCH ESO INS MOS16 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS16 LEN = 20.09 / MOSi slit length in arcsec HIERARCH ESO INS MOS16 POSANG= 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS17 RA = 5.90600600 / RA of slit in deg HIERARCH ESO INS MOS17 DEC = -72.12638800 / DEC of slit in deg HIERARCH ESO INS MOS17 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS17 LEN = 22.37 / MOSi slit length in arcsec HIERARCH ESO INS MOS17 POSANG= 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS18 RA = 5.88880500 / RA of slit in deg HIERARCH ESO INS MOS18 DEC = -72.13269500 / DEC of slit in deg HIERARCH ESO INS MOS18 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS18 LEN = 20.09 / MOSi slit length in arcsec HIERARCH ESO INS MOS18 POSANG= 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS MOS19 RA = 5.87159200 / RA of slit in deg HIERARCH ESO INS MOS19 DEC = -72.13900000 / DEC of slit in deg HIERARCH ESO INS MOS19 WID = 0.00 / MOSi slit width in arcsec HIERARCH ESO INS MOS19 LEN = 22.37 / MOSi slit length in arcsec HIERARCH ESO INS MOS19 POSANG= 0.000 / MOS slit posang (N=0 E=90) HIERARCH ESO INS LAMP10 NAME = 'FlatRed+2' / Name of the lamp switched on HIERARCH ESO INS LAMP10 TIME = 5.000 / Lamp ilumination time in sec. HIERARCH ESO INS MOS1 POS = 9.000003e+01 / Position of the slit 1 in mm. HIERARCH ESO INS MOS1 WIDTH = 2.999450e-01 / Width of the MOS slit 1 in mm. HIERARCH ESO INS MOS2 POS = 6.999967e+01 / Position of the slit 2 in mm. HIERARCH ESO INS MOS2 WIDTH = 2.996540e-01 / Width of the MOS slit 2 in mm. HIERARCH ESO INS MOS3 POS = 6.999992e+01 / Position of the slit 3 in mm. HIERARCH ESO INS MOS3 WIDTH = 3.001540e-01 / Width of the MOS slit 3 in mm. HIERARCH ESO INS MOS4 POS = 5.999997e+01 / Position of the slit 4 in mm. HIERARCH ESO INS MOS4 WIDTH = 2.990500e-01 / Width of the MOS slit 4 in mm. HIERARCH ESO INS MOS5 POS = 4.999995e+01 / Position of the slit 5 in mm. HIERARCH ESO INS MOS5 WIDTH = 3.001060e-01 / Width of the MOS slit 5 in mm. HIERARCH ESO INS MOS6 POS = 4.000011e+01 / Position of the slit 6 in mm. HIERARCH ESO INS MOS6 WIDTH = 2.997830e-01 / Width of the MOS slit 6 in mm. HIERARCH ESO INS MOS7 POS = 2.999997e+01 / Position of the slit 7 in mm. HIERARCH ESO INS MOS7 WIDTH = 3.000600e-01 / Width of the MOS slit 7 in mm. HIERARCH ESO INS MOS8 POS = 1.999998e+01 / Position of the slit 8 in mm. HIERARCH ESO INS MOS8 WIDTH = 3.000320e-01 / Width of the MOS slit 8 in mm. HIERARCH ESO INS MOS9 POS = 9.999977e+00 / Position of the slit 9 in mm. HIERARCH ESO INS MOS9 WIDTH = 3.000470e-01 / Width of the MOS slit 9 in mm. HIERARCH ESO INS MOS10 POS = 2.000000e-06 / Position of the slit 10 in mm. HIERARCH ESO INS MOS10 WIDTH = 2.999960e-01 / Width of the MOS slit 10 in mm. HIERARCH ESO INS MOS11 POS = -9.999966e+00 / Position of the slit 11 in mm. HIERARCH ESO INS MOS11 WIDTH = 2.999320e-01 / Width of the MOS slit 11 in mm. HIERARCH ESO INS MOS12 POS = -2.000025e+01 / Position of the slit 12 in mm. HIERARCH ESO INS MOS12 WIDTH = 2.995010e-01 / Width of the MOS slit 12 in mm. HIERARCH ESO INS MOS13 POS = -3.000037e+01 / Position of the slit 13 in mm. HIERARCH ESO INS MOS13 WIDTH = 2.997380e-01 / Width of the MOS slit 13 in mm. HIERARCH ESO INS MOS14 POS = -4.000010e+01 / Position of the slit 14 in mm. HIERARCH ESO INS MOS14 WIDTH = 3.001890e-01 / Width of the MOS slit 14 in mm. HIERARCH ESO INS MOS15 POS = -4.999995e+01 / Position of the slit 15 in mm. HIERARCH ESO INS MOS15 WIDTH = 2.998980e-01 / Width of the MOS slit 15 in mm. HIERARCH ESO INS MOS16 POS = -5.999965e+01 / Position of the slit 16 in mm. HIERARCH ESO INS MOS16 WIDTH = 2.992920e-01 / Width of the MOS slit 16 in mm. HIERARCH ESO INS MOS17 POS = -7.000008e+01 / Position of the slit 17 in mm. HIERARCH ESO INS MOS17 WIDTH = 3.001660e-01 / Width of the MOS slit 17 in mm. HIERARCH ESO INS MOS18 POS = -8.000004e+01 / Position of the slit 18 in mm. HIERARCH ESO INS MOS18 WIDTH = 3.000790e-01 / Width of the MOS slit 18 in mm. HIERARCH ESO INS MOS19 POS = -9.000012e+01 / Position of the slit 19 in mm. HIERARCH ESO INS MOS19 WIDTH = 3.002380e-01 / Width of the MOS slit 19 in mm. HISTORY SETHEAD 2.4 1998-09-04 14:49 PC001002 and PC002001 updated ARCFILE = 'TS1.1998-03-19T01:17:23.199.fits' / Archive File Name TEST_0 = 0 / test insert of keyword 0 TEST_1 = 1 / test insert of keyword 1 TEST_2 = 2 / test insert of keyword 2 TEST_3 = 3 / test insert of keyword 3 TEST_4 = 4 / test insert of keyword 4 TEST_5 = 5 / test insert of keyword 5 TEST_6 = 6 / test insert of keyword 6 TEST_7 = 7 / test insert of keyword 7 TEST_8 = 8 / test insert of keyword 8 TEST_9 = 9 / test insert of keyword 9 TEST_10 = 10 / test insert of keyword 10 TEST_11 = 11 / test insert of keyword 11 TEST_12 = 12 / test insert of keyword 12 TEST_13 = 13 / test insert of keyword 13 TEST_14 = 14 / test insert of keyword 14 TEST_15 = 15 / test insert of keyword 15 TEST_16 = 16 / test insert of keyword 16 TEST_17 = 17 / test insert of keyword 17 TEST_18 = 18 / test insert of keyword 18 TEST_19 = 19 / test insert of keyword 19 TEST_20 = 20 / test insert of keyword 20 TEST_21 = 21 / test insert of keyword 21 TEST_22 = 22 / test insert of keyword 22 TEST_23 = 23 / test insert of keyword 23 TEST_24 = 24 / test insert of keyword 24 TEST_25 = 25 / test insert of keyword 25 TEST_26 = 26 / test insert of keyword 26 TEST_27 = 27 / test insert of keyword 27 TEST_28 = 28 / test insert of keyword 28 TEST_29 = 29 / test insert of keyword 29 TEST_30 = 30 / test insert of keyword 30 TEST_31 = 31 / test insert of keyword 31 TEST_32 = 32 / test insert of keyword 32 TEST_33 = 33 / test insert of keyword 33 COMMENT FitsIO: added 1 block to header TEST_34 = 34 / test insert of keyword 34 TEST_35 = 35 / test insert of keyword 35 TEST_36 = 36 / test insert of keyword 36 TEST_37 = 37 / test insert of keyword 37 TEST_38 = 38 / test insert of keyword 38 TEST_39 = 39 / test insert of keyword 39 TEST_40 = 40 / test insert of keyword 40 TEST_41 = 41 / test insert of keyword 41 TEST_42 = 42 / test insert of keyword 42 TEST_43 = 43 / test insert of keyword 43 TEST_44 = 44 / test insert of keyword 44 TEST_45 = 45 / test insert of keyword 45 TEST_46 = 46 / test insert of keyword 46 TEST_47 = 47 / test insert of keyword 47 TEST_48 = 48 / test insert of keyword 48 TEST_49 = 49 / test insert of keyword 49 TEST_50 = 50 / test insert of keyword 50 TEST_51 = 51 / test insert of keyword 51 TEST_52 = 52 / test insert of keyword 52 TEST_53 = 53 / test insert of keyword 53 TEST_54 = 54 / test insert of keyword 54 TEST_55 = 55 / test insert of keyword 55 TEST_56 = 56 / test insert of keyword 56 TEST_57 = 57 / test insert of keyword 57 TEST_58 = 58 / test insert of keyword 58 TEST_59 = 59 / test insert of keyword 59 TEST_60 = 60 / test insert of keyword 60 TEST_61 = 61 / test insert of keyword 61 TEST_62 = 62 / test insert of keyword 62 TEST_63 = 63 / test insert of keyword 63 TEST_64 = 64 / test insert of keyword 64 TEST_65 = 65 / test insert of keyword 65 TEST_66 = 66 / test insert of keyword 66 TEST_67 = 67 / test insert of keyword 67 TEST_68 = 68 / test insert of keyword 68 COMMENT FitsIO: added 1 block to header TEST_69 = 69 / test insert of keyword 69 TEST_70 = 70 / test insert of keyword 70 TEST_71 = 71 / test insert of keyword 71 TEST_72 = 72 / test insert of keyword 72 TEST_73 = 73 / test insert of keyword 73 TEST_74 = 74 / test insert of keyword 74 TEST_75 = 75 / test insert of keyword 75 TEST_76 = 76 / test insert of keyword 76 TEST_77 = 77 / test insert of keyword 77 TEST_78 = 78 / test insert of keyword 78 TEST_79 = 79 / test insert of keyword 79 TEST_80 = 80 / test insert of keyword 80 TEST_81 = 81 / test insert of keyword 81 TEST_82 = 82 / test insert of keyword 82 TEST_83 = 83 / test insert of keyword 83 TEST_84 = 84 / test insert of keyword 84 TEST_85 = 85 / test insert of keyword 85 TEST_86 = 86 / test insert of keyword 86 TEST_87 = 87 / test insert of keyword 87 TEST_88 = 88 / test insert of keyword 88 TEST_89 = 89 / test insert of keyword 89 TEST_90 = 90 / test insert of keyword 90 TEST_91 = 91 / test insert of keyword 91 TEST_92 = 92 / test insert of keyword 92 TEST_93 = 93 / test insert of keyword 93 TEST_94 = 94 / test insert of keyword 94 TEST_95 = 95 / test insert of keyword 95 TEST_96 = 96 / test insert of keyword 96 TEST_97 = 97 / test insert of keyword 97 TEST_98 = 98 / test insert of keyword 98 TEST_99 = 99 / test insert of keyword 99 TEST_100= 100 / test insert of keyword 100 TEST_101= 101 / test insert of keyword 101 TEST_102= 102 / test insert of keyword 102 TEST_103= 103 / test insert of keyword 103 COMMENT FitsIO: added 1 block to header TEST_104= 104 / test insert of keyword 104 TEST_105= 105 / test insert of keyword 105 TEST_106= 106 / test insert of keyword 106 TEST_107= 107 / test insert of keyword 107 TEST_108= 108 / test insert of keyword 108 TEST_109= 109 / test insert of keyword 109 TEST_110= 110 / test insert of keyword 110 TEST_111= 111 / test insert of keyword 111 TEST_112= 112 / test insert of keyword 112 TEST_113= 113 / test insert of keyword 113 TEST_114= 114 / test insert of keyword 114 TEST_115= 115 / test insert of keyword 115 TEST_116= 116 / test insert of keyword 116 TEST_117= 117 / test insert of keyword 117 TEST_118= 118 / test insert of keyword 118 TEST_119= 119 / test insert of keyword 119 TEST_120= 120 / test insert of keyword 120 TEST_121= 121 / test insert of keyword 121 TEST_122= 122 / test insert of keyword 122 TEST_123= 123 / test insert of keyword 123 TEST_124= 124 / test insert of keyword 124 TEST_125= 125 / test insert of keyword 125 TEST_126= 126 / test insert of keyword 126 TEST_127= 127 / test insert of keyword 127 TEST_128= 128 / test insert of keyword 128 TEST_129= 129 / test insert of keyword 129 TEST_130= 130 / test insert of keyword 130 TEST_131= 131 / test insert of keyword 131 TEST_132= 132 / test insert of keyword 132 TEST_133= 133 / test insert of keyword 133 TEST_134= 134 / test insert of keyword 134 TEST_135= 135 / test insert of keyword 135 TEST_136= 136 / test insert of keyword 136 TEST_137= 137 / test insert of keyword 137 TEST_138= 138 / test insert of keyword 138 COMMENT FitsIO: added 1 block to header TEST_139= 139 / test insert of keyword 139 TEST_140= 140 / test insert of keyword 140 TEST_141= 141 / test insert of keyword 141 TEST_142= 142 / test insert of keyword 142 TEST_143= 143 / test insert of keyword 143 TEST_144= 144 / test insert of keyword 144 TEST_145= 145 / test insert of keyword 145 TEST_146= 146 / test insert of keyword 146 TEST_147= 147 / test insert of keyword 147 TEST_148= 148 / test insert of keyword 148 TEST_149= 149 / test insert of keyword 149 TEST_150= 150 / test insert of keyword 150 TEST_151= 151 / test insert of keyword 151 TEST_152= 152 / test insert of keyword 152 TEST_153= 153 / test insert of keyword 153 TEST_154= 154 / test insert of keyword 154 TEST_155= 155 / test insert of keyword 155 TEST_156= 156 / test insert of keyword 156 TEST_157= 157 / test insert of keyword 157 TEST_158= 158 / test insert of keyword 158 TEST_159= 159 / test insert of keyword 159 TEST_160= 160 / test insert of keyword 160 TEST_161= 161 / test insert of keyword 161 TEST_162= 162 / test insert of keyword 162 TEST_163= 163 / test insert of keyword 163 TEST_164= 164 / test insert of keyword 164 TEST_165= 165 / test insert of keyword 165 TEST_166= 166 / test insert of keyword 166 TEST_167= 167 / test insert of keyword 167 TEST_168= 168 / test insert of keyword 168 TEST_169= 169 / test insert of keyword 169 TEST_170= 170 / test insert of keyword 170 TEST_171= 171 / test insert of keyword 171 TEST_172= 172 / test insert of keyword 172 TEST_173= 173 / test insert of keyword 173 COMMENT FitsIO: added 1 block to header TEST_174= 174 / test insert of keyword 174 TEST_175= 175 / test insert of keyword 175 TEST_176= 176 / test insert of keyword 176 TEST_177= 177 / test insert of keyword 177 TEST_178= 178 / test insert of keyword 178 TEST_179= 179 / test insert of keyword 179 TEST_180= 180 / test insert of keyword 180 TEST_181= 181 / test insert of keyword 181 TEST_182= 182 / test insert of keyword 182 TEST_183= 183 / test insert of keyword 183 TEST_184= 184 / test insert of keyword 184 TEST_185= 185 / test insert of keyword 185 TEST_186= 186 / test insert of keyword 186 TEST_187= 187 / test insert of keyword 187 TEST_188= 188 / test insert of keyword 188 TEST_189= 189 / test insert of keyword 189 TEST_190= 190 / test insert of keyword 190 TEST_191= 191 / test insert of keyword 191 TEST_192= 192 / test insert of keyword 192 TEST_193= 193 / test insert of keyword 193 TEST_194= 194 / test insert of keyword 194 TEST_195= 195 / test insert of keyword 195 TEST_196= 196 / test insert of keyword 196 TEST_197= 197 / test insert of keyword 197 TEST_198= 198 / test insert of keyword 198 TEST_199= 199 / test insert of keyword 199 TEST_200= 200 / test insert of keyword 200 TEST_201= 201 / test insert of keyword 201 TEST_202= 202 / test insert of keyword 202 TEST_203= 203 / test insert of keyword 203 TEST_204= 204 / test insert of keyword 204 TEST_205= 205 / test insert of keyword 205 TEST_206= 206 / test insert of keyword 206 TEST_207= 207 / test insert of keyword 207 TEST_208= 208 / test insert of keyword 208 COMMENT FitsIO: added 1 block to header TEST_209= 209 / test insert of keyword 209 TEST_210= 210 / test insert of keyword 210 TEST_211= 211 / test insert of keyword 211 TEST_212= 212 / test insert of keyword 212 TEST_213= 213 / test insert of keyword 213 TEST_214= 214 / test insert of keyword 214 TEST_215= 215 / test insert of keyword 215 TEST_216= 216 / test insert of keyword 216 TEST_217= 217 / test insert of keyword 217 TEST_218= 218 / test insert of keyword 218 TEST_219= 219 / test insert of keyword 219 TEST_220= 220 / test insert of keyword 220 TEST_221= 221 / test insert of keyword 221 TEST_222= 222 / test insert of keyword 222 TEST_223= 223 / test insert of keyword 223 TEST_224= 224 / test insert of keyword 224 TEST_225= 225 / test insert of keyword 225 TEST_226= 226 / test insert of keyword 226 TEST_227= 227 / test insert of keyword 227 TEST_228= 228 / test insert of keyword 228 TEST_229= 229 / test insert of keyword 229 TEST_230= 230 / test insert of keyword 230 TEST_231= 231 / test insert of keyword 231 TEST_232= 232 / test insert of keyword 232 TEST_233= 233 / test insert of keyword 233 TEST_234= 234 / test insert of keyword 234 TEST_235= 235 / test insert of keyword 235 TEST_236= 236 / test insert of keyword 236 TEST_237= 237 / test insert of keyword 237 TEST_238= 238 / test insert of keyword 238 TEST_239= 239 / test insert of keyword 239 TEST_240= 240 / test insert of keyword 240 TEST_241= 241 / test insert of keyword 241 TEST_242= 242 / test insert of keyword 242 TEST_243= 243 / test insert of keyword 243 END €¾€¼€½€Â€Ã€»€Â€Ê€× …ÁwÈTµ(…1€ü€Ì€Æ€Ä€¿€Á€Â€Ã€Á€»€½€½€½€Ä€Á€Á€È€ÓtÁ,ÈÚ´r…M€ú€Ñ€Ë€¾€Á€Ä€¹€¹€¿€¾€¼€¹€¿€¿€Å€Æ€Ç€Ò €Á"ȉ´í…€ï€Õ€È€Å€¿€Ã€½€½€Å€½€¾€¿€¿€Ä€Ã€Å€È€Ñ~Á²È¦´Ä…7€ù€Ò€Ä€Á€Å€¿€Â€¾€À€½€¿€¿€Â€½€Á€É€É€Ó ŽÂÈY´ƒ…"€ï€Ö€Ê€É€Â€Æ€»€Ã€À€¾€»€¾€¾€¿€¿€Å€Ì€ÒJÁ‹È±´Ç…@€å€Ô€Í€Æ€Á€Â€À€¿€À€·€º€»€Á€½€À€Æ€Ì€Õ5ÁÈm´Ì…@€ò€Í€Â€Á€Æ€Â€Ç€½€½€¹€½€½€¹€º€Ä€½€Í€ÓAÀÜÈ7´Q…=€ð€Ï€Ç€Å€¿€Ä€»€À€À€¼€Â€¾€Â€¿€Â€À€Ë€Ô MÀàȯ´/…€ô€Ø€Æ€È€À€Á€¾€¿€À€º€¸€¾€À€¼€Ã€Á€È€ÚZÁÈf´\„ý€ô€Ð€Ç€½€Ã€¿€¾€Ã€Ä€·€»€½€¾€¼€½€È€È€Ê7ÁWÇì´…€ù€Ë€É€Æ€Ã€À€¼€½€¾€Á€¼€¼€Á€À€½€Â€Æ€Õ„ÁÈg´(…#€ñ€Ï€Æ€À€Á€»€¾€Á€½€¾€»€¾€¾€À€¾€Æ€Æ€ÕFÁ@Èâ´…:€í€Ï€Ë€À€Ç€Á€¼€½€½€¿€½€½€À€À€¾€Ä€É€ÓvÁ"ÈÔ´W… €î€Ñ€Å€Ä€Å€Â€Á€¿€º€½€Â€»€¾€½€¿€È€É€Ñ ?À¶Èt´ …€ó€Ú€Ë€Á€À€Â€¿€À€½€¿€½€º€½€Á€¿€À€Ç€ÛZÁmȯ³Ý… €ë€Î€¿€É€¾€¿€¿€¿€¾€Â€»€Á€¼€½€¿€Â€Ì€Õ"Â-Ȱ³±…€ø€Ì€Â€À€¾€À€¼€Ä€¹€À€»€Á€Á€½€À€Ê€Æ€Ñ ƒÁÈö³ä…,€ó€Ó€Æ€Á€Æ€¿€Á€½€º€¸€¼€¼€Á€Ä€½€Æ€É€ÍNÁ­Èí´%…&€ñ€Ê€È€¾€À€À€½€½€¿€½€À€¾€Ã€Å€Â€Å€Â€Õ DÁéÈÙµ …<€ô€Ë€Ê€À€À€Â€À€º€»€½€Á€º€Ã€¼€Â€Æ€È€Î;À«È…´w…C€ï€Ë€È€Æ€½€À€½€Á€¾€¾€¾€½€½€½€¿€Ç€Í€ÓŒÝÁ˜È<´E…;€ë€Ë€Â€Ä€»€È€Ä€½€½€¹€¹€¾€¹€Ä€Æ€À€Å€ÕIÀàÈÏ´Q…#€ð€Ï€Æ€Æ€À€Á€Â€º€Å€½€¼€º€¿€Á€¿€Á€Ë€ÕvÁÈ¿´m…*€ð€Õ€Å€Å€À€À€½€¿€¾€¼€»€½€¾€¼€Æ€É€×€û¦ŽRÁæÉ´º…€ö€Ï€È€Á€Ã€Ã€¹€Â€½€½€¾€À€»€º€½€Ü„¯î©WÆÉ@¶Ê‡e¤€í€Ë€Ç€Á€Á€½€¿€¼€½€À€»€º€Ä€Ã€Ï7‰Ü¦ÀÚÈFȘÀhŸ7ˆ2K€Õ€Á€Á€Â€º€Á€»€¾€¼€¸€½€À€·€È‰s¢„¶Õ¼³¼<¶ß¡ê‰b€Ô€Æ€¼€¼€¾€¹€¸€º€¼€¸€»€¾€½€É€òƒNŠ>Ò‘Ö‘Ÿ„‰ªƒ9€Ë€Å€Â€¼€º€¿€¹€¼€½€º€Â€À€¼€Â€Ç;‚„ƒ·„„ƒ‚E0€×€Ã€¾€¹€¿€À€¼€¾€¼€·€½€Á€¹€¼€»€É€à7ƒ·Ì¿€Ö€Â€Å€Á€½€½€º€À€»XTENSION= 'BINTABLE' / binary table extension BITPIX = 8 / 8-bit bytes NAXIS = 2 / 2-dimensional binary table NAXIS1 = 4021 / width of table in bytes NAXIS2 = 100 / number of rows in table PCOUNT = 0 / size of special data area GCOUNT = 1 / one data group (required keyword) TFIELDS = 3 / number of fields in each row TTYPE1 = 'Avalue ' / label for field 1 TFORM1 = '20A ' / data format of field: ASCII Character TTYPE2 = 'Lvalue ' / label for field 2 TFORM2 = '1L ' / data format of field: 1-byte LOGICAL TUNIT2 = 'm**2 ' / physical unit of field TTYPE3 = 'Evalue ' / label for field 3 TFORM3 = '1000E ' / data format of field: 4-byte REAL TUNIT3 = 'cm ' / physical unit of field EXTNAME = 'iter_test' / name of this binary table extension END changed to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to true Tchanged to false Fchanged to false Fchanged to false Fchanged to false Fchanged to false Fskycat-3.1.2-starlink-1b/bootstrap000077500000000000000000000030701215713201500171000ustar00rootroot00000000000000#!/bin/sh #****************************************************************************** # European Southern Observatory / Data Management and Operations Division # Data Flow System department # "@(#) $Id: bootstrap,v 1.1 2010/07/01 15:40:17 cguirao Exp $" #****************************************************************************** # ############################################################################# # HEADER # ############################################################################# # ------- # CHANGES # ------- # WHO WHAT WHEN WHERE # cguirao created 2006/02/20 1_0 # # ------------------- # GENERAL DESCRIPTION # ------------------- # Bootstrap script for packages with Autotools. # The execution of this script generates the Autotools scripts (i.e. configure) # To be executed after a complet check-out of project from CVS # and after the execution of a "make clean-maintainer" # ############################################################################# # MAIN # ############################################################################# # This is to filter out annoying messages. But it failed to exit with the # same error code #autoreconf -i -s --force 2>&1 | egrep -v "libgcrypt.m4:23" | egrep -v "Extending" | egrep -v "ao.m4:9" autoreconf -i -s --force >/dev/null 2>&1 result=$? if [ $result -ne 0 ]; then echo "bootstrap: \"autoreconf -i -s --force\" failed." echo "bootstrap: execute it by hand to get more info" fi exit $result skycat-3.1.2-starlink-1b/cat/000077500000000000000000000000001215713201500157045ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/cat/CHANGES000066400000000000000000001020011215713201500166710ustar00rootroot00000000000000CHANGES to the "catlib" Catalog Interface Library ------------------------------------------------- This file contains a list of changes to the "catlib" libraries. The latest changes are at the top. --------------- 20.10.08 released catlib-4.1.0 ----------------- * Fixes for gcc version 4.2.4. --------------- 03.02.06 released catlib-4.0 ------------------- * Major update: see top level CHANGES file. --------------- 20.01.03 released cat-3.7.4 ----------------- * Ported to gcc-3.2.1 and Tcl-8.4.1 --------------- 27.02.02 released catlib-3.7.3 ----------------- * Fixed problem with temporary downloaded image files being deleted too soon. (Now they are only deleted after they are loaded, so that the OS can delete them later on.) --------------- 27.08.01 released catlib-3.7.2 ----------------- * Merged in minor changes from Peter Biereichel (added some #include files). --------------- 17.02.01 released catlib-3.7.1 ----------------- * Fixed a bug that occurred when a catalog config entry had a copyright field but no x,y or ra,dec columns defined. --------------- 20.09.00 released catlib-3.7 ----------------- * Added changes to support galactic and ecliptic coordinates (pass equinox as a string instead of a double, where the value may be a number (2000, 1950, ...) or a coordinate system name ("FK5, "GALACTIC", ...). --------------- 02.03.00 released catlib-3.6 ----------------- * TclAstroCat.C::queryCmd: now returns a TCL_ERROR if a table row does not contain a valid coordinate position when it should. The previous versions tried to continue, but the error message overwrote the result of the query (in the Tcl result). --------------- 25.10.99 released catlib-3.5 -------------------- * Merged in changes made by Peter Biereichel --------------- 09.09.99 released catlib-3.4.1 -------------------- * Updated for egcs/gcc-2.95. --------------- 22.07.99 released catlib-3.4 ---------------------- * TCS catalogs: fixed a bug dealing with TCS catalogs (error message was "empty TCS result"). The problem was caused by adding an extra parameter to the init() method in the base class (TabTable), but not in the derived class (TcsQueryResult), so that inheritance did not work as expected. * Fixed problem with catalog directory hierarchies. Previously, catalog names had to be unique in the entire catalog hierarchy. Now, the interface has been changed slightly to fix this. A catalog directory argument may now be either a name, as before, or a tcl list of catalog directories, forming a path to the catalog's parent directory. Also, catalogs are now searched for only in the given directory, not recursively down the tree. The "astrocat open" command now also takes an optional directory argument, so that you can open a catalog in a specific directory. The changes are all backward compatible, except for one: there is no more recursive search for catalogs in the tree. However, it is not likely that this feature was used. --------------- 21.06.99 released catlib-3.3.3 ---------------------- * TclAstroCat.C: allow empty RA and DEC columns in query results where ra_col and dec_col are defined (previously an error mesage was generated: "error in RA value, expected HH:MM:SS"). --------------- 22.03.99 released catlib-3.3.2 ---------------------- * Replaced itclsh2.2 with itclsh@ITCL_VERSION@ in Makefile.in. * Fixed a potential bug in the handling of local catalogs. "mmap" was being used to read the catalog file and the resulting string was not always null terminated. Now class LocalCatalog makes a null terminated copy and passes it to class TabTable, which reuses it instead of making a copy of it again. --------------- 28.12.98 released catlib-3.3.1 ---------------------- * Rebuild tclIndex file whenever configure is run, since Tcl8 version is not compatible with tcl7 version (see makelinks script). * TcsCatalog.h: fixed problem with hidden virtual methods reported by the sunpro CC compiler. --------------- 16.11.98 released catlib-3.3 ---------------------- * Ported to tcl8.0.3 (still compatible with tcl7.6/tk4.2/BLT2.1) - Updated namespace syntax and BLT graph handling * Local catalog files starting with "/tmp/" are no longer written to the ~/.skycat/skycat.cfg file. --------------- 30.9.98 released catlib-3.2.2 ---------------------- * Changed the release structure of the catlib package to include the necessary utility packages. Now the catlib tarfile also contains the astrotcl and tclutil packages. The top level Makefile and configure script automatically determine which packages to make. * Fixed a problem dealing with temporary image files and mmap (The fix in the previous version was not working). * Fixed minor bug in TclAstroCat.C::saveCmd() (when the headings argument is not specified). * Added a "History" menu item in the Data-Servers menu for displaying the new image history catalog. --------------- 23.9.98 released catlib-3.2.1 ---------------------- * Fixed minor bugs in test programs, updated docs, updated C interface, added comments indicating that the astroImage interface is obsolete and that the astroCatalog interfaces should be used instead. * Fixed a bug introduced in the previous version. The temp file for images from image servers was being reused instead of using a new file each time, which caused problems with the display that had the file mapped. * Changed the error handling for empty catalogs so that a catalog with no headings (and no dashed line after the heading) is not considerred an error, but just an empty catalog. --------------- 7.9.98 released catlib-3.2 ---------------------- * Fixed a bug dealing with catalog name servers (SIMBAD, NED) introduced in the previous version. * Removed default for limit on number of rows returned from a catalog query (%n in URL). * Merged the image server interfaces with the catalog interfaces. The AstroImage and TclAstroImage classes, and the astroimage Tcl command are still available for backward compatibility, but are now obsolete and should no longer be used. The AstroCatalog and TclAstroCat classes, and the astrocat Tcl command now handle image servers as well as catalogs. The "getimage" methods/subcommands are now part of the catalog classes. The merge was made to avoid duplicating large chunks of code, since there are many similarities in the two interfaces. * Now it is possible to generate image server windows with custom search labels and without the default search widgets (name, ra, dec, radius). This was previously only supported for catalogs. In both cases, if you don't want the default search widgets, add these lines to the config entry: ra_col: -1 dec_col: -1 x_col: -1 y_col: -1 For catalogs, this means that there are no searchable ra,dec or x,y columns. For image servers, it means that you can't search by these values, so they are not displayed. * Catalog config file: Allow search columns with only one value (previously only min and max values were allowed). This feature is enabled if the second label is missing in the "search_cols: " keyword in the catalog config file. For example, in an image server: search_cols: patch Patch will display a "Patch:" label and entry in the user interface. In the URL for the image server, "%cond" will then be replaced by "patch=22", if the user typed in 22. * Fixed the handling of the "maxRows" field for searching catalogs, so that, if it is left blank or zero, there is no limit (previous versions had a default limit). --------------- 5.8.98 released catlib-3.1.18 ---------------------- * AstroCatalog.C:getPreview() Added code to check the the HTTP Content-Encoding of image files (instead of only the Content-type), to help recognize compression types. * TclAstroCat.C, TclAstroImage.C: added "authorize" subcommands to set username and password for HTTP access after an HTTP server returns an "Authorization Required" error. This can be used together with the tclutil/PasswdDialog widget to ask for the username and password for an HTTP service. * AstroCat.tcl, AstroImage.tcl: added a check for a special authorization error message returned from an HTTP GET. A password dialog is displayed where the user can type in the username and password for the HTTP service (first time only). * AstroImage: added support for backup URLs for image servers (was previously only supported for catalogs). This is activated by using the "backup1" and "backup2" keywords in the catalog config file. * "Reload Config File" now works recursively and reloads the information in any remote catalog directories that were open. Previously, only the top level catalogs were reloaded. * Added the X11 library directory to shared lib path in startup script. * Fixed a bug in TabTable.C where the "id" column was still assumed to be always 0. Now the id column index is given as a parameter (taken from catalog config file). * Changed the way that rows are inserted into local catalogs. They were previously appended to the end of the file after removing duplicates. Now the original row position is kept and the row is updated if it already exists (same id) and appended otherwise. (Changed TabTable::insert()). * The catalog and image server windows were using up too many file descriptors (1 each for a log file and 2 each for an HTTP feedback pipe) and in one case, the log file was being opened, but not closed, so that you could eventually run out of fds. Now the pipe and log file are only opened as needed and closed again immediately. --------------- 07.07.98 released catlib-3.1.17 ---------------------- * AstroCat.tcl: Fixed minor debugging problem: propagate -debug flag to AstroQuery.tcl. * QueryResult.C: allow local catalog search without ra,dec columns * CatalogInfo.C: fixed handling of default column positions for ra and dec, to allow catalogs with no ra,dec or x,y columns. --------------- 26.6.98 released catlib-3.1.16 ---------------------- * TcsCatalogObject.h: removed unused method "isNull(int v)", to avoid error message from egcs-1.0.3 compiler about value being too large for int. * AstroCat.tcl, ProxyDialog.tcl: added a menu (under Options) and dialog window for setting a proxy server for HTTP catalog access from behind a firewall. --------------- 19.6.98 released catlib-3.1.15---------------------- * TclQueryUtil.C: Minor change in the way query coordinates are interpreted. If the RA value is an integer, it is assumed to be in hours (as before), but if it is a decimal number (3.2, for example), it is assumed to be in degrees. * AstroCat.tcl: fixed bug in the handling of the MORE URL (mostly used for HST catalogs). The "M=" part before the URL was not being recognized. --------------- 28.5.98 released catlib-3.1.14---------------------- * AstroCat.tcl: MORE and PREVIEW fields can now be commands. No special check is made for "http://" or "file://" as before. * AstroCatalog.C: added check for "SIMPLE" keyword in PREVIEW result, in case the PREVIEW URL is a command and there is no mime-type. * AstroCat.tcl: "Data-Servers/Local catalogs" menu: Added check for local catalogs, to see if the file exists. If not, you are asked if you want to specify a new name or remove the catalog from the menu. * TclAstroCat.C: Minor change in handling of equinox to default to "2000" for galactic or ecliptic coords. * AstroImage.tcl: added "Select Area..." button to AstroImage window to select the area of the image to fetch (as with the catalog window). --------------- 13.5.98 released catlib-3.1.13---------------------- * Added a "help" field to the catalog config file, which may optionally contain a URL pointing to information about the catalog. If the "help" URL is specified, a "Help" button appears in the user interface, which displays the URL in netscape (using the remote interface, if netscape is already running). Changes in AstroCat.tcl, AstroImage.tcl, TclAstroCatalog.[Ch], CatalogInfo.[Ch], TclAstroImage.[Ch]. * Fixed problem with "Preview" images that was caused by using the same temporary file to hold the image each time (now uses a new file each time and deletes the old one). --------------- 4.5.98 released catlib-3.1.12---------------------- * CatalogInfo.C: Fixed the "reload()" method ("Reload Config File") to remove "dead" catalog entries (entries that were removed from the config file since the last time it was read). --------------- 28.4.98 released catlib-3.1.11 --------------------- * Fixed minor bugs in AstroCat.tcl::get_table and get_equinox (was using wrong component name) * AstroCat (catalog window) layout: removed some padding to save space. --------------- 15.4.98 released catlib-3.1.10 --------------------- * (doc, *.tcl): For documenting the "public interface": Updated comments on all Itk component declarations and added "public", "private" and "protected" keywords in the source to help identify the public interface, which is documented in man pages generated from the source by the itcldoc utility (tclutil package). * AstroImage.tcl: Clear image before loading a new image (to avoid problems with decompression and temp files). * Minor changes in configure script and top level makefile for shared libraries * Fixed some bugs added in recent releases (printing query results, setting search columns). --------------- 25.03.98 released catlib-3.1.9 --------------------- * Updated man pages and documentation --------------- 25.03.98 released catlib-3.1.8 --------------------- * Removed declaration for strcasecmp in TabTable.C, since it reportedly conflicted with system definitions in dec alpha. * Added "clone" number to window headers, to help identify related windows when there is more than one main window. --------------- 05.03.98 released catlib-3.1.7 --------------------- * Added short help message for plot symbols * For backward compatibility: Removed dependence on the Tix package (now part of tclutil package). * For backward compatibility with applications using the cat library: The dependency on the astrotcl and tclutil packages is now hidden from applications. libcat.a (.so, .sl, etc.), now contains the astrotcl and tclutil object files, the $prefix/include/cat dir contains copies of the astrotcl and tclutil header files, and the Cat_Init() routine also initializes these packages as well as the Tix package, which is now also included in the tclutil package. --------------- 13.2.98 released catlib-3.1.6 --------------------- * Minor change: removed AstroCat::list_windows method, since no longer needed. --------------- 9.2.98 released catlib-3.1.5 --------------------- * Fixed minor problems with test programs --------------- 3.2.98 released catlib-3.1.4 --------------------- * Added a default mag range of (0..15) for gsc-server only, as a temporary special case until the gsc-server is modified to allow the magnitude to be empty, (i.e.: "mag=," instead of "mag=0,15"). gsc-server doesn't accept a negative mag value, so it doesn't help to set the default range to (-99..99) or some arbitrary range. --------------- 25.01.98 released catlib-3.1.3 --------------------- * Updated comments in Itcl sources for automatic generation of man pages. (There are now man pages for all Itcl classes). * Split the "top level" AstroCat class into different "frame" classes, by request. Now the AstroCat class is made up of an AstroQuery class (defines the panel with the search entries) and the QueryResult class (defines the table for displaying the query results). None of these classes knows about images. For image support, see the Skycat package, which contains classes that are derived from these and add image support. * Added additional plot symbols: arrow, line, compass, ellipse. These (and the "plus" symbol) are all rotated relative to world coordinate "north", if it is known. --------------- released catlib-3.1.2 --------------------------- * Fixed PreviewPlot class (used to plot HST preview data). (Was out of date after upgrade to BLT-2.1). * Split AstroCat class to remove dependence on Skycat. All image related operations, such as plotting objects on an image, are now done in a subclass in the Skycat package. * Catalog config entry: If ra_col, dec_col, x_col, and y_col are all set, then the catalog is assumed to have both ra,dec and x,y columns in the query output. In this case, allow searching by ra,dec, but plot the results using x,y (image coords). (Requested by awicenec@eso.org, for cases where WCS info is incorrect, but x,y coordinates are OK). * Compilied sources with the SunPRO C++ compiler and fixed problems that showed up there and not with gcc. * Reorganized sources: The catalog library is no longer dependent on the RTD package. It is now dependent on two new packages: The Tclutil package was created by gathering "generic" Tcl and C++ code from various applications into a single generic Tcl package. The Astrotcl package was created by gathering general astronomy related Tcl and C++ code from other packages into a single, reusable package. If you were previously loading the Cat and Rtd packages dynamically, you will need to add "package require" statements for the Tclutil and Astrotcl packages, and remove the reference to Rtd, if you don't need Rtd image support. If you were linking the packages statically, you will need to add calls to Tclutil_Init and Astrotcl_Init in tkAppInit.C, and remove the call to Rtd_Init, if you don't need the Rtd image features. If you were using the catalog C++ classes directly, you will need to add some -I compiler options to your Makefiles: (-I$(INSTALLDIR)/astrotcl -I$(INSTALLDIR)/tclutil). The C interface is not affected by this. * The Itcl catalog widgets (AstroCat, AstroImage, etc.) are now a part of the cat package (They were previously part of the skycat package). --------------- 3 Nov 97 released catlib-3.0 ---------------------- * Added support for catalog directories via the new keyword "directory" in the catalog config file. An entry with "serv_type" equal to "directory" should have in the "url" field a URL pointing to another catalog config file. The catalog list is stored as a hierarchical list of catalog entries. New methods and Tcl subcommands have been added to navigate the hierarchy. * Added support for specifying search and sort columns, sort order, column display order, columns to hide or show (see below). * Config file: added new keywords: is_tcs: boolean value indicates whether catalog is a TCS catalog search_cols: list of columns that can be searched sort_cols: list of columns to sort by sort_order: "increasing" or "decreasing" - tells how to sort. show_cols: list of columns to display (default all). Indicates the order of the columns and which ones to show or hide. * Config File: extended the meaning of the "symbol" entry to include information about the color, shape, angle, size and units of plot symbols. New syntax: symbol: colnames symbol sizeexpr : colnames symbol sizeexpr : ... where colnames - is a list of column names used as variables in the entry symbol - is the symbol to use, one of: square, circle, triangle, cross, plus, diamond, elipse. The symbol may also be a list such as {circle yellow} and some symbols take extra args for ratio and angle (elipse, plus), which may be expressions using column names as variables. sizeexpr - is an expression in terms of colnames above, used to determine the size of the symbol. It may also be a list {expr units}, where units is one of {image "deg J2000" "deg B1950"} (default: image, for image pixel coords, see RTD doc for coordinate syntax). The column names can be used as variables in the expression using "$" (following Tcl syntax). examples: symbol: mag circle 15-$mag : xyz square (1-$xyz)*2.5 symbol: {a/b pa mag} {ellipse yellow ${a/b} $pa} {15-$mag} symbol: "a/b pa mag" "ellipse yellow ${a/b} $pa" "15-$mag" * Tcl interface: added new astrocat Tcl subcommands: $cat entry get ?name? ?directory? $cat entry update $info ?name? ?directory? $cat entry add $info ?directory? $cat entry remove $name The entry subcommand can be used to navigate and edit the catalog config information. $cat reload Reload the catalog config file. Use this if the config file was edited and you want to access the new info. $cat sortcols $cat sortorder $cat showcols $cat searchcols Get or set the values of these new keywords in the catalog config file. $cat root Returns the name of the root catalog directory. * Tcl interface: Added options to astrocat Tcl subcommand to support catalog directories. New usage: $cat info $serv_type ?$directory? * C++ interface: - class CatalogInfo: added methods for dealing with catalog directories appending, updating, removing entries, reloading the config file. The file ~/.skycat/skycat.cfg is no longer referenced in this lib (skycat does a "setenv CATLIB_CONFIG ~/.skycat/skycat.cfg" on startup). $SKYCAT_CONFIG is still supported, but $CATLIB_CONFIG is preferred. - class CatalogInfoEntry: added new members for new catalog config keywords, added a "link" member for directory entries, added append() method. - TcsCatalog classes: added code to handle the new ra_col and dec_col changes. * catalog URLs (entries in the config file) may now be local commands as well as file:/ and http:/ entries. If the URL starts with a / and is the name of a local file AND the config file is also local the command will be executed with the given arguments and the result should be a standard query result in tab table format. Substitution is performed on the arguments in the same way as for the http:/ and file:/ entries (%ra for ra, etc...). * Added code to support catalogs in either World coordinates or image coordinates (previously only World Coordinates were supported). A catalog is considerred to be in World Coords by default unless the keywords "x_col" and "y_col" are used (see below). * The catalog library now allows catalogs with varying column order. Previously catalogs were required to have the first 3 columns "id", "ra", and "dec". This is now the default behaviour, but may be overridden with the keywords: "id_col", "ra_col", and "dec_col" in the catalog config file or the header of the search results or local catalog. For example: serv_type: catalog long_name: My test catalog server ... id_col: 6 ra_col: 0 dec_col: 1 Or if the catalog is using image coords instead of World coords: id_col: 6 x_col: 0 y_col: 1 * Catalog config information is now read from query results as well as from the catalog config file and local catalog headers. --------------- 24 April 97 released catlib-2.9 ---------------------- * AstroCatalog: The methods getObject and searchClosestStar (and the C versions acGetObject and acSearchClosestStar) no longer return an error if the object is not found (requested by mcomin). Updated the man pages to state this. *** NOTE: This is a change in behavior from the previous versions *** * Minor changes to man pages to make args and return values more clear. * class AstroCatalog: added "%cond" to the list of variables that are substituted in the catalog config file URLs. This is needed in order to implement the "CatalogSearch()" method, which specifies a list of columns and min and max values to search for. %cond - insert search condition, if any, in the format col1:minVal:maxVal,col2:minVal:maxVal,... Note that there are not yet any catalog servers that use this field, so that the CatalogSearch() method will still not work, but this should change when the servers support this type of search. --------------- 22 April 97 released catlib-2.8 ---------------------- * More minor changes in the configure scripts and makefiles for dealing with shared libraries on HP. * allow mag to be negative (was previously not allowed) in catalog searches. * added this text to the man pages AstroCatalog.man3 (C++ version) and astroCatalog.man3 (C version) QUERY PARAMETERS Parameters for catalog searches are checked to make sure they are valid and in the correct range. A radius value must be between 0.0 and 300.0 arcmin. A magnitude may have any value. For ranges, such as min and max radius and min and max magnitude, the order of the arguments is not important, since they will be rearranged as needed. If both min and max values are 0.0, they are ignored for that search. * made minor changes to the INSTALL file and installation section of the frame docs. --------------- 11 Apr 97 released catlib-2.7 --------------------- * added support for shared libraries and loadable Tcl modules use: configure --enable-shared to create the shared library (libcat.so or libcat.sl). * changed the name of the Tcl init routine for the cat lib from TclAstroCat_Init to Cat_init, to comply with the standards for loadable modules in the new Tcl version (The old version is still supported for backward compat.) * changed the configure script and Makefiles to get information from the rtdConfig.sh script installed by Rtd and produce a catConfig.sh with more information, that can be used by other applications. (Rtd gets the info from tclConfig.sh, tkconfig.sh, etc...). * fixed bug in local catalog search when there is no "mag" column. Now the mag range is ignored if there is no mag column. --------------- 10 Feb 97 released catlib-2.6 --------------------- * fixed bug in local catalog search method (TabTable::search) * added error message for case where you search by ID, but the catalog URL doesn't support it, and when you search by RA,DEC and the URL doesn't support that. Note that the GSC now does support search by object ID, but the default catalog config file (http://archive.eso.org/skycat/skycat.cfg) doesn't include support for it yet, since it would break earlier skycat releases. You can fetch the above URL (with netscape) and look for the GSC entry, which has an alternative URL for GSC commented out. You can put the file in your ~/.skycat directory (named skycat.cfg) or set the environment variable SKYCAT_CONFIG or CATLIB_CONFIG to a URL pointing to the file (file:... or http:...). A future version of skycat will allow the user to build up a private catalog config file interactively. --------------- 30 Jan 97 released catlib-2.5 --------------------- * Added support for backup catalog servers and local catalog config files. The config file has 2 new keywords: "backup1" and "backup2". These are used if there is an error accessing the "url" field for the catalog. * Made changes to the handling of local catalogs to try to improve the performance. Local catalogs are kept entirely in memory now. --------------- 21 Nov 96 released catlib-2.4 --------------------- * Made configure scripts and sources Linux compatible. Thanks to Sidik Isani for supplying the patches for this. * (Catlib) It is now possible to search GSC by Id. --------------- 8 Nov 96 released as catlib-2.3, part of skycat 1.0.1 * Added copyright field to catalog config file and the CatalogInfo class. --------------- 7 Nov 96 released as catlib-2.2, part of skycat 1.0 * Fixed bug in impl. of AstroImage::getArea (where you specify 2 positions and want to get the objects in the box). Now the 2 positions are translated into a center position and radius (since none of the catalog server URLs currently have a place for 2 positions...). To do this, addded a method "WorldCoords::center()" to get the center pos and radius from 2 positions. * Fixed bug when saving local catalogs for images that are not J2000. (The catalog was saved as B1950, for example and later treated as J2000 when loaded). Now all local catalogs are saved (the ra,dec columns) in equinox J2000 and are expected to be in J2000 when opened. For this, an extra argument was added to some astrocat tcl subcommands: the "save" and "remove" commands now take an "equinox" optional argument that defaults to 2000. * Local catalogs: class QueryResult/TcsQueryResult: The catalog config file entry info is now written to local catalog headers. This is needed so you can determine what plot symbols and columns to use in skycat. The syntax is the same as in the catalog config file and the entry is used if it is found. * added rcs keywords as static constants to source files (for Giorgio). --------------- 1 Oct 96 released as catlib-2.0, part of skycat 1.0b12 --------------- 20 Sep 96 released as catlib-2.0b1, part of skycat 1.0b11 * the environment variable CATLIB_CONFIG is accepted instead of SKYCAT_CONFIG (they both have the same meaning: a URL pointing to the catalog config file with the default list of catalogs and their descriptions. * split the "./cat" directory into "./cat" (catalog libraries only) and "./skycat" (skycat application, interpreted and single binary versions), by request. Note that the catalog libraries still depend on two rtd libraries: libwcs.a (rtdwcs) and libutl.a (rtdutl). These are general purpose libraries for handling world coordinates and shared memory, etc. ---------------- 14 Aug 96 released as part of skycat-1.0b10 ------------------ * added bounds checking in catalog classes (catalog query), now enforces: 0 <= ra < 24 -90 <= dec <= 90 mag (no check, order so that min $@.result 2>&1 ;\ if cmp $@.result $(srcdir)/tests/$@.ok ;\ then echo "$@: PASSED" ; \ else echo "*** $@: TEST FAILED: see $@.result" ; \ fi rm test.table ctests: $(C_TEST_APPS) # The C interface tests need a C++ main, since the library contains C++ $(C_TEST_APPS): main.o FORCE $(COMPILE) -o $@ main.o $(srcdir)/tests/$@.c $(TEST_LIBS) $(LIBS) cp $(srcdir)/tests/test.table . -@@LD_LIBRARY_PATH_VAR@=@exec_prefix@/lib; export @LD_LIBRARY_PATH_VAR@ ;\ $@ > $@.result 2>&1 ;\ if cmp $@.result $(srcdir)/tests/$@.ok ;\ then echo "$@: PASSED" ; \ else echo "*** $@: TEST FAILED: see $@.result" ; \ fi rm test.table #======================================================================== # Run Tcl test cases #======================================================================== #tcltest: binaries libraries # (cd tests; sh all.tcl) FORCE: skycat-3.1.2-starlink-1b/cat/README000066400000000000000000000020131215713201500165600ustar00rootroot00000000000000 CAT, A Library for Accessing Astronomical Catalogs in C++, C and Tcl --------------------------------------------------------------------- This directory contains the source code for a set of libraries for accessing astronomical catalogs locally and over the network. The core is written in C++. In addition, Tcl and "plain" C interfaces are supported. For installation instructions, see the file INSTALL in the parent directory. See the CHANGES file in this directory for a list of recent changes. The following URLs may also be of interest: Skycat home page: http://archive.eso.org/skycat/ Sources and binaries: ftp://ftp.eso.org/pub/archive/skycat/README.html Postscript, PDF, and FrameMaker Documentation: ftp://ftp.eso.org/pub/archive/skycat/doc HTML Docs: http://archive.eso.org/skycat/docs/skycat-man.html -------------------------------------- Contacts: Allan Brighton (abrighto@eso.org) Peter Biereichel (pbiereic@eso.org) ESO - European Southern Observatory -------------------------------------- skycat-3.1.2-starlink-1b/cat/VERSION000066400000000000000000000000151215713201500167500ustar00rootroot00000000000000catlib-4.1.0 skycat-3.1.2-starlink-1b/cat/aclocal.m4000066400000000000000000000072041215713201500175470ustar00rootroot00000000000000builtin(include,../tclconfig/tcl.m4) AC_DEFUN(CAT_CONFIG, [ # Load the Tclutil definitions cf=../tclutil/tclutilConfig.sh if test -f $cf ; then . $cf AC_SUBST(tclutil_VERSION) AC_SUBST(tclutil_LIB_FILE) AC_SUBST(tclutil_BUILD_LIB_SPEC) AC_SUBST(tclutil_BUILD_DIR) AC_SUBST(tclutil_LIB_SPEC) AC_SUBST(BLT_LIB_SPEC) AC_SUBST(tclutil_SRC_DIR) AC_SUBST(tclutil_PKG_OBJECTS) AC_SUBST(CFITSIO_LIB_SPEC) else AC_MSG_ERROR([$cf doesn't exist]) fi # Load the Astrotcl definitions cf=../astrotcl/astrotclConfig.sh if test -f $cf ; then . $cf AC_SUBST(astrotcl_VERSION) AC_SUBST(astrotcl_LIB_FILE) AC_SUBST(astrotcl_BUILD_LIB_SPEC) AC_SUBST(astrotcl_BUILD_DIR) AC_SUBST(astrotcl_LIB_SPEC) AC_SUBST(astrotcl_SRC_DIR) AC_SUBST(astrotcl_PKG_OBJECTS) else AC_MSG_ERROR([$cf doesn't exist]) fi # ----------------------------------------------------------------------- # Optionally merge object and header files from dependent packages to make one master lib # ----------------------------------------------------------------------- MERGED=1 AC_ARG_ENABLE(merge, [AC_HELP_STRING([--enable-merge],[merge the contents of dependent packages into a master catalog library])], [MERGED=$enableval], [MERGED=no]) changequote(<<, >>) csources=`cd $srcdir; echo generic/*.[Cc]` changequote([, ]) cat_headers=`cd $srcdir; echo generic/*.h` astrotcl_headers=`cd $srcdir; echo ../astrotcl/{generic,press,libwcs,cfitsio}/*.h` tclutil_headers=`cd $srcdir; echo ../tclutil/generic/*.h` cat_includes="-I$srcdir/generic -I$srcdir/bitmaps" astrotcl_includes="-I$srcdir/../astrotcl/generic -I$srcdir/../astrotcl/cfitsio -I$srcdir/../astrotcl/libwcs" tclutil_includes="-I$srcdir/../tclutil/generic" cincludes="${cat_includes} ${astrotcl_includes} ${tclutil_includes}" tclsources=`cd $srcdir; echo library/*.tcl library/*.xpm` if test $MERGED = yes ; then echo "Will build merged master catalog library" cheaders="${cat_headers} ${astrotcl_headers} ${tclutil_headers}" MERGE_OBJECTS="$astrotcl_PKG_OBJECTS $tclutil_PKG_OBJECTS" dnl AC_DEFINE(MERGE_OBJECTS, 1, [merge the contents of dependent packages into a master catalog library]) else echo "Not making a merged master catalog library" cheaders="${cat_headers}" MERGE_OBJECTS="" fi AC_SUBST(MERGE_OBJECTS) # ----------------------------------------------------------------------- AC_DEFINE(USE_COMPAT_CONST, 1, [For compatibility between tcl8.4 and previous tcl releases]) #------------------------------------------------------------------------ # Check if we require additional libraries to support C++ shareable # libraries. system=`uname -s`-`uname -r` SHLIB_LD_CXX_LIBS="" export SHLIB_LD_CXX_LIBS case $system in SunOS-5*) SHLIB_LD_CXX_LIBS="-lCrun -lCstd" ;; OSF*) SHLIB_LD_CXX_LIBS="-lcxx -lcxxstd" ;; esac AC_SUBST(SHLIB_LD_CXX_LIBS) #------------------------------------------------------------------------- # The cxx C++ compiler under Tru64 UNIX needs the special # CXXFLAGS "-std gnu -D__USE_STD_IOSTREAM=1". These allow the standard # library streams headers to work and to generate templates that do # not require special handling throughout skycat directories (normally # template object files are created in various cxx_repository subdirectories, # this way the object files are kept embedded the usual object files, see # the cxx man page for details). #------------------------------------------------------------------------- export CXXFLAGS case $system in OSF*) case "x$CXX" in xcxx*) CXXFLAGS="$CXXFLAGS -g3 -std gnu -D__USE_STD_IOSTREAM=1" ;; esac ;; esac ]) skycat-3.1.2-starlink-1b/cat/bitmaps/000077500000000000000000000000001215713201500173435ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/cat/bitmaps/bitmaps.tcl000066400000000000000000000017201215713201500215060ustar00rootroot00000000000000#!../bin/rtdimage_wish # # E.S.O. - VLT project/ ESO Archive # # "@(#) $Id: bitmaps.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # script to generate C code declaring X bitmaps so that the (binary) application # doesn't have to be delivered with the bitmap files. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 21 Nov 95 Created puts { /* * E.S.O. - VLT project / ESO Archive * "@(#) $Id: bitmaps.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * Tk Bitmap/Pixmap definitions * * This file was generated by ../bitmaps/bitmaps.tcl - DO NO EDIT */ #include #include } puts "void defineCatBitmaps(Tcl_Interp *interp) {" foreach file [glob -nocomplain *.xbm] { set name [file rootname $file] puts " #include \"$file\"" puts " Tk_DefineBitmap(interp, Tk_GetUid(\"$name\"), (char*)${name}_bits, ${name}_width, ${name}_height);\n" } puts "}" exit 0 skycat-3.1.2-starlink-1b/cat/bitmaps/symb_arrow.xbm000066400000000000000000000004561215713201500222440ustar00rootroot00000000000000#define symb_arrow_width 16 #define symb_arrow_height 16 static unsigned char symb_arrow_bits[] = { 0x00, 0x01, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x0f, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/cat/bitmaps/symb_circle.xbm000066400000000000000000000004501215713201500223450ustar00rootroot00000000000000#define symb_circle_width 16 #define symb_circle_height 16 static char symb_circle_bits[] = { 0xe0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x02, 0x40, 0x02, 0x40, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x02, 0x40, 0x02, 0x40, 0x04, 0x20, 0x18, 0x18, 0xe0, 0x07}; skycat-3.1.2-starlink-1b/cat/bitmaps/symb_compass.xbm000066400000000000000000000004641215713201500225560ustar00rootroot00000000000000#define symb_compass_width 16 #define symb_compass_height 16 static unsigned char symb_compass_bits[] = { 0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x0f, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/cat/bitmaps/symb_cross.xbm000066400000000000000000000004561215713201500222430ustar00rootroot00000000000000#define symb_cross_width 16 #define symb_cross_height 16 static unsigned char symb_cross_bits[] = { 0x01, 0x80, 0x02, 0x40, 0x04, 0x20, 0x08, 0x10, 0x10, 0x08, 0x20, 0x04, 0x40, 0x02, 0x80, 0x01, 0x80, 0x01, 0x40, 0x02, 0x20, 0x04, 0x10, 0x08, 0x08, 0x10, 0x04, 0x20, 0x02, 0x40, 0x01, 0x80}; skycat-3.1.2-starlink-1b/cat/bitmaps/symb_diamond.xbm000066400000000000000000000004641215713201500225240ustar00rootroot00000000000000#define symb_diamond_width 16 #define symb_diamond_height 16 static unsigned char symb_diamond_bits[] = { 0x80, 0x01, 0x40, 0x02, 0x20, 0x04, 0x10, 0x08, 0x08, 0x10, 0x04, 0x20, 0x02, 0x40, 0x01, 0x80, 0x01, 0x80, 0x02, 0x40, 0x04, 0x20, 0x08, 0x10, 0x10, 0x08, 0x20, 0x04, 0x40, 0x02, 0x80, 0x01}; skycat-3.1.2-starlink-1b/cat/bitmaps/symb_ellipse.xbm000066400000000000000000000004641215713201500225460ustar00rootroot00000000000000#define symb_ellipse_width 16 #define symb_ellipse_height 16 static unsigned char symb_ellipse_bits[] = { 0x00, 0x00, 0x00, 0x0e, 0x80, 0x11, 0x40, 0x20, 0x20, 0x40, 0x10, 0x40, 0x08, 0x40, 0x08, 0x40, 0x04, 0x20, 0x02, 0x20, 0x02, 0x10, 0x01, 0x08, 0x01, 0x04, 0x02, 0x02, 0x84, 0x01, 0x78, 0x00}; skycat-3.1.2-starlink-1b/cat/bitmaps/symb_line.xbm000066400000000000000000000004531215713201500220360ustar00rootroot00000000000000#define symb_line_width 16 #define symb_line_height 16 static unsigned char symb_line_bits[] = { 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}; skycat-3.1.2-starlink-1b/cat/bitmaps/symb_plus.xbm000066400000000000000000000004531215713201500220720ustar00rootroot00000000000000#define symb_plus_width 16 #define symb_plus_height 16 static unsigned char symb_plus_bits[] = { 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xff, 0xff, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}; skycat-3.1.2-starlink-1b/cat/bitmaps/symb_square.xbm000066400000000000000000000004501215713201500224040ustar00rootroot00000000000000#define symb_square_width 16 #define symb_square_height 16 static char symb_square_bits[] = { 0xff, 0xff, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0xff, 0xff}; skycat-3.1.2-starlink-1b/cat/bitmaps/symb_triangle.xbm000066400000000000000000000004671215713201500227210ustar00rootroot00000000000000#define symb_triangle_width 16 #define symb_triangle_height 16 static unsigned char symb_triangle_bits[] = { 0x80, 0x01, 0x80, 0x01, 0x40, 0x02, 0x40, 0x02, 0x20, 0x04, 0x20, 0x04, 0x10, 0x08, 0x10, 0x08, 0x08, 0x10, 0x08, 0x10, 0x04, 0x20, 0x04, 0x20, 0x02, 0x40, 0x02, 0x40, 0x01, 0x80, 0xff, 0xff}; skycat-3.1.2-starlink-1b/cat/catConfig.sh.in000066400000000000000000000031501215713201500205410ustar00rootroot00000000000000# E.S.O. - VLT project # $Id: catConfig.sh.in,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # catConfig.sh -- # # This shell script (for sh) is generated automatically by Cat's # configure script. It will create shell variables for most of # the configuration options discovered by the configure script. # This script is intended to be included by the configure scripts # for Cat extensions so that they don't have to figure this all # out for themselves. This file does not duplicate information # already provided by tclConfig.sh, so you may need to use that # file in addition to this one. # # The information in this file is specific to a single platform. # Cat's version number. cat_VERSION='@PACKAGE_VERSION@' # The name of the Cat library: cat_LIB_FILE=@cat_LIB_FILE@ # String to pass to linker to pick up the Cat library from its # build directory. cat_BUILD_LIB_SPEC='@cat_BUILD_LIB_SPEC@' # Cat build directory. cat_BUILD_DIR='@cat_BUILD_DIR@' # String to pass to linker to pick up the Cat library from its # installed directory. cat_LIB_SPEC='@cat_LIB_SPEC@' # Location of the top-level source directories from which Cat # was built. This is the directory that contains generic, unix, etc. # If Cat was compiled in a different place than the directory # containing the source files, this points to the location of the sources, # not the location where Cat was compiled. cat_SRC_DIR='@cat_SRC_DIR@' # List of object files used to build the library (for merging packages). cat_PKG_OBJECTS='@cat_PKG_OBJECTS@' # List of header filesinstalled for this library (for merging packages). cat_PKG_HEADERS='@cat_PKG_HEADERS@' skycat-3.1.2-starlink-1b/cat/cat_version.tcl.in000066400000000000000000000001511215713201500213260ustar00rootroot00000000000000# This file is generated by configure: DO NOT EDIT BY HAND proc cat_version {} { return @CAT_VERSION@ } skycat-3.1.2-starlink-1b/cat/configure000077500000000000000000013161551215713201500176270ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by Starlink Autoconf 2.59 for cat 4.1.0. # # Copyright (C) 2003 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` exec 6>&1 # # Initializations. # ac_default_prefix=/usr/local ac_config_libobj_dir=. cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. # This variable seems obsolete. It should probably be removed, and # only ac_max_sed_lines should be used. : ${ac_max_here_lines=38} # Identity of this package. PACKAGE_NAME='cat' PACKAGE_TARNAME='cat' PACKAGE_VERSION='4.1.0' PACKAGE_STRING='cat 4.1.0' PACKAGE_BUGREPORT='' # Factoring default headers for most tests. ac_includes_default="\ #include #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_STAT_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #if HAVE_INTTYPES_H # include #else # if HAVE_STDINT_H # include # endif #endif #if HAVE_UNISTD_H # include #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CYGPATH EXEEXT PKG_LIB_FILE PKG_STUB_LIB_FILE PKG_STUB_SOURCES PKG_STUB_OBJECTS PKG_TCL_SOURCES PKG_HEADERS PKG_INCLUDES PKG_LIBS PKG_CFLAGS TCL_VERSION TCL_BIN_DIR TCL_SRC_DIR TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_LIBS TCL_DEFS TCL_EXTRA_CFLAGS TCL_LD_FLAGS TCL_SHLIB_LD_LIBS TK_VERSION TK_BIN_DIR TK_SRC_DIR TK_LIB_FILE TK_LIB_FLAG TK_LIB_SPEC TK_STUB_LIB_FILE TK_STUB_LIB_FLAG TK_STUB_LIB_SPEC TK_LIBS TK_XINCLUDES CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT CPP CXX CXXFLAGS ac_ct_CXX INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA SET_MAKE RANLIB ac_ct_RANLIB EGREP MATH_LIBS tclutil_VERSION tclutil_LIB_FILE tclutil_BUILD_LIB_SPEC tclutil_BUILD_DIR tclutil_LIB_SPEC BLT_LIB_SPEC tclutil_SRC_DIR tclutil_PKG_OBJECTS CFITSIO_LIB_SPEC astrotcl_VERSION astrotcl_LIB_FILE astrotcl_BUILD_LIB_SPEC astrotcl_BUILD_DIR astrotcl_LIB_SPEC astrotcl_SRC_DIR astrotcl_PKG_OBJECTS MERGE_OBJECTS SHLIB_LD_CXX_LIBS PKG_SOURCES PKG_OBJECTS CLEANFILES TCL_INCLUDES TK_INCLUDES TCL_THREADS SHARED_BUILD AR CELIB_DIR LIBOBJS SHLIB_SUFFIX DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING STLIB_LD SHLIB_LD SHLIB_CFLAGS SHLIB_LD_LIBS LDFLAGS_DEBUG LDFLAGS_OPTIMIZE LD_LIBRARY_PATH_VAR TCL_DBGX CFLAGS_DEFAULT LDFLAGS_DEFAULT MAKE_LIB MAKE_SHARED_LIB MAKE_STATIC_LIB MAKE_STUB_LIB RANLIB_STUB TCLSH_PROG WISH_PROG cat_LIB_FILE cat_BUILD_LIB_SPEC cat_BUILD_DIR cat_LIB_SPEC cat_PKG_OBJECTS cat_SRC_DIR LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_option in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval "enable_$ac_feature=no" ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "enable_$ac_feature='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "with_$ac_package='$ac_optarg'" ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/-/_/g'` eval "with_$ac_package=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` eval "$ac_envvar='$ac_optarg'" export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute paths. for ac_var in exec_prefix prefix do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* | NONE | '' ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # Be sure to have absolute paths. for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ localstatedir libdir includedir oldincludedir infodir mandir do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_confdir=`(dirname "$0") 2>/dev/null || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 { (exit 1); exit 1; }; } else { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi fi (cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 { (exit 1); exit 1; }; } srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` ac_env_build_alias_set=${build_alias+set} ac_env_build_alias_value=$build_alias ac_cv_env_build_alias_set=${build_alias+set} ac_cv_env_build_alias_value=$build_alias ac_env_host_alias_set=${host_alias+set} ac_env_host_alias_value=$host_alias ac_cv_env_host_alias_set=${host_alias+set} ac_cv_env_host_alias_value=$host_alias ac_env_target_alias_set=${target_alias+set} ac_env_target_alias_value=$target_alias ac_cv_env_target_alias_set=${target_alias+set} ac_cv_env_target_alias_value=$target_alias ac_env_CC_set=${CC+set} ac_env_CC_value=$CC ac_cv_env_CC_set=${CC+set} ac_cv_env_CC_value=$CC ac_env_CFLAGS_set=${CFLAGS+set} ac_env_CFLAGS_value=$CFLAGS ac_cv_env_CFLAGS_set=${CFLAGS+set} ac_cv_env_CFLAGS_value=$CFLAGS ac_env_LDFLAGS_set=${LDFLAGS+set} ac_env_LDFLAGS_value=$LDFLAGS ac_cv_env_LDFLAGS_set=${LDFLAGS+set} ac_cv_env_LDFLAGS_value=$LDFLAGS ac_env_CPPFLAGS_set=${CPPFLAGS+set} ac_env_CPPFLAGS_value=$CPPFLAGS ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} ac_cv_env_CPPFLAGS_value=$CPPFLAGS ac_env_CPP_set=${CPP+set} ac_env_CPP_value=$CPP ac_cv_env_CPP_set=${CPP+set} ac_cv_env_CPP_value=$CPP ac_env_CXX_set=${CXX+set} ac_env_CXX_value=$CXX ac_cv_env_CXX_set=${CXX+set} ac_cv_env_CXX_value=$CXX ac_env_CXXFLAGS_set=${CXXFLAGS+set} ac_env_CXXFLAGS_value=$CXXFLAGS ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set} ac_cv_env_CXXFLAGS_value=$CXXFLAGS # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures cat 4.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] _ACEOF cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --infodir=DIR info documentation [PREFIX/info] --mandir=DIR man documentation [PREFIX/man] _ACEOF cat <<\_ACEOF X features: --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of cat 4.1.0:";; esac cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-merge merge the contents of dependent packages into a master catalog library --enable-threads build with threads --enable-shared build and link with shared libraries --enable-shared --enable-64bit enable 64bit support (where applicable) --enable-64bit-vis enable 64bit Sparc VIS support --enable-wince enable Win/CE support (where applicable) --disable-load disallow dynamic loading and "load" command --enable-symbols build with debugging symbols --disable-symbols Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-tcl directory containing tcl configuration (tclConfig.sh) --with-tk directory containing tk configuration (tkConfig.sh) --with-tclinclude directory containing the public Tcl header files --with-tkinclude directory containing the public Tk header files. --with-x use the X Window System --with-celib=DIR use Windows/CE support library from DIR Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor CXX C++ compiler command CXXFLAGS C++ compiler flags Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d $ac_dir || continue ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_srcdir/configure.gnu; then echo $SHELL $ac_srcdir/configure.gnu --help=recursive elif test -f $ac_srcdir/configure; then echo $SHELL $ac_srcdir/configure --help=recursive elif test -f $ac_srcdir/configure.ac || test -f $ac_srcdir/configure.in; then echo $ac_configure --help else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi cd $ac_popdir done fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF cat configure 4.1.0 generated by Starlink Autoconf 2.59 Copyright (C) 2003 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit 0 fi exec 5>config.log cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by cat $as_me 4.1.0, which was generated by Starlink Autoconf 2.59. Invocation command line was $ $0 $@ _ACEOF { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` hostinfo = `(hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" # Get rid of the leading space. ac_sep=" " ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Be sure not to use single quotes in there, as some shells, # such as our DU 5.0 friend, will then `close' the trap. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, { (set) 2>&1 | case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in *ac_space=\ *) sed -n \ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" ;; *) sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------- ## ## Output files. ## ## ------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo sed "/^$/d" confdefs.h | sort echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core && rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo >confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . $cache_file;; *) . ./$cache_file;; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in `(set) 2>&1 | sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val="\$ac_cv_env_${ac_var}_value" eval ac_new_val="\$ac_env_${ac_var}_value" case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu #-------------------------------------------------------------------- # Call TEA_INIT as the first TEA_ macro to set up initial vars. # This will define a ${TEA_PLATFORM} variable == "unix" or "windows" # as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE. #-------------------------------------------------------------------- # TEA extensions pass this us the version of TEA they think they # are compatible with. TEA_VERSION="3.4" echo "$as_me:$LINENO: checking for correct TEA configuration" >&5 echo $ECHO_N "checking for correct TEA configuration... $ECHO_C" >&6 if test x"${PACKAGE_NAME}" = x ; then { { echo "$as_me:$LINENO: error: The PACKAGE_NAME variable must be defined by your TEA configure.in" >&5 echo "$as_me: error: The PACKAGE_NAME variable must be defined by your TEA configure.in" >&2;} { (exit 1); exit 1; }; } fi if test x"3.4" = x ; then { { echo "$as_me:$LINENO: error: TEA version not specified." >&5 echo "$as_me: error: TEA version not specified." >&2;} { (exit 1); exit 1; }; } elif test "3.4" != "${TEA_VERSION}" ; then echo "$as_me:$LINENO: result: warning: requested TEA version \"3.4\", have \"${TEA_VERSION}\"" >&5 echo "${ECHO_T}warning: requested TEA version \"3.4\", have \"${TEA_VERSION}\"" >&6 else echo "$as_me:$LINENO: result: ok (TEA ${TEA_VERSION})" >&5 echo "${ECHO_T}ok (TEA ${TEA_VERSION})" >&6 fi case "`uname -s`" in *win32*|*WIN32*|*CYGWIN_NT*|*CYGWIN_9*|*CYGWIN_ME*|*MINGW32_*) # Extract the first word of "cygpath", so it can be a program name with args. set dummy cygpath; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CYGPATH+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CYGPATH"; then ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CYGPATH="cygpath -w" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo" fi fi CYGPATH=$ac_cv_prog_CYGPATH if test -n "$CYGPATH"; then echo "$as_me:$LINENO: result: $CYGPATH" >&5 echo "${ECHO_T}$CYGPATH" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi EXEEXT=".exe" TEA_PLATFORM="windows" ;; *) CYGPATH=echo EXEEXT="" TEA_PLATFORM="unix" ;; esac # Check if exec_prefix is set. If not use fall back to prefix. # Note when adjusted, so that TEA_PREFIX can correct for this. # This is needed for recursive configures, since autoconf propagates # $prefix, but not $exec_prefix (doh!). if test x$exec_prefix = xNONE ; then exec_prefix_default=yes exec_prefix=$prefix fi # This package name must be replaced statically for AC_SUBST to work # Substitute STUB_LIB_FILE in case package creates a stub library too. # We AC_SUBST these here to ensure they are subst'ed, # in case the user doesn't call TEA_ADD_... #-------------------------------------------------------------------- # Load the tclConfig.sh file #-------------------------------------------------------------------- # # Ok, lets find the tcl configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tcl # if test x"${no_tcl}" = x ; then # we reset no_tcl in case something fails here no_tcl=true # Check whether --with-tcl or --without-tcl was given. if test "${with_tcl+set}" = set; then withval="$with_tcl" with_tclconfig=${withval} fi; echo "$as_me:$LINENO: checking for Tcl configuration" >&5 echo $ECHO_N "checking for Tcl configuration... $ECHO_C" >&6 if test "${ac_cv_c_tclconfig+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # First check to see if --with-tcl was specified. if test x"${with_tclconfig}" != x ; then case ${with_tclconfig} in */tclConfig.sh ) if test -f ${with_tclconfig}; then { echo "$as_me:$LINENO: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5 echo "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;} with_tclconfig=`echo ${with_tclconfig} | sed 's!/tclConfig\.sh$!!'` fi ;; esac if test -f "${with_tclconfig}/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` else { { echo "$as_me:$LINENO: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&5 echo "$as_me: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&2;} { (exit 1); exit 1; }; } fi fi # check in a few common install locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d ${TCLTK_ROOT}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i; pwd)` break fi done fi # then check for a private Tcl installation if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ../tcl \ `ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \ ../../tcl \ `ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \ ../../../tcl \ `ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ `ls -d /System/Library/Frameworks 2>/dev/null` \ ; do if test -f "$i/Tcl.framework/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi fi if test x"${ac_cv_c_tclconfig}" = x ; then TCL_BIN_DIR="# no Tcl configs found" { echo "$as_me:$LINENO: WARNING: \"Cannot find Tcl configuration definitions\"" >&5 echo "$as_me: WARNING: \"Cannot find Tcl configuration definitions\"" >&2;} exit 0 else no_tcl= TCL_BIN_DIR=${ac_cv_c_tclconfig} echo "$as_me:$LINENO: result: found $TCL_BIN_DIR/tclConfig.sh" >&5 echo "${ECHO_T}found $TCL_BIN_DIR/tclConfig.sh" >&6 fi fi echo "$as_me:$LINENO: checking for existence of $TCL_BIN_DIR/tclConfig.sh" >&5 echo $ECHO_N "checking for existence of $TCL_BIN_DIR/tclConfig.sh... $ECHO_C" >&6 if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then echo "$as_me:$LINENO: result: loading" >&5 echo "${ECHO_T}loading" >&6 . $TCL_BIN_DIR/tclConfig.sh else echo "$as_me:$LINENO: result: file not found" >&5 echo "${ECHO_T}file not found" >&6 fi # # If the TCL_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TCL_LIB_SPEC will be set to the value # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC # instead of TCL_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. # if test -f $TCL_BIN_DIR/Makefile ; then TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC} TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC} TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH} fi # # eval is required to do the TCL_DBGX substitution # eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\"" eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\"" #AC_SUBST(TCL_BUILD_LIB_SPEC) #AC_SUBST(TCL_BUILD_STUB_LIB_SPEC) #-------------------------------------------------------------------- # Load the tkConfig.sh file if necessary (Tk extension) #-------------------------------------------------------------------- # # Ok, lets find the tk configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tk # if test x"${no_tk}" = x ; then # we reset no_tk in case something fails here no_tk=true # Check whether --with-tk or --without-tk was given. if test "${with_tk+set}" = set; then withval="$with_tk" with_tkconfig=${withval} fi; echo "$as_me:$LINENO: checking for Tk configuration" >&5 echo $ECHO_N "checking for Tk configuration... $ECHO_C" >&6 if test "${ac_cv_c_tkconfig+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # First check to see if --with-tkconfig was specified. if test x"${with_tkconfig}" != x ; then case ${with_tkconfig} in */tkConfig.sh ) if test -f ${with_tkconfig}; then { echo "$as_me:$LINENO: WARNING: --with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself" >&5 echo "$as_me: WARNING: --with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself" >&2;} with_tkconfig=`echo ${with_tkconfig} | sed 's!/tkConfig\.sh$!!'` fi ;; esac if test -f "${with_tkconfig}/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)` else { { echo "$as_me:$LINENO: error: ${with_tkconfig} directory doesn't contain tkConfig.sh" >&5 echo "$as_me: error: ${with_tkconfig} directory doesn't contain tkConfig.sh" >&2;} { (exit 1); exit 1; }; } fi fi # check in a few common install locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d ${TCLTK_ROOT}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ ; do if test -f "$i/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i; pwd)` break fi done fi # then check for a private Tk library if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ../tk \ `ls -dr ../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../tk[8-9].[0-9] 2>/dev/null` \ `ls -dr ../tk[8-9].[0-9]* 2>/dev/null` \ ../../tk \ `ls -dr ../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../tk[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../tk[8-9].[0-9]* 2>/dev/null` \ ../../../tk \ `ls -dr ../../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../../tk[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../../tk[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/unix; pwd)` break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ `ls -d /System/Library/Frameworks 2>/dev/null` \ ; do if test -f "$i/Tk.framework/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/Tk.framework; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ${srcdir}/../tk \ `ls -dr ${srcdir}/../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ${srcdir}/../tk[8-9].[0-9] 2>/dev/null` \ `ls -dr ${srcdir}/../tk[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/unix; pwd)` break fi done fi fi if test x"${ac_cv_c_tkconfig}" = x ; then TK_BIN_DIR="# no Tk configs found" { echo "$as_me:$LINENO: WARNING: \"Cannot find Tk configuration definitions\"" >&5 echo "$as_me: WARNING: \"Cannot find Tk configuration definitions\"" >&2;} exit 0 else no_tk= TK_BIN_DIR=${ac_cv_c_tkconfig} echo "$as_me:$LINENO: result: found $TK_BIN_DIR/tkConfig.sh" >&5 echo "${ECHO_T}found $TK_BIN_DIR/tkConfig.sh" >&6 fi fi echo "$as_me:$LINENO: checking for existence of ${TK_BIN_DIR}/tkConfig.sh" >&5 echo $ECHO_N "checking for existence of ${TK_BIN_DIR}/tkConfig.sh... $ECHO_C" >&6 if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then echo "$as_me:$LINENO: result: loading" >&5 echo "${ECHO_T}loading" >&6 . $TK_BIN_DIR/tkConfig.sh else echo "$as_me:$LINENO: result: could not find ${TK_BIN_DIR}/tkConfig.sh" >&5 echo "${ECHO_T}could not find ${TK_BIN_DIR}/tkConfig.sh" >&6 fi # # If the TK_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TK_LIB_SPEC will be set to the value # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC # instead of TK_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. # if test -f $TK_BIN_DIR/Makefile ; then TK_LIB_SPEC=${TK_BUILD_LIB_SPEC} TK_STUB_LIB_SPEC=${TK_BUILD_STUB_LIB_SPEC} TK_STUB_LIB_PATH=${TK_BUILD_STUB_LIB_PATH} fi # Ensure windowingsystem is defined if test "${TEA_PLATFORM}" = "unix" ; then case ${TK_DEFS} in *MAC_OSX_TK*) cat >>confdefs.h <<\_ACEOF #define MAC_OSX_TK 1 _ACEOF TEA_WINDOWINGSYSTEM="aqua" ;; *) TEA_WINDOWINGSYSTEM="x11" ;; esac elif test "${TEA_PLATFORM}" = "windows" ; then TEA_WINDOWINGSYSTEM="win32" fi # # eval is required to do the TK_DBGX substitution # eval "TK_LIB_FILE=\"${TK_LIB_FILE}\"" eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\"" eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\"" eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\"" eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\"" eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\"" #----------------------------------------------------------------------- # Handle the --prefix=... option by defaulting to what Tcl gave. # Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER. #----------------------------------------------------------------------- if test "${prefix}" = "NONE"; then prefix_default=yes if test x"${TCL_PREFIX}" != x; then { echo "$as_me:$LINENO: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&5 echo "$as_me: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&6;} prefix=${TCL_PREFIX} else { echo "$as_me:$LINENO: --prefix defaulting to /usr/local" >&5 echo "$as_me: --prefix defaulting to /usr/local" >&6;} prefix=/usr/local fi fi if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \ -o x"${exec_prefix_default}" = x"yes" ; then #if test x"${TCL_EXEC_PREFIX}" != x; then #AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}]) #exec_prefix=${TCL_EXEC_PREFIX} #else { echo "$as_me:$LINENO: --exec-prefix defaulting to ${prefix}" >&5 echo "$as_me: --exec-prefix defaulting to ${prefix}" >&6;} exec_prefix=$prefix #fi fi #----------------------------------------------------------------------- # Standard compiler checks. # This sets up CC by using the CC env var, or looks for gcc otherwise. # This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create # the basic setup necessary to compile executables. #----------------------------------------------------------------------- ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f $ac_dir/shtool; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} { (exit 1); exit 1; }; } fi ac_config_guess="$SHELL $ac_aux_dir/config.guess" ac_config_sub="$SHELL $ac_aux_dir/config.sub" ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE) # in this macro, they need to go into TEA_SETUP_COMPILER instead. # If the user did not set CFLAGS, set it now to keep # the AC_PROG_CC macro from adding "-g -O2". if test "${CFLAGS+set}" != "set" ; then CFLAGS="" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CC" && break done CC=$ac_ct_CC fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 (eval $ac_link_default) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Find the output, starting from the most likely. This scheme is # not robust to junk in `.', hence go to wildcards (a.*) only as a last # resort. # Be careful to initialize this variable, since it used to be cached. # Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. ac_cv_exeext= # b.out is created by i960 compilers. for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; conftest.$ac_ext ) # This is the source file. ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` # FIXME: I believe we export ac_cv_exeext for Libtool, # but it would be cool to find out if it's true. Does anybody # maintain Libtool? --akim. export ac_cv_exeext break;; * ) break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6 # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6 echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` export ac_cv_exeext break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6 rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6 OBJEXT=$ac_cv_objext ac_objext=$OBJEXT echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS CFLAGS="-g" echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cc_g=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 if test "${ac_cv_prog_cc_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_stdc=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std1 is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std1. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX 10.20 and later -Ae # HP-UX older versions -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_stdc=$ac_arg break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext done rm -f conftest.$ac_ext conftest.$ac_objext CC=$ac_save_CC fi case "x$ac_cv_prog_cc_stdc" in x|xno) echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6 ;; *) echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 CC="$CC $ac_cv_prog_cc_stdc" ;; esac # Some people use a C++ compiler to compile C. Since we use `exit', # in C++ we need to declare it. In case someone uses the same compiler # for both compiling C and C++ we need to have the C++ compiler decide # the declaration of exit, since it's the most demanding environment. cat >conftest.$ac_ext <<_ACEOF #ifndef __cplusplus choke me #endif _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration #include int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_cv_c_compiler_gnu = yes; then GCC=yes fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6 ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=cc ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -n "$ac_tool_prefix"; then for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then echo "$as_me:$LINENO: result: $CXX" >&5 echo "${ECHO_T}$CXX" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 echo "${ECHO_T}$ac_ct_CXX" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CXX" && break done test -n "$ac_ct_CXX" || ac_ct_CXX="g++" CXX=$ac_ct_CXX fi # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C++ compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 if test "${ac_cv_cxx_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 GXX=`test $ac_compiler_gnu = yes && echo yes` ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS CXXFLAGS="-g" echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cxx_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cxx_g=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi for ac_declaration in \ '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration #include int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL=$ac_install_sh fi fi echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' #-------------------------------------------------------------------- # Checks to see if the make program sets the $MAKE variable. #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.make <<\_ACEOF all: @echo 'ac_maketemp="$(MAKE)"' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi rm -f conftest.make fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 SET_MAKE= else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 SET_MAKE="MAKE=${MAKE-make}" fi #-------------------------------------------------------------------- # Find ranlib #-------------------------------------------------------------------- if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then echo "$as_me:$LINENO: result: $RANLIB" >&5 echo "${ECHO_T}$RANLIB" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 echo "${ECHO_T}$ac_ct_RANLIB" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi RANLIB=$ac_ct_RANLIB else RANLIB="$ac_cv_prog_RANLIB" fi #-------------------------------------------------------------------- # Determines the correct binary file extension (.o, .obj, .exe etc.) #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6 if test "${ac_cv_prog_egrep+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | (grep -E '(a|b)') >/dev/null 2>&1 then ac_cv_prog_egrep='grep -E' else ac_cv_prog_egrep='egrep' fi fi echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 echo "${ECHO_T}$ac_cv_prog_egrep" >&6 EGREP=$ac_cv_prog_egrep echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6 if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here. #------------------------------------------------------------------------ # If we're using GCC, see if the compiler understands -pipe. If so, use it. # It makes compiling go faster. (This is only a performance feature.) #------------------------------------------------------------------------ if test -z "$no_pipe" -a -n "$GCC"; then echo "$as_me:$LINENO: checking if the compiler understands -pipe" >&5 echo $ECHO_N "checking if the compiler understands -pipe... $ECHO_C" >&6 OLDCC="$CC" CC="$CC -pipe" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CC="$OLDCC" echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi #-------------------------------------------------------------------- # Pick up flags from the environment (user). #-------------------------------------------------------------------- CC="${CC} $CFLAGS" CXX="${CXX} $CXXFLAGS $CFLAGS" #-------------------------------------------------------------------- # Common compiler flag setup #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6 if test "${ac_cv_c_bigendian+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # See if sys/param.h defines the BYTE_ORDER macro. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN bogus endian macros #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then # It does; now see whether it defined to BIG_ENDIAN or not. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_bigendian=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_bigendian=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # It does not; compile a test program. if test "$cross_compiling" = yes; then # try to guess the endianness by grepping values into an object file ac_cv_c_bigendian=unknown cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } int main () { _ascii (); _ebcdic (); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long l; char c[sizeof (long)]; } u; u.l = 1; exit (u.c[sizeof (long) - 1] == 1); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_bigendian=no else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_c_bigendian=yes fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 echo "${ECHO_T}$ac_cv_c_bigendian" >&6 case $ac_cv_c_bigendian in yes) cat >>confdefs.h <<\_ACEOF #define WORDS_BIGENDIAN 1 _ACEOF ;; no) ;; *) { { echo "$as_me:$LINENO: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&5 echo "$as_me: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} { (exit 1); exit 1; }; } ;; esac if test "${TEA_PLATFORM}" = "unix" ; then #-------------------------------------------------------------------- # On a few very rare systems, all of the libm.a stuff is # already in libc.a. Set compiler flags accordingly. # Also, Linux requires the "ieee" library for math to work # right (and it must appear before "-lm"). #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking for sin" >&5 echo $ECHO_N "checking for sin... $ECHO_C" >&6 if test "${ac_cv_func_sin+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define sin to an innocuous variant, in case declares sin. For example, HP-UX 11i declares gettimeofday. */ #define sin innocuous_sin /* System header to define __stub macros and hopefully few prototypes, which can conflict with char sin (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef sin /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char sin (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_sin) || defined (__stub___sin) choke me #else char (*f) () = sin; #endif #ifdef __cplusplus } #endif int main () { return f != sin; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_sin=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_sin=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_sin" >&5 echo "${ECHO_T}$ac_cv_func_sin" >&6 if test $ac_cv_func_sin = yes; then MATH_LIBS="" else MATH_LIBS="-lm" fi echo "$as_me:$LINENO: checking for main in -lieee" >&5 echo $ECHO_N "checking for main in -lieee... $ECHO_C" >&6 if test "${ac_cv_lib_ieee_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lieee $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_ieee_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ieee_main=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_ieee_main" >&5 echo "${ECHO_T}$ac_cv_lib_ieee_main" >&6 if test $ac_cv_lib_ieee_main = yes; then MATH_LIBS="-lieee $MATH_LIBS" fi #-------------------------------------------------------------------- # Interactive UNIX requires -linet instead of -lsocket, plus it # needs net/errno.h to define the socket-related error codes. #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking for main in -linet" >&5 echo $ECHO_N "checking for main in -linet... $ECHO_C" >&6 if test "${ac_cv_lib_inet_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-linet $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_inet_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_inet_main=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_inet_main" >&5 echo "${ECHO_T}$ac_cv_lib_inet_main" >&6 if test $ac_cv_lib_inet_main = yes; then LIBS="$LIBS -linet" fi if test "${ac_cv_header_net_errno_h+set}" = set; then echo "$as_me:$LINENO: checking for net/errno.h" >&5 echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6 if test "${ac_cv_header_net_errno_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5 echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking net/errno.h usability" >&5 echo $ECHO_N "checking net/errno.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking net/errno.h presence" >&5 echo $ECHO_N "checking net/errno.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: net/errno.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: net/errno.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: net/errno.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: net/errno.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: net/errno.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: net/errno.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: net/errno.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: net/errno.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the cat lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for net/errno.h" >&5 echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6 if test "${ac_cv_header_net_errno_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_net_errno_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5 echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6 fi if test $ac_cv_header_net_errno_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_NET_ERRNO_H 1 _ACEOF fi #-------------------------------------------------------------------- # Check for the existence of the -lsocket and -lnsl libraries. # The order here is important, so that they end up in the right # order in the command line generated by make. Here are some # special considerations: # 1. Use "connect" and "accept" to check for -lsocket, and # "gethostbyname" to check for -lnsl. # 2. Use each function name only once: can't redo a check because # autoconf caches the results of the last check and won't redo it. # 3. Use -lnsl and -lsocket only if they supply procedures that # aren't already present in the normal libraries. This is because # IRIX 5.2 has libraries, but they aren't needed and they're # bogus: they goof up name resolution if used. # 4. On some SVR4 systems, can't use -lsocket without -lnsl too. # To get around this problem, check for both libraries together # if -lsocket doesn't work by itself. #-------------------------------------------------------------------- tcl_checkBoth=0 echo "$as_me:$LINENO: checking for connect" >&5 echo $ECHO_N "checking for connect... $ECHO_C" >&6 if test "${ac_cv_func_connect+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define connect to an innocuous variant, in case declares connect. For example, HP-UX 11i declares gettimeofday. */ #define connect innocuous_connect /* System header to define __stub macros and hopefully few prototypes, which can conflict with char connect (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef connect /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char connect (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_connect) || defined (__stub___connect) choke me #else char (*f) () = connect; #endif #ifdef __cplusplus } #endif int main () { return f != connect; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_connect=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_connect=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5 echo "${ECHO_T}$ac_cv_func_connect" >&6 if test $ac_cv_func_connect = yes; then tcl_checkSocket=0 else tcl_checkSocket=1 fi if test "$tcl_checkSocket" = 1; then echo "$as_me:$LINENO: checking for setsockopt" >&5 echo $ECHO_N "checking for setsockopt... $ECHO_C" >&6 if test "${ac_cv_func_setsockopt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define setsockopt to an innocuous variant, in case declares setsockopt. For example, HP-UX 11i declares gettimeofday. */ #define setsockopt innocuous_setsockopt /* System header to define __stub macros and hopefully few prototypes, which can conflict with char setsockopt (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef setsockopt /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char setsockopt (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_setsockopt) || defined (__stub___setsockopt) choke me #else char (*f) () = setsockopt; #endif #ifdef __cplusplus } #endif int main () { return f != setsockopt; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_setsockopt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_setsockopt=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_setsockopt" >&5 echo "${ECHO_T}$ac_cv_func_setsockopt" >&6 if test $ac_cv_func_setsockopt = yes; then : else echo "$as_me:$LINENO: checking for setsockopt in -lsocket" >&5 echo $ECHO_N "checking for setsockopt in -lsocket... $ECHO_C" >&6 if test "${ac_cv_lib_socket_setsockopt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char setsockopt (); int main () { setsockopt (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_socket_setsockopt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_socket_setsockopt=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_socket_setsockopt" >&5 echo "${ECHO_T}$ac_cv_lib_socket_setsockopt" >&6 if test $ac_cv_lib_socket_setsockopt = yes; then LIBS="$LIBS -lsocket" else tcl_checkBoth=1 fi fi fi if test "$tcl_checkBoth" = 1; then tk_oldLibs=$LIBS LIBS="$LIBS -lsocket -lnsl" echo "$as_me:$LINENO: checking for accept" >&5 echo $ECHO_N "checking for accept... $ECHO_C" >&6 if test "${ac_cv_func_accept+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define accept to an innocuous variant, in case declares accept. For example, HP-UX 11i declares gettimeofday. */ #define accept innocuous_accept /* System header to define __stub macros and hopefully few prototypes, which can conflict with char accept (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef accept /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char accept (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_accept) || defined (__stub___accept) choke me #else char (*f) () = accept; #endif #ifdef __cplusplus } #endif int main () { return f != accept; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_accept=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_accept=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_accept" >&5 echo "${ECHO_T}$ac_cv_func_accept" >&6 if test $ac_cv_func_accept = yes; then tcl_checkNsl=0 else LIBS=$tk_oldLibs fi fi echo "$as_me:$LINENO: checking for gethostbyname" >&5 echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6 if test "${ac_cv_func_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define gethostbyname to an innocuous variant, in case declares gethostbyname. For example, HP-UX 11i declares gettimeofday. */ #define gethostbyname innocuous_gethostbyname /* System header to define __stub macros and hopefully few prototypes, which can conflict with char gethostbyname (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef gethostbyname /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostbyname (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) choke me #else char (*f) () = gethostbyname; #endif #ifdef __cplusplus } #endif int main () { return f != gethostbyname; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_gethostbyname=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_gethostbyname=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6 if test $ac_cv_func_gethostbyname = yes; then : else echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5 echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6 if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostbyname (); int main () { gethostbyname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_nsl_gethostbyname=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_nsl_gethostbyname=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6 if test $ac_cv_lib_nsl_gethostbyname = yes; then LIBS="$LIBS -lnsl" fi fi # Don't perform the eval of the libraries here because DL_LIBS # won't be set until we call TEA_CONFIG_CFLAGS TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}' echo "$as_me:$LINENO: checking dirent.h" >&5 echo $ECHO_N "checking dirent.h... $ECHO_C" >&6 if test "${tcl_cv_dirent_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #ifndef _POSIX_SOURCE # ifdef __Lynx__ /* * Generate compilation error to make the test fail: Lynx headers * are only valid if really in the POSIX environment. */ missing_procedure(); # endif #endif DIR *d; struct dirent *entryPtr; char *p; d = opendir("foobar"); entryPtr = readdir(d); p = entryPtr->d_name; closedir(d); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_dirent_h=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_dirent_h=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi if test $tcl_cv_dirent_h = no; then cat >>confdefs.h <<\_ACEOF #define NO_DIRENT_H 1 _ACEOF fi echo "$as_me:$LINENO: result: $tcl_ok" >&5 echo "${ECHO_T}$tcl_ok" >&6 if test "${ac_cv_header_errno_h+set}" = set; then echo "$as_me:$LINENO: checking for errno.h" >&5 echo $ECHO_N "checking for errno.h... $ECHO_C" >&6 if test "${ac_cv_header_errno_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5 echo "${ECHO_T}$ac_cv_header_errno_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking errno.h usability" >&5 echo $ECHO_N "checking errno.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking errno.h presence" >&5 echo $ECHO_N "checking errno.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: errno.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: errno.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: errno.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: errno.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: errno.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: errno.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: errno.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: errno.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the cat lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for errno.h" >&5 echo $ECHO_N "checking for errno.h... $ECHO_C" >&6 if test "${ac_cv_header_errno_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_errno_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5 echo "${ECHO_T}$ac_cv_header_errno_h" >&6 fi if test $ac_cv_header_errno_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_ERRNO_H 1 _ACEOF fi if test "${ac_cv_header_float_h+set}" = set; then echo "$as_me:$LINENO: checking for float.h" >&5 echo $ECHO_N "checking for float.h... $ECHO_C" >&6 if test "${ac_cv_header_float_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5 echo "${ECHO_T}$ac_cv_header_float_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking float.h usability" >&5 echo $ECHO_N "checking float.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking float.h presence" >&5 echo $ECHO_N "checking float.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: float.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: float.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: float.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: float.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: float.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: float.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: float.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: float.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the cat lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for float.h" >&5 echo $ECHO_N "checking for float.h... $ECHO_C" >&6 if test "${ac_cv_header_float_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_float_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5 echo "${ECHO_T}$ac_cv_header_float_h" >&6 fi if test $ac_cv_header_float_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_FLOAT_H 1 _ACEOF fi if test "${ac_cv_header_values_h+set}" = set; then echo "$as_me:$LINENO: checking for values.h" >&5 echo $ECHO_N "checking for values.h... $ECHO_C" >&6 if test "${ac_cv_header_values_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5 echo "${ECHO_T}$ac_cv_header_values_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking values.h usability" >&5 echo $ECHO_N "checking values.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking values.h presence" >&5 echo $ECHO_N "checking values.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: values.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: values.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: values.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: values.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: values.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: values.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: values.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: values.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the cat lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for values.h" >&5 echo $ECHO_N "checking for values.h... $ECHO_C" >&6 if test "${ac_cv_header_values_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_values_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5 echo "${ECHO_T}$ac_cv_header_values_h" >&6 fi if test $ac_cv_header_values_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_VALUES_H 1 _ACEOF fi if test "${ac_cv_header_limits_h+set}" = set; then echo "$as_me:$LINENO: checking for limits.h" >&5 echo $ECHO_N "checking for limits.h... $ECHO_C" >&6 if test "${ac_cv_header_limits_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5 echo "${ECHO_T}$ac_cv_header_limits_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking limits.h usability" >&5 echo $ECHO_N "checking limits.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking limits.h presence" >&5 echo $ECHO_N "checking limits.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: limits.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: limits.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: limits.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: limits.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: limits.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: limits.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: limits.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: limits.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the cat lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for limits.h" >&5 echo $ECHO_N "checking for limits.h... $ECHO_C" >&6 if test "${ac_cv_header_limits_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_limits_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5 echo "${ECHO_T}$ac_cv_header_limits_h" >&6 fi if test $ac_cv_header_limits_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIMITS_H 1 _ACEOF else cat >>confdefs.h <<\_ACEOF #define NO_LIMITS_H 1 _ACEOF fi if test "${ac_cv_header_stdlib_h+set}" = set; then echo "$as_me:$LINENO: checking for stdlib.h" >&5 echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6 if test "${ac_cv_header_stdlib_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5 echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking stdlib.h usability" >&5 echo $ECHO_N "checking stdlib.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking stdlib.h presence" >&5 echo $ECHO_N "checking stdlib.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: stdlib.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: stdlib.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: stdlib.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: stdlib.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: stdlib.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: stdlib.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: stdlib.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: stdlib.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the cat lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for stdlib.h" >&5 echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6 if test "${ac_cv_header_stdlib_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_stdlib_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5 echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6 fi if test $ac_cv_header_stdlib_h = yes; then tcl_ok=1 else tcl_ok=0 fi cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strtol" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strtoul" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strtod" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* if test $tcl_ok = 0; then cat >>confdefs.h <<\_ACEOF #define NO_STDLIB_H 1 _ACEOF fi if test "${ac_cv_header_string_h+set}" = set; then echo "$as_me:$LINENO: checking for string.h" >&5 echo $ECHO_N "checking for string.h... $ECHO_C" >&6 if test "${ac_cv_header_string_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5 echo "${ECHO_T}$ac_cv_header_string_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking string.h usability" >&5 echo $ECHO_N "checking string.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking string.h presence" >&5 echo $ECHO_N "checking string.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: string.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: string.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: string.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: string.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: string.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: string.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: string.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: string.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the cat lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for string.h" >&5 echo $ECHO_N "checking for string.h... $ECHO_C" >&6 if test "${ac_cv_header_string_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_string_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5 echo "${ECHO_T}$ac_cv_header_string_h" >&6 fi if test $ac_cv_header_string_h = yes; then tcl_ok=1 else tcl_ok=0 fi cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strstr" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strerror" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* # See also memmove check below for a place where NO_STRING_H can be # set and why. if test $tcl_ok = 0; then cat >>confdefs.h <<\_ACEOF #define NO_STRING_H 1 _ACEOF fi if test "${ac_cv_header_sys_wait_h+set}" = set; then echo "$as_me:$LINENO: checking for sys/wait.h" >&5 echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6 if test "${ac_cv_header_sys_wait_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking sys/wait.h usability" >&5 echo $ECHO_N "checking sys/wait.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking sys/wait.h presence" >&5 echo $ECHO_N "checking sys/wait.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: sys/wait.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: sys/wait.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: sys/wait.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: sys/wait.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: sys/wait.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: sys/wait.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the cat lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for sys/wait.h" >&5 echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6 if test "${ac_cv_header_sys_wait_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_sys_wait_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 fi if test $ac_cv_header_sys_wait_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_SYS_WAIT_H 1 _ACEOF fi if test "${ac_cv_header_dlfcn_h+set}" = set; then echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking dlfcn.h usability" >&5 echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking dlfcn.h presence" >&5 echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: dlfcn.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the cat lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_dlfcn_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 fi if test $ac_cv_header_dlfcn_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_DLFCN_H 1 _ACEOF fi # OS/390 lacks sys/param.h (and doesn't need it, by chance). for ac_header in sys/param.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the cat lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Let the user call this, because if it triggers, they will # need a compat/strtod.c that is correct. Users can also # use Tcl_GetDouble(FromObj) instead. #TEA_BUGGY_STRTOD fi #-------------------------------------------------------------------- # Do application specific checks (see aclocal.m4) #-------------------------------------------------------------------- # Load the Tclutil definitions cf=../tclutil/tclutilConfig.sh if test -f $cf ; then . $cf else { { echo "$as_me:$LINENO: error: $cf doesn't exist" >&5 echo "$as_me: error: $cf doesn't exist" >&2;} { (exit 1); exit 1; }; } fi # Load the Astrotcl definitions cf=../astrotcl/astrotclConfig.sh if test -f $cf ; then . $cf else { { echo "$as_me:$LINENO: error: $cf doesn't exist" >&5 echo "$as_me: error: $cf doesn't exist" >&2;} { (exit 1); exit 1; }; } fi # ----------------------------------------------------------------------- # Optionally merge object and header files from dependent packages to make one master lib # ----------------------------------------------------------------------- MERGED=1 # Check whether --enable-merge or --disable-merge was given. if test "${enable_merge+set}" = set; then enableval="$enable_merge" MERGED=$enableval else MERGED=no fi; csources=`cd $srcdir; echo generic/*.[Cc]` cat_headers=`cd $srcdir; echo generic/*.h` astrotcl_headers=`cd $srcdir; echo ../astrotcl/{generic,press,libwcs,cfitsio}/*.h` tclutil_headers=`cd $srcdir; echo ../tclutil/generic/*.h` cat_includes="-I$srcdir/generic -I$srcdir/bitmaps" astrotcl_includes="-I$srcdir/../astrotcl/generic -I$srcdir/../astrotcl/cfitsio -I$srcdir/../astrotcl/libwcs" tclutil_includes="-I$srcdir/../tclutil/generic" cincludes="${cat_includes} ${astrotcl_includes} ${tclutil_includes}" tclsources=`cd $srcdir; echo library/*.tcl library/*.xpm` if test $MERGED = yes ; then echo "Will build merged master catalog library" cheaders="${cat_headers} ${astrotcl_headers} ${tclutil_headers}" MERGE_OBJECTS="$astrotcl_PKG_OBJECTS $tclutil_PKG_OBJECTS" else echo "Not making a merged master catalog library" cheaders="${cat_headers}" MERGE_OBJECTS="" fi # ----------------------------------------------------------------------- cat >>confdefs.h <<\_ACEOF #define USE_COMPAT_CONST 1 _ACEOF #------------------------------------------------------------------------ # Check if we require additional libraries to support C++ shareable # libraries. system=`uname -s`-`uname -r` SHLIB_LD_CXX_LIBS="" export SHLIB_LD_CXX_LIBS case $system in SunOS-5*) SHLIB_LD_CXX_LIBS="-lCrun -lCstd" ;; OSF*) SHLIB_LD_CXX_LIBS="-lcxx -lcxxstd" ;; esac #------------------------------------------------------------------------- # The cxx C++ compiler under Tru64 UNIX needs the special # CXXFLAGS "-std gnu -D__USE_STD_IOSTREAM=1". These allow the standard # library streams headers to work and to generate templates that do # not require special handling throughout skycat directories (normally # template object files are created in various cxx_repository subdirectories, # this way the object files are kept embedded the usual object files, see # the cxx man page for details). #------------------------------------------------------------------------- export CXXFLAGS case $system in OSF*) case "x$CXX" in xcxx*) CXXFLAGS="$CXXFLAGS -g3 -std gnu -D__USE_STD_IOSTREAM=1" ;; esac ;; esac #----------------------------------------------------------------------- # __CHANGE__ # Specify the C source files to compile in TEA_ADD_SOURCES, # public headers that need to be installed in TEA_ADD_HEADERS, # stub library C source files to compile in TEA_ADD_STUB_SOURCES, # and runtime Tcl library files in TEA_ADD_TCL_SOURCES. # This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS # and PKG_TCL_SOURCES. #----------------------------------------------------------------------- vars="${csources}" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done vars="${cheaders}" for i in $vars; do # check for existence, be strict because it is installed if test ! -f "${srcdir}/$i" ; then { { echo "$as_me:$LINENO: error: could not find header file '${srcdir}/$i'" >&5 echo "$as_me: error: could not find header file '${srcdir}/$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_HEADERS="$PKG_HEADERS $i" done vars="${cincludes}" for i in $vars; do PKG_INCLUDES="$PKG_INCLUDES $i" done if test $MERGED = yes ; then vars="${BLT_LIB_SPEC} ${CFITSIO_LIB_SPEC}" for i in $vars; do if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then # Convert foo.lib to -lfoo for GCC. No-op if not *.lib i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'` fi PKG_LIBS="$PKG_LIBS $i" done else vars="$astrotcl_BUILD_LIB_SPEC $tclutil_BUILD_LIB_SPEC ${BLT_LIB_SPEC} ${CFITSIO_LIB_SPEC}" for i in $vars; do if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then # Convert foo.lib to -lfoo for GCC. No-op if not *.lib i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'` fi PKG_LIBS="$PKG_LIBS $i" done fi PKG_CFLAGS="$PKG_CFLAGS " vars="" for i in $vars; do # check for existence - allows for generic/win/unix VPATH if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find stub source file '$i'" >&5 echo "$as_me: error: could not find stub source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j" done vars="${tclsources}" for i in $vars; do # check for existence, be strict because it is installed if test ! -f "${srcdir}/$i" ; then { { echo "$as_me:$LINENO: error: could not find tcl source file '${srcdir}/$i'" >&5 echo "$as_me: error: could not find tcl source file '${srcdir}/$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i" done #-------------------------------------------------------------------- # __CHANGE__ # A few miscellaneous platform-specific items: # # Define a special symbol for Windows (BUILD_sample in this case) so # that we create the export library with the dll. # # Windows creates a few extra files that need to be cleaned up. # You can add more files to clean if your extension creates any extra # files. # # TEA_ADD_* any platform specific compiler/build info here. #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" ; then cat >>confdefs.h <<\_ACEOF #define BUILD_cat 1 _ACEOF CLEANFILES="*.lib *.dll *.exp *.ilk *.pdb vc*.pch" #TEA_ADD_SOURCES([win/winFile.c]) #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"]) else CLEANFILES="" #TEA_ADD_SOURCES([unix/unixFile.c]) #TEA_ADD_LIBS([-lsuperfly]) fi #-------------------------------------------------------------------- # __CHANGE__ # Choose which headers you need. Extension authors should try very # hard to only rely on the Tcl public header files. Internal headers # contain private data structures and are subject to change without # notice. # This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking for Tcl public headers" >&5 echo $ECHO_N "checking for Tcl public headers... $ECHO_C" >&6 # Check whether --with-tclinclude or --without-tclinclude was given. if test "${with_tclinclude+set}" = set; then withval="$with_tclinclude" with_tclinclude=${withval} fi; if test "${ac_cv_c_tclh+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Use the value from --with-tclinclude, if it was given if test x"${with_tclinclude}" != x ; then if test -f "${with_tclinclude}/tcl.h" ; then ac_cv_c_tclh=${with_tclinclude} else { { echo "$as_me:$LINENO: error: ${with_tclinclude} directory does not contain tcl.h" >&5 echo "$as_me: error: ${with_tclinclude} directory does not contain tcl.h" >&2;} { (exit 1); exit 1; }; } fi else # If Tcl was built as a framework, attempt to use # the framework's Headers directory case ${TCL_DEFS} in *TCL_FRAMEWORK*) list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`" ;; *) list="" ;; esac # Look in the source dir only if Tcl is not installed, # and in that situation, look there before installed locations. if test -f "$TCL_BIN_DIR/Makefile" ; then list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`" fi # Check order: pkg --prefix location, Tcl's --prefix location, # relative to directory of tclConfig.sh. eval "temp_includedir=${includedir}" list="$list \ `ls -d ${temp_includedir} 2>/dev/null` \ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then list="$list /usr/local/include /usr/include" if test x"${TCL_INCLUDE_SPEC}" != x ; then d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'` list="$list `ls -d ${d} 2>/dev/null`" fi fi for i in $list ; do if test -f "$i/tcl.h" ; then ac_cv_c_tclh=$i break fi done fi fi # Print a message based on how we determined the include path if test x"${ac_cv_c_tclh}" = x ; then { { echo "$as_me:$LINENO: error: tcl.h not found. Please specify its location with --with-tclinclude" >&5 echo "$as_me: error: tcl.h not found. Please specify its location with --with-tclinclude" >&2;} { (exit 1); exit 1; }; } else echo "$as_me:$LINENO: result: ${ac_cv_c_tclh}" >&5 echo "${ECHO_T}${ac_cv_c_tclh}" >&6 fi # Convert to a native path and substitute into the output files. INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}` TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" #TEA_PRIVATE_TCL_HEADERS echo "$as_me:$LINENO: checking for Tk public headers" >&5 echo $ECHO_N "checking for Tk public headers... $ECHO_C" >&6 # Check whether --with-tkinclude or --without-tkinclude was given. if test "${with_tkinclude+set}" = set; then withval="$with_tkinclude" with_tkinclude=${withval} fi; if test "${ac_cv_c_tkh+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Use the value from --with-tkinclude, if it was given if test x"${with_tkinclude}" != x ; then if test -f "${with_tkinclude}/tk.h" ; then ac_cv_c_tkh=${with_tkinclude} else { { echo "$as_me:$LINENO: error: ${with_tkinclude} directory does not contain tk.h" >&5 echo "$as_me: error: ${with_tkinclude} directory does not contain tk.h" >&2;} { (exit 1); exit 1; }; } fi else # If Tk was built as a framework, attempt to use # the framework's Headers directory. case ${TK_DEFS} in *TK_FRAMEWORK*) list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`" ;; *) list="" ;; esac # Look in the source dir only if Tk is not installed, # and in that situation, look there before installed locations. if test -f "$TK_BIN_DIR/Makefile" ; then list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`" fi # Check order: pkg --prefix location, Tk's --prefix location, # relative to directory of tkConfig.sh, Tcl's --prefix location, # relative to directory of tclConfig.sh. eval "temp_includedir=${includedir}" list="$list \ `ls -d ${temp_includedir} 2>/dev/null` \ `ls -d ${TK_PREFIX}/include 2>/dev/null` \ `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then list="$list /usr/local/include /usr/include" fi for i in $list ; do if test -f "$i/tk.h" ; then ac_cv_c_tkh=$i break fi done fi fi # Print a message based on how we determined the include path if test x"${ac_cv_c_tkh}" = x ; then { { echo "$as_me:$LINENO: error: tk.h not found. Please specify its location with --with-tkinclude" >&5 echo "$as_me: error: tk.h not found. Please specify its location with --with-tkinclude" >&2;} { (exit 1); exit 1; }; } else echo "$as_me:$LINENO: result: ${ac_cv_c_tkh}" >&5 echo "${ECHO_T}${ac_cv_c_tkh}" >&6 fi # Convert to a native path and substitute into the output files. INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}` TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" if test "${TEA_WINDOWINGSYSTEM}" = "win32" \ -o "${TEA_WINDOWINGSYSTEM}" = "aqua"; then # On Windows and Aqua, we need the X compat headers echo "$as_me:$LINENO: checking for X11 header files" >&5 echo $ECHO_N "checking for X11 header files... $ECHO_C" >&6 if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`" TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" fi echo "$as_me:$LINENO: result: ${INCLUDE_DIR_NATIVE}" >&5 echo "${ECHO_T}${INCLUDE_DIR_NATIVE}" >&6 fi #TEA_PRIVATE_TK_HEADERS if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then echo "$as_me:$LINENO: checking for X" >&5 echo $ECHO_N "checking for X... $ECHO_C" >&6 # Check whether --with-x or --without-x was given. if test "${with_x+set}" = set; then withval="$with_x" fi; # $have_x is `yes', `no', `disabled', or empty when we do not yet know. if test "x$with_x" = xno; then # The user explicitly disabled X. have_x=disabled else if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then # Both variables are already set. have_x=yes else if test "${ac_cv_have_x+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # One or both of the vars are not set, and there is no cached value. ac_x_includes=no ac_x_libraries=no rm -fr conftest.dir if mkdir conftest.dir; then cd conftest.dir # Make sure to not put "make" in the Imakefile rules, since we grep it out. cat >Imakefile <<'_ACEOF' acfindx: @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"' _ACEOF if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} acfindx 2>/dev/null | grep -v make` # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. for ac_extension in a so sl dylib la dll; do if test ! -f $ac_im_usrlibdir/libX11.$ac_extension && test -f $ac_im_libdir/libX11.$ac_extension; then ac_im_usrlibdir=$ac_im_libdir; break fi done # Screen out bogus values from the imake configuration. They are # bogus both because they are the default anyway, and because # using them would break gcc on systems where it needs fixed includes. case $ac_im_incroot in /usr/include) ;; *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; esac case $ac_im_usrlibdir in /usr/lib | /lib) ;; *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; esac fi cd .. rm -fr conftest.dir fi # Standard set of common directories for X headers. # Check X11 before X11Rn because it is often a symlink to the current release. ac_x_header_dirs=' /usr/X11/include /usr/X11R6/include /usr/X11R5/include /usr/X11R4/include /usr/include/X11 /usr/include/X11R6 /usr/include/X11R5 /usr/include/X11R4 /usr/local/X11/include /usr/local/X11R6/include /usr/local/X11R5/include /usr/local/X11R4/include /usr/local/include/X11 /usr/local/include/X11R6 /usr/local/include/X11R5 /usr/local/include/X11R4 /usr/X386/include /usr/x386/include /usr/XFree86/include/X11 /usr/include /usr/local/include /usr/unsupported/include /usr/athena/include /usr/local/x11r5/include /usr/lpp/Xamples/include /usr/openwin/include /usr/openwin/share/include' if test "$ac_x_includes" = no; then # Guess where to find include files, by looking for Intrinsic.h. # First, try using that file with no special directory specified. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # We can compile using X headers with no special include directory. ac_x_includes= else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 for ac_dir in $ac_x_header_dirs; do if test -r "$ac_dir/X11/Intrinsic.h"; then ac_x_includes=$ac_dir break fi done fi rm -f conftest.err conftest.$ac_ext fi # $ac_x_includes = no if test "$ac_x_libraries" = no; then # Check for the libraries. # See if we find them without any special options. # Don't add to $LIBS permanently. ac_save_LIBS=$LIBS LIBS="-lXt $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { XtMalloc (0) ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then LIBS=$ac_save_LIBS # We can link X programs with no special library path. ac_x_libraries= else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 LIBS=$ac_save_LIBS for ac_dir in `echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` do # Don't even attempt the hair of trying to link an X program! for ac_extension in a so sl dylib la dll; do if test -r $ac_dir/libXt.$ac_extension; then ac_x_libraries=$ac_dir break 2 fi done done fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi # $ac_x_libraries = no if test "$ac_x_includes" = no || test "$ac_x_libraries" = no; then # Didn't find X anywhere. Cache the known absence of X. ac_cv_have_x="have_x=no" else # Record where we found X for the cache. ac_cv_have_x="have_x=yes \ ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries" fi fi fi eval "$ac_cv_have_x" fi # $with_x != no if test "$have_x" != yes; then echo "$as_me:$LINENO: result: $have_x" >&5 echo "${ECHO_T}$have_x" >&6 no_x=yes else # If each of the values was on the command line, it overrides each guess. test "x$x_includes" = xNONE && x_includes=$ac_x_includes test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries # Update the cache value to reflect the command line values. ac_cv_have_x="have_x=yes \ ac_x_includes=$x_includes ac_x_libraries=$x_libraries" echo "$as_me:$LINENO: result: libraries $x_libraries, headers $x_includes" >&5 echo "${ECHO_T}libraries $x_libraries, headers $x_includes" >&6 fi not_really_there="" if test "$no_x" = ""; then if test "$x_includes" = ""; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 not_really_there="yes" fi rm -f conftest.err conftest.$ac_ext else if test ! -r $x_includes/X11/Intrinsic.h; then not_really_there="yes" fi fi fi if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then echo "$as_me:$LINENO: checking for X11 header files" >&5 echo $ECHO_N "checking for X11 header files... $ECHO_C" >&6 XINCLUDES="# no special path needed" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 XINCLUDES="nope" fi rm -f conftest.err conftest.$ac_ext if test "$XINCLUDES" = nope; then dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include" for i in $dirs ; do if test -r $i/X11/Intrinsic.h; then echo "$as_me:$LINENO: result: $i" >&5 echo "${ECHO_T}$i" >&6 XINCLUDES=" -I$i" break fi done fi else if test "$x_includes" != ""; then XINCLUDES=-I$x_includes else XINCLUDES="# no special path needed" fi fi if test "$XINCLUDES" = nope; then echo "$as_me:$LINENO: result: could not find any!" >&5 echo "${ECHO_T}could not find any!" >&6 XINCLUDES="# no include files found" fi if test "$no_x" = yes; then echo "$as_me:$LINENO: checking for X11 libraries" >&5 echo $ECHO_N "checking for X11 libraries... $ECHO_C" >&6 XLIBSW=nope dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib" for i in $dirs ; do if test -r $i/libX11.dylib -o -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl; then echo "$as_me:$LINENO: result: $i" >&5 echo "${ECHO_T}$i" >&6 XLIBSW="-L$i -lX11" x_libraries="$i" break fi done else if test "$x_libraries" = ""; then XLIBSW=-lX11 else XLIBSW="-L$x_libraries -lX11" fi fi if test "$XLIBSW" = nope ; then echo "$as_me:$LINENO: checking for XCreateWindow in -lXwindow" >&5 echo $ECHO_N "checking for XCreateWindow in -lXwindow... $ECHO_C" >&6 if test "${ac_cv_lib_Xwindow_XCreateWindow+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXwindow $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char XCreateWindow (); int main () { XCreateWindow (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_Xwindow_XCreateWindow=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xwindow_XCreateWindow=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_Xwindow_XCreateWindow" >&5 echo "${ECHO_T}$ac_cv_lib_Xwindow_XCreateWindow" >&6 if test $ac_cv_lib_Xwindow_XCreateWindow = yes; then XLIBSW=-lXwindow fi fi if test "$XLIBSW" = nope ; then echo "$as_me:$LINENO: result: could not find any! Using -lX11." >&5 echo "${ECHO_T}could not find any! Using -lX11." >&6 XLIBSW=-lX11 fi if test x"${XLIBSW}" != x ; then PKG_LIBS="${PKG_LIBS} ${XLIBSW}" fi fi #-------------------------------------------------------------------- # Check whether --enable-threads or --disable-threads was given. # This auto-enables if Tcl was compiled threaded. #-------------------------------------------------------------------- # Check whether --enable-threads or --disable-threads was given. if test "${enable_threads+set}" = set; then enableval="$enable_threads" tcl_ok=$enableval else tcl_ok=yes fi; if test "${enable_threads+set}" = set; then enableval="$enable_threads" tcl_ok=$enableval else tcl_ok=yes fi if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then TCL_THREADS=1 if test "${TEA_PLATFORM}" != "windows" ; then # We are always OK on Windows, so check what this platform wants. cat >>confdefs.h <<\_ACEOF #define USE_THREAD_ALLOC 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _REENTRANT 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _THREAD_SAFE 1 _ACEOF echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthread" >&5 echo $ECHO_N "checking for pthread_mutex_init in -lpthread... $ECHO_C" >&6 if test "${ac_cv_lib_pthread_pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_pthread_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthread_pthread_mutex_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_pthread_pthread_mutex_init" >&6 if test $ac_cv_lib_pthread_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "no"; then # Check a little harder for __pthread_mutex_init in the # same library, as some systems hide it there until # pthread.h is defined. We could alternatively do an # AC_TRY_COMPILE with pthread.h, but that will work with # libpthread really doesn't exist, like AIX 4.2. # [Bug: 4359] echo "$as_me:$LINENO: checking for __pthread_mutex_init in -lpthread" >&5 echo $ECHO_N "checking for __pthread_mutex_init in -lpthread... $ECHO_C" >&6 if test "${ac_cv_lib_pthread___pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char __pthread_mutex_init (); int main () { __pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_pthread___pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthread___pthread_mutex_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_pthread___pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_pthread___pthread_mutex_init" >&6 if test $ac_cv_lib_pthread___pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthread" else echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthreads" >&5 echo $ECHO_N "checking for pthread_mutex_init in -lpthreads... $ECHO_C" >&6 if test "${ac_cv_lib_pthreads_pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthreads $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_pthreads_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthreads_pthread_mutex_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_pthreads_pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_pthreads_pthread_mutex_init" >&6 if test $ac_cv_lib_pthreads_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthreads" else echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc" >&5 echo $ECHO_N "checking for pthread_mutex_init in -lc... $ECHO_C" >&6 if test "${ac_cv_lib_c_pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_c_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_c_pthread_mutex_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_c_pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_c_pthread_mutex_init" >&6 if test $ac_cv_lib_c_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "no"; then echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc_r" >&5 echo $ECHO_N "checking for pthread_mutex_init in -lc_r... $ECHO_C" >&6 if test "${ac_cv_lib_c_r_pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc_r $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_c_r_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_c_r_pthread_mutex_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_c_r_pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_c_r_pthread_mutex_init" >&6 if test $ac_cv_lib_c_r_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -pthread" else TCL_THREADS=0 { echo "$as_me:$LINENO: WARNING: \"Don t know how to find pthread lib on your system - thread support disabled\"" >&5 echo "$as_me: WARNING: \"Don t know how to find pthread lib on your system - thread support disabled\"" >&2;} fi fi fi fi fi else TCL_THREADS=0 fi # Do checking message here to not mess up interleaved configure output echo "$as_me:$LINENO: checking for building with threads" >&5 echo $ECHO_N "checking for building with threads... $ECHO_C" >&6 if test "${TCL_THREADS}" = "1"; then cat >>confdefs.h <<\_ACEOF #define TCL_THREADS 1 _ACEOF #LIBS="$LIBS $THREADS_LIBS" echo "$as_me:$LINENO: result: yes (default)" >&5 echo "${ECHO_T}yes (default)" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi # TCL_THREADS sanity checking. See if our request for building with # threads is the same as the way Tcl was built. If not, warn the user. case ${TCL_DEFS} in *THREADS=1*) if test "${TCL_THREADS}" = "0"; then { echo "$as_me:$LINENO: WARNING: Building ${PACKAGE_NAME} without threads enabled, but building against Tcl that IS thread-enabled. It is recommended to use --enable-threads." >&5 echo "$as_me: WARNING: Building ${PACKAGE_NAME} without threads enabled, but building against Tcl that IS thread-enabled. It is recommended to use --enable-threads." >&2;} fi ;; *) if test "${TCL_THREADS}" = "1"; then { echo "$as_me:$LINENO: WARNING: --enable-threads requested, but building against a Tcl that is NOT thread-enabled. This is an OK configuration that will also run in a thread-enabled core." >&5 echo "$as_me: WARNING: --enable-threads requested, but building against a Tcl that is NOT thread-enabled. This is an OK configuration that will also run in a thread-enabled core." >&2;} fi ;; esac #-------------------------------------------------------------------- # The statement below defines a collection of symbols related to # building as a shared library instead of a static library. #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking how to build libraries" >&5 echo $ECHO_N "checking how to build libraries... $ECHO_C" >&6 # Check whether --enable-shared or --disable-shared was given. if test "${enable_shared+set}" = set; then enableval="$enable_shared" tcl_ok=$enableval else tcl_ok=yes fi; if test "${enable_shared+set}" = set; then enableval="$enable_shared" tcl_ok=$enableval else tcl_ok=yes fi if test "$tcl_ok" = "yes" ; then echo "$as_me:$LINENO: result: shared" >&5 echo "${ECHO_T}shared" >&6 SHARED_BUILD=1 else echo "$as_me:$LINENO: result: static" >&5 echo "${ECHO_T}static" >&6 SHARED_BUILD=0 cat >>confdefs.h <<\_ACEOF #define STATIC_BUILD 1 _ACEOF fi #-------------------------------------------------------------------- # This macro figures out what flags to use with the compiler/linker # when building shared/static debug/optimized objects. This information # can be taken from the tclConfig.sh file, but this figures it all out. #-------------------------------------------------------------------- # Step 0: Enable 64 bit support? echo "$as_me:$LINENO: checking if 64bit support is enabled" >&5 echo $ECHO_N "checking if 64bit support is enabled... $ECHO_C" >&6 # Check whether --enable-64bit or --disable-64bit was given. if test "${enable_64bit+set}" = set; then enableval="$enable_64bit" do64bit=$enableval else do64bit=no fi; echo "$as_me:$LINENO: result: $do64bit" >&5 echo "${ECHO_T}$do64bit" >&6 # Step 0.b: Enable Solaris 64 bit VIS support? echo "$as_me:$LINENO: checking if 64bit Sparc VIS support is requested" >&5 echo $ECHO_N "checking if 64bit Sparc VIS support is requested... $ECHO_C" >&6 # Check whether --enable-64bit-vis or --disable-64bit-vis was given. if test "${enable_64bit_vis+set}" = set; then enableval="$enable_64bit_vis" do64bitVIS=$enableval else do64bitVIS=no fi; echo "$as_me:$LINENO: result: $do64bitVIS" >&5 echo "${ECHO_T}$do64bitVIS" >&6 if test "$do64bitVIS" = "yes"; then # Force 64bit on with VIS do64bit=yes fi # Step 0.c: Cross-compiling options for Windows/CE builds? if test "${TEA_PLATFORM}" = "windows" ; then echo "$as_me:$LINENO: checking if Windows/CE build is requested" >&5 echo $ECHO_N "checking if Windows/CE build is requested... $ECHO_C" >&6 # Check whether --enable-wince or --disable-wince was given. if test "${enable_wince+set}" = set; then enableval="$enable_wince" doWince=$enableval else doWince=no fi; echo "$as_me:$LINENO: result: $doWince" >&5 echo "${ECHO_T}$doWince" >&6 fi # Step 1: set the variable "system" to hold the name and version number # for the system. This can usually be done via the "uname" command, but # there are a few systems, like Next, where this doesn't work. echo "$as_me:$LINENO: checking system version (for dynamic loading)" >&5 echo $ECHO_N "checking system version (for dynamic loading)... $ECHO_C" >&6 if test -f /usr/lib/NextStep/software_version; then system=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version` else system=`uname -s`-`uname -r` if test "$?" -ne 0 ; then echo "$as_me:$LINENO: result: unknown (can't find uname command)" >&5 echo "${ECHO_T}unknown (can't find uname command)" >&6 system=unknown else # Special check for weird MP-RAS system (uname returns weird # results, and the version is kept in special file). if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then system=MP-RAS-`awk '{print }' /etc/.relid` fi if test "`uname -s`" = "AIX" ; then system=AIX-`uname -v`.`uname -r` fi if test "${TEA_PLATFORM}" = "windows" ; then system=windows fi echo "$as_me:$LINENO: result: $system" >&5 echo "${ECHO_T}$system" >&6 fi fi # Step 2: check for existence of -ldl library. This is needed because # Linux can use either -ldl or -ldld for dynamic loading. echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 if test "${ac_cv_lib_dl_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char dlopen (); int main () { dlopen (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 if test $ac_cv_lib_dl_dlopen = yes; then have_dl=yes else have_dl=no fi # Step 3: set configuration options based on system name and version. # This is similar to Tcl's unix/tcl.m4 except that we've added a # "windows" case and CC_SEARCH_FLAGS becomes LD_SEARCH_FLAGS for us # (and we have no CC_SEARCH_FLAGS). do64bit_ok=no LDFLAGS_ORIG="$LDFLAGS" TCL_EXPORT_FILE_SUFFIX="" UNSHARED_LIB_SUFFIX="" TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`' ECHO_VERSION='`echo ${PACKAGE_VERSION}`' TCL_LIB_VERSIONS_OK=ok CFLAGS_DEBUG=-g if test "$GCC" = "yes" ; then CFLAGS_OPTIMIZE=-O2 CFLAGS_WARNING="-Wall -Wno-implicit-int" else CFLAGS_OPTIMIZE=-O CFLAGS_WARNING="" fi TCL_NEEDS_EXP_FILE=0 TCL_BUILD_EXP_FILE="" TCL_EXP_FILE="" # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_AR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="ar" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then echo "$as_me:$LINENO: result: $AR" >&5 echo "${ECHO_T}$AR" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi STLIB_LD='${AR} cr' LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH" case $system in windows) # This is a 2-stage check to make sure we have the 64-bit SDK # We have to know where the SDK is installed. # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs # MACHINE is IX86 for LINK, but this is used by the manifest, # which requires x86|amd64|ia64. MACHINE="X86" if test "$do64bit" != "no" ; then if test "x${MSSDK}x" = "xx" ; then MSSDK="C:/Progra~1/Microsoft Platform SDK" fi MSSDK=`echo "$MSSDK" | sed -e 's!\\\!/!g'` PATH64="" case "$do64bit" in amd64|x64|yes) MACHINE="AMD64" ; # default to AMD64 64-bit build PATH64="${MSSDK}/Bin/Win64/x86/AMD64" ;; ia64) MACHINE="IA64" PATH64="${MSSDK}/Bin/Win64" ;; esac if test ! -d "${PATH64}" ; then { echo "$as_me:$LINENO: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&5 echo "$as_me: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&2;} { echo "$as_me:$LINENO: WARNING: Ensure latest Platform SDK is installed" >&5 echo "$as_me: WARNING: Ensure latest Platform SDK is installed" >&2;} do64bit="no" else echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5 echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6 do64bit_ok="yes" fi fi if test "$doWince" != "no" ; then if test "$do64bit" != "no" ; then { { echo "$as_me:$LINENO: error: Windows/CE and 64-bit builds incompatible" >&5 echo "$as_me: error: Windows/CE and 64-bit builds incompatible" >&2;} { (exit 1); exit 1; }; } fi if test "$GCC" = "yes" ; then { { echo "$as_me:$LINENO: error: Windows/CE and GCC builds incompatible" >&5 echo "$as_me: error: Windows/CE and GCC builds incompatible" >&2;} { (exit 1); exit 1; }; } fi # First, look for one uninstalled. # the alternative search directory is invoked by --with-celib if test x"${no_celib}" = x ; then # we reset no_celib in case something fails here no_celib=true # Check whether --with-celib or --without-celib was given. if test "${with_celib+set}" = set; then withval="$with_celib" with_celibconfig=${withval} fi; echo "$as_me:$LINENO: checking for Windows/CE celib directory" >&5 echo $ECHO_N "checking for Windows/CE celib directory... $ECHO_C" >&6 if test "${ac_cv_c_celibconfig+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # First check to see if --with-celibconfig was specified. if test x"${with_celibconfig}" != x ; then if test -d "${with_celibconfig}/inc" ; then ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)` else { { echo "$as_me:$LINENO: error: ${with_celibconfig} directory doesn't contain inc directory" >&5 echo "$as_me: error: ${with_celibconfig} directory doesn't contain inc directory" >&2;} { (exit 1); exit 1; }; } fi fi # then check for a celib library if test x"${ac_cv_c_celibconfig}" = x ; then for i in \ ../celib-palm-3.0 \ ../celib \ ../../celib-palm-3.0 \ ../../celib \ `ls -dr ../celib-*3.[0-9]* 2>/dev/null` \ ${srcdir}/../celib-palm-3.0 \ ${srcdir}/../celib \ `ls -dr ${srcdir}/../celib-*3.[0-9]* 2>/dev/null` \ ; do if test -d "$i/inc" ; then ac_cv_c_celibconfig=`(cd $i; pwd)` break fi done fi fi if test x"${ac_cv_c_celibconfig}" = x ; then { { echo "$as_me:$LINENO: error: Cannot find celib support library directory" >&5 echo "$as_me: error: Cannot find celib support library directory" >&2;} { (exit 1); exit 1; }; } else no_celib= CELIB_DIR=${ac_cv_c_celibconfig} CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'` echo "$as_me:$LINENO: result: found $CELIB_DIR" >&5 echo "${ECHO_T}found $CELIB_DIR" >&6 fi fi # Set defaults for common evc4/PPC2003 setup # Currently Tcl requires 300+, possibly 420+ for sockets CEVERSION=420; # could be 211 300 301 400 420 ... TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ... ARCH=ARM; # could be ARM MIPS X86EM ... PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002" if test "$doWince" != "yes"; then # If !yes then the user specified something # Reset ARCH to allow user to skip specifying it ARCH= eval `echo $doWince | awk -F, '{ \ if (length($1)) { printf "CEVERSION=\"%s\"\n", $1; \ if ($1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \ if (length($2)) { printf "TARGETCPU=\"%s\"\n", toupper($2) }; \ if (length($3)) { printf "ARCH=\"%s\"\n", toupper($3) }; \ if (length($4)) { printf "PLATFORM=\"%s\"\n", $4 }; \ }'` if test "x${ARCH}" = "x" ; then ARCH=$TARGETCPU; fi fi OSVERSION=WCE$CEVERSION; if test "x${WCEROOT}" = "x" ; then WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0" if test ! -d "${WCEROOT}" ; then WCEROOT="C:/Program Files/Microsoft eMbedded Tools" fi fi if test "x${SDKROOT}" = "x" ; then SDKROOT="C:/Program Files/Windows CE Tools" if test ! -d "${SDKROOT}" ; then SDKROOT="C:/Windows CE Tools" fi fi WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'` SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'` if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \ -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then { { echo "$as_me:$LINENO: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&5 echo "$as_me: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&2;} { (exit 1); exit 1; }; } doWince="no" else # We could PATH_NOSPACE these, but that's not important, # as long as we quote them when used. CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include" if test -d "${CEINCLUDE}/${TARGETCPU}" ; then CEINCLUDE="${CEINCLUDE}/${TARGETCPU}" fi CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" fi fi if test "$GCC" != "yes" ; then if test "${SHARED_BUILD}" = "0" ; then runtime=-MT else runtime=-MD fi if test "$do64bit" != "no" ; then # All this magic is necessary for the Win64 SDK RC1 - hobbs CC="\"${PATH64}/cl.exe\"" CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\"" RC="\"${MSSDK}/bin/rc.exe\"" lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\"" LINKBIN="\"${PATH64}/link.exe\"" CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d" CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" # Avoid 'unresolved external symbol __security_cookie' # errors, c.f. http://support.microsoft.com/?id=894573 vars="bufferoverflowU.lib" for i in $vars; do if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then # Convert foo.lib to -lfoo for GCC. No-op if not *.lib i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'` fi PKG_LIBS="$PKG_LIBS $i" done elif test "$doWince" != "no" ; then CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin" if test "${TARGETCPU}" = "X86"; then CC="\"${CEBINROOT}/cl.exe\"" else CC="\"${CEBINROOT}/cl${ARCH}.exe\"" fi CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\"" RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\"" arch=`echo ${ARCH} | awk '{print tolower($0)}'` defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS" if test "${SHARED_BUILD}" = "1" ; then # Static CE builds require static celib as well defs="${defs} _DLL" fi for i in $defs ; do cat >>confdefs.h <<_ACEOF #define $i 1 _ACEOF done cat >>confdefs.h <<_ACEOF #define _WIN32_WCE $CEVERSION _ACEOF cat >>confdefs.h <<_ACEOF #define UNDER_CE $CEVERSION _ACEOF CFLAGS_DEBUG="-nologo -Zi -Od" CFLAGS_OPTIMIZE="-nologo -Ox" lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'` lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo" LINKBIN="\"${CEBINROOT}/link.exe\"" else RC="rc" lflags="-nologo" LINKBIN="link" CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d" CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" fi fi if test "$GCC" = "yes"; then # mingw gcc mode RC="windres" CFLAGS_DEBUG="-g" CFLAGS_OPTIMIZE="-O2" SHLIB_LD="$CXX -shared" UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}" LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}" else SHLIB_LD="${LINKBIN} -dll ${lflags}" # link -lib only works when -lib is the first arg STLIB_LD="${LINKBIN} -lib ${lflags}" UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib' PATHTYPE=-w # For information on what debugtype is most useful, see: # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp # This essentially turns it all on. LDFLAGS_DEBUG="-debug:full -debugtype:both -warn:2" LDFLAGS_OPTIMIZE="-release" if test "$doWince" != "no" ; then LDFLAGS_CONSOLE="-link ${lflags}" LDFLAGS_WINDOW=${LDFLAGS_CONSOLE} else LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}" LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}" fi fi SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".dll" SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll' TCL_LIB_VERSIONS_OK=nodots # Bogus to avoid getting this turned off DL_OBJS="tclLoadNone.obj" ;; AIX-*) if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes" ; then # AIX requires the _r compiler when gcc isn't being used case "${CC}" in *_r) # ok ... ;; *) CC=${CC}_r ;; esac echo "$as_me:$LINENO: result: Using $CC for compiling with threads" >&5 echo "${ECHO_T}Using $CC for compiling with threads" >&6 fi LIBS="$LIBS -lc" SHLIB_CFLAGS="" SHLIB_SUFFIX=".so" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadDl.o" LD_LIBRARY_PATH_VAR="LIBPATH" # AIX v<=4.1 has some different flags than 4.2+ if test "$system" = "AIX-4.1" -o "`uname -v`" -lt "4" ; then #LIBOBJS="$LIBOBJS tclLoadAix.o" case $LIBOBJS in "tclLoadAix.$ac_objext" | \ *" tclLoadAix.$ac_objext" | \ "tclLoadAix.$ac_objext "* | \ *" tclLoadAix.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS tclLoadAix.$ac_objext" ;; esac DL_LIBS="-lld" fi # Check to enable 64-bit flags for compiler/linker on AIX 4+ if test "$do64bit" = "yes" -a "`uname -v`" -gt "3" ; then if test "$GCC" = "yes" ; then { echo "$as_me:$LINENO: WARNING: \"64bit mode not supported with GCC on $system\"" >&5 echo "$as_me: WARNING: \"64bit mode not supported with GCC on $system\"" >&2;} else do64bit_ok=yes CFLAGS="$CFLAGS -q64" LDFLAGS="$LDFLAGS -q64" RANLIB="${RANLIB} -X64" AR="${AR} -X64" SHLIB_LD_FLAGS="-b64" fi fi if test "`uname -m`" = "ia64" ; then # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC SHLIB_LD="/usr/ccs/bin/ld -G -z text" # AIX-5 has dl* in libc.so DL_LIBS="" if test "$GCC" = "yes" ; then LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' else LD_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}' fi else if test "$GCC" = "yes" ; then SHLIB_LD="$CXX -shared" else SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry" fi SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}" DL_LIBS="-ldl" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' TCL_NEEDS_EXP_FILE=1 TCL_EXPORT_FILE_SUFFIX='${PACKAGE_VERSION}.exp' fi # On AIX <=v4 systems, libbsd.a has to be linked in to support # non-blocking file IO. This library has to be linked in after # the MATH_LIBS or it breaks the pow() function. The way to # insure proper sequencing, is to add it to the tail of MATH_LIBS. # This library also supplies gettimeofday. # # AIX does not have a timezone field in struct tm. When the AIX # bsd library is used, the timezone global and the gettimeofday # methods are to be avoided for timezone deduction instead, we # deduce the timezone by comparing the localtime result on a # known GMT value. echo "$as_me:$LINENO: checking for gettimeofday in -lbsd" >&5 echo $ECHO_N "checking for gettimeofday in -lbsd... $ECHO_C" >&6 if test "${ac_cv_lib_bsd_gettimeofday+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbsd $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gettimeofday (); int main () { gettimeofday (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_bsd_gettimeofday=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_bsd_gettimeofday=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_gettimeofday" >&5 echo "${ECHO_T}$ac_cv_lib_bsd_gettimeofday" >&6 if test $ac_cv_lib_bsd_gettimeofday = yes; then libbsd=yes else libbsd=no fi if test $libbsd = yes; then MATH_LIBS="$MATH_LIBS -lbsd" cat >>confdefs.h <<\_ACEOF #define USE_DELTA_FOR_TZ 1 _ACEOF fi ;; BeOS*) SHLIB_CFLAGS="-fPIC" SHLIB_LD="${CXX} -nostart" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" ;; BSD/OS-2.1*|BSD/OS-3*) SHLIB_CFLAGS="" SHLIB_LD="shlicc -r" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS="" ;; BSD/OS-4.*) SHLIB_CFLAGS="-export-dynamic -fPIC" SHLIB_LD="$CXX -shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -export-dynamic" LD_SEARCH_FLAGS="" ;; dgux*) SHLIB_CFLAGS="-K PIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS="" ;; HP-UX-*.11.*) # Use updated header definitions where possible cat >>confdefs.h <<\_ACEOF #define _XOPEN_SOURCE_EXTENDED 1 _ACEOF SHLIB_SUFFIX=".sl" echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 if test "${ac_cv_lib_dld_shl_load+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char shl_load (); int main () { shl_load (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dld_shl_load=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_shl_load=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 if test $ac_cv_lib_dld_shl_load = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = yes; then SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadShl.o" DL_LIBS="-ldld" LDFLAGS="$LDFLAGS -Wl,-E" LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.' LD_LIBRARY_PATH_VAR="SHLIB_PATH" fi if test "$GCC" = "yes" ; then SHLIB_LD="$CXX -shared -fPIC" SHLIB_LD_LIBS='${LIBS}' LD_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.' fi # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc #CFLAGS="$CFLAGS +DAportable" # Check to enable 64-bit flags for compiler/linker if test "$do64bit" = "yes" ; then if test "$GCC" = "yes" ; then hpux_arch=`${CC} -dumpmachine` case $hpux_arch in hppa64*) # 64-bit gcc in use. Fix flags for GNU ld. do64bit_ok=yes SHLIB_LD="${CXX} -shared -fPIC" SHLIB_LD_LIBS='${LIBS}' ;; *) { echo "$as_me:$LINENO: WARNING: \"64bit mode not supported with GCC on $system\"" >&5 echo "$as_me: WARNING: \"64bit mode not supported with GCC on $system\"" >&2;} ;; esac else do64bit_ok=yes CFLAGS="$CFLAGS +DD64" LDFLAGS="$LDFLAGS +DD64" fi fi ;; HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*) SHLIB_SUFFIX=".sl" echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 if test "${ac_cv_lib_dld_shl_load+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char shl_load (); int main () { shl_load (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dld_shl_load=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_shl_load=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 if test $ac_cv_lib_dld_shl_load = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = yes; then SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" SHLIB_LD_LIBS="" DL_OBJS="tclLoadShl.o" DL_LIBS="-ldld" LDFLAGS="$LDFLAGS -Wl,-E" LD_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.' fi LD_LIBRARY_PATH_VAR="SHLIB_PATH" ;; IRIX-4.*) SHLIB_CFLAGS="-G 0" SHLIB_SUFFIX=".a" SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadAout.o" DL_LIBS="" LDFLAGS="$LDFLAGS -Wl,-D,08000000" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' SHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a' ;; IRIX-5.*) SHLIB_CFLAGS="" SHLIB_LD="ld -shared -rdata_shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' ;; IRIX-6.*|IRIX64-6.5*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' if test "$GCC" = "yes" ; then CFLAGS="$CFLAGS -mabi=n32" LDFLAGS="$LDFLAGS -mabi=n32" else case $system in IRIX-6.3) # Use to build 6.2 compatible binaries on 6.3. CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS" ;; *) CFLAGS="$CFLAGS -n32" ;; esac LDFLAGS="$LDFLAGS -n32" fi ;; IRIX64-6.*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' # Check to enable 64-bit flags for compiler/linker if test "$do64bit" = "yes" ; then if test "$GCC" = "yes" ; then { echo "$as_me:$LINENO: WARNING: 64bit mode not supported by gcc" >&5 echo "$as_me: WARNING: 64bit mode not supported by gcc" >&2;} else do64bit_ok=yes SHLIB_LD="ld -64 -shared -rdata_shared" CFLAGS="$CFLAGS -64" LDFLAGS="$LDFLAGS -64" fi fi ;; Linux*) SHLIB_CFLAGS="-fPIC" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" CFLAGS_OPTIMIZE="-O2" # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings # when you inline the string and math operations. Turn this off to # get rid of the warnings. #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES" if test "$have_dl" = yes; then SHLIB_LD="${CXX} -shared" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,--export-dynamic" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' else if test "${ac_cv_header_dld_h+set}" = set; then echo "$as_me:$LINENO: checking for dld.h" >&5 echo $ECHO_N "checking for dld.h... $ECHO_C" >&6 if test "${ac_cv_header_dld_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_dld_h" >&5 echo "${ECHO_T}$ac_cv_header_dld_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking dld.h usability" >&5 echo $ECHO_N "checking dld.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking dld.h presence" >&5 echo $ECHO_N "checking dld.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: dld.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: dld.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: dld.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: dld.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: dld.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: dld.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: dld.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: dld.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: dld.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: dld.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the cat lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for dld.h" >&5 echo $ECHO_N "checking for dld.h... $ECHO_C" >&6 if test "${ac_cv_header_dld_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_dld_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_dld_h" >&5 echo "${ECHO_T}$ac_cv_header_dld_h" >&6 fi if test $ac_cv_header_dld_h = yes; then SHLIB_LD="ld -shared" DL_OBJS="tclLoadDld.o" DL_LIBS="-ldld" LD_SEARCH_FLAGS="" fi fi if test "`uname -m`" = "alpha" ; then CFLAGS="$CFLAGS -mieee" fi # The combo of gcc + glibc has a bug related # to inlining of functions like strtod(). The # -fno-builtin flag should address this problem # but it does not work. The -fno-inline flag # is kind of overkill but it works. # Disable inlining only when one of the # files in compat/*.c is being linked in. if test x"${USE_COMPAT}" != x ; then CFLAGS="$CFLAGS -fno-inline" fi ;; GNU*) SHLIB_CFLAGS="-fPIC" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" if test "$have_dl" = yes; then SHLIB_LD="${CXX} -shared" DL_OBJS="" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,--export-dynamic" LD_SEARCH_FLAGS="" else if test "${ac_cv_header_dld_h+set}" = set; then echo "$as_me:$LINENO: checking for dld.h" >&5 echo $ECHO_N "checking for dld.h... $ECHO_C" >&6 if test "${ac_cv_header_dld_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_dld_h" >&5 echo "${ECHO_T}$ac_cv_header_dld_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking dld.h usability" >&5 echo $ECHO_N "checking dld.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking dld.h presence" >&5 echo $ECHO_N "checking dld.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: dld.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: dld.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: dld.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: dld.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: dld.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: dld.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: dld.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: dld.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: dld.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: dld.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the cat lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for dld.h" >&5 echo $ECHO_N "checking for dld.h... $ECHO_C" >&6 if test "${ac_cv_header_dld_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_dld_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_dld_h" >&5 echo "${ECHO_T}$ac_cv_header_dld_h" >&6 fi if test $ac_cv_header_dld_h = yes; then SHLIB_LD="ld -shared" DL_OBJS="" DL_LIBS="-ldld" LD_SEARCH_FLAGS="" fi fi if test "`uname -m`" = "alpha" ; then CFLAGS="$CFLAGS -mieee" fi ;; MP-RAS-02*) SHLIB_CFLAGS="-K PIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS="" ;; MP-RAS-*) SHLIB_CFLAGS="-K PIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,-Bexport" LD_SEARCH_FLAGS="" ;; NetBSD-*|FreeBSD-[1-2].*) # Not available on all versions: check for include file. if test "${ac_cv_header_dlfcn_h+set}" = set; then echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking dlfcn.h usability" >&5 echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking dlfcn.h presence" >&5 echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: dlfcn.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the cat lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_dlfcn_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 fi if test $ac_cv_header_dlfcn_h = yes; then # NetBSD/SPARC needs -fPIC, -fpic will not do. SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' echo "$as_me:$LINENO: checking for ELF" >&5 echo $ECHO_N "checking for ELF... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __ELF__ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so' else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' fi rm -f conftest* else SHLIB_CFLAGS="" SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".a" DL_OBJS="tclLoadAout.o" DL_LIBS="" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' fi # FreeBSD doesn't handle version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; OpenBSD-*) SHLIB_LD="${CXX} -shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS="" echo "$as_me:$LINENO: checking for ELF" >&5 echo $ECHO_N "checking for ELF... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __ELF__ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' fi rm -f conftest* # OpenBSD doesn't do version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; FreeBSD-*) # FreeBSD 3.* and greater have ELF. SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LDFLAGS="$LDFLAGS -export-dynamic" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' if test "${TCL_THREADS}" = "1" ; then # The -pthread needs to go in the CFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` CFLAGS="$CFLAGS -pthread" LDFLAGS="$LDFLAGS -pthread" fi case $system in FreeBSD-3.*) # FreeBSD-3 doesn't handle version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so' TCL_LIB_VERSIONS_OK=nodots ;; esac ;; Darwin-*) CFLAGS_OPTIMIZE="-Os" SHLIB_CFLAGS="-fno-common" if test $do64bit = yes; then do64bit_ok=yes CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" fi SHLIB_LD='${CXX} -dynamiclib ${CFLAGS} ${LDFLAGS}' echo "$as_me:$LINENO: checking if ld accepts -single_module flag" >&5 echo $ECHO_N "checking if ld accepts -single_module flag... $ECHO_C" >&6 if test "${tcl_cv_ld_single_module+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { int i; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_ld_single_module=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_ld_single_module=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$hold_ldflags fi echo "$as_me:$LINENO: result: $tcl_cv_ld_single_module" >&5 echo "${ECHO_T}$tcl_cv_ld_single_module" >&6 if test $tcl_cv_ld_single_module = yes; then SHLIB_LD="${SHLIB_LD} -Wl,-single_module" fi SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".dylib" DL_OBJS="tclLoadDyld.o" DL_LIBS="" # Don't use -prebind when building for Mac OS X 10.4 or later only: test -z "${MACOSX_DEPLOYMENT_TARGET}" || \ test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F. '{print $2}'`" -lt 4 && \ LDFLAGS="$LDFLAGS -prebind" LDFLAGS="$LDFLAGS -headerpad_max_install_names" echo "$as_me:$LINENO: checking if ld accepts -search_paths_first flag" >&5 echo $ECHO_N "checking if ld accepts -search_paths_first flag... $ECHO_C" >&6 if test "${tcl_cv_ld_search_paths_first+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-search_paths_first" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { int i; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_ld_search_paths_first=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_ld_search_paths_first=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$hold_ldflags fi echo "$as_me:$LINENO: result: $tcl_cv_ld_search_paths_first" >&5 echo "${ECHO_T}$tcl_cv_ld_search_paths_first" >&6 if test $tcl_cv_ld_search_paths_first = yes; then LDFLAGS="$LDFLAGS -Wl,-search_paths_first" fi LD_SEARCH_FLAGS="" LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH" ;; NEXTSTEP-*) SHLIB_CFLAGS="" SHLIB_LD="$CXX -nostdlib -r" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadNext.o" DL_LIBS="" LD_SEARCH_FLAGS="" ;; OS/390-*) CFLAGS_OPTIMIZE="" # Optimizer is buggy cat >>confdefs.h <<\_ACEOF #define _OE_SOCKETS 1 _ACEOF ;; OSF1-1.0|OSF1-1.1|OSF1-1.2) # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1 SHLIB_CFLAGS="" # Hack: make package name same as library name SHLIB_LD='ld -R -export :' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadOSF.o" DL_LIBS="" LD_SEARCH_FLAGS="" ;; OSF1-1.*) # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2 SHLIB_CFLAGS="-fPIC" if test "$SHARED_BUILD" = "1" ; then SHLIB_LD="ld -shared" else SHLIB_LD="ld -non_shared" fi SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS="" ;; OSF1-V*) # Digital OSF/1 SHLIB_CFLAGS="" if test "$SHARED_BUILD" = "1" ; then SHLIB_LD='ld -shared -expect_unresolved "*"' else SHLIB_LD='ld -non_shared -expect_unresolved "*"' fi SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' if test "$GCC" = "yes" ; then CFLAGS="$CFLAGS -mieee" else CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee" fi # see pthread_intro(3) for pthread support on osf1, k.furukawa if test "${TCL_THREADS}" = "1" ; then CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE" CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64" LIBS=`echo $LIBS | sed s/-lpthreads//` if test "$GCC" = "yes" ; then LIBS="$LIBS -lpthread -lmach -lexc" else CFLAGS="$CFLAGS -pthread" # PWD: don't need this. #LDFLAGS="$LDFLAGS -pthread" fi fi ;; QNX-6*) # QNX RTP # This may work for all QNX, but it was only reported for v6. SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" # dlopen is in -lc on QNX DL_LIBS="" LD_SEARCH_FLAGS="" ;; RISCos-*) SHLIB_CFLAGS="-G 0" SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".a" DL_OBJS="tclLoadAout.o" DL_LIBS="" LDFLAGS="$LDFLAGS -Wl,-D,08000000" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' ;; SCO_SV-3.2*) # Note, dlopen is available only on SCO 3.2.5 and greater. However, # this test works, since "uname -s" was non-standard in 3.2.4 and # below. if test "$GCC" = "yes" ; then SHLIB_CFLAGS="-fPIC -melf" LDFLAGS="$LDFLAGS -melf -Wl,-Bexport" else SHLIB_CFLAGS="-Kpic -belf" LDFLAGS="$LDFLAGS -belf -Wl,-Bexport" fi SHLIB_LD="ld -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS="" ;; SINIX*5.4*) SHLIB_CFLAGS="-K PIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS="" ;; SunOS-4*) SHLIB_CFLAGS="-PIC" SHLIB_LD="ld" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' # SunOS can't handle version numbers with dots in them in library # specs, like -ltcl7.5, so use -ltcl75 instead. Also, it # requires an extra version number at the end of .so file names. # So, the library has to have a name like libtcl75.so.1.0 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; SunOS-5.[0-6]) # Careful to not let 5.10+ fall into this case # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. cat >>confdefs.h <<\_ACEOF #define _REENTRANT 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _POSIX_PTHREAD_SEMANTICS 1 _ACEOF # Note: need the LIBS below, otherwise Tk won't find Tcl's # symbols when dynamically loaded into tclsh. SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" if test "$GCC" = "yes" ; then SHLIB_CFLAGS="-fPIC" SHLIB_LD="$CXX -shared" LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' else SHLIB_LD="$CXX -G -z text" LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' SHLIB_CFLAGS="-KPIC" fi ;; SunOS-5*) # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. cat >>confdefs.h <<\_ACEOF #define _REENTRANT 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _POSIX_PTHREAD_SEMANTICS 1 _ACEOF # Check to enable 64-bit flags for compiler/linker if test "$do64bit" = "yes" ; then arch=`isainfo` if test "$arch" = "sparcv9 sparc" ; then if test "$GCC" = "yes" ; then if test "`gcc -dumpversion` | awk -F. '{print }'" -lt "3" ; then { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5 echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;} else do64bit_ok=yes CFLAGS="$CFLAGS -m64 -mcpu=v9" LDFLAGS="$LDFLAGS -m64 -mcpu=v9" fi else do64bit_ok=yes if test "$do64bitVIS" = "yes" ; then CFLAGS="$CFLAGS -xarch=v9a" LDFLAGS="$LDFLAGS -xarch=v9a" else CFLAGS="$CFLAGS -xarch=v9" LDFLAGS="$LDFLAGS -xarch=v9" fi # Solaris 64 uses this as well #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64" fi elif test "$arch" = "amd64 i386" ; then if test "$GCC" = "yes" ; then { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5 echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;} else do64bit_ok=yes CFLAGS="$CFLAGS -xarch=amd64" LDFLAGS="$LDFLAGS -xarch=amd64" fi else { echo "$as_me:$LINENO: WARNING: 64bit mode not supported for $arch" >&5 echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;} fi fi # Note: need the LIBS below, otherwise Tk won't find Tcl's # symbols when dynamically loaded into tclsh. SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" if test "$GCC" = "yes" ; then SHLIB_CFLAGS="-fPIC" SHLIB_LD="$CXX -shared" LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' if test "$do64bit" = "yes" ; then # We need to specify -static-libgcc or we need to # add the path to the sparv9 libgcc. # JH: static-libgcc is necessary for core Tcl, but may # not be necessary for extensions. SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc" # for finding sparcv9 libgcc, get the regular libgcc # path, remove so name and append 'sparcv9' #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..." #LD_SEARCH_FLAGS="${LD_SEARCH_FLAGS},-R,$v9gcclibdir" fi else SHLIB_CFLAGS="-KPIC" SHLIB_LD="$CXX -G -z text" LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' fi ;; ULTRIX-4.*) SHLIB_CFLAGS="-G 0" SHLIB_SUFFIX=".a" SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadAout.o" DL_LIBS="" LDFLAGS="$LDFLAGS -Wl,-D,08000000" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' if test "$GCC" != "yes" ; then CFLAGS="$CFLAGS -DHAVE_TZSET -std1" fi ;; UNIX_SV* | UnixWare-5*) SHLIB_CFLAGS="-KPIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers # that don't grok the -Bexport option. Test that it does. hold_ldflags=$LDFLAGS echo "$as_me:$LINENO: checking for ld accepts -Bexport flag" >&5 echo $ECHO_N "checking for ld accepts -Bexport flag... $ECHO_C" >&6 LDFLAGS="$LDFLAGS -Wl,-Bexport" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { int i; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then found=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 LDFLAGS=$hold_ldflags found=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext echo "$as_me:$LINENO: result: $found" >&5 echo "${ECHO_T}$found" >&6 LD_SEARCH_FLAGS="" ;; esac if test "$do64bit" != "no" -a "$do64bit_ok" = "no" ; then { echo "$as_me:$LINENO: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5 echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;} fi # Step 4: If pseudo-static linking is in use (see K. B. Kenny, "Dynamic # Loading for Tcl -- What Became of It?". Proc. 2nd Tcl/Tk Workshop, # New Orleans, LA, Computerized Processes Unlimited, 1994), then we need # to determine which of several header files defines the a.out file # format (a.out.h, sys/exec.h, or sys/exec_aout.h). At present, we # support only a file format that is more or less version-7-compatible. # In particular, # - a.out files must begin with `struct exec'. # - the N_TXTOFF on the `struct exec' must compute the seek address # of the text segment # - The `struct exec' must contain a_magic, a_text, a_data, a_bss # and a_entry fields. # The following compilation should succeed if and only if either sys/exec.h # or a.out.h is usable for the purpose. # # Note that the modified COFF format used on MIPS Ultrix 4.x is usable; the # `struct exec' includes a second header that contains information that # duplicates the v7 fields that are needed. if test "x$DL_OBJS" = "xtclLoadAout.o" ; then echo "$as_me:$LINENO: checking sys/exec.h" >&5 echo $ECHO_N "checking sys/exec.h... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct exec foo; unsigned long seek; int flag; #if defined(__mips) || defined(mips) seek = N_TXTOFF (foo.ex_f, foo.ex_o); #else seek = N_TXTOFF (foo); #endif flag = (foo.a_magic == OMAGIC); return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_ok=usable else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_ok=unusable fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $tcl_ok" >&5 echo "${ECHO_T}$tcl_ok" >&6 if test $tcl_ok = usable; then cat >>confdefs.h <<\_ACEOF #define USE_SYS_EXEC_H 1 _ACEOF else echo "$as_me:$LINENO: checking a.out.h" >&5 echo $ECHO_N "checking a.out.h... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct exec foo; unsigned long seek; int flag; #if defined(__mips) || defined(mips) seek = N_TXTOFF (foo.ex_f, foo.ex_o); #else seek = N_TXTOFF (foo); #endif flag = (foo.a_magic == OMAGIC); return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_ok=usable else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_ok=unusable fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $tcl_ok" >&5 echo "${ECHO_T}$tcl_ok" >&6 if test $tcl_ok = usable; then cat >>confdefs.h <<\_ACEOF #define USE_A_OUT_H 1 _ACEOF else echo "$as_me:$LINENO: checking sys/exec_aout.h" >&5 echo $ECHO_N "checking sys/exec_aout.h... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct exec foo; unsigned long seek; int flag; #if defined(__mips) || defined(mips) seek = N_TXTOFF (foo.ex_f, foo.ex_o); #else seek = N_TXTOFF (foo); #endif flag = (foo.a_midmag == OMAGIC); return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_ok=usable else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_ok=unusable fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $tcl_ok" >&5 echo "${ECHO_T}$tcl_ok" >&6 if test $tcl_ok = usable; then cat >>confdefs.h <<\_ACEOF #define USE_SYS_EXEC_AOUT_H 1 _ACEOF else DL_OBJS="" fi fi fi fi # Step 5: disable dynamic loading if requested via a command-line switch. # Check whether --enable-load or --disable-load was given. if test "${enable_load+set}" = set; then enableval="$enable_load" tcl_ok=$enableval else tcl_ok=yes fi; if test "$tcl_ok" = "no"; then DL_OBJS="" fi if test "x$DL_OBJS" != "x" ; then BUILD_DLTEST="\$(DLTEST_TARGETS)" else echo "Can't figure out how to do dynamic loading or shared libraries" echo "on this system." SHLIB_CFLAGS="" SHLIB_LD="" SHLIB_SUFFIX="" DL_OBJS="tclLoadNone.o" DL_LIBS="" LDFLAGS="$LDFLAGS_ORIG" LD_SEARCH_FLAGS="" BUILD_DLTEST="" fi # If we're running gcc, then change the C flags for compiling shared # libraries to the right flags for gcc, instead of those for the # standard manufacturer compiler. if test "$DL_OBJS" != "tclLoadNone.o" ; then if test "$GCC" = "yes" ; then case $system in AIX-*) ;; BSD/OS*) ;; IRIX*) ;; NetBSD-*|FreeBSD-*) ;; Darwin-*) ;; RISCos-*) ;; SCO_SV-3.2*) ;; ULTRIX-4.*) ;; windows) ;; *) SHLIB_CFLAGS="-fPIC" ;; esac fi fi if test "$SHARED_LIB_SUFFIX" = "" ; then SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}' fi if test "$UNSHARED_LIB_SUFFIX" = "" ; then UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a' fi # These must be called after we do the basic CFLAGS checks and # verify any possible 64-bit or similar switches are necessary echo "$as_me:$LINENO: checking for required early compiler flags" >&5 echo $ECHO_N "checking for required early compiler flags... $ECHO_C" >&6 tcl_flags="" if test "${tcl_cv_flag__isoc99_source+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char *p = (char *)strtoll; char *q = (char *)strtoull; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_flag__isoc99_source=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _ISOC99_SOURCE 1 #include int main () { char *p = (char *)strtoll; char *q = (char *)strtoull; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_flag__isoc99_source=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_flag__isoc99_source=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_flag__isoc99_source}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define _ISOC99_SOURCE 1 _ACEOF tcl_flags="$tcl_flags _ISOC99_SOURCE" fi if test "${tcl_cv_flag__largefile64_source+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct stat64 buf; int i = stat64("/", &buf); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_flag__largefile64_source=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _LARGEFILE64_SOURCE 1 #include int main () { struct stat64 buf; int i = stat64("/", &buf); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_flag__largefile64_source=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_flag__largefile64_source=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_flag__largefile64_source}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define _LARGEFILE64_SOURCE 1 _ACEOF tcl_flags="$tcl_flags _LARGEFILE64_SOURCE" fi if test "x${tcl_flags}" = "x" ; then echo "$as_me:$LINENO: result: none" >&5 echo "${ECHO_T}none" >&6 else echo "$as_me:$LINENO: result: ${tcl_flags}" >&5 echo "${ECHO_T}${tcl_flags}" >&6 fi echo "$as_me:$LINENO: checking for 64-bit integer type" >&5 echo $ECHO_N "checking for 64-bit integer type... $ECHO_C" >&6 if test "${tcl_cv_type_64bit+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else tcl_cv_type_64bit=none # See if the compiler knows natively about __int64 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { __int64 value = (__int64) 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_type_64bit=__int64 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_type_64bit="long long" fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext # See if we should use long anyway Note that we substitute in the # type that is our current guess for a 64-bit type inside this check # program, so it should be modified only carefully... cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { switch (0) { case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ; } ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_type_64bit=${tcl_type_64bit} else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "${tcl_cv_type_64bit}" = none ; then cat >>confdefs.h <<\_ACEOF #define TCL_WIDE_INT_IS_LONG 1 _ACEOF echo "$as_me:$LINENO: result: using long" >&5 echo "${ECHO_T}using long" >&6 elif test "${tcl_cv_type_64bit}" = "__int64" \ -a "${TEA_PLATFORM}" = "windows" ; then # We actually want to use the default tcl.h checks in this # case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER* echo "$as_me:$LINENO: result: using Tcl header defaults" >&5 echo "${ECHO_T}using Tcl header defaults" >&6 else cat >>confdefs.h <<_ACEOF #define TCL_WIDE_INT_TYPE ${tcl_cv_type_64bit} _ACEOF echo "$as_me:$LINENO: result: ${tcl_cv_type_64bit}" >&5 echo "${ECHO_T}${tcl_cv_type_64bit}" >&6 # Now check for auxiliary declarations echo "$as_me:$LINENO: checking for struct dirent64" >&5 echo $ECHO_N "checking for struct dirent64... $ECHO_C" >&6 if test "${tcl_cv_struct_dirent64+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { struct dirent64 p; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_struct_dirent64=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_struct_dirent64=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRUCT_DIRENT64 1 _ACEOF fi echo "$as_me:$LINENO: result: ${tcl_cv_struct_dirent64}" >&5 echo "${ECHO_T}${tcl_cv_struct_dirent64}" >&6 echo "$as_me:$LINENO: checking for struct stat64" >&5 echo $ECHO_N "checking for struct stat64... $ECHO_C" >&6 if test "${tcl_cv_struct_stat64+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct stat64 p; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_struct_stat64=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_struct_stat64=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_struct_stat64}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRUCT_STAT64 1 _ACEOF fi echo "$as_me:$LINENO: result: ${tcl_cv_struct_stat64}" >&5 echo "${ECHO_T}${tcl_cv_struct_stat64}" >&6 echo "$as_me:$LINENO: checking for off64_t" >&5 echo $ECHO_N "checking for off64_t... $ECHO_C" >&6 if test "${tcl_cv_type_off64_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { off64_t offset; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_type_off64_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_type_off64_t=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_type_off64_t}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_TYPE_OFF64_T 1 _ACEOF fi echo "$as_me:$LINENO: result: ${tcl_cv_type_off64_t}" >&5 echo "${ECHO_T}${tcl_cv_type_off64_t}" >&6 fi #-------------------------------------------------------------------- # Set the default compiler switches based on the --enable-symbols option. #-------------------------------------------------------------------- DBGX="" echo "$as_me:$LINENO: checking for build with symbols" >&5 echo $ECHO_N "checking for build with symbols... $ECHO_C" >&6 # Check whether --enable-symbols or --disable-symbols was given. if test "${enable_symbols+set}" = set; then enableval="$enable_symbols" tcl_ok=$enableval else tcl_ok=no fi; if test "$tcl_ok" = "no"; then CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}" LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}" echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 else CFLAGS_DEFAULT="${CFLAGS_DEBUG}" LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}" if test "$tcl_ok" = "yes"; then echo "$as_me:$LINENO: result: yes (standard debugging)" >&5 echo "${ECHO_T}yes (standard debugging)" >&6 fi fi if test "${TEA_PLATFORM}" != "windows" ; then LDFLAGS_DEFAULT="${LDFLAGS}" fi if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then cat >>confdefs.h <<\_ACEOF #define TCL_MEM_DEBUG 1 _ACEOF fi if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then if test "$tcl_ok" = "all"; then echo "$as_me:$LINENO: result: enabled symbols mem debugging" >&5 echo "${ECHO_T}enabled symbols mem debugging" >&6 else echo "$as_me:$LINENO: result: enabled $tcl_ok debugging" >&5 echo "${ECHO_T}enabled $tcl_ok debugging" >&6 fi fi #-------------------------------------------------------------------- # Everyone should be linking against the Tcl stub library. If you # can't for some reason, remove this definition. If you aren't using # stubs, you also need to modify the SHLIB_LD_LIBS setting below to # link against the non-stubbed Tcl library. Add Tk too if necessary. #-------------------------------------------------------------------- # allan: can't use stubs, due to BLT dependency #AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs]) #AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs]) #-------------------------------------------------------------------- # This macro generates a line to use when building a library. It # depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS, # and TEA_LOAD_TCLCONFIG macros above. #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then MAKE_STATIC_LIB="\${STLIB_LD} -out:\$@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\$@ \$(PKG_OBJECTS)" MAKE_STUB_LIB="\${STLIB_LD} -out:\$@ \$(PKG_STUB_OBJECTS)" else MAKE_STATIC_LIB="\${STLIB_LD} \$@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} -o \$@ \$(PKG_OBJECTS) \${LDFLAGS_DEFAULT} \${SHLIB_LD_LIBS}" MAKE_STUB_LIB="\${STLIB_LD} \$@ \$(PKG_STUB_OBJECTS)" fi if test "${SHARED_BUILD}" = "1" ; then MAKE_LIB="${MAKE_SHARED_LIB} " else MAKE_LIB="${MAKE_STATIC_LIB} " fi #-------------------------------------------------------------------- # Shared libraries and static libraries have different names. # Use the double eval to make sure any variables in the suffix is # substituted. (@@@ Might not be necessary anymore) #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" ; then if test "${SHARED_BUILD}" = "1" ; then # We force the unresolved linking of symbols that are really in # the private libraries of Tcl and Tk. SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_LIB_FILE}`\"" if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_LIB_FILE}`\"" fi eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" else eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" fi # Some packages build there own stubs libraries eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" # These aren't needed on Windows (either MSVC or gcc) RANLIB=: RANLIB_STUB=: else RANLIB_STUB="${RANLIB}" if test "${SHARED_BUILD}" = "1" ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_LIB_SPEC}" if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_LIB_SPEC}" fi eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" RANLIB=: else eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" fi # Some packages build there own stubs libraries eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" fi # These are escaped so that only CFLAGS is picked up at configure time. # The other values will be substituted at make time. CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}" if test "${SHARED_BUILD}" = "1" ; then CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}" fi #-------------------------------------------------------------------- # Determine the name of the tclsh and/or wish executables in the # Tcl and Tk build directories or the location they were installed # into. These paths are used to support running test cases only, # the Makefile should not be making use of these paths to generate # a pkgIndex.tcl file or anything else at extension build time. #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking for tclsh" >&5 echo $ECHO_N "checking for tclsh... $ECHO_C" >&6 if test -f "${TCL_BIN_DIR}/Makefile" ; then # tclConfig.sh is in Tcl build directory if test "${TEA_PLATFORM}" = "windows"; then TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" else TCLSH_PROG="${TCL_BIN_DIR}/tclsh" fi else # tclConfig.sh is in install location if test "${TEA_PLATFORM}" = "windows"; then TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" else TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}" fi list="`ls -d ${TCL_PREFIX}/bin 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null`" for i in $list ; do if test -f "$i/${TCLSH_PROG}" ; then REAL_TCL_BIN_DIR="`cd "$i"; pwd`" break fi done TCLSH_PROG="${REAL_TCL_BIN_DIR}/${TCLSH_PROG}" fi echo "$as_me:$LINENO: result: ${TCLSH_PROG}" >&5 echo "${ECHO_T}${TCLSH_PROG}" >&6 echo "$as_me:$LINENO: checking for wish" >&5 echo $ECHO_N "checking for wish... $ECHO_C" >&6 if test -f "${TK_BIN_DIR}/Makefile" ; then # tkConfig.sh is in Tk build directory if test "${TEA_PLATFORM}" = "windows"; then WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" else WISH_PROG="${TK_BIN_DIR}/wish" fi else # tkConfig.sh is in install location if test "${TEA_PLATFORM}" = "windows"; then WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" else WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}" fi list="`ls -d ${TK_PREFIX}/bin 2>/dev/null` \ `ls -d ${TK_BIN_DIR}/../bin 2>/dev/null`" for i in $list ; do if test -f "$i/${WISH_PROG}" ; then REAL_TK_BIN_DIR="`cd "$i"; pwd`" break fi done WISH_PROG="${REAL_TK_BIN_DIR}/${WISH_PROG}" fi echo "$as_me:$LINENO: result: ${WISH_PROG}" >&5 echo "${ECHO_T}${WISH_PROG}" >&6 #-------------------------------------------------------------------- # These are for catConfig.sh #-------------------------------------------------------------------- cat_LIB_FILE=${PKG_LIB_FILE} eval pkglibdir="${libdir}" if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then eval cat_LIB_FLAG="-lcat${PACKAGE_VERSION}" else eval cat_LIB_FLAG="-lcat`echo ${PACKAGE_VERSION} | tr -d .`" fi cat_BUILD_LIB_SPEC="-L`pwd` ${cat_LIB_FLAG}" cat_BUILD_DIR="`pwd`" cat_LIB_SPEC="-L${pkglibdir} ${cat_LIB_FLAG}" for i in ${PKG_OBJECTS} ; do cat_PKG_OBJECTS="$cat_PKG_OBJECTS ../cat/$i" done # cat_SRC_DIR must be a fully qualified path eval cat_SRC_DIR="$srcdir" cat_SRC_DIR=`cd "${cat_SRC_DIR}"; pwd` #-------------------------------------------------------------------- # Finally, substitute all of the various values into the Makefile. # You may alternatively have a special pkgIndex.tcl.in or other files # which require substituting th AC variables in. Include these here. #-------------------------------------------------------------------- ac_config_files="$ac_config_files Makefile pkgIndex.tcl catConfig.sh cat_version.tcl" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. { (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } | sed ' t clear : clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ : end' >>confcache if diff $cache_file confcache >/dev/null 2>&1; then :; else if test -w $cache_file; then test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" cat confcache >$cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/; s/:*\${srcdir}:*/:/; s/:*@srcdir@:*/:/; s/^\([^=]*=[ ]*\):*/\1/; s/:*$//; s/^[^=]*=[ ]*$//; }' fi # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then we branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. cat >confdef2opt.sed <<\_ACEOF t clear : clear s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g t quote s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g t quote d : quote s,[ `~#$^&*(){}\\|;'"<>?],\\&,g s,\[,\\&,g s,\],\\&,g s,\$,$$,g p _ACEOF # We use echo to avoid assuming a particular line-breaking character. # The extra dot is to prevent the shell from consuming trailing # line-breaks from the sub-command output. A line-break within # single-quotes doesn't work because, if this script is created in a # platform that uses two characters for line-breaks (e.g., DOS), tr # would break. ac_LF_and_DOT=`echo; echo .` DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` rm -f confdef2opt.sed ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_i=`echo "$ac_i" | sed 's/\$U\././;s/\.o$//;s/\.obj$//'` # 2. Add them. ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH exec 6>&1 # Open the log real soon, to keep \$[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. Logging --version etc. is OK. exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX } >&5 cat >&5 <<_CSEOF This file was extended by cat $as_me 4.1.0, which was generated by Starlink Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ _CSEOF echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 echo >&5 _ACEOF # Files that config.status was made for. if test -n "$ac_config_files"; then echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS fi if test -n "$ac_config_headers"; then echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS fi if test -n "$ac_config_links"; then echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS fi if test -n "$ac_config_commands"; then echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS fi cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ cat config.status 4.1.0 configured by $0, generated by Starlink Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2003 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." srcdir=$srcdir INSTALL="$INSTALL" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "x$1" : 'x\([^=]*\)='` ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` ac_shift=: ;; -*) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; *) # This is not an option, so the user has probably given explicit # arguments. ac_option=$1 ac_need_defaults=false;; esac case $ac_option in # Handling of the options. _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --vers* | -V ) echo "$ac_cs_version"; exit 0 ;; --he | --h) # Conflict between --help and --header { { echo "$as_me:$LINENO: error: ambiguous option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_config_target in $ac_config_targets do case "$ac_config_target" in # Handling of arguments. "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; "pkgIndex.tcl" ) CONFIG_FILES="$CONFIG_FILES pkgIndex.tcl" ;; "catConfig.sh" ) CONFIG_FILES="$CONFIG_FILES catConfig.sh" ;; "cat_version.tcl" ) CONFIG_FILES="$CONFIG_FILES cat_version.tcl" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason to put it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Create a temporary directory, and hook for its removal unless debugging. $debug || { trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./confstat$$-$RANDOM (umask 077 && mkdir $tmp) } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "\$CONFIG_FILES"; then # Protect against being on the right side of a sed subst in config.status. sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF s,@SHELL@,$SHELL,;t t s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t s,@exec_prefix@,$exec_prefix,;t t s,@prefix@,$prefix,;t t s,@program_transform_name@,$program_transform_name,;t t s,@bindir@,$bindir,;t t s,@sbindir@,$sbindir,;t t s,@libexecdir@,$libexecdir,;t t s,@datadir@,$datadir,;t t s,@sysconfdir@,$sysconfdir,;t t s,@sharedstatedir@,$sharedstatedir,;t t s,@localstatedir@,$localstatedir,;t t s,@libdir@,$libdir,;t t s,@includedir@,$includedir,;t t s,@oldincludedir@,$oldincludedir,;t t s,@infodir@,$infodir,;t t s,@mandir@,$mandir,;t t s,@build_alias@,$build_alias,;t t s,@host_alias@,$host_alias,;t t s,@target_alias@,$target_alias,;t t s,@DEFS@,$DEFS,;t t s,@ECHO_C@,$ECHO_C,;t t s,@ECHO_N@,$ECHO_N,;t t s,@ECHO_T@,$ECHO_T,;t t s,@LIBS@,$LIBS,;t t s,@CYGPATH@,$CYGPATH,;t t s,@EXEEXT@,$EXEEXT,;t t s,@PKG_LIB_FILE@,$PKG_LIB_FILE,;t t s,@PKG_STUB_LIB_FILE@,$PKG_STUB_LIB_FILE,;t t s,@PKG_STUB_SOURCES@,$PKG_STUB_SOURCES,;t t s,@PKG_STUB_OBJECTS@,$PKG_STUB_OBJECTS,;t t s,@PKG_TCL_SOURCES@,$PKG_TCL_SOURCES,;t t s,@PKG_HEADERS@,$PKG_HEADERS,;t t s,@PKG_INCLUDES@,$PKG_INCLUDES,;t t s,@PKG_LIBS@,$PKG_LIBS,;t t s,@PKG_CFLAGS@,$PKG_CFLAGS,;t t s,@TCL_VERSION@,$TCL_VERSION,;t t s,@TCL_BIN_DIR@,$TCL_BIN_DIR,;t t s,@TCL_SRC_DIR@,$TCL_SRC_DIR,;t t s,@TCL_LIB_FILE@,$TCL_LIB_FILE,;t t s,@TCL_LIB_FLAG@,$TCL_LIB_FLAG,;t t s,@TCL_LIB_SPEC@,$TCL_LIB_SPEC,;t t s,@TCL_STUB_LIB_FILE@,$TCL_STUB_LIB_FILE,;t t s,@TCL_STUB_LIB_FLAG@,$TCL_STUB_LIB_FLAG,;t t s,@TCL_STUB_LIB_SPEC@,$TCL_STUB_LIB_SPEC,;t t s,@TCL_LIBS@,$TCL_LIBS,;t t s,@TCL_DEFS@,$TCL_DEFS,;t t s,@TCL_EXTRA_CFLAGS@,$TCL_EXTRA_CFLAGS,;t t s,@TCL_LD_FLAGS@,$TCL_LD_FLAGS,;t t s,@TCL_SHLIB_LD_LIBS@,$TCL_SHLIB_LD_LIBS,;t t s,@TK_VERSION@,$TK_VERSION,;t t s,@TK_BIN_DIR@,$TK_BIN_DIR,;t t s,@TK_SRC_DIR@,$TK_SRC_DIR,;t t s,@TK_LIB_FILE@,$TK_LIB_FILE,;t t s,@TK_LIB_FLAG@,$TK_LIB_FLAG,;t t s,@TK_LIB_SPEC@,$TK_LIB_SPEC,;t t s,@TK_STUB_LIB_FILE@,$TK_STUB_LIB_FILE,;t t s,@TK_STUB_LIB_FLAG@,$TK_STUB_LIB_FLAG,;t t s,@TK_STUB_LIB_SPEC@,$TK_STUB_LIB_SPEC,;t t s,@TK_LIBS@,$TK_LIBS,;t t s,@TK_XINCLUDES@,$TK_XINCLUDES,;t t s,@CC@,$CC,;t t s,@CFLAGS@,$CFLAGS,;t t s,@LDFLAGS@,$LDFLAGS,;t t s,@CPPFLAGS@,$CPPFLAGS,;t t s,@ac_ct_CC@,$ac_ct_CC,;t t s,@OBJEXT@,$OBJEXT,;t t s,@CPP@,$CPP,;t t s,@CXX@,$CXX,;t t s,@CXXFLAGS@,$CXXFLAGS,;t t s,@ac_ct_CXX@,$ac_ct_CXX,;t t s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t s,@INSTALL_DATA@,$INSTALL_DATA,;t t s,@SET_MAKE@,$SET_MAKE,;t t s,@RANLIB@,$RANLIB,;t t s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t s,@EGREP@,$EGREP,;t t s,@MATH_LIBS@,$MATH_LIBS,;t t s,@tclutil_VERSION@,$tclutil_VERSION,;t t s,@tclutil_LIB_FILE@,$tclutil_LIB_FILE,;t t s,@tclutil_BUILD_LIB_SPEC@,$tclutil_BUILD_LIB_SPEC,;t t s,@tclutil_BUILD_DIR@,$tclutil_BUILD_DIR,;t t s,@tclutil_LIB_SPEC@,$tclutil_LIB_SPEC,;t t s,@BLT_LIB_SPEC@,$BLT_LIB_SPEC,;t t s,@tclutil_SRC_DIR@,$tclutil_SRC_DIR,;t t s,@tclutil_PKG_OBJECTS@,$tclutil_PKG_OBJECTS,;t t s,@CFITSIO_LIB_SPEC@,$CFITSIO_LIB_SPEC,;t t s,@astrotcl_VERSION@,$astrotcl_VERSION,;t t s,@astrotcl_LIB_FILE@,$astrotcl_LIB_FILE,;t t s,@astrotcl_BUILD_LIB_SPEC@,$astrotcl_BUILD_LIB_SPEC,;t t s,@astrotcl_BUILD_DIR@,$astrotcl_BUILD_DIR,;t t s,@astrotcl_LIB_SPEC@,$astrotcl_LIB_SPEC,;t t s,@astrotcl_SRC_DIR@,$astrotcl_SRC_DIR,;t t s,@astrotcl_PKG_OBJECTS@,$astrotcl_PKG_OBJECTS,;t t s,@MERGE_OBJECTS@,$MERGE_OBJECTS,;t t s,@SHLIB_LD_CXX_LIBS@,$SHLIB_LD_CXX_LIBS,;t t s,@PKG_SOURCES@,$PKG_SOURCES,;t t s,@PKG_OBJECTS@,$PKG_OBJECTS,;t t s,@CLEANFILES@,$CLEANFILES,;t t s,@TCL_INCLUDES@,$TCL_INCLUDES,;t t s,@TK_INCLUDES@,$TK_INCLUDES,;t t s,@TCL_THREADS@,$TCL_THREADS,;t t s,@SHARED_BUILD@,$SHARED_BUILD,;t t s,@AR@,$AR,;t t s,@CELIB_DIR@,$CELIB_DIR,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@SHLIB_SUFFIX@,$SHLIB_SUFFIX,;t t s,@DL_LIBS@,$DL_LIBS,;t t s,@CFLAGS_DEBUG@,$CFLAGS_DEBUG,;t t s,@CFLAGS_OPTIMIZE@,$CFLAGS_OPTIMIZE,;t t s,@CFLAGS_WARNING@,$CFLAGS_WARNING,;t t s,@STLIB_LD@,$STLIB_LD,;t t s,@SHLIB_LD@,$SHLIB_LD,;t t s,@SHLIB_CFLAGS@,$SHLIB_CFLAGS,;t t s,@SHLIB_LD_LIBS@,$SHLIB_LD_LIBS,;t t s,@LDFLAGS_DEBUG@,$LDFLAGS_DEBUG,;t t s,@LDFLAGS_OPTIMIZE@,$LDFLAGS_OPTIMIZE,;t t s,@LD_LIBRARY_PATH_VAR@,$LD_LIBRARY_PATH_VAR,;t t s,@TCL_DBGX@,$TCL_DBGX,;t t s,@CFLAGS_DEFAULT@,$CFLAGS_DEFAULT,;t t s,@LDFLAGS_DEFAULT@,$LDFLAGS_DEFAULT,;t t s,@MAKE_LIB@,$MAKE_LIB,;t t s,@MAKE_SHARED_LIB@,$MAKE_SHARED_LIB,;t t s,@MAKE_STATIC_LIB@,$MAKE_STATIC_LIB,;t t s,@MAKE_STUB_LIB@,$MAKE_STUB_LIB,;t t s,@RANLIB_STUB@,$RANLIB_STUB,;t t s,@TCLSH_PROG@,$TCLSH_PROG,;t t s,@WISH_PROG@,$WISH_PROG,;t t s,@cat_LIB_FILE@,$cat_LIB_FILE,;t t s,@cat_BUILD_LIB_SPEC@,$cat_BUILD_LIB_SPEC,;t t s,@cat_BUILD_DIR@,$cat_BUILD_DIR,;t t s,@cat_LIB_SPEC@,$cat_LIB_SPEC,;t t s,@cat_PKG_OBJECTS@,$cat_PKG_OBJECTS,;t t s,@cat_SRC_DIR@,$cat_SRC_DIR,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_lines=48 ac_sed_frag=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_lines # Line after last line for current file. ac_more_lines=: ac_sed_cmds= while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag else sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag fi if test ! -s $tmp/subs.frag; then ac_more_lines=false else # The purpose of the label and of the branching condition is to # speed up the sed processing (if there are no `@' at all, there # is no need to browse any of the substitutions). # These are the two extra sed commands mentioned above. (echo ':t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" else ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" fi ac_sed_frag=`expr $ac_sed_frag + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_lines` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi fi # test -n "$CONFIG_FILES" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_builddir$INSTALL ;; esac if test x"$ac_file" != x-; then { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} rm -f "$ac_file" fi # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then configure_input= else configure_input="$ac_file. " fi configure_input=$configure_input"Generated from `echo $ac_file_in | sed 's,.*/,,'` by configure." # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo "$f";; *) # Relative if test -f "$f"; then # Build tree echo "$f" elif test -f "$srcdir/$f"; then # Source tree echo "$srcdir/$f" else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s,@configure_input@,$configure_input,;t t s,@srcdir@,$ac_srcdir,;t t s,@abs_srcdir@,$ac_abs_srcdir,;t t s,@top_srcdir@,$ac_top_srcdir,;t t s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t s,@builddir@,$ac_builddir,;t t s,@abs_builddir@,$ac_abs_builddir,;t t s,@top_builddir@,$ac_top_builddir,;t t s,@abs_top_builddir@,$ac_abs_top_builddir,;t t s,@INSTALL@,$ac_INSTALL,;t t " $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out rm -f $tmp/stdin if test x"$ac_file" != x-; then mv $tmp/out $ac_file else cat $tmp/out rm -f $tmp/out fi done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi skycat-3.1.2-starlink-1b/cat/configure.in000066400000000000000000000215401215713201500202170ustar00rootroot00000000000000# E.S.O. - VLT project # $Id: configure.in,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is used with GNU autoconf to generate a configure script # # usage: % autoconf # only if configure.in changed # % configure # % make # % make install # # who when what # -------------- -------- --------------------------------------------- # Allan Brighton 15/12/05 Rewrote using TCL TEA standard # ----------------------------------------------------------------------- #----------------------------------------------------------------------- # Sample configure.in for Tcl Extensions. The only places you should # need to modify this file are marked by the string __CHANGE__ #----------------------------------------------------------------------- #----------------------------------------------------------------------- # __CHANGE__ # Set your package name and version numbers here. # # This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION # set as provided. These will also be added as -D defs in your Makefile # so you can encode the package version directly into the source files. #----------------------------------------------------------------------- AC_INIT([cat], [4.1.0]) #-------------------------------------------------------------------- # Call TEA_INIT as the first TEA_ macro to set up initial vars. # This will define a ${TEA_PLATFORM} variable == "unix" or "windows" # as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE. #-------------------------------------------------------------------- TEA_INIT([3.4]) #-------------------------------------------------------------------- # Load the tclConfig.sh file #-------------------------------------------------------------------- TEA_PATH_TCLCONFIG TEA_LOAD_TCLCONFIG #-------------------------------------------------------------------- # Load the tkConfig.sh file if necessary (Tk extension) #-------------------------------------------------------------------- TEA_PATH_TKCONFIG TEA_LOAD_TKCONFIG #----------------------------------------------------------------------- # Handle the --prefix=... option by defaulting to what Tcl gave. # Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER. #----------------------------------------------------------------------- TEA_PREFIX #----------------------------------------------------------------------- # Standard compiler checks. # This sets up CC by using the CC env var, or looks for gcc otherwise. # This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create # the basic setup necessary to compile executables. #----------------------------------------------------------------------- TEA_SETUP_COMPILER #-------------------------------------------------------------------- # Do application specific checks (see aclocal.m4) #-------------------------------------------------------------------- CAT_CONFIG #----------------------------------------------------------------------- # __CHANGE__ # Specify the C source files to compile in TEA_ADD_SOURCES, # public headers that need to be installed in TEA_ADD_HEADERS, # stub library C source files to compile in TEA_ADD_STUB_SOURCES, # and runtime Tcl library files in TEA_ADD_TCL_SOURCES. # This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS # and PKG_TCL_SOURCES. #----------------------------------------------------------------------- TEA_ADD_SOURCES([${csources}]) TEA_ADD_HEADERS([${cheaders}]) TEA_ADD_INCLUDES([${cincludes}]) if test $MERGED = yes ; then TEA_ADD_LIBS(${BLT_LIB_SPEC} ${CFITSIO_LIB_SPEC}) else TEA_ADD_LIBS([$astrotcl_BUILD_LIB_SPEC $tclutil_BUILD_LIB_SPEC ${BLT_LIB_SPEC} ${CFITSIO_LIB_SPEC}]) fi TEA_ADD_CFLAGS([]) TEA_ADD_STUB_SOURCES([]) TEA_ADD_TCL_SOURCES([${tclsources}]) #-------------------------------------------------------------------- # __CHANGE__ # A few miscellaneous platform-specific items: # # Define a special symbol for Windows (BUILD_sample in this case) so # that we create the export library with the dll. # # Windows creates a few extra files that need to be cleaned up. # You can add more files to clean if your extension creates any extra # files. # # TEA_ADD_* any platform specific compiler/build info here. #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" ; then AC_DEFINE(BUILD_cat, 1, [Build windows export dll]) CLEANFILES="*.lib *.dll *.exp *.ilk *.pdb vc*.pch" #TEA_ADD_SOURCES([win/winFile.c]) #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"]) else CLEANFILES="" #TEA_ADD_SOURCES([unix/unixFile.c]) #TEA_ADD_LIBS([-lsuperfly]) fi AC_SUBST(CLEANFILES) #-------------------------------------------------------------------- # __CHANGE__ # Choose which headers you need. Extension authors should try very # hard to only rely on the Tcl public header files. Internal headers # contain private data structures and are subject to change without # notice. # This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG #-------------------------------------------------------------------- TEA_PUBLIC_TCL_HEADERS #TEA_PRIVATE_TCL_HEADERS TEA_PUBLIC_TK_HEADERS #TEA_PRIVATE_TK_HEADERS TEA_PATH_X #-------------------------------------------------------------------- # Check whether --enable-threads or --disable-threads was given. # This auto-enables if Tcl was compiled threaded. #-------------------------------------------------------------------- TEA_ENABLE_THREADS #-------------------------------------------------------------------- # The statement below defines a collection of symbols related to # building as a shared library instead of a static library. #-------------------------------------------------------------------- TEA_ENABLE_SHARED #-------------------------------------------------------------------- # This macro figures out what flags to use with the compiler/linker # when building shared/static debug/optimized objects. This information # can be taken from the tclConfig.sh file, but this figures it all out. #-------------------------------------------------------------------- TEA_CONFIG_CFLAGS #-------------------------------------------------------------------- # Set the default compiler switches based on the --enable-symbols option. #-------------------------------------------------------------------- TEA_ENABLE_SYMBOLS #-------------------------------------------------------------------- # Everyone should be linking against the Tcl stub library. If you # can't for some reason, remove this definition. If you aren't using # stubs, you also need to modify the SHLIB_LD_LIBS setting below to # link against the non-stubbed Tcl library. Add Tk too if necessary. #-------------------------------------------------------------------- # allan: can't use stubs, due to BLT dependency #AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs]) #AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs]) #-------------------------------------------------------------------- # This macro generates a line to use when building a library. It # depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS, # and TEA_LOAD_TCLCONFIG macros above. #-------------------------------------------------------------------- TEA_MAKE_LIB #-------------------------------------------------------------------- # Determine the name of the tclsh and/or wish executables in the # Tcl and Tk build directories or the location they were installed # into. These paths are used to support running test cases only, # the Makefile should not be making use of these paths to generate # a pkgIndex.tcl file or anything else at extension build time. #-------------------------------------------------------------------- TEA_PROG_TCLSH TEA_PROG_WISH #-------------------------------------------------------------------- # These are for catConfig.sh #-------------------------------------------------------------------- cat_LIB_FILE=${PKG_LIB_FILE} eval pkglibdir="${libdir}" if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then eval cat_LIB_FLAG="-lcat${PACKAGE_VERSION}" else eval cat_LIB_FLAG="-lcat`echo ${PACKAGE_VERSION} | tr -d .`" fi cat_BUILD_LIB_SPEC="-L`pwd` ${cat_LIB_FLAG}" cat_BUILD_DIR="`pwd`" cat_LIB_SPEC="-L${pkglibdir} ${cat_LIB_FLAG}" for i in ${PKG_OBJECTS} ; do cat_PKG_OBJECTS="$cat_PKG_OBJECTS ../cat/$i" done AC_SUBST(cat_LIB_FILE) AC_SUBST(cat_BUILD_LIB_SPEC) AC_SUBST(cat_BUILD_DIR) AC_SUBST(cat_LIB_SPEC) AC_SUBST(cat_PKG_OBJECTS) # cat_SRC_DIR must be a fully qualified path eval cat_SRC_DIR="$srcdir" cat_SRC_DIR=`cd "${cat_SRC_DIR}"; pwd` AC_SUBST(cat_SRC_DIR) #-------------------------------------------------------------------- # Finally, substitute all of the various values into the Makefile. # You may alternatively have a special pkgIndex.tcl.in or other files # which require substituting th AC variables in. Include these here. #-------------------------------------------------------------------- AC_OUTPUT([Makefile pkgIndex.tcl catConfig.sh cat_version.tcl]) skycat-3.1.2-starlink-1b/cat/generic/000077500000000000000000000000001215713201500173205ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/cat/generic/AstroCatalog.C000066400000000000000000000654761215713201500220310ustar00rootroot00000000000000/* * E.S.O. - VLT project/ESO Archive * $Id: AstroCatalog.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * AstroCatalog.C - method definitions for class AstroCatalog * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 95 Created * Peter W. Draper 01 May 03 Added "ws" and "hs" to get width and * height in arcsecs (2MASS image servers) * Peter W. Draper 10 Dec 03 Moved "delete cat" in nameToWorldCoords * so that it is performed after the last * reference to "cat" (->equinox()). * Started crashing query subprocess. * 27 Aug 08 Allow image/fits as a content type. */ static const char* const rcsId="@(#) $Id: AstroCatalog.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include #include #include #include #include #include #include #include #include "error.h" #include "DCompress.h" #include "WorldOrImageCoords.h" #include "HTTP.h" #include "Mem.h" #include "AstroCatalog.h" #include "LocalCatalog.h" using namespace std; /* * swap 2 values */ static inline void swap(double& x1, double& x2) { double tmp = x2; x2 = x1; x1 = tmp; } /* * constructor - used internally only, public interface uses "open(name)" * "e" is the catalog config entry object for this catalog * (see CatalogInfo class) */ AstroCatalog::AstroCatalog(CatalogInfoEntry* e) : entry_(e), status_(OK), more_(0), tmpfile_(NULL) { newTempFile(); } /* * destructor - close catalog and free any resources */ AstroCatalog::~AstroCatalog() { if (tmpfile_) { unlink(tmpfile_); free(tmpfile_); } } /* * copy constructor */ AstroCatalog::AstroCatalog(const AstroCatalog& a) { tmpfile_ = a.tmpfile_ ? strdup(a.tmpfile_) : (char*)NULL; } /* * Return true if the given entry is for a catalog (not an image server or dir) */ int AstroCatalog::isCatalog(CatalogInfoEntry* e) { const char* s = e->servType(); return (strcmp(s, "catalog") == 0 || strcmp(s, "local") == 0 || strcmp(s, "archive") == 0 || strcmp(s, "namesvr") == 0); } /* * Return true if the given entry is for an image server */ int AstroCatalog::isImageServer(CatalogInfoEntry* e) { return (strcmp(e->servType(), "imagesvr") == 0); } /* * Return true if the given entry is for a local catalog */ int AstroCatalog::isLocalCatalog(CatalogInfoEntry* e) { return (strcmp(e->servType(), "local") == 0); } /* * Generate an error message indicating that the wrong type of * catalog was used. */ int AstroCatalog::wrongServType(CatalogInfoEntry* e) { return error("This operation is not allowed for catalogs of type ", e->servType()); } /* * Do a dummy query to get the column names for this catalog and set the * member variable info_ to the result. The return value is 0 if the * query was successful. * * XXX need a standard query syntax for this ? */ int AstroCatalog::getInfo() { if (! isCatalog(entry_)) return ERROR; int more = more_; // don't want to overwrite this flag here AstroQuery q; if (entry_->isWcs()) q.pos(WorldCoords(0., 0.)); // dummy world coords else if (entry_->isPix()) q.pos(ImageCoords(0., 0.)); // dummy image coords q.maxRows(1); int nrows = query(q, NULL, info_); more_ = more; // restore value of this flag if (nrows >= 0) return OK; return ERROR; } /* * If we don't have the header info for this catalog, get it and * return the status. */ int AstroCatalog::checkInfo() { if (info_.numCols() > 0) return 0; return getInfo(); } /* * return the number of columns in the catalog */ int AstroCatalog::numCols() { return ((checkInfo() == OK) ? info_.numCols() : -1); } /* * return a ptr to an array of catalog column names */ char** AstroCatalog::colNames() { return (char**)((checkInfo() == OK) ? info_.colNames() : NULL); } /* * return the name of the given column */ const char* AstroCatalog::colName(int col) { return ((checkInfo() == OK) ? info_.colName(col) : (char*)NULL); } /* * return the column index for the given column name */ int AstroCatalog::colIndex(const char* colName) { return ((checkInfo() == OK) ? info_.colIndex(colName) : -1); } /* * This static method is called to open the named catalog and return a * pointer to an AstroCatalog object for it, or NULL if errors occur. * This is the main entry point to the class. */ AstroCatalog* AstroCatalog::open(const char* name) { // get the entry for this catalog type CatalogInfoEntry* e = CatalogInfo::lookup(name); if (!e) return NULL; // error - no config entry AstroCatalog* result = NULL; if (isLocalCatalog(e)) { result = new LocalCatalog(e); // derived class handles local catalog files } else if (isCatalog(e) || isImageServer(e)) { result = new AstroCatalog(e); // this class handles catalogs and image servers } else { fmt_error("'%s' is of type '%s', not a catalog, archive or image server", name, e->servType()); return NULL; } if (result->status() != 0) { delete result; return NULL; // error making catalog } return result; // normal return } /* * static method to use a name server catalog (simbad_ns@eso or ned_ns@eso) * to get the coordinates from the object name. If feedback is not NULL, * status info is written to the given open file. * * On success, sets the position arg and returns 0, else 1. */ int AstroCatalog::nameToWorldCoords( const char* objName, WorldOrImageCoords& pos, const char* nameServer, FILE* feedback) { double ra, dec; QueryResult result; AstroCatalog* cat = AstroCatalog::open(nameServer); if (cat == NULL) return ERROR; if (cat->getObject(objName, 0, NULL, result)) { delete cat; return ERROR; } if (result.get(0, cat->ra_col(), ra) || result.get(0, cat->dec_col(), dec)) { delete cat; return ERROR; } pos = WorldCoords(ra, dec, cat->equinox()); delete cat; return 0; } /* * Pass a query to the catalog and return the number of objects found. * Only the given columns are retrieved. * * Args: * q - (in) object describing the query * * filename - (in) filename to hold results, or null * * result - (out) reference to object used to access the results * * The return value is the number of rows found, or 0 if none were found. * A return value of -1 indicates an error. */ int AstroCatalog::query(const AstroQuery& q, const char* filename, QueryResult& result) { if (! isCatalog(entry_)) return wrongServType(entry_); // generate the URL for a standard query in buf (using ostringstream) char* result_buf = NULL; int nlines = 0; // if the first URL doesn't work, try the others, if specified const char* urls[3]; urls[0] = entry_->url(); urls[1] = entry_->backup1(); urls[2] = entry_->backup2(); char url[10000]; char* ctype = (char *)""; for (int i = 0; i < 3 && urls[i]; i++) { if (genHttpQuery(url, sizeof(url), q, urls[i]) != 0) return -1; // send the query result_buf = http_.get(url, nlines); ctype = http_.content_type(); if (!ctype) ctype = (char *)""; if (result_buf != NULL && strcmp(ctype, "text/html") != 0) break; // don't go to backup URL if it was a request for authorization if (http_.authorizationRequired()) break; } if (result_buf == NULL) return -1; // error in http get // check the Content-type of the return data if (strcmp(ctype, "text/html") == 0) { // most likely an error message http_.html_error(result_buf); return -1; } // note the catalog config entry in the results // (This contains important info, such as the location of the id, a and dec cols) result.entry(entry_, result_buf); if (result.init(result_buf) != 0) return -1; // error // sort result ? // note: do this before truncating to maxRows to get correct results if (q.numSortCols()) result.sort(q.numSortCols(), q.sortCols(), q.sortOrder()); if (q.maxRows() && result.numRows() > q.maxRows()) { more_ = 1; result.numRows(q.maxRows()); } else { more_ = 0; } // if we didn't already, note the catalog's column heading info if (info_.numCols() <= 0 && info_.init(result.numCols(), result.colNames(), "", 1) != 0) return -1; if (filename && result.save(filename) != 0) return -1; return result.numRows(); } /* * Request an image from the image server based on the given query description * and return 0 if all is ok. (Only valid for image servers). * The name of a FITS file containing the resulting image can be accessed as * this->tmpfile(). * * The catalog config file defines the URL used to get the image. */ int AstroCatalog::getImage(const AstroQuery& q) { if (! isImageServer(entry_)) return wrongServType(entry_); // if the first URL doesn't work, try the others, if specified const char* urls[3]; urls[0] = entry_->url(); urls[1] = entry_->backup1(); urls[2] = entry_->backup2(); char url[10000]; // for each url, backup-url, etc... for (int i = 0; i < 3 && urls[i]; i++) { if (genHttpQuery(url, sizeof(url), q, urls[i]) != 0) return 1; // error if (getImage(url) == 0) return 0; // normal return // don't go to backup URL if it was a request for authorization if (http_.authorizationRequired()) return 1; // error } return 1; // error, none of the URLs worked } /* * Given a URL for an image, request the image from the image server and * return 0 if all is ok. The name of the FITS file containing the * resulting image can be accessed with the method "this->tmpfile()" */ int AstroCatalog::getImage(const char* url) { char* ctype = (char *)""; if (getPreview(url, ctype) == 0 && ( strcmp(ctype, "image/x-fits") == 0 || strcmp(ctype, "image/fits" ) == 0 ) ) return 0; // ok return 1; // error } /* * generate the HTTP catalog query string from the AstroQuery object and URL string * and write it to the given buffer (buf) of size bufsz. * * Note: if the query specifies only an object Id, we need to handle a * a search for the specific ID * * Note: if 2 positions or a width and height were specified in the query, * we need to return the objects in the "area" * * Note: if 1 pos (+ optional mag0, mag1) are specified in the query and * maxRows is 1, we are looking for the "closest" object * * The following substitutions are then performed on the given URL: * * %ra, %dec - world coordinates of center point (for catalogs based in wcs) * * %x, %y - image coordinates of center point (for pixel based catalogs) * * %w, %h - width and height of area in arcmin (area query) * * %ws, %hs - width and height of area in arcsec (area query) * * %r1, %r2 - min and max radius (for circular query) * * %m1, %m2 - min and max magnitude * * %n - max number of rows to return * * %cols - comma sep. list of columns to return: col1,col2,...coln * * %id - ID field of item to return (if supported) * * %mime-type - value for http mime-type field * * %sort - insert list of sort columns: col1,col2,... * * %sortorder - insert string: increasing or decreasing * * %cond - insert search condition, if any, in the format * col1=minVal,maxVal&col2=minVal,maxVal,... */ int AstroCatalog::genHttpQuery(char* buf, int bufsz, const AstroQuery& q, const char* url) { if (q.pos().status() != 0) return ERROR; std::ostringstream os; int i; int url_has_id = 0, url_has_radec = 0, url_has_xy = 0; // XXX temp - until gsc-server is fixed const char* shortName = entry_->shortName(); if (shortName && strncmp(shortName, "gsc", 3) == 0 && q.mag1() == 0.0 && q.mag2() == 0.0) { ((AstroQuery&)q).mag(0., 15.); } // expand the variables in the catalog server command while(*url) { if (*url == '%') { url++; if (*url == '%') { // make "%%" expand to "%" os << '%'; url ++; } else if (strncmp(url, "id", 2) == 0) { os << q.id(); url += 2; url_has_id++; } else if (strncmp(url, "ra", 2) == 0) { os << q.pos().ra(); url += 2; url_has_radec++; } else if (strncmp(url, "dec", 3) == 0) { os << q.pos().dec(); url += 3; url_has_radec++; } else if (*url == 'x') { os << q.pos().x(); url++; url_has_xy++; } else if (*url == 'y') { os << q.pos().y(); url++; url_has_xy++; } else if (strncmp(url, "r1", 2) == 0) { if (q.radius1() != 0.0 || q.radius2() != 0.0) os << q.radius1(); url += 2; } else if (strncmp(url, "r2", 2) == 0) { if (q.radius1() != 0.0 || q.radius2() != 0.0) os << q.radius2(); url += 2; } else if (strncmp(url, "m1", 2) == 0) { if (q.mag1() != 0.0 || q.mag2() != 0.0) os << q.mag1(); url += 2; } else if (strncmp(url, "m2", 2) == 0) { if (q.mag1() != 0.0 || q.mag2() != 0.0) os << q.mag2(); url += 2; } else if (*url == 'n') { // request one more row than maxRows, // so we can determine if that was all... if (q.maxRows() > 0) os << q.maxRows()+1; url++; } else if (strncmp(url, "ws", 2) == 0) { if (q.width() != 0.0 || q.height() != 0.0) os << q.width() * 60.0; url++; } else if (strncmp(url, "hs", 2) == 0) { if (q.width() != 0.0 || q.height() != 0.0) os << q.height() * 60.0; url++; } else if (strncmp(url, "w", 1) == 0) { if (q.width() != 0.0 || q.height() != 0.0) os << q.width(); url++; } else if (strncmp(url, "h", 1) == 0) { if (q.width() != 0.0 || q.height() != 0.0) os << q.height(); url++; } else if (strncmp(url, "cols", 4) == 0) { // insert a list of column names for (i = 0; i < q.numCols(); i++) { os << q.colName(i); if (q.numCols() - i > 1) os << ','; } url += 4; } else if (strncmp(url, "sortorder", 9) == 0) { os << ((q.sortOrder() < 0) ? "decreasing" : "increasing"); url += 9; } else if (strncmp(url, "sort", 4) == 0) { // insert a list of sort column names // XXX note: not all servers may accept the list... int n = q.numSortCols(); if (n > 0) { char** ar = q.sortCols(); for (i = 0; i < n; i++) { os << ar[i]; if (n - i > 1) os << ','; } } url += 4; } else if (strncmp(url, "cond", 4) == 0) { // insert a list of condition column names and min/max values int n = q.numSearchCols(); if (n > 0) { char** arcols = q.searchCols(); char** armin = q.minValues(); char** armax = q.maxValues(); for (i = 0; i < n; i++) { // if min and max are the same or max is empty, assume a // single value, otherwise a range of values if (strcmp(armin[i], armax[i]) == 0 || strlen(armax[i]) == 0) os << arcols[i] << "=" << armin[i]; else os << arcols[i] << "=" << armin[i] << "," << armax[i]; if (n - i > 1) os << '&'; } } url += 4; } else if (strncmp(url, "mime-type", 9) == 0) { os << "application/x-fits"; // should be hard coded in the config file? url += 9; } else { // if it is not recognized, ignore, don't substitue... } } else { os << *url++; } } strncpy(buf, os.str().c_str(), bufsz); // report an error if the caller specified an id, but there is none in the URL if (strlen(q.id()) && ! url_has_id) return fmt_error("%s does not suppport search by id", name()); // report an error if the caller supplied a position, but there is none in the URL if (!q.pos().isNull()) { if (q.pos().isWcs() && !url_has_radec) return fmt_error("%s does not suppport search by World Coordinates", name()); if (!q.pos().isWcs() && !url_has_xy) return fmt_error("%s does not suppport search by image coordinates", name()); } return 0; } /* * Get the number of columns and the column names * for the this catalog and return 0 if all is OK. * * Args: * * numCols, out - number of result columns * colNames, out - reference to array of column names * colTypes, out - reference to array of column type names */ int AstroCatalog::getDescription(int& numCols, char**& colNames) { if (! isCatalog(entry_)) return wrongServType(entry_); if (checkInfo() == OK) { numCols = info_.numCols(); colNames = (char**)info_.colNames(); return 0; } return error("couldn't get catalog info"); } /* * Get the values for the specified columns for the object given by "id" * in the catalog and return 0 if all is OK. * * Args: * * id in - object id in catalog * numCols in - number of columns to get * colNames in - array of column names to read * result out - reference to object managing result rows */ int AstroCatalog::getObject( const char* id, int numCols, char** colNames, QueryResult& result) { if (! isCatalog(entry_)) return wrongServType(entry_); AstroQuery q; q.id(id); q.colNames(numCols, colNames); q.maxRows(1); int nrows = query(q, NULL, result); if (nrows < 0) return 1; // error return return 0; } /* * Get the values for all objects in the specified world coordinates area * Note: This routines returns the number of rows found (in numFound). * * Args: * * numCols in - number of columns to get * colNames in - array of column names to read * pos0 in - coordinates of area - first point * pos1 in - second point of area * mag0 in - min magnitude * mag1 in - max magnitude * maxRows in - max number of rows to return * filename in - if not null, write results to this file * result out - reference to object managing result rows */ int AstroCatalog::getArea( int numCols, char** colNames, const WorldOrImageCoords& pos0, const WorldOrImageCoords& pos1, double mag0, double mag1, int maxRows, const char* filename, int& numFound, QueryResult& result) { if (! isCatalog(entry_)) return wrongServType(entry_); AstroQuery q; q.pos(pos0, pos1); q.colNames(numCols, colNames); q.maxRows(maxRows); numFound = query(q, filename, result); if (numFound < 0) return 1; // error return 0; } /* * Get the values for all objects in the specified circle/ring. * Note: This routines returns the number of rows found (in numFound). * * Args: * * numCols in - number of columns to get * colNames in - array of column names to read * pos in - center position in world coordinates * radius0 in - min radius * radius1 in - max radius * mag0 in - min magnitude * mag1 in - max magnitude * maxRows in - max number of rows to return * filename in - if not null, write results to this file * numFound out - number of objects found * result out - reference to object managing result rows */ int AstroCatalog::circularSearch( int numCols, char** colNames, const WorldOrImageCoords& pos, double radius0, double radius1, double mag0, double mag1, int maxRows, const char* filename, int& numFound, QueryResult& result) { if (! isCatalog(entry_)) return wrongServType(entry_); AstroQuery q; q.pos(pos); q.radius(radius0, radius1); q.mag(mag0, mag1); q.colNames(numCols, colNames); q.maxRows(maxRows); numFound = query(q, filename, result); if (numFound < 0) return 1; // error return 0; } /* * search for the star closest to the given position, with the magnitude in * the given range and return (via the last 2 args) the columns requested * by "colNames" * * Args: * * numCols in - number of columns to get * colNames in - array of column names to read * pos in - center position in world coordinates * mag0 in - min magnitude * mag1 in - max magnitude * result out - reference to object managing result rows */ int AstroCatalog::searchClosestStar( int numCols, char** colNames, const WorldOrImageCoords& pos, double mag0, double mag1, QueryResult& result) { if (! isCatalog(entry_)) return wrongServType(entry_); AstroQuery q; q.pos(pos); q.mag(mag0, mag1); q.colNames(numCols, colNames); q.maxRows(1); int nrows = query(q, NULL, result); if (nrows < 0) return 1; // error return return 0; } /* * search for the stars fulfilling the specified criteria * * Args: * * numCols in - number of columns to get * colNames in - array of column names to get * * numSearchCols in - number of search columns (for to minVals, maxVals) * searchCols in - array of search column names for conditions * (for minVals, maxVals below) * minVals in - optional array of min values for searchCols * maxVals in - optional array of max values for searchCols * * maxRows in - max number of rows to return * filename in - if not null, write results to this file * numFound out - number of objects found * result out - reference to object managing result rows */ int AstroCatalog::CatalogSearch( int numCols, char** colNames, int numSearchCols, char** searchCols, char** minVals, char** maxVals, int maxRows, const char* filename, int& numFound, QueryResult& result) { if (! isCatalog(entry_)) return wrongServType(entry_); AstroQuery q; q.colNames(numCols, colNames); q.condition(numSearchCols, searchCols, minVals, maxVals); q.maxRows(maxRows); numFound = query(q, filename, result); if (numFound < 0) return 1; // error return 0; } /* * Generate a new temp file name for holding images or preview data. (We * could reuse it, but if it is still open and/or mmap'ed, it will cause * an error). We also check the name to see if the user may have set the * tmpfile name, for backward compatibility. */ void AstroCatalog::newTempFile() { static int count = 0; // used to make a unique file name if (!tmpfile_ || strncmp(tmpfile_, "/tmp/cat", 8) == 0) { // set default temp file for holding preview data char buf[80]; sprintf(buf, "/tmp/cat%d%d.fits", (int)getpid(), count++); tmpfile(buf); } } /* * set the name of the temp file used to hold preview data fetched * via http and remove the previous temp file, if it exists. */ void AstroCatalog::tmpfile(const char* name) { if (tmpfile_) { unlink(tmpfile_); free(tmpfile_); } tmpfile_ = strdup(name); } /* * Given a URL pointing to preview data (FITS image or tab table data), * request the data from the server and return 0 if all is OK. On * return, if there were no errors, the "ctype" argument is set to the * Content-type of the result to indicate the type of data. The data is * automatically decompressed if needed (if the content-type is * recognized). The "tmpfile()" method gives the name of the file * containing the results on success. */ int AstroCatalog::getPreview(const char* url, char*& ctype) { // we need to use a new file, since the old one may be still in use // (even after it was deleted, since it may still be open and/or mmapped) newTempFile(); // open the tmp file std::ofstream f(tmpfile_); if (!f) return sys_error("could not open file for writing: ", tmpfile_); if (http_.get(url, f) != 0) { unlink(tmpfile_); return ERROR; } f.close(); // check the Content-type of the return data to determine whether it // needs to be decompressed and if so, how... ctype = http_.content_type(); if (!ctype) ctype = (char *)""; if (strcmp(ctype, "text/html") == 0) { // most likely an HTML formatted server error message std::ifstream is(tmpfile_); unlink(tmpfile_); return http_.html_error(is); } // for now, assume uncompressed table if the Content-type is not recognized char* t = ctype; int is_image = 0; if (strncmp(ctype, "image/", 6) == 0) { t = ctype+6; is_image++; } else if (strncmp(ctype, "text/", 5) == 0) { t = ctype+5; } else { // unknown content type, check if it might be a FITS file Mem m(tmpfile_); if (m.status() == 0 && m.size() >= 2880 && strncmp((const char*)m.ptr(), "SIMPLE", 6) == 0) { ctype = (char *)"image/x-fits"; // assume FITS file is_image++; } else { ctype = (char *)"text/x-starbase"; // assume catalog data } return 0; } // In some cases the Content-type only gives the general type and // we need to check the Content-Encoding also. For example "file.fits.gz" // might have a Content-type of image/x-fits and Content-Encoding of // x-gzip char* ce = http_.content_encoding(); if (is_image && strcmp(t, "x-fits") == 0 && ce != NULL) { if (strcmp(ce, "x-gzip") == 0) { ctype = (char *)"image/x-gfits"; t = ctype+6; } else if (strcmp(ce, "x-compress") == 0) { ctype = (char *)"image/x-cfits"; t = ctype+6; } } // pure FITS or starbase table ? if (strcmp(t, "x-fits") == 0 || strcmp(t, "fits" ) == 0 || strcmp(t, "fits") == 0 || strcmp(t, "x-starbase") == 0 || strcmp(t, "plain") == 0 || strcmp(t, "tab-separated-values") == 0) { return 0; // not compressed, just return filename } Compress::CompressType type = Compress::NO_COMPRESS; if (strcmp(t, "x-hfits") == 0) { type = Compress::H_COMPRESS; // Hcompressed FITS file } else if (strcmp(t, "x-gfits") == 0 || strcmp(t, "x-gstarbase") == 0) { type = Compress::GZIP_COMPRESS; // GZIPed FITS or tab table } else if (strcmp(t, "x-cfits") == 0 || strcmp(t, "x-cstarbase") == 0) { type = Compress::UNIX_COMPRESS; // UNIX Compressed FITS ir tab table } else if (strcmp(t, "x-sfits") == 0) { // Compressed FITS file (Stark) // type = Compress::S_COMPRESS; unlink(tmpfile_); return error("x-sfits compression (Stark) not supported"); } else { unlink(tmpfile_); return error("unknown preview data Content-type: ", ctype); } // do the decompression FILE* feedback = http_.feedback(); if (feedback) { fprintf(feedback, "decompressing data...\n"); fflush(feedback); } Compress c; if (c.decompress(tmpfile_, type) != 0) { unlink(tmpfile_); return ERROR; } // correct Content-type after decompression ctype = (char*)(is_image ? "image/x-fits" : "text/x-starbase"); // if we got here, then we have the FITS file, so return the file name return 0; } /* * return the text of the previous error message */ const char* AstroCatalog::getError() { return last_error(); // from error.h } /* * reset the error message buffer to empty */ void AstroCatalog::clearError() { clear_error(); // from error.h } skycat-3.1.2-starlink-1b/cat/generic/AstroCatalog.h000066400000000000000000000263431215713201500220640ustar00rootroot00000000000000// -*-c++-*- #ifndef _AstroCatalog_h_ #define _AstroCatalog_h_ /* * E.S.O. - VLT project/ESO Archive * $Id: AstroCatalog.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * AstroCatalog.h - class definitions for accessing astronomical * catalogs * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 95 Created * Peter W. Draper 21 Jan 99 Moved constructor into public interface. * 20 Mar 09 Added various accessors for meta-data * (VO and comments) * 08 May 09 Added stc_col member */ using namespace std; #include #include "CatalogInfo.h" #include "AstroQuery.h" #include "QueryResult.h" #include "HTTP.h" class WorldCoords; class WorldOrImageCoords; /* * Class AstroCatalog * * This class manages access to astronomical catalogs via a collection * HTTP catalog servers. The main entry point is the "open" method, * which returns a pointer to a class object representing the catalog. */ class AstroCatalog { protected: HTTP http_; // http server handle char* tmpfile_; // temp file to hold fits image int status_; // status after constructor int more_; // true if more rows would have been available // but were not fetched (due to query limit) QueryResult info_; // column name info for this catalog CatalogInfoEntry* entry_; // ptr to the config entry for this catalog // query server for catalog column names and put result in info_ virtual int getInfo(); virtual int checkInfo(); // generate the query string from the given url and query info virtual int genHttpQuery (char* buf, int bufsz, const AstroQuery& q, const char* url); // generate a new temp filename to hold an image or preview data void newTempFile(); public: // constructor - create catalog class instance // note: public interface uses AstroCatalog::open(). // The argument represents the entry in the catalog config file for this catalog AstroCatalog(CatalogInfoEntry*); // destructor - close catalog and free any resources virtual ~AstroCatalog(); // copy constructor AstroCatalog(const AstroCatalog&); // open the named catalog and return a pointer to a new // AstroCatalog object created for it or NULL if errors occur static AstroCatalog* open(const char* name); // use a name server catalog (like simbad_ns@eso or ned_ns@eso) // to get the coordinates from the object name. If feedback is not NULL, // status info is written to the given open file. static int nameToWorldCoords( const char* objName, WorldOrImageCoords& pos, const char* nameServer = "simbad_ns@eso", FILE* feedback = NULL); // Return true if the given entry is for a catalog, archive or name server static int isCatalog(CatalogInfoEntry*); // Return true if the given entry is for an image server static int isImageServer(CatalogInfoEntry*); // Return true if the given entry is for a local catalog static int isLocalCatalog(CatalogInfoEntry*); // Generate an error message indicating that the wrong type of catalog was used. static int wrongServType(CatalogInfoEntry*); // Pass a query to the catalog and return the number of objects found. virtual int query(const AstroQuery& q, const char* filename, QueryResult& result); // return the symbol entry for this catalog (symbol info for plotting) const char* symbol() {return entry_->symbol();} // return the search_cols entry for this catalog const char* searchCols() {return entry_->searchCols();} // return the sort_cols entry for this catalog const char* sortCols() {return entry_->sortCols();} // return the sort_order entry for this catalog const char* sortOrder() {return entry_->sortOrder();} // return the show_cols entry for this catalog const char* showCols() {return entry_->showCols();} // return the copyright field const char* copyright() {return entry_->copyright();} // return the help field const char* help() {return entry_->help();} // return the column index for standard fields, may be set in config file // or in header or result int id_col() {return entry_->id_col();} int ra_col() {return entry_->ra_col();} int dec_col() {return entry_->dec_col();} int x_col() {return entry_->x_col();} int y_col() {return entry_->y_col();} int is_tcs() {return entry_->is_tcs();} int stc_col() {return entry_->stc_col();} // PWD: more "standard" fields. const char* system() {return entry_->system();} double epoch() {return entry_->epoch();} const char* equinoxprefix() {return entry_->equinoxprefix();} const char* unit() {return entry_->unit();} const char* ucd() {return entry_->ucd();} const char* utype() {return entry_->utype();} const char* datatype() {return entry_->datatype();} // return or set comments associated with catalog const char* comments() {return entry_->comments();} void comments(const char* comments) {entry_->comments(comments);} // return true if the catalog uses world coordinates int isWcs() {return entry_->isWcs();} // return true if the catalog uses image pixel coords int isPix() {return entry_->isPix();} // return the equinox of the catalog (default: 2000.) double equinox() {return entry_->equinox();} // set the file ptr to use for http feedback during transfers void feedback(FILE* f) {http_.feedback(f);} // member access: // return status (after constructor) for error checking int status() {return status_;} // return the name of this catalog const char* name() {return entry_->longName();} const char* longName() {return entry_->longName();} const char* shortName() {return entry_->shortName();} // return the serv_type entry from the config file ("catalog", "local", ...) const char* servType() {return entry_->servType();} // return the url field from the config file const char* url() {return entry_->url();} // return the number of columns in the catalog virtual int numCols() ; // return the column names virtual char** colNames() ; virtual const char* colName(int col); // return the column index for the given column name virtual int colIndex(const char* colName); // return true if the catalog contains the given column int hasCol(const char* name) {return (colIndex(name) >= 0);} // return true if more than "maxRows" rows would have been available // to the last call to query() int more() {return more_;} // set/get the temp file to use for getting preview data via http void tmpfile(const char* name); const char* tmpfile() {return tmpfile_;} // Request an image from the image server based on the given query description int getImage(const AstroQuery& q); // Given a URL for an image, request the image from the image server int getImage(const char* url); // fetch a preview image or plot data using the given url int getPreview(const char* url, char*& content_type); // return the handle for the HTTP object used to do the GET // (can be used to determine header values, or check if a // username and password are needed) HTTP& http() {return http_;} // get the catalog config entry for this catalog CatalogInfoEntry* entry() {return entry_;}; // For the VLT Catalog interface // Get the number of columns and the column names // for the this catalog and return 0 if all is OK virtual int getDescription( int& numCols, // out - number of result columns char**& colNames); // out - reference to array of column names // Get the values for the specified columns for the object given by "id" // in the catalog and return 0 if all is OK virtual int getObject( const char* id, // in - object id in catalog int numCols, // in - number of columns to get char** colNames, // in - array of column names to read QueryResult& result); // out - ref to object managing result // Get the values for all objects in the specified world coordinates area // Note: This routines returns the number of rows found (in numFound). virtual int getArea( int numCols, // in - number of columns to get char** colNames, // in - array of column names to read const WorldOrImageCoords& pos0, // in - coordinates of area - first point const WorldOrImageCoords& pos1, // in - second point of area double mag0, // in - min magnitude double mag1, // in - max magnitude int maxRows, // in - max number of rows to return const char* filename, // in - if not null, write results to this file int& numFound, // out - number of objects found QueryResult& result); // out - ref to object managing result // Get the values for all objects in the specified circle/ring. // Note: This routines returns the number of rows found (in numFound). virtual int circularSearch( int numCols, // in - number of columns to get char** colNames, // in - array of column names to read const WorldOrImageCoords& pos, // in - center position in world coordinates double radius0, // in - min radius double radius1, // in - max radius double mag0, // in - min magnitude double mag1, // in - max magnitude int maxRows, // in - max number of rows to return const char* filename, // in - if not null, write results to this file int& numFound, // out - number of objects found QueryResult& result); // out - ref to object managing result // search for the star closest to the given position, with the magnitude in // the given range and return (via the last 2 args) the columns requested // by "colNames" virtual int searchClosestStar( int numCols, // in - number of columns to get char** colNames, // in - array of column names to read const WorldOrImageCoords& pos, // in - center position in world coordinates double mag0, // in - min magnitude double mag1, // in - max magnitude QueryResult& result); // out - ref to object managing result // search for the stars fulfilling the specified criteria virtual int CatalogSearch( int numCols, // in - number of columns to get char** colNames, // in - array of column names to read int numSearchCols, // in - number of search cond. columns char** searchCols, // in - array of search cond.column names char** minVals, // in - optional array of min search values char** maxVals, // in - optional array of max search values int maxRows, // in - max number of rows to return const char* filename, // in - if not null, write results to this file int& numFound, // out - number of objects found QueryResult& result); // out - ref to object managing result // return the text of the previous error message static const char* getError(); // reset the error message buffer to empty static void clearError(); }; #endif /* _AstroCatalog_h_ */ skycat-3.1.2-starlink-1b/cat/generic/AstroImage.C000066400000000000000000000155111215713201500214620ustar00rootroot00000000000000/* * E.S.O. - VLT project/ESO Archive * $Id: AstroImage.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * AstroImage.C - method definitions for class AstroImage * * ------------------------------------------------------------------ * NOTE: This class is obsolete, please use the AstroCatalog class * instead. * ------------------------------------------------------------------ * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 95 Created */ static const char* const rcsId="@(#) $Id: AstroImage.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; using namespace std; #include #include #include #include #include #include #include #include #include #include "error.h" #include "DCompress.h" #include "AstroImage.h" /* * constructor - used internally only, public interface uses "open(name)" */ AstroImage::AstroImage(CatalogInfoEntry* e) : entry_(e), status_(OK) { // set default temp file for holding images char buf[32]; sprintf(buf, "/tmp/img%d.fits", (int)getpid()); tmpfile_ = strdup(buf); } /* * destructor - close catalog and free any resources */ AstroImage::~AstroImage() { unlink(tmpfile_); if (tmpfile_) free(tmpfile_); } /* * copy constructor */ AstroImage::AstroImage(const AstroImage& a) { tmpfile_ = a.tmpfile_ ? strdup(a.tmpfile_) : (char*)NULL; } /* * set the name of the temp file used to hold the image */ void AstroImage::tmpfile(const char* name) { if (tmpfile_) free(tmpfile_); tmpfile_ = strdup(name); } /* * open the named image server and return a pointer to an AstroImage * object for it, or NULL if errors occur */ AstroImage* AstroImage::open(const char* name) { // get the entry for this image server type CatalogInfoEntry* e = CatalogInfo::lookup(name); if (!e) return NULL; if (strcmp(e->servType(), "imagesvr") == 0) { return new AstroImage(e); } fmt_error("'%s' is of type '%s', and not 'imagesvr' as required here", name, e->servType()); return NULL; } /* * Request an image from the image server and return 0 if all is ok. * The name of a FITS file containing the resulting image can be accessed as * this->tmpfile(). * * The catalog config file defines the URL used to get the image. The URL * may contain variables to be expanded: * * %ra, %dec - replaced with the ra,dec world coords of the center position * * %x, %y - replaced with the x,y image coords of the center position * * %w, %h - replaced with the width and heith arguments in arcmin for * world coords or pixels for image coords. * * Note each catalog supports either world coords or image coords, but not * both. * */ int AstroImage::getImage(const WorldOrImageCoords& pos, double width, double height) { if (pos.isNull() || width <= 0 || height <= 0) { return error("must set position, width and height for image request"); } // if the first URL doesn't work, try the others, if specified const char* urls[3]; urls[0] = entry_->url(); urls[1] = entry_->backup1(); urls[2] = entry_->backup2(); // for each url, backup-url, etc... for (int i = 0; i < 3 && urls[i]; i++) { // generate the http url command ostringstream os; // expand the variables in the http server command const char* p = urls[i]; while(*p) { if (*p == '%') { p++; if (strncmp(p, "ra", 2) == 0) { os << pos.ra(); p += 2; } else if (strncmp(p, "dec", 3) == 0) { // include plus sign, if needed os << pos.dec(); p += 3; } else if (*p == 'x') { os << pos.x(); p++; } else if (*p == 'y') { os << pos.y(); p++; } else if (*p == 'w') { os << width; p++; } else if (*p == 'h') { os << height; p++; } else if (strncmp(p, "mime-type", 9) == 0) { // os << "image/x-gfits"; // ?should be hard coded in the config file os << "application/x-fits"; // ?should be hard coded in the config file p += 9; } } else { os << *p++; } } if (getImage(os.str().c_str()) == 0) return 0; // don't go to backup URL if it was a request for authorization if (http_.authorizationRequired()) return 1; } return 1; // error } /* * Given a URL for the image, request the image from the image server and * return 0 if all is ok. The name of the FITS file containing the * resulting image can be accessed with the method "this->tmpfile()" */ int AstroImage::getImage(const char* url) { // open the tmp file ofstream f(tmpfile_); if (!f) { return error("could not open file for writing", tmpfile_); } if (http_.get(url, f) != 0) return ERROR; f.close(); // check the Content-type of the return image to determine whether it // needs to be decompressed and if so, how... char* ctype = http_.content_type(); if (!ctype) ctype = (char *)""; // if the Content-type is not recognized... if (strncmp(ctype, "image/", 6) != 0) { // check if it might still be a FITS file: ifstream is(tmpfile_); char buf[81]; if (is && is.get(buf, 80) && strncmp(buf, "SIMPLE", 6) == 0) return 0; // if not a FITS file, try to interpret as a HTML error is.seekg(0); return http_.html_error(is); } char* t = ctype+6; // In some cases the Content-type only gives the general type and // we need to check the Content-Encoding also. For example "file.fits.gz" // might have a Content-type of image/x-fits and Content-Encoding of // x-gzip char* ce = http_.content_encoding(); if (strcmp(t, "x-fits") == 0 && ce != NULL) { if (strcmp(ce, "x-gzip") == 0) t = (char *)"x-gfits"; else if (strcmp(ce, "x-compress") == 0) t = (char *)"x-cfits"; } if (strcmp(t, "x-fits") == 0) { // Pure FITS file return 0; // not compressed, just return filename } Compress::CompressType type = Compress::NO_COMPRESS; if (strcmp(t, "x-hfits") == 0) { // Hcompressed FITS file type = Compress::H_COMPRESS; } else if (strcmp(t, "x-gfits") == 0) { // GZIPed FITS file type = Compress::GZIP_COMPRESS; } else if (strcmp(t, "x-cfits") == 0) { // Compressed FITS file (UNIX) type = Compress::UNIX_COMPRESS; } else if (strcmp(t, "x-sfits") == 0) { // Compressed FITS file (Stark) // type = Compress::S_COMPRESS; return error("x-sfits compression (Stark) not supported"); } else { return error("unknown image Content-type: ", ctype); } // do the decompression FILE* feedback = http_.feedback(); if (feedback) { fprintf(feedback, "decompressing image...\n"); fflush(feedback); } Compress c; if (c.decompress(tmpfile_, type) != 0) { return ERROR; } // if we got here, then we have the FITS file return 0; } skycat-3.1.2-starlink-1b/cat/generic/AstroImage.h000066400000000000000000000065551215713201500215370ustar00rootroot00000000000000// -*-c++-*- #ifndef _AstroImage_h_ #define _AstroImage_h_ /* * E.S.O. - VLT project/ESO Archive * $Id: AstroImage.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * AstroImage.h - base class definitions for classes that retrieve an image * from a catalog based on object name, position, width and height. * * ------------------------------------------------------------------ * NOTE: This class is obsolete, please use the AstroCatalog class * instead. * ------------------------------------------------------------------ * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 30 Sep 95 Created */ #include #include "HTTP.h" #include "WorldOrImageCoords.h" #include "CatalogInfo.h" /* * Class AstroImage * * This class is used to retrieve images from a remote image server based * on a name or position and a width and height in arc minutes. The main * entry point is the "open" method, which returns a pointer to a class * object for the image server. */ class AstroImage { protected: HTTP http_; // http server handle char* tmpfile_; // temp file to hold fits image int status_; // status after constructor CatalogInfoEntry* entry_; // ptr to the entry for this image svr // constructor - create catalog class instance // note: public interface uses AstroImage::open to hide subclass info AstroImage(CatalogInfoEntry*); public: // copy constructor AstroImage(const AstroImage&); // destructor - close catalog and free any resources virtual ~AstroImage(); // open the named catalog and return a pointer to an AstroImage // object allocated for it or NULL if errors occur static AstroImage* open(const char* name); // pass a request to the catalog and return the name of a FITS file // containing the resulting image, or NULL if not found int getImage(const WorldOrImageCoords& pos, double width, double height); int getImage(const char* url); // return a pointer to the first config entry // (for link list traversal) static CatalogInfoEntry* firstCatalog() { return CatalogInfo::first(); } // set the file ptr to use for http feedback during image transfers void feedback(FILE* f) {http_.feedback(f);} // member access: // return status (after constructor) for error checking int status() {return status_;} // return the handle for the HTTP object used to do the GET // (can be used to determine header values, or check if a // username and password are needed) HTTP& http() {return http_;} // set/get the temp file to use for getting images via http void tmpfile(const char* name); const char* tmpfile() {return tmpfile_;} // return the name of this service const char* name() {return entry_->longName();} const char* longName() {return entry_->longName();} const char* shortName() {return entry_->shortName();} // return the copyright field const char* copyright() {return entry_->copyright();} // return the help field const char* help() {return entry_->help();} // return true if the image server uses world coordinates int isWcs() {return entry_->isWcs();} // return true if the image server uses image pixel coordinates int isPix() {return entry_->isPix();} }; #endif /* _AstroImage_h_ */ skycat-3.1.2-starlink-1b/cat/generic/AstroQuery.C000066400000000000000000000165021215713201500215460ustar00rootroot00000000000000/* * E.S.O. - VLT project/ESO Archive * $Id: AstroQuery.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * AstroQuery.C - method definitions for class AstroQuery * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 95 Created */ static const char* const rcsId="@(#) $Id: AstroQuery.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include #include #include #include #include #include "error.h" #include "util.h" #include "AstroQuery.h" /* * constructor - initialize fields to null values. */ AstroQuery::AstroQuery() : id_(NULL), pos_(), mag1_(0.0), mag2_(0.0), radius1_(0.0), radius2_(0.0), width_(0.0), height_(0.0), numCols_(0), colNames_(NULL), maxRows_(0), numSortCols_(0), sortCols_(NULL), numSearchCols_(0), searchCols_(NULL), minValues_(NULL), maxValues_(NULL) { } /* * copy constructor */ AstroQuery::AstroQuery(const AstroQuery& a) : id_(a.id_ ? strdup(a.id_) : (char*)NULL), pos_(a.pos_), mag1_(a.mag1_), mag2_(a.mag2_), radius1_(a.radius1_), radius2_(a.radius2_), width_(a.width_), height_(a.height_), numCols_(a.numCols_), colNames_(copyArray(a.numCols_, a.colNames_)), maxRows_(a.maxRows_), numSortCols_(a.numSortCols_), sortCols_(copyArray(a.numSortCols_, a.sortCols_)), numSearchCols_(a.numSearchCols_), searchCols_(copyArray(a.numSearchCols_, a.searchCols_)), minValues_(copyArray(a.numSearchCols_, a.minValues_)), maxValues_(copyArray(a.numSearchCols_, a.maxValues_)) { } /* * destructor */ AstroQuery::~AstroQuery() { if (id_) free(id_); // PWD: let these leak. In fact these can be new or malloc memory // depending on various freeflag values... Need to track which. // if (colNames_) // delete[] colNames_; // if (sortCols_) // delete[] sortCols_; // if (searchCols_) // delete[] searchCols_ ; // if (minValues_) // delete[] minValues_; // if (maxValues_) // delete[] maxValues_; } /* * check that the given column name array is valid * returns 0 if the args were OK. */ static int check(int n, char** ar) { if ((n && !ar) || (ar && !n)) return error("invalid column name arguments", "", EINVAL); if (n) for (int i = 0; i < n; i++) if (!ar[i]) return error("incomplete column name array", "", EINVAL); return 0; } /* * set center pos, radius, width and height by setting 2 positions * The positions may be in World or Image coordinates (the units of * the radius, width and height are based on the type of coords - * arcmin or pixel). */ int AstroQuery::pos(const WorldOrImageCoords& p1, const WorldOrImageCoords& p2) { if (p1.status() || p2.status()) return error("invalid position argument", last_error(), EINVAL); radius1_ = 0.; pos_ = WorldOrImageCoords::center(p1, p2, radius2_, width_, height_); return pos_.status(); } /* * set the values of the min and max magnitude */ int AstroQuery::mag(double m1, double m2) { if (m1 < m2) { mag1_ = m1; mag2_ = m2; } else { mag1_ = m2; mag2_ = m1; } return 0; } /* * set the values of the min and max radius */ int AstroQuery::radius(double r1, double r2) { if (r1 < 0.0 || r2 < 0.0) return error("negative radius argument", "", EINVAL); if (r1 < r2) { radius1_ = r1; radius2_ = r2; } else { radius1_ = r2; radius2_ = r1; } // if (pos_.isWcs() && (r1 > 300.0 || r2 > 300.0)) // return error("radius too large (max 300 arcmin)", "", EINVAL); return 0; } /* * set the max radius (with 0 min radius) */ int AstroQuery::radius(double r) { if (r < 0.0) return error("negative radius", "", EINVAL); if (pos_.isNull()) return error("radius for catalog query set with no center position"); //if (pos_.isWcs() && r > 300.) // return error("radius too large (max 300 arcmin)", "", EINVAL); radius1_ = 0.0; radius2_ = r; return 0; } /* * set the number of columns and column names for the query to get * and check that the array is valid (0 and NULL is ok, use default * which is all columns). * If freeFlag is true, the memory for the array is used and freed when * no longer needed, otherwise a copy is made. * * returns 0 if the args were OK. */ int AstroQuery::colNames(int numCols, char** colNames, int freeFlag) { if (check(numCols, colNames) != 0) return ERROR; if (! freeFlag) colNames = copyArray(numCols, colNames); numCols_ = numCols; colNames_ = colNames; return 0; } /* * set the number and names of the columns to sort by. * returns 0 if the args were OK. * If freeFlag is true, the memory for the array is used and freed when * no longer needed, otherwise a copy is made. */ int AstroQuery::sort(int numSortCols, char** sortCols, int freeFlag) { if (numSortCols && check(numSortCols, sortCols) != 0) return ERROR; if (! freeFlag) sortCols = copyArray(numSortCols, sortCols); numSortCols_ = numSortCols; sortCols_ = sortCols; return 0; } /* * Set the condition for the query. This is defined as an array of column * names to compare (and the number of columns), an array of min values * and an array of max values (all char* values). * If freeFlag is true, the memory for the arrays is used and freed when * no longer needed, otherwise a copy is made. * * For backward compatibility, if the column name is "mag", the mag1 and * mag2 fields are set. * * returns 0 if the args were OK. */ int AstroQuery::condition(int n, char** cols, char** low, char** high, int freeFlag) { if ((n && (!cols || (!low && !high))) || ((cols || low || high) && !n)) return error("invalid search condition arguments", "", EINVAL); if (n) { for (int i = 0; i < n; i++) { if (!cols[i] || (high && !high[i]) || (low && !low[i])) return error("incomplete search condition arguments", "", EINVAL); // for backward compat, set mag1, mag2 if col name is mag if (strcasecmp(cols[i], "mag") == 0) { double m1, m2; if (sscanf(low[i], "%lf", &m1) == 1 && sscanf(high[i], "%lf", &m2) == 1) { mag(m1, m2); } } } } if (! freeFlag) { cols = copyArray(n, searchCols_); low = copyArray(n, minValues_); high = copyArray(n, maxValues_); } numSearchCols_ = n; searchCols_ = cols; minValues_ = low; maxValues_ = high; return 0; } /* * set the dimensions for an area query */ int AstroQuery::dim(double w, double h) { if (w < 0.0 || h < 0.0) return error("negative width or height for query", "", EINVAL); width_ = w; height_ = h; return 0; } /* * set the max magnitude (with 0 min mag) */ int AstroQuery::mag(double m) { // if (m < 0.0) // return error("negative magnitude"); mag1_ = 0.0; mag2_ = m; return 0; } /* * set the max number of rows to return */ int AstroQuery::maxRows(int n) { if (n < 0) return error("negative value set for max number of rows"); maxRows_ = n; return 0; } /* * return the name of the given column or NULL if out of range */ const char* AstroQuery::colName(int col) const { if (col >= 0 && col < numCols_) return colNames_[col]; return NULL; } skycat-3.1.2-starlink-1b/cat/generic/AstroQuery.h000066400000000000000000000102021215713201500216020ustar00rootroot00000000000000// -*-c++-*- #ifndef _AstroQuery_h_ #define _AstroQuery_h_ /* * E.S.O. - VLT project * $Id: AstroQuery.h,v 1.2 2010/07/21 19:39:54 cguirao Exp $ * * AstroQuery.h - class describing a query to search an astronomical catalog. * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 27 Sep 95 Created */ #include #include #include "WorldOrImageCoords.h" /* * Class AstroQuery * * This class is used in star catalog queries to specify which object(s) * to search for. * * The class attributes specify the conditions for the search, such as * id, name, position, radius, etc. All of the fields are * optional. Fields are set to the appropriate null value, if they are * not being used. * */ class AstroQuery { protected: char* id_; // object Id WorldOrImageCoords pos_; // center position as right ascension, declination double mag1_, mag2_; // min, max magnitude of object (most, least bright) double radius1_, radius2_; // min, max radius in arcmin from center double width_, height_; // width, height in arcmin from center int numCols_; // number of columns corresp. to colNames_ below char** colNames_; // ptr to array of column names to get (default all) int maxRows_; // max number of rows to get int numSortCols_; // number of columns corresp. to sortCols_ below char** sortCols_; // array of column names to sort by int sortOrder_; // >=0 means increasing, <0 means decreasing int numSearchCols_; // number of columns corresp. to searchCols_ below char** searchCols_; // ptr to array of column names to compare char** minValues_; // ptr to array of min column values or NULL char** maxValues_; // ptr to array of max column values or NULL // copy constructor (don't use) AstroQuery(const AstroQuery&); public: // constructors: // search by object Id (for a specific object) // The Id must be gotten by a previous search... AstroQuery(); ~AstroQuery(); // member access (set and get member values) // // note: methods with args set the member values and return the error status. // methods with no args return the value. const char* id() const {return (id_ ? id_ : "");} int id(const char* s) {id_ = strdup(s); return 0;} const WorldOrImageCoords& pos() const {return pos_;} int pos(const WorldOrImageCoords& p) {pos_ = p; return p.status();} // set center, width and height by setting 2 positions int pos(const WorldOrImageCoords& p1, const WorldOrImageCoords& p2); double width() const {return width_;} void width(double w) {width_ = w;} double height() const {return height_;} void height(double h) {height_ = h;} int dim(double w, double h); double mag1() const {return mag1_;} double mag2() const {return mag2_;} int mag(double m); int mag(double m1, double m2); // set min/max mag with check double radius1() const {return radius1_;} double radius2() const {return radius2_;} int radius(double r); int radius(double r1, double r2); // set min/max radius with check char** colNames() const {return colNames_;} const char* colName(int col) const; int numCols() const {return numCols_;} int colNames(int n, char** ar, int freeFlag = 0); int numSortCols() const {return numSortCols_;} char** sortCols() const {return sortCols_;} int sort(int numSortCols, char** sortCols, int freeFlag = 0); int sortOrder() const {return sortOrder_;} void sortOrder(int i) {sortOrder_ = i;} int maxRows() const {return maxRows_;} int maxRows(int n); // set the search conditions (min and max values for given columns) int numSearchCols() const {return numSearchCols_;} char** searchCols() const {return searchCols_;} char** minValues() const {return minValues_;} char** maxValues() const {return maxValues_;} int condition(int numSearchCols, char** searchCols, char**minVals, char**maxVals, int freeFlag = 0); }; #endif /* _AstroQuery_h_ */ skycat-3.1.2-starlink-1b/cat/generic/CatalogInfo.C000066400000000000000000000770511215713201500216240ustar00rootroot00000000000000/* * E.S.O. - VLT project/ESO Archive * $Id: CatalogInfo.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * CatalogInfo.C - method definitions for class CatalogInfo, CatalogInfoEntry * * This class is used to load, edit, access and save catalog config files * either locally or via HTTP from a remote host. * * A config file contains the information necessary to access catalogs. * The syntax for each catalog entry is: * * serv_type: service type, one of: catalog, namesvr, imagesvr * directory, local ... (see Service Types below) * * long_name: long name of service for displaying * short_name: short name of service * url: URL used to access catalog, %ra,%dec, etc. expanded (see below) * * symbol: the symbol to use to plot the given column value * (see Plotting below) * * copyright: optional copyright notice to display in user interface * * help: optional URL pointing to help for the catalog * * search_cols: optional list of columns that can be searched by in the format * col1 "col1 min label" "col1 max label" : ... * example: * search_cols: mag "Brightest (min)" "Faintest (max)" * * sort_cols: optional list of columns to sort by {col1 col2 ...} * sort_order: optional: set to "increasing" or "decreasing" * * show_cols: optional list of columns to display (default: all) * * id_col: column containing id field * ra_col: * dec_col: columns containing ra and dec (for catalogs supporting WCS) * * x_col: * y_col: columns containing x,y coords (for catalogs not supporting WCS) * * is_tcs: flag: true if using TCS columns * * stc_col: column with STC region description (VO WCS) * * Service Types * --------------- * * The currently known service types are: * * catalog - server returns a tab separated table of row/col values * * namesvr - server returns a single line with id, ra and dec to resolve * the given object name * * imagesvr - server returns an image file * * directory - the URL is a pointer to another catalog config file * * local - a local catalog * * * Syntax for "url" field: * -------------------------- * * The url field is used to build a URL to get the results via HTTP. * The syntax is like this: * * http://host:port/cgi-bin/server?arg1&arg2&...argn * * (if ":port" is missing, it defaults to 80.) * * Substitutions are performed on the URL as follows: * * For catalogs: * * %ra, %dec - coordinates of center point * * %w, %h - width and height in arcmin * * %r1, %r2 - min and max radius (for circular query) * %r - use when server only accepts single radius value * * %m1, %m2 - min and max magnitude * %m - use when server only accepts single magnitude * * %n - max number of rows to return * * %cols - list of columns to return (col1,col2,...coln) * * %id - ID field of item to return (if supported) * * %mime-type - value for http mime-type field * * Name servers only need the %id field, which is set to the object name. * * Plotting column values * ---------------------- * * The syntax for the "symbol:" field is as follows: * * symbol: colnames symbol expr : colnames symbol expr : ... * * where * colnames - is a list of column names used (in symbol or expr) * * symbol - is the symbol to use, one of: square, circle, triangle, cross, * plus, diamond, ellipse. * The symbol may also be a list such as {circle yellow} and some * symbols take extra args for ratio and angle (ellipse). * * expr - is an expression in terms of colnames above, used to determine the * size of the symbol. It may also be a list {expr units}, where units * is one of {image "deg $equinox"... } (default: image) (see rtd for * coordinate syntax). The column names (colnames) can be used as variables * in the expression using "$" (following Tcl syntax). * * example: * symbol: mag circle 15-$mag : xyz square (1-$xyz)*2.5 * symbol: {a/b pa mag} {ellipse yellow ${a/b} $pa} {15-$mag} * symbol: "a/b pa mag" "ellipse yellow ${a/b} $pa" "15-$mag" * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 29 Oct 95 Created * Peter W. Draper 25 Sep 03 Modified to output ra_col and dec_col * even when at default values. Can cause * problems when x_col and y_col are also * set (after ra_col and dec_col). * 04 Jul 08 Add additional meta-data support (ucd, utype, * unit and datatype), required for VO world. * 03 Dec 08 Always output ra_col, dec_col, x_col and y_col. * This is needed for catalogues that are saved * and do not have this information set (otherwise * when read back the default columns are assumed). * 20 Mar 09 Add support for comments. Note these are not * output as they are verbose and associated * with local catalogues (so are volatile). */ static const char* const rcsId="@(#) $Id: CatalogInfo.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include #include #include #include #include #include #include #include "error.h" #include "util.h" #include "HTTP.h" #include "CatalogInfo.h" using namespace std; // define the default URL for the catalog config info const char* catlib_config_url_ = "http://archive.eso.org/skycat/skycat2.0.cfg"; // config info used if the http config file can't be found static const char* config_info_ = "serv_type: catalog\n" "long_name: Guide Star Catalog at ESO\n" "short_name: gsc@eso\n" "url: http://archive.eso.org/skycat/servers/gsc-server?%ra%dec&obj=%id&r=%r1,%r2&m=%m1,%m2&n=%n&f=8&s=R&F=*\n" "symbol: mag circle 15-$mag\n" "search_cols: mag \"Brightest (min)\" \"Faintest (max)\"" "\n" "serv_type: imagesvr\n" "long_name: Digitized Sky Server at ESO\n" "short_name: dss@eso\n" "url: http://archive.eso.org/cgi-bin/dss?ra=%ra&dec=%dec&mime-type=%mime-type&x=%w&y=%h\n" "\n" "serv_type: namesvr\n" "long_name: SIMBAD Names\n" "short_name: simbad_ns@eso\n" "url: http://archive.eso.org/cgi-bin/sim-server?&o=%id\n" "\n" "serv_type: directory\n" "long_name: ESO Catalogs\n" "short_name: catalogs@eso\n" "url: http://archive.eso.org/skycat/skycat2.0.cfg\n" ; // linked list of catalog entries CatalogInfoEntry* CatalogInfo::entries_ = NULL; // initial undefined column index value static const int undef_col_ = -99; /* * strip leading and trailing white space from s and * return the result (s is modified) */ static char* strip(char* s) { char* p = s; while(isspace(*p)) p++; s = p; p += (strlen(p) - 1); while(p >= s && isspace(*p)) *p-- = '\0'; return s; } /* * split buf on the ':' char and strip leading and trailing * white space on both keyword and value */ int split(char* buf, char*& keyword, char*& value) { // split keyword : value char* p = strchr(buf, ':'); if (!p) return 1; *p++ = '\0'; keyword = strip(buf); value = strip(p); return 0; } /* * read a line from the stream into buf and return the stream. * Lines ending with backslash are continued on the next line */ istream& CatalogInfo::getline(istream& f, char* buf, int size) { if (f.getline(buf, size)) { char* p = buf; int i = strlen(p); if ( i > 0 ) { i -= 1; while(f && p[i] == '\\') { size -= i; p = p + i; if (f.getline(p, size)) { i = strlen(p); if ( i == 0 ) break; i -= 1; } } } } return f; } /* * load a catalog config file from the given istream, construct a * linked list of entries from the file and return a pointer to the * first entry in the list, or NULL if there were errors. * * The arguments are: * * f - istream open for reading the config file (or buffer) * filename - name of file (or URL) for error reporting */ CatalogInfoEntry* CatalogInfo::load(istream& f, const char* filename) { int line = 0; // line number in config file char buf[10*2048]; // contents of a line char* keyword; // left of ':' char* value; // right of ':' CatalogInfoEntry* entry = NULL; // for list of catalog entries CatalogInfoEntry* first = NULL; while(getline(f, buf, sizeof(buf))) { line++; // skip comments and empty lines if (buf[0] == '#' || strlen(buf) == 0) continue; // split keyword : value if (split(buf, keyword, value) != 0) { cfg_error(filename, line, "missing ':'"); delete first; return NULL; } if (strcmp(keyword, "serv_type") == 0) { // check that the current entry is complete and start a new one if (entry) { char* s; if ((s = entry->check()) != NULL) { cfg_error(filename, line, s); delete first; return NULL; } if (first != entry) { if (first->append(entry) != 0) { delete first; return NULL; } } entry = new CatalogInfoEntry; } else { // start the first entry first = entry = new CatalogInfoEntry; } } else if (! entry) { cfg_error(filename, line, "missing 'serv_type:' keyword"); delete first; return NULL; } set_entry_value(entry, keyword, value, 0); } // check last entry if (entry) { char* s; if ((s = entry->check()) != NULL) { cfg_error(filename, line, s); delete first; return NULL; } if (first != entry) { if (first->append(entry) != 0) { delete first; return NULL; } } } else { error("no entries in config file: ", filename); } return first; } /* * Set the value for the given keyword in the given entry. If updateFlag * is 1, only set fields that may be updated after an entry is * created. Fields such as the catalog name and URL may not be modified, * but the symbol and search_col info may be. * * We want to avoid overwriting changes that a user may have made interactively * in an application. Where it makes sense, string fields are only updated if * they were not already set. */ int CatalogInfo::set_entry_value(CatalogInfoEntry* entry, const char* keyword, const char* value, int updateFlag) { if (!updateFlag) { if (strcmp(keyword, "serv_type") == 0) { entry->servType(value); } else if (strcmp(keyword, "long_name") == 0) { entry->longName(value); } else if (strcmp(keyword, "short_name") == 0) { entry->shortName(value); } else if (strcmp(keyword, "url") == 0) { entry->url(value); } else if (strcmp(keyword, "backup1") == 0) { entry->backup1(value); } else if (strcmp(keyword, "backup2") == 0) { entry->backup2(value); } } if (strcmp(keyword, "symbol") == 0) { if (! entry->symbol()) entry->symbol(value); } else if (strcmp(keyword, "search_cols") == 0) { if (! entry->searchCols()) entry->searchCols(value); } else if (strcmp(keyword, "sort_cols") == 0) { if (! entry->sortCols()) entry->sortCols(value); } else if (strcmp(keyword, "sort_order") == 0) { if (! entry->sortOrder()) entry->sortOrder(value); } else if (strcmp(keyword, "show_cols") == 0) { if (! entry->showCols()) entry->showCols(value); } else if (strcmp(keyword, "copyright") == 0) { entry->copyright(value); } else if (strcmp(keyword, "help") == 0) { entry->help(value); } else if (strcmp(keyword, "id_col") == 0) { int id_col = undef_col_; if (sscanf(value, "%d", &id_col) == 1 && id_col != undef_col_) entry->id_col(id_col); } else if (strcmp(keyword, "ra_col") == 0) { int ra_col = undef_col_; if (sscanf(value, "%d", &ra_col) == 1 && ra_col != undef_col_) entry->ra_col(ra_col); } else if (strcmp(keyword, "dec_col") == 0) { int dec_col = undef_col_; if (sscanf(value, "%d", &dec_col) == 1 && dec_col != undef_col_) entry->dec_col(dec_col); } else if (strcmp(keyword, "x_col") == 0) { int x_col = undef_col_; if (sscanf(value, "%d", &x_col) == 1 && x_col != undef_col_) entry->x_col(x_col); } else if (strcmp(keyword, "y_col") == 0) { int y_col = undef_col_; if (sscanf(value, "%d", &y_col) == 1 && y_col != undef_col_) entry->y_col(y_col); } else if (strcmp(keyword, "is_tcs") == 0) { int is_tcs = 0; if (sscanf(value, "%d", &is_tcs) == 1) entry->is_tcs(is_tcs); } // PWD: extras. else if (strcmp(keyword, "stc_col") == 0) { int stc_col = undef_col_; if (sscanf(value, "%d", &stc_col) == 1 && stc_col != undef_col_) entry->stc_col(stc_col); } else if (strcmp(keyword, "system") == 0) { entry->system(value); } else if (strcmp(keyword, "epoch") == 0) { double d; const char *p = value; if ( p[0] == 'j' || p[0] == 'J' ) { entry->epochprefix( "J" ); p++; } else if ( p[0] == 'b' || p[0] == 'B' ) { entry->epochprefix( "B" ); p++; } else { entry->epochprefix( "" ); } if (sscanf(p, "%lf", &d) == 1) { entry->epoch(d); } } else if (strcmp(keyword, "equinox") == 0) { double d; const char *p = value; if ( p[0] == 'j' || p[0] == 'J' ) { entry->equinoxprefix( "J" ); p++; } else if ( p[0] == 'b' || p[0] == 'B' ) { entry->equinoxprefix( "B" ); p++; } else { entry->equinoxprefix( "" ); } if (sscanf(p, "%lf", &d) == 1) { entry->equinox(d); } } else if (strcmp(keyword, "unit") == 0) { entry->unit(value); } else if (strcmp(keyword, "ucd") == 0) { entry->ucd(value); } else if (strcmp(keyword, "utype") == 0) { entry->utype(value); } else if (strcmp(keyword, "datatype") == 0) { entry->datatype(value); } else if ( strcmp(keyword, "comments") == 0) { entry->comments(value); } return 0; } /* * report the error with the filename and line number included */ int CatalogInfo::cfg_error(const char* filename, int line, const char* msg1, const char* msg2) { ostringstream os; os << "error in catalog config file: " << filename << ": line " << line << ": " << msg1 << msg2; return error(os.str().c_str()); } /* * This static method is used to load the root catalog config info * the first time through and return the error status (0 is OK, * 1 for error). */ int CatalogInfo::load() { if (entries_) delete entries_; entries_ = loadRootConfig(); if (!entries_) return 1; // error // add a link to the main ESO config URL, if it is not already there const char* longName = "ESO Catalogs"; const char* shortName = "catalogs@eso"; if (strcmp(entries_->url(), catlib_config_url_) != 0 && ! lookup(entries_, longName) && ! lookup(entries_, shortName)) { CatalogInfoEntry* e = new CatalogInfoEntry; e->servType("directory"); e->url(catlib_config_url_); e->longName(longName); e->shortName(shortName); if (append(e) != 0) return 1; // error } return 0; } /* * This static method is used to reload the root catalog config info * after it has been edited by hand, to make the new data available * in the application. Since pointers to the current entries may still * be in use, we need to update the existing entries. */ int CatalogInfo::reload() { // get default config CatalogInfoEntry* root = loadRootConfig(); if (!root) return 1; // error int status = reload(first(), root->link()); delete root; return status; } /* * This static method is used to reload catalog config info after it has * been edited by hand, to make the new data available in the * application. Since pointers to the old entries may still be in use, we * need to update the old entries with the data from the new * entries. */ int CatalogInfo::reload(CatalogInfoEntry* oldEntry, CatalogInfoEntry* newEntry) { // merge into existing entries for (CatalogInfoEntry* ne = newEntry; ne != NULL; ne = ne->next()) { // see if we have this entry already, and if so, update it int found = 0; for (CatalogInfoEntry* e = oldEntry; e != NULL; e = e->next()) { if (strcmp(e->longName(), ne->longName()) == 0 || strcmp(e->shortName(), ne->shortName()) == 0) { if (e->link()) { // follow opened catalog directory links if (strcmp(ne->servType(), "directory") == 0) { if (load(ne) != 0 || reload(e->link(), ne->link()) != 0) return 1; // error } } // copy the data from the new entry to update the old one // and restore the catalog directory link, if any, since // the update is recursive and follows directory links. CatalogInfoEntry* link = e->link(); CatalogInfoEntry* next = e->next(); *e = *ne; // (see CatalogInfoEntry::operator=, no links copied) e->link(link); e->next(next); found++; break; } } if (!found) { // if this is a new entry, append a copy of it // (see copy constructor: no links copied) CatalogInfoEntry* copy = new CatalogInfoEntry(*ne); oldEntry->append(copy); } } // Remove any "dead" entries (entries that were deleted from the config file). CatalogInfoEntry* e = oldEntry; while (e != NULL) { int found = 0; for (CatalogInfoEntry* ne = newEntry; ne != NULL; ne = ne->next()) { if (strcmp(e->longName(), ne->longName()) == 0 || strcmp(e->shortName(), ne->shortName()) == 0) { found++; break; } } if (!found) { // Entry not found in the new list, remove it CatalogInfoEntry* next = e->next(); remove(e); e = next; } else { e = e->next(); } } return 0; } /* * This static method is used to load the root catalog config info the * first time through and return a pointer to the root entry, or NULL * if there was an error. * * The root catalog config file is searched for in the following URL * locations: * * $CATLIB_CONFIG * $SKYCAT_CONFIG (for backward compat) * ESO default URL * hard coded default */ CatalogInfoEntry* CatalogInfo::loadRootConfig() { // look for a catalog config file in the standard places and make the // first one found the root of the catalog server tree CatalogInfoEntry* e = new CatalogInfoEntry; e->servType("directory"); e->longName("Default Catalog List"); e->shortName("default"); // check the CATLIB_CONFIG environment variable char* url = getenv("CATLIB_CONFIG"); if (url) { e->url(url); if (load(e) == 0) return e; } // check the SKYCAT_CONFIG environment variable url = getenv("SKYCAT_CONFIG"); if (url) { e->url(url); if (load(e) == 0) return e; } // try the default URL e->url(catlib_config_url_); if (load(e) == 0) return e; // if all else fails, use this hard coded config info e->url("default"); istringstream is(config_info_); e->link(load(is)); if (! e->link()) { delete e; return NULL; // error } return e; // normal return } /* * This static method is used to load catalog config info and return the * error status (0 is OK, 1 for error). * * The argument should be a catalog entry of type "directory", where the * URL points to the catalog config file. There may be multiple such * entries in the form of a catalog server tree. */ int CatalogInfo::load(CatalogInfoEntry* e) { // loop through the url list until success HTTP http; int nlines = 0; char * s = http.get(e->url(), nlines); if (!s) return 1; // http error char* ctype = (http.content_type() ? http.content_type() : (char*)""); if (strcmp(ctype, "text/html") == 0) { // most likely an error message return http.html_error(s); } istringstream is(s); e->link(load(is, e->url())); if (! e->link()) return 1; // input error // if it is a local config file, allow URL commands if (strncmp(e->url(), "file:", 5) == 0) HTTP::allowUrlExec(1); return 0; // normal return } /* * return a pointer to the first config file entry * Note that entries_ points to the root of a hierarchical list * of catalog entries. Here we return the first item under the root. */ CatalogInfoEntry* CatalogInfo::first() { // load the config file the first time through if (!entries_) if (load() != 0) return NULL; return entries_->link(); } /* * return a pointer to the root config file entry. */ CatalogInfoEntry* CatalogInfo::root() { // load the config file the first time through if (!entries_) if (load() != 0) return NULL; return entries_; } /* * This static method returns a pointer to the catalog config entry for * the given catalog */ CatalogInfoEntry* CatalogInfo::lookup(const char* name) { // load the config file the first time through if (!entries_) if (load() != 0) return NULL; CatalogInfoEntry* e = lookup(entries_, name); if (e) return e; // if "name" is not a known catalog, it might be a local catalog in a file // in tab table format. if (access(name, R_OK) == 0) return lookupFile(name); error("unknown catalog name: ", name); return NULL; } /* * This static method returns a pointer to the catalog config entry for * the given catalog, searching only in the catalog directory specified by * the given entry. */ CatalogInfoEntry* CatalogInfo::lookup(CatalogInfoEntry* entry, const char* name) { // special case at root? if (entry == entries_ && strcmp(name, entry->longName()) == 0) return entry; for (CatalogInfoEntry* e = entry->link(); e != NULL; e = e->next()) { if (strcmp(e->longName(), name) == 0 || strcmp(e->shortName(), name) == 0) return e; } return NULL; } /* * Make a catalog config entry for a local catalog. * * See if the given file has a catalog config entry in the header part * (we add this to the header of a local catalog in * QueryResult::printTableTop). If no config info can be found in the * header, make a default catalog entry for it. * * The return value is a pointer to the new entry or NULL for errors. */ CatalogInfoEntry* CatalogInfo::lookupFile(const char* name) { ifstream is(name); if (!is) { sys_error("can't open file: ", name); return NULL; } CatalogInfoEntry* entry = new CatalogInfoEntry; // add fields from the file header updateConfigEntry(is, entry); // add fixed entries entry->servType("local"); entry->longName(name); entry->shortName(fileBasename(name)); entry->url(name); if (append(entry) != 0) { delete entry; return NULL; } return (entry); } /* * Append the given entry to the end of the top level catalog directory * list */ int CatalogInfo::append(CatalogInfoEntry* e) { // add to end of top level entry list, don't allow duplicates for (CatalogInfoEntry* p = first(); p != NULL; p = p->next()) { if (strcmp(p->longName(), e->longName()) == 0 || strcmp(p->shortName(), e->shortName()) == 0) { // fprintf(stderr, "warning: duplicate entry in catalog list: %s (%s)\n", // e->longName(), e->shortName()); return 0; } if (!p->next()) { p->next(e); break; } } return 0; } /* * Remove the given entry from the catalog directory list. It is removed * from the list but not deleted, as it might still be referenced * somewhere. */ int CatalogInfo::remove(CatalogInfoEntry* e) { remove(e, entries_); return 0; } /* * Remove the given entry from the given catalog directory list. It is * removed from the list but not deleted, as it might still be referenced * somewhere. */ void CatalogInfo::remove(CatalogInfoEntry* e, CatalogInfoEntry* dir) { if (e) { if (e == dir->link()) { // first item in sublist dir->link(e->next()); e->next(NULL); } else { for (CatalogInfoEntry* p = dir->link(); p != NULL; p = p->next()) { if (p->next() == e) { p->next(e->next()); e->next(NULL); break; } if (p->link()) remove(e, p); } } } } /* * Read config keyword entries from the given stream and update the given * entry values. */ void CatalogInfo::updateConfigEntry(istream& is, CatalogInfoEntry* entry) { if (! entry) return; char buf[2048]; char* keyword; // left of ':' char* value; // right of ':' while (getline(is, buf, sizeof(buf))) { if (buf[0] == '-') break; // end of header // skip comments and empty lines if (buf[0] == '#' || strlen(buf) == 0) continue; // split keyword : value if (split(buf, keyword, value) != 0) { continue; } set_entry_value(entry, keyword, value, 1); } } /* * default constructor - initialize null keyword values amd set default * column values. */ CatalogInfoEntry::CatalogInfoEntry() : id_col_(undef_col_), ra_col_(undef_col_), dec_col_(undef_col_), x_col_(undef_col_), y_col_(undef_col_), is_tcs_(0), stc_col_(undef_col_), equinox_(2000.), epoch_(2000.), link_(NULL), next_(NULL) { for (int i = 0; i < NUM_KEY_STRINGS_; i++) val_[i] = NULL; } /* * copy constructor */ CatalogInfoEntry::CatalogInfoEntry(const CatalogInfoEntry& e) : id_col_(e.id_col_), ra_col_(e.ra_col_), dec_col_(e.dec_col_), x_col_(e.x_col_), y_col_(e.y_col_), is_tcs_(e.is_tcs_), stc_col_(undef_col_), equinox_(e.equinox_), epoch_(e.epoch_), link_(NULL), // no links or marks copied next_(NULL) { for (int i = 0; i < NUM_KEY_STRINGS_; i++) val_[i] = e.val_[i] ? strdup(e.val_[i]) : (char*)NULL; } /* * assignment operator */ CatalogInfoEntry& CatalogInfoEntry::operator=(const CatalogInfoEntry& e) { id_col_ = e.id_col_; ra_col_ = e.ra_col_; dec_col_ = e.dec_col_; x_col_ = e.x_col_; y_col_ = e.y_col_; is_tcs_ = e.is_tcs_; stc_col_ = e.stc_col_; equinox_ = e.equinox_; epoch_ = e.epoch_; // don't copy the links or marks for (int i = 0; i < NUM_KEY_STRINGS_; i++) val_[i] = e.val_[i] ? strdup(e.val_[i]) : (char*)NULL; return *this; } /* * destructor */ CatalogInfoEntry::~CatalogInfoEntry() { if (link_) delete link_; if (next_) delete next_; for (int i = 0; i < NUM_KEY_STRINGS_; i++) { if (val_[i]) { free(val_[i]); val_[i] = NULL; } } } /* * check that all required fields have been set and return an error message * if any field is missing, otherwise NULL if there were no errors */ char* CatalogInfoEntry::check() { if (longName() == NULL) return (char *)"missing long_name"; if (shortName() == NULL) return (char *)"missing short_name"; if (url() == NULL) return (char *)"missing url"; return NULL; // OK } /* * Return the column number for the id, default to 0, or -1 if there * is no id column */ int CatalogInfoEntry::id_col() const { if (id_col_ == undef_col_) return 0; return id_col_; } /* * Return the column number for the X coord, default to -1 (no X column) */ int CatalogInfoEntry::x_col() const { if (x_col_ == undef_col_) return -1; return x_col_; } /* * Return the column number for the Y coord, default to -1 (no Y column) */ int CatalogInfoEntry::y_col() const { if (y_col_ == undef_col_) return -1; return y_col_; } /* * Return the column number for ra, default to 1 if there is no * X column defined, or -1 if there is no ra column. */ int CatalogInfoEntry::ra_col() const { if (ra_col_ == undef_col_) { if (x_col_ == undef_col_) return 1; return -1; } return ra_col_; } /* * Return the column number for dec, default to 2 if there is no * Y column defined, or -1 if there is no dec column. */ int CatalogInfoEntry::dec_col() const { if (dec_col_ == undef_col_) { if (y_col_ == undef_col_) return 2; return -1; } return dec_col_; } /* * Return the column number for the STC region, defaults to -1 if no * STC column is defined. */ int CatalogInfoEntry::stc_col() const { if (stc_col_ == undef_col_) return -1; return stc_col_; } /* * set the value for a config keyword */ void CatalogInfoEntry::setVal_(KeyStrings keyword, const char* s) { if (val_[keyword]) { free(val_[keyword]); val_[keyword] = NULL; } if (s && strlen(s)) { val_[keyword] = strdup(s); } } /* * append the given entry to the end of the list and return an error * if there was already an entryt with the same name there. */ int CatalogInfoEntry::append(CatalogInfoEntry* e) { // add to end of top level entry list for (CatalogInfoEntry* p = this; p != NULL; p = p->next_) { if (strcmp(p->longName(), e->longName()) == 0 || strcmp(p->shortName(), e->shortName()) == 0) { // fprintf(stderr, "warning: duplicate entry in catalog list: %s (%s)\n", // e->longName(), e->shortName()); return 0; } if (!p->next_) { p->next_ = e; break; } } return 0; } /* * output operator: format similar to config file input: * keyword: value ... */ ostream& operator<<(ostream& os, const CatalogInfoEntry& e) { if (e.servType()) os << "serv_type: " << e.servType() << endl; if (e.longName()) os << "long_name: " << e.longName() << endl; if (e.shortName()) os << "short_name: " << e.shortName() << endl; if (e.url()) os << "url: " << e.url() << endl; if (e.backup1()) os << "backup1: " << e.backup1() << endl; if (e.backup2()) os << "backup2: " << e.backup1() << endl; if (e.symbol()) os << "symbol: " << e.symbol() << endl; if (e.searchCols()) os << "search_cols: " << e.searchCols() << endl; if (e.sortCols()) os << "sort_cols: " << e.sortCols() << endl; if (e.showCols()) os << "show_cols: " << e.showCols() << endl; if (e.copyright()) os << "copyright: " << e.copyright() << endl; if (e.help()) os << "help: " << e.help() << endl; if (e.equinox() != 2000.) { if ( e.equinoxprefix() ) os << "equinox: " << e.equinoxprefix() << e.equinox() << endl; else os << "equinox: " << e.equinox() << endl; } if (e.id_col() > 0) os << "id_col: " << e.id_col() << endl; // PWD: always write these values if defined. if (e.ra_col() != undef_col_ ) os << "ra_col: " << e.ra_col() << endl; if (e.dec_col() != undef_col_ ) os << "dec_col: " << e.dec_col() << endl; if (e.x_col() != undef_col_ ) os << "x_col: " << e.x_col() << endl; if (e.y_col() != undef_col_ ) os << "y_col: " << e.y_col() << endl; if (e.is_tcs()) os << "is_tcs: " << e.is_tcs() << endl; // PWD: extras. if (e.stc_col() != undef_col_ ) os << "stc_col: " << e.stc_col() << endl; if (e.epoch() != 2000.) { if ( e.epochprefix() ) os << "epoch: " << e.epochprefix() << e.epoch() << endl; else os << "epoch: " << e.epoch() << endl; } if (e.system()) os << "system: " << e.system() << endl; if (e.unit()) os << "unit: " << e.unit() << endl; if (e.ucd()) os << "ucd: " << e.ucd() << endl; if (e.utype()) os << "utype: " << e.utype() << endl; if (e.datatype()) os << "datatype: " << e.datatype() << endl; return os; } skycat-3.1.2-starlink-1b/cat/generic/CatalogInfo.h000066400000000000000000000252221215713201500216620ustar00rootroot00000000000000// -*-c++-*- #ifndef _CatalogInfo_h_ #define _CatalogInfo_h_ /* * E.S.O. - VLT project/ESO Archive * $Id: CatalogInfo.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * CatalogInfo.h - class holding catalog config information * from the Catalog.cfg file * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 29 Sep 95 Created * Peter W. Draper 01 Jul 08 Added system, epoch, unit, ucd, utype * and datatype support, plus equinox as string. * Needed for VO interop. * 20 Mar 09 Added hooks for preserving comments extracted * from a local catalogue. * 08 May 09 Added stc_col support. */ using namespace std; #include #include #include // forward ref class CatalogInfoEntry; /* * This class manages the catalog config file info. Many of the methods * are static, since the information needs to be cached and shared by * other classes. */ class CatalogInfo { private: // handle for catalog config info for static access static CatalogInfo* catInfo_; // hierarchical list of all catalog entries static CatalogInfoEntry* entries_; // for error reporting static int cfg_error(const char* filename, int line, const char* msg1, const char* msg2 = ""); // load the root config file static CatalogInfoEntry* loadRootConfig(); // Set the value for the given keyword in the given entry static int set_entry_value(CatalogInfoEntry* entry, const char* keyword, const char* value, int updateFlag); // read a line from the stream into buf and return the stream. // Lines ending with backslash are continued on the next line static istream& getline(istream& f, char* buf, int size); // Remove the given entry from the given catalog directory list. static void remove(CatalogInfoEntry* e, CatalogInfoEntry* dir); public: // constructor CatalogInfo() {} // load the default catalog config file static int load(); // load a catalog config file static int load(CatalogInfoEntry*); // reload the default catalog config file after it has been edited by hand // and update recursively any already opened catalog directories static int reload(); // update the old catalog entry with the info from the new one (recursive) static int reload(CatalogInfoEntry* oldEntry, CatalogInfoEntry* newEntry); // load config file info from the given stream (filename for error reporting) static CatalogInfoEntry* load(istream&, const char* filename = "internal"); // return a pointer to the catalog config file entry for the given catalog static CatalogInfoEntry* lookup(const char* catalogName); // as above, but starting the search with the given entry rather than at the root static CatalogInfoEntry* lookup(CatalogInfoEntry* entry, const char* name); // get config entry for a local catalog from the header static CatalogInfoEntry* lookupFile(const char* catalogFileName); // Read config keyword entries from the given stream and update the given // entry values static void updateConfigEntry(istream& is, CatalogInfoEntry* entry); // Append the given entry to the end of the main catalog list static int append(CatalogInfoEntry* e); // Remove the given entry from the catalog list static int remove(CatalogInfoEntry* e); // return a pointer to the first config file entry under the root entry static CatalogInfoEntry* first(); // return a pointer to the root config file entry static CatalogInfoEntry* root(); }; /* * one of these is kept in a list for each catalog entry * in the config file */ class CatalogInfoEntry { friend class CatalogInfo; private: // This enum defines one keyword for each of the config keyword entries // that have string values and is used to index an array of strings // representing the keyword values. enum KeyStrings { SERVTYPE_, // service type (catalog, namesvr, imagesvr, ...) LONGNAME_, // long name for display SHORTNAME_, // short catalog name URL_, // http url to use, with wildcards %ra, %dec, ... BACKUP1_, // backup URL (1) BACKUP2_, // backup URL (2) SYMBOL_, // plot symbol info SEARCH_COLS, // list of searchable column info: colname minLabel maxLabel, ... SORT_COLS, // list of columns to sort by SORT_ORDER, // "increasing" or "decreasing" SHOW_COLS, // list of columns to display (default: all) COPYRIGHT_, // copyright notice for server HELP_, // URL pointing to help page fpr catalog SYSTEM_, // system of the celestial coordinates (FK5, FK4 etc.) EQUINOX_, // equinox qualifying string (J or B) EPOCH_, // epoch qualifying string (J or B) UNIT_, // units for all columns "unit1 \t unit2 \t \t unit4 \t..." UCD_, // UCDs for all columns "ucd1 \t ucd2 \t \t ucd4 \t..." UTYPE_, // utypes for all columns "utype1 \t utype2 \t \t utype4 \t..." DATATYPE_, // datatypes of columns, if interpreted COMMENTS_, // comments associated with entry, if any NUM_KEY_STRINGS_ // dummy last entry, number of keywords }; // array of values for config file keywords, indexed by above enum char* val_[NUM_KEY_STRINGS_]; // integer keyword values int id_col_; // column containing object id int ra_col_; // RA column int dec_col_; // DEC int x_col_; // instead of RA, can use pixel coords X,Y int y_col_; int is_tcs_; // flag: true if using TCS columns int stc_col_; // column containing STC region // double keyword values double equinox_; // equinox of wcs coords (default: J2000) double epoch_; // epoch of wcs coords (default: 2000) CatalogInfoEntry* link_; // If the url is a catalog config file or URL // this points to the first entry in that list. // (i.e.: used for a directory entry, if loaded). CatalogInfoEntry* next_; // next pointer for linked list of entries // set the value for a config keyword void setVal_(KeyStrings keyword, const char* s); public: // default constructor CatalogInfoEntry(); // copy constructor CatalogInfoEntry(const CatalogInfoEntry&); // assignment CatalogInfoEntry& operator=(const CatalogInfoEntry&); // destructor ~CatalogInfoEntry(); // check that all fields have been set and return 0 if all ok char* check(); // set string keyword values void servType(const char* s) {setVal_(SERVTYPE_, s);} void longName(const char* s) {setVal_(LONGNAME_, s);} void shortName(const char* s) {setVal_(SHORTNAME_, s);} void url(const char* s) {setVal_(URL_, s);} void backup1(const char* s) {setVal_(BACKUP1_, s);} void backup2(const char* s) {setVal_(BACKUP2_, s);} void symbol(const char* s) {setVal_(SYMBOL_, s);} void searchCols(const char* s){setVal_(SEARCH_COLS, s);} void sortCols(const char* s) {setVal_(SORT_COLS, s);} void sortOrder(const char* s) {setVal_(SORT_ORDER, s);} void showCols(const char* s) {setVal_(SHOW_COLS, s);} void copyright(const char* s) {setVal_(COPYRIGHT_, s);} void help(const char* s) {setVal_(HELP_, s);} void system(const char* s) {setVal_(SYSTEM_, s);} void equinoxprefix(const char* s) {setVal_(EQUINOX_, s);} void epochprefix(const char* s) {setVal_(EPOCH_, s);} void unit(const char* s) {setVal_(UNIT_, s);} void ucd(const char* s) {setVal_(UCD_, s);} void utype(const char* s) {setVal_(UTYPE_, s);} void datatype(const char* s) {setVal_(DATATYPE_, s);} void comments(const char* s) {setVal_(COMMENTS_, s);} // set int keyword values void id_col(int i) {id_col_ = i;} void ra_col(int i) {ra_col_ = i;} void dec_col(int i) {dec_col_ = i;} void x_col(int i) {x_col_ = i;} void y_col(int i) {y_col_ = i;} void is_tcs(int i) {is_tcs_ = i;} void stc_col(int i) {stc_col_ = i;} // set double keyword values void equinox(double d) {equinox_ = d;} void epoch(double d) {epoch_ = d;} // get string keyword values const char* servType() const {return val_[SERVTYPE_];} const char* longName() const {return val_[LONGNAME_];} const char* shortName() const {return val_[SHORTNAME_];} const char* url() const {return val_[URL_];} const char* backup1() const {return val_[BACKUP1_];} const char* backup2() const {return val_[BACKUP2_];} const char* symbol() const {return val_[SYMBOL_];} const char* searchCols() const {return val_[SEARCH_COLS];} const char* sortCols() const {return val_[SORT_COLS];} const char* sortOrder() const {return val_[SORT_ORDER];} const char* showCols() const {return val_[SHOW_COLS];} const char* copyright() const {return val_[COPYRIGHT_];} const char* help() const {return val_[HELP_];} const char* system() const {return val_[SYSTEM_] ? val_[SYSTEM_] : "";} const char* equinoxprefix() const {return val_[EQUINOX_];} const char* epochprefix() const {return val_[EPOCH_];} const char* unit() const {return val_[UNIT_];} const char* ucd() const {return val_[UCD_];} const char* utype() const {return val_[UTYPE_];} const char* datatype() const {return val_[DATATYPE_];} const char* comments() const {return val_[COMMENTS_];} // get int keyword values int id_col() const; int ra_col() const; int dec_col() const; int x_col() const; int y_col() const; int is_tcs() const {return is_tcs_;} int stc_col() const; // get double keyword values double equinox() const {return equinox_;} double epoch() const {return epoch_;} // return true if the catalog uses word coordinates int isWcs() {return ra_col() >= 0 && dec_col() >= 0;} // return true if the catalog uses image pixel coordinates int isPix() {return x_col() >= 0 && y_col() >= 0;} // set/get pointer to link entry CatalogInfoEntry* link() const {return link_;} void link(CatalogInfoEntry*e) {link_ = e;} // append the given entry to the end of the list int append(CatalogInfoEntry* e); // set/get pointer to next entry CatalogInfoEntry* next() const {return next_;} void next(CatalogInfoEntry*e) {next_ = e;} // output operator (output in format similar to input config file) friend ostream& operator<<(ostream&, const CatalogInfoEntry&); }; #endif /* _CatalogInfo_h_ */ skycat-3.1.2-starlink-1b/cat/generic/LocalCatalog.C000066400000000000000000000110611215713201500217500ustar00rootroot00000000000000/* * E.S.O. - VLT project/ESO Archive * $Id: LocalCatalog.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * LocalCatalog.C - method definitions for class LocalCatalog * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 11 Jun 96 Created */ static const char* const rcsId="@(#) $Id: LocalCatalog.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include #include #include #include #include #include #include #include "error.h" #include "Mem.h" #include "LocalCatalog.h" /* * static method to check the validity of a tab table file. * Returns 0 if OK. */ int LocalCatalog::check_table(const char* file) { TabTable t; return TabTable::head(file, t); } /* * constructor - used internally only, public interface uses "open(name)" * "e" is the catalog config entry object for this catalog. * (see CatalogInfo class) * * In this case, the catalog config entry may have been created automatically. * The name of the file containing the local catalog (tab table) is stored in * "e->url()", which is normally used to store the URL for HTTP access, but is * used here for the filename. * */ LocalCatalog::LocalCatalog(CatalogInfoEntry* e) : AstroCatalog(e), filename_(strdup(e->url())) { status_ = getInfo(); } /* * destructor */ LocalCatalog::~LocalCatalog() { if (filename_) free(filename_); } /* * Run a query on the local catalog and return the number of objects found. * * Args: * q - (in) object describing the query * * filename - (in) filename to hold results, or null * * result - (out) reference to object to manage the results. * * The return value is the number of rows found, or 0 if none were found. * A return value of -1 indicates an error. * * (Redefined from parent class to work with local catalogs) */ int LocalCatalog::query(const AstroQuery& q, const char* filename, QueryResult& result) { if (checkInfo() != 0) return -1; // note the catalog config entry in the results result.entry(entry_); if (result.query(q, info_, filename, more_) != 0) return -1; return result.numRows(); } /* * If we don't have the info for this catalog, get it and * return the status. Here we also check if the file has been modified, * (by an insert or remove operation) and reload it if needed. */ int LocalCatalog::checkInfo() { if (info_.numCols() > 0) { struct stat buf; if (stat(filename_, &buf) != 0) return sys_error("can't access file: ", filename_); if (buf.st_mtime == timestamp_) return 0; } return getInfo(); } /* * Read the local catalog to get the column names and also read in the * data to make later searches faster. The return value is 0 for * success. The info_ member holds the column info and the local catalog * data for searching. It must be updated if the data changes. */ int LocalCatalog::getInfo() { // note update time of file, so we know if it has been modified... struct stat buf; if (stat(filename_, &buf) != 0) return sys_error("can't access file: ", filename_); timestamp_ = buf.st_mtime; // mmap the file and put it in a TabTable Mem m(filename_); if (m.status() != 0) return 1; // make a null terminated copy, which will be managed by info_ size_t size = m.size() + 1; char* data = (char*)malloc(size); if (!data) return fmt_error("can't allocate %d bytes for %s", size, filename_); strncpy(data, (char*)m.ptr(), size-1); data[size-1] = '\0'; if (info_.init(data, 0, 1) != 0) return 1; // copy the comments from table to entry int n = info_.numComments(); if ( n > 0 ) { char* c = NULL; int have = 1024; int l = 0; int used = 0; char* com = (char*)malloc(have); com[0] = '\0'; char* p = com; for ( int i = 0; i < n; i++ ) { info_.getComment( i, c ); l = strlen( c ); if (( used + l ) >= have) { have += 1024; com = (char*)realloc(com, have); p = com + used; } strcpy( p, c ); used += l+1; p += l; if (i < (n-1)) { *p++ = '\n'; // new line not NULL. } } entry_->comments(com); free(com); } // this will extract any catalog config info from the file's header info_.entry(entry_, data); return 0; } skycat-3.1.2-starlink-1b/cat/generic/LocalCatalog.h000066400000000000000000000043551215713201500220250ustar00rootroot00000000000000// -*-c++-*- #ifndef _LocalCatalog_h_ #define _LocalCatalog_h_ /* * E.S.O. - VLT project/ESO Archive * $Id: LocalCatalog.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * LocalCatalog.h - class definitions for accessing local * catalogs stored as starbase format tab tables. * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 11 Jun 96 Created * Peter W. Draper 21 Sep 98 Modified private data members to be * protected. Need these for derived * classes. * 03 Jul 08 Added getQuery() method to access whole * data without an actual query. */ #include "AstroCatalog.h" /* * Class LocalCatalog * * This class is used to search a local catalog stored as a file * in tab table format. The format of the table is something like: * * TableName * * VAR=Value * * A B C * - - - * 0 1 3 * 3 2 4 * ... * * where the table name and variable assignments are optional. */ class LocalCatalog : public AstroCatalog { protected: // PWD: change here char* filename_; // file name for local catalog time_t timestamp_; // last update time of file, for caching public: // constructor - create local catalog class instance // note: public interface uses AstroCatalog::open() with the name of the // file containing the local catalog. // The argument represents the entry in the catalog config file for this catalog // (made automatially, if not already present). LocalCatalog(CatalogInfoEntry*); // destructor ~LocalCatalog(); // Run a query on the catalog and return the number of objects found. // (redefined here to work with local catalogs) virtual int query(const AstroQuery& q, const char* filename, QueryResult& result); // check the validity of a tab table file static int check_table(const char* file); // query server for catalog column names and put result in info_ virtual int getInfo(); virtual int checkInfo(); // get the full query for whole table. QueryResult& getQuery() {return info_;} }; #endif /* _LocalCatalog_h_ */ skycat-3.1.2-starlink-1b/cat/generic/QueryResult.C000066400000000000000000000243131215713201500217330ustar00rootroot00000000000000/* * E.S.O. - VLT project/ESO Archive * $Id: QueryResult.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * QueryResult.C - method definitions for class QueryResult * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 07 Nov 95 Created */ static const char* const rcsId="@(#) $Id: QueryResult.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; using namespace std; #include #include #include #include #include #include #include #include "error.h" #include "QueryResult.h" #include "WorldOrImageCoords.h" #include "AstroQuery.h" // This is a dummy null catalog entry, used as a default static CatalogInfoEntry* defaultEntry_ = new CatalogInfoEntry; /* * constructor: initialize empty table */ QueryResult::QueryResult() : TabTable(), entry_(defaultEntry_) {} /* * constructor: init from query result buffer */ QueryResult::QueryResult(const char* result) : TabTable(result), entry_(defaultEntry_) {} /* * constructor: initialize from data buffer without headings */ QueryResult::QueryResult(int numCols, char** colNames, const char* result) : TabTable(numCols, colNames, result), entry_(defaultEntry_) {} /* * if the result row contains a position (ra, dec) or (x, y), * get it and return success (0). * * Note that by convention the first 3 fields are id, ra and dec, in J2000, * unless otherwise defined in the catalog config entry. For example, if the * config entry specifies: "x_col: 1" and "y_col: 2", then we look for image * coordinates x and y in columns 1 and 2. */ int QueryResult::getPos(int row, WorldOrImageCoords& pos) const { if (entry_->isWcs()) { // use world coords char* ra; // get ra and dec as strings char* dec; // so we can accept H:M:S or d.ddd if (get(row, entry_->ra_col(), ra) || get(row, entry_->dec_col(), dec)) return 1; // error pos = WorldCoords(ra, dec, entry_->equinox(), 1); if (pos.status() == 0) return 0; // success return 1; // error } else if (entry_->isPix()) { // use image coords double x, y; if (get(row, entry_->x_col(), x) || get(row, entry_->y_col(), y)) return 1; // error pos = ImageCoords(x, y); if (pos.status() == 0) return 0; // success return 1; // error } return error("This catalog does not have coordinates"); } /* * get the position from the given row as world coords or report * an error if the catalog is not using world coords */ int QueryResult::getPos(int row, WorldCoords& pos) const { if (! entry_->isWcs()) return error("catalog does not support world coordinates"); WorldOrImageCoords p; if (getPos(row, p) != 0) return 1; pos = p.wc(); return 0; } /* * Search the given tab table for all objects in the specified world or * image coordinate circle/ring and fill "*this" table with the results. * The return value is 0 if all is OK. * * Args: * * table in - tab table to search * q i in - object holding query conditions * maxRows in - max number of rows to find */ int QueryResult::circularSearch( const TabTable& table, const AstroQuery& q, int maxRows) { int tcols = table.numCols(), trows = table.numRows(); // copy table header for the result if (init(tcols, table.colNames(), "", 0) != 0) return ERROR; if (maxRows <= 0) return 0; // search rows and put matching rows in "os" ostringstream os; int n = 0; int i = 0; // get col index for mag int mag_col = inputColIndex("mag"); // get array of col indexed for search columns const int maxcols = 255; if ((n = q.numSearchCols()) > maxcols) return error("too many search columns"); int search_cols[maxcols]; for(i = 0; i < n; i++) search_cols[i] = inputColIndex(q.searchCols()[i]); n = 0; for(i = 0; i < trows; i++) { if (circularCompareRow(table, i, q, mag_col, search_cols) == 0) { table.printRow(os, i); if (++n >= maxRows) break; } } int status = init(numCols_, colNames_, os.str().c_str(), maxRows); return status; return 0; } /* * Given a tab table and a row number, return 0 if the query position * (q.pos()) is within the given radius range (q.radius1(), q.radius2()) * and mag (if applicable) is in the given magnitude range (q.mag1(), * q.mag2()) and all of the other conditions given by q are met. * * mag_col is the column for "mag" or -1 if there is no mag column in the * table, in which case the mag range is ignored. * * Another way of specifying a mag range or a range for any other column * is to use the general purpose condition fields in the AstroQuery object: * q.searchCols(), q.minValues(), q.maxValues(). These are used if set. * (Note that for backward compat., the hard coded values for mag1,mag2 are * still supported, although they could be handled more generally using * q.searchCols(), ...) * * The search_cols parameter is used to save time by passing an array of * column indexes for the search columns (if any). * * The positions are taken either from the columns for ra and dec, if we * are using world coords, or the columns for x and y if we are using * image coords) * * The radius is assumed to be in arcmin for world coords, or pixel for * image coords. */ int QueryResult::circularCompareRow(const TabTable& table, int row, const AstroQuery& q, int mag_col, int* search_cols) { // get value for mag, if there is one if (mag_col != -1 && (q.mag1() != 0.0 || q.mag2() != 0.0)) { double mag; if (table.get(row, mag_col, mag) != 0 || mag < q.mag1() || mag > q.mag2()) return 1; } if (entry_->isWcs() || entry_->isPix()) { if (q.radius1() || q.radius2()) { // get ra,dec point WorldOrImageCoords p; if (entry_->isWcs()) { char* ra; char* dec; if (table.get(row, entry_->ra_col(), ra) != 0 || table.get(row, entry_->dec_col(), dec) != 0) return 1; p = WorldCoords(ra, dec, entry_->equinox(), 1); } else if (entry_->isPix()) { // get x,y double x, y; if (table.get(row, entry_->x_col(), x) != 0 || table.get(row, entry_->y_col(), y) != 0) return 1; p = ImageCoords(x, y); } if (p.status() != 0) return ERROR; // see if point is in radius double dist = q.pos().dist(p); if (dist < q.radius1() || dist > q.radius2()) return 1; // position for row not in range } } // check any other conditions for column values int n = q.numSearchCols(); if (n > 0) { char** minValues = q.minValues(); char** maxValues = q.maxValues(); char* tableValue; for(int i = 0; i < n; i++) { if (table.get(row, search_cols[i], tableValue) != 0) return 1; // since we don't know the type of the column, try double, then int, then string double d, d1, d2; int j, j1, j2; if (sscanf(tableValue, "%lf", &d) == 1 && sscanf(minValues[i], "%lf", &d1) == 1 && sscanf(maxValues[i], "%lf", &d2) == 1) { // compare as double if (d < d1 || d > d2) return 1; // no match } else if (sscanf(tableValue, "%d", &j) == 1 && sscanf(minValues[i], "%d", &j1) == 1 && sscanf(maxValues[i], "%d", &j2) == 1) { // compare as int if (j < j1 || j > j2) return 1; // no match } else { // compare as string if (strcmp(tableValue, minValues[i]) < 0 || strcmp(tableValue, maxValues[i]) > 0) return 1; // no match } } } return 0; // a match } /* * Query the given tab table using the condition described by the * given AstroQuery object. * * Args: * q - (in) object describing the query * * table - (in) table to search * outfile - (in) optional filename to hold results, or null * * more - (out) set to 1 if more objects would be available but were * not returned because q.maxRows was set lower * * The return value 0 if all is OK. The number found is available as this->numRows(). */ int QueryResult::query(const AstroQuery& q, const TabTable& table, const char* outfile, int& more) { // Note: if we have to sort, we don't want to loose data by discarding rows before sorting. // Otherwise, if not sorting, we can save space and time and discard unwanted rows earlier. // In any case, add at least 1 to maxRows, so we can see if there would be more rows available... int maxRows = q.maxRows()+1; if (q.numSortCols() > 0 || q.maxRows() == 0) maxRows = table.numRows(); if (strlen(q.id()) != 0) { // search for id only centerPos_.setNull(); if (search(table, entry_->id_col(), q.id(), maxRows) != 0) return ERROR; } else { centerPos_ = q.pos(); if (circularSearch(table, q, maxRows) != 0) return ERROR; } // sort result ? // note: do this before truncating to maxRows to get correct results if (q.numSortCols()) sort(q.numSortCols(), q.sortCols(), q.sortOrder()); if (q.maxRows() && numRows_ > q.maxRows()) { more = 1; numRows(q.maxRows()); } else { more = 0; } if (outfile && save(outfile) != 0) return ERROR; return 0; } /* * print the table title (and any other info preceding the column headings) * (may be redefined in a derived class to add more info) */ void QueryResult::printTableTop(ostream& os, const char* title) { if (! title) title = "QueryResult"; TabTable::printTableTop(os, title); // add some info from the config file entry, if known, so that we know later // what plot symbol to use when loading the file as a local catalog if (entry_ && entry_->servType()) { os << "\n# Config entry for original catalog server:\n" << *entry_; os << "# End config entry\n\n"; } } /* * Set the catalog config entry for this object. This is included in the * file when this object is saved as a local catalog. The optional result * arg may be a pointer to the result of a catalog query, which may * contain config configuration information. If specified, it is scanned * to update the entry with the new information. */ void QueryResult::entry(CatalogInfoEntry* e, const char* result) { entry_ = e; if (result) { istringstream is(result); CatalogInfo::updateConfigEntry(is, e); } } skycat-3.1.2-starlink-1b/cat/generic/QueryResult.h000066400000000000000000000110131215713201500217710ustar00rootroot00000000000000// -*-c++-*- #ifndef _QueryResult_h_ #define _QueryResult_h_ /* * E.S.O. - VLT project/ESO Archive * $Id: QueryResult.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * QueryResult.h - class definitions for accessing results of a catalog * query * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 7 Nov 95 Created * Peter W. Draper 13 Jan 09 Added getEntry method. * 8 May 09 Added stc_col support. */ #include "WorldOrImageCoords.h" #include "CatalogInfo.h" #include "AstroQuery.h" #include "TabTable.h" /* * Class QueryResult * * This class manages the result of an AstroCatalog::query. The basic * result is a char buffer that contains one row per line where each * column is separated by a tab character. * * This class provides transparent access to the result based on a * row,column index and allows for type conversion from string to the * desired type. */ class QueryResult : public TabTable { protected: WorldOrImageCoords centerPos_; // saved ra,dec or x,y pos from previous query CatalogInfoEntry* entry_; // catalog config file entry pointer, // used if not null when saving to a file // given a tab table (with columns ra and dec)and a row, return 0 if ra and dec // are within the given radius (in arcmin) and mag is in the given magnitude range. virtual int circularCompareRow(const TabTable& table, int row, const AstroQuery& q, int mag_col, int* search_cols); // Search the given tab table for all objects in the specified world // coordinate circle/ring and fill "*this" table with the results. virtual int circularSearch(const TabTable& table, const AstroQuery& q, int maxRows); // print table title and othe info... virtual void printTableTop(ostream& os, const char* title = NULL); public: // constructor: initialize empty table QueryResult(); // constructor: init from query result buffer QueryResult(const char* result); // constructor: initialize from data buffer without headings QueryResult(int numCols, char** colNames, const char* result); // destructor: free any allocated memory virtual ~QueryResult() {} // get the position from the given row as world or image coords virtual int getPos(int row, WorldOrImageCoords& pos) const; // get the position from the given row as world coords or report // an error if the catalog is not using world coords virtual int getPos(int row, WorldCoords& pos) const; // Query the given tab table using the condition described by the // given AstroQuery object. virtual int query(const AstroQuery& q, const TabTable& table, const char* outfile, int& more); // member access // Set the catalog config entry for this object. This is included in the // file when this object is saved as a local catalog. The optional result // arg may be a pointer to the result of a catalog query, which may // contain config configuration information. If specified, it is scanned // to update the entry with the new information. virtual void entry(CatalogInfoEntry* e, const char* result = NULL); // access config info that may have been included in the header // of the query result virtual const char* symbol() const {return entry_->symbol();} virtual const char* copyright() const {return entry_->copyright();} virtual const char* help() const {return entry_->help();} virtual const char* shortName() const {return entry_->shortName();} virtual const char* longName() const {return entry_->longName();} virtual int id_col() const {return entry_->id_col();} virtual int ra_col() const {return entry_->ra_col();} virtual int dec_col() const {return entry_->dec_col();} virtual int x_col() const {return entry_->x_col();} virtual int y_col() const {return entry_->y_col();} virtual double equinox() const {return entry_->equinox();} virtual int stc_col() const {return entry_->stc_col();} // return true if the catalog uses world coords virtual int isWcs() const {return entry_->isWcs();} // return true if the catalog uses image pixel coords virtual int isPix() const {return entry_->isPix();} // get the CatalogInfoEntry instance. CatalogInfoEntry * getInfo() {return entry_;} }; #endif /* _QueryResult_h_ */ skycat-3.1.2-starlink-1b/cat/generic/TabTable.C000066400000000000000000000776511215713201500211220ustar00rootroot00000000000000/* * E.S.O. - VLT project/ESO Archive * $Id: TabTable.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * TabTable.C - method definitions for class TabTable * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 08 Jan 96 Created * Peter W. Draper 17 Mar 09 Add changes to support access to the table comments */ static const char* const rcsId="@(#) $Id: TabTable.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; using namespace std; #include #include #include #include #include #include #include #include #include #include "error.h" #include "util.h" #include "TabTable.h" // these are needed only during a table sort static TabTable* thisPtr_; int TabTable::numSortCols_ = 0; char** TabTable::sortCols_ = NULL; int* TabTable::sortColIndexes_ = NULL; int TabTable::sortOrder_ = 0; int TabTable::sortStatus_ = 0; /* * constructor: initialize empty table */ TabTable::TabTable(char sep) : numRows_(0), numCols_(0), colNames_(NULL), buf_(NULL), table_(NULL), index_(NULL), comments_(NULL), numComments_(0), sep_(sep), status_(0) { } /* * constructor: initialize table from buffer in tab table format: * * VAR VALUE VALUE ... * ... * COL1 COL2 COL3 ... COLN * --- ---- ---- ---- * data data data data * ... * * Currently, anything up to the column headings is ignored (This may change * later). The format is the same as the tab table format used by starbase. * A line beginning with a "-" separates the column names from the data * and all column headings and data are separated by tabs (or sep char). * * The part preceding the column headings may be used later to set certain * variables pertaining to the table. In this case, a variable may have * one or more values, separated by tabs (sep char). * * If maxRows is nonzero, only upto that many rows are taken from buf. */ TabTable::TabTable(const char* buf, int maxRows, char sep) : numRows_(0), numCols_(0), colNames_(NULL), buf_(NULL), table_(NULL), index_(NULL), comments_(NULL), numComments_(0), sep_(sep), status_(0) { status_ = init(buf, maxRows); } /* * constructor: initialize table from data buffer without headings. * The first two args specify the number column headings and their names. * If maxRows is nonzero, only upto that many rows are taken from buf. */ TabTable::TabTable(int numCols, char** colNames, const char* buf, int maxRows, char sep) : numRows_(0), numCols_(0), colNames_(NULL), buf_(NULL), table_(NULL), index_(NULL), comments_(NULL), numComments_(0), sep_(sep), status_(0) { status_ = init(numCols, colNames, buf, maxRows); } /* * destructor: free any allocated memory */ TabTable::~TabTable() { clear(); } /* * Fill the table from the given buffer in tab table format. * If maxRows is nonzero, only upto that many rows are taken from buf. * If owner is nonzero, this class will take control of the memory * for buf, otherwise it makes a copy. The data string in buf should be * null terminated. */ int TabTable::init(const char* buf, int maxRows, int owner) { clear(); // erase any existing rows if (owner) buf_ = (char*)buf; else buf_ = strdup(buf); // scan the table to set colNames, numRows, numCols and get start of data char* line = NULL; if (scanTable(maxRows, line) != 0) return ERROR; return fillTable(line); } /* * Initialize the table from the data buffer (without heading lines). * The first two args specify the number column headings and their names. * If maxRows is nonzero, only upto that many rows are taken from buf. * If owner is nonzero, this class will take control of the memory * for buf, otherwise it makes a copy. The data string in buf should be * null terminated. */ int TabTable::init(int numCols, char** colNames, const char* buf, int maxRows, int owner) { // count the data rows char* nbuf = (owner ? (char*)buf : strdup(buf)); // (watch out for this: t.init(t.colNames()) (don't delete before using...)) char** cnames = copyArray(numCols, colNames); clear(); // erase any existing rows buf_ = nbuf; numRows_ = getNumLines(buf_, maxRows); numCols_ = numCols; colNames_ = cnames; numComments_ = 0; // fill the table rows from the buffer return fillTable(buf_); } /* * make the table empty and free any resources used */ int TabTable::clear() { if (table_) { delete[] table_; table_ = NULL; } if (index_) { delete[] index_; index_ = NULL; } if (comments_) { delete[] comments_; comments_ = NULL; } if (colNames_) { delete[] colNames_; colNames_ = NULL; } numCols_ = 0; numRows_ = 0; numComments_ = 0; if (buf_) { free(buf_); buf_ = NULL; } return 0; } /* * util: trim white space from string and return value */ static char* trim(char* s) { if (strlen(s)) { while(isspace(*s)) s++; char* p = s + strlen(s) - 1; while(isspace(*p) && p > s) *p-- = '\0'; } return s; } /* * scan the table to set colNames, numRows, numCols and set the "start" pointer * to point to the start of the data rows. * If maxRows is nonzero, the input is truncated to that many rows. * Returns 0 if OK. * * As part of routine locate and record any header comments. */ int TabTable::scanTable(int maxRows, char*& start) { char* line = buf_; // start of current line char* head = NULL; // start of header line with column names char* prev_line = NULL; // ptr to previous line char* p; int i; start = NULL; // points to start of data rows, if any for (p = strchr(line, '\n'); p; p = strchr(line = p+1, '\n')) { if (*line == '-') { line = start = p + 1; // data starts after "---" line head = prev_line; // header is line before "---" break; } prev_line = line; // If a comment line count it. if (*line == '#') { numComments_++; } *p = '\0'; } // Now gather the comments. if ( numComments_ > 0 ) { comments_ = new char*[numComments_]; // Back to head of buf_. Note lines are now NULL terminated. char *cline = buf_; int i = 0; for (p = strchr(cline, '\0'); p; p = strchr(cline = p+1, '\0')) { if (*cline == '-') { // No more comments. break; } if (*cline == '#') { comments_[i++] = cline; //cout << cline << endl; } } } if (! head) { // status_ = error("bad tab table format, no '---' line found"); // allow missing headers return 0; } // get the column names (and strip any leading and trailing white space) char* colNames[MAX_COLUMNS]; for (p = strchr(head, sep_); p; p = strchr(head = p+1, sep_)) { *p = '\0'; colNames[numCols_++] = head; } colNames[numCols_++] = head; colNames_ = new char*[numCols_]; for (i = 0; i < numCols_; i++) colNames_[i] = trim(colNames[i]); // count the data rows numRows_ = getNumLines(line, maxRows); return 0; } /* * create and fill the internal table from the given buffer in tab table format * and return 0 if all is OK */ int TabTable::fillTable(char* buf) { if (numRows_ == 0 || numCols_ == 0) return 0; // empty table without a header table_ = new char*[numRows_*numCols_]; index_ = new int[numRows_]; if (!table_ || !index_) { return error("could not allocate enough memory for TabTable"); } // fill the table with row,col values for (int i = 0; i < numRows_; i++) { index_[i] = i; // default order: no sorting yet char* p = strchr(buf, '\n'); if (!p) { char msg[255]; sprintf(msg, "expected %d rows, but found %d", numRows_, i); return error(msg); } *p++ = '\0'; if (splitList(buf, table_+(i*numCols_)) != 0) return ERROR; buf = p; // set for next line } return 0; } /* * scan the given buffer and return the number of lines. * If maxRows is nonzero, truncate the buffer after that many lines. */ int TabTable::getNumLines(char* buf, int maxRows) { int n = 0; for (char* p = strchr(buf, '\n'); p; p = strchr(buf = p+1, '\n')) { if (maxRows > 0 && n >= maxRows) { *++p = '\0'; return maxRows; } if (strncmp(buf, "[EOD]", 5) == 0) { // XXX special case (should be in HTTP.C ?) *buf = '\0'; break; } n++; } return n; } /* * split the given line into numCols_ strings and put them in the given array, * which is assumed to be large enough (at least numCols_ long). * Returns 0 on success, otherwise 1 and an error message. */ int TabTable::splitList(char* line, char** colValues) { char* val = line; int col; for (col = 0; col < numCols_; col++) { char* p = strchr(val, sep_); if (!p) { colValues[col] = trim(val); val = (char *)""; continue; // fill any missing cols with empty values } *p++ = '\0'; colValues[col] = trim(val); val = p; // set for next column } return 0; } /* * report an error in the tab table input at the given row and col, * that the given type of value was expected and the given string value * was found. */ int TabTable::tab_error(int row, int col, char* expected, char* value) const { ostringstream os; os << "error in tab table input: row " << (row+1) << ", col " << (col+1) << ", expected " << expected << ", but found '" << value << "'"; return error(os.str().c_str()); } /* * return the result column index for the given result column name */ int TabTable::colIndex(const char* colName) const { for (int i = 0; i < numCols_; i++) if (strcasecmp(colName, colNames_[i]) == 0) return i; return -1; } /* * return the column name for the given column index */ const char* TabTable::colName(int col) const { if (col >= 0 && col < numCols_ && numCols_ > 0) return colNames_[col]; return NULL; } /* * save the contents of this object as a tab table file and return 0 if * all is OK. */ int TabTable::save(const char* filename) { ofstream os(filename); if (!os) return sys_error("can't open file: ", filename); return save(os); } /* * save the contents of this object as a tab table to the * given stream and return 0 if all is OK. */ int TabTable::save(ostream& os) { if (numCols() == 0) return error("no data to save"); int i, row, col; // print the title (and any other info preceding the column headings) printTableTop(os); // headings int ncols = numCols(), n = ncols-1; for (col = 0; col < ncols; col++) { os << colName(col); if (col < n) os << '\t'; } os << endl; // dashed line for (col = 0; col < ncols; col++) { int l = strlen(colName(col)); for(i = 0; i < l; i++) os << '-'; if (col < n) os << '\t'; } os << endl; // rows and columns return printRows(os); } /* * print the table title (and any other info preceding the column headings) * (may be redefined in a derived class to add more info) */ void TabTable::printTableTop(ostream& os, const char* title) { if (! title) title = "TabTable"; os << title << endl; } /* * append the contents of this object to a tab table file and return 0 if * all is OK. */ int TabTable::append(const char* filename) { if (numRows() == 0 || numCols() == 0) return error("no data to append"); TabTable t; if (head(filename, t) != 0) // get table header in t return ERROR; if (compareHeadings(t) != 0) // compare with this table return error("tables have different columns"); ofstream os(filename, ios::app); if (! os) return sys_error("can't append to file: ", filename); return printRows(os); } /* * Insert the contents of this object (0 or more rows) in a tab table * file and return 0 if all is OK. * * Each row is assumed here to have a unique id column. If a row already * exists with the same id as one that we want to insert, the row is * replaced with the new one. Otherwise, the new row is added at the end * of the file. * * filename is the name of the file to insert in. * * col is the column index of the id column, used to check for * duplicates. */ int TabTable::insert(const char* filename, int col) { if (numRows() == 0 || numCols() == 0) return error("no data to insert"); // make sure we have a valid id column if (col < 0) col = 0; if (checkTableIndex(0, col) != 0) return ERROR; TabTable t; if (head(filename, t) != 0) // get table header in t return ERROR; if (compareHeadings(t) != 0) // compare with this table return error("tables have different columns"); ifstream is(filename); if (! is) return sys_error("can't open file: ", filename); char tmpfile[2048]; sprintf(tmpfile, "%s.TMP", filename); ofstream os(tmpfile); if (! os) return sys_error("can't open file: ", tmpfile); // skip heading char buf[MAX_ROW_SIZE]; while (is.getline(buf, sizeof(buf))) { os << buf << endl; if (buf[0] == '-') break; } // make an array of flags, insertedRow[i] is 1 if row i was inserted in the file int* insertedRow = new int[numRows_]; int row; for (row = 0; row < numRows_; row++) insertedRow[row] = 0; while (is.getline(buf, sizeof(buf))) { if ((row = findRow(buf, col)) < 0) { // if row is not found in this object, add it unchanged to the output file os << buf << endl; } else { // found matching id, add new row to the file to replace the old one printRow(os, row); insertedRow[row] = 1; } } // append any rows that were not inserted in the file for (row = 0; row < numRows_; row++) if (!insertedRow[row]) printRow(os, row); delete[] insertedRow; // make a backup file and rename the tmpfile to the original char bakfile[2048]; sprintf(bakfile, "%s.BAK", filename); if (rename(filename, bakfile) != 0) return sys_error("can't rename file to file.BAK for: ", filename); if (rename(tmpfile, filename) != 0) return sys_error("can't rename file.TMP to file for: ", filename); return 0; } /* * remove all rows in the given tab table file where the value in the * given column matches the value in the same column in any row of this * object. * * For example: if col 0 is the id column and you want to remove any row * from the file foo.tab containing ids from this object, you would call: * * table.remove("foo.tab", 0); * */ int TabTable::remove(const char* filename, int col) { // make sure we have a valid id column if (col < 0) col = 0; if (numRows() == 0 || numCols() == 0) return error("no data rows to remove"); if (checkTableIndex(0, col) != 0) return ERROR; TabTable t; if (head(filename, t) != 0) // get table header in t return ERROR; if (compareHeadings(t) != 0) // compare with this table return error("tables have different columns"); // read from filename and write to $filename.tmp (rename later) ifstream is(filename); if (!is) return sys_error("can't open file: ", filename); char tmpfile[2048]; sprintf(tmpfile, "%s.TMP", filename); ofstream os(tmpfile); if (! os) return sys_error("can't open file: ", tmpfile); char buf[MAX_ROW_SIZE]; // skip heading while (is.getline(buf, sizeof(buf))) { os << buf << endl; if (buf[0] == '-') break; } while (is.getline(buf, sizeof(buf))) { if (findRow(buf, col) < 0) // if row is not found os << buf << endl; // then add to output file } char bakfile[2048]; sprintf(bakfile, "%s.BAK", filename); if (rename(filename, bakfile) != 0) return sys_error("can't rename file to file.BAK for: ", filename); if (rename(tmpfile, filename) != 0) return sys_error("can't rename file.TMP to file for: ", filename); return 0; } /* * If there is a row in this object matching the given column in the the given * row (in buf, a tab separated table row), then return the row number, * otherwise -1. * */ int TabTable::findRow(const char* tableRow, int col) { int i, row, n = numCols_-1; char* colValues[MAX_COLUMNS]; char buf[MAX_ROW_SIZE]; strncpy(buf, tableRow, sizeof(buf)-1); // make a copy, since nulls are inserted by splitList splitList(buf, colValues); for (row = 0; row < numRows_; row++) { if (strcmp(colValues[col], table_[row*numCols_+col]) == 0) return row; } return -1; } /* * local compare function for qsort (method sort), pass on to member method */ static int compareQsort(const void* e1, const void* e2) { return thisPtr_->compareRows(*(int*)e1, *(int*)e2); } /* * local compare function: try to compare numerically, if possible and return * <. = or > 0, as by strcmp. */ static int compareValues(const char* s1, const char* s2) { // try numeric comparison first double d1, d2; int numeric = 2; if (!s1 || sscanf(s1, "%lf", &d1) != 1) numeric--; if (!s2 || sscanf(s2, "%lf", &d2) != 1) numeric--; if (numeric) { if (d1 > d2) return 1; if (d1 < d2) return -1; return 0; } else return strcmp(s1, s2); } /* * compare the given rows and return <. = or > 0, as by strcmp. */ int TabTable::compareRows(int row1, int row2) { int ret = 0; for (int i = 0; i < numSortCols_; i++) { char* item1 = table_[row1*numCols_+sortColIndexes_[i]]; char* item2 = table_[row2*numCols_+sortColIndexes_[i]]; if ((ret = compareValues(item1, item2)) != 0) break; } return ret * sortOrder_; } /* * sort the contents of this tab table by the given columns * numSortCols - the number of columns in the array * sortCols - the array of columns to sort by * sortOrder - >=0 means increasing, <0 means decreasing */ int TabTable::sort(int numSortCols, char** sortCols, int sortOrder) { // since the compare function is a static member, it needs to know these thisPtr_ = this; numSortCols_ = numSortCols; sortOrder_ = (sortOrder >= 0 ? 1 : -1); sortCols_ = sortCols; sortStatus_ = 0; // use integer index instead of column name int colIndexes[MAX_COLUMNS]; for(int i = 0; i < numSortCols; i++) { colIndexes[i] = colIndex(sortCols[i]); if (colIndexes[i] < 0) colIndexes[i] = 0; } sortColIndexes_ = colIndexes; qsort((char*)index_, numRows_, sizeof(int), compareQsort); return sortStatus_; } /* * Search the given tab table file for upto maxRows rows where the given * column has the given value and fill this table with the resulting * rows. * * Args: * * filename - tab table file to search * * searchCol - index of the column to compare (0..n) * * value - value for comparison * * maxRows - max number of rows to find */ int TabTable::search(const char* filename, int searchCol, const char* value, int maxRows) { // open file to search ifstream is(filename); if (!is) return sys_error("can't open file: ", filename); // get table header from stream into result if (head(is, *this) != 0) return ERROR; if (maxRows <= 0) return 0; if (numCols_ < 1) return error("no id column"); return search(is, 1, &colNames_[searchCol], (char**)&value, (char**)&value, maxRows); } /* * Search the given tab table for upto maxRows rows where the given * column has the given value and fill this table with the resulting * rows. * * Args: * * table - tab table to search * * searchCol - index of the column to compare (0..n) * * value - value for comparison * * maxRows - max number of rows to find */ int TabTable::search(const TabTable& table, int searchCol, const char* value, int maxRows) { int tcols = table.numCols(); if (tcols < 1) return error("table contains no columns"); // copy table header for the result if (init(tcols, table.colNames(), "", 0) != 0) return ERROR; if (maxRows <= 0) return 0; return search(table, 1, &colNames_[searchCol], (char**)&value, (char**)&value, maxRows); } /* * Internal version: assumes header has already been read. Search the * given stream for upto maxRows rows with columns values matching the * given arguments and fill this table with the resulting rows. * * Args: * * is - stream positioned at first row after header * * numSearchCols - number of columns in argument arrays * * searchCols - names of the columns to compare * * minValues - min/max values for comparison * maxValues * * maxRows - max number of rows to find */ int TabTable::search(istream& is, int numSearchCols, char** searchCols, char** minValues, char** maxValues, int maxRows) { // read and search rows, put matching rows in "os" char buf[MAX_ROW_SIZE]; ostringstream os; int n = 0; while (is.getline(buf, sizeof(buf))) { if (compareRow(buf, numSearchCols, searchCols, minValues, maxValues) == 0) { os << buf << endl; if (++n >= maxRows) break; } } int status = init(numCols_, colNames_, os.str().c_str(), maxRows); return status; } /* * Internal version: assumes header has already been read. Search the * given tab table for upto maxRows rows with columns values matching the * given arguments and fill this table with the resulting rows. * * Args: * * table - tab table to search * * numSearchCols - number of columns in argument arrays * * searchCols - names of the columns to compare * * minValues - min/max values for comparison * maxValues * * maxRows - max number of rows to find */ int TabTable::search(const TabTable& table, int numSearchCols, char** searchCols, char** minValues, char** maxValues, int maxRows) { // read and search rows, put matching rows in "os" int trows = table.numRows(); ostringstream os; int n = 0; for(int i = 0; i < trows; i++) { if (compareRow(table, i, numSearchCols, searchCols, minValues, maxValues) == 0) { table.printRow(os, i); if (++n >= maxRows) break; } } int status = init(numCols_, colNames_, os.str().c_str(), maxRows); return status; } /* * Search the given tab table file for upto maxRows rows where the given * column has the given value and fill this table with the resulting * rows. * * Args: * * filename - tab table file to search * * searchCol - name of the column to compare * * value - value for comparison * * maxRows - max number of rows to find */ int TabTable::search(const char* filename, const char* searchCol, const char* value, int maxRows) { return search(filename, 1, (char**)&searchCol, (char**)&value, (char**)&value, maxRows); } /* * Search the given tab table for upto maxRows rows where the given * column has the given value and fill this table with the resulting * rows. * * Args: * * table - tab table to search * * searchCol - name of the column to compare * * value - value for comparison * * maxRows - max number of rows to find */ int TabTable::search(const TabTable& table, const char* searchCol, const char* value, int maxRows) { return search(table, 1, (char**)&searchCol, (char**)&value, (char**)&value, maxRows); } /* * Search the given tab table file for upto maxRows rows with columns * values matching the given arguments and fill this table with the * resulting rows. * * Args: * * filename - tab table file to search * numSearchCols - number of columns in argument arrays * * searchCols - names of the columns to compare * * minValues - min/max values for comparison * maxValues * * maxRows - max number of rows to find */ int TabTable::search(const char* filename, int numSearchCols, char** searchCols, char** minValues, char** maxValues, int maxRows) { // open file to search ifstream is(filename); if (!is) return sys_error("can't open file: ", filename); // get table header from stream into result if (head(is, *this) != 0) return ERROR; if (maxRows <= 0) return 0; if (numCols_ < 1) return 0; return search(is, numSearchCols, searchCols, minValues, maxValues, maxRows); } /* * given a buffer containing a row for this table, compare the row with * the given column min and max values and return 0 if there is a match. * * (This method simply splits buf into columns and calls the overeloaded * method below, see the comments there) */ int TabTable::compareRow(char* buf, int numSearchCols, char** searchCols, char** minValues, char** maxValues) { // need to make a copy of the row, since splitList replaces tabs with null chars char buf2[MAX_ROW_SIZE]; strcpy(buf2, buf); char* colValues[MAX_COLUMNS]; if (splitList(buf2, colValues) != 0) return ERROR; return compareRow(colValues, numSearchCols, searchCols, minValues, maxValues); } /* * given a row with columns for this table, compare the row with the * given column min and max values and return 0 if there is a match. * * The first argument represents the row data to be searched. The rest of * the arguments describe the search condition such that * * minValue[i] <= colValues[i] <= maxValue[i] * * Either minValues or maxValues, or any of thier elements may be NULL, * to indicate + or - infinity. * * A numeric comparison is done, if possible. * * If all of the specified conditions are met, 0 is returned. */ int TabTable::compareRow(char** colValues, int numSearchmCols, char** searchCols, char** minValues, char** maxValues) { // for each search column specified... for (int col = 0; col < numSearchmCols; col++) { // see if this table has a column by that name... int i = inputColIndex(searchCols[col]); if (i < 0) return 1; // can't compare non-existant column if (compareCol(colValues[i], (minValues ? minValues[col] : (char*)NULL), (maxValues ? maxValues[col] : (char*)NULL)) != 0) return 1; // column value failed condition } return 0; // condition passed } /* * given a tab table and a row number, compare the row with * the given column min and max values and return 0 if there is a match. */ int TabTable::compareRow(const TabTable& table, int row, int numSearchCols, char** searchCols, char** minValues, char** maxValues) { // for each search column specified... for (int col = 0; col < numSearchCols; col++) { // see if this table has a column by that name... int i = inputColIndex(searchCols[col]); if (i < 0) return 1; // can't compare non-existant column char* s; // get column value in table if (table.get(row, i, s) != 0) return 1; if (compareCol(s, (minValues ? minValues[col] : (char*)NULL), (maxValues ? maxValues[col] : (char*)NULL)) != 0) return 1; // column value failed condition } return 0; // condition passed } /* * return 0 if the given value is in the given range, doing a numeric comparison if * possible. */ int TabTable::compareCol(const char* value, const char* minValue, const char* maxValue) { // try numeric comparison first double d, dmin, dmax; int numeric = 2; if (!minValue || sscanf(minValue, "%lf", &dmin) != 1) { dmin = -HUGE_VAL; numeric--; } if (!maxValue || sscanf(maxValue, "%lf", &dmax) != 1) { dmax = HUGE_VAL; numeric--; } if (numeric && sscanf(value, "%lf", &d) == 1) { if (d < dmin || d > dmax) return 1; // condition failed } else { // try string comparison if ((minValue && strcmp(minValue, value) > 0) || (maxValue && strcmp(maxValue, value) < 0)) return 1; // condition failed } return 0; // condition passed } /* * print the table rows to the given stream */ int TabTable::printRows(ostream& os) const { int row; for (row = 0; row < numRows_; row++) { printRow(os, row); } return 0; } /* * print the given table row to the given stream */ int TabTable::printRow(ostream& os, int row) const { int n = numCols_-1, r = index_[row]; for (int col = 0; col < numCols_; col++) { os << table_[r*numCols_+col]; if (col < n) os << '\t'; } os << endl; return 0; } /* * static method: * read the heading info from the given file and put it in the given object. */ int TabTable::head(const char* filename, TabTable& t) { ifstream is(filename); if (!is) { return sys_error("can't open file: ", filename); } return head(is, t); } /* * static method: * read the heading info from the given stream and put it in the given object */ int TabTable::head(istream& is, TabTable& t) { ostringstream os; char buf[MAX_HEADER_SIZE]; while (is.getline(buf, sizeof(buf))) { os << buf << endl; if (buf[0] == '-') break; } int status = t.init(os.str().c_str()); return status; } /* * compare headings in this table and the given one and return 0 * if they are the same. */ int TabTable::compareHeadings(const TabTable& t) { int ncols = numCols(); if (t.numCols() != ncols) return 1; for (int i = 0; i < ncols; i++) if (strcmp(colName(i), t.colName(i)) != 0) return 1; return 0; } /* * check the given row and col index and generate an error if out of range */ int TabTable::checkTableIndex(int row, int col) const { if (row < 0 || row >= numRows_) { char msg[80]; sprintf(msg, "row index %d out of range (max %d)", row, numRows_-1); return error(msg); } if (col < 0 || col >= numCols_) { char msg[80]; sprintf(msg, "column index %d out of range (max %d)", col, numCols_-1); return error(msg); } return 0; } /* * get the value at the given row,column as a char string */ int TabTable::get(int row, int col, char*& value) const { if (checkTableIndex(row, col) != 0) return ERROR; value = table_[index_[row]*numCols_+col]; return 0; } /* * get the value at the given row,column as an int */ int TabTable::get(int row, int col, int& value) const { char* p; if (get(row, col, p) != 0) return 1; // error if (sscanf(p, "%d", &value) != 1) return tab_error(row, col, (char *)"int", p); return 0; } /* * get the value at the given row,column as a double */ int TabTable::get(int row, int col, double& value) const { char* p; if (get(row, col, p) != 0) return 1; if (sscanf(p, "%lf", &value) != 1) return tab_error(row, col, (char *)"double", p); return 0; } /* * get the value at the given row,column as a float */ int TabTable::get(int row, int col, float& value) const { char* p; double d; if (get(row, col, p) != 0) return 1; // error if (sscanf(p, "%f", &value) != 1) return tab_error(row, col, (char *)"float", p); return 0; } /* * get the value at the given row,column as a short int */ int TabTable::get(int row, int col, short& value) const { char* p; int i; if (get(row, col, p) != 0) return 1; // error if (sscanf(p, "%d", &i) != 1) return tab_error(row, col, (char *)"short", p); value = i; return 0; } /* * get the value at the given row,column as a char */ int TabTable::get(int row, int col, char& value) const { char* p; if (get(row, col, p) != 0) return 1; // error value = *p; return 0; } /* * get the value at the given row,column * (just convert col name to index and call the inherited method) * - use a macro, since the code is always the same - just different * types. */ #define TGET(T) \ int TabTable::get(int row, const char* s, T& value) const \ { \ int col = inputColIndex(s); \ if (col < 0) \ return error("invalid result column: ", s); \ return TabTable::get(row, col, value); \ } TGET(char*) TGET(int) TGET(short) TGET(double) TGET(float) TGET(char) /* * Get a comment (see numComments() for how many are available). */ int TabTable::getComment(int n, char*& value) const { if ( n >= numComments_ ) { return 1; } value = comments_[n]; return 0; } skycat-3.1.2-starlink-1b/cat/generic/TabTable.h000066400000000000000000000231351215713201500211530ustar00rootroot00000000000000// -*-c++-*- #ifndef _TabTable_h_ #define _TabTable_h_ /* * E.S.O. - VLT project/ESO Archive * $Id: TabTable.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * TabTable.h - class definitions for accessing values from a char buffer * in the format of table, such as the result of a database query, * where the rows are separated by newlines and the columns by * tabs (or other given char). * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 9 Jan 96 Created * Peter W. Draper 28 Aug 08 Increase MAX_COLUMNS to 512 from 256. * 17 Mar 09 Add changes to access header comments. */ using namespace std; #include /* * Class TabTable * * This class manages a buffer containing a table where the rows are * separated by newlines and the columns by tabs (or other char). The * class provides transparent access to the table based on a row,column * index and allows for type conversion from string to the desired type. */ class TabTable { protected: int numRows_; // number of rows int numCols_; // number of columns char** colNames_; // array of column names char* buf_; // saved copy of input buffer (memory for table) char** table_; // array of row/col values int* index_; // array of row indexes for sorting char** comments_; // array of comments extracted from header int numComments_; // number of comments char sep_; // separator char (default: \t) int status_; // status after constructor (0 if OK) // these are set and used only during a table sort for use by compare methods static int numSortCols_; // number of columns to sort by static char** sortCols_; // array of sort column names static int* sortColIndexes_;// array of sort column indexes static int sortOrder_; // sort order (increasing if >= 0) static int sortStatus_; // status after sort (0 is ok) // scan the table to set colNames, numRows, numCols and set the start of data ptr virtual int scanTable(int maxRows, char*& start); // util to split a line into string array virtual int splitList(char* line, char** colValues); // report errors in input virtual int tab_error(int row, int col, char* expected, char* value) const; // scan the given buffer and return the number of lines virtual int getNumLines(char* buf, int maxRows); // create and fill the internal table from the given buffer in tab table format virtual int fillTable(char* buf); // internal search util: assumes stream is positioned at first row virtual int search(istream& is, int numSearchCols, char** searchCols, char** minValues, char** maxValues, int maxRows); // given a row with columns for this table, compare the row with the // given column min and max values and return 0 if there is a match. virtual int compareRow(char* buf, int numSearchCols, char** searchCols, char** minValues, char** maxValues); // same as above, but with the row split into a string array virtual int compareRow(char** colValues, int numSearchmCols, char** searchCols, char** minValues, char** maxValues); int compareRow(const TabTable& table, int row, int numSearchCols, char** searchCols, char** minValues, char** maxValues); // return 0 if the given value is in the given range, doing a numeric comparison if // possible. virtual int compareCol(const char* value, const char* minValue, const char* maxValue); // return column index in input for the given column name // (may be redefined by a derived class taht changes column names or positions) virtual int inputColIndex(const char* colName) const {return colIndex(colName);} // check that row and column are in range virtual int checkTableIndex(int row, int col=0) const; // print table title and other info virtual void printTableTop(ostream& os, const char* title = NULL); // copy constructor (not defined) // TabTable(const TabTable&); public: // constants enum {MAX_ROW_SIZE=8*1024}; // max size of a tab table row enum {MAX_HEADER_SIZE=1024}; // max size of a tab table heading enum {MAX_COLUMNS=512}; // max number of table columns public: // constructor: initialize empty table TabTable(char sep = '\t'); // constructor: initialize table from buffer in tab table format TabTable(const char* buf, int maxRows = 0, char sep = '\t'); // constructor: initialize table from data buffer without headings TabTable(int numCols, char** colNames, const char* buf, int maxRows = 0, char sep = '\t'); // destructor: free any allocated memory virtual ~TabTable(); // make the table empty and free any resources used virtual int clear(); // fill the table from the given buffer in tab table format virtual int init(const char* buf, int maxRows = 0, int owner = 0); // fill the table from the given buffer in tab table format, with headings // specified separately virtual int init(int numCols, char** colNames, const char* buf, int maxRows = 0, int owner = 0); // access to row,column values // set the parameter value and return 0 on success virtual int get(int row, int col, char*& value) const; virtual int get(int row, int col, int& value) const; virtual int get(int row, int col, double& value) const; virtual int get(int row, int col, float& value) const; virtual int get(int row, int col, short& value) const; virtual int get(int row, int col, char& value) const; // get table values by column name virtual int get(int row, const char* colName, char*& value) const; virtual int get(int row, const char* colName, int& value) const; virtual int get(int row, const char* colName, double& value) const; virtual int get(int row, const char* colName, float& value) const; virtual int get(int row, const char* colName, short& value) const; virtual int get(int row, const char* colName, char& value) const; // return the table column index for the given table column name virtual int colIndex(const char* colName) const; // return the column name for the given column index virtual const char* colName(int col) const; // return true if the table contains the given column virtual int hasCol(const char* name) const {return (colIndex(name) >= 0);} // read the heading info from the given stream and return object for it static int head(const char* filename, TabTable&); static int head(istream&, TabTable&); // compare headings in this table and the given one virtual int compareHeadings(const TabTable& t); // compare the given rows virtual int compareRows(int row1, int row2); // save the contents of this object as a tab table virtual int save(const char* filename); virtual int save(ostream&); // append the contents of this object to the given tab table file virtual int append(const char* filename); // insert (or update) the contents of this object to the given tab table file virtual int insert(const char* filename, int col = 0); // remove rows in the tab table file that match the given col in this object virtual int remove(const char* filename, int col); // find a row in this object matching the col in the given tab separated table row virtual int findRow(const char* tableRow, int col); // sort the contents of this tab table by the given columns virtual int sort(int numSortCols, char** sortCols, int sortOrder = 0); // Search the given tab table for upto maxRows rows with columns // values matching the given arguments and fill this table with the // resulting rows. virtual int search(const TabTable& table, int numSearchCols, char** searchCols, char** minValues, char** maxValues, int maxRows); // search as above, but for a single column name and value virtual int search(const TabTable& table, const char* searchCol, const char* value, int maxRows); // search as above, but for a single column index and value virtual int search(const TabTable& table, int searchCol, const char* value, int maxRows); // Search the given tab table file for upto maxRows rows with columns // values matching the given arguments and fill this table with the // resulting rows. virtual int search(const char* filename, int numSearchCols, char** searchCols, char** minValues, char** maxValues, int maxRows); // search as above, but for a single column name and value virtual int search(const char* filename, const char* searchCol, const char* value, int maxRows); // search as above, but for a single column index and value virtual int search(const char* filename, int searchCol, const char* value, int maxRows); // print the table rows to the given stream virtual int printRows(ostream& os) const; // print the given table row to the given stream virtual int printRow(ostream& os, int row) const; // output operator friend ostream& operator<<(ostream& os, TabTable& t) { t.save(os); return os; } // get a comment int getComment(int n, char*& value) const; // member access virtual int numRows() const {return numRows_;} virtual void numRows(int n) {if (n < numRows_ && n >= 0) numRows_ = n;} virtual int numCols() const {return numCols_;} virtual char** colNames() const {return colNames_;} virtual int status() const {return status_;} virtual int numComments() const {return numComments_;} }; #endif /* _TabTable_h_ */ skycat-3.1.2-starlink-1b/cat/generic/TclAstroCat.C000066400000000000000000001616131215713201500216170ustar00rootroot00000000000000/* * E.S.O. - VLT project/Archive * $Id: TclAstroCat.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * TclAstroCat.C - method definitions for class TclAstroCat * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 95 Created * pbiereic 26/08/99 Changed Cat_Init() * Peter W. Draper 17/09/08 Added VO support meta-data access. * 28/11/08 Change removeQueryResult to use the id_col * value rather than 0. * 18/03/09 Added comments command. * 20/07/09 Use object interface for building the query * table list. Old interface very slow in tcl8.5. */ static const char* const rcsId="@(#) $Id: TclAstroCat.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; using namespace std; #include #include #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "TabTable.h" #include "Mem.h" #include "error.h" #include "util.h" #include "LocalCatalog.h" #include "TclAstroCat.h" #include "TclQueryUtil.h" // from BLT package (now locally because this routine was deleted with blt2.1) extern "C" int Blt_GraphElement( Tcl_Interp *interp, /* Interpreter of the graph widget */ char *pathName, /* Path name of the graph widget */ char *elemName, /* Name of the element to reset */ int numValues, /* Number of values in array */ double *valueArr, /* Array of x,y coordinate pairs */ char *xVector, /* Name of x array */ char *yVector); /* Name of y array */ // initialize these dependent packages here for backward compat extern "C" int Tclutil_Init(Tcl_Interp *interp); extern "C" int Astrotcl_Init(Tcl_Interp *interp); // generated code for bitmaps used in tcl scripts void defineCatBitmaps(Tcl_Interp*); // Tcl procedure to search for an init for Cat startup file. static char initScript[] = "if {[info proc ::cat::Init]==\"\"} {\n\ namespace eval ::cat {}\n\ proc ::cat::Init {} {\n" #ifdef MAC_TCL " source -rsrc CatInit.tcl\n" #else " global cat_library\n\ tcl_findLibrary cat " PACKAGE_VERSION " " PACKAGE_VERSION " CatInit.tcl CAT_LIBRARY cat_library\n" #endif " }\n\ }\n\ ::cat::Init"; /* * Declare a table of tcl subcommands. * * NOTE: keep this table sorted, so we can use a binary search on it ! * (select lines in emacs and use M-x sort-lines) */ static class TclAstroCatSubCmds { public: char* name; // method name int (TclAstroCat::*fptr)(int argc, char* argv[]); int min_args; // minimum number of args int max_args; // maximum number of args } subcmds_[] = { {"authorize", &TclAstroCat::authorizeCmd, 0, 4}, {"check", &TclAstroCat::checkCmd, 1, 1}, {"checkrow", &TclAstroCat::checkrowCmd, 1, 1}, {"close", &TclAstroCat::closeCmd, 0, 0}, {"comments", &TclAstroCat::commentsCmd, 0, 1}, {"copyright", &TclAstroCat::copyrightCmd, 0, 0}, {"datatype", &TclAstroCat::datatypeCmd, 0, 0}, {"dec_col", &TclAstroCat::dec_colCmd, 0, 0}, {"entry", &TclAstroCat::entryCmd, 1, 4}, {"epoch", &TclAstroCat::epochCmd, 0, 0}, {"equinox", &TclAstroCat::equinoxCmd, 0, 0}, {"equinoxprefix",&TclAstroCat::equinoxPrefixCmd,0, 0}, {"feedback", &TclAstroCat::feedbackCmd, 1, 1}, {"getcol", &TclAstroCat::getcolCmd, 2, 2}, {"getidpos", &TclAstroCat::getidposCmd, 1, 1}, {"getimage", &TclAstroCat::getimageCmd, 0, 99}, {"getpreview", &TclAstroCat::getpreviewCmd, 2, 4}, {"hascol", &TclAstroCat::hascolCmd, 1, 1}, {"headings", &TclAstroCat::headingsCmd, 0, 0}, {"help", &TclAstroCat::helpCmd, 0, 0}, {"id_col", &TclAstroCat::id_colCmd, 0, 0}, {"info", &TclAstroCat::infoCmd, 1, 2}, {"is_tcs", &TclAstroCat::is_tcsCmd, 0, 2}, {"ispix", &TclAstroCat::ispixCmd, 0, 0}, {"iswcs", &TclAstroCat::iswcsCmd, 0, 0}, {"load", &TclAstroCat::loadCmd, 1, 2}, {"longname", &TclAstroCat::longnameCmd, 0, 2}, {"more", &TclAstroCat::moreCmd, 0, 0}, {"open", &TclAstroCat::openCmd, 1, 2}, {"plot", &TclAstroCat::plotCmd, 5, 5}, {"query", &TclAstroCat::queryCmd, 0, 99}, {"querypos", &TclAstroCat::queryposCmd, 0, 0}, {"ra_col", &TclAstroCat::ra_colCmd, 0, 0}, {"reload", &TclAstroCat::reloadCmd, 0, 0}, {"remove", &TclAstroCat::removeCmd, 1, 4}, {"root", &TclAstroCat::rootCmd, 0, 0}, {"save", &TclAstroCat::saveCmd, 1, 5}, {"searchcols", &TclAstroCat::searchcolsCmd, 0, 1}, {"servtype", &TclAstroCat::servtypeCmd, 0, 2}, {"shortname", &TclAstroCat::shortnameCmd, 0, 2}, {"showcols", &TclAstroCat::showcolsCmd, 0, 1}, {"sortcols", &TclAstroCat::sortcolsCmd, 0, 1}, {"sortorder", &TclAstroCat::sortorderCmd, 0, 1}, {"stc_col", &TclAstroCat::stc_colCmd, 0, 0}, {"symbol", &TclAstroCat::symbolCmd, 0, 1}, {"system", &TclAstroCat::systemCmd, 0, 0}, {"ucd", &TclAstroCat::ucdCmd, 0, 0}, {"unit", &TclAstroCat::unitCmd, 0, 0}, {"url", &TclAstroCat::urlCmd, 0, 2}, {"utype", &TclAstroCat::utypeCmd, 0, 0}, {"x_col", &TclAstroCat::x_colCmd, 0, 0}, {"y_col", &TclAstroCat::y_colCmd, 0, 0}, }; /* * Call the given method in this class with the given arguments */ int TclAstroCat::call(const char* name, int len, int argc, char* argv[]) { // since this tcl command has a lot of subcommands, // we do a binary search on the method table int low = 0, high = sizeof(subcmds_)/sizeof(*subcmds_) - 1, mid, cond; while (low <= high) { mid = (low + high) / 2; if ((cond = strcmp(name, subcmds_[mid].name)) < 0) high = mid - 1; else if (cond > 0) low = mid + 1; else { TclAstroCatSubCmds& t = subcmds_[mid]; if (check_args(name, argc, t.min_args, t.max_args) != TCL_OK) return TCL_ERROR; return (this->*t.fptr)(argc, argv); } } // not found ? extend search to parent class return TclCommand::call(name, len, argc, argv); } /* * A call to this function can be made from the tkAppInit file at startup * to install the Tcl astrocat and astroimage and relaxted commands * * (note: for convenience, we also install related commands here) */ extern "C" int TclAstroImage_Init(Tcl_Interp *interp); extern "C" int TclWorldCoords_Init(Tcl_Interp *interp); extern "C" int TclTcsCat_Init(Tcl_Interp *interp); extern "C" int Cat_Init(Tcl_Interp* interp) { // Initialize the local packages that "cat" depends on (we include the // object files from these packages directly, to avoid having the // extra dependencies.) // initialize the tclutil package if (Tclutil_Init(interp) == TCL_ERROR) { return TCL_ERROR; } // initialize the astrotcl package if (Astrotcl_Init(interp) == TCL_ERROR) { return TCL_ERROR; } char buf[2048]; // set up Cat Tcl package if (Tcl_PkgProvide (interp, "Cat", PACKAGE_VERSION) != TCL_OK) { return TCL_ERROR; } // define bitmaps used by Tcl library defineCatBitmaps(interp); // install the astroimage command if (TclAstroImage_Init(interp) == TCL_ERROR) { return TCL_ERROR; } // install the wcs command if (TclWorldCoords_Init(interp) == TCL_ERROR) { return TCL_ERROR; } // install the tcscat command if (TclTcsCat_Init(interp) == TCL_ERROR) { return TCL_ERROR; } // install the astrocat command Tcl_CreateCommand(interp, "astrocat", (Tcl_CmdProc*)TclAstroCat::astroCatCmd, NULL, NULL); // Set the global Tcl variable cat_version Tcl_SetVar(interp, "cat_version", PACKAGE_VERSION, TCL_GLOBAL_ONLY); return Tcl_Eval(interp, initScript); } /* * for backward compat. */ extern "C" int TclAstroCat_Init(Tcl_Interp* interp) { return Cat_Init(interp); } /* * Implementation of the tcl extended command "astrocat" - * usage: see man page for more details */ int TclAstroCat::astroCatCmd(ClientData, Tcl_Interp* interp, int argc, char* argv[]) { if (argc != 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " instanceName\"", NULL); return TCL_ERROR; } TclAstroCat* cmd = new TclAstroCat(interp, argv[0], argv[1]); return cmd->status(); } /* * Constructor - * * Create an "astrocat" object in tcl for accessing the contents of star * catalogs. * * Note that the tcl command for this object is created in the * parent class constructor. */ TclAstroCat::TclAstroCat(Tcl_Interp* interp, const char* cmdname, const char* instname) : TclCommand(interp, cmdname, instname), cat_(NULL), feedback_(NULL), result_(NULL) { strcpy(equinoxStr_, "2000"); } /* * desctructor */ TclAstroCat::~TclAstroCat() { if (cat_) delete cat_; if (result_) delete result_; } /* * Return the catalog directory entry for the given name or list of * names. * * "dirList" may be the name of a catalog directory, or a Tcl list * of catalog directory names forming the path to the directory. */ CatalogInfoEntry* TclAstroCat::lookupCatalogDirectoryEntry(const char* dirList) { // empty strings means use root if (dirList == NULL || strlen(dirList) == 0) return CatalogInfo::root(); // check if it is not a list, but the name of the directory CatalogInfoEntry* entry = CatalogInfo::lookup(dirList); if (!entry) { Tcl_ResetResult(interp_); int n; char** dirs; if (Tcl_SplitList(interp_, (char*)dirList, &n, &dirs) != TCL_OK) { return NULL; } entry = CatalogInfo::lookup(dirs[0]); if (!entry) { error("catalog directory entry not found for: ", dirs[0]); return NULL; } for(int i = 1; i < n; i++) { entry = CatalogInfo::lookup(entry, dirs[i]); if (!entry) { fmt_error("catalog directory entry for '%s' not found under '%s'", dirs[i], dirs[i-1]); return NULL; } if (strcmp(entry->servType(), "directory") != 0) { fmt_error("'%s' is not a catalog directory entry", dirs[i]); return NULL; } } } if (entry && strcmp(entry->servType(), "directory") != 0) { fmt_error("'%s' is not a catalog directory entry", entry->longName()); return NULL; } return entry; } /* * Open the given astromonical catalog and refer to it in future * queries. * * Usage: $cat open catalogName ?catalogDirectory? * * Where "name" is the name of the catalog (short or long name) * and the optional "catalogDirectory" argument is the name of the * catalog directory containing the catalog, or a list * of catalog directories forming the path to the catalog. * This may be used to avoid conflicts when two catalogs in * different parts of the tree have the same name. */ int TclAstroCat::openCmd(int argc, char* argv[]) { if (cat_) { delete cat_; cat_ = NULL; } if (argc == 1 || (argc == 2 && strlen(argv[1]) == 0)) { // open given catalog cat_ = AstroCatalog::open(argv[0]); if (!cat_) return TCL_ERROR; } if (argc == 2) { // open given catalog in given directory path CatalogInfoEntry* entry = lookupCatalogDirectoryEntry(argv[1]); if (!entry) return TCL_ERROR; entry = CatalogInfo::lookup(entry, argv[0]); if (!entry) return fmt_error("catalog entry for '%s' not found under '%s': ", argv[0], argv[1]); // make a new AstroCatalog object from the entry if (AstroCatalog::isLocalCatalog(entry)) cat_ = new LocalCatalog(entry); else cat_ = new AstroCatalog(entry); if (!cat_ || cat_->status() != 0) return TCL_ERROR; } // set up feedback, if requested if (feedback_) cat_->feedback(feedback_); return TCL_OK; } /* * close the current catalog, if one was open */ int TclAstroCat::closeCmd(int argc, char* argv[]) { if (cat_) delete cat_; cat_ = NULL; return TCL_OK; } /* * save subcommand: * * usage: $cat save $filename ?$iflag? ?$data? ?$equinox? ?$headings? * * With 1 arg, save the results of the previous query to the given file. * * If $iflag is true, the data is inserted in the file if it already * exists and the file is sorted and duplicates removed. * * If $data is specified, it should be a Tcl list of rows to be saved, in * the format returned by the query command. * * If $equinox is specified, it is the equinox of the ra and dec columns in * the data (the first 3 columns are assumed to be id, ra and dec, unless * otherwise defined in the catalog config entry or header). * * If $headings is given, it is used as a Tcl list of column headings. * Otherwise the catalog headings are used, if there is a current * catalog. * * The data is saved to a file in the form of a local catalog (tab table) * that can be loaded again or processed by starbase utilities. */ int TclAstroCat::saveCmd(int argc, char* argv[]) { int iflag = 0; char* filename = argv[0]; if (argc >= 2) { if (Tcl_GetBoolean(interp_, argv[1], &iflag) != TCL_OK) return TCL_ERROR; } if (argc <= 2) { if (!result_) return error("no previous data to save"); int id_col = 0; // catalog's id column index if (cat_) id_col = cat_->entry()->id_col(); return (iflag ? result_->insert(filename, id_col) : result_->save(filename)); } int numCols = 0;; char** colNames = NULL; int freeColNames = 0; char* equinoxStr = (char *)"J2000"; if (argc >= 4) equinoxStr = argv[3]; // get the column names if (argc <= 4) { // use current catalog if (!cat_) return error("no catalog is currently open"); numCols = cat_->numCols(); colNames = cat_->colNames(); } else if (argc == 5) { // use headings list if (Tcl_SplitList(interp_, argv[4], &numCols, &colNames) != TCL_OK) return TCL_ERROR; freeColNames++; // delete memory later } else { return error("wrong # of args for save"); // should not get here ... } // save the query results int status = saveQueryResult(filename, numCols, (char**)colNames, argv[2], iflag, equinoxStr); // clean up if (freeColNames && colNames) Tcl_Free((char *)colNames); // free split list of column headings return status; } /* * Save the query results with the given columns and values to the given * filename. If iflag is true, insert in the existing file, otherwise create * a new file. * "equinoxStr" specifies the equinox of the image being displayed, or one of " "J2000", "B1950", "GALACTIC", "ECLIPTIC". * (the coordinate conversion routines expect coordinates in this system). */ int TclAstroCat::saveQueryResult(const char* filename, int numCols, char** colNames, char* info, int iflag, const char* equinoxStr) { // create a QueryResult object from the headings and data and // save (or append) it to the file QueryResult r; int id_col = 0; // catalog's id column index if (cat_) { r.entry(cat_->entry()); id_col = cat_->entry()->id_col(); } if (getQueryResult(numCols, colNames, info, equinoxStr, r) != TCL_OK) return TCL_ERROR; return (iflag ? r.insert(filename, id_col) : r.save(filename)); } /* * Remove the query results with the given columns and values from the given * filename. * "equinoxStr" specifies the equinox of the image being displayed, or one of " "J2000", "B1950", "GALACTIC", "ECLIPTIC". * (the coordinate conversion routines expect coordinates in this system). */ int TclAstroCat::removeQueryResult(const char* filename, int numCols, char** colNames, char* info, const char* equinoxStr) { // create a QueryResult object from the headings and data and // remove rows matching it from the file QueryResult r; int id_col = 0; if (cat_) { r.entry(cat_->entry()); id_col = cat_->entry()->id_col(); } if (getQueryResult(numCols, colNames, info, equinoxStr, r) != TCL_OK) return TCL_ERROR; return r.remove(filename, id_col); } /* * remove subcommand: * * usage: $cat remove $filename ?$data? ?$equinox? ?$headings? * * With 1 arg, remove the results of the previous query from the given file. * * If $data is specified, it should be a Tcl list of rows to be removed, in * the format returned by the query command. * * If $equinox is specified, it is the equinox of ra and dec in $data (so that * ra,dec can be converted to J2000 for comparison). * * If $headings is given, it is used as a Tcl list of column headings. * Otherwise the catalog headings are used, if there is a current * catalog. * * The data rows are removed from the file, which should be in the form of a * local catalog (tab table), such as that used by the starbase utilities. */ int TclAstroCat::removeCmd(int argc, char* argv[]) { if (argc <= 1) { if (!result_) return error("no previous data for remove"); return result_->remove(argv[0], 0); } int numCols = 0;; char** colNames = NULL; int freeColNames = 0; double equinox = 2000.; char* equinoxStr = (char *)"J2000"; if (argc >= 3) equinoxStr = argv[2]; // get the column names if (argc <= 3) { // use current catalog if (!cat_) return error("no catalog is currently open"); numCols = cat_->numCols(); colNames = cat_->colNames(); } else if (argc == 4) { // use headings list if (Tcl_SplitList(interp_, argv[3], &numCols, &colNames) != TCL_OK) return TCL_ERROR; freeColNames++; // delete memory later } else { return error("wrong # of args for remove"); // should not get here ... } // create a QueryResult object from the headings and data and // remove rows matching it from the file int status = removeQueryResult(argv[0], numCols, (char**)colNames, argv[1], equinoxStr); // clean up if (freeColNames && colNames) Tcl_Free((char *)colNames); // free split list of column headings return status; } /* * Check that the given filename is a valid local catalog * (tab table format). */ int TclAstroCat::checkCmd(int argc, char* argv[]) { return LocalCatalog::check_table(argv[0]); } /* * Tcl subcommand: "iswcs" returns true if the catalog is based on world * coordinates */ int TclAstroCat::iswcsCmd(int argc, char* argv[]) { if (!cat_) return error("no catalog is open"); return set_result(cat_->isWcs()); } /* * Tcl subcommand: "ispix" returns true if the catalog is based on image * pixel coordinates */ int TclAstroCat::ispixCmd(int argc, char* argv[]) { if (!cat_) return error("no catalog is open"); return set_result(cat_->isPix()); } /* * Check that the given row (tcl list of columns) is valid for a local * catalog. The row should contain valid values for ra and dec, if we are * using world coords, or x and y, if we are using image coords. The * default columns are "id ra dec ...", but can be overridden in the * catalog config file or header. * * usage: $cat checkrow $data * * generates an error if the position (ra, dec) or (x, y) is not found or * is not in range */ int TclAstroCat::checkrowCmd(int argc, char* argv[]) { int numValues; char** values; if (Tcl_SplitList(interp_, argv[0], &numValues, &values) != TCL_OK) return TCL_ERROR; // if (numValues < 3) { // free(values); // return error("expected at least 3 columns (id, ra, dec or id, x, y)"); // } if (! cat_) return error("no catalog is currently selected"); WorldOrImageCoords pos; if (cat_->isWcs()) pos = WorldCoords(values[cat_->ra_col()], values[cat_->dec_col()]); else if (cat_->isPix()) pos = ImageCoords(values[cat_->x_col()], values[cat_->y_col()]); Tcl_Free((char *)values); return pos.status(); } /* * feedback subcommand: * * specifies a Tcl file descriptor to use to write feedback info during * HTTP transfer of catalog data. 1 Arg: file descriptor. */ int TclAstroCat::feedbackCmd(int argc, char* argv[]) { if (strlen(argv[0]) != 0) { if (Tcl_GetOpenFile(interp_, argv[0], 1, 1, (ClientData*)&feedback_) != TCL_OK) return TCL_ERROR; } else { feedback_ = NULL; } if (cat_) cat_->feedback(feedback_); return TCL_OK; } /* * pass a query to the current catalog and return the result as a list of * rows. * * usage: $cat query -option value ... * * See comments in genAstroQuery in TclQueryUtil.C for details on the * options. * * The result is a tcl list of query result rows, where each row is a tcl list * of column values. */ int TclAstroCat::queryCmd(int argc, char* argv[]) { if (!cat_) return error("no catalog is currently open"); // generate the query from the command args AstroQuery q; if (genAstroQuery(interp_, argc, argv, q, pos1_, pos2_, equinoxStr_, feedback_, cat_->entry()) != TCL_OK) return TCL_ERROR; // make new QueryResult object, or reuse previous one if (result_) result_->clear(); else result_ = new QueryResult; // do the query int nrows = cat_->query(q, NULL, *result_); // get the results int ncols = result_->numCols(); char* s; int i = 0, j = 0; int errs = 0; if (nrows >= 0) { Tcl_ResetResult(interp_); Tcl_Obj *result = Tcl_GetObjResult(interp_); for (i = 0; i < nrows; i++) { // start a row Tcl_Obj *list = Tcl_NewListObj(0, NULL); if (cat_->isWcs()) { // include formatted world coords WorldCoords pos; if (result_->getPos(i, pos) != 0) return TCL_ERROR; // format the ra,dec position arguments in H:M:S... char ra_buf[32], dec_buf[32]; int ra_col = result_->ra_col(), dec_col = result_->dec_col(); pos.print(ra_buf, dec_buf, equinoxStr_); // put the column values in a list for (j = 0; j < ncols; j++) { if (result_->get(i, j, s) != 0) s = (char *)""; if (j == ra_col) Tcl_ListObjAppendElement(interp_, list, Tcl_NewStringObj(ra_buf,-1)); else if (j == dec_col) Tcl_ListObjAppendElement(interp_, list, Tcl_NewStringObj(dec_buf,-1)); else Tcl_ListObjAppendElement(interp_, list, Tcl_NewStringObj(s, -1)); } } else { // image coords - no special formatting needed // put the column values in a list for (j = 0; j < ncols; j++) { if (result_->get(i, j, s) != 0) s = (char *)""; Tcl_ListObjAppendElement(interp_, list, Tcl_NewStringObj(s, -1)); } } // end a row Tcl_ListObjAppendElement(interp_, result, list); } return TCL_OK; } return TCL_ERROR; // an query error occured (and was reported) } /* * Request an image from the current image server and return (in Tcl) * the name of the FITS file holding the image. * * usage: $cat getimage -option value ... * * See comments in genAstroQuery in TclQueryUtil.C for details on the * options. */ int TclAstroCat::getimageCmd(int argc, char* argv[]) { if (!cat_) return error("no catalog is currently open"); // generate the query from the command args AstroQuery q; if (genAstroQuery(interp_, argc, argv, q, pos1_, pos2_, equinoxStr_, feedback_, cat_->entry()) != TCL_OK) return TCL_ERROR; // do the query if (cat_->getImage(q) != 0) return TCL_ERROR; return set_result(cat_->tmpfile()); } /* * querypos subcommand: * * usage: $cat querypos * * Return the world or image coordinate position arguments from the most * recent query, posibly expanded by a name server such as SIMBAD. The * result is a list of the form {ra dec equinox} for world coordinates * or just {x y} for image coords. * */ int TclAstroCat::queryposCmd(int argc, char* argv[]) { ostringstream os; if (! pos1_.isNull()) { pos1_.print(os, equinoxStr_); // print coords in given equinox if (pos1_.isWcs()) os << " " << equinoxStr_; return set_result(os.str().c_str()); } return TCL_OK; } /* * catalog "info" subcommand: * * usage: $cat info $serv_type ?$directory? * * This command returns a list of catalogs from the catalog config file. * The "serv_type" argument determines which catalogs are listed (one of: * catalog, namesvr, imagesvr, directory, local...). * * If $serv_type is an empty string, all entries are returned. * * If $directory is specified, the return list will be from the given * catalog directory entry, retrieved via HTTP if needed. The default, if * no $directory is given, is the top level list read from the default * config file at startup. $directory may also be a tcl list of directories * forming the path to the target directory. */ int TclAstroCat::infoCmd(int argc, char* argv[]) { Tcl_ResetResult(interp_); CatalogInfoEntry* e; if (argc == 2) { e = lookupCatalogDirectoryEntry(argv[1]); if (!e) return TCL_ERROR; if (! e->link()) { if (CatalogInfo::load(e) != 0) // follow catalog dir link return TCL_ERROR; } } else { e = CatalogInfo::root(); } if (!e || !e->link()) return error("can't find catalog info"); e = e->link(); // get pointer to first catalog in directory // get the serv_type Tcl_ResetResult(interp_); int n = strlen(argv[0]); for (; e != NULL; e = e->next()) { if (strncmp(argv[0], e->servType(), n) == 0) { // ignore local catalogs in /tmp, since they will be deleted later if (! (strcmp(e->servType(), "local") == 0 && strncmp(e->url(), "/tmp/", 5) == 0)) { Tcl_AppendElement(interp_, (char*)e->longName()); } } } return TCL_OK; } /* * catalog "root" subcommand: * * usage: $cat root * * This command returns the name of the root catalog directory * */ int TclAstroCat::rootCmd(int argc, char* argv[]) { Tcl_ResetResult(interp_); const CatalogInfoEntry* e = CatalogInfo::root(); if (!e) return error("no catalogs are loaded"); return set_result(e->longName()); } /* * append the given keyword/value pair to the Tcl result */ void TclAstroCat::appendKeyVal(const char* keyword, const char* value) { if (! value) return; Tcl_AppendResult(interp_, " {", NULL); Tcl_AppendElement(interp_, (char*)keyword); Tcl_AppendElement(interp_, (char*)value); Tcl_AppendResult(interp_, "}", NULL); } /* * append the given list value to the Tcl result. The value is assumed * to already be a a colon separated list of space separated lists. * "a b c : d e f". Here we make sure that the lists are proper Tcl lists, * with special chars handled correctly. */ int TclAstroCat::appendListVal(const char* value) { if (! value) return TCL_OK; char* v = strdup(value); char* p; char* q = v; do { Tcl_AppendResult(interp_, " {", NULL); p = strchr(q, ':'); if (p) *p++ = '\0'; int numValues; char** values; if (Tcl_SplitList(interp_, q, &numValues, &values) != TCL_OK) { free(v); Tcl_ResetResult(interp_); return Tcl_SplitList(interp_, q, &numValues, &values); } q = p; for(int i = 0; i < numValues; i++) { Tcl_AppendElement(interp_, values[i]); } Tcl_Free((char *)values); Tcl_AppendResult(interp_, "}", NULL); } while(p); return TCL_OK; } /* * append the given keyword/value pair to the Tcl result and make a * proper tcl list of lists out of the value, which should have the * format "a b c : d e f : ...", where ':' is the sep char for the main * lists, and space is the sep char for the sublists. */ int TclAstroCat::appendKeyListVal(const char* keyword, const char* value) { if (! value || ! strlen(value)) return TCL_OK; Tcl_AppendResult(interp_, " {", NULL); Tcl_AppendElement(interp_, (char*)keyword); Tcl_AppendResult(interp_, " {", NULL); if (appendListVal(value) != TCL_OK) return TCL_ERROR; Tcl_AppendResult(interp_, "}", NULL); Tcl_AppendResult(interp_, "}", NULL); return TCL_OK; } /* * This method is used to write the value of entries that have the * format: "a b c : d e f" in the config file, but are treated as * tcl lists of lists in Tcl. * * Write the config file format entry value part to the stream. */ int TclAstroCat::tclListToConfigStreamValue(const char* tclList, ostream& os) { int numValues = 0; char** values = NULL; // split into {keyword value} lists if (Tcl_SplitList(interp_, (char*)tclList, &numValues, &values) != TCL_OK) return TCL_ERROR; for (int i = 0; i < numValues; i++) { os << values[i]; if (i < (numValues-1)) os << " : "; } Tcl_Free((char *)values); return TCL_OK; } /* * write the given catalog config entry line (tcl list format) to the * given stream in the format: * * keyword; value */ int TclAstroCat::tclListToConfigStreamLine(const char* tclList, ostream& os) { int numValues = 0; char** values = NULL; // split into {keyword value} lists if (Tcl_SplitList(interp_, (char*)tclList, &numValues, &values) != TCL_OK) return TCL_ERROR; if (numValues != 2) { Tcl_Free((char *)values); return error("astrocat: expected {keyword value} list, not: ", tclList); } const char* keyword = values[0]; const char* value = values[1]; // append to an inline config entry to pass to the entry update method if (strcmp(keyword, "symbol") == 0 || strcmp(keyword, "search_cols") == 0) { os << keyword << ": "; if (tclListToConfigStreamValue(value, os) != TCL_OK) { Tcl_Free((char *)values); return TCL_ERROR; } os << endl; } else { os << keyword << ": " << value << endl; } Tcl_Free((char *)values); return TCL_OK; } /* * write the given catalog config entry (tcl list format) to the * given stream in the format: * * keyword; value * keyword: valuue */ int TclAstroCat::tclListToConfigStream(const char* tclList, ostream& os) { int numValues = 0; char** values = NULL; // split into {keyword value} lists if (Tcl_SplitList(interp_, (char*)tclList, &numValues, &values) != TCL_OK) return TCL_ERROR; for (int i = 0; i < numValues; i++) { if (tclListToConfigStreamLine(values[i], os) != TCL_OK) { Tcl_Free((char *)values); return TCL_ERROR; } } Tcl_Free((char *)values); return TCL_OK; } /* * catalog "entry" subcommand: * * usage: $cat entry get ?name? ?directory? * or: $cat entry set $info ?name? ?directory? * or: $cat entry update $info ?name? ?directory? * or: $cat entry add $info ?directory? * or: $cat entry remove $name * * "entry get" returns the catalog config entry for the currently open * catalog or for the given catalog if one is specified. * * The format of the return value is a tcl list of {keyword value} pairs: * * {{key value} {key value} ...} * * for example: * * {{serv_type catalog} * {long_name "Guide Star Catalog at ESO"} * {short_name gsc@eso} * {url http://archive.eso.org/...} * {symbol ...} * {id_col 0} * {ra_col 1} * {dec_col 2} * ...} * * If the "directory" argument is specified, the entry is searched for * starting in the given catalog directory, otherwise it is searched for * starting at the top level directory (the catalog entries are linked * in a hierarchical list or directory structure). "directory" may also be * a tcl list of catalog directories, forming the path to the directory. * * "entry update" allows you to update fields in the catalog's config * entry. Some fields, such as the catalog name and URL can not be * changed in this way, however the column positions id_col, ra_col, * dec_col, etc... may be updated. The format for the update info is the * same as that returned by "entry get". The directory argument has the * same meaning as with the "entry get" subcommand. * * Note: The "entry update" command is needed, for example, when a * catalog query was run in a subprocess. The results of the query may * include config info, such as the default plot symbol and the columns * for id, ra and dec. This subcommand can be used to get this * information back into the parent process catalog entry. * * "entry add" adds a new catalog entry to the internal list. The format * of the argument is the same as that for update. The entry is added to the * given directory or the top level if none is specified. * * "entry remove" removes the entry for the named catalog from the internal * default catalog list. * */ int TclAstroCat::entryCmd(int argc, char* argv[]) { CatalogInfoEntry* e; CatalogInfoEntry* dir = CatalogInfo::root(); if (! dir) return TCL_ERROR; Tcl_ResetResult(interp_); if (strcmp(argv[0], "get") == 0) { char buf[80]; if (argc == 1) { // get entry from current catalog if (! cat_) return error("no catalog is open"); e = cat_->entry(); } else { if (argc > 2) { // use given catalog directory dir = lookupCatalogDirectoryEntry(argv[2]); if (!dir) return TCL_ERROR; } // get entry from named catalog e = CatalogInfo::lookup(dir, argv[1]); if (!e) return error("can't find catalog entry for: ", argv[1]); } // return tcl list with config entry info appendKeyVal("serv_type", (char*)e->servType()); appendKeyVal("long_name", (char*)e->longName()); appendKeyVal("short_name", (char*)e->shortName()); appendKeyVal("url", (char*)e->url()); appendKeyVal("backup1", (char*)e->backup1()); appendKeyVal("backup2", (char*)e->backup2()); if (appendKeyListVal("symbol", (char*)e->symbol()) != TCL_OK) return TCL_ERROR; if (appendKeyListVal("search_cols", (char*)e->searchCols()) != TCL_OK) return TCL_ERROR; appendKeyVal("sort_cols", (char*)e->sortCols()); appendKeyVal("sort_order", (char*)e->sortOrder()); appendKeyVal("show_cols", (char*)e->showCols()); appendKeyVal("copyright", (char*)e->copyright()); appendKeyVal("help", (char*)e->help()); appendKeyVal("system", (char*)e->system()); // don't include these values if they are already defaults if (e->equinox() != 2000.) { sprintf(buf, "%lg", e->equinox()); appendKeyVal("equinox", buf); } if (e->id_col() != 0) { sprintf(buf, "%d", e->id_col()); appendKeyVal("id_col", buf); } if (e->ra_col() != 1) { sprintf(buf, "%d", e->ra_col()); appendKeyVal("ra_col", buf); } if (e->dec_col() != 2) { sprintf(buf, "%d", e->dec_col()); appendKeyVal("dec_col", buf); } if (e->x_col() != -1) { sprintf(buf, "%d", e->x_col()); appendKeyVal("x_col", buf); } if (e->y_col() != -1) { sprintf(buf, "%d", e->y_col()); appendKeyVal("y_col", buf); } if (e->is_tcs()) { sprintf(buf, "%d", e->is_tcs()); appendKeyVal("is_tcs", buf); } if (e->stc_col() != -1) { sprintf(buf, "%d", e->stc_col()); appendKeyVal("stc_col", buf); } } else if (strcmp(argv[0], "remove") == 0) { e = CatalogInfo::lookup(argv[1]); if (!e) return TCL_ERROR; return CatalogInfo::remove(e); } else { int update = 0, set = 0; if (strcmp(argv[0], "update") == 0) { update++; if (argc == 4 && !(dir = lookupCatalogDirectoryEntry(argv[3]))) return TCL_ERROR; } else if (strcmp(argv[0], "set") == 0) { set++; if (argc == 4 && !(dir = lookupCatalogDirectoryEntry(argv[3]))) return TCL_ERROR; } else if (strcmp(argv[0], "add") == 0) { if (argc == 3 && !(dir = lookupCatalogDirectoryEntry(argv[2]))) return TCL_ERROR; } else { return error("unknown astrocat entry subcommand: ", argv[0]); } // update the entry with new info if (argc < 2) return error("missing catalog entry argument"); ostringstream os; // convert tcl list entry to config file format if (tclListToConfigStream(argv[1], os) != TCL_OK) return TCL_ERROR; // read the new config file entry if (! os) return error("internal error writing config entry"); istringstream is(os.str()); if (update || set) { if (argc == 2) { // use current catalog entry if (! cat_) return error("no catalog is open"); e = cat_->entry(); } else { // update named catalog entry (in named dir) e = CatalogInfo::lookup(dir, argv[2]); if (!e) return error("can't find catalog entry for: ", argv[2]); } if (update) { /* entry update */ CatalogInfo::updateConfigEntry(is, e); } else { /* entry set */ CatalogInfoEntry* ne = CatalogInfo::load(is); if (! ne) return TCL_ERROR; *e = *ne; } } else { /* entry add */ e = CatalogInfo::load(is); if (! e) return TCL_ERROR; // add to end of main entry list return CatalogInfo::append(e); } } return TCL_OK; } /* * load subcommand: * * usage: $cat load $filename ?longName? * * This command loads the named catalog config file, making the catalogs * in it available to the application under the given name * (default: last component of file name). */ int TclAstroCat::loadCmd(int argc, char* argv[]) { ifstream is(argv[0]); if (!is) return sys_error("can't open file: ", argv[0]); CatalogInfoEntry* e = CatalogInfo::load(is, argv[0]); if (!e) return TCL_ERROR; // make a directory entry for the file and add it to the catalog tree CatalogInfoEntry* dir = new CatalogInfoEntry; dir->servType("directory"); char url[2048+5]; sprintf(url, "file:%s", argv[0]); dir->url(url); const char* s = fileBasename(argv[0]); dir->shortName(s); if (argc > 1) s = argv[1]; dir->longName(s); // name to be displayed dir->link(e); return CatalogInfo::append(dir); } /* * reload subcommand: * * usage: $cat reload * * This command reloads the default catalog config file and updates the * internal catalog entries from it. This is meant to be used after * the config file has been edited by hand to make the new data available * to the application. */ int TclAstroCat::reloadCmd(int argc, char* argv[]) { return CatalogInfo::reload(); } /* * more subcommand: return true if there were more rows * to fetch on the last query (i.e.: not all rows that were * found were returned due to limits) */ int TclAstroCat::moreCmd(int argc, char* argv[]) { return set_result(cat_ ? cat_->more() : 0); } /* * headings subcommand: return a Tcl list of the column headings */ int TclAstroCat::headingsCmd(int argc, char* argv[]) { if (cat_) { int n = cat_->numCols(); if (n < 0) return TCL_ERROR; for(int i = 0; i < n; i++) Tcl_AppendElement(interp_, (char*)cat_->colName(i)); } return TCL_OK; } /* * column subcommands: id_col, ra_col, dec_col, x_col, y_col & stc_col * Just return the column index from the catalog config entry. */ int TclAstroCat::id_colCmd(int argc, char* argv[]) { if (cat_) return set_result(cat_->id_col()); return TCL_OK; } int TclAstroCat::ra_colCmd(int argc, char* argv[]) { if (cat_) return set_result(cat_->ra_col()); return TCL_OK; } int TclAstroCat::dec_colCmd(int argc, char* argv[]) { if (cat_) return set_result(cat_->dec_col()); return TCL_OK; } int TclAstroCat::x_colCmd(int argc, char* argv[]) { if (cat_) return set_result(cat_->x_col()); return TCL_OK; } int TclAstroCat::y_colCmd(int argc, char* argv[]) { if (cat_) return set_result(cat_->y_col()); return TCL_OK; } int TclAstroCat::stc_colCmd(int argc, char* argv[]) { if (cat_) return set_result(cat_->stc_col()); return TCL_OK; } /* * VO meta-data subcommands: */ int TclAstroCat::systemCmd(int argc, char* argv[]) { if (cat_) return set_result(cat_->system()); return TCL_OK; } int TclAstroCat::epochCmd(int argc, char* argv[]) { if (cat_) return set_result(cat_->epoch()); return TCL_OK; } int TclAstroCat::equinoxCmd(int argc, char* argv[]) { if (cat_) return set_result(cat_->equinox()); return TCL_OK; } int TclAstroCat::equinoxPrefixCmd(int argc, char* argv[]) { if (cat_) return set_result(cat_->equinoxprefix()); return TCL_OK; } int TclAstroCat::unitCmd(int argc, char* argv[]) { if (cat_) return set_result(cat_->unit()); return TCL_OK; } int TclAstroCat::ucdCmd(int argc, char* argv[]) { if (cat_) return set_result(cat_->ucd()); return TCL_OK; } int TclAstroCat::utypeCmd(int argc, char* argv[]) { if (cat_) return set_result(cat_->utype()); return TCL_OK; } int TclAstroCat::datatypeCmd(int argc, char* argv[]) { if (cat_) return set_result(cat_->datatype()); return TCL_OK; } /* * is_tcs command: * * usage: $cat is_tcs ?catalog? ?boolValue? * * With 0 or 1 arg, returns true if this catalog (or the given one) * is a TCS catalog. * * If a value is specified, it sets the tcs flag for the given catalog. * */ int TclAstroCat::is_tcsCmd(int argc, char* argv[]) { if (argc == 0) { if (cat_) return set_result(cat_->is_tcs()); return set_result(0); } CatalogInfoEntry* e = CatalogInfo::lookup(argv[0]); if (!e) return TCL_ERROR; if (argc == 1) return set_result(e->is_tcs()); int is_tcs = 0; if (Tcl_GetBoolean(interp_, argv[1], &is_tcs) != TCL_OK) return TCL_ERROR; e->is_tcs(is_tcs); return set_result(0); } /* * symbol subcommand: * * usage: $cat symbol ?value? * * With no args, return the "symbol" entry for this catalog. * With one arg, specify a new value for the symbol entry, * which should be a list of the form: * * {{colNames symbolExpr sizeExpr} ...} * * where colNames is a list of column names used, symbolExpr is one of * the accepted symbol expressions, such as "circle ?color?" and * sizeExpr is an expression (or a list of {expr ?units?}) giving the * radius of an object. */ int TclAstroCat::symbolCmd(int argc, char* argv[]) { if (argc == 0) { if (cat_) return appendListVal(cat_->symbol()); } if (! cat_) return error("no catalog is open"); cat_->entry()->symbol(argv[0]); return TCL_OK; } /* * searchcols subcommand: * * usage: $cat searchcols ?value? * * With no args, return the "search_cols" entry for this catalog. * With one arg, specify a new value for the search_cols entry, * which should be a list of the form: * * {{colName minLabel maxLabel} ...} * */ int TclAstroCat::searchcolsCmd(int argc, char* argv[]) { if (argc == 0) { if (cat_) return appendListVal(cat_->searchCols()); } else if (! cat_) return error("no catalog is open"); cat_->entry()->searchCols(argv[0]); return TCL_OK; } /* * sortcols subcommand: * * usage: $cat sortcols ?value? * * With no args, return the "sort_cols" entry for this catalog. * With one arg, specify a new value for the sort_cols entry, * which should be a list of the form: * * {col1 col2 ...} * */ int TclAstroCat::sortcolsCmd(int argc, char* argv[]) { if (argc == 0) { if (cat_) return set_result(cat_->sortCols()); } else if (! cat_) return error("no catalog is open"); cat_->entry()->sortCols(argv[0]); return TCL_OK; } /* * sortorder subcommand: * * usage: $cat sortorder ?value? * * With no args, return the "sort_order" entry for this catalog. * With one arg, specify a new value for the sort_order entry, * which should be a list of the form: * * {col1 col2 ...} * */ int TclAstroCat::sortorderCmd(int argc, char* argv[]) { if (argc == 0) { if (cat_) return set_result(cat_->sortOrder()); } else if (! cat_) return error("no catalog is open"); cat_->entry()->sortOrder(argv[0]); return TCL_OK; } /* * showcols subcommand: * * usage: $cat showcols ?value? * * With no args, return the "show_cols" entry for this catalog. * With one arg, specify a new value for the show_cols entry, * which should be a list of the form: * * {col1 col2 ...} * */ int TclAstroCat::showcolsCmd(int argc, char* argv[]) { if (argc == 0) { if (cat_) return set_result(cat_->showCols()); } else if (! cat_) return error("no catalog is open"); cat_->entry()->showCols(argv[0]); return TCL_OK; } /* * copyright subcommand: return the copyright info for this catalog * from the catalog config file. */ int TclAstroCat::copyrightCmd(int argc, char* argv[]) { if (cat_) { return set_result(cat_->copyright()); } return TCL_OK; } /* * help subcommand: return the help info for this catalog * from the catalog config file. */ int TclAstroCat::helpCmd(int argc, char* argv[]) { if (cat_) { return set_result(cat_->help()); } return TCL_OK; } /* * servtype subcommand: return the servtype for this catalog or * for the given catalog. * * "directory" may be the name of the parent catalog directory, or a list * of parent directories forming the path to the given name. * * usage: $cat servtype ?name? ?directory? */ int TclAstroCat::servtypeCmd(int argc, char* argv[]) { if (argc == 0) { if (cat_) { return set_result(cat_->servType()); } return TCL_OK; } CatalogInfoEntry* dir = CatalogInfo::root(); if (argc == 2) { // use given catalog directory dir = lookupCatalogDirectoryEntry(argv[1]); if (!dir) return TCL_ERROR; } const CatalogInfoEntry* e = CatalogInfo::lookup(dir, argv[0]); if (e) return set_result(e->servType()); return TCL_OK; } /* * url subcommand: return the url for this catalog or * for the given catalog. * * usage: $cat url ?name? ?directory? * * "directory" may be the name of the parent catalog directory, or a list * of parent directories forming the path to the given name. */ int TclAstroCat::urlCmd(int argc, char* argv[]) { if (argc == 0) { if (cat_) { return set_result(cat_->url()); } return TCL_OK; } CatalogInfoEntry* dir = CatalogInfo::root(); if (argc == 2) { // use given catalog directory dir = lookupCatalogDirectoryEntry(argv[1]); if (!dir) return TCL_ERROR; } const CatalogInfoEntry* e = CatalogInfo::lookup(dir, argv[0]); if (e) return set_result(e->url()); return TCL_OK; } /* * hascol subcommand: return true if the catalog contains the * given column name (in the config entry). */ int TclAstroCat::hascolCmd(int argc, char* argv[]) { if (cat_) { return set_result(cat_->hasCol(argv[0])); } return set_result(0); } /* * getcol subcommand: given a row of output from a query, * return the value for the named column in Tcl * * example: set preview [$cat getcol preview $row] */ int TclAstroCat::getcolCmd(int argc, char* argv[]) { int numValues; char** values; int index = -1; if (cat_) index = cat_->colIndex(argv[0]); if (index >= 0) { if (Tcl_SplitList(interp_, argv[1], &numValues, &values) != TCL_OK) return TCL_ERROR; if (index < numValues) { set_result(values[index]); } Tcl_Free((char *)values); } else { return error("no such column: ", argv[0]); } return TCL_OK; } /* * getidpos subcommand: given a row of output from a query, return a list * {id ra dec} (or {id x y} if we're not using wcs) for the given * row. The positions of the 3 columns default to the first 3 columns: * id, ra and dec, but might be specified differently in the catalog * config entry or result header. * * example: lassign [$cat getidpos $row] id ra dec */ int TclAstroCat::getidposCmd(int argc, char* argv[]) { // get column indexes from catalog info int id_col = 0, ra_col = 1, dec_col = 2; if (cat_) { id_col = cat_->id_col(); ra_col = cat_->ra_col(); dec_col = cat_->dec_col(); } int numValues; char** values; if (Tcl_SplitList(interp_, argv[0], &numValues, &values) != TCL_OK) return TCL_ERROR; Tcl_ResetResult(interp_); if (id_col >= 0 && id_col < numValues && ra_col >= 0 && ra_col < numValues && dec_col >= 0 && dec_col < numValues) { Tcl_AppendElement(interp_, values[id_col]); Tcl_AppendElement(interp_, values[ra_col]); Tcl_AppendElement(interp_, values[dec_col]); } Tcl_Free((char *)values); return TCL_OK; } /* * getpreview subcommand: given a URL from a query output line, get the * preview data and put it in a temp file. The return value in Tcl is a * list of {filename type}, where filename is the name of the file * containing the preview data and type is either "image" for a * decompressed FITS image or "table" for a tab table with data to be * plotted in a graph. * * The temp file is re-used and deleted in the destructor. * * example: set preview [$cat getpreview -url "http://...." ?-tmpfile "/tmp/img..."?] * * -url specifies the URL to use * * -tmpfile can be used to specify the image file name to use * */ int TclAstroCat::getpreviewCmd(int argc, char* argv[]) { if (!cat_) return error("no catalog is open"); char* url = NULL; for (int i = 0; i < argc; i += 2) { char* option = argv[i]; char* value = argv[i+1]; if (strcmp(option, "-url") == 0) { url = value; } else if (strcmp(option, "-tmpfile") == 0) { if (value) { unlink(cat_->tmpfile()); cat_->tmpfile(value); } } } if (!url) return error("missing -url option"); char* type; if (cat_->getPreview(url, type) != 0) return TCL_ERROR; Tcl_ResetResult(interp_); Tcl_AppendElement(interp_, (char*)cat_->tmpfile()); Tcl_AppendElement(interp_, type); return TCL_OK; } /* * authorize subcommand: If the previous HTTP GET returned an * authorization error: (The HTML error text returned in Tcl contained * the string: "Authorization Required"), the application can * ask the user to enter a username and password to use to access the * URL and then retry the GET after using this subcommand to set the * authorization information to use. * * usage: * * $cat authorize * $cat authorize username passwd ?realm server? * * With no arguments, this command returns a list of the form * * {needpasswd realm server} * * where: * needpasswd is nonzero if a password is required for the URL * realm is the string taken from the HTTP header (Basic realm=...). * server is the name of the target server that wants the password. * * If arguments are specified, they should be the username and password * and optionally the realm and server hostname. If the last 2 args are * specified, the information is stored in a file for later lookup * (see tclutil/util/src/HTTP.C). */ int TclAstroCat::authorizeCmd(int argc, char* argv[]) { if (!cat_) return error("no catalog is open"); if (argc == 0) { HTTP& http = cat_->http(); ostringstream os; os << http.authorizationRequired() << " " << http.www_auth_realm() << " " << http.hostname(); return set_result(os.str().c_str()); } if (argc == 2) HTTP::authorize(argv[0], argv[1]); else if (argc == 4) HTTP::authorize(argv[0], argv[1], argv[2], argv[3]); else return error("expected: astrocat authorize ?username passwd realm server?"); return TCL_OK; } /* * longname subcommand: * * usage: $cat longname ?name? ?directory? * * returns the long_name field from the catalog config file * for the given long or short name, or for the current catalog. * * "directory" may be the name of the parent catalog directory, or a list * of parent directories forming the path to the given name. */ int TclAstroCat::longnameCmd(int argc, char* argv[]) { if (argc == 0) { if (cat_) return set_result(cat_->longName()); return TCL_OK; } CatalogInfoEntry* dir = CatalogInfo::root(); if (argc == 2) { // use given catalog directory dir = lookupCatalogDirectoryEntry(argv[1]); if (!dir) return TCL_ERROR; } const CatalogInfoEntry* e = CatalogInfo::lookup(dir, argv[0]); if (e) return set_result(e->longName()); return TCL_OK; } /* * plot subcommand: plot the contents of the given tab table file in the given * BLT graph widget). * * usage: $cat plot $graph $element $filename xVector yVector * * element is the BLT graph element name * * filename is the local catalog file * * xVector is the name of the BLT x vector * * yVector is the name of the BLT y vector * * The data for the given element in the given graph will be set * directly from here without going through tcl. * * The return value in Tcl is the number of rows (for the graph's x-axis) * */ int TclAstroCat::plotCmd(int argc, char* argv[]) { char* graph = argv[0]; char* elem = argv[1]; char* filename = argv[2]; // mmap the file to get the data in memory Mem m(filename); if (m.status() != 0) return TCL_ERROR; // make a tab table out of the file TabTable tab((char*)m.ptr()); if (tab.status() != 0) return TCL_ERROR; // plot each row under the element name of the column heading int ncols = tab.numCols(); if (ncols < 2) return error("expected at least 2 table columns to plot"); // XXX how to interp 3 or more columns ? int nrows = tab.numRows(); int nvalues = nrows*2; double* xyvalues = new double[nvalues]; int n; for (int row = 0; row < nrows; row++) { if (tab.get(row, 0, xyvalues[n=row*2]) != 0 || tab.get(row, 1, xyvalues[++n]) != 0) { delete[] xyvalues; return TCL_ERROR; } } if (Blt_GraphElement(interp_, graph, elem, nvalues, xyvalues, argv[3], argv[4]) != TCL_OK) { delete[] xyvalues; return TCL_ERROR; } delete[] xyvalues; return set_result(nrows); } /* * shortname subcommand: * * usage: $cat shortname ?name? ?directory? * * returns the short_name field from the catalog config file * for the given long name, or for the current catalog. * * "directory" may be the name of the parent catalog directory, or a list * of parent directories forming the path to the given name. */ int TclAstroCat::shortnameCmd(int argc, char* argv[]) { if (argc == 0) { if (cat_) return set_result(cat_->shortName()); return TCL_OK; } CatalogInfoEntry* dir = CatalogInfo::root(); if (argc == 2) { // use given catalog directory dir = lookupCatalogDirectoryEntry(argv[1]); if (!dir) return TCL_ERROR; } const CatalogInfoEntry* e = CatalogInfo::lookup(dir, argv[0]); if (e) return set_result(e->shortName()); return TCL_OK; } /* * Convert the given list from a Tcl list to a QueryResult (tab table), * given the number of columns and the column headings. * * Note: this is needed to make a clean interface between the Tcl and C++ * classes. The Tcl part needs this because of the way that queries are * done in the background, so that the original results are lost when the * child process ends. That is why we have to convert back from Tcl list * to tab table here. It has the added advantage of making a flexible Tcl * command interface where you can specify catalog data as Tcl lists. * * The equinoxStr parameter may be a number in string form, such as "2000", * or "1950.", or it may also be one of "J2000", "B1950", "GALACTIC", "ECLIPTIC". * This value is used to convert the coordinates into the internal J2000 format. * * Normally the first 3 columns are id, ra and dec, but we can't rely on * this, so we take the column info from the QueryResult object (the * r.entry() method should be called to set the catalog entry before calling * this method). */ int TclAstroCat::getQueryResult(int numCols, char** colNames, const char* list, const char* equinoxStr, QueryResult& r) { ostringstream os; int numRows = 0; char** rows = NULL; char raStr[32], decStr[32]; int status = Tcl_SplitList(interp_, (char*)list, &numRows, &rows); if (status == TCL_OK) { for (int row = 0; row < numRows; row++) { int ncols = 0; char** cols = NULL; if (Tcl_SplitList(interp_, rows[row], &ncols, &cols) != TCL_OK || ncols != numCols) { status = error("wrong number of columns: ", rows[row]); break; } int n = ncols-1; if (r.isWcs()) { // if catalog uses world coords... // convert ra,dec to J2000, then print out in the catalog's equinox int ra_col = r.ra_col(); int dec_col = r.dec_col(); const char* raPtr = cols[ra_col]; const char* decPtr = cols[dec_col]; WorldCoords pos(raPtr, decPtr, equinoxStr); // converts to J2000 internally if (pos.status() != 0) { raStr[0] = decStr[0] = '\0'; } else { // print in catalog's equinox pos.print(raStr, decStr, r.equinox()); } // output the columns for (int col = 0; col < ncols; col++) { if (col == ra_col) os << raStr; // ra and dec are formatted specially else if (col == dec_col) os << decStr; else os << cols[col]; if (col < n) os << '\t'; } } else { // output the columns for (int col = 0; col < ncols; col++) { os << cols[col]; if (col < n) os << '\t'; } } os << '\n'; Tcl_Free((char *)cols); } } // create a QueryResult object from the headings and data and // save (or append) it to the file if (status == 0) status = r.init(numCols, colNames, os.str().c_str()); if (rows) Tcl_Free((char *)rows); // free split list of rows return status; } /* * comments subcommand: * * usage: $cat comments ?comments? * * return or set the comments associated with the current catalog. */ int TclAstroCat::commentsCmd(int argc, char* argv[]) { if (argc == 0) { if (cat_) return set_result(cat_->comments()); return TCL_OK; } if (cat_) { cat_->comments(argv[1]); return TCL_OK; } return error( "cannot set comments, no current catalog" ); } skycat-3.1.2-starlink-1b/cat/generic/TclAstroCat.h000066400000000000000000000126621215713201500216630ustar00rootroot00000000000000// -*-c++-*- #ifndef _TclAstroCat_h_ #define _TclAstroCat_h_ /* * E.S.O. - VLT project/ESO Archive * $Id: TclAstroCat.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * TclAstroCat.h - Tcl interface to the AstroCatalog C++ class for * accessing astronomical catalogs * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 95 Created * Peter W. Draper 18 Mar 09 Added commentsCmd and various commands for * VO support. */ using namespace std; #include "TclCommand.h" #include "AstroCatalog.h" /* * This class declares the methods used to implement the Tcl astrocat * command for accessing astronomical catalogs. */ class TclAstroCat : public TclCommand { protected: AstroCatalog* cat_; // pointer to current open catalog WorldOrImageCoords pos1_, pos2_; // saved positions from last query char equinoxStr_[32]; // saved equinox option from last query FILE* feedback_; // file ptr for feedback during xfer, if set QueryResult* result_; // saved pointer to results of previous query // call a member function by name virtual int call(const char* name, int len, int argc, char* argv[]); // convert tcl list to QueryResult given column headings virtual int getQueryResult(int numCols, char** colNames, const char* list, const char* equinoxStr, QueryResult& r); // Save (or insert) query results to the given file. virtual int saveQueryResult(const char* filename, int numCols, char** colNames, char* info, int iflag, const char* equinoxStr = NULL); // Remove query results from the given file. virtual int removeQueryResult(const char* filename, int numCols, char** colNames, char* info, const char* equinoxStr = NULL); // append the given keyword/value pair to the list virtual void appendKeyVal(const char* keyword, const char* value); virtual int appendKeyListVal(const char* keyword, const char* value); virtual int appendListVal(const char* value); // convert tcl list cat entry to config file format virtual int tclListToConfigStreamValue(const char* tclList, ostream& os); virtual int tclListToConfigStreamLine(const char* tclList, ostream& os); virtual int tclListToConfigStream(const char* tclList, ostream& os); // Return the catalog directory entry for the given name or path CatalogInfoEntry* lookupCatalogDirectoryEntry(const char* dirList); public: // constructor TclAstroCat(Tcl_Interp*, const char* cmdname, const char* instname); ~TclAstroCat(); // entry point from Tcl static int astroCatCmd(ClientData, Tcl_Interp* interp, int argc, char* argv[]); // -- tcl subcommands -- virtual int authorizeCmd(int argc, char* argv[]); virtual int checkCmd(int argc, char* argv[]); virtual int checkrowCmd(int argc, char* argv[]); virtual int closeCmd(int argc, char* argv[]); virtual int copyrightCmd(int argc, char* argv[]); virtual int dec_colCmd(int argc, char* argv[]); virtual int entryCmd(int argc, char* argv[]); virtual int feedbackCmd(int argc, char* argv[]); virtual int getcolCmd(int argc, char* argv[]); virtual int getidposCmd(int argc, char* argv[]); virtual int getimageCmd(int argc, char* argv[]); virtual int getpreviewCmd(int argc, char* argv[]); virtual int hascolCmd(int argc, char* argv[]); virtual int headingsCmd(int argc, char* argv[]); virtual int helpCmd(int argc, char* argv[]); virtual int id_colCmd(int argc, char* argv[]); virtual int infoCmd(int argc, char* argv[]); virtual int is_tcsCmd(int argc, char* argv[]); virtual int ispixCmd(int argc, char* argv[]); virtual int iswcsCmd(int argc, char* argv[]); virtual int loadCmd(int argc, char* argv[]); virtual int longnameCmd(int argc, char* argv[]); virtual int moreCmd(int argc, char* argv[]); virtual int openCmd(int argc, char* argv[]); virtual int plotCmd(int argc, char* argv[]); virtual int queryCmd(int argc, char* argv[]); virtual int queryposCmd(int argc, char* argv[]); virtual int ra_colCmd(int argc, char* argv[]); virtual int reloadCmd(int argc, char* argv[]); virtual int removeCmd(int argc, char* argv[]); virtual int rootCmd(int argc, char* argv[]); virtual int saveCmd(int argc, char* argv[]); virtual int searchcolsCmd(int argc, char* argv[]); virtual int servtypeCmd(int argc, char* argv[]); virtual int shortnameCmd(int argc, char* argv[]); virtual int showcolsCmd(int argc, char* argv[]); virtual int sortcolsCmd(int argc, char* argv[]); virtual int sortorderCmd(int argc, char* argv[]); virtual int stc_colCmd(int argc, char* argv[]); virtual int symbolCmd(int argc, char* argv[]); virtual int urlCmd(int argc, char* argv[]); virtual int x_colCmd(int argc, char* argv[]); virtual int y_colCmd(int argc, char* argv[]); // PWD: extras. virtual int systemCmd(int argc, char* argv[]); virtual int epochCmd(int argc, char* argv[]); virtual int equinoxCmd(int argc, char* argv[]); virtual int equinoxPrefixCmd(int argc, char* argv[]); virtual int unitCmd(int argc, char* argv[]); virtual int ucdCmd(int argc, char* argv[]); virtual int utypeCmd(int argc, char* argv[]); virtual int datatypeCmd(int argc, char* argv[]); virtual int commentsCmd(int argc, char* argv[]); }; #endif /* _TclAstroCat_h_ */ skycat-3.1.2-starlink-1b/cat/generic/TclAstroImage.C000066400000000000000000000274311215713201500221310ustar00rootroot00000000000000 /* * E.S.O. - VLT project/Archive * $Id: TclAstroImage.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * StarCat.C - method definitions for class TclAstroImage * * ------------------------------------------------------------------ * NOTE: This class is obsolete, please use the TclAstroCat class * instead. * ------------------------------------------------------------------ * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 95 Created */ static const char* const rcsId="@(#) $Id: TclAstroImage.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; using namespace std; #include #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "TclAstroCat.h" #include "TclAstroImage.h" /* * declare a table of tcl subcommands * format: name, min_args, max_args, method */ static class TclAstroImageSubCmds { public: char* name; // method name int (TclAstroImage::*fptr)(int argc, char* argv[]); int min_args; // minimum number of args int max_args; // maximum number of args } subcmds_[] = { {(char *)"authorize", &TclAstroImage::authorizeCmd, 0, 4}, {(char *)"open", &TclAstroImage::openCmd, 1, 1}, {(char *)"close", &TclAstroImage::closeCmd, 0, 0}, {(char *)"getimage", &TclAstroImage::getimageCmd, 6, 99}, {(char *)"info", &TclAstroImage::infoCmd, 1, 1}, {(char *)"centerpos", &TclAstroImage::centerposCmd, 0, 0}, {(char *)"copyright", &TclAstroImage::copyrightCmd, 0, 0}, {(char *)"help", &TclAstroImage::helpCmd, 0, 0}, {(char *)"iswcs", &TclAstroImage::iswcsCmd, 0, 0}, {(char *)"ispix", &TclAstroImage::ispixCmd, 0, 0}, {(char *)"feedback", &TclAstroImage::feedbackCmd, 1, 1}, {(char *)"longname", &TclAstroImage::longnameCmd, 1, 1}, {(char *)"shortname", &TclAstroImage::shortnameCmd, 1, 1} }; /* * Call the given method in this class with the given arguments */ int TclAstroImage::call(const char* name, int len, int argc, char* argv[]) { for(unsigned int i = 0; i < sizeof(subcmds_)/sizeof(*subcmds_); i++) { TclAstroImageSubCmds* t = &subcmds_[i]; if (strncmp(t->name, name, len) == 0) { if (check_args(name, argc, t->min_args, t->max_args) != TCL_OK) return TCL_ERROR; return (this->*t->fptr)(argc, argv); } } return TclCommand::call(name, len, argc, argv); } /* * A call to this function can be made from the tkAppInit file at startup * to install the starcat command */ extern "C" int TclAstroImage_Init(Tcl_Interp* interp) { Tcl_CreateCommand(interp, "astroimage", (Tcl_CmdProc*)TclAstroImage::astroImageCmd, NULL, NULL); return TCL_OK; } /* * Implementation of the tcl extended command "astroimage" - * usage: see man page for more details */ int TclAstroImage::astroImageCmd(ClientData, Tcl_Interp* interp, int argc, char* argv[]) { if (argc != 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " instanceName catalogName\"", NULL); return TCL_ERROR; } TclAstroImage* cmd = new TclAstroImage(interp, argv[0], argv[1]); return cmd->status(); } /* * Constructor - * * Create an "astroimage" object in tcl for accessing the contents of star * catalogs. * * Note that the tcl command for this object is created in the * parent class constructor. */ TclAstroImage::TclAstroImage(Tcl_Interp* interp, const char* cmdname, const char* instname) : TclCommand(interp, cmdname, instname), im_(NULL), equinox_(2000.0), feedback_(NULL) { } /* * destructor */ TclAstroImage::~TclAstroImage() { if (im_) delete im_; } /* * Open the given astromonical catalog and refer to it in future * queries. */ int TclAstroImage::openCmd(int argc, char* argv[]) { if (im_) delete im_; im_ = AstroImage::open(argv[0]); if (!im_) return TCL_ERROR; // set up feedback, if requested if (feedback_) im_->feedback(feedback_); return TCL_OK; } /* * close the current catalog, if one was open */ int TclAstroImage::closeCmd(int argc, char* argv[]) { if (im_) delete im_; im_ = NULL; return TCL_OK; } /* * Request an image from the current image catalog and return (in Tcl) * the name of the FITS file holding the image. * * usage: $cat getimage ?-equinox equinox? -pos $pos -width $width \ * -height $height -tmpfile $file * * -pos - should be in the WCS format: H:M:S[+-]D:M:S * -equinox - equinox for position (default 2000) * * -tmpfile - can be used to specify the pathname of the image file * * -nameserver - name of nameserver catalog to use (simbad@eso, ned@eso,...) * * -name - can be used instead of -pos. The name will be resolved * using the value of -nameserver (default: SIMBAD) * * -width - dimensions of image to get * -height * */ int TclAstroImage::getimageCmd(int argc, char* argv[]) { if (!im_) return error("no catalog is currently open"); // option variables double width = 0.0, height = 0.0; char* nameServer = (char *)"simbad@eso"; int got_pos = 0; // flag: true if we read the position arg equinox_ = 2000.0; pos_.setNull(); // parse options for (int i = 0; i < argc; i += 2) { char* option = argv[i]; char* value = argv[i+1]; if (strcmp(option, "-pos") == 0) { got_pos++; // get ra and dec char** values = NULL; int numValues = 0; if (Tcl_SplitList(interp_, value, &numValues, &values) != TCL_OK) return TCL_ERROR; if (numValues != 2) return error("for -pos: expected list with 2 items"); if (im_->isWcs()) pos_ = WorldCoords(values[0], values[1], equinox_); else if (im_->isPix()) pos_ = ImageCoords(values[0], values[1]); Tcl_Free((char *)values); if (pos_.status()) return TCL_ERROR; } else if (strcmp(option, "-equinox") == 0) { if (got_pos) return error("-equinox should precede the -pos argument"); while(*value && !isdigit(*value)) value++; // skip "J" in J 2000, or "B" in B 1950 if (Tcl_GetDouble(interp_, value, &equinox_) != TCL_OK) return error("bad value for equinox: ", Tcl_GetStringResult(interp_)); } else if (strcmp(option, "-width") == 0) { if (Tcl_GetDouble(interp_, value, &width) != TCL_OK) return error("bad value for width: ", Tcl_GetStringResult(interp_)); } else if (strcmp(option, "-height") == 0) { if (Tcl_GetDouble(interp_, value, &height) != TCL_OK) return error("bad value for height: ", Tcl_GetStringResult(interp_)); } else if (strcmp(option, "-nameserver") == 0) { nameServer = value; } else if (strcmp(option, "-name") == 0) { if (AstroCatalog::nameToWorldCoords(value, pos_, nameServer, feedback_) != 0) return TCL_ERROR; } else if (strcmp(option, "-tmpfile") == 0) { if (value) { unlink(im_->tmpfile()); im_->tmpfile(value); } } } if (pos_.isNull() || width == 0.0 || height == 0.0) return error("must specify a name or position, width and height"); // send the query if (im_->getImage(pos_, width, height) != 0) return TCL_ERROR; return set_result(im_->tmpfile()); } /* * querypos subcommand: * * Return the world coordinate position arguments from the most recent * request, posibly expanded by SIMBAD. The result is a list of the form * {ra dec} */ int TclAstroImage::centerposCmd(int argc, char* argv[]) { ostringstream os; pos_.print(os, equinox_); // print coords in given equinox if (im_->isWcs()) os << " " << equinox_; return set_result(os.str().c_str()); } /* * copyright subcommand: return the copyright info for this image server * from the config file. */ int TclAstroImage::copyrightCmd(int argc, char* argv[]) { if (im_) { return set_result(im_->copyright()); } return TCL_OK; } /* * help subcommand: return the help info for this image server * from the config file. */ int TclAstroImage::helpCmd(int argc, char* argv[]) { if (im_) { return set_result(im_->help()); } return TCL_OK; } /* * feedback subcommand: * * specifies a Tcl file descriptor to use to write feedback info during * HTTP transfer of image. 1 Arg: file descriptor. */ int TclAstroImage::feedbackCmd(int argc, char* argv[]) { if (strlen(argv[0]) != 0) { if (Tcl_GetOpenFile(interp_, argv[0], 1, 1, (ClientData*)&feedback_) != TCL_OK) return TCL_ERROR; } else { feedback_ = NULL; } if (im_) im_->feedback(feedback_); return TCL_OK; } /* * "info" subcommand: * * usage: $im info $serv_type * * This command returns a list of servers from the config file * (skycat.cfg). The "serv_type" argument determines which catalogs * are listed (one of: catalog, namesvr, imagesvr). */ int TclAstroImage::infoCmd(int argc, char* argv[]) { const CatalogInfoEntry* e = CatalogInfo::first(); if (!e) return TCL_ERROR; Tcl_ResetResult(interp_); // get the serv_type for (; e != NULL; e = e->next()) { if (strncmp(argv[0], e->servType(), strlen(e->servType())) == 0) { Tcl_AppendElement(interp_, (char*)e->longName()); } } return TCL_OK; } /* * longname subcommand: return the long_name field from the catalog config file */ int TclAstroImage::longnameCmd(int argc, char* argv[]) { const CatalogInfoEntry* e = CatalogInfo::lookup(argv[0]); if (e) return set_result(e->longName()); return TCL_OK; } /* * shortname subcommand: return the short_name field from the catalog config file */ int TclAstroImage::shortnameCmd(int argc, char* argv[]) { const CatalogInfoEntry* e = CatalogInfo::lookup(argv[0]); if (e) return set_result(e->shortName()); return TCL_OK; } /* * Tcl subcommand: "iswcs" returns true if the catalog is based on world * coordinates */ int TclAstroImage::iswcsCmd(int argc, char* argv[]) { if (!im_) return error("no catalog is open"); return set_result(im_->isWcs()); } /* * Tcl subcommand: "ispix" returns true if the catalog is based on image * coordinates */ int TclAstroImage::ispixCmd(int argc, char* argv[]) { if (!im_) return error("no catalog is open"); return set_result(im_->isPix()); } /* * authorize subcommand: If the previous HTTP GET returned an * authorization error: (The HTML error text returned in Tcl contained * the string: "Authorization Required"), the application can * ask the user to enter a username and password to use to access the * URL and then retry the GET after using this subcommand to set the * authorization information to use. * * usage: * * $cat authorize * $cat authorize username passwd * * With no arguments, this command returns a list of the form * * {needpasswd realm server} * * where: * needpasswd is nonzero if a password is required for the URL * realm is the string taken from the HTTP header (Basic realm=...). * server is the name of the target server that wants the password. * * If arguments are specified, they should be the username and password. * These are saved and used again when the GET is retried, as well as for * all future GETS in this session, unless a new username and password * are given (as a result of an authorization error...). */ int TclAstroImage::authorizeCmd(int argc, char* argv[]) { if (!im_) return error("no image server is open"); if (argc == 0) { HTTP& http = im_->http(); ostringstream os; os << http.authorizationRequired() << " " << http.www_auth_realm() << " " << http.hostname(); return set_result(os.str().c_str()); } if (argc == 2) HTTP::authorize(argv[0], argv[1]); else if (argc == 4) HTTP::authorize(argv[0], argv[1], argv[2], argv[3]); else return error("expected: astroimage authorize ?username passwd realm server?"); return TCL_OK; } skycat-3.1.2-starlink-1b/cat/generic/TclAstroImage.h000066400000000000000000000043171215713201500221740ustar00rootroot00000000000000// -*-c++-*- #ifndef _TclAstroImage_h_ #define _TclAstroImage_h_ /* * E.S.O. - VLT project/ESO Archive * $Id: TclAstroImage.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * TclAstroImage.h - Tcl interface to the AstroImage C++ class for * accessing images from catalogs * * ------------------------------------------------------------------ * NOTE: This class is obsolete, please use the TclAstroCat class * instead. * ------------------------------------------------------------------ * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 95 Created */ #include #include "TclCommand.h" #include "AstroImage.h" /* * This class declares the methods used to implement the Tcl astroimage * command for retrieving images from catalogs. */ class TclAstroImage : public TclCommand { protected: AstroImage* im_; // pointer to current open catalog WorldOrImageCoords pos_; // saved position from last request double equinox_; // saved equinox from last request FILE* feedback_; // file ptr for feedback during xfer, if set // call a member function by name virtual int call(const char* name, int len, int argc, char* argv[]); public: // constructor TclAstroImage(Tcl_Interp*, const char* cmdname, const char* instname); ~TclAstroImage(); // entry point from Tcl static int astroImageCmd(ClientData, Tcl_Interp* interp, int argc, char* argv[]); // -- tcl subcommands -- virtual int authorizeCmd(int argc, char* argv[]); virtual int openCmd(int argc, char* argv[]); virtual int closeCmd(int argc, char* argv[]); virtual int getimageCmd(int argc, char* argv[]); virtual int centerposCmd(int argc, char* argv[]); virtual int infoCmd(int argc, char* argv[]); virtual int copyrightCmd(int argc, char* argv[]); virtual int helpCmd(int argc, char* argv[]); virtual int feedbackCmd(int argc, char* argv[]); virtual int longnameCmd(int argc, char* argv[]); virtual int shortnameCmd(int argc, char* argv[]); virtual int iswcsCmd(int argc, char* argv[]); virtual int ispixCmd(int argc, char* argv[]); }; #endif /* _TclAstroImage_h_ */ skycat-3.1.2-starlink-1b/cat/generic/TclQueryUtil.C000066400000000000000000000254441215713201500220430ustar00rootroot00000000000000/* * E.S.O. - VLT project/Archive * $Id: TclQueryUtil.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * TclQueryUtil.C - utility routines used by TclAstroCat and TclTcsCat * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 14 Jun 96 Created */ static const char* const rcsId="@(#) $Id: TclQueryUtil.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; using namespace std; #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "tcl.h" #include "error.h" #include "AstroCatalog.h" /* * This utility routine generates an AstroQuery object, given the command * line arguments for a Tcl query command. In addition, the world coordinate * position and equinox arguments of the query are returned. * * This assumes a Tcl query command with the following syntax: * * $cat query -option value ... * * Most options correspond to the AstroQuery class members and methods: * * -id $id * catalog id of object, (as returned from a previous query). If this * is specified, -pos, -name, -mag and -radius should not be * specified and will be ignored. * * -pos {ra dec} * -pos {x y} * -pos {ra1 dec1 ra2 dec2} * -pos {x1 y1 x2 y2} * World {ra, dec} or image {x, y} coordinates of center position, or * list {ra1 dec1 ra2 dec2} or {x1 y1 x2 y2} of 2 points for an area. * World Coordinates are given as {H:M:S[+-]D:M:S} in the given * equinox. If the catalog config entry contains the keywords * "x_col" and "y_col", the coords are interpreted as image coords, * otherwise world coords. * * -equinox $equinox * equinox for position (default 2000). May also be a string of the form * "J2000", "B1950", "GALACTIC", "ECLIPTIC", to indicate the type of the * search coordinates. * * -width $w * -height $h * Dimensions of rectangle with pos at center (alternative to * specifying 2 positions) in arcmin for world coords or pixel for * image coords. * * -mag $mag * max or list {min max} magnitude of object * * -radius $r * max or list (min max} radius from position (in arcmin for world * coords or pixel for image coords). * * -nameserver $ns * name of nameserver catalog to use (simbad@eso, ned@eso,...) * * -name $name * can be used instead of -pos. The name will be resolved using the * value of -nameserver (default: SIMBAD) * * -columns {col1 col2 ...} * list of columns to return * * -searchcols {col1 col2 ...} * list of columns to search by. The -minvalues and -maxvalues options * supply the corresponding value ranges and must have the same lengths. * * -minvalues {v1 v2 ...} * -maxvalues {v1 v2 ...} * list of values corresponding to the columns specified with the -searchcols * option. The values may be numeric or string format, but the lists must have * the same lengths as the one specified by the -searchcols option. * * -sort {col1 col2 ...} * list of column names to sort by * * -sortorder increasing * -sortorder decreasing * Specify the sort order. * * -nrows $n * max number of rows to return. * * Each option has one value, however, for a range or area query, some * values can be a list, such as -radius "$rad1 $rad2" to give a radius * range or -pos "$pos1 $pos2" to give an area. * * If -columns is not specified, all columns are assumed. Otherwise, if * -columns is specified, the column names should be valid for the * catalog and the result will be a list of rows with those columns. * * Note that not all catalogs will support sorting by all fields. * * On return, the AstroQuery object is set so that it cat be passed to a * query routine. In addition the world coordinate position and * equinox args are set, if applicable. * * The feedback argument, if not null, should be a pointer to an open * file to which feedback information should be printed during the query. */ int genAstroQuery(Tcl_Interp* interp, int argc, char* argv[], AstroQuery& q, WorldOrImageCoords& pos1, WorldOrImageCoords& pos2, char* equinoxStr, FILE* feedback, CatalogInfoEntry* entry) { // set defaults int status = 0; pos1.setNull(); pos2.setNull(); int isWcs = entry->isWcs(); int isPix = entry->isPix(); strcpy(equinoxStr, "2000"); double radius1 = 0.0, radius2 = 0.0; double mag1 = 0.0, mag2 = 0.0; double width = 0.0, height = 0.0; char* id = (char *)""; char* nameServer = (char *)"simbad@eso"; // for sorting int numSortCols = 0; char** sortCols = NULL; char* sortOrder = (char *)"increasing"; int nrows = 0; // no default limit... // column selection int numCols = 0; char** colNames = NULL; // for searching by colName, minValue, maxValue int numSearchCols = 0; char** searchCols = NULL; char** minValues = NULL; char** maxValues = NULL; // misc int got_pos = 0; // flag: true if we read the position arg char** values = NULL; int numValues = 0; // parse options for (int i = 0; i < argc; i += 2) { char* option = argv[i]; char* value = argv[i+1]; // first handle options with only one value if (strcmp(option, "-id") == 0) { id = value; } else if (strcmp(option, "-nameserver") == 0) { nameServer = value; } else if (strcmp(option, "-sortorder") == 0) { sortOrder = value; if (strlen(value) == 0) sortOrder = (char *)"increasing"; else if (strcmp(sortOrder, "increasing") != 0 && strcmp(sortOrder, "decreasing") != 0) return error("expected -sortorder increasing (or decreasing), not: ", sortOrder); } else if (strcmp(option, "-name") == 0) { if (AstroCatalog::nameToWorldCoords(value, pos1, nameServer, feedback) != 0) return TCL_ERROR; } else if (strcmp(option, "-equinox") == 0) { if (got_pos) return error("-equinox should precede the -pos argument"); strcpy(equinoxStr, value); } else if (strcmp(option, "-nrows") == 0) { if (Tcl_GetInt(interp, value, &nrows) != TCL_OK) return error("bad value for max number of rows: ", Tcl_GetStringResult(interp));; } else if (strcmp(option, "-width") == 0) { if (Tcl_GetDouble(interp, value, &width) != TCL_OK) return error("bad -width value: ", Tcl_GetStringResult(interp)); } else if (strcmp(option, "-height") == 0) { if (Tcl_GetDouble(interp, value, &height) != TCL_OK) return error("bad -height value: ", Tcl_GetStringResult(interp)); } else { // handle options whic 2) { status = error("expected 1 or 2 values for -radius option"); break; } if (numValues == 2 && Tcl_GetDouble(interp, values[1], &radius2) != TCL_OK) { status = error("bad max radius value: ", Tcl_GetStringResult(interp)); break; } if (Tcl_GetDouble(interp, values[0], &radius1) != TCL_OK) { status = error("bad min radius value: ", Tcl_GetStringResult(interp)); break; } } else if (strcmp(option, "-mag") == 0) { if (numValues > 2) { status = error("expected 1 or 2 values for -mag"); break; } if (numValues == 2 && Tcl_GetDouble(interp, values[1], &mag2) != TCL_OK) { status = error("bad max magnitude value: ", Tcl_GetStringResult(interp)); break; } if (Tcl_GetDouble(interp, values[0], &mag1) != TCL_OK) { status = error("bad min magnitude value: ", Tcl_GetStringResult(interp)); break; } } else if (strcmp(option, "-columns") == 0) { numCols = numValues; colNames = values; values = NULL; // don't free } else if (strcmp(option, "-sort") == 0) { numSortCols = numValues; sortCols = values; values = NULL; // don't free } else if (strcmp(option, "-searchcols") == 0) { numSearchCols = numValues; searchCols = values; values = NULL; // don't free } else if (strcmp(option, "-minvalues") == 0) { if (numValues != numSearchCols) { status = error("number of items for -minvalues not the same as for -searchcols"); break; } minValues = values; values = NULL; // don't free } else if (strcmp(option, "-maxvalues") == 0) { if (numValues != numSearchCols) { status = error("number of items for -maxvalues not the same as for -searchcols"); break; } maxValues = values; values = NULL; // don't free } } } if (values) Tcl_Free((char *)values); if (status != TCL_OK) return TCL_ERROR; // setup the query object and return an error if the arguments are invalid // (args are checked by AstroQuery class) if (strlen(id) && q.id(id)) return TCL_ERROR; if (pos2.isNull()) { if (! pos1.isNull()) if (q.pos(pos1)) return TCL_ERROR; } else { if (q.pos(pos1, pos2)) return ERROR; } if (radius2) { if (q.radius(radius1, radius2)) return TCL_ERROR; } else if (radius1) { if (q.radius(radius1)) return TCL_ERROR; } if (mag2) { if (q.mag(mag1, mag2)) return TCL_ERROR; } else if (mag1) { if (q.mag(mag1)) return TCL_ERROR; } if (width && height) if (q.dim(width, height)) return TCL_ERROR; if (numCols && colNames) if (q.colNames(numCols, (char**)colNames, 1)) return TCL_ERROR; if (nrows && q.maxRows(nrows)) return TCL_ERROR; if (numSortCols && sortCols) { if (q.sort(numSortCols, (char**)sortCols, 1)) return TCL_ERROR; q.sortOrder(*sortOrder == 'i' ? 1 : -1); } if (numSearchCols && searchCols) { if (q.condition(numSearchCols, (char**)searchCols, (char**)minValues, (char**)maxValues, 1)) return TCL_ERROR; } return TCL_OK; } skycat-3.1.2-starlink-1b/cat/generic/TclQueryUtil.h000066400000000000000000000012651215713201500221030ustar00rootroot00000000000000// -*-c++-*- #ifndef _TclQueryUtil_h_ #define _TclQueryUtil_h_ /* * E.S.O. - VLT project/ESO Archive * $Id: TclQueryUtil.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * TclQueryUtil.h - utility routines for Tcl catalog commands * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 14 Jun 96 Created */ #include #include class AstroQuery; class WorldCoords; int genAstroQuery(Tcl_Interp* interp, int argc, char* argv[], AstroQuery& q, WorldOrImageCoords& pos1, WorldOrImageCoords& pos2, char* equinoxStr, FILE* feedback, CatalogInfoEntry* entry); #endif /* _TclQueryUtil_h_ */ skycat-3.1.2-starlink-1b/cat/generic/TclTcsCat.C000066400000000000000000000150331215713201500212520ustar00rootroot00000000000000/* * E.S.O. - VLT project/Archive * $Id: TclTcsCat.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * TclTcsCat.C - method definitions for class TclTcsCat * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 95 Created */ static const char* const rcsId="@(#) $Id: TclTcsCat.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; using namespace std; #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "TcsCatalog.h" #include "TcsLocalCatalog.h" #include "TclQueryUtil.h" #include "TclTcsCat.h" /* * A call to this function can be made from the tkAppInit file at startup * to install the tcscat command */ extern "C" int TclTcsCat_Init(Tcl_Interp* interp) { // install the tcscat command Tcl_CreateCommand(interp, "tcscat", (Tcl_CmdProc*)TclTcsCat::tcsCatCmd, NULL, NULL); return TCL_OK; } /* * Implementation of the tcl extended command "tcscat" - * usage: see man page for more details */ int TclTcsCat::tcsCatCmd(ClientData, Tcl_Interp* interp, int argc, char* argv[]) { if (argc != 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " instanceName\"", NULL); return TCL_ERROR; } TclTcsCat* cmd = new TclTcsCat(interp, argv[0], argv[1]); return cmd->status(); } /* * Constructor - * * Create a "tcscat" object in tcl for accessing the contents of TCS * catalogs. * * Note that the tcl command for this object is created in the * base class constructor. */ TclTcsCat::TclTcsCat(Tcl_Interp* interp, const char* cmdname, const char* instname) : TclAstroCat(interp, cmdname, instname) { } /* * desctructor */ TclTcsCat::~TclTcsCat() { } /* * Save the given query results with the given columns to the given * filename. If iflag is true, insert in the existing file, otherwise create * a new file. "equinox" specifies the equinox of the data (the first 3 columns * are assumed to be the object id, ra and dec). * (This method is redefined here to do the save in TCS catalog format) */ int TclTcsCat::saveQueryResult(const char* filename, int numCols, char** colNames, char* info, int iflag, const char* equinoxStr) { // create a QueryResult object from the headings and data and // save (or append) it to the file TcsQueryResult r; if (getQueryResult(numCols, colNames, info, equinoxStr, r) != TCL_OK) return TCL_ERROR; int id_col = 0; // catalog's id column index if (cat_) id_col = cat_->entry()->id_col(); return (iflag ? r.insert(filename, id_col) : r.save(filename)); } /* * Remove the query results with the given columns and values from the given * filename. "equinox" specifies the equinox of the data (the first 3 columns * are assumed to be the object id, ra and dec). * (redefined here to use TCS catalog format) */ int TclTcsCat::removeQueryResult(const char* filename, int numCols, char** colNames, char* info, const char* equinoxStr) { // create a QueryResult object from the headings and data and // remove rows matching it from the file TcsQueryResult r; // if (cat_) // r.entry(cat_->entry()); if (getQueryResult(numCols, colNames, info, equinoxStr, r) != TCL_OK) return TCL_ERROR; return r.remove(filename, 0); } /* * Open the given astromonical catalog and refer to it in future * queries. */ int TclTcsCat::openCmd(int argc, char* argv[]) { if (cat_) delete cat_; cat_ = TcsCatalog::open(argv[0]); if (!cat_) return TCL_ERROR; // set up feedback, if requested if (feedback_) cat_->feedback(feedback_); return TCL_OK; } /* * Check that the given filename is a valid local TCS catalog * (tab table format with standard TCS columns). */ int TclTcsCat::checkCmd(int argc, char* argv[]) { return TcsLocalCatalog::check_table(argv[0]); } /* * pass a query to the current catalog and return the result as a list of * rows. * * usage: $cat query -option value ... * * Most options correspond to the AstroQuery class members and methods: * * -id - catalog id of object, (as returned from a previous * query). If this is specified, -pos, -name, -mag and * -radius should not be specified and will be ignored. * * -pos - World coordinates pos of center {ra dec}, or list * {ra1 dec1 ra2 dec2} of 2 points for an area. * Position is given as {H:M:S[+-]D:M:S} in J2000 * * -width - dimensions of rectangle with pos at center (alternative * -height to specifying 2 positions) in arcmin * * -equinox - equinox for position (default 2000) * * -mag - max or list {min max} magnitude of object * * -radius - max or list (min max} radius from position * * -nameserver - name of nameserver catalog to use (simbad@eso, ned@eso,...) * * -name - can be used instead of -pos. The name will be resolved * using the value of -nameserver (default: SIMBAD) * * -sort {name if column to sort by} * * -nrows {max number of rows to return} * * Each option has one value, however, for a range or area query, some * values can be a list, such as -radius "$rad1 $rad2" to give a radius * range or -pos "$pos1 $pos2" to give an area. * * Note that not all catalogs will support sorting by all fields. */ int TclTcsCat::queryCmd(int argc, char* argv[]) { if (!cat_) return error("no catalog is currently open"); // generate the query from the command args AstroQuery q; if (genAstroQuery(interp_, argc, argv, q, pos1_, pos2_, equinoxStr_, feedback_, cat_->entry()) != TCL_OK) return TCL_ERROR; // XXX make error msg if -columns was specified ? // make new QueryResult object, or reuse previous one if (result_) result_->clear(); else result_ = new TcsQueryResult; int nrows = cat_->query(q, NULL, *result_); // format results as a tcl list of rows char* s; int i = 0, j = 0; int errs = 0; WorldCoords pos; char buf[1024]; if (nrows > 0) { for (i = 0; i < nrows; i++) { TcsCatalogObject obj; if (((TcsQueryResult*)result_)->getObj(i, obj) != 0) break; obj.print(buf, sizeof(buf)); Tcl_AppendElement(interp_, buf) ; } // see if an error occured in the above loop (causing a break) if (i != nrows) return TCL_ERROR; } if (nrows < 0) return TCL_ERROR; // an query error occured (and was reported) return TCL_OK; } skycat-3.1.2-starlink-1b/cat/generic/TclTcsCat.h000066400000000000000000000027141215713201500213210ustar00rootroot00000000000000// -*-c++-*- #ifndef _TclTcsCat_h_ #define _TclTcsCat_h_ /* * E.S.O. - VLT project/ESO Archive * $Id: TclTcsCat.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * TclTcsCat.h - Tcl interface to the TcsCatalog C++ class for * accessing TCS catalogs * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 14 Jun 96 Created */ #include "TclAstroCat.h" #include "TcsCatalog.h" /* * This class declares the methods used to implement the Tcl tcscat * command for accessing TCS catalogs. */ class TclTcsCat : public virtual TclAstroCat { protected: // Save (or insert) query results to the given file. virtual int saveQueryResult(const char* filename, int numCols, char** colNames, char* info, int iflag, const char* equinoxStr); // Remove query results from the given file. virtual int removeQueryResult(const char* filename, int numCols, char** colNames, char* info, const char* equinoxStr); public: // constructor TclTcsCat(Tcl_Interp*, const char* cmdname, const char* instname); ~TclTcsCat(); // entry point from Tcl static int tcsCatCmd(ClientData, Tcl_Interp* interp, int argc, char* argv[]); // -- redefined tcl subcommands -- int openCmd(int argc, char* argv[]); int checkCmd(int argc, char* argv[]); int queryCmd(int argc, char* argv[]); }; #endif /* _TclTcsCat_h_ */ skycat-3.1.2-starlink-1b/cat/generic/TcsCatalog.C000066400000000000000000000053231215713201500214530ustar00rootroot00000000000000/* * E.S.O. - VLT project/ESO Archive * $Id: TcsCatalog.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * TcsCatalog.C - method definitions for class TcsCatalog * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 13 Jun 96 Created */ static const char* const rcsId="@(#) $Id: TcsCatalog.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include #include #include #include #include "error.h" #include "TcsLocalCatalog.h" #include "TcsCatalog.h" /* * open the named catalog and return a pointer to a TcsCatalog * object for that catalog or NULL if errors occur */ TcsCatalog* TcsCatalog::open(const char* name) { // get the entry for this catalog type CatalogInfoEntry* e = CatalogInfo::lookup(name); if (!e) return NULL; // error - no config entry TcsCatalog* result = NULL; if (strcmp(e->servType(), "local") == 0) result = new TcsLocalCatalog(e); // derived class for local catalogs else result = new TcsCatalog(e); // class for (remote) catalogs if (result->status() != 0) { delete result; return NULL; // error making catalog } return result; // normal return } /* * Get the values for the specified columns for the object given by "id" * in the catalog and return 0 if all is OK. * * Args: * * id in - object id in catalog * obj out - catalog info for row, if found */ int TcsCatalog::getObject( const char* id, TcsCatalogObject& obj) { AstroQuery q; q.id(id); q.maxRows(1); TcsQueryResult result; int nrows = query(q, NULL, result); if (nrows < 0) return 1; // error return if (nrows == 0) { return error("object not found: ", id); // error, not found } int status = result.getObj(0, obj); return status; } /* * search for the star closest to the given position, with the magnitude in * the given range * * Args: * * numCols in - number of columns to get * colNames in - array of column names to read * pos in - center position in world coordinates * mag0 in - min magnitude * mag1 in - max magnitude * obj out - object containing data for row, if found */ int TcsCatalog::searchClosestStar( const WorldCoords& pos, double mag0, double mag1, TcsCatalogObject& obj) { AstroQuery q; q.pos(pos); q.mag(mag0, mag1); q.maxRows(1); TcsQueryResult result; int nrows = query(q, NULL, result); if (nrows < 0) return 1; // error return if (nrows == 0) { return error("no objects found"); } int status = result.getObj(0, obj); return 0; } skycat-3.1.2-starlink-1b/cat/generic/TcsCatalog.h000066400000000000000000000100041215713201500215100ustar00rootroot00000000000000// -*-c++-*- #ifndef _TcsCatalog_h_ #define _TcsCatalog_h_ /* * E.S.O. - VLT project/ESO Archive * $Id: TcsCatalog.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * TcsCatalog.h - class specialized for accessing GSC, PPM or similar catalogs * for use by the TCS (Telescope Control Software). * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 13 Jun 96 Created */ #include "AstroCatalog.h" #include "TcsQueryResult.h" /* * Class TcsCatalog * * This class is like class AstroCatalog, except that it assumes a * catalog has fixed columns, such as those that are found in the GSC or * PPM catalogs. This class restricts itself to these fixed columns and * ignores the rest. Each row of a TcsCatalog can be represented by a * TcsCatalogObject. Any missing column values are set to the appropriate * null value. */ class TcsCatalog : public AstroCatalog { private: public: // Note: these two methods are inherited. We just need to redefine them here to avoid // compiler warnings about hiding the parent versions. // Get the values for the specified columns for the object given by "id" // in the catalog and return 0 if all is OK virtual int getObject( const char* id, // in - object id in catalog int numCols, // in - number of columns to get char** colNames, // in - array of column names to read QueryResult& result) { // out - ref to object managing result return AstroCatalog::getObject(id, numCols, colNames, result); } // search for the star closest to the given position, with the magnitude in // the given range and return (via the last 2 args) the columns requested // by "colNames" virtual int searchClosestStar( int numCols, // in - number of columns to get char** colNames, // in - array of column names to read const WorldOrImageCoords& pos, // in - center position in world coordinates double mag0, // in - min magnitude double mag1, // in - max magnitude QueryResult& result) { // out - ref to object managing result return AstroCatalog::searchClosestStar(numCols, colNames, pos, mag0, mag1, result); } public: // constructor - create catalog class instance // note: public interface uses TcsCatalog::open(). // The argument represents the entry in the catalog config file for this catalog TcsCatalog(CatalogInfoEntry* e) : AstroCatalog(e) {} // destructor - close catalog and free any resources virtual ~TcsCatalog() {} // open the named catalog and return a pointer to a new // TcsCatalog object created for it or NULL if errors occur static TcsCatalog* open(const char* name); // return the number of columns in the catalog int numCols() {return TcsCatalogObject::numCols();} // return the column names char** colNames() {return TcsCatalogObject::colNames();} const char* colName(int col) {return TcsCatalogObject::colName(col);} // return the column index for the given column name int colIndex(const char* colName) {return TcsCatalogObject::colIndex(colName);} // return true if the catalog contains the given column int hasCol(const char* name) {return (colIndex(name) >= 0);} // -- the interface for the next 2 methods is different for TCS -- // Get the object given by "id" in the catalog and return 0 if all is OK virtual int getObject( const char* id, // in - object id in catalog TcsCatalogObject& obj); // out - object for row, if found // search for the star closest to the given position, with the magnitude in // the given range virtual int searchClosestStar( const WorldCoords& pos, // in - center position in world coordinates double mag0, // in - min magnitude double mag1, // in - max magnitude TcsCatalogObject& obj); // out - object for row, if found }; #endif /* _TcsCatalog_h_ */ skycat-3.1.2-starlink-1b/cat/generic/TcsCatalogObject.C000066400000000000000000000260531215713201500226050ustar00rootroot00000000000000/* * E.S.O. - VLT project/ESO Archive * $Id: TcsCatalogObject.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * TcsCatalogObject.C - method definitions for class TcsCatalogObject * * See the man page for a complete description. * * who when whuat * -------------- -------- ---------------------------------------- * Allan Brighton 13 Jun 96 Created * pbiereic 20/10/03 method printTableRow (VLTSW20030366, cmagagna) */ static const char* const rcsId="@(#) $Id: TcsCatalogObject.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; using namespace std; #include #include #include #include #include #include "error.h" #include "WorldCoords.h" #include "TcsCatalogObject.h" // static array of column names static char* colNames_[] = { (char *)"id", (char *)"ra", (char *)"dec", (char *)"cooSystem", (char *)"epoch", (char *)"pma", (char *)"pmd", (char *)"radvel", (char *)"parallax", (char *)"cooType", (char *)"band", (char *)"mag", (char *)"more", (char *)"preview", (char *)"distance", (char *)"pa" }; // constants for column names enum { ID, RA, DEC, COOSYSTEM, EPOCH, PMA, PMD, RADVEL, PARALLAX, COOTYPE, BAND, MAG, MORE, PREVIEW, DISTANCE, PA }; // number of columns static const int numCols_ = sizeof(colNames_)/sizeof(char*); // -- local utils -- // return an allocated copy of the string, or NULL if it is NULL static inline char* copy(const char* s) {return s ? strdup(s) : (char*)NULL;} /* * check that the given value is in the given range and return 0 * if it is, otherwise generate an error */ static int check(const char* name, double v, double low, double hi) { return (v >= low && v <= hi) ? 0 : error(name, ": column value out of range"); } /* * check that the given string value has one of the specified values */ static int check(const char* name, const char* v, const char* a, const char* b) { return (strcmp(v, a) == 0 || strcmp(v, b) == 0) ? 0 : error(name, ": invalid column value"); } /* * constructor: initialize all fields to default values or null */ TcsCatalogObject::TcsCatalogObject() : ra_(TCS_CATALOG_NULL_DOUBLE), dec_(TCS_CATALOG_NULL_DOUBLE), epoch_(2000.), pma_(TCS_CATALOG_NULL_DOUBLE), pmd_(TCS_CATALOG_NULL_DOUBLE), radvel_(TCS_CATALOG_NULL_DOUBLE), parallax_(TCS_CATALOG_NULL_DOUBLE), mag_(TCS_CATALOG_NULL_DOUBLE), more_(NULL), preview_(NULL), distance_(TCS_CATALOG_NULL_DOUBLE), pa_(TCS_CATALOG_NULL_DOUBLE) { id_[0] = '\0'; strcpy(cooSystem_, "J2000"); strcpy(cooType_, "M"); strcpy(band_, "V"); } /* * copy constructor */ TcsCatalogObject::TcsCatalogObject(const TcsCatalogObject& t) : ra_(t.ra_), dec_(t.dec_), epoch_(t.epoch_), pma_(t.pma_), pmd_(t.pmd_), radvel_(t.radvel_), parallax_(t.parallax_), mag_(t.mag_), more_(copy(t.more_)), preview_(copy(t.preview_)), distance_(t.distance_), pa_(t.pa_) { strcpy(id_, t.id_); strcpy(cooSystem_, t.cooSystem_); strcpy(cooType_, t.cooType_); strcpy(band_, t.band_); } /* * result all fields to default values */ void TcsCatalogObject::reset() { *this = TcsCatalogObject(); } /* * assignment operator */ TcsCatalogObject& TcsCatalogObject::operator=(const TcsCatalogObject& t) { if (more_) free(more_); if (preview_) free(preview_); strcpy(id_, t.id_); ra_ = t.ra_; dec_ = t.dec_; strcpy(cooSystem_, t.cooSystem_); epoch_ = t.epoch_; pma_ = t.pma_; pmd_ = t.pmd_; radvel_ = t.radvel_; parallax_ = t.parallax_; strcpy(cooType_, t.cooType_); strcpy(band_, t.band_); mag_ = t.mag_; more_ = copy(t.more_); preview_ = copy(t.preview_); distance_ = t.distance_; pa_ = t.pa_; return *this; } /* * destructor */ TcsCatalogObject::~TcsCatalogObject() { if (more_) free(more_); if (preview_) free(preview_); } /* * output operator (Tcl list format) */ ostream& operator<<(ostream& os, const TcsCatalogObject& t) { os << '{' << t.id_ << '}'; if (t.ra_ != TCS_CATALOG_NULL_DOUBLE && t.dec_ != TCS_CATALOG_NULL_DOUBLE) { // convert to h:m:s before printing WorldCoords pos(t.ra_, t.dec_); os << ' ' << pos.ra() << ' ' << pos.dec(); } else { os << " {} {}"; } os << " {" << t.cooSystem_ << "}"; os << ' ' << t.epoch_; if (t.pma_ != TCS_CATALOG_NULL_DOUBLE) os << ' ' << t.pma_; else os << " {}"; if (t.pmd_ != TCS_CATALOG_NULL_DOUBLE) os << ' ' << t.pmd_; else os << " {}"; if (t.radvel_ != TCS_CATALOG_NULL_DOUBLE) os << ' ' << t.radvel_; else os << " {}"; if (t.parallax_ != TCS_CATALOG_NULL_DOUBLE) os << ' ' << t.parallax_; else os << " {}"; os << " {" << t.cooType_ << "}"; os << " {" << t.band_ << "}"; if (t.mag_ != TCS_CATALOG_NULL_DOUBLE) os << ' ' << t.mag_; else os << " {}"; os << " {" << (t.more_ ? t.more_ : "") << "}"; os << " {" << (t.preview_ ? t.preview_ : "") << "}"; if (t.distance_ != TCS_CATALOG_NULL_DOUBLE) os << ' ' << t.distance_; else os << " {}"; if (t.pa_ != TCS_CATALOG_NULL_DOUBLE) os << ' ' << t.pa_; else os << " {}"; return os; } /* * print this object as a tab separated row */ int TcsCatalogObject::printTableRow(ostream& os) { char t = '\t'; os << ( id() ? id() : "" ) << t << ra() << t << dec() << t << ( cooSystem() ? cooSystem() : "" ) << t << epoch() << t << pma() << t << pmd() << t << radvel() << t << parallax() << t << ( cooType() ? cooType() : "" ) << t << ( band() ? band() : "" ) << t << mag() << t << ( more() ? more() : "" ) << t << ( preview() ? preview() : "" ) << t << distance() << t << pa() << endl; return 0; } /* * print this object to the given buffer */ void TcsCatalogObject::print(char* buf, int bufsize) { ostringstream os; os << *this; strncpy(buf, os.str().c_str(), bufsize); } /* * print the headings to the given ostream * to match the output of the above output operator (<<). */ void TcsCatalogObject::printHeadings(ostream& os) { for (int i = 0; i < numCols_; i++) { os << colNames_[i]; if (i < (numCols_-1)) os << ' '; } } /* * print the headings to the given buffer, separated by tabs * to match the output of the above output operator (<<). */ void TcsCatalogObject::printHeadings(char* buf, int bufsize) { ostringstream os; printHeadings(os); strncpy(buf, os.str().c_str(), bufsize); } /* * set fields, with range checking, return 0 if OK */ int TcsCatalogObject::id(const char* v) { if (!v) { id_[0] = '\0'; return error("null string specified for object id"); } strncpy(id_, v, sizeof(id_)-1); return 0; } int TcsCatalogObject::ra(double v) { ra_ = v; return check("ra", v, 0., 360.); } int TcsCatalogObject::dec(double v) { dec_ = v; return check("dec", v, -90., 90.); } int TcsCatalogObject::cooSystem(const char* v) { strncpy(cooSystem_, (v ? v : ""), sizeof(cooSystem_)-1); return check("cooSystem", v, "B1950", "J2000"); } int TcsCatalogObject::epoch(double v) { epoch_ = v; return check("epoch", v, -2000., 3000.); } int TcsCatalogObject::pma(double v) { pma_ = v; return check("pma", v, -10., 10.); } int TcsCatalogObject::pmd(double v) { pmd_ = v; return check("pmd", v, -10., 10.); } int TcsCatalogObject::radvel(double v) { radvel_ = v; return check("radvel", v, -200000., 200000.); } int TcsCatalogObject::parallax(double v) { parallax_ = v; return check("parallax", v, -10000., 10000.); } int TcsCatalogObject::cooType(const char* v) { strncpy(cooType_, (v ? v : ""), sizeof(cooType_)-1); return check("cooType", v, "M", "A"); } int TcsCatalogObject::band(const char* v) { strncpy(band_, (v ? v : ""), sizeof(band_)-1); return 0; } int TcsCatalogObject::mag(double v) { mag_ = v; return 0; } int TcsCatalogObject::more(const char* v) { if (more_) free(more_); more_ = copy(v); return 0; } int TcsCatalogObject::preview(const char* v) { if (preview_) free(preview_); preview_ = copy(v); return 0; } int TcsCatalogObject::distance(double v) { distance_ = v; return 0; } int TcsCatalogObject::pa(double v) { pa_ = v; return 0; } // -- for compat with AstroCatalog: -- /* * return the number of columns in the catalog */ int TcsCatalogObject::numCols() { return numCols_; } /* * return a ptr to an array of catalog column names */ char** TcsCatalogObject::colNames() { return colNames_; } /* * return the name of the given column */ const char* TcsCatalogObject::colName(int col) { if (col >= 0 && col < numCols_) return colNames_[col]; error("invalid column index"); return NULL; } /* * return the column index for the given column name */ int TcsCatalogObject::colIndex(const char* colName) { for (int i = 0; i < numCols_; i++) { if (strcmp(colName, colNames_[i]) == 0) return i; } return -1; } /* * Compare the given column (member) of this object with the given object. * The column index corresponds to the column heading array at the top of this * file (it is more efficient to use the index than the col name...). * Return <. = or > 0, as by strcmp. */ int TcsCatalogObject::compare(const TcsCatalogObject& obj, int colIndex) { double d1 = 0., d2 = 0.; const char* s1 = "", *s2 = ""; int numeric = 1; switch(colIndex) { case ID: s1 = id_; s2 = obj.id_; numeric--; break; case RA: d1 = ra_; d2 = obj.ra_; break; case DEC: d1 = dec_; d2 = obj.dec_; break; case COOSYSTEM: s1 = cooSystem_; s2 = obj.cooSystem_; numeric--; break; case EPOCH: d1 = epoch_; d2 = obj.epoch_; break; case PMA: d1 = pma_; d2 = obj.pma_; break; case PMD: d1 = pmd_; d2 = obj.pmd_; break; case RADVEL: d1 = radvel_; d2 = obj.radvel_; break; case PARALLAX: d1 = parallax_; d2 = obj.parallax_; break; case COOTYPE: s1 = cooType_; s2 = obj.cooType_; numeric--; break; case BAND: s1 = band_; s2 = obj.band_; numeric--; break; case MAG: d1 = mag_; d2 = obj.mag_; break; case MORE: s1 = more_; s2 = obj.more_; numeric--; break; case PREVIEW: s1 = preview_; s2 = obj.preview_; numeric--; break; case DISTANCE: d1 = distance_; d2 = obj.distance_; break; case PA: d1 = pa_; d2 = obj.pa_; break; default: return error("invalid TCS column index"); } if (numeric) { if (d1 > d2) return 1; if (d1 < d2) return -1; return 0; } else { return strcmp((s1 ? s1 : ""), (s2 ? s2 : "")); } } /* * Compare the given column (member) of this object with the given object. * The column name corresponds to the column heading array at the top of this * file. * Return <. = or > 0, as by strcmp. */ int TcsCatalogObject::compare(const TcsCatalogObject& obj, char* colName) { int i = colIndex(colName); if (i >= 0) return compare(obj, i); return 0; } skycat-3.1.2-starlink-1b/cat/generic/TcsCatalogObject.h000066400000000000000000000112011215713201500226370ustar00rootroot00000000000000// -*-c++-*- #ifndef _TcsCatalogObject_h_ #define _TcsCatalogObject_h_ /* * E.S.O. - VLT project/ESO Archive * $Id: TcsCatalogObject.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * TcsCatalogObject.h - class representing one row of results from a * TcsCatalog query. * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 13 Jun 96 Created */ using namespace std; // NULL values //#define TCS_CATALOG_NULL_INT 4294967294 /* (2^32 - 1) */ #define TCS_CATALOG_NULL_DOUBLE 1.E-300 /* * This object represents the contents of one row of GSC/PPM results. * Missing values are set to the appropriate null value (see above). */ class TcsCatalogObject { private: char id_[64]; // object catalog id double ra_; // Alpha coordinate for the target in decimal degrees double dec_; // Delta coordinate for the target in decimal degrees char cooSystem_[8]; // Equinox system and equinox ("B1950" or "J2000") double epoch_; // Epoch expressed as decimal year double pma_; // Proper Motion Alpha in radians/year (-10.0 to 10.0) double pmd_; // Proper Motion Delta in radians/year (-10.0 to 10.0) double radvel_; // radial velocity in km/sec (-200000 to 200000) double parallax_; // Parallax in arcseconds (-10000 to 10000) char cooType_[4]; // Coordinate type as "M" for mean or "A" for apparent character char band_[4]; // Magnitude wavelength band ("V") double mag_; // Object's magnitude in given band char* more_; // An HTTP URL pointing to more info on the object char* preview_; // An HTTP URL pointing to an image of the object double distance_; // distance to center of the field double pa_; // position angle based on center of the field public: // constructor: initialize all fields to null TcsCatalogObject(); // copy constructor TcsCatalogObject(const TcsCatalogObject&); // destructor ~TcsCatalogObject(); // assignment TcsCatalogObject& operator=(const TcsCatalogObject &); // output operator friend ostream& operator<<(ostream&, const TcsCatalogObject&); // print this object to the given buffer void print(char* buf, int bufsize); // print the headings to match the output of '<<' above static void printHeadings(ostream& os); static void printHeadings(char* buf, int bufsize); // print this object as a tab separated row int printTableRow(ostream&); // result all fields to default values void reset(); // return true if the given value is null (by convention) //static int isNull(int v) {return (v == int(TCS_CATALOG_NULL_INT));} static int isNull(double v) {return (v == TCS_CATALOG_NULL_DOUBLE);} static int isNull(const char* v) {return (!v || !*v);} // set fields, with range checking, return 0 if OK int id(const char*); int ra(double); int dec(double); int cooSystem(const char*); int epoch(double); int pma(double); int pmd(double); int radvel(double); int parallax(double); int cooType(const char*); int band(const char*); int mag(double); int more(const char*); int preview(const char*); int distance(double); int pa(double); // member access: return member value const char* id() {return id_;} double ra() {return ra_;} double dec() {return dec_;} const char* cooSystem() {return cooSystem_;} double epoch() {return epoch_;} double pma() {return pma_;} double pmd() {return pmd_;} double radvel() {return radvel_;} double parallax() {return parallax_;} const char* cooType() {return cooType_;} const char* band() {return band_;} double mag() {return mag_;} const char* more() {return more_ ? more_ : "";} const char* preview() {return preview_ ? preview_ : "";} double distance() {return distance_;} double pa() {return pa_;} // for compat. with AstroCatalog // return the number of columns in the catalog static int numCols(); // return the column names static char** colNames(); static const char* colName(int col); // return the column index for the given column name static int colIndex(const char* colName); // return true if the catalog contains the given column static int hasCol(const char* name) {return (colIndex(name) >= 0);} // Compare the given column (member) of this object with the given object. int compare(const TcsCatalogObject& obj, int colIndex); int compare(const TcsCatalogObject& obj, char* colName); }; #endif /* _TcsCatalogObject_h_ */ skycat-3.1.2-starlink-1b/cat/generic/TcsLocalCatalog.C000066400000000000000000000070271215713201500224310ustar00rootroot00000000000000/* * E.S.O. - VLT project/ESO Archive * $Id: TcsLocalCatalog.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * TcsLocalCatalog.C - method definitions for class TcsLocalCatalog * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 21 Jun 96 Created */ static const char* const rcsId="@(#) $Id: TcsLocalCatalog.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; using namespace std; #include #include #include #include #include #include #include "error.h" #include "Mem.h" #include "TcsLocalCatalog.h" /* * static method to check the validity of a tab table file. * Returns 0 if OK. */ int TcsLocalCatalog::check_table(const char* file) { TabTable t; return TabTable::head(file, t); } /* * constructor - used internally only, public interface uses "open(name)" * "e" is the catalog config entry object for this catalog. * (see CatalogInfo class) * * In this case, the catalog config entry may have been created automatically. * The name of the file containing the local catalog (tab table) is stored in * "e->url()", which is normally used to store the URL for HTTP access, but is * used here for the filename. * */ TcsLocalCatalog::TcsLocalCatalog(CatalogInfoEntry* e) : TcsCatalog(e), filename_(strdup(e->url())) { status_ = getInfo(); } /* * destructor */ TcsLocalCatalog::~TcsLocalCatalog() { if (filename_) free(filename_); } /* * Run a query on the local TCS catalog and return the number of objects found. * * Args: * q - (in) object describing the query * * filename - (in) filename to hold results, or null * * result - (out) reference to object to manage the results. * * The return value is the number of rows found, or 0 if none were found. * A return value of -1 indicates an error. * * (Redefined from parent class to work with local catalogs) */ int TcsLocalCatalog::query(const AstroQuery& q, const char* filename, QueryResult& result) { if (checkInfo() != 0) return 1; // note the catalog config entry in the results result.entry(entry_); if (result.query(q, info_, filename, more_) != 0) return -1; return result.numRows(); } /* * If we don't have the info for this catalog, get it and * return the status. Here we also check if the file has been modified, * (by an insert or remove operation) and reload it if needed. */ int TcsLocalCatalog::checkInfo() { if (info_.numCols() > 0) { struct stat buf; if (stat(filename_, &buf) != 0) return sys_error("can't access file: ", filename_); if (buf.st_mtime == timestamp_) return 0; } return getInfo(); } /* * Read the local catalog to get the column names and also read in the * data to make later searches faster later. The return value is 0 for * success. The info_ member holds the column info and the local catalog * data for searching. It must be updated if the data changes. */ int TcsLocalCatalog::getInfo() { // note update time of file, so we know if it has been modified... struct stat buf; if (stat(filename_, &buf) != 0) return sys_error("can't access file: ", filename_); timestamp_ = buf.st_mtime; // mmap the file and put it in a TabTable Mem m(filename_); if (info_.init((char*)m.ptr()) != 0) return 1; // this will extract any catalog config info from the file's header info_.entry(entry_, (char*)m.ptr()); return 0; } skycat-3.1.2-starlink-1b/cat/generic/TcsLocalCatalog.h000066400000000000000000000033421215713201500224720ustar00rootroot00000000000000// -*-c++-*- #ifndef _TcsLocalCatalog_h_ #define _TcsLocalCatalog_h_ /* * E.S.O. - VLT project/ESO Archive * $Id: TcsLocalCatalog.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * TcsLocalCatalog.h - class definitions for accessing local * TCS catalogs stored as starbase format tab tables. * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 21 Jun 96 Created */ #include "TcsCatalog.h" /* * Class TcsLocalCatalog * * This class is like LocalCatalog, except that the table columns are fixed * to be a subset of the GSC/PPM columns. */ class TcsLocalCatalog : public TcsCatalog { private: char* filename_; // file name for local catalog time_t timestamp_; // last update time of file, for caching protected: public: // constructor - create local TCS catalog class instance // note: public interface uses TcsCatalog::open() with the name of the // file containing the local TCS catalog. // The argument represents the entry in the catalog config file for this catalog // (made automatially, if not already present). TcsLocalCatalog(CatalogInfoEntry* e); // destructor ~TcsLocalCatalog(); // Run a query on the catalog and return the number of objects found. // (redefined here to work with local catalogs) virtual int query(const AstroQuery& q, const char* filename, QueryResult& result); // check the validity of a tab table file static int check_table(const char* file); // query server for catalog column names and put result in info_ virtual int getInfo(); virtual int checkInfo(); }; #endif /* _TcsLocalCatalog_h_ */ skycat-3.1.2-starlink-1b/cat/generic/TcsQueryResult.C000066400000000000000000000257011215713201500224070ustar00rootroot00000000000000/* * E.S.O. - VLT project/ESO Archive * $Id: TcsQueryResult.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * TcsQueryResult.C - method definitions for class TcsQueryResult * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 13 Jun 96 Created */ static const char* const rcsId="@(#) $Id: TcsQueryResult.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; using namespace std; #include #include #include #include #include #include "error.h" #include "WorldCoords.h" #include "TcsQueryResult.h" /* * Fill the table from the given buffer in tab table format. * If maxRows is nonzero, only upto that many rows are taken from buf. * (redefined from parent class to add init of objects_ array) */ int TcsQueryResult::init(const char* buf, int maxRows, int owner) { if (TabTable::init(buf, maxRows, owner) != 0) return ERROR; return make_objects(); } /* * Initialize the table from the data buffer (without heading lines). * The first two args specify the number column headings and their names. * If maxRows is nonzero, only upto that many rows are taken from buf. * (redefined from parent class to add init of objects_ array) */ int TcsQueryResult::init(int numCols, char** colNames, const char* buf, int maxRows, int owner) { if (TabTable::init(numCols, colNames, buf, maxRows, owner) != 0) return ERROR; return make_objects(); } /* * make the table empty and free any resources used * (redefined from parent class to add cleanup of objects_ array) */ int TcsQueryResult::clear() { if (TabTable::clear() != 0) return ERROR; if (objects_ != NULL) { delete [] objects_; objects_ = NULL; } return 0; } /* * make the objects_ array to hold the data for the rows */ int TcsQueryResult::make_objects() { if (objects_ != NULL) { delete [] objects_; objects_ = NULL; } if (numRows_ <= 0) return 0; objects_ = new TcsCatalogObject[numRows_]; if (!objects_) return error("no enough memory"); for (int row = 0; row < numRows_; row++) { if (getObjFromTable(row, objects_[row]) != 0) { delete [] objects_; objects_ = NULL; return ERROR; } } return 0; } /* * get the value at the given row,column as a double * and allow missing columns to be set to the null value */ int TcsQueryResult::getDouble(int row, int col, double& value) { char* p; if (get(row, col, p) != 0) return 1; if (strlen(p) == 0) value = TCS_CATALOG_NULL_DOUBLE; else if (sscanf(p, "%lf", &value) != 1) return tab_error(row, col, (char *)"double", p); return 0; } /* * Access a TcsCatalog (GSC/PPM) result row and fill out the given TcsCatalogObject. * (For compat. with earlier version: it is more efficient to use getObj(int row)) */ int TcsQueryResult::getObj(int row, TcsCatalogObject& t) const { if (checkTableIndex(row) != 0) return ERROR; if (!objects_) return error("empty TCS result"); t = objects_[index_[row]]; return 0; } /* * Return a pointer to an object for the given row or NULL if there is * an error. The memory belongs to this class and should not deleted. */ TcsCatalogObject* TcsQueryResult::getObj(int row) const { if (checkTableIndex(row) != 0) return NULL; if (!objects_) { error("empty TCS result"); return NULL; } return &objects_[index_[row]]; } /* * Access a TcsCatalog (GSC/PPM) result row and fill out the given TcsCatalogObject. * Any missing fields are left at the default or null value. */ int TcsQueryResult::getObjFromTable(int row, TcsCatalogObject& t) { int i; char* s; double d; WorldCoords pos; // ra and dec t.reset(); if (!entry_->isWcs()) return error("catalog does not support World Coordinates"); // set the id, ra and dec if (get(row, id_col(), s) != 0 || t.id(s) != 0 || getPos(row, pos) != 0 || t.ra(pos.ra_deg()) != 0 || t.dec(pos.dec_deg()) != 0) return ERROR; // look for GSC or PPM (http catalog server) names and set the rest // epoch if ((i = inputColIndex("epoch")) >= 0) { if (getDouble(row, i, d) != 0 || t.epoch(d) != 0) return ERROR; } // pma if ((i = inputColIndex("pma")) >= 0) { if (getDouble(row, i, d) != 0 || t.pma(d) != 0) return ERROR; } // pmd if ((i = inputColIndex("pmd")) >= 0) { if (getDouble(row, i, d) != 0 || t.pmd(d) != 0) return ERROR; } // radvel if ((i = inputColIndex("radvel")) >= 0) { if (getDouble(row, i, d) != 0 || t.radvel(d) != 0) return ERROR; } // parallax if ((i = inputColIndex("parallax")) >= 0) { if (getDouble(row, i, d) != 0 || t.parallax(d) != 0) return ERROR; } // mag if ((i = inputColIndex("mag")) >= 0) { if (getDouble(row, i, d) != 0 || t.mag(d) != 0) return ERROR; } // more if ((i = inputColIndex("more")) >= 0) { if (get(row, i, s) != 0 || t.more(s) != 0) return ERROR; } // preview if ((i = inputColIndex("preview")) >= 0) { if (get(row, i, s) != 0 || t.preview(s) != 0) return ERROR; } // distance if ((i = inputColIndex("distance")) >= 0) { if (getDouble(row, i, d) != 0 || t.distance(d) != 0) return ERROR; } // pa if ((i = inputColIndex("pa")) >= 0) { if (getDouble(row, i, d) != 0 || t.pa(d) != 0) return ERROR; } // cooSystem if ((i = inputColIndex("cooSystem")) >= 0) { if (get(row, i, s) != 0 || t.cooSystem(s) != 0) return ERROR; } // cooType if ((i = inputColIndex("cooType")) >= 0) { if (get(row, i, s) != 0 || t.cooType(s) != 0) return ERROR; } // band if ((i = inputColIndex("band")) >= 0) { if (get(row, i, s) != 0 || t.band(s) != 0) return ERROR; } // calculate some missing values if needed (distance to center and pa) if (TcsCatalogObject::isNull(t.distance()) || TcsCatalogObject::isNull(t.pa())) { if (!centerPos_.isNull()) { if (t.distance(centerPos_.wc().dist(pos, d)) != 0 || t.pa(d) != 0) return ERROR; } } return 0; } /* * return column index in the original input for the given TCS column name * (might be different than the output index) */ int TcsQueryResult::inputColIndex(const char* colName) const { int i = -1; if ((i = TabTable::colIndex(colName)) >= 0) return i; // insert any name changes here if (strcmp(colName, "distance") == 0) return TabTable::colIndex("d'"); return -1; } /* * print the given table row to the given stream */ int TcsQueryResult::printRow(ostream& os, int row) const { // output the rows TcsCatalogObject* obj = getObj(row); if (obj == NULL) return ERROR; obj->printTableRow(os); return 0; } /* * print the table title (and any other info preceding the column headings) * (redefined here from parent class to add TCS column info in table header) */ void TcsQueryResult::printTableTop(ostream& os, const char* title) { if (! title) title = "TcsQueryResult"; QueryResult::printTableTop(os, title); // add TCS header // comment os << "\n" << "# This file contains catalog information in TCS tab table format\n" << "\n"; // TCS column info os << "# Column descriptions:\n" << "id_desc= Object ID\n" << "id_type= string # Object ID\n" << "\n" << "ra_desc= Alpha coordinate for the target in decimal degrees\n" << "ra_units= deg\n" << "ra_type= real\n" << "ra_range= 0.,360\n" << "\n" << "dec_desc= Delta coordinate for the target in decimal degrees\n" << "dec_unit= deg\n" << "dec_type= real\n" << "dec_range= 0.,360.\n" << "\n" << "cooSystem_desc= Equinox system and equinox (only 1950 or 2000 are accepted)\n" << "cooSystem_type= string\n" << "cooSystem_range= enum B1950, J2000\n" << "cooSystem_def_val= \"J2000\"\n" << "\n" << "epoch_desc= Epoch expressed as decimal year.\n" << "epoch_type= real\n" << "epoch_range= -2000.,3000.\n" << "epoch_def_val= 2000.\n" << "\n" << "pma_desc= Proper motion alpha in radians/year (-10.0 to 10.0)\n" << "pma_unit= arcsecs/year\n" << "pma_type= real\n" << "pma_range= -10.,10.\n" << "pma_def_val= 0.0\n" << "\n" << "pmd_desc= Proper motion delta in radians/year (-10.0 to 10.0) \n" << "pmd_unit= arcsecs/year\n" << "pmd_type= real\n" << "pmd_range= -10.,10.\n" << "pmd_def_val= 0.0\n" << "\n" << "radvel_desc= Radial velocity in km/sec (-200000 to 200000)\n" << "radvel_unit= km/sec\n" << "radvel_type= real\n" << "radvel_range= -200000.,200000.\n" << "radvel_def_val= 0.\n" << "\n" << "parallax_desc= Parallax in arcseconds (-10000 to 10000)\n" << "parallax_unit= arcseconds\n" << "parallax_type= real\n" << "parallax_range= -10000.0,10000.0\n" << "parallax_def_val= 0.0\n" << "\n" << "cooType_desc= Coordinate type as \"m\" for mean or \"a\" for apparent character\n" << "cooType_type= string\n" << "cooType_range= enum \"m\",\"a\"\n" << "cooType_def_val= \"m\"\n" << "\n" << "band_desc= Magnitude wavelength band\n" << "band_type= string\n" << "band_def_val= \"v\"\n" << "\n" << "mag_desc= Object's magnitude in given band\n" << "mag_unit= magnitude\n" << "mag_type= real\n" << "mag_def_val= 0.0\n" << "\n" << "more_desc= An HTTP URL pointing to more info on the object\n" << "more_unit= http url\n" << "more_type=string\n" << "more_def_val= \"\"\n" << "\n" << "preview_desc= An HTTP URL pointing to an image of the object\n" << "preview_unit= http url\n" << "preview_type= string\n" << "preview_def_val= \"\"\n" << "\n" << "distance_desc= Object distance to field center\n" << "distance_unit= arcmin\n" << "distance_type= real\n" << "\n" << "pa_desc= Object position angle to field center (east of north)\n" << "pa_unit= deg\n" << "pa_type= real\n" << "\n" << "# NULL values\n" << "string_null= \"\" # empty string\n" << "real_null= 1.e-300\n" << "int_null= 4294967294 # (2^32 - 1)\n" << "\n"; } /* * compare the given rows and return <. = or > 0, as by strcmp. * (redefined from parent class to allow compare of columns that * have been renamed or calculated (d', pa)) */ int TcsQueryResult::compareRows(int row1, int row2) { if (row1 < 0 || row1 >= numRows_ || row2 < 0 || row2 >= numRows_) return (sortStatus_ = error("sort row index out of range")); // don't use index_[row] here since we are sorting it int ret = 0; for (int i = 0; i < numSortCols_; i++) { if ((ret = objects_[row1].compare(objects_[row2], sortColIndexes_[i])) != 0) break; } return ret * sortOrder_; } skycat-3.1.2-starlink-1b/cat/generic/TcsQueryResult.h000066400000000000000000000103571215713201500224550ustar00rootroot00000000000000// -*-c++-*- #ifndef _TcsQueryResult_h_ #define _TcsQueryResult_h_ /* * E.S.O. - VLT project/ESO Archive * $Id: TcsQueryResult.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * TcsQueryResult.h - class definitions for accessing results of a * TCS catalog query * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 13 Jun 96 Created */ using namespace std; #include "QueryResult.h" #include "TcsCatalogObject.h" /* * Class TcsQueryResult * * This class manages the result of an TcsCatalog::query. Internally * a QueryResult object manages the "tab table" query results (this could * be changed later if performance is an issue). * * This class provides transparent access to the result based on a * row,column index and, unlike the QueryResult class, is specialized for * accessing the GSC and PPM catalogs. There are special methods to return * GSC and PPM fields in common units and to determine if a field is present * in the catalog. */ class TcsQueryResult : public QueryResult { private: // copy constructor (not defined) TcsQueryResult(TcsQueryResult&); protected: // array of objects created from the rows (better for sorting) TcsCatalogObject* objects_; // get the value at the given row,column as a double // and allow missing columns to be set to the null value virtual int getDouble(int row, int col, double& value); // return column index in the original input for the given TCS column name // (might be different than the output index) virtual int inputColIndex(const char* colName) const; // compare 2 rows (redefined from parent class to compare TCS objects) virtual int compareRows(int row1, int row2); // make array of Tcs objects virtual int make_objects(); // access a TcsCatalog (GSC/PPM) result row: fill out the given TcsCatalogObject virtual int getObjFromTable(int row, TcsCatalogObject&); // print table title and other info virtual void printTableTop(ostream& os, const char* title = NULL); public: // constructor: initialize empty table TcsQueryResult() : QueryResult(), objects_(NULL) {} // constructor: init from query result buffer TcsQueryResult(const char* result) : QueryResult(result), objects_(NULL) {} // destructor: free any allocated memory virtual ~TcsQueryResult() {} // make the table empty and free any resources used virtual int clear(); // fill the table from the given buffer in tab table format virtual int init(const char* buf, int maxRows = 0, int owner = 0); // fill the table from the given buffer in tab table format, with headings // specified separately virtual int init(int numCols, char** colNames, const char* buf, int maxRows = 0, int owner = 0); // access a TcsCatalog (GSC/PPM) result row: fill out the given TcsCatalogObject virtual int getObj(int row, TcsCatalogObject&) const; // Return a pointer to an object for the given row or NULL if there is // an error. The memory belongs to this class and should not deleted. TcsCatalogObject* getObj(int row) const; // print the given table row to the given stream virtual int printRow(ostream& os, int row) const; // -- redefine these to deal with TCS columns -- // get array of TCS column names, number of columns virtual char** colNames() const {return TcsCatalogObject::colNames();} virtual int numCols() const {return TcsCatalogObject::numCols();} // return the TCS column name for the given TCS column index virtual const char* colName(int col) const {return TcsCatalogObject::colName(col);} // return the TCS column index for the given TCS column name virtual int colIndex(const char* colName) const {return TcsCatalogObject::colIndex(colName);} // redefine these here from the base class, since the columns are fixed virtual int id_col() const {return 0;} virtual int ra_col() const {return 1;} virtual int dec_col() const {return 2;} virtual int x_col() const {return -1;} virtual int y_col() const {return -1;} }; #endif /* _TcsQueryResult_h_ */ skycat-3.1.2-starlink-1b/cat/generic/astro_catalog.C000066400000000000000000000326411215713201500222540ustar00rootroot00000000000000/* * E.S.O. - VLT project/ESO Archive * $Id: astro_catalog.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * astroCatalog.C - C interface implementation for C++ class AstroCatalog * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 13 Oct 95 Created */ static const char* const rcsId="@(#) $Id: astro_catalog.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; using namespace std; #include #include #include "error.h" // include the C++ and C interfaces #include "AstroCatalog.h" extern "C" { #include "astro_catalog.h" } /* * check that the given catalog handle is not null and return its * error status */ static int acCheckHandle(AcHandle handle) { if (handle) return ((AstroCatalog*)handle)->status(); return error("internal error: ", "bad catalog handle", EINVAL); } /* * check that the given query result handle is not null and return its * error status */ static int acCheckResult(AcResult handle) { if (handle) return ((QueryResult*)handle)->status(); return error("internal error: ", "bad query result handle", EINVAL); } /* * open the named catalog and return a handle for it or NULL if there * were errors */ AcHandle acOpen(char* name) { return (AcHandle)AstroCatalog::open(name); } /* close the catalog and free its resources */ void acClose(AcHandle handle) { if (handle) delete (AstroCatalog*)handle; } /* * return true if there would have been more than "maxRows" available * in the last query */ int acMore(AcHandle handle) { if (acCheckHandle(handle) != OK) return ERROR; return ((AstroCatalog*)handle)->more(); } /* return the number of colums in the catalog */ int acNumCols(AcHandle handle) { if (acCheckHandle(handle) != OK) return ERROR; return ((AstroCatalog*)handle)->numCols(); } /* return the name of the given column in the catalog */ char* acColName(AcHandle handle, int col) { if (acCheckHandle(handle) != OK) return NULL; return (char*)((AstroCatalog*)handle)->colName(col); } /* return a pointer to an array with the names of the columns in the catalog*/ char** acColNames(AcHandle handle) { if (acCheckHandle(handle) != OK) return NULL; return (char**)((AstroCatalog*)handle)->colNames(); } /* return the index for the given column name the catalog */ int acColIndex(AcHandle handle, char* name) { if (acCheckHandle(handle) != OK) return ERROR; return ((AstroCatalog*)handle)->colIndex(name); } /* * Get the number of columns, the column names and types ("char", "int", * "float") for the given catalog and return 0 if all is OK */ int acGetDescription( AcHandle handle, /* in - catalog handle*/ int* numCols, /* out - number of result columns */ char*** colNames) /* out - ptr to array of column names */ { if (acCheckHandle(handle) != OK) return ERROR; return ((AstroCatalog*)handle)->getDescription( *numCols, *colNames); // we don't enforce the const in C } /* * Get the values for the specified columns for the object given by "id" * in the named catalog and return 0 if all is OK */ int acGetObject( AcHandle handle, /* in - catalog handle */ char* id, /* in - object id in catalog */ int numCols, /* in - number of columns to get (size of colNames) */ char** colNames, /* in - null terminated array of column names to read */ AcResult* result) /* out - handle for accessing query results (see below) */ { if (acCheckHandle(handle) != OK) return ERROR; QueryResult* qr = new QueryResult; int status = ((AstroCatalog*)handle)->getObject( id, numCols, colNames, *qr); if (status == 0) *result = (AcResult)qr; return status; } /* * Get the values for all objects in the specified world coordinates area */ int acGetArea( AcHandle handle, /* in - catalog handle */ int numCols, /* in - number of columns to get (size of colNames) */ char** colNames, /* in - null terminated array of column names to read */ double ra0, /* in - coordinates of area */ double dec0, double ra1, double dec1, double mag0, /* in - min magnitude */ double mag1, /* in - max magnitude */ int maxRows, /* in - max number of rows to return */ char* filename, /* in - if not null, write results to this file */ int* numFound, /* out - number of objects found */ AcResult* result) /* out - handle for accessing query results (see below) */ { if (acCheckHandle(handle) != OK) return ERROR; QueryResult* qr = new QueryResult; int status = ((AstroCatalog*)handle)->getArea( numCols, colNames, WorldCoords(ra0, dec0), WorldCoords(ra1, dec1), mag0, mag1, maxRows, filename, *numFound, *qr); if (status == 0) *result = (AcResult)qr; return status; } /* * pass a request to the image server and return the name of a FITS file * containing the resulting image, or NULL if not found * * Args: * * handle - handle returned from ac_open() * * ra, dec - world coordinates position (in deg) * * width, height - dimensions of image to return (in arcmin). * * The return filename is the name of a temporary file that will * be reused on the next call to this routine. * * XXX note: this routine should probably return the status instead * of the filename (the C++ method returns the status). */ char* acGetImage(AcHandle handle, double ra, double dec, double width, double height) { if (acCheckHandle(handle) != OK) return NULL; AstroQuery q; q.pos(WorldCoords(ra, dec)); q.width(width); q.height(height); if (((AstroCatalog*)handle)->getImage(q) != 0) return NULL; return (char*)(((AstroCatalog*)handle)->tmpfile()); } /* return the error message for the most recent error */ char* acGetError() { return last_error(); } /* * return the error code for the most recent error * (see errno.h for the posible error codes) */ int acGetErrorCode() { return last_error_code(); } /* * Get the values for all objects in the specified circle/ring. */ int acCircularSearch( AcHandle handle, /* in - catalog handle */ int numCols, /* in - number of columns to get (size of colNames) */ char** colNames, /* in - null terminated array of column names to read */ double ra, /* in - center position in world coordinates */ double dec, double radius0, /* in - min radius */ double radius1, /* in - max radius */ double mag0, /* in - min magnitude */ double mag1, /* in - max magnitude */ int maxRows, /* in - max number of rows to return */ char* filename, /* in - if not null, write results to this file */ int* numFound, /* out - number of objects found */ AcResult* result) /* out - handle for accessing query results (see below) */ { if (acCheckHandle(handle) != OK) return ERROR; QueryResult* qr = new QueryResult; int status = ((AstroCatalog*)handle)->circularSearch( numCols, colNames, WorldCoords(ra, dec), radius0, radius1, mag0, mag1, maxRows, filename, *numFound, *qr); if (status == 0) *result = (AcResult)qr; return status; } /* * search for the star closest to the given position, with the magnitude in * the given range and return (via the last 2 args) the columns requested * by "colNames" */ int acSearchClosestStar( AcHandle handle, /* in - catalog handle */ int numCols, /* in - number of columns to get (size of colNames) */ char** colNames, /* in - null terminated array of column names to read */ double ra, /* in - center position in world coordinates */ double dec, double mag0, /* in - min magnitude */ double mag1, /* in - max magnitude */ AcResult* result) /* out - handle for accessing query results (see below) */ { if (acCheckHandle(handle) != OK) return ERROR; QueryResult* qr = new QueryResult; int status = ((AstroCatalog*)handle)->searchClosestStar( numCols, colNames, WorldCoords(ra, dec), mag0, mag1, *qr); if (status == 0) *result = (AcResult)qr; return status; } /* * search for the stars fulfilling the specified criteria */ int acCatalogSearch( AcHandle handle, /* in - catalog handle */ int numCols, /* in - number of columns to get */ char** colNames, /* in - array of column names to read */ int numSearchCols, /* in - number of search columns */ char** searchCols, /* in - array of column names to search */ char** minVals, /* in - optional array of min values */ char** maxVals, /* in - optional array of max values */ int maxRows, /* in - max number of rows to return */ const char* filename, /* in - if not null, write results to this file */ int* numFound, /* out - number of objects found */ AcResult* result) /* out - handle for accessing query results (see below) */ { if (acCheckHandle(handle) != OK) return ERROR; QueryResult* qr = new QueryResult; int status = ((AstroCatalog*)handle)->CatalogSearch( numCols, colNames, numSearchCols, searchCols, minVals, maxVals, maxRows, filename, *numFound, *qr); if (status == 0) *result = (AcResult)qr; return status; } /* * --- routines for accessing the query results --- */ /* return number of result rows */ int acrNumRows(AcResult handle) { if (acCheckResult(handle) != OK) return ERROR; return ((QueryResult*)handle)->numRows(); } /* return number of result columns */ int acrNumCols(AcResult handle) { if (acCheckResult(handle) != OK) return ERROR; return ((QueryResult*)handle)->numCols(); } /* return a pointer to an array of result column names */ char** acrColNames(AcResult handle) { if (acCheckResult(handle) != OK) return NULL; return (char**)((QueryResult*)handle)->colNames(); } /* * Note: there are various versions for different data types and parameters. * All return 0 for success and set the last argument value or return * 1 for error. */ /* get result values by row and column index */ int acrGetString(AcResult handle, int row, int col, char** value) { if (acCheckResult(handle) != OK) return ERROR; return ((QueryResult*)handle)->get(row, col, *value); } int acrGetInt(AcResult handle, int row, int col, int* value) { if (acCheckResult(handle) != OK) return ERROR; return ((QueryResult*)handle)->get(row, col, *value); } int acrGetDouble(AcResult handle, int row, int col, double* value) { if (acCheckResult(handle) != OK) return ERROR; return ((QueryResult*)handle)->get(row, col, *value); } int acrGetFloat(AcResult handle, int row, int col, float* value) { if (acCheckResult(handle) != OK) return ERROR; return ((QueryResult*)handle)->get(row, col, *value); } int acrGetShort(AcResult handle,int row, int col, short* value) { if (acCheckResult(handle) != OK) return ERROR; return ((QueryResult*)handle)->get(row, col, *value); } int acrGetChar(AcResult handle,int row, int col, char* value) { if (acCheckResult(handle) != OK) return ERROR; return ((QueryResult*)handle)->get(row, col, *value); } /* get result values row and column name */ int acrGetNString(AcResult handle, int row, const char* colName, char** value) { if (acCheckResult(handle) != OK) return ERROR; return ((QueryResult*)handle)->get(row, colName, *value); } int acrGetNInt(AcResult handle, int row, const char* colName, int* value) { if (acCheckResult(handle) != OK) return ERROR; return ((QueryResult*)handle)->get(row, colName, *value); } int acrGetNDouble(AcResult handle, int row, const char* colName, double* value) { if (acCheckResult(handle) != OK) return ERROR; return ((QueryResult*)handle)->get(row, colName, *value); } int acrGetNFloat(AcResult handle, int row, const char* colName, float* value) { if (acCheckResult(handle) != OK) return ERROR; return ((QueryResult*)handle)->get(row, colName, *value); } int acrGetNShort(AcResult handle, int row, const char* colName, short* value) { if (acCheckResult(handle) != OK) return ERROR; return ((QueryResult*)handle)->get(row, colName, *value); } int acrGetNChar(AcResult handle, int row, const char* colName, char* value) { if (acCheckResult(handle) != OK) return ERROR; return ((QueryResult*)handle)->get(row, colName, *value); } /* * if the result contains a wcs position (fields ra and dec), * get it and return success (0), otherwise return an error. * * The last 2 args should normally be "ra", "dec". */ int acrGetWC(AcResult handle, int row, WC* pos) { if (acCheckResult(handle) != OK) return ERROR; WorldOrImageCoords w; int status = ((QueryResult*)handle)->getPos(row, w); if (status == 0) { pos->ra.hours = w.ra().hours(); pos->ra.min = w.ra().min(); pos->ra.sec = w.ra().sec(); pos->ra.val = w.ra().val(); pos->dec.hours = w.dec().hours(); pos->dec.min = w.dec().min(); pos->dec.sec = w.dec().sec(); pos->dec.val = w.dec().val(); return 0; } return ERROR; } /* * return the result column index for the given result column name */ int acrColIndex(AcResult handle, const char* colName) { if (acCheckResult(handle) != OK) return ERROR; return ((QueryResult*)handle)->colIndex(colName); } /* * delete the result object (free the memory) */ void acrDelete(AcResult handle) { if (acCheckResult(handle) != OK) return; QueryResult* r = ((QueryResult*)handle); if (r) delete r; } skycat-3.1.2-starlink-1b/cat/generic/astro_catalog.h000066400000000000000000000165551215713201500223270ustar00rootroot00000000000000#ifndef _astroCatalog_h_ #define _astroCatalog_h_ /* * E.S.O. - VLT project * $Id: astro_catalog.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * astro_catalog.h - C interface to C++ class AstroCatalog * * (Note: C applications must have at least a dummy C++ main and link * with C++) * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created */ #include "world_coords.h" /* handle for an open catalog */ typedef void* AcHandle; /* handle for accessing the result of a query */ typedef void* AcResult; /* * open the named catalog and return a handle for it or NULL if there * were errors */ AcHandle acOpen(char* name); /* close the catalog and free its resources */ void acClose(AcHandle); /* * return true if there would have been more than "nrows" available * in the last query */ int acMore(AcHandle); /* return the number of colums in the catalog */ int acNumCols(AcHandle); /* return the name of the given column in the catalog */ char* acColName(AcHandle, int col); /* return a pointer to an array with the names of the columns in the catalog*/ char** acColNames(AcHandle); /* return the index for the given column name the catalog */ int acColIndex(AcHandle handle, char* name); /* * Get the number of columns, the column names * for the given catalog and return 0 if all is OK */ int acGetDescription( AcHandle cat, /* in - catalog handle */ int* numCols, /* out - number of result columns */ char*** colNames); /* out - ptr to array of column names */ /* * Get the values for the specified columns for the object given by "id" * in the given catalog and return 0 if all is OK */ int acGetObject( AcHandle cat, /* in - catalog handle */ char* id, /* in - object id in catalog */ int numCols, /* in - number of columns to get (size of colNames) */ char** colNames, /* in - array[numCols] of column names to read */ AcResult* result); /* out - handle for accessing query results (see below) */ /* * Get the values for all objects in the specified world coordinates area */ int acGetArea( AcHandle cat, /* in - catalog handle */ int numCols, /* in - number of columns to get (size of colNames) */ char** colNames, /* in - array[numCols] of column names to read */ double ra0, /* in - coordinates of area */ double dec0, double ra1, double dec1, double mag0, /* in - min magnitude */ double mag1, /* in - max magnitude */ int maxRows, /* in - max number of rows to return */ char* filename, /* in - if not null, write results to this file */ int* numFound, /* out - number of objects found */ AcResult* result); /* out - handle for accessing query results (see below) */ /* * return a pointer to the most recent error message */ char* acGetError(); /* * return the error code (from ) for the most recent error */ int acGetErrorCode(); /* * Get the values for all objects in the specified circle/ring. */ int acCircularSearch( AcHandle cat, /* in - catalog handle */ int numCols, /* in - number of columns to get (size of colNames) */ char** colNames, /* in - array[numCols] of column names to read */ double ra, /* in - center position in world coordinates */ double dec, double radius0, /* in - min radius */ double radius1, /* in - max radius */ double mag0, /* in - min magnitude */ double mag1, /* in - max magnitude */ int maxRows, /* in - max number of rows to return */ char* filename, /* in - if not null, write results to this file */ int* numFound, /* out - number of objects found */ AcResult* result); /* out - handle for accessing query results (see below) */ /* * search for the star closest to the given position, with the magnitude in * the given range and return (via the last 2 args) the columns requested * by "colNames" */ int acSearchClosestStar( AcHandle cat, /* in - catalog handle */ int numCols, /* in - number of columns to get (size of colNames) */ char** colNames, /* in - array[numCols] of column names to read */ double ra, /* in - center position in world coordinates */ double dec, double mag0, /* in - min magnitude */ double mag1, /* in - max magnitude */ AcResult* result); /* out - handle for accessing query results (see below) */ /* * search for the stars fulfilling the specified criteria */ int acCatalogSearch( AcHandle cat, /* in - catalog handle */ int numCols, /* in - number of columns to get */ char** colNames, /* in - array[numCols] of column names to read */ int numSearchCols, /* in - number of search columns */ char** searchCols, /* in - array of column names to search */ char** minVals, /* in - optional array of min values */ char** maxVals, /* in - optional array of max values */ int maxRows, /* in - max number of rows to return */ const char* filename, /* in - if not null, write results to this file */ int* numFound, /* out - number of objects found */ AcResult* result); /* out - handle for accessing query results (see below) */ /* * pass a request to the catalog and return the name of a FITS file * containing the resulting image, or NULL if not found * * Args: * * handle - handle returned from ac_open() * * ra, dec - world coordinates position * * width, height - dimensions of image to return. * * The return filename is the name of a temporary file that will * be reused on the next call to this routine. */ char* acGetImage(AcHandle handle, double ra, double dec, double width, double height); /* * --- routines for accessing the query results --- */ /* return number of result rows */ int acrNumRows(AcResult); /* return number of result columns */ int acrNumCols(AcResult); /* return a pointer to an array of result column names */ char** acrColNames(AcResult); /* * Get result values: * * Note: there are various versions for different data types and parameters. * All return 0 for success and set the last argument value or return * 1 for error. */ /* get result values by row and column index */ int acrGetString(AcResult, int row, int col, char** value); int acrGetInt(AcResult, int row, int col, int* value); int acrGetDouble(AcResult, int row, int col, double* value); int acrGetFloat(AcResult, int row, int col, float* value); int acrGetShort(AcResult,int row, int col, short* value); int acrGetChar(AcResult,int row, int col, char* value); /* get result values by row and column name */ int acrGetNString(AcResult,int row, const char* colName, char** value); int acrGetNInt(AcResult,int row, const char* colName, int* value); int acrGetNDouble(AcResult,int row, const char* colName, double* value); int acrGetNFloat(AcResult,int row, const char* colName, float* value); int acrGetNShort(AcResult,int row, const char* colName, short* value); int acrGetNChar(AcResult,int row, const char* colName, char* value); /* * if the result contains a wcs position (fields ra and dec), * get it and return success (0) */ int acrGetWC(AcResult, int row, WC* pos); /* * return the result column index for the given result column name */ int acrColIndex(AcResult,const char* colName); /* * delete the result object (free the memory) */ void acrDelete(AcResult); #endif /* __astroCatalog_h_ */ skycat-3.1.2-starlink-1b/cat/generic/astro_image.C000066400000000000000000000042511215713201500217200ustar00rootroot00000000000000/* * E.S.O. - VLT project/ESO Archive * $Id: astro_image.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * astroImage.C - C interface implementation for C++ class AstroImage * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 13 Oct 95 Created * 02/01/06 Renamed astroImage.C to astro_image.C to avoid * name conflict on file systems that ignore case */ static const char* const rcsId="@(#) $Id: astro_image.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; // include the C++ and C interfaces #include #include "error.h" #include "AstroImage.h" extern "C" { #include "astro_image.h" #include "astro_catalog.h" } /* * check that the given handle is not null and return its * error status */ static int aiCheckHandle(AiHandle handle) { if (handle) return ((AstroImage*)handle)->status(); return error("internal error: ", "bad image server handle", EINVAL); } /* * open the named image server and return a handle for it or NULL if * there were errors */ AiHandle aiOpen(char* name) { return (AiHandle)AstroImage::open(name); } /* close the image server connection and free its resources */ void aiClose(AiHandle handle) { if (handle) delete (AstroImage*)handle; } /* * pass a request to the image server and return the name of a FITS file * containing the resulting image, or NULL if not found * * Args: * * handle - handle returned from ai_open() * * ra, dec - world coordinates position * * width, height - dimensions of image to return. * * The return filename is the name of a temporary file that will * be reused on the next call to this routine. * * XXX note: this routine should probably return the status instead * of the filename (the C++ method returns the status). */ char* aiGetImage(AiHandle handle, double ra, double dec, double width, double height) { if (aiCheckHandle(handle) != OK) return NULL; if (((AstroImage*)handle)->getImage(WorldCoords(ra, dec), width, height) != 0) return NULL; return (char*)(((AstroImage*)handle)->tmpfile()); } skycat-3.1.2-starlink-1b/cat/generic/astro_image.h000066400000000000000000000026371215713201500217730ustar00rootroot00000000000000#ifndef _astroImage_h_ #define _astroImage_h_ /* * E.S.O. - VLT project * $Id: astro_image.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * astro_image.h - C interface to C++ class AstroImage * * (Note: C applications must have at least a dummy C++ main and link * with C++) * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * 02/01/06 Renamed astroImage.h to astro_image.h to avoid * name conflict on file systems that ignore case */ /* handle for an open image server */ typedef void* AiHandle; /* * open the named image server and return a handle for it or NULL if * there were errors */ AiHandle aiOpen(char* name); /* close the image server connection and free its resources */ void aiClose(AiHandle); /* * pass a request to the catalog and return the name of a FITS file * containing the resulting image, or NULL if not found * * Args: * * handle - handle returned from ai_open() * * ra, dec - world coordinates position * * width, height - dimensions of image to return. * * The return filename is the name of a temporary file that will * be reused on the next call to this routine. */ char* aiGetImage(AiHandle handle, double ra, double dec, double width, double height); #endif /* _astroImage_h_ */ skycat-3.1.2-starlink-1b/cat/generic/cat_bitmaps.C000066400000000000000000000034211215713201500217120ustar00rootroot00000000000000 /* * E.S.O. - VLT project / ESO Archive * "@(#) $Id: cat_bitmaps.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * Tk Bitmap/Pixmap definitions * * This file was generated by ../bitmaps/bitmaps.tcl - DO NO EDIT */ #include #include void defineCatBitmaps(Tcl_Interp *interp) { #include "symb_circle.xbm" Tk_DefineBitmap(interp, Tk_GetUid("symb_circle"), (char*)symb_circle_bits, symb_circle_width, symb_circle_height); #include "symb_cross.xbm" Tk_DefineBitmap(interp, Tk_GetUid("symb_cross"), (char*)symb_cross_bits, symb_cross_width, symb_cross_height); #include "symb_diamond.xbm" Tk_DefineBitmap(interp, Tk_GetUid("symb_diamond"), (char*)symb_diamond_bits, symb_diamond_width, symb_diamond_height); #include "symb_ellipse.xbm" Tk_DefineBitmap(interp, Tk_GetUid("symb_ellipse"), (char*)symb_ellipse_bits, symb_ellipse_width, symb_ellipse_height); #include "symb_plus.xbm" Tk_DefineBitmap(interp, Tk_GetUid("symb_plus"), (char*)symb_plus_bits, symb_plus_width, symb_plus_height); #include "symb_triangle.xbm" Tk_DefineBitmap(interp, Tk_GetUid("symb_triangle"), (char*)symb_triangle_bits, symb_triangle_width, symb_triangle_height); #include "symb_square.xbm" Tk_DefineBitmap(interp, Tk_GetUid("symb_square"), (char*)symb_square_bits, symb_square_width, symb_square_height); #include "symb_line.xbm" Tk_DefineBitmap(interp, Tk_GetUid("symb_line"), (char*)symb_line_bits, symb_line_width, symb_line_height); #include "symb_arrow.xbm" Tk_DefineBitmap(interp, Tk_GetUid("symb_arrow"), (char*)symb_arrow_bits, symb_arrow_width, symb_arrow_height); #include "symb_compass.xbm" Tk_DefineBitmap(interp, Tk_GetUid("symb_compass"), (char*)symb_compass_bits, symb_compass_width, symb_compass_height); } skycat-3.1.2-starlink-1b/cat/install000077500000000000000000000042121215713201500172770ustar00rootroot00000000000000#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5; it is not part of GNU. # # $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" instcmd="$mvprog" chmodcmd="" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; *) if [ x"$src" = x ] then src=$1 else dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` fi # Make a temp file name in the proper directory. dstdir=`dirname $dst` dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp # and set any options; do chmod last to preserve setuid bits if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi # Now rename the file to the real destination. $doit $rmcmd $dst $doit $mvcmd $dsttmp $dst exit 0 skycat-3.1.2-starlink-1b/cat/install.sh000077500000000000000000000042121215713201500177100ustar00rootroot00000000000000#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5; it is not part of GNU. # # $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" instcmd="$mvprog" chmodcmd="" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; *) if [ x"$src" = x ] then src=$1 else dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` fi # Make a temp file name in the proper directory. dstdir=`dirname $dst` dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp # and set any options; do chmod last to preserve setuid bits if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi # Now rename the file to the real destination. $doit $rmcmd $dst $doit $mvcmd $dsttmp $dst exit 0 skycat-3.1.2-starlink-1b/cat/library/000077500000000000000000000000001215713201500173505ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/cat/library/AstroCat.tcl000066400000000000000000001467071215713201500216130ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # @(#) $Id: AstroCat.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # AstroCat.tcl - user interface class for viewing catalog info # # See man page AstroCat(n) for a complete description. # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 14 Dec 95 created # P.W.Draper 12 Dec 97 added methods to get equinox and table name # 11 May 00 stop immediate delete of images, need backing # store for my catalogue handling commands. # 03 Mar 08 Remove check in new_catalog, opened file is # never closed (and can leave a temporary file). # 10 Nov 08 Add command to local catalogues menu to clear the list. itk::usual AstroCat {} # The AstroCat widget class defines a top level widget for searching and # displaying astronomical catalog data. It contains a menubar with items # for loading, editing, and saving catalog data and a table displaying # rows and columns of catalog data. This class does not know anything # about images or plotting objects in images, however these features may # be added in a derived class (see the SkySearch(n) in the skycat # package for an example). # # You can also run this class as a standalone application with the # command "astrocat". The application options are the same as the class # options. itcl::class cat::AstroCat { inherit util::TopLevelWidget # constructor constructor {args} { eval itk_initialize $args } # destructor - delete C++ based objects so that the temp # files are deleted destructor { # delete temp files on close catch { if {"[$w_.cat servtype]" == "local"} { if {"[string range $itk_option(-catalog) 0 4]" == "/tmp/"} { file delete $itk_option(-catalog) } } } catch { if { $tempimage_ != {} } { file delete $tempimage_ } } catch {$w_.cat delete} catch {close $rfd_} catch {close $wfd_} catch {unset instances_($instance_idx_)} if {"$current_instance_" == "$w_"} { set current_instance_ {} } } # called after options have been evaluated protected method init {} { # if running stand-alone, setup X defaults if {$itk_option(-standalone)} { util::setXdefaults cat::setXdefaults } # set the file used to keep track of URLs (for debugging) set_logfile # do window layout layout_dialog # enter widget name in instance array for later reference set_instance # add a short help window make_short_help # create an object for running interruptable batch queries Batch $w_.batch \ -command [code $this preview_done] \ -debug $itk_option(-debug) # position from previous window, if pos. if {"$current_instance_" != ""} { wm geometry $w_ +[winfo x $current_instance_]+[winfo y $current_instance_] } set current_instance_ $w_ # for local catalogs, start search automatically set name $itk_option(-catalog) if {"[$w_.cat servtype]" == "local"} { wm title $w_ "[file tail [$w_.cat longname $name $itk_option(-catalogdir)]] ($itk_option(-number))" wm iconname $w_ "[file tail [$w_.cat shortname $name $itk_option(-catalogdir)]]" search } # check for TCS catalog if {[$w_.cat is_tcs] || \ (! $itk_option(-tcs) \ && [file exists $name] \ && [is_tcs_catalog $name])} { global ::$w_.tcs set $w_.tcs 1 set_tcs_columns } set initialized_ 1 } # create the ~/.skycat dir if it does not already exists and keep a log # file there. protected method set_logfile {} { global ::env # open log file used to keep track of URLs (for debugging) set dir $env(HOME)/.skycat if {! [file isdirectory $dir]} { catch {mkdir $dir} } set logfile_name_ $dir/log } # open or close a pipe to get feedback during HTTP transfers. # (To save limited fds, we close the feedback pipe after each HTTP op). # The arg should be "on" to turn feedback on, or "off" to turn it off. protected method set_feedback {onoff} { # Process any pending file events. # Note: this is important: if we don't process the events before # closing the feedback file, a crash may result. update if {$itk_option(-debug)} { # if -debug was given, the feedback bit wont work, since the # query is done in the foreground and trying to read the feedback # from the pipe may cause the application to hang... return } if {"$onoff" == "on"} { lassign [pipe] rfd_ wfd_ fileevent $rfd_ readable [code $this feedback] $w_.cat feedback $wfd_ } elseif {[info exists rfd_]} { ::close $rfd_ ::close $wfd_ unset rfd_ wfd_ $w_.cat feedback {} } } # keep an array of instances(name,id) to help locate the # window for a catalog protected method set_instance {} { set name [$w_.cat longname $itk_option(-catalog) $itk_option(-catalogdir)] set id $itk_option(-id) set dirPath $itk_option(-catalogdir) set instance_idx_ "$name,$id,$dirPath" set instances_($instance_idx_) $w_ } # add the menu bar protected method add_menubar {} { TopLevelWidget::add_menubar set m [add_menubutton File "Display File menu"] set file_menu_ $m if {$iscat_} { add_menuitem $m command "Open" \ {Open a local catalog in tab table format} \ -command [code cat::AstroCat::local_catalog \ $itk_option(-id) \ [info class] \ $itk_option(-debug) $w_] \ -accelerator "Control-o" $m add separator add_menuitem $m command "Save as..." \ {Save listed objects to a local catalog file} \ -command [code $this save_as] \ -accelerator "Control-s" add_menuitem $m command "Add to..." \ {Add listed objects to a local catalog file} \ -command [code $this add_to] \ -accelerator "Control-a" add_menuitem $m command "Add selected..." \ {Add selected rows to a local catalog file} \ -command [code $this add_selected] \ -accelerator "Control-A" $m add separator add_menuitem $m command "Print..." \ {Print the listing to a printer or file} \ -command [code $this print] \ -accelerator "Control-p" add_menuitem $m command "Clear" \ {Clear the catalog listing} \ -command [code $this clear] $m add separator } add_menuitem $m command "Close" \ {Close this window} \ -command [code $this close] if {$itk_option(-standalone)} { add_menuitem $m command "Exit" \ {Exit the application} \ -command [code $this quit] \ -accelerator "Control-q" } if {$iscat_} { # Edit menu set m [add_menubutton Edit "Display Edit menu"] set edit_menu_ $m add_menuitem $m command "Remove selected" \ {Remove selected rows from the local catalog} \ -command [code $this remove_selected] \ -state disabled add_menuitem $m command "Enter new object..." \ {Enter the data for a new object for the local catalog} \ -command [code $this enter_new_object] \ -state disabled add_menuitem $m command "Edit selected object..." \ {Edit the data for the selected object in the local catalog} \ -command [code $this edit_selected_object] \ -state disabled } # Options menu set m [add_menubutton Options "Display Options menu"] set options_menu_ $m add_menuitem $m cascade "Set Name Server" \ {Select the name server used to resolve astronomical object names} \ -menu [set ns_menu_ [menu $itk_component(options).m.ns]] if {$iscat_} { add_menuitem $m checkbutton "Use TCS Columns" \ {Display the standard columns used by the ESO TCS (Telescope Control Software)} \ -command [code $this set_tcs_columns] \ -variable $w_.tcs \ -onvalue 1 \ -offvalue 0 $m add separator add_menuitem $m command "Set Sort Columns..." \ {Set options for sorting the query results} \ -command [code $this sort_dialog] \ -state disabled add_menuitem $m command "Hide/Show Columns..." \ {Set options for displaying columns of the query results} \ -command [code $this select_columns] \ -state disabled add_menuitem $m command "Set Search Columns..." \ {Set the list of columns to search by for this catalog} \ -command [code $this set_search_cols] \ -state disabled add_menuitem $m command "Set Plot Symbols..." \ {Set the symbol (color, size, etc.) to use to plot objects} \ -command [code $this set_plot_symbols] \ -state disabled $m add separator } add_menuitem $m command "Proxies..." \ "Define an HTTP proxy server." \ -command [code cat::AstroCat::proxies] check_proxies # add a menu of catalogs ("Data-Servers") add_catalog_menu $w_ $itk_option(-id) [info class] $itk_option(-debug) } # enable or disable some menus protected method set_menu_states {} { $options_menu_ entryconfig "Set Sort Columns..." -state normal $options_menu_ entryconfig "Hide/Show Columns..." -state normal if {[$w_.cat iswcs] || [$w_.cat ispix]} { set state normal } else { set state disabled } $options_menu_ entryconfig "Set Plot Symbols..." -state $state $options_menu_ entryconfig "Set Name Server" -state $state $options_menu_ entryconfig "Use TCS Columns" -state $state # determine states for some menu items if {"[$w_.cat servtype]" == "local"} { set state [set sstate normal] } else { set state [set sstate disabled] # allow user to edit search cols if URL contains "%cond" if {[string first "%cond" [$w_.cat url]] >= 0} { set sstate normal } } $edit_menu_ entryconfig "Remove selected" -state $state $edit_menu_ entryconfig "Enter new object..." -state $state $edit_menu_ entryconfig "Edit selected object..." -state $state $options_menu_ entryconfig "Set Search Columns..." -state $sstate } # add a menubutton with catalog items to the given TopLevelWidget. # # w is the caller's toplevel window (an instance of TopLevelWidget). # # id is an optional unique id to be associated with a new catalog widget. # # classname is the name of the AstroCat subclass to use to create new # catalog widgets (defaults to "AstroCat"). # # debug is a flag is passed from the command line. If true, querries # are run in the foreground, to make debugging easier. # # note: this is defined as a proc rather than a method so that it # can be accessed from outside the class to add the Data-Servers menu public proc add_catalog_menu {w {id ""} {classname AstroCat} {debug 0}} { # save this info so we can update the menu automatically later set catalog_menu_info_($w) \ [code cat::AstroCat::add_catalog_menu $w $id $classname $debug] # add the menu to the caller's menubar set m [$w add_menubutton "Data-Servers" "Display Data Servers menu"] $w add_menuitem $m cascade "Catalogs" \ {Select a catalog from the menu} \ -menu [menu $m.catalogs] fill_catalog_menu $w $id $classname $m.catalogs $debug catalog $w add_menuitem $m cascade "Image Servers" \ {Select an image server from the menu} \ -menu [menu $m.imagesvr] fill_catalog_menu $w $id $classname $m.imagesvr $debug imagesvr $w add_menuitem $m cascade "Archives" \ {Select an archive from the menu} \ -menu [menu $m.archive] fill_catalog_menu $w $id $classname $m.archive $debug archive $w add_menuitem $m cascade "Local Catalogs" \ {Select a local catalog from the menu} \ -menu [menu $m.local] fill_catalog_menu $w $id $classname $m.local $debug local shortname $m.local add separator $w add_menuitem $m.local command "Load from file..." \ {Open a local catalog file} \ -command [code cat::AstroCat::local_catalog $id $classname $debug $w] \ -accelerator "Control-O" # clear the local catalogs (handy when many local catalogs have been # opened). $w add_menuitem $m.local command "Clear local catalogs" \ {Clear all local catalogs from the list} \ -command [code clear_local_catalogs] $m add separator $w add_menuitem $m command "Browse Catalog Directories..." \ "Browse the catalog directory hierarchy to view \ catalogs or add them to the default list" \ -command [code cat::AstroCat::catalog_directory $id $classname $debug $w] \ -accelerator "Control-b" $w add_menuitem $m command "Reload config file..." \ "Reload the default catalog config file after it was edited by hand" \ -command [code cat::AstroCat::reload_config_file $w] \ -accelerator "Control-R" # if there is a local catalog called "history", add it to the menu also if {"[$astrocat_ servtype history]" == "local"} { $m add separator $w add_menuitem $m command "History..." \ "Open an automatically generated catalog of previously viewed images" \ -command [code cat::AstroCat::select_catalog history local $id $classname 0 $debug $w] \ -accelerator "Control-h" } } # reload the default catalog config file using the given astrocat object public proc reload_config_file {w} { global ::env set config_file $env(HOME)/.skycat/skycat.cfg if {[file exists $config_file]} { set env(CATLIB_CONFIG) "file:$config_file" } if {[catch {$astrocat_ reload} msg]} { error_dialog $msg $w } # make sure these windows are updated catch {destroy $w_.symconf} catch {destroy $w_.searchconf} if {[winfo exists .catinf]} { .catinf reinit_tree } if {[info exists instances_]} { foreach i [array names instances_] { $instances_($i) update_search_options } } update_catalog_menus } # Check for a file ~/.skycat/proxies, once each session, and # use it to initialize environment variables for a proxy server # (see also tclutil/util/src/HTTP.C). public proc check_proxies {} { global ::env # only do it once if {$checked_proxies_} { return } cat::ProxyDialog::check_proxies $env(HOME)/.skycat/proxies set checked_proxies_ 1 } # Pop up a dialog to set or change the HTTP proxy server. public proc proxies {} { global ::env utilReUseWidget ProxyDialog .proxy \ -configfile $env(HOME)/.skycat/proxies } # pop up a window to browse the catalog directories. # # id is an optional unique id to be associated with a new catalog widget. # # classname is the name of the AstroCat subclass to use to create new # catalog widgets (defaults to "AstroCat"). # # debug is a flag is passed from the command line. If true, querries # are run in the foreground, to make debugging easier. # # w should be the caller's top level window, if specified. # proc catalog_directory {{id ""} {classname AstroCat} {debug 0} {w ""}} { utilReUseWidget cat::CatalogInfo .catinf \ -id $id \ -classname $classname \ -debug $debug \ -callerw $w \ -command [code cat::AstroCat::update_catalog_menus] # put the window clone number in the title if {[winfo exists $w]} { catch {wm title .catinf "Catalog Directory ([$w cget -number])"} } } # update all of the catalog menus in all instances to show # the current catalog info. public proc update_catalog_menus {} { foreach i [array names catalog_menu_info_] { if {[winfo exists [utilNamespaceTail $i]]} { eval $catalog_menu_info_($i) } } } # pop up a dialog to set the plot symbols to use for this catalog public method set_plot_symbols {} { set columns $headings_ if {[llength $columns] == 0} { info_dialog "Please make a query first so that the column names are known" $w_ return } utilReUseWidget cat::SymbolConfig $w_.symconf \ -catalog $itk_option(-catalog) \ -astrocat [code $w_.cat] \ -columns $columns \ -command [code $this plot] } # pop up a dialog to set the search columns to use for this catalog public method set_search_cols {} { set columns $headings_ if {[llength $columns] == 0} { info_dialog "Please make a query first so that the column names are known" $w_ return } utilReUseWidget cat::SearchConfig $w_.searchconf \ -catalog $itk_option(-catalog) \ -command [code $this update_search_options] \ -astrocat [code $w_.cat] \ -columns $columns } # update the search option entries after they have been edited public method update_search_options {} { $searchopts_ update_search_options } # close this window public method close {} { if {$itk_option(-standalone)} { wm iconify $w_ } else { wm withdraw $w_ } } # pop up a dialog to sort the list public method sort_dialog {} { $results_ sort_dialog } # called when the user has selected columns to sort the results by. # The first arg is the sort columns, the second arg is the order # (increasing, decreasing) public method set_sort_cols {sort_cols sort_order} { global ::$w_.tcs if {"[$w_.cat sortcols]" != "$sort_cols" \ || "[$w_.cat sortorder]" != "$sort_order"} { $w_.cat sortcols $sort_cols $w_.cat sortorder $sort_order $w_.cat is_tcs $itk_option(-catalog) [set $w_.tcs] cat::CatalogInfo::save {} $w_ 0 $results_ config -sort_cols $sort_cols -sort_order $sort_order search } } # pop up a dialog to select table columns to display public method select_columns {} { $results_ select_columns } # called when the user has selected columns to show public method set_show_cols {cols} { global ::$w_.tcs set show [$w_.cat showcols] if {"$show" == ""} { set show [$results_ get_headings] } if {"$show" != "$cols"} { $w_.cat showcols $cols $w_.cat is_tcs $itk_option(-catalog) [set $w_.tcs] cat::CatalogInfo::save {} $w_ 0 } } # add the name server catalogs to the name server menu protected method get_name_servers {} { set m $ns_menu_ if {[catch {set list [$w_.cat info namesvr]} msg]} { error_dialog $msg $w_ return } foreach namesvr $list { $m add radiobutton \ -label $namesvr \ -command [code $this set_namesvr $namesvr] \ -variable $m } if {![info exists namesvr]} { error_dialog "No default name server found for astronomical objects" return } # set default name server global ::$m set $m $namesvr set_namesvr $namesvr } # toggle the TCS option (use the tcscat or the astrocat Tcl command) public method set_tcs_columns {} { global ::$w_.tcs set is_tcs [set $w_.tcs] set itk_option(-tcs) $is_tcs catch {$w_.cat delete} if {$is_tcs} { tcscat $w_.cat } else { astrocat $w_.cat } if {[catch {$w_.cat open $itk_option(-catalog) $itk_option(-catalogdir)} msg]} { error_dialog $msg $w_ return } set iscat_ 1 # if changing formats, reset table column info and entry # since column names will change making previous info invalid if {[$w_.cat is_tcs] != $is_tcs} { $w_.cat is_tcs $itk_option(-catalog) $is_tcs set reset_columns_ 1 } if {[llength $headings_]} { search } } # reset table dialogs if needed public method reset_table {} { $results_ reset $results_ set_options {MORE PREVIEW more preview} Show 0 $w_.cat showcols {} $w_.cat sortcols {} cat::CatalogInfo::save {} $w_ 0 } # return true if the given file contains a TCS catalog public proc is_tcs_catalog {filename} { if {[catch {set f [open $filename]}]} { return 0 } set title [gets $f] ::close $f if {[string match "Tcs*" $title]} { return 1 } return 0 } # clear the table listing public method clear {} { catch {$results_ clear} } # pop up a dialog to print the table listing public method print {} { $results_ print_dialog } # Ask the user for the name of a local catalog file and then # open a window for the catalog. # # id is an optional unique id to be associated with a new catalog widget. # # classname is the name of the AstroCat subclass to use to create new # catalog widgets (defaults to "AstroCat"). # # $debug is a flag set from the command line arg. # # $w should be the top level window of the caller, if specified. public proc local_catalog {{id ""} {classname AstroCat} {debug 0} {w ""}} { set file [filename_dialog [pwd] *] if {"$file" != ""} { if {[file isfile $file]} { if {[catch {$astrocat_ check $file} msg]} { error_dialog $msg } else { select_catalog $file local $id $classname \ [is_tcs_catalog $file] $debug $w } } else { error_dialog "There is no file named '$file'" } } } # Fill up a menu of known data servers to choose from. # # w is the caller's top level widget (containing menubar) # # id is an optional unique id to be associated with a new catalog widget. # # classname is the name of the AstroCat subclass to use to create new # catalog widgets (defaults to "AstroCat"). # # $debug is a flag set from the command line arg. # # The serv_type argument should be one of: "catalog", "archive". # # An optional "cmd" argument may be set to longname or shortname # depending on the names you want in the menu (for local catalogs, # specify shortname, to avoid getting the complete path name in # the menu. public proc fill_catalog_menu {w id classname m debug serv_type {cmd longname}} { if {[catch {set catalog_list [lsort [$astrocat_ info $serv_type]]} msg]} { error_dialog $msg $w return } if {[llength $catalog_list]} { foreach i $catalog_list { set name [$astrocat_ $cmd $i] set is_tcs [$astrocat_ is_tcs $i] $w add_menuitem $m command $name \ "Open $serv_type: \"$i\"" \ -command [code cat::AstroCat::select_catalog $i $serv_type $id \ $classname $is_tcs $debug $w] } } } # Open a window for the given catalog, or report an error if the catalog # does not exist. # $name is the name of the catalog to open, # $classname is the class to use to open it, # $debug is an optional debugging flag, # $w should be set to the top level window of the caller (optional). public proc open_catalog_window {name {id ""} {classname AstroCat} {debug 0} {w ""}} { if {[catch {$astrocat_ open $name} msg]} { error_dialog $msg } cat::AstroCat::select_catalog $name catalog $id $classname 0 $debug $w } # save the current data to a local catalog public method save_as {} { $results_ save_as } # add the rows in the current listing to a local catalog file public method add_to {} { $results_ add_to } # add the currently selected rows to a local catalog file public method add_selected {} { $results_ add_selected } # remove the currently selected rows from a local catalog file public method remove_selected {} { $results_ remove_selected # update the display clear search } # pop up a dialog to enter the data for a new object for a local catalog public method enter_new_object {} { $results_ enter_new_object [code $this search] } # pop up a window so that the user can edit the selected object(s) public method edit_selected_object {} { $results_ edit_selected_object [code $this search] } # open the catalog for this window public method open_catalog {} { # create astrocat object (or tcscat if TCS catalog) global ::$w_.tcs if {[set $w_.tcs $itk_option(-tcs)]} { tcscat $w_.cat } else { astrocat $w_.cat } # normally -catalog should be specified when creating this widget # if not, choose a default... if {"$itk_option(-catalog)" == ""} { return # if {[catch {set catalog_list [$w_.cat info $itk_option(-catalogtype)]} msg]} { # error_dialog $msg $w_ # return # } # set itk_option(-catalog) [lindex $catalog_list [expr [llength $catalog_list]-1]] } # open the catalog set name $itk_option(-catalog) if {[catch {$w_.cat open $name $itk_option(-catalogdir)} msg]} { error_dialog $msg $w_ return -code error } # set iscat_ to true if the catalog is not an image server set iscat_ 1 if {"[$w_.cat servtype]" == "imagesvr"} { set iscat_ 0 } # if this is a local catalog, add it to the catalog menus and tree # XXX should check if local catalog was already known if {"[$w_.cat servtype]" == "local"} { update_catalog_menus # add to catalog tree, if there is one catch {.catinf insert_node $name} # add an entry to the config file for this catalog cat::CatalogInfo::save "" $w_ 0 } # display catalog name in header and icon wm title $w_ "[$w_.cat longname $name $itk_option(-catalogdir)] ($itk_option(-number))" wm iconname $w_ "[$w_.cat shortname $name $itk_option(-catalogdir)]" } # add the search options panel protected method add_search_options {} { # AstroQuery(n) widget for displaying catalog search options. itk_component add searchopts { set searchopts_ [AstroQuery $w_.searchopts \ -relief groove \ -borderwidth 2 \ -debug $itk_option(-debug) \ -astrocat [code $w_.cat] \ -searchcommand [code $this search] \ -feedbackcommand [code $this set_feedback] \ -command [code $this query_done]] } pack $itk_component(searchopts) \ -side top -fill x } # add the table for displaying the query results protected method add_result_table {} { # QueryResult(n) widget to display catalog query results itk_component add results { set results_ [QueryResult $w_.results \ -astrocat [code $w_.cat] \ -title "Search Results" \ -hscroll 1 \ -height 12 \ -sortcommand [code $this set_sort_cols] \ -layoutcommand [code $this set_show_cols] \ -selectmode extended \ -exportselection 0] } { } pack $itk_component(results) -side top -fill both -expand 1 bind $results_.listbox [code $this select_result_row] $results_ set_options {MORE PREVIEW more preview} Show 0 } # add the dialog button frame protected method add_dialog_buttons {} { # dialog buttons pack [frame $w_.buttons -borderwidth 2 -relief raised] \ -side top -fill x if {$iscat_} { set search_label "Search" } else { set search_label "Get Image" } pack \ [button $w_.search \ -text $search_label \ -command [code $this search]] \ -side left -expand 1 -pady 2m -in $w_.buttons if {$iscat_} { pack \ [button $w_.more \ -text "More Info" \ -state disabled \ -command [code $this more]] \ [button $w_.preview \ -text "Preview" \ -state disabled \ -command [code $this preview]] \ -side left -expand 1 -pady 2m -in $w_.buttons } pack \ [button $w_.stop \ -text "Stop" \ -state disabled \ -command [code $this interrupt]] \ [button $w_.close \ -text "Close" \ -command [code $this close]] \ -side left -expand 1 -pady 2m -in $w_.buttons # add a help button, if there is a help URL if {"[$w_.cat help]" != ""} { pack \ [button $w_.help \ -text "Help" \ -command [code $this help]] \ -side left -expand 1 -pady 2m -in $w_.buttons -before $w_.close } } # disable the search button, if the arg is 1, otherwise enable it public method disable_search {{arg 1}} { if {$arg} { set search_state_ disabled } else { set search_state_ normal } } # if the catalog has a "help" URL, try to display it in netscape using the # netscape remote interface. public method help {} { set url [$w_.cat help] if {"$url" != ""} { send_to_netscape $url } else { info_dialog "Sorry, no help is available for this catalog" } } # add a progress bar to display the progress of data transfers protected method add_progress_bar {} { # add a progress bar at the botton pack [ProgressBar $w_.progress] \ -side top -fill x } # do the dialog window layout protected method layout_dialog {} { open_catalog add_menubar add_search_options get_name_servers if {$iscat_} { add_result_table } add_dialog_buttons add_progress_bar } # add a short help window and set the help texts protected method make_short_help {} { TopLevelWidget::make_short_help add_short_help $results_ \ {Query results: {bitmap b1} = select object, \ double click {bitmap b1} = label object, \ {bitmap dragb2} = scroll list} if {$iscat_} { add_short_help $w_.search \ {{bitmap b1} = start catalog search} add_short_help $w_.preview \ {{bitmap b1} = view the preview image or plot data for the selected object} add_short_help $w_.more \ {{bitmap b1} = display more information for the selected object} } else { add_short_help $w_.search \ {{bitmap b1} = fetch the image from the image server} } add_short_help $w_.stop \ {{bitmap b1} = interrupt the current catalog operation} if {[winfo exists $w_.help]} { add_short_help $w_.help \ {{bitmap b1} = Display help information for catalog in netscape} } add_short_help $w_.close {{bitmap b1} = close this window} add_short_help $w_.progress {Progress bar: displays status of work in progress} } # This proc is called when the named catalog selected from the menu. # # serv_type is the type of the catalog: one of: catalog, archive, # local, imagesvr, etc... # # id is an optional unique id to be associated with a new catalog widget. # # classname is the name of the AstroCat subclass to use to create new # catalog widgets (defaults to "AstroCat"). # # tcs_flag can be set to true, if you know it is a TCS catalog. # # $debug is a flag set from the command line arg. # # $w should be the top level window of the caller (optional). public proc select_catalog {name serv_type id classname {tcs_flag 0} {debug 0} {w ""}} { new_catalog $name $id $classname $debug $tcs_flag "catalog" $w } # set the name server to use to resolve object names public method set_namesvr {name} { $searchopts_ config -namesvr $name } # interrupt the current search public method interrupt {} { $w_.batch interrupt $searchopts_ interrupt set_feedback off catch {$results_ config -title "Search Results"} set_state normal } # set/reset widget states while busy public method set_state {state} { set state_ $state if {"$state" == "normal"} { catch {blt::busy release $w_.options} catch {focus -lastfor $w_.options} $w_.search config -state $search_state_ $w_.stop config -state disabled } else { catch {focus .} catch {blt::busy hold $w_.options} $w_.search config -state disabled catch { $w_.more config -state disabled $w_.preview config -state disabled } $w_.stop config -state normal } update idletasks $w_.progress reset } # this method is called by the fileevent handler during the data transfer # from the HTTP C++ class to give the user feedback about how much there is # left to copy, etc... # Read a line from the feedback pipe, which should contain text to be displayed # in the progress widget. # # When we are in busy (disabled, waiting) mode, we also interpret some special # messages, such as: "total length: n bytes" to update the progress bar. public method feedback {} { set text [gets $rfd_] if {"$state_" != "normal"} { if {[scan $text {total length: %d bytes} n] == 1} { $w_.progress config -to $n } elseif {[scan $text {read %d bytes} n] == 1} { $w_.progress config -value $n } elseif {[scan $text {url: %s} url] == 1} { catch { set fd [open $logfile_name_ a+] puts $fd "[clock format [clock seconds]]\n$itk_option(-catalog)\n$url\n\n" ::close $fd } } } $w_.progress config -text $text update idletasks } # This method could be used by a plugin to set the contents of the listing # without doing a query. # The arguments are the table headings (list of strings) and the table data # (list of rows, where each row is a list of values). The "more" flag is # optional and indicates that there would be more data. public method set_info {headings info {more 0}} { query_done "" $headings $info $more } # This method is called when the background query is done. # # Args: # # errmsg - If this is not empty, it contains an error message and # the following args should be ignored. If there were no # errors, this arg is an empty string. # # headings - are the column headings # # info - is a list of rows (result of query) # # more - is a flag set to 1 if there were more rows available that were # not returned due to the maxrows limit set. public method query_done {errmsg headings info more} { if {"$errmsg" != ""} { # check if we need user/passwd info. errmsg should have the format: # "Authorization Required for at " if {[regsub {Authorization Required} $errmsg {Enter username} msg]} { lassign [passwd_dialog $msg] username passwd if {"$username" != "" && "$passwd" != ""} { lassign $errmsg {} {} {} realm {} host $w_.cat authorize $username $passwd $realm $host $searchopts_ search } } else { set_state normal catch {$results_ config -title "Search Results"} # error messages starting with "***" are only displayed in progress win if {"[string range $errmsg 0 2]" != "***"} { error_dialog $errmsg $w_ } after 0 [list $w_.progress config -text $errmsg] } } else { if {! $iscat_} { # for image servers, the info is the image file name set filename $info # load the image and remove the temp file display_image_file $filename if { $tempimage_ != {} } { catch {file delete $tempimage_} } set tempimage_ $filename } else { busy { set prev_headings $headings_ set headings_ $headings set info_ $info # update table $results_ config -headings $headings_ if {$reset_columns_} { set reset_columns_ 0 reset_table } if {"$prev_headings" != "$headings_"} { $results_ update_options set_menu_states } $results_ config -info $info # need to know the equinox of the results, if using world coords if {[$w_.cat iswcs]} { lassign [$w_.searchopts get_pos_radius] {} {} equinox $results_ config -equinox $equinox } if {$more} { set more "+" } else { set more "" } $results_ config -title "Search Results ([$results_ total_rows]$more)" # note column indexes in array (use upper case to simplify search) catch {unset col_} set n -1 foreach i $headings_ { set col_($i) [incr n] } # plot stars #puts "plot time: [expr [lindex [time plot] 0]/1000000.]" plot } } set_state normal } } # start the catalog search based on the current search options # and display the results in the table. public method search {args} { # start the query in the background catch { $results_ config -title "Searching..." $results_ clear } set_state disabled set servtype [$w_.cat servtype] if {"$servtype" == "local"} { $w_.progress config -text "Searching catalog..." } elseif {"$servtype" == "imagesvr"} { $w_.progress config -text "Attempting to contact image server..." } else { $w_.progress config -text "Attempting to contact catalog server..." } $w_.progress look_busy $searchopts_ search } # Get the requested image from the image server based on the given arguments # for the world coord position or name and the given width and height public method getimage_from_args {ra dec name equinox width height} { $searchopts_ set_pos_width_height [list $ra $dec $equinox $width $height $name] search } # If the given name is the name of a local catalog, check that the file exists, # and if not, ask the user for a new path name or remove it from the menu. public proc check_local_catalog {name {id ""} {classname AstroCat} {debug 0} {tcs_flag 0} {type "catalog"} {w ""} {dirPath ""}} { if {"[$astrocat_ servtype $name $dirPath]" != "local"} { return 0 } set file [$astrocat_ url $name] if {[file isfile $file]} { return 0 } set msg "The catalog file [file tail $file] does not exists. \ Do you want to specify a new name?" switch [choice_dialog $msg {{Specify a new name} Cancel {Remove from menu}}] { {Specify a new name} { set file [filename_dialog] if {[file isfile $file]} { $astrocat_ entry remove $name new_catalog $file $id $classname $debug $tcs_flag $type $w $dirPath if {[winfo exists .catinf]} { .catinf reinit_tree } } } Cancel { return 1 } {Remove from menu} { $astrocat_ entry remove $name if {[winfo exists .catinf]} { .catinf reinit_tree } } } # update config file and menus cat::CatalogInfo::save "" $w 0 update_catalog_menus return 1 } # remove all local catalogues from the list. public proc clear_local_catalogs {} { if {[catch {set catalog_list [lsort [$astrocat_ info local]]} msg]} { error_dialog $msg return } if {[llength $catalog_list]} { foreach i $catalog_list { set name [$astrocat_ longname $i] $astrocat_ entry remove $name } cat::CatalogInfo::save "" "" 0 update_catalog_menus } } # set the values for the position and radius entries from the given # list, which should be in the format {ra dec equinox radius} if # we are using wcs, otherwise {x y radius}. public method set_pos_radius {list} { $searchopts_ set_pos_radius $list } # set the values for the position, width and height entries from # the given list, which should be in the format # {ra dec equinox width height (in arcmin)} for wcs, or {x y width height}, # for pixel coordinates. public method set_pos_width_height {list} { $searchopts_ set_pos_width_height $list } # This method is called whenever a result row is selected. # Note the selected values and enable/disable some buttons public method select_result_row {} { $w_.results select_result_row if {! [info exists col_(PREVIEW)] && ! [info exists col_(MORE)]} { return } set row [lindex [$results_ get_selected] 0] if {[llength $row] == 0} { return } set preview [get_col PREVIEW $row] set more [get_col MORE $row] set object_name_ [lindex $row 0] # note: HST returns P=http:.... if {! [regsub {P=(.*)} $preview {\1} preview_url_]} { set preview_url_ $preview } if {"$preview_url_" == ""} { $w_.preview config -state disabled } else { $w_.preview config -state normal } # note: HST returns M=http:.... if {! [regsub {M=(.*)} $more {\1} more_url_]} { set more_url_ $more } if {"$more_url_" == ""} { $w_.more config -state disabled } else { $w_.more config -state normal } } # assuming there is a field called "preview" that is the URL of an # image, get the image or table data for the selected line over HTTP # and display it # # The preview data may be an image or other data, such as a tab table to # display as a graph (like the "cuts" (RtdImageSpectrum) graph). public method preview {} { if {[$results_ num_selected] == 0} { warning_dialog "Please select an object from the list first" $w_ return } if {! [info exists col_(PREVIEW)]} { warning_dialog "Previewing is not supported for this catalog" $w_ return } if {"$preview_url_" == ""} { warning_dialog "No preview for this object" $w_ return } # if it is a file URL, we can just get the file if {[string first file: $preview_url_] == 0} { set filename [string range $preview_url_ 5 end] preview_done 0 [list $filename image/x-fits] } else { # HTTP: do it in the background, since it may take a while set_state disabled $w_.progress config -text "Attempting to contact server..." $w_.progress look_busy # set up the feedback pipe set_feedback on $w_.batch bg_eval [code $this get_preview] } } # get the preview image given by $preview_url_ into a temp file protected method get_preview {} { # get the preview and call preview_done $w_.cat getpreview -url $preview_url_ } # This method is called when we have received the preview data # The "status" argument is the status of the background http get operation (0 if ok). # The result is a list of {filename Content-type}, where filename contains the data # and Content-type indicates the type of the preview data. Decompression is already # taken care of, so we only expect to get a FITS image here or a tab table to plot. # # If we get an authorization error, we ask the user to type in a username and # password and retry the operation with the new info. This is needed for some # HTTP server sites that have special restrictions on data access (especially # image access). protected method preview_done {status result} { set_feedback off if {$status} { # check if we need user/passwd info. errmsg should have the format: # "Authorization Required for at " if {[regsub {Authorization Required} $result {Enter username} msg]} { lassign [passwd_dialog $msg] username passwd if {"$username" != "" && "$passwd" != ""} { lassign $result {} {} {} realm {} host $w_.cat authorize $username $passwd $realm $host preview } } else { error_dialog $result $w_ } } else { if {[llength $result] != 2} { error_dialog "error getting preview data (result = $result)" } else { lassign $result filename type if {"$type" == "image/x-fits"} { # load the image and remove the temp file display_image_file $filename } elseif {"$type" == "text/tab-separated-values" \ || "$type" == "text/x-starbase" \ || "$type" == "text/plain" \ || "$type" == ""} { PreviewPlot $w_.pplot[incr count_] \ -file $filename \ -name $object_name_ \ -shorthelpwin $this \ -transient 1 } else { error_dialog "unrecognized Content-type for preview data: $type" } if {[string first file: $preview_url_] != 0} { # if the image was retrieved via http, remove it catch {file delete $filename} } } } set_state normal # restore preview button state... select_result_row } # send a URL to be displayed by netscape public proc send_to_netscape {url} { if {[catch {exec netscape -remote "openURL($url)"} msg1]} { if {! [string match $msg1 "netscape: warning"]} { if {[catch {exec netscape $url &} msg2]} { warning_dialog "couldn't start netscape: $msg1" } else { info_dialog "Starting netscape..." } } } else { info_dialog "Sending help URL to netscape..." } } # use the "more" URL to display more info about an object using netscape # or mosaic public method more {} { if {[$results_ num_selected] == 0} { warning_dialog "Please select an object from the list first" $w_ return } if {"$more_url_" == ""} { warning_dialog "No more information is available for this object" $w_ return } # start netscape $w_.progress config -text "sending URL to netscape..." update idletasks send_to_netscape $more_url_ } # return the value for the given column name in the given row public method get_col {name row} { if {[info exists col_($name)]} { return [lindex $row $col_($name)] } } # This member proc is used to open a window for the named catalog, # or reuse the existing one for the catalog, if it is already open. # # name is the long name of catalog from config file # # id is an optional unique id to be associated with a new catalog widget. # # classname is the name of the AstroCat subclass to use to create new # catalog widgets (defaults to "AstroCat"). # # debug is a flag: if true, run queries in foreground # # tcs_flag may be set to true if the catalog is TCS format # # type is the catalog serv_type (here it is enough to specify "catalog" or # "imagesvr". # # w should be the top level window of the caller, if specified. # # dirPath may be the name of the catalog directory (or a tcl list forming # the path to it). The default is the root catalog directory. public proc new_catalog {name {id ""} {classname AstroCat} {debug 0} {tcs_flag 0} {type "catalog"} {w ""} {dirPath ""}} { # if it is a local catalog, make sure it exists still, or get a new name if {[check_local_catalog $name $id $classname $debug $tcs_flag $type $w $dirPath] != 0} { return } set i "$name,$id,$dirPath" if {[info exists instances_($i)] && [winfo exists $instances_($i)]} { utilRaiseWindow $instances_($i) if {"[$instances_($i).cat servtype]" == "local"} { # for local catalogs, search automatically when opened $instances_($i) search } return } # If $w was specified, put the window under that top level window # so we get the window numbers right (for cloning, see TopLevelWidget). if {[winfo exists $w]} { set instname $w.ac[incr n_instances_] } else { set instname .ac[incr n_instances_] } set instances_($i) \ [$classname $instname \ -id $id \ -debug $debug \ -catalog $name \ -catalogtype $type \ -catalogdir $dirPath \ -tcs $tcs_flag \ -transient 0 \ -center 0] } # Return a Tcl list of instances of this class. By default # (and for backward compatibility) only catalog windows are # included - not image servers. If "choice" is "all", then # all instances are returned. If choice is imagesvr, only # image server windows are returned. public proc instances {{choice catalogs}} { set list {} if {[info exists instances_]} { foreach i [array names instances_] { if {[winfo exists $instances_($i)]} { if {[$instances_($i) iscat]} { # instance of a catalog window if {"$choice" == "catalogs" || "$choice" == "all"} { lappend list $instances_($i) } } else { # instance of an image server window if {"$choice" == "imagesvr"} { lappend list $instances_($i) } } } } } return $list } # Return the widget instance for the given catalog, if found, # otherwise an empty string public proc get_instance {catalog} { foreach w [cat::AstroCat::instances all] { if {"[$w cget -catalog]" == "$catalog"} { return $w } } } # Return 1 if this window is for a searchable catalog, # and 0 otherwise (in which case it must be an image server window). public method iscat {} { return $iscat_ } # --------------------------------------------------------------- # The following methods deal with images and plotting of objects # in an image and are meant to be defined in a derived class. # See the skycat/skycat/interp/library/SkySearch.tcl for an example. # --------------------------------------------------------------- # plot the stars/objects found in the previous search in a (image) window. # The symbols to use are taken from the config file. # (To be defined in a subclass) public method plot {} { } # display the given image file (To be defined in a subclass) public method display_image_file {filename} { } # return the equinox public method get_equinox {} { return [component searchopts get_equinox] } # return the name of the TableList public method get_table {} { if {[info exists itk_component(results)]} { return $itk_component(results) } error "This catalog is an image server" } # -- options -- # name of catalog itk_option define -catalog catalog Catalog "" { # make sure we use full path name for local catalogs set f $itk_option(-catalog) if {[file exists $f] && "[string index $f 0]" != "/"} { set itk_option(-catalog) [pwd]/$f } } # type of catalog (catalog or archive) itk_option define -catalogtype catalogType CatalogType "catalog" # name of catalog directory, or a tcl list forming the path to it (empty means root) itk_option define -catalogdir catalogDir CatalogDir "" # Optional unique id, used in searching for already existing catalog widgets. itk_option define -id id Id "" # list of catalog column headings (from results of most recent query) protected variable headings_ {} # result from most recent query (list of rows) protected variable info_ {} # font to use for labels itk_option define -labelfont labelFont LabelFont TkDefaultFont # font to use for values itk_option define -valuefont valueFont ValueFont TkDefaultFont # font to use for ra,dec labels itk_option define -wcsfont wcsFont WcsFont {Symbol -14} # set the width for displaying labels itk_option define -labelwidth labelWidth LabelWidth 12 # set the anchor for labels itk_option define -anchor anchor Anchor e # flag: if true, run queries in foreground for better debugging itk_option define -debug debug Debug 0 # if -tcs is 1, use fixed format TCS catalog listings itk_option define -tcs tcs Tcs {0} # AstroQuery widget used to manage search options protected variable searchopts_ {} # QueryResult widget used to display search results protected variable results_ {} # array(uppercase col name) of col index from catalog headings protected variable col_ # preview URLs for selected object protected variable preview_url_ {} # more-info URLs for selected object protected variable more_url_ {} # pipe to read feedback during HTTP transfer protected variable rfd_ # pipe to write feedback during HTTP transfer protected variable wfd_ # current state: normal, disabled (i.e.: waiting) protected variable state_ {normal} # log file handle (used to log URLs) protected variable logfile_name_ # flag: set at end of constructor protected variable initialized_ 0 # index of this object in the instances_ array protected variable instance_idx_ {} # name of File menu widget protected variable file_menu_ # name of Edit menu widget protected variable edit_menu_ # name of Options menu widget protected variable options_menu_ # name of Name Server menu widget protected variable ns_menu_ # flag: set when the column headings are changed between TCS and normal protected variable reset_columns_ {0} # currently selected object (Id field in row) protected variable object_name_ {} # count used for filename generation protected variable count_ 0 # flag: true if catalog is not an image server protected variable iscat_ 1 # flag: true if searching is allowed protected variable search_state_ normal # name of temporary image file, deleted when new image is # obtained, or when object destroyed. protected variable tempimage_ {} # -- common variables (common to all instances of this class) -- # C++ astrocat object used by static member procs protected common astrocat_ [astrocat ::cat::.astrocat] # array mapping catalog name to widget/class name protected common instances_ # instance count protected common n_instances_ 0 # current instance name protected common current_instance_ {} # array(TopLevelWidget instance) of command used to update the # Data-Servers menu. This is used to make it posible to update # all instances of this menu in various top level windows. protected common catalog_menu_info_ # flag: set to 1 after we checked for a proxy server protected common checked_proxies_ 0 } skycat-3.1.2-starlink-1b/cat/library/AstroImage.tcl000066400000000000000000000571631215713201500221230ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # @(#) $Id: AstroImage.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # AstroImage.tcl - user interface class for accessing image servers # such as DSS (Digitized Sky Survey) # # See man page AstroImage(1) for a complete description. # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 11 Oct 95 created itk::usual AstroImage {} # AstroImage is a user interface class for accessing image servers # such as DSS (Digitized Sky Survey). itcl::class cat::AstroImage { inherit util::TopLevelWidget # constructor constructor {args} { eval itk_initialize $args } # called after options have been evaluated protected method init {} { global ::env if {"$itk_option(-image)" == ""} { error_dialog "Can't create AstroImage widget: no skycat image widget was specified" destroy $w_ return } wm title $w_ "Image Servers ($itk_option(-number))" # set the file used to keep track of URLs (for debugging) set_logfile # do window layout layout_dialog # set up feedback for HTTP ##set_feedback on # add a short help window make_short_help # create an object for running interruptable batch image requests Batch $w_.batch \ -command [code $this request_done] \ -debug $itk_option(-debug) set initialized_ 1 config -image $itk_option(-image) } # destructor - delete C++ based objects so that the temp image # files are deleted destructor { catch {$w_.im delete} catch {file delete $itk_option(-tmpfile)} ##set_feedback off } # add the menu bar protected method add_menubar {} { TopLevelWidget::add_menubar set m [add_menubutton File] add_menuitem $m command "Close" \ {Close this window} \ -command [code $this quit] set m [add_menubutton Options] add_menuitem $m cascade "Name Server" \ {Select the name server used to resolve astronomical object names} \ -menu [set ns_menu [menu $itk_component(options).m.ns]] get_name_servers $ns_menu # ImageServers menu set m [add_menubutton ImageServers] fill_imagesvr_menu $m imagesvr } # Fill up a menu of known data servers to choose from. # The serv_type argument should be one of: "catalog", "archive", "imagesvr". public method fill_imagesvr_menu {m {serv_type "imagesvr"}} { if {[catch {set imagesvr_list [lsort [$w_.im info $serv_type]]} msg]} { error_dialog $msg $w_ return } if {[llength $imagesvr_list]} { foreach i $imagesvr_list { add_menuitem $m command $i \ "Open $serv_type: \"$i\"" \ -command [code $this select_imagesvr $i] } } } # called when an imagesvr ($name) is selected from the menu. public method select_imagesvr {name} { cat::AstroImage::new_imagesvr $name $itk_option(-image) $itk_option(-debug) } # create the ~/.skycat dir if it does not already exists and keep a log # file there. protected method set_logfile {} { global ::env # open log file used to keep track of URLs (for debugging) set dir $env(HOME)/.skycat if {! [file isdirectory $dir]} { catch {mkdir $dir} } set logfile_name_ $dir/log } # quit and close the window public method quit {} { if {$itk_option(-standalone)} { destroy $w_ } else { wm withdraw $w_ } } # add the name server catalogs to the given menu public method get_name_servers {m} { if {[catch {set list [$w_.im info namesvr]} msg]} { error_dialog $msg $w_ return } foreach namesvr_ $list { $m add radiobutton \ -label $namesvr_ \ -command [code $this set_namesvr $namesvr_] \ -variable $m } # set default name server global ::$m set $m $namesvr_ } # do the dialog window layout protected method layout_dialog {} { # create astroimage object astroimage $w_.im add_menubar pack [frame $w_.main] \ -side top -fill both pack [frame $w_.main.top -relief groove -borderwidth 2] \ -side top -fill x pack [set f [frame $w_.main.top.f -relief groove -borderwidth 2]] \ -side top -fill x -pady 1m blt::blttable $f blt::blttable $f \ [set name_ [LabelEntry $f.name \ -text "Object Name:" \ -command [code $this getimage] \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -anchor e \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] \ 0,0 -fill x -pady 1m \ [set equinox_ [LabelEntry $f.equinox \ -text "Equinox:" \ -autoselect 1 \ -value "J2000" \ -command [code $this getimage] \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -anchor e \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] \ 0,1 -fill x -pady 1m \ [set ra_ [LabelEntry $f.ra \ -text "a:" \ -autoselect 1 \ -command [code $this getimage] \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -anchor e \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-wcsfont)]] \ 1,0 -fill x -pady 1m \ [set dec_ [LabelEntry $f.dec \ -text "d:" \ -autoselect 1 \ -command [code $this getimage] \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -anchor e \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-wcsfont)]] \ 1,1 -fill x -pady 1m \ [set width_ [LabelEntry $f.width \ -text "Width in" \ -command [code $this getimage] \ -labelwidth [expr $itk_option(-labelwidth)-3] \ -valuewidth $itk_option(-valuewidth) \ -anchor e \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] \ 2,0 -fill x -pady 1m \ [set height_ [LabelEntry $f.height \ -text "Height in" \ -command [code $this getimage] \ -labelwidth [expr $itk_option(-labelwidth)-3] \ -valuewidth $itk_option(-valuewidth) \ -anchor e \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] \ 2,1 -fill x -pady 1m \ [set setf [frame $f.setf]] \ 3,1 -anchor e -fill x -pady 1m \ [set copyright_ [LabelValue $f.copyright \ -anchor w -relief flat \ -labelwidth 0 -valuewidth 0 \ -valuefont $itk_option(-labelfont)]] \ 4,0 -anchor e -fill x -pady 1m -columnspan 2 # add RA and DEC labels to width and height (different font) pack [label $f.width.ra -text "a:" -font $itk_option(-wcsfont)] \ -side left -after $f.width.label -padx 1 pack [label $f.height.dec -text "d:" -font $itk_option(-wcsfont)] \ -side left -after $f.height.label -padx 2 # add buttons for setting coordinates pack \ [set setfrom_ [button $setf.setfrom \ -text "Set From Image" \ -command [code $this set_default_values]]] \ [set selectarea_ [button $setf.selectarea \ -text "Select Area..." \ -command [code $this select_area]]] \ -side right -padx 1m -pady 2m blt::blttable configure $f C1 -padx 2m # dialog buttons pack [frame $w_.buttons -borderwidth 2 -relief groove] \ -side top -fill x pack \ [button $w_.getimage \ -text "Get Image" \ -command [code $this getimage]] \ [button $w_.stop \ -text "Stop" \ -state disabled \ -command [code $this interrupt]] \ [button $w_.close \ -text "Close" \ -command "wm withdraw $w_" ] \ -side left -expand 1 -pady 2m -in $w_.buttons # set the image server (default if not set) if {"$itk_option(-imagesvr)" == ""} { if {[catch {set imagesvr_list [$w_.im info imagesvr]} msg]} { error_dialog $msg $w_ return } set itk_option(-imagesvr) [lindex $imagesvr_list [expr [llength $imagesvr_list]-1]] } set_imagesvr $itk_option(-imagesvr) # add a help button, if there is a help URL if {"[$w_.im help]" != ""} { pack \ [button $w_.help \ -text "Help" \ -command [code $this help]] \ -side left -expand 1 -pady 2m -in $w_.buttons -before $w_.close } # ProgressBar(n) widget, to display the progress of a query itk_component add progress { ProgressBar $w_.progress } pack $itk_component(progress) -side bottom -fill x } # if the catalog has a "help" URL, try to display it in netscape using the # netscape remote interface. public method help {} { set url [$w_.im help] if {"$url" != ""} { cat::AstroCat::send_to_netscape $url } else { info_dialog "Sorry, no help is available for this image server" } } # add a short help window and set the help texts protected method make_short_help {} { TopLevelWidget::make_short_help add_short_help name_ {SIMBAD object name: resolved via SIMBAD server, if given} add_short_help $equinox_ {World Coordinates equinox, default J2000} add_short_help $ra_ {World Coordinates: right ascension (RA)} add_short_help $dec_ {World Coordinates: declination (DEC)} add_short_help $width_ {Width of image in World Coordinates (arcmin)} add_short_help $height_ {Height of image in World Coordinates (arcmin)} add_short_help $setfrom_ {Set default values from the image} add_short_help $w_.getimage {{bitmap b1} = start image request} add_short_help $w_.close {{bitmap b1} = close this window} add_short_help $w_.stop {{bitmap b1} = interrupt the current image fetch} } # set the name server to use to resolve object names public method set_namesvr {name} { set namesvr_ $name } # interrupt the current request public method interrupt {} { $w_.batch interrupt set_feedback off catch {file delete $itk_option(-tmpfile)} set_state normal } # set/reset widget states while busy public method set_state {state} { set state_ $state if {"$state" == "normal"} { catch {blt::busy release $w_.main} catch {focus -lastfor $w_.main} $w_.getimage config -state normal $w_.stop config -state disabled } else { catch {focus .} catch {blt::busy hold $w_.main} $w_.getimage config -state disabled $w_.stop config -state normal } update idletasks $w_.progress reset } # open or close a pipe to get feedback during HTTP transfers. # (To save limited fds, we close the feedback pipe after each HTTP op). # The arg should be "on" to turn feedback on, or "off" to turn it off. protected method set_feedback {onoff} { # Process any pending file events. # Note: this is important: if we don't process the events before # closing the feedback file, a crash may result. update if {$itk_option(-debug)} { # if -debug was given, the feedback bit wont work, since the # query is done in the foreground and trying to read the feedback # from the pipe may cause the application to hang... return } if {"$onoff" == "on"} { lassign [pipe] rfd_ wfd_ fileevent $rfd_ readable [code $this feedback] $w_.im feedback $wfd_ } elseif {[info exists rfd_]} { ::close $rfd_ ::close $wfd_ unset rfd_ wfd_ $w_.im feedback {} } } # this method is called by the fileevent handler during the image transfer # from the HTTP C++ class to give the user feedback about how much there is # left to copy, etc... # Read a line from the feedback pipe, which should contain text to be displayed # in the progress widget. public method feedback {} { set text [gets $rfd_] if {"$state_" != "normal"} { if {[scan $text {total length: %d bytes} n] == 1} { $w_.progress config -to $n } elseif {[scan $text {read %d bytes} n] == 1} { $w_.progress config -value $n } elseif {[scan $text {url: %s} url] == 1} { catch { set fd [open $logfile_name_ a+] puts $fd "[clock format [clock seconds]]\n$itk_option(-imagesvr)\n$url\n\n" ::close $fd } } } $w_.progress config -text $text update idletasks } # This method is called when the background request is done. # The arguments are the error status (0 is OK) and the result, # which is a list of {filename center-pos copyright} protected method request_done {status result} { set_feedback off if {$status} { # check if we need user/passwd info. errmsg should have the format: # "Authorization Required for at " if {[regsub {Authorization Required} $result {Enter username} msg]} { lassign [passwd_dialog $msg] username passwd if {"$username" != "" && "$passwd" != ""} { lassign $result {} {} {} realm {} host $w_.im authorize $username $passwd $realm $host getimage } } else { set_state normal error_dialog $result $w_ after 0 [list $w_.progress config -text $result] } } else { lassign $result filename pos copyright $w_.progress config -text "Loading Image..." $copyright_ configure -value $copyright update idletasks # load the image if {[catch {$itk_option(-image) config -file $filename} msg]} { error_dialog $msg } catch {file delete $filename} if {[llength $pos] >= 2} { lassign $pos ra dec equinox $ra_ config -value $ra $dec_ config -value $dec $name_ config -value "" } set_state normal } } # set (open) the current image server - called when user selects a # name from the menu public method set_imagesvr {name} { config -imagesvr $name wm title $w_ "$name ($itk_option(-number))" wm iconname $w_ [$w_.im shortname $name] $w_.im open $name $copyright_ configure -value [$w_.im copyright] set image $itk_option(-image) set instance_idx "$name,$image" set instances_($instance_idx) $w_ } # member proc (like a static member function) to create an instance of this # class for the named imagesvr (or reuse the existing one for the imagesvr) # # The args are: # # name - long name of imagesvr from config file # # image - name of skycat itcl image widget # # debug - flag: if true, run queries in foreground # # w should be the top level window of the caller (optional). public proc new_imagesvr {name image debug {w ""}} { set i "$name,$image" if {[info exists instances_($i)] && [winfo exists $instances_($i)]} { utilRaiseWindow $instances_($i) return } # If $w was specified, put the window under that top level window # so we get the window numbers right (for cloning, see TopLevelWidget). if {[winfo exists $w]} { set instname $w.ai[incr n_instances_] } else { set instname .ai[incr n_instances_] } set instances_($i) \ [AstroImage $instname \ -image $image -debug $debug -imagesvr $name -transient 0] } # return a list of the instances of this class public proc instances {} { set list {} if {[info exists instances_]} { foreach i [array names instances_] { if {[winfo exists $instances_($i)]} { lappend list $instances_($i) } } } return $list } # Get the requested image from the image server based on the current options # and display the resulting image (args are ignored here) public method getimage {args} { getimage_from_args \ [$ra_ get] [$dec_ get] [$name_ get] [$equinox_ get] \ [$width_ get] [$height_ get] 0 } # Get the requested image from the image server based on the given arguments # for the world coord position or name and the given width and height # if flag is 1, the entries are updated from the arguments. public method getimage_from_args {ra dec name equinox width height {flag 1}} { if {$flag} { $ra_ config -value $ra $dec_ config -value $dec $name_ config -value $name $equinox_ config -value $equinox $width_ config -value $width $height_ config -value $height } catch {file delete $itk_option(-tmpfile)} # generate a new tmpfile name config -tmpfile {} set cmd "$w_.im getimage -tmpfile $itk_option(-tmpfile)" if {"$equinox" != ""} { lappend cmd "-equinox" $equinox } if {"$name" != ""} { lappend cmd "-nameserver" $namesvr_ "-name" $name } elseif {"$ra" != "" && "$dec" != ""} { lappend cmd "-pos" [list $ra $dec] } else { warning_dialog "Please specify either an object name or a position in WCS" $w_ return } lappend cmd -width $width lappend cmd -height $height # start the request in the background set_state disabled $w_.progress config -text "Attempting to contact image server..." $w_.progress look_busy # set up the feedback pipe set_feedback on $w_.batch bg_eval [code [format { list [%s] [%s.im centerpos] } $cmd $w_]] } # Set the default values for the form entries: # set the default position (RA, DEC) to the image center, public method set_default_values {} { $name_ config -value "" if {[$w_.im iswcs]} { set center [$image_ wcscenter] if {[llength $center] == 0 || [$image_ isclear]} { return } lassign $center ra dec equinox set width [$image_ wcswidth] set height [$image_ wcsheight] set_pos_width_height [list $ra $dec $equinox $width $height] } else { set width [$image_ width] set height [$image_ height] set x [expr $width/2.] set y [expr $height/2.] set_pos_width_height [list $x $y $width $height] } } # set the values for the position, width and height entries from the # given list, which should be in the format {ra dec equinox width height} if # we are using wcs, or {x y width height} for image pixel coords. public method set_pos_width_height {list} { set n [llength $list] if {[$w_.im iswcs] && $n == 5} { # using world coords lassign $list ra dec equinox width height $ra_ config -value $ra $dec_ config -value $dec $equinox_ config -value $equinox $width_ config -value [format "%.2f" $width] $height_ config -value [format "%.2f" $height] } elseif {[$w_.im ispix] && $n == 4} { # using image coords lassign $list x y width height $x_ config -value $x $y_ config -value $y $equinox_ config -value "" $width_ config -value [format "%.2f" $width] $height_ config -value [format "%.2f" $height] } } # Ask the user to select an area to search interactively # and insert the resulting radius and center pos in the # catalog window. public method select_area {} { if {[$image_ isclear]} { return } set_pos_width_height [select_image_area [$w_.im iswcs]] } # convert the given input coordinates in the given input units to the # given output units and return a list {x y} with the new values. # The units may be one of {canvas image wcs deg "wcs $equinox", "deg $equinox"} public method convert_coords {in_x in_y in_units out_units} { return [$image_ convert coords $in_x $in_y $in_units {} {} $out_units] } # convert the given input distance in the given input units to the # given output distance and return a list {x y} with the new values. # The units may be one of {canvas image wcs deg "wcs $equinox", "deg $equinox"} public method convert_dist {in_x in_y in_units out_units} { return [$image_ convert dist $in_x $in_y $in_units {} {} $out_units] } # return the current equinox, or an empty string if the imagesvr does # not support world coordinates. The user can change the equinox used # to display coordinates by typing in a different value in the panel. public method get_imagesvr_equinox {} { if {[$w_.im iswcs]} { set equinox [$equinox_ get] if {"$equinox" == ""} { set equinox J2000 } return $equinox } } # Ask the user to select an area of the image by dragging out a region # on the image return the resulting center pos, width and height as a list of # {x y width height}, or {ra dec equinox width height} if wcs_flag # is 1. An empty string is returned if there is no image or the user # cancels the operation. public method select_image_area {wcs_flag} { if {"$image_" == ""} { return } if {[$image_ isclear]} { error_dialog "No image is currently loaded" return } # get canvas coords of selected area set list [$itk_option(-image) select_area] if {[llength $list] != 4} { return } lassign $list x0 y0 x1 y1 # get center and radius in canvas coords set x [expr ($x0+$x1)/2.] set y [expr ($y0+$y1)/2.] set w [expr abs($x1-$x0)] set h [expr abs($y1-$y0)] if {$wcs_flag} { # using world coords set equinox [get_imagesvr_equinox] if {[catch { lassign [convert_coords $x $y canvas "wcs $equinox" ] ra dec lassign [convert_dist $w $h canvas "deg $equinox" ] width height } msg]} { error_dialog "error converting canvas ($x, $y) to world coordinates: $msg" $w_ return } return [list $ra $dec $equinox [expr $width*60.] [expr $height*60.]] } else { # using image coords if {[catch { lassign [convert_coords $x $y canvas image] xi yi lassign [convert_dist $w $h canvas image] width height } msg]} { error_dialog "error converting canvas ($x, $y) to world coordinates: $msg" $w_ return } return [list $x $y $width $height] } } # -- options -- # default image server name itk_option define -imagesvr imagesvr Imagesvr "dss@eso" # image handle (itcl class: SkyCat or derived) itk_option define -image image Image {} { if {$initialized_} { set canvas_ [$itk_option(-image) get_canvas] set image_ [$itk_option(-image) get_image] set_default_values } } # font to use for labels itk_option define -labelfont labelFont LabelFont TkDefaultFont # font to use for values itk_option define -valuefont valueFont ValueFont TkFixedFont # font to use for ra,dec labels itk_option define -wcsfont wcsFont WcsFont {Symbol -14} # set the width for displaying labels itk_option define -labelwidth labelWidth LabelWidth 14 # set the width for displaying labels itk_option define -valuewidth valueWidth ValueWidth 14 # set the anchor for labels itk_option define -anchor anchor Anchor e # text for label displayed at top itk_option define -title title Title "Image Request Parameters" # flag: if true, run queries in foreground for better debugging itk_option define -debug debug Debug 0 # temp image file to use itk_option define -tmpfile tmpfile Tmpfile {} { if {"$itk_option(-tmpfile)" == ""} { set itk_option(-tmpfile) "/tmp/im[pid].$itk_option(-number).[incr count_]" } } # -- protected members -- # canvas window containing main image protected variable canvas_ # internal rtdimage widget for main image protected variable image_ # name field widget protected variable name_ # equinox field widget protected variable equinox_ # ra field widget protected variable ra_ # dec field widget protected variable dec_ # width field widget protected variable width_ # height field widget protected variable height_ # "set from image" field widget protected variable setfrom_ # copyright field protected variable copyright_ # pipe to read feedback during image transfer protected variable rfd_ # pipe to write feedback during image transfer protected variable wfd_ # name server to use to resolve object names protected variable namesvr_ {} # current state: normal, disabled (i.e.: waiting) protected variable state_ {normal} # log file handle (used to log URLs) protected variable logfile_ stdout # flag: set at end of constructor protected variable initialized_ 0 # count used for filename generation protected variable count_ 0 # log file handle (used to log URLs) protected variable logfile_name_ # -- common variables (shared by all instances) -- # array mapping catalog name to widget/class name protected common instances_ # instance count protected common n_instances_ 0 } skycat-3.1.2-starlink-1b/cat/library/AstroQuery.tcl000066400000000000000000000556451215713201500222110ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # @(#) $Id: AstroQuery.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # AstroQuery.tcl - widget for searching astronomical catalogs. # # See man page AstroQuery(n) for a complete description. # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 05 Jan 98 created itk::usual AstroQuery {} # An AstroQuery widget is defined as a frame containing entries for search # options. itcl::class cat::AstroQuery { inherit util::FrameWidget # constructor constructor {args} { itk_option add hull.borderwidth hull.relief eval itk_initialize $args } # called after options have been evaluated protected method init {} { # set flag to handle image servers differently if {"[$astrocat servtype]" == "imagesvr"} { set iscat_ 0 } else { set iscat_ 1 } add_search_options add_copyright set_short_help # create an object for running interruptable batch queries Batch $w_.batch \ -command [code $this query_done] \ -debug $itk_option(-debug) # set default values set_default_values } # update the search option entries after they have been edited public method update_search_options {} { if {"$search_col_info_" != "[$astrocat searchcols]"} { add_search_options add_copyright set_default_values } } # add (or update) the search options panel protected method add_search_options {} { if {! [winfo exists $w_.options]} { # Options frame itk_component add options { frame $w_.options } { } pack $w_.options \ -side top -fill x pack \ [label $w_.options.head -text "Search Options" ] \ -side top -pady 2 } if {[winfo exists $w_.options.f]} { destroy $w_.options.f } pack [set f [frame $w_.options.f]] \ -side top -fill x set search_opts_ [blt::blttable $f] set search_opts_row_ 0 # if we are using world coords, display name, equinox, ra, dec if {[$astrocat iswcs]} { add_search_option \ [set name_ \ [LabelEntry $f.name \ -text "Object Name:" \ -command $itk_option(-searchcommand) \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] \ [set equinox_ \ [LabelEntry $f.equinox \ -text "Equinox:" \ -value "J2000" \ -autoselect 1 \ -command $itk_option(-searchcommand) \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] add_search_option \ [set ra_ \ [LabelEntry $f.ra \ -text "a:" \ -autoselect 1 \ -command $itk_option(-searchcommand) \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-wcsfont)]] \ [set dec_ \ [LabelEntry $f.dec \ -text "d:" \ -autoselect 1 \ -command $itk_option(-searchcommand) \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-wcsfont)]] } elseif {[$astrocat ispix]} { # if we are using image coords, display x and y add_search_option \ [set x_ \ [LabelEntry $f.x \ -text "X:" \ -autoselect 1 \ -command $itk_option(-searchcommand) \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] \ [set y_ \ [LabelEntry $f.y \ -text "Y:" \ -autoselect 1 \ -command $itk_option(-searchcommand) \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] } if {[$astrocat iswcs] || [$astrocat ispix]} { if {$iscat_} { # add min and max radius items (for catalogs) add_search_option \ [set rad1_ [LabelEntry $f.rad1 \ -text "Min Radius:" \ -command $itk_option(-searchcommand) \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] \ [set rad2_ [LabelEntry $f.rad2 \ -text "Max Radius:" \ -command $itk_option(-searchcommand) \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] } else { # add width and height items (for image servers) add_search_option \ [set width_ [LabelEntry $f.width \ -text "Width:" \ -command $itk_option(-searchcommand) \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] \ [set height_ [LabelEntry $f.height \ -text "Height:" \ -command $itk_option(-searchcommand) \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] } } # display search columns from config entry. If the max value is missing, # assume just one value, otherwise a range: min..max set n 0 set search_col_info_ [$astrocat searchcols] catch {unset min_values_} catch {unset max_values_} set search_cols_ {} foreach col_info $search_col_info_ { if {[llength $col_info] < 2} { error_dialog \ "invalid search_cols entry in config file: \ '$col_info' ([llength $col_info])" $w_ continue } lassign $col_info col minStr maxStr if {"$col" == ""} { error_dialog "missing column value in config file entry: '$col_info'" $w_ continue } if {"$minStr" == ""} { error_dialog "missing min value in config file entry: '$col_info'" $w_ continue } lappend search_cols_ $col set min_values_($col) [LabelEntry $f.min$n \ -text "$minStr:" \ -command $itk_option(-searchcommand) \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)] if {"$maxStr" != ""} { set max_values_($col) [LabelEntry $f.max$n \ -text "$maxStr:" \ -command $itk_option(-searchcommand) \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)] add_search_option $min_values_($col) $max_values_($col) } else { add_search_option $min_values_($col) } incr n } # if the url contains a string such as mag=%m1,%m2, make sure the # user knows the defaults (maybe the servers should be changed?) if {[info exists min_values_(mag)]} { if {[string first {%m2} [$astrocat url]] != -1} { $min_values_(mag) config -value 0 $max_values_(mag) config -value 99 } } # if there were any search options at all... if {$search_opts_row_ > 0} { if {$iscat_} { add_search_option \ [set maxnum_ [LabelEntry $f.maxnum \ -text "Max Objects:" \ -command $itk_option(-searchcommand) \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] } blt::blttable configure $f C1 -padx 2m } else { # no options destroy $w_.options } update idletasks } # add copyright info to the search panel, if present protected method add_copyright {} { set s [$astrocat copyright] if {"$s" != "" && [winfo exists $search_opts_]} { blt::blttable $search_opts_ \ [LabelValue $search_opts_.copyright \ -anchor w -relief flat \ -labelwidth 0 -valuewidth 0 \ -value $s \ -valuefont $itk_option(-labelfont)] \ [incr search_opts_row_],0 -anchor e -fill x -pady 1m -columnspan 2 } } # add a row to the search options panel (blt table). # The args may be one or more widget names to put in a row in the panel. # Each widget is placed in a new column. An empty argument results in an # empty column for that row. If all are empty, the row is left empty. protected method add_search_option {args} { set col 0 foreach w $args { if {"$w" != ""} { blt::blttable $search_opts_ $w $search_opts_row_,$col \ -fill x -pady 1m } incr col } incr search_opts_row_ } # add short help texts to widgets protected method set_short_help {} { if {[$astrocat iswcs]} { add_short_help $name_ {object name: resolved via name server, if given} add_short_help $equinox_ {World Coordinates equinox, default J2000} add_short_help $ra_ {World Coordinates: right ascension (RA)} add_short_help $dec_ {World Coordinates: declination (DEC)} if {$iscat_} { add_short_help $rad1_ {Radius: minimum radius in arcmin for circular search} add_short_help $rad2_ {Radius: maximum radius in arcmin for circular search} add_short_help $maxnum_ {Max number of stars/objects to display} } else { add_short_help $width_ {Width in arcmin of image to get} add_short_help $height_ {Height in arcmin of image to get} } } elseif {[$astrocat ispix]} { add_short_help $x_ {Image coordinates: X value} add_short_help $y_ {Image coordinates: Y value} if {$iscat_} { add_short_help $rad1_ {Radius: minimum radius in pixels for circular search} add_short_help $rad2_ {Radius: maximum radius in pixels for circular search} add_short_help $maxnum_ {Max number of stars/objects to display} } else { add_short_help $width_ {Width in pixels of image to get} add_short_help $height_ {Height in pixels of image to get} } } foreach col $search_cols_ { if {$iscat_} { # add catalog help if {[info exists max_values_($col)]} { add_short_help $min_values_($col) \ "If set, search for rows where $col is greater than this value" add_short_help $max_values_($col) \ "If set, search for rows where $col is less than this value" } else { add_short_help $min_values_($col) \ "If set, search for rows with this $col value" } } else { # add image server help if {[info exists max_values_($col)]} { add_short_help $min_values_($col) \ "If set, fetch an image where $col is greater than this value" add_short_help $max_values_($col) \ "If set, fetch an image where $col is less than this value" } else { add_short_help $min_values_($col) \ "If set, fetch an image with this $col value" } } } } # interrupt the current search public method interrupt {} { $w_.batch interrupt } # start the catalog search based on the current search options # and display the results in the table. public method search {args} { if {$iscat_} { set cmd "$astrocat query" } else { set cmd "$astrocat getimage" } if {[$astrocat iswcs] || [$astrocat ispix]} { set equinox "" if {[$astrocat iswcs]} { set name [$name_ get] set x [$ra_ get] set y [$dec_ get] set equinox [$equinox_ get] } elseif {[$astrocat ispix]} { set name "" set x [$x_ get] set y [$y_ get] } if {$iscat_} { set rad1 [$rad1_ get] set rad2 [$rad2_ get] } else { set width [$width_ get] set height [$height_ get] } if {"$equinox" != ""} { lappend cmd "-equinox" $equinox } if {"$name" != ""} { lappend cmd "-nameserver" $namesvr "-name" $name } elseif {"$x" != "" && "$y" != ""} { lappend cmd "-pos" [list $x $y] } else { #warning_dialog "Please specify either an object name or a position in WCS" $w_ } if {$iscat_} { if {"$rad1" != "" || "$rad2" != ""} { lappend cmd "-radius" "$rad1 $rad2" } set maxnum [$maxnum_ get] if {"$maxnum" != ""} { lappend cmd "-nrows" $maxnum } if {"[set sort_cols [$astrocat sortcols]]" != ""} { lappend cmd "-sort" $sort_cols "-sortorder" [$astrocat sortorder] } } else { if {"$width" != "" || "$height" != ""} { lappend cmd -width $width -height $height } } } # add optional search columns if {"$search_cols_" != ""} { set minvalues {} set maxvalues {} set search_cols {} foreach col $search_cols_ { set min [$min_values_($col) get] if {[catch {set max [$max_values_($col) get]}]} { # if only one value, compare for equality, otherwise range set max $min } if {"$min" == "" && "$max" != "" || "$max" == "" && "$min" != ""} { error_dialog "Please specify min and max values for $col" return } if {"$min" == ""} { continue } lappend search_cols $col lappend minvalues $min lappend maxvalues $max } if {[llength $search_cols]} { lappend cmd -searchcols $search_cols -minvalues $minvalues -maxvalues $maxvalues } } if {"$itk_option(-feedbackcommand)" != ""} { eval $itk_option(-feedbackcommand) on } $w_.batch bg_eval [code $this do_query $cmd] } # return the result of a catalog query. Since this may be run in a separate # process via fork, all of the necessary info is returned in the format: # # {results headings entry querypos more} # # where: # # results are the query results (list of rows) # # headings are the result headings # # entry is the catalog config entry # # querypos is the center pos of the query # # more is a flag, 1 if more rows available # # For image servers, the result of the command is the name of the # file containing the image and the headings field is left empty. protected method do_query {cmd} { if {$iscat_} { return [list [eval $cmd] \ [$astrocat headings] \ [$astrocat entry get] \ [$astrocat querypos] \ [$astrocat more]] } else { return [list [eval $cmd] \ {}\ [$astrocat entry get] \ [$astrocat querypos] \ 0] } } # This method is called when the background query is done. # The arguments are the error status (0 is OK) and the result # of evaluating the Tcl commands. # # The result arg contains a list of items: # # {info headings entry pos more} # # Where: # # info is a list of rows (result of query) # # headings are the column headings # # entry is the catalog config entry (including info from the header # in the query result), # # pos is the query center position (possibly expanded by a name server) # # more is a flag indicating if there were more rows available that were # not returned due to the maxrows limit set. protected method query_done {status result} { if {"$itk_option(-feedbackcommand)" != ""} { eval $itk_option(-feedbackcommand) off } set cmd $itk_option(-command) if {$status} { lappend cmd $result {} {} 0 } else { lassign $result info_ headings_ entry pos more # update the catalog config entry with the entry data from the subprocess # (may have been modified by info in the query result header) $astrocat entry update $entry if {[llength $pos] >= 2} { if {[$astrocat iswcs]} { $name_ config -value "" lassign $pos ra dec equinox $ra_ config -value $ra $dec_ config -value $dec } elseif {[$astrocat ispix]} { lassign $pos x y $x_ config -value $x $y_ config -value $y } } lappend cmd "" $headings_ $info_ $more } # eval caller's command, if there is one if {"$itk_option(-command)" != ""} { eval $cmd } } # Set the default values for the form entries: # set the default position (RA, DEC) to the image center, # set the min radius to 0 and the max radius to the distance # from the center to the origin. public method set_default_values {} { # set the center coords and default radius if {[$astrocat iswcs]} { $name_ config -value "" $ra_ config -value "" $dec_ config -value "" $equinox_ config -value 2000 if {$iscat_} { $rad1_ config -value 0.0 $rad2_ config -value 10.0 $maxnum_ config -value 1000 } else { $width_ config -value 10.0 $height_ config -value 10.0 } } elseif {[$astrocat ispix]} { $x_ config -value "" $y_ config -value "" if {$iscat_} { $rad1_ config -value 0.0 $rad2_ config -value 255.0 $maxnum_ config -value 1000 } else { $width_ config -value 255.0 $height_ config -value 255.0 } } } # return the current equinox, or an empty string if the catalog does # not support world coordinates. The user can change the equinox used # to display coordinates by typing in a different value in the panel. public method get_catalog_equinox {} { if {[$astrocat iswcs]} { set equinox [$equinox_ get] if {"$equinox" == ""} { set equinox J2000 } return $equinox } } # set the values for the position and radius entries from the given # list, which should be in the format {ra dec equinox radius} if # we are using wcs, or {x y radius} for image pixel coords. # This method is only used for catalogs (not image servers). public method set_pos_radius {list} { set n [llength $list] if {[$astrocat iswcs] && $n == 4} { # using world coords lassign $list ra dec equinox radius $ra_ config -value $ra $dec_ config -value $dec $equinox_ config -value $equinox $rad1_ config -value 0.0 $rad2_ config -value $radius } elseif {[$astrocat ispix] && $n == 3} { # using image coords lassign $list x y radius $x_ config -value $x $y_ config -value $y $rad1_ config -value 0.0 $rad2_ config -value $radius } } # Set the values for the position, width and height entries from the # given list, which should be in the format: # {ra dec equinox width height name} # if we are using wcs, or: # {x y width height} for image pixel coords. # Any missing values at the end of the list are treated as blank. # This method is only used for image servers. public method set_pos_width_height {list} { set n [llength $list] if {[$astrocat iswcs] || $n == 5} { # using world coords lassign $list ra dec equinox width height name $ra_ config -value $ra $dec_ config -value $dec $equinox_ config -value $equinox catch {$width_ config -value [format "%.2f" $width]} catch {$height_ config -value [format "%.2f" $height]} $name_ config -value $name } elseif {[$astrocat ispix] || $n == 4} { # using image coords lassign $list x y width height $x_ config -value $x $y_ config -value $y $equinox_ config -value "" catch {$width_ config -value [format "%.2f" $width]} catch {$height_ config -value [format "%.2f" $height]} } } # get the values from the position and radius entries and return # a list in the format {ra dec equinox radius} if we are using wcs, # or {x y radius} for image pixel coords. public method get_pos_radius {} { if {[$astrocat iswcs]} { # using world coords return [list [$ra_ get] [$dec_ get] [$equinox_ get] [$rad2_ get]] } elseif {[$astrocat ispix]} { # using image coords return [list [$x_ get] [$y_ get] [$rad2_ get]] } } # Return the value in the equinox entry, of 2000 if there isn't one. public method get_equinox {} { if {[$astrocat iswcs]} { # using world coords return [$equinox_ get] } else { # using image coords return "2000" } } # -- options -- # Specify the command to evaluate with the results of a query. # The command is evaluated whenever a query is done with the # following args: # # errmsg - If this is not empty, it contains an error message and # the following args should be ignored. If there were no # errors, this arg is an empty string. # # headings - are the column headings # # info - is a list of rows (result of query) # # more - is a flag set to 1 if there were more rows available that were # not returned due to the maxrows limit set. itk_option define -command command Command {} # Specify the command to call to open and close a pipe used to give # feedback during HTTP transfers. The command takes 1 arg: "on" or "off". itk_option define -feedbackcommand feedbackCommand FeedbackCommand {} # Specify the search command to evaluate when the user types # (Can be used to set button states, etc. Defaults to [code $this search]) itk_option define -searchcommand searchCommand SearchCommand {} { if {"$itk_option(-searchcommand)" == ""} { set itk_option(-searchcommand) [code $this search] } } # font used for labels itk_option define -labelfont labelFont LabelFont TkDefaultFont # font used for values itk_option define -valuefont valueFont ValueFont TkFixedFont # font used for ra,dec labels itk_option define -wcsfont wcsFont WcsFont {Symbol -14} # set the width for displaying labels itk_option define -labelwidth labelWidth LabelWidth 15 # set the anchor for labels itk_option define -anchor anchor Anchor e # flag: if true, run queries in foreground for better debugging itk_option define -debug debug Debug 0 # -- public variables -- # astrocat (C++ based) object for accessing catalogs public variable astrocat # name server to use to resolve object names public variable namesvr {} # -- protected variables -- # blt table for search options protected variable search_opts_ # current row number for $search_opts_ protected variable search_opts_row_ 0 # saved value of catalog search_cols_ entry, for comparison protected variable search_col_info_ {} # widget name for name field protected variable name_ # widget name for equinox field protected variable equinox_ # widget name for RA field protected variable ra_ # widget name for DEC field protected variable dec_ # widget name for X field protected variable x_ # widget name for Y field protected variable y_ # widget name for min radius field protected variable rad1_ # widget name for max radius field protected variable rad2_ # widget name for image width field protected variable width_ # widget name for image height field protected variable height_ # widget name for "max number of objects" field protected variable maxnum_ # list of columns to search by protected variable search_cols_ {} # array(colName) of widget name for search column min fields protected variable min_values_ # array(colName) of widget name for search column max fields protected variable max_values_ # copyright field protected variable copyright_ # flag: true if catalog is not an image server protected variable iscat_ 1 } skycat-3.1.2-starlink-1b/cat/library/CatInit.tcl000066400000000000000000000007511215713201500214120ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: # # CatInit.tcl # # script which is executed by TclAstroCat.C to initialize tcl # # who when what # -------- --------- ---------------------------------------------- # pbiereic 24/08/99 created package require img::xpm package require Tclutil package require Astrotcl if {![lcontain $auto_path $cat_library]} { lappend auto_path $cat_library } namespace eval cat {namespace export *} namespace import -force cat::* skycat-3.1.2-starlink-1b/cat/library/CatalogInfo.tcl000066400000000000000000000424301215713201500222450ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # "@(#) $Id: CatalogInfo.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # CatalogInfo.tcl - widget for browsing through a hierarchical list of catalogs # # See man page CatalogInfo(n) for a complete description. # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 14 Oct 97 created itk::usual CatalogInfo {} # The CatalogInfo class defines a user interface for browsing through a # hierarchical list of catalogs. The list of catalogs is defined in catalog # config files at various hosts on the network or in local catalog config files. # This widget allows you to choose, from various catalog servers on the net, # which catalogs to keep in a personal default catalog list. itcl::class cat::CatalogInfo { inherit util::TopLevelWidget # constructor constructor {args} { eval itk_initialize $args } # destructor - delete C++ based objects so that the temp image # files are deleted destructor { catch {destroy $tree_} } # called after options have been evaluated protected method init {} { global ::cat_library # if running stand-alone, setup X defaults if {$itk_option(-standalone)} { cat::setXdefaults } wm title $w_ "Catalog Directory ($itk_option(-number))" wm iconname $w_ "Catalog Directory" # set the strings to display for server types set serv_types_(local) "local catalog" set serv_types_(directory) "directory" set serv_types_(catalog) "catalog" set serv_types_(archive) "archive" set serv_types_(imagesvr) "image server" set serv_types_(namesvr) "name server" set images_(local) [image create photo -file $cat_library/local.xpm] set images_(directory) [image create photo -file $cat_library/nsfolder.xpm] set images_(open_directory) [image create photo -file $cat_library/nsopenfold.xpm] set images_(catalog) [image create photo -file $cat_library/catalog.xpm] set images_(archive) [image create photo -file $cat_library/archive.xpm] set images_(imagesvr) [image create photo -file $cat_library/imagesvr.xpm] set images_(namesvr) [image create photo -file $cat_library/namesvr.xpm] # do window layout if {[layout_dialog]} { destroy $w_ return } # add a short help window make_short_help set initialized_ 1 } # add the menu bar protected method add_menubar {} { TopLevelWidget::add_menubar set m [add_menubutton File "Display File menu"] set file_menu_ $m add_menuitem $m command "Load config file..." \ {Load a local catalog configuration file and insert it in the catalog list.} \ -command [code $this load_config_file] add_menuitem $m command "Save to config file..." \ {Save catalog configuration information to a file.} \ -command [code cat::CatalogInfo::save_as $w_] $m add separator add_menuitem $m command "Close" \ {Apply changes and close this window} \ -command [code $this close] cat::AstroCat::add_catalog_menu $w_ $itk_option(-id) \ $itk_option(-classname) $itk_option(-debug) } # Apply the current changes, save to default file, call $command public method apply {{ask 0}} { if {$save_needed_} { if {!$ask || [confirm_dialog \ "Do you want to save your changes in the default catalog \ config file (~/.skycat/skycat.cfg)?" $w_]} { save {} $w_ $ask } if {"$command" != ""} { eval $command } } } # apply changes and close the window public method close {{ask 0}} { # apply $ask quit } # pop up a dialog to save the current info to a catalog config file # Note: this is defined as a proc so that it can be accessed by other # widgets without this widget being created first. $w should be the main # window of the calling widget. public proc save_as {w} { set file [filename_dialog [pwd] * $w] if {"$file" != ""} { save $file $w } } # save current config info to the given file, or if file is an empty # string, to the default config file. public proc save {file w {ask 1}} { global ::env set default_file $env(HOME)/.skycat/skycat.cfg if {"$file" == ""} { set file $default_file } set update 0 if {"$file" == "$default_file"} { incr update } elseif {$ask && [file isfile $file]} { if {![confirm_dialog "File: `[file tail $file]' exists \ - Do you want to overwrite it ?" $w]} { return } } if {[file isdir $file]} { error_dialog "File: `[file tail $file]' is a directory" $w return } # get the default catalog list if {[catch {set catalog_list [lsort [$astrocat_ info {}]]} msg]} { error_dialog $msg $w return } # use a temp file in case of errors if {[catch {set fd [open $file.tmp w]} msg]} { error_dialog $msg $w return } puts $fd "# Catalog config file" puts $fd "# This file was automatically generated by Skycat on [clock format [clock seconds]]" puts $fd "" foreach name $catalog_list { if {[catch {set entry [$astrocat_ entry get $name]} msg]} { error_dialog $msg $w ::close $fd catch {file delete $file.tmp} return } puts $fd "" foreach line $entry { lassign $line key value if {"$value" != ""} { if {"$key" == "symbol" || "$key" == "search_cols"} { puts $fd [format "%-15s %s" $key: [join $value " : "]] } else { puts $fd [format "%-15s %s" $key: $value] } } } } ::close $fd # backup $file, then rename $file.tmp to $file if {[file exists $file]} { if {[catch {file rename -force $file $file.BAK} msg]} { error_dialog $msg $w catch {file delete $file.tmp} return } } if {[catch {file rename -force $file.tmp $file} msg]} { error_dialog $msg $w catch {file delete $file.tmp} return } set save_needed_ 0 # tell widgets to update the catalog menus if {$update} { cat::AstroCat::update_catalog_menus } } # do the dialog window layout protected method layout_dialog {} { add_menubar add_tree_frame add_dialog_buttons init_tree return 0 } # add a frame for displaying a tree of catalog servers and catalogs # inside the given frame and side protected method add_tree_frame {} { set tf [frame $w_.tf] set tree_ $tf.tree set vs [scrollbar $w_.vs -orient vertical -command "$tree_ yview"] set hs [scrollbar $w_.hs -orient horizontal -command "$tree_ xview"] set rootdir_ [$astrocat_ root] treeview $tree_ \ -separator $sep_ \ -autocreate no \ -allowduplicates no \ -hideroot yes \ -selectcommand [code $this select_catalog] \ -yscrollcommand "$vs set" \ -xscrollcommand "$hs set" $tree_ column configure treeView -text Name $tree_ column insert end type -text Type -justify left $tree_ sort auto yes table $tf \ 0,0 $tree_ -fill both \ 0,1 $vs -fill y \ 1,0 $hs -fill x table configure $tf c1 r1 r2 -resize none pack $tf -side top -fill both -expand 1 } # initialize the tree of catalogs protected method init_tree {} { # add the root of the tree set id [add_node {} $rootdir_] open_catalog_directory $rootdir_ $id } # Add a node to the catalog tree. "path" is the path to the parent # of the new node in the format "a${sep_}b${sep_}c" where a is the # root and c is immediate parent of the new node. "name" is the name # of the new node and the text to display. protected method add_node {path name} { if {[string first $sep_ $name] != -1} { puts "invalid catalog '$name', contains invalid char: '$sep_'" return } if {"$path" == ""} { set newpath $name } else { set newpath "$path${sep_}$name" } set text $name set dirPath [split $path $sep_] # get server type and display string for it if {[catch {set serv_type [$astrocat_ servtype $name $dirPath]} msg]} { error_dialog $msg $w_ return } if {[info exists serv_types_($serv_type)]} { set type $serv_types_($serv_type) } else { set type $serv_type } # set icon to display if {[catch {set image $images_($serv_type)}]} { set image $images_(local) } if {"$serv_type" == "local"} { set text [file tail $name] } # add the node and server type set node [$tree_ insert end $newpath] $tree_ entry configure $node -data "type $serv_type" $tree_ entry configure $node \ -icons "$image $image" \ -activeicons "$image $image" $tree_ bind $node [code $this node_action $node $path $name $serv_type] return $node } # called for double click on a tree node protected method node_action {id path name serv_type} { if {"$serv_type" == "directory"} { open_catalog_directory $path${sep_}$name $id } else { open_catalog } } # called when a tree node is opened protected method open_catalog_directory {path id} { # get name and type of selected catalog if {"$path" == "$rootdir_"} { set name $rootdir_ set dirPath "" } else { set list [split $path $sep_] set name [lindex $list end] set dirPath [lrange $list 0 [expr [llength $list]-2]] } # catalog directory - add list of catalogs, or show existing list set children [$tree_ entry children $id] if {[llength $children] == 0} { # get and display list of catalogs under this node busy { set dirPath [split $path $sep_] set status [catch {set catalog_list [lsort [$astrocat_ info {} $dirPath]]} msg] } if {$status} { error_dialog $msg $w_ return } foreach i $catalog_list { add_node $path $i } $tree_ open $id # change the directory icon $tree_ entry configure $id \ -opencommand [code $this opened_catalog_directory $id] \ -closecommand [code $this closed_catalog_directory $id] opened_catalog_directory $id } # scroll so that the selected directory is at the top of the window #$tree_ yview $id } # Called when a catalog directory node is opened protected method opened_catalog_directory {id} { set image $images_(open_directory) $tree_ entry configure $id \ -icons "$image $image" \ -activeicons "$image $image" } # Called when a catalog directory node is closed protected method closed_catalog_directory {id} { set image $images_(directory) $tree_ entry configure $id \ -icons "$image $image" \ -activeicons "$image $image" } # add the dialog button frame protected method add_dialog_buttons {} { # dialog buttons pack [frame $w_.buttons -borderwidth 2 -relief raised] \ -side top -fill x pack \ [button $w_.add \ -text "Add" \ -state disabled \ -command [code $this add_catalog]] \ [button $w_.remove \ -text "Remove" \ -state disabled \ -command [code $this remove_catalog]] \ [button $w_.open \ -text "Open" \ -state disabled \ -command [code $this open_catalog]] \ [button $w_.close \ -text "Close" \ -command [code $this close]] \ -side left -expand 1 -padx 8m -pady 2m -in $w_.buttons } # called when a catalog is selected in the catalog list. protected method select_catalog {} { set id [$tree_ curselection] if {$id == ""} { return } set path [$tree_ get -full $id] set catalog_id_ $id set catalog_path_ [split $path $sep_] set catalog_dir_ [lrange $catalog_path_ 0 [expr [llength $catalog_path_]-2]] set catalog_ [lindex $catalog_path_ end] if {[catch {set serv_type [$astrocat_ servtype $catalog_ $catalog_dir_]} msg]} { error_dialog $msg $w_ return } if {"$serv_type" == "directory"} { $w_.open config -state disabled } else { $w_.open config -state normal } if {"$rootdir_${sep_}$catalog_" == "$path"} { $w_.add config -state disabled $w_.remove config -state normal } else { $w_.add config -state normal $w_.remove config -state disabled } } # open a window to search the selected catalog protected method open_catalog {args} { if {[catch {set serv_type [$astrocat_ servtype $catalog_ $catalog_dir_]} msg]} { error_dialog $msg $w_ return } cat::AstroCat::new_catalog \ $catalog_ \ $itk_option(-id) \ $itk_option(-classname) \ $itk_option(-debug) \ 0 \ $serv_type \ $itk_option(-callerw) \ $catalog_dir_ } # add a short help window and set the help texts protected method make_short_help {} { TopLevelWidget::make_short_help add_short_help $tree_ \ "Catalog list: {bitmap b1} = open and display catalog server contents, \ double-click to open a catalog window" add_short_help $w_.add {Add the selected catalog to the default list} add_short_help $w_.remove {Remove the selected catalog from the default list} add_short_help $w_.open {Open the selected catalog for searching} add_short_help $w_.close {Close: close this window} } # add the selected catalog to the catalog list protected method add_catalog {} { if {[catch {set e [$astrocat_ entry get $catalog_ $catalog_dir_]} msg]} { error_dialog $msg $w_ return } if {[catch {set shortName [$astrocat_ shortname $catalog_ $catalog_dir_]} msg]} { error_dialog $msg $w_ return } # get the current default catalog list if {[catch {set catalog_list [lsort [$astrocat_ info {}]]} msg]} { error_dialog $msg $w_ return } # check for duplicates foreach i $catalog_list { if {"$i" == "$catalog_"} { if {! [confirm_dialog \ "\"$catalog_\" is already in the default catalog list. \ Do you want to replace it?"]} { return } # update the entry definition if {[catch {$astrocat_ entry set $e $catalog_ $rootdir_} msg]} { error_dialog $msg $w_ return } incr save_needed_ return } else { if {[catch {set s [$astrocat_ shortname $i]} msg]} { error_dialog $msg $w_ return } if {"$s" == "$shortName"} { error_dialog "short name '$s' for '$catalog_' is not unique" $w_ return } } } # add the catalog to the default list if {[catch {$astrocat_ entry add $e} msg]} { error_dialog $msg $w_ return } # add the new entry to the tree (in sort order) insert_node $catalog_ incr save_needed_ apply } # insert the given catalog in the tree under the root, if it is # not already there. public method insert_node {name} { catch {add_node $rootdir_ $name} } # remove the selected catalog from the catalog list protected method remove_catalog {} { # if this is a directory... if {[catch {set serv_type [$astrocat_ servtype $catalog_ $catalog_dir_]} msg]} { error_dialog $msg $w_ return } if {[catch {$astrocat_ entry remove $catalog_} msg]} { error_dialog $msg $w_ return } $tree_ delete $catalog_id_ $w_.add config -state disabled $w_.remove config -state disabled $w_.open config -state disabled incr save_needed_ apply } # Pop up a dialog to open and load a catalog config file protected method load_config_file {} { set file [filename_dialog [pwd] * $w_] if {"$file" != ""} { if {[file isfile $file]} { if {[file isdir $file]} { error_dialog "File: `[file tail $file]' is a directory" $w_ return } } set name [input_dialog \ "Please enter a descriptive name for the new catalog directory:" \ $w_] if {"$name" == ""} { set name [file rootname [file tail $file]] } if {[catch {$astrocat_ load $file $name} msg]} { error_dialog $msg $w_ } insert_node $name incr save_needed_ apply } } # -- options -- # command to eval when done public variable command {} # debugging flag itk_option define -debug debug Debug 0 # Optional unique id, used in searching for already existing catalog widgets. itk_option define -id id Id "" # Optional: name of caller's top level widget. itk_option define -callerw callerw Callerw "" # name of a subclass of AstroCat to use to create new catalog widgets itk_option define -classname classname Classname "" # font to use for labels itk_option define -labelfont labelFont LabelFont TkDefaultFont # font to use for values itk_option define -valuefont valueFont ValueFont TkFixedFont # set the width for displaying labels itk_option define -labelwidth labelWidth LabelWidth 10 # set the anchor for labels itk_option define -anchor anchor Anchor e # -- protected variables -- # tree widget protected variable tree_ # array(serv_type) of server type text to display protected variable serv_types_ # array(serv_type) of image to display in tree node protected variable images_ # name of the root catalog directory protected variable rootdir_ # name of currently selected catalog protected variable catalog_ # id of currently selected catalog protected variable catalog_id_ # full path name of currently selected catalog protected variable catalog_path_ # currently selected catalog directory (as a list of catalog directories in the path) protected variable catalog_dir_ # set to true if the catalog configuration has been edited and needs to be saved protected variable save_needed_ 0 # separator char for tree widget (used in catalog path names) protected variable sep_ "^" # C++ astrocat object used by static member procs common astrocat_ [astrocat ::cat::.cataloginfo] } skycat-3.1.2-starlink-1b/cat/library/EnterObject.tcl000066400000000000000000000031011215713201500222530ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # @(#) $Id: EnterObject.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # EnterObject.tcl - Widget for entering data to add to a local catalog. # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 26 Jun 96 created itk::usual EnterObject {} # EnterObject is a dialog widget for entering object data to add to a # local catalog. itcl::class cat::EnterObject { inherit util::EntryForm # constructor constructor {args} { eval itk_initialize $args } # called after options have been evaluated protected method init {} { EntryForm::init wm title $w_ "Enter Object ($itk_option(-number))" if {"$itk_option(-image)" != ""} { $itk_component(buttons) append \ "Pick object..." \ [code $this pick_object] } } # this method is called to pop up a dialog to allow the user to pick # an object in the image public method pick_object {} { if {"$itk_option(-image)" != ""} { if {[catch {set list [$itk_option(-image) pick_dialog [code $this picked_object]]} msg]} { error_dialog $msg return } } } # this is called when an object has been selected with the pick dialog public method picked_object {list} { lassign $list x y ra dec equinox fwhmX fwhmY symetry object background set_entry ra $ra set_entry dec $dec } # -- options -- # optional image handle (itcl class RtdImage or derived class) itk_option define -image image Image {} # -- protected vars -- } skycat-3.1.2-starlink-1b/cat/library/PreviewPlot.tcl000066400000000000000000000132601215713201500223360ustar00rootroot00000000000000# E.S.O. - VLT project # "@(#) $Id: PreviewPlot.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # PreviewPlot.tcl - Widget for displaying a graph of tab table data # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 05 Aug 96 Created itk::usual PreviewPlot {} # PreviewPlot is an itcl widget for displaying a graph of tab table data, such # as that returned from a "Preview" URL in catalogs such as the HST. itcl::class cat::PreviewPlot { inherit util::TopLevelWidget # constructor: create a new instance of this class constructor {args} { eval itk_initialize $args wm minsize $w_ 10 10 wm title $w_ "$itk_option(-name) ($itk_option(-number))" # create astrocat object to manage tab table astrocat $w_.cat make_graph make_buttons make_short_help plot $itk_option(-file) } # destructor - clean up when deleted destructor { global ::tcl_version # delete the catalog object catch {$w_.cat delete} if {$tcl_version >= 8.0} { blt::vector destroy $xVector_ $yVector_ } } # make the graph subwindow protected method make_graph {} { global ::tcl_version # note: make the graph in the global namespace for now so that # the old blt utils (features.tcl) still work. Shouldn't be needed # with blt-2.0 or later... set cmd \ [list blt::graph $w_.graph \ -width 8i \ -height 5i \ -borderwidth 3 \ -relief groove \ -title "Preview Data for $itk_option(-name)" ] # BLT graph widget itk_component add graph { set graph_ [uplevel "#0" $cmd] } { } pack $itk_component(graph) \ -fill both -expand 1 -padx 1m -pady 1m add_short_help $itk_component(graph) \ {Graph: plot of preview data for object {bitmap dragb1} = zoom, {bitmap b2} = restore} # blt2.4f vector names ust start with a letter, no dots... # Also, they changed the default symbol to circle. Why? regsub -all {\.} v$graph_.xVector _ xVector_ regsub -all {\.} v$graph_.yVector _ yVector_ global $xVector_ $yVector_ if {$tcl_version >= 8.0} { $graph_ legend config -hide 1 if {![info exists $xVector_]} { blt::vector create $xVector_ $yVector_ } set symbol {} } else { $graph_ legend config -mapped 0 if {![info exists $xVector_]} { blt::vector $xVector_ $yVector_ } set symbol none } $graph_ element create elem -xdata $xVector_ -ydata $yVector_ -symbol $symbol # add BLT features ::Blt_ZoomStack $graph_ ::Blt_ActiveLegend $graph_ ::Blt_Crosshairs $graph_ ::Blt_ClosestPoint $graph_ bind bltCrosshairs \ "catch {$this dispXY %x %y; %W crosshairs configure -position @%x,%y}" # X,Y position frame itk_component add fpos { frame $w_.fpos -relief flat } # X position label. itk_component add xpos { label $itk_component(fpos).xpos -width 20 -anchor w } # Y position label itk_component add yval { label $itk_component(fpos).yval -width 20 -anchor w } pack $itk_component(xpos) $itk_component(yval) -fill x -expand 0 -side left pack $itk_component(fpos) -fill none -expand 0 } # plot the data in the file public method plot {file} { if {! [file exists $file]} { error_dialog "no preview file was specified to plot" return } if {[catch {$w_.cat open $file} msg]} { error_dialog $msg $w_ return } set x {} set y {} lassign [$w_.cat headings] x y $graph_ xaxis configure -title $x $graph_ yaxis configure -title $y global $xVector_ $yVector_ if {[catch { set numValues_ [$w_.cat plot $graph_ elem $file $xVector_ $yVector_] } msg]} { error_dialog "can't plot results: $msg" } # remove the temporary local catalog entry $w_.cat entry remove $itk_option(-file) } # display x, y values at cursor position protected method dispXY {x y} { global $yVector_ if {![$graph_ element closest $x $y "" -interpolate 1 -halo 10000]} { return } lassign [$graph_ invtransform $x $y] x y set x [expr int(round($x))] if {$x < 1 || $x >= $numValues_} { return } set yval [$yVector_ range $x $x] $itk_component(xpos) config -text "X: $x" $itk_component(yval) config -text "Value: $yval" } # make a hard copy of the graph display public method print {} { utilReUseWidget GraphPrint $w_.print -graph $graph_ } # make the button frame at the bottom of the window protected method make_buttons {} { pack [set b [frame $w_.buttons -borderwidth 2 -relief groove]] \ -side top -fill x pack \ [button $b.print -text "Print..." -command [code $this print]] \ [button $b.close -text "Close" -command [code $this quit]] \ -side left -expand 1 -padx 2m -pady 2m } # quit the window public method quit {} { catch {destroy $w_} } # add a short help window and set the help texts protected method make_short_help {} { TopLevelWidget::make_short_help add_short_help $graph_ {Graph: drag {bitmap dragb1} to zoom in, press {bitmap b3} to zoom back out} add_short_help $w_.buttons.print "Print: display a dialog window to print the graph \ to a postscript file or printer." add_short_help $w_.buttons.close "Close this window." } # -- options -- # file containing preview data in tab table format itk_option define -file file File {} # name of object/star (for title) itk_option define -name name Name {} # -- protected vars -- # name of graph widget protected variable graph_ # number of values displayed protected variable numValues_ 0 # x vector for graph protected variable xVector_ # y vector for graph protected variable yVector_ } skycat-3.1.2-starlink-1b/cat/library/ProxyDialog.tcl000066400000000000000000000107161215713201500223220ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # @(#) $Id: ProxyDialog.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # ProxyDialog.tcl - user interface class for defining a proxy server # for HTTP access. # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 26 Jun 98 created # P.W.Draper 05 Sep 08 modified some of the text descriptions itk::usual ProxyDialog {} itcl::class cat::ProxyDialog { inherit util::TopLevelWidget # constructor constructor {args} { eval itk_initialize $args } # called after options have been evaluated protected method init {} { global ::env wm title $w_ Proxies if {"$itk_option(-configfile)" == ""} { config -configfile $env(HOME)/.proxies } pack [message $w_.proxymsg \ -width 6.5i \ -padx 1m \ -anchor c \ -text "You may need to use a proxy server to access \ remote catalogs via HTTP.\ Please enter the hostname and port number for the proxy \ server:"] \ -side top -anchor w -pady 3m pack [set f [frame $w_.proxyf]] \ -side top -anchor w -fill x -pady 2m pack [LabelEntry $w_.proxy \ -text "HTTP Proxy server:" \ -anchor e \ -valuewidth 32] \ -side left -fill x -in $f pack [LabelEntry $w_.port \ -text "Port:" \ -anchor e \ -valuewidth 8] \ -side left -in $f pack [message $w_.noproxymsg \ -width 6.5i \ -padx 1m \ -anchor w \ -text "Below you can specify a list of domains for which no proxy \ server is needed (separate names by space or comma):"] \ -side top -anchor w -pady 3m pack [LabelEntry $w_.noproxy \ -text "No proxy for:" \ -anchor e] \ -side top -fill x -anchor w -pady 2m # add buttons pack [frame $w_.buttons -borderwidth 2 -relief raised] \ -side top -fill x -pady 2m pack \ [button $w_.ok \ -text "OK" \ -command [code $this ok]] \ [button $w_.reset \ -text "Reset" \ -command [code $this reset]] \ [button $w_.clear \ -text "Clear" \ -command [code $this clear]] \ [button $w_.cancel \ -text "Cancel" \ -command [code $this cancel]] \ -side left -expand 1 -pady 2m -in $w_.buttons # set values reset } # called when the OK button is pressed protected method ok {} { global ::env set proxy [string trim [$w_.proxy get]] set port [string trim [$w_.port get]] set noproxy [string trim [$w_.noproxy get]] if {"$proxy" != ""} { if {"$port" == ""} { set env(http_proxy) "http://$proxy/" } else { set env(http_proxy) "http://$proxy:$port/" } set env(http_noproxy) $noproxy set fd [open $itk_option(-configfile) w] puts $fd "http_proxy: $env(http_proxy)" puts $fd "http_noproxy: $env(http_noproxy)" close $fd } else { catch {file delete $itk_option(-configfile)} catch {unset env(http_proxy)} catch {unset env(http_noproxy)} } wm withdraw $w_ } # called when the Reset button is pressed protected method reset {} { global ::env set proxy {} set port {} set noproxy {} if {[info exists env(http_proxy)]} { if {[scan $env(http_proxy) {http://%[^:/]:%d} proxy port] != 2} { scan $env(http_proxy) {http://%[^:/]} proxy } } if {[info exists env(http_noproxy)]} { set noproxy $env(http_noproxy) } $w_.proxy config -value $proxy $w_.port config -value $port $w_.noproxy config -value $noproxy } # called when the Clear button is pressed protected method clear {} { $w_.proxy config -value {} $w_.port config -value {} $w_.noproxy config -value {} } # called when the Cancel button is pressed protected method cancel {} { wm withdraw $w_ } # Read the given config file (created by this class, see "ok" method) # and use it to initialize the environment variables for a proxy server # (see tclutil/util/src/HTTP.C). public proc check_proxies {file} { global ::env if {[file exists $file]} { set fd [open $file] while {[gets $fd line] != -1} { if {[regsub {http_proxy: (.*)} $line {\1} http_proxy]} { set env(http_proxy) $http_proxy } elseif {[regsub {http_noproxy: (.*)} $line {\1} http_noproxy]} { set env(http_noproxy) $http_noproxy } } close $fd } } # -- options -- # set the width for displaying labels itk_option define -configfile configFile ConfigFile {} } skycat-3.1.2-starlink-1b/cat/library/QueryResult.tcl000066400000000000000000000172341215713201500223670ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # @(#) $Id: QueryResult.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # QueryResult.tcl - Widget for viewing the results of a catalog query. # # See man page QueryResult(n) for a complete description. # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 5 Jan 98 created # A QueryResult widget frame is defined as a TableList (see TableList(n) # in the tclutil package) with some methods added for catalog # support. It is used to display the results of a catalog query. See # also AstroQuery(n) for the query paramaters, AstroCat(n) for the main # window or classes derived from these in the skycat package. # These classes do not deal with images - only catalog data. See the # derived classes in the skycat package for image support. itcl::class cat::QueryResult { inherit util::TableList # constructor constructor {args} { eval itk_initialize $args } # pop up a dialog to sort the list public method sort_dialog {} { if {[llength $headings_] == 0} { info_dialog "Please make a query first so that the column names are known" $w_ return } TableList::sort_dialog } # This method is called whenever a result row is selected. # If the row edit window exists, update it with the values for # the new row. public method select_result_row {} { if {[winfo exists $w_.ef]} { $w_.ef configure -values [lindex [get_selected] 0] } } # pop up a dialog to select table columns to display public method select_columns {} { if {[llength $headings_] == 0} { info_dialog "Please make a query first so that the column names are known" $w_ return } TableList::layout_dialog } # reset table dialogs if needed public method reset {} { foreach w "$w_.tblsort $w_.tblcfg" { if {[winfo exists $w]} { $w reset } } $astrocat showcols {} $astrocat sortcols {} } # save the current data to a local catalog public method save_as {} { set file [filename_dialog [pwd] * $w_] if {"$file" != ""} { if {[file isfile $file]} { if {![confirm_dialog "File: `[file tail $file]' exists \ - Do you want to overwrite it ?" $w_]} { return } if {[file isdir $file]} { error_dialog "File: `[file tail $file]' is a directory" $w_ return } } save_to_file $file $info_ $headings_ } } # add the rows in the current listing to a local catalog file public method add_to {} { if {[llength $info_] == 0} { error_dialog "There are no rows to save" $w_ return; } add_rows $info_ $headings_ } # add the currently selected rows to a local catalog file public method add_selected {} { set info [get_selected] if {[llength $info] == 0} { error_dialog "No rows are selected" $w_ return; } add_rows $info $headings_ } # add the given info rows (result of a query) to a local catalog file with # the given headings. The user selects the name of the catalog file. public method add_rows {info headings} { if {[llength $headings] == 0} { error_dialog "There is no data to save" $w_ return; } set file [filename_dialog [pwd] * $w_] if {"$file" != ""} { if {! [file isfile $file]} { if {[confirm_dialog "File: `[file tail $file]' does not exists \ - Do you want to create it ?" $w_]} { save_to_file $file $info $headings } } else { if {[file isdir $file]} { error_dialog "File: `[file tail $file]' is a directory" $w_ return } save_to_file $file $info $headings 1 } } } # remove the currently selected rows from a local catalog file public method remove_selected {} { set file [$astrocat longname] set info [get_selected] if {[llength $info] == 0} { error_dialog "No rows are selected" $w_ return; } if {! [confirm_dialog "Remove selected objects?" $w_]} { return } if {[catch {$astrocat remove $file $info $equinox $headings_} msg]} { error_dialog $msg $w_ return } } # save the given info (the result of query) to the given catalog file, # using the given column headings. # If iflag is 1, insert rows in the existing file. public method save_to_file {file info headings {iflag 0}} { if {[catch {$astrocat save $file $iflag $info $equinox $headings} msg]} { error_dialog "error saving rows to file: $msg" $w_ return 1 } return 0 } # Pop up a dialog to enter the data for a new object for a local catalog. # The command is evaluated after the users enters the new data. public method enter_new_object {{command ""}} { catch {delete object $w_.ef} EnterObject $w_.ef \ -title {Please enter the data for the object below:} \ -labels $headings_ \ -center 0 \ -command [code $this enter_object $command] } # check that the given row contains valid data for a catalog # and return 0 if OK public method check_row {data} { if {[catch {$astrocat checkrow $data} msg]} { error_dialog $msg return 1 } return 0 } # This method is called with the data for a new object to add to a local # catalog. The row is added to the local catalog file and the # command is evaluated. If a row with the given id already exists, it is # updated (after confirmation). public method enter_object {command info} { if {[check_row $info]} { return } # see if this id already exists... set id [lindex $info [$astrocat id_col]] set row [lindex [$astrocat query -id $id] 0] set file [$astrocat longname] set append 1 if {[llength $row]} { if {"$row" == "$info"} { info_dialog "No changes were made to $id." return } # object with this id already exists if {! [confirm_dialog "Update object $id ?" $w_]} { return } # replace with new data if {[save_to_file $file [list $info] $headings_ $append] != 0} { return } } else { # must be a new object if {! [confirm_dialog "Enter new object with id $id ?" $w_]} { return } save_to_file $file [list $info] $headings_ $append } # eval caller supplied command after change eval $command } # pop up a window so that the user can edit the selected object(s). # The optional command is evaluated with no args if the object is # changed. public method edit_selected_object {{command ""}} { catch {destroy $w_.ef} set values [lindex [get_selected] 0] if {[llength $values] == 0} { error_dialog "No rows are selected" $w_ return; } EnterObject $w_.ef \ -title {Please enter the data for the object below:} \ -labels $headings_ \ -values $values \ -command [code $this enter_object $command] } # update the table sort and column display options from the # catalog entry public method update_options {} { # sort cols config \ -sort_cols [$astrocat sortcols] \ -sort_order [$astrocat sortorder] # show/hide cols set show_cols [$astrocat showcols] if {[llength $show_cols]} { set_options $headings_ Show 0 set_options $show_cols Show 1 # $order should be a list of all columns (visible or not) # in the order they should be displayed set order $show_cols foreach i $order { set a($i) 1 } foreach i $headings_ { if {! [info exists a($i)]} { lappend order $i } } config -order $order } } # -- options -- # astrocat (C++ based) object for accessing catalogs public variable astrocat # equinox of ra and dec columns in query result public variable equinox 2000 } skycat-3.1.2-starlink-1b/cat/library/SearchConfig.tcl000066400000000000000000000176251215713201500224220ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # @(#) $Id: SearchConfig.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # SearchConfig.tcl - Widget for editing a list of search columns # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 22 Oct 97 created itk::usual SearchConfig {} # Class SearchConfig defines dialog window for editing the list of # search columns for the AstroCat catalog window. This allows you # to specify a list of columns to search by, save the information # in a local catalog config file and reconfigure the current windows # to include entries for the search columns. itcl::class cat::SearchConfig { inherit util::TopLevelWidget # constructor constructor {args} { eval itk_initialize $args } # called after options have been evaluated protected method init {} { wm title $w_ "Search Columns for $catalog ($itk_option(-number))" wm iconname $w_ "Search Columns for $catalog" add_tables add_dialog_buttons fill_tables make_short_help } # add a table listing the search columns and entries to edit protected method add_tables {} { pack [set dtab \ [DoubleTableList $w_.dtab \ -selectmode extended \ -command [code $this update_selection] \ -updown 1]] \ -side top -padx 2m -pady 2m -fill both -expand 1 set left_ [$dtab component left] set right_ [$dtab component right] bind [$left_ component listbox] +[code $this select_row $left_] bind [$right_ component listbox] +[code $this select_row $right_] $left_ config -headings {{Search Columns} MinLabel MaxLabel} $right_ config -headings {{Other Columns} MinLabel MaxLabel} # hide some columns $left_ set_option MinLabel Show 0 $left_ set_option MaxLabel Show 0 $right_ set_option MinLabel Show 0 $right_ set_option MaxLabel Show 0 $left_ config -width 12 -height 4 $right_ config -width 12 -height 4 # add entries for editing (left) table pack [set f [frame $w_.f -borderwidth 3 -relief groove]] \ -side top -padx 2m -pady 2m -ipadx 2m -ipady 2m -fill x pack \ [set col_ [LabelEntry $f.col \ -text "Column name:" \ -relief groove \ -disabledforeground black \ -state disabled \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] \ [set min_ [LabelEntry $f.min \ -text "Label for min value:" \ -command [code $this set_row] \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] \ [set max_ [LabelEntry $f.max \ -text "Label for max value:" \ -command [code $this set_row] \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] \ -side top -fill x -expand 1 } # fill the left and right tables with the column info protected method fill_tables {} { # get current search cols if {[catch {set search_cols [$astrocat searchcols]} msg]} { error_dialog $msg quit } if {[llength $search_cols]} { $left_ config -info $search_cols $left_ select_row 0 select_row $left_ } # set other available columns on right side foreach i $search_cols { set a([lindex $i 0]) 1 } set l {} foreach i $columns { if {![info exists a($i)]} { lappend l [list $i "Min $i" "Max $i"] } } $right_ config -info $l } # Update the selected row with the typed in values protected method set_row {args} { set row [get_row] if {"$row" != "" && "$sel_" != ""} { $left_ set_row $sel_ $row set sel_ $row } incr save_needed_ } # called when a table row (left or right) is selected protected method select_row {tab} { set sel_ [lindex [$tab get_selected] 0] lassign $sel_ col min max $col_ config -value $col $min_ config -value $min $max_ config -value $max if {"$tab" == "$left_"} { $w_.update config -state normal } else { $w_.update config -state disabled } } # update the selection in the listboxes after a change protected method update_selection {} { if {[llength [$left_ get_selected]]} { select_row $left_ } elseif {[llength [$right_ get_selected]]} { select_row $right_ } else { $col_ config -value {} $min_ config -value {} $max_ config -value {} } incr save_needed_ } # return a row based on the current entries or empty if not all of # the entries contain values protected method get_row {} { set row {} foreach w {col_ min_ max_} { set val [[set $w] get] if {"$val" == ""} { error_dialog "Please specify the column name and the min and max labels" return } lappend row $val } return $row } # apply the changes and close the window protected method apply {{ask 0}} { if {$save_needed_} { if {[catch {$astrocat searchcols [join [$left_ get_contents] :]} msg]} { error_dialog $msg $w_ return } if {!$ask || [confirm_dialog "Do you want to save your changes in the default catalog \ config file (~/.skycat/skycat.cfg)?" $w_]} { cat::CatalogInfo::save {} $w_ $ask set save_needed_ 0 } if {"$command" != ""} { eval $command } } quit } # add the dialog button frame protected method add_dialog_buttons {} { # dialog buttons pack [frame $w_.buttons -borderwidth 2 -relief raised] \ -side top -fill x pack \ [button $w_.ok \ -text "OK" \ -command [code $this apply]] \ [button $w_.cancel \ -text "Cancel" \ -command [code $this quit]] \ [button $w_.update \ -text "Update" \ -state disabled \ -command [code $this set_row]] \ -side left -expand 1 -padx 15m -pady 2m -in $w_.buttons } # add a short help window and set the help texts protected method make_short_help {} { TopLevelWidget::make_short_help add_short_help $left_ {List of search columns to display as entries in catalog window} add_short_help $right_ {List of other column names, select+click arrow buttons to move} add_short_help $col_ {Column name: name of selected search column (read-only)} add_short_help $min_ {Min value label: to be displayed on left side of catalog window} add_short_help $max_ {Max value label: to be displayed on right side of catalog window} add_short_help $w_.ok {OK: Apply changes and close window} add_short_help $w_.cancel {Cancel changes and close window} add_short_help $w_.update {Update list at top with current values} } # -- options -- # command to eval when done public variable command {} # catalog name public variable catalog {none} # astrocat (C++ based) object public variable astrocat # list of column headings for the catalog public variable columns {} # font to use for labels itk_option define -labelfont labelFont LabelFont TkDefaultFont # font to use for values itk_option define -valuefont valueFont ValueFont TkFixedFont # set the width for displaying labels itk_option define -labelwidth labelWidth LabelWidth 18 # set the anchor for labels itk_option define -anchor anchor Anchor e # -- protected vars -- # left listbox widget protected variable left_ # right listbox widget protected variable right_ # Widget displaying column name: name of selected search column (read-only) protected variable col_ # Widget displaying min value label. protected variable min_ # Widget displaying max value label. protected variable max_ # table row last selected protected variable sel_ {} # set to true if the catalog configuration has been edited and needs to be saved protected variable save_needed_ 0 } skycat-3.1.2-starlink-1b/cat/library/SymbolConfig.tcl000066400000000000000000000337411215713201500224570ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # @(#) $Id: SymbolConfig.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # SymbolConfig.tcl - Widget for editing plot symbol information # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 22 Oct 97 created itk::usual SymbolConfig {} # Class SymbolConfig defines a dialog window for editing the plot symbol # information for the AstroCat catalog window. The dialog lets you select # which symbols to plot under given conditions, the size, color, shape # of the symbols, specified as expressions in terms of column name variables. itcl::class cat::SymbolConfig { inherit util::TopLevelWidget # constructor constructor {args} { eval itk_initialize $args } # called after options have been evaluated protected method init {} { wm title $w_ "Plot Symbols for $catalog ($itk_option(-number))" wm iconname $w_ "Plot Symbols for $catalog" add_table add_dialog_buttons fill_table make_short_help } # add a table listing the symbols and some widgets to edit them protected method add_table {} { # table listing overview at top pack [set table_ \ [TableList $w_.table \ -height 3 \ -exportselection 0 \ -headings {Columns Symbol Color Ratio Angle Label Condition Size Units}]] \ -side top -padx 1m -pady 1m -fill both -expand 1 bind [$w_.table component listbox] <1> +[code $this update_table] bind [$w_.table component listbox] +[code $this select_row] # lower frame pack [set f [frame $w_.f]] \ -side top -padx 2m -pady 2m -ipadx 2m -ipady 2m -fill both -expand 1 # double listbox for choosing column names pack [frame $f.cols] \ -side top -fill x -expand 1 -ipady 2m pack \ [LabelWidget $f.cols.label \ -text "Columns:" \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -labelfont $itk_option(-labelfont)] \ -side left pack \ [DoubleList $f.cols.dlist \ -updown 0 \ -height 2 \ -width 12 \ -lefttitle Used \ -righttitle {Not Used}] \ -side left -padx 2m -fill both -expand 1 set left_ [$f.cols.dlist component left] set right_ [$f.cols.dlist component right] # set default contents of right list to catalog cols $right_ set_contents $columns pack \ [set symbol_ [LabelMenu $f.symbol \ -text "Symbol:" \ -relief raised \ -borderwidth 3 \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] \ [set color_ [LabelMenu $f.color \ -text "Color:" \ -relief raised \ -borderwidth 3 \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] \ [set ratio_ [LabelEntry $f.ratio \ -text "Ratio:" \ -state disabled \ -command [code $this apply] \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] \ [set angle_ [LabelEntry $f.angle \ -text "Angle:" \ -state disabled \ -command [code $this apply] \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] \ [set label_ [LabelEntry $f.label \ -text "Label:" \ -labelwidth $itk_option(-labelwidth) \ -command [code $this apply] \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] \ [set cond_ [LabelEntry $f.cond \ -text "Condition:" \ -labelwidth $itk_option(-labelwidth) \ -command [code $this apply] \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] \ [set size_ [LabelEntry $f.size \ -text "Size:" \ -labelwidth $itk_option(-labelwidth) \ -command [code $this apply] \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] \ [set units_ [LabelMenu $f.units \ -text "Units:" \ -relief raised \ -borderwidth 3 \ -labelwidth $itk_option(-labelwidth) \ -anchor $itk_option(-anchor) \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont)]] \ -side top -fill x -expand 1 -ipady 2m # fill the overview table if {[catch {set symbols [$astrocat symbol]} msg]} { error_dialog $msg quit } # add menu choices foreach i {circle square cross triangle diamond plus compass ellipse line arrow} { $symbol_ add \ -bitmap symb_$i \ -value $i \ -command [code $this set_symbol $i] } $color_ add \ -label "default (black&white)" \ -background [option get $color_ *Menu*background Background] \ -value {} foreach i $itk_option(-colors) { $color_ add \ -label { } \ -value $i \ -background $i } foreach i { {{default (image pixels)} {}} {{WCS degrees in J2000} {deg 2000}} {{WCS degrees in B1950} {deg 1950}}} { $units_ add \ -label [lindex $i 0] \ -value [lindex $i 1] } } # called when a symbol is selcted from the menu protected method set_symbol {symbol} { if {"$symbol" == "ellipse" \ || "$symbol" == "compass"\ || "$symbol" == "plus"\ || "$symbol" == "line"\ || "$symbol" == "arrow"} { set state normal } else { set state disabled } $ratio_ config -state $state $angle_ config -state $state } # fill the table with the symbol info for the current catalog protected method fill_table {} { set info {} foreach i [$astrocat symbol] { lassign $i cols sym expr lassign $sym symbol color ratio angle label cond lassign $expr size units lappend info [list $cols $symbol $color $ratio $angle $label $cond $size $units] } if {[llength $info]} { $table_ config -info $info $table_ select_row 0 select_row } else { after 1000 \ [code info_dialog \ "Note: This catalog does not have any plot symbols yet. \ To add a symbol, fill out the form below and then select 'Add Symbol'" $w_] } } # update the table display from the entries and return an empty # string if all was OK protected method update_table {args} { if {[catch {set row [get_row]} msg]} { error_dialog $msg return ERROR } if {"$row" != "" && "$sel_" != "" && "$sel_" != "$row"} { $table_ set_row $sel_ $row set sel_ $row incr save_needed_ } } # apply the current changes protected method apply {args} { if {"[update_table]" == "ERROR"} { return } save } # save the changes in the default config file protected method save {{ask 0}} { if {$save_needed_} { set info {} foreach i [$table_ get_contents] { if {[llength $i] == 9} { lassign $i cols symbol color ratio angle label cond size units lappend info [list $cols \ [list $symbol $color $ratio $angle $label $cond] \ [list $size $units]] } } if {[catch {$astrocat symbol [join $info :]} msg]} { error_dialog $msg $w_ return } if {!$ask || [confirm_dialog "Do you want to save your changes in the default catalog \ config file (~/.skycat/skycat.cfg)?" $w_]} { cat::CatalogInfo::save {} $w_ $ask set save_needed_ 0 } if {"$command" != ""} { eval $command } } } # called when a table row is selected protected method select_row {} { set sel_ [lindex [$table_ get_selected] 0] lassign $sel_ cols symbol color ratio angle label cond size units # put current columns used in the left box and others in the right foreach i $cols { set a($i) 1 } set other {} foreach i $columns { if {! [info exists a($i)]} { lappend other $i } } $left_ set_contents $cols $right_ set_contents $other $symbol_ config -value $symbol $color_ config -value $color $ratio_ config -value $ratio $angle_ config -value $angle $label_ config -value $label $cond_ config -value $cond set_symbol $symbol $size_ config -value $size $units_ config -value $units $w_.remove config -state normal } # return a table row based on the current entries and menus or empty # if no data was enterred. Raises an error if there was something wrong. protected method get_row {} { set row {} set cols [$left_ get_contents] set symbol [$symbol_ get] set color [$color_ get] set ratio [$ratio_ get] set angle [$angle_ get] set label [$label_ get] set cond [$cond_ get] set size [$size_ get] set units [$units_ get] # test the variable usage in the expressions foreach var $cols { set $var 1 } if {"$size" == ""} { if {[llength $cols]} { error "Please specify a value for size (expr or const) in $units" } return } foreach var {size ratio angle cond} { set v [set $var] if {"$v" != ""} { if {[catch {expr [set $var]} msg]} { error "in $var expr: $msg" } } } # label may also contain col name vars, but may not be numeric if {[catch {subst $label} msg]} { error "error in label '$label': $msg" } return [list $cols $symbol $color $ratio $angle $label $cond $size $units] } # add a new row to the table public method add_row {} { if {[catch {set row [get_row]} msg]} { error_dialog $msg return } if {"$row" != ""} { # no duplicates foreach i [$table_ get_contents] { if {"$i" == "$row"} { info_dialog "To add a new symbol, change some parameters and press Add Symbol" return [update_table] } } $table_ add_row $row $table_ select_row end select_row incr save_needed_ } } # remove the selected row from the table public method remove_row {} { $table_ remove_selected select_row incr save_needed_ } # apply the changes and close the window public method ok {} { apply quit } # add the dialog button frame protected method add_dialog_buttons {} { # dialog buttons pack [frame $w_.buttons -borderwidth 2 -relief raised] \ -side top -fill x pack \ [button $w_.ok \ -text "OK" \ -command [code $this ok]] \ [button $w_.apply \ -text "Apply" \ -command [code $this apply]] \ [button $w_.cancel \ -text "Cancel" \ -command [code $this cancel]] \ [button $w_.add \ -text "Add Symbol" \ -command [code $this add_row]] \ [button $w_.remove \ -text "Remove Symbol" \ -state disabled \ -command [code $this remove_row]] \ -side left -expand 1 -padx 6m -pady 2m -in $w_.buttons } # called when the cancel button is pressed. Delete the window so that # it will be reinitialized next time public method cancel {} { destroy $w_ } # add a short help window and set the help texts protected method make_short_help {} { TopLevelWidget::make_short_help add_short_help $table_ {Table listing symbols to plot, one symbol per row, click to select} add_short_help $symbol_ {Symbol to use to plot stars or other objects} add_short_help $color_ {Color in which to draw the symbol} add_short_help $ratio_ {Ratio of width to height, expr using column names as variables} add_short_help $angle_ {Angle of rotation for symbol, expr using column names as variables} add_short_help $label_ {Label for symbol, using column names as variables} add_short_help $cond_ {Condition for displaying symbol, using column names as variables} add_short_help $size_ {Size of symbol, expression using column names as variables} add_short_help $units_ {Units in which to interpret the size of the symbol} add_short_help $left_ {List of column names used as variables for Size, Ratio, Angle, Label, Condition} add_short_help $right_ {List of unused column names} add_short_help $w_.ok {OK: Apply changes and close window} add_short_help $w_.apply {Apply the current changes} add_short_help $w_.cancel {Cancel changes and Close window} add_short_help $w_.add {Add the current entry as a new plot symbol (must be unique)} add_short_help $w_.remove {Remove the selected plot symbol entry} } # -- options -- # command to eval when done public variable command {} # catalog name public variable catalog {none} # astrocat (C++ based) object public variable astrocat # list of column headings for the catalog public variable columns {} # font to use for labels itk_option define -labelfont labelFont LabelFont TkDefaultFont # font to use for values itk_option define -valuefont valueFont ValueFont TkFixedFont # set the width for displaying labels itk_option define -labelwidth labelWidth LabelWidth 8 # color list for color menu itk_option define -colors colors Colors { white black grey yellow red green blue lightblue pink purple orange violet navy turquoise cyan gold tan lavender bisque chartreuse } # set the anchor for labels itk_option define -anchor anchor Anchor e # -- protected vars -- # TableList widget displaying plot info protected variable table_ # symbol shape menu protected variable symbol_ # symbol color menu protected variable color_ # symbol ratio entry protected variable ratio_ # symbol angle entry protected variable angle_ # symbol label entry protected variable label_ # symbol condition entry protected variable cond_ # symbol size entry protected variable size_ # symbol units entry protected variable units_ # left column selection listbox protected variable left_ # right column selection listbox protected variable right_ # table row last selected protected variable sel_ {} # set to true if the catalog configuration has been edited and needs to be saved protected variable save_needed_ 0 } skycat-3.1.2-starlink-1b/cat/library/archive.xpm000066400000000000000000000010651215713201500215210ustar00rootroot00000000000000/* XPM */ static char * archive_xpm[] = { "16 16 9 1", " c #FFFFFFFF0000", ". c #C30BC30BC30B", "X c #FFFFFFFFFFFF", "o c #FFFF659530C2", "O c #65956595CF3C", "+ c #FFFF00000000", "@ c #9A699A69FFFF", "# c #820782078207", "$ c #C30BC30BC30B", " ..X.X.. .......", ". . . . ........", ".. o XOOOOOO..", "X + X@XOXO.", " oo+ +o#.@X@OXXO", "XX + X@XOOOO", ".. o .X@X@X@XO", ". . O @ @X@X@X@O", "X..XO@X@X@X@X@XO", "... O @X@X@X@X@O", "....O@X@X@X@X@XO", "....OX@X@X@X@X@O", "....O@X@X@X@X@XO", "....OX@X@X@X@X@O", ".$$.O@X@X@X@X@XO", "....OOOOOOOOOOOO"}; skycat-3.1.2-starlink-1b/cat/library/catalog.xpm000066400000000000000000000007411215713201500215120ustar00rootroot00000000000000/* XPM */ static char * catalog_xpm[] = { "16 16 5 1", " c #C30BC30BC30B", ". c #00000000FFFF", "X c #FFFFFFFFFFFF", "o c #000000008207", "O c #820782078207", " ", " .......... ", " .XXXXXXX.X. ", " ....XXXXX.XXo", " ..OXXXooOO oooo", " .XoXX. oXXXXXXo", ". XoXXXXXoO..oXo", ". XoXX.O oXXXXXo", ". XoXXXXXoO..oXo", ". XoXX.OOoXXXXXo", " . oXXXXoO...oXo", " ..OXXOooXXXXXXo", "...oooo ....oXo", ".o .XXXXXXXXXXo", "o oooooooooooo", " "}; skycat-3.1.2-starlink-1b/cat/library/catdefaults.tcl000066400000000000000000000044241215713201500223570ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # @(#) $Id: catdefaults.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # catdefaults.tcl - X defaults for itk catalog widgets # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 20 May 96 created # itk widget defaults (normally you'd put these in the itk sources, but # putting them here makes it easier to "pre-load" the classes for the single # binary version... proc cat::setXdefaults {} { #set menuBg DeepSkyBlue3 set menuBg #009acd set menuFg White option add *foreground Black option add *background Gray77 option add *DisabledForeground Gray90 option add *Button*foreground NavyBlue option add *Button*background Gray77 option add *Canvas*insertBackground white option add *Text.foreground Black option add *Listbox.foreground Black option add *Entry.foreground Black option add *Scrollbar.foreground Gray77 option add *Scrollbar.Width 14 option add *selectForeground Gray77 option add *selectBackground Black option add *highlightThickness 0 option add *Text.highlightThickness 2 option add *Entry.highlightThickness 2 option add *highlightBackground Gray77 option add *highlightColor Black #option add *shelp*Background FloralWhite #option add *plotBackground gray80 set labelFont TkDefaultFont option add *Listbox.font TkFixedFont option add *Entry.font TkFixedFont option add *titleFont TkDefaultFont option add *Button.Font $labelFont option add *Label.Font $labelFont option add *Menu.Font $labelFont option add *Menubutton.Font $labelFont option add *Message.Font $labelFont option add *Scale.Font $labelFont option add *Text.Font TkFixedFont option add *QueryResult.relief sunken option add *QueryResult.borderwidth 3 option add *QueryResult.font TkFixedFont option add *QueryResult.headingFont TkDefaultFont option add *QueryResult.headingLines 1 option add *QueryResult.titleFont TkDefaultFont option add *Menu*background $menuBg option add *Menu*foreground $menuFg option add *Menubutton*background $menuBg option add *menubar*background $menuBg option add *Menubutton*foreground $menuFg } skycat-3.1.2-starlink-1b/cat/library/imagesvr.xpm000066400000000000000000000020321215713201500217100ustar00rootroot00000000000000/* XPM */ static char * imagesvr_xpm[] = { "16 16 32 1", " c #CF3CCF3CCF3C", ". c #8E388E388E38", "X c #7DF77DF77DF7", "o c #AEBAAEBAAEBA", "O c #9E799E799E79", "+ c #6DB66DB66DB6", "@ c #C30BC30BC30B", "# c #4D344D344D34", "$ c #3CF34D346DB6", "% c #4D3486174514", "& c #55556DB63CF3", "* c #5D755D755D75", "= c #30C230C26595", "- c #3CF33CF33CF3", "; c #1C711C711C71", ": c #30C29A696595", "> c #DF7DDF7DDF7D", ", c #000000000000", "< c #04105D754514", "1 c #0C300C300C30", "2 c #BEFBBEFBBEFB", "3 c #451414510410", "4 c #A6999E79BEFB", "5 c #EFBEEFBEEFBE", "6 c #6DB665958617", "7 c #F3CEF3CEFFFF", "8 c #F3CEF3CEF3CE", "9 c #2CB22CB22CB2", "0 c #FFFFFFFFFFFF", "q c #FFFFF3CEF3CE", "w c #C71B9E799658", "e c #9E7924920410", " .XoO.ooOooOO.+@", "o#$#$$#$%&O..+*@", "o=*.o+-;-:*-#-$@", "O*.>O-,,;&<;;,;@", "X-oo1,,=-+;1,,,@", "+,*-,;#>.;;,,,;@", "#,1,,. 2 ;,,,,,@", "#,;,#> O;3,,,,@", "*,,;O>> 4*X.*,;@", "-,;+2.++O5 .>+,@", "++6O5*,;*O7 ++;@", ".o2887.,9$8>+;9@", "+ ;0000O*+q2;+;@", "$oo$XXo8ww9o9.;@", "*2*,,,,9;4;;w;e@", "*$9;,;,;9;.99$9@"}; skycat-3.1.2-starlink-1b/cat/library/local.xpm000066400000000000000000000007371215713201500211770ustar00rootroot00000000000000/* XPM */ static char * local_xpm[] = { "16 16 5 1", " c #C30BC30BC30B", ". c #00000000FFFF", "X c #FFFFFFFFFFFF", "o c #00000000FFFF", "O c #000000008207", " ", " .......... ", " .XXXXXXX.X. ", " .XooXooX.XXO ", " oXXXXXXXoOOO ", " oXXXXXXXXXXO ", " oXooXooXooXO ", " oXXXXXXXXXXO ", " oXXXXXXXXXXO ", " oXooXooXooXO ", " oXXXXXXXXXXO ", " oXXXXXXXXXXO ", " oXooXooXooXO ", " .XXXXXXXXXXO ", " OOOOOOOOOOOO ", " "}; skycat-3.1.2-starlink-1b/cat/library/mkIndex.tcl000077500000000000000000000003161215713201500214560ustar00rootroot00000000000000#!../bin/cat_wish # # mkIndex.tcl - generate a tclIndex file in the current directory # "@(#) $Id: mkIndex.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" package require Itcl auto_mkindex . *.tcl exit 0 skycat-3.1.2-starlink-1b/cat/library/namesvr.xpm000066400000000000000000000010131215713201500215440ustar00rootroot00000000000000/* XPM */ static char * namesvr_xpm[] = { "16 16 7 1", " c #C30BC30BC30B", ". c #208120812081", "X c #30C230C230C2", "o c #9A69CF3CFFFF", "O c #000000000000", "+ c #451445144514", "@ c #FFFF9A6930C2", " ", " .X.X.X.X.X.X. ", " XoooooooooooO ", " .oX++X++X+ooO ", " XoooooooooooO ", " .o@@@oooooooO ", " Xo@@@o++X+ooO ", " .oooooooooooO ", " Xo@@@oooooooO ", " .o@@@o++X+ooO ", " XoooooooooooO ", " .o@@@oooooooO ", " Xo@@@o++X+ooO ", " XoooooooooooO ", " .OOOOOOOOOOOO ", " "}; skycat-3.1.2-starlink-1b/cat/library/nsfolder.xpm000066400000000000000000000007221215713201500217130ustar00rootroot00000000000000/* XPM */ static char * nsfolder_xpm[] = { "15 16 5 1", " c #C30BC30BC30B", ". c #9A699A69FFFF", "X c #65956595CF3C", "o c #FFFFFFFFFFFF", "O c #000000000000", " ", " ", " ..... ", " . . . . ", ". . . . XXXXXX ", ".ooooooooooooX ", ".o . . . . . XO", ".o. . . . . .XO", ".o . . . . . XO", ".o. . . . . .XO", ".o . . . . . XO", ".o. . . . . .XO", "XXXXXXXXXXXXXXO", " OOOOOOOOOOOOOO", " ", " "}; skycat-3.1.2-starlink-1b/cat/library/nsopenfold.xpm000066400000000000000000000010161215713201500222430ustar00rootroot00000000000000/* XPM */ static char * nsopenfold_xpm[] = { "16 16 7 1", " c #C30BC30BC30B", ". c #9A699A69FFFF", "X c #FFFFFFFFFFFF", "o c #65956595CF3C", "O c #000000000000", "+ c #820782078207", "@ c #000034D33CF3", " ", " ", " ..... ", " .XXXXX. ", " .X. . .Xoooooo ", " .X . . .XXXXXo ", " .X. . . . . .oO", "oooooooooooo. oO", "oXXXXXXXXX O+.oO", " o. . . . . O oO", " o . . . . .@OoO", " o . . . . .@OO", " oooooooooooooO", " OOOOOOOOOOOOO", " ", " "}; skycat-3.1.2-starlink-1b/cat/man/000077500000000000000000000000001215713201500164575ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/cat/man/AstroCatalog.man3000066400000000000000000000377501215713201500216360ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: AstroCatalog.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 17 Oct 95 Created # NAME AstroCatalog - C++ class for accessing astromical catalogs SYNOPSIS #include "AstroCatalog.h" class AstroCatalog { ... public: AstroCatalog(const CatalogInfoEntry*); virtual ~AstroCatalog(); static AstroCatalog* open(const char* name); static int nameToWorldCoords( const char* objName, WorldCoords& pos, const char* nameServer = "simbad_ns@eso", FILE* feedback = NULL); virtual int query( const AstroQuery& q, const char* filename, QueryResult& result); const char* symbol(); const char* searchCols(); const char* sortCols(); const char* sortOrder(); const char* showCols(); const char* copyright(); int id_col(); int ra_col(); int dec_col(); int x_col(); int y_col(); int is_tcs(); int isWcs(); double equinox(); int getPreview(const char* url, char*& content_type); CatalogInfoEntry* entry(); void feedback(FILE* f); int status(); const char* name(); const char* longName(); const char* shortName(); const char* servType(); virtual int numCols() ; virtual char** colNames() ; virtual const char* colName(int col); virtual int colIndex(const char* colName); int hasCol(const char* name); int more(); int getDescription( int& numCols, char**& colNames); int getObject( const char* id, int numCols, char** colNames, QueryResult& result); int getArea( int numCols, char** colNames, const WorldCoords& pos0, const WorldCoords& pos1, double mag0, double mag1, int maxRows, const char* filename, int& numFound, QueryResult& result); int circularSearch( int numCols, char** colNames, const WorldCoords& pos, double radius0, double radius1, double mag0, double mag1, int maxRows, const char* filename, int& numFound, QueryResult& result); int searchClosestStar( int numCols, char** colNames, const WorldCoords& pos, double mag0, double mag1, QueryResult& result); int CatalogSearch( int numCols, char** colNames, int numSearchCols, char** searchCols, char** minVals, char** maxVals, int maxRows, const char* filename, int& numFound, QueryResult& result); static const char* getError(); static void clearError(); }; DESCRIPTION This class manages access to astronomical catalogs. The main entry point is the "open" method, which returns a pointer to an AstroCatalog object to be used to access the named catalog. This object should be deleted with "delete" when no longer needed. CATALOG SERVERS This class communicates with catalog servers via HTTP requests. The lists of servers and how to access them are kept in configuration files, which are accessed via HTTP or read from local files. The default catalog config file is a hard coded URL: http://archive.eso.org/skycat/skycat2.0.cfg The default can be overridden by defining the environment variable CATLIB_CONFIG to another valid HTTP URL. For compatibility with previous versions, the environment variable SKYCAT_CONFIG may also be used. LOCAL CATALOGS If the catalog name passed to the open method is the name of a file, it is taken to be a local catalog file in tab table format. This is the same format used by the Starbase utilities. A local catalog is an ASCII file containing an optional title and header information followed by the column headings, a dashed line and the data rows. The columns are separated by tabs. This is also the format of query results returned via HTTP from remote catalog servers. Example: Table1 # comment line # The header may contain catalog config information... symbol: mag circle 15-$mag search_cols: mag "Brightest (min)" "Faintest (max)" id ra dec pos-e mag ------ -- --- ----- --- A00050 3:19:28 8:26:29 0.2 13.49 A00098 3:19:32 8:34:15 0.4 13.40 A00288 3:19:21 8:31:19 0.2 13.13 A00314 3:19:44 8:30:58 0.2 13.98 The format of a local catalog is the same as the format of the result of a query to a remote catalog. The header may contain comments (with '#') and optional configuration information in the same format as the catalog config files. The pointer returned from the open method for files is a pointer to a LocalCatalog object, a subclass of AstroCatalog specialized in dealing with local catalogs. The interface is the same for remote and local catalogs, only the implementation is different in some ways (some virtual methods are redefined in the derived class). UNITS Unless otherwise stated, the units for all radius values are in arcmin for catalogs that support World Coordinates and image pixels for catalogs that do not. A catalog is considered to support World Coordinates if the values of ra_col and dec_col in the catalog config entry are valid (they are 1 and 2 by default). If x_col and y_col were given, the catalog is considered to be using image pixel coordinates. Floating point values for RA and DEC are always in degrees. The default equinox is J2000. QUERY PARAMETERS Parameters for catalog searches are checked to make sure they are valid and in the correct range. A radius value must be between 0.0 and 300.0 arcmin. A magnitude may have any value. For ranges, such as min and max radius and min and max magnitude, the order of the arguments is not important, since they will be rearranged as needed. If both min and max values are 0.0, they are ignored for that search. If you really want to search for objects with "0.0" magnitude, specify a range with small values that are not zero, for example, min/max mag = (-0.0001, +0.0001). FORMAT OF QUERY RESULTS Catalog query results are returned in a class QueryResult object. This object is used to access values based on a row and column index or column name. Overloaded "get" methods allow column values to be retrieved as int, short, float, double, char, char*, or WorldCoords (internally, the values are stored as strings). MEMORY MANAGEMENT Memory is allocated internally for the query results. It is the caller's responsibility to delete the result object when no longer needed. PUBLIC METHODS open(name) Open the named catalog and return a pointer an AstroCatalog (or LocalCatalog) object allocated for the catalog, or NULL if errors occur. Arguments: name (in) - catalog name or file name for local catalogs Return value: pointer to an allocated AstroCatalog or derived object query(q, filename, result) Pass the given query to the catalog server and return the number of objects found. Arguments: q (in ) - AstroQuery object, describes query. filename (in ) - Optional file name: if not NULL, a copy of the results from the server is written to the given file. result (out) - Set on successful return to contain and manage the query results. Return value: The number of objects found, or -1 if errors occured. nameToWorldCoords(objName, pos, nameServer, feedback) Use a name server catalog (like simbad_ns@eso or ned_ns@eso) to get the coordinates from the object name. If feedback is not NULL, status info is written to the given open file. Arguments: objName (in ) - name of star or astronomical object pos (out) - reference to WorldCoords object result nameServer (in ) - name server to use to resolve name feedback (in ) - file pointer for user interface feedback Return value: If successful, 0, otherwise 1. getDescription(numCols, colNames) Get the number of columns and the column names for the given catalog and return 0 if all is OK. The memory for the return arrays is managed internally and should not be modified by the caller. Arguments: numCols (out) - number of catalog columns colNames (out) - reference to array of column names Return value: If successful, 0, otherwise 1. getObject(id, numCols, colNames, result) Get the values for the specified columns for the object given by "id" in the catalog and return 0 if found. The id should be a valid object id obtained by a previous catalog query. If colNames is not NULL, it should be an array of column names to fetch, otherwise all columns are fetched. The result argument is set on return to contain the results of the query. Arguments: id (in ) - object id numCols (in) - number of columns (column names) colNames (in ) - array of column names to read, or NULL to read all columns. result (in/out) - set from query result data Return value: Returns 0 if there were no errors, otherwise 1. It is not considered an error if no object was found. getArea(numCols, colNames, pos0, pos1, mag0, mag1, maxRows, filename, numfound, results) Get the values for all objects in the rectangular region given by the two world coordinate points. If mag0 and mag1 are not 0.0, they are taken to be the minimum and maximum magnitude values for the query. If colNames is not NULL, it should be an array of column names to fetch, otherwise all columns are fetched. The number of object rows returned is limited to maxRows (the more() method can be called to see if more objects would have been available). On return, numFound is set to the number of objects found and, if any were found, result is set to be used for accessing the results. If filename is not NULL, the results will be copied to the given file in the format of a local catalog. Arguments: numCols (in) - number of columns (column names) colNames (in ) - array of column names to read, or NULL to read all pos0 (in ) - world coordinates of first point pos1 (in ) - world coordinates of second point mag0 (in ) - min magnitude mag1 (in ) - max magnitude maxRows (in ) - max number of rows to return filename (in ) - if not null, write results to this file numFound (out) - number of objects found result (in/out) - set to contain query result Return value: If successful, 0, otherwise 1. circularSearch(numCols, colNames, pos, radius0, radius1, mag0, mag1, maxRows, filename, numFound, result) Get the values for all objects in the circle or ring given by the world coordinate point and the min and max radius values. If mag0 and mag1 are not 0.0, they are taken to be the minimum and maximum magnitude values for the query. If colNames is not NULL, it should be an array of column names to fetch, otherwise all columns are fetched. The number of object rows returned is limited to maxRows (the more() method can be called to see if more objects would have been available). On return, numFound is set to the number of objects found and, if any were found, result is set to be used for accessing the results. If filename is not NULL, the results will be copied to the given file in the format of a local catalog. Arguments: numCols (in) - number of columns (column names) colNames (in ) - array of column names to read, or NULL to read all pos (in ) - world coordinates of center point radius0 (in ) - min radius from center point radius1 (in ) - max radius from center point mag0 (in ) - min magnitude mag1 (in ) - max magnitude maxRows (in ) - max number of rows to return filename (in ) - if not null, write results to this file numFound (out) - number of objects found result (in/out) - filled with query result Return value: If successful, 0, otherwise 1. searchClosestStar(numCols, colNames, pos, mag0, mag1, result) Get the values for the specified columns for the object in the catalog closest to the given position and return 0 if found. If colNames is not NULL, it should be an array of column names to fetch, otherwise all columns are fetched. If mag0 and mag1 are not 0.0, they are taken to be the minimum and maximum magnitude values for the query. The result argument is set on return to contain the query results. Arguments: numCols (in) - number of columns (column names) colNames (in ) - array of column names to read, or NULL to read all columns. pos (in ) - world coordinates of point mag0 (in ) - min magnitude mag1 (in ) - max magnitude result (in/out) - set to contain the query result Return value: Returns 0 if there were no errors, otherwise 1. It is not considered an error if no object was found. CatalogSearch(numCols, colNames, numSearchCols, searchCols, minVals, maxVals, maxRows, filename, numFound, result) Get the values for all objects fulfilling the specified criteria. The criteria are given by the array of column names to compare and two arrays of the same size containing min and max values, in string format, corresponding to the column names. Null strings are ignored, so, for example, if there is no min value, only the max value will be used. If colNames is not NULL, it should be an array of column names to fetch, otherwise all columns are fetched. The number of object rows returned is limited to maxRows (the more() method can be called to see if more objects would have been available). On return, numFound is set to the number of objects found and, if any were found, "result" is set for accessing the catalog values found. If filename is not NULL, the results will be copied to the given file in the format of a local catalog Arguments: numCols (in) - number of columns (column names) colNames (in ) - array of column names to read, or NULL to read all columns. numSearchCols (in ) - number of column names to compare searchCols (in ) - array of column names to compare minVals (in ) - array of column minimum values maxVals (in ) - array of column maximum values maxRows (in ) - max number of rows to return filename (in ) - if not null, write results to this file numFound (out) - set to number of objects found result (in/out) - contains query result Return value: Returns 0 if there were no errors, otherwise 1. getError() Return the text of the most recent error message reported by the catalog classes. clearError() Reset the error message buffer to empty. numCols() Return the number of columns in result lists. colName(col) Return the name of the given column (columns are numbered starting with zero). colNames() Return an array of the catalog column names. colIndex(name) Return the catalog column index for the given column name. hasCol(name) Return true if the catalog contains the given column. status() Return the status (after constructor) for error checking. If no errors occured, a value of 0 is returned. more() Return true if more than "maxRows" rows would have been available to the last call to query(). name() longName() shortName() Return the name (long name) or short name of this catalog. These are values defined in the catalog config file. symbol() searchCols() sortCols() sortOrder() showCols() copyright() id_col() ra_col() dec_col() x_col() y_col() is_tcs() isWcs() equinox() All these methods return the corresponding values from the catalog config entry for the current catalog. getPreview(url, content_type) Given a URL pointing to preview data (FITS image or tab table data), request the data from the server and return 0 if all is OK. On return, if there were no errors, the "ctype" argument is set to the Content-type of the result to indicate the type of data. The data is automatically decompressed if needed (if the content-type is recognized). The "tmpfile()" method gives the name of the file containing the results on success. entry() Return a pointer to the catalog config entry for the open catalog. feedback(FILE) Set the file pointer to use for http feedback during transfers. SEE ALSO AstroImage, WorldCoords(3C++) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/cat/man/AstroImage.man3000066400000000000000000000072211215713201500212740ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: AstroImage.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 17 Oct 95 Created # NAME AstroImage - C++ class for accessing astromical image servers (obsolete) SYNOPSIS #include "AstroImage.h" class AstroImage { ... public: AstroImage(const AstroImage&); virtual ~AstroImage(); static AstroImage* open(const char* name); int getImage(const WorldCoords& pos, double width, double height); int getImage(const char* url); static const CatalogInfoEntry* firstCatalog(); void feedback(FILE* f); int status(); void tmpfile(const char* name); const char* tmpfile(); const char* name(); const char* longName(); const char* shortName(); }; DESCRIPTION Note: This class is obsolete. Please use class AstroCatalog, which now also has the getImage method. This class is used to retrieve images from an HTTP based image server based on a name or position and a width and height in arcmin. The main entry point is the "open" method, which returns a pointer to an AstroImage object allocated for use with the named image server. IMAGE SERVERS This class communicates with an image server via HTTP requests. The list of servers and how to access them is kept in a configuration file, which is also accessed via HTTP. The default config file is: http://archive.eso.org/skycat/skycat.cfg The default can be overridden by defining the environment variable SKYCAT_CONFIG to another valid HTTP URL. UNITS Unless otherwise stated, the units for all radius values are in arcmin. Floating point values for RA and DEC are always in degrees. The default equinox is J2000. PUBLIC METHODS open(name) Open the named image server and return a pointer to an AstroImage object allocated for it, or NULL if errors occur. Arguments: name (in ) - Image server name (long or short name from catalog config file). Return value: Pointer to an AstroImage object created for the given image server. getImage(pos, width, height) Pass a request to the image server to get a FITS file at the given position with the given size and return the status. The name of the file holding the result can be accessed as this->tmpfile(). Arguments: pos (in ) - World coordinates of center of image. width (in ) - Image width in arcmin. height (in ) - Image height in arcmin. Return value: Status: 0 if OK, 1 for error. getImage(url) Given a URL for the image, request the image from the image server and return the status. The name of the file holding the result can be accessed as this->tmpfile(). Arguments: url (in ) - HTTP URL for image. Return value: Status: 0 if OK, 1 for error. firstCatalog() Return a pointer to the first catalog config entry (for link list traversal). feedback(FILE) Set the file pointer to use for HTTP feedback during image transfers. status() Return the status (after constructor) for error checking. A return value of 0 is normal, 1 for errors. name() longName() shortName() Return the name (long name) or short name of the image server from the catalog config file. tmpfile() tmpfile(name) Get (or set) the name of the temporary file to use to hold images retrieved from the image server. SEE ALSO AstroCatalog, WorldCoords(3C++) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/cat/man/AstroQuery.man3000066400000000000000000000074121215713201500213610ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: AstroQuery.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 27 Jun 96 Created # NAME AstroQuery - A class describing a query to search an astronomical catalog SYNOPSIS #include "AstroQuery.h" class AstroQuery { ... public: AstroQuery(); AstroQuery(const AstroQuery&); ~AstroQuery(); const char* id() const; int id(const char* s); const WorldCoords& pos() const; int pos(const WorldCoords& p); int pos(const WorldCoords& p1, const WorldCoords& p2); double width() const; void width(double w); double height() const; void height(double h); int dim(double w, double h); double mag1() const; double mag2() const; int mag(double m); int mag(double m1, double m2); double radius1() const; double radius2() const; int radius(double r); int radius(double r1, double r2); char** colNames() const; const char* colName(int col) const; int numCols() const; int colNames(int n, char** ar); const char* sort() const; int sort(const char* s); int maxRows() const; int maxRows(int n); int numSearchCols() const; char** searchCols() const; char** minValues() const; char** maxValues() const; int condition(int numSearchCols, char**searchCols, char**minVals, char**maxVals); }; DESCRIPTION This class is used in star catalog queries to specify which object(s) to search for. The class attributes specify the conditions for the search, such as id, name, position, radius, etc. All of the fields are optional. Fields are set to the appropriate null value, if they are not being used. PUBLIC METHODS All of the public methods in this class simply access class members (set and get member values). Methods with arguments set the member values and return the error status. Methods with no arguments return the value. id() const id(const char* s) Get or set the value for the object id to search for. pos() const pos(const WorldCoords& p) Get or set the center position for a radius search. pos(const WorldCoords& p1, const WorldCoords& p2) Calculate center position, width and height from the 2 corner positions. width() const width(w) height() const height(h) Get/set the value of the width or height fields (in arcmin). dim(double w, double h) Set the values of the width and height fields in arcmin. mag1() mag2() Get the max (or min and max) magnitude fields. mag(double m); Set the max magnitude for the query (min is 0.0). mag(double m1, double m2) Set min/max magnitude with check. radius1() const radius2() const Get max (or min and max) radius values in arcmin. radius(double r) Set the max radius for the query in arcmin (min is 0.0). radius(double r1, double r2) Set min/max radius with check. colNames() const Return array of column names. colName(int col) const Return name of given column. numCols() const Return number of columns. colNames(int n, char** ar) Set the number of columns and the column names. sort() const sort(const char* s) Get or set the sort column. maxRows() const maxRows(int n) Get or set the max number of rows to return from a query. numSearchCols() const searchCols() const minValues() const maxValues() const condition(int numSearchCols, char**searchCols, char**minVals, char**maxVals) Get or set the search conditions as min and max values for given columns (Not implemented yet). SEE ALSO AstroCatalog ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/cat/man/CatalogInfo.man3000066400000000000000000000063631215713201500214350ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: CatalogInfo.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 07 Nov 97 Created # NAME CatalogInfo - C++ class managing access to catalog configuration files SYNOPSIS #include "CatalogInfo.h" class CatalogInfo { ... public: CatalogInfo(); static int load(); static int reload(); static CatalogInfoEntry* load(istream&, const char* filename = "internal"); static int load(CatalogInfoEntry*); static CatalogInfoEntry* lookup(const char* catalogName); static CatalogInfoEntry* lookup(CatalogInfoEntry* entry, const char* name); static CatalogInfoEntry* lookupFile(const char* catalogFileName); static void updateConfigEntry(istream& is, CatalogInfoEntry* entry); static int append(CatalogInfoEntry* e); static int remove(CatalogInfoEntry* e); static CatalogInfoEntry* first(); static CatalogInfoEntry* root(); }; DESCRIPTION This class is used to load, edit, access and save catalog config files either locally or via HTTP from a remote host. Config files are referenced by a URL. This may be either http:/host/file for remote config files or file:/pathname for local files. This is a static class, since all of the information is meant to be globally available. The most common method called is "lookup", which returns a pointer to the catalog entry for a given catalog name. The default config file is loaded automatically the first time it is needed. There is a hard coded default URL that points to ESO's master config file. The environment variable CATLIB_CONFIG METHODS CatalogInfo() Constructor. Note that this is a static class (all methods are static), so no instances are required. load() Load the default catalog config file (called automatically). reload() Reload the default catalog config file after it has been edited by hand. load(istream, filename) Load a config file info from the given stream (filename is used for error reporting). load(entry) Load the catalog config file given by the entry's URL field. This is used for directory entries, to follow a catalog directory link. lookup(catalogName) Return a pointer to the catalog config file entry for the given catalog. lookup(entry, name) Look up the catalog name as above, but start the search with the given directory entry rather than at the root. lookupFile(catalogFileName) Get the config entry for a local catalog from the header updateConfigEntry(istream, entry) Read catalog config keyword entries from the given stream and update the given entry values. append(entry) Append the given entry to the end of the main catalog list. remove(entry) Remove the given entry from the main catalog list. first() Return a pointer to the first config file entry under the root entry. root() Return a pointer to the root config file entry. SEE ALSO CatalogInfoEntry, AstroCatalog(3C++), Catalog Library (Overview, part of Frame doc) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/cat/man/CatalogInfoEntry.man3000066400000000000000000000171741215713201500224610ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: CatalogInfoEntry.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 07 Nov 97 Created # NAME CatalogInfoEntry - C++ class representing a catalog config file entry SYNOPSIS #include "CatalogInfo.h" class CatalogInfoEntry { ... public: CatalogInfoEntry(); CatalogInfoEntry(const CatalogInfoEntry&); int operator=(const CatalogInfoEntry&); ~CatalogInfoEntry(); char* check(); void servType(const char* s); void longName(const char* s); void shortName(const char* s); void url(const char* s); void backup1(const char* s); void backup2(const char* s) void symbol(const char* s); void searchCols(const char* s); void sortCols(const char* s); void sortOrder(const char* s); void showCols(const char* s); void copyright(const char* s); void id_col(int i); void ra_col(int i); void dec_col(int i); void x_col(int i); void y_col(int i); void is_tcs(int i); void equinox(double d); const char* servType() const; const char* longName() const; const char* shortName() const; const char* url() const; const char* backup1() const; const char* backup2() const const char* symbol() const; const char* searchCols() const; const char* sortCols() const; const char* sortOrder() const; const char* showCols() const; const char* copyright() const; int id_col() const; int ra_col() const; int dec_col() const; int x_col() const; int y_col() const; int is_tcs() const; double equinox() const; int isWcs(); CatalogInfoEntry* link() const; void link(CatalogInfoEntry*e); int append(CatalogInfoEntry* e); CatalogInfoEntry* next() const; void next(CatalogInfoEntry*e); friend ostream& operator<<(ostream&, const CatalogInfoEntry&); }; DESCRIPTION Objects of class CatalogInfoEntry are used to represent catalog config file entries. The entries are linked together in the form of a hierarchical list. The next pointer points to the next catalog in the list and the link pointer points to the next list in the hierarchy. A config file entry contains the information necessary to access a catalog. The syntax for each catalog entry is: serv_type: service type, one of: catalog, namesvr, imagesvr directory, local... (see SERVICE TYPES below) long_name: long name of service for displaying short_name: short name of service url: URL used to access catalog, %ra,%dec, etc. expanded (see below) symbol: the symbol to use to plot the given column value (see SYMBOLS below) copyright: optional copyright notice to display in user interface search_cols: optional list of columns that can be searched by in the format col1 "col1 min label" "col1 max label" : ... example: search_cols: mag "Brightest (min)" "Faintest (max)" sort_cols: optional list of columns to sort by {col1 col2 ...} sort_order: optional: set to "increasing" or "decreasing" show_cols: optional list of columns to display (default: all) id_col: column containing id field ra_col: dec_col: columns containing ra and dec (for catalogs supporting WCS) x_col: y_col: columns containing x,y coords (for catalogs not supporting WCS) is_tcs: flag: true if using TCS columns SERVICE TYPES The currently known service types are: catalog - server returns a tab separated table of row/col values namesvr - server returns a single line with id, ra and dec to resolve the given object name imagesvr - server returns an image file directory - the URL is a pointer to another catalog config file local - a local catalog URL SYNTAX The url field is used to build a URL to get the results via HTTP. The syntax is like this: http://host:port/cgi-bin/server?arg1&arg2&...argn If ":port" is missing, it defaults to 80. Substitutions are performed on the URL as follows: %ra, %dec - coordinates of center point %w, %h - width and height in arcmin %r1, %r2 - min and max radius (for circular query) %r - use when server only accepts single radius value %m1, %m2 - min and max magnitude %m - use when server only accepts single magnitude %n - max number of rows to return %cols - list of columns to return (col1,col2,...coln) %id - ID field of item to return (if supported) %mime-type - value for http mime-type field Name servers only need the %id field, which is set to the object name. SYMBOLS The syntax for the "symbol:" field is as follows: symbol: colnames symbol expr : colnames symbol expr : ... where colnames - is a list of column names used (in symbol or expr) symbol - is the symbol to use, one of: square, circle, triangle, cross, plus, diamond, ellipse. The symbol may also be a list such as {circle yellow} and some symbols take extra args for ratio and angle (ellipse). expr - is an expression in terms of colnames above, used to determine the size of the symbol. It may also be a list {expr units}, where units is one of {"image" "deg J2000" "deg B1950}. The default is "image" pixel coordinates. See the RTD documentation for details on the syntax of coordinates and units. The column names (colnames) can be used as variables in the expression using "$" (following Tcl syntax). example: symbol: mag circle 15-$mag : xyz square (1-$xyz)*2.5 symbol: {a/b pa mag} {ellipse yellow ${a/b} $pa} {15-$mag} symbol: "a/b pa mag" "ellipse yellow ${a/b} $pa" "15-$mag" METHODS CatalogInfoEntry() Default constructor, sets all fields to NULL or default values. Use methods to set individual values. CatalogInfoEntry(entry) Copy constructor. operator=(entry) Assignment operator. ~CatalogInfoEntry() Destructor. check() Check that all required fields have been set and return 0 if all ok. servType(s) longName(s) shortName(s) url(s) backup1(s) backup2(s) symbol(s) searchCols(s) sortCols(s) sortOrder(s) showCols(s) copyright(s) Set string keyword values (copy is made internally). id_col(i) ra_col(i) dec_col(i) x_col(i) y_col(i) is_tcs(i) Set int keyword values. equinox(d) Set the equinox for the entry. servType() longName() shortName() url() backup1() backup2() symbol() searchCols() sortCols() sortOrder() showCols() copyright() Get string keyword values. id_col() ra_col() dec_col() x_col() y_col() is_tcs() Get int keyword values. equinox() Get the equinox. isWcs() Return true if the catalog uses word coordinates, that is, if ra_col and dec_col have valid values The default is to use World Coordinates with ra_col=1, dec_col=2. link() link(entry) Get or set the pointer to link entry. Link entries are for catalog directory entries, where the link points to the beginning of a new sublist of catalogs. append(entry) Append the given entry to the end of this list. next() next(entry) Get or set the pointer to next entry in the list. operator<<(ostream, entry) Output operator. The output format is like the config file format. SEE ALSO CatalogInfo, AstroCatalog(3C++) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/cat/man/LocalCatalog.man3000066400000000000000000000046001215713201500215640ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: LocalCatalog.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 27 Jun 96 Created # NAME LocalCatalog - Class for accessing local catalogs stored as tab tables SYNOPSIS #include "LocalCatalog.h" class LocalCatalog : public AstroCatalog { ... public: LocalCatalog(const CatalogInfoEntry*); virtual int query(const AstroQuery& q, const char* filename, QueryResult& result); static int check_table(const char* file); virtual int sort(const char* column, int numeric = 1); virtual int uniq(); }; DESCRIPTION This class can be used to search a local catalog stored as a file in tab table format. The format of the table is something like: TableName # comment line # catalog config information keyword: value ... A B C - - - 0 1 3 3 2 4 ... where the table name and catalog config info are optional. This is the same format used by the "Starbase" package or utilities (see: http://cfa-www.harvard.edu/~john/ for more about Starbase). UNITS Unless otherwise stated, the units for all radius values are in arcmin or image pixels, depending on the catalog config entry settings. The default is arcmin. Floating point values for RA and DEC are always in degrees. The default equinox is J2000, unless set otherwise in the catalog config entry or in the table header. PUBLIC METHODS LocalCatalog(const CatalogInfoEntry*) Constructor - create local catalog class instance. Note: public interface normally uses AstroCatalog::open() with the name of the file containing the local catalog. The argument represents the entry in the catalog config file for this catalog (made automatially, if not already present). query(const AstroQuery& q, const char* filename, QueryResult& result) Run a query on the catalog and return the number of objects found (redefined here to work with local catalogs, refer to the parent class AstroCatalog for details.). check_table(const char* file) Check the validity of a tab table file and return 0 if it is ok. SEE ALSO AstroCatalog ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/cat/man/ProxyDialog.mann000066400000000000000000000023371215713201500216000ustar00rootroot00000000000000# This file was automatically generated by itcldoc # from source code comments. Do not edit by hand! # This file may be processed by the ESO/VLT docDoManPages # command to produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. NAME ProxyDialog - user interface class for defining a proxy server NAMESPACE cat PARENT CLASS util::TopLevelWidget SYNOPSIS ProxyDialog ?options? DESCRIPTION E.S.O. - VLT project/ESO Archive @(#) $Id: ProxyDialog.tcl,v 1.2+++++++++++ 1998/10/28 17:37:23 abrighto Exp $ ProxyDialog.tcl - user interface class for defining a proxy server for HTTP access. who when what -------- --------- ---------------------------------------------- A.Brighton 26 Jun 98 created. WIDGET OPTIONS -configfile Set the width for displaying labels. PROTECTED METHODS cancel {} Called when the Cancel button is pressed. clear {} Called when the Clear button is pressed. init {} Called after options have been evaluated. ok {} Called when the OK button is pressed. reset {} Called when the Reset button is pressed. SEE ALSO TopLevelWidget(n) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/cat/man/QueryResult.man3000066400000000000000000000113701215713201500215450ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: QueryResult.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 27 Jun 96 Created # NAME QueryResult - Class for accessing results of a catalog query SYNOPSIS #include "QueryResult.h" class QueryResult : public TabTable { public: QueryResult(); QueryResult(const char* result); QueryResult(int numCols, char** colNames, const char* result); virtual ~QueryResult(); virtual int getPos(int row, WorldCoords& pos); virtual int getPos(int row, WorldOrImageCoords& pos); virtual int query(const AstroQuery& q, const char* infile, const char* outfile, int& more); virtual void entry(CatalogInfoEntry* e, const char* result = NULL); virtual const char* symbol() const; virtual const char* copyright() const; virtual int id_col() const; virtual int ra_col() const; virtual int dec_col() const; virtual int x_col() const; virtual int y_col() const; virtual double equinox() const; virtual int isWcs() const; }; DESCRIPTION This class manages the result of an AstroCatalog::query. The basic result is a char buffer that contains one row per line where each column is separated by a tab character. Since this is the same format as a local catalog, this class is also used to implement local catalogs (see LocalCatalog). This class provides transparent access to the result based on a row,column index and allows for type conversion from string to the desired type. This class is the same as class TabTable (the parent class), except that it assumes the table has at least the 3 columns "id", "ra" and "dec", if World Coordinates are supported, or "id", "x" and "y" if image coordinates are being used. This class adds methods to get the position for a row and to search in an circle, given the center position and radius. The class keeps a pointer to a catalog config entry that may be based on the original catalog entry or may be read from the header of the local catalog or query results. World Coordinates are assumed if the entry indicates that ra and dec columns are present. UNITS Unless otherwise stated, the units for all radius values are in arcmin for World Coordinates and image pixels otherwise.. Floating point values for RA and DEC are always in degrees. The default equinox is J2000. PUBLIC METHODS QueryResult() QueryResult(const char* result) QueryResult(int numCols, char** colNames, const char* result) The constructors have the same arguments as for the parent class TabTable. They initialize the table from a buffer in tab table format. See the TabTable constructors for details. getPos(int row, WorldCoords& pos) getPos(int row, WorldOrImageCoords& pos) Get the world coordinate or image pixel position for the given row from the columns "ra" and "dec", or "x" and "y", depending on the settings in the catalog config entry. By default the first 3 fields are: id, ra, dec, in J2000. Keywords in the catalog config entry may override these settings. The return value if 0 unless errors are detected. query(const AstroQuery& q, const char* infile, const char* outfile, int& more) Query the given tab table file using the condition described by the given AstroQuery object. Args: q - (in) object describing the query infile - (in) file to search outfile - (in) optional filename to hold results, or null more - (out) set to 1 if more objects would be available but were not returned because q.maxRows was set lower The return value 0 if all is OK. The number found is available as this->numRows(). entry(e, result) Set the catalog config entry for this object. This is included in the file when this object is saved as a local catalog. The optional result arg may be a pointer to the result of a catalog query, which may contain config configuration information. If specified, it is scanned to update the entry with the new information. symbol() id_col() ra_col() dec_col() x_col() y_col() equinox() All these methods return the corresponding values from the catalog config entry for the query results. This may be the same as for the catalog being searched or may have been modified by config information in the header of the query results or local catalog. isWcs() Returns true if the query results contain ra and dec columns for World Coordinate support. SEE ALSO AstroCatalog ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/cat/man/TabTable.man3000066400000000000000000000216001215713201500207140ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: TabTable.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 27 Jun 96 Created # NAME TabTable - Class for managing a tab separated table of values SYNOPSIS #include "TabTable.h" class TabTable { ... public: // constants enum {MAX_ROW_SIZE=8*1024}; // max size of a tab table row enum {MAX_HEADER_SIZE=1024}; // max size of a tab table heading enum {MAX_COLUMNS=255}; // max number of table columns public: TabTable(char sep = '\t'); TabTable(const char* buf, int maxRows = 0, char sep = '\t'); TabTable(int numCols, char** colNames, const char* buf, int maxRows = 0, char sep = '\t'); virtual ~TabTable(); virtual int clear(); virtual int init(const char* buf, int maxRows = 0); virtual int init(int numCols, char** colNames, const char* buf, int maxRows = 0); virtual int get(int row, int col, char*& value); virtual int get(int row, int col, int& value); virtual int get(int row, int col, double& value); virtual int get(int row, int col, float& value); virtual int get(int row, int col, short& value); virtual int get(int row, int col, char& value); virtual int get(int row, const char* colName, char*& value); virtual int get(int row, const char* colName, int& value); virtual int get(int row, const char* colName, double& value); virtual int get(int row, const char* colName, float& value); virtual int get(int row, const char* colName, short& value); virtual int get(int row, const char* colName, char& value); virtual int colIndex(const char* colName) const; virtual const char* colName(int col) const; virtual int hasCol(const char* name) const; static int head(const char* filename, TabTable&); static int head(istream&, TabTable&); virtual int compareHeadings(const TabTable& t); virtual int save(const char* filename); virtual int save(ostream&); virtual int append(const char* filename); virtual int remove(const char* filename); virtual int findRow(const char* tableRow); virtual int printRows(ostream& os); virtual int search(const char* filename, int numSearchCols, char** searchCols, char** minValues, char** maxValues, int maxRows); virtual int search(const char* filename, const char* searchCol, const char* value, int maxRows); virtual int search(const char* filename, int searchCol, const char* value, int maxRows); friend ostream& operator<<(ostream& os, TabTable& t); virtual int numRows() const; virtual void numRows(int n); virtual int numCols() const; virtual char** colNames() const; virtual int status() const; }; DESCRIPTION Class TabTable manages a buffer containing a table where the rows are separated by newlines and the columns by tabs (or other specified char). The class provides transparent access to the table based on a row,column index and allows for type conversion from string to the desired type. Methods are also available to print the table and save it to a file. PUBLIC METHODS TabTable(char sep = '\t') Constructor: initialize empty table. TabTable(const char* buf, int maxRows = 0, char sep = '\t') Constructor: initialize table from buffer in tab table format: VAR VALUE VALUE ... ... COL1 COL2 COL3 ... COLN --- ---- ---- ---- data data data data ... Currently, anything up to the column headings is ignored (This may change later). The format is the same as the tab table format used by starbase. A line beginning with a "-" separates the column names from the data and all column headings and data are separated by tabs (or sep char). The part preceding the column headings may be used later to set certain variables pertaining to the table. In this case, a variable may have one or more values, separated by tabs (sep char). If maxRows is nonzero, only upto that many rows are taken from buf. TabTable(int numCols, char** colNames, const char* buf, int maxRows = 0, char sep = '\t') Constructor: initialize table from data buffer without If maxRows is nonzero, only upto that many rows are taken from buf. headings. The first two args specify the number column headings and their names. ~TabTable() Destructor: free any allocated memory init(const char* buf, int maxRows = 0) Fill the table from the given buffer in tab table format. If maxRows is nonzero, only upto that many rows are taken from buf. init(int numCols, char** colNames, const char* buf, int maxRows = 0) Fill the table from the given buffer in tab table format, with headings specified separately. The first two args specify the number column headings and their names. If maxRows is nonzero, only upto that many rows are taken from buf. clear() Make the table empty and free any resources used get(int row, int col, char*& value) get(int row, int col, int& value) get(int row, int col, double& value) get(int row, int col, float& value) get(int row, int col, short& value) get(int row, int col, char& value) Get row,column values: the parameter "value" is set and 0 is returned if there are no errors. Values of type char* point to internal storage and should not be modified. get(int row, const char* colName, char*& value) get(int row, const char* colName, int& value) get(int row, const char* colName, double& value) get(int row, const char* colName, float& value) get(int row, const char* colName, short& value) get(int row, const char* colName, char& value) Get table values by column name. Values of type char* point to internal storage and should not be modified. colIndex(const char* colName) const Return the table column index for the given table column name. const char* colName(int col) const Return the column name for the given column index. hasCol(const char* name) const Return true if the table contains the given column. static int head(const char* filename, TabTable&) static int head(istream&, TabTable&) Read the heading info from the given stream and put it in the given table. compareHeadings(const TabTable& t) Compare headings in this table and the given one and return 0 if they are the same. save(const char* filename) save(ostream&) Save the contents of this object to the given file as a tab table. append(const char* filename) Append the contents of this object to the given tab table file remove(const char* filename) Remove rows in the tab table file that are also in this object. findRow(const char* tableRow) Find a row matching the given tab separated one and return the index. search(const char* filename, int numSearchCols, char** searchCols, char** minValues, char** maxValues, int maxRows) Search the given tab table file for upto maxRows rows with columns values matching the given arguments and fill this table with the resulting rows. Args: filename - tab table file to search numSearchCols - number of columns in argument arrays searchCols - names of the columns to compare minValues - min/max values for comparison maxValues maxRows - max number of rows to find search(const char* filename, const char* searchCol, const char* value, int maxRows); Search the given tab table file for upto maxRows rows where the given column has the given value and fill this table with the resulting rows. Args: filename - tab table file to search searchCol - name of the column to compare value - value for comparison maxRows - max number of rows to find search(const char* filename, int searchCol, const char* value, int maxRows); Search the given tab table file for upto maxRows rows where the given column has the given value and fill this table with the resulting rows. Args: filename - tab table file to search searchCol - index of the column to compare (0..n) value - value for comparison maxRows - max number of rows to find printRows(ostream& os) Print the table rows to the given stream in tab table format. friend ostream& operator<<(ostream& os, TabTable& t) Output operator, prints the table to the given stream in tab table format. numRows() const Return the number of rows in the table. void numRows(int n) Set the number of rows in the table. numCols() const Return the number of columns in the table. colNames() const Return an array of column names in the table. status() const Return the status after the constructor has completed. SEE ALSO QueryResult ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/cat/man/TcsCatalog.man3000066400000000000000000000120121215713201500212570ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: TcsCatalog.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 27 Jun 96 Created # NAME TcsCatalog - class for accessing TCS catalogs SYNOPSIS #include "TcsCatalog.h" class TcsCatalog : public AstroCatalog { public: TcsCatalog(const CatalogInfoEntry* e); virtual ~TcsCatalog(); static TcsCatalog* open(const char* name); int numCols(); char** colNames(); const char* colName(int col); int colIndex(const char* colName); int hasCol(const char* name); int getObject(const char* id, TcsCatalogObject& obj); int searchClosestStar(const WorldCoords& pos, double mag0, double mag1, TcsCatalogObject& obj); }; DESCRIPTION This class is a subclass of AstroCatalog specialized for accessing GSC, PPM or similar catalogs for use by the TCS (Telescope Control Software). A TcsCatalog is like an AstroCatalog, except that it assumes a catalog has fixed columns, such as those that are found in the GSC or PPM catalogs. This class restricts itself to these fixed columns and ignores the rest. Each row of a TcsCatalog can be represented by a TcsCatalogObject. Any missing column values are set to the appropriate null value (defined in TcsCatalogObject.h). CATALOG SERVERS This class uses the same catalog servers as the AstroCatalog class. Please refer to AstroCatalog for details. LOCAL CATALOGS The format of local catalog files and query results that are stored in files is the same here as in AstroCatalog, except that here the column names are fixed. In addition, catalogs saved in TCS format contain additional comments in the header indicating that the catalog is a TCS catalog and with the meanings of the columns. UNITS Unless otherwise stated, the units for all radius values are in arcmin. Floating point values for RA and DEC are always in degrees. The default equinox is J2000. QUERY PARAMETERS Parameters for catalog searches are checked to make sure they are valid and in the correct range. A radius value must be between 0.0 and 300.0 arcmin. A magnitude may have any value. For ranges, such as min and max radius and min and max magnitude, the order of the arguments is not important, since they will be rearranged as needed. If both min and max values are 0.0, they are ignored for that search. If you really want to search for objects with "0.0" magnitude, specify a range with small values that are not zero, for example, min/max mag = (-0.0001, +0.0001). PUBLIC METHODS TcsCatalog(const CatalogInfoEntry* e) Constructor - create a TCS catalog class instance. Note: the public interface normally uses TcsCatalog::open(). The argument represents the entry in the catalog config file for this catalog. ~TcsCatalog() Destructor - close catalog and free any resources. open(const char* name) Open the named catalog and return a pointer to a new TcsCatalog (or derived class) object created for it or NULL if errors occur. If the given name is really the name of a file, it is opened as a local catalog and the pointer returned is of type TcsLocalCatalog, a subclass of TcsCatalog. If the file is not in the correct format, a NULL pointer is returned. numCols() Return the number of columns in the catalog (fixed number). colNames() Return an array of column names (this is always the same for TCS catalogs). colName(int col) Return the name of the given column (fixed for TCS catalogs). colIndex(const char* colName) Return the column index for the given column name (fixed for TCS catalogs). hasCol(const char* name) Return true if the catalog contains the given column (fixed for TCS catalogs). int getObject(const char* id, TcsCatalogObject& obj) This method is redefined in this class to get the object given by "id" in the catalog and return 0 if all is OK. Note that the interface is changed here to use the TcsCatalogObject to hold the result rather than a QueryResult as in the parent class version. Arguments: id, (in ) - object id in catalog. obj (out) - object for row, if found. int searchClosestStar(const WorldCoords& pos, double mag0, double mag1, TcsCatalogObject& obj) This method is redefined in this class to search for the star closest to the given position, with the magnitude in the given range. Note that the interface is changed here to use the TcsCatalogObject to hold the result rather than a QueryResult as in the parent class version. Arguments: pos, (in ) - center position in world coordinates mag0, (in ) - min magnitude mag1, (in ) - max magnitude obj (out) - object for row, if found SEE ALSO AstroCatalog, TcsCatalogObject(3C++), TcsQueryResult(3C++), TcsLocalCatalog, tcscat(n) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/cat/man/TcsCatalogObject.man3000066400000000000000000000123551215713201500224200ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: TcsCatalogObject.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 27 Jun 96 Created # NAME TcsCatalogObject - Class representing one row of results of a TcsCatalog query. SYNOPSIS #include "TcsCatalogObject.h" // NULL values #define TCS_CATALOG_NULL_INT 4294967294 /* (2^32 - 1) */ #define TCS_CATALOG_NULL_DOUBLE 1.E-300 class TcsCatalogObject { ... public: TcsCatalogObject(); TcsCatalogObject(const TcsCatalogObject&); ~TcsCatalogObject(); TcsCatalogObject& operator=(const TcsCatalogObject &); friend ostream& operator<<(ostream&, const TcsCatalogObject&); void print(char* buf, int bufsize); static void printHeadings(ostream& os); static void printHeadings(char* buf, int bufsize); int printTableRow(ostream&); void reset(); static int isNull(int v); static int isNull(double v); static int isNull(const char* v); // set values int id(const char*); int ra(double); int dec(double); int cooSystem(const char*); int epoch(double); int pma(double); int pmd(double); int radvel(double); int parallax(double); int cooType(const char*); int band(const char*); int mag(double); int more(const char*); int preview(const char*); int distance(double); int pa(double); // get values const char* id(); double ra(); double dec(); const char* cooSystem(); double epoch(); double pma(); double pmd(); double radvel(); double parallax(); const char* cooType(); const char* band(); double mag(); const char* more(); const char* preview(); double distance(); double pa(); static int numCols(); static char** colNames(); static const char* colName(int col); static int colIndex(const char* colName); static int hasCol(const char* name); }; DESCRIPTION This object represents the contents of one row of TCS (GSC or PPM) query results. Missing values are set to the appropriate null value (see above). Methods are available to set and get the object values. The "set" methods do some error checking. The "get" methods are all simple "inline" methods that simply return the value. The following column values represent a TCS catalog object: id object catalog id ra Alpha coordinate for the target in decimal degrees dec Delta coordinate for the target in decimal degrees cooSystem Equinox system and equinox ("B1950" or "J2000") epoch Epoch expressed as decimal year pma Proper Motion Alpha in radians/year (-10.0 to 10.0) pmd Proper Motion Delta in radians/year (-10.0 to 10.0) radvel radial velocity in km/sec (-200000 to 200000) parallax Parallax in arcseconds (-10000 to 10000) cooType Coord. type: "M" for mean, "A" for apparent character band Magnitude wavelength band ("V") mag Object's magnitude in given band more An HTTP URL pointing to more info on the object preview An HTTP URL pointing to an image of the object distance distance to center of the field pa position angle based on center of the field UNITS Unless otherwise stated, the units for all radius values are in arcmin. Floating point values for RA and DEC are always in degrees. The default equinox is J2000. PUBLIC METHODS TcsCatalogObject() Constructor: initialize all fields to null. TcsCatalogObject(const TcsCatalogObject&) copy constructor. ~TcsCatalogObject() Destructor. TcsCatalogObject& operator=(const TcsCatalogObject &) Assignment. operator<<(ostream&, const TcsCatalogObject&) Output operator (Tcl list format). print(char* buf, int bufsize) Print this object to the given buffer. printHeadings(ostream& os) printHeadings(char* buf, int bufsize) Print the headings to match the output of '<<' above. printTableRow(ostream&) Print this object as a tab separated row reset() Result all fields to default values. isNull(int v) isNull(double v) isNull(const char* v) Return true if the given value is null (by convention). id(const char*) ra(double) dec(double) cooSystem(const char*) epoch(double) pma(double) pmd(double) radvel(double) parallax(double) cooType(const char*) band(const char*) mag(double) more(const char*) preview(const char*) distance(double) pa(double) Set fields, with range checking, return 0 if OK. id() ra() dec() cooSystem() epoch() pma() pmd() radvel() parallax() cooType() band() mag() more() preview() distance() pa() Member access: return member value. The following methods are for compatibility with other AstroCatalog classes: numCols() Return the number of columns in the catalog. colNames() Return an array of column names. colName(int col) Return the column name for the given column. colIndex(const char* colName) Return the column index for the given column name. hasCol(const char* name) Return true if the catalog contains the given column. SEE ALSO TcsCatalog, TcsQueryResult(3C++) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/cat/man/TcsQueryResult.man3000066400000000000000000000044621215713201500222230ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: TcsQueryResult.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 27 Jun 96 Created # NAME TcsQueryResult - class for accessing results of a TCS catalog query SYNOPSIS #include "TcsQueryResult.h" class TcsQueryResult : public QueryResult { ... public: TcsQueryResult(); TcsQueryResult(const char* result); virtual ~TcsQueryResult(); int getObj(int row, TcsCatalogObject&); int printRows(ostream& os); // -- redefine these to deal with TCS columns -- char** colNames(); int numCols(); const char* colName(int col); int colIndex(const char* colName); }; DESCRIPTION This class manages the result of an TcsCatalog::query. Internally a QueryResult object manages the "tab table" query results. This class provides transparent access to the result based on a row, column index and, unlike the QueryResult class, is specialized for accessing the TCS (GSC and PPM) catalogs. There are special methods to return GSC and PPM fields in common units and to determine if a field is present in the catalog. UNITS Unless otherwise stated, the units for all radius values are in arcmin. Floating point values for RA and DEC are always in degrees. The default equinox is J2000. PUBLIC METHODS TcsQueryResult() Constructor: initialize empty table. TcsQueryResult(const char* result) Constructor: initialize from query result buffer. ~TcsQueryResult() destructor: free any allocated memory. getObj(int row, TcsCatalogObject&); Access a TcsCatalog (GSC/PPM) result row: fill out the given TcsCatalogObject. printRows(ostream& os); Print table rows to the given stream. colNames() Get array of column names in a TCS query result. numCols() Get number of columns in a TCS query result. colName(int col) Return the column name for the given column index. int colIndex(const char* colName) Return the column index for the given column name SEE ALSO TcsCatalog, TcsCatalogObject(3C++) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/cat/man/astro_catalog.man3000066400000000000000000000447021215713201500220700ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: astro_catalog.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- -------------------------------------- # Allan Brighton 16 Oct 95 Created # NAME astroCatalog - C library for accessing astromical catalogs SYNOPSIS #include "astroCatalog.h" typedef void* AcHandle; typedef void* AcResult; AcHandle acOpen(char* name); void acClose(AcHandle); int acMore(AcHandle); int acNumCols(AcHandle) char* acColName(AcHandle, int col); char** acColNames(AcHandle); int acColIndex(AcHandle handle, char* name); char* acGetError(); int acGetErrorCode(); int acGetDescription( AcHandle cat, int* numCols, char*** colNames); int acGetObject( AcHandle cat, char* id, int numCols, char** colNames, AcResult* result); int acGetArea( AcHandle cat, int numCols, char** colNames, double ra0, double dec0, double ra1, double dec1, double mag0, double mag1, int maxRows, char* filename, int* numFound, AcResult* result); int acCircularSearch( AcHandle cat, int numCols, char** colNames, double ra, double dec, double radius0, double radius1, double mag0, double mag1, int maxRows, char* filename, int* numFound, AcResult* result); int acSearchClosestStar( AcHandle cat, int numCols, char** colNames, double ra, double dec, double mag0, double mag1, AcResult* result); int acCatalogSearch( AcHandle cat, int numCols, const char* const* colNames, int numSearchCols, char** searchCols, const char* const* minVals, const char* const* maxVals, int maxRows, const char* filename, int* numFound, AcResult* result); /* * --- routines for accessing the query results --- */ int acrNumRows(AcResult); int acrNumCols(AcResult); char** acrColNames(AcResult); int acrGetString(AcResult, int row, int col, char** value); int acrGetInt(AcResult, int row, int col, int* value); int acrGetDouble(AcResult, int row, int col, double* value); int acrGetFloat(AcResult, int row, int col, float* value); int acrGetShort(AcResult,int row, int col, short* value); int acrGetChar(AcResult,int row, int col, char* value); int acrGetNString(AcResult,int row, const char* colName, char** value); int acrGetNInt(AcResult,int row, const char* colName, int* value); int acrGetNDouble(AcResult,int row, const char* colName, double* value); int acrGetNFloat(AcResult,int row, const char* colName, float* value); int acrGetNShort(AcResult,int row, const char* colName, short* value); int acrGetNChar(AcResult,int row, const char* colName, char* value); int acrGetWC(AcResult, int row, WC* pos); int acrColIndex(AcResult,const char* colName); void acrDelete(AcResult); DESCRIPTION This man page describes a library for accessing astronomical catalogs from C applications in a generic way. Note: Although the library is implemented in C++, it also defines a C interface, which is described here. To use this library from C, an application must have a C++ main and be linked with the C++ compiler. This is easily done by renaming the C main to c_main and defining a C++ main that calls it. The main purpose of this library is to provide generic access to a variety of astronomical catalogs available locally or on the network. The interface hides the details of accessing the various catalogs and shows their contents in a uniform way. CATALOG SERVERS This class communicates with a catalog server via HTTP requests. The list of servers and how to access them is kept in a configuration file, which is also accessed via HTTP. The default config file is: http://archive.eso.org/skycat/skycat.cfg The default can be overridden by defining the environment variable SKYCAT_CONFIG to another valid HTTP URL. LOCAL CATALOGS If the catalog name passed to acOpen is the name of a file, it is taken to be a local catalog file in the format used by the Starbase utilities. A local catalog is an ASCII file containing an optional title and header information followed by the column headings, a dashed line and the data rows. The columns are separated by tabs. This is also the format of query results returned via HTTP from remote catalog servers. Example: Table1 id ra dec pos-e mag ------ -- --- ----- --- A00050 3:19:28 8:26:29 0.2 13.49 A00098 3:19:32 8:34:15 0.4 13.40 A00288 3:19:21 8:31:19 0.2 13.13 A00314 3:19:44 8:30:58 0.2 13.98 The pointer returned from acOpen for files is a pointer to an object for accessing local catalogs. The interface is the same for remote and local catalogs, only the implementation is different. QUERY PARAMETERS Parameters for catalog searches are checked to make sure they are valid and in the correct range. A radius value must be between 0.0 and 300.0 arcmin. A magnitude may have any value. For ranges, such as min and max radius and min and max magnitude, the order of the arguments is not important, since they will be rearranged as needed. If both min and max values are 0.0, they are ignored for that search. If you really want to search for objects with "0.0" magnitude, specify a range with small values that are not zero, for example, min/max mag = (-0.0001, +0.0001). FORMAT OF QUERY RESULTS Query results are accessed by a set of routines that operate on a an "AcResult" object that is returned as the last argument in the query routine calls. The object keeps a table of result rows and columns internally and provides an interface for extracting the values in various formats and data types. The format of query results in a file was described above (see LOCAL CATALOGS). ROUTINE NAMES Note that the astroCatalog routine names all have the prefix "ac", while the routines that operate on the query results all have the prefix "acr". MEMORY MANAGEMENT Memory is allocated for the query results. It is the caller's responsibility to delete the result object with the acrDelete() routine when it is no longer needed. ERROR HANDLING Most of the routines described here return non-zero on error and zero if all is OK (routines that return pointers return a NULL pointer on error). The text of the error message can be retrieved with the acGetError() function and an error code is available via the acGetErrorCode function. The error codes are the same as those in and have the same meanings (EINVAL means invalid operand - or parameter, 0 means no code was available). UNITS Unless otherwise stated, the units for all radius values are in arcmin. Floating point values for RA and DEC are always in degrees. The default equinox is J2000. ASTRO CATALOG C ROUTINES acOpen Open the named catalog and return a handle for it. The handle can be used in subsequent operations on the catalog. If the catalog can not be opened, NULL is returned and an error message can be retrieved with acGetError(). Arguments: name (in) - Catalog name, (long or short name) from the catalog config file. Return value: Catalog handle for use in future calls. Use acClose() to free resources when no longer needed. acClose Close the given catalog and free its resources. Arguments: handle (in) - Catalog handle returned from acOpen(). Return value: None acGetDescription Get the number of columns and the column names for the given catalog and return 0 if all is OK. The memory for the return arrays is managed internally and should not be modified by the caller. Arguments: handle (in ) - Catalog handle returned from acOpen(). numCols (out) - Number of catalog columns. colNames (out) - Pointer to array of column names. Return value: If successful, 0, otherwise 1. acGetObject Get the values for the specified columns for the object given by "id" in the catalog and return 0 if there are no errors. The id should be a valid object id obtained by a previous catalog query. If colNames is not NULL, it should be an array of "numCols" column names to fetch, otherwise all columns are fetched. "result" is set to point to an AcResult object for accessing the catalog values found (it may be empty). The memory for the result is allocated (see MEMORY MANAGEMENT above). Arguments: handle (in ) - Catalog handle. id (in ) - Object id. numCols (in ) - Number of column names specified colNames (in ) - Array[numCols] of column names to read, or NULL to read all columns. result (in/out) - Handle for accessing query results. Return value: Returns 0 on success, 1 for errors. It is not considered an error if no object is found. Use acrNumRows(result) to determine if an object was found. Comment: An error is returned if the catalog does not support query by Id. The GSC server now supports this, but older versions of the catalog config file do not have the new URL for this yet. acGetArea Get the values for all objects in the rectangular region given by the two world coordinate points. If mag0 and mag1 are not 0.0, they are taken to be the minimum and maximum magnitude values for the query. If colNames is not NULL, it should be an array of numCols column names to fetch, otherwise all columns are fetched. The number of object rows returned is limited to maxRows (the acMore() routine can be called to see if more objects would have been available). On return, numFound is set to the number of objects found and, if any were found, "result" is set to point to an AcResult object for accessing the catalog values found. The memory for the result is allocated (see MEMORY MANAGEMENT above). If filename is not NULL, the results will be copied to the given file in the format of a local catalog. Arguments: handle (in ) - Catalog handle. numCols (in ) - Number of column names specified. colNames (in ) - Array[numCols] of column names to read, or NULL to read all. ra0 (in ) - World coordinates of first point dec0 (in ) - in degrees. ra1 (in ) - World coordinates of second point dec1 (in ) - in degrees. mag0 (in ) - Min magnitude. mag1 (in ) - Max magnitude. maxRows (in ) - Max number of rows to return. filename (in ) - If not null, write results to this file. numFound (out) - Set to number of objects found. result (in/out) - Handle for accessing query results. Return value: If successful, 0, otherwise 1. Comment: An error is returned is the catalog does not support area querries. acCircularSearch Get the values for all objects in the circle or ring given by the world coordinate point and the min and max radius values. If mag0 and mag1 are not 0.0, they are taken to be the minimum and maximum magnitude values for the query. If colNames is not NULL, it should be an array of column names to fetch, otherwise all columns are fetched. The number of object rows returned is limited to maxRows (the acMore() routine can be called to see if more objects would have been available). On return, numFound is set to the number of objects found and, if any were found, "result" is set to point to an AcResult object for accessing the catalog values found. The memory for the result is allocated (see MEMORY MANAGEMENT above). If filename is not NULL, the results will be copied to the given file in the format of a local catalog. Arguments: handle (in ) - Catalog handle. numCols (in ) - Number of column names specified. colNames (in ) - Array[numCols] of column names to read, or NULL to read all. ra (in ) - World coordinates of center point dec (in ) - in degrees. radius0 (in ) - Min radius from center point. radius1 (in ) - Max radius from center point. mag0 (in ) - Min magnitude. mag1 (in ) - Max magnitude. maxRows (in ) - Max number of rows to return. filename (in ) - If not null, write results to this file. numFound (out) - Number of objects found. result (in/out) - Handle for accessing query results. Return value: If successful, 0, otherwise 1. acSearchClosestStar Get the values for the specified columns for the object in the catalog closest to the given position and return 0 if there are no errors. If colNames is not NULL, it should be an array of column names to fetch, otherwise all columns are fetched. If mag0 and mag1 are not 0.0, they are taken to be the minimum and maximum magnitude values for the query. "result" is set to point to an AcResult object for accessing the catalog values found (it may be empty if none were found). The memory for the result is allocated (see MEMORY MANAGEMENT above). Arguments: handle (in ) - Catalog handle. numCols (in ) - Number of column names specified. colNames (in ) - Array[numCols] of column names to read, or NULL to read all columns. ra (in ) - World coordinates of point dec (in ) - in degrees. mag0 (in ) - Min magnitude. mag1 (in ) - Max magnitude. result (in/out) - Handle for accessing query results. Return value: Returns 0 on success, 1 for errors. It is not considered an error if no object is found. Use acrNumRows(result) to determine if an object was found. acCatalogSearch Get the values for all objects fulfilling the specified criteria. The criteria are given by the array of column names to compare and two arrays of the same size containing min and max values, in string format, corresponding to the column names. Null strings are ignored, so, for example, if there is no min value, only the max value will be used. If colNames is not NULL, it should be an array of column names to fetch, otherwise all columns are fetched. The number of object rows returned is limited to maxRows (the acMore() routine can be called to see if more objects would have been available). On return, numFound is set to the number of objects found and, if any were found, "result" is set to point to an AcResult object for accessing the catalog values found. The memory for the result is allocated (see MEMORY MANAGEMENT above). If filename is not NULL, the results will be copied to the given file in the format of a local catalog. Arguments: handle (in ) - Catalog handle. numCols (in ) - Number of column names specified. colNames (in ) - Array[numCols] of column names to read, or NULL to read all. numSearchCols (in ) - number of column names to compare searchCols (in ) - array of column names to compare minVals (in ) - Array of column minimum values. maxVals (in ) - Array of column maximum values. maxRows (in ) - Max number of rows to return. filename (in ) - If not null, write results to this file. numFound (out) - Number of objects found. result (in/out) - Handle for accessing query results. Return value: If successful, 0, otherwise 1. acMore Return true if there would have been more rows available to the most recent query, but they were not returned because the maximum row (maxRows argument) limit was reached. Arguments: handle (in ) - catalog handle Return value: 1 if more rows were available, otherwise 0. acNumCols Return the number of columns in the catalog. Arguments: handle (in ) - catalog handle Return value: the number of columns in the catalog acColName Return the name of the given column in the catalog, or NULL if there is no such column. Arguments: handle (in ) - catalog handle col (in ) - column index (0..n) Return value: column name of NULL if none acColIndex Return the column index for the given column name, or -1 if there is no such column. Arguments: handle (in ) - catalog handle name (in ) - column name Return value: column index acGetError Return the text of the most recent error message reported by the catalog routines. Arguments: none Return value: pointer to error text (a static buffer) acGetErrorCode Return the error code from the most recent error message. This is one of the codes defined in , for example: EINVAL for an invalid argument value. Arguments: none Return value: error code value ACCESSING CATALOG QUERY RESULTS The following routines operate on the AcResult object returned from the query routines: acrNumRows Return the number of result rows. Arguments: handle (in ) - query result handle Return value: number of rows in result acrNumCols Return the number of result columns. Arguments: handle (in ) - query result handle Return value: number of columns in result acrColNames Return a pointer to an array of result column names. Arguments: handle (in ) - query result handle Return value: array of column names acrGetString acrGetInt acrGetDouble acrGetFloat acrGetShort acrGetChar Get result values by row and column index. Note: there are various versions for different data types and parameters. All return 0 for success and set the last argument value or return 1 for error. Arguments: handle (in ) - query result handle row (in ) - row index col (in ) - column index value (in/out) - address of variable to hold value Return value: 0 for success, otherwise 1 for error. acrGetNString acrGetNInt acrGetNDouble acrGetNFloat acrGetNShort acrGetNChar Get result values by row and column name. Note: there are various versions for different data types and parameters. All return 0 for success and set the last argument value or return 1 for error. Arguments: handle (in ) - query result handle row (in ) - row index col (in ) - column name value (in/out) - address of variable to hold value Return value: 0 for success, otherwise 1 for error. acrGetWC Get the position columns (RA and DEC) from the given result row and return success (0), otherwise error (1). Arguments: handle (in ) - query result handle row (in ) - row index pos (in/out) - address of WC object to hold coords Return value: 0 for success, otherwise 1 for error. acrColIndex Return the result column index for the given result column name. Arguments: handle (in ) - query result handle colName (in ) - name of column Return value: column index or -1 for error. acrDelete Delete the result object (free the memory). SEE ALSO AstroCatalog, TclAstroCat(3C++) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/cat/man/astro_image.man3000066400000000000000000000067211215713201500215370ustar00rootroot00000000000000# $Id: astro_image.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 16 Oct 95 Created # NAME astroImage - C Library for accessing astronomical image servers (obsolete) SYNOPSIS #include "astroImage.h" typedef void* AiHandle; AiHandle aiOpen(char* name); void aiClose(AiHandle); char* aiGetImage(AiHandle handle, double ra, double dec, double width, double height); DESCRIPTION Note: This interface is obsolete. Please use the astroCatalog interface, which now also supports image servers. This man page describes a library for accessing astronomical image servers from C applications in a generic way. Note: Although the library is implemented in C++, it also defines a C interface, which is described here. To use this library from C, an application must have a C++ main and be linked with the C++ compiler. This is easily done by renaming the C main to c_main and defining a C++ main that calls it. The main purpose of this library is to provide generic access to a variety of astronomical image servers available locally or on the network. The interface hides the details of accessing the various servers. IMAGE SERVERS This class communicates with an image server via HTTP requests. The list of servers and how to access them is kept in a configuration file, which is also accessed via HTTP. The default config file is: http://archive.eso.org/skycat/skycat.cfg The default can be overridden by defining the environment variable SKYCAT_CONFIG to another valid HTTP URL. ERROR HANDLING Most of the routines described here return non-zero on error and zero if all is OK (routines that return pointers return a NULL pointer on error). The text of the error message can be retrieved with the acGetError() function and an error code is available via the acGetErrorCode function. The error codes are the same as those in and have the same meanings (EINVAL means invalid operand - or parameter, 0 means no code was available). UNITS Unless otherwise stated, the units for all radius values are in arcmin. Floating point values for RA and DEC are always in degrees. The default equinox is J2000. C ROUTINES aiOpen Open the named image server and return a handle for it or NULL if there were errors. The handle can be used in subsequent operations on the image server. Arguments: name (in) - image server name Return value: image server handle for use in future calls aiClose Close the image server connection and free its resources. Arguments: handle (in) - image server handle Return value: None aiGetImage Pass a request to the image server and return the name of a FITS file containing the resulting image, or NULL if not found. The return filename is the name of a temporary file that will be reused on the next call to this routine. Arguments: handle (in) - image server handle ra (in ) - world coordinates of center point dec (in ) - in degrees width (in ) - width of image in arc-minutes image (in ) - height of image in arc-minutes Return value: pointer to temporary FITS file containing image SEE ALSO AstroImage, TclAstroImage(3C++) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/cat/man/astrocat.man1000066400000000000000000000023651215713201500210630ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: astrocat.man1,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 27 Mar 98 Created # NAME astrocat - Standalone catalog browser application SYNOPSIS astrocat ?catalogName? ?options? DESCRIPTION The "astrocat" command is a standalone user interface to the catalog library. This window interface can be used to query catalogs and get configuration about the available catalogs. See the man pages for astrocat(n) and AstroCatalog(3) for details that are not described here. If a catalog name is specified, it should be one of the names in the catalog configuration file, for example, "gsc@eso". If no catalog name is specified, a default is chosen (first in config file) and you can choose a new catalog from the menus. OPTIONS See AstroCat(n), the Itcl class version, which has the same options. SEE ALSO astrocat(n), AstroCat(n), AstroCatalog(3) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/cat/man/astrocat.mann000066400000000000000000000371461215713201500211650ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: astrocat.mann,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 25 Jan 98 Created # NAME astrocat - Tcl interface to the catalog library SYNOPSIS astrocat $instName $instName subcommand ... DESCRIPTION The "astrocat" Tcl command is the Tcl interface to the catalog library, in particular the AstroCatalog(3) class. This command can be used to query catalogs and get configuration about the available catalogs. See the man page for AstroCatalog(3) for details that are not described here. The astrocat Tcl command creates a new Tcl command with the same name as its argument ($instName) that provides the subcommands described below. CATALOG DIRECTORIES Catalogs may be organized in hierarchies, with catalog directories containing other catalogs. Some subcommands accept an optional "directory" argument, which may be either the name of the catalog directory, or a tcl list of directories forming a catalog directory path. Note that only catalog directories may be specified in this way, not the catalog names themselves. SUBCOMMANDS $instName authorize $instName authorize username passwd ?realm server? If the previous HTTP GET returned an authorization error: (The HTML error text returned in Tcl contained the string: "Authorization Required"), the application can ask the user to enter a username and password to use to access the URL and then retry the GET after using this subcommand to set the authorization information to use. With no arguments, this command returns a list of the form {needpasswd realm server} where: needpasswd is nonzero if a password is required for the URL. realm is the string taken from the HTTP header (Basic realm=...). server is the name of the target server that wants the password. If arguments are specified, they should be the username and password and optionally the realm and server hostname. If the last 2 args are specified, the information is stored in a file for later lookup (see HTTP(3)). $instName check $filename Check that the given filename is a valid local catalog (tab table format). $instName checkrow $row Check that the given row (Tcl list of columns) is valid for a local catalog. The row should contain valid values for ra and dec, if we are using world coords, or x and y, if we are using image coords. The default columns are "id ra dec ...", but can be overridden in the catalog config file or header. This command generates an error if the position (ra, dec) or (x, y) is not found or is not in range. $instName close Close the current catalog, if one was open. $instName copyright Return the copyright string for this catalog from the catalog config file. $instName dec_col Return the value of the dec_col keyword for this catalog from the catalog config file. $instName delete Use the "$instName delete" subcommand to free the resources for this object and remove the Tcl command. $instName entry get ?$name? ?$directory? $instName entry set $$info ?$name? ?$directory? $instName entry update $info ?$name? ?$directory? $instName entry add $info ?$directory? $instName entry remove $name "entry get" returns the catalog config entry for the currently open catalog or for the given catalog if one is specified. The format of the return value is a tcl list of {keyword value} pairs: {{key value} {key value} ...} for example: {{serv_type catalog} {long_name "Guide Star Catalog at ESO"} {short_name gsc@eso} {url http://archive.eso.org/...} {symbol ...} {id_col 0} {ra_col 1} {dec_col 2} ...} If the "directory" argument is specified, the entry is searched for in the given catalog directory, otherwise it is searched for starting at the top level directory (the catalog entries are linked in a hierarchical list or directory structure). "entry update" allows you to update fields in the catalog's config entry. Some fields, such as the catalog name and URL can not be changed in this way, however the column positions id_col, ra_col, dec_col, etc... may be updated. The format for the update info is the same as that returned by "entry get". The directory argument has the same meaning as with the "entry get" subcommand. Note: The "entry update" command is needed, for example, when a catalog query was run in a subprocess. The results of the query may include config info, such as the default plot symbol and the columns for id, ra and dec. This subcommand can be used to get this information back into the parent process catalog entry. "entry add" adds a new catalog entry to the internal list. The format of the argument is the same as that for update. The entry is added to the given directory or the top level if none is specified. "entry remove" removes the entry for the named catalog from the internal default catalog list. $instName feedback $fileDesc Specifies a Tcl file descriptor to use to write feedback info during HTTP transfer of catalog data. 1 Arg: file descriptor. $instName getcol Given a row of output from a query, return the value for the named column in Tcl. example: set preview [$cat getcol preview $row] $instName getidpos Given a row of output from a query, return a list {id ra dec} (or {id x y} if we're not using wcs) for the given row. The positions of the 3 columns default to the first 3 columns: id, ra and dec, but might be specified differently in the catalog config entry or result header. example: lassign [$cat getidpos $row] id ra dec $instName getimage -option value ... Request an image from the current image server and return the name of the FITS file holding the image. The options are the same as for the query subcommand. $instName getpreview ?-url $url? ?-tmpfile $filename? Given a URL from a query output line, get the preview data and put it in a temp file. The return value in Tcl is a list of {filename type}, where filename is the name of the file containing the preview data and type is either "image" for a decompressed FITS image or "table" for a tab table with data to be plotted in a graph. The temp file is re-used and deleted in the destructor. example: set preview [$cat getpreview -url "http://...." ?-tmpfile "/tmp/img..."?] -url specifies the URL to use. -tmpfile can be used to specify the image file name to use. $instName hascol Return true if the catalog contains the given column name (in the config entry). $instName headings Return a Tcl list of the column headings. $instName help Return the help info for this catalog from the catalog config file. $instName id_col Return the value of the id_col keyword for this catalog from the catalog config file. $instName info $serv_type ?$directory? This command returns a list of catalogs from the catalog config file. The "serv_type" argument determines which catalogs are listed (one of: catalog, namesvr, imagesvr, directory, local...). If $serv_type is an empty string, all entries are returned. If $directory is specified, the return list will be from the given catalog directory entry, retrieved via HTTP if needed. The default, if no $directory is given, is the top level list read from the default config file at startup. $instName is_tcs ?$name? ?$newValue? With 0 or 1 arg, returns true if this catalog (or the given one) is a TCS catalog. If $newValue is specified, it sets the tcs flag for the given catalog. $instName ispix Returns true if the catalog is based on image pixel coordinates. $instName iswcs Returns true if the catalog is based on world coordinates. $instName load $filename This command loads the named catalog config file, making the catalogs in it available to the application. $instName longname ?name? Returns the long_name field from the catalog config file for the given long or short name, or for the current catalog. $instName more Return true if there were more rows to fetch on the last query (i.e.: not all rows that were found were returned due to limits). $instName open name ?directory? Open the named astromonical catalog and refer to it in future queries. If a directory argument is given, it may be either the name of the catalog directory to search, or a tcl list forming the path to the catalog directory. $instName plot $graph $element $filename $xVector $yVector Plot the contents of the given tab table file in the given BLT graph widget. element is the BLT graph element name filename is the local catalog file xVector is the name of the BLT x vector yVector is the name of the BLT y vector The data for the given element in the given graph will be set directly from here without going through tcl. The return value in Tcl is the number of rows (for the graph's x-axis) $instName query ?-option $value ...? Pass a query to the current catalog and return the result as a Tcl list of rows, where each row is a Tcl list of values. Options and Values: -id $id Specify the catalog id of the object, (as returned from a previous query). If this is specified, -pos, -name, -mag and -radius should not be specified and will be ignored. -pos {ra dec} -pos {x y} -pos {ra1 dec1 ra2 dec2} -pos {x1 y1 x2 y2} World {ra, dec} or image {x, y} coordinates of center position, or list {ra1 dec1 ra2 dec2} or {x1 y1 x2 y2} of 2 points for an area. World Coordinates are given as {H:M:S[+-]D:M:S} in the given equinox. If the catalog config entry contains the keywords "x_col" and "y_col", the coords are interpreted as image coords, otherwise world coords. -equinox $equinox specify the quinox for position (default 2000). -width $w -height $h Dimensions of rectangle with pos at center (alternative to specifying 2 positions) in arcmin for world coords or pixel for image coords. -mag $mag Max or list {min max} magnitude of object -radius $r Max or list (min max} radius from position (in arcmin for world coords or pixel for image coords). -nameserver $ns Name of nameserver catalog to use (simbad@eso, ned@eso,...). -name $name Can be used instead of -pos. The name will be resolved using the value of -nameserver (default: SIMBAD) -columns {col1 col2 ...} Specify a list of columns to return. -searchcols {col1 col2 ...} Specify a list of columns to search by. The -minvalues and -maxvalues options supply the corresponding value ranges and must have the same lengths. -minvalues {v1 v2 ...} -maxvalues {v1 v2 ...} Specify a list of values corresponding to the columns specified with the -searchcols option. The values may be numeric or string format, but the lists must have the same lengths as the one specified by the -searchcols option. -sort {col1 col2 ...} Set the list of column names to sort by. -sortorder increasing -sortorder decreasing Set the sort order. -nrows $n Set the max number of rows to return. Each option has one value, however, for a range or area query, some values can be a list, such as -radius "$rad1 $rad2" to give a radius range or -pos "$pos1 $pos2" to give an area. If -columns is not specified, all columns are assumed. Otherwise, if -columns is specified, the column names should be valid for the catalog and the result will be a list of rows with those columns. Note that not all catalogs will support sorting by all fields. $instName querypos Return the world or image coordinate position arguments from the most recent query, posibly expanded by a name server such as SIMBAD. The result is a list of the form {ra dec equinox} for world coordinates or just {x y} for image coords. $instName ra_col return the value of the ra_col field from the config file. $instName reload This command reloads the default catalog config file and updates the internal catalog entries from it. This is meant to be used after the config file has been edited by hand to make the new data available to the application. $instName remove $filename ?$data? ?$equinox? ?$headings? With 1 arg, remove the results of the previous query from the given file. If $data is specified, it should be a Tcl list of rows to be removed, in the format returned by the query command. If $equinox is specified, it is the equinox of ra and dec in $data (so that ra,dec can be converted to J2000 for comparison). If $headings is given, it is used as a Tcl list of column headings. Otherwise the catalog headings are used, if there is a current catalog. The data rows are removed from the file, which should be in the form of a local catalog (tab table), such as that used by the starbase utilities. $instName root This command returns the name of the root catalog directory. $instName save $filename ?$iflag? ?$data? ?$equinox? ?$headings? With 1 arg, save the results of the previous query to the given file. If $iflag is true, the data is inserted in the file if it already exists and the file is sorted and duplicates removed. If $data is specified, it should be a Tcl list of rows to be saved, in the format returned by the query command. If $equinox is specified, it is the equinox of the ra and dec columns in the data (the first 3 columns are assumed to be id, ra and dec, unless otherwise defined in the catalog config entry or header). If $headings is given, it is used as a Tcl list of column headings. Otherwise the catalog headings are used, if there is a current catalog. The data is saved to a file in the form of a local catalog (tab table) that can be loaded again or processed by starbase utilities. $instName searchcols ?newValue? With no args, return the "search_cols" entry for this catalog. With one arg, specify a new value for the search_cols entry, which should be a list of the form: {{colName minLabel maxLabel} ...} $instName servtype ?name? Return the servtype for this catalog or for the given catalog. $instName shortname ?name? Returns the short_name field from the catalog config file for the given long name, or for the current catalog. $instName showcols ?newValue? With no args, return the "show_cols" entry for this catalog. With one arg, specify a new value for the show_cols entry, which should be a list of the form: {col1 col2 ...}. $instName sortcols ?newValue? With no args, return the "sort_cols" entry for this catalog. With one arg, specify a new value for the sort_cols entry, which should be a list of the form: {col1 col2 ...} $instName sortorder With no args, return the "sort_order" entry for this catalog. With one arg, specify a new value for the sort_order entry, which should be a list of the form: {col1 col2 ...} $instName symbol ?newValue? With no args, return the "symbol" entry for this catalog. With one arg, specify a new value for the symbol entry, which should be a list of the form: {{colNames symbolExpr sizeExpr} ...} where colNames is a list of column names used, symbolExpr is one of the accepted symbol expressions, such as "circle ?color?" and sizeExpr is an expression (or a list of {expr ?units?}) giving the radius of an object. $instName url ?name? Return the url for this catalog or for the given catalog. $instName x_col Return the value of the x_col keyword for this catalog from the catalog config file. $instName y_col Return the value of the y_col keyword for this catalog from the catalog config file. SEE ALSO AstroCatalog(3) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/cat/man/tcscat.mann000066400000000000000000000027561215713201500206250ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: tcscat.mann,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 25 Mar 98 Created # NAME tcscat - Tcl interface to the catalog library (TCS version) SYNOPSIS tcscat $instName $instName subcommand ... DESCRIPTION The "tcscat" Tcl command is the TCS (Telescope Control System) Tcl interface to the catalog library, in particular the TcsCatalog(3C++) class, which is a subclass of AstroCatalog(3C++). This command inherits all of the features of the "astrocat" Tcl command, but is designed for use with catalogs that have a fixed number of known columns. See the man page for TcsCatalogObject(3C++) for a description of the columns. A tcscat object can read other types of catalogs, but saving a catalog saves it in TCS format, which contains only the known columns, with default values inserted where necessary. SUBCOMMANDS The tcscat Tcl command creates a new Tcl command with the same name as its argument ($instName). The subcommands are the same as the "astrocat" subcommands, (see astrocat(n)). Only the behavior is redefined. SEE ALSO astrocat(n), TcsCatalog(3C++), TcsCatalogObject(3C++) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/cat/pkgIndex.tcl.in000066400000000000000000000002151215713201500205640ustar00rootroot00000000000000# Tcl package index file, version 1.0 package ifneeded Cat @PACKAGE_VERSION@ [list load [file join [file dirname $dir] @PKG_LIB_FILE@] Cat] skycat-3.1.2-starlink-1b/cat/tests/000077500000000000000000000000001215713201500170465ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/cat/tests/all.tcl000066400000000000000000000005531215713201500203250ustar00rootroot00000000000000#!/bin/sh # The next line restarts using tclutil.sh \ exec wish $0 ${1+"$@"} set n 0 foreach testfile [lsort [glob t*.tcl]] { if {"$testfile" != "test.tcl"} { incr n set name [string range [file rootname $testfile] 1 end] pack \ [button .b$n \ -text $name \ -command "exec wish $testfile -geometry +300+300 &"] \ -side top -fill x } } skycat-3.1.2-starlink-1b/cat/tests/dss.fits000066400000000000000000000550001215713201500205260ustar00rootroot00000000000000SIMPLE = T /FITS header BITPIX = 16 /No.Bits per pixel NAXIS = 2 /No.dimensions NAXIS1 = 35 /Length X axis NAXIS2 = 35 /Length Y axis EXTEND = T / DATE = '04/01/06 ' /Date of FITS file creation ORIGIN = 'CASB -- STScI ' /Origin of FITS image PLTLABEL= 'E1618 ' /Observatory plate label PLATEID = '07WS ' /GSSS Plate ID REGION = 'XE198 ' /GSSS Region Name DATE-OBS= '20/12/57 ' /UT date of Observation UT = '05:36:00.00 ' /UT time of observation EPOCH = 1.9579677734375E+03 /Epoch of plate PLTRAH = 3 /Plate center RA PLTRAM = 9 / PLTRAS = 3.2780210000000E+01 / PLTDECSN= '+ ' /Plate center Dec PLTDECD = 42 / PLTDECM = 33 / PLTDECS = 3.1743320000000E+01 / EQUINOX = 2.0000000000000E+03 /Julian Reference frame equinox EXPOSURE= 4.5000000000000E+01 /Exposure time minutes BANDPASS= 8 /GSSS Bandpass code PLTGRADE= 1 /Plate grade PLTSCALE= 6.7200000000000E+01 /Plate Scale arcsec per mm SITELAT = '+33:24:24.00 ' /Latitude of Observatory SITELONG= '-116:51:48.00 ' /Longitude of Observatory TELESCOP= 'Palomar 48-inch Schmidt'/Telescope where plate taken CNPIX1 = 2846 /X corner (pixels) CNPIX2 = 5050 /Y corner DATATYPE= 'INTEGER*2 ' /Type of Data SCANIMG = 'XE198_07WS_00_00.PIM'/Name of original scan SCANNUM = 0 /Identifies scan of the plate DCHOPPED= F /Image repaired for chopping effects DSHEARED= F /Image repaired for shearing effects DSCNDNUM= 0 /Identifies descendant of plate scan image XPIXELSZ= 2.5284450000000E+01 /X pixel size microns YPIXELSZ= 2.5284450000000E+01 /Y pixel size microns PPO1 = 0.0000000000000E+00 /Orientation Coefficients PPO2 = 0.0000000000000E+00 / PPO3 = 1.7747471555000E+05 / PPO4 = 0.0000000000000E+00 / PPO5 = 0.0000000000000E+00 / PPO6 = 1.7747471555000E+05 / AMDX1 = 6.7240987715710E+01 /Plate solution x coefficients AMDX2 = 3.6605616579680E-01 / AMDX3 = -1.3732674154580E+02 / AMDX4 = -2.2170938540070E-05 / AMDX5 = -2.0113447317610E-05 / AMDX6 = -2.1108647953950E-05 / AMDX7 = 0.0000000000000E+00 / AMDX8 = 1.8223387505210E-06 / AMDX9 = -9.7173567076310E-08 / AMDX10 = 2.3013465940930E-06 / AMDX11 = -6.6734677147540E-08 / AMDX12 = 0.0000000000000E+00 / AMDX13 = 0.0000000000000E+00 / AMDX14 = 0.0000000000000E+00 / AMDX15 = 0.0000000000000E+00 / AMDX16 = 0.0000000000000E+00 / AMDX17 = 0.0000000000000E+00 / AMDX18 = 0.0000000000000E+00 / AMDX19 = 0.0000000000000E+00 / AMDX20 = 0.0000000000000E+00 / AMDY1 = 6.7250690753980E+01 /Plate solution y coefficients AMDY2 = -3.6679440186020E-01 / AMDY3 = -3.1235334956310E+02 / AMDY4 = -3.5598357942100E-05 / AMDY5 = 2.4433823111370E-08 / AMDY6 = 4.3754127047740E-07 / AMDY7 = 0.0000000000000E+00 / AMDY8 = 2.0663931384810E-06 / AMDY9 = 2.9377276167040E-09 / AMDY10 = 2.0894436743940E-06 / AMDY11 = -2.4710339600070E-08 / AMDY12 = 0.0000000000000E+00 / AMDY13 = 0.0000000000000E+00 / AMDY14 = 0.0000000000000E+00 / AMDY15 = 0.0000000000000E+00 / AMDY16 = 0.0000000000000E+00 / AMDY17 = 0.0000000000000E+00 / AMDY18 = 0.0000000000000E+00 / AMDY19 = 0.0000000000000E+00 / AMDY20 = 0.0000000000000E+00 / Based on photographic data of the National Geographic Society -- Palomar Observatory Sky Survey (NGS-POSS) obtained using the Oschin Telescope on Palomar Mountain. The NGS-POSS was funded by a grant from the National Geographic Society to the California Institute of Technology. The plates were processed into the present compressed digital form with their permission. The Digitized Sky Survey was produced at the Space Telescope Science Institute under US Government grant NAG W-2166. Investigators using these scans are requested to include the above acknowledgements in any publications. Copyright (c) 1994, Association of Universities for Research in Astronomy, Inc. All rights reserved. DATAMAX = 14239 /Maximum data value DATAMIN = 4672 /Minimum data value OBJECT = 'dss26885 ' /Object ID OBJCTRA = '03 19 48.000 ' /Object Right Ascension (J2000) OBJCTDEC= '+41 30 39.00 ' /Object Declination (J2000) OBJCTX = 2863.08 /Object X on plate (pixels) OBJCTY = 5067.67 /Object Y on plate (pixels) CTYPE1 = 'RA---TAN' /R.A. in tangent plane projection CTYPE2 = 'DEC--TAN' /DEC. in tangent plane projection CRPIX1 = 17.5 /Refpix of first axis CRPIX2 = 17.5 /Refpix of second axis CRVAL1 = 4.9950032970688E+01 /RA at Ref pix in decimal degrees CRVAL2 = 4.1510514400833E+01 /DEC at Ref pix in decimal degrees CROTA1 = -2.0273621441398E+00 /Rotation angle of first axis (deg) CROTA2 = -2.0273621441398E+00 /Rotation angle of second axis (deg) Warning: CROTA2 is inaccurate due to considerable skew SKEW = -1.8658208368743E+00, -2.1889034514053E+00 /Measure of skew CDELT1 = -4.7341644542403E-04 /RA pixel step (deg) CDELT2 = 4.7352430348753E-04 /DEC pixel step (deg) CD1_1 = -4.7307100872915E-04 /CD matrix CD1_2 = 1.5417459595016E-05 /CD matrix CD2_1 = 1.8081800184200E-05 /CD matrix CD2_2 = 4.7327324869782E-04 /CD matrix PC001001= 9.9927033228733E-01 /PC matrix PC001002= -3.2566379440425E-02 /PC matrix PC002001= 3.8185580024143E-02 /PC matrix PC002002= 9.9946981646377E-01 /PC matrix END ++Ô‰>óOOO¦¦¦¦¦¦¦ùù¦¦¢¢¢HOõõõšõHH@††‰‰ä䪪ªª[SS¦[ýýý¢ªOOOõšHHšØ3‰ä‰‰®®SS[[[®Sª_[®®ùùSSOõõšùØ3‰äää®®®®[[[¶¶¶c¹__nk[®®SSSSªOšõù7‘ì‘c¶¶¶¶kgggÁŶ[¶[ªOHHž‘ìFìccc½kkkkÅkÁÁÁgŶ[¶¶[[[ªO¢¢žÜ‘ììììkÅkÅrrGGšš Kðéé ¹_²WWý¦¦S7ìFFì¡kÅÅ r Í"' Í ¡ ¡ôô!¥ KCCÁ¹ ²Wý¦[[[S‘FF¡¡ûÅÅÅ Í$Ü#‚#‚"©!O"©"©$Z# ø øÁÁ¹_[®®‘FF¡¡û !z#‚$Ü$Ü$Ü$"©$$'%µ#­#­!Ñ!Ñn¹¶[[FF¥ð÷R v#+#Ø%3%Š&ä'‘'‘&b&b'½'½)n(& $±#+#+!Ñ vŶ__¹WFF¥¥R ¬ v#+%3&&ä(?(ì+¡)))))n((À'f#+#+#+!Ñ kk__¹WF¡!Z!Z"#a#+$†%à';(?*ô*ô,N+)Ä+Ì+Ì*È((À(À';%à#Ø"~!zÅÅ ²_WF¡!Z!Z"#a%à';)ð+J,N,N-©//.-Ô/Ü-',#,#+u+u(•';%3!#"Õ ÅgÁ²©^ f!À!À$u&(»*Ã-x.Ò.Ò0Ú0Ú112‹1Þ1Þ0-.Ò-x-x*A(æ&ß$*"x!¼662¹ f!À#%Ð'a*,.Ò.Ò1‡333æ5@4“4“2â1‡0--x,ö+›)”&ß%-#Ó!Ë qëë¹"n#È%#)2)h,-x0-0Ú34ê6D5í5í5í5í4ê31‡.Ò.P*A*A'Œ%Û%Û#Ó!˜>Û…!"n%#&})h,.Ò1‡254ê4ê6D5í5í5í5í6D4ê2â0-.P,ö+›+›(%Û%-"x˜>Û…!j"Ä"Ä(.+/)2‹2‹34ê5—5—6ñ6ñ5—6ñ5í5í3æ11/T-ú-ú+E(9%„&1#| ó˜>‰Ûbb!j(.%y(.+,t/Ö2‹34ê5—5—5—5—6ñ5—5í5í3æ110¯/T,Ÿ)ê(9(9'Œ$ט ó˜ãÛb ½$Ì&'&Ô)‰,t,t-Î1Þ36D4ê6D6D6D6D6D5í4“3æ2‹1\0+ò'â)”,I*A&1!  E>ã6b ½"#r&Ô)‰,t,t,t0ƒ36D6D7Ÿ6D6D6D6D5í4“3æ2‹0.§+ò'â)”,I+›'Œ!  Eã‰Û ;"ð"B"B'¬)*—+ò-L02`56o55—5—4ê6D6D4ê2â1‡0-L,Ÿ)ê'â&ˆ%Û#&Ã!¼a]à!•##'¬))=*—+ò.§/«2`3º2`4<4<34ê3251‡0--L-L,Ÿ)ê%-! q qÃ!¼]3 è#$÷'¬)*—*—+ò.§.þ0X1125251‡1‡0-0-.%,Ë+E,Ÿ,Ÿ(#Ó! q!Ë!˼aV~3 è"B$÷&R)=)=)=+ò*î,I.P.P/€/€0-0-0-0-.%,Ë+E)ê)ê("xà q q¼¼a°/‰!>!>$¡$¡$€'5)=)=(æ(æ,I,I.%.%0-.Ò.|.|-Î)¿+E)ê'â&ˆ"ÏÀmm¼¼a‰äää ‘#F#&%Û%-'â'Œ$×$*&ß(»+p-x,+Ç)(d' ('5&ˆ%-"Ï!u""m¼¼iÔ/‰‰ ‘!ì!Ë!Ë#Ó%-$*"Ï"Ï$*$¬'a(»(»)¿' ' ' '5%Û%Û$€""""""mii¼zÔÔÔÜ7 q¼Ã#Ó"Ï!u!u"Ï#Q#Q$¬$¬%¯%¯$U$U$€#&#&!Ë""""""miiY  hpã>ë! BB œ!÷!÷#Q!÷#Q#Q#Q#Q!÷"""""" ÇÃ!!i¸]  h`»‰ã EBBB œ œ!÷ œ!÷!÷!÷B œmmm ÇÃiii¸]¨¨¯ »»``66>>çç”””ïï”””””ÀÀÀe¼¼a¯ ````ÛÛ‰‰22:::”:”::::ee °a¨UU  ]·22ß…Ô.‰‰ããÛ62ß…°°]¨¬Rÿÿ¤XTENSION= 'BINTABLE' / binary table extension BITPIX = 8 / 8-bit bytes NAXIS = 2 / 2-dimensional binary table NAXIS1 = 28 / width of table in bytes NAXIS2 = 16 / number of rows in table PCOUNT = 0 / size of special data area GCOUNT = 1 / one data group (required keyword) TFIELDS = 4 / number of fields in each row TTYPE1 = 'INTEGRATED_SIGNAL' / label for field 1 TFORM1 = '1D ' / data format of the field: 8-byte DOUBLE TUNIT1 = 'log10Counts' / physical unit of field TTYPE2 = 'MAGNITUDE' / label for field 2 TFORM2 = '1D ' / data format of the field: 8-byte DOUBLE TUNIT2 = 'E_Magnitude' / physical unit of field TTYPE3 = 'UNCERTAINTY' / label for field 3 TFORM3 = '1D ' / data format of the field: 8-byte DOUBLE TUNIT3 = 'E_Magnitude' / physical unit of field TTYPE4 = 'NUMBER_OF_OBJECTS' / label for field 4 TFORM4 = '1J ' / data format of the field: 4-byte INTEGER TUNIT4 = 'Objects ' / physical unit of field EXTNAME = 'Photometric CALTABLE' / name of this binary table extension CALCNTXT= 'POSS_E ' /Context in which calibration is valid CALVERSN= '10/07/1996' /Calibration version THRESHLD= 500 /Threshold above sky which signal is measured The lookup table in this extension may be used to infer the magnitude of stars on plates within the context of CALCNTXT. The log(Integrated Signal) is obtained for a star by summing the total counts above THRESHLD above the background. For example, if the background for a star is measured to be 4000 and THRESHLD is 500, then the integrated signal is the sum of counts above 4500. The table may then be interpolated to log10(4500) to obtain the star's magnitude. "Number of Objects" is the number of objects used to derive the calibrated magnitude in each row of the table. HISTORY TASK: fselect3.3e on FILENAME: posse_cal.fits HISTORY Expression: !(MAGNITUDE==0) HISTORY fselect3.3e at 1/5/97 9:42:8.0 END @™™ @2ff`@33:@0áÊÀ?èSw@@/¨u?å·$`=@ÌÌÔ@.À ?á×p P@™™¡@,e¦À?áÎÂ`¬@ffn@*yÀ?ã þ`*@33;@(¹@?â!´`ò@@&N¿à?âkâ @ÌÌÕ@$•÷€?àÐE@'@™™¢@# ?Ý«³ .@ffo@" €?ÙäzÀ®@33<@!Fz?Úgk€q@ @ i ?ÙóãÀ'@ÌÌÖ@Äòà?Ý„]€ @™™£@€@ffp@A‰@skycat-3.1.2-starlink-1b/cat/tests/main.C000066400000000000000000000006331215713201500201000ustar00rootroot00000000000000/* * E.S.O. - VLT project * $Id: main.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * main.C - C++ main for testing C interface * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 13 Oct 95 Created */ extern "C" int c_main(int argc, char** argv); int main(int argc, char** argv) { c_main(argc, argv); return 0; } skycat-3.1.2-starlink-1b/cat/tests/tAstroCat000066400000000000000000000013601215713201500206750ustar00rootroot00000000000000#!/bin/sh #\ test -f ../demos/cat_env.sh && . ../demos/cat_env.sh #\ P=$PWD; DIRN=`dirname $0`; cd $DIRN; XP=`pwd`; cd $P #\ if [ -z "$CAT_LIBRARY" ] ; then #\ WISH=cat_wish; L=`dirname $XP`; CAT_LIBRARY="$L/lib/cat" ; export CAT_LIBRARY #\ else WISH=$CAT_LIBRARY/../bin/cat_wish #\ fi #\ LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${INSTALL_TARGET}/lib:/vlt/APR2003/tcltk/lib:/vlt/APR2003/tcltk/lib/itcl:/usr/X11R6/lib" #\ exec $WISH "$0" ${1+"$@"} # -------------------------------------------------- source test.tcl puts "testing the astrocat Tcl command..." astrocat cat cat open gsc@eso puts "GSC headings: [cat headings]" puts "GSC query:" set list [cat query -pos {3:19:48 +41:30:39} -radius 10 -nrows 10] foreach i $list { puts $i } exit 0 skycat-3.1.2-starlink-1b/cat/tests/tAstroCat.tcl000077500000000000000000000003721215713201500214630ustar00rootroot00000000000000source test.tcl puts "testing the astrocat Tcl command..." astrocat cat cat open gsc@eso puts "GSC headings: [cat headings]" puts "GSC query:" set list [cat query -pos {3:19:48 +41:30:39} -radius 10 -nrows 10] foreach i $list { puts $i } exit 0 skycat-3.1.2-starlink-1b/cat/tests/tAstroCatalog.C000066400000000000000000000043141215713201500217230ustar00rootroot00000000000000/* * E.S.O. - VLT project / ESO Archive * $Id: tAstroCatalog.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * tAstroCatalog.C - test cases for class AstroCatalog * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 95 Created */ using namespace std; #include #include #include #include "error.h" #include "AstroCatalog.h" main() { // gcc doesn't need this, but SunCC does... ios::sync_with_stdio(); // errors will be printed on stderr automatically set_error_handler(print_error); // open the GSC catalog AstroCatalog* cat = AstroCatalog::open("gsc@eso"); if (!cat) { printf("AstroCatalog::open returned NULL\n"); exit(1); } // query the GSC for a list of objects at the given pos and radius WorldCoords pos(3, 19, 48, 41, 30, 39); AstroQuery q; q.pos(pos); q.radius(10); q.maxRows(10); cout << "Query GSC for objects at pos " << q.pos() << ", in radius " << q.radius1() << ".." << q.radius2() << ":" << endl; QueryResult result; int num_results = cat->query(q, "./tAstroCatalog.out", result); if (num_results < 0) { cout << "Query returned an error\n"; exit(1); } cout << "Query returns: " << num_results << " objects, out of " << q.maxRows() << " requested" << endl; cout << "More objects ?: " << (cat->more() ? "YES" : "NO") << endl; cout << "---Result List---" << endl; int ncols = cat->numCols(); int i, j; cout << "columns:\n"; for (i = 0; i < ncols; i++) cout << cat->colName(i) << "\t"; cout << "\n\nresults:\n"; char* s; for (i = 0; i < num_results; i++) { // print the Id if (result.get(i, 0, s) == 0) cout << s << "\t"; else cout << "ERROR\t"; // print the position in H:M:S+D:M:S if (result.getPos(i, pos) == 0) cout << pos.ra() << "\t" << pos.dec() << "\t"; else cout << "ERROR\t"; // print the other columns for (j = 3; j < ncols; j++) { if (result.get(i, j, s) == 0) cout << s << "\t"; else cout << "ERROR\t"; } cout << endl; } cout << "-----------------" << endl; return 0; } skycat-3.1.2-starlink-1b/cat/tests/tAstroCatalog.ok000066400000000000000000000016131215713201500221510ustar00rootroot00000000000000Query GSC for objects at pos 03:19:48.000 +41:30:39.00, in radius 0..10: Query returns: 10 objects, out of 10 requested More objects ?: YES ---Result List--- columns: gsc_id ra dec pos-e mag mag-e mu d' pa results: GSC0285601078 03:19:48.230 +41:30:42.23 0.2 9.23 0.40 F 0.07 39; GSC0285600314 03:19:44.443 +41:30:58.21 0.2 13.98 0.40 F 0.74 296; GSC0285601162 03:19:51.151 +41:31:25.97 0.2 12.93 0.40 F 0.98 37; GSC0285601446 03:19:55.541 +41:31:23.74 0.2 13.72 0.40 F 1.60 62; GSC0285600342 03:19:57.262 +41:31:34.72 0.2 12.31 0.40 F 1.97 62; GSC0285600334 03:19:48.197 +41:32:50.14 0.2 11.77 0.40 F 2.19 1; GSC0285600886 03:19:36.175 +41:29:58.13 0.2 10.86 0.40 F 2.32 253; GSC0285600672 03:19:35.119 +41:30:39.67 0.2 13.39 0.40 F 2.41 270; GSC0285601758 03:19:48.557 +41:28:09.44 0.2 13.78 0.40 F 2.49 178; GSC0285601402 03:19:52.481 +41:33:00.04 0.2 14.67 0.40 F 2.50 20; ----------------- skycat-3.1.2-starlink-1b/cat/tests/tAstroImage000066400000000000000000000016121215713201500212100ustar00rootroot00000000000000#!/bin/sh #\ test -f ../demos/cat_env.sh && . ../demos/cat_env.sh #\ P=$PWD; DIRN=`dirname $0`; cd $DIRN; XP=`pwd`; cd $P #\ if [ -z "$CAT_LIBRARY" ] ; then #\ WISH=cat_wish; L=`dirname $XP`; CAT_LIBRARY="$L/lib/cat" ; export CAT_LIBRARY #\ else WISH=$CAT_LIBRARY/../bin/cat_wish #\ fi #\ LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${INSTALL_TARGET}/lib:/vlt/APR2003/tcltk/lib:/vlt/APR2003/tcltk/lib/itcl:/usr/X11R6/lib" #\ exec $WISH "$0" ${1+"$@"} # -------------------------------------------------- source test.tcl puts "testing the astrocat Tcl command with an image server..." astrocat cat cat open dss@eso puts "getting image..." if {[catch { set filename [cat getimage -pos {3:19:48 +41:30:39} -width 1 -height 1] } msg]} { puts "getimage returned error: '$msg'" exit 1 } puts "getimage returns filename = '$filename', renaming to ./dss.fits..." exec mv $filename ./dss.fits exit 0 skycat-3.1.2-starlink-1b/cat/tests/tAstroImage.C000066400000000000000000000027071215713201500213770ustar00rootroot00000000000000/* * E.S.O. - VLT project / ESO Archive * $Id: tAstroImage.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * tAstroImage.C - test cases for class AstroCatalog with an image server * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 95 Created */ using namespace std; #include #include #include #include #include "error.h" #include "AstroCatalog.h" main() { // gcc doesn't need this, but SunCC does... ios::sync_with_stdio(); // errors will be printed on stderr automatically set_error_handler(print_error); // Try to retrieve an image from the DSS server AstroCatalog* cat = AstroCatalog::open("dss@eso"); if (!cat) { printf("AstroCatalog::open returned NULL\n"); exit(1); } AstroQuery q; q.pos(WorldCoords(3, 19, 48, 41, 30, 39)); q.width(1.); q.height(1.); cout << "Retrieve DSS image at pos " << q.pos() << ", with width " << q.width() << " and height " << q.height() << ":" << endl; int result = cat->getImage(q); if (result != 0) { cout << "DSS Test failed\n"; exit(1); } const char* filename = cat->tmpfile(); cout << "DSS returned image file (renaming to ./dss.fits)\n"; ostringstream os; os << "mv " << filename << " ./dss.fits"; if (system(os.str().c_str()) != 0) sys_error("file rename error"); return 0; } skycat-3.1.2-starlink-1b/cat/tests/tAstroImage.ok000066400000000000000000000002021215713201500216120ustar00rootroot00000000000000Retrieve DSS image at pos 03:19:48.000 +41:30:39.00, with width 1 and height 1: DSS returned image file (renaming to ./dss.fits) skycat-3.1.2-starlink-1b/cat/tests/tAstroImage.tcl000066400000000000000000000006721215713201500217760ustar00rootroot00000000000000source test.tcl # # test the astroimage tcl command # puts "testing the astrocat Tcl command with an image server..." astrocat cat cat open dss@eso puts "getting image..." if {[catch { set filename [cat getimage -pos {3:19:48 +41:30:39} -width 1 -height 1] } msg]} { puts "getimage returned error: '$msg'" exit 1 } puts "getimage returns filename = '$filename', renaming to ./dss.fits..." exec mv $filename ./dss.fits exit 0 skycat-3.1.2-starlink-1b/cat/tests/tLocalCatalog.C000066400000000000000000000046321215713201500216700ustar00rootroot00000000000000/* * E.S.O. - VLT project / ESO Archive * $Id: tLocalCatalog.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * tLocalCatalog.C - test cases for class LocalCatalog * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 11 Jun 96 Created */ using namespace std; #include #include #include #include "error.h" #include "LocalCatalog.h" main() { // gcc doesn't need this, but SunCC does... ios::sync_with_stdio(); // errors will be printed on stderr automatically set_error_handler(print_error); // open the GSC catalog AstroCatalog* cat = AstroCatalog::open("test.table"); if (!cat) { printf("LocalCatalog::open returned NULL\n"); exit(1); } // query the GSC for a list of objects at the given pos and radius WorldCoords pos(3, 19, 48, 41, 30, 39); AstroQuery q; q.pos(pos); q.radius(10); q.maxRows(10); cout << "Query GSC for objects at pos " << q.pos() << ", in radius " << q.radius1() << ".." << q.radius2() << ":" << endl; QueryResult result; int num_results = cat->query(q, "./tLocalCatalog.out", result); if (num_results < 0) { cout << "Query returned an error\n"; exit(1); } cout << "Query returns: " << num_results << " objects, out of " << q.maxRows() << " requested" << endl; cout << "More objects ?: " << (cat->more() ? "YES" : "NO") << endl; cout << "---Result List---" << endl; int ncols = cat->numCols(); int i, j; cout << "columns:\n"; for (i = 0; i < ncols; i++) cout << cat->colName(i) << "\t"; cout << "\n\nresults:\n"; char* s; for (i = 0; i < num_results; i++) { // print the Id if (result.get(i, 0, s) == 0) cout << s << "\t"; else cout << "ERROR\t"; // print the position in H:M:S+D:M:S if (result.getPos(i, pos) == 0) cout << pos.ra() << "\t" << pos.dec() << "\t"; else cout << "ERROR\t"; // print the other columns for (j = 3; j < ncols; j++) { if (result.get(i, j, s) == 0) cout << s << "\t"; else cout << "ERROR\t"; } cout << endl; } cout << "-----------------" << endl; cout << "test searching by Id in a local catalog\n"; if (cat->getObject("GSC0286902884", 0, NULL, result) != 0) { cout << "ERROR\n"; } else { cout << "OK\n" << result << endl;; } return 0; } skycat-3.1.2-starlink-1b/cat/tests/tLocalCatalog.ok000066400000000000000000000023471215713201500221200ustar00rootroot00000000000000Query GSC for objects at pos 03:19:48.000 +41:30:39.00, in radius 0..10: Query returns: 10 objects, out of 10 requested More objects ?: YES ---Result List--- columns: gsc-id ra dec pos-e mag mag-e mu d' pa results: GSC0285600050 03:19:28.140 +41:26:29.00 0.2 13.49 0.40 F 5.63 222; GSC0285600098 03:19:32.990 +41:34:15.42 0.4 13.40 0.40 F 4.58 322; GSC0285600288 03:19:21.100 +41:31:19.74 0.2 13.13 0.40 F 5.12 277; GSC0285600314 03:19:44.440 +41:30:58.21 0.2 13.98 0.40 F 0.77 293; GSC0285600334 03:19:48.200 +41:32:50.14 0.2 11.77 0.40 F 2.16 360; GSC0285600342 03:19:57.260 +41:31:34.72 0.2 12.31 0.40 F 1.92 62; GSC0285600418 03:19:24.110 +41:34:44.58 0.2 11.69 0.40 F 6.08 312; GSC0285600518 03:19:47.840 +41:25:46.45 0.2 12.74 0.40 F 4.90 181; GSC0285600526 03:19:26.740 +41:32:26.23 0.2 11.25 0.40 F 4.39 294; GSC0285600548 03:19:51.070 +41:26:09.89 0.4 12.09 0.40 F 4.54 173; ----------------- test searching by Id in a local catalog OK QueryResult # Config entry for original catalog server: serv_type: local long_name: test.table short_name: test.table url: test.table # End config entry gsc-id ra dec pos-e mag mag-e mu d' pa ------ -- --- ----- --- ----- -- -- -- GSC0286902884 03:20:0.87 +41:33:14.00 0.2 13.07 0.40 F 3.49 43; skycat-3.1.2-starlink-1b/cat/tests/tPreviewPlot000066400000000000000000000012041215713201500214320ustar00rootroot00000000000000#!/bin/sh #\ test -f ../demos/cat_env.sh && . ../demos/cat_env.sh #\ P=$PWD; DIRN=`dirname $0`; cd $DIRN; XP=`pwd`; cd $P #\ if [ -z "$CAT_LIBRARY" ] ; then #\ WISH=cat_wish; L=`dirname $XP`; CAT_LIBRARY="$L/lib/cat" ; export CAT_LIBRARY #\ else WISH=$CAT_LIBRARY/../bin/cat_wish #\ fi #\ LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${INSTALL_TARGET}/lib:/vlt/APR2003/tcltk/lib:/vlt/APR2003/tcltk/lib/itcl:/usr/X11R6/lib" #\ exec $WISH "$0" ${1+"$@"} # -------------------------------------------------- source test.tcl puts "auto_path = $auto_path" util::setXdefaults wm withdraw . PreviewPlot .pp -file test.preview tkwait window .pp exit skycat-3.1.2-starlink-1b/cat/tests/tPreviewPlot.tcl000077500000000000000000000002531215713201500222210ustar00rootroot00000000000000source test.tcl # test the PreviewPlot class puts "auto_path = $auto_path" util::setXdefaults wm withdraw . PreviewPlot .pp -file test.preview tkwait window .pp exit skycat-3.1.2-starlink-1b/cat/tests/tQueryResult.C000066400000000000000000000062321215713201500216450ustar00rootroot00000000000000/* * E.S.O. - VLT project * $Id: tQueryResult.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * tQueryResult.C - test cases for class QueryResult * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 95 Created */ using namespace std; #include #include #include #include #include "Mem.h" #include "error.h" #include "WorldCoords.h" #include "QueryResult.h" /* * util: print the file to the stream */ static int print_file(const char* filename, ostream& os) { ifstream is(filename); if (!is) return 1; char buf[1024]; while(is.getline(buf, sizeof(buf))) os << buf << endl; return 0; } main() { // gcc doesn't need this, but SunCC does... ios::sync_with_stdio(); // errors will be printed on stderr automatically set_error_handler(print_error); // dummy table data in Tcl list format char buf[1024]; sprintf(buf, "col1\tcol2\tcol3\n---\t---\t---\n%s\n%s\n%s\n%s\n", "1\t1.0\taa", "2\t2.0\tbbbb", "3\t3.0\tc c c", "4\t4.0\t"); QueryResult t(buf); if (t.status() != 0) { printf("test 1 failed"); exit(1); } cout << "table t = \n" << t; int n; double d; float f; short s; for (int i = 0; i < t.numRows(); i++) { for (int j = 0; j < t.numCols(); j++) { char* s; if (t.get(i, t.colName(j), s) != 0) { printf("test 2 failed at row %d, col %d\n", i, j); exit(1); } printf("row %d, col %d: \"%s\"\n", i, j, s); } if (t.get(i, 0, n) != 0) { printf("test 3 failed at row %d, col 0\n", i); exit(1); } if (t.get(i, 0, s) != 0) { printf("test 4 failed at row %d, col 0\n", i); exit(1); } if (t.get(i, 0, d) != 0) { printf("test 5 failed at row %d, col 0\n", i); exit(1); } if (t.get(i, 1, d) != 0) { printf("test 6 failed at row %d, col 1\n", i); exit(1); } if (t.get(i, 1, f) != 0) { printf("test 7 failed at row %d, col 1\n", i); exit(1); } } if (n != 4 || s != 4 || d != 4.0 || f != 4.0) { printf("test 8 failed\n"); exit(1); } // -- test insert -- cout << "testing insert of rows:\n"; // save table t to a file char* filename = "tQueryResult.out"; if (t.save(filename) != 0) { printf("test 9 failed"); exit(1); } sprintf(buf, "col1\tcol2\tcol3\n---\t---\t---\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", "3\t3.0\tc c c", "2\t2.0\tbbbb", "1\t1.0\taa", "1\t1.0\taa", "3\t3.0\tc c c", "5\t5.0\tddd", "2\t2.0\tbbbb", "1\t1.0\taa", "4\t4.0\t"); QueryResult t2(buf); if (t2.status() != 0) { printf("test 10 failed"); exit(1); } cout << "table t2 = \n" << t2; if (t2.insert(filename) != 0) { printf("test 11 failed"); exit(1); } cout << "result after insert:\n"; if (print_file(filename, cout) != 0) { printf("test 12 failed"); exit(1); } cout << "testing remove of rows:\n"; if (t.remove(filename, 0) != 0) { printf("test 13 failed"); exit(1); } if (print_file(filename, cout) != 0) { printf("test 14 failed"); exit(1); } return 0; } skycat-3.1.2-starlink-1b/cat/tests/tQueryResult.ok000066400000000000000000000013201215713201500220650ustar00rootroot00000000000000table t = QueryResult col1 col2 col3 ---- ---- ---- 1 1.0 aa 2 2.0 bbbb 3 3.0 c c c 4 4.0 row 0, col 0: "1" row 0, col 1: "1.0" row 0, col 2: "aa" row 1, col 0: "2" row 1, col 1: "2.0" row 1, col 2: "bbbb" row 2, col 0: "3" row 2, col 1: "3.0" row 2, col 2: "c c c" row 3, col 0: "4" row 3, col 1: "4.0" row 3, col 2: "" testing insert of rows: table t2 = QueryResult col1 col2 col3 ---- ---- ---- 3 3.0 c c c 2 2.0 bbbb 1 1.0 aa 1 1.0 aa 3 3.0 c c c 5 5.0 ddd 2 2.0 bbbb 1 1.0 aa 4 4.0 result after insert: QueryResult col1 col2 col3 ---- ---- ---- 1 1.0 aa 2 2.0 bbbb 3 3.0 c c c 4 4.0 1 1.0 aa 3 3.0 c c c 5 5.0 ddd 2 2.0 bbbb 1 1.0 aa testing remove of rows: QueryResult col1 col2 col3 ---- ---- ---- 5 5.0 ddd skycat-3.1.2-starlink-1b/cat/tests/tTabTable.C000066400000000000000000000066641215713201500210300ustar00rootroot00000000000000/* * E.S.O. - VLT project * $Id: tTabTable.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * tTabTable.C - test cases for class TabTable * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 08 Jan 96 Created */ using namespace std; #include #include #include "error.h" #include "TabTable.h" main() { // gcc doesn't need this, but SunCC does... ios::sync_with_stdio(); // errors will be printed on stderr automatically set_error_handler(print_error); // dummy table data in Tab list format char buf[256]; sprintf(buf, "col1\tcol2\tcol3\n---\t---\t---\n%s\n%s\n%s\n%s\n", "1\t1.0\taa", "2\t2.0\tbbbb", "3\t3.0\tc c c", "4\t4.0\t"); TabTable t(buf); if (t.status() != 0) { printf("test 1 failed\n"); exit(1); } int n; double d; float f; short s; for (int i = 0; i < t.numRows(); i++) { for (int j = 0; j < t.numCols(); j++) { char* s; if (t.get(i, j, s) != 0) { printf("test 2 failed at row %d, col %d\n", i, j); exit(1); } printf("row %d: %s = \"%s\"\n", i, t.colName(j), s); } if (t.get(i, 0, n) != 0) { printf("test 3 failed at row %d, col 0\n", i); exit(1); } if (t.get(i, 0, s) != 0) { printf("test 4 failed at row %d, col 0\n", i); exit(1); } if (t.get(i, 0, d) != 0) { printf("test 5 failed at row %d, col 0\n", i); exit(1); } if (t.get(i, 1, d) != 0) { printf("test 6 failed at row %d, col 1\n", i); exit(1); } if (t.get(i, 1, f) != 0) { printf("test 7 failed at row %d, col 1\n", i); exit(1); } } if (n != 4 || s != 4 || d != 4.0 || f != 4.0) { printf("test 8 failed\n"); exit(1); } // test save method char* filename = "tTabTable.out"; if (t.save(filename) != 0) { printf("test 9 failed\n"); exit(1); } // test append method if (t.append(filename) != 0) { printf("test 10 failed\n"); exit(1); } // test alternate constructor TabTable* t2 = new TabTable(t.numCols(), t.colNames(), buf); if (t.compareHeadings(*t2)) { printf("test 11 failed\n"); exit(1); } TabTable* t3 = new TabTable(t2->numCols(), t2->colNames(), buf); delete t2; TabTable t4; if (TabTable::head(filename, t4) != 0) { printf("test 12 failed\n"); exit(1); } if (t3->compareHeadings(t4)) { printf("test 13 failed\n"); exit(1); } // test search method on file saved above cout << "testing search method:\n"; TabTable t5; char** searchCols = t.colNames(); int numCols = t.numCols(); char* minValues[3]; char* maxValues[3]; minValues[0] = "2"; // col0 maxValues[0] = "3"; minValues[1] = "1"; // col1 maxValues[1] = "3"; minValues[2] = "a"; // col2 maxValues[2] = "d"; if (t5.search(filename, numCols, searchCols, minValues, maxValues, 10) != 0) { printf("test 14 failed\n"); exit(1); } cout << "results of search:\n" << t5; // test sort method int ncols = 1; char* colName = "col2"; if (t5.sort(1, &colName) != 0) { printf("test 15 failed\n"); exit(1); } cout << "results after sort:\n" << t5; // test search for single value cout << "\ntesting search method for single column:\n"; if (t5.search(filename, "col2", "2.0", 1) != 0) { printf("test 16 failed\n"); exit(1); } cout << "results of search:\n" << t5; return 0; } skycat-3.1.2-starlink-1b/cat/tests/tTabTable.ok000066400000000000000000000011121215713201500212360ustar00rootroot00000000000000row 0: col1 = "1" row 0: col2 = "1.0" row 0: col3 = "aa" row 1: col1 = "2" row 1: col2 = "2.0" row 1: col3 = "bbbb" row 2: col1 = "3" row 2: col2 = "3.0" row 2: col3 = "c c c" row 3: col1 = "4" row 3: col2 = "4.0" row 3: col3 = "" testing search method: results of search: TabTable col1 col2 col3 ---- ---- ---- 2 2.0 bbbb 3 3.0 c c c 2 2.0 bbbb 3 3.0 c c c results after sort: TabTable col1 col2 col3 ---- ---- ---- 2 2.0 bbbb 2 2.0 bbbb 3 3.0 c c c 3 3.0 c c c testing search method for single column: results of search: TabTable col1 col2 col3 ---- ---- ---- 2 2.0 bbbb skycat-3.1.2-starlink-1b/cat/tests/tTcsCat000066400000000000000000000013551215713201500203420ustar00rootroot00000000000000#!/bin/sh #\ test -f ../demos/cat_env.sh && . ../demos/cat_env.sh #\ P=$PWD; DIRN=`dirname $0`; cd $DIRN; XP=`pwd`; cd $P #\ if [ -z "$CAT_LIBRARY" ] ; then #\ WISH=cat_wish; L=`dirname $XP`; CAT_LIBRARY="$L/lib/cat" ; export CAT_LIBRARY #\ else WISH=$CAT_LIBRARY/../bin/cat_wish #\ fi #\ LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${INSTALL_TARGET}/lib:/vlt/APR2003/tcltk/lib:/vlt/APR2003/tcltk/lib/itcl:/usr/X11R6/lib" #\ exec $WISH "$0" ${1+"$@"} # -------------------------------------------------- source test.tcl puts "testing the tcscat Tcl command..." tcscat cat cat open gsc@eso puts "GSC headings: [cat headings]" puts "GSC query:" set list [cat query -pos {3:19:48 +41:30:39} -radius 10 -nrows 10] foreach i $list { puts $i } exit 0 skycat-3.1.2-starlink-1b/cat/tests/tTcsCat.tcl000077500000000000000000000004311215713201500211200ustar00rootroot00000000000000source test.tcl # # test the tcscat tcl command # puts "testing the tcscat Tcl command..." tcscat cat cat open gsc@eso puts "GSC headings: [cat headings]" puts "GSC query:" set list [cat query -pos {3:19:48 +41:30:39} -radius 10 -nrows 10] foreach i $list { puts $i } exit 0 skycat-3.1.2-starlink-1b/cat/tests/tTcsCatalog.C000066400000000000000000000042401215713201500213620ustar00rootroot00000000000000/* * E.S.O. - VLT project / ESO Archive * $Id: tTcsCatalog.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * tTcsCatalog.C - test cases for class TcsCatalog * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 13 Jun 96 Created */ using namespace std; #include #include #include #include "error.h" #include "TcsCatalog.h" main() { // gcc doesn't need this, but SunCC does... ios::sync_with_stdio(); // errors will be printed on stderr automatically set_error_handler(print_error); // open the GSC catalog TcsCatalog* cat = TcsCatalog::open("gsc@eso"); if (!cat) { printf("TcsCatalog::open returned NULL\n"); exit(1); } // query the GSC for a list of objects at the given pos and radius WorldCoords pos(3, 19, 48, 41, 30, 39); AstroQuery q; q.pos(pos); q.radius(10); q.maxRows(10); cout << "Query GSC for objects at pos " << q.pos() << ", in radius " << q.radius1() << ".." << q.radius2() << ":" << endl; TcsQueryResult result; int num_results = cat->query(q, "./tTcsCatalog.out", result); if (num_results < 0) { cout << "Query returned an error\n"; exit(1); } cout << "Query returns: " << num_results << " objects, out of " << q.maxRows() << " requested" << endl; cout << "More objects ?: " << (cat->more() ? "YES" : "NO") << endl; cout << "---Result List---" << endl; // print the column headings cout << "Results:\n\n"; TcsCatalogObject::printHeadings(cout); cout << "\n-\n"; // print out the rows TcsCatalogObject obj; // holds data for one row for (int row = 0; row < num_results; row++) { if (result.getObj(row, obj) != 0) cout << "row " << row << ": ERROR\n"; else cout << obj << endl; } // -- test VLT type interface -- cout << "\ntest VLT style interface:\n\n"; if (cat->searchClosestStar(pos, 0., 15, obj) != 0) { cout << "searchClosestStar: returned error\n"; } else { cout << "searchClosestStar for " << pos << ": returned row:\n" << obj << endl; } return 0; } skycat-3.1.2-starlink-1b/cat/tests/tTcsCatalog.ok000066400000000000000000000025651215713201500216210ustar00rootroot00000000000000Query GSC for objects at pos 03:19:48.000 +41:30:39.00, in radius 0..10: Query returns: 10 objects, out of 10 requested More objects ?: YES ---Result List--- Results: id ra dec cooSystem epoch pma pmd radvel parallax cooType band mag more preview distance pa - {GSC0285601078} 03:19:48.230 +41:30:42.23 {J2000} 2000 {} {} {} {} {M} {V} 9.23 {} {} 0.07 39 {GSC0285600314} 03:19:44.443 +41:30:58.21 {J2000} 2000 {} {} {} {} {M} {V} 13.98 {} {} 0.74 296 {GSC0285601162} 03:19:51.151 +41:31:25.97 {J2000} 2000 {} {} {} {} {M} {V} 12.93 {} {} 0.98 37 {GSC0285601446} 03:19:55.541 +41:31:23.74 {J2000} 2000 {} {} {} {} {M} {V} 13.72 {} {} 1.6 62 {GSC0285600342} 03:19:57.262 +41:31:34.72 {J2000} 2000 {} {} {} {} {M} {V} 12.31 {} {} 1.97 62 {GSC0285600334} 03:19:48.197 +41:32:50.14 {J2000} 2000 {} {} {} {} {M} {V} 11.77 {} {} 2.19 1 {GSC0285600886} 03:19:36.175 +41:29:58.13 {J2000} 2000 {} {} {} {} {M} {V} 10.86 {} {} 2.32 253 {GSC0285600672} 03:19:35.119 +41:30:39.67 {J2000} 2000 {} {} {} {} {M} {V} 13.39 {} {} 2.41 270 {GSC0285601758} 03:19:48.557 +41:28:09.44 {J2000} 2000 {} {} {} {} {M} {V} 13.78 {} {} 2.49 178 {GSC0285601402} 03:19:52.481 +41:33:00.04 {J2000} 2000 {} {} {} {} {M} {V} 14.67 {} {} 2.5 20 test VLT style interface: searchClosestStar for 03:19:48.000 +41:30:39.00: returned row: {GSC0285601078} 03:19:48.230 +41:30:42.23 {J2000} 2000 {} {} {} {} {M} {V} 9.23 {} {} 0.07 39 skycat-3.1.2-starlink-1b/cat/tests/tTcsLocalCatalog.C000066400000000000000000000042621215713201500223410ustar00rootroot00000000000000/* * E.S.O. - VLT project / ESO Archive * $Id: tTcsLocalCatalog.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * tTcsLocalCatalog.C - test cases for class TcsLocalCatalog * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 19 Nov 97 Created */ using namespace std; #include #include #include #include "error.h" #include "TcsCatalog.h" main() { // gcc doesn't need this, but SunCC does... ios::sync_with_stdio(); // errors will be printed on stderr automatically set_error_handler(print_error); // open the GSC catalog TcsCatalog* cat = TcsCatalog::open("test.table"); if (!cat) { printf("TcsCatalog::open returned NULL\n"); exit(1); } // query the GSC for a list of objects at the given pos and radius WorldCoords pos(3, 19, 48, 41, 30, 39); AstroQuery q; q.pos(pos); q.radius(10); q.maxRows(10); cout << "Query GSC for objects at pos " << q.pos() << ", in radius " << q.radius1() << ".." << q.radius2() << ":" << endl; TcsQueryResult result; int num_results = cat->query(q, "./tTcsCatalog.out", result); if (num_results < 0) { cout << "Query returned an error\n"; exit(1); } cout << "Query returns: " << num_results << " objects, out of " << q.maxRows() << " requested" << endl; cout << "More objects ?: " << (cat->more() ? "YES" : "NO") << endl; cout << "---Result List---" << endl; // print the column headings cout << "Results:\n\n"; TcsCatalogObject::printHeadings(cout); cout << "\n-\n"; // print out the rows TcsCatalogObject obj; // holds data for one row for (int row = 0; row < num_results; row++) { if (result.getObj(row, obj) != 0) cout << "row " << row << ": ERROR\n"; else cout << obj << endl; } // -- test VLT type interface -- cout << "\ntest VLT style interface:\n\n"; if (cat->searchClosestStar(pos, 0., 15, obj) != 0) { cout << "searchClosestStar: returned error\n"; } else { cout << "searchClosestStar for " << pos << ": returned row:\n" << obj << endl; } return 0; } skycat-3.1.2-starlink-1b/cat/tests/tTcsLocalCatalog.ok000066400000000000000000000025761215713201500225760ustar00rootroot00000000000000Query GSC for objects at pos 03:19:48.000 +41:30:39.00, in radius 0..10: Query returns: 10 objects, out of 10 requested More objects ?: YES ---Result List--- Results: id ra dec cooSystem epoch pma pmd radvel parallax cooType band mag more preview distance pa - {GSC0285600050} 03:19:28.140 +41:26:29.00 {J2000} 2000 {} {} {} {} {M} {V} 13.49 {} {} 5.63 222 {GSC0285600098} 03:19:32.990 +41:34:15.42 {J2000} 2000 {} {} {} {} {M} {V} 13.4 {} {} 4.58 322 {GSC0285600288} 03:19:21.100 +41:31:19.74 {J2000} 2000 {} {} {} {} {M} {V} 13.13 {} {} 5.12 277 {GSC0285600314} 03:19:44.440 +41:30:58.21 {J2000} 2000 {} {} {} {} {M} {V} 13.98 {} {} 0.77 293 {GSC0285600334} 03:19:48.200 +41:32:50.14 {J2000} 2000 {} {} {} {} {M} {V} 11.77 {} {} 2.16 360 {GSC0285600342} 03:19:57.260 +41:31:34.72 {J2000} 2000 {} {} {} {} {M} {V} 12.31 {} {} 1.92 62 {GSC0285600418} 03:19:24.110 +41:34:44.58 {J2000} 2000 {} {} {} {} {M} {V} 11.69 {} {} 6.08 312 {GSC0285600518} 03:19:47.840 +41:25:46.45 {J2000} 2000 {} {} {} {} {M} {V} 12.74 {} {} 4.9 181 {GSC0285600526} 03:19:26.740 +41:32:26.23 {J2000} 2000 {} {} {} {} {M} {V} 11.25 {} {} 4.39 294 {GSC0285600548} 03:19:51.070 +41:26:09.89 {J2000} 2000 {} {} {} {} {M} {V} 12.09 {} {} 4.54 173 test VLT style interface: searchClosestStar for 03:19:48.000 +41:30:39.00: returned row: {GSC0285600050} 03:19:28.140 +41:26:29.00 {J2000} 2000 {} {} {} {} {M} {V} 13.49 {} {} 5.63 222 skycat-3.1.2-starlink-1b/cat/tests/tastro_catalog.c000066400000000000000000000144441215713201500222270ustar00rootroot00000000000000/* * E.S.O. - VLT project/ ESO Archive * $Id: tastro_catalog.c,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * tastroCatalog.C - test cases for C interface to class AstroCatalog * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 13 Oct 95 Created */ #include #include #include #include "astro_catalog.h" #include "world_coords.h" /* * C main: * note: since the background library os is in C++, we need a C++ main * that calls this C main... */ void c_main() { AcHandle cat; /* handle for catalog */ AcResult result; /* handle for query results */ WC wc1, wc2; /* world coords in HMS */ /* query parameters */ double ra1, dec1, ra2, dec2; double radius1 = 0.0, radius2 = 10.0; double mag1 = 0.0, mag2 = 15.0; int i, j, numCols, numRows; char** colNames = NULL; char* s; double dval; /* hard code the name of the catalog we are testing here. * Note: in the C and C++ interfaces, you can get a list of available * catalogs */ char* catName = "gsc@eso"; /* open the GSC catalog */ printf("opening %s...\n", catName); cat = acOpen(catName); if (!cat) { printf("acOpen failed to open: %s: %s\n", catName, acGetError()); exit(1); } /* first initialize the world coords */ wcInitFromHMS( &wc1, 3, 20, 13.736, /* RA */ 41, 25, 32.28, /* DEC */ 2000.0); /* equinox */ ra1 = wc1.ra.val * 15; /* get ra in degrees */ dec1 = wc1.dec.val; wcInitFromHMS( &wc2, 3, 19, 22.535, /* RA */ 41, 35, 49.75, /* DEC */ 2000.0); /* equinox */ ra2 = wc2.ra.val * 15; /* get ra in degrees */ dec2 = wc2.dec.val; /* get and print out the number of columns and the column names */ printf("\ntesting acGetDescription()...\n"); if (acGetDescription( cat, /* catalog handle */ &numCols, /* gets set to number of columns */ &colNames) /* gets set to array of column names */ != 0) { printf("acGetDescription failed: %s\n", acGetError()); exit(1); } printf("%s has %d columns:\ncolumns: ", catName, numCols); for(i = 0; i < numCols; i++) printf(" %s", colNames[i]); printf("\n\n"); /* do a circular search */ printf("\ntesting acCircularSearch()...\n"); if (acCircularSearch( cat, /* catalog handle */ numCols, /* number of columns to get */ colNames, /* names of columns to get */ ra1, /* RA pos */ dec1, /* DEC pos */ radius1, /* min radius */ radius2, /* max radius */ mag1, /* min mag value (brightest) */ mag2, /* max mag value (dimest) */ 10, /* max rows */ NULL, /* filename */ &numRows, /* set to number of rows found */ &result) /* set to result handle */ != 0) { printf("acCircularSearch failed: %s\n", acGetError()); exit(1); } /* print out the results */ printf("acCircularSearch returned %d rows (%d), %d cols (%d):\n", numRows, acrNumRows(result), numCols, acrNumCols(result)); for (i = 0; i < numRows; i++) { for (j = 0; j < numCols; j++) { if (acrGetString(result, i, j, &s) != 0) { printf("acrGetString failed: %s\n", acGetError()); exit(1); } else { printf("row %d, col %d: %s = %s\n", i, j, colNames[j], s); } } } /* free the results */ acrDelete(result); result = NULL; /* do an area search */ printf("\ntesting acGetArea() ...\n"); if (acGetArea( cat, /* catalog handle */ numCols, /* number of columns to get */ colNames, /* names of columns to get */ ra1, /* RA pos */ dec1, /* DEC pos */ ra2, /* RA pos */ dec2, /* DEC pos */ mag1, /* min mag value (brightest) */ mag2, /* max mag value (dimest) */ 10, /* max rows */ NULL, /* filename */ &numRows, /* set to number of rows found */ &result) /* set to result handle */ != 0) { printf("acGetArea failed: %s\n", acGetError()); } else { printf("acGetArea returned %d rows\n", numRows); } /* Search by Id */ printf("\ntesting acGetObject() ...\n"); if (acGetObject( cat, /* catalog handle */ "GSC0286902474", /* Id */ numCols, /* number of columns to get */ colNames, /* names of columns to get */ &result) /* set to result handle */ != 0) { printf("acGetObject failed: %s\n", acGetError()); } else { /* print out the results */ printf("acGetObject results :\n"); for (j = 0; j < numCols; j++) { if (acrGetString(result, 0, j, &s) != 0) { printf("acrGetString failed: %s\n", acGetError()); } else { printf("col %d: %s = %s\n", j, acColName(cat, j), s); } } } /* test search closest star... */ printf("\ntesting acSearchClosestStar()...\n"); if (acSearchClosestStar( cat, /* catalog handle */ numCols, /* number of columns to get */ colNames, /* names of columns to get */ ra1, /* RA pos */ dec1, /* DEC pos */ mag1, /* min mag value (brightest) */ mag2, /* max mag value (dimest) */ &result) /* set to result handle */ != 0) { printf("acSearchClosestStar failed: %s\n", acGetError()); exit(1); } /* print out the results */ printf("acSearchClosestStar results :\n"); for (j = 0; j < numCols; j++) { if (acrGetString(result, 0, j, &s) != 0) { printf("acrGetString failed: %s\n", acGetError()); } else { printf("col %d: %s = %s\n", j, acColName(cat, j), s); } } /* test some of the utility routines */ printf("testing other utility routines...\n"); if (acrNumRows(result) != 1) printf("acrNumRows failed\n"); if (acrNumCols(result) != numCols) printf("acrNumCols failed\n"); for (i = 0; i < numCols; i++) { if (strcmp(acrColNames(result)[i], acColNames(cat)[i]) != 0) printf("column name error for column %d\n", i); } /* and by column name ... */ if (acrGetNDouble(result, 0, "mag", &dval) != 0) printf("error in acrGetNDouble\n"); else printf("value for 'mag' by col name is %f\n", dval); if (acrGetNDouble(result, 0, "dec", &dval) != 0) printf("error in acrGetNDouble\n"); else printf("value for 'dec'as float by col name is %f\n", dval); if (acrGetWC(result, 0, &wc1) != 0) printf("error in acrGetWC\n"); else printf("value for ra (degrees) and dec from acrGetWC: %f %f\n", wc1.ra.val * 15, wc1.dec.val); /* normal exit */ exit(0); } skycat-3.1.2-starlink-1b/cat/tests/tastro_catalog.ok000066400000000000000000000063101215713201500224070ustar00rootroot00000000000000Guide Star Catalog at ESO does not suppport search by id opening gsc@eso... testing acGetDescription()... gsc@eso has 9 columns: columns: gsc_id ra dec pos-e mag mag-e mu d' pa testing acCircularSearch()... acCircularSearch returned 10 rows (10), 9 cols (9): row 0, col 0: gsc_id = GSC0286902722 row 0, col 1: ra = 50.06755 row 0, col 2: dec = 41.41473 row 0, col 3: pos-e = 0.2 row 0, col 4: mag = 13.30 row 0, col 5: mag-e = 0.40 row 0, col 6: mu = F row 0, col 7: d' = 0.80 row 0, col 8: pa = 145; row 1, col 0: gsc_id = GSC0286902944 row 1, col 1: ra = 50.05112 row 1, col 2: dec = 41.41135 row 1, col 3: pos-e = 0.2 row 1, col 4: mag = 13.97 row 1, col 5: mag-e = 0.40 row 1, col 6: mu = F row 1, col 7: d' = 0.90 row 1, col 8: pa = 198; row 2, col 0: gsc_id = GSC0286902474 row 2, col 1: ra = 50.06464 row 2, col 2: dec = 41.39870 row 2, col 3: pos-e = 0.2 row 2, col 4: mag = 12.15 row 2, col 5: mag-e = 0.40 row 2, col 6: mu = F row 2, col 7: d' = 1.65 row 2, col 8: pa = 168; row 3, col 0: gsc_id = GSC0286902570 row 3, col 1: ra = 50.11334 row 3, col 2: dec = 41.39969 row 3, col 3: pos-e = 0.2 row 3, col 4: mag = 12.69 row 3, col 5: mag-e = 0.40 row 3, col 6: mu = F row 3, col 7: d' = 2.97 row 3, col 8: pa = 122; row 4, col 0: gsc_id = GSC0286902564 row 4, col 1: ra = 50.11210 row 4, col 2: dec = 41.46054 row 4, col 3: pos-e = 0.2 row 4, col 4: mag = 13.81 row 4, col 5: mag-e = 0.40 row 4, col 6: mu = F row 4, col 7: d' = 3.24 row 4, col 8: pa = 50; row 5, col 0: gsc_id = GSC0286902856 row 5, col 1: ra = 50.08727 row 5, col 2: dec = 41.37378 row 5, col 3: pos-e = 0.2 row 5, col 4: mag = 14.05 row 5, col 5: mag-e = 0.40 row 5, col 6: mu = F row 5, col 7: d' = 3.39 row 5, col 8: pa = 157; row 6, col 0: gsc_id = GSC0286902776 row 6, col 1: ra = 50.05037 row 6, col 2: dec = 41.36709 row 6, col 3: pos-e = 0.2 row 6, col 4: mag = 11.00 row 6, col 5: mag-e = 0.40 row 6, col 6: mu = F row 6, col 7: d' = 3.53 row 6, col 8: pa = 185; row 7, col 0: gsc_id = GSC0285601584 row 7, col 1: ra = 49.98170 row 7, col 2: dec = 41.40847 row 7, col 3: pos-e = 0.2 row 7, col 4: mag = 14.35 row 7, col 5: mag-e = 0.40 row 7, col 6: mu = F row 7, col 7: d' = 3.55 row 7, col 8: pa = 253; row 8, col 0: gsc_id = GSC0286902744 row 8, col 1: ra = 50.03461 row 8, col 2: dec = 41.36635 row 8, col 3: pos-e = 0.2 row 8, col 4: mag = 13.11 row 8, col 5: mag-e = 0.40 row 8, col 6: mu = F row 8, col 7: d' = 3.70 row 8, col 8: pa = 196; row 9, col 0: gsc_id = GSC0286902405 row 9, col 1: ra = 50.10083 row 9, col 2: dec = 41.37231 row 9, col 3: pos-e = 0.2 row 9, col 4: mag = 10.64 row 9, col 5: mag-e = 0.40 row 9, col 6: mu = F row 9, col 7: d' = 3.75 row 9, col 8: pa = 148; testing acGetArea() ... acGetArea returned 10 rows testing acGetObject() ... acGetObject failed: Guide Star Catalog at ESO does not suppport search by id testing acSearchClosestStar()... acSearchClosestStar results : col 0: gsc_id = GSC0286902722 col 1: ra = 50.06755 col 2: dec = 41.41473 col 3: pos-e = 0.2 col 4: mag = 13.30 col 5: mag-e = 0.40 col 6: mu = F col 7: d' = 0.80 col 8: pa = 145; testing other utility routines... value for 'mag' by col name is 13.300000 value for 'dec'as float by col name is 41.414730 value for ra (degrees) and dec from acrGetWC: 50.067550 41.414730 skycat-3.1.2-starlink-1b/cat/tests/tastro_image.c000066400000000000000000000032051215713201500216700ustar00rootroot00000000000000/* * E.S.O. - VLT project/ ESO Archive * $Id: tastro_image.c,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * tastroImage.C - test cases for class C interface to AstroImage classes * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 95 Created */ #include #include #include #include "astro_catalog.h" #include "world_coords.h" /* * C main: * note: since the background library is in C++, we need a C++ main * that calls this C main... */ void c_main() { AcHandle im; /* handle for image server */ WC wc; /* world coords */ double ra, dec; double width = 1.0, height = 1.0; /* dimensions of image */ char buf[256]; char* filename; /* Try to retrieve an image from the DSS server */ im = acOpen("dss@eso"); if (!im) { printf("acOpen failed to open DSS server: %s\n", acGetError()); exit(1); } /* first initialize the world coords */ wcInitFromHMS(&wc, 3, 19, 48, 41, 30, 39, 2000.0); ra = wc.ra.val * 15; /* RA in degrees */ dec = wc.dec.val; printf("Retrieve DSS image at pos %d:%d:%f %d %d %f, width: %f, height: %f:\n", wc.ra.hours, wc.ra.min, wc.ra.sec, wc.dec.hours, wc.dec.min, wc.dec.sec, width, height); filename = acGetImage(im, ra, dec, width, height); if (filename == NULL) { printf("DSS Test failed: %s", acGetError()); exit(1); } printf("DSS returned file name (renaming to ./dss.fits)\n"); sprintf(buf, "mv %s ./dss.fits", filename); if (system(buf) != 0) perror("file rename error"); exit(0); } skycat-3.1.2-starlink-1b/cat/tests/tastro_image.ok000066400000000000000000000002151215713201500220550ustar00rootroot00000000000000Retrieve DSS image at pos 3:19:48.000000 41 30 39.000000, width: 1.000000, height: 1.000000: DSS returned file name (renaming to ./dss.fits) skycat-3.1.2-starlink-1b/cat/tests/test.preview000066400000000000000000000016141215713201500214320ustar00rootroot00000000000000PreviewData This is a test of a tab table to plot X Y Z - - - 1 3 7.7 1 3 8 1 3 8 1 3 8 1 4 8 1 4 8 1 4 8 1 4 8 1 5 8 1 5 8 1 5 8 2 3 7.7 2 3 7.7 2 3 7.7 2 4 7 2 4 7 2 4 7 2 4 7 2 5 6 2 5 6 2 5 6 2 5 7 2 5 7 2 5 7 2 5 7 2 5 7.7 2 5 7.7 2 5 7.7 2 5 8 2 5 8 2 5 8 2 5 8 2 5 8 2 5 8 2 5 8 2 5 8 2 6 5 2 6 5 2 6 5 2 6 6 2 6 6 2 6 6 2 6 7 2 6 7 2 6 7 2 6 7 2 6 7 2 6 7 2 6 8 2 6 8 2 6 8 2 6 8 2 6 8 2 6 8 2.2 3.3 8.9 2.2 3.3 8.9 2.2 3.3 8.9 2.2 3.3 8.9 2.2 4.3 7 2.2 4.3 7 2.2 4.3 7 2.2 4.3 8.9 2.2 4.3 8.9 2.2 4.3 8.9 2.2 7 9 2.2 7 9 2.2 7 9 3 4 7 3 4 7 3 4 7 3 4 7 3 5 4 3 5 4 3 5 4 3 5 4 3 5 6 3 5 6 3 5 6 3 5 6 3 5 6 3 5 6 3 5 6 3 5 7 3 5 7 3 5 7 3 6 5 3 6 5 3 6 5 3 6 6 3 6 6 3 6 6 3 6 6 3 6 6 3 6 6 3 6 6 3 6 6 3 6 6 3 6 6 3 6 6 3 6 6 3 6 6 3 6 6 3 6 7 3 6 7 3 6 7 3 6 7 3 6 7 3 6 7 3 6 7 3.2 6 9 3.2 6 9 3.2 6 9 3.2 6 9 4 3 8 4 3 8 4 3 8 4 3 8 4 5 5 4 5 5 4 5 5 4 6 5 4 6 5 4 6 5 4 6 5 4 6 8 4 6 8 4 6 8 skycat-3.1.2-starlink-1b/cat/tests/test.table000066400000000000000000000064331215713201500210440ustar00rootroot00000000000000Local Catalog This table was generated by skycat.tcl on Mon Jun 10 19:35:18 MET DST 1996 by user allan from "Guide Star Catalog at ESO" gsc-id ra dec pos-e mag mag-e mu d' pa ------ -- --- ----- --- ----- -- -- -- GSC0285600050 03:19:28.14 +41:26:29.00 0.2 13.49 0.40 F 5.63 222; GSC0285600098 03:19:32.99 +41:34:15.42 0.4 13.40 0.40 F 4.58 322; GSC0285600288 03:19:21.10 +41:31:19.74 0.2 13.13 0.40 F 5.12 277; GSC0285600314 03:19:44.44 +41:30:58.21 0.2 13.98 0.40 F 0.77 293; GSC0285600334 03:19:48.20 +41:32:50.14 0.2 11.77 0.40 F 2.16 360; GSC0285600342 03:19:57.26 +41:31:34.72 0.2 12.31 0.40 F 1.92 62; GSC0285600418 03:19:24.11 +41:34:44.58 0.2 11.69 0.40 F 6.08 312; GSC0285600518 03:19:47.84 +41:25:46.45 0.2 12.74 0.40 F 4.90 181; GSC0285600526 03:19:26.74 +41:32:26.23 0.2 11.25 0.40 F 4.39 294; GSC0285600548 03:19:51.07 +41:26:9.89 0.4 12.09 0.40 F 4.54 173; GSC0285600582 03:19:54.12 +41:33:48.49 0.2 10.75 0.40 F 3.32 19; GSC0285600616 03:19:37.64 +41:36:26.75 0.2 12.20 0.40 F 6.11 341; GSC0285600662 03:19:51.46 +41:34:25.36 0.2 11.67 0.40 F 3.80 9; GSC0285600672 03:19:35.12 +41:30:39.67 0.2 13.39 0.40 F 2.46 270; GSC0285600676 03:19:17.86 +41:30:25.06 0.2 13.87 0.40 F 5.69 267; GSC0285600832 03:19:36.32 +41:34:21.40 0.2 13.69 0.40 F 4.31 329; GSC0285600856 03:19:37.23 +41:29:9.78 1.2 13.94 0.40 F 2.55 234; GSC0285600886 03:19:36.18 +41:29:58.13 0.2 10.86 0.40 F 2.37 253; GSC0285600980 03:19:36.51 +41:25:2.75 0.2 11.09 0.40 F 6.04 201; GSC0285601044 03:19:45.74 +41:24:6.01 0.2 13.97 0.40 F 6.59 184; GSC0285601066 03:19:34.23 +41:34:50.23 0.2 12.10 0.40 F 4.92 328; GSC0285601078 03:19:48.23 +41:30:42.23 0.2 9.23 0.40 F 0.03 357; GSC0285601092 03:19:47.80 +41:35:46.82 0.2 12.93 0.40 F 5.11 359; GSC0285601162 03:19:51.15 +41:31:25.97 0.2 12.93 0.40 F 0.94 36; GSC0285601186 03:19:40.54 +41:32:55.46 0.2 12.17 0.40 F 2.67 327; GSC0285601330 03:19:51.48 +41:27:24.41 0.2 11.31 0.40 F 3.32 169; GSC0285601350 03:19:21.30 +41:29:27.53 1.2 10.51 0.40 F 5.19 257; GSC0285601402 03:19:52.48 +41:33:0.04 0.2 14.67 0.40 F 2.46 19; GSC0285601410 03:19:59.05 +41:28:46.60 0.2 12.61 0.40 F 2.77 133; GSC0285601412 03:19:25.94 +41:35:25.62 0.2 13.91 0.40 F 6.33 319; GSC0285601426 03:19:40.49 +41:35:44.59 0.2 12.26 0.40 F 5.27 344; GSC0285601446 03:19:55.54 +41:31:23.74 0.2 13.72 0.40 F 1.55 62; GSC0285601492 03:19:43.79 +41:27:25.56 0.2 14.56 0.40 F 3.35 194; GSC0285601540 03:19:34.87 +41:33:42.80 0.2 13.62 0.40 F 3.94 321; GSC0285601584 03:19:55.61 +41:24:30.49 0.2 14.35 0.40 F 6.32 167; GSC0285601598 03:19:15.86 +41:31:58.58 0.2 13.45 0.40 F 6.20 282; GSC0285601660 03:19:19.80 +41:32:2.54 0.2 13.65 0.40 F 5.50 284; GSC0285601758 03:19:48.56 +41:28:9.44 0.2 13.78 0.40 F 2.52 179; GSC0285601824 03:19:22.38 +41:25:46.16 0.2 13.07 0.40 F 6.89 225; GSC0286902390 03:20:14.03 +41:30:29.59 0.2 13.43 0.40 F 4.83 92; GSC0286902594 03:20:15.39 +41:34:55.92 0.2 11.76 0.40 F 6.63 50; GSC0286902669 03:20:22.14 +41:32:23.46 0.2 11.55 0.40 F 6.57 75; GSC0286902672 03:20:17.31 +41:32:34.26 0.2 12.47 0.40 F 5.76 71; GSC0286902678 03:20:4.95 +41:34:21.76 0.2 13.08 0.40 F 4.84 40; GSC0286902822 03:20:2.72 +41:30:34.42 0.2 14.73 0.40 F 2.71 92; GSC0286902844 03:20:2.60 +41:30:59.51 0.2 13.44 0.40 F 2.71 83; GSC0286902860 03:20:19.22 +41:33:4.93 0.2 12.98 0.40 F 6.28 67; GSC0286902884 03:20:0.87 +41:33:14.00 0.2 13.07 0.40 F 3.49 43; skycat-3.1.2-starlink-1b/cat/tests/test.tcl000066400000000000000000000011761215713201500205360ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: test.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # test.tcl - tcl defs to set up environment for test scripts # # Usage: source test.tcl # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 08 Apr 97 created proc tkerror {msg} { global errorInfo puts stderr "$errorInfo" tkerror__ "error: $msg" } # for debugging: print all errors on stderr catch {tkerror} rename tkerror tkerror__ #lappend auto_path ../library package require Cat set tk_strictMotif 1 tk appname Tclutil utilPrintErrors util::setXdefaults skycat-3.1.2-starlink-1b/configure000077500000000000000000002160131215713201500170470ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by Starlink Autoconf 2.59 for skycat 3.1.2. # # Copyright (C) 2003 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` exec 6>&1 # # Initializations. # ac_default_prefix=/usr/local ac_config_libobj_dir=. cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. # This variable seems obsolete. It should probably be removed, and # only ac_max_sed_lines should be used. : ${ac_max_here_lines=38} # Identity of this package. PACKAGE_NAME='skycat' PACKAGE_TARNAME='skycat' PACKAGE_VERSION='3.1.2' PACKAGE_STRING='skycat 3.1.2' PACKAGE_BUGREPORT='' ac_subdirs_all="$ac_subdirs_all tclutil astrotcl rtd cat skycat" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS subdirs LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_option in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval "enable_$ac_feature=no" ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "enable_$ac_feature='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "with_$ac_package='$ac_optarg'" ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/-/_/g'` eval "with_$ac_package=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` eval "$ac_envvar='$ac_optarg'" export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute paths. for ac_var in exec_prefix prefix do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* | NONE | '' ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # Be sure to have absolute paths. for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ localstatedir libdir includedir oldincludedir infodir mandir do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_confdir=`(dirname "$0") 2>/dev/null || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 { (exit 1); exit 1; }; } else { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi fi (cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 { (exit 1); exit 1; }; } srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` ac_env_build_alias_set=${build_alias+set} ac_env_build_alias_value=$build_alias ac_cv_env_build_alias_set=${build_alias+set} ac_cv_env_build_alias_value=$build_alias ac_env_host_alias_set=${host_alias+set} ac_env_host_alias_value=$host_alias ac_cv_env_host_alias_set=${host_alias+set} ac_cv_env_host_alias_value=$host_alias ac_env_target_alias_set=${target_alias+set} ac_env_target_alias_value=$target_alias ac_cv_env_target_alias_set=${target_alias+set} ac_cv_env_target_alias_value=$target_alias # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures skycat 3.1.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] _ACEOF cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --infodir=DIR info documentation [PREFIX/info] --mandir=DIR man documentation [PREFIX/man] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of skycat 3.1.2:";; esac cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-merge merge the contents of compile-time dependent packages into master rtd, cat and skycat libraries Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-blt=DIR link with BLT library installed in DIR _ACEOF fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d $ac_dir || continue ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_srcdir/configure.gnu; then echo $SHELL $ac_srcdir/configure.gnu --help=recursive elif test -f $ac_srcdir/configure; then echo $SHELL $ac_srcdir/configure --help=recursive elif test -f $ac_srcdir/configure.ac || test -f $ac_srcdir/configure.in; then echo $ac_configure --help else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi cd $ac_popdir done fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF skycat configure 3.1.2 generated by Starlink Autoconf 2.59 Copyright (C) 2003 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit 0 fi exec 5>config.log cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by skycat $as_me 3.1.2, which was generated by Starlink Autoconf 2.59. Invocation command line was $ $0 $@ _ACEOF { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` hostinfo = `(hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" # Get rid of the leading space. ac_sep=" " ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Be sure not to use single quotes in there, as some shells, # such as our DU 5.0 friend, will then `close' the trap. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, { (set) 2>&1 | case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in *ac_space=\ *) sed -n \ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" ;; *) sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------- ## ## Output files. ## ## ------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo sed "/^$/d" confdefs.h | sort echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core && rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo >confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . $cache_file;; *) . ./$cache_file;; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in `(set) 2>&1 | sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val="\$ac_cv_env_${ac_var}_value" eval ac_new_val="\$ac_env_${ac_var}_value" case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in tclconfig $srcdir/tclconfig; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f $ac_dir/shtool; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in tclconfig $srcdir/tclconfig" >&5 echo "$as_me: error: cannot find install-sh or install.sh in tclconfig $srcdir/tclconfig" >&2;} { (exit 1); exit 1; }; } fi ac_config_guess="$SHELL $ac_aux_dir/config.guess" ac_config_sub="$SHELL $ac_aux_dir/config.sub" ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. # Check whether --with-blt or --without-blt was given. if test "${with_blt+set}" = set; then withval="$with_blt" with_blt=$withval fi; # Check whether --enable-merge or --disable-merge was given. if test "${enable_merge+set}" = set; then enableval="$enable_merge" MERGED=$enableval else MERGED=no fi; echo "build merged master libraries for rtd, cat and skycat? $MERGED" subdirs="$subdirs tclutil astrotcl rtd cat skycat" ac_config_files="$ac_config_files Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. { (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } | sed ' t clear : clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ : end' >>confcache if diff $cache_file confcache >/dev/null 2>&1; then :; else if test -w $cache_file; then test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" cat confcache >$cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/; s/:*\${srcdir}:*/:/; s/:*@srcdir@:*/:/; s/^\([^=]*=[ ]*\):*/\1/; s/:*$//; s/^[^=]*=[ ]*$//; }' fi # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then we branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. cat >confdef2opt.sed <<\_ACEOF t clear : clear s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g t quote s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g t quote d : quote s,[ `~#$^&*(){}\\|;'"<>?],\\&,g s,\[,\\&,g s,\],\\&,g s,\$,$$,g p _ACEOF # We use echo to avoid assuming a particular line-breaking character. # The extra dot is to prevent the shell from consuming trailing # line-breaks from the sub-command output. A line-break within # single-quotes doesn't work because, if this script is created in a # platform that uses two characters for line-breaks (e.g., DOS), tr # would break. ac_LF_and_DOT=`echo; echo .` DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` rm -f confdef2opt.sed ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_i=`echo "$ac_i" | sed 's/\$U\././;s/\.o$//;s/\.obj$//'` # 2. Add them. ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH exec 6>&1 # Open the log real soon, to keep \$[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. Logging --version etc. is OK. exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX } >&5 cat >&5 <<_CSEOF This file was extended by skycat $as_me 3.1.2, which was generated by Starlink Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ _CSEOF echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 echo >&5 _ACEOF # Files that config.status was made for. if test -n "$ac_config_files"; then echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS fi if test -n "$ac_config_headers"; then echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS fi if test -n "$ac_config_links"; then echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS fi if test -n "$ac_config_commands"; then echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS fi cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ skycat config.status 3.1.2 configured by $0, generated by Starlink Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2003 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." srcdir=$srcdir _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "x$1" : 'x\([^=]*\)='` ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` ac_shift=: ;; -*) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; *) # This is not an option, so the user has probably given explicit # arguments. ac_option=$1 ac_need_defaults=false;; esac case $ac_option in # Handling of the options. _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --vers* | -V ) echo "$ac_cs_version"; exit 0 ;; --he | --h) # Conflict between --help and --header { { echo "$as_me:$LINENO: error: ambiguous option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_config_target in $ac_config_targets do case "$ac_config_target" in # Handling of arguments. "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason to put it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Create a temporary directory, and hook for its removal unless debugging. $debug || { trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./confstat$$-$RANDOM (umask 077 && mkdir $tmp) } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "\$CONFIG_FILES"; then # Protect against being on the right side of a sed subst in config.status. sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF s,@SHELL@,$SHELL,;t t s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t s,@exec_prefix@,$exec_prefix,;t t s,@prefix@,$prefix,;t t s,@program_transform_name@,$program_transform_name,;t t s,@bindir@,$bindir,;t t s,@sbindir@,$sbindir,;t t s,@libexecdir@,$libexecdir,;t t s,@datadir@,$datadir,;t t s,@sysconfdir@,$sysconfdir,;t t s,@sharedstatedir@,$sharedstatedir,;t t s,@localstatedir@,$localstatedir,;t t s,@libdir@,$libdir,;t t s,@includedir@,$includedir,;t t s,@oldincludedir@,$oldincludedir,;t t s,@infodir@,$infodir,;t t s,@mandir@,$mandir,;t t s,@build_alias@,$build_alias,;t t s,@host_alias@,$host_alias,;t t s,@target_alias@,$target_alias,;t t s,@DEFS@,$DEFS,;t t s,@ECHO_C@,$ECHO_C,;t t s,@ECHO_N@,$ECHO_N,;t t s,@ECHO_T@,$ECHO_T,;t t s,@LIBS@,$LIBS,;t t s,@subdirs@,$subdirs,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_lines=48 ac_sed_frag=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_lines # Line after last line for current file. ac_more_lines=: ac_sed_cmds= while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag else sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag fi if test ! -s $tmp/subs.frag; then ac_more_lines=false else # The purpose of the label and of the branching condition is to # speed up the sed processing (if there are no `@' at all, there # is no need to browse any of the substitutions). # These are the two extra sed commands mentioned above. (echo ':t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" else ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" fi ac_sed_frag=`expr $ac_sed_frag + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_lines` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi fi # test -n "$CONFIG_FILES" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac if test x"$ac_file" != x-; then { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} rm -f "$ac_file" fi # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then configure_input= else configure_input="$ac_file. " fi configure_input=$configure_input"Generated from `echo $ac_file_in | sed 's,.*/,,'` by configure." # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo "$f";; *) # Relative if test -f "$f"; then # Build tree echo "$f" elif test -f "$srcdir/$f"; then # Source tree echo "$srcdir/$f" else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s,@configure_input@,$configure_input,;t t s,@srcdir@,$ac_srcdir,;t t s,@abs_srcdir@,$ac_abs_srcdir,;t t s,@top_srcdir@,$ac_top_srcdir,;t t s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t s,@builddir@,$ac_builddir,;t t s,@abs_builddir@,$ac_abs_builddir,;t t s,@top_builddir@,$ac_top_builddir,;t t s,@abs_top_builddir@,$ac_abs_top_builddir,;t t " $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out rm -f $tmp/stdin if test x"$ac_file" != x-; then mv $tmp/out $ac_file else cat $tmp/out rm -f $tmp/out fi done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi # # CONFIG_SUBDIRS section. # if test "$no_recursion" != yes; then # Remove --cache-file and --srcdir arguments so they do not pile up. ac_sub_configure_args= ac_prev= for ac_arg in $ac_configure_args; do if test -n "$ac_prev"; then ac_prev= continue fi case $ac_arg in -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \ | --c=*) ;; --config-cache | -C) ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) ;; *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;; esac done # Always prepend --prefix to ensure using the same prefix # in subdir configurations. ac_sub_configure_args="--prefix=$prefix $ac_sub_configure_args" ac_popdir=`pwd` for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue # Do not complain, so a configure script can configure whichever # parts of a large source tree are present. test -d $srcdir/$ac_dir || continue { echo "$as_me:$LINENO: configuring in $ac_dir" >&5 echo "$as_me: configuring in $ac_dir" >&6;} { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_srcdir/configure.gnu; then ac_sub_configure="$SHELL '$ac_srcdir/configure.gnu'" elif test -f $ac_srcdir/configure; then ac_sub_configure="$SHELL '$ac_srcdir/configure'" elif test -f $ac_srcdir/configure.in; then ac_sub_configure=$ac_configure else { echo "$as_me:$LINENO: WARNING: no configuration information is in $ac_dir" >&5 echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;} ac_sub_configure= fi # The recursion is here. if test -n "$ac_sub_configure"; then # Make the cache file name correct relative to the subdirectory. case $cache_file in [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;; *) # Relative path. ac_sub_cache_file=$ac_top_builddir$cache_file ;; esac { echo "$as_me:$LINENO: running $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5 echo "$as_me: running $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;} # The eval makes quoting arguments work. eval $ac_sub_configure $ac_sub_configure_args \ --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir || { { echo "$as_me:$LINENO: error: $ac_sub_configure failed for $ac_dir" >&5 echo "$as_me: error: $ac_sub_configure failed for $ac_dir" >&2;} { (exit 1); exit 1; }; } fi cd $ac_popdir done fi skycat-3.1.2-starlink-1b/configure.in000066400000000000000000000016751215713201500174570ustar00rootroot00000000000000# E.S.O. - VLT project # $Id: configure.in,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is used with GNU autoconf to generate a configure script for # building Skycat. # # who when what # -------------- -------- --------------------------------------------- # Allan Brighton 15/12/05 Rewrote using TCL TEA standard # ----------------------------------------------------------------------- AC_INIT([skycat], [3.1.2]) AC_CONFIG_AUX_DIR(tclconfig) AC_ARG_WITH(blt, [AC_HELP_STRING([--with-blt=DIR],[link with BLT library installed in DIR])], with_blt=$withval) AC_ARG_ENABLE(merge, [AC_HELP_STRING([--enable-merge],[merge the contents of compile-time dependent packages into master rtd, cat and skycat libraries])], [MERGED=$enableval], [MERGED=no]) echo "build merged master libraries for rtd, cat and skycat? $MERGED" AC_CONFIG_SUBDIRS(tclutil astrotcl rtd cat skycat) AC_OUTPUT([Makefile]) skycat-3.1.2-starlink-1b/doit000077500000000000000000000004351215713201500160240ustar00rootroot00000000000000#!/bin/sh # Convenience script to configure, build and install skycat in the given prefix dir. # Edit the next line: prefix=/usr/local #prefix=$HOME/work/eso/skycat/install make -f Makefile.in autoconf configure --prefix=$prefix --exec_prefix=$prefix make all install #make release skycat-3.1.2-starlink-1b/plugins/000077500000000000000000000000001215713201500166165ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/plugins/README000066400000000000000000000007431215713201500175020ustar00rootroot00000000000000 Skycat Plugins ============== This directory contains a sample plugin for skycat, which is a script that can be dynamically loaded by skycat to add new features. * graphics_features This directory contains some simple Tcl scripts that add a menu item to the Skycat "Graphics" menu for saving and reloading line graphics, optionally based on world coordinates and also with a "sticky" option that keeps the graphics around after a new image has been loaded. skycat-3.1.2-starlink-1b/plugins/graphics_features/000077500000000000000000000000001215713201500223145ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/plugins/graphics_features/README000066400000000000000000000007671215713201500232060ustar00rootroot00000000000000 Skycat Plugin Examples ====================== This directory contains the Tcl sources for an example skycat plugin that adds the ability to save line graphics to a file in world or image coordinates and reload them again. To use this file for skycat, set the environment variable SKYCAT_PLUGIN to the path name of the SkyCat_plugin.tcl file. This file defines one tcl proc: SkyCat_plugin, which takes one argument: the name of the top level skycat widget. See the skycat documentation for details. skycat-3.1.2-starlink-1b/plugins/graphics_features/SkyCat_plugin.tcl000066400000000000000000000026041215713201500255760ustar00rootroot00000000000000#-*-tcl-*- # E.S.O. - VLT project/ESO Archive # $Id: SkyCat_plugin.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # SkyCat_plugin.tcl - example SkyCat plug-in script # # This is an example plugin file for skycat. It can be used to add # features to skycat at startup. To use this file for skycat, set the # environment variable SKYCAT_PLUGIN to the path name of this file. # # This file must define at least one tcl proc: SkyCat_plugin, which # takes one argument: the name of the top level skycat widget. # # This plugin adds the ability to save and reload line graphics by # adding 2 menu items to the Graphics menu. # # See the documentation, man pages and Itcl widget source code for details. # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 20 Jan 98 created # puts "Loading the graphics features plugin..." # This proc is required. It will be called once for each skycat # instance. The parameter is the name ("$this") of the SkyCat # class object. proc SkyCat_plugin {this} { # get the toplevel widget name set w [utilNamespaceTail $this] # call a proc to add items to the Graphics menu. # Note that the directory containing this file is automatically # appended to the Tcl auto_path, so we can just call a proc # as long as there is a tclIndex file in this directory. add_graphics_features $w } skycat-3.1.2-starlink-1b/plugins/graphics_features/VERSION000066400000000000000000000000261215713201500233620ustar00rootroot00000000000000graphics_features-1.0 skycat-3.1.2-starlink-1b/plugins/graphics_features/graphics_features.tcl000066400000000000000000000154431215713201500265250ustar00rootroot00000000000000#-*-tcl-*- # E.S.O. - VLT project/ESO Archive # $Id: graphics_features.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # graphics_features.tcl - add graphics features to Skycat Graphics # menu. # # The add_graphics_features proc is called by the example SkyCat # plugin script in this directory to add menu items to the Graphics # menu in Skycat to save and reload line graphics. # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 20 Jan 98 created # # Add "Save Graphics" and "Load Graphics" menu items to the Skycat # Graphics menu so that line graphics may be saved to a file and # reloaded later. You can save the graphics using world or image # coordinates and specify when reloading, whether or not the graphics # should be "sticky" and remain after a new image is loaded. # # $w is the name of the top level window. proc add_graphics_features {w} { # get the path name of the Graphics menu # (see TopLevelWidget in tclutil) set m [$w get_menu Graphics] $m add separator $w add_menuitem $m command "Save graphics..." \ {Save line graphics to a file} \ -command [code save_graphics $w] $w add_menuitem $m command "Load graphics..." \ {Load line graphics from a file} \ -command [code load_graphics $w] } # convert the given coordinates from $from_units to $to_units using the given # rtdimage handle and return the result. $coords may be a list of an even # number of values {x1 y1 x2 y2 x3 y3 ...}. The result is the same list, # converted to the output coordinates. proc convert_coords {coords from_units to_units image} { set result {} set len [llength $coords] for {set i 0} {$i < $len} {incr i 2} { set ix [lindex $coords $i] set iy [lindex $coords [expr $i+1]] $image convert coords $ix $iy $from_units x y $to_units lappend result $x $y } return $result } # Ask for a file name and save line graphics to the given file proc save_graphics {w} { set filename [filename_dialog] if {"$filename" == ""} { return } # check if file exists and, if so, ask for confirmation if {[file exists $filename]} { if {! [confirm_dialog "File `[file tail $filename]' exists. Overwrite it?"]} { return } } # ask if we should save the graphics in world or image coords set choice [choice_dialog \ "Please select the type of coordinates to save the graphics in:" \ {{World Coordinates} {Image Coordinates} Cancel} {World Coordinates} $w] if {$choice == "Cancel"} { return } elseif {$choice == "World Coordinates"} { set units {deg J2000} } else { set units image } # create the file if {[catch {set fd [open $filename w]} msg]} { error_dialog $msg return } # get the handle of the canvas window for the image set canvas [$w component image component canvas] # get the handle for the rtdimage item (for converting coordinates) set image [$w component image get_image] # get the handle for the image' graphic editor (class CanvasDraw) # so that we can deselect any selected graphic objects set draw [$w component image component draw] $draw deselect_objects # save the coordinate type: degrees J2000 or image pixel coords puts $fd "set units \"$units\"" # loop through the canvas items foreach item [$canvas find all] { set type [$canvas type $item] if {"$type" == "image"} { continue } # get item coords and convert from canvas coords to $units set coords [convert_coords [$canvas coords $item] canvas $units $image] # add a special tag to this item so we can delete it before reloading it $canvas addtag $filename withtag $item # get list of configuration options for the item set config {} foreach cfg [$canvas itemconfigure $item] { lappend config [list [lindex $cfg 0] [lindex $cfg 4]] } puts $fd [list $type $coords $config] } close $fd } # Ask for a file name and load the line graphics from the given file proc load_graphics {w} { set filename [filename_dialog] if {"$filename" == ""} { return } # make sure the file exists if {! [file exists $filename]} { error_dialog "file `[file tail $filename]' does not exist" return } # open the file for reading if {[catch {set fd [open $filename]} msg]} { error_dialog $msg return } # get the handle of the canvas window for the image set canvas [$w component image component canvas] # get the handle for the rtdimage item (for converting coordinates) set image [$w component image get_image] # get the handle for the image' graphic editor (class CanvasDraw) # so that we can set bindings for editing objects set draw [$w component image component draw] # check for "set units..." line set linenum 0 if {[gets $fd line] != -1} { incr linenum if {[llength $line] != 3} { error_dialog "bad input file format: line $linenum, expected: set units ..." close $fd return } lassign $line s1 s2 s3 # check for "set units..." line if {"$s1" == "set" && "$s2" == "units"} { eval $line } else { error_dialog "expected first line to be \"set units ...\"" $w close $fd return } } # if using image coords, ask if the graphics should be "sticky" # (i.e.: stay after new image is loaded) set sticky 0 if {"$units" == "image"} { set choice [choice_dialog \ "Do you want these items to remain visible after you load a new image?:" \ {Yes No Cancel} No $w] if {$choice == "Cancel"} { return } elseif {$choice == "Yes"} { set sticky 1 } else { set sticky 0 } } # delete any items that have already been loaded from this file $canvas delete $filename # loop through the contents of the file and create canvas items while {[gets $fd line] != -1} { incr linenum if {[llength $line] != 3} { error_dialog "bad input file format: line $linenum, expected: type coords config" close $fd return } lassign $line type coords config # convert coords from $units to canvas coords if {[catch {set coords [convert_coords $coords $units canvas $image]} msg]} { puts $msg continue } set id [eval $canvas create $type $coords] foreach cfg $config { lassign $cfg opt arg $canvas itemconfigure $id $opt $arg } # items with the "objects" tag are always deleted when a new image is loaded # so if we want the graphics to be "sticky", we remove that tag. # (The util::CanvasDraw class assigns the "objects" tag for graphic objects # created interactively and other classes follow the convention also.) if {$sticky} { $canvas dtag $id objects $canvas dtag $id $draw.objects $canvas addtag sticky withtag $id } # add bindings so that the items may be edited and saved again $draw add_object_bindings $id } close $fd } skycat-3.1.2-starlink-1b/rtd/000077500000000000000000000000001215713201500157265ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/rtd/CHANGES000066400000000000000000001753751215713201500167430ustar00rootroot00000000000000CHANGES to the RTD Sources -------------------------- This file contains a list of changes to the RTD software and user interface. The latest changes are at the top. --------------- 20.10.08 released rtd-3.2.1 ----------------- * Revised RtdImageHduChooser.tcl --------------- 20.10.08 released rtd-3.2.0 ----------------- * Added support for data types double and long long int. --------------- 10.09.07 released rtd-3.1 ------------------- * Increased maximum number of views of an image from 8 to 64 --------------- 03.02.06 released rtd-3.0 ------------------- * Major update: see top level CHANGES file. --------------- 04.04.05 released rtd-2.29 ----------------- * Merged in RTD changes from Peter Biereichel: * Fixed: too many open files when building colormaps.C * rtdRemote.c: Fixed: variable argument list * workaround bug in tcl 8.4.3 (SourceForge Request ID 835020) * using TCL_CC_SEARCH_FLAGS from tclConfig.sh as of tcl8.4 * added LD_SEARCH_FLAGS to build librtd.so * VLTSW20030157: View->Cuts pop-up window information missing * tested with APR2004 (tcl8.4, itcl3.3) * Test with gcc 3.3: variable argument list has changed * Documented in rtdSem.c and rtdImageEvent.c: semId must be set to -1 if semaphore locking is not used (semId=0 is a valid number). Users usually just clear the image event info structure before filling in the data needed. This has given interference problems with other processes on Solaris after booting the machine. * The image data byte order in RTD is clarified here: - FITS uses network byte ordering (big Endian) and binary FITS images on disks are also in big Endian. - In most cases RTD mmap's image files to avoid copying of images into memory which may lead to heavy disk swaps for very large images. So RTD needs to change the byte order on-the-fly when running on little Endian (i386) machines. The speed hit is pretty small since RTD only works on the visable image part. - A camera process can store the data into shm either in native byte order or tell RTD to do the byte-swap since the data were generated by a machine with a different byte order. - RTD used to have the "native" byte order flag which only did the byte swap for networked byte ordered data on little Endian machines. With the new "shmEndian" flag it is also possible to tell RTD (via an image event) that the data need to be byte-swapped. In the rtdimg/test directory there is a test program tRtdEndian.tcl which tests many Endian/datatype combinations, also including bias subtraction. * Revised the BiasImage and ImageTemplate class (didn't work with all combinations of data-types/endians). * include.mk files contains a flag SRCS_OPTL which only installes some include files (eg. from cfitsio) when VLTROOT is not set. This change was on request (SPR) since these includes gave problems with the RTD VLTSW distribution, which also contains cfitsio (but latest version). * By request: RtdImage.tcl automatically launches rtdServer when needed. * Updated printout for rtd --help (SPR). * Generally 'using namespace std' instead of specifying ::std * "autocut" uses autoSetCutLevels(99.5) instead of medianFilter(). This gives much better results and is also faster. In fact, users complaint about the bad cut-level setting via medianFilter(). * For Allan: --no-print-directory -s in makefile.mk.in was re-enabled again since the output was too verbose. One can easily overlook compiler errors (which happens several times to me). * Added define for SOCKLEN_T in define.h --------------- 20.01.03 released rtd-2.24 ----------------- * Ported to gcc-3.2.1 and Tcl-8.4.1 --------------- 27.02.02 released rtd-2.23 ----------------- * Fixed minor bug in HDU Chooser dialog. --------------- 13.12.01 released rtd-2.22 ----------------- * Enabled WCS coordinate conversion outside of the image area (by request). Now the RA and Dec values are also displayed when the mouse leaves the image area. * fixed problem with equinox syntax reported by David Terrett. --------------- 27.08.01 released rtd-2.21 ----------------- * Merged in changes from Peter Biereichel (see rtd-2.20.10). * Fixed the -float_panel and -panel_orient options as well as the show/hide control panel menu item. --------------- 21.08.01 released rtd-2.20.10 ----------------- * RtdImageCtrl.tcl: loading an image detaches the camera. Re-open pops-up again the HDU chooser (in case that it was closed before). * New widget for viewing the FITS header (RtdImageFitsHeader.tcl) which also shows the headers of the HDU's (becoming more important for VLT/VLTI projects). * RtdImageHduChooser.tcl shows HDU images only on request for speed reasons. Double clicking on a binary FITS table will show/hide the binary table (needed for FLAMES and other VLT projects). Displays only images with NAXIS >=2 (needed for VLT CCD software). * New widgets for 'Pick Object' (RtdImagePick2.tcl and RtdImagePickView.tcl) which allow to pick an object with a given sample size. They will be used by VLT applications like 'tcscam' and are made more general/public than RtdImagePick.tcl (RtdImagePick.tcl wasn't made for inheritance). * added 'statistics noise' subcommand for computing RMS, mean, average, min, max values on a user defined area. * added bltgraph subcommand for plotting VLTI scans (currently used by the VINCI application 'rtdvi'). * added info subcommand (info bbox, etc.). * All image event related tasks revised: o removed XSyncSetPriority() in RtdImage.C since this blocked X-clients after rapid image events (had to reboot Linux). o rtdServer was re-written (C++) for simplification and since Paranal reported that sometimes it exited without any message (nor core dump). o tRtd was generalized for testing image events. Currently it supports short image data only. o New widget for tRtd options which comes up when Rtd is started with the -debug option. o Performance measurements (and widget) revised. o Added method flushX() to ImageDisplay.C * Restructured the code of RtdImage.C since it became too large. Image commands are now in RtdCmds.C, coordinate routines in RtdCoords.C and HDU routines in RtdHDU.C. * Adapted all Makefile.in files for makefile.mk which now contains RTD standard rules. The standard rules were adapted from the previous Makefiles. Note, the standard rules still need to be done for all other sub-packages (tclutil, astotcl, etc.) -- need to talk with Allan... * Fixed "array out of bounds" in getMinMax() (ImageTemplates.C) * added RtdImage options -fillWidth, -fillHeight for auto scaling the image (needed by VLT autoguider which switches full image display to window and vice versa). * iqefunc.c: The old Midas routine crashed RTD. Bug fixed by pbiereic and kbanse (SPR VLTSW20000143). * RtdImage::loadFile() opens the file with reading only to avoid that the file is changed on disk (SPR VLTSW20000144). * for gcc version 2.95.2 on HP-UX 11: had to re-order in a number of files - maybe obsolete with new gcc version... --------------- 30.07.01 released rtd-2.20.9 ----------------- * Fixed problem with X shared memory, ssh and X11 forwarding: (X shm areas are not freed, so don't use them in this case) Added check in RtdImage.C for screen number "0", since when using X11 forwarding with ssh, the display is set to something like "host:10:0" - a proxy server, and the X shared memory is never freed. --------------- 18.05.01 released rtd-2.20.8 ----------------- * Ported to tcl8.3.3 (still compatible with earlier versions). The main change was to update the image related code to use the changed C Tk image interface. --------------- 11.05.01 released rtd-2.20.7 ----------------- * Changed the way multiple FITS image extensions are combined when you press the "Display as One Image" button in the HDU Chooser dialog. Previously, it was assumed that the CRPIX values were negative. Now they may be positive or negative and the resulting image is shifted to begin at 0,0 (See CompoundImage.C). --------------- 17.02.01 released rtd-2.20.6 ----------------- * Fixed a bug converting coordinates between deg and wcs using the rtd tcl subcommand "convert". --------------- 20.09.00 released rtd-2.20.5 ----------------- * Minor layout changes in RtdImageTrans.tcl (slightly different pack padding). * Minor bug fixes in the RtdImageHDUChooser.tcl, for case where CRPIX1 or 2 is not defined. * Fixed a bug in the display of galactic coordinates: RA was being displayed in hours and the equinox was displayed as 2000. Now RA is displayed in degrees and the equinox is displayed as "GALACTIC". --------------- 21.03.00 released rtd-2.20.4 ----------------- * Tested compiling with Sun-CC 4.2 and fixed a number of incompatibilities. * Fixed a panel layout problem introduced in the previous version (when -panel_orient = "horizontal"). * Fixed a statement in ImageData.C that caused compiler error message with some compilers. * Display only the tail end of the file name in the Object field (when the FITS OBJECT keyword is not defined) to save space. --------------- 02.03.00 released rtd-2.20.3 ----------------- * Added support for displaying WFI type images, which contain multiple image extensions, as a single image, based on the CRPIX values in the extensions. The default bahavoir is as before, except that there is a new button in the HDU window "Display as one Image". * Added a new button in the HDU window: "Use Settings from Main Image" that sets the colormap, color scaling options and cut levels for the preview images from the main image. This is needed, since the preview images often appear black when they have not been not prescaled. * Added a new RTD option: -panel_orient horizontal|vertical and added code to support having the main info panel on the left with a vertical orientation. The default for RTD is horizontal, as before. * Added code to check for valid command line options. (Previously the command line options were passed to the Rtd Itcl class directly, but there seems to be a bug in the current Tcl or Itcl version that caused the application to crash when passed an invalid option.) --------------- 27.12.99 released rtd-2.20.2 ----------------------------- * Minor bug fixes for pick object window (RtdImagePick, RtdImageZoomView) --------------- 13.11.99 released rtd-2.20.1 ----------------------------- * RtdImagePick.tcl: Fixed minor bug in pick object window (rectangle was not being displayed in the center of the image). * Merged in changes from Peter Biereichel (see below): * RtdImage.C / RtdImagePick.tcl: Better accuracy for 'pick object' which is required for telescope and instrument operations * RtdImage.C: subtract startX and startY from reference pixels for WCS display in the info panel (this is a quick fix not taking binning into account). * Comment changed in rtdImageEvent.h: Rotation angle is anticlockwise positive (not clockwise) * Added wcsFlags in rtdImageEvent.h and wcsdeltset command --------------- 25.10.99 released rtd-2.20 ------------------------------- * Merged in changes from Peter Biereichel (see below) * colors are initialized only when needed: moved call to initColors() from Rtd_Init() to the RtdImage constructor. * The installed version can be tar'ed to other "identical" target machines without the need to set environment variables before starting RTD. This is needed in the VLT environment where RTD is build on one machine and copied to all the other target machines. For this the following changes were made: - RtdImage::Rtd_Init() searches for RtdInit.tcl in the way itclx does (see also rtdimg/include/RtdInit.icc) - all links were removed in the installation directory - rtd.sh has become a general startup script. For tcl applications rtd.sh is merged with the tcl script by the Makefile (see directories rtdimg/demos and rtdimg/test) - all Makefiles include makefile.mk which allows to redefine the default (i.e. the generated-) installation root directory. - rtd/src/Makefile takes as default generated installation directory INTROOT or VLTROOT if PREFIX is not defined, otherwise /usr/local. The installation root directory can be redefined with 'make install PREFIX=' or setting INSTALL_TARGET before running 'make install'. * Configure option --with-vltgnu added. This option is specific to the gnu installation of the VLT software. * Added image extensions to RTD (copied from Skycat) * Added program options: -attach, -rtd_geometry and -rtd_title * RtdImage.C: Pass the rapid frame event on to the first rapid frame when the frameId in the rtdIMAGE_INFO structure doesn't exists. * Moved "Bias Image" from the Real-Time menu to the File menu * Added: Help menu * Added options -xscale and -yscale (the old options which now work properly) * Changed tRemote.tcl and RtdRemote.tcl. tRemote.tcl is used for an automatic test of Rtd. * man.mk allows to generated man pages from sources (see e.g. rtdevt/man/Makefile) * tkCanvasPsImage.c: uncommented fprintf() --------------- 11.08.99 released rtd-2.19.28 ---------------------------- * Fixed minor bug in RtdImage.C: flipCmd: return correct value for "flip xy". * Updated for egcs/gcc-2.95 (This compiler version is stricter for C++ code and even fails the solaris X11 header files, unless told to ignore the errors...). (see also rtd/src/Makefile) --------------- 16.05.99 released rtd-2.19.27 ---------------------------- * Fixed the -shm_data and -shm_header options again. There were problems since we started using cfitsio (It still had a reference to the old mmapped image data). Now the SysV shared memory is is passed to cfitsio as it should be. However, this required some incompatible changes: now the header and data are kept in a single shared memory area (previously in separate areas. To make up for this, "rtdimage shm get header/data" subcommands now returns a list of 4 values {shmId offset length size}, instead of only the shmId. The list values are the shared memory id, the offset in the shared memory area where the header or data begin, the length of the header or data, and the size of the shared memory area. *** NOTE: possible incompatibility *** * Fixed the isclear() method in RtdImage.C (called by the rtdimage isclear tcl subcommand). The method was assuming that a cleared image had a zero length header, which was not correct. --------------- 30.03.99 released rtd-2.19.26 ---------------------------- * Merged in changes from Peter Biereichel (below): Added new rtdimage subcommand 'biasimage' and widget 'RtdImageBias' for on-the-fly bias image subtraction. The widget can be called from the real-time menu. The features are: o Fast, since only the visible part of the image is updated (as usual, thank's to Allan) o Up to 5 bias images can be loaded (this value could be changed in BiasData.h) o Commands for loading a bias image from a file, copying the current image to a selected bias frame, clearing, displaying ... o Works globally for all Rtd clones. Note, when saving an image, the raw image and not the subtracted image is saved (this could be discussed). * rtdImageEvent.c, rtdServer.c: Added socket option TCP_NODELAY for faster image updates on HP-UX. * hput.c: changed 'long tsec' to 'time_t tsec' (astrotcl/wcslib). * RtdImage::isclear(): bug fixed * RtdRemote.C: argument 3 of 'getsockname' and 'accept' must be 'int' on HP-UX (was 'unsigned int' before) * RtdImage::call(): change strncmp() to strcmp() for commands like remote, remotetcl ---------------------------------------------------------------------------- * RtdRemote.C: Added #ifdef for linux unsigned (although the man page says it should be int, the compiler complains it should be unsigned). --------------- 22.03.99 released rtd-2.19.25 ---------------------------- * Fixed the Exit menu item to really exit and not just close the window, in the case where there is more than one main window. * Fixed socket error check in rtdrmt/src/rtdRemote.c. * Replaced itclsh2.2 with itclsh@ITCL_VERSION@ in Makefile.in. * Changed "quit" method in Rtd.tcl to use "delete object $this" instead of "destroy $w_" and "exit", so that class destructors are called as expected. * RtdImageSpectrum.tcl, RtdImageCut.tcl: removed "global" declaration for BLT vectors, since it caused a crash in tcl8.0.5/blt2.4g (something to do with variable traces). * ImageData.C: flip(): fixed an "off by one" bug that caused the wrong coordinates to be displayed for pixels when the image was rotated and/or flipped at zoom 1. * RtdImageZoomView.tcl: corrected the location of the square in the center of the zoom window (was off by one at zoom 1). * Merged in changes from Peter W. Draper (Starlink) to support 16 and 24 bit color. * Added minor fix to pan window to center the target image if needed. * Change min/max colors to 0/256 in RtdImageColors.tcl when using a read-only colormap. * Fixed the colormap shift method so that it takes the current ITT into account. * Added replacements for calls to memset in class LookupTable and ImageData when dealing with ulong instead of byte. * class ImageDisplay: made putpixel() inline and removed unnecessary check, to improve performance. Also fixed the "clear()" method to work with ulongs instead of bytes (for truecolor support). * Added code to RtdImageColors.tcl to update the color ramp when changing colormap files or itts in truecolor mode. * Added call to new routine Tk_CanvasWindowCoordsNoClip() in tclutil/src/tkCanvasImagePs.c to work around Tk's limit on canvas coordinates to short range. Now the canvas coordinates do not have to be clipped to short range. --------------- 28.12.98 released rtd-2.19.24 ---------------------------- * Rebuild tclIndex file whenever configure is run, since Tcl8 version is not compatible with tcl7 version (see makelinks script). * rtdimg/src/RtdImage.h: added include rtdImageEvt.h to avoid Sunpro cc compiler warning. * rtilib/src/saoutil.c: commented out calloc declaration to avoid conflict reported by sunpro cc. --------------- 03.12.98 released rtd-2.19.23 ---------------------------- * Fixed a minor bug in the destructors for the itcl classes RtdImage and RtdImagePopup. In the first case, the rtdimage object was not being deleted as it should; in the second it was, but should not have been. * Changed the ImageData::write() method (used to save a FITS file or a section of one to disk) to be compatible with the new FitsIO class. --------------- 16.11.98 released rtd-2.19.22 ---------------------------- * Ported to tcl8.0.3 (still compatible with tcl7.6/tk4.2) - Updated namespace syntax - Changed "class" to "itcl::class" for Itcl class declarations - Use full namespace pathnames for itcl member procs - Changed color initialization to be compatible with tcl8.0 (colormap is now initialized in Rtd_Init() and set for all windows) - Added code to handle vectors in the old and new BLT versions (The BLT vector interface changed) - Updated Makefiles and configure scripts to work in both versions - For backward compatibility, Rtd_Init automatically imports all of the required namespaces (rtd::*, util::*, blt::*, itcl::*, itk::*). (Use "namespace import -force" to avoid errors importing the same namespace twice.) - set tk_strictMotif to 1 (changes colors in menu selection) * the RTD is now using the CFITSIO library for FITS access (see the astrotcl package). No incompatible changes were introduced. Only the internal implementation of the FitsIO class was changed and some new methods were added for handling FITS tables and HDUs. The FITS files are still memory mapped (the cfitsio "memory" interface is used). Note that the cfitsio library routines are only used to access the FITS headers and extensions. Since there are no FITS headers involved in "real-time" mode, there is no performace penalty from using the library (the cfitsio routines are not called at all in that case). * RtdImage.C, ImageData.C: Minor changes to handle FITS files with multiple HDU. The RTD only displays the first HDU in a FITS file. If the first HDU is empty, a blank image is displayed. The Skycat application (based on the RTD) contains full support for displaying multiple HDUs and FITS tables, which are treated like local catalogs. --------------- 30.9.98 released rtd-2.19.21 ---------------------------- * Minor change to rtdimage cmap and itt commands so that "$im cmap file" returns the current colormap file and "$im itt file" returns the current itt file. * Changed the release structure of the rtd package to include the necessary utility packages. Now the rtd tarfile also contains the astrotcl and tclutil packages. The top level Makefile and configure script automatically determine which packages to make. --------------- 23.9.98 released rtd-2.19.20 ---------------------------- * Made some minor changes in the rtd colormap and display code to help support 16 and 24 bit color. It is still not directly supported though, since some changes would still need to be made in the ImageData and derived classes to deal with short and int pixel values and byte swapping, etc. For now, you can use 24 bit color only if your display also supports 8-bit pseudocolor while in 24-bit mode (see the Tk command "winfo visuals ."). This works, for example on a Sun Ultra, but not on my Linux machine. * Changed error message given when X visual is not supported. (For now, we still need 8 bit pseudocolor). * Removed menu accelerator Control-w, since it conflicted with the text bindings in entries. --------------- 7.9.98 released rtd-2.19.19 ------------------------------ * Removed trailing "\" in rtdevt/src/Makefile.in * For ESO detector chip coordinates: Changed "HIERARCH ESO DET WIN ..." to "HIERARCH ESO DET WIN1 ...", since the former keyword is not used. A number is always appended to WIN. For now, we only consider the first WIN. --------------- 5.8.98 released rtd-2.19.18 ------------------------------ * Color scaling: Added new command line option "-color_scale" to set the color scaling on startup. The option takes a value: one of linear, log, sqrt, histeq. Also made changes so that the color scaling setting is remembered between images and reapplied. (Source files changed: Rtdimage.tcl, Rtd.tcl, RtdImage.C, ImageData.[Ch]) * Coordinates: Added new coordinate type: "chip", for detector chip or CCD coordinates, that takes into account the origin of the chip and binning. X,Y coordinates in the user interface are now displayed in chip coordinates, which are the same as image coordinates, unless the FITS keywords "HIERARCH ESO DET WIN STRX" and "...STRY" are defined or special fields in the real-time image event struct are set (see below). * Added two new fields to the RTD real-time image event struct in rtdImageEvent.h: startX and startY, with the same meaning as the FITS keywords "HIERARCH ESO DET WIN STRX" and "...STRY" above. These fields are used, along with the existing binningX and binningY fields, to calculate and display the detector chip coordinates. The change is backward compatible, since it uses previously reserved space in the structure. If the values are set to 0, they have no effect. * RTD now reads cut level values from the real-time image events and sets the image cut levels, unless the user set them already by hand. User values override real-time event cut level values. * Changed the arguments to the RtdImage::displayImageEvent() method. This is an internal method, so this should not be an incompatible change. * Implemented "histogram equalization" color scaling and added it to the list of choices in the Rtd "Colors" popup window. The code to implement this was taken from saoimage-1.23.2 and modified only slightly. In order to be able to use histogram equalization code on "byte" images (BITPIX=8), also, the lookup table size had to be changed to 64k, from 256 bytes, which it was previously. * Added the X11 library directory to shared lib path in startup script. * Added code to handle NAN values for image pixels. They are now treated as blank pixels. --------------- 26.6.98 released rtd-2.19.17 ------------------------------ * RtdImage.tcl, RtdImagePrint.tcl: Changed footers in postscript output to include object name, file name and center position. * Compiling: rtdevt/*.c: fixed calls to semctl to avoid errors reported by egcs-1.0.3 (gcc-2.8.x). Removed "void" from "main()". --------------- 19.6.98 released rtd-2.19.16 ------------------------------ * RtdImageCtrl.tcl: fixed minor bug in pack command that showed up only when the options -float_panel and -with_grid were used together. * RtdImage.tcl, RtdImagePrint.tcl: went back to using the tk postscript command for printing images and graphics. This improves the quality of the postscript output over the screendump version, which used the "xgrabsc" utility to do a screendump. The default Tk canvas postscript command does not support printing images and the available patch could not handle large, zoomed in images. This version is now based on a Tk canvas extention I added to the tclutil package and does not require a patch to Tk. The extension is based on the patch, with fixes provided by Peter Draper of Starlink, who also modified the rtd print dialog box. The new dialog box has optional footers in place of headers and has a new option to print the whole canvas window, including any graphics that extend outside the image boundaries. * RtdImage.tcl: changed focus policy to fix problems with mouse pointer warping (moving mouse with arrow keys). The previous version included some code to avoid obscure problems with the CDE window manager, with the "click to focus" setting. If anyone has problems with the new version, please let me know. --------------- 28.5.98 released rtd-2.19.15 ------------------------------ * Added C++ method: RtdImage::makeImage(), replacing calls to ImageData::makeImage() to help simplify the code for derived classes and avoid duplicating code. No change in funtionality or interface. * RtdImage.C: added method isclear(), returns true if image is cleared. * Fixed bug in RtdImageColors.tcl that caused the colormap listing to be empty in certain cases. The colormap files are compiled in and no longer searched for in $RTD_LIBRARY/colormaps. --------------- 4.5.98 released rtd-2.19.14 ------------------------------ * Changed the RtdImage convertCoords() and convertCoordsStr() methods to fix bug in handling images with equinox != 2000. * Changed default zoom limits to -10..20 (was -5..9), (-min_scale, -max_scale) --------------- 28.4.98 released rtd-2.19.13 ------------------------------ * Increased label width for Rtd panel (RtdImagePanel), since labels were being cut off on some screens. * RtdImagePick.tcl (Pick Object): Merged in Peter Biereichel's changes, which include using the RtdImageZoomView class for the image (same as zoom window). This lets you zoom in and out to get the correct resolution. Also Fixed a bug in the "scale_changed" method that showed up on images that were not square. * RtdImage.C: rtdimage "statistics" subcommand (used by Pick Object window): If the user clicks on the image background, so that no FWHM can be calculated, the x,y and ra,dec coordinates of the point selected are returned and fwhmX and fwhmY are set to 0 (Previously, the results were undefined in this case). --------------- 15.4.98 released rtd-2.19.12 ------------------------------ * (doc, *.tcl): For documenting the "public interface": Updated comments on all Itk component declarations and added "public", "private" and "protected" keywords in the source to help identify the public interface, which is documented in man pages generated from the source by the itcldoc utility (tclutil package). * Minor changes in configure script and top level makefile for shared libraries * RtdImagePick.tcl (PickObject window), added "-orient" option, to change layout to "horizontal" or "vertical". Default is same as before (by request, to save window space). * RtdImagePick.tcl: moved initialization from constructor to "init" method, for easier subclassing. * Added command line option for "Pick Object" window layout: usage: "rtd -pickobjectorient vertical" (default: horizontal). (Option also added option to RtdImage.tcl and Rtd.tcl). * ImageData::write(): fixed a bug in image pixel coordinate conversion that caused the world coordinates to be slightly shifted in images created with the "Save region as..." Rtd menu. * Increased some buffer sizes in class RtdRPTool, since specifying a long file name caused the buffers to overflow (defaults were set too low). --------------- 31.03.98 released rtd-2.19.11 ------------------------------ * Updated man pages and documentation * RtdImage.C: Fixed the -shm_data and -shm_header options, which were no longer working after earlier changes. * Added -usexshm option to RtdImageColormap so that it follows the convention of the other rtd images. --------------- 25.03.98 released rtd-2.19.10 ------------------------------ * Made minor changes in the C++ class RtdImage, to make it easier to derive a subclass with its own configuration options (Added 2 optional arguments to RtdImage constructor). * Changed "blank image" size from 10x10 to 2x2 image, since people really seem to use 10x10 pixel images. (The size is sometimes used to determine if the image is "blank"). * ImageData.C: modified setScale so that dispWidth and dispHeight cannot be zero when using very large negative scales (this happens for extremely thin images, i.e. 5000x37), * Removed ImageData::read, use ImageData::makeImage() instead, since it allows different image types through subclassing. * Moved the WCS object (for managing world coordinates) from the ImageData to the ImageIO class (in astrotcl/wcslib). No change to the public interface. This makes it possible for a derived class (of ImageIORep) to replace the WCS implementation with a new one. * RtdImage.h now defines the RTD_OPTIONS macro, which can be used by derived classes to add new options to the rtdimage command. * Rtd.tcl: changed clone method (Menu: "New Window") to not reload the original image again. * RtdImage.tcl: Fixed bindings for -with_warp option to use "+" to not overwrite previous bindings. * Rtd.tcl: Change keyboard accelerators for menu items to use instead of , since is used in Tk for popping up a menu with the keyboard (see -underline option in menubutton(n)). * RtdImage.tcl: Fixed focus code to allow warping the mouse cursor and menu traversal without conflict. * Rtd.tcl, RtdImageCtrl.tcl: - Added -float_panel option to allow info panel to be in a popup window (default is off, no change), usage: rtd ... -float_panel 1, to enable. - Added -panel_layout option to allow changing the order of the zoom and pan windows in the layout (default is the same as before, no change). Usage: rtd ... -panel_layout $value, where value is one of {saoimage reverse default}, for an saoimage type layout, reverse or default. * Added "clone" number to window headers, to help identify related windows when there is more than one main window. --------------- 05.03.98 released rtd-2.19.9 ------------------------------ * Made minor change in the color ramp Tcl code, so that you can now scale and shift the colormap, without it always reverting to the original state. Previously, the colormap shift and scale operations caused the colormap to revert to the original state at the start. * For backward compatibility with applications using the rtd library: The dependency on the astrotcl and tclutil packages is now hidden from applications. librtd.a (.so, .sl, etc.), now contains the astrotcl and tclutil object files, the $prefix/include/rtd dir contains copies of the astrotcl and tclutil header files, and the Rtd_Init() routine also initializes these packages. * Minor changes/bug fixes: - added check in pan window widget (RtdImagePan.tcl) in case there are problems converting world coords ("catch draw_compass"). - propagate -min_scale and -max_scale options to the rapid frame popup (determines the min and max magnification). --------------- 13.2.98 released rtd-2.19.8 ------------------------------ * Fixed a bug in the "pick object" window that showed up when the main image was rotated (minor change made in RtdImagePick.tcl::update_rect. * Fixed the "Hide/Show Popup Windows" feature (moved the implementation to the tclutil package: class TopLevelWidget). The new implementation is more general and less error prone. --------------- 9.2.98 released rtd-2.19.7 ------------------------------ * Fixed problems with floating point precision when converting world coordinates (raised from default of 6 digits to max 17 digits.) * Fixed bug in introduced in the last version that could cause a core dump when setting the cut levels (in ImageTemplates::getMinMax). * Fixed minor syntax error in RtdImage.C that was not found by g++. * Fixed problem with "gethostname" prototype on solaris-2.6 in RtdRemote.C. --------------- 3.2.98 released rtd-2.19.6 ------------------------------ * Added selection mechanism to select a region of the image or canvas. The graphics toolbox now contains a "region" item that can be used to select a region of the image. The new RtdImage -regioncommand option can be used to have a tcl command evaluated whenever a region is selected. Also added binding as a shortcut to select a region * Added a menu item to the "Real-Time ==> Rapid Frame menu": "Delete Rapid Frame", to delete the current rapid frame. * Added a new rtdimage subcommand: "mmap", which has a similar syntax to the "shm" subcommand. The rtd "shm" subcommand is used to manipulate sysV shared memory areas containing the image and header data. The rtd "mmap" subcommand does the same, but with "mmap" memory, which is the default, since rtd uses mmap to read image files. * Fixed bugs in the rtd shm "create" and "delete" subcommand (check for number of arguments was wrong, transformation settings were not being saved). * Added options to rtd (class and command line) to change the magnification range allowed in the user interface: -min_scale and -max_scale, and changed the default range from (-5, 9) to (-10, 20). * Rtd now checks the value of the FITS "BLANK" or "BADPIXEL" keywords and ignores these pixels when setting cutlevels or doing any calculations. The blank pixels are displayed black by default. --------------- 26.01.98 released rtd-2.19.5 ---------------------------- * Updated comments in Itcl sources for automatic generation of man pages. (There are now man pages for all Itcl classes). * Added menu accelerators, keyboard shortcuts for menus --------------- released rtd-2.19.4 ------------------------------------- * Fixed image printing problems (rtd now no longer creates a copy of the image and graphics, but just makes sure the window is not covered by other windows before doing a screendump of the image window). * Compilied sources with the SunPRO C++ compiler and fixed problems that showed up there and not with gcc. * Changes in source configuration: Rtd previously contained a lot of generic code that was not Rtd specific. In order to make simplify the Rtd package and make the generic code available for other applications, 2 new packages were added (see below). Each package can be dynamically loaded and handled in the same was as the Rtd package. The Tclutil package was created by gathering "generic" Tcl and C++ code from various applications into a single generic Tcl package. The Astrotcl package was created by gathering general astronomy related Tcl and C++ code from other packages into a single, reusable package. If you were previously loading the Rtd package dynamically, you will need to add "package require" statements for the Tclutil and Astrotcl packages. If you were linking the package statically, you will need to add calls to Tclutil_Init and Astrotcl_Init in tkAppInit.C. If you were using the rtd C++ classes directly, you will need to add some -I compiler options to your Makefiles: (-I$(INSTALLDIR)/astrotcl -I$(INSTALLDIR)/tclutil). * renamed CanvasPrint to RtdImagePrint, since it is now rtd specific, and made minor changes to the options (pass rtd image obj as option). Restored earlier version of CanvasPrint that does not use xgrabc, for use for generic canvas printing. Added code to print the line graphics when printing an RTD image (was missing after previous changes by P. Biereichel). * Colormap files are now compiled in. This is slightly more efficient and makes it easier to create a single binary application to deliver. You can still load colormap files, but any found in the rtdimg/colormaps directory are compiled in statically. * Added plug-in capability for top level widgets. The basic idea is this: for each top level widget, you have the possibility to specify a plugin file to be sourced after the widget has been created. This is done automatically by the common base class. For any class XYZ, the default initialisation file is ~/.xyzrc and may be overridden by the environment variable $XYZRC. The file should define a Tcl proc named "xyz_plugin". If the plugin file is found, it is sourced and the plugin proc is called with one argument: the name of the widget ($this). If there are multiple instances of a widget, the plugin proc is called once for each. The plugin proc can use Itcl methods and Tcl commands to add menu buttons and other widgets, make changes or additions to the user interface or even replace the contents of key methods. * Tcl scripts: made a number of minor changes in the general purpose Itk widgets that were need for skycat. * RtdImage.C, FitsIO.C: the rtd "clear" command now optionally creates a blank image without world coordinates (previously it always created one with world coords). This change was needed to allow catalogs in skycat that are based on image coords. * FitsIO.C: Files are written in compressed format if they have the extension .hfits, .gfits or .cfits * fixed some bugs for image event synchronization via semaphores * Merged changes from D.Hopkinson (RMP nulticasting, statistics, etc.), P. Biereichel and A. Brighton into a single version. * Mem.C, RtdImage.C, configure.in: added code to handle the different prototypes for the semctl(2) system call on Linux, Solaris and HP. * RtdImage.C: replaced "sigignore(SIGFPE)" with "signal(SIGFPE, SIG_IGN)" for linux support. * rtdwcs: fixed a number of bugs in class FitsIO and related wcslib C functions, mostly dealing with inserting Fits keywords (not used by RTD, but used elsewhere...). * class Mem: added various changes and bug fixes; added a length field (used to indicate the length of the FITS header when the header and image are both mmapped from the same file). --------------- 04 Aug 97 released rtd-2.19 -------------------------------------- * fixed a minor bug in Mem_Map.C (added check in destructor for failed mmap) * Default option itk_option(-disp_image_icon) set to 0 * New option itk_option(-with_warp). Default is 1 for main image only. The option is used to make arrow keys move mouse pointer by one pixel. * The remote interface was extended: the new rtdimage command "remotetcl" eval's Tcl commands in Rtd's Tcl interpreter. For an example see files rtdimg/demos/tRemoteTcl* and rtdimg/library/RtdRemoteTcl.tcl. The proc's connect_to_rtd {} and send_to_rtd {rtd_fd args} are contained in rtdimg/library/tclutil.tcl * Bug fixed in postscript print itk classes (xgrabsc) * The updated RTD PostScript document is in rtd/doc/rtd.ps * New RTD Performance measurement tool in menu "Real-time". To run it use rtd -debug 1; "Attach to camera"; Start Performance Tool from menu "Real-time" * New Recorder/Playback tool in menu "Real-time". This tool works on FITS cubes. * BITPIX=-16 converts to standard FITS format * Support for image event synchronization via semaphores * X synchronisation option implemented for X11R6 * The Rtd image event structure had to be changed because of the new options X synchronisation and image event synchronization via semaphores. * fixed bugs in rtdServer.c and rtdImageEvent.c * Value display in Cuts...; Pixel table with statistics * various bug fixes in the handling of Fits keywords (class FitsIO) and mmap files (class Mem) as well as in the wcslib (hget.c, hput.c) --------------- 17 Jun 97 released rtd-2.18.2 ----------------------------------- * fixed bug in rtdutl/src/Mem.C, method shared(int) (use length() rather than size()). * LabelEntry.tcl, RtdImageCut.tcl: replaced references to the Iwidgets class "entryfield" with equivalent local code in LabelEntry.tcl. This is needed so that we don't have to load the entire iwidgets sources in the single binary version of skycat. The added features include a -validate option of the LabelEntry and derived classes. * CanvasPrint.tcl: allow for the XGRABSCBIN variable to not be set. This is needed for the binary skycat release. By default, look for xgrabsc in the shell $PATH if $XGRABSCBIN is not set --------------- 30 April 97 released rtd-2.18.1 ---------------------------------- * class HTTP: added new feature to HTTP::get(url) (can be used in catalog config file URLs): Now the get method accepts 3 types of URL: - http://host/path - URL: do an HTTP get - file:/path - get the file - /path - command: exec the command and read the standard output. This was a request from Andreas (awicenec@eso.org). * Minor configure script additions, for creating binary release of skycat --------------- 22 April 97 released rtd-2.18 ------------------------------------ * More minor changes in the configure scripts and makefiles for dealing with shared libraries on HP. * Tested on Linux 2.x (watch out for old /usr/lib/libBLT.a, which can be linked in by mistake instead of the new BLT2.1 library). * Updated the Mem class (rtd/rtdutl) with a newer version that handles the case on HP where the same file is mmapped twice, which returns an error under HP-UX. The new version keeps a list of Mem objects and reuses an existing object if needed. --------------- 16 April 97 released rtd-2.17 ------------------------------------ * fixed bug that showed up when you "attach" a camera after viewing an image of the same size. The problem was in the way the image data size was checked: the size (data.size()) was used rather than the length (data.length()), which can be different if the FITS header is also stored in the same shared memory object (class Mem). * minor configure/Makefile changes. Tested with Sun-CC. --------------- 11 April 97 released rtd-2.16 ------------------------------------ * changed the name of the Tcl init routine for Rtd from RtdImage_Init to Rtd_init, to comply with the standards for loadable modules in the new Tcl version (The old version is still supported for backward compat.) * changed the configure script and Makefiles to get information from the from the installed Tcl configuration files: tclConfig.sh, tkconfig.sh, itclConfig.sh, tclxConfig.sh, ... rather than try to guess the correct values. Rtd also produces its own rtdConfig.sh script, which can be used by other applications to find out library and path names for Rtd as well as X and Tcl/Tk. The tclConfig.sh script also contains information on how to generate and use shared libraries on each OS, which is non-trivial and very system dependent. * To set the version number for a new Rtd release, you only have to edit the VERSION file now. The configure script picks this up and generates the necessary #defines and make variables, etc. * replaced GNU make, gcc, Solaris and HP-UX specific features from the Makefiles and configure scripts that were added in rtd-2.15. These are OK for use at ESO, but would cause problems for anyone else who didn't use GNU make or gcc, etc. --------------- 08 April 97 released rtd-2.15 ------------------------------------ * Peter Biereichel ported Rtd to Itcl2.2 and added initial support for shared libraries and modules (based on work done by Kim Gillies). use: configure --enable-shared to create the shared library (librtd.so or librtd.sl). --------------- 01 April 97 released rtd-2.14 ------------------------------------ * adapted for new Tcl/Tk release (tcl 7.6, tk 4.2, [incr Tcl] 2.2, [incr Tk] 2.2...) (see file genTclTk on this directory for a sample installation script for Tcl/Tk) * support for shared libraries: configure tcl/tk, BLT and rtd-2.14 with --enable-shared The Makefiles will create shared libraries as well as archive library files. * master shared library (librtd.so or librtd.sl) can be dynamically loaded with the tcl "load" command (RtdImage_Init was renamed to Rtd_Init) * uses xgrabsc.2_41 (screen dump) for canvas image print --------------- 10 Feb 97 released rtd-2.13 (intern) ----------------------------- * fixed another bug related to shared memory. It seems that the destroy_notify routine in RtdImage.C, which was supposed to cleanup any shared memory it created before exiting, was actually being called at other times, such as when the mouse enters the image window. Seems to be some kind of Tk4.0 bug? Commented out for now. This bug did not affect most users. It only turned up if you were using the RTD remote interface and/or the "shm" subcommand to access image shared memory using SysV shared memory. --------------- 05 Feb 97 released rtd-2.12 (intern) ----------------------------- * fixed bug in [rtdimage shm get] (rtdimage tcl subcommand to return shared memory id, and/or force image to be in shared memory) --------------- 30 Jan 97 released rtd-2.11 -------------------------------------- * Added World Coordinates support to the real-time image events by extending the rtdIMAGE_INFO struct in rtd/rtdevt/rtdImageEvent.h and using the new info in RtdImage.C to set the world coordinates information for the image. The following fields were added to the image event: double ra; /* Center right ascension in degrees */ double dec; /* Center declination in degrees */ double secpix; /* Number of arcseconds per pixel */ double xrefpix; /* Reference pixel X coordinate */ double yrefpix; /* Reference pixel Y coordinate */ double rotate; /* Rotation angle (clockwise positive) in degrees */ int equinox; /* Equinox of coordinates, 1950 and 2000 supported */ double epoch; /* Epoch of coordinates, used for FK4/FK5 conversion, no effect if 0 */ char proj[8]; /* Projection: one of: "-SIN", "-TAN", "-ARC", "-NCP", "-GLS", "-MER", "-AIT", "-STG", "PLATE", "LINEAR", "PIXEL" */ (I think the projection (proj) is only used for display and does not have any effect. I included it because it is part of the function interface (in Doug Mink's wcslib). *** (NOTE: incompatible change: clients must at least be recompiled!) --------------- 21 Nov 96 released rtd-2.9 -------------------------------------- * Made configure scripts and sources Linux compatible. Fixed byte-swap problems on machines that have a byte order different from the network. Thanks to Sidik Isani for supplying the patches for this. * The "Pick Object" feature (View Menu) now also works for images that do not support world coordinates (RtdImage.C, RtdImagePick.tcl). * rtdutl: class HTTP: Local file URLs are now supported, i.e., file:/path/name... --------------- 8 Nov 96 released as rtd-2.8, part of skycat 1.0.1 --------------- * (Rtd) Fixed compass to display East correctly (was reversed...) --------------- 7 Nov 96 released as rtd-2.7, part of skycat 1.0 ------------------ * (WCS lib) Major improvements in the World Coordinates handling. The WCS information for HST images should be handled correctly now, so you can plot guide stars, etc. This previously worked correctly only for some images (such as those from DSS). Many thanks to Doug Mink (dmink@cfa.harvard.edu) for supplying the WCS library and bug fixes. * (Rtd) added a new "Grid" feature (see View menu) that displays a world coordinates based grid over the image. You can also control the grid size (distance in arcsecs between grid lines) in a new entry in the main panel. * (Rtd) The compass widget (N-E display in panel) was removed and replaced with a more correct display in the Pan window. The Pan window now displays 2 arrows indicating the real north and east for the image, based on the world coordinate information. * fixed bug in "measure band" display that caused incorrect distances to be displayed for the width and height lines (the diagonal was ok). (Needed to convert all 3 points from canvas to world coordinates rather than using only 2 points and assuming a linear coordinate system...) (in RtdImage.C). * Added bindings to measure band so that arrow keys can be used to position it. * fixed bug in conversion between world coordinate and pixel distances (in WCS.C). --------------- 18 Oct 96 released as rtd-2.6, part of skycat 1.0b15 ------------------ * rapid frame was being deleting by the "Graphics:clear" menu item: fixed. * graphics: added code to disable line graphics (menu and popup) when image is cleared. * fixed syntax problems in HMS.h and WorldCoords.h reported by mcomin@eso.org that show up when using g++/libg++ and the file is included, which defines templates for operator functions... --------------- 15 Oct 96 released as rtd-2.5, part of skycat 1.0b14 ------------------ * got new version of SAO WCS lib from Doug Mink with some fixes for images where the equinox and epoch were not set. * (Rtd) Changed the way image cut levels are set by default. In the previous version, cut levels were not changed at all when a new image was loaded, which meant that you usually had to press the "Auto Set Cut Levels" button to make the image visible. Now this has been changed as follows: If you set the cut levels explicitly by typing in a number or moving a slider bar, etc., they will not be changed, even if a new image is loaded. However, if you have the cut levels calculated automatically by pressing the "Auto Set Cut Levels" button or the "Median Filter" button, etc., then it is assumed that new cut levels can be set automatically when a new image is loaded. (We would be interested to hear any comments on this. Maybe we should make this behavior optional ny adding a checkbutton somewhere...) * changed bindings on the "measure band" (RtdImageMBand.tcl) so that it acts more like a menu or the line graphics: it will stay up if you click <3>, release and then drag. Clicking <3> again makes it go away. now makes it "freeze" so you can keep it where it is. (or ) displays just the single line mband. * Made a number of changes designed to improve performance on very large images (got test image from Kim Gillies: 170 MB, 8192 x 5464 floats): * the zoom window is no longer updated from the pan window, since that can cause a lot of disk activity on large images (the mouse easily crosses the entire pan image, which would have to be displayed in the zoom window). * auto set cut levels, median filter, finding min/max pixel, etc. now are only calculated for the visible part of the image and (for speed) don't examine all image pixels. (modified getDist() and medianFilter() methods). * added a check and a warning dialog for the case where a very large image is zoomed so that the canvas scroll area exceeds the range of a "short" (32k pixels in X or Y), since there is an internal Tk limit there. I could get around this with a hack, but it would require access to Tk internals that would cause compilation problems in the VLT environment. * fixed problems propagating cut level changes to zoom window (RtdImage.C) * added rcs keywords as static constants to source files (for Giorgio). * added a "Reset" button to the EntryForm class - used to enter WCS data (rtd) and local catalog data (skycat). --------------- 1 Oct 96 released as rtd-2.4, part of skycat 1.0b12 ------------------ * Class ImageData/WCS/RtdImage: removed wcs* routines and replaced them with a new class called "WCS" (module rtdwcs) that is the interface to Doug Mink's SAO WCS lib. Class ImageData now has a method "wcs()" that returns a reference to the WCS object rather than implementing methods like "wcs2pix()" itself. The WCS class uses reference counting so that it is easier to share the information in different rtdimage views. * added a Tcl/Tk interface for setting and displaying the basic WCS info (using the rtdimage wcsset subcommand) and added a new View menu item "WCS Information". * added 2 new rtd subcommands for setting WCS information from outside: "wcsset" (to set WCS parameters) and "wcsshift" to shift the WCS center of the image. See the rtdimage(n) man page for details. * fixed bugs in Mem/Mem_Map classes: do read-only mmap (was read/write: bad for read-only image files), report errors correctly (inserted missing error messages), initialize status_ member variable (was missing). * added error checking in FitsIO.C to catch incomplete FITS files or files that have the wrong type. * added global Tcl variable "rtd_version", set to the version number: "2.4", ... * ImageColor: made changes in colormap handling in an attempt to avoid flashing when using a private colormap. Added new tcl command: "rtd_set_cmap" to set colormap for popup windows to be the same as rtdimage. * FitsIO: Display of FITS header (item in View menu) changed so that displayed copy of header is formatted for ASCII display (with newlines, no NULL chars). * FitsIO: loading large FITS files should be faster now, due to use of mmap(2) in place of reading the file. * wcslib, rtilib: started using new SAO wcslib (wcssubs-1.0) version. Changes in the wcslib pix2wcst routine (converts image pixel coords to a WCS string) caused problems (coords are sometimes output in degrees, sometimes HMS). Replaced calls to pix2wcst with pix2wcs. --------------- 20 Sep 96 released as rtd-2.4b1, part of skycat 1.0b11 ------------------ * Added range checks in LookupTable.C to fix problems caused by keeping previous cut levels for different image data types * rtdutl: non-ANSI-C "press" sources: removed -traditional option from Makefile.in (not available with "cc") and fixed declarations in C sources (taken from "press" module) so that gcc doesn't complain. (was reported by K. Gillies). * min/max pixel values: (ImageTemplates.C): changed algorithm to not examine every pixel on large images. On smaller images, the time is not so important, but on very large images it can take a long time. Now only every nth pixel is examined, which should give an estimate of the min/max pixel values. * All transformations (flipX,Y, rotate, scale) and cut level settings are now kept between image loads and after a "clear" operation (requested by P.Biereichel). * fixed bugs that sometimes caused the values displayed in the upper panel (X, Y, pixel value) to be off by 1 with respect to the zoom window. The problem showed up when the image was at zoom factor 1 and with certain transformations applied and also in rapid frames. It should work correctly now. (Changes in RtdImage.C, ImageData.C, ImageTemplates.C) * RtdImage.C: RtdImageCamera::display(): added "frameId" arg to calls to the pre and post camera commands to differentiate between rapid frames and the main frame. (requested by pbiereic). This affects calls to the pre and post commands specified in the rtdimage "camera attach" command. * RtdImage.C: configureNotify(): fixed bug that sometimes caused the image to not be redrawn correctly after a window manager maximize/minimize resize operation. * RtdImageCtrl.tcl: new_image_cmd: added code to destroy "spectrum" window when a new image is loaded (problem was reported in SPR Nr: 960518 when new image was smaller in real-time mode: could not reproduce) * Real-time interface: in RtdImage.tcl: detach_camera: inserted a call to "$image_ update" to make sure all image windows are up to date with the shared memory image. (This might be needed due to timing problems between the shared memory image and the socket being read from the rtdServer.) * RtdImage.C: added new rtdimage subcommand: "$image update" forces the image to be updated from memory, where it may have been changed by a separate process accessing shared memory... * spectrum (View::Cuts..." menu item): ignore errors when line is too small (was reported as SPR Nr: 960536, forwarded by P. Biereichel) * added code (from P. Biereichel) to make sure zoom window gets cleared when the mouse leaves the image window (see RtdImageZoomView.tcl) ---------------- 14 Aug 96 released rtd as part of skycat-1.0b10 ------------------ * added check for "SIMPLE = ..." keyword/line at beginning of FITS files * rtdimage: "Open File" now recognizes suffixes for compression: hfits (H_COMPRESS), gfits, gzfits (GZIP), cfits (UNIX_COMPRESS) * fixed bug when FITS keyword "CTYPE1" was not "RA --", as described in mail from Alberto Micol (just removed restriction in CTYPE1 being "RA--") * rtilib: class ImageData: added a new class "LookupTable" to make it easier to share and manage color lookup tables. Also changed the way the "Blank" pixel is implemented (more efficient now). * Cut levels and transformations (flipXY, rotate, scale) are now kept even when a new image is loaded. * rapid frame: embedded rapid frames (in main image) get the cut levels and transformations (but no image data) from the main image. Popup rapid frames (in separate window) can have their own transformations and cut levels (but transformations from the main image still propagate). * It is now allowed to set the cut levels outside of the min/max pixel range. * added new "View" menu item "Hide Control Panel" to toggle the visibility of the top control panel. * added new "View" menu item "Magnification" to set the image scale when the control panel is not visible. * changed default bindings in canvas so that you can scroll with button <2> when the control panel is not visible. * added support for "mmap" in Mem class (rtdutl), using code from the ACE class library (modified by Kim Gillies). mmap is now used to read files more efficiently for local catalogs and decompression. Later it will also be used to load image files (need to first start using new sao-wcslib). ---------------- 6 Aug 96 released rtd as part of skycat-1.0b9 ------------------ * added decompression algorithms (H-compress, gzip, unix) the PREVIEW field in catalog query results is now interpreted as an image OR a tab table to plot, based on the "Content-type" field of the preview data returned. The current implementation is based on the document: http://arch-http.hq.eso.org/~amicol/asu_94.html If the "Content-type" of the preview is recognized, it is plotted as a graph or loaded as an image... ---------------- 1 Aug 96 released rtd as part of skycat-1.0b8 ------------------ * Added an interface for selecting an object/star in the image and calculating the center, FWHM and angle (see View menu, "Pick object") * Fixed problems with world coordinates where (hour == -0.0). (0:0:1 -0:0:1) should work correctly now. * removed the "wcs2pix" and "pix2wcs" tcl subcommands (use the "convert coords" subcommand instead...) * Graphic items are now clipped to (about) the size of the image (incuding rapid frame rect and panning rect) * Cut levels for rapid frames are no longer set from the master image. Rapid frames can have thier own cut levels and transformations. ---------------- 24 Jul 96 released as part of skycat-1.0b6 ------------------ * rapid frames are now assumed to start at 0,0 * you can set the cut levels separately for rapid frames * you can rotate/flip/scale rapid frames separately * you can no longer move a rapid frame outside of the image * I added a test utility for rapid frames that you can access as follows: rtd -debug 1 This uses a test program (tRtd) that is installed with rtd. You can change the update interval by specifying the -interval option: rtd -debug 1 -interval 200 The default is 100 ms. ---------------- 28 May 96 released as part of skycat-1.0a10 ------------------ * The main visible changes are some new menu items and support for a private colormap... ---------------- 23 May 96 released as part of skycat-1.0a9 ------------------ * private colormaps are used when there are not enough colors. The default minimum amount of colors is 30 and the default max is 60. You can set these via the -min_color and -max_color options. If min_colors colors are not found, a private colormap is installed. I tried to save the GUI colors to avoid flashing... * There is a new menu item under File for "cloning" the main window. The main windows share the same colors, but otherwise are like 2 different applications. * I added a menu item to the View menu to hide/show the popup windows. ---------------- 12 Apr 96 released as part of skycat-1.0a8 ------------------ * added pop up rapid frame window with zoom controls * added a new zoom window (the old one is still available with an option) which works over any rtd image (pan window, rapid frame,...) * added a remote control interface (see man page rtdRemote(3)) * added some new Rtd commands to allow remote access to the image and header in shared memory (see RtdImage(n), commands: shm, remote) * new Rtd subcommands for converting between any 2 coordinate systems (see RtdImage(n): convert command). * RtdImage now understands the following coordinate systems: canvas coordinates screen coordinates image coordinates world coordinates (H:M:S and degrees, any equinox) For example, coordinates may now be specified as: $x $y canvas or: $ra $dec "wcs 1950" ---------------- 21 Feb 96 released as part of skycat-1.0a4 ------------------ * negative world coordinates are now handled correctly * bzero and bscale Fits keywords are now used * support for the BLANK fits keyword for blank pixels * the Pixel table has been implemented in C++ * We are now using the new saoimage-1.18 wcslib (mixed with the DSS plate code from 1-15, due to problems in the new version) ---------------- 6 Feb 96 released rtd as part of skycat-1.0a2 ------------------ * lots of bug fixes * added a menu item for viewing the FITS header ---------------- 25 Feb 96 released rtd as part of skycat-1.0a1 ------------------ * Added versions for Solaris (with shared libs) and HP ----------- Sep 18, 1995: begin change log for RTD ---------- skycat-3.1.2-starlink-1b/rtd/Makefile.in000077500000000000000000000423411215713201500200020ustar00rootroot00000000000000# Makefile.in -- # # This file is a Makefile for Sample TEA Extension. If it has the name # "Makefile.in" then it is a template for a Makefile; to generate the # actual Makefile, run "./configure", which is a configuration script # generated by the "autoconf" program (constructs like "@foo@" will get # replaced in the actual Makefile). # # Copyright (c) 1999 Scriptics Corporation. # Copyright (c) 2002-2005 ActiveState Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: Makefile.in,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ #======================================================================== # Add additional lines to handle any additional AC_SUBST cases that # have been added in a customized configure script. #======================================================================== #SAMPLE_NEW_VAR = @SAMPLE_NEW_VAR@ # Install these scripts PROGS = rtd tRtd # Extra static library and binaries for real-time image servers and clients RTDEVT_LIB = librtdImgEvt.a RTDEVT_OBJ = rtdClient.o rtd_server.o rtdSERVER.o rtdCLNT.o rtdSem.o rtdImageEvent.o rtdCubeDisplay.o rtdLOG.o RTD_SERVER = rtdServer RTD_SERVER_OBJS = rtd_server.o rtdSERVER.o rtdCLNT.o rtdLOG.o RTDEVT_DEMOS = rtdClient rtdCubeDisplay # Extra static C library for remote RTD access RTD_REMOTE_LIB = librtdRemote.a RTD_REMOTE_OBJ = rtd_remote.o # Testing applications TEST_APPS = tImageEvent tRtd trtdRemote # For convenience (and backward compatibility), merge in the required package objects MERGE_OBJECTS = @MERGE_OBJECTS@ #======================================================================== # Nothing of the variables below this line should need to be changed. # Please check the TARGETS section below to make sure the make targets # are correct. #======================================================================== #======================================================================== # The names of the source files is defined in the configure script. # The object files are used for linking into the final library. # This will be used when a dist target is added to the Makefile. # It is not important to specify the directory, as long as it is the # $(srcdir) or in the generic, win or unix subdirectory. #======================================================================== PKG_SOURCES = @PKG_SOURCES@ PKG_OBJECTS = @PKG_OBJECTS@ PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ #======================================================================== # PKG_TCL_SOURCES identifies Tcl runtime files that are associated with # this package that need to be installed, if any. #======================================================================== PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ #======================================================================== # This is a list of public header files to be installed, if any. #======================================================================== PKG_HEADERS = @PKG_HEADERS@ #======================================================================== # "PKG_LIB_FILE" refers to the library (dynamic or static as per # configuration options) composed of the named objects. #======================================================================== PKG_LIB_FILE = @PKG_LIB_FILE@ PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ PKG_BIN_FILE = bin_BINARIES = $(PKG_BIN_FILE) $(RTD_SERVER) $(RTDEVT_DEMOS) $(PROGS) lib_BINARIES = $(PKG_LIB_FILE) $(RTDEVT_LIB) $(RTD_REMOTE_LIB) BINARIES = $(lib_BINARIES) $(bin_BINARIES) SHELL = @SHELL@ srcdir = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ libdir = @libdir@ datadir = @datadir@ mandir = @mandir@ includedir = @includedir@ DESTDIR = PKG_DIR = $(PACKAGE_NAME)$(PACKAGE_VERSION) pkgdatadir = $(datadir)/$(PKG_DIR) pkglibdir = $(libdir)/$(PKG_DIR) pkgincludedir = $(includedir)/$(PACKAGE_NAME) top_builddir = . INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ CC = @CC@ CXX = @CXX@ CFLAGS_DEFAULT = @CFLAGS_DEFAULT@ #CFLAGS_WARNING = @CFLAGS_WARNING@ CLEANFILES = @CLEANFILES@ $(TEST_APPS) *.o tests/*.o EXEEXT = @EXEEXT@ LDFLAGS_DEFAULT = @LDFLAGS_DEFAULT@ MAKE_LIB = @MAKE_LIB@ $(MERGE_OBJECTS) MAKE_SHARED_LIB = @MAKE_SHARED_LIB@ MAKE_STATIC_LIB = @MAKE_STATIC_LIB@ MAKE_STUB_LIB = @MAKE_STUB_LIB@ OBJEXT = @OBJEXT@ RANLIB = @RANLIB@ RANLIB_STUB = @RANLIB_STUB@ SHLIB_CFLAGS = @SHLIB_CFLAGS@ SHLIB_LD = @SHLIB_LD@ SHLIB_LD_LIBS = @PKG_LIBS@ @SHLIB_LD_LIBS@ @SHLIB_LD_CXX_LIBS@ STLIB_LD = @STLIB_LD@ #TCL_DEFS = @TCL_DEFS@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_SRC_DIR = @TCL_SRC_DIR@ #TK_BIN_DIR = @TK_BIN_DIR@ #TK_SRC_DIR = @TK_SRC_DIR@ # Not used, but retained for reference of what libs Tcl required #TCL_LIBS = @TCL_LIBS@ #======================================================================== # TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our # package without installing. The other environment variables allow us # to test against an uninstalled Tcl. Add special env vars that you # require for testing here (like TCLX_LIBRARY). #======================================================================== EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR) #EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR) TCLLIBPATH = $(top_builddir) TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \ @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \ PATH="$(EXTRA_PATH):$(PATH)" \ TCLLIBPATH="$(TCLLIBPATH)" # TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library` TCLSH_PROG = @TCLSH_PROG@ TCLSH = $(TCLSH_ENV) $(TCLSH_PROG) #WISH_PROG = @WISH_PROG@ #WISH = $(TCLSH_ENV) $(WISH_PROG) SHARED_BUILD = @SHARED_BUILD@ #INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@ PKG_CFLAGS = @PKG_CFLAGS@ # TCL_DEFS is not strictly need here, but if you remove it, then you # must make sure that configure.in checks for the necessary components # that your library may use. TCL_DEFS can actually be a problem if # you do not compile with a similar machine setup as the Tcl core was # compiled with. #DEFS = $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS) DEFS = @DEFS@ $(PKG_CFLAGS) CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl ${PACKAGE_NAME}Config.sh ${PACKAGE_NAME}.sh ${PACKAGE_NAME}_version.tcl CPPFLAGS = @CPPFLAGS@ LIBS = @PKG_LIBS@ @LIBS@ AR = @AR@ CFLAGS = @CFLAGS@ CXXFLAGS = @CXXFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(CXXFLAGS) #======================================================================== # Start of user-definable TARGETS section #======================================================================== #======================================================================== # TEA TARGETS. Please note that the "libraries:" target refers to platform # independent files, and the "binaries:" target inclues executable programs and # platform-dependent libraries. Modify these targets so that they install # the various pieces of your package. The make and install rules # for the BINARIES that you specified above have already been done. #======================================================================== all: binaries libraries doc tclIndex #======================================================================== # The binaries target builds executable programs, Windows .dll's, unix # shared/static libraries, and any other platform-dependent files. # The list of targets to build for "binaries:" is specified at the top # of the Makefile, in the "BINARIES" variable. #======================================================================== binaries: $(BINARIES) libraries: tclIndex: (cd $(srcdir)/library; $(TCLSH_PROG) mkIndex.tcl) # Scripts created by configure depend on their .in files and config.status # (since they are cleaned). rtd: rtd.in config.status ./config.status #======================================================================== # Your doc target should differentiate from doc builds (by the developer) # and doc installs (see install-doc), which just install the docs on the # end user machine when building from source. #======================================================================== doc: # generate man pages for itcl classes gendoc: (cd $(srcdir)/library; $(TCLSH) itcldoc [A-Z]*.tcl) # remove generated man pages cleandoc: rm -f $(srcdir)/man/[A-Z]*.mann install: all install-binaries install-libraries install-doc install-binaries: binaries install-lib-binaries install-bin-binaries #======================================================================== # This rule installs platform-independent files, such as header files. # The list=...; for p in $$list handles the empty list case x-platform. #======================================================================== install-libraries: libraries @test -d $(DESTDIR)$(pkgincludedir) || mkdir -p $(DESTDIR)$(pkgincludedir) @echo "Installing header files in $(DESTDIR)$(pkgincludedir)" @list='$(PKG_HEADERS)'; for i in $$list; do \ echo "Installing $(srcdir)/$$i" ; \ $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(pkgincludedir) ; \ done; #======================================================================== # Install documentation. Unix manpages should go in the $(mandir) # directory. #======================================================================== install-doc: #install-doc: doc # @mkdir -p $(DESTDIR)$(mandir)/mann # @echo "Installing documentation in $(DESTDIR)$(mandir)" # @list='$(srcdir)/doc/*.n'; for i in $$list; do \ # echo "Installing $$i"; \ # rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \ # $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \ # done shell: binaries libraries @$(TCLSH) $(SCRIPT) gdb: $(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT) depend: #======================================================================== # $(PKG_LIB_FILE) should be listed as part of the BINARIES variable # mentioned above. That will ensure that this target is built when you # run "make binaries". # # The $(PKG_OBJECTS) objects are created and linked into the final # library. In most cases these object files will correspond to the # source files above. #======================================================================== $(PKG_LIB_FILE): $(PKG_OBJECTS) $(MERGE_OBJECTS) -rm -f $(PKG_LIB_FILE) ${MAKE_LIB} $(RANLIB) $(PKG_LIB_FILE) #$(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS) # -rm -f $(PKG_STUB_LIB_FILE) # ${MAKE_STUB_LIB} # $(RANLIB_STUB) $(PKG_STUB_LIB_FILE) #======================================================================== # We need to enumerate the list of .c to .o lines here. # # In the following lines, $(srcdir) refers to the toplevel directory # containing your extension. If your sources are in a subdirectory, # you will have to modify the paths to reflect this: # # sample.$(OBJEXT): $(srcdir)/generic/sample.c # $(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@ # # Setting the VPATH variable to a list of paths will cause the makefile # to look into these paths when resolving .c to .obj dependencies. # As necessary, add $(srcdir):$(srcdir)/compat:.... #======================================================================== VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/rtdevt:$(srcdir)/tests .c.@OBJEXT@: $(COMPILE) -c `@CYGPATH@ $<` -o $@ .C.@OBJEXT@: $(CXXCOMPILE) -c `@CYGPATH@ $<` -o $@ #======================================================================== # End of user-definable section #======================================================================== #======================================================================== # Don't modify the file to clean here. Instead, set the "CLEANFILES" # variable in configure.in #======================================================================== clean: -test -z "$(BINARIES)" || rm -f $(BINARIES) -rm -f *.$(OBJEXT) core *.core -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean: clean -rm -f *.tab.c -rm -f $(CONFIG_CLEAN_FILES) -rm -rf config.cache config.log config.status autom4te.cache #======================================================================== # Install binary object libraries. On Windows this includes both .dll and # .lib files. Because the .lib files are not explicitly listed anywhere, # we need to deduce their existence from the .dll file of the same name. # Library files go into the lib directory. # In addition, this will generate the pkgIndex.tcl # file in the install location (assuming it can find a usable tclsh shell) # # You should not have to modify this target. #======================================================================== install-lib-binaries: binaries @test -d $(DESTDIR)$(pkglibdir) || mkdir -p $(DESTDIR)$(pkglibdir) @list='$(lib_BINARIES)'; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libdir)/$$p"; \ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libdir)/$$p; \ stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \ if test "x$$stub" = "xstub"; then \ echo " $(RANLIB_STUB) $(DESTDIR)$(libdir)/$$p"; \ $(RANLIB_STUB) $(DESTDIR)$(libdir)/$$p; \ else \ echo " $(RANLIB) $(DESTDIR)$(libdir)/$$p"; \ $(RANLIB) $(DESTDIR)$(libdir)/$$p; \ fi; \ ext=`echo $$p|sed -e "s/.*\.//"`; \ if test "x$$ext" = "xdll"; then \ lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \ if test -f $$lib; then \ echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(libdir)/$$lib"; \ $(INSTALL_DATA) $$lib $(DESTDIR)$(libdir)/$$lib; \ fi; \ fi; \ fi; \ done @echo " Install $(PACKAGE_NAME)Config.sh $(DESTDIR)$(libdir)" @$(INSTALL_DATA) $(PACKAGE_NAME)Config.sh $(DESTDIR)$(libdir); @list='$(PKG_TCL_SOURCES) library/tclIndex $(PACKAGE_NAME)_version.tcl'; \ for p in $$list; do \ if test -f $(srcdir)/$$p; then \ destp=`basename $$p`; \ echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \ fi; \ done @if test "x$(SHARED_BUILD)" = "x1"; then \ echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \ $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \ fi # (cd $(DESTDIR)$(pkglibdir); $(TCLSH_PROG) mkIndex.tcl) #======================================================================== # Install binary executables (e.g. .exe files and dependent .dll files) # This is for files that must go in the bin directory (located next to # wish and tclsh), like dependent .dll files on Windows. # # You should not have to modify this target, except to define bin_BINARIES # above if necessary. #======================================================================== install-bin-binaries: binaries @test -d $(DESTDIR)$(bindir) || mkdir -p $(DESTDIR)$(bindir) @list='$(bin_BINARIES)'; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \ fi; \ done .SUFFIXES: .c .$(OBJEXT) .C Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status uninstall-binaries: list='$(lib_BINARIES)'; for p in $$list; do \ rm -f $(DESTDIR)$(pkglibdir)/$$p; \ done list='$(PKG_TCL_SOURCES)'; for p in $$list; do \ p=`basename $$p`; \ rm -f $(DESTDIR)$(pkglibdir)/$$p; \ done list='$(bin_BINARIES)'; for p in $$list; do \ rm -f $(DESTDIR)$(bindir)/$$p; \ done .PHONY: all binaries clean depend distclean doc install libraries test # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: #======================================================================== # rtdevt targets for real-time image servers and clients #======================================================================== $(RTDEVT_LIB): $(RTDEVT_OBJ) - $(RM) $@ $(AR) r $@ $(RTDEVT_OBJ) $(RANLIB_STUB) $@ $(RTD_SERVER): $(RTD_SERVER_OBJS) $(CXXCOMPILE) -o $@ $(RTD_SERVER_OBJS) $(RTDEVT_LIB) @LIBS@ rtdClient: rtdClient.o $(CXXCOMPILE) -o $@ $? $(RTDEVT_LIB) @LIBS@ rtdCubeDisplay: rtdCubeDisplay.o $(CXXCOMPILE) -o $@ $? $(RTDEVT_LIB) @LIBS@ #======================================================================== # RTD Remote access C library #======================================================================== $(RTD_REMOTE_LIB): $(RTD_REMOTE_OBJ) - $(RM) $@ $(AR) r $@ $(RTD_REMOTE_OBJ) $(RANLIB_STUB) $@ #======================================================================== # C++ Test cases #======================================================================== test: binaries libraries $(TEST_APPS) tImageEvent: tImageEvent.o $(CXXCOMPILE) -o $@ $@.o $(RTDEVT_LIB) @LIBS@ trtdRemote: trtdRemote.o $(COMPILE) -o $@ $@.o $(RTD_REMOTE_LIB) @LIBS@ tRtd: tRtd.o tRtdEvt.o tRtdEvtData.o $(CXXCOMPILE) -o $@ $@.o tRtdEvt.o tRtdEvtData.o \ @rtd_BUILD_LIB_SPEC@ @TK_LIB_SPEC@ @TCL_LIB_SPEC@ ${LDFLAGS_DEFAULT} ${LIBS} #======================================================================== # Run Tcl test cases #======================================================================== #tcltest: binaries libraries # (cd tests; sh all.tcl) FORCE: skycat-3.1.2-starlink-1b/rtd/README000066400000000000000000000026641215713201500166160ustar00rootroot00000000000000 RTD, A Real-Time Display Widget for Tk -------------------------------------- This directory contains the source code for the ESO/VLT RTD (Real-Time Display), a Tk widget, library and application for viewing FITS images from shared memory or files. -------------------------------------- Contacts: Allan Brighton (abrighton@gemini.edu) Peter Biereichel (pbiereic@eso.org) ESO - European Southern Observatory -------------------------------------- Once installed, you can start the application with the command "rtd". There is also a simulation mode, which may be started with the command rtd -debug 1 This automatically starts the rtdServer and a simulation application, tRtd, that generates dummy images. Rtd always starts the rtdServer background process as needed when you attach a camera. For installation instructions, see the file INSTALL in the parent directory. See the CHANGES file in this directory for a list of recent changes. The following URLs may also be of interest: Skycat home page: http://archive.eso.org/skycat/ Sources and binaries: ftp://ftp.eso.org/pub/archive/skycat/README.html Postscript, PDF, and FrameMaker Documentation: ftp://ftp.eso.org/pub/archive/skycat/doc HTML Docs: http://archive.eso.org/skycat/docs/skycat-man.html -------------------------------------- Contacts: Allan Brighton (abrighto@eso.org) ESO - European Southern Observatory -------------------------------------- skycat-3.1.2-starlink-1b/rtd/VERSION000066400000000000000000000000121215713201500167670ustar00rootroot00000000000000rtd-3.2.1 skycat-3.1.2-starlink-1b/rtd/aclocal.m4000066400000000000000000000130641215713201500175720ustar00rootroot00000000000000builtin(include,../tclconfig/tcl.m4) AC_DEFUN(RTD_CONFIG, [ # ----------------------------------------------------------------------- # Load the Tclutil definitions cf=../tclutil/tclutilConfig.sh if test -f $cf ; then . $cf AC_SUBST(tclutil_VERSION) AC_SUBST(tclutil_LIB_FILE) AC_SUBST(tclutil_BUILD_LIB_SPEC) AC_SUBST(tclutil_BUILD_DIR) AC_SUBST(tclutil_LIB_SPEC) AC_SUBST(BLT_LIB_DIR) AC_SUBST(BLT_LIB_SPEC) AC_SUBST(tclutil_SRC_DIR) AC_SUBST(tclutil_PKG_OBJECTS) AC_SUBST(CFITSIO_LIB_DIR) AC_SUBST(CFITSIO_LIB_SPEC) else AC_MSG_ERROR([$cf doesn't exist]) fi # Load the Astrotcl definitions cf=../astrotcl/astrotclConfig.sh if test -f $cf ; then . $cf AC_SUBST(astrotcl_VERSION) AC_SUBST(astrotcl_LIB_FILE) AC_SUBST(astrotcl_BUILD_LIB_SPEC) AC_SUBST(astrotcl_BUILD_DIR) AC_SUBST(astrotcl_LIB_SPEC) AC_SUBST(astrotcl_SRC_DIR) AC_SUBST(astrotcl_PKG_OBJECTS) else AC_MSG_ERROR([$cf doesn't exist]) fi # ----------------------------------------------------------------------- # Optionally merge object and header files from dependent packages to make one master rtd lib MERGED=1 AC_ARG_ENABLE(merge, [AC_HELP_STRING([--enable-merge],[merge the contents of dependent packages into a master library])], [MERGED=$enableval], [MERGED=no]) tclsources=`cd $srcdir; echo library/*.tcl` changequote(<<, >>) csources=`cd $srcdir; echo generic/*.[Cc] rtdevt/rtdImageEvent.c rtdevt/rtdSem.c` changequote([, ]) rtd_headers=`cd $srcdir; echo generic/*.h generic/*.icc rtdevt/rtdImageEvent.h rtdevt/rtdSem.h` astrotcl_headers=`cd $srcdir; echo ../astrotcl/{generic,press,libwcs,cfitsio}/*.h` tclutil_headers=`cd $srcdir; echo ../tclutil/generic/*.h` rtd_includes="-I$srcdir/generic -I$srcdir/rtdevt -I$srcdir/bitmaps" astrotcl_includes="-I$srcdir/../astrotcl/generic -I$srcdir/../astrotcl/cfitsio -I$srcdir/../astrotcl/libwcs" tclutil_includes="-I$srcdir/../tclutil/generic" cincludes="${rtd_includes} ${astrotcl_includes} ${tclutil_includes}" if test $MERGED = yes ; then echo "Will build merged master rtd library" cheaders="${rtd_headers} ${astrotcl_headers} ${tclutil_headers}" MERGE_OBJECTS="$astrotcl_PKG_OBJECTS $tclutil_PKG_OBJECTS" dnl AC_DEFINE(MERGE_OBJECTS, 1, [merge the contents of dependent packages into a master library]) else echo "Not making a merged master rtd library" cheaders="${rtd_headers}" MERGE_OBJECTS="" fi AC_SUBST(MERGE_OBJECTS) # ----------------------------------------------------------------------- AC_DEFINE(USE_COMPAT_CONST, 1, [For compatibility between tcl8.4 and previous tcl releases]) # ----------------------------------------------------------------------- AC_MSG_CHECKING([sysv shared memory prototypes]) AC_EGREP_HEADER([int.*shmdt.*\(], [sys/shm.h], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no); AC_DEFINE(NEED_SHM_PROTO, 1, [Check if we need (or can use) shared memory (sysv/shm) prototypes])]) # ----------------------------------------------------------------------- AC_MSG_CHECKING([gethostname prototype]) AC_EGREP_HEADER([int.*gethostname.*\(], [unistd.h], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no); AC_DEFINE(NEED_GETHOSTNAME_PROTO, 1, [Check if we need a prototype for gethostname()])]) # ----------------------------------------------------------------------- AC_CHECK_SIZEOF(long, 4) # ----------------------------------------------------------------------- # there are some idiosyncrasies with semun defs (used in semxxx). Solaris # does not define it at all # ------------------------------------------------------------------------- AC_MSG_CHECKING("do we have union semun defined") AC_TRY_COMPILE( [#include #include #include #include ], [ union semun filler; ], [ AC_DEFINE(HAVE_UNION_SEMUN) AC_MSG_RESULT("yes") ], AC_MSG_RESULT("no") ) AC_DEFINE(HAVE_NET_SERVICES) AC_CHECK_HEADERS(sys/filio.h) # Check if we need (or can use) the socklen_t type. AC_CHECK_TYPES([socklen_t],,,[#include ]) #------------------------------------------------------------------------ AC_LANG(C++) AC_MSG_CHECKING([fd_set]) AC_TRY_COMPILE([ #include #include #include ], [fd_set readFds; select(32, &readFds, 0, 0, 0);], test_ok=yes, test_ok=no) if test $test_ok = yes; then AC_DEFINE(HAVE_SELECT_FD_SET, 1, [See if the select system call uses fd_set arguments]) fi AC_MSG_RESULT($test_ok) #------------------------------------------------------------------------ # Check if we require additional libraries to support C++ shareable # libraries. system=`uname -s`-`uname -r` SHLIB_LD_CXX_LIBS="" export SHLIB_LD_CXX_LIBS case $system in SunOS-5*) SHLIB_LD_CXX_LIBS="-lCrun -lCstd" ;; OSF*) SHLIB_LD_CXX_LIBS="-lcxx -lcxxstd" ;; esac AC_SUBST(SHLIB_LD_CXX_LIBS) #------------------------------------------------------------------------- # The cxx C++ compiler under Tru64 UNIX needs the special # CXXFLAGS "-std gnu -D__USE_STD_IOSTREAM=1". These allow the standard # library streams headers to work and to generate templates that do # not require special handling throughout skycat directories (normally # template object files are created in various cxx_repository subdirectories, # this way the object files are kept embedded the usual object files, see # the cxx man page for details). #------------------------------------------------------------------------- export CXXFLAGS case $system in OSF*) case "x$CXX" in xcxx*) CXXFLAGS="$CXXFLAGS -g3 -std gnu -D__USE_STD_IOSTREAM=1" ;; esac ;; esac ]) skycat-3.1.2-starlink-1b/rtd/bitmaps/000077500000000000000000000000001215713201500173655ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/rtd/bitmaps/README000066400000000000000000000002431215713201500202440ustar00rootroot00000000000000Be sure to run update_bitmaps.sh if you add or modify a bitmap in this directory. This will create ../generic/rtd_bitmaps.C which defines the bitmaps in C code. skycat-3.1.2-starlink-1b/rtd/bitmaps/Right.xbm000066400000000000000000000015561215713201500211610ustar00rootroot00000000000000#define Right_width 32 #define Right_height 32 static char Right_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x01, 0xf0, 0xff, 0xff, 0x03, 0xf0, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0x03, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/rtd/bitmaps/big_right.xbm000066400000000000000000000015721215713201500220400ustar00rootroot00000000000000#define big_right_width 32 #define big_right_height 32 static char big_right_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0xf0, 0xff, 0x03, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0xf0, 0xff, 0x3f, 0x00, 0xf0, 0xff, 0xff, 0x00, 0xf0, 0xff, 0xff, 0x03, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x03, 0xf0, 0xff, 0xff, 0x00, 0xf0, 0xff, 0x3f, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0xf0, 0xff, 0x03, 0x00, 0xf0, 0xff, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/rtd/bitmaps/bitmaps.tcl000066400000000000000000000016441215713201500215350ustar00rootroot00000000000000#!../bin/rtdimage_wish # # E.S.O. - VLT project # # "@(#) $Id: bitmaps.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # script to generate C code declaring X bitmaps so that the (binary) application # doesn't have to be delivered with the bitmap files. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 21 Nov 95 Created puts { /* * E.S.O. - VLT project * "@(#) $Id: bitmaps.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * Bitmap definitions for Tk * * This file was generated by ../bitmaps/bitmaps.tcl - DO NO EDIT */ #include #include } puts "void defineRtdBitmaps(Tcl_Interp *interp) {" foreach file [glob *.xbm] { set name [file rootname $file] puts " #include \"$file\"" puts " Tk_DefineBitmap(interp, Tk_GetUid(\"$name\"), (char*)${name}_bits, ${name}_width, ${name}_height);\n" } puts "}" exit 0 skycat-3.1.2-starlink-1b/rtd/bitmaps/double_left.xbm000066400000000000000000000016001215713201500223560ustar00rootroot00000000000000#define double_left_width 32 #define double_left_height 32 static char double_left_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x08, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xe0, 0x00, 0x0e, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0xf8, 0x80, 0x0f, 0x00, 0xfc, 0xc0, 0x0f, 0x00, 0xfe, 0xe0, 0x0f, 0x00, 0xff, 0xf0, 0x0f, 0x80, 0xff, 0xf8, 0x0f, 0xc0, 0xff, 0xfc, 0x0f, 0xe0, 0xff, 0xfe, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xfe, 0x0f, 0xc0, 0xff, 0xfc, 0x0f, 0x80, 0xff, 0xf8, 0x0f, 0x00, 0xff, 0xf0, 0x0f, 0x00, 0xfe, 0xe0, 0x0f, 0x00, 0xfc, 0xc0, 0x0f, 0x00, 0xf8, 0x80, 0x0f, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0xe0, 0x00, 0x0e, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/rtd/bitmaps/double_right.xbm000066400000000000000000000016031215713201500225440ustar00rootroot00000000000000#define double_right_width 32 #define double_right_height 32 static char double_right_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x30, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0xf0, 0x01, 0x1f, 0x00, 0xf0, 0x03, 0x3f, 0x00, 0xf0, 0x07, 0x7f, 0x00, 0xf0, 0x0f, 0xff, 0x00, 0xf0, 0x1f, 0xff, 0x01, 0xf0, 0x3f, 0xff, 0x03, 0xf0, 0x7f, 0xff, 0x07, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0x7f, 0xff, 0x07, 0xf0, 0x3f, 0xff, 0x03, 0xf0, 0x1f, 0xff, 0x01, 0xf0, 0x0f, 0xff, 0x00, 0xf0, 0x07, 0x7f, 0x00, 0xf0, 0x03, 0x3f, 0x00, 0xf0, 0x01, 0x1f, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x70, 0x00, 0x07, 0x00, 0x30, 0x00, 0x03, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/rtd/bitmaps/record.xbm000066400000000000000000000015611215713201500213560ustar00rootroot00000000000000#define record_width 32 #define record_height 32 static char record_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf8, 0x1f, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0xf8, 0x1f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/rtd/bitmaps/rect.xbm000066400000000000000000000015531215713201500210360ustar00rootroot00000000000000#define rect_width 32 #define rect_height 32 static char rect_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/rtd/bitmaps/update_bitmaps.sh000077500000000000000000000002051215713201500227220ustar00rootroot00000000000000#!/bin/sh # # This script updates a C source file to contain the bitmaps in this dir. tclsh bitmaps.tcl > ../generic/rtd_bitmaps.C skycat-3.1.2-starlink-1b/rtd/colormaps/000077500000000000000000000000001215713201500177255ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/rtd/colormaps/README000066400000000000000000000002461215713201500206070ustar00rootroot00000000000000Be sure to run update_colormaps.sh if you add or modify a colormap in this directory. This will create ../generic/colormaps.C which defines the colormaps in C code. skycat-3.1.2-starlink-1b/rtd/colormaps/aips0.lasc000066400000000000000000000324001215713201500216040ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.47451 0.00000 0.60784 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.37255 0.65490 0.92549 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.69412 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/backgr.lasc000066400000000000000000000324001215713201500220210ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.01587 0.01587 0.01587 0.03174 0.03174 0.03174 0.04761 0.04761 0.04761 0.06348 0.06348 0.06348 0.07935 0.07935 0.07935 0.09522 0.09522 0.09522 0.11109 0.11109 0.11109 0.12696 0.12696 0.12696 0.14283 0.14283 0.14283 0.15870 0.15870 0.15870 0.17457 0.17457 0.17457 0.19044 0.19044 0.19044 0.20631 0.20631 0.20631 0.22218 0.22218 0.22218 0.23805 0.23805 0.23805 0.25392 0.25392 0.25392 0.26979 0.26979 0.26979 0.28566 0.28566 0.28566 0.30153 0.30153 0.30153 0.31740 0.31740 0.31740 0.33327 0.33327 0.33327 0.34914 0.34914 0.34914 0.36501 0.36501 0.36501 0.38088 0.38088 0.38088 0.39675 0.39675 0.39675 0.41262 0.41262 0.41262 0.42849 0.42849 0.42849 0.44436 0.44436 0.44436 0.46023 0.46023 0.46023 0.47610 0.47610 0.47610 0.49197 0.49197 0.49197 0.50784 0.50784 0.50784 0.52371 0.52371 0.52371 0.53958 0.53958 0.53958 0.55545 0.55545 0.55545 0.57132 0.57132 0.57132 0.58719 0.58719 0.58719 0.60306 0.60306 0.60306 0.61893 0.61893 0.61893 0.63480 0.63480 0.63480 0.65067 0.65067 0.65067 0.66654 0.66654 0.66654 0.68241 0.68241 0.68241 0.69828 0.69828 0.69828 0.71415 0.71415 0.71415 0.73002 0.73002 0.73002 0.74589 0.74589 0.74589 0.76176 0.76176 0.76176 0.77763 0.77763 0.77763 0.79350 0.79350 0.79350 0.80937 0.80937 0.80937 0.82524 0.82524 0.82524 0.84111 0.84111 0.84111 0.85698 0.85698 0.85698 0.87285 0.87285 0.87285 0.88872 0.88872 0.88872 0.90459 0.90459 0.90459 0.92046 0.92046 0.92046 0.93633 0.93633 0.93633 0.95220 0.95220 0.95220 0.96807 0.96807 0.96807 0.98394 0.98394 0.98394 0.99981 0.99981 0.99981 0.00000 0.00000 0.99981 0.00000 0.01587 0.98394 0.00000 0.03174 0.96807 0.00000 0.04761 0.95220 0.00000 0.06348 0.93633 0.00000 0.07935 0.92046 0.00000 0.09522 0.90459 0.00000 0.11109 0.88872 0.00000 0.12696 0.87285 0.00000 0.14283 0.85698 0.00000 0.15870 0.84111 0.00000 0.17457 0.82524 0.00000 0.19044 0.80937 0.00000 0.20631 0.79350 0.00000 0.22218 0.77763 0.00000 0.23805 0.76176 0.00000 0.25392 0.74589 0.00000 0.26979 0.73002 0.00000 0.28566 0.71415 0.00000 0.30153 0.69828 0.00000 0.31740 0.68241 0.00000 0.33327 0.66654 0.00000 0.34914 0.65067 0.00000 0.36501 0.63480 0.00000 0.38088 0.61893 0.00000 0.39675 0.60306 0.00000 0.41262 0.58719 0.00000 0.42849 0.57132 0.00000 0.44436 0.55545 0.00000 0.46023 0.53958 0.00000 0.47610 0.52371 0.00000 0.49197 0.50784 0.00000 0.50784 0.49197 0.00000 0.52371 0.47610 0.00000 0.53958 0.46023 0.00000 0.55545 0.44436 0.00000 0.57132 0.42849 0.00000 0.58719 0.41262 0.00000 0.60306 0.39675 0.00000 0.61893 0.38088 0.00000 0.63480 0.36501 0.00000 0.65067 0.34914 0.00000 0.66654 0.33327 0.00000 0.68241 0.31740 0.00000 0.69828 0.30153 0.00000 0.71415 0.28566 0.00000 0.73002 0.26979 0.00000 0.74589 0.25392 0.00000 0.76176 0.23805 0.00000 0.77763 0.22218 0.00000 0.79350 0.20631 0.00000 0.80937 0.19044 0.00000 0.82524 0.17457 0.00000 0.84111 0.15870 0.00000 0.85698 0.14283 0.00000 0.87285 0.12696 0.00000 0.88872 0.11109 0.00000 0.90459 0.09522 0.00000 0.92046 0.07935 0.00000 0.93633 0.06348 0.00000 0.95220 0.04761 0.00000 0.96807 0.03174 0.00000 0.98394 0.01587 0.00000 0.99981 0.00000 0.00000 1.00000 0.00000 0.01587 1.00000 0.00000 0.03174 1.00000 0.00000 0.04761 1.00000 0.00000 0.06348 1.00000 0.00000 0.07935 1.00000 0.00000 0.09522 1.00000 0.00000 0.11109 1.00000 0.00000 0.12696 1.00000 0.00000 0.14283 1.00000 0.00000 0.15870 1.00000 0.00000 0.17457 1.00000 0.00000 0.19044 1.00000 0.00000 0.20631 1.00000 0.00000 0.22218 1.00000 0.00000 0.23805 1.00000 0.00000 0.25392 1.00000 0.00000 0.26979 1.00000 0.00000 0.28566 1.00000 0.00000 0.30153 1.00000 0.00000 0.31740 1.00000 0.00000 0.33327 1.00000 0.00000 0.34914 1.00000 0.00000 0.36501 1.00000 0.00000 0.38088 1.00000 0.00000 0.39675 1.00000 0.00000 0.41262 1.00000 0.00000 0.42849 1.00000 0.00000 0.44436 1.00000 0.00000 0.46023 1.00000 0.00000 0.47610 1.00000 0.00000 0.49197 1.00000 0.00000 0.50784 1.00000 0.00000 0.52371 1.00000 0.00000 0.53958 1.00000 0.00000 0.55545 1.00000 0.00000 0.57132 1.00000 0.00000 0.58719 1.00000 0.00000 0.60306 1.00000 0.00000 0.61893 1.00000 0.00000 0.63480 1.00000 0.00000 0.65067 1.00000 0.00000 0.66654 1.00000 0.00000 0.68241 1.00000 0.00000 0.69828 1.00000 0.00000 0.71415 1.00000 0.00000 0.73002 1.00000 0.00000 0.74589 1.00000 0.00000 0.76176 1.00000 0.00000 0.77763 1.00000 0.00000 0.79350 1.00000 0.00000 0.80937 1.00000 0.00000 0.82524 1.00000 0.00000 0.84111 1.00000 0.00000 0.85698 1.00000 0.00000 0.87285 1.00000 0.00000 0.88872 1.00000 0.00000 0.90459 1.00000 0.00000 0.92046 1.00000 0.00000 0.93633 1.00000 0.00000 0.95220 1.00000 0.00000 0.96807 1.00000 0.00000 0.98394 1.00000 0.00000 0.99981 1.00000 0.00000 1.00000 0.99981 0.00000 1.00000 0.98394 0.00000 1.00000 0.96807 0.00000 1.00000 0.95220 0.00000 1.00000 0.93633 0.00000 1.00000 0.92046 0.00000 1.00000 0.90459 0.00000 1.00000 0.88872 0.00000 1.00000 0.87285 0.00000 1.00000 0.85698 0.00000 1.00000 0.84111 0.00000 1.00000 0.82524 0.00000 1.00000 0.80937 0.00000 1.00000 0.79350 0.00000 1.00000 0.77763 0.00000 1.00000 0.76176 0.00000 1.00000 0.74589 0.00000 1.00000 0.73002 0.00000 1.00000 0.71415 0.00000 1.00000 0.69828 0.00000 1.00000 0.68241 0.00000 1.00000 0.66654 0.00000 1.00000 0.65067 0.00000 1.00000 0.63480 0.00000 1.00000 0.61893 0.00000 1.00000 0.60306 0.00000 1.00000 0.58719 0.00000 1.00000 0.57132 0.00000 1.00000 0.55545 0.00000 1.00000 0.53958 0.00000 1.00000 0.52371 0.00000 1.00000 0.50784 0.00000 1.00000 0.49197 0.00000 1.00000 0.47610 0.00000 1.00000 0.46023 0.00000 1.00000 0.44436 0.00000 1.00000 0.42849 0.00000 1.00000 0.41262 0.00000 1.00000 0.39675 0.00000 1.00000 0.38088 0.00000 1.00000 0.36501 0.00000 1.00000 0.34914 0.00000 1.00000 0.33327 0.00000 1.00000 0.31740 0.00000 1.00000 0.30153 0.00000 1.00000 0.28566 0.00000 1.00000 0.26979 0.00000 1.00000 0.25392 0.00000 1.00000 0.23805 0.00000 1.00000 0.22218 0.00000 1.00000 0.20631 0.00000 1.00000 0.19044 0.00000 1.00000 0.17457 0.00000 1.00000 0.15870 0.00000 1.00000 0.14283 0.00000 1.00000 0.12696 0.00000 1.00000 0.11109 0.00000 1.00000 0.09522 0.00000 1.00000 0.07935 0.00000 1.00000 0.06348 0.00000 1.00000 0.04761 0.00000 1.00000 0.03174 0.00000 1.00000 0.01587 0.00000 1.00000 0.00000 0.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/blue.lasc000066400000000000000000000324001215713201500215170ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00392 0.00000 0.00000 0.00784 0.00000 0.00000 0.01176 0.00000 0.00000 0.01569 0.00000 0.00000 0.01961 0.00000 0.00000 0.02353 0.00000 0.00000 0.02745 0.00000 0.00000 0.03137 0.00000 0.00000 0.03529 0.00000 0.00000 0.03922 0.00000 0.00000 0.04314 0.00000 0.00000 0.04706 0.00000 0.00000 0.05098 0.00000 0.00000 0.05490 0.00000 0.00000 0.05882 0.00000 0.00000 0.06275 0.00000 0.00000 0.06667 0.00000 0.00000 0.07059 0.00000 0.00000 0.07451 0.00000 0.00000 0.07843 0.00000 0.00000 0.08235 0.00000 0.00000 0.08627 0.00000 0.00000 0.09020 0.00000 0.00000 0.09412 0.00000 0.00000 0.09804 0.00000 0.00000 0.10196 0.00000 0.00000 0.10588 0.00000 0.00000 0.10980 0.00000 0.00000 0.11373 0.00000 0.00000 0.11765 0.00000 0.00000 0.12157 0.00000 0.00000 0.12549 0.00000 0.00000 0.12941 0.00000 0.00000 0.13333 0.00000 0.00000 0.13725 0.00000 0.00000 0.14118 0.00000 0.00000 0.14510 0.00000 0.00000 0.14902 0.00000 0.00000 0.15294 0.00000 0.00000 0.15686 0.00000 0.00000 0.16078 0.00000 0.00000 0.16471 0.00000 0.00000 0.16863 0.00000 0.00000 0.17255 0.00000 0.00000 0.17647 0.00000 0.00000 0.18039 0.00000 0.00000 0.18431 0.00000 0.00000 0.18824 0.00000 0.00000 0.19216 0.00000 0.00000 0.19608 0.00000 0.00000 0.20000 0.00000 0.00000 0.20392 0.00000 0.00000 0.20784 0.00000 0.00000 0.21176 0.00000 0.00000 0.21569 0.00000 0.00000 0.21961 0.00000 0.00000 0.22353 0.00000 0.00000 0.22745 0.00000 0.00000 0.23137 0.00000 0.00000 0.23529 0.00000 0.00000 0.23922 0.00000 0.00000 0.24314 0.00000 0.00000 0.24706 0.00000 0.00000 0.25098 0.00000 0.00000 0.25490 0.00000 0.00000 0.25882 0.00000 0.00000 0.26275 0.00000 0.00000 0.26667 0.00000 0.00000 0.27059 0.00000 0.00000 0.27451 0.00000 0.00000 0.27843 0.00000 0.00000 0.28235 0.00000 0.00000 0.28627 0.00000 0.00000 0.29020 0.00000 0.00000 0.29412 0.00000 0.00000 0.29804 0.00000 0.00000 0.30196 0.00000 0.00000 0.30588 0.00000 0.00000 0.30980 0.00000 0.00000 0.31373 0.00000 0.00000 0.31765 0.00000 0.00000 0.32157 0.00000 0.00000 0.32549 0.00000 0.00000 0.32941 0.00000 0.00000 0.33333 0.00000 0.00000 0.33725 0.00000 0.00000 0.34118 0.00000 0.00000 0.34510 0.00000 0.00000 0.34902 0.00000 0.00000 0.35294 0.00000 0.00000 0.35686 0.00000 0.00000 0.36078 0.00000 0.00000 0.36471 0.00000 0.00000 0.36863 0.00000 0.00000 0.37255 0.00000 0.00000 0.37647 0.00000 0.00000 0.38039 0.00000 0.00000 0.38431 0.00000 0.00000 0.38824 0.00000 0.00000 0.39216 0.00000 0.00000 0.39608 0.00000 0.00000 0.40000 0.00000 0.00000 0.40392 0.00000 0.00000 0.40784 0.00000 0.00000 0.41176 0.00000 0.00000 0.41569 0.00000 0.00000 0.41961 0.00000 0.00000 0.42353 0.00000 0.00000 0.42745 0.00000 0.00000 0.43137 0.00000 0.00000 0.43529 0.00000 0.00000 0.43922 0.00000 0.00000 0.44314 0.00000 0.00000 0.44706 0.00000 0.00000 0.45098 0.00000 0.00000 0.45490 0.00000 0.00000 0.45882 0.00000 0.00000 0.46275 0.00000 0.00000 0.46667 0.00000 0.00000 0.47059 0.00000 0.00000 0.47451 0.00000 0.00000 0.47843 0.00000 0.00000 0.48235 0.00000 0.00000 0.48627 0.00000 0.00000 0.49020 0.00000 0.00000 0.49412 0.00000 0.00000 0.49804 0.00000 0.00000 0.50196 0.00000 0.00000 0.50588 0.00000 0.00000 0.50980 0.00000 0.00000 0.51373 0.00000 0.00000 0.51765 0.00000 0.00000 0.52157 0.00000 0.00000 0.52549 0.00000 0.00000 0.52941 0.00000 0.00000 0.53333 0.00000 0.00000 0.53725 0.00000 0.00000 0.54118 0.00000 0.00000 0.54510 0.00000 0.00000 0.54902 0.00000 0.00000 0.55294 0.00000 0.00000 0.55686 0.00000 0.00000 0.56078 0.00000 0.00000 0.56471 0.00000 0.00000 0.56863 0.00000 0.00000 0.57255 0.00000 0.00000 0.57647 0.00000 0.00000 0.58039 0.00000 0.00000 0.58431 0.00000 0.00000 0.58824 0.00000 0.00000 0.59216 0.00000 0.00000 0.59608 0.00000 0.00000 0.60000 0.00000 0.00000 0.60392 0.00000 0.00000 0.60784 0.00000 0.00000 0.61176 0.00000 0.00000 0.61569 0.00000 0.00000 0.61961 0.00000 0.00000 0.62353 0.00000 0.00000 0.62745 0.00000 0.00000 0.63137 0.00000 0.00000 0.63529 0.00000 0.00000 0.63922 0.00000 0.00000 0.64314 0.00000 0.00000 0.64706 0.00000 0.00000 0.65098 0.00000 0.00000 0.65490 0.00000 0.00000 0.65882 0.00000 0.00000 0.66275 0.00000 0.00000 0.66667 0.00000 0.00000 0.67059 0.00000 0.00000 0.67451 0.00000 0.00000 0.67843 0.00000 0.00000 0.68235 0.00000 0.00000 0.68627 0.00000 0.00000 0.69020 0.00000 0.00000 0.69412 0.00000 0.00000 0.69804 0.00000 0.00000 0.70196 0.00000 0.00000 0.70588 0.00000 0.00000 0.70980 0.00000 0.00000 0.71373 0.00000 0.00000 0.71765 0.00000 0.00000 0.72157 0.00000 0.00000 0.72549 0.00000 0.00000 0.72941 0.00000 0.00000 0.73333 0.00000 0.00000 0.73725 0.00000 0.00000 0.74118 0.00000 0.00000 0.74510 0.00000 0.00000 0.74902 0.00000 0.00000 0.75294 0.00000 0.00000 0.75686 0.00000 0.00000 0.76078 0.00000 0.00000 0.76471 0.00000 0.00000 0.76863 0.00000 0.00000 0.77255 0.00000 0.00000 0.77647 0.00000 0.00000 0.78039 0.00000 0.00000 0.78431 0.00000 0.00000 0.78824 0.00000 0.00000 0.79216 0.00000 0.00000 0.79608 0.00000 0.00000 0.80000 0.00000 0.00000 0.80392 0.00000 0.00000 0.80784 0.00000 0.00000 0.81176 0.00000 0.00000 0.81569 0.00000 0.00000 0.81961 0.00000 0.00000 0.82353 0.00000 0.00000 0.82745 0.00000 0.00000 0.83137 0.00000 0.00000 0.83529 0.00000 0.00000 0.83922 0.00000 0.00000 0.84314 0.00000 0.00000 0.84706 0.00000 0.00000 0.85098 0.00000 0.00000 0.85490 0.00000 0.00000 0.85882 0.00000 0.00000 0.86275 0.00000 0.00000 0.86667 0.00000 0.00000 0.87059 0.00000 0.00000 0.87451 0.00000 0.00000 0.87843 0.00000 0.00000 0.88235 0.00000 0.00000 0.88627 0.00000 0.00000 0.89020 0.00000 0.00000 0.89412 0.00000 0.00000 0.89804 0.00000 0.00000 0.90196 0.00000 0.00000 0.90588 0.00000 0.00000 0.90980 0.00000 0.00000 0.91373 0.00000 0.00000 0.91765 0.00000 0.00000 0.92157 0.00000 0.00000 0.92549 0.00000 0.00000 0.92941 0.00000 0.00000 0.93333 0.00000 0.00000 0.93725 0.00000 0.00000 0.94118 0.00000 0.00000 0.94510 0.00000 0.00000 0.94902 0.00000 0.00000 0.95294 0.00000 0.00000 0.95686 0.00000 0.00000 0.96078 0.00000 0.00000 0.96471 0.00000 0.00000 0.96863 0.00000 0.00000 0.97255 0.00000 0.00000 0.97647 0.00000 0.00000 0.98039 0.00000 0.00000 0.98431 0.00000 0.00000 0.98824 0.00000 0.00000 0.99216 0.00000 0.00000 0.99608 0.00000 0.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/blulut.lasc000066400000000000000000000324001215713201500220770ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00392 0.00000 0.00000 0.00784 0.00000 0.00000 0.01176 0.00000 0.00000 0.01569 0.00000 0.00000 0.01961 0.00000 0.00000 0.02353 0.00000 0.00000 0.02745 0.00000 0.00000 0.03137 0.00000 0.00000 0.03529 0.00000 0.00000 0.03922 0.00000 0.00000 0.04314 0.00000 0.00000 0.04706 0.00001 0.00001 0.05098 0.00001 0.00001 0.05490 0.00001 0.00001 0.05882 0.00002 0.00002 0.06275 0.00002 0.00002 0.06667 0.00002 0.00002 0.07059 0.00003 0.00003 0.07451 0.00004 0.00004 0.07843 0.00005 0.00005 0.08235 0.00006 0.00006 0.08627 0.00007 0.00007 0.09020 0.00008 0.00008 0.09412 0.00009 0.00009 0.09804 0.00011 0.00011 0.10196 0.00013 0.00013 0.10588 0.00015 0.00015 0.10980 0.00017 0.00017 0.11373 0.00019 0.00019 0.11765 0.00022 0.00022 0.12157 0.00025 0.00025 0.12549 0.00028 0.00028 0.12941 0.00032 0.00032 0.13333 0.00035 0.00035 0.13725 0.00040 0.00040 0.14118 0.00044 0.00044 0.14510 0.00049 0.00049 0.14902 0.00055 0.00055 0.15294 0.00061 0.00061 0.15686 0.00067 0.00067 0.16078 0.00074 0.00074 0.16471 0.00081 0.00081 0.16863 0.00089 0.00089 0.17255 0.00097 0.00097 0.17647 0.00106 0.00106 0.18039 0.00115 0.00115 0.18431 0.00126 0.00126 0.18824 0.00136 0.00136 0.19216 0.00148 0.00148 0.19608 0.00160 0.00160 0.20000 0.00173 0.00173 0.20392 0.00187 0.00187 0.20784 0.00201 0.00201 0.21176 0.00216 0.00216 0.21569 0.00233 0.00233 0.21961 0.00250 0.00250 0.22353 0.00268 0.00268 0.22745 0.00287 0.00287 0.23137 0.00307 0.00307 0.23529 0.00327 0.00327 0.23922 0.00349 0.00349 0.24314 0.00373 0.00373 0.24706 0.00397 0.00397 0.25098 0.00422 0.00422 0.25490 0.00449 0.00449 0.25882 0.00477 0.00477 0.26275 0.00506 0.00506 0.26667 0.00536 0.00536 0.27059 0.00568 0.00568 0.27451 0.00601 0.00601 0.27843 0.00636 0.00636 0.28235 0.00672 0.00672 0.28627 0.00709 0.00709 0.29020 0.00748 0.00748 0.29412 0.00789 0.00789 0.29804 0.00831 0.00831 0.30196 0.00875 0.00875 0.30588 0.00921 0.00921 0.30980 0.00969 0.00969 0.31373 0.01018 0.01018 0.31765 0.01069 0.01069 0.32157 0.01122 0.01122 0.32549 0.01177 0.01177 0.32941 0.01235 0.01235 0.33333 0.01294 0.01294 0.33725 0.01355 0.01355 0.34118 0.01418 0.01418 0.34510 0.01484 0.01484 0.34902 0.01552 0.01552 0.35294 0.01622 0.01622 0.35686 0.01694 0.01694 0.36078 0.01769 0.01769 0.36471 0.01847 0.01847 0.36863 0.01926 0.01926 0.37255 0.02009 0.02009 0.37647 0.02094 0.02094 0.38039 0.02181 0.02181 0.38431 0.02272 0.02272 0.38824 0.02365 0.02365 0.39216 0.02461 0.02461 0.39608 0.02560 0.02560 0.40000 0.02662 0.02662 0.40392 0.02767 0.02767 0.40784 0.02875 0.02875 0.41176 0.02986 0.02986 0.41569 0.03100 0.03100 0.41961 0.03218 0.03218 0.42353 0.03338 0.03338 0.42745 0.03463 0.03463 0.43137 0.03590 0.03590 0.43529 0.03721 0.03721 0.43922 0.03856 0.03856 0.44314 0.03994 0.03994 0.44706 0.04136 0.04136 0.45098 0.04282 0.04282 0.45490 0.04432 0.04432 0.45882 0.04585 0.04585 0.46275 0.04743 0.04743 0.46667 0.04904 0.04904 0.47059 0.05070 0.05070 0.47451 0.05239 0.05239 0.47843 0.05413 0.05413 0.48235 0.05591 0.05591 0.48627 0.05774 0.05774 0.49020 0.05961 0.05961 0.49412 0.06153 0.06153 0.49804 0.06349 0.06349 0.50196 0.06549 0.06549 0.50588 0.06755 0.06755 0.50980 0.06965 0.06965 0.51373 0.07180 0.07180 0.51765 0.07400 0.07400 0.52157 0.07625 0.07625 0.52549 0.07856 0.07856 0.52941 0.08091 0.08091 0.53333 0.08331 0.08331 0.53725 0.08577 0.08577 0.54118 0.08829 0.08829 0.54510 0.09086 0.09086 0.54902 0.09348 0.09348 0.55294 0.09616 0.09616 0.55686 0.09890 0.09890 0.56078 0.10169 0.10169 0.56471 0.10455 0.10455 0.56863 0.10746 0.10746 0.57255 0.11044 0.11044 0.57647 0.11347 0.11347 0.58039 0.11657 0.11657 0.58431 0.11973 0.11973 0.58824 0.12296 0.12296 0.59216 0.12624 0.12624 0.59608 0.12960 0.12960 0.60000 0.13302 0.13302 0.60392 0.13651 0.13651 0.60784 0.14007 0.14007 0.61176 0.14369 0.14369 0.61569 0.14739 0.14739 0.61961 0.15116 0.15116 0.62353 0.15500 0.15500 0.62745 0.15891 0.15891 0.63137 0.16289 0.16289 0.63529 0.16695 0.16695 0.63922 0.17109 0.17109 0.64314 0.17530 0.17530 0.64706 0.17959 0.17959 0.65098 0.18395 0.18395 0.65490 0.18840 0.18840 0.65882 0.19292 0.19292 0.66275 0.19753 0.19753 0.66667 0.20222 0.20222 0.67059 0.20699 0.20699 0.67451 0.21185 0.21185 0.67843 0.21679 0.21679 0.68235 0.22182 0.22182 0.68627 0.22693 0.22693 0.69020 0.23213 0.23213 0.69412 0.23742 0.23742 0.69804 0.24280 0.24280 0.70196 0.24827 0.24827 0.70588 0.25384 0.25384 0.70980 0.25949 0.25949 0.71373 0.26524 0.26524 0.71765 0.27109 0.27109 0.72157 0.27703 0.27703 0.72549 0.28307 0.28307 0.72941 0.28920 0.28920 0.73333 0.29544 0.29544 0.73725 0.30178 0.30178 0.74118 0.30821 0.30821 0.74510 0.31476 0.31476 0.74902 0.32140 0.32140 0.75294 0.32815 0.32815 0.75686 0.33500 0.33500 0.76078 0.34196 0.34196 0.76471 0.34903 0.34903 0.76863 0.35621 0.35621 0.77255 0.36350 0.36350 0.77647 0.37090 0.37090 0.78039 0.37841 0.37841 0.78431 0.38603 0.38603 0.78824 0.39377 0.39377 0.79216 0.40163 0.40163 0.79608 0.40960 0.40960 0.80000 0.41769 0.41769 0.80392 0.42590 0.42590 0.80784 0.43423 0.43423 0.81176 0.44268 0.44268 0.81569 0.45126 0.45126 0.81961 0.45996 0.45996 0.82353 0.46878 0.46878 0.82745 0.47773 0.47773 0.83137 0.48681 0.48681 0.83529 0.49601 0.49601 0.83922 0.50535 0.50535 0.84314 0.51482 0.51482 0.84706 0.52442 0.52442 0.85098 0.53415 0.53415 0.85490 0.54402 0.54402 0.85882 0.55403 0.55403 0.86275 0.56417 0.56417 0.86667 0.57445 0.57445 0.87059 0.58487 0.58487 0.87451 0.59543 0.59543 0.87843 0.60613 0.60613 0.88235 0.61698 0.61698 0.88627 0.62798 0.62798 0.89020 0.63911 0.63911 0.89412 0.65040 0.65040 0.89804 0.66184 0.66184 0.90196 0.67342 0.67342 0.90588 0.68516 0.68516 0.90980 0.69705 0.69705 0.91373 0.70909 0.70909 0.91765 0.72129 0.72129 0.92157 0.73365 0.73365 0.92549 0.74616 0.74616 0.92941 0.75883 0.75883 0.93333 0.77167 0.77167 0.93725 0.78466 0.78466 0.94118 0.79782 0.79782 0.94510 0.81115 0.81115 0.94902 0.82464 0.82464 0.95294 0.83830 0.83830 0.95686 0.85213 0.85213 0.96078 0.86612 0.86612 0.96471 0.88029 0.88029 0.96863 0.89464 0.89464 0.97255 0.90915 0.90915 0.97647 0.92385 0.92385 0.98039 0.93872 0.93872 0.98431 0.95377 0.95377 0.98824 0.96899 0.96899 0.99216 0.98441 0.98441 0.99608 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/color.lasc000066400000000000000000000324001215713201500217060ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.00000 0.18431 0.93725 0.00000 0.18431 0.93725 0.00000 0.18431 0.93725 0.00000 0.18431 0.93725 0.00000 0.18431 0.93725 0.00000 0.18431 0.93725 0.00000 0.18431 0.93725 0.00000 0.18431 0.93725 0.00000 0.18431 0.93725 0.00000 0.18431 0.93725 0.00000 0.18431 0.93725 0.00000 0.18431 0.93725 0.00000 0.18431 0.93725 0.00000 0.18431 0.93725 0.00000 0.18431 0.93725 0.00000 0.18431 0.93725 0.00000 0.37255 0.74902 0.00000 0.37255 0.74902 0.00000 0.37255 0.74902 0.00000 0.37255 0.74902 0.00000 0.37255 0.74902 0.00000 0.37255 0.74902 0.00000 0.37255 0.74902 0.00000 0.37255 0.74902 0.00000 0.37255 0.74902 0.00000 0.37255 0.74902 0.00000 0.37255 0.74902 0.00000 0.37255 0.74902 0.00000 0.37255 0.74902 0.00000 0.37255 0.74902 0.00000 0.37255 0.74902 0.00000 0.37255 0.74902 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.74902 0.30980 0.00000 0.74902 0.30980 0.00000 0.74902 0.30980 0.00000 0.74902 0.30980 0.00000 0.74902 0.30980 0.00000 0.74902 0.30980 0.00000 0.74902 0.30980 0.00000 0.74902 0.30980 0.00000 0.74902 0.30980 0.00000 0.74902 0.30980 0.00000 0.74902 0.30980 0.00000 0.74902 0.30980 0.00000 0.74902 0.30980 0.00000 0.74902 0.30980 0.00000 0.74902 0.30980 0.00000 0.74902 0.30980 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.30980 0.62353 0.00000 0.30980 0.62353 0.00000 0.30980 0.62353 0.00000 0.30980 0.62353 0.00000 0.30980 0.62353 0.00000 0.30980 0.62353 0.00000 0.30980 0.62353 0.00000 0.30980 0.62353 0.00000 0.30980 0.62353 0.00000 0.30980 0.62353 0.00000 0.30980 0.62353 0.00000 0.30980 0.62353 0.00000 0.30980 0.62353 0.00000 0.30980 0.62353 0.00000 0.30980 0.62353 0.00000 0.30980 0.62353 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.49804 0.49804 0.00000 0.62353 0.30980 0.00000 0.62353 0.30980 0.00000 0.62353 0.30980 0.00000 0.62353 0.30980 0.00000 0.62353 0.30980 0.00000 0.62353 0.30980 0.00000 0.62353 0.30980 0.00000 0.62353 0.30980 0.00000 0.62353 0.30980 0.00000 0.62353 0.30980 0.00000 0.62353 0.30980 0.00000 0.62353 0.30980 0.00000 0.62353 0.30980 0.00000 0.62353 0.30980 0.00000 0.62353 0.30980 0.00000 0.62353 0.30980 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.93725 0.00000 0.00000 0.74902 0.00000 0.30980 0.74902 0.00000 0.30980 0.74902 0.00000 0.30980 0.74902 0.00000 0.30980 0.74902 0.00000 0.30980 0.74902 0.00000 0.30980 0.74902 0.00000 0.30980 0.74902 0.00000 0.30980 0.74902 0.00000 0.30980 0.74902 0.00000 0.30980 0.74902 0.00000 0.30980 0.74902 0.00000 0.30980 0.74902 0.00000 0.30980 0.74902 0.00000 0.30980 0.74902 0.00000 0.30980 0.74902 0.00000 0.30980 skycat-3.1.2-starlink-1b/rtd/colormaps/colormaps.tcl000066400000000000000000000027341215713201500224360ustar00rootroot00000000000000#!../bin/rtdimage_wish # # E.S.O. - VLT project # # "@(#) $Id: colormaps.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # script to generate C code including static colormaps, so that the , # (binary) application doesn't have to be delivered with the colormap files. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 19 Nov 97 Created # pbiereic 31/01/05 Fixed: too many open files puts { /* * E.S.O. - VLT project * "@(#) $Id: colormaps.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * Colormap definitions for RTD * * This file was generated by ../colormaps/colormaps.tcl - DO NO EDIT */ #include #include } puts "void defineColormaps() {" # colormaps foreach file [glob *.lasc] { set fd [open $file] set name [file tail $file] set root [file rootname $name] set ar ${root}_lasc puts "\tstatic RGBColor $ar\[\] = {" while {[gets $fd line] != -1} { puts "\t\t{[join $line {, }]}," } puts "\t};" puts "\tnew ColorMapInfo((char *)\"$name\", $ar);\n" close $fd } # itts foreach file [glob *.iasc] { set fd [open $file] set name [file tail $file] set root [file rootname $name] set ar ${root}_iasc puts "\tstatic double $ar\[\] = {" while {[gets $fd line] != -1} { puts "\t\t[lindex $line 0]," } puts "\t};" puts "\tnew ITTInfo((char *)\"$name\", $ar);\n" close $fd } puts "}" exit 0 skycat-3.1.2-starlink-1b/rtd/colormaps/equa.iasc000066400000000000000000000154001215713201500215210ustar00rootroot00000000000000 0.06275 0.13725 0.22353 0.30196 0.36078 0.41176 0.46275 0.50588 0.54510 0.57647 0.60392 0.62745 0.64706 0.66275 0.68235 0.69412 0.70588 0.71765 0.72941 0.73725 0.74510 0.75686 0.76471 0.76863 0.77647 0.78039 0.78824 0.79216 0.79608 0.80000 0.80392 0.80784 0.81176 0.81569 0.81961 0.82353 0.82745 0.83137 0.83529 0.83922 0.84314 0.84314 0.84706 0.85098 0.85490 0.85882 0.85882 0.86275 0.86667 0.86667 0.87059 0.87451 0.87451 0.87843 0.87843 0.88235 0.88235 0.88627 0.88627 0.89020 0.89020 0.89412 0.89412 0.89804 0.89804 0.90196 0.90196 0.90588 0.90588 0.90980 0.90980 0.91373 0.91373 0.91765 0.91765 0.92157 0.92157 0.92549 0.92549 0.92941 0.92941 0.93333 0.93333 0.93725 0.93725 0.93725 0.94118 0.94118 0.94510 0.94510 0.94510 0.94902 0.94902 0.95294 0.95294 0.95294 0.95686 0.95686 0.95686 0.96078 0.96078 0.96078 0.96471 0.96471 0.96471 0.96471 0.96863 0.96863 0.96863 0.96863 0.97255 0.97255 0.97255 0.97255 0.97255 0.97255 0.97647 0.97647 0.97647 0.97647 0.97647 0.97647 0.98039 0.98039 0.98039 0.98039 0.98039 0.98039 0.98039 0.98039 0.98039 0.98039 0.98431 0.98431 0.98431 0.98431 0.98431 0.98431 0.98431 0.98431 0.98431 0.98431 0.98431 0.98824 0.98824 0.98824 0.98824 0.98824 0.98824 0.98824 0.98824 0.98824 0.98824 0.98824 0.98824 0.98824 0.98824 0.98824 0.98824 0.98824 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99216 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 0.99608 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/expo.iasc000066400000000000000000000154001215713201500215410ustar00rootroot00000000000000 0.00458 0.00689 0.00920 0.01152 0.01386 0.01620 0.01855 0.02091 0.02328 0.02565 0.02804 0.03044 0.03285 0.03526 0.03769 0.04012 0.04257 0.04502 0.04748 0.04996 0.05244 0.05493 0.05743 0.05995 0.06247 0.06500 0.06754 0.07010 0.07266 0.07523 0.07781 0.08041 0.08301 0.08562 0.08824 0.09088 0.09352 0.09618 0.09884 0.10152 0.10420 0.10690 0.10960 0.11232 0.11505 0.11779 0.12054 0.12330 0.12607 0.12885 0.13164 0.13445 0.13726 0.14009 0.14293 0.14578 0.14863 0.15151 0.15439 0.15728 0.16019 0.16310 0.16603 0.16897 0.17192 0.17488 0.17786 0.18084 0.18384 0.18685 0.18987 0.19290 0.19595 0.19900 0.20207 0.20515 0.20824 0.21135 0.21447 0.21760 0.22074 0.22389 0.22706 0.23024 0.23343 0.23663 0.23985 0.24308 0.24632 0.24957 0.25284 0.25612 0.25942 0.26272 0.26604 0.26937 0.27272 0.27608 0.27945 0.28283 0.28623 0.28964 0.29307 0.29651 0.29996 0.30342 0.30690 0.31039 0.31390 0.31742 0.32095 0.32450 0.32806 0.33164 0.33523 0.33883 0.34245 0.34608 0.34973 0.35339 0.35707 0.36076 0.36446 0.36818 0.37191 0.37566 0.37942 0.38320 0.38699 0.39080 0.39462 0.39846 0.40231 0.40618 0.41006 0.41396 0.41788 0.42180 0.42575 0.42971 0.43368 0.43767 0.44168 0.44570 0.44974 0.45379 0.45786 0.46195 0.46605 0.47017 0.47430 0.47845 0.48262 0.48680 0.49100 0.49522 0.49945 0.50370 0.50797 0.51225 0.51655 0.52087 0.52520 0.52955 0.53392 0.53830 0.54270 0.54712 0.55156 0.55601 0.56048 0.56497 0.56948 0.57400 0.57855 0.58311 0.58768 0.59228 0.59689 0.60153 0.60618 0.61085 0.61553 0.62024 0.62496 0.62970 0.63447 0.63925 0.64404 0.64886 0.65370 0.65855 0.66343 0.66832 0.67323 0.67817 0.68312 0.68809 0.69308 0.69809 0.70312 0.70817 0.71324 0.71833 0.72344 0.72856 0.73371 0.73888 0.74407 0.74928 0.75451 0.75977 0.76504 0.77033 0.77564 0.78098 0.78633 0.79171 0.79711 0.80253 0.80797 0.81343 0.81891 0.82442 0.82994 0.83549 0.84106 0.84665 0.85226 0.85790 0.86356 0.86924 0.87494 0.88066 0.88641 0.89218 0.89797 0.90379 0.90963 0.91549 0.92137 0.92728 0.93321 0.93916 0.94514 0.95114 0.95716 0.96321 0.96928 0.97538 0.98150 0.98764 0.99381 0.99888 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/gamma.iasc000066400000000000000000000154001215713201500216500ustar00rootroot00000000000000 0.11285 0.13544 0.15416 0.17045 0.18502 0.19831 0.21059 0.22206 0.23284 0.24304 0.25275 0.26202 0.27090 0.27945 0.28768 0.29564 0.30334 0.31081 0.31807 0.32513 0.33201 0.33872 0.34526 0.35167 0.35793 0.36406 0.37007 0.37596 0.38173 0.38741 0.39298 0.39846 0.40385 0.40915 0.41437 0.41952 0.42458 0.42957 0.43449 0.43935 0.44414 0.44887 0.45353 0.45814 0.46270 0.46720 0.47165 0.47604 0.48039 0.48469 0.48894 0.49315 0.49732 0.50144 0.50552 0.50957 0.51357 0.51754 0.52146 0.52536 0.52922 0.53304 0.53683 0.54059 0.54432 0.54801 0.55168 0.55531 0.55892 0.56250 0.56605 0.56958 0.57307 0.57655 0.57999 0.58342 0.58681 0.59019 0.59354 0.59686 0.60017 0.60345 0.60671 0.60995 0.61317 0.61637 0.61955 0.62271 0.62584 0.62896 0.63206 0.63515 0.63821 0.64126 0.64429 0.64730 0.65029 0.65327 0.65623 0.65918 0.66211 0.66502 0.66792 0.67080 0.67367 0.67652 0.67936 0.68218 0.68499 0.68778 0.69057 0.69333 0.69609 0.69883 0.70156 0.70427 0.70697 0.70966 0.71234 0.71501 0.71766 0.72030 0.72293 0.72555 0.72815 0.73075 0.73333 0.73591 0.73847 0.74102 0.74356 0.74609 0.74861 0.75112 0.75361 0.75610 0.75858 0.76105 0.76351 0.76596 0.76840 0.77083 0.77325 0.77566 0.77806 0.78046 0.78284 0.78522 0.78759 0.78994 0.79229 0.79464 0.79697 0.79929 0.80161 0.80392 0.80622 0.80851 0.81079 0.81307 0.81534 0.81760 0.81985 0.82210 0.82434 0.82657 0.82879 0.83101 0.83322 0.83542 0.83762 0.83980 0.84198 0.84416 0.84633 0.84849 0.85064 0.85279 0.85493 0.85706 0.85919 0.86131 0.86343 0.86553 0.86764 0.86973 0.87182 0.87391 0.87598 0.87806 0.88012 0.88218 0.88424 0.88628 0.88833 0.89036 0.89239 0.89442 0.89644 0.89845 0.90046 0.90246 0.90446 0.90645 0.90844 0.91042 0.91240 0.91437 0.91634 0.91830 0.92025 0.92221 0.92415 0.92609 0.92803 0.92996 0.93189 0.93381 0.93572 0.93763 0.93954 0.94144 0.94334 0.94523 0.94712 0.94901 0.95088 0.95276 0.95463 0.95649 0.95836 0.96021 0.96206 0.96391 0.96576 0.96760 0.96943 0.97126 0.97309 0.97491 0.97673 0.97854 0.98035 0.98216 0.98396 0.98576 0.98755 0.98934 0.99113 0.99291 0.99469 0.99646 0.99823 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/green.lasc000066400000000000000000000324001215713201500216700ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00000 0.00392 0.00000 0.00000 0.00784 0.00000 0.00000 0.01176 0.00000 0.00000 0.01569 0.00000 0.00000 0.01961 0.00000 0.00000 0.02353 0.00000 0.00000 0.02745 0.00000 0.00000 0.03137 0.00000 0.00000 0.03529 0.00000 0.00000 0.03922 0.00000 0.00000 0.04314 0.00000 0.00000 0.04706 0.00000 0.00000 0.05098 0.00000 0.00000 0.05490 0.00000 0.00000 0.05882 0.00000 0.00000 0.06275 0.00000 0.00000 0.06667 0.00000 0.00000 0.07059 0.00000 0.00000 0.07451 0.00000 0.00000 0.07843 0.00000 0.00000 0.08235 0.00000 0.00000 0.08627 0.00000 0.00000 0.09020 0.00000 0.00000 0.09412 0.00000 0.00000 0.09804 0.00000 0.00000 0.10196 0.00000 0.00000 0.10588 0.00000 0.00000 0.10980 0.00000 0.00000 0.11373 0.00000 0.00000 0.11765 0.00000 0.00000 0.12157 0.00000 0.00000 0.12549 0.00000 0.00000 0.12941 0.00000 0.00000 0.13333 0.00000 0.00000 0.13725 0.00000 0.00000 0.14118 0.00000 0.00000 0.14510 0.00000 0.00000 0.14902 0.00000 0.00000 0.15294 0.00000 0.00000 0.15686 0.00000 0.00000 0.16078 0.00000 0.00000 0.16471 0.00000 0.00000 0.16863 0.00000 0.00000 0.17255 0.00000 0.00000 0.17647 0.00000 0.00000 0.18039 0.00000 0.00000 0.18431 0.00000 0.00000 0.18824 0.00000 0.00000 0.19216 0.00000 0.00000 0.19608 0.00000 0.00000 0.20000 0.00000 0.00000 0.20392 0.00000 0.00000 0.20784 0.00000 0.00000 0.21176 0.00000 0.00000 0.21569 0.00000 0.00000 0.21961 0.00000 0.00000 0.22353 0.00000 0.00000 0.22745 0.00000 0.00000 0.23137 0.00000 0.00000 0.23529 0.00000 0.00000 0.23922 0.00000 0.00000 0.24314 0.00000 0.00000 0.24706 0.00000 0.00000 0.25098 0.00000 0.00000 0.25490 0.00000 0.00000 0.25882 0.00000 0.00000 0.26275 0.00000 0.00000 0.26667 0.00000 0.00000 0.27059 0.00000 0.00000 0.27451 0.00000 0.00000 0.27843 0.00000 0.00000 0.28235 0.00000 0.00000 0.28627 0.00000 0.00000 0.29020 0.00000 0.00000 0.29412 0.00000 0.00000 0.29804 0.00000 0.00000 0.30196 0.00000 0.00000 0.30588 0.00000 0.00000 0.30980 0.00000 0.00000 0.31373 0.00000 0.00000 0.31765 0.00000 0.00000 0.32157 0.00000 0.00000 0.32549 0.00000 0.00000 0.32941 0.00000 0.00000 0.33333 0.00000 0.00000 0.33725 0.00000 0.00000 0.34118 0.00000 0.00000 0.34510 0.00000 0.00000 0.34902 0.00000 0.00000 0.35294 0.00000 0.00000 0.35686 0.00000 0.00000 0.36078 0.00000 0.00000 0.36471 0.00000 0.00000 0.36863 0.00000 0.00000 0.37255 0.00000 0.00000 0.37647 0.00000 0.00000 0.38039 0.00000 0.00000 0.38431 0.00000 0.00000 0.38824 0.00000 0.00000 0.39216 0.00000 0.00000 0.39608 0.00000 0.00000 0.40000 0.00000 0.00000 0.40392 0.00000 0.00000 0.40784 0.00000 0.00000 0.41176 0.00000 0.00000 0.41569 0.00000 0.00000 0.41961 0.00000 0.00000 0.42353 0.00000 0.00000 0.42745 0.00000 0.00000 0.43137 0.00000 0.00000 0.43529 0.00000 0.00000 0.43922 0.00000 0.00000 0.44314 0.00000 0.00000 0.44706 0.00000 0.00000 0.45098 0.00000 0.00000 0.45490 0.00000 0.00000 0.45882 0.00000 0.00000 0.46275 0.00000 0.00000 0.46667 0.00000 0.00000 0.47059 0.00000 0.00000 0.47451 0.00000 0.00000 0.47843 0.00000 0.00000 0.48235 0.00000 0.00000 0.48627 0.00000 0.00000 0.49020 0.00000 0.00000 0.49412 0.00000 0.00000 0.49804 0.00000 0.00000 0.50196 0.00000 0.00000 0.50588 0.00000 0.00000 0.50980 0.00000 0.00000 0.51373 0.00000 0.00000 0.51765 0.00000 0.00000 0.52157 0.00000 0.00000 0.52549 0.00000 0.00000 0.52941 0.00000 0.00000 0.53333 0.00000 0.00000 0.53725 0.00000 0.00000 0.54118 0.00000 0.00000 0.54510 0.00000 0.00000 0.54902 0.00000 0.00000 0.55294 0.00000 0.00000 0.55686 0.00000 0.00000 0.56078 0.00000 0.00000 0.56471 0.00000 0.00000 0.56863 0.00000 0.00000 0.57255 0.00000 0.00000 0.57647 0.00000 0.00000 0.58039 0.00000 0.00000 0.58431 0.00000 0.00000 0.58824 0.00000 0.00000 0.59216 0.00000 0.00000 0.59608 0.00000 0.00000 0.60000 0.00000 0.00000 0.60392 0.00000 0.00000 0.60784 0.00000 0.00000 0.61176 0.00000 0.00000 0.61569 0.00000 0.00000 0.61961 0.00000 0.00000 0.62353 0.00000 0.00000 0.62745 0.00000 0.00000 0.63137 0.00000 0.00000 0.63529 0.00000 0.00000 0.63922 0.00000 0.00000 0.64314 0.00000 0.00000 0.64706 0.00000 0.00000 0.65098 0.00000 0.00000 0.65490 0.00000 0.00000 0.65882 0.00000 0.00000 0.66275 0.00000 0.00000 0.66667 0.00000 0.00000 0.67059 0.00000 0.00000 0.67451 0.00000 0.00000 0.67843 0.00000 0.00000 0.68235 0.00000 0.00000 0.68627 0.00000 0.00000 0.69020 0.00000 0.00000 0.69412 0.00000 0.00000 0.69804 0.00000 0.00000 0.70196 0.00000 0.00000 0.70588 0.00000 0.00000 0.70980 0.00000 0.00000 0.71373 0.00000 0.00000 0.71765 0.00000 0.00000 0.72157 0.00000 0.00000 0.72549 0.00000 0.00000 0.72941 0.00000 0.00000 0.73333 0.00000 0.00000 0.73725 0.00000 0.00000 0.74118 0.00000 0.00000 0.74510 0.00000 0.00000 0.74902 0.00000 0.00000 0.75294 0.00000 0.00000 0.75686 0.00000 0.00000 0.76078 0.00000 0.00000 0.76471 0.00000 0.00000 0.76863 0.00000 0.00000 0.77255 0.00000 0.00000 0.77647 0.00000 0.00000 0.78039 0.00000 0.00000 0.78431 0.00000 0.00000 0.78824 0.00000 0.00000 0.79216 0.00000 0.00000 0.79608 0.00000 0.00000 0.80000 0.00000 0.00000 0.80392 0.00000 0.00000 0.80784 0.00000 0.00000 0.81176 0.00000 0.00000 0.81569 0.00000 0.00000 0.81961 0.00000 0.00000 0.82353 0.00000 0.00000 0.82745 0.00000 0.00000 0.83137 0.00000 0.00000 0.83529 0.00000 0.00000 0.83922 0.00000 0.00000 0.84314 0.00000 0.00000 0.84706 0.00000 0.00000 0.85098 0.00000 0.00000 0.85490 0.00000 0.00000 0.85882 0.00000 0.00000 0.86275 0.00000 0.00000 0.86667 0.00000 0.00000 0.87059 0.00000 0.00000 0.87451 0.00000 0.00000 0.87843 0.00000 0.00000 0.88235 0.00000 0.00000 0.88627 0.00000 0.00000 0.89020 0.00000 0.00000 0.89412 0.00000 0.00000 0.89804 0.00000 0.00000 0.90196 0.00000 0.00000 0.90588 0.00000 0.00000 0.90980 0.00000 0.00000 0.91373 0.00000 0.00000 0.91765 0.00000 0.00000 0.92157 0.00000 0.00000 0.92549 0.00000 0.00000 0.92941 0.00000 0.00000 0.93333 0.00000 0.00000 0.93725 0.00000 0.00000 0.94118 0.00000 0.00000 0.94510 0.00000 0.00000 0.94902 0.00000 0.00000 0.95294 0.00000 0.00000 0.95686 0.00000 0.00000 0.96078 0.00000 0.00000 0.96471 0.00000 0.00000 0.96863 0.00000 0.00000 0.97255 0.00000 0.00000 0.97647 0.00000 0.00000 0.98039 0.00000 0.00000 0.98431 0.00000 0.00000 0.98824 0.00000 0.00000 0.99216 0.00000 0.00000 0.99608 0.00000 0.00000 1.00000 0.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/greenlut.lasc000066400000000000000000000140001215713201500224110ustar00rootroot000000000000000.00000 0.00000 0.00000 0.00000 0.00392 0.00000 0.00000 0.00784 0.00000 0.00000 0.01176 0.00000 0.00000 0.01569 0.00000 0.00000 0.01961 0.00000 0.00000 0.02353 0.00000 0.00000 0.02745 0.00000 0.00000 0.03137 0.00000 0.00000 0.03529 0.00000 0.00000 0.03922 0.00000 0.00000 0.04314 0.00000 0.00000 0.04706 0.00000 0.00001 0.05098 0.00001 0.00001 0.05490 0.00001 0.00001 0.05882 0.00001 0.00002 0.06275 0.00002 0.00002 0.06667 0.00002 0.00002 0.07059 0.00002 0.00003 0.07451 0.00003 0.00004 0.07843 0.00004 0.00005 0.08235 0.00005 0.00006 0.08627 0.00006 0.00007 0.09020 0.00007 0.00008 0.09412 0.00008 0.00009 0.09804 0.00009 0.00011 0.10196 0.00011 0.00013 0.10588 0.00013 0.00015 0.10980 0.00015 0.00017 0.11373 0.00017 0.00019 0.11765 0.00019 0.00022 0.12157 0.00022 0.00025 0.12549 0.00025 0.00028 0.12941 0.00028 0.00032 0.13333 0.00032 0.00035 0.13725 0.00035 0.00040 0.14118 0.00040 0.00044 0.14510 0.00044 0.00049 0.14902 0.00049 0.00055 0.15294 0.00055 0.00061 0.15686 0.00061 0.00067 0.16078 0.00067 0.00074 0.16471 0.00074 0.00081 0.16863 0.00081 0.00089 0.17255 0.00089 0.00097 0.17647 0.00097 0.00106 0.18039 0.00106 0.00115 0.18431 0.00115 0.00126 0.18824 0.00126 0.00136 0.19216 0.00136 0.00148 0.19608 0.00148 0.00160 0.20000 0.00160 0.00173 0.20392 0.00173 0.00187 0.20784 0.00187 0.00201 0.21176 0.00201 0.00216 0.21569 0.00216 0.00233 0.21961 0.00233 0.00250 0.22353 0.00250 0.00268 0.22745 0.00268 0.00287 0.23137 0.00287 0.00307 0.23529 0.00307 0.00327 0.23922 0.00327 0.00349 0.24314 0.00349 0.00373 0.24706 0.00373 0.00397 0.25098 0.00397 0.00422 0.25490 0.00422 0.00449 0.25882 0.00449 0.00477 0.26275 0.00477 0.00506 0.26667 0.00506 0.00536 0.27059 0.00536 0.00568 0.27451 0.00568 0.00601 0.27843 0.00601 0.00636 0.28235 0.00636 0.00672 0.28627 0.00672 0.00709 0.29020 0.00709 0.00748 0.29412 0.00748 0.00789 0.29804 0.00789 0.00831 0.30196 0.00831 0.00875 0.30588 0.00875 0.00921 0.30980 0.00921 0.00969 0.31373 0.00969 0.01018 0.31765 0.01018 0.01069 0.32157 0.01069 0.01122 0.32549 0.01122 0.01177 0.32941 0.01177 0.01235 0.33333 0.01235 0.01294 0.33725 0.01294 0.01355 0.34118 0.01355 0.01418 0.34510 0.01418 0.01484 0.34902 0.01484 0.01552 0.35294 0.01552 0.01622 0.35686 0.01622 0.01694 0.36078 0.01694 0.01769 0.36471 0.01769 0.01847 0.36863 0.01847 0.01926 0.37255 0.01926 0.02009 0.37647 0.02009 0.02094 0.38039 0.02094 0.02181 0.38431 0.02181 0.02272 0.38824 0.02272 0.02365 0.39216 0.02365 0.02461 0.39608 0.02461 0.02560 0.40000 0.02560 0.02662 0.40392 0.02662 0.02767 0.40784 0.02767 0.02875 0.41176 0.02875 0.02986 0.41569 0.02986 0.03100 0.41961 0.03100 0.03218 0.42353 0.03218 0.03338 0.42745 0.03338 0.03463 0.43137 0.03463 0.03590 0.43529 0.03590 0.03721 0.43922 0.03721 0.03856 0.44314 0.03856 0.03994 0.44706 0.03994 0.04136 0.45098 0.04136 0.04282 0.45490 0.04282 0.04432 0.45882 0.04432 0.04585 0.46275 0.04585 0.04743 0.46667 0.04743 0.04904 0.47059 0.04904 0.05070 0.47451 0.05070 0.05239 0.47843 0.05239 0.05413 0.48235 0.05413 0.05591 0.48627 0.05591 0.05774 0.49020 0.05774 0.05961 0.49412 0.05961 0.06153 0.49804 0.06153 0.06349 0.50196 0.06349 0.06549 0.50588 0.06549 0.06755 0.50980 0.06755 0.06965 0.51373 0.06965 0.07180 0.51765 0.07180 0.07400 0.52157 0.07400 0.07625 0.52549 0.07625 0.07856 0.52941 0.07856 0.08091 0.53333 0.08091 0.08331 0.53725 0.08331 0.08577 0.54118 0.08577 0.08829 0.54510 0.08829 0.09086 0.54902 0.09086 0.09348 0.55294 0.09348 0.09616 0.55686 0.09616 0.09890 0.56078 0.09890 0.10169 0.56471 0.10169 0.10455 0.56863 0.10455 0.10746 0.57255 0.10746 0.11044 0.57647 0.11044 0.11347 0.58039 0.11347 0.11657 0.58431 0.11657 0.11973 0.58824 0.11973 0.12296 0.59216 0.12296 0.12624 0.59608 0.12624 0.12960 0.60000 0.12960 0.13302 0.60392 0.13302 0.13651 0.60784 0.13651 0.14007 0.61176 0.14007 0.14369 0.61569 0.14369 0.14739 0.61961 0.14739 0.15116 0.62353 0.15116 0.15500 0.62745 0.15500 0.15891 0.63137 0.15891 0.16289 0.63529 0.16289 0.16695 0.63922 0.16695 0.17109 0.64314 0.17109 0.17530 0.64706 0.17530 0.17959 0.65098 0.17959 0.18395 0.65490 0.18395 0.18840 0.65882 0.18840 0.19292 0.66275 0.19292 0.19753 0.66667 0.19753 0.20222 0.67059 0.20222 0.20699 0.67451 0.20699 0.21185 0.67843 0.21185 0.21679 0.68235 0.21679 0.22182 0.68627 0.22182 0.22693 0.69020 0.22693 0.23213 0.69412 0.23213 0.23742 0.69804 0.23742 0.24280 0.70196 0.24280 0.24827 0.70588 0.24827 0.25384 0.70980 0.25384 0.25949 0.71373 0.25949 0.26524 0.71765 0.26524 0.27109 0.72157 0.27109 0.27703 0.72549 0.27703 0.28307 0.72941 0.28307 0.28920 0.73333 0.28920 0.29544 0.73725 0.29544 0.30178 0.74118 0.30178 0.30821 0.74510 0.30821 0.31476 0.74902 0.31476 0.32140 0.75294 0.32140 0.32815 0.75686 0.32815 0.33500 0.76078 0.33500 0.34196 0.76471 0.34196 0.34903 0.76863 0.34903 0.35621 0.77255 0.35621 0.36350 0.77647 0.36350 0.37090 0.78039 0.37090 0.37841 0.78431 0.37841 0.38603 0.78824 0.38603 0.39377 0.79216 0.39377 0.40163 0.79608 0.40163 0.40960 0.80000 0.40960 0.41769 0.80392 0.41769 0.42590 0.80784 0.42590 0.43423 0.81176 0.43423 0.44268 0.81569 0.44268 0.45126 0.81961 0.45126 0.45996 0.82353 0.45996 0.46878 0.82745 0.46878 0.47773 0.83137 0.47773 0.48681 0.83529 0.48681 0.49601 0.83922 0.49601 0.50535 0.84314 0.50535 0.51482 0.84706 0.51482 0.52442 0.85098 0.52442 0.53415 0.85490 0.53415 0.54402 0.85882 0.54402 0.55403 0.86275 0.55403 0.56417 0.86667 0.56417 0.57445 0.87059 0.57445 0.58487 0.87451 0.58487 0.59543 0.87843 0.59543 0.60613 0.88235 0.60613 0.61698 0.88627 0.61698 0.62798 0.89020 0.62798 0.63911 0.89412 0.63911 0.65040 0.89804 0.65040 0.66184 0.90196 0.66184 0.67342 0.90588 0.67342 0.68516 0.90980 0.68516 0.69705 0.91373 0.69705 0.70909 0.91765 0.70909 0.72129 0.92157 0.72129 0.73365 0.92549 0.73365 0.74616 0.92941 0.74616 0.75883 0.93333 0.75883 0.77167 0.93725 0.77167 0.78466 0.94118 0.78466 0.79782 0.94510 0.79782 0.81115 0.94902 0.81115 0.82464 0.95294 0.82464 0.83830 0.95686 0.83830 0.85213 0.96078 0.85213 0.86612 0.96471 0.86612 0.88029 0.96863 0.88029 0.89464 0.97255 0.89464 0.90915 0.97647 0.90915 0.92385 0.98039 0.92385 0.93872 0.98431 0.93872 0.95377 0.98824 0.95377 0.96899 0.99216 0.96899 0.98441 0.99608 0.98441 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/heat.lasc000066400000000000000000000324001215713201500215110ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.01176 0.00392 0.00000 0.02353 0.00784 0.00000 0.03529 0.01176 0.00000 0.04706 0.01569 0.00000 0.05882 0.01961 0.00000 0.07059 0.02353 0.00000 0.08235 0.02745 0.00000 0.09412 0.03137 0.00000 0.10588 0.03529 0.00000 0.11765 0.03922 0.00000 0.12941 0.04314 0.00000 0.14118 0.04706 0.00000 0.15294 0.05098 0.00000 0.16471 0.05490 0.00000 0.17647 0.05882 0.00000 0.18824 0.06275 0.00000 0.20000 0.06667 0.00000 0.21176 0.07059 0.00000 0.22353 0.07451 0.00000 0.23529 0.07843 0.00000 0.24706 0.08235 0.00000 0.25882 0.08627 0.00000 0.27059 0.09020 0.00000 0.28235 0.09412 0.00000 0.29412 0.09804 0.00000 0.30588 0.10196 0.00000 0.31765 0.10588 0.00000 0.32941 0.10980 0.00000 0.34118 0.11373 0.00000 0.35294 0.11765 0.00000 0.36471 0.12157 0.00000 0.37647 0.12549 0.00000 0.38824 0.12941 0.00000 0.40000 0.13333 0.00000 0.41176 0.13725 0.00000 0.42353 0.14118 0.00000 0.43529 0.14510 0.00000 0.44706 0.14902 0.00000 0.45882 0.15294 0.00000 0.47059 0.15686 0.00000 0.48235 0.16078 0.00000 0.49412 0.16471 0.00000 0.50588 0.16863 0.00000 0.51765 0.17255 0.00000 0.52941 0.17647 0.00000 0.54118 0.18039 0.00000 0.55294 0.18431 0.00000 0.56471 0.18824 0.00000 0.57647 0.19216 0.00000 0.58824 0.19608 0.00000 0.60000 0.20000 0.00000 0.61176 0.20392 0.00000 0.62353 0.20784 0.00000 0.63529 0.21176 0.00000 0.64706 0.21569 0.00000 0.65882 0.21961 0.00000 0.67059 0.22353 0.00000 0.68235 0.22745 0.00000 0.69412 0.23137 0.00000 0.70588 0.23529 0.00000 0.71765 0.23922 0.00000 0.72941 0.24314 0.00000 0.74118 0.24706 0.00000 0.75294 0.25098 0.00000 0.76471 0.25490 0.00000 0.77647 0.25882 0.00000 0.78824 0.26275 0.00000 0.80000 0.26667 0.00000 0.81176 0.27059 0.00000 0.82353 0.27451 0.00000 0.83529 0.27843 0.00000 0.84706 0.28235 0.00000 0.85882 0.28627 0.00000 0.87059 0.29020 0.00000 0.88235 0.29412 0.00000 0.89412 0.29804 0.00000 0.90588 0.30196 0.00000 0.91765 0.30588 0.00000 0.92941 0.30980 0.00000 0.94118 0.31373 0.00000 0.95294 0.31765 0.00000 0.96471 0.32157 0.00000 0.97647 0.32549 0.00000 0.98824 0.32941 0.00000 1.00000 0.33333 0.00000 1.00000 0.33725 0.00000 1.00000 0.34118 0.00000 1.00000 0.34510 0.00000 1.00000 0.34902 0.00000 1.00000 0.35294 0.00000 1.00000 0.35686 0.00000 1.00000 0.36078 0.00000 1.00000 0.36471 0.00000 1.00000 0.36863 0.00000 1.00000 0.37255 0.00000 1.00000 0.37647 0.00000 1.00000 0.38039 0.00000 1.00000 0.38431 0.00000 1.00000 0.38824 0.00000 1.00000 0.39216 0.00000 1.00000 0.39608 0.00000 1.00000 0.40000 0.00000 1.00000 0.40392 0.00000 1.00000 0.40784 0.00000 1.00000 0.41176 0.00000 1.00000 0.41569 0.00000 1.00000 0.41961 0.00000 1.00000 0.42353 0.00000 1.00000 0.42745 0.00000 1.00000 0.43137 0.00000 1.00000 0.43529 0.00000 1.00000 0.43922 0.00000 1.00000 0.44314 0.00000 1.00000 0.44706 0.00000 1.00000 0.45098 0.00000 1.00000 0.45490 0.00000 1.00000 0.45882 0.00000 1.00000 0.46275 0.00000 1.00000 0.46667 0.00000 1.00000 0.47059 0.00000 1.00000 0.47451 0.00000 1.00000 0.47843 0.00000 1.00000 0.48235 0.00000 1.00000 0.48627 0.00000 1.00000 0.49020 0.00000 1.00000 0.49412 0.00000 1.00000 0.49804 0.00000 1.00000 0.50196 0.00000 1.00000 0.50588 0.00000 1.00000 0.50980 0.00000 1.00000 0.51373 0.00000 1.00000 0.51765 0.00000 1.00000 0.52157 0.00000 1.00000 0.52549 0.00000 1.00000 0.52941 0.00000 1.00000 0.53333 0.00000 1.00000 0.53725 0.00000 1.00000 0.54118 0.00000 1.00000 0.54510 0.00000 1.00000 0.54902 0.00000 1.00000 0.55294 0.00000 1.00000 0.55686 0.00000 1.00000 0.56078 0.00000 1.00000 0.56471 0.00000 1.00000 0.56863 0.00000 1.00000 0.57255 0.00000 1.00000 0.57647 0.00000 1.00000 0.58039 0.00000 1.00000 0.58431 0.00000 1.00000 0.58824 0.00000 1.00000 0.59216 0.00000 1.00000 0.59608 0.00000 1.00000 0.60000 0.00000 1.00000 0.60392 0.00000 1.00000 0.60784 0.00000 1.00000 0.61176 0.00000 1.00000 0.61569 0.00000 1.00000 0.61961 0.00000 1.00000 0.62353 0.00000 1.00000 0.62745 0.00000 1.00000 0.63137 0.00000 1.00000 0.63529 0.00000 1.00000 0.63922 0.00000 1.00000 0.64314 0.00000 1.00000 0.64706 0.00000 1.00000 0.65098 0.01176 1.00000 0.65490 0.02353 1.00000 0.65882 0.03529 1.00000 0.66275 0.04706 1.00000 0.66667 0.05882 1.00000 0.67059 0.07059 1.00000 0.67451 0.08235 1.00000 0.67843 0.09412 1.00000 0.68235 0.10588 1.00000 0.68627 0.11765 1.00000 0.69020 0.12941 1.00000 0.69412 0.14118 1.00000 0.69804 0.15294 1.00000 0.70196 0.16471 1.00000 0.70588 0.17647 1.00000 0.70980 0.18824 1.00000 0.71373 0.20000 1.00000 0.71765 0.21176 1.00000 0.72157 0.22353 1.00000 0.72549 0.23529 1.00000 0.72941 0.24706 1.00000 0.73333 0.25882 1.00000 0.73725 0.27059 1.00000 0.74118 0.28235 1.00000 0.74510 0.29412 1.00000 0.74902 0.30588 1.00000 0.75294 0.31765 1.00000 0.75686 0.32941 1.00000 0.76078 0.34118 1.00000 0.76471 0.35294 1.00000 0.76863 0.36471 1.00000 0.77255 0.37647 1.00000 0.77647 0.38824 1.00000 0.78039 0.40000 1.00000 0.78431 0.41176 1.00000 0.78824 0.42353 1.00000 0.79216 0.43529 1.00000 0.79608 0.44706 1.00000 0.80000 0.45882 1.00000 0.80392 0.47059 1.00000 0.80784 0.48235 1.00000 0.81176 0.49412 1.00000 0.81569 0.50588 1.00000 0.81961 0.51765 1.00000 0.82353 0.52941 1.00000 0.82745 0.54118 1.00000 0.83137 0.55294 1.00000 0.83529 0.56471 1.00000 0.83922 0.57647 1.00000 0.84314 0.58824 1.00000 0.84706 0.60000 1.00000 0.85098 0.61176 1.00000 0.85490 0.62353 1.00000 0.85882 0.63529 1.00000 0.86275 0.64706 1.00000 0.86667 0.65882 1.00000 0.87059 0.67059 1.00000 0.87451 0.68235 1.00000 0.87843 0.69412 1.00000 0.88235 0.70588 1.00000 0.88627 0.71765 1.00000 0.89020 0.72941 1.00000 0.89412 0.74118 1.00000 0.89804 0.75294 1.00000 0.90196 0.76471 1.00000 0.90588 0.77647 1.00000 0.90980 0.78824 1.00000 0.91373 0.80000 1.00000 0.91765 0.81176 1.00000 0.92157 0.82353 1.00000 0.92549 0.83529 1.00000 0.92941 0.84706 1.00000 0.93333 0.85882 1.00000 0.93725 0.87059 1.00000 0.94118 0.88235 1.00000 0.94510 0.89412 1.00000 0.94902 0.90588 1.00000 0.95294 0.91765 1.00000 0.95686 0.92941 1.00000 0.96078 0.94118 1.00000 0.96471 0.95294 1.00000 0.96863 0.96471 1.00000 0.97255 0.97647 1.00000 0.97647 0.98824 1.00000 0.98039 1.00000 1.00000 0.98431 1.00000 1.00000 0.98824 1.00000 1.00000 0.99216 1.00000 1.00000 0.99608 1.00000 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/idl11.lasc000066400000000000000000000324001215713201500215020ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00000 0.00392 0.00392 0.00000 0.00784 0.00784 0.00000 0.01176 0.01176 0.00000 0.01569 0.01569 0.00000 0.03137 0.03137 0.00000 0.04706 0.04706 0.00000 0.06275 0.06275 0.00000 0.08235 0.08235 0.00000 0.09804 0.09804 0.00000 0.11373 0.11373 0.00000 0.12941 0.12941 0.00000 0.14902 0.14902 0.00000 0.16471 0.16471 0.00000 0.18039 0.18039 0.00000 0.19608 0.19608 0.00000 0.21569 0.21569 0.00000 0.23137 0.23137 0.00000 0.24706 0.24706 0.00000 0.26275 0.26275 0.00000 0.28235 0.28235 0.00000 0.29804 0.29804 0.00000 0.31373 0.31373 0.00000 0.32941 0.32941 0.00000 0.34902 0.34902 0.00000 0.36471 0.36471 0.00000 0.38039 0.38039 0.00000 0.39608 0.39608 0.00000 0.41569 0.41569 0.00000 0.43137 0.43137 0.00000 0.44706 0.44706 0.00000 0.46275 0.46275 0.00000 0.48235 0.48235 0.00000 0.49804 0.49804 0.00000 0.51373 0.51373 0.00000 0.52941 0.52941 0.00000 0.54902 0.54902 0.00000 0.56471 0.56471 0.00000 0.58039 0.58039 0.00000 0.59608 0.59608 0.00000 0.61569 0.61569 0.00000 0.63137 0.63137 0.00000 0.64706 0.64706 0.00000 0.66275 0.66275 0.00000 0.68235 0.68235 0.00000 0.69804 0.69804 0.00000 0.71373 0.71373 0.00000 0.72941 0.72941 0.00000 0.74902 0.74902 0.00000 0.76471 0.76471 0.00000 0.78039 0.78039 0.00000 0.79608 0.79608 0.00000 0.81569 0.81569 0.00000 0.83137 0.83137 0.00000 0.84706 0.84706 0.00000 0.86275 0.86275 0.00000 0.88235 0.88235 0.00000 0.89804 0.89804 0.00000 0.91373 0.91373 0.00000 0.92941 0.92941 0.00000 0.94902 0.94902 0.00000 0.96471 0.96471 0.00000 0.98039 0.98039 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 0.98431 1.00000 0.00000 0.96863 1.00000 0.00000 0.95294 1.00000 0.00000 0.93725 1.00000 0.00000 0.92157 1.00000 0.00000 0.90588 1.00000 0.00000 0.89020 1.00000 0.00000 0.87451 1.00000 0.00000 0.85882 1.00000 0.00000 0.84314 1.00000 0.00000 0.82745 1.00000 0.00000 0.81176 1.00000 0.00000 0.79608 1.00000 0.00000 0.78039 1.00000 0.00000 0.76471 1.00000 0.00000 0.74902 1.00000 0.00000 0.73333 1.00000 0.00000 0.71765 1.00000 0.00000 0.70196 1.00000 0.00000 0.68627 1.00000 0.00000 0.66667 1.00000 0.00000 0.65098 1.00000 0.00000 0.63529 1.00000 0.00000 0.61961 1.00000 0.00000 0.60392 1.00000 0.00000 0.58824 1.00000 0.00000 0.57255 1.00000 0.00000 0.55686 1.00000 0.00000 0.54118 1.00000 0.00000 0.52549 1.00000 0.00000 0.50980 1.00000 0.00000 0.49412 1.00000 0.00000 0.47843 1.00000 0.00000 0.46275 1.00000 0.00000 0.44706 1.00000 0.00000 0.43137 1.00000 0.00000 0.41569 1.00000 0.00000 0.40000 1.00000 0.00000 0.38431 1.00000 0.00000 0.36863 1.00000 0.00000 0.35294 1.00000 0.00000 0.33333 1.00000 0.00000 0.31765 1.00000 0.00000 0.30196 1.00000 0.00000 0.28627 1.00000 0.00000 0.27059 1.00000 0.00000 0.25490 1.00000 0.00000 0.23922 1.00000 0.00000 0.22353 1.00000 0.00000 0.20784 1.00000 0.00000 0.19216 1.00000 0.00000 0.17647 1.00000 0.00000 0.16078 1.00000 0.00000 0.14510 1.00000 0.00000 0.12941 1.00000 0.00000 0.11373 1.00000 0.00000 0.09804 1.00000 0.00000 0.08235 1.00000 0.00000 0.06667 1.00000 0.00000 0.05098 1.00000 0.00000 0.03529 1.00000 0.00000 0.01961 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.01569 0.00000 1.00000 0.03137 0.00000 1.00000 0.04706 0.00000 1.00000 0.06275 0.00000 1.00000 0.07843 0.00000 1.00000 0.09412 0.00000 1.00000 0.10980 0.00000 1.00000 0.12549 0.00000 1.00000 0.14118 0.00000 1.00000 0.15686 0.00000 1.00000 0.17255 0.00000 1.00000 0.18824 0.00000 1.00000 0.20392 0.00000 1.00000 0.21961 0.00000 1.00000 0.23529 0.00000 1.00000 0.25098 0.00000 1.00000 0.26667 0.00000 1.00000 0.28235 0.00000 1.00000 0.29804 0.00000 1.00000 0.31373 0.00000 1.00000 0.33333 0.00000 1.00000 0.34902 0.00000 1.00000 0.36471 0.00000 1.00000 0.38039 0.00000 1.00000 0.39608 0.00000 1.00000 0.41176 0.00000 1.00000 0.42745 0.00000 1.00000 0.44314 0.00000 1.00000 0.45882 0.00000 1.00000 0.47451 0.00000 1.00000 0.49020 0.00000 1.00000 0.50588 0.00000 1.00000 0.52157 0.00000 1.00000 0.53725 0.00000 1.00000 0.55294 0.00000 1.00000 0.56863 0.00000 1.00000 0.58431 0.00000 1.00000 0.60000 0.00000 1.00000 0.61569 0.00000 1.00000 0.63137 0.00000 1.00000 0.64706 0.00000 1.00000 0.66667 0.00000 1.00000 0.68235 0.00000 1.00000 0.69804 0.00000 1.00000 0.71373 0.00000 1.00000 0.72941 0.00000 1.00000 0.74510 0.00000 1.00000 0.76078 0.00000 1.00000 0.77647 0.00000 1.00000 0.79216 0.00000 1.00000 0.80784 0.00000 1.00000 0.82353 0.00000 1.00000 0.83922 0.00000 1.00000 0.85490 0.00000 1.00000 0.87059 0.00000 1.00000 0.88627 0.00000 1.00000 0.90196 0.00000 1.00000 0.91765 0.00000 1.00000 0.93333 0.00000 1.00000 0.94902 0.00000 1.00000 0.96471 0.00000 1.00000 0.98039 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 0.98431 1.00000 0.00000 0.96863 1.00000 0.00000 0.95294 1.00000 0.00000 0.93725 1.00000 0.00000 0.92157 1.00000 0.00000 0.90588 1.00000 0.00000 0.89020 1.00000 0.00000 0.87451 1.00000 0.00000 0.85490 1.00000 0.00000 0.83922 1.00000 0.00000 0.82353 1.00000 0.00000 0.80784 1.00000 0.00000 0.79216 1.00000 0.00000 0.77647 1.00000 0.00000 0.76078 1.00000 0.00000 0.74510 1.00000 0.00000 0.72941 1.00000 0.00000 0.70980 1.00000 0.00000 0.69412 1.00000 0.00000 0.67843 1.00000 0.00000 0.66275 1.00000 0.00000 0.64706 1.00000 0.00000 0.63137 1.00000 0.00000 0.61569 1.00000 0.00000 0.60000 1.00000 0.00000 0.58431 1.00000 0.00000 0.56471 1.00000 0.00000 0.54902 1.00000 0.00000 0.53333 1.00000 0.00000 0.51765 1.00000 0.00000 0.50196 1.00000 0.00000 0.48627 1.00000 0.00000 0.47059 1.00000 0.00000 0.45490 1.00000 0.00000 0.43922 1.00000 0.00000 0.41961 1.00000 0.00000 0.40392 1.00000 0.00000 0.38824 1.00000 0.00000 0.37255 1.00000 0.00000 0.35686 1.00000 0.00000 0.34118 1.00000 0.00000 0.32549 1.00000 0.00000 0.30980 1.00000 0.00000 0.29412 1.00000 0.00000 0.27451 1.00000 0.00000 0.25882 1.00000 0.00000 0.24314 1.00000 0.00000 0.22745 1.00000 0.00000 0.21176 1.00000 0.00000 0.19608 1.00000 0.00000 0.18039 1.00000 0.00000 0.16471 1.00000 0.00000 0.14902 1.00000 0.00000 0.12941 1.00000 0.00000 0.11373 1.00000 0.00000 0.09804 1.00000 0.00000 0.08235 1.00000 0.00000 0.06667 1.00000 0.00000 0.05098 1.00000 0.00000 0.03529 1.00000 0.00000 0.01961 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/idl12.lasc000066400000000000000000000324001215713201500215030ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00000 0.32941 0.00000 0.00000 0.32941 0.00000 0.00000 0.32941 0.00000 0.00000 0.32941 0.00000 0.00000 0.32941 0.00000 0.00000 0.32941 0.00000 0.00000 0.32941 0.00000 0.00000 0.32941 0.00000 0.00000 0.32941 0.00000 0.00000 0.32941 0.00000 0.00000 0.32941 0.00000 0.00000 0.32941 0.00000 0.00000 0.32941 0.00000 0.00000 0.32941 0.00000 0.00000 0.32941 0.00000 0.00000 0.65882 0.00000 0.00000 0.65882 0.00000 0.00000 0.65882 0.00000 0.00000 0.65882 0.00000 0.00000 0.65882 0.00000 0.00000 0.65882 0.00000 0.00000 0.65882 0.00000 0.00000 0.65882 0.00000 0.00000 0.65882 0.00000 0.00000 0.65882 0.00000 0.00000 0.65882 0.00000 0.00000 0.65882 0.00000 0.00000 0.65882 0.00000 0.00000 0.65882 0.00000 0.00000 0.65882 0.00000 0.00000 0.65882 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.32941 0.00000 1.00000 0.32941 0.00000 1.00000 0.32941 0.00000 1.00000 0.32941 0.00000 1.00000 0.32941 0.00000 1.00000 0.32941 0.00000 1.00000 0.32941 0.00000 1.00000 0.32941 0.00000 1.00000 0.32941 0.00000 1.00000 0.32941 0.00000 1.00000 0.32941 0.00000 1.00000 0.32941 0.00000 1.00000 0.32941 0.00000 1.00000 0.32941 0.00000 1.00000 0.32941 0.00000 1.00000 0.32941 0.00000 1.00000 0.65882 0.00000 1.00000 0.65882 0.00000 1.00000 0.65882 0.00000 1.00000 0.65882 0.00000 1.00000 0.65882 0.00000 1.00000 0.65882 0.00000 1.00000 0.65882 0.00000 1.00000 0.65882 0.00000 1.00000 0.65882 0.00000 1.00000 0.65882 0.00000 1.00000 0.65882 0.00000 1.00000 0.65882 0.00000 1.00000 0.65882 0.00000 1.00000 0.65882 0.00000 1.00000 0.65882 0.00000 1.00000 0.65882 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.50196 0.00000 1.00000 0.50196 0.00000 1.00000 0.50196 0.00000 1.00000 0.50196 0.00000 1.00000 0.50196 0.00000 1.00000 0.50196 0.00000 1.00000 0.50196 0.00000 1.00000 0.50196 0.00000 1.00000 0.50196 0.00000 1.00000 0.50196 0.00000 1.00000 0.50196 0.00000 1.00000 0.50196 0.00000 1.00000 0.50196 0.00000 1.00000 0.50196 0.00000 1.00000 0.50196 0.00000 1.00000 0.50196 0.00000 1.00000 1.00000 0.00000 0.86275 1.00000 0.00000 0.86275 1.00000 0.00000 0.86275 1.00000 0.00000 0.86275 1.00000 0.00000 0.86275 1.00000 0.00000 0.86275 1.00000 0.00000 0.86275 1.00000 0.00000 0.86275 1.00000 0.00000 0.86275 1.00000 0.00000 0.86275 1.00000 0.00000 0.86275 1.00000 0.00000 0.86275 1.00000 0.00000 0.86275 1.00000 0.00000 0.86275 1.00000 0.00000 0.86275 1.00000 0.00000 0.86275 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.50196 1.00000 0.00000 0.50196 1.00000 0.00000 0.50196 1.00000 0.00000 0.50196 1.00000 0.00000 0.50196 1.00000 0.00000 0.50196 1.00000 0.00000 0.50196 1.00000 0.00000 0.50196 1.00000 0.00000 0.50196 1.00000 0.00000 0.50196 1.00000 0.00000 0.50196 1.00000 0.00000 0.50196 1.00000 0.00000 0.50196 1.00000 0.00000 0.50196 1.00000 0.00000 0.50196 1.00000 0.00000 0.50196 1.00000 0.00000 0.25098 1.00000 0.00000 0.25098 1.00000 0.00000 0.25098 1.00000 0.00000 0.25098 1.00000 0.00000 0.25098 1.00000 0.00000 0.25098 1.00000 0.00000 0.25098 1.00000 0.00000 0.25098 1.00000 0.00000 0.25098 1.00000 0.00000 0.25098 1.00000 0.00000 0.25098 1.00000 0.00000 0.25098 1.00000 0.00000 0.25098 1.00000 0.00000 0.25098 1.00000 0.00000 0.25098 1.00000 0.00000 0.25098 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 0.86275 0.74510 0.74510 0.86275 0.74510 0.74510 0.86275 0.74510 0.74510 0.86275 0.74510 0.74510 0.86275 0.74510 0.74510 0.86667 0.74510 0.74510 0.86667 0.74510 0.74510 0.86667 0.74510 0.74510 0.86667 0.74510 0.74510 0.86667 0.74510 0.74510 0.87059 0.74510 0.74510 0.87059 0.74510 0.74510 0.87059 0.74510 0.74510 0.87059 0.74510 0.74510 0.87059 0.74510 0.74510 0.87451 0.74510 0.74510 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 0.86275 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/idl14.lasc000066400000000000000000000324001215713201500215050ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00000 0.16471 0.00000 0.00000 0.33333 0.00000 0.00000 0.49804 0.00000 0.00000 0.66667 0.00000 0.00000 0.83137 0.00000 0.00000 1.00000 0.00000 0.00000 0.96471 0.00000 0.00000 0.92549 0.00000 0.00000 0.88627 0.00000 0.00000 0.84706 0.00000 0.00000 0.80784 0.00000 0.00000 0.77255 0.00000 0.00000 0.73333 0.00000 0.00000 0.69412 0.00000 0.00000 0.65490 0.00000 0.00000 0.61569 0.00000 0.00000 0.58039 0.00000 0.00000 0.54118 0.00000 0.00000 0.50196 0.00000 0.00000 0.46275 0.00000 0.00000 0.42353 0.00000 0.00000 0.38824 0.00000 0.00000 0.34902 0.00000 0.00000 0.30980 0.00000 0.00000 0.27059 0.00000 0.00000 0.23137 0.00000 0.00000 0.19608 0.00000 0.00000 0.15686 0.00000 0.00000 0.11765 0.00000 0.00000 0.07843 0.00000 0.00000 0.03922 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.03137 0.00000 0.00000 0.06275 0.00000 0.00000 0.09412 0.00000 0.00000 0.12549 0.00000 0.00000 0.16078 0.00000 0.00000 0.19216 0.00000 0.00000 0.22353 0.00000 0.00000 0.25490 0.00000 0.00000 0.29020 0.00000 0.00000 0.32157 0.00000 0.00000 0.35294 0.00000 0.00000 0.38431 0.00000 0.00000 0.41569 0.00000 0.00000 0.45098 0.00000 0.00000 0.48235 0.00000 0.00000 0.51373 0.00000 0.00000 0.54510 0.00000 0.00000 0.58039 0.00000 0.00000 0.61176 0.00000 0.00000 0.64314 0.00000 0.00000 0.67451 0.00000 0.00000 0.70588 0.00000 0.00000 0.74118 0.00000 0.00000 0.77255 0.00000 0.00000 0.80392 0.00000 0.00000 0.83529 0.00000 0.00000 0.87059 0.00000 0.00000 0.90196 0.00000 0.00000 0.93333 0.00000 0.00000 0.96471 0.00000 0.00000 1.00000 0.00000 0.00000 0.00000 0.02745 0.00000 0.01961 0.05882 0.00000 0.03922 0.09020 0.00000 0.05882 0.12157 0.00000 0.08235 0.15294 0.00000 0.10196 0.18431 0.00000 0.12157 0.21569 0.00000 0.14510 0.24706 0.00000 0.16471 0.27451 0.00000 0.18431 0.30588 0.00000 0.20784 0.33725 0.00000 0.22745 0.36863 0.00000 0.24706 0.40000 0.00000 0.27059 0.43137 0.00000 0.29020 0.46275 0.00000 0.30980 0.49412 0.00000 0.33333 0.52549 0.00000 0.34902 0.55686 0.00000 0.36863 0.59216 0.00000 0.38431 0.62353 0.00000 0.40392 0.65882 0.00000 0.42353 0.69020 0.00000 0.43922 0.72157 0.00000 0.45882 0.75686 0.00000 0.47451 0.78824 0.00000 0.49412 0.82353 0.00000 0.51373 0.85490 0.00000 0.52941 0.88627 0.00000 0.54902 0.92157 0.00000 0.56471 0.95294 0.00000 0.58431 0.98824 0.00000 0.60392 0.00000 0.00000 0.00000 0.00392 0.00000 0.00000 0.00784 0.00000 0.00000 0.01176 0.00000 0.00000 0.01569 0.00000 0.00000 0.01961 0.00000 0.00000 0.02353 0.00000 0.00000 0.02745 0.00000 0.00000 0.03137 0.00000 0.00000 0.03529 0.00000 0.00000 0.03922 0.00000 0.00000 0.04314 0.00000 0.00000 0.04706 0.00000 0.00000 0.05490 0.00000 0.00000 0.06275 0.00000 0.00000 0.07059 0.00000 0.00000 0.07843 0.00000 0.00000 0.09020 0.00000 0.00000 0.09804 0.00000 0.00000 0.10588 0.00000 0.00000 0.11373 0.00000 0.00000 0.12549 0.00000 0.00000 0.13333 0.00000 0.00000 0.14118 0.00000 0.00000 0.14902 0.00000 0.00000 0.16078 0.00000 0.00000 0.17255 0.00000 0.00000 0.18431 0.00000 0.00000 0.19608 0.00000 0.00000 0.20784 0.00000 0.00000 0.21961 0.00000 0.00000 0.23137 0.00000 0.00000 0.24706 0.00000 0.00000 0.25882 0.00000 0.00000 0.27059 0.00000 0.00000 0.28235 0.00000 0.00000 0.29412 0.00000 0.00000 0.30588 0.00000 0.00000 0.32157 0.00000 0.00392 0.33333 0.00000 0.00392 0.34902 0.00000 0.00392 0.36471 0.00000 0.00392 0.38039 0.00000 0.00392 0.39608 0.00000 0.00392 0.41176 0.00000 0.00392 0.42353 0.00000 0.00392 0.43922 0.00000 0.00392 0.45490 0.00000 0.00392 0.47059 0.00000 0.00392 0.48627 0.00000 0.00392 0.50196 0.00392 0.00392 0.51373 0.00392 0.00392 0.52941 0.00392 0.00392 0.54510 0.00392 0.00392 0.56078 0.00392 0.00392 0.57647 0.00392 0.00392 0.59216 0.00392 0.00392 0.60784 0.00392 0.00392 0.62353 0.00392 0.00392 0.63922 0.00392 0.00392 0.65490 0.00392 0.00392 0.67059 0.00392 0.00392 0.68627 0.00392 0.00392 0.69804 0.00392 0.00392 0.70980 0.00392 0.00392 0.72549 0.00392 0.00392 0.73725 0.00392 0.00392 0.75294 0.00392 0.00392 0.76471 0.00392 0.00392 0.77647 0.00392 0.00392 0.79216 0.00392 0.00392 0.80392 0.00392 0.00392 0.81961 0.00392 0.00392 0.83137 0.00392 0.00392 0.84706 0.00392 0.00784 0.85490 0.00392 0.00784 0.86275 0.00392 0.00784 0.87451 0.00392 0.00784 0.88235 0.00392 0.00784 0.89020 0.00392 0.00784 0.90196 0.00392 0.00784 0.90980 0.00392 0.00784 0.91765 0.00392 0.00784 0.92941 0.00392 0.00784 0.93725 0.00392 0.00784 0.94510 0.00392 0.00784 0.95686 0.00784 0.00784 0.95686 0.00784 0.00784 0.96078 0.00784 0.00784 0.96471 0.00784 0.00784 0.96863 0.00784 0.00784 0.96863 0.00784 0.00784 0.97255 0.00784 0.00784 0.97647 0.00784 0.00784 0.98039 0.00784 0.00784 0.98039 0.00784 0.00784 0.98431 0.00784 0.00784 0.98824 0.00784 0.00784 0.99216 0.00784 0.00784 0.99608 0.00392 0.00784 0.99608 0.00392 0.00784 0.99608 0.01176 0.00784 0.99608 0.01961 0.00784 0.99608 0.03137 0.00784 0.99608 0.03922 0.00784 0.99608 0.04706 0.00784 0.99608 0.05882 0.00784 0.99608 0.06667 0.00784 0.99608 0.07451 0.00784 0.99608 0.08627 0.00784 0.99608 0.09412 0.00784 0.99608 0.10196 0.00784 0.99608 0.11373 0.00784 0.99608 0.12157 0.00784 0.99608 0.12941 0.00784 0.99608 0.14118 0.00784 0.99608 0.14118 0.00784 0.99608 0.14902 0.01176 0.99608 0.15686 0.01569 0.99608 0.16471 0.01961 1.00000 0.17647 0.02745 1.00000 0.18824 0.03529 1.00000 0.20000 0.04706 1.00000 0.21176 0.05490 1.00000 0.22745 0.06667 1.00000 0.23922 0.07843 1.00000 0.25098 0.09020 1.00000 0.26275 0.10588 1.00000 0.27451 0.11765 1.00000 0.28627 0.13333 1.00000 0.30196 0.15294 1.00000 0.32157 0.17255 1.00000 0.34118 0.19216 1.00000 0.36078 0.21569 1.00000 0.37647 0.23529 1.00000 0.39216 0.25490 1.00000 0.40784 0.27843 1.00000 0.42353 0.29804 1.00000 0.44314 0.32157 1.00000 0.46667 0.34902 1.00000 0.49020 0.38039 1.00000 0.51373 0.40784 1.00000 0.54118 0.43922 1.00000 0.56471 0.47059 1.00000 0.59216 0.50196 1.00000 0.61569 0.53333 1.00000 0.64314 0.56863 1.00000 0.67059 0.60000 1.00000 0.69804 0.63529 1.00000 0.72549 0.67059 1.00000 0.75686 0.70588 1.00000 0.78431 0.74118 1.00000 0.81569 0.77647 1.00000 0.84314 0.81176 1.00000 0.87451 0.85098 1.00000 0.89804 0.87843 1.00000 0.92157 0.90980 1.00000 0.94902 0.93725 1.00000 0.97255 0.96863 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/idl15.lasc000066400000000000000000000324001215713201500215060ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.07059 0.00392 0.00392 0.14118 0.00784 0.01176 0.21176 0.01176 0.01961 0.28235 0.01569 0.02745 0.35294 0.01961 0.03529 0.42353 0.02353 0.04314 0.49804 0.02745 0.05098 0.56863 0.03137 0.05882 0.63922 0.03529 0.06667 0.70980 0.03922 0.07451 0.78039 0.04314 0.08235 0.85098 0.04706 0.09020 0.92157 0.05098 0.09804 0.99608 0.05490 0.10588 0.97647 0.05882 0.11373 0.95686 0.06275 0.12157 0.93725 0.06667 0.12941 0.91765 0.07059 0.13725 0.89804 0.07451 0.14510 0.87451 0.07843 0.15294 0.85490 0.08235 0.16078 0.83529 0.08627 0.16863 0.81569 0.09020 0.17647 0.79608 0.09412 0.18431 0.77255 0.09804 0.19216 0.75294 0.10196 0.20000 0.73333 0.10588 0.20784 0.71373 0.10980 0.21569 0.69412 0.11373 0.22353 0.67451 0.11765 0.23137 0.65098 0.12157 0.23922 0.63137 0.12549 0.24706 0.61176 0.12941 0.25490 0.59216 0.13333 0.26275 0.57255 0.13725 0.27059 0.54902 0.14118 0.27843 0.52941 0.14510 0.28627 0.50980 0.14902 0.29412 0.49020 0.15294 0.30196 0.47059 0.15686 0.30980 0.45098 0.16078 0.31765 0.42745 0.16471 0.32549 0.40784 0.16863 0.33333 0.38824 0.17255 0.34118 0.36863 0.17647 0.34902 0.34902 0.18039 0.35686 0.32549 0.18431 0.36471 0.30588 0.18824 0.37255 0.28627 0.19216 0.38039 0.26667 0.19608 0.38824 0.24706 0.20000 0.39608 0.22745 0.20392 0.40392 0.20392 0.20784 0.41176 0.18431 0.21176 0.41961 0.16471 0.21569 0.42745 0.14510 0.21961 0.43529 0.12549 0.22353 0.44314 0.10196 0.22745 0.45098 0.08235 0.23137 0.45882 0.06275 0.23529 0.46667 0.04314 0.23922 0.47451 0.02353 0.24314 0.48235 0.00000 0.24706 0.49020 0.25098 0.25098 0.49804 0.25490 0.25490 0.50588 0.25882 0.25882 0.51373 0.26275 0.26275 0.52157 0.26667 0.26667 0.52941 0.27059 0.27059 0.53725 0.27451 0.27451 0.54510 0.27843 0.27843 0.55294 0.28235 0.28235 0.56078 0.28627 0.28627 0.56863 0.29020 0.29020 0.57647 0.29412 0.29412 0.58431 0.29804 0.29804 0.59216 0.30196 0.30196 0.60000 0.30588 0.30588 0.60784 0.30980 0.30980 0.61569 0.31373 0.31373 0.62353 0.31765 0.31765 0.63137 0.32157 0.32157 0.63922 0.32549 0.32549 0.64706 0.32941 0.32941 0.65490 0.33333 0.33333 0.66275 0.33725 0.33725 0.67059 0.34118 0.34118 0.67843 0.34510 0.34510 0.68627 0.34902 0.34902 0.69412 0.35294 0.35294 0.70196 0.35686 0.35686 0.70980 0.36078 0.36078 0.71765 0.36471 0.36471 0.72549 0.36863 0.36863 0.73333 0.37255 0.37255 0.74118 0.37647 0.37647 0.74902 0.38039 0.38039 0.75686 0.38431 0.38431 0.76471 0.38824 0.38824 0.77255 0.39216 0.39216 0.78039 0.39608 0.39608 0.78824 0.40000 0.40000 0.79608 0.40392 0.40392 0.80392 0.40784 0.40784 0.81176 0.41176 0.41176 0.81961 0.41569 0.41569 0.82745 0.41961 0.41961 0.83529 0.42353 0.42353 0.84314 0.42745 0.42745 0.85098 0.43137 0.43137 0.85882 0.43529 0.43529 0.86667 0.43922 0.43922 0.87451 0.44314 0.44314 0.88235 0.44706 0.44706 0.89020 0.45098 0.45098 0.89804 0.45490 0.45490 0.90588 0.45882 0.45882 0.91373 0.46275 0.46275 0.92157 0.46667 0.46667 0.92941 0.47059 0.47059 0.93725 0.47451 0.47451 0.94510 0.47843 0.47843 0.95294 0.48235 0.48235 0.96078 0.48627 0.48627 0.96863 0.49020 0.49020 0.97647 0.49412 0.49412 0.98431 0.49804 0.49804 0.99216 0.50196 0.50196 1.00000 0.50588 0.50588 0.98431 0.50980 0.50980 0.96863 0.51373 0.51373 0.95294 0.51765 0.51765 0.93333 0.52157 0.52157 0.91765 0.52549 0.52549 0.90196 0.52941 0.52941 0.88627 0.53333 0.53333 0.86667 0.53725 0.53725 0.85098 0.54118 0.54118 0.83529 0.54510 0.54510 0.81961 0.54902 0.54902 0.80000 0.55294 0.55294 0.78431 0.55686 0.55686 0.76863 0.56078 0.56078 0.75294 0.56471 0.56471 0.73333 0.56863 0.56863 0.71765 0.57255 0.57255 0.70196 0.57647 0.57647 0.68627 0.58039 0.58039 0.66667 0.58431 0.58431 0.65098 0.58824 0.58824 0.63529 0.59216 0.59216 0.61961 0.59608 0.59608 0.60000 0.60000 0.60000 0.58431 0.60392 0.60392 0.56863 0.60784 0.60784 0.55294 0.61176 0.61176 0.53333 0.61569 0.61569 0.51765 0.61961 0.61961 0.50196 0.62353 0.62353 0.48627 0.62745 0.62745 0.46667 0.63137 0.63137 0.45098 0.63529 0.63529 0.43529 0.63922 0.63922 0.41961 0.64314 0.64314 0.40000 0.64706 0.64706 0.38431 0.65098 0.65098 0.36863 0.65490 0.65490 0.35294 0.65882 0.65882 0.33333 0.66275 0.66275 0.31765 0.66667 0.66667 0.30196 0.67059 0.67059 0.28627 0.67451 0.67451 0.26667 0.67843 0.67843 0.25098 0.68235 0.68235 0.23529 0.68627 0.68627 0.21961 0.69020 0.69020 0.20000 0.69412 0.69412 0.18431 0.69804 0.69804 0.16863 0.70196 0.70196 0.15294 0.70588 0.70588 0.13333 0.70980 0.70980 0.11765 0.71373 0.71373 0.10196 0.71765 0.71765 0.08627 0.72157 0.72157 0.06667 0.72549 0.72549 0.05098 0.72941 0.72941 0.03529 0.73333 0.73333 0.01961 0.73725 0.73725 0.00000 0.74118 0.74118 0.01176 0.74510 0.74510 0.02745 0.74902 0.74902 0.04314 0.75294 0.75294 0.05882 0.75686 0.75686 0.07451 0.76078 0.76078 0.08627 0.76471 0.76471 0.10196 0.76863 0.76863 0.11765 0.77255 0.77255 0.13333 0.77647 0.77647 0.14902 0.78039 0.78039 0.16078 0.78431 0.78431 0.17647 0.78824 0.78824 0.19216 0.79216 0.79216 0.20784 0.79608 0.79608 0.22353 0.80000 0.80000 0.23529 0.80392 0.80392 0.25098 0.80784 0.80784 0.26667 0.81176 0.81176 0.28235 0.81569 0.81569 0.29804 0.81961 0.81961 0.30980 0.82353 0.82353 0.32549 0.82745 0.82745 0.34118 0.83137 0.83137 0.35686 0.83529 0.83529 0.37255 0.83922 0.83922 0.38431 0.84314 0.84314 0.40000 0.84706 0.84706 0.41569 0.85098 0.85098 0.43137 0.85490 0.85490 0.44706 0.85882 0.85882 0.45882 0.86275 0.86275 0.47451 0.86667 0.86667 0.49020 0.87059 0.87059 0.50588 0.87451 0.87451 0.52157 0.87843 0.87843 0.53725 0.88235 0.88235 0.54902 0.88627 0.88627 0.56471 0.89020 0.89020 0.58039 0.89412 0.89412 0.59608 0.89804 0.89804 0.61176 0.90196 0.90196 0.62353 0.90588 0.90588 0.63922 0.90980 0.90980 0.65490 0.91373 0.91373 0.67059 0.91765 0.91765 0.68627 0.92157 0.92157 0.69804 0.92549 0.92549 0.71373 0.92941 0.92941 0.72941 0.93333 0.93333 0.74510 0.93725 0.93725 0.76078 0.94118 0.94118 0.77255 0.94510 0.94510 0.78824 0.94902 0.94902 0.80392 0.95294 0.95294 0.81961 0.95686 0.95686 0.83529 0.96078 0.96078 0.84706 0.96471 0.96471 0.86275 0.96863 0.96863 0.87843 0.97255 0.97255 0.89412 0.97647 0.97647 0.90980 0.98039 0.98039 0.92157 0.98431 0.98431 0.93725 0.98824 0.98824 0.95294 0.99216 0.99216 0.96863 0.99608 0.99608 0.98431 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/idl2.lasc000066400000000000000000000324001215713201500214220ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00000 0.14118 0.00000 0.00000 0.28235 0.00000 0.00000 0.29412 0.00000 0.00000 0.30980 0.00000 0.00000 0.32157 0.00000 0.00000 0.33725 0.00000 0.00000 0.35294 0.00000 0.00000 0.36471 0.00000 0.00000 0.38039 0.00000 0.00000 0.39216 0.00000 0.00000 0.40784 0.00000 0.00000 0.42353 0.00000 0.00000 0.45882 0.00000 0.00000 0.49412 0.00000 0.00000 0.52941 0.00000 0.00000 0.56471 0.00000 0.00000 0.60000 0.00000 0.00000 0.63529 0.00000 0.00000 0.67059 0.00000 0.00000 0.70588 0.00000 0.00000 0.74118 0.00000 0.00000 0.77647 0.00000 0.00000 0.81176 0.00000 0.00000 0.84706 0.00000 0.00000 0.88235 0.00000 0.00000 0.91765 0.00000 0.00000 0.95294 0.00000 0.00000 0.98824 0.00000 0.02353 0.97647 0.00000 0.04706 0.96471 0.00000 0.07059 0.95294 0.00000 0.09412 0.94118 0.00000 0.11765 0.91765 0.00000 0.14118 0.89412 0.00000 0.16471 0.87059 0.00000 0.18824 0.84706 0.00000 0.21176 0.82353 0.00000 0.23529 0.80000 0.00000 0.25882 0.77647 0.00000 0.28235 0.75294 0.00000 0.30588 0.72941 0.00000 0.32941 0.70588 0.00000 0.35294 0.68235 0.00000 0.37647 0.65882 0.00000 0.40000 0.63529 0.00000 0.42353 0.61176 0.00000 0.44706 0.58824 0.00000 0.47059 0.56471 0.00000 0.49412 0.54118 0.00000 0.51765 0.51765 0.00000 0.54118 0.49412 0.00000 0.56471 0.47059 0.00000 0.58824 0.44706 0.00000 0.61176 0.42353 0.00000 0.63529 0.40000 0.00000 0.65882 0.37647 0.00000 0.68235 0.35294 0.00000 0.70588 0.32941 0.00000 0.72941 0.30588 0.00000 0.75294 0.28235 0.00000 0.77647 0.25882 0.00000 0.80000 0.23529 0.00000 0.82353 0.21176 0.00000 0.84706 0.18824 0.00000 0.87059 0.16471 0.00000 0.89412 0.14118 0.00000 0.91765 0.11765 0.00000 0.94118 0.09412 0.00000 0.95294 0.07059 0.00000 0.96471 0.04706 0.00000 0.97647 0.02353 0.00000 0.98824 0.00000 0.00000 0.98824 0.00000 0.00000 0.98824 0.00000 0.00000 0.98824 0.00000 0.00000 0.98824 0.00000 0.00392 0.98431 0.00000 0.01176 0.98039 0.00000 0.01961 0.97647 0.00000 0.02745 0.97255 0.00000 0.03529 0.97255 0.00000 0.03922 0.97255 0.00000 0.04706 0.97255 0.00000 0.05490 0.97255 0.00000 0.06275 0.96863 0.00000 0.07059 0.96471 0.00000 0.07843 0.96078 0.00000 0.08627 0.95686 0.00000 0.09804 0.95294 0.00000 0.10588 0.94902 0.00000 0.11373 0.94510 0.00000 0.12157 0.94118 0.00000 0.13333 0.94118 0.00000 0.13725 0.93725 0.00000 0.14510 0.93333 0.00000 0.15294 0.92941 0.00000 0.16078 0.92549 0.00000 0.16863 0.92549 0.00000 0.17647 0.92549 0.00000 0.18431 0.92549 0.00000 0.19608 0.92157 0.00000 0.20392 0.91765 0.00000 0.21176 0.91373 0.00000 0.21961 0.90980 0.00000 0.23137 0.90588 0.00000 0.23922 0.90196 0.00000 0.24706 0.89804 0.00000 0.25490 0.89412 0.00000 0.26275 0.89412 0.00000 0.26667 0.89412 0.00000 0.27451 0.89412 0.00000 0.28235 0.89412 0.00000 0.29020 0.89020 0.00000 0.29804 0.88627 0.00000 0.30588 0.88235 0.00000 0.31373 0.87843 0.00000 0.32549 0.87451 0.00000 0.33333 0.87059 0.00000 0.34118 0.86667 0.00000 0.34902 0.86275 0.00392 0.36078 0.85882 0.00392 0.36863 0.85490 0.00392 0.37647 0.85098 0.00392 0.38431 0.84706 0.00000 0.39608 0.84706 0.00000 0.40000 0.84706 0.00000 0.40784 0.84706 0.00000 0.41569 0.84706 0.00000 0.42353 0.84314 0.00000 0.43137 0.83922 0.00000 0.43922 0.83529 0.00000 0.44706 0.83137 0.00000 0.45490 0.82745 0.00000 0.46275 0.82353 0.00000 0.47059 0.81961 0.00000 0.47843 0.81569 0.00000 0.49020 0.81176 0.00000 0.49804 0.80784 0.00000 0.50588 0.80392 0.00000 0.51373 0.80000 0.00000 0.52549 0.80000 0.00000 0.52941 0.80000 0.00000 0.53725 0.80000 0.00000 0.54510 0.80000 0.00000 0.55294 0.79608 0.00000 0.56078 0.79216 0.00000 0.56863 0.78824 0.00000 0.57647 0.78431 0.00000 0.58824 0.78039 0.00000 0.59608 0.77647 0.00000 0.60392 0.77255 0.00000 0.61176 0.76863 0.00000 0.62353 0.76863 0.00000 0.62745 0.76863 0.00000 0.63529 0.76863 0.00000 0.63922 0.76863 0.00000 0.64706 0.76471 0.00000 0.65490 0.76078 0.00000 0.66275 0.75686 0.00000 0.67059 0.75294 0.00000 0.68235 0.74902 0.00000 0.69020 0.74510 0.00000 0.69804 0.74118 0.00000 0.70588 0.73725 0.00000 0.71765 0.73333 0.00000 0.72549 0.72941 0.00000 0.73333 0.72549 0.00000 0.74118 0.72157 0.00000 0.75294 0.72157 0.00000 0.75686 0.72157 0.00000 0.76471 0.72157 0.00000 0.77255 0.72157 0.00000 0.78039 0.71765 0.00000 0.78824 0.71373 0.00000 0.79608 0.70980 0.00000 0.80392 0.70588 0.00000 0.81569 0.70196 0.00000 0.82353 0.69804 0.00000 0.83137 0.69412 0.00000 0.83922 0.69020 0.00000 0.84706 0.69020 0.00000 0.85098 0.69020 0.00000 0.85882 0.69020 0.00000 0.86667 0.69020 0.00000 0.87451 0.68627 0.00000 0.88235 0.68235 0.00000 0.89020 0.67843 0.00000 0.89804 0.67451 0.00000 0.90980 0.67059 0.00000 0.91765 0.66667 0.00000 0.92549 0.66275 0.00000 0.93333 0.65882 0.00000 0.94510 0.65490 0.00000 0.95294 0.65098 0.00000 0.96078 0.64706 0.00000 0.96863 0.64314 0.00000 0.98039 0.64314 0.00000 0.98431 0.64314 0.00000 0.98824 0.64314 0.00000 0.99216 0.64314 0.00000 1.00000 0.63922 0.00000 1.00000 0.63529 0.00000 1.00000 0.63137 0.00000 1.00000 0.62745 0.00000 1.00000 0.62353 0.00000 1.00000 0.61961 0.00000 1.00000 0.61569 0.00000 1.00000 0.61176 0.00000 1.00000 0.60784 0.00000 1.00000 0.60392 0.00000 1.00000 0.60000 0.00000 1.00000 0.59608 0.00000 1.00000 0.59608 0.00000 1.00000 0.59608 0.00000 1.00000 0.59608 0.00000 1.00000 0.59608 0.00000 1.00000 0.59216 0.00000 1.00000 0.58824 0.00000 1.00000 0.58431 0.00000 1.00000 0.58039 0.00000 1.00000 0.59216 0.03137 1.00000 0.60392 0.06275 1.00000 0.61569 0.09412 1.00000 0.62745 0.12549 1.00000 0.63922 0.15686 1.00000 0.65098 0.18824 1.00000 0.66275 0.21961 1.00000 0.67451 0.25098 1.00000 0.69020 0.28235 1.00000 0.70588 0.31373 1.00000 0.72157 0.34510 1.00000 0.73725 0.37647 1.00000 0.74902 0.40784 1.00000 0.76078 0.43922 1.00000 0.77255 0.47059 1.00000 0.78431 0.50196 1.00000 0.79608 0.52941 1.00000 0.80784 0.55686 1.00000 0.81961 0.58431 1.00000 0.83137 0.61176 1.00000 0.84314 0.64314 1.00000 0.85490 0.67451 1.00000 0.86667 0.70588 1.00000 0.87843 0.73725 1.00000 0.89412 0.76863 1.00000 0.90980 0.80000 1.00000 0.92549 0.83137 1.00000 0.94118 0.86275 1.00000 0.95294 0.89412 1.00000 0.96471 0.92549 1.00000 0.97647 0.95686 1.00000 0.98824 0.98824 1.00000 0.99216 0.99216 1.00000 0.99608 0.99608 1.00000 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/idl4.lasc000066400000000000000000000324001215713201500214240ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00784 0.00000 0.00000 0.01569 0.00000 0.00000 0.02353 0.00000 0.00000 0.03137 0.00000 0.00000 0.03922 0.00000 0.00000 0.04706 0.00000 0.00000 0.05490 0.00000 0.00000 0.06275 0.00000 0.00000 0.07059 0.00000 0.00000 0.07843 0.00000 0.00000 0.08627 0.00000 0.00000 0.09804 0.00000 0.00000 0.10588 0.00000 0.00000 0.11373 0.00000 0.00000 0.12157 0.00000 0.00000 0.12941 0.00000 0.00000 0.13725 0.00000 0.00000 0.14510 0.00000 0.00000 0.15294 0.00000 0.00000 0.16078 0.00000 0.00000 0.16863 0.00000 0.00000 0.17647 0.00000 0.00000 0.18431 0.00000 0.00000 0.19608 0.00000 0.00000 0.20392 0.00000 0.00000 0.21176 0.00000 0.00000 0.21961 0.00000 0.00000 0.22745 0.00000 0.00000 0.23529 0.00000 0.00000 0.24314 0.00000 0.00000 0.25098 0.00000 0.00000 0.25882 0.00000 0.01176 0.26667 0.00000 0.02353 0.27451 0.00000 0.03529 0.28235 0.00000 0.04706 0.29412 0.00000 0.05882 0.30196 0.00000 0.07059 0.30980 0.00000 0.08235 0.31765 0.00000 0.09804 0.32549 0.00000 0.10980 0.33333 0.00000 0.12157 0.34118 0.00000 0.13333 0.34902 0.00000 0.14510 0.35686 0.00000 0.15686 0.36471 0.00000 0.16863 0.37255 0.00000 0.18039 0.38039 0.00000 0.19608 0.39216 0.00000 0.20784 0.39216 0.00000 0.21961 0.39216 0.00000 0.23137 0.39216 0.00000 0.24314 0.39216 0.00000 0.25490 0.39216 0.00000 0.26667 0.39216 0.00000 0.27843 0.39216 0.00000 0.29412 0.39216 0.00000 0.30588 0.39216 0.00000 0.31765 0.39216 0.00000 0.32941 0.39216 0.00000 0.34118 0.39216 0.00000 0.35294 0.39216 0.00000 0.36471 0.39216 0.00000 0.37647 0.39216 0.00000 0.39216 0.39216 0.00000 0.40392 0.39216 0.00000 0.41569 0.39216 0.00000 0.42745 0.39216 0.00000 0.43922 0.39216 0.00000 0.45098 0.39216 0.00000 0.46275 0.39216 0.00000 0.47451 0.39216 0.00000 0.49020 0.39216 0.00000 0.50196 0.39216 0.00000 0.51373 0.39216 0.00000 0.52549 0.39216 0.00000 0.53725 0.39216 0.00000 0.54902 0.39216 0.00000 0.56078 0.39216 0.00000 0.57255 0.39216 0.00000 0.58824 0.39216 0.00000 0.58824 0.37647 0.00000 0.58824 0.36471 0.00000 0.58824 0.35294 0.00000 0.58824 0.34118 0.00000 0.58824 0.32941 0.00000 0.58824 0.31765 0.00000 0.58824 0.30588 0.00000 0.58824 0.29412 0.00000 0.58824 0.27843 0.00000 0.58824 0.26667 0.00000 0.58824 0.25490 0.00000 0.58824 0.24314 0.00000 0.58824 0.23137 0.00000 0.58824 0.21961 0.00000 0.58824 0.20784 0.00000 0.58824 0.19608 0.00000 0.58431 0.18039 0.00000 0.58039 0.16863 0.00000 0.58039 0.15686 0.00000 0.57647 0.14510 0.00000 0.57255 0.13333 0.00000 0.57255 0.12157 0.00000 0.56863 0.10980 0.00000 0.56863 0.09804 0.00000 0.56471 0.08235 0.00000 0.56078 0.07059 0.00000 0.56078 0.05882 0.00000 0.55686 0.04706 0.00000 0.55294 0.03529 0.00000 0.55294 0.02353 0.00000 0.54902 0.01176 0.00000 0.54902 0.00000 0.02745 0.53725 0.00000 0.05882 0.52941 0.00000 0.08627 0.51765 0.00000 0.11765 0.50980 0.00000 0.14510 0.49804 0.00000 0.17647 0.49020 0.00000 0.20392 0.47843 0.00000 0.23529 0.47059 0.00000 0.26275 0.45882 0.00000 0.29412 0.45098 0.00000 0.32157 0.43922 0.00000 0.35294 0.43137 0.00000 0.38039 0.41961 0.00000 0.41176 0.41176 0.00000 0.43922 0.40000 0.00000 0.47059 0.39216 0.00000 0.49020 0.36471 0.00000 0.50980 0.34118 0.00000 0.52941 0.31765 0.00000 0.54902 0.29412 0.00000 0.56863 0.26667 0.00000 0.58824 0.24314 0.00000 0.60784 0.21961 0.00000 0.62745 0.19608 0.00000 0.64706 0.16863 0.00000 0.66667 0.14510 0.00000 0.68627 0.12157 0.00000 0.70588 0.09804 0.00000 0.72549 0.07059 0.00000 0.74510 0.04706 0.00000 0.76471 0.02353 0.00000 0.78431 0.00000 0.00000 0.78431 0.00784 0.00000 0.78824 0.01569 0.00000 0.78824 0.02353 0.00000 0.79216 0.03529 0.00000 0.79216 0.04314 0.00000 0.79608 0.05098 0.00000 0.79608 0.06275 0.00000 0.80000 0.07059 0.00000 0.80000 0.07843 0.00000 0.80392 0.09020 0.00000 0.80392 0.09804 0.00000 0.80784 0.10588 0.00000 0.80784 0.11373 0.00000 0.81176 0.12549 0.00000 0.81176 0.13333 0.00000 0.81569 0.14118 0.00000 0.81569 0.15294 0.00000 0.81961 0.16078 0.00000 0.81961 0.16863 0.00000 0.82353 0.18039 0.00000 0.82353 0.18824 0.00000 0.82745 0.19608 0.00000 0.82745 0.20784 0.00000 0.83137 0.21569 0.00000 0.83137 0.22353 0.00000 0.83529 0.23137 0.00000 0.83529 0.24314 0.00000 0.83922 0.25098 0.00000 0.83922 0.25882 0.00000 0.84314 0.27059 0.00000 0.84314 0.27843 0.00000 0.84706 0.28627 0.00000 0.84706 0.29804 0.00000 0.85098 0.30588 0.00000 0.85098 0.31373 0.00000 0.85490 0.32549 0.00000 0.85490 0.33333 0.00000 0.85882 0.34118 0.00000 0.85882 0.34902 0.00000 0.86275 0.36078 0.00000 0.86275 0.36863 0.00000 0.86667 0.37647 0.00000 0.86667 0.38824 0.00000 0.87059 0.39608 0.00000 0.87059 0.40392 0.00000 0.87451 0.41569 0.00000 0.87451 0.42353 0.00000 0.87843 0.43137 0.00000 0.87843 0.44314 0.00000 0.88235 0.45098 0.00000 0.88235 0.45882 0.00000 0.88627 0.46667 0.00000 0.88627 0.47843 0.00000 0.89020 0.48627 0.00000 0.89020 0.49412 0.00000 0.89412 0.50588 0.00000 0.89412 0.51373 0.00000 0.89804 0.52157 0.00000 0.89804 0.53333 0.00000 0.90196 0.54118 0.00000 0.90196 0.54902 0.00000 0.90588 0.55686 0.00000 0.90588 0.56863 0.00000 0.90980 0.57647 0.00000 0.90980 0.58431 0.00000 0.91373 0.59608 0.00000 0.91373 0.60392 0.00000 0.91765 0.61176 0.00000 0.91765 0.62353 0.00000 0.92157 0.63137 0.00000 0.92157 0.63922 0.00000 0.92549 0.65098 0.00000 0.92549 0.65882 0.00000 0.92941 0.66667 0.00000 0.92941 0.67451 0.00000 0.93333 0.68627 0.00000 0.93333 0.69412 0.00000 0.93725 0.70196 0.00000 0.93725 0.71373 0.00000 0.94118 0.72157 0.00000 0.94118 0.72941 0.00000 0.94510 0.74118 0.00000 0.94510 0.74902 0.00000 0.94902 0.75686 0.00000 0.94902 0.76863 0.00000 0.95294 0.77647 0.00000 0.95294 0.78431 0.00000 0.95686 0.79216 0.00000 0.95686 0.80392 0.00000 0.96078 0.81176 0.00000 0.96078 0.81961 0.00000 0.96471 0.83137 0.00000 0.96471 0.83922 0.00000 0.96863 0.84706 0.00000 0.96863 0.85882 0.00000 0.97255 0.86667 0.00000 0.97255 0.87451 0.00000 0.97647 0.88627 0.00000 0.97647 0.89412 0.00000 0.98039 0.90196 0.00000 0.98039 0.90980 0.00000 0.98431 0.92157 0.00000 0.98431 0.92941 0.00000 0.98824 0.93725 0.00000 0.98824 0.94902 0.00000 0.99216 0.95686 0.00000 0.99216 0.96471 0.00000 0.99608 0.97647 0.00000 0.99608 0.98431 0.00000 1.00000 0.99216 0.00000 1.00000 1.00000 0.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/idl5.lasc000066400000000000000000000324001215713201500214250ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00000 0.00000 0.01961 0.00000 0.00000 0.03922 0.00000 0.00000 0.05882 0.00000 0.00000 0.07843 0.00000 0.00000 0.10196 0.00000 0.00000 0.12157 0.00000 0.00000 0.14118 0.00000 0.00000 0.16078 0.00000 0.00000 0.18039 0.00000 0.00000 0.20392 0.00000 0.00000 0.22353 0.00000 0.00000 0.24314 0.00000 0.00000 0.26275 0.00000 0.00000 0.28235 0.00000 0.00000 0.30588 0.00000 0.00000 0.32549 0.00000 0.00000 0.34510 0.00000 0.00000 0.36471 0.00000 0.00000 0.38431 0.00000 0.00000 0.40784 0.00000 0.00000 0.42745 0.00000 0.00000 0.44706 0.00000 0.00000 0.46667 0.00000 0.00000 0.48627 0.00000 0.00000 0.50980 0.00000 0.00000 0.52941 0.00000 0.00000 0.54902 0.00000 0.00000 0.56863 0.00000 0.00000 0.58824 0.00000 0.00000 0.61176 0.00000 0.00000 0.63137 0.00000 0.00000 0.65098 0.00000 0.00000 0.67059 0.00000 0.00000 0.69020 0.00000 0.00000 0.71373 0.00000 0.00000 0.73333 0.00000 0.00000 0.75294 0.00000 0.00000 0.77255 0.00000 0.00000 0.79216 0.00000 0.00000 0.81569 0.00000 0.00000 0.83529 0.00000 0.00000 0.85490 0.00000 0.00000 0.87451 0.00000 0.00000 0.89412 0.00000 0.00000 0.91765 0.00000 0.00000 0.93725 0.00000 0.00000 0.95686 0.01569 0.00000 0.97647 0.03529 0.00000 1.00000 0.05490 0.00000 0.98039 0.07451 0.00000 0.96078 0.09020 0.00000 0.93725 0.10980 0.00000 0.91765 0.12941 0.00000 0.89412 0.14902 0.00000 0.87451 0.16471 0.00000 0.85490 0.18431 0.00000 0.83137 0.20392 0.00000 0.81176 0.22353 0.00000 0.78824 0.23922 0.00000 0.76863 0.25882 0.00000 0.74510 0.27843 0.00000 0.72549 0.29804 0.00000 0.70588 0.31765 0.00000 0.68235 0.31765 0.00000 0.66275 0.31765 0.00000 0.63922 0.31765 0.00000 0.61961 0.31765 0.00000 0.59608 0.31765 0.00000 0.57647 0.31765 0.00000 0.55686 0.31765 0.00000 0.53333 0.31373 0.00000 0.51373 0.31373 0.00000 0.49020 0.31373 0.00000 0.47059 0.31373 0.00000 0.44706 0.31373 0.00000 0.42745 0.31373 0.00000 0.40784 0.31373 0.00000 0.38431 0.30980 0.00000 0.36471 0.32941 0.00000 0.34118 0.34902 0.00000 0.32157 0.36863 0.00000 0.29804 0.38824 0.00000 0.27843 0.40784 0.00000 0.25882 0.42745 0.00000 0.23529 0.44706 0.00000 0.21569 0.46667 0.00000 0.19216 0.48627 0.00000 0.17255 0.50588 0.00000 0.14902 0.52549 0.00000 0.12941 0.54510 0.00000 0.10980 0.56471 0.00000 0.08627 0.58431 0.00000 0.06667 0.60392 0.00000 0.04314 0.62353 0.00000 0.02353 0.64314 0.00000 0.00000 0.66275 0.00000 0.00000 0.68235 0.00000 0.00000 0.70588 0.00000 0.00000 0.72549 0.00000 0.00000 0.74510 0.00000 0.00000 0.76863 0.00000 0.00000 0.78824 0.00000 0.00000 0.80784 0.00000 0.00000 0.83137 0.00000 0.00000 0.85098 0.00000 0.00000 0.87059 0.00000 0.00000 0.89412 0.00000 0.00000 0.91373 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.01961 0.00000 1.00000 0.03922 0.00000 1.00000 0.06275 0.00000 1.00000 0.08235 0.00000 1.00000 0.10588 0.00000 1.00000 0.12549 0.00000 1.00000 0.14510 0.00000 1.00000 0.16863 0.00000 1.00000 0.18824 0.00000 1.00000 0.21176 0.00000 1.00000 0.23137 0.00000 1.00000 0.25098 0.00000 1.00000 0.27451 0.00000 1.00000 0.29412 0.00000 1.00000 0.31765 0.00000 1.00000 0.33333 0.01569 1.00000 0.35294 0.03529 1.00000 0.37255 0.05490 1.00000 0.39216 0.07451 1.00000 0.41176 0.09412 1.00000 0.42745 0.10980 1.00000 0.44706 0.12941 1.00000 0.46667 0.14902 1.00000 0.48627 0.16863 1.00000 0.50588 0.18824 1.00000 0.52549 0.20784 1.00000 0.54118 0.22353 1.00000 0.56078 0.24314 1.00000 0.58039 0.26275 1.00000 0.60000 0.28235 1.00000 0.61961 0.30196 1.00000 0.63922 0.32157 1.00000 0.63922 0.30196 1.00000 0.63922 0.27843 1.00000 0.63922 0.25490 1.00000 0.63922 0.23137 1.00000 0.63922 0.20784 1.00000 0.63922 0.18431 1.00000 0.63922 0.16078 1.00000 0.63922 0.14118 1.00000 0.63922 0.11765 1.00000 0.63922 0.09412 1.00000 0.63922 0.07059 1.00000 0.63922 0.04706 1.00000 0.63922 0.02353 1.00000 0.63922 0.00000 1.00000 0.63922 0.00000 1.00000 0.63922 0.00000 1.00000 0.63922 0.00000 0.97255 0.63922 0.00000 0.94118 0.63922 0.00000 0.90980 0.63922 0.00000 0.88235 0.63922 0.00000 0.85098 0.63922 0.00000 0.81961 0.63922 0.00000 0.79216 0.63922 0.00000 0.76078 0.63922 0.00000 0.72941 0.63922 0.00000 0.70196 0.63922 0.00000 0.67059 0.63922 0.00000 0.63922 0.63922 0.00000 0.65882 0.63922 0.00000 0.67843 0.63922 0.00000 0.69804 0.66275 0.01176 0.71765 0.68627 0.02353 0.73725 0.70980 0.03529 0.75686 0.73333 0.04706 0.77647 0.75686 0.06275 0.79608 0.78039 0.07451 0.81961 0.80392 0.08627 0.83922 0.83137 0.09804 0.85882 0.85490 0.11373 0.87843 0.87843 0.12549 0.89804 0.90196 0.13725 0.91765 0.92549 0.14902 0.93725 0.94902 0.16078 0.95686 0.97255 0.17647 0.97647 1.00000 0.18824 1.00000 1.00000 0.20000 1.00000 1.00000 0.21176 1.00000 1.00000 0.22745 1.00000 1.00000 0.23922 1.00000 1.00000 0.25098 1.00000 1.00000 0.26275 1.00000 1.00000 0.27843 1.00000 1.00000 0.29020 1.00000 1.00000 0.30196 1.00000 1.00000 0.31373 1.00000 1.00000 0.32549 1.00000 1.00000 0.34118 1.00000 1.00000 0.35294 1.00000 1.00000 0.36471 1.00000 1.00000 0.37647 1.00000 1.00000 0.39216 1.00000 1.00000 0.40392 1.00000 1.00000 0.41569 1.00000 1.00000 0.42745 1.00000 1.00000 0.43922 1.00000 1.00000 0.45490 1.00000 1.00000 0.46667 1.00000 1.00000 0.47843 1.00000 1.00000 0.49020 1.00000 1.00000 0.50588 1.00000 1.00000 0.51765 1.00000 1.00000 0.52941 1.00000 1.00000 0.54118 1.00000 1.00000 0.55686 1.00000 1.00000 0.56863 1.00000 1.00000 0.58039 1.00000 1.00000 0.59216 1.00000 1.00000 0.60392 1.00000 1.00000 0.61961 1.00000 1.00000 0.63137 1.00000 1.00000 0.64314 1.00000 1.00000 0.65490 1.00000 1.00000 0.67059 1.00000 1.00000 0.68235 1.00000 1.00000 0.69412 1.00000 1.00000 0.70588 1.00000 1.00000 0.71765 1.00000 1.00000 0.73333 1.00000 1.00000 0.74510 1.00000 1.00000 0.75686 1.00000 1.00000 0.76863 1.00000 1.00000 0.78431 1.00000 1.00000 0.79608 1.00000 1.00000 0.80784 1.00000 1.00000 0.81961 1.00000 1.00000 0.83529 1.00000 1.00000 0.84706 1.00000 1.00000 0.85882 1.00000 1.00000 0.87059 1.00000 1.00000 0.88235 1.00000 1.00000 0.89804 1.00000 1.00000 0.90980 1.00000 1.00000 0.92157 1.00000 1.00000 0.93333 1.00000 1.00000 0.94902 1.00000 1.00000 0.96078 1.00000 1.00000 0.97255 1.00000 1.00000 0.98431 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/idl6.lasc000066400000000000000000000324001215713201500214260ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.01176 0.00000 0.00000 0.02745 0.00000 0.00000 0.04314 0.00000 0.00000 0.05882 0.00000 0.00000 0.07451 0.00000 0.00000 0.08627 0.00000 0.00000 0.10196 0.00000 0.00000 0.11765 0.00000 0.00000 0.13333 0.00000 0.00000 0.14902 0.00000 0.00000 0.16078 0.00000 0.00000 0.17647 0.00000 0.00000 0.19216 0.00000 0.00000 0.20784 0.00000 0.00000 0.22353 0.00000 0.00000 0.23529 0.00000 0.00000 0.25098 0.00000 0.00000 0.26667 0.00000 0.00000 0.28235 0.00000 0.00000 0.29804 0.00000 0.00000 0.30980 0.00000 0.00000 0.32549 0.00000 0.00000 0.34118 0.00000 0.00000 0.35686 0.00000 0.00000 0.37255 0.00000 0.00000 0.38431 0.00000 0.00000 0.40000 0.00000 0.00000 0.41569 0.00000 0.00000 0.43137 0.00000 0.00000 0.44706 0.00000 0.00000 0.45882 0.00000 0.00000 0.47451 0.00000 0.00000 0.49020 0.00000 0.00000 0.50588 0.00000 0.00000 0.52157 0.00000 0.00000 0.53725 0.00000 0.00000 0.54902 0.00000 0.00000 0.56471 0.00000 0.00000 0.58039 0.00000 0.00000 0.59608 0.00000 0.00000 0.61176 0.00000 0.00000 0.62353 0.00000 0.00000 0.63922 0.00000 0.00000 0.65490 0.00000 0.00000 0.67059 0.00000 0.00000 0.68627 0.00000 0.00000 0.69804 0.00000 0.00000 0.71373 0.00000 0.00000 0.72941 0.00000 0.00000 0.74510 0.00000 0.00000 0.76078 0.00000 0.00000 0.77255 0.00000 0.00000 0.78824 0.00000 0.00000 0.80392 0.00000 0.00000 0.81961 0.00000 0.00000 0.83529 0.00000 0.00000 0.84706 0.00000 0.00000 0.86275 0.00000 0.00000 0.87843 0.00000 0.00000 0.89412 0.00000 0.00000 0.90980 0.00000 0.00000 0.92157 0.00000 0.00000 0.93725 0.00000 0.00000 0.95294 0.00000 0.00000 0.96863 0.01176 0.00000 0.98431 0.02745 0.00000 1.00000 0.04314 0.00000 0.98431 0.05882 0.00000 0.96863 0.07451 0.00000 0.95294 0.09020 0.00000 0.93725 0.10588 0.00000 0.92157 0.12157 0.00000 0.90196 0.13725 0.00000 0.88627 0.15294 0.00000 0.87059 0.16863 0.00000 0.85490 0.18431 0.00000 0.83922 0.20000 0.00000 0.82353 0.21569 0.00000 0.80392 0.23137 0.00000 0.78824 0.24706 0.00000 0.77255 0.26275 0.00000 0.75686 0.27843 0.00000 0.74118 0.29412 0.00000 0.72157 0.30980 0.00000 0.70588 0.32549 0.00000 0.69020 0.34118 0.00000 0.67451 0.35686 0.00000 0.65882 0.37255 0.00000 0.64314 0.38824 0.00000 0.62353 0.40392 0.00000 0.60784 0.41961 0.00000 0.59216 0.43529 0.00000 0.57647 0.45098 0.00000 0.56078 0.46667 0.00000 0.54118 0.48235 0.00000 0.52549 0.49804 0.00000 0.50980 0.51373 0.00000 0.49412 0.52941 0.00000 0.47843 0.54510 0.00000 0.46275 0.56078 0.00000 0.44314 0.57647 0.00000 0.42745 0.59216 0.00000 0.41176 0.60784 0.00000 0.39608 0.62353 0.00000 0.38039 0.63922 0.00000 0.36078 0.65490 0.00000 0.34510 0.67059 0.00000 0.32941 0.68627 0.00000 0.31373 0.70196 0.00000 0.29804 0.71765 0.00000 0.28235 0.73333 0.00000 0.26275 0.74902 0.00000 0.24706 0.76471 0.00000 0.23137 0.78039 0.00000 0.21569 0.79608 0.00000 0.20000 0.81176 0.00000 0.18039 0.82745 0.00000 0.16471 0.84314 0.00000 0.14902 0.85882 0.00000 0.13333 0.87451 0.00000 0.11765 0.89020 0.00000 0.10196 0.90588 0.00000 0.08235 0.92157 0.00000 0.06667 0.93725 0.00000 0.05098 0.95294 0.00000 0.03529 0.96863 0.00000 0.01961 0.98431 0.01176 0.00000 1.00000 0.02745 0.00000 0.98431 0.04314 0.00000 0.96863 0.05882 0.00000 0.95294 0.07451 0.00000 0.93725 0.09020 0.00000 0.92157 0.10588 0.00000 0.90588 0.11765 0.00000 0.89020 0.13333 0.00000 0.87451 0.14902 0.00000 0.85882 0.16471 0.00000 0.84314 0.18039 0.00000 0.82745 0.19608 0.00000 0.81176 0.21176 0.00000 0.79608 0.22353 0.00000 0.78039 0.23922 0.00000 0.76471 0.25490 0.00000 0.74902 0.27059 0.00000 0.73333 0.28627 0.00000 0.71765 0.30196 0.00000 0.70196 0.31765 0.00000 0.68627 0.33333 0.00000 0.66667 0.34510 0.00000 0.65098 0.36078 0.00000 0.63529 0.37647 0.00000 0.61961 0.39216 0.00000 0.60392 0.40784 0.00000 0.58824 0.42353 0.00000 0.57255 0.43922 0.00000 0.55686 0.45098 0.00000 0.54118 0.46667 0.00000 0.52549 0.48235 0.00000 0.50980 0.49804 0.00000 0.49412 0.51373 0.00000 0.47843 0.52941 0.00000 0.46275 0.54510 0.00000 0.44706 0.55686 0.00000 0.43137 0.57255 0.00000 0.41569 0.58824 0.00000 0.40000 0.60392 0.00000 0.38431 0.61961 0.00000 0.36863 0.63529 0.00000 0.35294 0.65098 0.00000 0.33333 0.66667 0.00000 0.31765 0.67843 0.00000 0.30196 0.69412 0.00000 0.28627 0.70980 0.00000 0.27059 0.72549 0.00000 0.25490 0.74118 0.00000 0.23922 0.75686 0.00000 0.22353 0.77255 0.00000 0.20784 0.78431 0.00000 0.19216 0.80000 0.00000 0.17647 0.81569 0.00000 0.16078 0.83137 0.00000 0.14510 0.84706 0.00000 0.12941 0.86275 0.00000 0.11373 0.87843 0.00000 0.09804 0.89020 0.00000 0.08235 0.90588 0.00000 0.06667 0.92157 0.00000 0.05098 0.93725 0.00000 0.03529 0.95294 0.00000 0.01961 0.96863 0.00000 0.00000 0.98431 0.00000 0.00000 1.00000 0.00000 0.00000 0.98431 0.00000 0.00000 0.96863 0.00000 0.00000 0.95294 0.00000 0.00000 0.93725 0.00000 0.00000 0.92157 0.00000 0.00000 0.90588 0.00000 0.00000 0.89020 0.00000 0.00000 0.87451 0.00000 0.00000 0.85882 0.00000 0.00000 0.84314 0.00000 0.00000 0.82745 0.00000 0.00000 0.81176 0.00000 0.00000 0.79608 0.00000 0.00000 0.78039 0.00000 0.00000 0.76471 0.00000 0.00000 0.74902 0.00000 0.00000 0.73333 0.00000 0.00000 0.71765 0.00000 0.00000 0.70196 0.00000 0.00000 0.68627 0.00000 0.00000 0.66667 0.00000 0.00000 0.65098 0.00000 0.00000 0.63529 0.00000 0.00000 0.61961 0.00000 0.00000 0.60392 0.00000 0.00000 0.58824 0.00000 0.00000 0.57255 0.00000 0.00000 0.55686 0.00000 0.00000 0.54118 0.00000 0.00000 0.52549 0.00000 0.00000 0.50980 0.00000 0.00000 0.49412 0.00000 0.00000 0.47843 0.00000 0.00000 0.46275 0.00000 0.00000 0.44706 0.00000 0.00000 0.43137 0.00000 0.00000 0.41569 0.00000 0.00000 0.40000 0.00000 0.00000 0.38431 0.00000 0.00000 0.36863 0.00000 0.00000 0.35294 0.00000 0.00000 0.33333 0.00000 0.00000 0.31765 0.00000 0.00000 0.30196 0.00000 0.00000 0.28627 0.00000 0.00000 0.27059 0.00000 0.00000 0.25490 0.00000 0.00000 0.23922 0.00000 0.00000 0.22353 0.00000 0.00000 0.20784 0.00000 0.00000 0.19216 0.00000 0.00000 0.17647 0.00000 0.00000 0.16078 0.00000 0.00000 0.14510 0.00000 0.00000 0.12941 0.00000 0.00000 0.11373 0.00000 0.00000 0.09804 0.00000 0.00000 0.08235 0.00000 0.00000 0.06667 0.00000 0.00000 0.05098 0.00000 0.00000 0.03529 0.00000 0.00000 0.01961 0.00000 0.00000 0.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/isophot.lasc000066400000000000000000000324001215713201500222550ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.03922 0.00000 0.00000 0.07843 0.00000 0.00000 0.11765 0.00000 0.00000 0.15686 0.00000 0.00000 0.19608 0.00000 0.00000 0.23529 0.00000 0.00000 0.27843 0.00000 0.00000 0.31765 0.00000 0.00000 0.35686 0.00000 0.00000 0.39608 0.00000 0.00000 0.43529 0.00000 0.00000 0.47451 0.00000 0.00000 0.51765 0.00000 0.00000 0.55686 0.00000 0.00000 0.59608 0.00000 0.00000 0.63529 0.00000 0.00000 0.67451 0.00000 0.00000 0.71765 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 0.00000 0.00000 0.87843 0.00000 0.00000 0.91765 0.00000 0.00000 0.95686 0.00000 0.00000 1.00000 0.00000 0.03137 1.00000 0.00000 0.06275 1.00000 0.00000 0.09412 1.00000 0.00000 0.12549 1.00000 0.00000 0.15686 1.00000 0.00000 0.18824 1.00000 0.00000 0.21961 1.00000 0.00000 0.25490 1.00000 0.00000 0.28627 1.00000 0.00000 0.31765 1.00000 0.00000 0.34902 1.00000 0.00000 0.38039 1.00000 0.00000 0.41176 1.00000 0.00000 0.44314 1.00000 0.00000 0.47843 1.00000 0.00000 0.49804 1.00000 0.00000 0.51765 1.00000 0.00000 0.53725 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 0.00000 0.61961 1.00000 0.00000 0.63922 1.00000 0.00000 0.65882 1.00000 0.00000 0.67843 1.00000 0.00000 0.70196 1.00000 0.00000 0.72157 1.00000 0.00000 0.74118 1.00000 0.00000 0.76078 1.00000 0.00000 0.78431 1.00000 0.00000 0.79608 1.00000 0.00000 0.81176 1.00000 0.00000 0.82353 1.00000 0.00000 0.83922 1.00000 0.00000 0.85490 1.00000 0.00000 0.86667 1.00000 0.00000 0.88235 1.00000 0.00000 0.89412 1.00000 0.00000 0.90980 1.00000 0.00000 0.92549 1.00000 0.00000 0.93725 1.00000 0.00000 0.95294 1.00000 0.00000 0.96863 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 0.00000 1.00000 0.96078 0.00000 1.00000 0.94118 0.00000 1.00000 0.92157 0.00000 1.00000 0.90196 0.00000 1.00000 0.88235 0.00000 1.00000 0.86275 0.00000 1.00000 0.84314 0.00000 1.00000 0.82353 0.00000 1.00000 0.80392 0.00000 1.00000 0.78431 0.00000 1.00000 0.76471 0.00000 1.00000 0.74510 0.00000 1.00000 0.72549 0.00000 1.00000 0.70588 0.00000 1.00000 0.65490 0.00000 1.00000 0.60784 0.00000 1.00000 0.56078 0.00000 1.00000 0.51373 0.00000 1.00000 0.46667 0.00000 1.00000 0.41961 0.00000 1.00000 0.37255 0.00000 1.00000 0.32549 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 0.00000 1.00000 0.13725 0.00000 1.00000 0.09020 0.00000 1.00000 0.04314 0.00000 1.00000 0.00000 0.04706 1.00000 0.00000 0.09412 1.00000 0.00000 0.14118 1.00000 0.00000 0.18824 1.00000 0.00000 0.23529 1.00000 0.00000 0.28235 1.00000 0.00000 0.32941 1.00000 0.00000 0.37647 1.00000 0.00000 0.42353 1.00000 0.00000 0.47059 1.00000 0.00000 0.51765 1.00000 0.00000 0.56471 1.00000 0.00000 0.61176 1.00000 0.00000 0.65882 1.00000 0.00000 0.70588 1.00000 0.00000 0.72549 1.00000 0.00000 0.74510 1.00000 0.00000 0.76471 1.00000 0.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 0.84314 1.00000 0.00000 0.86275 1.00000 0.00000 0.88235 1.00000 0.00000 0.90196 1.00000 0.00000 0.92157 1.00000 0.00000 0.94118 1.00000 0.00000 0.96078 1.00000 0.00000 0.98039 1.00000 0.00000 1.00000 1.00000 0.00000 0.99608 0.98039 0.00000 0.99608 0.96078 0.00000 0.99608 0.94118 0.00000 0.99608 0.92549 0.00000 0.99216 0.90588 0.00000 0.99216 0.88627 0.00000 0.99216 0.87059 0.00000 0.99216 0.85098 0.00000 0.98824 0.83137 0.00000 0.98824 0.81569 0.00000 0.98824 0.79608 0.00000 0.98824 0.77647 0.00000 0.98824 0.76078 0.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 0.98824 0.69020 0.00000 0.98824 0.67059 0.00000 0.98824 0.65490 0.00000 0.98824 0.63922 0.00000 0.98824 0.61961 0.00000 0.99216 0.60392 0.00000 0.99216 0.58824 0.00000 0.99216 0.56863 0.00000 0.99216 0.55294 0.00000 0.99608 0.53725 0.00000 0.99608 0.51765 0.00000 0.99608 0.50196 0.00000 0.99608 0.48627 0.00000 1.00000 0.47059 0.00000 1.00000 0.43529 0.00000 1.00000 0.40392 0.00000 1.00000 0.37255 0.00000 1.00000 0.34118 0.00000 1.00000 0.30980 0.00000 1.00000 0.27843 0.00000 1.00000 0.24706 0.00000 1.00000 0.21569 0.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 0.09020 0.00000 1.00000 0.05882 0.00000 1.00000 0.02745 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.04706 1.00000 0.00000 0.09412 1.00000 0.00000 0.14118 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 0.00000 0.32941 1.00000 0.00000 0.37647 1.00000 0.00000 0.42353 1.00000 0.00000 0.47059 1.00000 0.00000 0.51765 1.00000 0.00000 0.56471 1.00000 0.00000 0.61176 1.00000 0.00000 0.65882 1.00000 0.00000 0.70588 1.00000 0.00000 0.72549 1.00000 0.00000 0.74902 1.00000 0.00000 0.77255 1.00000 0.00000 0.79608 1.00000 0.00000 0.81569 1.00000 0.00000 0.83922 1.00000 0.00000 0.86275 1.00000 0.00000 0.88627 1.00000 0.00000 0.90588 1.00000 0.00000 0.92941 1.00000 0.00000 0.95294 1.00000 0.00000 0.97647 1.00000 0.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 0.14118 1.00000 1.00000 0.17647 1.00000 1.00000 0.21176 1.00000 1.00000 0.25098 1.00000 1.00000 0.28627 1.00000 1.00000 0.32157 1.00000 1.00000 0.36078 1.00000 1.00000 0.39608 1.00000 1.00000 0.43137 1.00000 1.00000 0.47059 1.00000 1.00000 0.48627 1.00000 1.00000 0.50588 1.00000 1.00000 0.52157 1.00000 1.00000 0.54118 1.00000 1.00000 0.56078 1.00000 1.00000 0.57647 1.00000 1.00000 0.59608 1.00000 1.00000 0.61176 1.00000 1.00000 0.63137 1.00000 1.00000 0.65098 1.00000 1.00000 0.66667 1.00000 1.00000 0.68627 1.00000 1.00000 0.70588 1.00000 1.00000 0.74510 1.00000 1.00000 0.78824 1.00000 1.00000 0.83137 1.00000 1.00000 0.87059 1.00000 1.00000 0.91373 1.00000 1.00000 0.95686 1.00000 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/itt.fmt000066400000000000000000000000441215713201500212330ustar00rootroot00000000000000DEFINE/FIELD 15 26 R F12.5 :ITT END skycat-3.1.2-starlink-1b/rtd/colormaps/ittasc.prg000066400000000000000000000010771215713201500217330ustar00rootroot00000000000000! @(#)ittasc.prg 8.1.1.1 (ESO-IPG) 8/31/94 15:51:57 ! ++++++++++++++ ! ! Midas procedure ittasc.prg ! to convert Midas ITT to ASCII file which can later be used to regenerate ! that ITT via: CREATE/TABLE using itt.fmt as Format file ! ! xyz.itt -> xyz.iasc ! ! KB 910315 ! ! ++++++++++++++ ! ASSIGN/PRINT FILE itt.lis ! -COPY 'P1'.itt temp.tbl NAME/COLUMN temp :ITT F12.5 PRINT/TABLE temp :ITT ! $ sh $MIDASHOME/$MIDVERS/systab/ascii/display/ittasc.sh itt.lis 'P1'.iasc ASSIGN/PRINT T ! $ rm itt.lis $ rm temp.tbl ! WRITE/OUT table 'P1'.itt processed ... skycat-3.1.2-starlink-1b/rtd/colormaps/ittasc.sh000066400000000000000000000006541215713201500215550ustar00rootroot00000000000000# "@(#) $Id: ittasc.sh,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # @(#)ittasc.sh 8.1.1.1 (ESO-IPG) 8/31/94 15:51:58 # Bourne shell script ittasc.sh # to delete lines 1-4 and last line of ascii table file # and to remove 1. field # sed '1,4d $d' $1 >temp.temp # # now we use awk to throw out the sequence field # awk '{ printf " %s\n", $2 }' temp.temp >temp.final # mv temp.final $2 rm temp.temp skycat-3.1.2-starlink-1b/rtd/colormaps/jigsaw.iasc000066400000000000000000000154001215713201500220520ustar00rootroot00000000000000 0.00000 0.01569 0.03137 0.04706 0.06275 0.07843 0.09412 0.10980 0.12549 0.14118 0.15686 0.17255 0.18824 0.20392 0.21961 0.23529 0.25098 0.26667 0.28235 0.29804 0.31373 0.33333 0.34902 0.36471 0.38039 0.39608 0.41176 0.42745 0.44314 0.45882 0.47451 0.49020 0.50588 0.52157 0.53725 0.55294 0.56863 0.58431 0.60000 0.61569 0.63137 0.64706 0.66667 0.68235 0.69804 0.71373 0.72941 0.74510 0.76078 0.77647 0.79216 0.80784 0.82353 0.83922 0.85490 0.87059 0.88627 0.90196 0.91765 0.93333 0.94902 0.96471 0.98039 0.99608 0.00000 0.01569 0.03137 0.04706 0.06275 0.07843 0.09412 0.10980 0.12549 0.14118 0.15686 0.17255 0.18824 0.20392 0.21961 0.23529 0.25098 0.26667 0.28235 0.29804 0.31373 0.33333 0.34902 0.36471 0.38039 0.39608 0.41176 0.42745 0.44314 0.45882 0.47451 0.49020 0.50588 0.52157 0.53725 0.55294 0.56863 0.58431 0.60000 0.61569 0.63137 0.64706 0.66667 0.68235 0.69804 0.71373 0.72941 0.74510 0.76078 0.77647 0.79216 0.80784 0.82353 0.83922 0.85490 0.87059 0.88627 0.90196 0.91765 0.93333 0.94902 0.96471 0.98039 0.99608 0.00000 0.01569 0.03137 0.04706 0.06275 0.07843 0.09412 0.10980 0.12549 0.14118 0.15686 0.17255 0.18824 0.20392 0.21961 0.23529 0.25098 0.26667 0.28235 0.29804 0.31373 0.33333 0.34902 0.36471 0.38039 0.39608 0.41176 0.42745 0.44314 0.45882 0.47451 0.49020 0.50588 0.52157 0.53725 0.55294 0.56863 0.58431 0.60000 0.61569 0.63137 0.64706 0.66667 0.68235 0.69804 0.71373 0.72941 0.74510 0.76078 0.77647 0.79216 0.80784 0.82353 0.83922 0.85490 0.87059 0.88627 0.90196 0.91765 0.93333 0.94902 0.96471 0.98039 0.99608 0.00000 0.01569 0.03137 0.04706 0.06275 0.07843 0.09412 0.10980 0.12549 0.14118 0.15686 0.17255 0.18824 0.20392 0.21961 0.23529 0.25098 0.26667 0.28235 0.29804 0.31373 0.33333 0.34902 0.36471 0.38039 0.39608 0.41176 0.42745 0.44314 0.45882 0.47451 0.49020 0.50588 0.52157 0.53725 0.55294 0.56863 0.58431 0.60000 0.61569 0.63137 0.64706 0.66667 0.68235 0.69804 0.71373 0.72941 0.74510 0.76078 0.77647 0.79216 0.80784 0.82353 0.83922 0.85490 0.87059 0.88627 0.90196 0.91765 0.93333 0.94902 0.96471 0.98039 0.99608 skycat-3.1.2-starlink-1b/rtd/colormaps/lasritt.iasc000066400000000000000000000154001215713201500222500ustar00rootroot00000000000000 0.05882 0.12157 0.18431 0.24706 0.30980 0.37255 0.43529 0.49804 0.56078 0.62353 0.68627 0.74902 0.81176 0.87451 0.93725 1.00000 0.05882 0.05882 0.05882 0.05882 0.05882 0.05882 0.05882 0.05882 0.12157 0.12157 0.12157 0.12157 0.12157 0.12157 0.12157 0.12157 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.24706 0.24706 0.24706 0.24706 0.24706 0.24706 0.24706 0.24706 0.30980 0.30980 0.30980 0.30980 0.30980 0.30980 0.30980 0.30980 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.43529 0.43529 0.43529 0.43529 0.43529 0.43529 0.43529 0.43529 0.49804 0.49804 0.49804 0.49804 0.49804 0.49804 0.49804 0.49804 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.62353 0.62353 0.62353 0.62353 0.62353 0.62353 0.62353 0.62353 0.68627 0.68627 0.68627 0.68627 0.68627 0.68627 0.68627 0.68627 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.81176 0.81176 0.81176 0.81176 0.81176 0.81176 0.81176 0.81176 0.87451 0.87451 0.87451 0.87451 0.87451 0.87451 0.87451 0.87451 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 0.05882 0.05882 0.05882 0.05882 0.05882 0.05882 0.05882 0.12157 0.12157 0.12157 0.12157 0.12157 0.12157 0.12157 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.18431 0.24706 0.24706 0.24706 0.24706 0.24706 0.24706 0.24706 0.30980 0.30980 0.30980 0.30980 0.30980 0.30980 0.30980 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.37255 0.43529 0.43529 0.43529 0.43529 0.43529 0.43529 0.43529 0.49804 0.49804 0.49804 0.49804 0.49804 0.49804 0.49804 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.56078 0.62353 0.62353 0.62353 0.62353 0.62353 0.62353 0.62353 0.68627 0.68627 0.68627 0.68627 0.68627 0.68627 0.68627 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.74902 0.81176 0.81176 0.81176 0.81176 0.81176 0.81176 0.81176 0.87451 0.87451 0.87451 0.87451 0.87451 0.87451 0.87451 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 0.93725 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/light.lasc000066400000000000000000000324001215713201500216770ustar00rootroot00000000000000 0.00000 0.00392 0.00000 0.00000 0.00784 0.01961 0.00000 0.01176 0.05490 0.00000 0.01569 0.08627 0.00000 0.01961 0.10980 0.00000 0.02353 0.13725 0.00000 0.02745 0.15686 0.00000 0.03137 0.18039 0.00000 0.03529 0.20000 0.00000 0.03922 0.21569 0.00000 0.04314 0.23529 0.00000 0.04706 0.25098 0.00000 0.05098 0.26275 0.00000 0.05490 0.28235 0.00000 0.05882 0.29412 0.00000 0.06275 0.30588 0.00000 0.06667 0.31765 0.00000 0.07059 0.33333 0.00000 0.07451 0.34118 0.00000 0.07843 0.35294 0.00000 0.08235 0.36078 0.00000 0.08627 0.37255 0.00000 0.09020 0.38431 0.00000 0.09412 0.39216 0.00392 0.09804 0.40000 0.00784 0.10196 0.41176 0.01176 0.10588 0.41961 0.01569 0.10980 0.43137 0.01569 0.11373 0.43529 0.01961 0.11765 0.44314 0.02353 0.12157 0.45098 0.02745 0.12549 0.45882 0.02745 0.12941 0.46667 0.03137 0.13333 0.47059 0.03529 0.13725 0.48235 0.04314 0.14118 0.48627 0.04706 0.14510 0.49412 0.05098 0.14902 0.50196 0.05882 0.15294 0.50588 0.06667 0.15686 0.50980 0.07451 0.16078 0.51765 0.08235 0.16471 0.52157 0.09020 0.16863 0.53333 0.09804 0.17255 0.53725 0.10588 0.17647 0.54118 0.11765 0.18039 0.54902 0.12941 0.18431 0.55294 0.14118 0.18824 0.55686 0.15294 0.19216 0.56078 0.16471 0.19608 0.56471 0.18039 0.20000 0.57255 0.18824 0.20392 0.58039 0.20000 0.20784 0.58431 0.21569 0.21176 0.58824 0.23137 0.21569 0.59216 0.24706 0.21961 0.59608 0.26275 0.22353 0.60000 0.27843 0.22745 0.60392 0.29412 0.23137 0.60784 0.30980 0.23529 0.61176 0.32941 0.23922 0.61569 0.34902 0.24314 0.61961 0.36863 0.24706 0.62745 0.38431 0.25098 0.63137 0.40392 0.25490 0.63529 0.41569 0.25882 0.63922 0.43529 0.26275 0.64314 0.45490 0.26667 0.64706 0.47059 0.27059 0.65098 0.48627 0.27451 0.65490 0.50196 0.27843 0.65490 0.51765 0.28235 0.65882 0.52941 0.28627 0.66275 0.54902 0.29020 0.66667 0.56471 0.29412 0.67059 0.58039 0.29804 0.67843 0.59216 0.30196 0.67843 0.60392 0.30588 0.68235 0.61961 0.30980 0.68627 0.63137 0.31373 0.69020 0.63922 0.31765 0.69020 0.65098 0.32157 0.69412 0.65882 0.32549 0.69804 0.67059 0.32941 0.70196 0.67843 0.33333 0.70196 0.69020 0.33725 0.70588 0.69804 0.34118 0.70980 0.70588 0.34510 0.71373 0.71373 0.34902 0.71373 0.72157 0.35294 0.71765 0.72941 0.35686 0.72157 0.73725 0.36078 0.72157 0.74510 0.36471 0.72941 0.75294 0.36863 0.73333 0.76078 0.37255 0.73333 0.76863 0.37647 0.73725 0.77647 0.38039 0.74118 0.78039 0.38431 0.74118 0.78824 0.38824 0.74510 0.79608 0.39216 0.74510 0.80392 0.39608 0.74902 0.80784 0.40000 0.75294 0.81176 0.40392 0.75294 0.81961 0.40784 0.75686 0.82353 0.41176 0.76078 0.82745 0.41569 0.76078 0.83529 0.41961 0.76471 0.83922 0.42353 0.76471 0.84314 0.42745 0.76863 0.84706 0.43137 0.76863 0.85098 0.43529 0.77255 0.85490 0.43922 0.78039 0.85882 0.44314 0.78039 0.86275 0.44706 0.78431 0.86667 0.45098 0.78431 0.87059 0.45490 0.78824 0.87451 0.45882 0.78824 0.87843 0.46275 0.79216 0.88235 0.46667 0.79216 0.88627 0.47059 0.79608 0.89020 0.47451 0.79608 0.89412 0.47843 0.80000 0.89804 0.48235 0.80000 0.89804 0.48627 0.80392 0.90196 0.49020 0.80392 0.90588 0.49412 0.80784 0.90980 0.49804 0.80784 0.91373 0.50196 0.81176 0.91373 0.50588 0.81176 0.91765 0.50980 0.81569 0.92157 0.51373 0.81569 0.92157 0.51765 0.81961 0.92549 0.52157 0.81961 0.92941 0.52549 0.82745 0.92941 0.52941 0.82745 0.93333 0.53333 0.83137 0.93725 0.53725 0.83137 0.93725 0.54118 0.83529 0.93725 0.54510 0.83529 0.94118 0.54902 0.83922 0.94118 0.55294 0.83922 0.94510 0.55686 0.83922 0.94510 0.56078 0.84314 0.94902 0.56471 0.84314 0.94902 0.56863 0.84706 0.95294 0.57255 0.84706 0.95294 0.57647 0.85098 0.95294 0.58039 0.85098 0.95686 0.58431 0.85490 0.95686 0.58824 0.85490 0.96078 0.59216 0.85490 0.96078 0.59608 0.85882 0.96078 0.60000 0.85882 0.96471 0.60392 0.86275 0.96471 0.60784 0.86275 0.96471 0.61176 0.86275 0.96863 0.61569 0.86667 0.96863 0.61961 0.86667 0.97255 0.62353 0.87059 0.97255 0.62745 0.87059 0.97255 0.63137 0.87059 0.97647 0.63529 0.87843 0.97647 0.63922 0.87843 0.98039 0.64314 0.88235 0.98039 0.64706 0.88235 0.98039 0.65098 0.88235 0.98431 0.65490 0.88627 0.98431 0.65882 0.88627 0.98431 0.66275 0.89020 0.98824 0.66667 0.89020 0.98824 0.67059 0.89020 0.98824 0.67451 0.89412 0.99216 0.67843 0.89412 0.99216 0.68235 0.89412 0.99216 0.68627 0.89804 0.99216 0.69020 0.89804 0.99216 0.69412 0.89804 0.99608 0.69804 0.90196 0.99608 0.70196 0.90196 0.99608 0.70588 0.90588 0.99608 0.70980 0.90588 0.99608 0.71373 0.90588 0.99608 0.71765 0.90980 0.99608 0.72157 0.90980 0.99608 0.72549 0.90980 0.99608 0.72941 0.91373 0.99608 0.73333 0.91373 0.99608 0.73725 0.91373 0.99608 0.74118 0.91765 0.99608 0.74510 0.91765 0.99608 0.74902 0.91765 0.99608 0.75294 0.92157 0.99608 0.75686 0.92157 0.99608 0.76078 0.92157 0.99608 0.76471 0.92941 0.99608 0.76863 0.92941 0.99608 0.77255 0.92941 0.99608 0.77647 0.93333 0.99608 0.78039 0.93333 0.99608 0.78431 0.93333 0.99608 0.78824 0.93725 1.00000 0.79216 0.93725 1.00000 0.79608 0.93725 1.00000 0.80000 0.94118 1.00000 0.80392 0.94118 1.00000 0.80784 0.94118 1.00000 0.81176 0.94118 1.00000 0.81569 0.94510 1.00000 0.81961 0.94510 1.00000 0.82353 0.94510 1.00000 0.82745 0.94902 1.00000 0.83137 0.94902 1.00000 0.83529 0.94902 1.00000 0.83922 0.95294 1.00000 0.84314 0.95294 1.00000 0.84706 0.95294 1.00000 0.85098 0.95686 1.00000 0.85490 0.95686 1.00000 0.85882 0.95686 1.00000 0.86275 0.95686 1.00000 0.86667 0.96078 1.00000 0.87059 0.96078 1.00000 0.87451 0.96078 1.00000 0.87843 0.96471 1.00000 0.88235 0.96471 1.00000 0.88627 0.96471 1.00000 0.89020 0.96471 1.00000 0.89412 0.96863 1.00000 0.89804 0.96863 1.00000 0.90196 0.96863 1.00000 0.90588 0.97255 1.00000 0.90980 0.97255 1.00000 0.91373 0.97255 1.00000 0.91765 0.97255 1.00000 0.92157 0.98039 1.00000 0.92549 0.98039 1.00000 0.92941 0.98039 1.00000 0.93333 0.98039 1.00000 0.93725 0.98431 1.00000 0.94118 0.98431 1.00000 0.94510 0.98431 1.00000 0.94902 0.98824 1.00000 0.95294 0.98824 1.00000 0.95686 0.98824 1.00000 0.96078 0.98824 1.00000 0.96471 0.99216 1.00000 0.96863 0.99216 1.00000 0.97255 0.99216 1.00000 0.97647 0.99216 1.00000 0.98039 0.99608 1.00000 0.98431 0.99608 1.00000 0.98824 0.99608 1.00000 0.99216 0.99608 1.00000 0.99608 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/log.iasc000066400000000000000000000154001215713201500213470ustar00rootroot00000000000000 0.00000 0.01961 0.05490 0.08627 0.10980 0.13725 0.15686 0.18039 0.20000 0.21569 0.23529 0.25098 0.26275 0.28235 0.29412 0.30588 0.31765 0.33333 0.34118 0.35294 0.36078 0.37255 0.38431 0.39216 0.40000 0.41176 0.41961 0.43137 0.43529 0.44314 0.45098 0.45882 0.46667 0.47059 0.48235 0.48627 0.49412 0.50196 0.50588 0.50980 0.51765 0.52157 0.53333 0.53725 0.54118 0.54902 0.55294 0.55686 0.56078 0.56471 0.57255 0.58039 0.58431 0.58824 0.59216 0.59608 0.60000 0.60392 0.60784 0.61176 0.61569 0.61961 0.62745 0.63137 0.63529 0.63922 0.64314 0.64706 0.65098 0.65490 0.65490 0.65882 0.66275 0.66667 0.67059 0.67843 0.67843 0.68235 0.68627 0.69020 0.69020 0.69412 0.69804 0.70196 0.70196 0.70588 0.70980 0.71373 0.71373 0.71765 0.72157 0.72157 0.72941 0.73333 0.73333 0.73725 0.74118 0.74118 0.74510 0.74510 0.74902 0.75294 0.75294 0.75686 0.76078 0.76078 0.76471 0.76471 0.76863 0.76863 0.77255 0.78039 0.78039 0.78431 0.78431 0.78824 0.78824 0.79216 0.79216 0.79608 0.79608 0.80000 0.80000 0.80392 0.80392 0.80784 0.80784 0.81176 0.81176 0.81569 0.81569 0.81961 0.81961 0.82745 0.82745 0.83137 0.83137 0.83529 0.83529 0.83922 0.83922 0.83922 0.84314 0.84314 0.84706 0.84706 0.85098 0.85098 0.85490 0.85490 0.85490 0.85882 0.85882 0.86275 0.86275 0.86275 0.86667 0.86667 0.87059 0.87059 0.87059 0.87843 0.87843 0.88235 0.88235 0.88235 0.88627 0.88627 0.89020 0.89020 0.89020 0.89412 0.89412 0.89412 0.89804 0.89804 0.89804 0.90196 0.90196 0.90588 0.90588 0.90588 0.90980 0.90980 0.90980 0.91373 0.91373 0.91373 0.91765 0.91765 0.91765 0.92157 0.92157 0.92157 0.92941 0.92941 0.92941 0.93333 0.93333 0.93333 0.93725 0.93725 0.93725 0.94118 0.94118 0.94118 0.94118 0.94510 0.94510 0.94510 0.94902 0.94902 0.94902 0.95294 0.95294 0.95294 0.95686 0.95686 0.95686 0.95686 0.96078 0.96078 0.96078 0.96471 0.96471 0.96471 0.96471 0.96863 0.96863 0.96863 0.97255 0.97255 0.97255 0.97255 0.98039 0.98039 0.98039 0.98039 0.98431 0.98431 0.98431 0.98824 0.98824 0.98824 0.98824 0.99216 0.99216 0.99216 0.99216 0.99608 0.99608 0.99608 0.99608 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/lut.fmt000066400000000000000000000001471215713201500212430ustar00rootroot00000000000000DEFINE/FIELD 15 26 R F12.5 :RED DEFINE/FIELD 28 39 R F12.5 :GREEN DEFINE/FIELD 41 52 R F12.5 :BLUE END skycat-3.1.2-starlink-1b/rtd/colormaps/lutasc.prg000066400000000000000000000012101215713201500217240ustar00rootroot00000000000000! @(#)lutasc.prg 8.1.1.1 (ESO-IPG) 8/31/94 15:51:21 ! ++++++++++++++ ! ! Midas procedure lutasc.prg ! to convert Midas LUT to ASCII file which can later be used to regenerate ! that LUT via: CREATE/TABLE using lut.fmt as Format file ! ! xyz.lut -> xyz.lasc ! ! KB 910315 ! ! ++++++++++++++ ! ASSIGN/PRINT FILE lut.lis ! -COPY 'P1'.lut temp.tbl NAME/COLUMN temp :RED F12.5 NAME/COLUMN temp :GREEN F12.5 NAME/COLUMN temp :BLUE F12.5 PRINT/TABLE temp :RED :GREEN :BLUE ! $ sh $MIDASHOME/$MIDVERS/systab/ascii/display/lutasc.sh lut.lis 'P1'.lasc ASSIGN/PRINT T ! $ rm lut.lis $ rm temp.tbl ! WRITE/OUT table 'P1'.lut processed ... skycat-3.1.2-starlink-1b/rtd/colormaps/lutasc.sh000066400000000000000000000006701215713201500215570ustar00rootroot00000000000000# "@(#) $Id: lutasc.sh,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # @(#)lutasc.sh 8.1.1.1 (ESO-IPG) 8/31/94 15:51:22 # Bourne shell script # to delete lines 1-4 and last line of ascii table file # and to remove 1. field # sed '1,4d $d' $1 >temp.temp # # now we use awk to throw out the sequence field # awk '{ printf " %s %s %s\n", $2, $3, $4 }' temp.temp >temp.final # mv temp.final $2 rm temp.temp skycat-3.1.2-starlink-1b/rtd/colormaps/manycol.lasc000066400000000000000000000324001215713201500222320ustar00rootroot00000000000000 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.72549 0.00000 0.72549 0.72549 0.00000 0.72549 0.72549 0.00000 0.72549 0.72549 0.00000 0.72549 0.72549 0.00000 0.72549 0.72549 0.00000 0.72549 0.72549 0.00000 0.72549 0.72549 0.00000 0.72549 0.72549 0.00000 0.72549 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.72549 0.00000 0.72549 0.72549 0.00000 0.72549 0.72549 0.00000 0.72549 0.72549 0.00000 0.72549 0.72549 0.00000 0.72549 0.72549 0.00000 0.72549 0.72549 0.00000 0.72549 0.72549 0.00000 0.72549 0.72549 0.00000 0.72549 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.34902 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.44706 0.78431 0.92549 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 0.00000 0.69020 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 0.69020 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.00000 0.88235 0.00000 0.72549 0.00000 0.72549 0.72549 0.00000 0.72549 skycat-3.1.2-starlink-1b/rtd/colormaps/neg.iasc000066400000000000000000000154001215713201500213370ustar00rootroot00000000000000 1.00000 0.99608 0.99216 0.98824 0.98431 0.98039 0.97647 0.97255 0.96863 0.96471 0.96078 0.95686 0.95294 0.94902 0.94510 0.94118 0.93725 0.93333 0.92941 0.92549 0.92157 0.91765 0.91373 0.90980 0.90588 0.90196 0.89804 0.89412 0.89020 0.88627 0.88235 0.87843 0.87451 0.87059 0.86667 0.86275 0.85882 0.85490 0.85098 0.84706 0.84314 0.83922 0.83529 0.83137 0.82745 0.82353 0.81961 0.81569 0.81176 0.80784 0.80392 0.80000 0.79608 0.79216 0.78824 0.78431 0.78039 0.77647 0.77255 0.76863 0.76471 0.76078 0.75686 0.75294 0.74902 0.74510 0.74118 0.73725 0.73333 0.72941 0.72549 0.72157 0.71765 0.71373 0.70980 0.70588 0.70196 0.69804 0.69412 0.69020 0.68627 0.68235 0.67843 0.67451 0.67059 0.66667 0.66275 0.65882 0.65490 0.65098 0.64706 0.64314 0.63922 0.63529 0.63137 0.62745 0.62353 0.61961 0.61569 0.61176 0.60784 0.60392 0.60000 0.59608 0.59216 0.58824 0.58431 0.58039 0.57647 0.57255 0.56863 0.56471 0.56078 0.55686 0.55294 0.54902 0.54510 0.54118 0.53725 0.53333 0.52941 0.52549 0.52157 0.51765 0.51373 0.50980 0.50588 0.50196 0.49804 0.49412 0.49020 0.48627 0.48235 0.47843 0.47451 0.47059 0.46667 0.46275 0.45882 0.45490 0.45098 0.44706 0.44314 0.43922 0.43529 0.43137 0.42745 0.42353 0.41961 0.41569 0.41176 0.40784 0.40392 0.40000 0.39608 0.39216 0.38824 0.38431 0.38039 0.37647 0.37255 0.36863 0.36471 0.36078 0.35686 0.35294 0.34902 0.34510 0.34118 0.33725 0.33333 0.32941 0.32549 0.32157 0.31765 0.31373 0.30980 0.30588 0.30196 0.29804 0.29412 0.29020 0.28627 0.28235 0.27843 0.27451 0.27059 0.26667 0.26275 0.25882 0.25490 0.25098 0.24706 0.24314 0.23922 0.23529 0.23137 0.22745 0.22353 0.21961 0.21569 0.21176 0.20784 0.20392 0.20000 0.19608 0.19216 0.18824 0.18431 0.18039 0.17647 0.17255 0.16863 0.16471 0.16078 0.15686 0.15294 0.14902 0.14510 0.14118 0.13725 0.13333 0.12941 0.12549 0.12157 0.11765 0.11373 0.10980 0.10588 0.10196 0.09804 0.09412 0.09020 0.08627 0.08235 0.07843 0.07451 0.07059 0.06667 0.06275 0.05882 0.05490 0.05098 0.04706 0.04314 0.03922 0.03529 0.03137 0.02745 0.02353 0.01961 0.01569 0.01176 0.00784 0.00392 0.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/neglog.iasc000066400000000000000000000154001215713201500220410ustar00rootroot00000000000000 1.00000 0.98039 0.94510 0.91373 0.89020 0.86275 0.84314 0.81961 0.80000 0.78431 0.76471 0.74902 0.73725 0.71765 0.70588 0.69412 0.68235 0.66667 0.65882 0.64706 0.63922 0.62745 0.61569 0.60784 0.60000 0.58824 0.58039 0.56863 0.56471 0.55686 0.54902 0.54118 0.53333 0.52941 0.51765 0.51373 0.50588 0.49804 0.49412 0.49020 0.48235 0.47843 0.46667 0.46275 0.45882 0.45098 0.44706 0.44314 0.43922 0.43529 0.42745 0.41961 0.41569 0.41176 0.40784 0.40392 0.40000 0.39608 0.39216 0.38824 0.38431 0.38039 0.37255 0.36863 0.36471 0.36078 0.35686 0.35294 0.34902 0.34510 0.34510 0.34118 0.33725 0.33333 0.32941 0.32157 0.32157 0.31765 0.31373 0.30980 0.30980 0.30588 0.30196 0.29804 0.29804 0.29412 0.29020 0.28627 0.28627 0.28235 0.27843 0.27843 0.27059 0.26667 0.26667 0.26275 0.25882 0.25882 0.25490 0.25490 0.25098 0.24706 0.24706 0.24314 0.23922 0.23922 0.23529 0.23529 0.23137 0.23137 0.22745 0.21961 0.21961 0.21569 0.21569 0.21176 0.21176 0.20784 0.20784 0.20392 0.20392 0.20000 0.20000 0.19608 0.19608 0.19216 0.19216 0.18824 0.18824 0.18431 0.18431 0.18039 0.18039 0.17255 0.17255 0.16863 0.16863 0.16471 0.16471 0.16078 0.16078 0.16078 0.15686 0.15686 0.15294 0.15294 0.14902 0.14902 0.14510 0.14510 0.14510 0.14118 0.14118 0.13725 0.13725 0.13725 0.13333 0.13333 0.12941 0.12941 0.12941 0.12157 0.12157 0.11765 0.11765 0.11765 0.11373 0.11373 0.10980 0.10980 0.10980 0.10588 0.10588 0.10588 0.10196 0.10196 0.10196 0.09804 0.09804 0.09412 0.09412 0.09412 0.09020 0.09020 0.09020 0.08627 0.08627 0.08627 0.08235 0.08235 0.08235 0.07843 0.07843 0.07843 0.07059 0.07059 0.07059 0.06667 0.06667 0.06667 0.06275 0.06275 0.06275 0.05882 0.05882 0.05882 0.05882 0.05490 0.05490 0.05490 0.05098 0.05098 0.05098 0.04706 0.04706 0.04706 0.04314 0.04314 0.04314 0.04314 0.03922 0.03922 0.03922 0.03529 0.03529 0.03529 0.03529 0.03137 0.03137 0.03137 0.02745 0.02745 0.02745 0.02745 0.01961 0.01961 0.01961 0.01961 0.01569 0.01569 0.01569 0.01176 0.01176 0.01176 0.01176 0.00784 0.00784 0.00784 0.00784 0.00392 0.00392 0.00392 0.00392 0.00000 0.00000 0.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/null.iasc000066400000000000000000000154001215713201500215400ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/pastel.lasc000066400000000000000000000324001215713201500220600ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00000 0.00000 1.00000 0.01961 0.00000 0.98039 0.05490 0.00000 0.94510 0.08627 0.00392 0.91373 0.10980 0.00392 0.89020 0.13725 0.00392 0.86275 0.15686 0.00392 0.84314 0.18039 0.00392 0.81961 0.20000 0.00784 0.80000 0.21569 0.00784 0.78431 0.23529 0.00784 0.76471 0.25098 0.00784 0.74902 0.26275 0.01176 0.73725 0.28235 0.01176 0.71765 0.29412 0.01176 0.70588 0.30588 0.01176 0.69412 0.31765 0.01176 0.68235 0.33333 0.01569 0.66667 0.34118 0.01569 0.65882 0.35294 0.01569 0.64706 0.36078 0.01569 0.63922 0.37255 0.01961 0.62745 0.38431 0.01961 0.61569 0.39216 0.01961 0.60784 0.40000 0.01961 0.60000 0.41176 0.02353 0.58824 0.41961 0.02353 0.58039 0.43137 0.02353 0.56863 0.43529 0.02745 0.56471 0.44314 0.02745 0.55686 0.45098 0.02745 0.54902 0.45882 0.02745 0.54118 0.46667 0.03137 0.53333 0.47059 0.03137 0.52941 0.48235 0.03137 0.51765 0.48627 0.03529 0.51373 0.49412 0.03529 0.50588 0.50196 0.03529 0.49804 0.50588 0.03529 0.49412 0.50980 0.04314 0.49020 0.51765 0.04314 0.48235 0.52157 0.04314 0.47843 0.53333 0.04706 0.46667 0.53725 0.04706 0.46275 0.54118 0.04706 0.45882 0.54902 0.05098 0.45098 0.55294 0.05098 0.44706 0.55686 0.05098 0.44314 0.56078 0.05490 0.43922 0.56471 0.05490 0.43529 0.57255 0.05490 0.42745 0.58039 0.05882 0.41961 0.58431 0.05882 0.41569 0.58824 0.05882 0.41176 0.59216 0.06275 0.40784 0.59608 0.06275 0.40392 0.60000 0.06275 0.40000 0.60392 0.06667 0.39608 0.60784 0.06667 0.39216 0.61176 0.06667 0.38824 0.61569 0.07059 0.38431 0.61961 0.07059 0.38039 0.62745 0.07451 0.37255 0.63137 0.07451 0.36863 0.63529 0.07451 0.36471 0.63922 0.07843 0.36078 0.64314 0.07843 0.35686 0.64706 0.08235 0.35294 0.65098 0.08235 0.34902 0.65490 0.08235 0.34510 0.65490 0.08627 0.34510 0.65882 0.08627 0.34118 0.66275 0.09020 0.33725 0.66667 0.09020 0.33333 0.67059 0.09020 0.32941 0.67843 0.09412 0.32157 0.67843 0.09412 0.32157 0.68235 0.09804 0.31765 0.68627 0.09804 0.31373 0.69020 0.10196 0.30980 0.69020 0.10196 0.30980 0.69412 0.10588 0.30588 0.69804 0.10588 0.30196 0.70196 0.10980 0.29804 0.70196 0.10980 0.29804 0.70588 0.10980 0.29412 0.70980 0.11765 0.29020 0.71373 0.11765 0.28627 0.71373 0.12157 0.28627 0.71765 0.12157 0.28235 0.72157 0.12549 0.27843 0.72157 0.12549 0.27843 0.72941 0.12941 0.27059 0.73333 0.12941 0.26667 0.73333 0.13333 0.26667 0.73725 0.13725 0.26275 0.74118 0.13725 0.25882 0.74118 0.14118 0.25882 0.74510 0.14118 0.25490 0.74510 0.14510 0.25490 0.74902 0.14510 0.25098 0.75294 0.14902 0.24706 0.75294 0.14902 0.24706 0.75686 0.15294 0.24314 0.76078 0.15686 0.23922 0.76078 0.15686 0.23922 0.76471 0.16078 0.23529 0.76471 0.16078 0.23529 0.76863 0.16471 0.23137 0.76863 0.16863 0.23137 0.77255 0.16863 0.22745 0.78039 0.17255 0.21961 0.78039 0.17255 0.21961 0.78431 0.17647 0.21569 0.78431 0.18039 0.21569 0.78824 0.18039 0.21176 0.78824 0.18431 0.21176 0.79216 0.18824 0.20784 0.79216 0.18824 0.20784 0.79608 0.19608 0.20392 0.79608 0.20000 0.20392 0.80000 0.20000 0.20000 0.80000 0.20392 0.20000 0.80392 0.20784 0.19608 0.80392 0.20784 0.19608 0.80784 0.21176 0.19216 0.80784 0.21569 0.19216 0.81176 0.21961 0.18824 0.81176 0.21961 0.18824 0.81569 0.22353 0.18431 0.81569 0.22745 0.18431 0.81961 0.23137 0.18039 0.81961 0.23137 0.18039 0.82745 0.23529 0.17255 0.82745 0.23922 0.17255 0.83137 0.24314 0.16863 0.83137 0.24314 0.16863 0.83529 0.24706 0.16471 0.83529 0.25098 0.16471 0.83922 0.25490 0.16078 0.83922 0.25882 0.16078 0.83922 0.26275 0.16078 0.84314 0.26275 0.15686 0.84314 0.27059 0.15686 0.84706 0.27451 0.15294 0.84706 0.27843 0.15294 0.85098 0.28235 0.14902 0.85098 0.28627 0.14902 0.85490 0.29020 0.14510 0.85490 0.29412 0.14510 0.85490 0.29804 0.14510 0.85882 0.29804 0.14118 0.85882 0.30196 0.14118 0.86275 0.30588 0.13725 0.86275 0.30980 0.13725 0.86275 0.31373 0.13725 0.86667 0.31765 0.13333 0.86667 0.32157 0.13333 0.87059 0.32549 0.12941 0.87059 0.33333 0.12941 0.87059 0.33725 0.12941 0.87843 0.34118 0.12157 0.87843 0.34510 0.12157 0.88235 0.34902 0.11765 0.88235 0.35294 0.11765 0.88235 0.35686 0.11765 0.88627 0.36078 0.11373 0.88627 0.36471 0.11373 0.89020 0.37255 0.10980 0.89020 0.37647 0.10980 0.89020 0.38039 0.10980 0.89412 0.38431 0.10588 0.89412 0.38824 0.10588 0.89412 0.39216 0.10588 0.89804 0.40000 0.10196 0.89804 0.40392 0.10196 0.89804 0.40784 0.10196 0.90196 0.41176 0.09804 0.90196 0.41961 0.09804 0.90588 0.42353 0.09412 0.90588 0.42745 0.09412 0.90588 0.43529 0.09412 0.90980 0.43922 0.09020 0.90980 0.44314 0.09020 0.90980 0.45098 0.09020 0.91373 0.45490 0.08627 0.91373 0.45882 0.08627 0.91373 0.46667 0.08627 0.91765 0.47059 0.08235 0.91765 0.47843 0.08235 0.91765 0.48235 0.08235 0.92157 0.49020 0.07843 0.92157 0.49412 0.07843 0.92157 0.50196 0.07843 0.92941 0.50588 0.07059 0.92941 0.51373 0.07059 0.92941 0.51765 0.07059 0.93333 0.52549 0.06667 0.93333 0.52941 0.06667 0.93333 0.53725 0.06667 0.93725 0.54118 0.06275 0.93725 0.54902 0.06275 0.93725 0.55686 0.06275 0.94118 0.56078 0.05882 0.94118 0.56863 0.05882 0.94118 0.57647 0.05882 0.94118 0.58039 0.05882 0.94510 0.58824 0.05490 0.94510 0.59608 0.05490 0.94510 0.60000 0.05490 0.94902 0.60784 0.05098 0.94902 0.61569 0.05098 0.94902 0.62353 0.05098 0.95294 0.63137 0.04706 0.95294 0.63529 0.04706 0.95294 0.64314 0.04706 0.95686 0.65098 0.04314 0.95686 0.65882 0.04314 0.95686 0.66667 0.04314 0.95686 0.67451 0.04314 0.96078 0.68235 0.03922 0.96078 0.69020 0.03922 0.96078 0.69804 0.03922 0.96471 0.70588 0.03529 0.96471 0.71373 0.03529 0.96471 0.72157 0.03529 0.96471 0.72941 0.03529 0.96863 0.73725 0.03137 0.96863 0.74510 0.03137 0.96863 0.75294 0.03137 0.97255 0.76078 0.02745 0.97255 0.77255 0.02745 0.97255 0.78039 0.02745 0.97255 0.78824 0.02745 0.98039 0.79608 0.01961 0.98039 0.80392 0.01961 0.98039 0.81569 0.01961 0.98039 0.82353 0.01961 0.98431 0.83137 0.01569 0.98431 0.84314 0.01569 0.98431 0.85098 0.01569 0.98824 0.86275 0.01176 0.98824 0.87059 0.01176 0.98824 0.87843 0.01176 0.98824 0.89020 0.01176 0.99216 0.89804 0.00784 0.99216 0.90980 0.00784 0.99216 0.91765 0.00784 0.99216 0.92941 0.00784 0.99608 0.94118 0.00392 0.99608 0.94902 0.00392 0.99608 0.96078 0.00392 0.99608 0.97255 0.00392 1.00000 0.98039 0.00000 1.00000 0.99216 0.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/rainbow.lasc000066400000000000000000000324001215713201500222310ustar00rootroot00000000000000 0.00000 0.00000 0.16471 0.02745 0.00000 0.18431 0.05882 0.00000 0.20000 0.08627 0.00000 0.21961 0.11373 0.00000 0.23922 0.14510 0.00000 0.25882 0.17647 0.00000 0.27843 0.20392 0.00000 0.29804 0.23137 0.00000 0.31765 0.26275 0.00000 0.33725 0.29412 0.00000 0.35686 0.32157 0.00000 0.37647 0.35294 0.00000 0.39608 0.38039 0.00000 0.41569 0.41176 0.00000 0.43529 0.43922 0.00000 0.45490 0.47059 0.00000 0.47451 0.49804 0.00000 0.49412 0.52941 0.00000 0.51373 0.55686 0.00000 0.53725 0.58824 0.00000 0.55686 0.55686 0.00000 0.57647 0.52941 0.00000 0.59608 0.49804 0.00000 0.61569 0.47059 0.00000 0.63922 0.43922 0.00000 0.65882 0.41176 0.00000 0.67843 0.38039 0.00000 0.70196 0.35294 0.00000 0.72157 0.32157 0.00000 0.74118 0.29412 0.00000 0.76471 0.26275 0.00000 0.78431 0.23137 0.00000 0.80392 0.20392 0.00000 0.82745 0.17647 0.00000 0.84706 0.14510 0.00000 0.87059 0.11373 0.00000 0.89020 0.08627 0.00000 0.91373 0.05882 0.00000 0.93333 0.02745 0.00000 0.95686 0.00000 0.00000 0.97647 0.00000 0.00000 1.00000 0.00000 0.02353 0.97647 0.00000 0.04706 0.95686 0.00000 0.06275 0.93333 0.00000 0.08235 0.91373 0.00000 0.09804 0.89020 0.00000 0.11373 0.87059 0.00000 0.12941 0.84706 0.00000 0.14118 0.82745 0.00000 0.15686 0.80392 0.00000 0.16863 0.78431 0.00000 0.18431 0.76471 0.00000 0.19608 0.74118 0.00000 0.21176 0.72157 0.00000 0.22353 0.70196 0.00000 0.23529 0.67843 0.00000 0.25098 0.65882 0.00000 0.26275 0.63922 0.00000 0.27451 0.61569 0.00000 0.28627 0.59608 0.00000 0.29804 0.57647 0.00000 0.30980 0.55686 0.00000 0.32157 0.53725 0.00000 0.33333 0.51373 0.00000 0.34510 0.49412 0.00000 0.35686 0.47451 0.00000 0.36863 0.45490 0.00000 0.38039 0.43529 0.00000 0.39216 0.41569 0.00000 0.40392 0.39608 0.00000 0.41176 0.37647 0.00000 0.42353 0.35686 0.00000 0.43529 0.33725 0.00000 0.44706 0.31765 0.00000 0.45882 0.29804 0.00000 0.46667 0.27843 0.00000 0.47843 0.25882 0.00000 0.49020 0.23922 0.00000 0.49804 0.21961 0.00000 0.50980 0.20000 0.00000 0.52157 0.18431 0.00000 0.52941 0.16471 0.00000 0.54118 0.14510 0.00000 0.55294 0.12941 0.00000 0.56078 0.10980 0.00000 0.57255 0.09412 0.00000 0.58431 0.07451 0.00000 0.59216 0.05882 0.00000 0.60392 0.04314 0.00000 0.61176 0.02745 0.00000 0.62353 0.01176 0.00000 0.63137 0.00000 0.00000 0.64314 0.00000 0.00000 0.65098 0.00000 0.00000 0.66275 0.00000 0.00000 0.67059 0.00000 0.00000 0.68235 0.00000 0.00000 0.69020 0.00000 0.00000 0.70196 0.00000 0.00000 0.70980 0.00000 0.00000 0.72157 0.00000 0.00000 0.72941 0.00000 0.00000 0.74118 0.00000 0.00000 0.74902 0.00000 0.00000 0.76078 0.00000 0.00000 0.76863 0.00000 0.00000 0.77647 0.00000 0.00000 0.78824 0.00000 0.00000 0.79608 0.00000 0.00000 0.80784 0.00000 0.00000 0.81569 0.00000 0.00000 0.82353 0.00000 0.00000 0.83529 0.00000 0.00000 0.84314 0.00000 0.00000 0.85490 0.00000 0.00000 0.86275 0.00000 0.00000 0.87059 0.00000 0.00000 0.88235 0.00000 0.00000 0.89020 0.00000 0.00000 0.89804 0.00000 0.00000 0.90980 0.00000 0.00000 0.91765 0.00000 0.00000 0.92549 0.00000 0.00000 0.93725 0.00000 0.00000 0.94510 0.00000 0.00000 0.95294 0.00000 0.00000 0.96078 0.00000 0.00000 0.97255 0.00000 0.00000 0.98039 0.00000 0.00000 0.98824 0.00000 0.00000 1.00000 0.00000 0.00000 0.98824 0.00000 0.00000 0.98039 0.00000 0.00000 0.97255 0.00000 0.00000 0.96078 0.00000 0.00000 0.95294 0.00000 0.00000 0.94510 0.00000 0.00000 0.93725 0.00000 0.00000 0.92549 0.00000 0.00000 0.91765 0.00000 0.00000 0.90980 0.00000 0.00000 0.89804 0.00000 0.00000 0.89020 0.00000 0.00000 0.88235 0.00000 0.00000 0.87059 0.00000 0.00000 0.86275 0.00000 0.00000 0.85490 0.00000 0.00000 0.84314 0.00000 0.00000 0.83529 0.00000 0.00000 0.82353 0.00000 0.00000 0.81569 0.00000 0.00000 0.80784 0.00000 0.00000 0.79608 0.00000 0.00000 0.78824 0.00000 0.00000 0.77647 0.00000 0.00784 0.76863 0.00000 0.03529 0.77647 0.00000 0.06667 0.78824 0.00000 0.09804 0.80000 0.00000 0.12941 0.81176 0.00000 0.16471 0.82745 0.00000 0.20000 0.84314 0.00000 0.23529 0.85882 0.00000 0.26667 0.87059 0.00000 0.30588 0.89020 0.00000 0.34118 0.90196 0.00000 0.37647 0.92157 0.00000 0.41176 0.93333 0.00000 0.44706 0.95294 0.00000 0.48627 0.96863 0.00000 0.52157 0.98824 0.00000 0.56078 1.00000 0.00000 0.59608 1.00000 0.00000 0.63529 1.00000 0.00000 0.67059 1.00000 0.00000 0.70980 1.00000 0.00000 0.74902 1.00000 0.00000 0.78431 1.00000 0.00000 0.82353 1.00000 0.00000 0.85882 1.00000 0.00000 0.89804 1.00000 0.00000 0.93333 1.00000 0.00000 0.97647 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 0.99608 1.00000 0.00000 0.98039 1.00000 0.00000 0.96078 0.97647 0.00000 0.94510 0.93725 0.00000 0.92549 0.89804 0.00000 0.90980 0.85882 0.00000 0.89412 0.81961 0.00000 0.87451 0.78039 0.00000 0.85882 0.74118 0.00000 0.83922 0.70196 0.00000 0.82353 0.66275 0.00000 0.80392 0.62353 0.00000 0.78824 0.58431 0.00000 0.76863 0.54510 0.00000 0.75686 0.50980 0.00000 0.74118 0.46667 0.00000 0.72549 0.43137 0.00000 0.70980 0.39216 0.00000 0.69412 0.35294 0.00000 0.68235 0.31765 0.00000 0.66275 0.27451 0.00000 0.65098 0.23922 0.00000 0.63529 0.20000 0.00000 0.62745 0.16863 0.00000 0.61569 0.12941 0.00000 0.60784 0.09804 0.00000 0.61961 0.08235 0.00000 0.62745 0.06275 0.00000 0.63922 0.04706 0.00000 0.64706 0.02353 0.00000 0.65882 0.00000 0.00000 0.66667 0.00000 0.00000 0.67843 0.00000 0.00000 0.68627 0.00000 0.00000 0.69804 0.00000 0.00000 0.70980 0.00000 0.00000 0.71765 0.00000 0.00000 0.72941 0.00000 0.00000 0.73725 0.00000 0.00000 0.74902 0.00000 0.00000 0.75686 0.00000 0.00000 0.76863 0.00000 0.00000 0.77647 0.00000 0.00000 0.78824 0.00000 0.00000 0.80000 0.00784 0.00784 0.80784 0.02745 0.02745 0.81961 0.05098 0.05098 0.82745 0.08235 0.08235 0.83922 0.11373 0.11373 0.84706 0.14902 0.14902 0.85882 0.19216 0.19216 0.86667 0.23137 0.23137 0.87843 0.27843 0.27843 0.88627 0.32549 0.32549 0.89804 0.37647 0.37647 0.90980 0.43137 0.43137 0.91765 0.48627 0.48627 0.92941 0.54118 0.54118 0.93725 0.60000 0.60000 0.94902 0.66275 0.66275 0.95686 0.72549 0.72549 0.96863 0.79216 0.79216 0.97647 0.85882 0.85882 0.98824 0.92941 0.92941 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/rainbow1.lasc000066400000000000000000000324001215713201500223120ustar00rootroot00000000000000 0.00000 0.00000 0.16471 0.02745 0.00000 0.18431 0.05882 0.00000 0.20000 0.08627 0.00000 0.21961 0.11373 0.00000 0.23922 0.14510 0.00000 0.25882 0.17647 0.00000 0.27843 0.20392 0.00000 0.29804 0.23137 0.00000 0.31765 0.26275 0.00000 0.33725 0.29412 0.00000 0.35686 0.32157 0.00000 0.37647 0.35294 0.00000 0.39608 0.38039 0.00000 0.41569 0.41176 0.00000 0.43529 0.43922 0.00000 0.45490 0.47059 0.00000 0.47451 0.49804 0.00000 0.49412 0.52941 0.00000 0.51373 0.55686 0.00000 0.53725 0.58824 0.00000 0.55686 0.55686 0.00000 0.57647 0.52941 0.00000 0.59608 0.49804 0.00000 0.61569 0.47059 0.00000 0.63922 0.43922 0.00000 0.65882 0.41176 0.00000 0.67843 0.38039 0.00000 0.70196 0.35294 0.00000 0.72157 0.32157 0.00000 0.74118 0.29412 0.00000 0.76471 0.26275 0.00000 0.78431 0.23137 0.00000 0.80392 0.20392 0.00000 0.82745 0.17647 0.00000 0.84706 0.14510 0.00000 0.87059 0.11373 0.00000 0.89020 0.08627 0.00000 0.91373 0.05882 0.00000 0.93333 0.02745 0.00000 0.95686 0.00000 0.00000 0.97647 0.00000 0.00000 1.00000 0.00000 0.00000 0.97647 0.00000 0.00784 0.95686 0.00000 0.01569 0.93333 0.00000 0.02353 0.91373 0.00000 0.03137 0.89020 0.00000 0.03922 0.87059 0.00000 0.05098 0.85098 0.00000 0.06275 0.83137 0.00000 0.07843 0.81176 0.00000 0.09804 0.79216 0.00000 0.11765 0.77255 0.00000 0.13725 0.75294 0.00000 0.15686 0.73333 0.00000 0.17647 0.71373 0.00000 0.19608 0.69412 0.00000 0.21569 0.67451 0.00000 0.23529 0.65882 0.00000 0.25490 0.64314 0.00000 0.27059 0.62745 0.00000 0.28627 0.61176 0.00000 0.30196 0.59608 0.00000 0.32157 0.58039 0.00000 0.33333 0.56471 0.00000 0.34510 0.54902 0.00000 0.35686 0.53333 0.00000 0.36863 0.51765 0.00000 0.38039 0.50196 0.00000 0.39216 0.48627 0.00000 0.40392 0.47059 0.00000 0.41176 0.45882 0.00000 0.42353 0.44706 0.00000 0.43529 0.43529 0.00000 0.44706 0.42353 0.00000 0.45882 0.41176 0.00000 0.46667 0.40000 0.00000 0.47843 0.38824 0.00000 0.49020 0.37647 0.00000 0.49804 0.36471 0.00000 0.50980 0.35294 0.00000 0.52157 0.34118 0.00000 0.52941 0.32941 0.00000 0.54118 0.31765 0.00000 0.55294 0.30588 0.00000 0.56078 0.29412 0.00000 0.57255 0.28235 0.00000 0.58431 0.27059 0.00000 0.59216 0.25882 0.00000 0.60392 0.24706 0.00000 0.61176 0.23529 0.00000 0.62353 0.22353 0.00000 0.63137 0.21176 0.00000 0.64314 0.20000 0.00000 0.65098 0.18824 0.00000 0.66275 0.17647 0.00000 0.67059 0.16471 0.00000 0.68235 0.15294 0.00000 0.69020 0.14118 0.00000 0.70196 0.12941 0.00000 0.70980 0.11765 0.00000 0.72157 0.10196 0.00000 0.72941 0.08627 0.00000 0.74118 0.07059 0.00000 0.74902 0.05490 0.00000 0.76078 0.03922 0.00000 0.76863 0.02353 0.00000 0.77647 0.00000 0.00000 0.78824 0.00000 0.00000 0.79608 0.00000 0.00000 0.80784 0.00000 0.00000 0.81569 0.00000 0.00000 0.82353 0.00000 0.00000 0.83529 0.00000 0.00000 0.84314 0.00000 0.00000 0.85490 0.00000 0.00000 0.86275 0.00000 0.00000 0.87059 0.00000 0.00000 0.88235 0.00000 0.00000 0.89020 0.00000 0.00000 0.89804 0.00000 0.00000 0.90980 0.00000 0.00000 0.91765 0.00000 0.00000 0.92549 0.00000 0.00000 0.93725 0.00000 0.00000 0.94510 0.00000 0.00000 0.95294 0.00000 0.00000 0.96078 0.00000 0.00000 0.97255 0.00000 0.00000 0.98039 0.00000 0.00000 0.98824 0.00000 0.00784 1.00000 0.00000 0.01569 0.98824 0.00000 0.02353 0.98039 0.00000 0.03137 0.97255 0.00000 0.04314 0.96078 0.00000 0.05490 0.95294 0.00000 0.06667 0.94510 0.00000 0.07843 0.93725 0.00000 0.09020 0.92549 0.00000 0.10196 0.91765 0.00000 0.11373 0.90980 0.00000 0.12549 0.89804 0.00000 0.13725 0.89020 0.00000 0.14902 0.88235 0.00000 0.16471 0.87059 0.00000 0.20000 0.86275 0.00000 0.23529 0.85490 0.00000 0.26667 0.84314 0.00000 0.30588 0.83529 0.00000 0.34118 0.82353 0.00000 0.37647 0.81569 0.00000 0.41176 0.80784 0.00000 0.44706 0.79608 0.00000 0.48627 0.78824 0.00000 0.52157 0.77647 0.00000 0.56078 0.76863 0.00000 0.59608 0.77647 0.00000 0.63529 0.78824 0.00000 0.67059 0.80000 0.00000 0.70980 0.81176 0.00000 0.74902 0.82745 0.00000 0.78431 0.84314 0.00000 0.82353 0.85882 0.00000 0.85882 0.87059 0.00000 0.89804 0.89020 0.00000 0.93333 0.90196 0.00000 0.97647 0.92157 0.00000 1.00000 0.93333 0.00000 1.00000 0.95294 0.00000 1.00000 0.96863 0.00000 1.00000 0.98824 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 0.99608 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 0.97647 0.00000 1.00000 0.93725 0.00000 1.00000 0.89804 0.00000 1.00000 0.85882 0.00000 1.00000 0.81961 0.00000 1.00000 0.78039 0.00000 1.00000 0.74118 0.00000 1.00000 0.70196 0.00000 1.00000 0.66275 0.00000 1.00000 0.62353 0.00000 1.00000 0.58431 0.00000 1.00000 0.54510 0.00000 1.00000 0.50980 0.00000 1.00000 0.46667 0.00000 1.00000 0.43137 0.00000 1.00000 0.39216 0.00000 1.00000 0.35294 0.00000 1.00000 0.31765 0.00000 1.00000 0.27451 0.00000 1.00000 0.23922 0.00000 1.00000 0.20000 0.00000 1.00000 0.16863 0.00000 1.00000 0.12941 0.00000 1.00000 0.09804 0.00000 1.00000 0.08235 0.00000 1.00000 0.06275 0.00000 1.00000 0.04706 0.00000 1.00000 0.02353 0.00000 1.00000 0.00000 0.00000 0.99216 0.00000 0.00000 0.98431 0.00000 0.00000 0.97647 0.00000 0.00000 0.96863 0.00000 0.00000 0.96078 0.00000 0.00000 0.95294 0.00000 0.00000 0.94510 0.00000 0.00000 0.93725 0.00000 0.00000 0.92941 0.00000 0.00000 0.92157 0.00000 0.00000 0.91373 0.00000 0.00000 0.90588 0.00000 0.00000 0.89804 0.00000 0.00000 0.89020 0.00000 0.00000 0.88235 0.00000 0.00000 0.87451 0.00000 0.00000 0.86667 0.00000 0.00000 0.85882 0.00000 0.00000 0.85098 0.00000 0.00000 0.84314 0.00000 0.00000 0.83529 0.00000 0.00000 0.82745 0.00000 0.00000 0.81961 0.00000 0.00000 0.81176 0.00000 0.00000 0.80392 0.00000 0.00000 0.79608 0.00000 0.00000 0.78824 0.00000 0.00000 0.78039 0.00000 0.00000 0.77255 0.00000 0.00000 0.76471 0.00000 0.00000 0.75686 0.00000 0.00000 0.74902 0.00000 0.00000 0.74118 0.00000 0.00000 0.73333 0.00000 0.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/rainbow2.lasc000066400000000000000000000324001215713201500223130ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.03137 0.00000 0.03137 0.06275 0.00000 0.06275 0.09412 0.00000 0.09412 0.12549 0.00000 0.12549 0.15686 0.00000 0.15686 0.18824 0.00000 0.18824 0.21961 0.00000 0.21961 0.25098 0.00000 0.25098 0.28235 0.00000 0.28235 0.31373 0.00000 0.31373 0.34510 0.00000 0.34510 0.37647 0.00000 0.37647 0.40784 0.00000 0.40784 0.43922 0.00000 0.43922 0.47059 0.00000 0.47059 0.50196 0.00000 0.50196 0.53333 0.00000 0.53333 0.56471 0.00000 0.56471 0.59608 0.00000 0.59608 0.62745 0.00000 0.62745 0.65882 0.00000 0.65882 0.69020 0.00000 0.69020 0.72157 0.00000 0.72157 0.75294 0.00000 0.75294 0.78431 0.00000 0.78431 0.81569 0.00000 0.81569 0.84706 0.00000 0.84706 0.87843 0.00000 0.87843 0.90980 0.00000 0.90980 0.94118 0.00000 0.94118 0.97255 0.00000 0.97255 1.00000 0.00000 1.00000 0.96863 0.00000 1.00000 0.93725 0.00000 1.00000 0.90588 0.00000 1.00000 0.87451 0.00000 1.00000 0.84314 0.00000 1.00000 0.81176 0.00000 1.00000 0.78039 0.00000 1.00000 0.74902 0.00000 1.00000 0.71765 0.00000 1.00000 0.68627 0.00000 1.00000 0.65490 0.00000 1.00000 0.62353 0.00000 1.00000 0.59216 0.00000 1.00000 0.56078 0.00000 1.00000 0.52941 0.00000 1.00000 0.49804 0.00000 1.00000 0.46667 0.00000 1.00000 0.43529 0.00000 1.00000 0.40392 0.00000 1.00000 0.37255 0.00000 1.00000 0.34118 0.00000 1.00000 0.30980 0.00000 1.00000 0.27843 0.00000 1.00000 0.24706 0.00000 1.00000 0.21569 0.00000 1.00000 0.18431 0.00000 1.00000 0.15294 0.00000 1.00000 0.12157 0.00000 1.00000 0.09020 0.00000 1.00000 0.05882 0.00000 1.00000 0.02745 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.03137 1.00000 0.00000 0.06275 1.00000 0.00000 0.09412 1.00000 0.00000 0.12549 1.00000 0.00000 0.15686 1.00000 0.00000 0.18824 1.00000 0.00000 0.21961 1.00000 0.00000 0.25098 1.00000 0.00000 0.28235 1.00000 0.00000 0.31373 1.00000 0.00000 0.34510 1.00000 0.00000 0.37647 1.00000 0.00000 0.40784 1.00000 0.00000 0.43922 1.00000 0.00000 0.47059 1.00000 0.00000 0.50196 1.00000 0.00000 0.53333 1.00000 0.00000 0.56471 1.00000 0.00000 0.59608 1.00000 0.00000 0.62745 1.00000 0.00000 0.65882 1.00000 0.00000 0.69020 1.00000 0.00000 0.72157 1.00000 0.00000 0.75294 1.00000 0.00000 0.78431 1.00000 0.00000 0.81569 1.00000 0.00000 0.84706 1.00000 0.00000 0.87843 1.00000 0.00000 0.90980 1.00000 0.00000 0.94118 1.00000 0.00000 0.97255 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 0.96863 0.00000 1.00000 0.93725 0.00000 1.00000 0.90588 0.00000 1.00000 0.87451 0.00000 1.00000 0.84314 0.00000 1.00000 0.81176 0.00000 1.00000 0.78039 0.00000 1.00000 0.74902 0.00000 1.00000 0.71765 0.00000 1.00000 0.68627 0.00000 1.00000 0.65490 0.00000 1.00000 0.62353 0.00000 1.00000 0.59216 0.00000 1.00000 0.56078 0.00000 1.00000 0.52941 0.00000 1.00000 0.49804 0.00000 1.00000 0.46667 0.00000 1.00000 0.43529 0.00000 1.00000 0.40392 0.00000 1.00000 0.37255 0.00000 1.00000 0.34118 0.00000 1.00000 0.30980 0.00000 1.00000 0.27843 0.00000 1.00000 0.24706 0.00000 1.00000 0.21569 0.00000 1.00000 0.18431 0.00000 1.00000 0.15294 0.00000 1.00000 0.12157 0.00000 1.00000 0.09020 0.00000 1.00000 0.05882 0.00000 1.00000 0.02745 0.00000 1.00000 0.00000 0.03137 1.00000 0.00000 0.06275 1.00000 0.00000 0.09412 1.00000 0.00000 0.12549 1.00000 0.00000 0.15686 1.00000 0.00000 0.18824 1.00000 0.00000 0.21961 1.00000 0.00000 0.25098 1.00000 0.00000 0.28235 1.00000 0.00000 0.31373 1.00000 0.00000 0.34510 1.00000 0.00000 0.37647 1.00000 0.00000 0.40784 1.00000 0.00000 0.43922 1.00000 0.00000 0.47059 1.00000 0.00000 0.50196 1.00000 0.00000 0.53333 1.00000 0.00000 0.56471 1.00000 0.00000 0.59608 1.00000 0.00000 0.62745 1.00000 0.00000 0.65882 1.00000 0.00000 0.69020 1.00000 0.00000 0.72157 1.00000 0.00000 0.75294 1.00000 0.00000 0.78431 1.00000 0.00000 0.81569 1.00000 0.00000 0.84706 1.00000 0.00000 0.87843 1.00000 0.00000 0.90980 1.00000 0.00000 0.94118 1.00000 0.00000 0.97255 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 0.98431 0.00000 1.00000 0.96863 0.00000 1.00000 0.95294 0.00000 1.00000 0.93725 0.00000 1.00000 0.92157 0.00000 1.00000 0.90588 0.00000 1.00000 0.89020 0.00000 1.00000 0.87451 0.00000 1.00000 0.85882 0.00000 1.00000 0.84314 0.00000 1.00000 0.82745 0.00000 1.00000 0.81176 0.00000 1.00000 0.79608 0.00000 1.00000 0.78039 0.00000 1.00000 0.76471 0.00000 1.00000 0.74902 0.00000 1.00000 0.73333 0.00000 1.00000 0.71765 0.00000 1.00000 0.70196 0.00000 1.00000 0.68627 0.00000 1.00000 0.67059 0.00000 1.00000 0.65490 0.00000 1.00000 0.63922 0.00000 1.00000 0.62353 0.00000 1.00000 0.60784 0.00000 1.00000 0.59216 0.00000 1.00000 0.57647 0.00000 1.00000 0.56078 0.00000 1.00000 0.54510 0.00000 1.00000 0.52941 0.00000 1.00000 0.51373 0.00000 1.00000 0.49804 0.00000 1.00000 0.48235 0.00000 1.00000 0.46667 0.00000 1.00000 0.45098 0.00000 1.00000 0.43529 0.00000 1.00000 0.41961 0.00000 1.00000 0.40392 0.00000 1.00000 0.38824 0.00000 1.00000 0.37255 0.00000 1.00000 0.35686 0.00000 1.00000 0.34118 0.00000 1.00000 0.32549 0.00000 1.00000 0.30980 0.00000 1.00000 0.29412 0.00000 1.00000 0.27843 0.00000 1.00000 0.26275 0.00000 1.00000 0.24706 0.00000 1.00000 0.23137 0.00000 1.00000 0.21569 0.00000 1.00000 0.20000 0.00000 1.00000 0.18431 0.00000 1.00000 0.16863 0.00000 1.00000 0.15294 0.00000 1.00000 0.13725 0.00000 1.00000 0.12157 0.00000 1.00000 0.10588 0.00000 1.00000 0.09020 0.00000 1.00000 0.07451 0.00000 1.00000 0.05882 0.00000 1.00000 0.04314 0.00000 1.00000 0.02745 0.00000 1.00000 0.01176 0.00000 1.00000 0.00000 0.00000 1.00000 0.03137 0.03137 1.00000 0.06275 0.06275 1.00000 0.09412 0.09412 1.00000 0.12549 0.12549 1.00000 0.15686 0.15686 1.00000 0.18824 0.18824 1.00000 0.21961 0.21961 1.00000 0.25098 0.25098 1.00000 0.28235 0.28235 1.00000 0.31373 0.31373 1.00000 0.34510 0.34510 1.00000 0.37647 0.37647 1.00000 0.40784 0.40784 1.00000 0.43922 0.43922 1.00000 0.47059 0.47059 1.00000 0.50196 0.50196 1.00000 0.53333 0.53333 1.00000 0.56471 0.56471 1.00000 0.59608 0.59608 1.00000 0.62745 0.62745 1.00000 0.65882 0.65882 1.00000 0.69020 0.69020 1.00000 0.72157 0.72157 1.00000 0.75294 0.75294 1.00000 0.78431 0.78431 1.00000 0.81569 0.81569 1.00000 0.84706 0.84706 1.00000 0.87843 0.87843 1.00000 0.90980 0.90980 1.00000 0.94118 0.94118 1.00000 0.97255 0.97255 skycat-3.1.2-starlink-1b/rtd/colormaps/rainbow3.lasc000066400000000000000000000324001215713201500223140ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.03922 0.00000 0.00000 0.07843 0.00000 0.00000 0.11765 0.00000 0.00000 0.15686 0.00000 0.00000 0.20000 0.00000 0.00000 0.23922 0.00000 0.00000 0.27843 0.00000 0.00000 0.31765 0.00000 0.00000 0.35686 0.00000 0.00000 0.40000 0.00000 0.00000 0.43922 0.00000 0.00000 0.47843 0.00000 0.00000 0.51765 0.00000 0.00000 0.55686 0.00000 0.00000 0.60000 0.00000 0.00000 0.63922 0.00000 0.00000 0.67843 0.00000 0.00000 0.71765 0.00000 0.00000 0.75686 0.00000 0.00000 0.80000 0.00000 0.00000 0.83922 0.00000 0.00000 0.87843 0.00000 0.00000 0.91765 0.00000 0.00000 0.95686 0.00000 0.00000 1.00000 0.00000 0.03137 1.00000 0.00000 0.06275 1.00000 0.00000 0.09412 1.00000 0.00000 0.12549 1.00000 0.00000 0.15686 1.00000 0.00000 0.18824 1.00000 0.00000 0.21961 1.00000 0.00000 0.25490 1.00000 0.00000 0.28627 1.00000 0.00000 0.31765 1.00000 0.00000 0.34902 1.00000 0.00000 0.38039 1.00000 0.00000 0.41176 1.00000 0.00000 0.44314 1.00000 0.00000 0.47843 1.00000 0.00000 0.49804 1.00000 0.00000 0.51765 1.00000 0.00000 0.53725 1.00000 0.00000 0.55686 1.00000 0.00000 0.58039 1.00000 0.00000 0.60000 1.00000 0.00000 0.61961 1.00000 0.00000 0.63922 1.00000 0.00000 0.65882 1.00000 0.00000 0.68235 1.00000 0.00000 0.70196 1.00000 0.00000 0.72157 1.00000 0.00000 0.74118 1.00000 0.00000 0.76078 1.00000 0.00000 0.78431 1.00000 0.00000 0.79608 1.00000 0.00000 0.81176 1.00000 0.00000 0.82745 1.00000 0.00000 0.83922 1.00000 0.00000 0.85490 1.00000 0.00000 0.87059 1.00000 0.00000 0.88235 1.00000 0.00000 0.89804 1.00000 0.00000 0.91373 1.00000 0.00000 0.92549 1.00000 0.00000 0.94118 1.00000 0.00000 0.95686 1.00000 0.00000 0.96863 1.00000 0.00000 0.98431 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 0.98039 0.00000 1.00000 0.96078 0.00000 1.00000 0.94118 0.00000 1.00000 0.92157 0.00000 1.00000 0.90196 0.00000 1.00000 0.88235 0.00000 1.00000 0.86275 0.00000 1.00000 0.84314 0.00000 1.00000 0.82353 0.00000 1.00000 0.80392 0.00000 1.00000 0.78431 0.00000 1.00000 0.76471 0.00000 1.00000 0.74510 0.00000 1.00000 0.72549 0.00000 1.00000 0.70588 0.00000 1.00000 0.65882 0.00000 1.00000 0.61176 0.00000 1.00000 0.56471 0.00000 1.00000 0.51765 0.00000 1.00000 0.47059 0.00000 1.00000 0.42353 0.00000 1.00000 0.37647 0.00000 1.00000 0.32549 0.00000 1.00000 0.27843 0.00000 1.00000 0.23137 0.00000 1.00000 0.18431 0.00000 1.00000 0.13725 0.00000 1.00000 0.09020 0.00000 1.00000 0.04314 0.00000 1.00000 0.00000 0.04706 1.00000 0.00000 0.09412 1.00000 0.00000 0.14118 1.00000 0.00000 0.18824 1.00000 0.00000 0.23529 1.00000 0.00000 0.28235 1.00000 0.00000 0.32941 1.00000 0.00000 0.37647 1.00000 0.00000 0.42353 1.00000 0.00000 0.47059 1.00000 0.00000 0.51765 1.00000 0.00000 0.56471 1.00000 0.00000 0.61176 1.00000 0.00000 0.65882 1.00000 0.00000 0.70588 1.00000 0.00000 0.72549 1.00000 0.00000 0.74510 1.00000 0.00000 0.76471 1.00000 0.00000 0.78431 1.00000 0.00000 0.80392 1.00000 0.00000 0.82353 1.00000 0.00000 0.84314 1.00000 0.00000 0.86275 1.00000 0.00000 0.88235 1.00000 0.00000 0.90196 1.00000 0.00000 0.92157 1.00000 0.00000 0.94118 1.00000 0.00000 0.96078 1.00000 0.00000 0.98039 1.00000 0.00000 1.00000 1.00000 0.00000 0.99608 0.98039 0.00000 0.99608 0.96078 0.00000 0.99608 0.94510 0.00000 0.99608 0.92549 0.00000 0.99608 0.90588 0.00000 0.99216 0.89020 0.00000 0.99216 0.87059 0.00000 0.99216 0.85098 0.00000 0.99216 0.83529 0.00000 0.99216 0.81569 0.00000 0.98824 0.79608 0.00000 0.98824 0.78039 0.00000 0.98824 0.76078 0.00000 0.98824 0.74118 0.00000 0.98824 0.72549 0.00000 0.98824 0.70588 0.00000 0.98824 0.69020 0.00000 0.98824 0.67451 0.00000 0.98824 0.65490 0.00000 0.99216 0.63922 0.00000 0.99216 0.62353 0.00000 0.99216 0.60392 0.00000 0.99216 0.58824 0.00000 0.99216 0.57255 0.00000 0.99608 0.55294 0.00000 0.99608 0.53725 0.00000 0.99608 0.52157 0.00000 0.99608 0.50196 0.00000 0.99608 0.48627 0.00000 1.00000 0.47059 0.00000 1.00000 0.43922 0.00000 1.00000 0.40784 0.00000 1.00000 0.37647 0.00000 1.00000 0.34510 0.00000 1.00000 0.31373 0.00000 1.00000 0.28235 0.00000 1.00000 0.25098 0.00000 1.00000 0.21569 0.00000 1.00000 0.18431 0.00000 1.00000 0.15294 0.00000 1.00000 0.12157 0.00000 1.00000 0.09020 0.00000 1.00000 0.05882 0.00000 1.00000 0.02745 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.04706 1.00000 0.00000 0.09412 1.00000 0.00000 0.14118 1.00000 0.00000 0.18824 1.00000 0.00000 0.23529 1.00000 0.00000 0.28235 1.00000 0.00000 0.32941 1.00000 0.00000 0.37647 1.00000 0.00000 0.42353 1.00000 0.00000 0.47059 1.00000 0.00000 0.51765 1.00000 0.00000 0.56471 1.00000 0.00000 0.61176 1.00000 0.00000 0.65882 1.00000 0.00000 0.70588 1.00000 0.00000 0.72549 1.00000 0.00000 0.74902 1.00000 0.00000 0.77255 1.00000 0.00000 0.79608 1.00000 0.00000 0.81569 1.00000 0.00000 0.83922 1.00000 0.00000 0.86275 1.00000 0.00000 0.88627 1.00000 0.00000 0.90588 1.00000 0.00000 0.92941 1.00000 0.00000 0.95294 1.00000 0.00000 0.97647 1.00000 0.00000 1.00000 1.00000 0.03529 1.00000 1.00000 0.07059 1.00000 1.00000 0.10588 1.00000 1.00000 0.14118 1.00000 1.00000 0.18039 1.00000 1.00000 0.21569 1.00000 1.00000 0.25098 1.00000 1.00000 0.28627 1.00000 1.00000 0.32549 1.00000 1.00000 0.36078 1.00000 1.00000 0.39608 1.00000 1.00000 0.43137 1.00000 1.00000 0.47059 1.00000 1.00000 0.48627 1.00000 1.00000 0.50588 1.00000 1.00000 0.52157 1.00000 1.00000 0.54118 1.00000 1.00000 0.56078 1.00000 1.00000 0.57647 1.00000 1.00000 0.59608 1.00000 1.00000 0.61176 1.00000 1.00000 0.63137 1.00000 1.00000 0.65098 1.00000 1.00000 0.66667 1.00000 1.00000 0.68627 1.00000 1.00000 0.70588 1.00000 1.00000 0.74510 1.00000 1.00000 0.78824 1.00000 1.00000 0.83137 1.00000 1.00000 0.87059 1.00000 1.00000 0.91373 1.00000 1.00000 0.95686 1.00000 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/rainbow4.lasc000066400000000000000000000324001215713201500223150ustar00rootroot00000000000000 0.00000 0.00000 0.01176 0.00000 0.00000 0.02745 0.00000 0.00000 0.04314 0.00000 0.00000 0.05882 0.00000 0.00000 0.07451 0.00000 0.00000 0.09020 0.00000 0.00000 0.10588 0.00000 0.00000 0.12157 0.00000 0.00000 0.13725 0.00000 0.00000 0.15294 0.00000 0.00000 0.16863 0.00000 0.00000 0.18431 0.00000 0.00000 0.20000 0.00000 0.00000 0.21176 0.00000 0.00000 0.22745 0.00000 0.00000 0.24314 0.00000 0.00000 0.25882 0.00000 0.00000 0.27451 0.00000 0.00000 0.29020 0.00000 0.00000 0.30588 0.00000 0.00000 0.32157 0.00000 0.00000 0.33725 0.00000 0.00000 0.35294 0.00000 0.00000 0.36863 0.00000 0.00000 0.38431 0.00000 0.00000 0.40000 0.00000 0.00000 0.41176 0.00000 0.00000 0.42745 0.00000 0.00000 0.44314 0.00000 0.00000 0.45882 0.00000 0.00000 0.47451 0.00000 0.00000 0.49020 0.00000 0.00000 0.50588 0.00000 0.00000 0.52157 0.00000 0.00000 0.53725 0.00000 0.00000 0.55294 0.00000 0.00000 0.56863 0.00000 0.00000 0.58431 0.00000 0.00000 0.60000 0.00000 0.00000 0.61176 0.00000 0.00000 0.62745 0.00000 0.00000 0.64314 0.00000 0.00000 0.65882 0.00000 0.00000 0.67451 0.00000 0.00000 0.69020 0.00000 0.00000 0.70588 0.00000 0.00000 0.72157 0.00000 0.00000 0.73725 0.00000 0.00000 0.75294 0.00000 0.00000 0.76863 0.00000 0.00000 0.78431 0.00000 0.00000 0.80000 0.00000 0.00000 0.81176 0.00000 0.00000 0.82745 0.00000 0.00000 0.84314 0.00000 0.00000 0.85882 0.00000 0.00000 0.87451 0.00000 0.00000 0.89020 0.00000 0.00000 0.90588 0.00000 0.00000 0.92157 0.00000 0.00000 0.93725 0.00000 0.00000 0.95294 0.00000 0.00000 0.96863 0.00000 0.00000 0.98431 0.00000 0.00000 1.00000 0.00000 0.03529 1.00000 0.00000 0.07059 1.00000 0.00000 0.10980 1.00000 0.00000 0.14510 1.00000 0.00000 0.18039 1.00000 0.00000 0.21961 1.00000 0.00000 0.25490 1.00000 0.00000 0.29412 1.00000 0.00000 0.32941 1.00000 0.00000 0.36471 1.00000 0.00000 0.40392 1.00000 0.00000 0.43922 1.00000 0.00000 0.47843 1.00000 0.00000 0.50196 1.00000 0.00000 0.52549 1.00000 0.00000 0.54902 1.00000 0.00000 0.57255 1.00000 0.00000 0.59608 1.00000 0.00000 0.61961 1.00000 0.00000 0.64314 1.00000 0.00000 0.66667 1.00000 0.00000 0.69020 1.00000 0.00000 0.71373 1.00000 0.00000 0.73725 1.00000 0.00000 0.76078 1.00000 0.00000 0.78431 1.00000 0.00000 0.80000 1.00000 0.00000 0.81569 1.00000 0.00000 0.83137 1.00000 0.00000 0.84706 1.00000 0.00000 0.86667 1.00000 0.00000 0.88235 1.00000 0.00000 0.89804 1.00000 0.00000 0.91373 1.00000 0.00000 0.93333 1.00000 0.00000 0.94902 1.00000 0.00000 0.96471 1.00000 0.00000 0.98039 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 0.97647 0.00000 1.00000 0.95294 0.00000 1.00000 0.92941 0.00000 1.00000 0.90588 0.00000 1.00000 0.88627 0.00000 1.00000 0.86275 0.00000 1.00000 0.83922 0.00000 1.00000 0.81569 0.00000 1.00000 0.79608 0.00000 1.00000 0.77255 0.00000 1.00000 0.74902 0.00000 1.00000 0.72549 0.00000 1.00000 0.70588 0.00000 1.00000 0.65098 0.00000 1.00000 0.59608 0.00000 1.00000 0.54118 0.00000 1.00000 0.48627 0.00000 1.00000 0.43137 0.00000 1.00000 0.37647 0.00000 1.00000 0.32549 0.00000 1.00000 0.27059 0.00000 1.00000 0.21569 0.00000 1.00000 0.16078 0.00000 1.00000 0.10588 0.00000 1.00000 0.05098 0.00000 1.00000 0.00000 0.05098 1.00000 0.00000 0.10588 1.00000 0.00000 0.16078 1.00000 0.00000 0.21569 1.00000 0.00000 0.27059 1.00000 0.00000 0.32549 1.00000 0.00000 0.37647 1.00000 0.00000 0.43137 1.00000 0.00000 0.48627 1.00000 0.00000 0.54118 1.00000 0.00000 0.59608 1.00000 0.00000 0.65098 1.00000 0.00000 0.70588 1.00000 0.00000 0.72549 1.00000 0.00000 0.74902 1.00000 0.00000 0.77255 1.00000 0.00000 0.79608 1.00000 0.00000 0.81569 1.00000 0.00000 0.83922 1.00000 0.00000 0.86275 1.00000 0.00000 0.88627 1.00000 0.00000 0.90588 1.00000 0.00000 0.92941 1.00000 0.00000 0.95294 1.00000 0.00000 0.97647 1.00000 0.00000 1.00000 1.00000 0.00000 0.99608 0.97647 0.00000 0.99608 0.95686 0.00000 0.99608 0.93333 0.00000 0.99608 0.91373 0.00000 0.99216 0.89412 0.00000 0.99216 0.87059 0.00000 0.99216 0.85098 0.00000 0.99216 0.82745 0.00000 0.98824 0.80784 0.00000 0.98824 0.78824 0.00000 0.98824 0.76471 0.00000 0.98824 0.74510 0.00000 0.98824 0.72549 0.00000 0.98824 0.70588 0.00000 0.98824 0.68627 0.00000 0.98824 0.66667 0.00000 0.98824 0.64706 0.00000 0.99216 0.62745 0.00000 0.99216 0.60784 0.00000 0.99216 0.58824 0.00000 0.99216 0.56863 0.00000 0.99608 0.54902 0.00000 0.99608 0.52941 0.00000 0.99608 0.50980 0.00000 0.99608 0.49020 0.00000 1.00000 0.47059 0.00000 1.00000 0.43137 0.00000 1.00000 0.39608 0.00000 1.00000 0.36078 0.00000 1.00000 0.32549 0.00000 1.00000 0.28627 0.00000 1.00000 0.25098 0.00000 1.00000 0.21569 0.00000 1.00000 0.18039 0.00000 1.00000 0.14118 0.00000 1.00000 0.10588 0.00000 1.00000 0.07059 0.00000 1.00000 0.03529 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.05098 1.00000 0.00000 0.10588 1.00000 0.00000 0.16078 1.00000 0.00000 0.21569 1.00000 0.00000 0.27059 1.00000 0.00000 0.32549 1.00000 0.00000 0.37647 1.00000 0.00000 0.43137 1.00000 0.00000 0.48627 1.00000 0.00000 0.54118 1.00000 0.00000 0.59608 1.00000 0.00000 0.65098 1.00000 0.00000 0.70588 1.00000 0.00000 0.72549 1.00000 0.00000 0.74902 1.00000 0.00000 0.77255 1.00000 0.00000 0.79608 1.00000 0.00000 0.81569 1.00000 0.00000 0.83922 1.00000 0.00000 0.86275 1.00000 0.00000 0.88627 1.00000 0.00000 0.90588 1.00000 0.00000 0.92941 1.00000 0.00000 0.95294 1.00000 0.00000 0.97647 1.00000 0.00000 1.00000 1.00000 0.03529 1.00000 1.00000 0.07059 1.00000 1.00000 0.10588 1.00000 1.00000 0.14118 1.00000 1.00000 0.18039 1.00000 1.00000 0.21569 1.00000 1.00000 0.25098 1.00000 1.00000 0.28627 1.00000 1.00000 0.32549 1.00000 1.00000 0.36078 1.00000 1.00000 0.39608 1.00000 1.00000 0.43137 1.00000 1.00000 0.47059 1.00000 1.00000 0.48627 1.00000 1.00000 0.50588 1.00000 1.00000 0.52157 1.00000 1.00000 0.54118 1.00000 1.00000 0.56078 1.00000 1.00000 0.57647 1.00000 1.00000 0.59608 1.00000 1.00000 0.61176 1.00000 1.00000 0.63137 1.00000 1.00000 0.65098 1.00000 1.00000 0.66667 1.00000 1.00000 0.68627 1.00000 1.00000 0.70588 1.00000 1.00000 0.74510 1.00000 1.00000 0.78824 1.00000 1.00000 0.83137 1.00000 1.00000 0.87059 1.00000 1.00000 0.91373 1.00000 1.00000 0.95686 1.00000 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/ramp.iasc000066400000000000000000000060001215713201500215210ustar00rootroot00000000000000 0.00000 0.00392 0.00784 0.01176 0.01569 0.01961 0.02353 0.02745 0.03137 0.03529 0.03922 0.04314 0.04706 0.05098 0.05490 0.05882 0.06275 0.06667 0.07059 0.07451 0.07843 0.08235 0.08627 0.09020 0.09412 0.09804 0.10196 0.10588 0.10980 0.11373 0.11765 0.12157 0.12549 0.12941 0.13333 0.13725 0.14118 0.14510 0.14902 0.15294 0.15686 0.16078 0.16471 0.16863 0.17255 0.17647 0.18039 0.18431 0.18824 0.19216 0.19608 0.20000 0.20392 0.20784 0.21177 0.21569 0.21961 0.22353 0.22745 0.23137 0.23529 0.23922 0.24314 0.24706 0.25098 0.25490 0.25882 0.26275 0.26667 0.27059 0.27451 0.27843 0.28235 0.28628 0.29020 0.29412 0.29804 0.30196 0.30588 0.30980 0.31372 0.31765 0.32157 0.32549 0.32941 0.33333 0.33726 0.34118 0.34510 0.34902 0.35294 0.35686 0.36078 0.36471 0.36863 0.37255 0.37647 0.38039 0.38431 0.38823 0.39216 0.39608 0.40000 0.40392 0.40784 0.41176 0.41569 0.41961 0.42353 0.42745 0.43137 0.43529 0.43922 0.44314 0.44706 0.45098 0.45490 0.45882 0.46275 0.46667 0.47059 0.47451 0.47843 0.48235 0.48628 0.49020 0.49412 0.49804 0.50196 0.50588 0.50980 0.51372 0.51765 0.52157 0.52549 0.52941 0.53333 0.53726 0.54118 0.54510 0.54902 0.55294 0.55686 0.56078 0.56471 0.56863 0.57255 0.57647 0.58039 0.58431 0.58823 0.59216 0.59608 0.60000 0.60392 0.60784 0.61177 0.61569 0.61961 0.62353 0.62745 0.63137 0.63529 0.63922 0.64314 0.64706 0.65098 0.65490 0.65882 0.66275 0.66667 0.67059 0.67451 0.67843 0.68235 0.68627 0.69020 0.69412 0.69804 0.70196 0.70588 0.70980 0.71373 0.71765 0.72157 0.72549 0.72941 0.73333 0.73725 0.74118 0.74510 0.74902 0.75294 0.75686 0.76078 0.76471 0.76863 0.77255 0.77647 0.78039 0.78431 0.78824 0.79216 0.79608 0.80000 0.80392 0.80784 0.81176 0.81569 0.81961 0.82353 0.82745 0.83137 0.83529 0.83922 0.84314 0.84706 0.85098 0.85490 0.85882 0.86274 0.86667 0.87059 0.87451 0.87843 0.88235 0.88628 0.89020 0.89412 0.89804 0.90196 0.90588 0.90980 0.91373 0.91765 0.92157 0.92549 0.92941 0.93333 0.93725 0.94118 0.94510 0.94902 0.95294 0.95686 0.96078 0.96471 0.96863 0.97255 0.97647 0.98039 0.98431 0.98823 0.99216 0.99608 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/ramp.lasc000066400000000000000000000220001215713201500215220ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00392 0.00392 0.00392 0.00784 0.00784 0.00784 0.01176 0.01176 0.01176 0.01569 0.01569 0.01569 0.01961 0.01961 0.01961 0.02353 0.02353 0.02353 0.02745 0.02745 0.02745 0.03137 0.03137 0.03137 0.03529 0.03529 0.03529 0.03922 0.03922 0.03922 0.04314 0.04314 0.04314 0.04706 0.04706 0.04706 0.05098 0.05098 0.05098 0.05490 0.05490 0.05490 0.05882 0.05882 0.05882 0.06275 0.06275 0.06275 0.06667 0.06667 0.06667 0.07059 0.07059 0.07059 0.07451 0.07451 0.07451 0.07843 0.07843 0.07843 0.08235 0.08235 0.08235 0.08627 0.08627 0.08627 0.09020 0.09020 0.09020 0.09412 0.09412 0.09412 0.09804 0.09804 0.09804 0.10196 0.10196 0.10196 0.10588 0.10588 0.10588 0.10980 0.10980 0.10980 0.11373 0.11373 0.11373 0.11765 0.11765 0.11765 0.12157 0.12157 0.12157 0.12549 0.12549 0.12549 0.12941 0.12941 0.12941 0.13333 0.13333 0.13333 0.13725 0.13725 0.13725 0.14118 0.14118 0.14118 0.14510 0.14510 0.14510 0.14902 0.14902 0.14902 0.15294 0.15294 0.15294 0.15686 0.15686 0.15686 0.16078 0.16078 0.16078 0.16471 0.16471 0.16471 0.16863 0.16863 0.16863 0.17255 0.17255 0.17255 0.17647 0.17647 0.17647 0.18039 0.18039 0.18039 0.18431 0.18431 0.18431 0.18824 0.18824 0.18824 0.19216 0.19216 0.19216 0.19608 0.19608 0.19608 0.20000 0.20000 0.20000 0.20392 0.20392 0.20392 0.20784 0.20784 0.20784 0.21177 0.21177 0.21177 0.21569 0.21569 0.21569 0.21961 0.21961 0.21961 0.22353 0.22353 0.22353 0.22745 0.22745 0.22745 0.23137 0.23137 0.23137 0.23529 0.23529 0.23529 0.23922 0.23922 0.23922 0.24314 0.24314 0.24314 0.24706 0.24706 0.24706 0.25098 0.25098 0.25098 0.25490 0.25490 0.25490 0.25882 0.25882 0.25882 0.26275 0.26275 0.26275 0.26667 0.26667 0.26667 0.27059 0.27059 0.27059 0.27451 0.27451 0.27451 0.27843 0.27843 0.27843 0.28235 0.28235 0.28235 0.28628 0.28628 0.28628 0.29020 0.29020 0.29020 0.29412 0.29412 0.29412 0.29804 0.29804 0.29804 0.30196 0.30196 0.30196 0.30588 0.30588 0.30588 0.30980 0.30980 0.30980 0.31372 0.31372 0.31372 0.31765 0.31765 0.31765 0.32157 0.32157 0.32157 0.32549 0.32549 0.32549 0.32941 0.32941 0.32941 0.33333 0.33333 0.33333 0.33726 0.33726 0.33726 0.34118 0.34118 0.34118 0.34510 0.34510 0.34510 0.34902 0.34902 0.34902 0.35294 0.35294 0.35294 0.35686 0.35686 0.35686 0.36078 0.36078 0.36078 0.36471 0.36471 0.36471 0.36863 0.36863 0.36863 0.37255 0.37255 0.37255 0.37647 0.37647 0.37647 0.38039 0.38039 0.38039 0.38431 0.38431 0.38431 0.38823 0.38823 0.38823 0.39216 0.39216 0.39216 0.39608 0.39608 0.39608 0.40000 0.40000 0.40000 0.40392 0.40392 0.40392 0.40784 0.40784 0.40784 0.41176 0.41176 0.41176 0.41569 0.41569 0.41569 0.41961 0.41961 0.41961 0.42353 0.42353 0.42353 0.42745 0.42745 0.42745 0.43137 0.43137 0.43137 0.43529 0.43529 0.43529 0.43922 0.43922 0.43922 0.44314 0.44314 0.44314 0.44706 0.44706 0.44706 0.45098 0.45098 0.45098 0.45490 0.45490 0.45490 0.45882 0.45882 0.45882 0.46275 0.46275 0.46275 0.46667 0.46667 0.46667 0.47059 0.47059 0.47059 0.47451 0.47451 0.47451 0.47843 0.47843 0.47843 0.48235 0.48235 0.48235 0.48628 0.48628 0.48628 0.49020 0.49020 0.49020 0.49412 0.49412 0.49412 0.49804 0.49804 0.49804 0.50196 0.50196 0.50196 0.50588 0.50588 0.50588 0.50980 0.50980 0.50980 0.51372 0.51372 0.51372 0.51765 0.51765 0.51765 0.52157 0.52157 0.52157 0.52549 0.52549 0.52549 0.52941 0.52941 0.52941 0.53333 0.53333 0.53333 0.53726 0.53726 0.53726 0.54118 0.54118 0.54118 0.54510 0.54510 0.54510 0.54902 0.54902 0.54902 0.55294 0.55294 0.55294 0.55686 0.55686 0.55686 0.56078 0.56078 0.56078 0.56471 0.56471 0.56471 0.56863 0.56863 0.56863 0.57255 0.57255 0.57255 0.57647 0.57647 0.57647 0.58039 0.58039 0.58039 0.58431 0.58431 0.58431 0.58823 0.58823 0.58823 0.59216 0.59216 0.59216 0.59608 0.59608 0.59608 0.60000 0.60000 0.60000 0.60392 0.60392 0.60392 0.60784 0.60784 0.60784 0.61177 0.61177 0.61177 0.61569 0.61569 0.61569 0.61961 0.61961 0.61961 0.62353 0.62353 0.62353 0.62745 0.62745 0.62745 0.63137 0.63137 0.63137 0.63529 0.63529 0.63529 0.63922 0.63922 0.63922 0.64314 0.64314 0.64314 0.64706 0.64706 0.64706 0.65098 0.65098 0.65098 0.65490 0.65490 0.65490 0.65882 0.65882 0.65882 0.66275 0.66275 0.66275 0.66667 0.66667 0.66667 0.67059 0.67059 0.67059 0.67451 0.67451 0.67451 0.67843 0.67843 0.67843 0.68235 0.68235 0.68235 0.68627 0.68627 0.68627 0.69020 0.69020 0.69020 0.69412 0.69412 0.69412 0.69804 0.69804 0.69804 0.70196 0.70196 0.70196 0.70588 0.70588 0.70588 0.70980 0.70980 0.70980 0.71373 0.71373 0.71373 0.71765 0.71765 0.71765 0.72157 0.72157 0.72157 0.72549 0.72549 0.72549 0.72941 0.72941 0.72941 0.73333 0.73333 0.73333 0.73725 0.73725 0.73725 0.74118 0.74118 0.74118 0.74510 0.74510 0.74510 0.74902 0.74902 0.74902 0.75294 0.75294 0.75294 0.75686 0.75686 0.75686 0.76078 0.76078 0.76078 0.76471 0.76471 0.76471 0.76863 0.76863 0.76863 0.77255 0.77255 0.77255 0.77647 0.77647 0.77647 0.78039 0.78039 0.78039 0.78431 0.78431 0.78431 0.78824 0.78824 0.78824 0.79216 0.79216 0.79216 0.79608 0.79608 0.79608 0.80000 0.80000 0.80000 0.80392 0.80392 0.80392 0.80784 0.80784 0.80784 0.81176 0.81176 0.81176 0.81569 0.81569 0.81569 0.81961 0.81961 0.81961 0.82353 0.82353 0.82353 0.82745 0.82745 0.82745 0.83137 0.83137 0.83137 0.83529 0.83529 0.83529 0.83922 0.83922 0.83922 0.84314 0.84314 0.84314 0.84706 0.84706 0.84706 0.85098 0.85098 0.85098 0.85490 0.85490 0.85490 0.85882 0.85882 0.85882 0.86274 0.86274 0.86274 0.86667 0.86667 0.86667 0.87059 0.87059 0.87059 0.87451 0.87451 0.87451 0.87843 0.87843 0.87843 0.88235 0.88235 0.88235 0.88628 0.88628 0.88628 0.89020 0.89020 0.89020 0.89412 0.89412 0.89412 0.89804 0.89804 0.89804 0.90196 0.90196 0.90196 0.90588 0.90588 0.90588 0.90980 0.90980 0.90980 0.91373 0.91373 0.91373 0.91765 0.91765 0.91765 0.92157 0.92157 0.92157 0.92549 0.92549 0.92549 0.92941 0.92941 0.92941 0.93333 0.93333 0.93333 0.93725 0.93725 0.93725 0.94118 0.94118 0.94118 0.94510 0.94510 0.94510 0.94902 0.94902 0.94902 0.95294 0.95294 0.95294 0.95686 0.95686 0.95686 0.96078 0.96078 0.96078 0.96471 0.96471 0.96471 0.96863 0.96863 0.96863 0.97255 0.97255 0.97255 0.97647 0.97647 0.97647 0.98039 0.98039 0.98039 0.98431 0.98431 0.98431 0.98823 0.98823 0.98823 0.99216 0.99216 0.99216 0.99608 0.99608 0.99608 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/random.lasc000066400000000000000000000324001215713201500220500ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.47059 0.00000 0.86275 0.47059 0.00000 0.86275 0.47059 0.00000 0.86275 0.70588 0.00000 0.90196 0.70588 0.00000 0.90196 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.51765 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98431 0.81176 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.47059 0.78431 1.00000 0.47059 0.78431 1.00000 0.47059 0.78431 1.00000 0.62745 0.62745 1.00000 0.62745 0.62745 1.00000 0.78431 0.47059 1.00000 0.78431 0.47059 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.76863 1.00000 1.00000 0.86275 1.00000 1.00000 0.86275 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 0.89804 1.00000 1.00000 0.86275 1.00000 1.00000 0.86275 1.00000 1.00000 0.86275 1.00000 1.00000 0.86275 1.00000 1.00000 0.86275 1.00000 1.00000 0.86275 1.00000 1.00000 0.86275 1.00000 1.00000 0.86275 1.00000 1.00000 0.86275 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 0.92157 0.61961 1.00000 0.78431 0.47059 1.00000 0.78431 0.47059 1.00000 0.78431 0.47059 1.00000 0.78431 0.47059 1.00000 0.78431 0.47059 1.00000 0.78431 0.47059 1.00000 0.78431 0.47059 1.00000 0.78431 0.47059 1.00000 0.78431 0.47059 1.00000 0.65882 0.59608 1.00000 0.62745 0.62745 1.00000 0.62745 0.62745 1.00000 0.62745 0.62745 1.00000 0.62745 0.62745 1.00000 0.62745 0.62745 1.00000 0.62745 0.62745 1.00000 0.62745 0.62745 1.00000 0.62745 0.62745 1.00000 0.62745 0.62745 1.00000 0.47059 0.78431 1.00000 0.47059 0.78431 1.00000 0.47059 0.78431 1.00000 0.47059 0.78431 1.00000 0.47059 0.78431 1.00000 0.47059 0.78431 1.00000 0.47059 0.78431 1.00000 0.47059 0.78431 1.00000 0.47059 0.78431 1.00000 0.26275 0.87843 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 0.74118 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.65490 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.36078 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.98431 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 0.99608 0.97647 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98824 0.77647 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.36863 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.46667 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 0.91373 0.00000 0.97255 0.70588 0.00000 0.90196 0.70588 0.00000 0.90196 0.70588 0.00000 0.90196 0.70588 0.00000 0.90196 0.70588 0.00000 0.90196 0.70588 0.00000 0.90196 0.70588 0.00000 0.90196 0.70588 0.00000 0.90196 0.70588 0.00000 0.90196 0.53333 0.00000 0.87451 0.47059 0.00000 0.86275 0.47059 0.00000 0.86275 0.47059 0.00000 0.86275 0.47059 0.00000 0.86275 0.47059 0.00000 0.86275 0.47059 0.00000 0.86275 0.47059 0.00000 0.86275 0.47059 0.00000 0.86275 0.47059 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.80392 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.13725 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/random1.lasc000066400000000000000000000324001215713201500221310ustar00rootroot00000000000000 0.00000 0.00000 0.16471 0.00000 0.00000 0.16471 0.00000 0.00000 0.16471 0.00000 0.00000 0.16471 0.00000 0.00000 0.16471 0.00000 0.00000 0.16471 0.00000 0.00000 0.16471 0.00000 0.00000 0.16471 0.23137 0.00000 0.31765 0.23137 0.00000 0.31765 0.23137 0.00000 0.31765 0.23137 0.00000 0.31765 0.23137 0.00000 0.31765 0.23137 0.00000 0.31765 0.23137 0.00000 0.31765 0.23137 0.00000 0.31765 0.47059 0.00000 0.47451 0.47059 0.00000 0.47451 0.47059 0.00000 0.47451 0.47059 0.00000 0.47451 0.47059 0.00000 0.47451 0.47059 0.00000 0.47451 0.47059 0.00000 0.47451 0.47059 0.00000 0.47451 0.47059 0.00000 0.63922 0.47059 0.00000 0.63922 0.47059 0.00000 0.63922 0.47059 0.00000 0.63922 0.47059 0.00000 0.63922 0.47059 0.00000 0.63922 0.47059 0.00000 0.63922 0.47059 0.00000 0.63922 0.23137 0.00000 0.80392 0.23137 0.00000 0.80392 0.23137 0.00000 0.80392 0.23137 0.00000 0.80392 0.23137 0.00000 0.80392 0.23137 0.00000 0.80392 0.23137 0.00000 0.80392 0.23137 0.00000 0.80392 0.00000 0.00000 0.97647 0.00000 0.00000 0.97647 0.00000 0.00000 0.97647 0.00000 0.00000 0.97647 0.00000 0.00000 0.97647 0.00000 0.00000 0.97647 0.00000 0.00000 0.97647 0.00000 0.00000 0.97647 0.00000 0.05098 0.85098 0.00000 0.05098 0.85098 0.00000 0.05098 0.85098 0.00000 0.05098 0.85098 0.00000 0.05098 0.85098 0.00000 0.05098 0.85098 0.00000 0.05098 0.85098 0.00000 0.05098 0.85098 0.00000 0.19608 0.69412 0.00000 0.19608 0.69412 0.00000 0.19608 0.69412 0.00000 0.19608 0.69412 0.00000 0.19608 0.69412 0.00000 0.19608 0.69412 0.00000 0.19608 0.69412 0.00000 0.19608 0.69412 0.00000 0.33333 0.56471 0.00000 0.33333 0.56471 0.00000 0.33333 0.56471 0.00000 0.33333 0.56471 0.00000 0.33333 0.56471 0.00000 0.33333 0.56471 0.00000 0.33333 0.56471 0.00000 0.33333 0.56471 0.00000 0.42353 0.44706 0.00000 0.42353 0.44706 0.00000 0.42353 0.44706 0.00000 0.42353 0.44706 0.00000 0.42353 0.44706 0.00000 0.42353 0.44706 0.00000 0.42353 0.44706 0.00000 0.42353 0.44706 0.00000 0.50980 0.35294 0.00000 0.50980 0.35294 0.00000 0.50980 0.35294 0.00000 0.50980 0.35294 0.00000 0.50980 0.35294 0.00000 0.50980 0.35294 0.00000 0.50980 0.35294 0.00000 0.50980 0.35294 0.00000 0.59216 0.25882 0.00000 0.59216 0.25882 0.00000 0.59216 0.25882 0.00000 0.59216 0.25882 0.00000 0.59216 0.25882 0.00000 0.59216 0.25882 0.00000 0.59216 0.25882 0.00000 0.59216 0.25882 0.00000 0.67059 0.16471 0.00000 0.67059 0.16471 0.00000 0.67059 0.16471 0.00000 0.67059 0.16471 0.00000 0.67059 0.16471 0.00000 0.67059 0.16471 0.00000 0.67059 0.16471 0.00000 0.67059 0.16471 0.00000 0.74902 0.05490 0.00000 0.74902 0.05490 0.00000 0.74902 0.05490 0.00000 0.74902 0.05490 0.00000 0.74902 0.05490 0.00000 0.74902 0.05490 0.00000 0.74902 0.05490 0.00000 0.74902 0.05490 0.00000 0.82353 0.00000 0.00000 0.82353 0.00000 0.00000 0.82353 0.00000 0.00000 0.82353 0.00000 0.00000 0.82353 0.00000 0.00000 0.82353 0.00000 0.00000 0.82353 0.00000 0.00000 0.82353 0.00000 0.00000 0.89804 0.00000 0.00000 0.89804 0.00000 0.00000 0.89804 0.00000 0.00000 0.89804 0.00000 0.00000 0.89804 0.00000 0.00000 0.89804 0.00000 0.00000 0.89804 0.00000 0.00000 0.89804 0.00000 0.00000 0.97255 0.00000 0.00000 0.97255 0.00000 0.00000 0.97255 0.00000 0.00000 0.97255 0.00000 0.00000 0.97255 0.00000 0.00000 0.97255 0.00000 0.00000 0.97255 0.00000 0.00000 0.97255 0.00000 0.05490 0.95294 0.00000 0.05490 0.95294 0.00000 0.05490 0.95294 0.00000 0.05490 0.95294 0.00000 0.05490 0.95294 0.00000 0.05490 0.95294 0.00000 0.05490 0.95294 0.00000 0.05490 0.95294 0.00000 0.14902 0.88235 0.00000 0.14902 0.88235 0.00000 0.14902 0.88235 0.00000 0.14902 0.88235 0.00000 0.14902 0.88235 0.00000 0.14902 0.88235 0.00000 0.14902 0.88235 0.00000 0.14902 0.88235 0.00000 0.41176 0.80784 0.00000 0.41176 0.80784 0.00000 0.41176 0.80784 0.00000 0.41176 0.80784 0.00000 0.41176 0.80784 0.00000 0.41176 0.80784 0.00000 0.41176 0.80784 0.00000 0.41176 0.80784 0.00000 0.70980 0.81176 0.00000 0.70980 0.81176 0.00000 0.70980 0.81176 0.00000 0.70980 0.81176 0.00000 0.70980 0.81176 0.00000 0.70980 0.81176 0.00000 0.70980 0.81176 0.00000 0.70980 0.81176 0.00000 1.00000 0.93333 0.00000 1.00000 0.93333 0.00000 1.00000 0.93333 0.00000 1.00000 0.93333 0.00000 1.00000 0.93333 0.00000 1.00000 0.93333 0.00000 1.00000 0.93333 0.00000 1.00000 0.93333 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 0.70196 0.00000 1.00000 0.70196 0.00000 1.00000 0.70196 0.00000 1.00000 0.70196 0.00000 1.00000 0.70196 0.00000 1.00000 0.70196 0.00000 1.00000 0.70196 0.00000 1.00000 0.70196 0.00000 1.00000 0.39216 0.00000 1.00000 0.39216 0.00000 1.00000 0.39216 0.00000 1.00000 0.39216 0.00000 1.00000 0.39216 0.00000 1.00000 0.39216 0.00000 1.00000 0.39216 0.00000 1.00000 0.39216 0.00000 1.00000 0.09804 0.00000 1.00000 0.09804 0.00000 1.00000 0.09804 0.00000 1.00000 0.09804 0.00000 1.00000 0.09804 0.00000 1.00000 0.09804 0.00000 1.00000 0.09804 0.00000 1.00000 0.09804 0.00000 0.97647 0.00000 0.00000 0.97647 0.00000 0.00000 0.97647 0.00000 0.00000 0.97647 0.00000 0.00000 0.97647 0.00000 0.00000 0.97647 0.00000 0.00000 0.97647 0.00000 0.00000 0.97647 0.00000 0.00000 0.91373 0.00000 0.00000 0.91373 0.00000 0.00000 0.91373 0.00000 0.00000 0.91373 0.00000 0.00000 0.91373 0.00000 0.00000 0.91373 0.00000 0.00000 0.91373 0.00000 0.00000 0.91373 0.00000 0.00000 0.85098 0.00000 0.00000 0.85098 0.00000 0.00000 0.85098 0.00000 0.00000 0.85098 0.00000 0.00000 0.85098 0.00000 0.00000 0.85098 0.00000 0.00000 0.85098 0.00000 0.00000 0.85098 0.00000 0.00000 0.78824 0.00000 0.00000 0.78824 0.00000 0.00000 0.78824 0.00000 0.00000 0.78824 0.00000 0.00000 0.78824 0.00000 0.00000 0.78824 0.00000 0.00000 0.78824 0.00000 0.00000 0.78824 0.00000 0.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/random2.lasc000066400000000000000000000324001215713201500221320ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00392 0.47059 0.00392 0.00392 0.47059 0.00392 0.00392 0.47059 0.00392 0.00392 0.47059 0.00392 0.00392 0.47059 0.00392 0.00392 0.47059 0.00392 0.00392 0.47059 0.00392 0.00392 0.47059 0.00392 0.00392 0.47059 0.00392 0.00392 0.47059 0.00392 0.00392 0.62745 0.00392 0.00392 0.62745 0.00392 0.00392 0.62745 0.00392 0.00392 0.62745 0.00392 0.00392 0.62745 0.00392 0.00392 0.62745 0.00392 0.00392 0.62745 0.00392 0.00392 0.62745 0.00392 0.00392 0.62745 0.00392 0.00392 0.62745 0.00392 0.00392 0.78431 0.00392 0.00392 0.78431 0.00392 0.00392 0.78431 0.00392 0.00392 0.78431 0.00392 0.00392 0.78431 0.00392 0.00392 0.78431 0.00392 0.00392 0.78431 0.00392 0.00392 0.78431 0.00392 0.00392 0.78431 0.00392 0.00392 0.78431 0.00392 0.00392 1.00000 0.00392 0.00392 1.00000 0.00392 0.00392 1.00000 0.00392 0.00392 1.00000 0.00392 0.00392 1.00000 0.00392 0.00392 1.00000 0.00392 0.00392 1.00000 0.00392 0.00392 1.00000 0.00392 0.00392 1.00000 0.00392 0.00392 1.00000 0.00392 0.00392 0.86275 0.47059 0.00392 0.86275 0.47059 0.00392 0.86275 0.47059 0.00392 0.86275 0.47059 0.00392 0.86275 0.47059 0.00392 0.86275 0.47059 0.00392 0.86275 0.47059 0.00392 0.86275 0.47059 0.00392 0.86275 0.47059 0.00392 0.86275 0.47059 0.00000 0.78431 0.62745 0.00000 0.78431 0.62745 0.00000 0.78431 0.62745 0.00000 0.78431 0.62745 0.00000 0.78431 0.62745 0.00000 0.78431 0.62745 0.00000 0.78431 0.62745 0.00000 0.78431 0.62745 0.00000 0.78431 0.62745 0.00000 0.78431 0.62745 0.00000 0.70588 0.78431 0.00000 0.70588 0.78431 0.00000 0.70588 0.78431 0.00000 0.70588 0.78431 0.00000 0.70588 0.78431 0.00000 0.70588 0.78431 0.00000 0.70588 0.78431 0.00000 0.70588 0.78431 0.00000 0.70588 0.78431 0.00000 0.70588 0.78431 0.00000 0.62745 1.00000 0.00000 0.62745 1.00000 0.00000 0.62745 1.00000 0.00000 0.62745 1.00000 0.00000 0.62745 1.00000 0.00000 0.62745 1.00000 0.00000 0.62745 1.00000 0.00000 0.62745 1.00000 0.00000 0.62745 1.00000 0.00000 0.62745 1.00000 0.23529 0.47059 1.00000 0.23529 0.47059 1.00000 0.23529 0.47059 1.00000 0.23529 0.47059 1.00000 0.23529 0.47059 1.00000 0.23529 0.47059 1.00000 0.23529 0.47059 1.00000 0.23529 0.47059 1.00000 0.23529 0.47059 1.00000 0.23529 0.47059 1.00000 0.23529 0.00392 1.00000 0.23529 0.00392 1.00000 0.23529 0.00392 1.00000 0.23529 0.00392 1.00000 0.23529 0.00392 1.00000 0.23529 0.00392 1.00000 0.23529 0.00392 1.00000 0.23529 0.00392 1.00000 0.23529 0.00392 1.00000 0.23529 0.00392 1.00000 0.47059 0.00392 0.78431 0.47059 0.00392 0.78431 0.47059 0.00392 0.78431 0.47059 0.00392 0.78431 0.47059 0.00392 0.78431 0.47059 0.00392 0.78431 0.47059 0.00392 0.78431 0.47059 0.00392 0.78431 0.47059 0.00392 0.78431 0.47059 0.00392 0.78431 0.62745 0.00392 0.62745 0.62745 0.00392 0.62745 0.62745 0.00392 0.62745 0.62745 0.00392 0.62745 0.62745 0.00392 0.62745 0.62745 0.00392 0.62745 0.62745 0.00392 0.62745 0.62745 0.00392 0.62745 0.62745 0.00392 0.62745 0.62745 0.00392 0.62745 0.78431 0.00392 0.47059 0.78431 0.00392 0.47059 0.78431 0.00392 0.47059 0.78431 0.00392 0.47059 0.78431 0.00392 0.47059 0.78431 0.00392 0.47059 0.78431 0.00392 0.47059 0.78431 0.00392 0.47059 0.78431 0.00392 0.47059 0.78431 0.00392 0.47059 0.90196 0.11765 0.23529 0.90196 0.11765 0.23529 0.90196 0.11765 0.23529 0.90196 0.11765 0.23529 0.90196 0.11765 0.23529 0.90196 0.11765 0.23529 0.90196 0.11765 0.23529 0.90196 0.11765 0.23529 0.90196 0.11765 0.23529 0.90196 0.11765 0.23529 1.00000 0.23529 0.00000 1.00000 0.23529 0.00000 1.00000 0.23529 0.00000 1.00000 0.23529 0.00000 1.00000 0.23529 0.00000 1.00000 0.23529 0.00000 1.00000 0.23529 0.00000 1.00000 0.23529 0.00000 1.00000 0.23529 0.00000 1.00000 0.23529 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 0.99216 0.59608 0.00000 0.99216 0.59608 0.00000 0.99216 0.59608 0.00000 0.99216 0.59608 0.00000 0.99216 0.59608 0.00000 0.99216 0.59608 0.00000 0.99216 0.59608 0.00000 0.99216 0.59608 0.00000 0.99216 0.59608 0.00000 0.99216 0.59608 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98039 0.90196 0.00000 0.98039 0.90196 0.00000 0.98039 0.90196 0.00000 0.98039 0.90196 0.00000 0.98039 0.90196 0.00000 0.98039 0.90196 0.00000 0.98039 0.90196 0.00000 0.98039 0.90196 0.00000 0.98039 0.90196 0.00000 0.98039 0.90196 0.00000 0.98039 0.98039 0.47059 0.98039 0.98039 0.47059 0.98039 0.98039 0.47059 0.98039 0.98039 0.47059 0.98039 0.98039 0.47059 0.98039 0.98039 0.47059 0.98039 0.98039 0.47059 0.98039 0.98039 0.47059 0.98039 0.98039 0.47059 0.98039 0.98039 0.47059 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/random3.lasc000066400000000000000000000324001215713201500221330ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.47059 0.00000 0.00000 0.47059 0.00000 0.00000 0.47059 0.00000 0.00000 0.47059 0.00000 0.00000 0.47059 0.00000 0.00000 0.47059 0.00000 0.00000 0.47059 0.00000 0.00000 0.47059 0.00000 0.00000 0.47059 0.00000 0.00000 0.47059 0.00000 0.00000 0.47059 0.00000 0.00000 0.47059 0.00000 0.00000 0.47059 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.47059 1.00000 0.00000 0.47059 1.00000 0.00000 0.47059 1.00000 0.00000 0.47059 1.00000 0.00000 0.47059 1.00000 0.00000 0.47059 1.00000 0.00000 0.47059 1.00000 0.00000 0.47059 1.00000 0.00000 0.47059 1.00000 0.00000 0.47059 1.00000 0.00000 0.47059 1.00000 0.00000 0.47059 1.00000 0.00000 0.47059 1.00000 0.00000 0.78431 1.00000 0.00000 0.78431 1.00000 0.00000 0.78431 1.00000 0.00000 0.78431 1.00000 0.00000 0.78431 1.00000 0.00000 0.78431 1.00000 0.00000 0.78431 1.00000 0.00000 0.78431 1.00000 0.00000 0.78431 1.00000 0.00000 0.78431 1.00000 0.00000 0.78431 1.00000 0.00000 0.78431 1.00000 0.00000 0.78431 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.47059 1.00000 1.00000 0.47059 1.00000 1.00000 0.47059 1.00000 1.00000 0.47059 1.00000 1.00000 0.47059 1.00000 1.00000 0.47059 1.00000 1.00000 0.47059 1.00000 1.00000 0.47059 1.00000 1.00000 0.47059 1.00000 1.00000 0.47059 1.00000 1.00000 0.47059 1.00000 1.00000 0.47059 1.00000 1.00000 0.47059 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/random4.lasc000066400000000000000000000324001215713201500221340ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.70588 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.00000 0.00000 0.86275 0.47059 0.00000 0.86275 0.47059 0.00000 0.86275 0.47059 0.00000 0.86275 0.47059 0.00000 0.86275 0.47059 0.00000 0.86275 0.47059 0.00000 0.86275 0.47059 0.00000 0.86275 0.47059 0.00000 0.86275 0.47059 0.00000 0.86275 0.47059 0.00000 0.86275 0.47059 0.00000 0.86275 0.47059 0.00000 0.86275 0.70588 0.00000 0.90196 0.70588 0.00000 0.90196 0.70588 0.00000 0.90196 0.70588 0.00000 0.90196 0.70588 0.00000 0.90196 0.70588 0.00000 0.90196 0.70588 0.00000 0.90196 0.70588 0.00000 0.90196 0.70588 0.00000 0.90196 0.70588 0.00000 0.90196 0.70588 0.00000 0.90196 0.70588 0.00000 0.90196 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 1.00000 0.47059 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98824 0.72549 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 0.98431 0.85098 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.70588 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 0.70588 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.47059 0.78431 1.00000 0.47059 0.78431 1.00000 0.47059 0.78431 1.00000 0.47059 0.78431 1.00000 0.47059 0.78431 1.00000 0.47059 0.78431 1.00000 0.47059 0.78431 1.00000 0.47059 0.78431 1.00000 0.47059 0.78431 1.00000 0.47059 0.78431 1.00000 0.47059 0.78431 1.00000 0.47059 0.78431 1.00000 0.62745 0.62745 1.00000 0.62745 0.62745 1.00000 0.62745 0.62745 1.00000 0.62745 0.62745 1.00000 0.62745 0.62745 1.00000 0.62745 0.62745 1.00000 0.62745 0.62745 1.00000 0.62745 0.62745 1.00000 0.62745 0.62745 1.00000 0.62745 0.62745 1.00000 0.62745 0.62745 1.00000 0.62745 0.62745 1.00000 0.78431 0.47059 1.00000 0.78431 0.47059 1.00000 0.78431 0.47059 1.00000 0.78431 0.47059 1.00000 0.78431 0.47059 1.00000 0.78431 0.47059 1.00000 0.78431 0.47059 1.00000 0.78431 0.47059 1.00000 0.78431 0.47059 1.00000 0.78431 0.47059 1.00000 0.78431 0.47059 1.00000 0.78431 0.47059 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.70588 1.00000 1.00000 0.86275 1.00000 1.00000 0.86275 1.00000 1.00000 0.86275 1.00000 1.00000 0.86275 1.00000 1.00000 0.86275 1.00000 1.00000 0.86275 1.00000 1.00000 0.86275 1.00000 1.00000 0.86275 1.00000 1.00000 0.86275 1.00000 1.00000 0.86275 1.00000 1.00000 0.86275 1.00000 1.00000 0.86275 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/random5.lasc000066400000000000000000000324001215713201500221350ustar00rootroot00000000000000 0.00000 0.00000 1.00000 0.00000 0.00000 0.99216 0.00000 0.00000 0.98824 0.00392 0.00000 0.98431 0.00392 0.00000 0.98039 0.00784 0.00000 0.97647 0.00784 0.00000 0.96863 0.01176 0.00000 0.96471 0.01569 0.00000 0.96078 0.01569 0.00000 0.95686 0.01961 0.00000 0.95294 0.01961 0.00000 0.94510 0.02353 0.00784 0.94118 0.02745 0.01569 0.93725 0.02745 0.02745 0.93333 0.03137 0.03922 0.92941 0.03529 0.05098 0.92157 0.03529 0.06667 0.91765 0.03922 0.08235 0.91373 0.04314 0.09804 0.90980 0.04706 0.11765 0.90588 0.04706 0.09804 0.90196 0.05098 0.08235 0.89412 0.05490 0.06667 0.89020 0.05490 0.05098 0.88627 0.05882 0.03922 0.88235 0.06275 0.02745 0.87843 0.06667 0.01569 0.87059 0.07059 0.00784 0.86667 0.07059 0.00000 0.86275 0.07451 0.00000 0.85882 0.07843 0.00392 0.85490 0.08235 0.01176 0.85098 0.08235 0.02353 0.84314 0.08627 0.03922 0.83922 0.09020 0.05490 0.83529 0.09412 0.07059 0.83137 0.09804 0.09020 0.82745 0.09804 0.10980 0.82353 0.10196 0.13333 0.81569 0.10588 0.15686 0.81176 0.10980 0.13333 0.80784 0.11373 0.10980 0.80392 0.11765 0.09020 0.80000 0.11765 0.07059 0.79608 0.12157 0.05490 0.79216 0.12549 0.03922 0.78431 0.12941 0.02353 0.78039 0.13333 0.01176 0.77647 0.13725 0.00392 0.77255 0.14118 0.00000 0.76863 0.14118 0.00392 0.76471 0.14510 0.01569 0.75686 0.14902 0.03137 0.75294 0.15294 0.04706 0.74902 0.15686 0.06667 0.74510 0.16078 0.09020 0.74118 0.16471 0.11373 0.73725 0.16863 0.13725 0.73333 0.17255 0.16471 0.72549 0.17255 0.19608 0.72157 0.17647 0.16471 0.71765 0.18039 0.13725 0.71373 0.18431 0.11373 0.70980 0.18824 0.09020 0.70588 0.19216 0.06667 0.70196 0.19608 0.04706 0.69804 0.20000 0.03137 0.69020 0.20392 0.01569 0.68627 0.20784 0.00392 0.68235 0.21176 0.00000 0.67843 0.21176 0.00784 0.67451 0.21569 0.02353 0.67059 0.21961 0.04314 0.66667 0.22353 0.06667 0.66275 0.22745 0.09412 0.65490 0.23137 0.12549 0.65098 0.23529 0.15686 0.64706 0.23922 0.19608 0.64314 0.24314 0.23137 0.63922 0.24706 0.27451 0.63529 0.25098 0.23137 0.63137 0.25490 0.19608 0.62745 0.25882 0.15686 0.61961 0.26275 0.12549 0.61569 0.26667 0.09412 0.61176 0.27059 0.06667 0.60784 0.27451 0.04314 0.60392 0.27843 0.02353 0.60000 0.28235 0.00784 0.59608 0.28627 0.00000 0.59216 0.29020 0.00784 0.58824 0.29412 0.03137 0.58431 0.29804 0.05490 0.57647 0.29804 0.08627 0.57255 0.30196 0.12157 0.56863 0.30588 0.16078 0.56471 0.30980 0.20392 0.56078 0.31373 0.25098 0.55686 0.31765 0.29804 0.55294 0.32157 0.35294 0.54902 0.32549 0.29804 0.54510 0.32941 0.25098 0.54118 0.33333 0.20392 0.53725 0.33725 0.16078 0.52941 0.34118 0.12157 0.52549 0.34510 0.08627 0.52157 0.34902 0.05490 0.51765 0.35294 0.03137 0.51373 0.35686 0.00784 0.50980 0.36078 0.00000 0.50588 0.36471 0.01176 0.50196 0.37255 0.03529 0.49804 0.37647 0.07059 0.49412 0.38039 0.10588 0.49020 0.38431 0.14902 0.48627 0.38824 0.20000 0.48235 0.39216 0.25098 0.47843 0.39608 0.30588 0.47059 0.40000 0.36471 0.46667 0.40392 0.43137 0.46275 0.40784 0.36471 0.45882 0.41176 0.30588 0.45490 0.41569 0.25098 0.45098 0.41961 0.20000 0.44706 0.42353 0.14902 0.44314 0.42745 0.10588 0.43922 0.43137 0.07059 0.43529 0.43529 0.03529 0.43137 0.43922 0.01176 0.42745 0.44314 0.00000 0.42353 0.44706 0.01569 0.41961 0.45098 0.04314 0.41569 0.45490 0.08235 0.41176 0.45882 0.12549 0.40784 0.46275 0.17647 0.40392 0.46667 0.23529 0.40000 0.47059 0.29804 0.39608 0.47843 0.36471 0.39216 0.48235 0.43137 0.38824 0.48627 0.50980 0.38431 0.49020 0.43137 0.38039 0.49412 0.36471 0.37647 0.49804 0.29804 0.37255 0.50196 0.23529 0.36471 0.50588 0.17647 0.36078 0.50980 0.12549 0.35686 0.51373 0.08235 0.35294 0.51765 0.04314 0.34902 0.52157 0.01569 0.34510 0.52549 0.00000 0.34118 0.52941 0.01569 0.33725 0.53725 0.05098 0.33333 0.54118 0.09412 0.32941 0.54510 0.14510 0.32549 0.54902 0.20784 0.32157 0.55294 0.27059 0.31765 0.55686 0.34118 0.31373 0.56078 0.41961 0.30980 0.56471 0.50196 0.30588 0.56863 0.58824 0.30196 0.57255 0.50196 0.29804 0.57647 0.41961 0.29804 0.58431 0.34118 0.29412 0.58824 0.27059 0.29020 0.59216 0.20784 0.28627 0.59608 0.14510 0.28235 0.60000 0.09412 0.27843 0.60392 0.05098 0.27451 0.60784 0.01569 0.27059 0.61176 0.00000 0.26667 0.61569 0.01961 0.26275 0.61961 0.05882 0.25882 0.62745 0.10588 0.25490 0.63137 0.16863 0.25098 0.63529 0.23529 0.24706 0.63922 0.30980 0.24314 0.64314 0.38824 0.23922 0.64706 0.47451 0.23529 0.65098 0.56863 0.23137 0.65490 0.66667 0.22745 0.66275 0.56863 0.22353 0.66667 0.47451 0.21961 0.67059 0.38824 0.21569 0.67451 0.30980 0.21176 0.67843 0.23529 0.21176 0.68235 0.16863 0.20784 0.68627 0.10588 0.20392 0.69020 0.05882 0.20000 0.69804 0.01961 0.19608 0.70196 0.00000 0.19216 0.70588 0.02353 0.18824 0.70980 0.06275 0.18431 0.71373 0.12157 0.18039 0.71765 0.18824 0.17647 0.72157 0.26275 0.17255 0.72549 0.34510 0.17255 0.73333 0.43529 0.16863 0.73725 0.52941 0.16471 0.74118 0.63529 0.16078 0.74510 0.74510 0.15686 0.74902 0.63529 0.15294 0.75294 0.52941 0.14902 0.75686 0.43529 0.14510 0.76471 0.34510 0.14118 0.76863 0.26275 0.14118 0.77255 0.18824 0.13725 0.77647 0.12157 0.13333 0.78039 0.06275 0.12941 0.78431 0.02353 0.12549 0.79216 0.00000 0.12157 0.79608 0.02353 0.11765 0.80000 0.07059 0.11765 0.80392 0.13333 0.11373 0.80784 0.20784 0.10980 0.81176 0.29020 0.10588 0.81569 0.38039 0.10196 0.82353 0.47843 0.09804 0.82745 0.58824 0.09804 0.83137 0.70196 0.09412 0.83529 0.82353 0.09020 0.83922 0.70196 0.08627 0.84314 0.58824 0.08235 0.85098 0.47843 0.08235 0.85490 0.38039 0.07843 0.85882 0.29020 0.07451 0.86275 0.20784 0.07059 0.86667 0.13333 0.07059 0.87059 0.07059 0.06667 0.87843 0.02353 0.06275 0.88235 0.00000 0.05882 0.88627 0.02745 0.05490 0.89020 0.07843 0.05490 0.89412 0.14510 0.05098 0.90196 0.22745 0.04706 0.90588 0.31765 0.04706 0.90980 0.41569 0.04314 0.91373 0.52549 0.03922 0.91765 0.64314 0.03529 0.92157 0.76863 0.03529 0.92941 0.90196 0.03137 0.93333 0.76863 0.02745 0.93725 0.64314 0.02745 0.94118 0.52549 0.02353 0.94510 0.41569 0.01961 0.95294 0.31765 0.01961 0.95686 0.25882 0.01569 0.96078 0.23137 0.01569 0.96471 0.23922 0.01176 0.96863 0.27843 0.00784 0.97647 0.35294 0.00784 0.98039 0.46275 0.00392 0.98431 0.58431 0.00392 0.98824 0.71373 0.00000 0.99216 0.85098 0.00000 1.00000 1.00000 0.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/random6.lasc000066400000000000000000000324001215713201500221360ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00000 0.14118 0.00000 0.00000 0.28235 0.00000 0.00000 0.42353 0.00000 0.00000 0.56471 0.00000 0.00000 0.70588 0.00000 0.00000 0.84706 0.00000 0.00000 0.98824 0.00000 0.00000 0.00000 0.14118 0.00000 0.14118 0.14118 0.00000 0.28235 0.14118 0.00000 0.42353 0.14118 0.00000 0.56471 0.14118 0.00000 0.70588 0.14118 0.00000 0.84706 0.14118 0.00000 0.98824 0.14118 0.00000 0.00000 0.28235 0.00000 0.14118 0.28235 0.00000 0.28235 0.28235 0.00000 0.42353 0.28235 0.00000 0.56471 0.28235 0.00000 0.70588 0.28235 0.00000 0.84706 0.28235 0.00000 0.98824 0.28235 0.00000 0.00000 0.42353 0.00000 0.14118 0.42353 0.00000 0.28235 0.42353 0.00000 0.42353 0.42353 0.00000 0.56471 0.42353 0.00000 0.70588 0.42353 0.00000 0.84706 0.42353 0.00000 0.98824 0.42353 0.00000 0.00000 0.56471 0.00000 0.14118 0.56471 0.00000 0.28235 0.56471 0.00000 0.42353 0.56471 0.00000 0.56471 0.56471 0.00000 0.70588 0.56471 0.00000 0.84706 0.56471 0.00000 0.98824 0.56471 0.00000 0.00000 0.70588 0.00000 0.14118 0.70588 0.00000 0.28235 0.70588 0.00000 0.42353 0.70588 0.00000 0.56471 0.70588 0.00000 0.70588 0.70588 0.00000 0.84706 0.70588 0.00000 0.98824 0.70588 0.00000 0.00000 0.84706 0.00000 0.14118 0.84706 0.00000 0.28235 0.84706 0.00000 0.42353 0.84706 0.00000 0.56471 0.84706 0.00000 0.70588 0.84706 0.00000 0.84706 0.84706 0.00000 0.98824 0.84706 0.00000 0.00000 0.98824 0.00000 0.14118 0.98824 0.00000 0.28235 0.98824 0.00000 0.42353 0.98824 0.00000 0.56471 0.98824 0.00000 0.70588 0.98824 0.00000 0.84706 0.98824 0.00000 0.98824 0.98824 0.00000 0.00000 0.00000 0.32941 0.14118 0.00000 0.32941 0.28235 0.00000 0.32941 0.42353 0.00000 0.32941 0.56471 0.00000 0.32941 0.70588 0.00000 0.32941 0.84706 0.00000 0.32941 0.98824 0.00000 0.32941 0.00000 0.14118 0.32941 0.14118 0.14118 0.32941 0.28235 0.14118 0.32941 0.42353 0.14118 0.32941 0.56471 0.14118 0.32941 0.70588 0.14118 0.32941 0.84706 0.14118 0.32941 0.98824 0.14118 0.32941 0.00000 0.28235 0.32941 0.14118 0.28235 0.32941 0.28235 0.28235 0.32941 0.42353 0.28235 0.32941 0.56471 0.28235 0.32941 0.70588 0.28235 0.32941 0.84706 0.28235 0.32941 0.98824 0.28235 0.32941 0.00000 0.42353 0.32941 0.14118 0.42353 0.32941 0.28235 0.42353 0.32941 0.42353 0.42353 0.32941 0.56471 0.42353 0.32941 0.70588 0.42353 0.32941 0.84706 0.42353 0.32941 0.98824 0.42353 0.32941 0.00000 0.56471 0.32941 0.14118 0.56471 0.32941 0.28235 0.56471 0.32941 0.42353 0.56471 0.32941 0.56471 0.56471 0.32941 0.70588 0.56471 0.32941 0.84706 0.56471 0.32941 0.98824 0.56471 0.32941 0.00000 0.70588 0.32941 0.14118 0.70588 0.32941 0.28235 0.70588 0.32941 0.42353 0.70588 0.32941 0.56471 0.70588 0.32941 0.70588 0.70588 0.32941 0.84706 0.70588 0.32941 0.98824 0.70588 0.32941 0.00000 0.84706 0.32941 0.14118 0.84706 0.32941 0.28235 0.84706 0.32941 0.42353 0.84706 0.32941 0.56471 0.84706 0.32941 0.70588 0.84706 0.32941 0.84706 0.84706 0.32941 0.98824 0.84706 0.32941 0.00000 0.98824 0.32941 0.14118 0.98824 0.32941 0.28235 0.98824 0.32941 0.42353 0.98824 0.32941 0.56471 0.98824 0.32941 0.70588 0.98824 0.32941 0.84706 0.98824 0.32941 0.98824 0.98824 0.32941 0.00000 0.00000 0.65882 0.14118 0.00000 0.65882 0.28235 0.00000 0.65882 0.42353 0.00000 0.65882 0.56471 0.00000 0.65882 0.70588 0.00000 0.65882 0.84706 0.00000 0.65882 0.98824 0.00000 0.65882 0.00000 0.14118 0.65882 0.14118 0.14118 0.65882 0.28235 0.14118 0.65882 0.42353 0.14118 0.65882 0.56471 0.14118 0.65882 0.70588 0.14118 0.65882 0.84706 0.14118 0.65882 0.98824 0.14118 0.65882 0.00000 0.28235 0.65882 0.14118 0.28235 0.65882 0.28235 0.28235 0.65882 0.42353 0.28235 0.65882 0.56471 0.28235 0.65882 0.70588 0.28235 0.65882 0.84706 0.28235 0.65882 0.98824 0.28235 0.65882 0.00000 0.42353 0.65882 0.14118 0.42353 0.65882 0.28235 0.42353 0.65882 0.42353 0.42353 0.65882 0.56471 0.42353 0.65882 0.70588 0.42353 0.65882 0.84706 0.42353 0.65882 0.98824 0.42353 0.65882 0.00000 0.56471 0.65882 0.14118 0.56471 0.65882 0.28235 0.56471 0.65882 0.42353 0.56471 0.65882 0.56471 0.56471 0.65882 0.70588 0.56471 0.65882 0.84706 0.56471 0.65882 0.98824 0.56471 0.65882 0.00000 0.70588 0.65882 0.14118 0.70588 0.65882 0.28235 0.70588 0.65882 0.42353 0.70588 0.65882 0.56471 0.70588 0.65882 0.70588 0.70588 0.65882 0.84706 0.70588 0.65882 0.98824 0.70588 0.65882 0.00000 0.84706 0.65882 0.14118 0.84706 0.65882 0.28235 0.84706 0.65882 0.42353 0.84706 0.65882 0.56471 0.84706 0.65882 0.70588 0.84706 0.65882 0.84706 0.84706 0.65882 0.98824 0.84706 0.65882 0.00000 0.98824 0.65882 0.14118 0.98824 0.65882 0.28235 0.98824 0.65882 0.42353 0.98824 0.65882 0.56471 0.98824 0.65882 0.70588 0.98824 0.65882 0.84706 0.98824 0.65882 0.98824 0.98824 0.65882 0.00000 0.00000 0.98824 0.14118 0.00000 0.98824 0.28235 0.00000 0.98824 0.42353 0.00000 0.98824 0.56471 0.00000 0.98824 0.70588 0.00000 0.98824 0.84706 0.00000 0.98824 0.98824 0.00000 0.98824 0.00000 0.14118 0.98824 0.14118 0.14118 0.98824 0.28235 0.14118 0.98824 0.42353 0.14118 0.98824 0.56471 0.14118 0.98824 0.70588 0.14118 0.98824 0.84706 0.14118 0.98824 0.98824 0.14118 0.98824 0.00000 0.28235 0.98824 0.14118 0.28235 0.98824 0.28235 0.28235 0.98824 0.42353 0.28235 0.98824 0.56471 0.28235 0.98824 0.70588 0.28235 0.98824 0.84706 0.28235 0.98824 0.98824 0.28235 0.98824 0.00000 0.42353 0.98824 0.14118 0.42353 0.98824 0.28235 0.42353 0.98824 0.42353 0.42353 0.98824 0.56471 0.42353 0.98824 0.70588 0.42353 0.98824 0.84706 0.42353 0.98824 0.98824 0.42353 0.98824 0.00000 0.56471 0.98824 0.14118 0.56471 0.98824 0.28235 0.56471 0.98824 0.42353 0.56471 0.98824 0.56471 0.56471 0.98824 0.70588 0.56471 0.98824 0.84706 0.56471 0.98824 0.98824 0.56471 0.98824 0.00000 0.70588 0.98824 0.14118 0.70588 0.98824 0.28235 0.70588 0.98824 0.42353 0.70588 0.98824 0.56471 0.70588 0.98824 0.70588 0.70588 0.98824 0.84706 0.70588 0.98824 0.98824 0.70588 0.98824 0.00000 0.84706 0.98824 0.14118 0.84706 0.98824 0.28235 0.84706 0.98824 0.42353 0.84706 0.98824 0.56471 0.84706 0.98824 0.70588 0.84706 0.98824 0.84706 0.84706 0.98824 0.98824 0.84706 0.98824 0.00000 0.98824 0.98824 0.14118 0.98824 0.98824 0.28235 0.98824 0.98824 0.42353 0.98824 0.98824 0.56471 0.98824 0.98824 0.70588 0.98824 0.98824 0.84706 0.98824 0.98824 0.98824 0.98824 skycat-3.1.2-starlink-1b/rtd/colormaps/real.lasc000066400000000000000000000324001215713201500215130ustar00rootroot00000000000000 0.00784 0.00392 0.00000 0.01569 0.00784 0.00000 0.02353 0.01176 0.00000 0.03137 0.01569 0.00000 0.03922 0.01961 0.00000 0.04706 0.02353 0.00000 0.05490 0.02745 0.00000 0.06275 0.03137 0.00000 0.07059 0.03529 0.00000 0.07843 0.03922 0.00000 0.08627 0.04314 0.00000 0.09412 0.04706 0.00000 0.10196 0.05098 0.00000 0.10980 0.05490 0.00000 0.11765 0.05882 0.00000 0.12549 0.06275 0.00000 0.13333 0.06667 0.00000 0.14118 0.07059 0.00000 0.14902 0.07451 0.00000 0.15686 0.07843 0.00000 0.16471 0.08235 0.00000 0.17255 0.08627 0.00000 0.18039 0.09020 0.00000 0.18824 0.09412 0.00000 0.19608 0.09804 0.00000 0.20392 0.10196 0.00000 0.21176 0.10588 0.00000 0.21961 0.10980 0.00000 0.22745 0.11373 0.00000 0.23529 0.11765 0.00000 0.24314 0.12157 0.00000 0.25098 0.12549 0.00000 0.25882 0.12941 0.00000 0.26667 0.13333 0.00000 0.27451 0.13725 0.00000 0.28235 0.14118 0.00000 0.29020 0.14510 0.00000 0.29804 0.14902 0.00000 0.30588 0.15294 0.00000 0.31373 0.15686 0.00000 0.32157 0.16078 0.00000 0.32941 0.16471 0.00000 0.33725 0.16863 0.00000 0.34510 0.17255 0.00000 0.35294 0.17647 0.00000 0.36078 0.18039 0.00000 0.36863 0.18431 0.00000 0.37647 0.18824 0.00000 0.38431 0.19216 0.00000 0.39216 0.19608 0.00000 0.40000 0.20000 0.00000 0.40784 0.20392 0.00000 0.41569 0.20784 0.00000 0.42353 0.21176 0.00000 0.43137 0.21569 0.00000 0.43922 0.21961 0.00000 0.44706 0.22353 0.00000 0.45490 0.22745 0.00000 0.46275 0.23137 0.00000 0.47059 0.23529 0.00000 0.47843 0.23922 0.00000 0.48627 0.24314 0.00000 0.49412 0.24706 0.00000 0.50196 0.25098 0.00000 0.50980 0.25490 0.00000 0.51765 0.25882 0.00000 0.52549 0.26275 0.00000 0.53333 0.26667 0.00000 0.54118 0.27059 0.00000 0.54902 0.27451 0.00000 0.55686 0.27843 0.00000 0.56471 0.28235 0.00000 0.57255 0.28627 0.00000 0.58039 0.29020 0.00000 0.58824 0.29412 0.00000 0.59608 0.29804 0.00000 0.60392 0.30196 0.00000 0.61176 0.30588 0.00000 0.61961 0.30980 0.00000 0.62745 0.31373 0.00000 0.63529 0.31765 0.00000 0.64314 0.32157 0.00000 0.65098 0.32549 0.00000 0.65882 0.32941 0.00000 0.66667 0.33333 0.00000 0.67451 0.33725 0.00000 0.68235 0.34118 0.00000 0.69020 0.34510 0.00000 0.69804 0.34902 0.00000 0.70588 0.35294 0.00000 0.71373 0.35686 0.00000 0.72157 0.36078 0.00000 0.72941 0.36471 0.00000 0.73725 0.36863 0.00000 0.74510 0.37255 0.00000 0.75294 0.37647 0.00000 0.76078 0.38039 0.00000 0.76863 0.38431 0.00000 0.77647 0.38824 0.00000 0.78431 0.39216 0.00000 0.79216 0.39608 0.00000 0.80000 0.40000 0.00000 0.80784 0.40392 0.00000 0.81569 0.40784 0.00000 0.82353 0.41176 0.00000 0.83137 0.41569 0.00000 0.83922 0.41961 0.00000 0.84706 0.42353 0.00000 0.85490 0.42745 0.00000 0.86275 0.43137 0.00000 0.87059 0.43529 0.00000 0.87843 0.43922 0.00000 0.88627 0.44314 0.00000 0.89412 0.44706 0.00000 0.90196 0.45098 0.00000 0.90980 0.45490 0.00000 0.91765 0.45882 0.00000 0.92549 0.46275 0.00000 0.93333 0.46667 0.00000 0.94118 0.47059 0.00000 0.94902 0.47451 0.00000 0.95686 0.47843 0.00000 0.96471 0.48235 0.00000 0.97255 0.48627 0.00000 0.98039 0.49020 0.00000 0.98824 0.49412 0.00000 0.99608 0.49804 0.00000 1.00000 0.50196 0.00000 1.00000 0.50588 0.00784 1.00000 0.50980 0.01569 1.00000 0.51373 0.02353 1.00000 0.51765 0.03137 1.00000 0.52157 0.03922 1.00000 0.52549 0.04706 1.00000 0.52941 0.05490 1.00000 0.53333 0.06275 1.00000 0.53725 0.07059 1.00000 0.54118 0.07843 1.00000 0.54510 0.08627 1.00000 0.54902 0.09412 1.00000 0.55294 0.10196 1.00000 0.55686 0.10980 1.00000 0.56078 0.11765 1.00000 0.56471 0.12549 1.00000 0.56863 0.13333 1.00000 0.57255 0.14118 1.00000 0.57647 0.14902 1.00000 0.58039 0.15686 1.00000 0.58431 0.16471 1.00000 0.58824 0.17255 1.00000 0.59216 0.18039 1.00000 0.59608 0.18824 1.00000 0.60000 0.19608 1.00000 0.60392 0.20392 1.00000 0.60784 0.21176 1.00000 0.61176 0.21961 1.00000 0.61569 0.22745 1.00000 0.61961 0.23529 1.00000 0.62353 0.24314 1.00000 0.62745 0.25098 1.00000 0.63137 0.25882 1.00000 0.63529 0.26667 1.00000 0.63922 0.27451 1.00000 0.64314 0.28235 1.00000 0.64706 0.29020 1.00000 0.65098 0.29804 1.00000 0.65490 0.30588 1.00000 0.65882 0.31373 1.00000 0.66275 0.32157 1.00000 0.66667 0.32941 1.00000 0.67059 0.33725 1.00000 0.67451 0.34510 1.00000 0.67843 0.35294 1.00000 0.68235 0.36078 1.00000 0.68627 0.36863 1.00000 0.69020 0.37647 1.00000 0.69412 0.38431 1.00000 0.69804 0.39216 1.00000 0.70196 0.40000 1.00000 0.70588 0.40784 1.00000 0.70980 0.41569 1.00000 0.71373 0.42353 1.00000 0.71765 0.43137 1.00000 0.72157 0.43922 1.00000 0.72549 0.44706 1.00000 0.72941 0.45490 1.00000 0.73333 0.46275 1.00000 0.73725 0.47059 1.00000 0.74118 0.47843 1.00000 0.74510 0.48627 1.00000 0.74902 0.49412 1.00000 0.75294 0.50196 1.00000 0.75686 0.50980 1.00000 0.76078 0.51765 1.00000 0.76471 0.52549 1.00000 0.76863 0.53333 1.00000 0.77255 0.54118 1.00000 0.77647 0.54902 1.00000 0.78039 0.55686 1.00000 0.78431 0.56471 1.00000 0.78824 0.57255 1.00000 0.79216 0.58039 1.00000 0.79608 0.58824 1.00000 0.80000 0.59608 1.00000 0.80392 0.60392 1.00000 0.80784 0.61176 1.00000 0.81176 0.61961 1.00000 0.81569 0.62745 1.00000 0.81961 0.63529 1.00000 0.82353 0.64314 1.00000 0.82745 0.65098 1.00000 0.83137 0.65882 1.00000 0.83529 0.66667 1.00000 0.83922 0.67451 1.00000 0.84314 0.68235 1.00000 0.84706 0.69020 1.00000 0.85098 0.69804 1.00000 0.85490 0.70588 1.00000 0.85882 0.71373 1.00000 0.86275 0.72157 1.00000 0.86667 0.72941 1.00000 0.87059 0.73725 1.00000 0.87451 0.74510 1.00000 0.87843 0.75294 1.00000 0.88235 0.76078 1.00000 0.88627 0.76863 1.00000 0.89020 0.77647 1.00000 0.89412 0.78431 1.00000 0.89804 0.79216 1.00000 0.90196 0.80000 1.00000 0.90588 0.80784 1.00000 0.90980 0.81569 1.00000 0.91373 0.82353 1.00000 0.91765 0.83137 1.00000 0.92157 0.83922 1.00000 0.92549 0.84706 1.00000 0.92941 0.85490 1.00000 0.93333 0.86275 1.00000 0.93725 0.87059 1.00000 0.94118 0.87843 1.00000 0.94510 0.88627 1.00000 0.94902 0.89412 1.00000 0.95294 0.90196 1.00000 0.95686 0.90980 1.00000 0.96078 0.91765 1.00000 0.96471 0.92549 1.00000 0.96863 0.93333 1.00000 0.97255 0.94118 1.00000 0.97647 0.94902 1.00000 0.98039 0.95686 1.00000 0.98431 0.96471 1.00000 0.98824 0.97255 1.00000 0.99216 0.98039 1.00000 0.99608 0.98824 1.00000 1.00000 0.99608 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/red.lasc000066400000000000000000000324001215713201500213420ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00392 0.00000 0.00000 0.00784 0.00000 0.00000 0.01176 0.00000 0.00000 0.01569 0.00000 0.00000 0.01961 0.00000 0.00000 0.02353 0.00000 0.00000 0.02745 0.00000 0.00000 0.03137 0.00000 0.00000 0.03529 0.00000 0.00000 0.03922 0.00000 0.00000 0.04314 0.00000 0.00000 0.04706 0.00000 0.00000 0.05098 0.00000 0.00000 0.05490 0.00000 0.00000 0.05882 0.00000 0.00000 0.06275 0.00000 0.00000 0.06667 0.00000 0.00000 0.07059 0.00000 0.00000 0.07451 0.00000 0.00000 0.07843 0.00000 0.00000 0.08235 0.00000 0.00000 0.08627 0.00000 0.00000 0.09020 0.00000 0.00000 0.09412 0.00000 0.00000 0.09804 0.00000 0.00000 0.10196 0.00000 0.00000 0.10588 0.00000 0.00000 0.10980 0.00000 0.00000 0.11373 0.00000 0.00000 0.11765 0.00000 0.00000 0.12157 0.00000 0.00000 0.12549 0.00000 0.00000 0.12941 0.00000 0.00000 0.13333 0.00000 0.00000 0.13725 0.00000 0.00000 0.14118 0.00000 0.00000 0.14510 0.00000 0.00000 0.14902 0.00000 0.00000 0.15294 0.00000 0.00000 0.15686 0.00000 0.00000 0.16078 0.00000 0.00000 0.16471 0.00000 0.00000 0.16863 0.00000 0.00000 0.17255 0.00000 0.00000 0.17647 0.00000 0.00000 0.18039 0.00000 0.00000 0.18431 0.00000 0.00000 0.18824 0.00000 0.00000 0.19216 0.00000 0.00000 0.19608 0.00000 0.00000 0.20000 0.00000 0.00000 0.20392 0.00000 0.00000 0.20784 0.00000 0.00000 0.21176 0.00000 0.00000 0.21569 0.00000 0.00000 0.21961 0.00000 0.00000 0.22353 0.00000 0.00000 0.22745 0.00000 0.00000 0.23137 0.00000 0.00000 0.23529 0.00000 0.00000 0.23922 0.00000 0.00000 0.24314 0.00000 0.00000 0.24706 0.00000 0.00000 0.25098 0.00000 0.00000 0.25490 0.00000 0.00000 0.25882 0.00000 0.00000 0.26275 0.00000 0.00000 0.26667 0.00000 0.00000 0.27059 0.00000 0.00000 0.27451 0.00000 0.00000 0.27843 0.00000 0.00000 0.28235 0.00000 0.00000 0.28627 0.00000 0.00000 0.29020 0.00000 0.00000 0.29412 0.00000 0.00000 0.29804 0.00000 0.00000 0.30196 0.00000 0.00000 0.30588 0.00000 0.00000 0.30980 0.00000 0.00000 0.31373 0.00000 0.00000 0.31765 0.00000 0.00000 0.32157 0.00000 0.00000 0.32549 0.00000 0.00000 0.32941 0.00000 0.00000 0.33333 0.00000 0.00000 0.33725 0.00000 0.00000 0.34118 0.00000 0.00000 0.34510 0.00000 0.00000 0.34902 0.00000 0.00000 0.35294 0.00000 0.00000 0.35686 0.00000 0.00000 0.36078 0.00000 0.00000 0.36471 0.00000 0.00000 0.36863 0.00000 0.00000 0.37255 0.00000 0.00000 0.37647 0.00000 0.00000 0.38039 0.00000 0.00000 0.38431 0.00000 0.00000 0.38824 0.00000 0.00000 0.39216 0.00000 0.00000 0.39608 0.00000 0.00000 0.40000 0.00000 0.00000 0.40392 0.00000 0.00000 0.40784 0.00000 0.00000 0.41176 0.00000 0.00000 0.41569 0.00000 0.00000 0.41961 0.00000 0.00000 0.42353 0.00000 0.00000 0.42745 0.00000 0.00000 0.43137 0.00000 0.00000 0.43529 0.00000 0.00000 0.43922 0.00000 0.00000 0.44314 0.00000 0.00000 0.44706 0.00000 0.00000 0.45098 0.00000 0.00000 0.45490 0.00000 0.00000 0.45882 0.00000 0.00000 0.46275 0.00000 0.00000 0.46667 0.00000 0.00000 0.47059 0.00000 0.00000 0.47451 0.00000 0.00000 0.47843 0.00000 0.00000 0.48235 0.00000 0.00000 0.48627 0.00000 0.00000 0.49020 0.00000 0.00000 0.49412 0.00000 0.00000 0.49804 0.00000 0.00000 0.50196 0.00000 0.00000 0.50588 0.00000 0.00000 0.50980 0.00000 0.00000 0.51373 0.00000 0.00000 0.51765 0.00000 0.00000 0.52157 0.00000 0.00000 0.52549 0.00000 0.00000 0.52941 0.00000 0.00000 0.53333 0.00000 0.00000 0.53725 0.00000 0.00000 0.54118 0.00000 0.00000 0.54510 0.00000 0.00000 0.54902 0.00000 0.00000 0.55294 0.00000 0.00000 0.55686 0.00000 0.00000 0.56078 0.00000 0.00000 0.56471 0.00000 0.00000 0.56863 0.00000 0.00000 0.57255 0.00000 0.00000 0.57647 0.00000 0.00000 0.58039 0.00000 0.00000 0.58431 0.00000 0.00000 0.58824 0.00000 0.00000 0.59216 0.00000 0.00000 0.59608 0.00000 0.00000 0.60000 0.00000 0.00000 0.60392 0.00000 0.00000 0.60784 0.00000 0.00000 0.61176 0.00000 0.00000 0.61569 0.00000 0.00000 0.61961 0.00000 0.00000 0.62353 0.00000 0.00000 0.62745 0.00000 0.00000 0.63137 0.00000 0.00000 0.63529 0.00000 0.00000 0.63922 0.00000 0.00000 0.64314 0.00000 0.00000 0.64706 0.00000 0.00000 0.65098 0.00000 0.00000 0.65490 0.00000 0.00000 0.65882 0.00000 0.00000 0.66275 0.00000 0.00000 0.66667 0.00000 0.00000 0.67059 0.00000 0.00000 0.67451 0.00000 0.00000 0.67843 0.00000 0.00000 0.68235 0.00000 0.00000 0.68627 0.00000 0.00000 0.69020 0.00000 0.00000 0.69412 0.00000 0.00000 0.69804 0.00000 0.00000 0.70196 0.00000 0.00000 0.70588 0.00000 0.00000 0.70980 0.00000 0.00000 0.71373 0.00000 0.00000 0.71765 0.00000 0.00000 0.72157 0.00000 0.00000 0.72549 0.00000 0.00000 0.72941 0.00000 0.00000 0.73333 0.00000 0.00000 0.73725 0.00000 0.00000 0.74118 0.00000 0.00000 0.74510 0.00000 0.00000 0.74902 0.00000 0.00000 0.75294 0.00000 0.00000 0.75686 0.00000 0.00000 0.76078 0.00000 0.00000 0.76471 0.00000 0.00000 0.76863 0.00000 0.00000 0.77255 0.00000 0.00000 0.77647 0.00000 0.00000 0.78039 0.00000 0.00000 0.78431 0.00000 0.00000 0.78824 0.00000 0.00000 0.79216 0.00000 0.00000 0.79608 0.00000 0.00000 0.80000 0.00000 0.00000 0.80392 0.00000 0.00000 0.80784 0.00000 0.00000 0.81176 0.00000 0.00000 0.81569 0.00000 0.00000 0.81961 0.00000 0.00000 0.82353 0.00000 0.00000 0.82745 0.00000 0.00000 0.83137 0.00000 0.00000 0.83529 0.00000 0.00000 0.83922 0.00000 0.00000 0.84314 0.00000 0.00000 0.84706 0.00000 0.00000 0.85098 0.00000 0.00000 0.85490 0.00000 0.00000 0.85882 0.00000 0.00000 0.86275 0.00000 0.00000 0.86667 0.00000 0.00000 0.87059 0.00000 0.00000 0.87451 0.00000 0.00000 0.87843 0.00000 0.00000 0.88235 0.00000 0.00000 0.88627 0.00000 0.00000 0.89020 0.00000 0.00000 0.89412 0.00000 0.00000 0.89804 0.00000 0.00000 0.90196 0.00000 0.00000 0.90588 0.00000 0.00000 0.90980 0.00000 0.00000 0.91373 0.00000 0.00000 0.91765 0.00000 0.00000 0.92157 0.00000 0.00000 0.92549 0.00000 0.00000 0.92941 0.00000 0.00000 0.93333 0.00000 0.00000 0.93725 0.00000 0.00000 0.94118 0.00000 0.00000 0.94510 0.00000 0.00000 0.94902 0.00000 0.00000 0.95294 0.00000 0.00000 0.95686 0.00000 0.00000 0.96078 0.00000 0.00000 0.96471 0.00000 0.00000 0.96863 0.00000 0.00000 0.97255 0.00000 0.00000 0.97647 0.00000 0.00000 0.98039 0.00000 0.00000 0.98431 0.00000 0.00000 0.98824 0.00000 0.00000 0.99216 0.00000 0.00000 0.99608 0.00000 0.00000 1.00000 0.00000 0.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/redlut.lasc000066400000000000000000000140001215713201500220630ustar00rootroot000000000000000.00000 0.00000 0.00000 0.00392 0.00000 0.00000 0.00784 0.00000 0.00000 0.01176 0.00000 0.00000 0.01569 0.00000 0.00000 0.01961 0.00000 0.00000 0.02353 0.00000 0.00000 0.02745 0.00000 0.00000 0.03137 0.00000 0.00000 0.03529 0.00000 0.00000 0.03922 0.00000 0.00000 0.04314 0.00000 0.00000 0.04706 0.00000 0.00000 0.05098 0.00001 0.00001 0.05490 0.00001 0.00001 0.05882 0.00001 0.00001 0.06275 0.00002 0.00002 0.06667 0.00002 0.00002 0.07059 0.00002 0.00002 0.07451 0.00003 0.00003 0.07843 0.00004 0.00004 0.08235 0.00005 0.00005 0.08627 0.00006 0.00006 0.09020 0.00007 0.00007 0.09412 0.00008 0.00008 0.09804 0.00009 0.00009 0.10196 0.00011 0.00011 0.10588 0.00013 0.00013 0.10980 0.00015 0.00015 0.11373 0.00017 0.00017 0.11765 0.00019 0.00019 0.12157 0.00022 0.00022 0.12549 0.00025 0.00025 0.12941 0.00028 0.00028 0.13333 0.00032 0.00032 0.13725 0.00035 0.00035 0.14118 0.00040 0.00040 0.14510 0.00044 0.00044 0.14902 0.00049 0.00049 0.15294 0.00055 0.00055 0.15686 0.00061 0.00061 0.16078 0.00067 0.00067 0.16471 0.00074 0.00074 0.16863 0.00081 0.00081 0.17255 0.00089 0.00089 0.17647 0.00097 0.00097 0.18039 0.00106 0.00106 0.18431 0.00115 0.00115 0.18824 0.00126 0.00126 0.19216 0.00136 0.00136 0.19608 0.00148 0.00148 0.20000 0.00160 0.00160 0.20392 0.00173 0.00173 0.20784 0.00187 0.00187 0.21176 0.00201 0.00201 0.21569 0.00216 0.00216 0.21961 0.00233 0.00233 0.22353 0.00250 0.00250 0.22745 0.00268 0.00268 0.23137 0.00287 0.00287 0.23529 0.00307 0.00307 0.23922 0.00327 0.00327 0.24314 0.00349 0.00349 0.24706 0.00373 0.00373 0.25098 0.00397 0.00397 0.25490 0.00422 0.00422 0.25882 0.00449 0.00449 0.26275 0.00477 0.00477 0.26667 0.00506 0.00506 0.27059 0.00536 0.00536 0.27451 0.00568 0.00568 0.27843 0.00601 0.00601 0.28235 0.00636 0.00636 0.28627 0.00672 0.00672 0.29020 0.00709 0.00709 0.29412 0.00748 0.00748 0.29804 0.00789 0.00789 0.30196 0.00831 0.00831 0.30588 0.00875 0.00875 0.30980 0.00921 0.00921 0.31373 0.00969 0.00969 0.31765 0.01018 0.01018 0.32157 0.01069 0.01069 0.32549 0.01122 0.01122 0.32941 0.01177 0.01177 0.33333 0.01235 0.01235 0.33725 0.01294 0.01294 0.34118 0.01355 0.01355 0.34510 0.01418 0.01418 0.34902 0.01484 0.01484 0.35294 0.01552 0.01552 0.35686 0.01622 0.01622 0.36078 0.01694 0.01694 0.36471 0.01769 0.01769 0.36863 0.01847 0.01847 0.37255 0.01926 0.01926 0.37647 0.02009 0.02009 0.38039 0.02094 0.02094 0.38431 0.02181 0.02181 0.38824 0.02272 0.02272 0.39216 0.02365 0.02365 0.39608 0.02461 0.02461 0.40000 0.02560 0.02560 0.40392 0.02662 0.02662 0.40784 0.02767 0.02767 0.41176 0.02875 0.02875 0.41569 0.02986 0.02986 0.41961 0.03100 0.03100 0.42353 0.03218 0.03218 0.42745 0.03338 0.03338 0.43137 0.03463 0.03463 0.43529 0.03590 0.03590 0.43922 0.03721 0.03721 0.44314 0.03856 0.03856 0.44706 0.03994 0.03994 0.45098 0.04136 0.04136 0.45490 0.04282 0.04282 0.45882 0.04432 0.04432 0.46275 0.04585 0.04585 0.46667 0.04743 0.04743 0.47059 0.04904 0.04904 0.47451 0.05070 0.05070 0.47843 0.05239 0.05239 0.48235 0.05413 0.05413 0.48627 0.05591 0.05591 0.49020 0.05774 0.05774 0.49412 0.05961 0.05961 0.49804 0.06153 0.06153 0.50196 0.06349 0.06349 0.50588 0.06549 0.06549 0.50980 0.06755 0.06755 0.51373 0.06965 0.06965 0.51765 0.07180 0.07180 0.52157 0.07400 0.07400 0.52549 0.07625 0.07625 0.52941 0.07856 0.07856 0.53333 0.08091 0.08091 0.53725 0.08331 0.08331 0.54118 0.08577 0.08577 0.54510 0.08829 0.08829 0.54902 0.09086 0.09086 0.55294 0.09348 0.09348 0.55686 0.09616 0.09616 0.56078 0.09890 0.09890 0.56471 0.10169 0.10169 0.56863 0.10455 0.10455 0.57255 0.10746 0.10746 0.57647 0.11044 0.11044 0.58039 0.11347 0.11347 0.58431 0.11657 0.11657 0.58824 0.11973 0.11973 0.59216 0.12296 0.12296 0.59608 0.12624 0.12624 0.60000 0.12960 0.12960 0.60392 0.13302 0.13302 0.60784 0.13651 0.13651 0.61176 0.14007 0.14007 0.61569 0.14369 0.14369 0.61961 0.14739 0.14739 0.62353 0.15116 0.15116 0.62745 0.15500 0.15500 0.63137 0.15891 0.15891 0.63529 0.16289 0.16289 0.63922 0.16695 0.16695 0.64314 0.17109 0.17109 0.64706 0.17530 0.17530 0.65098 0.17959 0.17959 0.65490 0.18395 0.18395 0.65882 0.18840 0.18840 0.66275 0.19292 0.19292 0.66667 0.19753 0.19753 0.67059 0.20222 0.20222 0.67451 0.20699 0.20699 0.67843 0.21185 0.21185 0.68235 0.21679 0.21679 0.68627 0.22182 0.22182 0.69020 0.22693 0.22693 0.69412 0.23213 0.23213 0.69804 0.23742 0.23742 0.70196 0.24280 0.24280 0.70588 0.24827 0.24827 0.70980 0.25384 0.25384 0.71373 0.25949 0.25949 0.71765 0.26524 0.26524 0.72157 0.27109 0.27109 0.72549 0.27703 0.27703 0.72941 0.28307 0.28307 0.73333 0.28920 0.28920 0.73725 0.29544 0.29544 0.74118 0.30178 0.30178 0.74510 0.30821 0.30821 0.74902 0.31476 0.31476 0.75294 0.32140 0.32140 0.75686 0.32815 0.32815 0.76078 0.33500 0.33500 0.76471 0.34196 0.34196 0.76863 0.34903 0.34903 0.77255 0.35621 0.35621 0.77647 0.36350 0.36350 0.78039 0.37090 0.37090 0.78431 0.37841 0.37841 0.78824 0.38603 0.38603 0.79216 0.39377 0.39377 0.79608 0.40163 0.40163 0.80000 0.40960 0.40960 0.80392 0.41769 0.41769 0.80784 0.42590 0.42590 0.81176 0.43423 0.43423 0.81569 0.44268 0.44268 0.81961 0.45126 0.45126 0.82353 0.45996 0.45996 0.82745 0.46878 0.46878 0.83137 0.47773 0.47773 0.83529 0.48681 0.48681 0.83922 0.49601 0.49601 0.84314 0.50535 0.50535 0.84706 0.51482 0.51482 0.85098 0.52442 0.52442 0.85490 0.53415 0.53415 0.85882 0.54402 0.54402 0.86275 0.55403 0.55403 0.86667 0.56417 0.56417 0.87059 0.57445 0.57445 0.87451 0.58487 0.58487 0.87843 0.59543 0.59543 0.88235 0.60613 0.60613 0.88627 0.61698 0.61698 0.89020 0.62798 0.62798 0.89412 0.63911 0.63911 0.89804 0.65040 0.65040 0.90196 0.66184 0.66184 0.90588 0.67342 0.67342 0.90980 0.68516 0.68516 0.91373 0.69705 0.69705 0.91765 0.70909 0.70909 0.92157 0.72129 0.72129 0.92549 0.73365 0.73365 0.92941 0.74616 0.74616 0.93333 0.75883 0.75883 0.93725 0.77167 0.77167 0.94118 0.78466 0.78466 0.94510 0.79782 0.79782 0.94902 0.81115 0.81115 0.95294 0.82464 0.82464 0.95686 0.83830 0.83830 0.96078 0.85213 0.85213 0.96471 0.86612 0.86612 0.96863 0.88029 0.88029 0.97255 0.89464 0.89464 0.97647 0.90915 0.90915 0.98039 0.92385 0.92385 0.98431 0.93872 0.93872 0.98824 0.95377 0.95377 0.99216 0.96899 0.96899 0.99608 0.98441 0.98441 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/smooth.lasc000066400000000000000000000324001215713201500221010ustar00rootroot00000000000000 0.00000 0.00000 1.00000 0.01569 0.00000 0.98431 0.03529 0.00000 0.96471 0.05098 0.00000 0.94902 0.06667 0.00000 0.93333 0.08627 0.00000 0.91373 0.10196 0.00000 0.89804 0.11765 0.00000 0.88235 0.13725 0.00000 0.86275 0.15294 0.00000 0.84706 0.16863 0.00000 0.83137 0.18824 0.00000 0.81176 0.20392 0.00000 0.79608 0.21961 0.00000 0.78039 0.23922 0.00000 0.76078 0.25490 0.00000 0.74510 0.27059 0.00000 0.72941 0.28627 0.00000 0.71373 0.30588 0.00000 0.69412 0.32157 0.00000 0.67843 0.33725 0.00000 0.66275 0.35686 0.00000 0.64314 0.37255 0.00000 0.62745 0.38824 0.00000 0.61176 0.40784 0.00000 0.59216 0.42353 0.00000 0.57647 0.43922 0.00000 0.56078 0.45882 0.00000 0.54118 0.47451 0.00000 0.52549 0.49020 0.00000 0.50980 0.50980 0.00000 0.49020 0.52549 0.00000 0.47451 0.54118 0.00000 0.45882 0.56078 0.00000 0.43922 0.57647 0.00000 0.42353 0.59216 0.00000 0.40784 0.61176 0.00000 0.38824 0.62745 0.00000 0.37255 0.64314 0.00000 0.35686 0.66275 0.00000 0.33725 0.67843 0.00000 0.32157 0.69412 0.00000 0.30588 0.71373 0.00000 0.28627 0.72941 0.00000 0.27059 0.74510 0.00000 0.25490 0.76078 0.00000 0.23922 0.78039 0.00000 0.21961 0.79608 0.00000 0.20392 0.81176 0.00000 0.18824 0.83137 0.00000 0.16863 0.84706 0.00000 0.15294 0.86275 0.00000 0.13725 0.88235 0.00000 0.11765 0.89804 0.00000 0.10196 0.91373 0.00000 0.08627 0.93333 0.00000 0.06667 0.94902 0.00000 0.05098 0.96471 0.00000 0.03529 0.98431 0.00000 0.01569 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.01176 0.00000 1.00000 0.01961 0.00000 1.00000 0.03137 0.00000 1.00000 0.03922 0.00000 1.00000 0.05098 0.00000 1.00000 0.05882 0.00000 1.00000 0.07059 0.00000 1.00000 0.08235 0.00000 1.00000 0.09020 0.00000 1.00000 0.10196 0.00000 1.00000 0.10980 0.00000 1.00000 0.12157 0.00000 1.00000 0.12941 0.00000 1.00000 0.14118 0.00000 0.99608 0.15294 0.00000 0.99608 0.16078 0.00000 0.99608 0.17255 0.00000 0.99608 0.18039 0.00000 0.99608 0.19216 0.00000 0.99608 0.20392 0.00000 0.99608 0.21176 0.00000 0.99608 0.22353 0.00000 0.99608 0.23137 0.00000 0.99608 0.24314 0.00000 0.99608 0.25098 0.00000 0.99608 0.26275 0.00000 0.99608 0.27451 0.00000 0.99608 0.28235 0.00000 0.99608 0.29412 0.00000 0.99608 0.30196 0.00000 0.99608 0.31373 0.00000 0.99608 0.32157 0.00000 0.99608 0.33333 0.00000 0.99608 0.34510 0.00000 0.99608 0.35294 0.00000 0.99608 0.36471 0.00000 0.99608 0.37255 0.00000 0.99608 0.38431 0.00000 0.99608 0.39216 0.00000 0.99608 0.40392 0.00000 0.99608 0.41569 0.00000 0.99608 0.42353 0.00000 0.99608 0.43529 0.00000 0.99608 0.44314 0.00000 0.99216 0.45490 0.00000 0.99216 0.46667 0.00000 0.99216 0.47451 0.00000 0.99216 0.48627 0.00000 0.99216 0.49412 0.00000 0.99216 0.50588 0.00000 0.99216 0.51373 0.00000 0.99216 0.52549 0.00000 0.99216 0.53725 0.00000 0.99216 0.54510 0.00000 0.99216 0.55686 0.00000 0.99216 0.56471 0.00000 0.99216 0.57647 0.00000 0.99216 0.58431 0.00000 0.99216 0.59608 0.00000 0.99216 0.60000 0.00000 0.99216 0.60784 0.00000 0.99216 0.61176 0.00000 0.99216 0.61569 0.00000 0.99216 0.61961 0.00000 0.99216 0.62745 0.00000 0.99216 0.63137 0.00000 0.99216 0.63529 0.00000 0.99216 0.64314 0.00000 0.98824 0.64706 0.00000 0.98824 0.65098 0.00000 0.98824 0.65882 0.00000 0.98824 0.66275 0.00000 0.98824 0.66667 0.00000 0.98824 0.67451 0.00000 0.98824 0.67843 0.00000 0.98824 0.68235 0.00000 0.98824 0.68627 0.00000 0.98824 0.69412 0.00000 0.98824 0.69804 0.00000 0.98824 0.70196 0.00000 0.98824 0.70980 0.00000 0.98824 0.71373 0.00000 0.98824 0.71765 0.00000 0.98824 0.72549 0.00000 0.98824 0.72941 0.00000 0.98824 0.73333 0.00000 0.98824 0.73725 0.00000 0.98824 0.74510 0.00000 0.98824 0.74902 0.00000 0.98431 0.75294 0.00000 0.98431 0.76078 0.00000 0.98431 0.76471 0.00000 0.98431 0.76863 0.00000 0.98431 0.77255 0.00000 0.98431 0.78039 0.00000 0.98431 0.78431 0.00000 0.98431 0.78824 0.00000 0.98431 0.79608 0.00000 0.98431 0.80000 0.00000 0.98431 0.80392 0.00000 0.98431 0.81176 0.00000 0.98431 0.81569 0.00000 0.98431 0.81961 0.00000 0.98431 0.82745 0.00000 0.98431 0.83137 0.00000 0.98431 0.83529 0.00000 0.98431 0.83922 0.00000 0.98431 0.84706 0.00000 0.98431 0.85098 0.00000 0.98039 0.85490 0.00000 0.98039 0.86275 0.00000 0.98039 0.86667 0.00000 0.98039 0.87059 0.00000 0.98039 0.87843 0.00000 0.98039 0.88235 0.00000 0.98039 0.88627 0.00000 0.98039 0.89020 0.00000 0.98039 0.89804 0.00000 0.98039 0.90196 0.00000 0.98039 0.90196 0.00000 0.96471 0.88627 0.00000 0.94902 0.87059 0.00000 0.92941 0.85490 0.00000 0.91373 0.83922 0.00000 0.89804 0.82745 0.00000 0.88235 0.81176 0.00000 0.86275 0.79608 0.00000 0.84706 0.78039 0.00000 0.83137 0.76471 0.00000 0.81569 0.74902 0.00000 0.79608 0.73333 0.00000 0.78039 0.71765 0.00000 0.76471 0.70196 0.00000 0.74902 0.68627 0.00000 0.72941 0.67451 0.00000 0.71373 0.65882 0.00000 0.69804 0.64314 0.00000 0.68235 0.62745 0.00000 0.66275 0.61176 0.00000 0.64706 0.59608 0.00000 0.63137 0.58039 0.00000 0.61569 0.56471 0.00000 0.60000 0.54902 0.00000 0.58039 0.53333 0.00000 0.56471 0.52157 0.00000 0.54902 0.50588 0.00000 0.53333 0.49020 0.00000 0.51373 0.47451 0.00000 0.49804 0.45882 0.00000 0.48235 0.44314 0.00000 0.46667 0.42745 0.00000 0.44706 0.41176 0.00000 0.43137 0.39608 0.00000 0.41569 0.38039 0.00000 0.40000 0.36863 0.00000 0.38039 0.35294 0.00000 0.36471 0.33725 0.00000 0.34902 0.32157 0.00000 0.33333 0.30588 0.00000 0.31765 0.29020 0.00000 0.29804 0.27451 0.00000 0.28235 0.25882 0.00000 0.26667 0.24314 0.00000 0.25098 0.22745 0.00000 0.23137 0.21569 0.00000 0.21569 0.20000 0.00000 0.20000 0.18431 0.00000 0.18431 0.16863 0.00000 0.16471 0.15294 0.00000 0.14902 0.13725 0.00000 0.13333 0.12157 0.00000 0.11765 0.10588 0.00000 0.09804 0.09020 0.00000 0.08235 0.07451 0.00000 0.06667 0.06275 0.00000 0.05098 0.04706 0.00000 0.03137 0.03137 0.00000 0.01569 0.01569 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/smooth1.lasc000066400000000000000000000324001215713201500221620ustar00rootroot00000000000000 0.30980 0.29020 0.22353 0.32157 0.30196 0.23922 0.33333 0.31765 0.25490 0.34510 0.32941 0.27059 0.35686 0.34510 0.29020 0.36863 0.36078 0.30588 0.38039 0.37647 0.32549 0.39216 0.38824 0.34510 0.40392 0.40392 0.36471 0.41569 0.41961 0.38431 0.42745 0.43529 0.40392 0.43922 0.45098 0.42353 0.45098 0.46667 0.44314 0.46275 0.48235 0.46667 0.47451 0.49804 0.48627 0.49020 0.51765 0.50980 0.50196 0.53333 0.53333 0.51373 0.54902 0.55686 0.52549 0.56863 0.58039 0.54118 0.58431 0.60392 0.55294 0.60000 0.62745 0.56863 0.61961 0.65098 0.58039 0.63529 0.67843 0.59216 0.65490 0.70196 0.60784 0.67059 0.72941 0.61961 0.69020 0.75686 0.63529 0.70980 0.78431 0.64706 0.72549 0.75686 0.66275 0.74510 0.72941 0.67843 0.76471 0.70588 0.69020 0.78431 0.68235 0.70588 0.80392 0.65882 0.71765 0.82353 0.64314 0.73333 0.80392 0.62353 0.74902 0.78824 0.60392 0.76471 0.77255 0.58824 0.77647 0.75686 0.57255 0.79216 0.74118 0.55686 0.80784 0.73333 0.54118 0.82353 0.71765 0.52941 0.83922 0.70588 0.51373 0.85490 0.69804 0.50588 0.87059 0.68235 0.49412 0.85490 0.67451 0.48627 0.83922 0.66667 0.47843 0.82745 0.65882 0.47059 0.81569 0.65098 0.46275 0.80392 0.63922 0.45882 0.79216 0.63529 0.45490 0.78431 0.62745 0.45098 0.77255 0.61961 0.44706 0.76078 0.61176 0.44706 0.74902 0.60784 0.44706 0.74510 0.60392 0.44706 0.73333 0.60000 0.44706 0.72941 0.59608 0.45098 0.71765 0.59216 0.45490 0.70980 0.58824 0.45882 0.70588 0.58824 0.46275 0.69412 0.58431 0.47059 0.69020 0.58039 0.47843 0.68235 0.58039 0.48627 0.67843 0.58039 0.49412 0.67451 0.57647 0.50588 0.66667 0.58039 0.51373 0.66275 0.57647 0.52941 0.65490 0.58039 0.54118 0.65098 0.58039 0.55686 0.64706 0.58039 0.57255 0.64314 0.58431 0.58824 0.63529 0.58824 0.60392 0.63529 0.58824 0.62353 0.63137 0.59216 0.64314 0.62745 0.59608 0.65882 0.62745 0.60000 0.68235 0.62353 0.60392 0.70588 0.62353 0.60784 0.72941 0.61961 0.61176 0.75686 0.61961 0.61961 0.78431 0.61569 0.62745 0.75686 0.61569 0.63529 0.72941 0.61176 0.63922 0.70588 0.61176 0.65098 0.68235 0.61176 0.65882 0.65882 0.61176 0.66667 0.64314 0.61176 0.67451 0.62353 0.61176 0.68235 0.60392 0.61176 0.69804 0.58824 0.61176 0.70588 0.57255 0.61569 0.71765 0.55686 0.61569 0.73333 0.54118 0.61961 0.74118 0.52941 0.61961 0.75686 0.51373 0.62353 0.77255 0.50588 0.62353 0.78824 0.49412 0.62745 0.80392 0.48627 0.62745 0.82353 0.47843 0.63137 0.80392 0.47059 0.63529 0.78824 0.46275 0.63529 0.77255 0.45882 0.64314 0.75686 0.45490 0.64706 0.74118 0.45098 0.65098 0.73333 0.44706 0.65490 0.71765 0.44706 0.66275 0.70588 0.44706 0.66667 0.69804 0.44706 0.67451 0.68235 0.44706 0.67843 0.67451 0.45098 0.68235 0.66667 0.45490 0.69020 0.65882 0.45882 0.69412 0.65098 0.46275 0.70588 0.63922 0.47059 0.70980 0.63529 0.47843 0.71765 0.62745 0.48627 0.72941 0.61961 0.49412 0.73333 0.61176 0.50588 0.74510 0.60784 0.51373 0.74902 0.60392 0.52941 0.76078 0.60000 0.54118 0.77647 0.59608 0.55686 0.79216 0.59216 0.57255 0.80392 0.58824 0.58824 0.81961 0.58824 0.60392 0.83922 0.58431 0.62353 0.85490 0.58039 0.64314 0.87451 0.58039 0.65882 0.89804 0.58039 0.68235 0.92157 0.57647 0.70588 0.91373 0.58039 0.72941 0.90588 0.57647 0.75686 0.89804 0.58039 0.78431 0.89412 0.58039 0.75686 0.88627 0.58039 0.72941 0.88235 0.58431 0.70588 0.87843 0.58824 0.68235 0.87451 0.58824 0.65882 0.87059 0.59216 0.64314 0.86275 0.59608 0.62353 0.86275 0.60000 0.60392 0.85882 0.60392 0.58824 0.85882 0.60784 0.57255 0.85490 0.61176 0.55686 0.85098 0.61961 0.54118 0.85490 0.62745 0.52941 0.85098 0.63529 0.51373 0.85098 0.63922 0.50588 0.85098 0.65490 0.49412 0.85098 0.67059 0.48627 0.85490 0.68235 0.47843 0.85098 0.69804 0.47059 0.85490 0.71373 0.46275 0.85098 0.74118 0.45882 0.85490 0.75686 0.45490 0.85882 0.78039 0.45098 0.86275 0.80392 0.44706 0.86275 0.82353 0.44706 0.86667 0.85098 0.44706 0.87059 0.87843 0.44706 0.87451 0.90980 0.44706 0.87843 0.93725 0.45098 0.88235 0.97255 0.45490 0.88627 0.96471 0.45882 0.89020 0.96078 0.46275 0.89804 0.95686 0.47059 0.90196 0.95294 0.47843 0.90588 0.94902 0.48627 0.91373 0.94902 0.49412 0.91765 0.94510 0.50588 0.92549 0.94118 0.51373 0.92941 0.94510 0.52941 0.94118 0.94118 0.54118 0.94902 0.94510 0.55686 0.95294 0.94510 0.57255 0.96078 0.94510 0.58824 0.97255 0.94902 0.60392 0.98039 0.94902 0.62745 0.98824 0.95294 0.65098 0.99608 0.95686 0.67451 1.00000 0.95686 0.70588 1.00000 0.96078 0.73333 1.00000 0.96863 0.76863 1.00000 0.97255 0.80392 1.00000 0.98039 0.84314 1.00000 0.98431 0.82353 0.98824 0.99216 0.80784 0.96078 0.99608 0.79608 0.93333 1.00000 0.78431 0.90980 1.00000 0.77255 0.88235 1.00000 0.76471 0.85882 1.00000 0.75686 0.83137 1.00000 0.74902 0.80784 1.00000 0.74118 0.78039 1.00000 0.73725 0.75686 1.00000 0.73333 0.73333 1.00000 0.72941 0.70588 1.00000 0.72941 0.69020 1.00000 0.72941 0.66667 0.97255 0.72941 0.64314 0.93725 0.73333 0.62353 0.90196 0.73725 0.60392 0.86667 0.74118 0.58431 0.83137 0.74510 0.56078 0.79608 0.75294 0.54510 0.76078 0.75686 0.52941 0.73333 0.76863 0.51373 0.69804 0.77647 0.50196 0.67059 0.78824 0.48627 0.63922 0.80392 0.47059 0.61176 0.81569 0.45490 0.58039 0.83137 0.44314 0.55294 0.84706 0.43529 0.52941 0.86667 0.42353 0.50588 0.88235 0.41569 0.47843 0.90196 0.41176 0.45490 0.92549 0.40392 0.43529 0.87843 0.40000 0.41569 0.83922 0.39216 0.39216 0.79608 0.38824 0.37647 0.75686 0.38431 0.35686 0.72157 0.38039 0.34118 0.67843 0.38039 0.32941 0.65098 0.37255 0.31765 0.61569 0.37255 0.30588 0.58431 0.37255 0.29804 0.55686 0.37255 0.29412 0.52549 0.37647 0.28627 0.50196 0.37647 0.28235 0.47843 0.38039 0.28235 0.45882 0.38431 0.27843 0.43922 0.38824 0.27843 0.41961 0.39608 0.27843 0.40784 0.40000 0.28235 0.40000 0.40784 0.28627 0.38824 0.41569 0.29020 0.38431 0.42353 0.29804 0.38039 0.43529 0.30588 0.37647 0.44706 0.31765 0.37647 0.45882 0.32549 0.38039 0.47059 0.34118 0.38431 0.48235 0.35294 0.39216 0.50196 0.37255 0.40000 0.51765 0.39216 0.40784 0.53725 0.41176 0.42353 0.55686 0.43922 0.43529 0.57647 0.46667 0.45098 0.60000 0.49804 0.47451 0.62745 0.52941 0.49804 0.65490 0.56078 0.52549 0.68235 0.59216 0.54902 0.70980 0.62745 0.58431 0.74118 0.66275 0.61569 0.77255 0.70196 0.65098 0.80392 0.74118 0.69020 0.83529 0.78039 0.73333 0.87059 0.82353 0.78431 skycat-3.1.2-starlink-1b/rtd/colormaps/smooth2.lasc000066400000000000000000000324001215713201500221630ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.06667 0.00000 0.00000 0.06667 0.00000 0.00000 0.06667 0.00000 0.00000 0.06667 0.00000 0.00000 0.06667 0.00000 0.00000 0.06667 0.00000 0.00000 0.06667 0.00000 0.00000 0.06667 0.00000 0.00000 0.13333 0.00000 0.00000 0.13333 0.00000 0.00000 0.13333 0.00000 0.00000 0.13333 0.00000 0.00000 0.13333 0.00000 0.00000 0.13333 0.00000 0.00000 0.13333 0.00000 0.00000 0.13333 0.00000 0.00000 0.20000 0.00000 0.00000 0.20000 0.00000 0.00000 0.20000 0.00000 0.00000 0.20000 0.00000 0.00000 0.20000 0.00000 0.00000 0.20000 0.00000 0.00000 0.20000 0.00000 0.00000 0.20000 0.00000 0.00000 0.26667 0.00000 0.00000 0.26667 0.00000 0.00000 0.26667 0.00000 0.00000 0.26667 0.00000 0.00000 0.26667 0.00000 0.00000 0.26667 0.00000 0.00000 0.26667 0.00000 0.00000 0.26667 0.00000 0.00000 0.33333 0.00000 0.00000 0.33333 0.00000 0.00000 0.33333 0.00000 0.00000 0.33333 0.00000 0.00000 0.33333 0.00000 0.00000 0.33333 0.00000 0.00000 0.33333 0.00000 0.00000 0.33333 0.00000 0.00000 0.40000 0.00000 0.00000 0.40000 0.00000 0.00000 0.40000 0.00000 0.00000 0.40000 0.00000 0.00000 0.40000 0.00000 0.00000 0.40000 0.00000 0.00000 0.40000 0.00000 0.00000 0.40000 0.00000 0.00000 0.46667 0.00000 0.00000 0.46667 0.00000 0.00000 0.46667 0.00000 0.00000 0.46667 0.00000 0.00000 0.46667 0.00000 0.00000 0.46667 0.00000 0.00000 0.46667 0.00000 0.00000 0.46667 0.00000 0.00000 0.53333 0.00000 0.00000 0.53333 0.00000 0.00000 0.53333 0.00000 0.00000 0.53333 0.00000 0.00000 0.53333 0.00000 0.00000 0.53333 0.00000 0.00000 0.53333 0.00000 0.00000 0.53333 0.06667 0.00000 0.53333 0.06667 0.00000 0.53333 0.06667 0.00000 0.53333 0.06667 0.00000 0.53333 0.06667 0.00000 0.53333 0.06667 0.00000 0.53333 0.06667 0.00000 0.53333 0.06667 0.00000 0.53333 0.13333 0.00000 0.53333 0.13333 0.00000 0.53333 0.13333 0.00000 0.53333 0.13333 0.00000 0.53333 0.13333 0.00000 0.53333 0.13333 0.00000 0.53333 0.13333 0.00000 0.53333 0.13333 0.00000 0.53333 0.20000 0.00000 0.53333 0.20000 0.00000 0.53333 0.20000 0.00000 0.53333 0.20000 0.00000 0.53333 0.20000 0.00000 0.53333 0.20000 0.00000 0.53333 0.20000 0.00000 0.53333 0.20000 0.00000 0.53333 0.26667 0.00000 0.53333 0.26667 0.00000 0.53333 0.26667 0.00000 0.53333 0.26667 0.00000 0.53333 0.26667 0.00000 0.53333 0.26667 0.00000 0.53333 0.26667 0.00000 0.53333 0.26667 0.00000 0.53333 0.33333 0.00000 0.53333 0.33333 0.00000 0.53333 0.33333 0.00000 0.53333 0.33333 0.00000 0.53333 0.33333 0.00000 0.53333 0.33333 0.00000 0.53333 0.33333 0.00000 0.53333 0.33333 0.00000 0.53333 0.40000 0.00000 0.53333 0.40000 0.00000 0.53333 0.40000 0.00000 0.53333 0.40000 0.00000 0.53333 0.40000 0.00000 0.53333 0.40000 0.00000 0.53333 0.40000 0.00000 0.53333 0.40000 0.00000 0.53333 0.46667 0.00000 0.53333 0.46667 0.00000 0.53333 0.46667 0.00000 0.53333 0.46667 0.00000 0.53333 0.46667 0.00000 0.53333 0.46667 0.00000 0.53333 0.46667 0.00000 0.53333 0.46667 0.00000 0.53333 0.53333 0.00000 0.53333 0.53333 0.00000 0.53333 0.53333 0.00000 0.53333 0.53333 0.00000 0.53333 0.53333 0.00000 0.46667 0.53333 0.00000 0.46667 0.53333 0.00000 0.46667 0.53333 0.00000 0.46667 0.60000 0.00000 0.40000 0.60000 0.00000 0.40000 0.60000 0.00000 0.40000 0.60000 0.00000 0.40000 0.60000 0.00000 0.33333 0.60000 0.00000 0.33333 0.60000 0.00000 0.33333 0.60000 0.00000 0.33333 0.66667 0.00000 0.26667 0.66667 0.00000 0.26667 0.66667 0.00000 0.26667 0.66667 0.00000 0.26667 0.66667 0.00000 0.20000 0.66667 0.00000 0.20000 0.66667 0.00000 0.20000 0.66667 0.00000 0.20000 0.73333 0.00000 0.13333 0.73333 0.00000 0.13333 0.73333 0.00000 0.13333 0.73333 0.00000 0.13333 0.73333 0.00000 0.06667 0.73333 0.00000 0.06667 0.73333 0.00000 0.06667 0.73333 0.00000 0.06667 0.80000 0.00000 0.00000 0.80000 0.00000 0.00000 0.80000 0.00000 0.00000 0.80000 0.00000 0.00000 0.80000 0.00000 0.00000 0.80000 0.00000 0.00000 0.80000 0.00000 0.00000 0.80000 0.00000 0.00000 0.86667 0.00000 0.00000 0.86667 0.00000 0.00000 0.86667 0.00000 0.00000 0.86667 0.00000 0.00000 0.86667 0.00000 0.00000 0.86667 0.00000 0.00000 0.86667 0.00000 0.00000 0.86667 0.00000 0.00000 0.93333 0.00000 0.00000 0.93333 0.00000 0.00000 0.93333 0.00000 0.00000 0.93333 0.00000 0.00000 0.93333 0.00000 0.00000 0.93333 0.00000 0.00000 0.93333 0.00000 0.00000 0.93333 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.06667 0.00000 1.00000 0.06667 0.00000 1.00000 0.13333 0.00000 1.00000 0.13333 0.00000 1.00000 0.20000 0.00000 1.00000 0.20000 0.00000 1.00000 0.26667 0.00000 1.00000 0.26667 0.00000 1.00000 0.33333 0.00000 1.00000 0.33333 0.00000 1.00000 0.40000 0.00000 1.00000 0.40000 0.00000 1.00000 0.46667 0.00000 1.00000 0.46667 0.00000 1.00000 0.53333 0.00000 1.00000 0.53333 0.00000 1.00000 0.60000 0.00000 1.00000 0.60000 0.00000 1.00000 0.66667 0.00000 1.00000 0.66667 0.00000 1.00000 0.73333 0.00000 1.00000 0.73333 0.00000 1.00000 0.80000 0.00000 1.00000 0.80000 0.00000 1.00000 0.86667 0.00000 1.00000 0.86667 0.00000 1.00000 0.93333 0.00000 1.00000 0.93333 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.06667 1.00000 1.00000 0.06667 1.00000 1.00000 0.13333 1.00000 1.00000 0.13333 1.00000 1.00000 0.20000 1.00000 1.00000 0.20000 1.00000 1.00000 0.26667 1.00000 1.00000 0.26667 1.00000 1.00000 0.33333 1.00000 1.00000 0.33333 1.00000 1.00000 0.40000 1.00000 1.00000 0.40000 1.00000 1.00000 0.46667 1.00000 1.00000 0.46667 1.00000 1.00000 0.53333 1.00000 1.00000 0.53333 1.00000 1.00000 0.60000 1.00000 1.00000 0.60000 1.00000 1.00000 0.66667 1.00000 1.00000 0.66667 1.00000 1.00000 0.73333 1.00000 1.00000 0.73333 1.00000 1.00000 0.80000 1.00000 1.00000 0.80000 1.00000 1.00000 0.86667 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/smooth3.lasc000066400000000000000000000324001215713201500221640ustar00rootroot00000000000000 0.00000 0.00000 0.00784 0.00000 0.00000 0.01795 0.00000 0.00000 0.03087 0.00000 0.00000 0.04434 0.00000 0.00000 0.05781 0.00000 0.00000 0.07128 0.00000 0.00000 0.08475 0.00000 0.00000 0.09822 0.00000 0.00000 0.11170 0.00000 0.00000 0.12231 0.00000 0.00000 0.13472 0.00000 0.00000 0.14819 0.00000 0.00000 0.16166 0.00000 0.00000 0.17513 0.00000 0.00000 0.18851 0.00000 0.00000 0.19862 0.00000 0.00000 0.21163 0.00000 0.00000 0.22510 0.00000 0.00000 0.23857 0.00000 0.00000 0.25080 0.00000 0.00000 0.26228 0.00000 0.00000 0.27885 0.00000 0.00000 0.28895 0.00000 0.00000 0.30201 0.00000 0.00000 0.31308 0.00000 0.00000 0.32503 0.00000 0.00000 0.33850 0.00000 0.00000 0.35197 0.00000 0.00000 0.36526 0.00000 0.00000 0.37536 0.00000 0.00000 0.39146 0.00000 0.00000 0.40341 0.00000 0.00000 0.41541 0.00000 0.00000 0.42754 0.00000 0.00000 0.43922 0.00000 0.00000 0.45559 0.00000 0.00000 0.46570 0.00000 0.00000 0.47885 0.00000 0.00000 0.49232 0.00000 0.00000 0.50579 0.00000 0.00000 0.51788 0.00000 0.00000 0.52881 0.00000 0.00000 0.54228 0.00000 0.00000 0.55576 0.00000 0.00000 0.56923 0.00000 0.00000 0.58016 0.00397 0.00000 0.59225 0.01356 0.00000 0.60572 0.02791 0.00000 0.61919 0.04507 0.00000 0.63234 0.06528 0.00000 0.64245 0.08235 0.00000 0.65569 0.10178 0.00000 0.66916 0.12198 0.00000 0.68263 0.14219 0.00000 0.69462 0.16240 0.00000 0.70565 0.18261 0.00000 0.71912 0.20281 0.00000 0.73259 0.21984 0.00000 0.74607 0.23668 0.00000 0.75954 0.25559 0.00000 0.77093 0.27580 0.00000 0.78256 0.29504 0.00000 0.79603 0.31063 0.00000 0.80909 0.31737 0.00000 0.81919 0.31765 0.00000 0.83575 0.31765 0.00000 0.84992 0.31765 0.00000 0.86339 0.31765 0.00000 0.87686 0.31765 0.00000 0.88932 0.31719 0.00000 0.89942 0.31382 0.00000 0.90953 0.31373 0.00000 0.92291 0.31373 0.00000 0.93638 0.31373 0.00000 0.94985 0.31373 0.00000 0.96332 0.31373 0.00000 0.97573 0.40250 0.05175 0.86307 0.99189 0.39528 0.05813 1.00000 0.40000 0.04706 0.84776 0.30312 0.04983 0.55402 0.11438 0.05319 0.38644 0.00000 0.05988 0.40664 0.00000 0.07442 0.42685 0.00000 0.09799 0.44706 0.00000 0.12157 0.46727 0.00000 0.13841 0.48466 0.00000 0.15806 0.50376 0.00000 0.17827 0.52397 0.00000 0.20018 0.54417 0.00000 0.22261 0.56438 0.00000 0.24281 0.58459 0.00000 0.26302 0.60480 0.00000 0.28323 0.62501 0.00000 0.30344 0.64521 0.00000 0.32364 0.66542 0.00000 0.34385 0.68563 0.00000 0.36406 0.70584 0.00000 0.38491 0.72604 0.00000 0.40840 0.74625 0.00000 0.42860 0.76937 0.00000 0.44881 0.79059 0.00000 0.46667 0.81260 0.00000 0.48711 0.83493 0.00000 0.50944 0.85513 0.00000 0.52964 0.87576 0.00000 0.54985 0.90607 0.00000 0.57006 0.93933 0.00000 0.59027 0.96821 0.00000 0.61047 0.98777 0.00000 0.63068 0.99737 0.00000 0.65089 1.00000 0.00000 0.67110 1.00000 0.00092 0.69149 1.00000 0.01776 0.71506 1.00000 0.03760 0.73564 1.00000 0.05781 0.75585 1.00000 0.07802 0.77606 1.00000 0.09822 0.79626 1.00000 0.11922 0.81647 1.00000 0.14279 0.83668 1.00000 0.16637 0.85689 1.00000 0.18690 0.88014 1.00000 0.20960 0.90122 1.00000 0.23124 0.92143 1.00000 0.25144 0.94164 1.00000 0.27165 0.96185 1.00000 0.29214 0.98178 1.00000 0.31571 0.99862 1.00000 0.33310 0.98454 1.00000 0.35248 0.96517 1.00000 0.37269 0.94496 1.00000 0.39290 0.92332 1.00000 0.41223 0.89974 1.00000 0.42907 0.87649 1.00000 0.44591 0.85628 1.00000 0.46588 0.83294 1.00000 0.48609 0.81195 1.00000 0.50630 0.79174 1.00000 0.52503 0.77006 1.00000 0.54279 0.74740 1.00000 0.56263 0.72720 1.00000 0.57947 0.70699 1.00000 0.59949 0.68360 1.00000 0.61707 0.66265 1.00000 0.62976 0.64037 1.00000 0.63682 0.61831 1.00000 0.63922 0.59811 1.00000 0.63922 0.57790 1.00000 0.63922 0.55769 1.00000 0.63922 0.53425 1.00000 0.63922 0.51335 1.00000 0.63922 0.49102 1.00000 0.63922 0.46902 1.00000 0.63922 0.44881 1.00000 0.63922 0.42860 1.00000 0.63922 0.40839 1.00000 0.63922 0.38491 1.00000 0.63922 0.36406 1.00000 0.63922 0.34168 0.99838 0.63922 0.31972 0.99077 0.63922 0.29845 0.97241 0.63922 0.27589 0.94546 0.63922 0.25905 0.91520 0.63922 0.23557 0.88489 0.63922 0.21476 0.85457 0.63922 0.19234 0.82426 0.63922 0.16876 0.79395 0.63922 0.14629 0.76309 0.63922 0.12664 0.72941 0.63922 0.10980 0.70583 0.63922 0.08622 0.69070 0.63922 0.06265 0.67949 0.63922 0.04133 0.67793 0.64092 0.02113 0.68582 0.64545 0.00554 0.69772 0.65278 0.00000 0.71793 0.66307 0.00000 0.73814 0.68665 0.00000 0.75834 0.71022 0.00000 0.77855 0.73380 0.00000 0.79876 0.75738 0.00000 0.81897 0.78095 0.00000 0.83982 0.80517 0.00000 0.86330 0.83202 0.00000 0.88351 0.85560 0.00000 0.90372 0.88208 0.00000 0.92393 0.90667 0.00000 0.94413 0.93025 0.00000 0.96434 0.95382 0.00000 0.98386 0.97740 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00305 1.00000 1.00000 0.01638 1.00000 1.00000 0.03322 1.00000 1.00000 0.05006 1.00000 1.00000 0.06773 1.00000 1.00000 0.08794 1.00000 1.00000 0.10815 1.00000 1.00000 0.12526 1.00000 1.00000 0.14464 1.00000 1.00000 0.16485 1.00000 1.00000 0.18506 1.00000 1.00000 0.20439 1.00000 1.00000 0.22155 1.00000 1.00000 0.24176 1.00000 1.00000 0.25883 1.00000 1.00000 0.27567 1.00000 1.00000 0.28642 1.00000 1.00000 0.28872 1.00000 1.00000 0.28350 1.00000 1.00000 0.27229 1.00000 1.00000 0.25208 1.00000 1.00000 0.22869 1.00000 1.00000 0.20511 1.00000 1.00000 0.18154 1.00000 1.00000 0.15796 1.00000 1.00000 0.13536 1.00000 1.00000 0.11473 1.00000 1.00000 0.09116 1.00000 1.00000 0.06435 1.00000 1.00000 0.04008 1.00000 1.00000 0.02076 1.00000 1.00000 0.00706 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.09305 1.00000 1.00000 0.33136 1.00000 1.00000 0.60966 1.00000 1.00000 0.83605 0.96674 1.00000 0.96343 0.75749 1.00000 1.00000 0.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/staircase.lasc000066400000000000000000000324001215713201500225460ustar00rootroot00000000000000 0.00392 0.00392 0.31373 0.00784 0.00784 0.31373 0.01176 0.01176 0.31373 0.01569 0.01569 0.31373 0.01961 0.01961 0.31373 0.02353 0.02353 0.31373 0.02745 0.02745 0.31373 0.03137 0.03137 0.31373 0.03529 0.03529 0.31373 0.03922 0.03922 0.31373 0.04314 0.04314 0.31373 0.04706 0.04706 0.31373 0.05098 0.05098 0.31373 0.05490 0.05490 0.31373 0.05882 0.05882 0.31373 0.06275 0.06275 0.31373 0.06667 0.06667 0.47059 0.07059 0.07059 0.47059 0.07451 0.07451 0.47059 0.07843 0.07843 0.47059 0.08235 0.08235 0.47059 0.08627 0.08627 0.47059 0.09020 0.09020 0.47059 0.09412 0.09412 0.47059 0.09804 0.09804 0.47059 0.10196 0.10196 0.47059 0.10588 0.10588 0.47059 0.10980 0.10980 0.47059 0.11373 0.11373 0.47059 0.11765 0.11765 0.47059 0.12157 0.12157 0.47059 0.12549 0.12549 0.47059 0.12941 0.12941 0.62745 0.13333 0.13333 0.62745 0.13725 0.13725 0.62745 0.14118 0.14118 0.62745 0.14510 0.14510 0.62745 0.14902 0.14902 0.62745 0.15294 0.15294 0.62745 0.15686 0.15686 0.62745 0.16078 0.16078 0.62745 0.16471 0.16471 0.62745 0.16863 0.16863 0.62745 0.17255 0.17255 0.62745 0.17647 0.17647 0.62745 0.18039 0.18039 0.62745 0.18431 0.18431 0.62745 0.18824 0.18824 0.62745 0.19216 0.19216 0.78431 0.19608 0.19608 0.78431 0.20000 0.20000 0.78431 0.20392 0.20392 0.78431 0.20784 0.20784 0.78431 0.21176 0.21176 0.78431 0.21569 0.21569 0.78431 0.21961 0.21961 0.78431 0.22353 0.22353 0.78431 0.22745 0.22745 0.78431 0.23137 0.23137 0.78431 0.23529 0.23529 0.78431 0.23922 0.23922 0.78431 0.24314 0.24314 0.78431 0.24706 0.24706 0.78431 0.25098 0.25098 0.78431 0.25490 0.25490 0.94118 0.25882 0.25882 0.94118 0.26275 0.26275 0.94118 0.26667 0.26667 0.94118 0.27059 0.27059 0.94118 0.27451 0.27451 0.94118 0.27843 0.27843 0.94118 0.28235 0.28235 0.94118 0.28627 0.28627 0.94118 0.29020 0.29020 0.94118 0.29412 0.29412 0.94118 0.29804 0.29804 0.94118 0.30196 0.30196 0.94118 0.30588 0.30588 0.94118 0.30980 0.30980 0.94118 0.31373 0.31373 0.94118 0.31765 0.31765 0.95294 0.32157 0.32157 0.96471 0.32549 0.32549 0.97647 0.32941 0.32941 0.98824 0.33333 0.33333 1.00000 0.00392 0.31373 0.00392 0.00784 0.31373 0.00784 0.01176 0.31373 0.01176 0.01569 0.31373 0.01569 0.01961 0.31373 0.01961 0.02353 0.31373 0.02353 0.02745 0.31373 0.02745 0.03137 0.31373 0.03137 0.03529 0.31373 0.03529 0.03922 0.31373 0.03922 0.04314 0.31373 0.04314 0.04706 0.31373 0.04706 0.05098 0.31373 0.05098 0.05490 0.31373 0.05490 0.05882 0.31373 0.05882 0.06275 0.31373 0.06275 0.06667 0.47059 0.06667 0.07059 0.47059 0.07059 0.07451 0.47059 0.07451 0.07843 0.47059 0.07843 0.08235 0.47059 0.08235 0.08627 0.47059 0.08627 0.09020 0.47059 0.09020 0.09412 0.47059 0.09412 0.09804 0.47059 0.09804 0.10196 0.47059 0.10196 0.10588 0.47059 0.10588 0.10980 0.47059 0.10980 0.11373 0.47059 0.11373 0.11765 0.47059 0.11765 0.12157 0.47059 0.12157 0.12549 0.47059 0.12549 0.12941 0.62745 0.12941 0.13333 0.62745 0.13333 0.13725 0.62745 0.13725 0.14118 0.62745 0.14118 0.14510 0.62745 0.14510 0.14902 0.62745 0.14902 0.15294 0.62745 0.15294 0.15686 0.62745 0.15686 0.16078 0.62745 0.16078 0.16471 0.62745 0.16471 0.16863 0.62745 0.16863 0.17255 0.62745 0.17255 0.17647 0.62745 0.17647 0.18039 0.62745 0.18039 0.18431 0.62745 0.18431 0.18824 0.62745 0.18824 0.19216 0.78431 0.19216 0.19608 0.78431 0.19608 0.20000 0.78431 0.20000 0.20392 0.78431 0.20392 0.20784 0.78431 0.20784 0.21176 0.78431 0.21176 0.21569 0.78431 0.21569 0.21961 0.78431 0.21961 0.22353 0.78431 0.22353 0.22745 0.78431 0.22745 0.23137 0.78431 0.23137 0.23529 0.78431 0.23529 0.23922 0.78431 0.23922 0.24314 0.78431 0.24314 0.24706 0.78431 0.24706 0.25098 0.78431 0.25098 0.25490 0.94118 0.25490 0.25882 0.94118 0.25882 0.26275 0.94118 0.26275 0.26667 0.94118 0.26667 0.27059 0.94118 0.27059 0.27451 0.94118 0.27451 0.27843 0.94118 0.27843 0.28235 0.94118 0.28235 0.28627 0.94118 0.28627 0.29020 0.94118 0.29020 0.29412 0.94118 0.29412 0.29804 0.94118 0.29804 0.30196 0.94118 0.30196 0.30588 0.94118 0.30588 0.30980 0.94118 0.30980 0.31373 0.94118 0.31373 0.31765 0.95294 0.31765 0.32157 0.96471 0.32157 0.32549 0.97647 0.32549 0.32941 0.98824 0.32941 0.33333 1.00000 0.33333 0.31373 0.00392 0.00392 0.31373 0.00784 0.00784 0.31373 0.01176 0.01176 0.31373 0.01569 0.01569 0.31373 0.01961 0.01961 0.31373 0.02353 0.02353 0.31373 0.02745 0.02745 0.31373 0.03137 0.03137 0.31373 0.03529 0.03529 0.31373 0.03922 0.03922 0.31373 0.04314 0.04314 0.31373 0.04706 0.04706 0.31373 0.05098 0.05098 0.31373 0.05490 0.05490 0.31373 0.05882 0.05882 0.31373 0.06275 0.06275 0.47059 0.06667 0.06667 0.47059 0.07059 0.07059 0.47059 0.07451 0.07451 0.47059 0.07843 0.07843 0.47059 0.08235 0.08235 0.47059 0.08627 0.08627 0.47059 0.09020 0.09020 0.47059 0.09412 0.09412 0.47059 0.09804 0.09804 0.47059 0.10196 0.10196 0.47059 0.10588 0.10588 0.47059 0.10980 0.10980 0.47059 0.11373 0.11373 0.47059 0.11765 0.11765 0.47059 0.12157 0.12157 0.47059 0.12549 0.12549 0.62745 0.12941 0.12941 0.62745 0.13333 0.13333 0.62745 0.13725 0.13725 0.62745 0.14118 0.14118 0.62745 0.14510 0.14510 0.62745 0.14902 0.14902 0.62745 0.15294 0.15294 0.62745 0.15686 0.15686 0.62745 0.16078 0.16078 0.62745 0.16471 0.16471 0.62745 0.16863 0.16863 0.62745 0.17255 0.17255 0.62745 0.17647 0.17647 0.62745 0.18039 0.18039 0.62745 0.18431 0.18431 0.62745 0.18824 0.18824 0.78431 0.19216 0.19216 0.78431 0.19608 0.19608 0.78431 0.20000 0.20000 0.78431 0.20392 0.20392 0.78431 0.20784 0.20784 0.78431 0.21176 0.21176 0.78431 0.21569 0.21569 0.78431 0.21961 0.21961 0.78431 0.22353 0.22353 0.78431 0.22745 0.22745 0.78431 0.23137 0.23137 0.78431 0.23529 0.23529 0.78431 0.23922 0.23922 0.78431 0.24314 0.24314 0.78431 0.24706 0.24706 0.78431 0.25098 0.25098 0.94118 0.25490 0.25490 0.94118 0.25882 0.25882 0.94118 0.26275 0.26275 0.94118 0.26667 0.26667 0.94118 0.27059 0.27059 0.94118 0.27451 0.27451 0.94118 0.27843 0.27843 0.94118 0.28235 0.28235 0.94118 0.28627 0.28627 0.94118 0.29020 0.29020 0.94118 0.29412 0.29412 0.94118 0.29804 0.29804 0.94118 0.30196 0.30196 0.94118 0.30588 0.30588 0.94118 0.30980 0.30980 0.94118 0.31373 0.31373 0.94902 0.39216 0.39216 0.96078 0.52941 0.52941 0.97255 0.66667 0.66667 0.98431 0.80392 0.80392 0.99216 0.80000 0.80000 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/stairs.iasc000066400000000000000000000154001215713201500220730ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.05882 0.05882 0.05882 0.05882 0.05882 0.05882 0.05882 0.05882 0.05882 0.05882 0.05882 0.05882 0.05882 0.05882 0.05882 0.11765 0.11765 0.11765 0.11765 0.11765 0.11765 0.11765 0.11765 0.11765 0.11765 0.11765 0.11765 0.11765 0.11765 0.11765 0.17647 0.17647 0.17647 0.17647 0.17647 0.17647 0.17647 0.17647 0.17647 0.17647 0.17647 0.17647 0.17647 0.17647 0.17647 0.23529 0.23529 0.23529 0.23529 0.23529 0.23529 0.23529 0.23529 0.23529 0.23529 0.23529 0.23529 0.23529 0.23529 0.23529 0.29412 0.29412 0.29412 0.29412 0.29412 0.29412 0.29412 0.29412 0.29412 0.29412 0.29412 0.29412 0.29412 0.29412 0.29412 0.35294 0.35294 0.35294 0.35294 0.35294 0.35294 0.35294 0.35294 0.35294 0.35294 0.35294 0.35294 0.35294 0.35294 0.35294 0.41176 0.41176 0.41176 0.41176 0.41176 0.41176 0.41176 0.41176 0.41176 0.41176 0.41176 0.41176 0.41176 0.41176 0.41176 0.47059 0.47059 0.47059 0.47059 0.47059 0.47059 0.47059 0.47059 0.47059 0.47059 0.47059 0.47059 0.47059 0.47059 0.47059 0.52941 0.52941 0.52941 0.52941 0.52941 0.52941 0.52941 0.52941 0.52941 0.52941 0.52941 0.52941 0.52941 0.52941 0.52941 0.58824 0.58824 0.58824 0.58824 0.58824 0.58824 0.58824 0.58824 0.58824 0.58824 0.58824 0.58824 0.58824 0.58824 0.58824 0.64706 0.64706 0.64706 0.64706 0.64706 0.64706 0.64706 0.64706 0.64706 0.64706 0.64706 0.64706 0.64706 0.64706 0.64706 0.70588 0.70588 0.70588 0.70588 0.70588 0.70588 0.70588 0.70588 0.70588 0.70588 0.70588 0.70588 0.70588 0.70588 0.70588 0.76471 0.76471 0.76471 0.76471 0.76471 0.76471 0.76471 0.76471 0.76471 0.76471 0.76471 0.76471 0.76471 0.76471 0.76471 0.82353 0.82353 0.82353 0.82353 0.82353 0.82353 0.82353 0.82353 0.82353 0.82353 0.82353 0.82353 0.82353 0.82353 0.82353 0.88235 0.88235 0.88235 0.88235 0.88235 0.88235 0.88235 0.88235 0.88235 0.88235 0.88235 0.88235 0.88235 0.88235 0.88235 0.94118 0.94118 0.94118 0.94118 0.94118 0.94118 0.94118 0.94118 0.94118 0.94118 0.94118 0.94118 0.94118 0.94118 0.94118 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/stairs8.lasc000066400000000000000000000324001215713201500221650ustar00rootroot00000000000000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 0.76471 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.49804 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/stairs9.lasc000066400000000000000000000324001215713201500221660ustar00rootroot00000000000000 0.00000 0.00000 0.00000 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.19608 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.60784 0.00000 0.47451 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.78431 0.00000 0.00000 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.92549 0.65490 0.37255 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.56863 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 0.96471 0.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.69412 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 1.00000 skycat-3.1.2-starlink-1b/rtd/colormaps/standard.lasc000066400000000000000000000324001215713201500223700ustar00rootroot00000000000000 0.00392 0.00392 0.33333 0.00784 0.00784 0.34118 0.01176 0.01176 0.34902 0.01569 0.01569 0.35686 0.01961 0.01961 0.36471 0.02353 0.02353 0.37255 0.02745 0.02745 0.38039 0.03137 0.03137 0.38824 0.03529 0.03529 0.39608 0.03922 0.03922 0.40392 0.04314 0.04314 0.41176 0.04706 0.04706 0.41961 0.05098 0.05098 0.42745 0.05490 0.05490 0.43529 0.05882 0.05882 0.44314 0.06275 0.06275 0.45098 0.06667 0.06667 0.45882 0.07059 0.07059 0.46667 0.07451 0.07451 0.47451 0.07843 0.07843 0.48235 0.08235 0.08235 0.49020 0.08627 0.08627 0.49804 0.09020 0.09020 0.50588 0.09412 0.09412 0.51373 0.09804 0.09804 0.52157 0.10196 0.10196 0.52941 0.10588 0.10588 0.53725 0.10980 0.10980 0.54510 0.11373 0.11373 0.55294 0.11765 0.11765 0.56078 0.12157 0.12157 0.56863 0.12549 0.12549 0.57647 0.12941 0.12941 0.58431 0.13333 0.13333 0.59216 0.13725 0.13725 0.60000 0.14118 0.14118 0.60784 0.14510 0.14510 0.61569 0.14902 0.14902 0.62353 0.15294 0.15294 0.63137 0.15686 0.15686 0.63922 0.16078 0.16078 0.64706 0.16471 0.16471 0.65490 0.16863 0.16863 0.66275 0.17255 0.17255 0.67059 0.17647 0.17647 0.67843 0.18039 0.18039 0.68627 0.18431 0.18431 0.69412 0.18824 0.18824 0.70196 0.19216 0.19216 0.70980 0.19608 0.19608 0.71765 0.20000 0.20000 0.72549 0.20392 0.20392 0.73333 0.20784 0.20784 0.74118 0.21176 0.21176 0.74902 0.21569 0.21569 0.75686 0.21961 0.21961 0.76471 0.22353 0.22353 0.77255 0.22745 0.22745 0.78039 0.23137 0.23137 0.78824 0.23529 0.23529 0.79608 0.23922 0.23922 0.80392 0.24314 0.24314 0.81176 0.24706 0.24706 0.81961 0.25098 0.25098 0.82745 0.25490 0.25490 0.83529 0.25882 0.25882 0.84314 0.26275 0.26275 0.85098 0.26667 0.26667 0.85882 0.27059 0.27059 0.86667 0.27451 0.27451 0.87451 0.27843 0.27843 0.88235 0.28235 0.28235 0.89020 0.28627 0.28627 0.89804 0.29020 0.29020 0.90588 0.29412 0.29412 0.91373 0.29804 0.29804 0.92157 0.30196 0.30196 0.92941 0.30588 0.30588 0.93725 0.30980 0.30980 0.94510 0.31373 0.31373 0.95294 0.31765 0.31765 0.96078 0.32157 0.32157 0.96863 0.32549 0.32549 0.97647 0.32941 0.32941 0.98431 0.33333 0.33333 0.99216 0.00392 0.33333 0.00392 0.00784 0.34118 0.00784 0.01176 0.34902 0.01176 0.01569 0.35686 0.01569 0.01961 0.36471 0.01961 0.02353 0.37255 0.02353 0.02745 0.38039 0.02745 0.03137 0.38824 0.03137 0.03529 0.39608 0.03529 0.03922 0.40392 0.03922 0.04314 0.41176 0.04314 0.04706 0.41961 0.04706 0.05098 0.42745 0.05098 0.05490 0.43529 0.05490 0.05882 0.44314 0.05882 0.06275 0.45098 0.06275 0.06667 0.45882 0.06667 0.07059 0.46667 0.07059 0.07451 0.47451 0.07451 0.07843 0.48235 0.07843 0.08235 0.49020 0.08235 0.08627 0.49804 0.08627 0.09020 0.50588 0.09020 0.09412 0.51373 0.09412 0.09804 0.52157 0.09804 0.10196 0.52941 0.10196 0.10588 0.53725 0.10588 0.10980 0.54510 0.10980 0.11373 0.55294 0.11373 0.11765 0.56078 0.11765 0.12157 0.56863 0.12157 0.12549 0.57647 0.12549 0.12941 0.58431 0.12941 0.13333 0.59216 0.13333 0.13725 0.60000 0.13725 0.14118 0.60784 0.14118 0.14510 0.61569 0.14510 0.14902 0.62353 0.14902 0.15294 0.63137 0.15294 0.15686 0.63922 0.15686 0.16078 0.64706 0.16078 0.16471 0.65490 0.16471 0.16863 0.66275 0.16863 0.17255 0.67059 0.17255 0.17647 0.67843 0.17647 0.18039 0.68627 0.18039 0.18431 0.69412 0.18431 0.18824 0.70196 0.18824 0.19216 0.70980 0.19216 0.19608 0.71765 0.19608 0.20000 0.72549 0.20000 0.20392 0.73333 0.20392 0.20784 0.74118 0.20784 0.21176 0.74902 0.21176 0.21569 0.75686 0.21569 0.21961 0.76471 0.21961 0.22353 0.77255 0.22353 0.22745 0.78039 0.22745 0.23137 0.78824 0.23137 0.23529 0.79608 0.23529 0.23922 0.80392 0.23922 0.24314 0.81176 0.24314 0.24706 0.81961 0.24706 0.25098 0.82745 0.25098 0.25490 0.83529 0.25490 0.25882 0.84314 0.25882 0.26275 0.85098 0.26275 0.26667 0.85882 0.26667 0.27059 0.86667 0.27059 0.27451 0.87451 0.27451 0.27843 0.88235 0.27843 0.28235 0.89020 0.28235 0.28627 0.89804 0.28627 0.29020 0.90588 0.29020 0.29412 0.91373 0.29412 0.29804 0.92157 0.29804 0.30196 0.92941 0.30196 0.30588 0.93725 0.30588 0.30980 0.94510 0.30980 0.31373 0.95294 0.31373 0.31765 0.96078 0.31765 0.32157 0.96863 0.32157 0.32549 0.97647 0.32549 0.32941 0.98431 0.32941 0.33333 0.99216 0.33333 0.33333 0.00392 0.00392 0.34118 0.00784 0.00784 0.34902 0.01176 0.01176 0.35686 0.01569 0.01569 0.36471 0.01961 0.01961 0.37255 0.02353 0.02353 0.38039 0.02745 0.02745 0.38824 0.03137 0.03137 0.39608 0.03529 0.03529 0.40392 0.03922 0.03922 0.41176 0.04314 0.04314 0.41961 0.04706 0.04706 0.42745 0.05098 0.05098 0.43529 0.05490 0.05490 0.44314 0.05882 0.05882 0.45098 0.06275 0.06275 0.45882 0.06667 0.06667 0.46667 0.07059 0.07059 0.47451 0.07451 0.07451 0.48235 0.07843 0.07843 0.49020 0.08235 0.08235 0.49804 0.08627 0.08627 0.50588 0.09020 0.09020 0.51373 0.09412 0.09412 0.52157 0.09804 0.09804 0.52941 0.10196 0.10196 0.53725 0.10588 0.10588 0.54510 0.10980 0.10980 0.55294 0.11373 0.11373 0.56078 0.11765 0.11765 0.56863 0.12157 0.12157 0.57647 0.12549 0.12549 0.58431 0.12941 0.12941 0.59216 0.13333 0.13333 0.60000 0.13725 0.13725 0.60784 0.14118 0.14118 0.61569 0.14510 0.14510 0.62353 0.14902 0.14902 0.63137 0.15294 0.15294 0.63922 0.15686 0.15686 0.64706 0.16078 0.16078 0.65490 0.16471 0.16471 0.66275 0.16863 0.16863 0.67059 0.17255 0.17255 0.67843 0.17647 0.17647 0.68627 0.18039 0.18039 0.69412 0.18431 0.18431 0.70196 0.18824 0.18824 0.70980 0.19216 0.19216 0.71765 0.19608 0.19608 0.72549 0.20000 0.20000 0.73333 0.20392 0.20392 0.74118 0.20784 0.20784 0.74902 0.21176 0.21176 0.75686 0.21569 0.21569 0.76471 0.21961 0.21961 0.77255 0.22353 0.22353 0.78039 0.22745 0.22745 0.78824 0.23137 0.23137 0.79608 0.23529 0.23529 0.80392 0.23922 0.23922 0.81176 0.24314 0.24314 0.81961 0.24706 0.24706 0.82745 0.25098 0.25098 0.83529 0.25490 0.25490 0.84314 0.25882 0.25882 0.85098 0.26275 0.26275 0.85882 0.26667 0.26667 0.86667 0.27059 0.27059 0.87451 0.27451 0.27451 0.88235 0.27843 0.27843 0.89020 0.28235 0.28235 0.89804 0.28627 0.28627 0.90588 0.29020 0.29020 0.91373 0.29412 0.29412 0.92157 0.29804 0.29804 0.92941 0.30196 0.30196 0.93725 0.30588 0.30588 0.94510 0.30980 0.30980 0.95294 0.31373 0.31373 0.96078 0.31765 0.31765 0.96863 0.32157 0.32157 0.97647 0.32549 0.32549 0.98431 0.32941 0.32941 0.99216 0.33333 0.33333 1.00000 0.33725 0.33725 skycat-3.1.2-starlink-1b/rtd/colormaps/update_colormaps.sh000066400000000000000000000002071215713201500236210ustar00rootroot00000000000000#!/bin/sh # # This script updates a C source file to contain the colormaps in this dir. tclsh colormaps.tcl > ../generic/colormaps.C skycat-3.1.2-starlink-1b/rtd/configure000077500000000000000000014113561215713201500176500ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by Starlink Autoconf 2.59 for rtd 3.2.1. # # Copyright (C) 2003 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` exec 6>&1 # # Initializations. # ac_default_prefix=/usr/local ac_config_libobj_dir=. cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. # This variable seems obsolete. It should probably be removed, and # only ac_max_sed_lines should be used. : ${ac_max_here_lines=38} # Identity of this package. PACKAGE_NAME='rtd' PACKAGE_TARNAME='rtd' PACKAGE_VERSION='3.2.1' PACKAGE_STRING='rtd 3.2.1' PACKAGE_BUGREPORT='' # Factoring default headers for most tests. ac_includes_default="\ #include #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_STAT_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #if HAVE_INTTYPES_H # include #else # if HAVE_STDINT_H # include # endif #endif #if HAVE_UNISTD_H # include #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CYGPATH EXEEXT PKG_LIB_FILE PKG_STUB_LIB_FILE PKG_STUB_SOURCES PKG_STUB_OBJECTS PKG_TCL_SOURCES PKG_HEADERS PKG_INCLUDES PKG_LIBS PKG_CFLAGS TCL_VERSION TCL_BIN_DIR TCL_SRC_DIR TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_LIBS TCL_DEFS TCL_EXTRA_CFLAGS TCL_LD_FLAGS TCL_SHLIB_LD_LIBS TK_VERSION TK_BIN_DIR TK_SRC_DIR TK_LIB_FILE TK_LIB_FLAG TK_LIB_SPEC TK_STUB_LIB_FILE TK_STUB_LIB_FLAG TK_STUB_LIB_SPEC TK_LIBS TK_XINCLUDES CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT CPP CXX CXXFLAGS ac_ct_CXX INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA SET_MAKE RANLIB ac_ct_RANLIB EGREP MATH_LIBS tclutil_VERSION tclutil_LIB_FILE tclutil_BUILD_LIB_SPEC tclutil_BUILD_DIR tclutil_LIB_SPEC BLT_LIB_DIR BLT_LIB_SPEC tclutil_SRC_DIR tclutil_PKG_OBJECTS CFITSIO_LIB_DIR CFITSIO_LIB_SPEC astrotcl_VERSION astrotcl_LIB_FILE astrotcl_BUILD_LIB_SPEC astrotcl_BUILD_DIR astrotcl_LIB_SPEC astrotcl_SRC_DIR astrotcl_PKG_OBJECTS MERGE_OBJECTS SHLIB_LD_CXX_LIBS PKG_SOURCES PKG_OBJECTS CLEANFILES TCL_INCLUDES TK_INCLUDES CXXCPP TCL_THREADS SHARED_BUILD AR CELIB_DIR LIBOBJS SHLIB_SUFFIX DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING STLIB_LD SHLIB_LD SHLIB_CFLAGS SHLIB_LD_LIBS LDFLAGS_DEBUG LDFLAGS_OPTIMIZE LD_LIBRARY_PATH_VAR TCL_DBGX CFLAGS_DEFAULT LDFLAGS_DEFAULT MAKE_LIB MAKE_SHARED_LIB MAKE_STATIC_LIB MAKE_STUB_LIB RANLIB_STUB TCLSH_PROG WISH_PROG rtd_LIB_FILE rtd_BUILD_LIB_SPEC rtd_BUILD_DIR rtd_LIB_SPEC rtd_PKG_OBJECTS rtd_SRC_DIR LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_option in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval "enable_$ac_feature=no" ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "enable_$ac_feature='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "with_$ac_package='$ac_optarg'" ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/-/_/g'` eval "with_$ac_package=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` eval "$ac_envvar='$ac_optarg'" export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute paths. for ac_var in exec_prefix prefix do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* | NONE | '' ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # Be sure to have absolute paths. for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ localstatedir libdir includedir oldincludedir infodir mandir do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_confdir=`(dirname "$0") 2>/dev/null || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 { (exit 1); exit 1; }; } else { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi fi (cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 { (exit 1); exit 1; }; } srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` ac_env_build_alias_set=${build_alias+set} ac_env_build_alias_value=$build_alias ac_cv_env_build_alias_set=${build_alias+set} ac_cv_env_build_alias_value=$build_alias ac_env_host_alias_set=${host_alias+set} ac_env_host_alias_value=$host_alias ac_cv_env_host_alias_set=${host_alias+set} ac_cv_env_host_alias_value=$host_alias ac_env_target_alias_set=${target_alias+set} ac_env_target_alias_value=$target_alias ac_cv_env_target_alias_set=${target_alias+set} ac_cv_env_target_alias_value=$target_alias ac_env_CC_set=${CC+set} ac_env_CC_value=$CC ac_cv_env_CC_set=${CC+set} ac_cv_env_CC_value=$CC ac_env_CFLAGS_set=${CFLAGS+set} ac_env_CFLAGS_value=$CFLAGS ac_cv_env_CFLAGS_set=${CFLAGS+set} ac_cv_env_CFLAGS_value=$CFLAGS ac_env_LDFLAGS_set=${LDFLAGS+set} ac_env_LDFLAGS_value=$LDFLAGS ac_cv_env_LDFLAGS_set=${LDFLAGS+set} ac_cv_env_LDFLAGS_value=$LDFLAGS ac_env_CPPFLAGS_set=${CPPFLAGS+set} ac_env_CPPFLAGS_value=$CPPFLAGS ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} ac_cv_env_CPPFLAGS_value=$CPPFLAGS ac_env_CPP_set=${CPP+set} ac_env_CPP_value=$CPP ac_cv_env_CPP_set=${CPP+set} ac_cv_env_CPP_value=$CPP ac_env_CXX_set=${CXX+set} ac_env_CXX_value=$CXX ac_cv_env_CXX_set=${CXX+set} ac_cv_env_CXX_value=$CXX ac_env_CXXFLAGS_set=${CXXFLAGS+set} ac_env_CXXFLAGS_value=$CXXFLAGS ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set} ac_cv_env_CXXFLAGS_value=$CXXFLAGS ac_env_CXXCPP_set=${CXXCPP+set} ac_env_CXXCPP_value=$CXXCPP ac_cv_env_CXXCPP_set=${CXXCPP+set} ac_cv_env_CXXCPP_value=$CXXCPP # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures rtd 3.2.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] _ACEOF cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --infodir=DIR info documentation [PREFIX/info] --mandir=DIR man documentation [PREFIX/man] _ACEOF cat <<\_ACEOF X features: --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of rtd 3.2.1:";; esac cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-merge merge the contents of dependent packages into a master library --enable-threads build with threads --enable-shared build and link with shared libraries --enable-shared --enable-64bit enable 64bit support (where applicable) --enable-64bit-vis enable 64bit Sparc VIS support --enable-wince enable Win/CE support (where applicable) --disable-load disallow dynamic loading and "load" command --enable-symbols build with debugging symbols --disable-symbols Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-tcl directory containing tcl configuration (tclConfig.sh) --with-tk directory containing tk configuration (tkConfig.sh) --with-tclinclude directory containing the public Tcl header files --with-tkinclude directory containing the public Tk header files. --with-x use the X Window System --with-celib=DIR use Windows/CE support library from DIR Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor CXX C++ compiler command CXXFLAGS C++ compiler flags CXXCPP C++ preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d $ac_dir || continue ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_srcdir/configure.gnu; then echo $SHELL $ac_srcdir/configure.gnu --help=recursive elif test -f $ac_srcdir/configure; then echo $SHELL $ac_srcdir/configure --help=recursive elif test -f $ac_srcdir/configure.ac || test -f $ac_srcdir/configure.in; then echo $ac_configure --help else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi cd $ac_popdir done fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF rtd configure 3.2.1 generated by Starlink Autoconf 2.59 Copyright (C) 2003 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit 0 fi exec 5>config.log cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by rtd $as_me 3.2.1, which was generated by Starlink Autoconf 2.59. Invocation command line was $ $0 $@ _ACEOF { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` hostinfo = `(hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" # Get rid of the leading space. ac_sep=" " ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Be sure not to use single quotes in there, as some shells, # such as our DU 5.0 friend, will then `close' the trap. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, { (set) 2>&1 | case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in *ac_space=\ *) sed -n \ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" ;; *) sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------- ## ## Output files. ## ## ------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo sed "/^$/d" confdefs.h | sort echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core && rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo >confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . $cache_file;; *) . ./$cache_file;; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in `(set) 2>&1 | sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val="\$ac_cv_env_${ac_var}_value" eval ac_new_val="\$ac_env_${ac_var}_value" case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu #-------------------------------------------------------------------- # Call TEA_INIT as the first TEA_ macro to set up initial vars. # This will define a ${TEA_PLATFORM} variable == "unix" or "windows" # as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE. #-------------------------------------------------------------------- # TEA extensions pass this us the version of TEA they think they # are compatible with. TEA_VERSION="3.4" echo "$as_me:$LINENO: checking for correct TEA configuration" >&5 echo $ECHO_N "checking for correct TEA configuration... $ECHO_C" >&6 if test x"${PACKAGE_NAME}" = x ; then { { echo "$as_me:$LINENO: error: The PACKAGE_NAME variable must be defined by your TEA configure.in" >&5 echo "$as_me: error: The PACKAGE_NAME variable must be defined by your TEA configure.in" >&2;} { (exit 1); exit 1; }; } fi if test x"3.4" = x ; then { { echo "$as_me:$LINENO: error: TEA version not specified." >&5 echo "$as_me: error: TEA version not specified." >&2;} { (exit 1); exit 1; }; } elif test "3.4" != "${TEA_VERSION}" ; then echo "$as_me:$LINENO: result: warning: requested TEA version \"3.4\", have \"${TEA_VERSION}\"" >&5 echo "${ECHO_T}warning: requested TEA version \"3.4\", have \"${TEA_VERSION}\"" >&6 else echo "$as_me:$LINENO: result: ok (TEA ${TEA_VERSION})" >&5 echo "${ECHO_T}ok (TEA ${TEA_VERSION})" >&6 fi case "`uname -s`" in *win32*|*WIN32*|*CYGWIN_NT*|*CYGWIN_9*|*CYGWIN_ME*|*MINGW32_*) # Extract the first word of "cygpath", so it can be a program name with args. set dummy cygpath; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CYGPATH+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CYGPATH"; then ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CYGPATH="cygpath -w" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo" fi fi CYGPATH=$ac_cv_prog_CYGPATH if test -n "$CYGPATH"; then echo "$as_me:$LINENO: result: $CYGPATH" >&5 echo "${ECHO_T}$CYGPATH" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi EXEEXT=".exe" TEA_PLATFORM="windows" ;; *) CYGPATH=echo EXEEXT="" TEA_PLATFORM="unix" ;; esac # Check if exec_prefix is set. If not use fall back to prefix. # Note when adjusted, so that TEA_PREFIX can correct for this. # This is needed for recursive configures, since autoconf propagates # $prefix, but not $exec_prefix (doh!). if test x$exec_prefix = xNONE ; then exec_prefix_default=yes exec_prefix=$prefix fi # This package name must be replaced statically for AC_SUBST to work # Substitute STUB_LIB_FILE in case package creates a stub library too. # We AC_SUBST these here to ensure they are subst'ed, # in case the user doesn't call TEA_ADD_... #-------------------------------------------------------------------- # Load the tclConfig.sh file #-------------------------------------------------------------------- # # Ok, lets find the tcl configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tcl # if test x"${no_tcl}" = x ; then # we reset no_tcl in case something fails here no_tcl=true # Check whether --with-tcl or --without-tcl was given. if test "${with_tcl+set}" = set; then withval="$with_tcl" with_tclconfig=${withval} fi; echo "$as_me:$LINENO: checking for Tcl configuration" >&5 echo $ECHO_N "checking for Tcl configuration... $ECHO_C" >&6 if test "${ac_cv_c_tclconfig+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # First check to see if --with-tcl was specified. if test x"${with_tclconfig}" != x ; then case ${with_tclconfig} in */tclConfig.sh ) if test -f ${with_tclconfig}; then { echo "$as_me:$LINENO: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5 echo "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;} with_tclconfig=`echo ${with_tclconfig} | sed 's!/tclConfig\.sh$!!'` fi ;; esac if test -f "${with_tclconfig}/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` else { { echo "$as_me:$LINENO: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&5 echo "$as_me: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&2;} { (exit 1); exit 1; }; } fi fi # check in a few common install locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d ${TCLTK_ROOT}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i; pwd)` break fi done fi # then check for a private Tcl installation if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ../tcl \ `ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \ ../../tcl \ `ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \ ../../../tcl \ `ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ `ls -d /System/Library/Frameworks 2>/dev/null` \ ; do if test -f "$i/Tcl.framework/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi fi if test x"${ac_cv_c_tclconfig}" = x ; then TCL_BIN_DIR="# no Tcl configs found" { echo "$as_me:$LINENO: WARNING: \"Cannot find Tcl configuration definitions\"" >&5 echo "$as_me: WARNING: \"Cannot find Tcl configuration definitions\"" >&2;} exit 0 else no_tcl= TCL_BIN_DIR=${ac_cv_c_tclconfig} echo "$as_me:$LINENO: result: found $TCL_BIN_DIR/tclConfig.sh" >&5 echo "${ECHO_T}found $TCL_BIN_DIR/tclConfig.sh" >&6 fi fi echo "$as_me:$LINENO: checking for existence of $TCL_BIN_DIR/tclConfig.sh" >&5 echo $ECHO_N "checking for existence of $TCL_BIN_DIR/tclConfig.sh... $ECHO_C" >&6 if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then echo "$as_me:$LINENO: result: loading" >&5 echo "${ECHO_T}loading" >&6 . $TCL_BIN_DIR/tclConfig.sh else echo "$as_me:$LINENO: result: file not found" >&5 echo "${ECHO_T}file not found" >&6 fi # # If the TCL_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TCL_LIB_SPEC will be set to the value # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC # instead of TCL_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. # if test -f $TCL_BIN_DIR/Makefile ; then TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC} TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC} TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH} fi # # eval is required to do the TCL_DBGX substitution # eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\"" eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\"" #AC_SUBST(TCL_BUILD_LIB_SPEC) #AC_SUBST(TCL_BUILD_STUB_LIB_SPEC) #-------------------------------------------------------------------- # Load the tkConfig.sh file if necessary (Tk extension) #-------------------------------------------------------------------- # # Ok, lets find the tk configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tk # if test x"${no_tk}" = x ; then # we reset no_tk in case something fails here no_tk=true # Check whether --with-tk or --without-tk was given. if test "${with_tk+set}" = set; then withval="$with_tk" with_tkconfig=${withval} fi; echo "$as_me:$LINENO: checking for Tk configuration" >&5 echo $ECHO_N "checking for Tk configuration... $ECHO_C" >&6 if test "${ac_cv_c_tkconfig+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # First check to see if --with-tkconfig was specified. if test x"${with_tkconfig}" != x ; then case ${with_tkconfig} in */tkConfig.sh ) if test -f ${with_tkconfig}; then { echo "$as_me:$LINENO: WARNING: --with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself" >&5 echo "$as_me: WARNING: --with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself" >&2;} with_tkconfig=`echo ${with_tkconfig} | sed 's!/tkConfig\.sh$!!'` fi ;; esac if test -f "${with_tkconfig}/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)` else { { echo "$as_me:$LINENO: error: ${with_tkconfig} directory doesn't contain tkConfig.sh" >&5 echo "$as_me: error: ${with_tkconfig} directory doesn't contain tkConfig.sh" >&2;} { (exit 1); exit 1; }; } fi fi # check in a few common install locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d ${TCLTK_ROOT}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ ; do if test -f "$i/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i; pwd)` break fi done fi # then check for a private Tk library if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ../tk \ `ls -dr ../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../tk[8-9].[0-9] 2>/dev/null` \ `ls -dr ../tk[8-9].[0-9]* 2>/dev/null` \ ../../tk \ `ls -dr ../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../tk[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../tk[8-9].[0-9]* 2>/dev/null` \ ../../../tk \ `ls -dr ../../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../../tk[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../../tk[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/unix; pwd)` break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ `ls -d /System/Library/Frameworks 2>/dev/null` \ ; do if test -f "$i/Tk.framework/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/Tk.framework; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ${srcdir}/../tk \ `ls -dr ${srcdir}/../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ${srcdir}/../tk[8-9].[0-9] 2>/dev/null` \ `ls -dr ${srcdir}/../tk[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/unix; pwd)` break fi done fi fi if test x"${ac_cv_c_tkconfig}" = x ; then TK_BIN_DIR="# no Tk configs found" { echo "$as_me:$LINENO: WARNING: \"Cannot find Tk configuration definitions\"" >&5 echo "$as_me: WARNING: \"Cannot find Tk configuration definitions\"" >&2;} exit 0 else no_tk= TK_BIN_DIR=${ac_cv_c_tkconfig} echo "$as_me:$LINENO: result: found $TK_BIN_DIR/tkConfig.sh" >&5 echo "${ECHO_T}found $TK_BIN_DIR/tkConfig.sh" >&6 fi fi echo "$as_me:$LINENO: checking for existence of ${TK_BIN_DIR}/tkConfig.sh" >&5 echo $ECHO_N "checking for existence of ${TK_BIN_DIR}/tkConfig.sh... $ECHO_C" >&6 if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then echo "$as_me:$LINENO: result: loading" >&5 echo "${ECHO_T}loading" >&6 . $TK_BIN_DIR/tkConfig.sh else echo "$as_me:$LINENO: result: could not find ${TK_BIN_DIR}/tkConfig.sh" >&5 echo "${ECHO_T}could not find ${TK_BIN_DIR}/tkConfig.sh" >&6 fi # # If the TK_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TK_LIB_SPEC will be set to the value # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC # instead of TK_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. # if test -f $TK_BIN_DIR/Makefile ; then TK_LIB_SPEC=${TK_BUILD_LIB_SPEC} TK_STUB_LIB_SPEC=${TK_BUILD_STUB_LIB_SPEC} TK_STUB_LIB_PATH=${TK_BUILD_STUB_LIB_PATH} fi # Ensure windowingsystem is defined if test "${TEA_PLATFORM}" = "unix" ; then case ${TK_DEFS} in *MAC_OSX_TK*) cat >>confdefs.h <<\_ACEOF #define MAC_OSX_TK 1 _ACEOF TEA_WINDOWINGSYSTEM="aqua" ;; *) TEA_WINDOWINGSYSTEM="x11" ;; esac elif test "${TEA_PLATFORM}" = "windows" ; then TEA_WINDOWINGSYSTEM="win32" fi # # eval is required to do the TK_DBGX substitution # eval "TK_LIB_FILE=\"${TK_LIB_FILE}\"" eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\"" eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\"" eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\"" eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\"" eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\"" #----------------------------------------------------------------------- # Handle the --prefix=... option by defaulting to what Tcl gave. # Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER. #----------------------------------------------------------------------- if test "${prefix}" = "NONE"; then prefix_default=yes if test x"${TCL_PREFIX}" != x; then { echo "$as_me:$LINENO: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&5 echo "$as_me: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&6;} prefix=${TCL_PREFIX} else { echo "$as_me:$LINENO: --prefix defaulting to /usr/local" >&5 echo "$as_me: --prefix defaulting to /usr/local" >&6;} prefix=/usr/local fi fi if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \ -o x"${exec_prefix_default}" = x"yes" ; then #if test x"${TCL_EXEC_PREFIX}" != x; then #AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}]) #exec_prefix=${TCL_EXEC_PREFIX} #else { echo "$as_me:$LINENO: --exec-prefix defaulting to ${prefix}" >&5 echo "$as_me: --exec-prefix defaulting to ${prefix}" >&6;} exec_prefix=$prefix #fi fi #----------------------------------------------------------------------- # Standard compiler checks. # This sets up CC by using the CC env var, or looks for gcc otherwise. # This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create # the basic setup necessary to compile executables. #----------------------------------------------------------------------- ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f $ac_dir/shtool; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} { (exit 1); exit 1; }; } fi ac_config_guess="$SHELL $ac_aux_dir/config.guess" ac_config_sub="$SHELL $ac_aux_dir/config.sub" ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE) # in this macro, they need to go into TEA_SETUP_COMPILER instead. # If the user did not set CFLAGS, set it now to keep # the AC_PROG_CC macro from adding "-g -O2". if test "${CFLAGS+set}" != "set" ; then CFLAGS="" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CC" && break done CC=$ac_ct_CC fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 (eval $ac_link_default) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Find the output, starting from the most likely. This scheme is # not robust to junk in `.', hence go to wildcards (a.*) only as a last # resort. # Be careful to initialize this variable, since it used to be cached. # Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. ac_cv_exeext= # b.out is created by i960 compilers. for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; conftest.$ac_ext ) # This is the source file. ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` # FIXME: I believe we export ac_cv_exeext for Libtool, # but it would be cool to find out if it's true. Does anybody # maintain Libtool? --akim. export ac_cv_exeext break;; * ) break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6 # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6 echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` export ac_cv_exeext break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6 rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6 OBJEXT=$ac_cv_objext ac_objext=$OBJEXT echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS CFLAGS="-g" echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cc_g=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 if test "${ac_cv_prog_cc_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_stdc=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std1 is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std1. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX 10.20 and later -Ae # HP-UX older versions -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_stdc=$ac_arg break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext done rm -f conftest.$ac_ext conftest.$ac_objext CC=$ac_save_CC fi case "x$ac_cv_prog_cc_stdc" in x|xno) echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6 ;; *) echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 CC="$CC $ac_cv_prog_cc_stdc" ;; esac # Some people use a C++ compiler to compile C. Since we use `exit', # in C++ we need to declare it. In case someone uses the same compiler # for both compiling C and C++ we need to have the C++ compiler decide # the declaration of exit, since it's the most demanding environment. cat >conftest.$ac_ext <<_ACEOF #ifndef __cplusplus choke me #endif _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration #include int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_cv_c_compiler_gnu = yes; then GCC=yes fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6 ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=cc ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -n "$ac_tool_prefix"; then for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then echo "$as_me:$LINENO: result: $CXX" >&5 echo "${ECHO_T}$CXX" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 echo "${ECHO_T}$ac_ct_CXX" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CXX" && break done test -n "$ac_ct_CXX" || ac_ct_CXX="g++" CXX=$ac_ct_CXX fi # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C++ compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 if test "${ac_cv_cxx_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 GXX=`test $ac_compiler_gnu = yes && echo yes` ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS CXXFLAGS="-g" echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cxx_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cxx_g=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi for ac_declaration in \ '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration #include int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL=$ac_install_sh fi fi echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' #-------------------------------------------------------------------- # Checks to see if the make program sets the $MAKE variable. #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.make <<\_ACEOF all: @echo 'ac_maketemp="$(MAKE)"' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi rm -f conftest.make fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 SET_MAKE= else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 SET_MAKE="MAKE=${MAKE-make}" fi #-------------------------------------------------------------------- # Find ranlib #-------------------------------------------------------------------- if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then echo "$as_me:$LINENO: result: $RANLIB" >&5 echo "${ECHO_T}$RANLIB" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 echo "${ECHO_T}$ac_ct_RANLIB" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi RANLIB=$ac_ct_RANLIB else RANLIB="$ac_cv_prog_RANLIB" fi #-------------------------------------------------------------------- # Determines the correct binary file extension (.o, .obj, .exe etc.) #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6 if test "${ac_cv_prog_egrep+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | (grep -E '(a|b)') >/dev/null 2>&1 then ac_cv_prog_egrep='grep -E' else ac_cv_prog_egrep='egrep' fi fi echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 echo "${ECHO_T}$ac_cv_prog_egrep" >&6 EGREP=$ac_cv_prog_egrep echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6 if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here. #------------------------------------------------------------------------ # If we're using GCC, see if the compiler understands -pipe. If so, use it. # It makes compiling go faster. (This is only a performance feature.) #------------------------------------------------------------------------ if test -z "$no_pipe" -a -n "$GCC"; then echo "$as_me:$LINENO: checking if the compiler understands -pipe" >&5 echo $ECHO_N "checking if the compiler understands -pipe... $ECHO_C" >&6 OLDCC="$CC" CC="$CC -pipe" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CC="$OLDCC" echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi #-------------------------------------------------------------------- # Pick up flags from the environment (user). #-------------------------------------------------------------------- CC="${CC} $CFLAGS" CXX="${CXX} $CXXFLAGS $CFLAGS" #-------------------------------------------------------------------- # Common compiler flag setup #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6 if test "${ac_cv_c_bigendian+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # See if sys/param.h defines the BYTE_ORDER macro. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN bogus endian macros #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then # It does; now see whether it defined to BIG_ENDIAN or not. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_bigendian=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_bigendian=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # It does not; compile a test program. if test "$cross_compiling" = yes; then # try to guess the endianness by grepping values into an object file ac_cv_c_bigendian=unknown cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } int main () { _ascii (); _ebcdic (); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long l; char c[sizeof (long)]; } u; u.l = 1; exit (u.c[sizeof (long) - 1] == 1); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_bigendian=no else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_c_bigendian=yes fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 echo "${ECHO_T}$ac_cv_c_bigendian" >&6 case $ac_cv_c_bigendian in yes) cat >>confdefs.h <<\_ACEOF #define WORDS_BIGENDIAN 1 _ACEOF ;; no) ;; *) { { echo "$as_me:$LINENO: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&5 echo "$as_me: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} { (exit 1); exit 1; }; } ;; esac if test "${TEA_PLATFORM}" = "unix" ; then #-------------------------------------------------------------------- # On a few very rare systems, all of the libm.a stuff is # already in libc.a. Set compiler flags accordingly. # Also, Linux requires the "ieee" library for math to work # right (and it must appear before "-lm"). #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking for sin" >&5 echo $ECHO_N "checking for sin... $ECHO_C" >&6 if test "${ac_cv_func_sin+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define sin to an innocuous variant, in case declares sin. For example, HP-UX 11i declares gettimeofday. */ #define sin innocuous_sin /* System header to define __stub macros and hopefully few prototypes, which can conflict with char sin (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef sin /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char sin (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_sin) || defined (__stub___sin) choke me #else char (*f) () = sin; #endif #ifdef __cplusplus } #endif int main () { return f != sin; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_sin=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_sin=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_sin" >&5 echo "${ECHO_T}$ac_cv_func_sin" >&6 if test $ac_cv_func_sin = yes; then MATH_LIBS="" else MATH_LIBS="-lm" fi echo "$as_me:$LINENO: checking for main in -lieee" >&5 echo $ECHO_N "checking for main in -lieee... $ECHO_C" >&6 if test "${ac_cv_lib_ieee_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lieee $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_ieee_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ieee_main=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_ieee_main" >&5 echo "${ECHO_T}$ac_cv_lib_ieee_main" >&6 if test $ac_cv_lib_ieee_main = yes; then MATH_LIBS="-lieee $MATH_LIBS" fi #-------------------------------------------------------------------- # Interactive UNIX requires -linet instead of -lsocket, plus it # needs net/errno.h to define the socket-related error codes. #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking for main in -linet" >&5 echo $ECHO_N "checking for main in -linet... $ECHO_C" >&6 if test "${ac_cv_lib_inet_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-linet $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_inet_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_inet_main=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_inet_main" >&5 echo "${ECHO_T}$ac_cv_lib_inet_main" >&6 if test $ac_cv_lib_inet_main = yes; then LIBS="$LIBS -linet" fi if test "${ac_cv_header_net_errno_h+set}" = set; then echo "$as_me:$LINENO: checking for net/errno.h" >&5 echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6 if test "${ac_cv_header_net_errno_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5 echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking net/errno.h usability" >&5 echo $ECHO_N "checking net/errno.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking net/errno.h presence" >&5 echo $ECHO_N "checking net/errno.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: net/errno.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: net/errno.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: net/errno.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: net/errno.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: net/errno.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: net/errno.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: net/errno.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: net/errno.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the rtd lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for net/errno.h" >&5 echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6 if test "${ac_cv_header_net_errno_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_net_errno_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5 echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6 fi if test $ac_cv_header_net_errno_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_NET_ERRNO_H 1 _ACEOF fi #-------------------------------------------------------------------- # Check for the existence of the -lsocket and -lnsl libraries. # The order here is important, so that they end up in the right # order in the command line generated by make. Here are some # special considerations: # 1. Use "connect" and "accept" to check for -lsocket, and # "gethostbyname" to check for -lnsl. # 2. Use each function name only once: can't redo a check because # autoconf caches the results of the last check and won't redo it. # 3. Use -lnsl and -lsocket only if they supply procedures that # aren't already present in the normal libraries. This is because # IRIX 5.2 has libraries, but they aren't needed and they're # bogus: they goof up name resolution if used. # 4. On some SVR4 systems, can't use -lsocket without -lnsl too. # To get around this problem, check for both libraries together # if -lsocket doesn't work by itself. #-------------------------------------------------------------------- tcl_checkBoth=0 echo "$as_me:$LINENO: checking for connect" >&5 echo $ECHO_N "checking for connect... $ECHO_C" >&6 if test "${ac_cv_func_connect+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define connect to an innocuous variant, in case declares connect. For example, HP-UX 11i declares gettimeofday. */ #define connect innocuous_connect /* System header to define __stub macros and hopefully few prototypes, which can conflict with char connect (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef connect /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char connect (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_connect) || defined (__stub___connect) choke me #else char (*f) () = connect; #endif #ifdef __cplusplus } #endif int main () { return f != connect; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_connect=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_connect=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5 echo "${ECHO_T}$ac_cv_func_connect" >&6 if test $ac_cv_func_connect = yes; then tcl_checkSocket=0 else tcl_checkSocket=1 fi if test "$tcl_checkSocket" = 1; then echo "$as_me:$LINENO: checking for setsockopt" >&5 echo $ECHO_N "checking for setsockopt... $ECHO_C" >&6 if test "${ac_cv_func_setsockopt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define setsockopt to an innocuous variant, in case declares setsockopt. For example, HP-UX 11i declares gettimeofday. */ #define setsockopt innocuous_setsockopt /* System header to define __stub macros and hopefully few prototypes, which can conflict with char setsockopt (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef setsockopt /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char setsockopt (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_setsockopt) || defined (__stub___setsockopt) choke me #else char (*f) () = setsockopt; #endif #ifdef __cplusplus } #endif int main () { return f != setsockopt; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_setsockopt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_setsockopt=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_setsockopt" >&5 echo "${ECHO_T}$ac_cv_func_setsockopt" >&6 if test $ac_cv_func_setsockopt = yes; then : else echo "$as_me:$LINENO: checking for setsockopt in -lsocket" >&5 echo $ECHO_N "checking for setsockopt in -lsocket... $ECHO_C" >&6 if test "${ac_cv_lib_socket_setsockopt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char setsockopt (); int main () { setsockopt (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_socket_setsockopt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_socket_setsockopt=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_socket_setsockopt" >&5 echo "${ECHO_T}$ac_cv_lib_socket_setsockopt" >&6 if test $ac_cv_lib_socket_setsockopt = yes; then LIBS="$LIBS -lsocket" else tcl_checkBoth=1 fi fi fi if test "$tcl_checkBoth" = 1; then tk_oldLibs=$LIBS LIBS="$LIBS -lsocket -lnsl" echo "$as_me:$LINENO: checking for accept" >&5 echo $ECHO_N "checking for accept... $ECHO_C" >&6 if test "${ac_cv_func_accept+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define accept to an innocuous variant, in case declares accept. For example, HP-UX 11i declares gettimeofday. */ #define accept innocuous_accept /* System header to define __stub macros and hopefully few prototypes, which can conflict with char accept (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef accept /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char accept (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_accept) || defined (__stub___accept) choke me #else char (*f) () = accept; #endif #ifdef __cplusplus } #endif int main () { return f != accept; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_accept=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_accept=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_accept" >&5 echo "${ECHO_T}$ac_cv_func_accept" >&6 if test $ac_cv_func_accept = yes; then tcl_checkNsl=0 else LIBS=$tk_oldLibs fi fi echo "$as_me:$LINENO: checking for gethostbyname" >&5 echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6 if test "${ac_cv_func_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define gethostbyname to an innocuous variant, in case declares gethostbyname. For example, HP-UX 11i declares gettimeofday. */ #define gethostbyname innocuous_gethostbyname /* System header to define __stub macros and hopefully few prototypes, which can conflict with char gethostbyname (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef gethostbyname /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostbyname (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) choke me #else char (*f) () = gethostbyname; #endif #ifdef __cplusplus } #endif int main () { return f != gethostbyname; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_gethostbyname=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_gethostbyname=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6 if test $ac_cv_func_gethostbyname = yes; then : else echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5 echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6 if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostbyname (); int main () { gethostbyname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_nsl_gethostbyname=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_nsl_gethostbyname=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6 if test $ac_cv_lib_nsl_gethostbyname = yes; then LIBS="$LIBS -lnsl" fi fi # Don't perform the eval of the libraries here because DL_LIBS # won't be set until we call TEA_CONFIG_CFLAGS TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}' echo "$as_me:$LINENO: checking dirent.h" >&5 echo $ECHO_N "checking dirent.h... $ECHO_C" >&6 if test "${tcl_cv_dirent_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #ifndef _POSIX_SOURCE # ifdef __Lynx__ /* * Generate compilation error to make the test fail: Lynx headers * are only valid if really in the POSIX environment. */ missing_procedure(); # endif #endif DIR *d; struct dirent *entryPtr; char *p; d = opendir("foobar"); entryPtr = readdir(d); p = entryPtr->d_name; closedir(d); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_dirent_h=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_dirent_h=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi if test $tcl_cv_dirent_h = no; then cat >>confdefs.h <<\_ACEOF #define NO_DIRENT_H 1 _ACEOF fi echo "$as_me:$LINENO: result: $tcl_ok" >&5 echo "${ECHO_T}$tcl_ok" >&6 if test "${ac_cv_header_errno_h+set}" = set; then echo "$as_me:$LINENO: checking for errno.h" >&5 echo $ECHO_N "checking for errno.h... $ECHO_C" >&6 if test "${ac_cv_header_errno_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5 echo "${ECHO_T}$ac_cv_header_errno_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking errno.h usability" >&5 echo $ECHO_N "checking errno.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking errno.h presence" >&5 echo $ECHO_N "checking errno.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: errno.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: errno.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: errno.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: errno.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: errno.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: errno.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: errno.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: errno.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the rtd lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for errno.h" >&5 echo $ECHO_N "checking for errno.h... $ECHO_C" >&6 if test "${ac_cv_header_errno_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_errno_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5 echo "${ECHO_T}$ac_cv_header_errno_h" >&6 fi if test $ac_cv_header_errno_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_ERRNO_H 1 _ACEOF fi if test "${ac_cv_header_float_h+set}" = set; then echo "$as_me:$LINENO: checking for float.h" >&5 echo $ECHO_N "checking for float.h... $ECHO_C" >&6 if test "${ac_cv_header_float_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5 echo "${ECHO_T}$ac_cv_header_float_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking float.h usability" >&5 echo $ECHO_N "checking float.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking float.h presence" >&5 echo $ECHO_N "checking float.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: float.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: float.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: float.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: float.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: float.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: float.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: float.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: float.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the rtd lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for float.h" >&5 echo $ECHO_N "checking for float.h... $ECHO_C" >&6 if test "${ac_cv_header_float_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_float_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5 echo "${ECHO_T}$ac_cv_header_float_h" >&6 fi if test $ac_cv_header_float_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_FLOAT_H 1 _ACEOF fi if test "${ac_cv_header_values_h+set}" = set; then echo "$as_me:$LINENO: checking for values.h" >&5 echo $ECHO_N "checking for values.h... $ECHO_C" >&6 if test "${ac_cv_header_values_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5 echo "${ECHO_T}$ac_cv_header_values_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking values.h usability" >&5 echo $ECHO_N "checking values.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking values.h presence" >&5 echo $ECHO_N "checking values.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: values.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: values.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: values.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: values.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: values.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: values.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: values.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: values.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the rtd lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for values.h" >&5 echo $ECHO_N "checking for values.h... $ECHO_C" >&6 if test "${ac_cv_header_values_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_values_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5 echo "${ECHO_T}$ac_cv_header_values_h" >&6 fi if test $ac_cv_header_values_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_VALUES_H 1 _ACEOF fi if test "${ac_cv_header_limits_h+set}" = set; then echo "$as_me:$LINENO: checking for limits.h" >&5 echo $ECHO_N "checking for limits.h... $ECHO_C" >&6 if test "${ac_cv_header_limits_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5 echo "${ECHO_T}$ac_cv_header_limits_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking limits.h usability" >&5 echo $ECHO_N "checking limits.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking limits.h presence" >&5 echo $ECHO_N "checking limits.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: limits.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: limits.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: limits.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: limits.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: limits.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: limits.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: limits.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: limits.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the rtd lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for limits.h" >&5 echo $ECHO_N "checking for limits.h... $ECHO_C" >&6 if test "${ac_cv_header_limits_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_limits_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5 echo "${ECHO_T}$ac_cv_header_limits_h" >&6 fi if test $ac_cv_header_limits_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIMITS_H 1 _ACEOF else cat >>confdefs.h <<\_ACEOF #define NO_LIMITS_H 1 _ACEOF fi if test "${ac_cv_header_stdlib_h+set}" = set; then echo "$as_me:$LINENO: checking for stdlib.h" >&5 echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6 if test "${ac_cv_header_stdlib_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5 echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking stdlib.h usability" >&5 echo $ECHO_N "checking stdlib.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking stdlib.h presence" >&5 echo $ECHO_N "checking stdlib.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: stdlib.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: stdlib.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: stdlib.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: stdlib.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: stdlib.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: stdlib.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: stdlib.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: stdlib.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the rtd lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for stdlib.h" >&5 echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6 if test "${ac_cv_header_stdlib_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_stdlib_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5 echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6 fi if test $ac_cv_header_stdlib_h = yes; then tcl_ok=1 else tcl_ok=0 fi cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strtol" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strtoul" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strtod" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* if test $tcl_ok = 0; then cat >>confdefs.h <<\_ACEOF #define NO_STDLIB_H 1 _ACEOF fi if test "${ac_cv_header_string_h+set}" = set; then echo "$as_me:$LINENO: checking for string.h" >&5 echo $ECHO_N "checking for string.h... $ECHO_C" >&6 if test "${ac_cv_header_string_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5 echo "${ECHO_T}$ac_cv_header_string_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking string.h usability" >&5 echo $ECHO_N "checking string.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking string.h presence" >&5 echo $ECHO_N "checking string.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: string.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: string.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: string.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: string.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: string.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: string.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: string.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: string.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the rtd lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for string.h" >&5 echo $ECHO_N "checking for string.h... $ECHO_C" >&6 if test "${ac_cv_header_string_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_string_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5 echo "${ECHO_T}$ac_cv_header_string_h" >&6 fi if test $ac_cv_header_string_h = yes; then tcl_ok=1 else tcl_ok=0 fi cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strstr" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strerror" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* # See also memmove check below for a place where NO_STRING_H can be # set and why. if test $tcl_ok = 0; then cat >>confdefs.h <<\_ACEOF #define NO_STRING_H 1 _ACEOF fi if test "${ac_cv_header_sys_wait_h+set}" = set; then echo "$as_me:$LINENO: checking for sys/wait.h" >&5 echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6 if test "${ac_cv_header_sys_wait_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking sys/wait.h usability" >&5 echo $ECHO_N "checking sys/wait.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking sys/wait.h presence" >&5 echo $ECHO_N "checking sys/wait.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: sys/wait.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: sys/wait.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: sys/wait.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: sys/wait.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: sys/wait.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: sys/wait.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the rtd lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for sys/wait.h" >&5 echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6 if test "${ac_cv_header_sys_wait_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_sys_wait_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 fi if test $ac_cv_header_sys_wait_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_SYS_WAIT_H 1 _ACEOF fi if test "${ac_cv_header_dlfcn_h+set}" = set; then echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking dlfcn.h usability" >&5 echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking dlfcn.h presence" >&5 echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: dlfcn.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the rtd lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_dlfcn_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 fi if test $ac_cv_header_dlfcn_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_DLFCN_H 1 _ACEOF fi # OS/390 lacks sys/param.h (and doesn't need it, by chance). for ac_header in sys/param.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the rtd lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Let the user call this, because if it triggers, they will # need a compat/strtod.c that is correct. Users can also # use Tcl_GetDouble(FromObj) instead. #TEA_BUGGY_STRTOD fi #-------------------------------------------------------------------- # Do application specific checks (see aclocal.m4) #-------------------------------------------------------------------- # ----------------------------------------------------------------------- # Load the Tclutil definitions cf=../tclutil/tclutilConfig.sh if test -f $cf ; then . $cf else { { echo "$as_me:$LINENO: error: $cf doesn't exist" >&5 echo "$as_me: error: $cf doesn't exist" >&2;} { (exit 1); exit 1; }; } fi # Load the Astrotcl definitions cf=../astrotcl/astrotclConfig.sh if test -f $cf ; then . $cf else { { echo "$as_me:$LINENO: error: $cf doesn't exist" >&5 echo "$as_me: error: $cf doesn't exist" >&2;} { (exit 1); exit 1; }; } fi # ----------------------------------------------------------------------- # Optionally merge object and header files from dependent packages to make one master rtd lib MERGED=1 # Check whether --enable-merge or --disable-merge was given. if test "${enable_merge+set}" = set; then enableval="$enable_merge" MERGED=$enableval else MERGED=no fi; tclsources=`cd $srcdir; echo library/*.tcl` csources=`cd $srcdir; echo generic/*.[Cc] rtdevt/rtdImageEvent.c rtdevt/rtdSem.c` rtd_headers=`cd $srcdir; echo generic/*.h generic/*.icc rtdevt/rtdImageEvent.h rtdevt/rtdSem.h` astrotcl_headers=`cd $srcdir; echo ../astrotcl/{generic,press,libwcs,cfitsio}/*.h` tclutil_headers=`cd $srcdir; echo ../tclutil/generic/*.h` rtd_includes="-I$srcdir/generic -I$srcdir/rtdevt -I$srcdir/bitmaps" astrotcl_includes="-I$srcdir/../astrotcl/generic -I$srcdir/../astrotcl/cfitsio -I$srcdir/../astrotcl/libwcs" tclutil_includes="-I$srcdir/../tclutil/generic" cincludes="${rtd_includes} ${astrotcl_includes} ${tclutil_includes}" if test $MERGED = yes ; then echo "Will build merged master rtd library" cheaders="${rtd_headers} ${astrotcl_headers} ${tclutil_headers}" MERGE_OBJECTS="$astrotcl_PKG_OBJECTS $tclutil_PKG_OBJECTS" else echo "Not making a merged master rtd library" cheaders="${rtd_headers}" MERGE_OBJECTS="" fi # ----------------------------------------------------------------------- cat >>confdefs.h <<\_ACEOF #define USE_COMPAT_CONST 1 _ACEOF # ----------------------------------------------------------------------- echo "$as_me:$LINENO: checking sysv shared memory prototypes" >&5 echo $ECHO_N "checking sysv shared memory prototypes... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "int.*shmdt.*\(" >/dev/null 2>&1; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; cat >>confdefs.h <<\_ACEOF #define NEED_SHM_PROTO 1 _ACEOF fi rm -f conftest* # ----------------------------------------------------------------------- echo "$as_me:$LINENO: checking gethostname prototype" >&5 echo $ECHO_N "checking gethostname prototype... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "int.*gethostname.*\(" >/dev/null 2>&1; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; cat >>confdefs.h <<\_ACEOF #define NEED_GETHOSTNAME_PROTO 1 _ACEOF fi rm -f conftest* # ----------------------------------------------------------------------- echo "$as_me:$LINENO: checking for long" >&5 echo $ECHO_N "checking for long... $ECHO_C" >&6 if test "${ac_cv_type_long+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((long *) 0) return 0; if (sizeof (long)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_long=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_long=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5 echo "${ECHO_T}$ac_cv_type_long" >&6 echo "$as_me:$LINENO: checking size of long" >&5 echo $ECHO_N "checking size of long... $ECHO_C" >&6 if test "${ac_cv_sizeof_long+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$ac_cv_type_long" = yes; then # The cast to unsigned long works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(((long) (sizeof (long))) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_lo=0 ac_mid=0 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr $ac_mid + 1` if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid + 1` fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(((long) (sizeof (long))) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=-1 ac_mid=-1 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(((long) (sizeof (long))) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_lo=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_hi=`expr '(' $ac_mid ')' - 1` if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid` fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo= ac_hi= fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=$ac_mid else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr '(' $ac_mid ')' + 1` fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in ?*) ac_cv_sizeof_long=$ac_lo;; '') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77 See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (long), 77 See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } ;; esac else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling See \`config.log' for more details." >&5 echo "$as_me: error: cannot run test program while cross compiling See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default long longval () { return (long) (sizeof (long)); } unsigned long ulongval () { return (long) (sizeof (long)); } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) exit (1); if (((long) (sizeof (long))) < 0) { long i = longval (); if (i != ((long) (sizeof (long)))) exit (1); fprintf (f, "%ld\n", i); } else { unsigned long i = ulongval (); if (i != ((long) (sizeof (long)))) exit (1); fprintf (f, "%lu\n", i); } exit (ferror (f) || fclose (f) != 0); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_long=`cat conftest.val` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77 See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (long), 77 See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi rm -f conftest.val else ac_cv_sizeof_long=0 fi fi echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5 echo "${ECHO_T}$ac_cv_sizeof_long" >&6 cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG $ac_cv_sizeof_long _ACEOF # ----------------------------------------------------------------------- # there are some idiosyncrasies with semun defs (used in semxxx). Solaris # does not define it at all # ------------------------------------------------------------------------- echo "$as_me:$LINENO: checking \"do we have union semun defined\"" >&5 echo $ECHO_N "checking \"do we have union semun defined\"... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { union semun filler; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cat >>confdefs.h <<\_ACEOF #define HAVE_UNION_SEMUN 1 _ACEOF echo "$as_me:$LINENO: result: \"yes\"" >&5 echo "${ECHO_T}\"yes\"" >&6 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 echo "$as_me:$LINENO: result: \"no\"" >&5 echo "${ECHO_T}\"no\"" >&6 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >>confdefs.h <<\_ACEOF #define HAVE_NET_SERVICES 1 _ACEOF for ac_header in sys/filio.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the rtd lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Check if we need (or can use) the socklen_t type. echo "$as_me:$LINENO: checking for socklen_t" >&5 echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6 if test "${ac_cv_type_socklen_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { if ((socklen_t *) 0) return 0; if (sizeof (socklen_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_socklen_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_socklen_t=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_socklen_t" >&5 echo "${ECHO_T}$ac_cv_type_socklen_t" >&6 if test $ac_cv_type_socklen_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_SOCKLEN_T 1 _ACEOF fi #------------------------------------------------------------------------ ac_ext=cc ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu echo "$as_me:$LINENO: checking fd_set" >&5 echo $ECHO_N "checking fd_set... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { fd_set readFds; select(32, &readFds, 0, 0, 0); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then test_ok=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 test_ok=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext if test $test_ok = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_SELECT_FD_SET 1 _ACEOF fi echo "$as_me:$LINENO: result: $test_ok" >&5 echo "${ECHO_T}$test_ok" >&6 #------------------------------------------------------------------------ # Check if we require additional libraries to support C++ shareable # libraries. system=`uname -s`-`uname -r` SHLIB_LD_CXX_LIBS="" export SHLIB_LD_CXX_LIBS case $system in SunOS-5*) SHLIB_LD_CXX_LIBS="-lCrun -lCstd" ;; OSF*) SHLIB_LD_CXX_LIBS="-lcxx -lcxxstd" ;; esac #------------------------------------------------------------------------- # The cxx C++ compiler under Tru64 UNIX needs the special # CXXFLAGS "-std gnu -D__USE_STD_IOSTREAM=1". These allow the standard # library streams headers to work and to generate templates that do # not require special handling throughout skycat directories (normally # template object files are created in various cxx_repository subdirectories, # this way the object files are kept embedded the usual object files, see # the cxx man page for details). #------------------------------------------------------------------------- export CXXFLAGS case $system in OSF*) case "x$CXX" in xcxx*) CXXFLAGS="$CXXFLAGS -g3 -std gnu -D__USE_STD_IOSTREAM=1" ;; esac ;; esac #----------------------------------------------------------------------- # __CHANGE__ # Specify the C source files to compile in TEA_ADD_SOURCES, # public headers that need to be installed in TEA_ADD_HEADERS, # stub library C source files to compile in TEA_ADD_STUB_SOURCES, # and runtime Tcl library files in TEA_ADD_TCL_SOURCES. # This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS # and PKG_TCL_SOURCES. #----------------------------------------------------------------------- vars="${csources}" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done vars="${cheaders}" for i in $vars; do # check for existence, be strict because it is installed if test ! -f "${srcdir}/$i" ; then { { echo "$as_me:$LINENO: error: could not find header file '${srcdir}/$i'" >&5 echo "$as_me: error: could not find header file '${srcdir}/$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_HEADERS="$PKG_HEADERS $i" done vars="${cincludes}" for i in $vars; do PKG_INCLUDES="$PKG_INCLUDES $i" done if test $MERGED = yes ; then vars="${BLT_LIB_SPEC} ${CFITSIO_LIB_SPEC}" for i in $vars; do if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then # Convert foo.lib to -lfoo for GCC. No-op if not *.lib i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'` fi PKG_LIBS="$PKG_LIBS $i" done else vars="$astrotcl_BUILD_LIB_SPEC $tclutil_BUILD_LIB_SPEC ${BLT_LIB_SPEC} ${CFITSIO_LIB_SPEC}" for i in $vars; do if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then # Convert foo.lib to -lfoo for GCC. No-op if not *.lib i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'` fi PKG_LIBS="$PKG_LIBS $i" done fi PKG_CFLAGS="$PKG_CFLAGS " vars="" for i in $vars; do # check for existence - allows for generic/win/unix VPATH if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find stub source file '$i'" >&5 echo "$as_me: error: could not find stub source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j" done vars="${tclsources}" for i in $vars; do # check for existence, be strict because it is installed if test ! -f "${srcdir}/$i" ; then { { echo "$as_me:$LINENO: error: could not find tcl source file '${srcdir}/$i'" >&5 echo "$as_me: error: could not find tcl source file '${srcdir}/$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i" done #-------------------------------------------------------------------- # __CHANGE__ # A few miscellaneous platform-specific items: # # Define a special symbol for Windows (BUILD_sample in this case) so # that we create the export library with the dll. # # Windows creates a few extra files that need to be cleaned up. # You can add more files to clean if your extension creates any extra # files. # # TEA_ADD_* any platform specific compiler/build info here. #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" ; then cat >>confdefs.h <<\_ACEOF #define BUILD_rtd 1 _ACEOF CLEANFILES="*.lib *.dll *.exp *.ilk *.pdb vc*.pch" #TEA_ADD_SOURCES([win/winFile.c]) #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"]) else CLEANFILES="" #TEA_ADD_SOURCES([unix/unixFile.c]) #TEA_ADD_LIBS([-lsuperfly]) fi #------------------------------------------------------------------------ # See if we can include tkCanvas.h, an internal tk header file needed # to work around a problem with clipping canvas coordinates on large # images. #------------------------------------------------------------------------ if test -f $TK_SRC_DIR/generic/tkCanvas.h ; then cat >>confdefs.h <<\_ACEOF #define HAVE_TKCANVAS_H 1 _ACEOF vars="-I$TK_SRC_DIR/generic" for i in $vars; do PKG_INCLUDES="$PKG_INCLUDES $i" done fi #-------------------------------------------------------------------- # __CHANGE__ # Choose which headers you need. Extension authors should try very # hard to only rely on the Tcl public header files. Internal headers # contain private data structures and are subject to change without # notice. # This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking for Tcl public headers" >&5 echo $ECHO_N "checking for Tcl public headers... $ECHO_C" >&6 # Check whether --with-tclinclude or --without-tclinclude was given. if test "${with_tclinclude+set}" = set; then withval="$with_tclinclude" with_tclinclude=${withval} fi; if test "${ac_cv_c_tclh+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Use the value from --with-tclinclude, if it was given if test x"${with_tclinclude}" != x ; then if test -f "${with_tclinclude}/tcl.h" ; then ac_cv_c_tclh=${with_tclinclude} else { { echo "$as_me:$LINENO: error: ${with_tclinclude} directory does not contain tcl.h" >&5 echo "$as_me: error: ${with_tclinclude} directory does not contain tcl.h" >&2;} { (exit 1); exit 1; }; } fi else # If Tcl was built as a framework, attempt to use # the framework's Headers directory case ${TCL_DEFS} in *TCL_FRAMEWORK*) list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`" ;; *) list="" ;; esac # Look in the source dir only if Tcl is not installed, # and in that situation, look there before installed locations. if test -f "$TCL_BIN_DIR/Makefile" ; then list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`" fi # Check order: pkg --prefix location, Tcl's --prefix location, # relative to directory of tclConfig.sh. eval "temp_includedir=${includedir}" list="$list \ `ls -d ${temp_includedir} 2>/dev/null` \ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then list="$list /usr/local/include /usr/include" if test x"${TCL_INCLUDE_SPEC}" != x ; then d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'` list="$list `ls -d ${d} 2>/dev/null`" fi fi for i in $list ; do if test -f "$i/tcl.h" ; then ac_cv_c_tclh=$i break fi done fi fi # Print a message based on how we determined the include path if test x"${ac_cv_c_tclh}" = x ; then { { echo "$as_me:$LINENO: error: tcl.h not found. Please specify its location with --with-tclinclude" >&5 echo "$as_me: error: tcl.h not found. Please specify its location with --with-tclinclude" >&2;} { (exit 1); exit 1; }; } else echo "$as_me:$LINENO: result: ${ac_cv_c_tclh}" >&5 echo "${ECHO_T}${ac_cv_c_tclh}" >&6 fi # Convert to a native path and substitute into the output files. INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}` TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" #TEA_PRIVATE_TCL_HEADERS echo "$as_me:$LINENO: checking for Tk public headers" >&5 echo $ECHO_N "checking for Tk public headers... $ECHO_C" >&6 # Check whether --with-tkinclude or --without-tkinclude was given. if test "${with_tkinclude+set}" = set; then withval="$with_tkinclude" with_tkinclude=${withval} fi; if test "${ac_cv_c_tkh+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Use the value from --with-tkinclude, if it was given if test x"${with_tkinclude}" != x ; then if test -f "${with_tkinclude}/tk.h" ; then ac_cv_c_tkh=${with_tkinclude} else { { echo "$as_me:$LINENO: error: ${with_tkinclude} directory does not contain tk.h" >&5 echo "$as_me: error: ${with_tkinclude} directory does not contain tk.h" >&2;} { (exit 1); exit 1; }; } fi else # If Tk was built as a framework, attempt to use # the framework's Headers directory. case ${TK_DEFS} in *TK_FRAMEWORK*) list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`" ;; *) list="" ;; esac # Look in the source dir only if Tk is not installed, # and in that situation, look there before installed locations. if test -f "$TK_BIN_DIR/Makefile" ; then list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`" fi # Check order: pkg --prefix location, Tk's --prefix location, # relative to directory of tkConfig.sh, Tcl's --prefix location, # relative to directory of tclConfig.sh. eval "temp_includedir=${includedir}" list="$list \ `ls -d ${temp_includedir} 2>/dev/null` \ `ls -d ${TK_PREFIX}/include 2>/dev/null` \ `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then list="$list /usr/local/include /usr/include" fi for i in $list ; do if test -f "$i/tk.h" ; then ac_cv_c_tkh=$i break fi done fi fi # Print a message based on how we determined the include path if test x"${ac_cv_c_tkh}" = x ; then { { echo "$as_me:$LINENO: error: tk.h not found. Please specify its location with --with-tkinclude" >&5 echo "$as_me: error: tk.h not found. Please specify its location with --with-tkinclude" >&2;} { (exit 1); exit 1; }; } else echo "$as_me:$LINENO: result: ${ac_cv_c_tkh}" >&5 echo "${ECHO_T}${ac_cv_c_tkh}" >&6 fi # Convert to a native path and substitute into the output files. INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}` TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" if test "${TEA_WINDOWINGSYSTEM}" = "win32" \ -o "${TEA_WINDOWINGSYSTEM}" = "aqua"; then # On Windows and Aqua, we need the X compat headers echo "$as_me:$LINENO: checking for X11 header files" >&5 echo $ECHO_N "checking for X11 header files... $ECHO_C" >&6 if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`" TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" fi echo "$as_me:$LINENO: result: ${INCLUDE_DIR_NATIVE}" >&5 echo "${ECHO_T}${INCLUDE_DIR_NATIVE}" >&6 fi #TEA_PRIVATE_TK_HEADERS ac_ext=cc ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6 if test -z "$CXXCPP"; then if test "${ac_cv_prog_CXXCPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi echo "$as_me:$LINENO: result: $CXXCPP" >&5 echo "${ECHO_T}$CXXCPP" >&6 ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=cc ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then echo "$as_me:$LINENO: checking for X" >&5 echo $ECHO_N "checking for X... $ECHO_C" >&6 # Check whether --with-x or --without-x was given. if test "${with_x+set}" = set; then withval="$with_x" fi; # $have_x is `yes', `no', `disabled', or empty when we do not yet know. if test "x$with_x" = xno; then # The user explicitly disabled X. have_x=disabled else if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then # Both variables are already set. have_x=yes else if test "${ac_cv_have_x+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # One or both of the vars are not set, and there is no cached value. ac_x_includes=no ac_x_libraries=no rm -fr conftest.dir if mkdir conftest.dir; then cd conftest.dir # Make sure to not put "make" in the Imakefile rules, since we grep it out. cat >Imakefile <<'_ACEOF' acfindx: @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"' _ACEOF if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} acfindx 2>/dev/null | grep -v make` # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. for ac_extension in a so sl dylib la dll; do if test ! -f $ac_im_usrlibdir/libX11.$ac_extension && test -f $ac_im_libdir/libX11.$ac_extension; then ac_im_usrlibdir=$ac_im_libdir; break fi done # Screen out bogus values from the imake configuration. They are # bogus both because they are the default anyway, and because # using them would break gcc on systems where it needs fixed includes. case $ac_im_incroot in /usr/include) ;; *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; esac case $ac_im_usrlibdir in /usr/lib | /lib) ;; *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; esac fi cd .. rm -fr conftest.dir fi # Standard set of common directories for X headers. # Check X11 before X11Rn because it is often a symlink to the current release. ac_x_header_dirs=' /usr/X11/include /usr/X11R6/include /usr/X11R5/include /usr/X11R4/include /usr/include/X11 /usr/include/X11R6 /usr/include/X11R5 /usr/include/X11R4 /usr/local/X11/include /usr/local/X11R6/include /usr/local/X11R5/include /usr/local/X11R4/include /usr/local/include/X11 /usr/local/include/X11R6 /usr/local/include/X11R5 /usr/local/include/X11R4 /usr/X386/include /usr/x386/include /usr/XFree86/include/X11 /usr/include /usr/local/include /usr/unsupported/include /usr/athena/include /usr/local/x11r5/include /usr/lpp/Xamples/include /usr/openwin/include /usr/openwin/share/include' if test "$ac_x_includes" = no; then # Guess where to find include files, by looking for Intrinsic.h. # First, try using that file with no special directory specified. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # We can compile using X headers with no special include directory. ac_x_includes= else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 for ac_dir in $ac_x_header_dirs; do if test -r "$ac_dir/X11/Intrinsic.h"; then ac_x_includes=$ac_dir break fi done fi rm -f conftest.err conftest.$ac_ext fi # $ac_x_includes = no if test "$ac_x_libraries" = no; then # Check for the libraries. # See if we find them without any special options. # Don't add to $LIBS permanently. ac_save_LIBS=$LIBS LIBS="-lXt $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { XtMalloc (0) ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then LIBS=$ac_save_LIBS # We can link X programs with no special library path. ac_x_libraries= else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 LIBS=$ac_save_LIBS for ac_dir in `echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` do # Don't even attempt the hair of trying to link an X program! for ac_extension in a so sl dylib la dll; do if test -r $ac_dir/libXt.$ac_extension; then ac_x_libraries=$ac_dir break 2 fi done done fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi # $ac_x_libraries = no if test "$ac_x_includes" = no || test "$ac_x_libraries" = no; then # Didn't find X anywhere. Cache the known absence of X. ac_cv_have_x="have_x=no" else # Record where we found X for the cache. ac_cv_have_x="have_x=yes \ ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries" fi fi fi eval "$ac_cv_have_x" fi # $with_x != no if test "$have_x" != yes; then echo "$as_me:$LINENO: result: $have_x" >&5 echo "${ECHO_T}$have_x" >&6 no_x=yes else # If each of the values was on the command line, it overrides each guess. test "x$x_includes" = xNONE && x_includes=$ac_x_includes test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries # Update the cache value to reflect the command line values. ac_cv_have_x="have_x=yes \ ac_x_includes=$x_includes ac_x_libraries=$x_libraries" echo "$as_me:$LINENO: result: libraries $x_libraries, headers $x_includes" >&5 echo "${ECHO_T}libraries $x_libraries, headers $x_includes" >&6 fi not_really_there="" if test "$no_x" = ""; then if test "$x_includes" = ""; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 not_really_there="yes" fi rm -f conftest.err conftest.$ac_ext else if test ! -r $x_includes/X11/Intrinsic.h; then not_really_there="yes" fi fi fi if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then echo "$as_me:$LINENO: checking for X11 header files" >&5 echo $ECHO_N "checking for X11 header files... $ECHO_C" >&6 XINCLUDES="# no special path needed" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 XINCLUDES="nope" fi rm -f conftest.err conftest.$ac_ext if test "$XINCLUDES" = nope; then dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include" for i in $dirs ; do if test -r $i/X11/Intrinsic.h; then echo "$as_me:$LINENO: result: $i" >&5 echo "${ECHO_T}$i" >&6 XINCLUDES=" -I$i" break fi done fi else if test "$x_includes" != ""; then XINCLUDES=-I$x_includes else XINCLUDES="# no special path needed" fi fi if test "$XINCLUDES" = nope; then echo "$as_me:$LINENO: result: could not find any!" >&5 echo "${ECHO_T}could not find any!" >&6 XINCLUDES="# no include files found" fi if test "$no_x" = yes; then echo "$as_me:$LINENO: checking for X11 libraries" >&5 echo $ECHO_N "checking for X11 libraries... $ECHO_C" >&6 XLIBSW=nope dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib" for i in $dirs ; do if test -r $i/libX11.dylib -o -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl; then echo "$as_me:$LINENO: result: $i" >&5 echo "${ECHO_T}$i" >&6 XLIBSW="-L$i -lX11" x_libraries="$i" break fi done else if test "$x_libraries" = ""; then XLIBSW=-lX11 else XLIBSW="-L$x_libraries -lX11" fi fi if test "$XLIBSW" = nope ; then echo "$as_me:$LINENO: checking for XCreateWindow in -lXwindow" >&5 echo $ECHO_N "checking for XCreateWindow in -lXwindow... $ECHO_C" >&6 if test "${ac_cv_lib_Xwindow_XCreateWindow+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXwindow $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char XCreateWindow (); int main () { XCreateWindow (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_Xwindow_XCreateWindow=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xwindow_XCreateWindow=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_Xwindow_XCreateWindow" >&5 echo "${ECHO_T}$ac_cv_lib_Xwindow_XCreateWindow" >&6 if test $ac_cv_lib_Xwindow_XCreateWindow = yes; then XLIBSW=-lXwindow fi fi if test "$XLIBSW" = nope ; then echo "$as_me:$LINENO: result: could not find any! Using -lX11." >&5 echo "${ECHO_T}could not find any! Using -lX11." >&6 XLIBSW=-lX11 fi if test x"${XLIBSW}" != x ; then PKG_LIBS="${PKG_LIBS} ${XLIBSW}" fi fi #-------------------------------------------------------------------- # Check whether --enable-threads or --disable-threads was given. # This auto-enables if Tcl was compiled threaded. #-------------------------------------------------------------------- # Check whether --enable-threads or --disable-threads was given. if test "${enable_threads+set}" = set; then enableval="$enable_threads" tcl_ok=$enableval else tcl_ok=yes fi; if test "${enable_threads+set}" = set; then enableval="$enable_threads" tcl_ok=$enableval else tcl_ok=yes fi if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then TCL_THREADS=1 if test "${TEA_PLATFORM}" != "windows" ; then # We are always OK on Windows, so check what this platform wants. cat >>confdefs.h <<\_ACEOF #define USE_THREAD_ALLOC 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _REENTRANT 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _THREAD_SAFE 1 _ACEOF echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthread" >&5 echo $ECHO_N "checking for pthread_mutex_init in -lpthread... $ECHO_C" >&6 if test "${ac_cv_lib_pthread_pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_pthread_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthread_pthread_mutex_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_pthread_pthread_mutex_init" >&6 if test $ac_cv_lib_pthread_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "no"; then # Check a little harder for __pthread_mutex_init in the # same library, as some systems hide it there until # pthread.h is defined. We could alternatively do an # AC_TRY_COMPILE with pthread.h, but that will work with # libpthread really doesn't exist, like AIX 4.2. # [Bug: 4359] echo "$as_me:$LINENO: checking for __pthread_mutex_init in -lpthread" >&5 echo $ECHO_N "checking for __pthread_mutex_init in -lpthread... $ECHO_C" >&6 if test "${ac_cv_lib_pthread___pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char __pthread_mutex_init (); int main () { __pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_pthread___pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthread___pthread_mutex_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_pthread___pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_pthread___pthread_mutex_init" >&6 if test $ac_cv_lib_pthread___pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthread" else echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthreads" >&5 echo $ECHO_N "checking for pthread_mutex_init in -lpthreads... $ECHO_C" >&6 if test "${ac_cv_lib_pthreads_pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthreads $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_pthreads_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthreads_pthread_mutex_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_pthreads_pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_pthreads_pthread_mutex_init" >&6 if test $ac_cv_lib_pthreads_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthreads" else echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc" >&5 echo $ECHO_N "checking for pthread_mutex_init in -lc... $ECHO_C" >&6 if test "${ac_cv_lib_c_pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_c_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_c_pthread_mutex_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_c_pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_c_pthread_mutex_init" >&6 if test $ac_cv_lib_c_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "no"; then echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc_r" >&5 echo $ECHO_N "checking for pthread_mutex_init in -lc_r... $ECHO_C" >&6 if test "${ac_cv_lib_c_r_pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc_r $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_c_r_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_c_r_pthread_mutex_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_c_r_pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_c_r_pthread_mutex_init" >&6 if test $ac_cv_lib_c_r_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -pthread" else TCL_THREADS=0 { echo "$as_me:$LINENO: WARNING: \"Don t know how to find pthread lib on your system - thread support disabled\"" >&5 echo "$as_me: WARNING: \"Don t know how to find pthread lib on your system - thread support disabled\"" >&2;} fi fi fi fi fi else TCL_THREADS=0 fi # Do checking message here to not mess up interleaved configure output echo "$as_me:$LINENO: checking for building with threads" >&5 echo $ECHO_N "checking for building with threads... $ECHO_C" >&6 if test "${TCL_THREADS}" = "1"; then cat >>confdefs.h <<\_ACEOF #define TCL_THREADS 1 _ACEOF #LIBS="$LIBS $THREADS_LIBS" echo "$as_me:$LINENO: result: yes (default)" >&5 echo "${ECHO_T}yes (default)" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi # TCL_THREADS sanity checking. See if our request for building with # threads is the same as the way Tcl was built. If not, warn the user. case ${TCL_DEFS} in *THREADS=1*) if test "${TCL_THREADS}" = "0"; then { echo "$as_me:$LINENO: WARNING: Building ${PACKAGE_NAME} without threads enabled, but building against Tcl that IS thread-enabled. It is recommended to use --enable-threads." >&5 echo "$as_me: WARNING: Building ${PACKAGE_NAME} without threads enabled, but building against Tcl that IS thread-enabled. It is recommended to use --enable-threads." >&2;} fi ;; *) if test "${TCL_THREADS}" = "1"; then { echo "$as_me:$LINENO: WARNING: --enable-threads requested, but building against a Tcl that is NOT thread-enabled. This is an OK configuration that will also run in a thread-enabled core." >&5 echo "$as_me: WARNING: --enable-threads requested, but building against a Tcl that is NOT thread-enabled. This is an OK configuration that will also run in a thread-enabled core." >&2;} fi ;; esac #-------------------------------------------------------------------- # The statement below defines a collection of symbols related to # building as a shared library instead of a static library. #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking how to build libraries" >&5 echo $ECHO_N "checking how to build libraries... $ECHO_C" >&6 # Check whether --enable-shared or --disable-shared was given. if test "${enable_shared+set}" = set; then enableval="$enable_shared" tcl_ok=$enableval else tcl_ok=yes fi; if test "${enable_shared+set}" = set; then enableval="$enable_shared" tcl_ok=$enableval else tcl_ok=yes fi if test "$tcl_ok" = "yes" ; then echo "$as_me:$LINENO: result: shared" >&5 echo "${ECHO_T}shared" >&6 SHARED_BUILD=1 else echo "$as_me:$LINENO: result: static" >&5 echo "${ECHO_T}static" >&6 SHARED_BUILD=0 cat >>confdefs.h <<\_ACEOF #define STATIC_BUILD 1 _ACEOF fi #-------------------------------------------------------------------- # This macro figures out what flags to use with the compiler/linker # when building shared/static debug/optimized objects. This information # can be taken from the tclConfig.sh file, but this figures it all out. #-------------------------------------------------------------------- # Step 0: Enable 64 bit support? echo "$as_me:$LINENO: checking if 64bit support is enabled" >&5 echo $ECHO_N "checking if 64bit support is enabled... $ECHO_C" >&6 # Check whether --enable-64bit or --disable-64bit was given. if test "${enable_64bit+set}" = set; then enableval="$enable_64bit" do64bit=$enableval else do64bit=no fi; echo "$as_me:$LINENO: result: $do64bit" >&5 echo "${ECHO_T}$do64bit" >&6 # Step 0.b: Enable Solaris 64 bit VIS support? echo "$as_me:$LINENO: checking if 64bit Sparc VIS support is requested" >&5 echo $ECHO_N "checking if 64bit Sparc VIS support is requested... $ECHO_C" >&6 # Check whether --enable-64bit-vis or --disable-64bit-vis was given. if test "${enable_64bit_vis+set}" = set; then enableval="$enable_64bit_vis" do64bitVIS=$enableval else do64bitVIS=no fi; echo "$as_me:$LINENO: result: $do64bitVIS" >&5 echo "${ECHO_T}$do64bitVIS" >&6 if test "$do64bitVIS" = "yes"; then # Force 64bit on with VIS do64bit=yes fi # Step 0.c: Cross-compiling options for Windows/CE builds? if test "${TEA_PLATFORM}" = "windows" ; then echo "$as_me:$LINENO: checking if Windows/CE build is requested" >&5 echo $ECHO_N "checking if Windows/CE build is requested... $ECHO_C" >&6 # Check whether --enable-wince or --disable-wince was given. if test "${enable_wince+set}" = set; then enableval="$enable_wince" doWince=$enableval else doWince=no fi; echo "$as_me:$LINENO: result: $doWince" >&5 echo "${ECHO_T}$doWince" >&6 fi # Step 1: set the variable "system" to hold the name and version number # for the system. This can usually be done via the "uname" command, but # there are a few systems, like Next, where this doesn't work. echo "$as_me:$LINENO: checking system version (for dynamic loading)" >&5 echo $ECHO_N "checking system version (for dynamic loading)... $ECHO_C" >&6 if test -f /usr/lib/NextStep/software_version; then system=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version` else system=`uname -s`-`uname -r` if test "$?" -ne 0 ; then echo "$as_me:$LINENO: result: unknown (can't find uname command)" >&5 echo "${ECHO_T}unknown (can't find uname command)" >&6 system=unknown else # Special check for weird MP-RAS system (uname returns weird # results, and the version is kept in special file). if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then system=MP-RAS-`awk '{print }' /etc/.relid` fi if test "`uname -s`" = "AIX" ; then system=AIX-`uname -v`.`uname -r` fi if test "${TEA_PLATFORM}" = "windows" ; then system=windows fi echo "$as_me:$LINENO: result: $system" >&5 echo "${ECHO_T}$system" >&6 fi fi # Step 2: check for existence of -ldl library. This is needed because # Linux can use either -ldl or -ldld for dynamic loading. echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 if test "${ac_cv_lib_dl_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char dlopen (); int main () { dlopen (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 if test $ac_cv_lib_dl_dlopen = yes; then have_dl=yes else have_dl=no fi # Step 3: set configuration options based on system name and version. # This is similar to Tcl's unix/tcl.m4 except that we've added a # "windows" case and CC_SEARCH_FLAGS becomes LD_SEARCH_FLAGS for us # (and we have no CC_SEARCH_FLAGS). do64bit_ok=no LDFLAGS_ORIG="$LDFLAGS" TCL_EXPORT_FILE_SUFFIX="" UNSHARED_LIB_SUFFIX="" TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`' ECHO_VERSION='`echo ${PACKAGE_VERSION}`' TCL_LIB_VERSIONS_OK=ok CFLAGS_DEBUG=-g if test "$GCC" = "yes" ; then CFLAGS_OPTIMIZE=-O2 CFLAGS_WARNING="-Wall -Wno-implicit-int" else CFLAGS_OPTIMIZE=-O CFLAGS_WARNING="" fi TCL_NEEDS_EXP_FILE=0 TCL_BUILD_EXP_FILE="" TCL_EXP_FILE="" # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_AR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="ar" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then echo "$as_me:$LINENO: result: $AR" >&5 echo "${ECHO_T}$AR" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi STLIB_LD='${AR} cr' LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH" case $system in windows) # This is a 2-stage check to make sure we have the 64-bit SDK # We have to know where the SDK is installed. # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs # MACHINE is IX86 for LINK, but this is used by the manifest, # which requires x86|amd64|ia64. MACHINE="X86" if test "$do64bit" != "no" ; then if test "x${MSSDK}x" = "xx" ; then MSSDK="C:/Progra~1/Microsoft Platform SDK" fi MSSDK=`echo "$MSSDK" | sed -e 's!\\\!/!g'` PATH64="" case "$do64bit" in amd64|x64|yes) MACHINE="AMD64" ; # default to AMD64 64-bit build PATH64="${MSSDK}/Bin/Win64/x86/AMD64" ;; ia64) MACHINE="IA64" PATH64="${MSSDK}/Bin/Win64" ;; esac if test ! -d "${PATH64}" ; then { echo "$as_me:$LINENO: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&5 echo "$as_me: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&2;} { echo "$as_me:$LINENO: WARNING: Ensure latest Platform SDK is installed" >&5 echo "$as_me: WARNING: Ensure latest Platform SDK is installed" >&2;} do64bit="no" else echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5 echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6 do64bit_ok="yes" fi fi if test "$doWince" != "no" ; then if test "$do64bit" != "no" ; then { { echo "$as_me:$LINENO: error: Windows/CE and 64-bit builds incompatible" >&5 echo "$as_me: error: Windows/CE and 64-bit builds incompatible" >&2;} { (exit 1); exit 1; }; } fi if test "$GCC" = "yes" ; then { { echo "$as_me:$LINENO: error: Windows/CE and GCC builds incompatible" >&5 echo "$as_me: error: Windows/CE and GCC builds incompatible" >&2;} { (exit 1); exit 1; }; } fi # First, look for one uninstalled. # the alternative search directory is invoked by --with-celib if test x"${no_celib}" = x ; then # we reset no_celib in case something fails here no_celib=true # Check whether --with-celib or --without-celib was given. if test "${with_celib+set}" = set; then withval="$with_celib" with_celibconfig=${withval} fi; echo "$as_me:$LINENO: checking for Windows/CE celib directory" >&5 echo $ECHO_N "checking for Windows/CE celib directory... $ECHO_C" >&6 if test "${ac_cv_c_celibconfig+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # First check to see if --with-celibconfig was specified. if test x"${with_celibconfig}" != x ; then if test -d "${with_celibconfig}/inc" ; then ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)` else { { echo "$as_me:$LINENO: error: ${with_celibconfig} directory doesn't contain inc directory" >&5 echo "$as_me: error: ${with_celibconfig} directory doesn't contain inc directory" >&2;} { (exit 1); exit 1; }; } fi fi # then check for a celib library if test x"${ac_cv_c_celibconfig}" = x ; then for i in \ ../celib-palm-3.0 \ ../celib \ ../../celib-palm-3.0 \ ../../celib \ `ls -dr ../celib-*3.[0-9]* 2>/dev/null` \ ${srcdir}/../celib-palm-3.0 \ ${srcdir}/../celib \ `ls -dr ${srcdir}/../celib-*3.[0-9]* 2>/dev/null` \ ; do if test -d "$i/inc" ; then ac_cv_c_celibconfig=`(cd $i; pwd)` break fi done fi fi if test x"${ac_cv_c_celibconfig}" = x ; then { { echo "$as_me:$LINENO: error: Cannot find celib support library directory" >&5 echo "$as_me: error: Cannot find celib support library directory" >&2;} { (exit 1); exit 1; }; } else no_celib= CELIB_DIR=${ac_cv_c_celibconfig} CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'` echo "$as_me:$LINENO: result: found $CELIB_DIR" >&5 echo "${ECHO_T}found $CELIB_DIR" >&6 fi fi # Set defaults for common evc4/PPC2003 setup # Currently Tcl requires 300+, possibly 420+ for sockets CEVERSION=420; # could be 211 300 301 400 420 ... TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ... ARCH=ARM; # could be ARM MIPS X86EM ... PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002" if test "$doWince" != "yes"; then # If !yes then the user specified something # Reset ARCH to allow user to skip specifying it ARCH= eval `echo $doWince | awk -F, '{ \ if (length($1)) { printf "CEVERSION=\"%s\"\n", $1; \ if ($1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \ if (length($2)) { printf "TARGETCPU=\"%s\"\n", toupper($2) }; \ if (length($3)) { printf "ARCH=\"%s\"\n", toupper($3) }; \ if (length($4)) { printf "PLATFORM=\"%s\"\n", $4 }; \ }'` if test "x${ARCH}" = "x" ; then ARCH=$TARGETCPU; fi fi OSVERSION=WCE$CEVERSION; if test "x${WCEROOT}" = "x" ; then WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0" if test ! -d "${WCEROOT}" ; then WCEROOT="C:/Program Files/Microsoft eMbedded Tools" fi fi if test "x${SDKROOT}" = "x" ; then SDKROOT="C:/Program Files/Windows CE Tools" if test ! -d "${SDKROOT}" ; then SDKROOT="C:/Windows CE Tools" fi fi WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'` SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'` if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \ -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then { { echo "$as_me:$LINENO: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&5 echo "$as_me: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&2;} { (exit 1); exit 1; }; } doWince="no" else # We could PATH_NOSPACE these, but that's not important, # as long as we quote them when used. CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include" if test -d "${CEINCLUDE}/${TARGETCPU}" ; then CEINCLUDE="${CEINCLUDE}/${TARGETCPU}" fi CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" fi fi if test "$GCC" != "yes" ; then if test "${SHARED_BUILD}" = "0" ; then runtime=-MT else runtime=-MD fi if test "$do64bit" != "no" ; then # All this magic is necessary for the Win64 SDK RC1 - hobbs CC="\"${PATH64}/cl.exe\"" CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\"" RC="\"${MSSDK}/bin/rc.exe\"" lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\"" LINKBIN="\"${PATH64}/link.exe\"" CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d" CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" # Avoid 'unresolved external symbol __security_cookie' # errors, c.f. http://support.microsoft.com/?id=894573 vars="bufferoverflowU.lib" for i in $vars; do if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then # Convert foo.lib to -lfoo for GCC. No-op if not *.lib i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'` fi PKG_LIBS="$PKG_LIBS $i" done elif test "$doWince" != "no" ; then CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin" if test "${TARGETCPU}" = "X86"; then CC="\"${CEBINROOT}/cl.exe\"" else CC="\"${CEBINROOT}/cl${ARCH}.exe\"" fi CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\"" RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\"" arch=`echo ${ARCH} | awk '{print tolower($0)}'` defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS" if test "${SHARED_BUILD}" = "1" ; then # Static CE builds require static celib as well defs="${defs} _DLL" fi for i in $defs ; do cat >>confdefs.h <<_ACEOF #define $i 1 _ACEOF done cat >>confdefs.h <<_ACEOF #define _WIN32_WCE $CEVERSION _ACEOF cat >>confdefs.h <<_ACEOF #define UNDER_CE $CEVERSION _ACEOF CFLAGS_DEBUG="-nologo -Zi -Od" CFLAGS_OPTIMIZE="-nologo -Ox" lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'` lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo" LINKBIN="\"${CEBINROOT}/link.exe\"" else RC="rc" lflags="-nologo" LINKBIN="link" CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d" CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" fi fi if test "$GCC" = "yes"; then # mingw gcc mode RC="windres" CFLAGS_DEBUG="-g" CFLAGS_OPTIMIZE="-O2" SHLIB_LD="$CXX -shared" UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}" LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}" else SHLIB_LD="${LINKBIN} -dll ${lflags}" # link -lib only works when -lib is the first arg STLIB_LD="${LINKBIN} -lib ${lflags}" UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib' PATHTYPE=-w # For information on what debugtype is most useful, see: # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp # This essentially turns it all on. LDFLAGS_DEBUG="-debug:full -debugtype:both -warn:2" LDFLAGS_OPTIMIZE="-release" if test "$doWince" != "no" ; then LDFLAGS_CONSOLE="-link ${lflags}" LDFLAGS_WINDOW=${LDFLAGS_CONSOLE} else LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}" LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}" fi fi SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".dll" SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll' TCL_LIB_VERSIONS_OK=nodots # Bogus to avoid getting this turned off DL_OBJS="tclLoadNone.obj" ;; AIX-*) if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes" ; then # AIX requires the _r compiler when gcc isn't being used case "${CC}" in *_r) # ok ... ;; *) CC=${CC}_r ;; esac echo "$as_me:$LINENO: result: Using $CC for compiling with threads" >&5 echo "${ECHO_T}Using $CC for compiling with threads" >&6 fi LIBS="$LIBS -lc" SHLIB_CFLAGS="" SHLIB_SUFFIX=".so" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadDl.o" LD_LIBRARY_PATH_VAR="LIBPATH" # AIX v<=4.1 has some different flags than 4.2+ if test "$system" = "AIX-4.1" -o "`uname -v`" -lt "4" ; then #LIBOBJS="$LIBOBJS tclLoadAix.o" case $LIBOBJS in "tclLoadAix.$ac_objext" | \ *" tclLoadAix.$ac_objext" | \ "tclLoadAix.$ac_objext "* | \ *" tclLoadAix.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS tclLoadAix.$ac_objext" ;; esac DL_LIBS="-lld" fi # Check to enable 64-bit flags for compiler/linker on AIX 4+ if test "$do64bit" = "yes" -a "`uname -v`" -gt "3" ; then if test "$GCC" = "yes" ; then { echo "$as_me:$LINENO: WARNING: \"64bit mode not supported with GCC on $system\"" >&5 echo "$as_me: WARNING: \"64bit mode not supported with GCC on $system\"" >&2;} else do64bit_ok=yes CFLAGS="$CFLAGS -q64" LDFLAGS="$LDFLAGS -q64" RANLIB="${RANLIB} -X64" AR="${AR} -X64" SHLIB_LD_FLAGS="-b64" fi fi if test "`uname -m`" = "ia64" ; then # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC SHLIB_LD="/usr/ccs/bin/ld -G -z text" # AIX-5 has dl* in libc.so DL_LIBS="" if test "$GCC" = "yes" ; then LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' else LD_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}' fi else if test "$GCC" = "yes" ; then SHLIB_LD="$CXX -shared" else SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry" fi SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}" DL_LIBS="-ldl" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' TCL_NEEDS_EXP_FILE=1 TCL_EXPORT_FILE_SUFFIX='${PACKAGE_VERSION}.exp' fi # On AIX <=v4 systems, libbsd.a has to be linked in to support # non-blocking file IO. This library has to be linked in after # the MATH_LIBS or it breaks the pow() function. The way to # insure proper sequencing, is to add it to the tail of MATH_LIBS. # This library also supplies gettimeofday. # # AIX does not have a timezone field in struct tm. When the AIX # bsd library is used, the timezone global and the gettimeofday # methods are to be avoided for timezone deduction instead, we # deduce the timezone by comparing the localtime result on a # known GMT value. echo "$as_me:$LINENO: checking for gettimeofday in -lbsd" >&5 echo $ECHO_N "checking for gettimeofday in -lbsd... $ECHO_C" >&6 if test "${ac_cv_lib_bsd_gettimeofday+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbsd $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gettimeofday (); int main () { gettimeofday (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_bsd_gettimeofday=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_bsd_gettimeofday=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_gettimeofday" >&5 echo "${ECHO_T}$ac_cv_lib_bsd_gettimeofday" >&6 if test $ac_cv_lib_bsd_gettimeofday = yes; then libbsd=yes else libbsd=no fi if test $libbsd = yes; then MATH_LIBS="$MATH_LIBS -lbsd" cat >>confdefs.h <<\_ACEOF #define USE_DELTA_FOR_TZ 1 _ACEOF fi ;; BeOS*) SHLIB_CFLAGS="-fPIC" SHLIB_LD="${CXX} -nostart" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" ;; BSD/OS-2.1*|BSD/OS-3*) SHLIB_CFLAGS="" SHLIB_LD="shlicc -r" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS="" ;; BSD/OS-4.*) SHLIB_CFLAGS="-export-dynamic -fPIC" SHLIB_LD="$CXX -shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -export-dynamic" LD_SEARCH_FLAGS="" ;; dgux*) SHLIB_CFLAGS="-K PIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS="" ;; HP-UX-*.11.*) # Use updated header definitions where possible cat >>confdefs.h <<\_ACEOF #define _XOPEN_SOURCE_EXTENDED 1 _ACEOF SHLIB_SUFFIX=".sl" echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 if test "${ac_cv_lib_dld_shl_load+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char shl_load (); int main () { shl_load (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dld_shl_load=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_shl_load=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 if test $ac_cv_lib_dld_shl_load = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = yes; then SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadShl.o" DL_LIBS="-ldld" LDFLAGS="$LDFLAGS -Wl,-E" LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.' LD_LIBRARY_PATH_VAR="SHLIB_PATH" fi if test "$GCC" = "yes" ; then SHLIB_LD="$CXX -shared -fPIC" SHLIB_LD_LIBS='${LIBS}' LD_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.' fi # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc #CFLAGS="$CFLAGS +DAportable" # Check to enable 64-bit flags for compiler/linker if test "$do64bit" = "yes" ; then if test "$GCC" = "yes" ; then hpux_arch=`${CC} -dumpmachine` case $hpux_arch in hppa64*) # 64-bit gcc in use. Fix flags for GNU ld. do64bit_ok=yes SHLIB_LD="${CXX} -shared -fPIC" SHLIB_LD_LIBS='${LIBS}' ;; *) { echo "$as_me:$LINENO: WARNING: \"64bit mode not supported with GCC on $system\"" >&5 echo "$as_me: WARNING: \"64bit mode not supported with GCC on $system\"" >&2;} ;; esac else do64bit_ok=yes CFLAGS="$CFLAGS +DD64" LDFLAGS="$LDFLAGS +DD64" fi fi ;; HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*) SHLIB_SUFFIX=".sl" echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 if test "${ac_cv_lib_dld_shl_load+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char shl_load (); int main () { shl_load (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dld_shl_load=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_shl_load=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 if test $ac_cv_lib_dld_shl_load = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = yes; then SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" SHLIB_LD_LIBS="" DL_OBJS="tclLoadShl.o" DL_LIBS="-ldld" LDFLAGS="$LDFLAGS -Wl,-E" LD_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.' fi LD_LIBRARY_PATH_VAR="SHLIB_PATH" ;; IRIX-4.*) SHLIB_CFLAGS="-G 0" SHLIB_SUFFIX=".a" SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadAout.o" DL_LIBS="" LDFLAGS="$LDFLAGS -Wl,-D,08000000" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' SHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a' ;; IRIX-5.*) SHLIB_CFLAGS="" SHLIB_LD="ld -shared -rdata_shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' ;; IRIX-6.*|IRIX64-6.5*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' if test "$GCC" = "yes" ; then CFLAGS="$CFLAGS -mabi=n32" LDFLAGS="$LDFLAGS -mabi=n32" else case $system in IRIX-6.3) # Use to build 6.2 compatible binaries on 6.3. CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS" ;; *) CFLAGS="$CFLAGS -n32" ;; esac LDFLAGS="$LDFLAGS -n32" fi ;; IRIX64-6.*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' # Check to enable 64-bit flags for compiler/linker if test "$do64bit" = "yes" ; then if test "$GCC" = "yes" ; then { echo "$as_me:$LINENO: WARNING: 64bit mode not supported by gcc" >&5 echo "$as_me: WARNING: 64bit mode not supported by gcc" >&2;} else do64bit_ok=yes SHLIB_LD="ld -64 -shared -rdata_shared" CFLAGS="$CFLAGS -64" LDFLAGS="$LDFLAGS -64" fi fi ;; Linux*) SHLIB_CFLAGS="-fPIC" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" CFLAGS_OPTIMIZE="-O2" # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings # when you inline the string and math operations. Turn this off to # get rid of the warnings. #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES" if test "$have_dl" = yes; then SHLIB_LD="${CXX} -shared" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,--export-dynamic" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' else if test "${ac_cv_header_dld_h+set}" = set; then echo "$as_me:$LINENO: checking for dld.h" >&5 echo $ECHO_N "checking for dld.h... $ECHO_C" >&6 if test "${ac_cv_header_dld_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_dld_h" >&5 echo "${ECHO_T}$ac_cv_header_dld_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking dld.h usability" >&5 echo $ECHO_N "checking dld.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking dld.h presence" >&5 echo $ECHO_N "checking dld.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: dld.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: dld.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: dld.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: dld.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: dld.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: dld.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: dld.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: dld.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: dld.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: dld.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the rtd lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for dld.h" >&5 echo $ECHO_N "checking for dld.h... $ECHO_C" >&6 if test "${ac_cv_header_dld_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_dld_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_dld_h" >&5 echo "${ECHO_T}$ac_cv_header_dld_h" >&6 fi if test $ac_cv_header_dld_h = yes; then SHLIB_LD="ld -shared" DL_OBJS="tclLoadDld.o" DL_LIBS="-ldld" LD_SEARCH_FLAGS="" fi fi if test "`uname -m`" = "alpha" ; then CFLAGS="$CFLAGS -mieee" fi # The combo of gcc + glibc has a bug related # to inlining of functions like strtod(). The # -fno-builtin flag should address this problem # but it does not work. The -fno-inline flag # is kind of overkill but it works. # Disable inlining only when one of the # files in compat/*.c is being linked in. if test x"${USE_COMPAT}" != x ; then CFLAGS="$CFLAGS -fno-inline" fi ;; GNU*) SHLIB_CFLAGS="-fPIC" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" if test "$have_dl" = yes; then SHLIB_LD="${CXX} -shared" DL_OBJS="" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,--export-dynamic" LD_SEARCH_FLAGS="" else if test "${ac_cv_header_dld_h+set}" = set; then echo "$as_me:$LINENO: checking for dld.h" >&5 echo $ECHO_N "checking for dld.h... $ECHO_C" >&6 if test "${ac_cv_header_dld_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_dld_h" >&5 echo "${ECHO_T}$ac_cv_header_dld_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking dld.h usability" >&5 echo $ECHO_N "checking dld.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking dld.h presence" >&5 echo $ECHO_N "checking dld.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: dld.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: dld.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: dld.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: dld.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: dld.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: dld.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: dld.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: dld.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: dld.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: dld.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the rtd lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for dld.h" >&5 echo $ECHO_N "checking for dld.h... $ECHO_C" >&6 if test "${ac_cv_header_dld_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_dld_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_dld_h" >&5 echo "${ECHO_T}$ac_cv_header_dld_h" >&6 fi if test $ac_cv_header_dld_h = yes; then SHLIB_LD="ld -shared" DL_OBJS="" DL_LIBS="-ldld" LD_SEARCH_FLAGS="" fi fi if test "`uname -m`" = "alpha" ; then CFLAGS="$CFLAGS -mieee" fi ;; MP-RAS-02*) SHLIB_CFLAGS="-K PIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS="" ;; MP-RAS-*) SHLIB_CFLAGS="-K PIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,-Bexport" LD_SEARCH_FLAGS="" ;; NetBSD-*|FreeBSD-[1-2].*) # Not available on all versions: check for include file. if test "${ac_cv_header_dlfcn_h+set}" = set; then echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking dlfcn.h usability" >&5 echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking dlfcn.h presence" >&5 echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: dlfcn.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------ ## ## Report this to the rtd lists. ## ## ------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_dlfcn_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 fi if test $ac_cv_header_dlfcn_h = yes; then # NetBSD/SPARC needs -fPIC, -fpic will not do. SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' echo "$as_me:$LINENO: checking for ELF" >&5 echo $ECHO_N "checking for ELF... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __ELF__ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so' else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' fi rm -f conftest* else SHLIB_CFLAGS="" SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".a" DL_OBJS="tclLoadAout.o" DL_LIBS="" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' fi # FreeBSD doesn't handle version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; OpenBSD-*) SHLIB_LD="${CXX} -shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS="" echo "$as_me:$LINENO: checking for ELF" >&5 echo $ECHO_N "checking for ELF... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __ELF__ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' fi rm -f conftest* # OpenBSD doesn't do version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; FreeBSD-*) # FreeBSD 3.* and greater have ELF. SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LDFLAGS="$LDFLAGS -export-dynamic" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' if test "${TCL_THREADS}" = "1" ; then # The -pthread needs to go in the CFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` CFLAGS="$CFLAGS -pthread" LDFLAGS="$LDFLAGS -pthread" fi case $system in FreeBSD-3.*) # FreeBSD-3 doesn't handle version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so' TCL_LIB_VERSIONS_OK=nodots ;; esac ;; Darwin-*) CFLAGS_OPTIMIZE="-Os" SHLIB_CFLAGS="-fno-common" if test $do64bit = yes; then do64bit_ok=yes CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" fi SHLIB_LD='${CXX} -dynamiclib ${CFLAGS} ${LDFLAGS}' echo "$as_me:$LINENO: checking if ld accepts -single_module flag" >&5 echo $ECHO_N "checking if ld accepts -single_module flag... $ECHO_C" >&6 if test "${tcl_cv_ld_single_module+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { int i; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_ld_single_module=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_ld_single_module=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$hold_ldflags fi echo "$as_me:$LINENO: result: $tcl_cv_ld_single_module" >&5 echo "${ECHO_T}$tcl_cv_ld_single_module" >&6 if test $tcl_cv_ld_single_module = yes; then SHLIB_LD="${SHLIB_LD} -Wl,-single_module" fi SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".dylib" DL_OBJS="tclLoadDyld.o" DL_LIBS="" # Don't use -prebind when building for Mac OS X 10.4 or later only: test -z "${MACOSX_DEPLOYMENT_TARGET}" || \ test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F. '{print $2}'`" -lt 4 && \ LDFLAGS="$LDFLAGS -prebind" LDFLAGS="$LDFLAGS -headerpad_max_install_names" echo "$as_me:$LINENO: checking if ld accepts -search_paths_first flag" >&5 echo $ECHO_N "checking if ld accepts -search_paths_first flag... $ECHO_C" >&6 if test "${tcl_cv_ld_search_paths_first+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-search_paths_first" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { int i; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_ld_search_paths_first=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_ld_search_paths_first=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$hold_ldflags fi echo "$as_me:$LINENO: result: $tcl_cv_ld_search_paths_first" >&5 echo "${ECHO_T}$tcl_cv_ld_search_paths_first" >&6 if test $tcl_cv_ld_search_paths_first = yes; then LDFLAGS="$LDFLAGS -Wl,-search_paths_first" fi LD_SEARCH_FLAGS="" LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH" ;; NEXTSTEP-*) SHLIB_CFLAGS="" SHLIB_LD="$CXX -nostdlib -r" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadNext.o" DL_LIBS="" LD_SEARCH_FLAGS="" ;; OS/390-*) CFLAGS_OPTIMIZE="" # Optimizer is buggy cat >>confdefs.h <<\_ACEOF #define _OE_SOCKETS 1 _ACEOF ;; OSF1-1.0|OSF1-1.1|OSF1-1.2) # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1 SHLIB_CFLAGS="" # Hack: make package name same as library name SHLIB_LD='ld -R -export :' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadOSF.o" DL_LIBS="" LD_SEARCH_FLAGS="" ;; OSF1-1.*) # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2 SHLIB_CFLAGS="-fPIC" if test "$SHARED_BUILD" = "1" ; then SHLIB_LD="ld -shared" else SHLIB_LD="ld -non_shared" fi SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS="" ;; OSF1-V*) # Digital OSF/1 SHLIB_CFLAGS="" if test "$SHARED_BUILD" = "1" ; then SHLIB_LD='ld -shared -expect_unresolved "*"' else SHLIB_LD='ld -non_shared -expect_unresolved "*"' fi SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' if test "$GCC" = "yes" ; then CFLAGS="$CFLAGS -mieee" else CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee" fi # see pthread_intro(3) for pthread support on osf1, k.furukawa if test "${TCL_THREADS}" = "1" ; then CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE" CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64" LIBS=`echo $LIBS | sed s/-lpthreads//` if test "$GCC" = "yes" ; then LIBS="$LIBS -lpthread -lmach -lexc" else CFLAGS="$CFLAGS -pthread" # PWD: don't need this. #LDFLAGS="$LDFLAGS -pthread" fi fi ;; QNX-6*) # QNX RTP # This may work for all QNX, but it was only reported for v6. SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" # dlopen is in -lc on QNX DL_LIBS="" LD_SEARCH_FLAGS="" ;; RISCos-*) SHLIB_CFLAGS="-G 0" SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".a" DL_OBJS="tclLoadAout.o" DL_LIBS="" LDFLAGS="$LDFLAGS -Wl,-D,08000000" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' ;; SCO_SV-3.2*) # Note, dlopen is available only on SCO 3.2.5 and greater. However, # this test works, since "uname -s" was non-standard in 3.2.4 and # below. if test "$GCC" = "yes" ; then SHLIB_CFLAGS="-fPIC -melf" LDFLAGS="$LDFLAGS -melf -Wl,-Bexport" else SHLIB_CFLAGS="-Kpic -belf" LDFLAGS="$LDFLAGS -belf -Wl,-Bexport" fi SHLIB_LD="ld -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS="" ;; SINIX*5.4*) SHLIB_CFLAGS="-K PIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS="" ;; SunOS-4*) SHLIB_CFLAGS="-PIC" SHLIB_LD="ld" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' # SunOS can't handle version numbers with dots in them in library # specs, like -ltcl7.5, so use -ltcl75 instead. Also, it # requires an extra version number at the end of .so file names. # So, the library has to have a name like libtcl75.so.1.0 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; SunOS-5.[0-6]) # Careful to not let 5.10+ fall into this case # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. cat >>confdefs.h <<\_ACEOF #define _REENTRANT 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _POSIX_PTHREAD_SEMANTICS 1 _ACEOF # Note: need the LIBS below, otherwise Tk won't find Tcl's # symbols when dynamically loaded into tclsh. SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" if test "$GCC" = "yes" ; then SHLIB_CFLAGS="-fPIC" SHLIB_LD="$CXX -shared" LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' else SHLIB_LD="$CXX -G -z text" LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' SHLIB_CFLAGS="-KPIC" fi ;; SunOS-5*) # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. cat >>confdefs.h <<\_ACEOF #define _REENTRANT 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _POSIX_PTHREAD_SEMANTICS 1 _ACEOF # Check to enable 64-bit flags for compiler/linker if test "$do64bit" = "yes" ; then arch=`isainfo` if test "$arch" = "sparcv9 sparc" ; then if test "$GCC" = "yes" ; then if test "`gcc -dumpversion` | awk -F. '{print }'" -lt "3" ; then { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5 echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;} else do64bit_ok=yes CFLAGS="$CFLAGS -m64 -mcpu=v9" LDFLAGS="$LDFLAGS -m64 -mcpu=v9" fi else do64bit_ok=yes if test "$do64bitVIS" = "yes" ; then CFLAGS="$CFLAGS -xarch=v9a" LDFLAGS="$LDFLAGS -xarch=v9a" else CFLAGS="$CFLAGS -xarch=v9" LDFLAGS="$LDFLAGS -xarch=v9" fi # Solaris 64 uses this as well #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64" fi elif test "$arch" = "amd64 i386" ; then if test "$GCC" = "yes" ; then { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5 echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;} else do64bit_ok=yes CFLAGS="$CFLAGS -xarch=amd64" LDFLAGS="$LDFLAGS -xarch=amd64" fi else { echo "$as_me:$LINENO: WARNING: 64bit mode not supported for $arch" >&5 echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;} fi fi # Note: need the LIBS below, otherwise Tk won't find Tcl's # symbols when dynamically loaded into tclsh. SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" if test "$GCC" = "yes" ; then SHLIB_CFLAGS="-fPIC" SHLIB_LD="$CXX -shared" LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' if test "$do64bit" = "yes" ; then # We need to specify -static-libgcc or we need to # add the path to the sparv9 libgcc. # JH: static-libgcc is necessary for core Tcl, but may # not be necessary for extensions. SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc" # for finding sparcv9 libgcc, get the regular libgcc # path, remove so name and append 'sparcv9' #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..." #LD_SEARCH_FLAGS="${LD_SEARCH_FLAGS},-R,$v9gcclibdir" fi else SHLIB_CFLAGS="-KPIC" SHLIB_LD="$CXX -G -z text" LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' fi ;; ULTRIX-4.*) SHLIB_CFLAGS="-G 0" SHLIB_SUFFIX=".a" SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadAout.o" DL_LIBS="" LDFLAGS="$LDFLAGS -Wl,-D,08000000" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' if test "$GCC" != "yes" ; then CFLAGS="$CFLAGS -DHAVE_TZSET -std1" fi ;; UNIX_SV* | UnixWare-5*) SHLIB_CFLAGS="-KPIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers # that don't grok the -Bexport option. Test that it does. hold_ldflags=$LDFLAGS echo "$as_me:$LINENO: checking for ld accepts -Bexport flag" >&5 echo $ECHO_N "checking for ld accepts -Bexport flag... $ECHO_C" >&6 LDFLAGS="$LDFLAGS -Wl,-Bexport" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { int i; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then found=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 LDFLAGS=$hold_ldflags found=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext echo "$as_me:$LINENO: result: $found" >&5 echo "${ECHO_T}$found" >&6 LD_SEARCH_FLAGS="" ;; esac if test "$do64bit" != "no" -a "$do64bit_ok" = "no" ; then { echo "$as_me:$LINENO: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5 echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;} fi # Step 4: If pseudo-static linking is in use (see K. B. Kenny, "Dynamic # Loading for Tcl -- What Became of It?". Proc. 2nd Tcl/Tk Workshop, # New Orleans, LA, Computerized Processes Unlimited, 1994), then we need # to determine which of several header files defines the a.out file # format (a.out.h, sys/exec.h, or sys/exec_aout.h). At present, we # support only a file format that is more or less version-7-compatible. # In particular, # - a.out files must begin with `struct exec'. # - the N_TXTOFF on the `struct exec' must compute the seek address # of the text segment # - The `struct exec' must contain a_magic, a_text, a_data, a_bss # and a_entry fields. # The following compilation should succeed if and only if either sys/exec.h # or a.out.h is usable for the purpose. # # Note that the modified COFF format used on MIPS Ultrix 4.x is usable; the # `struct exec' includes a second header that contains information that # duplicates the v7 fields that are needed. if test "x$DL_OBJS" = "xtclLoadAout.o" ; then echo "$as_me:$LINENO: checking sys/exec.h" >&5 echo $ECHO_N "checking sys/exec.h... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct exec foo; unsigned long seek; int flag; #if defined(__mips) || defined(mips) seek = N_TXTOFF (foo.ex_f, foo.ex_o); #else seek = N_TXTOFF (foo); #endif flag = (foo.a_magic == OMAGIC); return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_ok=usable else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_ok=unusable fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $tcl_ok" >&5 echo "${ECHO_T}$tcl_ok" >&6 if test $tcl_ok = usable; then cat >>confdefs.h <<\_ACEOF #define USE_SYS_EXEC_H 1 _ACEOF else echo "$as_me:$LINENO: checking a.out.h" >&5 echo $ECHO_N "checking a.out.h... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct exec foo; unsigned long seek; int flag; #if defined(__mips) || defined(mips) seek = N_TXTOFF (foo.ex_f, foo.ex_o); #else seek = N_TXTOFF (foo); #endif flag = (foo.a_magic == OMAGIC); return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_ok=usable else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_ok=unusable fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $tcl_ok" >&5 echo "${ECHO_T}$tcl_ok" >&6 if test $tcl_ok = usable; then cat >>confdefs.h <<\_ACEOF #define USE_A_OUT_H 1 _ACEOF else echo "$as_me:$LINENO: checking sys/exec_aout.h" >&5 echo $ECHO_N "checking sys/exec_aout.h... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct exec foo; unsigned long seek; int flag; #if defined(__mips) || defined(mips) seek = N_TXTOFF (foo.ex_f, foo.ex_o); #else seek = N_TXTOFF (foo); #endif flag = (foo.a_midmag == OMAGIC); return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_ok=usable else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_ok=unusable fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $tcl_ok" >&5 echo "${ECHO_T}$tcl_ok" >&6 if test $tcl_ok = usable; then cat >>confdefs.h <<\_ACEOF #define USE_SYS_EXEC_AOUT_H 1 _ACEOF else DL_OBJS="" fi fi fi fi # Step 5: disable dynamic loading if requested via a command-line switch. # Check whether --enable-load or --disable-load was given. if test "${enable_load+set}" = set; then enableval="$enable_load" tcl_ok=$enableval else tcl_ok=yes fi; if test "$tcl_ok" = "no"; then DL_OBJS="" fi if test "x$DL_OBJS" != "x" ; then BUILD_DLTEST="\$(DLTEST_TARGETS)" else echo "Can't figure out how to do dynamic loading or shared libraries" echo "on this system." SHLIB_CFLAGS="" SHLIB_LD="" SHLIB_SUFFIX="" DL_OBJS="tclLoadNone.o" DL_LIBS="" LDFLAGS="$LDFLAGS_ORIG" LD_SEARCH_FLAGS="" BUILD_DLTEST="" fi # If we're running gcc, then change the C flags for compiling shared # libraries to the right flags for gcc, instead of those for the # standard manufacturer compiler. if test "$DL_OBJS" != "tclLoadNone.o" ; then if test "$GCC" = "yes" ; then case $system in AIX-*) ;; BSD/OS*) ;; IRIX*) ;; NetBSD-*|FreeBSD-*) ;; Darwin-*) ;; RISCos-*) ;; SCO_SV-3.2*) ;; ULTRIX-4.*) ;; windows) ;; *) SHLIB_CFLAGS="-fPIC" ;; esac fi fi if test "$SHARED_LIB_SUFFIX" = "" ; then SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}' fi if test "$UNSHARED_LIB_SUFFIX" = "" ; then UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a' fi # These must be called after we do the basic CFLAGS checks and # verify any possible 64-bit or similar switches are necessary echo "$as_me:$LINENO: checking for required early compiler flags" >&5 echo $ECHO_N "checking for required early compiler flags... $ECHO_C" >&6 tcl_flags="" if test "${tcl_cv_flag__isoc99_source+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char *p = (char *)strtoll; char *q = (char *)strtoull; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_flag__isoc99_source=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _ISOC99_SOURCE 1 #include int main () { char *p = (char *)strtoll; char *q = (char *)strtoull; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_flag__isoc99_source=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_flag__isoc99_source=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_flag__isoc99_source}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define _ISOC99_SOURCE 1 _ACEOF tcl_flags="$tcl_flags _ISOC99_SOURCE" fi if test "${tcl_cv_flag__largefile64_source+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct stat64 buf; int i = stat64("/", &buf); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_flag__largefile64_source=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _LARGEFILE64_SOURCE 1 #include int main () { struct stat64 buf; int i = stat64("/", &buf); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_flag__largefile64_source=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_flag__largefile64_source=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_flag__largefile64_source}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define _LARGEFILE64_SOURCE 1 _ACEOF tcl_flags="$tcl_flags _LARGEFILE64_SOURCE" fi if test "x${tcl_flags}" = "x" ; then echo "$as_me:$LINENO: result: none" >&5 echo "${ECHO_T}none" >&6 else echo "$as_me:$LINENO: result: ${tcl_flags}" >&5 echo "${ECHO_T}${tcl_flags}" >&6 fi echo "$as_me:$LINENO: checking for 64-bit integer type" >&5 echo $ECHO_N "checking for 64-bit integer type... $ECHO_C" >&6 if test "${tcl_cv_type_64bit+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else tcl_cv_type_64bit=none # See if the compiler knows natively about __int64 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { __int64 value = (__int64) 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_type_64bit=__int64 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_type_64bit="long long" fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext # See if we should use long anyway Note that we substitute in the # type that is our current guess for a 64-bit type inside this check # program, so it should be modified only carefully... cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { switch (0) { case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ; } ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_type_64bit=${tcl_type_64bit} else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "${tcl_cv_type_64bit}" = none ; then cat >>confdefs.h <<\_ACEOF #define TCL_WIDE_INT_IS_LONG 1 _ACEOF echo "$as_me:$LINENO: result: using long" >&5 echo "${ECHO_T}using long" >&6 elif test "${tcl_cv_type_64bit}" = "__int64" \ -a "${TEA_PLATFORM}" = "windows" ; then # We actually want to use the default tcl.h checks in this # case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER* echo "$as_me:$LINENO: result: using Tcl header defaults" >&5 echo "${ECHO_T}using Tcl header defaults" >&6 else cat >>confdefs.h <<_ACEOF #define TCL_WIDE_INT_TYPE ${tcl_cv_type_64bit} _ACEOF echo "$as_me:$LINENO: result: ${tcl_cv_type_64bit}" >&5 echo "${ECHO_T}${tcl_cv_type_64bit}" >&6 # Now check for auxiliary declarations echo "$as_me:$LINENO: checking for struct dirent64" >&5 echo $ECHO_N "checking for struct dirent64... $ECHO_C" >&6 if test "${tcl_cv_struct_dirent64+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { struct dirent64 p; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_struct_dirent64=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_struct_dirent64=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRUCT_DIRENT64 1 _ACEOF fi echo "$as_me:$LINENO: result: ${tcl_cv_struct_dirent64}" >&5 echo "${ECHO_T}${tcl_cv_struct_dirent64}" >&6 echo "$as_me:$LINENO: checking for struct stat64" >&5 echo $ECHO_N "checking for struct stat64... $ECHO_C" >&6 if test "${tcl_cv_struct_stat64+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct stat64 p; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_struct_stat64=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_struct_stat64=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_struct_stat64}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRUCT_STAT64 1 _ACEOF fi echo "$as_me:$LINENO: result: ${tcl_cv_struct_stat64}" >&5 echo "${ECHO_T}${tcl_cv_struct_stat64}" >&6 echo "$as_me:$LINENO: checking for off64_t" >&5 echo $ECHO_N "checking for off64_t... $ECHO_C" >&6 if test "${tcl_cv_type_off64_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { off64_t offset; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_type_off64_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_type_off64_t=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_type_off64_t}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_TYPE_OFF64_T 1 _ACEOF fi echo "$as_me:$LINENO: result: ${tcl_cv_type_off64_t}" >&5 echo "${ECHO_T}${tcl_cv_type_off64_t}" >&6 fi #-------------------------------------------------------------------- # Set the default compiler switches based on the --enable-symbols option. #-------------------------------------------------------------------- DBGX="" echo "$as_me:$LINENO: checking for build with symbols" >&5 echo $ECHO_N "checking for build with symbols... $ECHO_C" >&6 # Check whether --enable-symbols or --disable-symbols was given. if test "${enable_symbols+set}" = set; then enableval="$enable_symbols" tcl_ok=$enableval else tcl_ok=no fi; if test "$tcl_ok" = "no"; then CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}" LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}" echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 else CFLAGS_DEFAULT="${CFLAGS_DEBUG}" LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}" if test "$tcl_ok" = "yes"; then echo "$as_me:$LINENO: result: yes (standard debugging)" >&5 echo "${ECHO_T}yes (standard debugging)" >&6 fi fi if test "${TEA_PLATFORM}" != "windows" ; then LDFLAGS_DEFAULT="${LDFLAGS}" fi if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then cat >>confdefs.h <<\_ACEOF #define TCL_MEM_DEBUG 1 _ACEOF fi if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then if test "$tcl_ok" = "all"; then echo "$as_me:$LINENO: result: enabled symbols mem debugging" >&5 echo "${ECHO_T}enabled symbols mem debugging" >&6 else echo "$as_me:$LINENO: result: enabled $tcl_ok debugging" >&5 echo "${ECHO_T}enabled $tcl_ok debugging" >&6 fi fi #-------------------------------------------------------------------- # Everyone should be linking against the Tcl stub library. If you # can't for some reason, remove this definition. If you aren't using # stubs, you also need to modify the SHLIB_LD_LIBS setting below to # link against the non-stubbed Tcl library. Add Tk too if necessary. #-------------------------------------------------------------------- # allan: can't use stubs, due to BLT dependency #AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs]) #AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs]) #-------------------------------------------------------------------- # This macro generates a line to use when building a library. It # depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS, # and TEA_LOAD_TCLCONFIG macros above. #-------------------------------------------------------------------- # rtd needs -lXext PKG_LIBS="${PKG_LIBS} -lXext" if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then MAKE_STATIC_LIB="\${STLIB_LD} -out:\$@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\$@ \$(PKG_OBJECTS)" MAKE_STUB_LIB="\${STLIB_LD} -out:\$@ \$(PKG_STUB_OBJECTS)" else MAKE_STATIC_LIB="\${STLIB_LD} \$@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} -o \$@ \$(PKG_OBJECTS) \${LDFLAGS_DEFAULT} \${SHLIB_LD_LIBS}" MAKE_STUB_LIB="\${STLIB_LD} \$@ \$(PKG_STUB_OBJECTS)" fi if test "${SHARED_BUILD}" = "1" ; then MAKE_LIB="${MAKE_SHARED_LIB} " else MAKE_LIB="${MAKE_STATIC_LIB} " fi #-------------------------------------------------------------------- # Shared libraries and static libraries have different names. # Use the double eval to make sure any variables in the suffix is # substituted. (@@@ Might not be necessary anymore) #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" ; then if test "${SHARED_BUILD}" = "1" ; then # We force the unresolved linking of symbols that are really in # the private libraries of Tcl and Tk. SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_LIB_FILE}`\"" if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_LIB_FILE}`\"" fi eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" else eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" fi # Some packages build there own stubs libraries eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" # These aren't needed on Windows (either MSVC or gcc) RANLIB=: RANLIB_STUB=: else RANLIB_STUB="${RANLIB}" if test "${SHARED_BUILD}" = "1" ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_LIB_SPEC}" if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_LIB_SPEC}" fi eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" RANLIB=: else eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" fi # Some packages build there own stubs libraries eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" fi # These are escaped so that only CFLAGS is picked up at configure time. # The other values will be substituted at make time. CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}" if test "${SHARED_BUILD}" = "1" ; then CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}" fi #-------------------------------------------------------------------- # Determine the name of the tclsh and/or wish executables in the # Tcl and Tk build directories or the location they were installed # into. These paths are used to support running test cases only, # the Makefile should not be making use of these paths to generate # a pkgIndex.tcl file or anything else at extension build time. #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking for tclsh" >&5 echo $ECHO_N "checking for tclsh... $ECHO_C" >&6 if test -f "${TCL_BIN_DIR}/Makefile" ; then # tclConfig.sh is in Tcl build directory if test "${TEA_PLATFORM}" = "windows"; then TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" else TCLSH_PROG="${TCL_BIN_DIR}/tclsh" fi else # tclConfig.sh is in install location if test "${TEA_PLATFORM}" = "windows"; then TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" else TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}" fi list="`ls -d ${TCL_PREFIX}/bin 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null`" for i in $list ; do if test -f "$i/${TCLSH_PROG}" ; then REAL_TCL_BIN_DIR="`cd "$i"; pwd`" break fi done TCLSH_PROG="${REAL_TCL_BIN_DIR}/${TCLSH_PROG}" fi echo "$as_me:$LINENO: result: ${TCLSH_PROG}" >&5 echo "${ECHO_T}${TCLSH_PROG}" >&6 echo "$as_me:$LINENO: checking for wish" >&5 echo $ECHO_N "checking for wish... $ECHO_C" >&6 if test -f "${TK_BIN_DIR}/Makefile" ; then # tkConfig.sh is in Tk build directory if test "${TEA_PLATFORM}" = "windows"; then WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" else WISH_PROG="${TK_BIN_DIR}/wish" fi else # tkConfig.sh is in install location if test "${TEA_PLATFORM}" = "windows"; then WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" else WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}" fi list="`ls -d ${TK_PREFIX}/bin 2>/dev/null` \ `ls -d ${TK_BIN_DIR}/../bin 2>/dev/null`" for i in $list ; do if test -f "$i/${WISH_PROG}" ; then REAL_TK_BIN_DIR="`cd "$i"; pwd`" break fi done WISH_PROG="${REAL_TK_BIN_DIR}/${WISH_PROG}" fi echo "$as_me:$LINENO: result: ${WISH_PROG}" >&5 echo "${ECHO_T}${WISH_PROG}" >&6 #-------------------------------------------------------------------- # These are for rtdConfig.sh #-------------------------------------------------------------------- rtd_LIB_FILE=${PKG_LIB_FILE} eval pkglibdir="${libdir}" if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then eval rtd_LIB_FLAG="-lrtd${PACKAGE_VERSION}" else eval rtd_LIB_FLAG="-lrtd`echo ${PACKAGE_VERSION} | tr -d .`" fi rtd_BUILD_LIB_SPEC="-L`pwd` ${rtd_LIB_FLAG}" rtd_BUILD_DIR="`pwd`" rtd_LIB_SPEC="-L${pkglibdir} ${rtd_LIB_FLAG}" for i in ${PKG_OBJECTS} ; do rtd_PKG_OBJECTS="$rtd_PKG_OBJECTS ../rtd/$i" done # rtd_SRC_DIR must be a fully qualified path eval rtd_SRC_DIR="$srcdir" rtd_SRC_DIR=`cd "${rtd_SRC_DIR}"; pwd` #-------------------------------------------------------------------- # Finally, substitute all of the various values into the Makefile. # You may alternatively have a special pkgIndex.tcl.in or other files # which require substituting th AC variables in. Include these here. #-------------------------------------------------------------------- ac_config_files="$ac_config_files Makefile pkgIndex.tcl rtdConfig.sh rtd rtd_version.tcl" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. { (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } | sed ' t clear : clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ : end' >>confcache if diff $cache_file confcache >/dev/null 2>&1; then :; else if test -w $cache_file; then test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" cat confcache >$cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/; s/:*\${srcdir}:*/:/; s/:*@srcdir@:*/:/; s/^\([^=]*=[ ]*\):*/\1/; s/:*$//; s/^[^=]*=[ ]*$//; }' fi # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then we branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. cat >confdef2opt.sed <<\_ACEOF t clear : clear s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g t quote s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g t quote d : quote s,[ `~#$^&*(){}\\|;'"<>?],\\&,g s,\[,\\&,g s,\],\\&,g s,\$,$$,g p _ACEOF # We use echo to avoid assuming a particular line-breaking character. # The extra dot is to prevent the shell from consuming trailing # line-breaks from the sub-command output. A line-break within # single-quotes doesn't work because, if this script is created in a # platform that uses two characters for line-breaks (e.g., DOS), tr # would break. ac_LF_and_DOT=`echo; echo .` DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` rm -f confdef2opt.sed ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_i=`echo "$ac_i" | sed 's/\$U\././;s/\.o$//;s/\.obj$//'` # 2. Add them. ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH exec 6>&1 # Open the log real soon, to keep \$[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. Logging --version etc. is OK. exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX } >&5 cat >&5 <<_CSEOF This file was extended by rtd $as_me 3.2.1, which was generated by Starlink Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ _CSEOF echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 echo >&5 _ACEOF # Files that config.status was made for. if test -n "$ac_config_files"; then echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS fi if test -n "$ac_config_headers"; then echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS fi if test -n "$ac_config_links"; then echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS fi if test -n "$ac_config_commands"; then echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS fi cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ rtd config.status 3.2.1 configured by $0, generated by Starlink Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2003 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." srcdir=$srcdir INSTALL="$INSTALL" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "x$1" : 'x\([^=]*\)='` ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` ac_shift=: ;; -*) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; *) # This is not an option, so the user has probably given explicit # arguments. ac_option=$1 ac_need_defaults=false;; esac case $ac_option in # Handling of the options. _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --vers* | -V ) echo "$ac_cs_version"; exit 0 ;; --he | --h) # Conflict between --help and --header { { echo "$as_me:$LINENO: error: ambiguous option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_config_target in $ac_config_targets do case "$ac_config_target" in # Handling of arguments. "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; "pkgIndex.tcl" ) CONFIG_FILES="$CONFIG_FILES pkgIndex.tcl" ;; "rtdConfig.sh" ) CONFIG_FILES="$CONFIG_FILES rtdConfig.sh" ;; "rtd" ) CONFIG_FILES="$CONFIG_FILES rtd" ;; "rtd_version.tcl" ) CONFIG_FILES="$CONFIG_FILES rtd_version.tcl" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason to put it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Create a temporary directory, and hook for its removal unless debugging. $debug || { trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./confstat$$-$RANDOM (umask 077 && mkdir $tmp) } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "\$CONFIG_FILES"; then # Protect against being on the right side of a sed subst in config.status. sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF s,@SHELL@,$SHELL,;t t s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t s,@exec_prefix@,$exec_prefix,;t t s,@prefix@,$prefix,;t t s,@program_transform_name@,$program_transform_name,;t t s,@bindir@,$bindir,;t t s,@sbindir@,$sbindir,;t t s,@libexecdir@,$libexecdir,;t t s,@datadir@,$datadir,;t t s,@sysconfdir@,$sysconfdir,;t t s,@sharedstatedir@,$sharedstatedir,;t t s,@localstatedir@,$localstatedir,;t t s,@libdir@,$libdir,;t t s,@includedir@,$includedir,;t t s,@oldincludedir@,$oldincludedir,;t t s,@infodir@,$infodir,;t t s,@mandir@,$mandir,;t t s,@build_alias@,$build_alias,;t t s,@host_alias@,$host_alias,;t t s,@target_alias@,$target_alias,;t t s,@DEFS@,$DEFS,;t t s,@ECHO_C@,$ECHO_C,;t t s,@ECHO_N@,$ECHO_N,;t t s,@ECHO_T@,$ECHO_T,;t t s,@LIBS@,$LIBS,;t t s,@CYGPATH@,$CYGPATH,;t t s,@EXEEXT@,$EXEEXT,;t t s,@PKG_LIB_FILE@,$PKG_LIB_FILE,;t t s,@PKG_STUB_LIB_FILE@,$PKG_STUB_LIB_FILE,;t t s,@PKG_STUB_SOURCES@,$PKG_STUB_SOURCES,;t t s,@PKG_STUB_OBJECTS@,$PKG_STUB_OBJECTS,;t t s,@PKG_TCL_SOURCES@,$PKG_TCL_SOURCES,;t t s,@PKG_HEADERS@,$PKG_HEADERS,;t t s,@PKG_INCLUDES@,$PKG_INCLUDES,;t t s,@PKG_LIBS@,$PKG_LIBS,;t t s,@PKG_CFLAGS@,$PKG_CFLAGS,;t t s,@TCL_VERSION@,$TCL_VERSION,;t t s,@TCL_BIN_DIR@,$TCL_BIN_DIR,;t t s,@TCL_SRC_DIR@,$TCL_SRC_DIR,;t t s,@TCL_LIB_FILE@,$TCL_LIB_FILE,;t t s,@TCL_LIB_FLAG@,$TCL_LIB_FLAG,;t t s,@TCL_LIB_SPEC@,$TCL_LIB_SPEC,;t t s,@TCL_STUB_LIB_FILE@,$TCL_STUB_LIB_FILE,;t t s,@TCL_STUB_LIB_FLAG@,$TCL_STUB_LIB_FLAG,;t t s,@TCL_STUB_LIB_SPEC@,$TCL_STUB_LIB_SPEC,;t t s,@TCL_LIBS@,$TCL_LIBS,;t t s,@TCL_DEFS@,$TCL_DEFS,;t t s,@TCL_EXTRA_CFLAGS@,$TCL_EXTRA_CFLAGS,;t t s,@TCL_LD_FLAGS@,$TCL_LD_FLAGS,;t t s,@TCL_SHLIB_LD_LIBS@,$TCL_SHLIB_LD_LIBS,;t t s,@TK_VERSION@,$TK_VERSION,;t t s,@TK_BIN_DIR@,$TK_BIN_DIR,;t t s,@TK_SRC_DIR@,$TK_SRC_DIR,;t t s,@TK_LIB_FILE@,$TK_LIB_FILE,;t t s,@TK_LIB_FLAG@,$TK_LIB_FLAG,;t t s,@TK_LIB_SPEC@,$TK_LIB_SPEC,;t t s,@TK_STUB_LIB_FILE@,$TK_STUB_LIB_FILE,;t t s,@TK_STUB_LIB_FLAG@,$TK_STUB_LIB_FLAG,;t t s,@TK_STUB_LIB_SPEC@,$TK_STUB_LIB_SPEC,;t t s,@TK_LIBS@,$TK_LIBS,;t t s,@TK_XINCLUDES@,$TK_XINCLUDES,;t t s,@CC@,$CC,;t t s,@CFLAGS@,$CFLAGS,;t t s,@LDFLAGS@,$LDFLAGS,;t t s,@CPPFLAGS@,$CPPFLAGS,;t t s,@ac_ct_CC@,$ac_ct_CC,;t t s,@OBJEXT@,$OBJEXT,;t t s,@CPP@,$CPP,;t t s,@CXX@,$CXX,;t t s,@CXXFLAGS@,$CXXFLAGS,;t t s,@ac_ct_CXX@,$ac_ct_CXX,;t t s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t s,@INSTALL_DATA@,$INSTALL_DATA,;t t s,@SET_MAKE@,$SET_MAKE,;t t s,@RANLIB@,$RANLIB,;t t s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t s,@EGREP@,$EGREP,;t t s,@MATH_LIBS@,$MATH_LIBS,;t t s,@tclutil_VERSION@,$tclutil_VERSION,;t t s,@tclutil_LIB_FILE@,$tclutil_LIB_FILE,;t t s,@tclutil_BUILD_LIB_SPEC@,$tclutil_BUILD_LIB_SPEC,;t t s,@tclutil_BUILD_DIR@,$tclutil_BUILD_DIR,;t t s,@tclutil_LIB_SPEC@,$tclutil_LIB_SPEC,;t t s,@BLT_LIB_DIR@,$BLT_LIB_DIR,;t t s,@BLT_LIB_SPEC@,$BLT_LIB_SPEC,;t t s,@tclutil_SRC_DIR@,$tclutil_SRC_DIR,;t t s,@tclutil_PKG_OBJECTS@,$tclutil_PKG_OBJECTS,;t t s,@CFITSIO_LIB_DIR@,$CFITSIO_LIB_DIR,;t t s,@CFITSIO_LIB_SPEC@,$CFITSIO_LIB_SPEC,;t t s,@astrotcl_VERSION@,$astrotcl_VERSION,;t t s,@astrotcl_LIB_FILE@,$astrotcl_LIB_FILE,;t t s,@astrotcl_BUILD_LIB_SPEC@,$astrotcl_BUILD_LIB_SPEC,;t t s,@astrotcl_BUILD_DIR@,$astrotcl_BUILD_DIR,;t t s,@astrotcl_LIB_SPEC@,$astrotcl_LIB_SPEC,;t t s,@astrotcl_SRC_DIR@,$astrotcl_SRC_DIR,;t t s,@astrotcl_PKG_OBJECTS@,$astrotcl_PKG_OBJECTS,;t t s,@MERGE_OBJECTS@,$MERGE_OBJECTS,;t t s,@SHLIB_LD_CXX_LIBS@,$SHLIB_LD_CXX_LIBS,;t t s,@PKG_SOURCES@,$PKG_SOURCES,;t t s,@PKG_OBJECTS@,$PKG_OBJECTS,;t t s,@CLEANFILES@,$CLEANFILES,;t t s,@TCL_INCLUDES@,$TCL_INCLUDES,;t t s,@TK_INCLUDES@,$TK_INCLUDES,;t t s,@CXXCPP@,$CXXCPP,;t t s,@TCL_THREADS@,$TCL_THREADS,;t t s,@SHARED_BUILD@,$SHARED_BUILD,;t t s,@AR@,$AR,;t t s,@CELIB_DIR@,$CELIB_DIR,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@SHLIB_SUFFIX@,$SHLIB_SUFFIX,;t t s,@DL_LIBS@,$DL_LIBS,;t t s,@CFLAGS_DEBUG@,$CFLAGS_DEBUG,;t t s,@CFLAGS_OPTIMIZE@,$CFLAGS_OPTIMIZE,;t t s,@CFLAGS_WARNING@,$CFLAGS_WARNING,;t t s,@STLIB_LD@,$STLIB_LD,;t t s,@SHLIB_LD@,$SHLIB_LD,;t t s,@SHLIB_CFLAGS@,$SHLIB_CFLAGS,;t t s,@SHLIB_LD_LIBS@,$SHLIB_LD_LIBS,;t t s,@LDFLAGS_DEBUG@,$LDFLAGS_DEBUG,;t t s,@LDFLAGS_OPTIMIZE@,$LDFLAGS_OPTIMIZE,;t t s,@LD_LIBRARY_PATH_VAR@,$LD_LIBRARY_PATH_VAR,;t t s,@TCL_DBGX@,$TCL_DBGX,;t t s,@CFLAGS_DEFAULT@,$CFLAGS_DEFAULT,;t t s,@LDFLAGS_DEFAULT@,$LDFLAGS_DEFAULT,;t t s,@MAKE_LIB@,$MAKE_LIB,;t t s,@MAKE_SHARED_LIB@,$MAKE_SHARED_LIB,;t t s,@MAKE_STATIC_LIB@,$MAKE_STATIC_LIB,;t t s,@MAKE_STUB_LIB@,$MAKE_STUB_LIB,;t t s,@RANLIB_STUB@,$RANLIB_STUB,;t t s,@TCLSH_PROG@,$TCLSH_PROG,;t t s,@WISH_PROG@,$WISH_PROG,;t t s,@rtd_LIB_FILE@,$rtd_LIB_FILE,;t t s,@rtd_BUILD_LIB_SPEC@,$rtd_BUILD_LIB_SPEC,;t t s,@rtd_BUILD_DIR@,$rtd_BUILD_DIR,;t t s,@rtd_LIB_SPEC@,$rtd_LIB_SPEC,;t t s,@rtd_PKG_OBJECTS@,$rtd_PKG_OBJECTS,;t t s,@rtd_SRC_DIR@,$rtd_SRC_DIR,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_lines=48 ac_sed_frag=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_lines # Line after last line for current file. ac_more_lines=: ac_sed_cmds= while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag else sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag fi if test ! -s $tmp/subs.frag; then ac_more_lines=false else # The purpose of the label and of the branching condition is to # speed up the sed processing (if there are no `@' at all, there # is no need to browse any of the substitutions). # These are the two extra sed commands mentioned above. (echo ':t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" else ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" fi ac_sed_frag=`expr $ac_sed_frag + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_lines` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi fi # test -n "$CONFIG_FILES" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_builddir$INSTALL ;; esac if test x"$ac_file" != x-; then { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} rm -f "$ac_file" fi # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then configure_input= else configure_input="$ac_file. " fi configure_input=$configure_input"Generated from `echo $ac_file_in | sed 's,.*/,,'` by configure." # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo "$f";; *) # Relative if test -f "$f"; then # Build tree echo "$f" elif test -f "$srcdir/$f"; then # Source tree echo "$srcdir/$f" else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s,@configure_input@,$configure_input,;t t s,@srcdir@,$ac_srcdir,;t t s,@abs_srcdir@,$ac_abs_srcdir,;t t s,@top_srcdir@,$ac_top_srcdir,;t t s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t s,@builddir@,$ac_builddir,;t t s,@abs_builddir@,$ac_abs_builddir,;t t s,@top_builddir@,$ac_top_builddir,;t t s,@abs_top_builddir@,$ac_abs_top_builddir,;t t s,@INSTALL@,$ac_INSTALL,;t t " $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out rm -f $tmp/stdin if test x"$ac_file" != x-; then mv $tmp/out $ac_file else cat $tmp/out rm -f $tmp/out fi done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi chmod ugo+rx rtd skycat-3.1.2-starlink-1b/rtd/configure.in000066400000000000000000000226271215713201500202500ustar00rootroot00000000000000# E.S.O. - VLT project # $Id: configure.in,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is used with GNU autoconf to generate a configure script # # usage: % autoconf # only if configure.in changed # % configure # % make # % make install # # who when what # -------------- -------- --------------------------------------------- # Allan Brighton 15/12/05 Rewrote using TCL TEA standard # ----------------------------------------------------------------------- #----------------------------------------------------------------------- # Sample configure.in for Tcl Extensions. The only places you should # need to modify this file are marked by the string __CHANGE__ #----------------------------------------------------------------------- #----------------------------------------------------------------------- # __CHANGE__ # Set your package name and version numbers here. # # This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION # set as provided. These will also be added as -D defs in your Makefile # so you can encode the package version directly into the source files. #----------------------------------------------------------------------- AC_INIT([rtd], [3.2.1]) #-------------------------------------------------------------------- # Call TEA_INIT as the first TEA_ macro to set up initial vars. # This will define a ${TEA_PLATFORM} variable == "unix" or "windows" # as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE. #-------------------------------------------------------------------- TEA_INIT([3.4]) #-------------------------------------------------------------------- # Load the tclConfig.sh file #-------------------------------------------------------------------- TEA_PATH_TCLCONFIG TEA_LOAD_TCLCONFIG #-------------------------------------------------------------------- # Load the tkConfig.sh file if necessary (Tk extension) #-------------------------------------------------------------------- TEA_PATH_TKCONFIG TEA_LOAD_TKCONFIG #----------------------------------------------------------------------- # Handle the --prefix=... option by defaulting to what Tcl gave. # Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER. #----------------------------------------------------------------------- TEA_PREFIX #----------------------------------------------------------------------- # Standard compiler checks. # This sets up CC by using the CC env var, or looks for gcc otherwise. # This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create # the basic setup necessary to compile executables. #----------------------------------------------------------------------- TEA_SETUP_COMPILER #-------------------------------------------------------------------- # Do application specific checks (see aclocal.m4) #-------------------------------------------------------------------- RTD_CONFIG #----------------------------------------------------------------------- # __CHANGE__ # Specify the C source files to compile in TEA_ADD_SOURCES, # public headers that need to be installed in TEA_ADD_HEADERS, # stub library C source files to compile in TEA_ADD_STUB_SOURCES, # and runtime Tcl library files in TEA_ADD_TCL_SOURCES. # This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS # and PKG_TCL_SOURCES. #----------------------------------------------------------------------- TEA_ADD_SOURCES([${csources}]) TEA_ADD_HEADERS([${cheaders}]) TEA_ADD_INCLUDES([${cincludes}]) if test $MERGED = yes ; then TEA_ADD_LIBS([${BLT_LIB_SPEC} ${CFITSIO_LIB_SPEC}]) else TEA_ADD_LIBS([$astrotcl_BUILD_LIB_SPEC $tclutil_BUILD_LIB_SPEC ${BLT_LIB_SPEC} ${CFITSIO_LIB_SPEC}]) fi TEA_ADD_CFLAGS([]) TEA_ADD_STUB_SOURCES([]) TEA_ADD_TCL_SOURCES([${tclsources}]) #-------------------------------------------------------------------- # __CHANGE__ # A few miscellaneous platform-specific items: # # Define a special symbol for Windows (BUILD_sample in this case) so # that we create the export library with the dll. # # Windows creates a few extra files that need to be cleaned up. # You can add more files to clean if your extension creates any extra # files. # # TEA_ADD_* any platform specific compiler/build info here. #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" ; then AC_DEFINE(BUILD_rtd, 1, [Build windows export dll]) CLEANFILES="*.lib *.dll *.exp *.ilk *.pdb vc*.pch" #TEA_ADD_SOURCES([win/winFile.c]) #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"]) else CLEANFILES="" #TEA_ADD_SOURCES([unix/unixFile.c]) #TEA_ADD_LIBS([-lsuperfly]) fi AC_SUBST(CLEANFILES) #------------------------------------------------------------------------ # See if we can include tkCanvas.h, an internal tk header file needed # to work around a problem with clipping canvas coordinates on large # images. #------------------------------------------------------------------------ if test -f $TK_SRC_DIR/generic/tkCanvas.h ; then AC_DEFINE(HAVE_TKCANVAS_H, 1, [See if we can include tkCanvas.h, an internal tk header]) TEA_ADD_INCLUDES([-I$TK_SRC_DIR/generic]) fi #-------------------------------------------------------------------- # __CHANGE__ # Choose which headers you need. Extension authors should try very # hard to only rely on the Tcl public header files. Internal headers # contain private data structures and are subject to change without # notice. # This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG #-------------------------------------------------------------------- TEA_PUBLIC_TCL_HEADERS #TEA_PRIVATE_TCL_HEADERS TEA_PUBLIC_TK_HEADERS #TEA_PRIVATE_TK_HEADERS TEA_PATH_X #-------------------------------------------------------------------- # Check whether --enable-threads or --disable-threads was given. # This auto-enables if Tcl was compiled threaded. #-------------------------------------------------------------------- TEA_ENABLE_THREADS #-------------------------------------------------------------------- # The statement below defines a collection of symbols related to # building as a shared library instead of a static library. #-------------------------------------------------------------------- TEA_ENABLE_SHARED #-------------------------------------------------------------------- # This macro figures out what flags to use with the compiler/linker # when building shared/static debug/optimized objects. This information # can be taken from the tclConfig.sh file, but this figures it all out. #-------------------------------------------------------------------- TEA_CONFIG_CFLAGS #-------------------------------------------------------------------- # Set the default compiler switches based on the --enable-symbols option. #-------------------------------------------------------------------- TEA_ENABLE_SYMBOLS #-------------------------------------------------------------------- # Everyone should be linking against the Tcl stub library. If you # can't for some reason, remove this definition. If you aren't using # stubs, you also need to modify the SHLIB_LD_LIBS setting below to # link against the non-stubbed Tcl library. Add Tk too if necessary. #-------------------------------------------------------------------- # allan: can't use stubs, due to BLT dependency #AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs]) #AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs]) #-------------------------------------------------------------------- # This macro generates a line to use when building a library. It # depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS, # and TEA_LOAD_TCLCONFIG macros above. #-------------------------------------------------------------------- # rtd needs -lXext PKG_LIBS="${PKG_LIBS} -lXext" TEA_MAKE_LIB #-------------------------------------------------------------------- # Determine the name of the tclsh and/or wish executables in the # Tcl and Tk build directories or the location they were installed # into. These paths are used to support running test cases only, # the Makefile should not be making use of these paths to generate # a pkgIndex.tcl file or anything else at extension build time. #-------------------------------------------------------------------- TEA_PROG_TCLSH TEA_PROG_WISH #-------------------------------------------------------------------- # These are for rtdConfig.sh #-------------------------------------------------------------------- rtd_LIB_FILE=${PKG_LIB_FILE} eval pkglibdir="${libdir}" if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then eval rtd_LIB_FLAG="-lrtd${PACKAGE_VERSION}" else eval rtd_LIB_FLAG="-lrtd`echo ${PACKAGE_VERSION} | tr -d .`" fi rtd_BUILD_LIB_SPEC="-L`pwd` ${rtd_LIB_FLAG}" rtd_BUILD_DIR="`pwd`" rtd_LIB_SPEC="-L${pkglibdir} ${rtd_LIB_FLAG}" for i in ${PKG_OBJECTS} ; do rtd_PKG_OBJECTS="$rtd_PKG_OBJECTS ../rtd/$i" done AC_SUBST(rtd_LIB_FILE) AC_SUBST(rtd_BUILD_LIB_SPEC) AC_SUBST(rtd_BUILD_DIR) AC_SUBST(rtd_LIB_SPEC) AC_SUBST(rtd_PKG_OBJECTS) # rtd_SRC_DIR must be a fully qualified path eval rtd_SRC_DIR="$srcdir" rtd_SRC_DIR=`cd "${rtd_SRC_DIR}"; pwd` AC_SUBST(rtd_SRC_DIR) #-------------------------------------------------------------------- # Finally, substitute all of the various values into the Makefile. # You may alternatively have a special pkgIndex.tcl.in or other files # which require substituting th AC variables in. Include these here. #-------------------------------------------------------------------- AC_OUTPUT([Makefile pkgIndex.tcl rtdConfig.sh rtd rtd_version.tcl]) chmod ugo+rx rtd skycat-3.1.2-starlink-1b/rtd/generic/000077500000000000000000000000001215713201500173425ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/rtd/generic/BiasData.C000066400000000000000000000127431215713201500211250ustar00rootroot00000000000000/* * E.S.O. - VLT project * * "@(#) $Id: BiasData.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * BiasData.C - member functions for class BiasData * * BiasData is a class for mananging the bias data which can be * subtracted from the image data * * who when what * -------- -------- ---------------------------------------- * pbiereic 22/03/99 Created * pbiereic 16/10/02 Byte order for shm data * pbiereic 14/09/07 Fixed: BiasData::file keeps the filename in a buffer again */ #include #include "BiasData.h" #include "error.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" BiasData::BiasData() : biasImage_(NULL), idxBias_(0) { for (int i=0; i< MAXBIAS; i++) { biasImages_[i] = NULL; files_[i][0] = '\0'; } clear(0); } /* * return status: selected bias image !loaded, on or off */ int BiasData::status() { if (! biasImage_) return -1; if (biasinfo_.on) return 1; return 0; } /* * switch bias subtraction on */ int BiasData::on() { if (! biasImage_) { error("selected bias image not loaded"); return 1; } biasinfo_.on = 1; return 0; } /* * switch bias subtraction off */ int BiasData::off() { if (! biasinfo_.on) return 1; biasinfo_.on = 0; return 0; } /* * return filename or objectname of a bias image */ char* BiasData::file(int nr) { if (nr < 0 || nr >=MAXBIAS) return '\0'; return &files_[nr][0]; } /* * load bias frame from file */ int BiasData::file(char *file, int nr) { FitsIO* fits = NULL; double bzero, bitpix; // if not '-' (stdin) check that it is a file if (strcmp(file, "-") != 0) { struct stat buf; if (stat(file, &buf) != 0 || S_ISREG(buf.st_mode) == 0) { error("expected a file, but got: ", file); return 1; } } int on = biasinfo_.on; clear(nr); // read the FITS image fits = FitsIO::read(file, O_RDONLY | S_IRUSR); if (!fits || fits->status() != 0) return 1; biasinfo_.usingNetBO = 1; /* * ushort images are a special case since FitsIO writes them * as short image with BZERO=32768. For bias subtraction we need * the true type back. */ fits->get("BITPIX", bitpix); fits->get("BZERO", bzero); if (bitpix == 16 && bzero == 32768) { int width, height; // copy the fits object fits->get("NAXIS1", width); fits->get("NAXIS2", height); int length = width * height * 2; Mem data(length, 0), header; if (data.status() != 0) return 1; FitsIO* fits2 = new FitsIO(width, height, -16, 0.0, 1.0, header, data); if (!fits2 || fits2->status() != 0) return 1; fits2->usingNetBO(BIGENDIAN); memcpy((char *)data.ptr(), (char *)fits->data().ptr(), length); delete fits; // convert short's to ushort's (native byte order) int i = width * height; unsigned short *pus = (unsigned short *)data.ptr(), us; short *pss = (short *)data.ptr(), ss; if (BIGENDIAN) { // native byte order? while (i--) { us = *pus++; *pss++ = (short)(us - 32768); } } else { while (i--) { us = *pus++; *pss++ = SWAP16(us) - 32768; } } biasImages_[nr] = ImageData::makeImage(BIASNAME, fits2 , &biasinfo_, 0); // Remember the byte order (=native) for the image. biasinfo_.usingNetBO = BIGENDIAN; } else { biasImages_[nr] = ImageData::makeImage(BIASNAME, fits , &biasinfo_, 0); } if (! biasImages_[nr]) return 1; if (nr == idxBias_) { biasinfo_.on = on; select(nr); } strcpy(&files_[nr][0], file); return 0; } /* * copy image to a bias frame */ int BiasData::copy(ImageData* image, char* filename, int nr) { if (! image || nr < 0 || nr >=MAXBIAS) return 1; int on = biasinfo_.on; clear(nr); int length = image->data().length(); Mem data(length, 0), header; if (data.status() != 0) return 1; FitsIO* fits = new FitsIO(image->width(), image->height(), image->dataType(), 0.0, 1.0, header, data); if (!fits || fits->status() != 0) return 1; // Remember the byte order for the image. biasinfo_.usingNetBO = image->image().usingNetBO(); fits->usingNetBO(biasinfo_.usingNetBO); biasImages_[nr] = ImageData::makeImage(BIASNAME, fits, &biasinfo_, 0); if (! biasImages_[nr]) return 1; memcpy((char *)data.ptr(), (char *)image->data().ptr(), length); biasImages_[nr]->object(image->object()); strcpy(&files_[nr][0], filename); if (nr == idxBias_) { biasinfo_.on = on; select(nr); } return 0; } /* * select a bias frame */ int BiasData::select(int nr) { if (nr < 0 || nr >= MAXBIAS) return 1; idxBias_ = nr; if (biasImages_[nr] != NULL) { biasImage_ = biasImages_[nr]; biasinfo_.ptr = (char *)biasImage_->image().dataPtr(); biasinfo_.width = biasImage_->image().width(); biasinfo_.height = biasImage_->image().height(); biasinfo_.type = biasImage_->dataType(); biasinfo_.usingNetBO = biasImage_->image().usingNetBO(); } else clear(nr); return 0; } /* * return number for selected bias frame */ int BiasData::select() { if (! biasImages_[idxBias_]) return -1; return idxBias_; } /* * clear bias frame */ void BiasData::clear(int nr) { if (nr < 0 || nr >=MAXBIAS) return; if (nr == idxBias_) { biasImage_ = NULL; biasinfo_.on = 0; biasinfo_.ptr = NULL; biasinfo_.width = 0; biasinfo_.height = 0; biasinfo_.type = -1; biasinfo_.usingNetBO = 0; } files_[nr][0] = '\0'; if (biasImages_[nr]) { delete biasImages_[nr]; biasImages_[nr] = NULL; } } skycat-3.1.2-starlink-1b/rtd/generic/BiasData.h000066400000000000000000000023511215713201500211640ustar00rootroot00000000000000#ifndef _BiasData_h_ #define _BiasData_h_ /* * E.S.O. - VLT project * * "@(#) $Id: BiasData.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * BiasData.h - class definitions for managing bias subtraction * * who when what * -------------- -------- ---------------------------------------- * P. Biereichel 22/03/99 Created */ #include #include #include "ImageData.h" #include "ImageIO.h" #include "Fits_IO.h" // max. number of bias frames #define MAXBIAS 5 #define BIASNAME "Bias" class BiasData { private: ImageData* biasImage_; // current bias image int idxBias_; // index to biasImages_[] ImageData* biasImages_[MAXBIAS]; biasINFO biasinfo_; char files_[MAXBIAS][1024]; public: // constructor, destructor BiasData(); ~BiasData(); int on(); int off(); void clear(int nr); int status(); char* file(int nr); int file(char *file, int nr); int copy(ImageData* image, char *filename, int nr); int select(int nr); int select(); ImageData* image() {return biasImage_;} biasINFO* biasInfo() {return &biasinfo_;} protected: }; #endif /* _BiasData_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/ByteImageData.C000066400000000000000000000035421215713201500221120ustar00rootroot00000000000000/* * E.S.O. - VLT project * * "@(#) $Id: ByteImageData.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * ByteImageData.C - member functions for class ByteImageData * * See the man page ImageData(3) for a complete description of this class * library. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * Peter W. Draper 15/03/99 Blank bin is always 128 * pbiereic 17/02/03 Added 'using namespace std'. * Peter W. Draper 23/06/09 Added parseBlank to get blank value in this type. */ static const char* const rcsId="@(#) $Id: ByteImageData.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; using namespace std; #include #include #include #include #include #include #include "ByteImageData.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" /* * This method is called from the parent class to convert the high and * low cut values to short range. In this case, there is no conversion * needed, since bytes are already in range. */ void ByteImageData::initShortConversion() { scaledLowCut_ = (int)lowCut_; scaledHighCut_ = (int)highCut_; if (haveBlank_) scaledBlankPixelValue_ = 128; } /* * Set the blank value from a given string. Return 1 if successful. */ int ByteImageData::parseBlank(const char* value) { long l; int n = sscanf(value, "%ld", &l); if ( n > 0 ) { blank_ = l; } return n; } /* * Include some standard methods as (cpp macro) templates: * These are methods that are the same for all derived classes of ImageData, * except that they work on a different raw data type */ #define CLASS_NAME ByteImageData #define DATA_TYPE byte #define NTOH(x) (x) #include "ImageTemplates.icc" #undef CLASS_NAME #undef DATA_TYPE #undef NTOH skycat-3.1.2-starlink-1b/rtd/generic/ByteImageData.h000066400000000000000000000051331215713201500221550ustar00rootroot00000000000000// -*-c++-*- #ifndef _ByteImageData_h_ #define _ByteImageData_h_ /* * E.S.O. - VLT project * * "@(#) $Id: ByteImageData.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * ByteImageData.h - class definitions for class ByteImageData * * See the man page ImageData(3) for a complete description of this class * library. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * Peter W. Draper 05/03/98 Added llookup * 14/07/98 Added check for blanks in lookup. * P.Biereichel 22/03/99 Added parameters for bias frame */ #include #include "ImageData.h" // This class is used for images where the raw data is made up of bytes class ByteImageData : public ImageData { private: // value of blank pixel, if known (if haveBlankPixel_ is nonzero) long blank_; // get value as unsigned short inline ushort convertToUshort(byte b) { return (ushort)b; } // return X image pixel value for raw image value inline byte lookup(byte b) { if ( !haveBlank_ ) return lookup_[(ushort)b]; if ( b != blank_ ) return lookup_[(ushort)b]; return lookup_[128]; } inline unsigned long llookup(byte b) { if ( !haveBlank_ ) return lookup_[(ushort)b]; if ( b != blank_ ) return lookup_[(ushort)b]; return lookup_[128]; } // return NTOH converted value evtl. subtracted with corresponding bias value byte getVal(byte* p, int idx); int getXsamples(byte *rawImage, int idx, int wbox, byte *samples); int getBsamples(byte *rawImage, int idx, int wbox, byte *samples); int getCsamples(byte *rawImage, int idx, int wbox, byte *samples); byte getMedian(byte *samples, int n); byte getBoxVal(byte *rawImage, int idx, int wbox, byte *samples, int xs); byte getRMS(byte *samples, int n); protected: // convert cut values to short range void initShortConversion(); public: // constructor ByteImageData(const char* name, const ImageIO& imio, int verbose) : ImageData(name, imio, verbose, 256 /* use a smaller lookup table */), blank_(128) { } // return class name as a string virtual const char* classname() { return "ByteImageData"; } // return the data type of the raw data int dataType() {return BYTE_IMAGE;} // return true if the data type is signed int isSigned() {return 0;} // return a copy of this object ImageData* copy() {return new ByteImageData(*this);} // include declarations for methods that differ only in raw data type # include "ImageTemplates.h" }; #endif /* _ByteImageData_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/ColorMapInfo.C000066400000000000000000000116311215713201500220000ustar00rootroot00000000000000/* * E.S.O. - VLT project * * "@(#) $Id: ColorMapInfo.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * ColorMapInfo.C - member routines for class ColorMapInfo * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * Peter W. Draper 14/07/98 Changed interpolate to get last colorcell * (so pure white/black is available in principle). * pbiereic 17/02/03 Added 'using namespace std'. Removed ::std specs. * Peter W. Draper 28/05/08 Stop leak of name from ::get. */ static const char* const rcsId="@(#) $Id: ColorMapInfo.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; using namespace std; #include #include #include #include #include #include #include "ColorMapInfo.h" #include "util.h" #include "error.h" // linked list, cache of colormap files ColorMapInfo* cmaps_ = NULL; /* * constructor - arguments are the name of the colormap * and an array of RGB color values. Both are assumed to * have been allocated. */ ColorMapInfo::ColorMapInfo(char* name, RGBColor* rgb) : name_(name), rgb_(rgb), next_(cmaps_), nameowner_(0) { // make this the head of the list of colormaps cmaps_ = this; } /* * constructor - main arguments are the name of the colormap and an array of * RGB color values. Both are assumed to have been allocated, but if nameowner * is 1 then the memory will be freed on destruction. */ ColorMapInfo::ColorMapInfo(char* name, RGBColor* rgb, int nameowner) : name_(name), rgb_(rgb), next_(cmaps_), nameowner_(nameowner) { // make this the head of the list of colormaps cmaps_ = this; } /* * destructor */ ColorMapInfo::~ColorMapInfo() { // remove from list if (this == cmaps_) { cmaps_ = next_; } else { for (ColorMapInfo* m = cmaps_; m; m = m->next_) { if (m->next_ == this) { m->next_ = next_; break; } } } // release the name_ pointer, if we've been given ownership if ( nameowner_ ) { free( name_ ); } } /* * read a ColorMap from a file and return a new instance for it */ ColorMapInfo* ColorMapInfo::get(char* filename) { // just use the basename to identify the colormap char* name = strdup(fileBasename(filename)); // see if we read this one already ColorMapInfo* m; for (m = cmaps_; m; m = m->next()) if (strcmp(m->name(), name) == 0) break; if (m) { free(name); return m; } // have to read in file ifstream f(filename); if (! f) { error("could not open colormap file: ", filename); free(name); return (ColorMapInfo*) NULL; } RGBColor* rgb = new RGBColor[MAX_COLOR]; if (! rgb) { error("could not allocate colormap"); free(name); return (ColorMapInfo*) NULL; } for (int i = 0; i < MAX_COLOR; i++) { f >> rgb[i]; } if (! f) { error("error reading colormap file: ", filename); free(name); return (ColorMapInfo*) NULL; } m = new ColorMapInfo(name, rgb, 1); if (! m) error("could not create colormap"); return m; } /* * write a list of loaded colormap files to the given stream * separated by spaces */ void ColorMapInfo::list(ostream& os) { ColorMapInfo* m; for (m = cmaps_; m; m = m->next()) os << m->name() << " "; } /* * set the red, green and blue values for the the colormap * and interpolate based on the count of available colors */ void ColorMapInfo::interpolate(XColor* colorCells, int colorCount) { int index; for (int i=0; i= colorCount) index = colorCount - 1; dest[i].red = src[index].red; dest[i].green = src[index].green; dest[i].blue = src[index].blue; } } skycat-3.1.2-starlink-1b/rtd/generic/ColorMapInfo.h000066400000000000000000000050021215713201500220400ustar00rootroot00000000000000// -*-c++-*- #ifndef _ColorMapInfo_h_ #define _ColorMapInfo_h_ /* * E.S.O. - VLT project * "@(#) $Id: ColorMapInfo.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * ColorMapInfo.h - class definitions for reading in color map files * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * pbiereic 17/02/03 Added 'using namespace std'. Removed ::std specs. * Peter W. Draper 19/09/07 Added rgbcolor member. */ using namespace std; #include #include #include #include /* color management */ enum {MAX_COLOR=256}; /* work with 8bit color */ // RGB color info struct RGBColor { float red, green, blue; // read an RGB entry friend istream& operator>>(istream& is, RGBColor& rgb) { is >> rgb.red >> rgb.green >> rgb.blue; return is; } }; // one of these is used to hold colormap info for each colormap // file read class ColorMapInfo { private: char* name_; // filename RGBColor* rgb_; // array of RGB values ColorMapInfo* next_; // pointer to next colormap int nameowner_; // true if we "own" the name_ memory pointer // copy constructor (not defined) ColorMapInfo(const ColorMapInfo&); public: // constructor - arguments are the name of the colormap // and an array of RGB color values. Both are assumed to // have been allocated. If second form we take ownership // of the name memory (allocated by malloc). ColorMapInfo(char* name, RGBColor* rgb); ColorMapInfo(char* name, RGBColor* rgb, int nameowner); // destructor ~ColorMapInfo(); // create and return ColorMap from a file description static ColorMapInfo* get(char* filename); // write a list of colormap files static void list(ostream&); // member access const char* name() const {return name_;} ColorMapInfo* next() {return next_;} const RGBColor* rgbcolor() {return rgb_;} // set the red, green and blue values from the colormap data // and interpolate based on the count of available colors void interpolate(XColor* colorCells, int colorCount); // rotate the colormap by the given amount void rotate(int amount, XColor* src, XColor* dest, int colorCount); // shift the colormap by the given amount void shift(int amount, XColor* src, XColor* dest, int colorCount); }; #endif /* _ColorMapInfo_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/CompoundImageData.C000066400000000000000000000642331215713201500227770ustar00rootroot00000000000000/* * E.S.O. - VLT project * * "@(#) $Id" * * CompoundImageData.C - member functions for class CompoundImageData * * This class is used for images that are divided into multiple HDUs * (FITS header/data units, FITS image extensions). The idea here * is to make it appear to the using class as if there is a single image. * The image extensions are combined based on the WCS information in * each header. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 14/02/00 Created * Peter W. Draper 14/12/05 Remove local knowledge of FitsIO class so * that other ImageIORep implementations can be * used. * 25/04/08 Add growAndShrink(). * 19/01/12 change setCutLevels to define highCut_ and * lowCut_ to be the same as the first extension, * otherwise we assume primary HDU has same bscale * and bzero. */ #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" #include "ImageIO.h" #include "error.h" #include "CompoundImageData.h" /* * Constructor: Create an array of image objects, one for each * image extension and initialize the image size to be the * complete size of all of the images. * * name - the name of the image (for logging/debugging * imio - the object representing the image file * hduList - the list of image HDU indexes to use * numHDUs - the number of image HDU indexes in hduList * biasInfo - used when calculating bias info * verbose - print diagnostic messages */ CompoundImageData::CompoundImageData(const char* name, const ImageIO& imio, int* hduList, int numHDUs, biasINFO* biasInfo, int verbose) : ImageData(name, imio, verbose) { numImages_ = numHDUs; images_ = new ImageData*[numImages_]; minX_ = maxX_ = minY_ = maxY_ = 0.; ImageIORep* imioRep = (ImageIORep*)imio.rep(); // create images and note the min/max coordinates for(int i = 0; i < numImages_; i++) { // need a (reference counted) copy so we can change the current HDU ImageIORep* imioRepExt = imioRep->copy(); if ((status_ = imioRepExt->setHDU(hduList[i])) != 0) { delete imioRepExt; return; // error } images_[i] = ImageData::makeImage(name, imioRepExt, biasInfo, verbose); double x0 = -images_[i]->crpix1_, y0 = -images_[i]->crpix2_, x1 = x0 + images_[i]->width_ - 1, y1 = y0 + images_[i]->height_ - 1; if (i == 0) { minX_ = min(x0, x1); minY_ = min(y0, y1); maxX_ = max(x0, x1); maxY_ = max(y0, y1); } else { minX_ = min(min(x0, x1), minX_); minY_ = min(min(y0, y1), minY_); maxX_ = max(max(x0, x1), maxX_); maxY_ = max(max(y0, y1), maxY_); } } // reset image dimensions to imclude the entire collection of images dispWidth_ = width_ = int(maxX_ - minX_ + 1); dispHeight_ = height_ = int(maxY_ - minY_ + 1); area_ = width_*height_; } /* * copy constructor * * Note that the classes managing the image data (ImageIO, Mem, ...) use * reference counting, so that the data is not actually copied normally, * but shared as long as possible. */ CompoundImageData::CompoundImageData(const CompoundImageData& im) : ImageData(im), numImages_(im.numImages_), minX_(im.minX_), maxX_(im.maxX_), minY_(im.minY_), maxY_(im.maxY_) { // copy the images_ array images_ = new ImageData*[numImages_]; for(int i = 0; i < numImages_; i++) { images_[i] = im.images_[i]->copy(); } } /* * Destructor: delete the image array. */ CompoundImageData::~CompoundImageData() { for(int i = 0; i < numImages_; i++) { delete images_[i]; } delete[] images_; } /* * Set x0, y0, x1, y1 to the bounds of the given image data in FITS image coordinates. */ void CompoundImageData::getBounds(ImageData* imageData, double& x0, double& y0, double& x1, double& y1) { x0 = -imageData->crpix1_ - minX_; y0 = -imageData->crpix2_ - minY_; x1 = x0 + imageData->width_ - 1; y1 = y0 + imageData->height_ - 1; } /* * Specify a new lookup table to use for this image and its size. * Redefined from parent class to pass on to each image extension. */ int CompoundImageData::lookupTable(LookupTable lookup) { if (ImageData::lookupTable(lookup) != 0) return 1; // error for(int i = 0; i < numImages_; i++) { if (images_[i]->lookupTable(lookup) != 0) return 1; // error } return 0; } /* * This method is used to save color information for pos. later use * * Note that the first and last colors are reserved for special use: * The first color should be black and the last color can be set to * some saturation color. */ void CompoundImageData::setColors(int ncolors, unsigned long* colors) { ImageData::setColors(ncolors, colors); for(int i = 0; i < numImages_; i++) { images_[i]->setColors(ncolors, colors); } } /* * Set the destination XImage buffer and the dimensions of the XImage in * pixels. (This class copies the rawimage to xImage, doing any necessary * transformations along the way.) */ void CompoundImageData::setXImage(ImageDisplay* xImage) { ImageData::setXImage(xImage); for(int i = 0; i < numImages_; i++) { images_[i]->setXImage(xImage); } } /* * Save the contents of the given region of this image to the given file. * The coordinates are expected in image pixel units. */ int CompoundImageData::write(const char* filename, double rx0, double ry0, double rx1, double ry1) { // XXX to be implemented return error("Sorry: saving a region is not supported for compound images yet"); } /* * Copy the cutlevels, scale, rotate and flip parameters from the * given struct to this image (see saveParams()). * If restoreCutLevels is non-zero (default), the saved cut-levels are restored * otherwise they are not and the cutlevels are left as they were * initialized (to the approx. min/max pixel value). * * Redefined from parent class to propagate to the image extensions. */ void CompoundImageData::restoreParams(ImageDataParams& p, int restoreCutLevels) { if (p.status != 0) return; // don't use if status != 0 ImageData::restoreParams(p, restoreCutLevels); for(int i = 0; i < numImages_; i++) { images_[i]->restoreParams(p, restoreCutLevels); } } /* * create the color scale lookup table for the image. * The arguments are: * * ncolors - the number of available colors * colors - an array of pixel values for the available colors * * The color scaling algorithm used is determined by the value of * colorScaleType_, which defaults to LINEAR_SCALE. */ void CompoundImageData::colorScale(int ncolors, unsigned long* colors) { int i; for(i = 0; i < numImages_; i++) { if (i == 0) { scaledLowCut_ = images_[i]->scaledLowCut_; scaledHighCut_ = images_[i]->scaledHighCut_; } else { scaledLowCut_ = min(images_[i]->scaledLowCut_, scaledLowCut_); scaledHighCut_ = max(images_[i]->scaledHighCut_, scaledHighCut_); } } ImageData::colorScale(ncolors, colors); for(i = 0; i < numImages_; i++) { images_[i]->lookupTable(lookup_); } } /* * set the scaling (zoom) factor */ void CompoundImageData::setScale(int xScale, int yScale) { ImageData::setScale(xScale, yScale); for(int i = 0; i < numImages_; i++) { images_[i]->setScale(xScale, yScale); } } /* * rotate the image by the given angle * (actually exchange the x/y axes if angle not 0) */ void CompoundImageData::rotate(int angle) { ImageData::rotate(angle); for(int i = 0; i < numImages_; i++) { images_[i]->rotate(angle); } } /* * flip the image X axis if b is non-zero */ void CompoundImageData::flipX(int b) { ImageData::flipX(b); for(int i = 0; i < numImages_; i++) { images_[i]->flipX(b); } } /* * flip the image Y axis if b is non-zero */ void CompoundImageData::flipY(int b) { ImageData::flipY(b); for(int i = 0; i < numImages_; i++) { images_[i]->flipY(b); } } /* * set the cut levels to the given values. * If scaled is 1, the low and high values should be already "scaled" with * bzero and bscale. */ void CompoundImageData::setCutLevels(double low, double high, int scaled) { ImageData::setCutLevels(low, high, scaled); for(int i = 0; i < numImages_; i++) { images_[i]->setCutLevels(low, high, scaled); } // Unscaling of cuts uses first extension HDU methods, so match those // (otherwise we assume primary HDU has same bscale and bzero as first // extension). if (scaled) { highCut_ = images_[0]->unScaleValue(high); lowCut_ = images_[0]->unScaleValue(low); } else { highCut_ = high; lowCut_ = low; } } /* Just pass on to the parent class and image extensions */ void CompoundImageData::subsample(int b) { ImageData::subsample(b); for(int i = 0; i < numImages_; i++) { images_[i]->subsample(b); } } /* Just pass on to the parent class and image extensions */ void CompoundImageData::sampmethod(int b) { ImageData::sampmethod(b); for(int i = 0; i < numImages_; i++) { images_[i]->sampmethod(b); } } /* Just pass on to the parent class and image extensions */ void CompoundImageData::verbose(int b) { ImageData::verbose(b); for(int i = 0; i < numImages_; i++) { images_[i]->verbose(b); } } /* Just pass on to the parent class and image extensions */ void CompoundImageData::name(const char* name) { ImageData::name(name); for(int i = 0; i < numImages_; i++) { images_[i]->name(name); } } /* Just pass on to the parent class and image extensions */ void CompoundImageData::object(const char* object) { ImageData::object(object); for(int i = 0; i < numImages_; i++) { images_[i]->object(object); } } /* * Return non-zero if the rectangle given by (ax0,ay0 ax1,ay1) intersects * the rectangle given by (bx0,by0 bx1,by1). */ inline int intersects(double ax0, double ay0, double ax1, double ay1, double bx0, double by0, double bx1, double by1) { return !((ax1 <= bx0) || (ay1 <= by0) || (ax0 >= bx1) || (ay0 >= by1)); } /* * Return non-zero if the point given by (x,y) intersects * the rectangle given by (x0,y0 x1,y1). */ inline int intersects(double x, double y, double x0, double y0, double x1, double y1) { return !((x <= x0) || (y <= y0) || (x >= x1) || (y >= y1)); } /* * Update the X image area starting at the given offset and continuing * to the end of the raw image or the end of the X image data, which * ever comes first. * * This method is used when the X Image is the same size as the visible * window (or image, if smaller) and displays the part of the image at * some x,y scroll offset. * * Redefined from the parent class to always clear teh XImage. */ void CompoundImageData::updateOffset(double x, double y) { if (!xImage_ || width_ <= 0 || height_ <= 0 || (update_pending_ == 0 && x == prevX_ && y == prevY_)) return; if (clear_) { // temp clear image xImage_->clear(color0_); clear_ = 0; return; } prevX_ = x; prevY_ = y; int x0 = int(x), y0 = int(y), x1 = width_-1, y1 = height_-1, dest_x = 0, dest_y = 0; // handle case where x0,y0 are negative (i.e.: image starts in the // middle of the window somewhere rather than the window starting at // the middle of the image) if (x < 0) { dest_x = -x0 + 1; x0 = 0; } if (y < 0) { dest_y = -y0 + 1; y0 = 0; } // always clear the XImage, since there may be different dest offsets xImage_->clear(color0_); // copy raw to X image while doing transformations toXImage(x0, y0, x1, y1, dest_x, dest_y); } /* * copy the raw image to the xImage, doing any transformations as * necessary. * * The arguments x0, y0, x1 and y1 are the bounding box of the region of * the raw image that needs to be copied (origin at (0,0)) * * dest_x and dest_y give the coordinates in the XImage where copying * should start. These are normally either (-x0,-y0) or (0,0). * * This method adjust the coordinates, if necessary and then calls * the virtual methods in derived classes to do the real work. * * As a side effect, the member variables x0_, y0_, x1_, y1_ are set to * the bounding box of the visible area of the image in FITS image * coordinates. */ void CompoundImageData::toXImage(int x0, int y0, int x1, int y1, int dest_x, int dest_y) { // set and clip the member variables x0_, y0_, x1_, y1_ setBounds(x0, y0, x1, y1, dest_x, dest_y); // Draw each image extension as needed for(int i = 0; i < numImages_; i++) { // Get the offset of the image extension in the complete image (dx, dy). // Note: crpix is by convention negative, y-axis reversed (origin at (1,1) ???), // but here we need positive values, with origin at (0,0) //int dx = -int(images_[i]->crpix1_) + 1, // dy = -int(images_[i]->crpix2_) + 1; int w = images_[i]->width_, h = images_[i]->height_; int dx =(int)(-images_[i]->crpix1_ - minX_), dy =(int)(-images_[i]->crpix2_ - minY_); if (! flipY_) dy = height_ - dy - h; // y-axis reversed here if (flipX_) dx = width_ - dx - w; if (intersects(x0_, y0_, x1_, y1_, dx, dy, dx+w-1, dy+h-1)) { int idest_x = dest_x + max(dx - x0_, 0); int idest_y = dest_y + max(dy - y0_, 0); // translate to the coordinates of the image extension x0 = max(x0_ - dx, 0); y0 = max(y0_ - dy, 0); x1 = w - 1; y1 = h - 1; if (x1 > x0 && y1 > y0) { images_[i]->toXImage(x0, y0, x1, y1, idest_x, idest_y); } } } // x0_, y0_, x1_ and y1_ are the coordinates of the visible part of // the image and are needed later for setting cut levels and calculating // the min/max pixel for the displayed image area. The display routines // called above (rawToXImage, grow, shrink) expect the coordinates to have // the origin at upper left (0,0) (XImage type coordinates), while the rest // of the code deals with FITS image coordinates (origin at lower left // (1, 1) at mag 1). flip(x0_, y0_, x1_, y1_); update_pending_ = 0; } /*---------------------------------------------------------------------------- * The methods below access the actual image data and are normally implemented * in ImageTemplates.icc. Here we need to define the methods to access the * correct image extensions, based on the visible area, or requested area * of the image. *----------------------------------------------------------------------------*/ /* * Scan the image to find the min and max values and set the member * variables accordingly. To save time, only the visible area of the * image is examined (x0_, y0_, x1_ and y1_ are set each time the * image is updated, however they are initially set to the entire * image). * The result is that the member variables minValue_ and maxValue_ * are set. */ void CompoundImageData::getMinMax() { int n = 0; for(int i = 0; i < numImages_; i++) { double x0, y0, x1, y1; getBounds(images_[i], x0, y0, x1, y1); if (intersects(x0_, y0_, x1_, y1_, x0, y0, x1, y1)) { images_[i]->getMinMax(); if (n++ == 0) { minValue_ = images_[i]->minValue_; maxValue_ = images_[i]->maxValue_; } else { minValue_ = min(images_[i]->minValue_, minValue_); maxValue_ = max(images_[i]->maxValue_, maxValue_); } } } } /* * print the coordinates and raw data value at the given x,y image * coords to the buffer * * A "-" is printed if the x,y coords are out of range. * "blank" is printed if the pixel is blank. */ char* CompoundImageData::getValue(char* buf, double x, double y) { for(int i = 0; i < numImages_; i++) { // get bounding box of this image extension double x0, y0, x1, y1; getBounds(images_[i], x0, y0, x1, y1); if (intersects(x, y, x0, y0, x1, y1)) { return images_[i]->getValue(buf, x-x0, y-y0); } } sprintf(buf, "%.1f %.1f -", x, y); return buf; } /* * return the value at the x,y image coords as a double. * * The input x,y is assumed to be in image coords. * If the coords are out of range, 0.0 is returned. */ double CompoundImageData::getValue(double x, double y) { for(int i = 0; i < numImages_; i++) { // get bounding box of this image extension double x0, y0, x1, y1; getBounds(images_[i], x0, y0, x1, y1); if (intersects(x, y, x0, y0, x1, y1)) { return images_[i]->getValue(x-x0, y-y0); } } return 0.0; } /* * print the X, Y coordinates, raw data value and World Coordinates * at the given x,y image coords to the given buffers. * * rx and ry are the image coordinates to use to access the pixel value. This might * be different than x,y, since x,y are the logical image coordinates, assuming the * image starts at 1,1, which might not actually be the case. * * A blank value is printed if the rx,ry coords are out of range. * * note: x, y and rx,ry are expected in image coords, while in the result, * xStr and yStr are in "chip" coords, since they should be displayed. */ void CompoundImageData::getValues(double x, double y, double rx, double ry, char* xStr, char* yStr, char* valueStr, char* raStr, char* decStr, char* equinoxStr) { *valueStr = '\0'; *xStr = '\0'; *yStr = '\0'; *raStr = '\0'; *decStr = '\0'; *equinoxStr = '\0'; for(int i = 0; i < numImages_; i++) { // get bounding box of this image extension double x0, y0, x1, y1; getBounds(images_[i], x0, y0, x1, y1); if (intersects(rx, ry, x0, y0, x1, y1)) { images_[i]->getValues(x-x0, y-y0, rx-x0, ry-y0, xStr, yStr, valueStr, raStr, decStr, equinoxStr); // display global chip coords for x and y double cx = x, cy = y; imageToChipCoords(cx, cy); sprintf(xStr, "%.1f", cx); sprintf(yStr, "%.1f", cy); return; } } } /* * Fill the given array with the pixel values surrounding the given point. * nrows and ncols give the dimensions of the array. Any values that are outside * of the image or are blank (BLANK keyword) are set to -HUGE_VAL. * * Note: it is assumed that nrows and ncols are odd numbers and that the array * is one row and column larger (nrows+1 x ncols+1), so that it can hold the * X and Y index headings. * * rx and ry are the image coordinates to use to access the pixel value. This might * be different than x,y, since x,y are the logical image coordinates, assuming the * image starts at 1,1, which might not actually be the case. * * note: x, y and rx,ry are expected in image coords, however the coordinates in the * result are "chip" coords, since they should be displayed. */ void CompoundImageData::getValues(double x, double y, double rx, double ry, double* ar, int nrows, int ncols, int flag) { // clear out array first int nn = (nrows+1)*(ncols+1); int i; for(i = 0; i < nn; i++) ar[i] = -HUGE_VAL; for(i = 0; i < numImages_; i++) { // get bounding box of this image extension double x0, y0, x1, y1; getBounds(images_[i], x0, y0, x1, y1); double m = ncols/2, n = nrows/2; if (intersects(rx-m, ry-n, rx+m, ry+n, x0, y0, x1, y1)) { images_[i]->getValues(x-x0, y-y0, rx-x0, ry-y0, ar, nrows, ncols, 1); } } } /* * Fill the given array with the pixel values (converted to floats as needed) * at the given x,y image pos, width and height. * * The array should be large enough for at least (w x h) floats. * * Any values that are outside of the image are set to blank or 0, if there * is no blank pixel value defined (If "flag" is non-zero, values outside * the image are not changed). * * Note: x and y are expected in image coordinates */ void CompoundImageData::getValues(double x, double y, int w, int h, float* ar, int flag) { // clear out array first int nn = w*h; int i; for(i = 0; i < nn; i++) ar[i] = 0; for(i = 0; i < numImages_; i++) { // get bounding box of this image extension double x0, y0, x1, y1; getBounds(images_[i], x0, y0, x1, y1); double m = w/2, n = h/2; if (intersects(x-m, y-n, x+m, y+n, x0, y0, x1, y1)) { images_[i]->getValues(x-x0, y-y0, w, h, ar, 1); } } } /* * Copy raw image data from this image to the given image data area, * starting at the image coordinates (x, y) and with the dimentions (w,h) * in pixels. Since this is a copy from one raw image to another, no * data conversion is done. */ void CompoundImageData::copyImageArea(void* data, double x, double y, int w, int h) { // XXX to be implemented error("Sorry: copying a region is not supported for compound images yet"); } /* * copy the raw image to the xImage * * The arguments x0, y0, x1 and y1 are the bounding box of the region of * the raw image that needs to be copied. * * dest_x and dest_y give the coordinates in the XImage where copying * should start. These are normally either (x0,y0) or (0,0). */ void CompoundImageData::rawToXImage(int x0, int y0, int x1, int y1, int dest_x, int dest_y) { return; // see toXImage() above } /* * This method is called to magnify the image by factors >= 2 * The arguments x0, y0, x1 and y1 are the bounding box of the region * that needs to be copied. * * dest_x and dest_y give the coordinates in the XImage where copying * should start. These are normally either (x0,y0) or (0,0). */ void CompoundImageData::grow(int x0, int y0, int x1, int y1, int dest_x, int dest_y) { return; // see toXImage() above } /* * This method is called to scale image when factor have different signs. * The arguments x0, y0, x1 and y1 are the bounding box of the region * that needs to be copied. * * dest_x and dest_y give the coordinates in the XImage where copying * should start. These are normally either (x0,y0) or (0,0). */ void CompoundImageData::growAndShrink(int x0, int y0, int x1, int y1, int dest_x, int dest_y) { return; // see toXImage() above } /* * This method is called to shrink the image. If subsample_ is 1, just * take every nth pixel as a sample, otherwise take the max of the * surrounding pixels * * dest_x and dest_y give the coordinates in the XImage where copying * should start. These are normally either (x0,y0) or (0,0). * * Note: there is a (non-fatal) bug here that shows up when dest_x,dest_y are non-zero, * (the image display gets split or mixed up somehow...) - needs some * testing to see what the cause is. */ void CompoundImageData::shrink(int x0, int y0, int x1, int y1, int dest_x, int dest_y) { return; // see toXImage() above } /* * Set the cut levels using a median filtering algorithm. * To save time, only the visible area of the image is examined * (x0_, y0_, x1_ and y1_ are set each time the image is updated). */ void CompoundImageData::medianFilter() { int n = 0; for(int i = 0; i < numImages_; i++) { double x0, y0, x1, y1; getBounds(images_[i], x0, y0, x1, y1); if (intersects(x0_, y0_, x1_, y1_, x0, y0, x1, y1)) { images_[i]->medianFilter(); if (n++ == 0) { lowCut_ = images_[i]->lowCut_; highCut_ = images_[i]->highCut_; } else { lowCut_ = min(images_[i]->lowCut_, lowCut_); highCut_ = max(images_[i]->highCut_, highCut_); } } } setCutLevels(lowCut_, highCut_, 0); } /* * scan the image to find the distribution of pixel values * and set the cut levels so that the given percent of pixels * are within the low and high cut values. */ void CompoundImageData::autoSetCutLevels(double percent) { int n = 0; for(int i = 0; i < numImages_; i++) { double x0, y0, x1, y1; getBounds(images_[i], x0, y0, x1, y1); if (intersects(x0_, y0_, x1_, y1_, x0, y0, x1, y1)) { images_[i]->autoSetCutLevels(percent); if (n++ == 0) { lowCut_ = images_[i]->lowCut_; highCut_ = images_[i]->highCut_; } else { lowCut_ = min(images_[i]->lowCut_, lowCut_); highCut_ = max(images_[i]->highCut_, highCut_); } } } setCutLevels(lowCut_, highCut_, 0); } /* * Fill the given array (xyvalues) with statistics about the distribution * of pixels in the visible image area (given by x0_, y0_, x1_, y1_). * xyvalues[n*2+1] is set to the number of pixels with value at or near n. * The factor is used to fit the information in the given size aray. */ void CompoundImageData::getPixDist(int numValues, double* xyvalues, double factor) { for(int i = 0; i < numImages_; i++) { double x0, y0, x1, y1; getBounds(images_[i], x0, y0, x1, y1); if (intersects(x0_, y0_, x1_, y1_, x0, y0, x1, y1)) { images_[i]->getPixDist(numValues, xyvalues, factor); } } } /* * Fill the given histogram with the distribution of pixels in the * visible image area (given by x0_, y0_, x1_, y1_). h.histogram[n] is * set to the number of pixels with a value of n (after conversion to * short if needed). */ void CompoundImageData::getHistogram(ImageDataHistogram& h) { for(int i = 0; i < numImages_; i++) { double x0, y0, x1, y1; getBounds(images_[i], x0, y0, x1, y1); if (intersects(x0_, y0_, x1_, y1_, x0, y0, x1, y1)) { images_[i]->getHistogram(h); } } } /* * If there is a special value for blank pixels, get it. * * Note that the blank pixel value is not scaled by bscale, since we * compare pixels values with this value before scaling. */ void CompoundImageData::initBlankPixel() { for(int i = 0; i < numImages_; i++) { images_[i]->initBlankPixel(); } } /* * initialize conversion from base type to short (trivial in this case) * and scale the low and high cut levels to short range */ void CompoundImageData::initShortConversion() { for(int i = 0; i < numImages_; i++) { images_[i]->initShortConversion(); scaledLowCut_ = images_[i]->scaledLowCut_; scaledHighCut_ = images_[i]->scaledHighCut_; } } /* * return the data type of the raw data */ int CompoundImageData::dataType() { return images_[0]->dataType(); } /* * return true if the data type is signed */ int CompoundImageData::isSigned() { return images_[0]->isSigned(); } /* * return a copy of this object */ ImageData* CompoundImageData::copy() { return new CompoundImageData(*this); } /* * return a blank pixel value. Assume same for all images and cast to * safest type (makes this call practically useless). */ double CompoundImageData::getBlank() { return (double) images_[0]->getBlank(); } skycat-3.1.2-starlink-1b/rtd/generic/CompoundImageData.h000066400000000000000000000152421215713201500230400ustar00rootroot00000000000000// -*-c++-*- #ifndef _CompoundImageData_h_ #define _CompoundImageData_h_ /* * E.S.O. - VLT project * * "@(#) $Id: CompoundImageData.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * CompoundImageData.h - class definitions for class CompoundImageData * * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 14/02/00 Created * Peter W. Draper 15/11/05 Added getBlank() and haveBlank(). * 25/04/08 Add growAndShrink(). */ #include "ImageData.h" /* * This class is used for images that are divided into multiple HDUs * (FITS header/data units, FITS image extensions). The idea here * is to make it appear to the using class as if there is a single image. * The image extensions are combined based on the WCS information in * each header. */ class CompoundImageData : public ImageData { protected: // Number of images in the images_ array int numImages_; // Array of image extensions to be combined to one image for display ImageData** images_; // bounds of the compound image double minX_, minY_, maxX_, maxY_; // value of blank pixel, if known (if haveBlankPixel_ is nonzero) float blank_; protected: // initialize conversion from base type void initShortConversion(); // check args and call virtual methods to copy raw data to xImage virtual void toXImage(int x0, int y0, int x1, int y1, int dest_x, int dest_y); // copy raw data to xImage, pos. with transformations (defined in derived class) void rawToXImage(int x0, int y0, int x1, int y1, int dest_x, int dest_y); void grow(int x0, int y0, int x1, int y1, int dest_x, int dest_y); void shrink(int x0, int y0, int x1, int y1, int dest_x, int dest_y); void growAndShrink(int x0, int y0, int x1, int y1, int dest_x, int dest_y); // Set x0, y0, x1, y1 to the bounds of the given image data in FITS image coordinates. void getBounds(ImageData* imageData, double& x0, double& y0, double& x1, double& y1); public: // constructor CompoundImageData(const char* name, const ImageIO& imio, int* hduList, int numHDUs, biasINFO* biasInfo, int verbose); // copy constructor (called by copy() member function) CompoundImageData(const CompoundImageData&); // destructor ~CompoundImageData(); // return class name as a string virtual const char* classname() { return "CompoundImageData"; } // return a copy of this object ImageData* copy(); // return the data type of the raw data int dataType(); // return true if the data type is signed int isSigned(); // set the image color lookup table int lookupTable(LookupTable); // set the image colormap void setColors(int ncolors, unsigned long* colors); // set the destination X image buffer, dimensions and raw image offset void setXImage(ImageDisplay* xImage); // Save the contents of the given region of this image to the given file. // The coordinates are expected in image pixel units. int write(const char* filename, double x0, double y0, double x1, double y1); // restore saved transformation parameters void restoreParams(ImageDataParams&, int restoreCutLevels = 1); // set the colors to use for the image void colorScale(int ncolors, unsigned long* colors); // set the scaling factor void setScale(int xScale, int yScale); // rotate the image (actually exchange the x/y axes) void rotate(int); // flip the image X axis if b is non-zero void flipX(int b); // flip the image Y axis if b is non-zero void flipY(int b); // manually set the cut levels (if scaled is true, min and max are "bscaled") void setCutLevels(double min, double max, int scaled); // just pass these on to the parent class and image extensions void subsample(int b); void sampmethod(int b); void verbose(int b); void name(const char* name); void object(const char *object); int getNumImages() {return numImages_;} // The methods below access the actual image data and are normally implemented // in ImageTemplates.icc. Here we need to define the methods to access the // correct image extensions, based on the visible area, or requested area // of the image. // calculate min and max pixel values void getMinMax(); // print raw data value at x,y coords to buffer char* getValue(char* buf, double x, double y); // return the value at the x,y coords as a double double getValue(double x, double y); // print the values at the given x,y coords to the buffers for display void getValues(double x, double y, double rx, double ry, char* xStr, char* yStr, char* valueStr, char* raStr, char* decStr, char* equinoxStr); // get array of image pixel values and x,y coords around a point void getValues(double x, double y, double rx, double ry, double* ar, int nrows, int ncols, int flag = 0); // get array of image pixel values at a given offset with given dimensions void getValues(double x, double y, int w, int h, float* ar, int flag = 0); // Copy raw image data from this image to the given image data area, // starting at the image coordinates (x, y) and with the dimentions (w, h) // in pixels. Since this is a copy from one raw image to another, no // data conversion is done. void copyImageArea(void* data, double x, double y, int w, int h); // update image from raw data starting at the given x,y offset void updateOffset(double x, double y); // automatically set the cut levels using median filtering void medianFilter(); // automatically set the cut levels to leave percent visible void autoSetCutLevels(double percent = 98.0); // get array with information about the pixel value distribution void getPixDist(int numValues, double* xyvalues, double factor); // If there is a special value for blank pixels, get it and set the // values of haveBlankPixel_ and scaledBlankPixelValue_. void initBlankPixel(); // Fill the given histogram with the distribution of pixels in the // visible image area void getHistogram(ImageDataHistogram&); // These need to be redefined to use the first image extension, // since the primary doesn't normally define BZERO and BSCALE.. double highCut() {return images_[0]->scaleValue(highCut_);} double lowCut() {return images_[0]->scaleValue(lowCut_);} double minValue() {return images_[0]->scaleValue(minValue_);} double maxValue() {return images_[0]->scaleValue(maxValue_);} // return the blank value. int haveBlank() {return haveBlank_;} double getBlank(); }; #endif /* _CompoundImageData_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/DoubleImageData.C000066400000000000000000000065011215713201500224170ustar00rootroot00000000000000/* * E.S.O. - VLT project * * "@(#) $Id: DoubleImageData.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * DoubleImageData.C - member functions for class DoubleImageData * * who when what * -------------- -------- ---------------------------------------- * Peter W. Draper 30/05/01 Created. * 29/10/07 Add colorScale so that a bin for NaN pixels * is always available (shared with blank). * Peter W. Draper 23/06/09 Added parseBlank to get blank value in this type. * pbiereic 12/08/07 Created * Peter W. Draper 17/05/12 Merged skycat version created by pbiereic. */ #include #include #include #include #include #include #include "DoubleImageData.h" #include "define.h" /* * Convert the given double to short by adding the bias, scaling, * rounding if necessary and checking the range. */ short DoubleImageData::scaleToShort( double d ) { if ( isnan(d) ) { return LOOKUP_BLANK; } // Blank pixel value is is special lookup table position. Note // Starlink uses a special value for floating point too (not a NaN). if ( haveBlank_ ) { if ( blank_ == d ) { return LOOKUP_BLANK; } } short s; d = (d + bias_) * scale_; if (d < 0.0 ) { if( ( d -= 0.5 ) < LOOKUP_MIN ) { s = LOOKUP_MIN; } else { s = (short)d; } } else { if( ( d += 0.5 ) > LOOKUP_MAX) { s = LOOKUP_MAX; } else { s = (short)d; } } return s; } /* * Initialize conversion from base type float to short * and scale the low and high cut levels to short range. * * Method: 2 member variables, bias_ and scale_, are set here and * used later to convert the float raw image data to short, which is * then used as an index in the lookup table: */ void DoubleImageData::initShortConversion() { bias_ = -((lowCut_ + highCut_) * 0.5); if( (highCut_ - lowCut_) > 0.0 ) { scale_ = LOOKUP_WIDTH / (highCut_ - lowCut_); } else { scale_ = 1.0; } scaledLowCut_ = scaleToShort(lowCut_); scaledHighCut_ = scaleToShort(highCut_); scaledBlankPixelValue_ = LOOKUP_BLANK; } /* * Define a scaledBlankPixelValue_ so that we have a blank bin for NaN's * not just blanks (both use same color). */ void DoubleImageData::colorScale(int ncolors, unsigned long* colors) { ImageData::colorScale(ncolors, colors); // Always set value for blank pixel in case we have NaNs, not just // when blank is set. lookup_.setPixelColor( scaledBlankPixelValue_, color0_ ); } /* * Set the blank value from a given string. Return 1 if successful. */ int DoubleImageData::parseBlank(const char* value) { double d; int n = sscanf(value, "%lf", &d); if ( n > 0 ) { blank_ = (double) d; } return n; } /* * Include some standard methods as (cpp macro) templates: * These are methods that are the same for all derived classes of ImageData, * except that they work on a different raw data type */ #define CLASS_NAME DoubleImageData #define DATA_TYPE double #ifndef NTOH # define NTOH(x) SWAP_DOUBLE(x) #endif // return true is the value x is a NAN (define to 0 for non-float types) #define ISNAN(x) isnan(x) #include "ImageTemplates.icc" #undef CLASS_NAME #undef DATA_TYPE #undef NTOH #undef ISNAN skycat-3.1.2-starlink-1b/rtd/generic/DoubleImageData.h000066400000000000000000000061041215713201500224630ustar00rootroot00000000000000// -*-c++-*- /* * E.S.O. - VLT project * * "@(#) $Id: DoubleImageData.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * DoubleImageData.h - class definitions for class DoubleImageData * * who when what * -------------- -------- ---------------------------------------- * Peter W. Draper 30/05/01 Created * 14/11/05 Added bias subtraction members. * Peter W. Draper 29/10/07 Added colorScale * pbiereic 12/08/07 Created * Peter W. Draper 17/05/12 Merged skycat version created by pbiereic. */ #include #include "ImageData.h" // This class is used for images where the raw data is made up of doubles. class DoubleImageData : public ImageData { private: // value of blank pixel, if known (if haveBlankPixel_ is nonzero) double blank_; double bias_; // offset for conversion to short lookup index double scale_; // factor for conversion to short lookup index // local methods used to get short index in lookup table short scaleToShort( double ); // as above, but unsigned inline ushort convertToUshort( double f ) { return ushort( scaleToShort( f ) ); } // Return X image pixel value for raw image value. // Convert the given double image value to byte, scaling to short // first and then using the short value as an index in the color // lookup table. inline byte lookup( double f ) { return lookup_[(ushort)scaleToShort(f)]; } inline unsigned long llookup( double f ) { return lookup_[(ushort)scaleToShort(f)]; } // return NTOH converted value evtl. subtracted with corresponding bias value double getVal(double* p, int idx); protected: // initialize conversion from base type to short, void initShortConversion(); // sprintf format for (x y value) virtual char* getXYValueFmt() {return (char *)"%.1f %.1f %.2f";} // sprintf format for image pixel value virtual char* getValueFmt() {return (char *)"%.2f";} int getXsamples(double *rawImage, int idx, int wbox, double *samples); int getBsamples(double *rawImage, int idx, int wbox, double *samples); int getCsamples(double *rawImage, int idx, int wbox, double *samples); double getMedian(double *samples, int n); double getBoxVal(double *rawImage, int idx, int wbox, double *samples, int xs); double getRMS(double *samples, int n); void colorScale(int ncolors, unsigned long* colors); public: // constructor DoubleImageData(const char* name, const ImageIO& imio, int verbose) : ImageData(name, imio, verbose), blank_(0), bias_(0.0), scale_(1.0) {} // return class name as a string virtual const char* classname() { return "DoubleImageData"; } // return the data type of the raw data int dataType() {return DOUBLE_IMAGE;} // return true if the data type is signed int isSigned() {return 1;} // return a copy of this object ImageData* copy() {return new DoubleImageData(*this);} // include declarations for methods that differ only in raw data type # include "ImageTemplates.h" }; skycat-3.1.2-starlink-1b/rtd/generic/FloatImageData.C000066400000000000000000000065471215713201500222640ustar00rootroot00000000000000/* * E.S.O. - VLT project * * "@(#) $Id: FloatImageData.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * FloatImageData.C - member functions for class FloatImageData * * See the man page RTI(3) for a complete description of this class * library. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * Peter W. Draper 15/03/99 Modified to use LOOKUP_BLANK for blank pixels. * 29/10/07 Add colorScale so that a bin for NaN pixels * is always available (shared with blank). * Peter W. Draper 23/06/09 Added parseBlank to get blank value in this type. */ #include #include #include #include #include #include #include "FloatImageData.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" /* * convert the given float to short by adding the bias, * scaling, rounding if necessary and checking the range */ short FloatImageData::scaleToShort(float d) { if ( isnan(d) ) { return LOOKUP_BLANK; } // Blank pixel value is is special lookup table position. Note // Starlink uses a special value for floating point too (not a NaN). if ( haveBlank_ ) { if ( blank_ == d ) { return LOOKUP_BLANK; } } short s; d = (d + bias_) * scale_; if (d < 0.0 ) { if((d -= 0.5) < LOOKUP_MIN) s = LOOKUP_MIN; else s = (short)d; } else { if((d += 0.5) > LOOKUP_MAX) s = LOOKUP_MAX; else s = (short)d; } return s; } /* * initialize conversion from base type float to short * and scale the low and high cut levels to short range * * Method: 2 member variables, bias_ and scale_, are set here and * used later to convert the float raw image data to short, which is * then used as an index in the lookup table: */ void FloatImageData::initShortConversion() { bias_ = -((lowCut_ + highCut_) * 0.5); if( (highCut_ - lowCut_) > 0.0 ) { scale_ = LOOKUP_WIDTH / (highCut_ - lowCut_); } else { scale_ = 1.0; } scaledLowCut_ = scaleToShort(lowCut_); scaledHighCut_ = scaleToShort(highCut_); scaledBlankPixelValue_ = LOOKUP_BLANK; } /* * Define a scaledBlankPixelValue_ so that we have a blank bin for NaN's * not just blanks (both use same color). */ void FloatImageData::colorScale(int ncolors, unsigned long* colors) { ImageData::colorScale(ncolors, colors); // Always set value for blank pixel in case we have NaNs, not just // when blank is set. lookup_.setPixelColor( scaledBlankPixelValue_, color0_ ); } /* * Set the blank value from a given string. Return 1 if successful. */ int FloatImageData::parseBlank(const char* value) { double d; int n = sscanf(value, "%lf", &d); if ( n > 0 ) { blank_ = (float) d; } return n; } /* * Include some standard methods as (cpp macro) templates: * These are methods that are the same for all derived classes of ImageData, * except that they work on a different raw data type */ #define CLASS_NAME FloatImageData #define DATA_TYPE float #ifndef NTOH # define NTOH(x) SWAP_FLOAT(x) #endif // return true is the value x is a NAN (define to 0 for non-float types) #define ISNAN(x) isnan(x) #include "ImageTemplates.icc" #undef CLASS_NAME #undef DATA_TYPE #undef NTOH #undef ISNAN skycat-3.1.2-starlink-1b/rtd/generic/FloatImageData.h000066400000000000000000000060341215713201500223200ustar00rootroot00000000000000// -*-c++-*- /* * E.S.O. - VLT project * * "@(#) $Id: FloatImageData.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * FloatImageData.h - class definitions for class FloatImageData * * See the man page ImageData(3) for a complete description of this class * library. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * Peter W. Draper 04/03/98 Added llookup * P.Biereichel 22/03/99 Added definitions for bias subtraction * Peter W. Draper 29/10/07 Added colorScale */ #include #include "ImageData.h" // This class is used for images where the raw data is made up of ints class FloatImageData : public ImageData { private: // value of blank pixel, if known (if haveBlankPixel_ is nonzero) float blank_; double bias_; // offset for conversion to short lookup index double scale_; // factor for conversion to short lookup index // local methods used to get short index in lookup table short scaleToShort(float); // as above, but unsigned inline ushort convertToUshort(float f) { return ushort(scaleToShort(f)); } // Return X image pixel value for raw image value. // Convert the given float image value to byte, scaling to short // first and then using the short value as an index in the color // lookup table. inline byte lookup(float f) {return lookup_[(ushort)scaleToShort(f)];} inline unsigned long llookup(float f) {return lookup_[(ushort)scaleToShort(f)];} // return NTOH converted value evtl. subtracted with corresponding bias value float getVal(float* p, int idx); protected: // initialize conversion from base type to short, void initShortConversion(); // sprintf format for (x y value) virtual char* getXYValueFmt() {return (char *)"%.1f %.1f %.2f";} // sprintf format for image pixel value virtual char* getValueFmt() {return (char *)"%.2f";} int getXsamples(float *rawImage, int idx, int wbox, float *samples); int getBsamples(float *rawImage, int idx, int wbox, float *samples); int getCsamples(float *rawImage, int idx, int wbox, float *samples); float getMedian(float *samples, int n); float getBoxVal(float *rawImage, int idx, int wbox, float *samples, int xs); float getRMS(float *samples, int n); void colorScale(int ncolors, unsigned long* colors); public: // constructor FloatImageData(const char* name, const ImageIO& imio, int verbose) : ImageData(name, imio, verbose), blank_(0), bias_(0.0), scale_(1.0) {} // return class name as a string virtual const char* classname() { return "FloatImageData"; } // return the data type of the raw data int dataType() {return FLOAT_IMAGE;} // return true if the data type is signed int isSigned() {return 1;} // return a copy of this object ImageData* copy() {return new FloatImageData(*this);} // include declarations for methods that differ only in raw data type # include "ImageTemplates.h" }; skycat-3.1.2-starlink-1b/rtd/generic/ITTInfo.C000066400000000000000000000102561215713201500207260ustar00rootroot00000000000000/* * E.S.O. - VLT project * "@(#) $Id: ITTInfo.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * ITTInfo.C - member routines for class ITTInfo * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * Peter W. Draper 14/07/98 Modified interpolate to use last value * (makes last colour pure). * pbiereic 17/02/03 Added 'using namespace std'. Removed ::std specs. */ static const char* const rcsId="@(#) $Id: ITTInfo.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; using namespace std; #include #include #include #include #include #include #include #include #include "ITTInfo.h" #include "error.h" #include "util.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" // list of itts, used for cache ITTInfo* itts_ = NULL; /* * constructor - arguments are the name of the itt * and an array of itt values. Both are assumed to * have been allocated. */ ITTInfo::ITTInfo(char* name, double* value) : value_(value), name_(name), next_(itts_) { // make this the head of the list itts_ = this; } /* * destructor */ ITTInfo::~ITTInfo() { // remove from list if (this == itts_) { itts_ = next_; } else { for (ITTInfo* m = itts_; m; m = m->next_) { if (m->next_ == this) { m->next_ = next_; break; } } } } /* * read a ITT from a file (if needed) and return a new instance for it */ ITTInfo* ITTInfo::get(char* filename) { // just use the basename to identify the colormap char* name = strdup(fileBasename(filename)); // see if we read this one already ITTInfo* m; for (m = itts_; m; m = m->next()) if (strcmp(m->name(), name) == 0) break; if (m) { free( name ); return m; } // have to read file ifstream f(filename); if (! f) { free( name ); error("could not open ITT file: ", filename); return (ITTInfo*) NULL; } double* value = new double[MAX_ITT]; if (! value) { free( name ); error("could not allocate ITT color table"); return (ITTInfo*) NULL; } for (int i = 0; i < MAX_ITT; i++) { f >> value[i]; } if (! f) { free( name ); error("error reading ITT file: ", filename); return (ITTInfo*) NULL; } m = new ITTInfo(name, value); if (! m) { error("could not create ITT"); } free( name ); return m; } /* * write a list of loaded itt files to the given stream * separated by spaces */ void ITTInfo::list(ostream& os) { ITTInfo* m; for (m = itts_; m; m = m->next()) os << m->name() << " "; } /* * Copy the rgb color values from src to dest and interpolate based * on the ITT table and the count of available colors */ void ITTInfo::interpolate(XColor* src, XColor* dest, int colorCount) { int c = colorCount - 1; int index, value; for (int i=0; i= start && i <= end) { index = ((i-start)*n)/dist; if (index < 0) index = 0; else if (index > n) index = n; } else if (i < start) { index = 0; } else { index = n; } value = (unsigned char)(value_[index]*c); dest[i].red = src[value].red; dest[i].green = src[value].green; dest[i].blue = src[value].blue; } } skycat-3.1.2-starlink-1b/rtd/generic/ITTInfo.h000066400000000000000000000032711215713201500207720ustar00rootroot00000000000000// -*-c++-*- #ifndef _ITTInfo_h_ #define _ITTInfo_h_ /* * E.S.O. - VLT project * "@(#) $Id: ITTInfo.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * ITTInfo.h - class definitions for reading in ITT * (intensity transfer table) files * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * pbiereic 17/02/03 Added 'using namespace std'. Removed ::std specs. */ using namespace std; #include #include enum {MAX_ITT=256}; /* work with 8bit color */ // one of these is used to hold ITT info for each ITT // file read class ITTInfo { private: char* name_; // filename double* value_; // array of ITT values ITTInfo* next_; // pointer to next ITT // copy constructor (not defined) ITTInfo(const ITTInfo&); public: // constructor ITTInfo(char* name, double* value); // destructor ~ITTInfo(); // create and return ITT from a file description static ITTInfo* get(char* filename); // write a list of ITT files static void list(ostream&); // member access const char* name() const {return name_;} ITTInfo* next() {return next_;} // Copy the rgb color values from src to dest and interpolate based // on the ITT table and the count of available colors void interpolate(XColor* src, XColor* dest, int colorCount); // Copy the rgb color values from src to dest as above, // and also scale the ITT values by the given amount void scale(int amount, XColor* src, XColor* dest, int colorCount); }; #endif /* _ITTInfo_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/ImageColor.C000066400000000000000000000277221215713201500215010ustar00rootroot00000000000000/* * E.S.O. - VLT project * "@(#) $Id: ImageColor.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * ImageColor.C - member routines for class ImageColor * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * Peter W. Draper 05/03/98 Added full support for X visuals in addition * to pseudocolor (merged my changes from GAIA). * 08/12/08 Don't overwrite pixelval_[0] in storeColors, * that's the background colour (black or a * user-defined value). * 03/11/09 Initialize all of pixelval_ in constructor. * Stops valgrind warnings in Tcl color allocs. * 19/08/11 Don't interpolate when using truecolor visuals. */ static const char* const rcsId="@(#) $Id: ImageColor.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include #include #include #include #include "ErrorHandler.h" #include "ImageColor.h" #include "error.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" /* * constructor: passed the X Display handle and the number of * colors to allocate initially. */ ImageColor::ImageColor(Display* display, Visual* visual, int depth, int numColors) : display_(display), visual_(visual), screen_(DefaultScreen(display_)), depth_(depth), cmapSize_(XCellsOfScreen(DefaultScreenOfDisplay(display_))), defaultCmap_(DefaultColormap(display_, DefaultScreen(display_))), colormap_(DefaultColormap(display_, DefaultScreen(display_))), colorCount_(0), freeCount_(0), cmaps_(NULL), cmap_(NULL), itts_(NULL), itt_(NULL), status_(0) { // Check if the visual we're dealing with is readonly, or if it // can be modified (XXX need to deal with DirectColor). if ( visual_->c_class == PseudoColor || visual_->c_class == DirectColor || visual_->c_class == GrayScale ) { readOnly_ = 0; } else { readOnly_ = 1; // Assume all colours are available, and use them. cmapSize_ = min(MAX_COLOR,int(pow( 2.0, depth_))); } // If default visual isn't the same then create a local colormap. Visual *defvis = DefaultVisual(display_, screen_); if ( defvis->c_class != visual_->c_class ) { colormap_ = XCreateColormap(display_, XRootWindow(display_, screen_), visual_, AllocNone); } // Initialisations. memset(pixelval_, '\0', sizeof(pixelval_)); memset(colorCells_, '\0', sizeof(colorCells_)); memset(ittCells_, '\0', sizeof(ittCells_)); memset(windowList_, '\0', sizeof(windowList_)); allocate(numColors); } /* * return the number of free color cells available (up to MAX_COLOR) */ int ImageColor::numFreeColors() { ErrorHandler errorHandler(display_); // catch X errors if ( ! readOnly_ ) { int i; for (i = MAX_COLOR-1; i > 0; i--) { if (XAllocColorCells(display_, colormap_, False, 0, 0, pixelval_, i) != 0) { XFreeColors(display_, colormap_, pixelval_, i, 0); // (note: here 0 return means error) return i; } } } else { // Readonly so all colors are free. return min(MAX_COLOR,int(pow( 2.0, depth_))); } return 0; } /* * free and then re-allocate at most numColors color cells */ int ImageColor::reallocate(int numColors) { if (readOnly_) { colorCount_ = cmapSize_; return 0; } if (colorCount_) { XFreeColors(display_, colormap_, pixelval_, colorCount_, 0); colorCount_ = 0; } if (allocate(numColors) == 0) { if (cmap_) if (loadColorMap(cmap_) != 0) return 1; } return 0; } /* * If we are using a 8-bit pseudocolor visual, this method allocates at most * numColors read/write color cells in the colormap. */ int ImageColor::allocate(int numColors) { if (readOnly_) { colorCount_ = cmapSize_; return 0; } // for 8-bit color, allocate read-write color cells if (colorCount_) { // free colors allocated in the default colormap XFreeColors(display_, colormap_, pixelval_, colorCount_, 0); colorCount_ = 0; } freeCount_ = numFreeColors(); if (numColors < freeCount_) colorCount_ = numColors; else colorCount_ = freeCount_; freeCount_ -= colorCount_; if (freeCount_ < 0) freeCount_ = 0; if (colorCount_ <= 0) return error("no more colors available"); if (XAllocColorCells(display_, colormap_, False, 0, 0, pixelval_, colorCount_) == 0) { colormap_ = defaultCmap_; freeCount_ = 0; colorCount_ = 0; return error("error allocating colors for colormap"); } for (int i=0; iinterpolate(colorCells_, colorCount_); // set first color to black, usually used for blank pixels colorCells_[0].red = colorCells_[0].green = colorCells_[0].blue = XBlackPixelOfScreen(DefaultScreenOfDisplay(display_)); // set last color default to white int n1 = colorCount_ - 1; colorCells_[n1].red = colorCells_[n1].green = colorCells_[n1].blue = XWhitePixelOfScreen(DefaultScreenOfDisplay(display_)); // re-install the ITT if necessary if (itt_) return loadITT(itt_); return storeColors(colorCells_); } /* * rotate the current colormap/ITT by the given amount */ int ImageColor::rotateColorMap(int amount) { if (!cmap_) return 0; if (!itt_) memcpy(ittCells_, colorCells_, sizeof(ittCells_)); // rotate, but reserve first and last cell cmap_->rotate(amount, ittCells_+1, colorCells_+1, colorCount_-2); if (itt_) memcpy(ittCells_, colorCells_, sizeof(ittCells_)); storeColors(colorCells_); return 0; } /* * shift the current colormap/ITT by the given amount */ int ImageColor::shiftColorMap(int amount) { if (!cmap_) return 0; // shift, but reserve first and last cell cmap_->shift(amount, colorCells_+1, ittCells_+1, colorCount_-2); storeColors(ittCells_); return 0; } /* * load an intensity transfer table (ITT) from the given file * where file contains MAX_COLOR ITT values, one per line */ int ImageColor::loadITT(char* filename) { ITTInfo* m = ITTInfo::get(filename); if (!m) return 1; return loadITT(m); } /* * load or re-load an intensity transfer table (ITT) */ int ImageColor::loadITT(ITTInfo* m) { itt_ = m; memcpy(ittCells_, colorCells_, sizeof(ittCells_)); // set the color values based on the itt map, but reserve // the first and last colors for special use m->interpolate(colorCells_+1, ittCells_+1, colorCount_-2); storeColors(ittCells_); return 0; } /* * scale (squeeze or stretch) the current colormap/ITT by the given amount */ int ImageColor::scaleITT(int amount) { if (!itt_) return 0; memcpy(ittCells_, colorCells_, sizeof(ittCells_)); // scale, but reserve first and last colors itt_->scale(amount, colorCells_+1, ittCells_+1, colorCount_-2); storeColors(ittCells_); return 0; } /* * reset colormap to original state */ int ImageColor::reset() { if (!cmap_) return 0; return loadColorMap(cmap_); } /* * If we are using a private colormap, set it for the given window. */ int ImageColor::setColormap(Tk_Window w) { if (colormap_ != defaultCmap_) Tk_SetWindowColormap(w, colormap_); return 0; } skycat-3.1.2-starlink-1b/rtd/generic/ImageColor.h000066400000000000000000000071261215713201500215420ustar00rootroot00000000000000// -*-c++-*- #ifndef _ImageColor_h_ #define _ImageColor_h_ /* * E.S.O. - VLT project * "@(#) $Id: ImageColor.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * ImageColor.h - class definitions for class ImageColor * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * Peter W. Draper 02/03/98 Added code to deal with none-pseudocolor * visuals. */ #include #include #include #include #include "ColorMapInfo.h" #include "ITTInfo.h" /* * An instance of this class is used to manage colors and colormaps * for RtdImage and derived widgets */ class ImageColor { private: Display* display_; // X display info Visual* visual_; // X visual int screen_; // default screen int depth_; // screen visual depth (8, 16, 24, ...) int readOnly_; // flag: true if we are using read-only colors int cmapSize_; // size of colormap Colormap defaultCmap_; // default colormap Colormap colormap_; // current colormap int colorCount_; // count of allocated colors int freeCount_; // number of colors to leave free // color pixel values unsigned long pixelval_[MAX_COLOR]; // colormap cells XColor colorCells_[MAX_COLOR]; XColor ittCells_[MAX_COLOR]; // cells after applying ITT // list of colormap info read from files ColorMapInfo* cmaps_; // current colormap ColorMapInfo* cmap_; // list of ITT info read from files ITTInfo* itts_; // current ITT ITTInfo* itt_; // keep a list of windows, whose colormaps are managed Tk_Window windowList_[126]; // status after constructor int status_; // -- private methods -- // reload existing colormap/itt int loadColorMap(ColorMapInfo*); int loadITT(ITTInfo*); int storeColors(XColor* colors); public: // constructor ImageColor(Display*, Visual*, int depth, int numColors); // member functions int numFreeColors(); int allocate(int numFreeColors); int reallocate(int numFreeColors); // load (reload) a color map from the given file int loadColorMap(char* filename); // load (reload) an ITT from the given file int loadITT(char* filename); // rotate the colormap by the given amount int rotateColorMap(int amount); // shift the colormap by the given amount int shiftColorMap(int amount); // scale the current colormap/ITT by the given amount int scaleITT(int amount); // reset colormap to original state int reset(); // start using a private colormap int usePrivateCmap(); // return true if we are using a private colormap int usingPrivateCmap() {return (colormap_ != defaultCmap_);} // if we are using a private colormap, set it for the given window int setColormap(Tk_Window); // member access int freeCount() const {return freeCount_;} int colorCount() const {return colorCount_;} unsigned long* pixelval() {return pixelval_;} unsigned long pixelval(int i) const {return pixelval_[i];} XColor* colorCells() {return itt_ ? ittCells_ : colorCells_;} int depth() const {return depth_;} const ColorMapInfo* cmap() const {return cmap_;} const ITTInfo* itt() const {return itt_;} int status() const {return status_;} int readOnly() const {return readOnly_;} // set the background color void setBackground( unsigned long pixval ) { pixelval_[0] = pixval ;} }; #endif /* _ImageColor_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/ImageData.C000066400000000000000000001324221215713201500212660ustar00rootroot00000000000000/* * E.S.O. - VLT project * "@(#) $Id: ImageData.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * ImageData.C - member functions for class ImageData * * See the man page ImageData(3) for a complete description of this class * library. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * * Peter W. Draper 02/07/96 Corrected autoSetCutLevels to set cutoff * according to number of pixels actually counted * Peter W. Draper 17/12/97 Modified setScale so that dispWidth and * dispHeight cannot be zero when using very * large negative scales (this happens for * extremely thin images, i.e. 5000x37). * * Peter W. Draper 03/02/97 Modified flip(int,int,int,int) to remove * -1 introduced by array coordinates. * Modified autoSetCutLevels to take account * of blank pixels. * * Allan Brighton 12/03/98 Removed ImageData::read, use makeImage instead, * since it allows different image types through * subclassing. * Moved WSC object (wcs_) to class ImageIO (does not * change the public interface). This makes it easier * to derive new image types or replace the WCS * implementation in a derived class of ImageIORep. * * Peter W. Draper 23/02/98 Added code to interpolate between the * autoSetCutLevels bins, increased the * number of bins to 2048 (from 256). * * Peter W. Draper 04/03/98 Added changes to support multiple display * visuals. Renamed setXImageData to setXImage. * * Peter W. Draper 13/01/99 Merged my changes into SkyCat 2.2. * pbiereic 22/03/99 Added code for bias frame * pbiereic 27/04/00 New Midas routine iqefunc.c * pbiereic 25/05/00 Added method 'fillToFit' * pbiereic 15/06/01 Added methods 'getYline4', 'getXline4', 'getBbox' and 'getMinMax' * Peter W. Draper 19/03/01 Stopped use of DATAMIN and DATAMAX * keywords, these are often incorrect, a * fact which cannot be worked around. * Peter W. Draper 30/05/01 Added support for double precision. * pbiereic 27/06/01 Added method 'noiseStatistics' * pbiereic 10/07/04 Added method 'getXline4' with specified x ranges * Peter W. Draper 08/01/07 Return a fake range in autoSetCutLevels for a * one pixel image. * pbiereic 09/10/05 fixed bug in 'getYline4' * Peter W. Draper 09/09/07 changed getIndex so that it rounds carefully * in the range 1 to -1. This clips at the image * edge, rather than one pixel further. * 16/04/08 Support xScale_ and yScale_ not having same sign * by decoupling when needed and adding a new * growAndShrink() member to handle this when * resampling/picking. * 08/07/08 When clearing in updateOffset (for zoomed images) * clear to black, not the blank color, which * can be another color. * 21/11/08 In flip do not apply the xScale>1 fudge. In fact * the limits are zero-based in getMinMax(). In * getDist treat bin width factor differently for * integers and others. Wasn't right for either case. * 23/06/09 Initialise new blankValue_ member. * 19/08/11 Make log and sqrt scalings use different * powers. This differentiates them and makes * them more like other display tools. * pbiereic 12/08/07 added support for data types double and long long int * Peter W. Draper 17/05/12 Merged skycat version for doubles created by * pbiereic. */ static const char* const rcsId="@(#) $Id: ImageData.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include #include #include #include #include #include #include "error.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" #include "Fits_IO.h" #include "fitshead.h" #include "NativeImageData.h" #include "ByteImageData.h" #include "XImageData.h" #include "ShortImageData.h" #include "UShortImageData.h" #include "LongImageData.h" #include "FloatImageData.h" #include "LongLongImageData.h" #include "DoubleImageData.h" #include "CompoundImageData.h" #include "ImageDisplay.h" // initialize static member variables // Note: these are static since there is only one static color map // or bias frame for all images of this class int ImageData::ncolors_ = 0; // number of available colors unsigned long* ImageData::colors_ = NULL; // array of color values unsigned long ImageData::color0_ = 0; // reserved color for blank pixels unsigned long ImageData::colorn_ = 0; // reserved color for saturated pixels biasINFO* ImageData::biasInfo_ = NULL; // ptr to description of bias frame // C routine used to get image statistics extern "C" { int iqe(float *pfm, float *pwm, int mx, int my, float *parm, float *sdev); } /* * constructor: initialize the image with the given name from the ImageIO * object holding the image data and description. * * If verbose is true, print debugging messages. * * lookup_size is optional and defaults to LOOKUP_SIZE (short range). It * can be specified as 256 for Byte images, for example. */ ImageData::ImageData(const char* imageName, const ImageIO& image, int verbose, int lookup_size) : image_(image), width_(image.width()), height_(image.height()), prevX_(0.0), prevY_(0.0), x0_(0), y0_(0), x1_(width_-1), y1_(height_-1), dispWidth_(width_), dispHeight_(height_), area_(width_*height_), xImage_(NULL), xImageData_(NULL), xImageBytesPerLine_(0), xImageSize_(0), xImageBytesPerPixel_(1), xImageMaxX_(width_-1), xImageMaxY_(height_-1), colorScaleType_(LINEAR_SCALE), haveBlank_(0), lowCut_(0.0), highCut_(0.0), scaledLowCut_(0), scaledHighCut_(0), scaledBlankPixelValue_(0), minValue_(0.0), maxValue_(0.0), logexpo_(6.0), sqrtexpo_(2.0), xScale_(1), yScale_(1), rotate_(0), flipX_(0), flipY_(0), startX_(0), startY_(0), binX_(1), binY_(1), prescanX_(0), prescanY_(0), overscanX_(0), overscanY_(0), crpix1_(0), crpix2_(0), subsample_(1), sampmethod_(0), update_pending_(1), verbose_(verbose), lookup_(lookup_size), clear_(0) { name(imageName); object(""); setBlank(""); } /* * copy constructor: copy the image * * Note that the classes managing the image data (ImageIO, Mem, ...) use * reference counting, so that the data is not actually copied normally, * but shared as long as possible. */ ImageData::ImageData(const ImageData& im) : image_(im.image_), width_(im.width_), height_(im.height_), prevX_(0.0), prevY_(0.0), x0_(0), y0_(0), x1_(width_-1), y1_(height_-1), dispWidth_(im.dispWidth_), dispHeight_(im.dispHeight_), area_(im.area_), xImage_(NULL), // will be set later xImageData_(NULL), xImageBytesPerLine_(0), xImageSize_(0), xImageMaxX_(0), xImageMaxY_(0), xImageBytesPerPixel_(1), colorScaleType_(im.colorScaleType_), haveBlank_(im.haveBlank_), lowCut_(im.lowCut_), highCut_(im.highCut_), scaledLowCut_(im.scaledLowCut_), scaledHighCut_(im.scaledHighCut_), scaledBlankPixelValue_(im.scaledBlankPixelValue_), minValue_(im.minValue_), maxValue_(im.maxValue_), logexpo_(im.logexpo_), sqrtexpo_(im.sqrtexpo_), xScale_(im.xScale_), yScale_(im.yScale_), rotate_(im.rotate_), flipX_(im.flipX_), flipY_(im.flipY_), startX_(im.startX_), startY_(im.startY_), binX_(im.binX_), binY_(im.binY_), prescanX_(im.prescanX_), prescanY_(im.prescanY_), overscanX_(im.overscanX_), overscanY_(im.overscanY_), crpix1_(im.crpix1_), crpix2_(im.crpix2_), subsample_(im.subsample_), sampmethod_(im.sampmethod_), update_pending_(1), verbose_(im.verbose_), lookup_(im.lookup_), clear_(0) { name(""); // new name should be set from outside object(im.object_); setBlank(im.blankValue_); } /* * Specify a new lookup table to use for this image and its size. * Note: only allowed if this is a copy of another image. */ int ImageData::lookupTable(LookupTable lookup) { if (lookup.size() != lookup_.size()) return error("warning: tried to copy lookup table with wrong size"); lookup_ = lookup; update_pending_++; return 0; } /* * This method is used to save color information for pos. later use * * Note that the first and last colors are reserved for special use: * The first color should be black and the last color can be set to * some saturation color. */ void ImageData::setColors(int ncolors, unsigned long* colors) { ncolors_ = ncolors - 2; colors_ = colors + 1; color0_ = colors[0]; colorn_ = colors[ncolors-1]; } /* * Set the destination XImage buffer and the dimensions of the XImage in * pixels. (This class copies the rawimage to xImage, doing any necessary * transformations along the way.) */ void ImageData::setXImage(ImageDisplay* xImage) { // save XImage info xImage_ = xImage; if ( xImage == NULL ) return; xImageData_ = xImage_->data(); xImageBytesPerPixel_ = xImage_->depth()/8; xImageBytesPerLine_ = xImage_->bytesPerLine(); // get XImage size in bytes xImageSize_ = xImageBytesPerLine_ * xImage_->height() * xImageBytesPerPixel_; // get the highest x,y indexes in the XImage double x = xImage_->width(); double y = xImage_->height(); undoTrans(x, y, 1); xImageMaxX_ = int(x)-1; xImageMaxY_ = int(y)-1; update_pending_++; } /* * Replace the current image data with new data of the same size and type */ void ImageData::data(const Mem& data) { image_.data(data); // make sure image is regenerated update_pending_++; } /* * Replace the current header with a new header */ void ImageData::header(const Mem& header) { // XXX reinitialize wcs() here ? image_.header(header); } /* * save the contents of this image to the given file */ int ImageData::write(const char* filename) { return image_.write(filename); } /* * Save the contents of the given region of this image to the given file. * The coordinates are expected in image pixel units. */ int ImageData::write(const char* filename, double rx0, double ry0, double rx1, double ry1) { double x0 = min(rx0,rx1), y0 = min(ry0,ry1); double x1 = max(rx0,rx1), y1 = max(ry0,ry1); int ix0, iy0, ix1, iy1; getIndex(x0, y0, ix0, iy0); getIndex(x1, y1, ix1, iy1); int w = ix1-ix0, h = iy1-iy0; // copy the original header and reset the relevant keywords const Mem& origHeader = image_.header(); int origHeaderSize = origHeader.length(); char* origHeaderPtr = (char*)origHeader.ptr(); Mem header(origHeaderSize, 0); if (header.status() != 0) return 1; // error char* head = (char*)header.ptr(); memcpy(head, origHeaderPtr, origHeaderSize); // Update the FITS keywords for the new image size. // Note: we can't use FitsIO for this, since we already have the header, // but the NAXIS keyword are wrong still, so fall back on wcssubs hget() // XXX to avoid crash for real-time images if (origHeaderSize > 0) { hlength(head, origHeaderSize); hputi4(head, "NAXIS1", w); hputcom(head, "NAXIS1", "Length X axis"); hputi4(head, "NAXIS2", h); hputcom(head, "NAXIS2", "Length Y axis"); } // update WCS keywords if needed if (origHeaderSize > 0 && wcs().isWcs()) { double cx = w/2.0, cy = h/2.0; hputr8(head, "CRPIX1", cx); hputcom(head, "CRPIX1", "Refpix of first axis"); hputr8(head, "CRPIX2", cy); hputcom(head, "CRPIX2", "Refpix of second axis"); double ra, dec; if (wcs().pix2wcs(ix0+cx, iy0+cy, ra, dec) != 0) return 1; hputr8(head, "CRVAL1", ra); hputcom(head, "CRVAL1", "RA at Ref pix in decimal degrees"); hputr8(head, "CRVAL2", dec); hputcom(head, "CRVAL2", "DEC at Ref pix in decimal degrees"); } // get and copy data for the specified image area int newDataSize = w*h*image_.pixelSize(); Mem data(newDataSize, 0); if (data.status() != 0) return 1; // error // copy the selected area copyImageArea(data.ptr(), x0, y0, w, h); // write the file so that FitsIO can edit it (keywords are incorrect still) // XXX Note: this is a bit tricky since class FitsIO is using the cfitsio // library and will complain if not editing a FITS file. FitsIO fits(w, h, image_.bitpix(), image_.bzero(), image_.bscale(), header, data); if (fits.status() != 0 || fits.write(filename) != 0) return 1; // error return 0; } /* * Make a new image from the given ImageIO object and return a pointer to * a derived class of this class specialized in that type of file/image. * * Note that pointers to classes such as FitsIO are automatically converted * to an ImageIO object through a special constructor. In this way, you can * add new image types by deriving a new classes in the same way as the * FitsIO class (from ImageIORep). * * name - is an arbitrary name for the image. * imio - is a reference to an ImageIO object for the image (or ptr, see above). * verbose - is a flag, if true, print out diagnostic messages. */ ImageData* ImageData::makeImage(const char* name, const ImageIO& imio, biasINFO* biasInfo, int verbose) { if (imio.status() != 0) return NULL; ImageData* image = NULL; // if this flag is true, use native byte order. int native = (BIGENDIAN == imio.usingNetBO()); switch (imio.bitpix()) { case BYTE_IMAGE: image = new ByteImageData(name, imio, verbose); break; case X_IMAGE: image = new XImageData(name, imio, verbose); break; case USHORT_IMAGE: if (native) image = new NativeUShortImageData(name, imio, verbose); else image = new UShortImageData(name, imio, verbose); break; case SHORT_IMAGE: if (native) image = new NativeShortImageData(name, imio, verbose); else image = new ShortImageData(name, imio, verbose); break; case LONG_IMAGE: if (native) image = new NativeLongImageData(name, imio, verbose); else image = new LongImageData(name, imio, verbose); break; case FLOAT_IMAGE: if (native) image = new NativeFloatImageData(name, imio, verbose); else image = new FloatImageData(name, imio, verbose); break; case LONGLONG_IMAGE: if (native) image = new NativeLongLongImageData(name, imio, verbose); else image = new LongLongImageData(name, imio, verbose); break; case DOUBLE_IMAGE: if (native) image = new NativeDoubleImageData(name, imio, verbose); else image = new DoubleImageData(name, imio, verbose); break; default: char buf[32]; sprintf(buf, "%d", imio.bitpix()); error("unsupported image BITPIX value: ", buf); } if (image) { image->setBiasInfo(biasInfo); return image->initImage(); } return image; } /* * Make a new compound image by combining the given image extensions * in the given ImageIO object and return a pointer to a derived class * of this class specialized in handling compound images, or null * if there is an error. * * The image extensions are combined based on the world coordinates * information in each header. An error is returned if this can't be * done. * * We only deal with FITS image extensions here, so an error is returned * if the ImageIO object is not a FITS file. * * name - is an arbitrary name for the image. * imio - is a reference to an ImageIO object for the FITS file. * hduList - is an array of image HDU indexes for the images to be combined * numHDUs - is the number of indexes in the hduList array * verbose - is a flag, if true, print out diagnostic messages. */ ImageData* ImageData::makeCompoundImage(const char* name, const ImageIO& imio, int* hduList, int numHDUs, biasINFO* biasInfo, int verbose) { ImageData* image = new CompoundImageData(name, imio, hduList, numHDUs, biasInfo, verbose); if (image) { if (image->status() != 0) { delete image; return NULL; } image->setBiasInfo(biasInfo); return image->initImage(); } return NULL; } /* * Initialize a new image. Determine the min and max pixel values, * set the default cut levels and get some keyword values that we * will need later. Returns a pointer to this image. */ ImageData* ImageData::initImage() { // See if there is a special value for blank pixels. // Note that the blank pixel value is not scaled by bscale, since // we compare pixels values with this value before scaling. initBlankPixel(); // get the values of the image keywords we need here char* s = image_.get("OBJECT"); if (s) { char* p = strchr(s, '\''); if (p) *p = '\0'; // make up for minor bug in (XXX old) wcslib - remove quotes object(s); // save object name } // save the values of CRPIX1 and CRPIX2 (for placing compound images) image_.get("CRPIX1", crpix1_, 1.); image_.get("CRPIX2", crpix2_, 1.); // save the values of DET.WIN.STRX and DET.WIN.STRY, needed to calculate // the chip coords image_.get("HIERARCH ESO DET WIN1 STRX", startX_, 1); image_.get("HIERARCH ESO DET WIN1 STRY", startY_, 1); // assume STRX and STRY start at (1,1), however we want just the offset from (0,0) startX_--; startY_--; if (startX_ < 0) startX_ = 0; if (startY_ < 0) startY_ = 0; // save the values of DET.WIN.BINX and DET.WIN.BINY for detector binning // settings for calculating the chip coordinates image_.get("HIERARCH ESO DET WIN1 BINX", binX_, 1); image_.get("HIERARCH ESO DET WIN1 BINY", binY_, 1); // assume BINX=1 and BINY=1 means no binning if (binX_ < 1) binX_ = 1; if (binY_ < 1) binY_ = 1; // save the values of DET.WIN.BINX and DET.WIN.BINY for detector binning // settings for calculating the chip coordinates image_.get("HIERARCH ESO DET OUT PRSCX", prescanX_, 0); image_.get("HIERARCH ESO DET OUT PRSCY", prescanY_, 0); image_.get("HIERARCH ESO DET OUT OVSCX", overscanX_, 0); image_.get("HIERARCH ESO DET OUT OVSCY", overscanY_, 0); if (prescanX_ < 0) prescanX_ = 0; if (prescanY_ < 0) prescanY_ = 0; if (overscanX_ < 0) overscanX_ = 0; if (overscanY_ < 0) overscanY_ = 0; // get min/max pixel and use to set default cut levels setDefaultCutLevels(); // initialize world coordinates, if the caller did not already if (! wcs().initialized()) { image_.wcsinit(); } return this; } /* * reinitialize the image after a change (such as moving to a new HDU) */ int ImageData::reinit() { initImage(); return 0; } /* * Copy the cutlevels, scale, rotate and flip parameters from the * this image to the given struct. */ void ImageData::saveParams(ImageDataParams& p) { p.status = 0; p.flipX = flipX_; p.flipY = flipY_; p.rotate = rotate_; p.xScale = xScale_; p.yScale = yScale_; p.dataType = dataType(); p.lowCut = lowCut_; p.highCut = highCut_; p.colorScale = colorScaleType_; } /* * Copy the cutlevels, scale, rotate and flip parameters from the * given struct to this image (see above). * If restoreCutLevels is non-zero (default), the saved cut-levels are restored * otherwise they are not and the cutlevels are left as they were * initialized (to the approx. min/max pixel value). */ void ImageData::restoreParams(ImageDataParams& p, int restoreCutLevels) { if (p.status != 0) return; // don't use if status != 0 flipX(p.flipX); flipY(p.flipY); rotate(p.rotate); setScale(p.xScale, p.yScale); if (restoreCutLevels && p.lowCut != p.highCut) setCutLevels(p.lowCut, p.highCut, 0); colorScaleType_ = p.colorScale; } /* * create the color scale lookup table for the image. * The arguments are: * * ncolors - the number of available colors * colors - an array of pixel values for the available colors * * The color scaling algorithm used is determined by the value of * colorScaleType_, which defaults to LINEAR_SCALE. */ void ImageData::colorScale(int ncolors, unsigned long* colors) { // save the color info for pos. later use setColors(ncolors, colors); // reset the lookup table lookup_.reset(colors_[0]); // call a method to create a lookup table for speedy access switch(colorScaleType_) { case LINEAR_SCALE: lookup_.linearScale(scaledLowCut_, scaledHighCut_, isSigned(), ncolors_, colors_); break; case LOG_SCALE: lookup_.logScale(scaledLowCut_, scaledHighCut_, isSigned(), ncolors_, colors_, logexpo_); break; case SQRT_SCALE: lookup_.sqrtScale(scaledLowCut_, scaledHighCut_, isSigned(), ncolors_, colors_, sqrtexpo_); break; case HISTEQ_SCALE: ImageDataHistogram h; getHistogram(h); lookup_.histeqScale(scaledLowCut_, scaledHighCut_, isSigned(), ncolors_, colors_, h.histogram, h.area); break; } // set value for blank pixel if (haveBlank_) lookup_.setPixelColor(scaledBlankPixelValue_, color0_); // make sure image is regenerated update_pending_++; } /* * set the scaling (zoom) factor */ void ImageData::setScale(int xScale, int yScale) { if (xScale == xScale_ && yScale == yScale_) return; xScale_ = xScale; yScale_ = yScale; if (xScale > 0) { dispWidth_ = width_ * xScale_; } else if (xScale < 0) { dispWidth_ = width_ / (-xScale_); if (dispWidth_ == 0) dispWidth_ = 1; } if (yScale > 0) { dispHeight_ = height_ * yScale_; } else if (yScale < 0) { dispHeight_ = height_ / (-yScale_); if (dispHeight_ == 0) dispHeight_ = 1; } area_ = width_*height_; if (rotate_) swap(dispWidth_, dispHeight_); update_pending_++; } /* * rotate the image by the given angle * (actually exchange the x/y axes if angle not 0) */ void ImageData::rotate(int angle) { angle = (angle != 0); // make boolean, since there is only one angle... if (rotate_ != angle) { rotate_ = angle; swap(dispWidth_, dispHeight_); swap(xImageMaxX_, xImageMaxY_); update_pending_++; } } /* * Flip the x,y coordinates according to the current transformations. * If width and height are given, they are used for flipping as needed. */ void ImageData::flip(double& x, double& y, int width, int height) { int c = (xScale_ > 1) ? 0 : 1; if (!flipY_) // raw image has y axis reversed y = ((height ? height : height_) - c) - y; if (flipX_) x = ((width ? width : width_) - c) - x; } /* * Flip both pairs of x,y coordinates according to the current transformations * and swap x0,x1 and y0,y1 resp. if flipped. */ void ImageData::flip(int& x0, int& y0, int& x1, int& y1) { // PWD: note these bounds remain in a 0,0 based system, which is // different to what is used elsewhere. if (!flipY_) { // raw image has y axis reversed int y = y0; int h = height_ - 1; y0 = h - y1; y1 = h - y; } if (flipX_) { int x = x0; int w = width_ - 1; x0 = w - x1; x1 = w - x; } } /* * apply the current transformations to the given coordinates * If distFlag is 1, x and y are treated as a distance, otherwise * they are treated as a point and flipped as needed. * If x and y offsets are specified, they are subtracted from x and y. * If width and height are given, they are used for flipping as needed. */ void ImageData::doTrans(double& x, double& y, int distFlag, double xOffset, double yOffset, int width, int height) { if (! distFlag) { // fits starts at 1,1 (0.5 is left side of pixel when zoomed) double f = (xScale_ > 1) ? 0.5 : 1.0; x -= f; y -= f; flip(x, y, width, height); x -= xOffset; y -= yOffset; } if (rotate_) swap(x, y); if (xScale_ > 1) { x *= xScale_; } else if (xScale_ < 0) { x /= -xScale_; } if (yScale_ > 1) { y *= yScale_; } else if (yScale_ < 0) { y /= -yScale_; } } /* * undo the current transformations on the given coordinates. * If distFlag is 1, x and y are treated as a distance, otherwise * they are treated as a point and flipped as needed. * If x and y offsets are specified, they are add to x and y. * If width and height are given, they are used for flipping as needed. */ void ImageData::undoTrans(double& x, double& y, int distFlag, double xOffset, double yOffset, int width, int height) { if (xScale_ > 1) { x /= xScale_; } else if (xScale_ < 0) { x *= -xScale_; } if (yScale_ > 1) { y /= yScale_; } else if (yScale_ < 0) { y *= -yScale_; } if (rotate_) swap(x, y); if (! distFlag) { x += xOffset; y += yOffset; flip(x, y, width, height); // fits starts at 1,1 (0.5 is left side of pixel when zoomed) double f = (xScale_ > 1) ? 0.5 : 1.0; x += f; y += f; } } /* * convert x,y image coords to a distance (from the origin) by flipping * where needed If width and height are given, they are used for flipping * as needed. */ void ImageData::coordsToDist(double& x, double& y, int width, int height) { // fits starts at 1,1 (0.5 is left side of pixel when zoomed) double f = (xScale_ > 1) ? 0.5 : 1.0; x -= f; y -= f; flip(x, y, width, height); } /* * convert an x,y distance (from the origin) to x,y image coords by * flipping where needed If width and height are given, they are used for * flipping as needed. */ void ImageData::distToCoords(double& x, double& y, int width, int height) { flip(x, y, width, height); // fits starts at 1,1 (0.5 is left side of pixel when zoomed) double f = (xScale_ > 1) ? 0.5 : 1.0; x += f; y += f; } /* * Convert the given image coordinates to detector chip/CCD coordinates. * While image coordinates start at 1,1 (.5,.5), chip coordinates might * have a different origin and/or binning. The the member variables * startX_ and startY_ give the offsets of the image origin. These are * set from the FITS keywords HIERARCH ESO DET WIN1 STRX and STRY, if * found, but may also be set via member methods. */ void ImageData::imageToChipCoords(double& x, double& y) { x = x * binX_ + startX_; y = y * binY_ + startY_; } /* * Convert the given detector chip/CCD coordinates to image coordinates. * (see comments above for imageToChipCoords). */ void ImageData::chipToImageCoords(double& x, double& y) { x = (x - startX_) / binX_; y = (y - startY_) / binY_; } /* * single argument versions of the above methods */ void ImageData::imageToChipCoords(double& x) { x += startX_; } void ImageData::chipToImageCoords(double& x) { x -= startX_; } /* * Convert floating point image coords to integer image array index. * (Image coords start at 1,1 at mag 1, array index is 0,0...) * * Return 0 if the index is in range, 1 otherwise. */ int ImageData::getIndex(double x, double y, int& ix, int& iy) { // get integer index in raw image for pixel value if (xScale_ > 1) { ix = int(x+0.5)-1; iy = int(y+0.5)-1; } else { ix = int(x-1.0); iy = int(y-1.0); } // return 0 if in range, otherwise 1 return (ix < 0 || iy < 0 || ix >= width_ || iy >= height_); //return 0; } /* * set the scaling factor so that the image will fit in the given box */ void ImageData::shrinkToFit(int width, int height) { int factor = -max((width_-1)/width+1, (height_-1)/height+1); if (factor >= -1) factor = 1; setScale(factor, factor); } /* * set the scaling factor so that the image will fill the given box */ void ImageData::fillToFit(int width, int height) { if (width_ <= 2 || height_ <=2) return; int factor = min(width/width_, height/height_); if (factor == 0) shrinkToFit(width, height); else setScale(factor, factor); } /* * set the default cut levels for the image to the min/max pixel * value. If DATAMIN and DATAMAX are defined in the FITS header, * use them, otherwise scan the image for the approx. min/max * values. * * PWD: remove DATAMIN and DATAMAX dependence. When these are * incorrect (happens too often) there's no way around it. */ void ImageData::setDefaultCutLevels() { // double d1, d2; // if (image_.get("DATAMIN", d1) == 0 && image_.get("DATAMAX", d2) == 0 && d1 < d2) { // // note that DATAMIN and MAX are AFTER adding bzero and multiplying // // by bscale. We only use these values to display to the user, but // // not internally, since we are going to scale everything to bytes // // in the end anyway. // minValue_ = unScaleValue(d1); // maxValue_ = unScaleValue(d2); // } // else { // scan image for min/max pixel value. Note that at this point, // we don't know how much of the image we will actually display, // so if the image is really huge, just take a 1k x 1k area in // the center. int xc = width_/2, yc = height_/2; if (xc > 512) { x0_ = xc-512; x1_ = xc+512; } if (yc > 512) { y0_ = yc-512; y1_ = yc+512; } getMinMax(); // } // set default cut levels setCutLevels(minValue_, maxValue_, 0); } /* * set the cut levels to the given values. * If scaled is 1, the low and high values should be already "scaled" with * bzero and bscale. */ void ImageData::setCutLevels(double low, double high, int scaled) { if (scaled) { highCut_ = unScaleValue(high); lowCut_ = unScaleValue(low); } else { highCut_ = high; lowCut_ = low; } // initialize conversion from base type to short, // used by color scaling algorithms as index in lookup table initShortConversion(); // make sure image is re-made update_pending_++; } /* * scan the image to find the distribution of pixel values * and set the cut levels so that the given percent of pixels * are within the low and high cut values. */ void ImageData::autoSetCutLevels(double percent) { // set initial default values getMinMax(); // get min/max pixel estimate for visible area double low = minValue_; double high = maxValue_; // xyvalues is an array of X,Y pairs where: // the X values are the pixel values (rounded to nearest factor) // the Y values are the number of pixels in a given range int numValues = 2048; double xyvalues[2048*2]; // get a rough distribution of the data getDist(numValues, xyvalues); // find out how many pixel we actually counted (may be significant // numbers of blanks) int npixels = 0; int i; for (i=0 ; i 0 ) { // change percent to cut off and split between low and high int cutoff = int((double(npixels)*(100.0-percent)/100.0)/2.0); // set low cut value npixels = 0; int nprev = 0; for (i=0 ; i= cutoff) { low = xyvalues[i*2]; if ( i != 0 ) { // Interpolate between the relevant bins. double interp = (double(cutoff)-double(nprev))/(double(npixels)-double(nprev)); low = xyvalues[(i-1)*2] + (low-xyvalues[(i-1)*2])*interp; } break; } } // set high cut value npixels = 0; nprev = 0; for (i=numValues-1 ; i>=0; i--) { nprev = npixels; npixels += (int)(xyvalues[i*2+1]); if (npixels >= cutoff) { high = xyvalues[i*2]; if ( i != numValues-1 ) { // Interpolate between the relevant bins. double interp = (double(cutoff)-double(nprev))/(double(npixels)-double(nprev)); high = xyvalues[(i+1)*2] + (xyvalues[(i+1)*2]-high)*interp; } break; } } } else { // Fake a range when there are no valid pixels (or just one). high = maxValue_ + 1.0; low = minValue_ - 1.0;; } if (high > low) setCutLevels(low, high, 1); } /* * Update the entire X image data, if necessary, from the raw data, * with transformations */ void ImageData::update() { if (xImage_ && update_pending_ && width_ > 0 && height_ > 0) { toXImage(0, 0, width_-1, height_-1, 0, 0); } } /* * Update the X image area starting at the given offset and continuing * to the end of the raw image or the end of the X image data, which * ever comes first. * * (This method is used when the X Image is the same size as the visible * window (or image, if smaller) and displays the part of the image at * some x,y scroll offset.) */ void ImageData::updateOffset(double x, double y) { if (!xImage_ || width_ <= 0 || height_ <= 0 || (update_pending_ == 0 && x == prevX_ && y == prevY_)) return; if (clear_) { // temp clear image xImage_->clear(0); // PWD: clear to black, not blank pixel color. clear_ = 0; return; } prevX_ = x; prevY_ = y; int x0 = int(x), y0 = int(y), x1 = width_-1, y1 = height_-1, dest_x = 0, dest_y = 0; // handle case where x0,y0 are negative (i.e.: image starts in the // middle of the window somewhere rather than the window starting at // the middle of the image) if (x < 0) { dest_x = -x0 + 1; x0 = 0; } if (y < 0) { dest_y = -y0 + 1; y0 = 0; } // we have to clear out the XImage if the new image doesn't cover it // up completely if (dest_x || dest_y || x1-x0 < xImageMaxX_ || y1-y0 < xImageMaxY_) { // if (verbose_) // printf("%s: clear ximage before update\n", name_); xImage_->clear(0); // PWD: clear to black, not blank pixel color. } // copy raw to X image while doing transformations toXImage(x0, y0, x1, y1, dest_x, dest_y); } /* * Clip and set the bounds of the visible portion of the image (x0_, y0_, x1_, y1_). * These are used by some operations, such as getMinMax() to save time. */ void ImageData::setBounds(int x0, int y0, int x1, int y1, int dest_x, int dest_y) { int maxx = width_ - 1, maxy = height_ - 1; x0_ = min(max(x0, 0), maxx); y0_ = min(max(y0, 0), maxy); x1_ = min(min(x1, maxx), x0_ + xImageMaxX_ - dest_x); y1_ = min(min(y1, maxy), y0_ + xImageMaxY_ - dest_y); } /* * copy the raw image to the xImage, doing any transformations as * necessary. * * The arguments x0, y0, x1 and y1 are the bounding box of the region of * the raw image that needs to be copied (origin at (0,0)) * * dest_x and dest_y give the coordinates in the XImage where copying * should start. These are normally either (-x0,-y0) or (0,0). * * This method adjust the coordinates, if necessary and then calls * the virtual methods in derived classes to do the real work. */ void ImageData::toXImage(int x0, int y0, int x1, int y1, int dest_x, int dest_y) { // no bias subtraction for colorramp int biasOn = biasInfo_->on; if (strcmp(this->name(), "Ramp") == 0) biasInfo_->on = 0; // set and clip the member variables x0_, y0_, x1_, y1_ setBounds(x0, y0, x1, y1, dest_x, dest_y); if (x0 > x1 || y0 > y1) return; // copy the relevant area of the raw image to the X image if ( (xScale_ == 0 || xScale_ == 1) && (yScale_ == 0 || yScale_ == 1) ) { rawToXImage(x0_, y0_, x1_, y1_, dest_x, dest_y); } else if ( (xScale_ > 1 && yScale_ >= 1) || (xScale_ >= 1 && yScale_ > 1) ) { grow(x0_, y0_, x1_, y1_, dest_x, dest_y); } else if (xScale_ < 0 && yScale_ < 0) { shrink(x0_, y0_, x1_, y1_, dest_x, dest_y); } else { growAndShrink(x0_, y0_, x1_, y1_, dest_x, dest_y); } // x0_, y0_, x1_ and y1_ are the coordinates of the visible part of // the image and are needed later for setting cut levels and calculating // the min/max pixel for the displayed image area. The display routines // called above (rawToXImage, grow, shrink) expect the coordinates to have // the origin at upper left (0,0) (XImage type coordinates), while the rest // of the code deals with FITS image coordinates (origin at lower left (1, 1)). flip(x0_, y0_, x1_, y1_); update_pending_ = 0; biasInfo_->on = biasOn; } /* * scan the raw image along the line (x0,y0) to (x1,y1) (image coords) * and generate an array with (index, pixel value) information. * * Return the number of (index,value) pairs generated for the line. * */ int ImageData::getSpectrum(double* xyvalues, int x0, int y0, int x1, int y1) { int i = 0; if (y1 == y0) { // horizontal line int startx = min(x0, x1); int endx = max(x0, x1); for (int x = startx; x <= endx; x++) { xyvalues[i*2] = i; xyvalues[i*2+1] = getValue(x, y0); i++; } return i; } if (x1 == x0) { // vertical line int starty = min(y0, y1); int endy = max(y0, y1); for (int y = starty; y <= endy; y++) { xyvalues[i*2] = i; xyvalues[i*2+1] = getValue(x0, y); i++; } return i; } // sloped line // use Bresenham midpoint line scan-conversion algorithm // see: Computer Graphics Princ. a. Pract., 2nd Ed., p. 78 // also see x11r5/mit/server/ddx/cfb/cfbline.c, cfbbres.c int x = x0; int y = y0; int e, e1, e2, e3; // bresenham error and increments int len; // length of segment int adx = x1 - x0; // abs values of dx and dy int ady = y1 - y0; int signdx = 1; // sign of dx and dy int signdy = 1; if (adx < 0) { adx = -adx; signdx = -1; } if (ady < 0) { ady = -ady; signdy = -1; } // start pixel xyvalues[i*2] = i; xyvalues[i*2+1] = getValue(x, y); i++; if (adx > ady) { // X major axis; e1 = ady << 1; e2 = e1 - (adx << 1); e3 = e2 - e1; e = -adx; len = adx; while (len--) { e += e1; x += signdx; if (e >= 0) { y += signdy; e += e3; } xyvalues[i*2] = i; xyvalues[i*2+1] = getValue(x, y); i++; } } else { // Y major axis e1 = adx << 1; e2 = e1 - (ady << 1); e3 = e2 - e1; e = -ady; len = ady; while(len--) { e += e1; y += signdy; if (e >= 0) { x += signdx; e += e3; } xyvalues[i*2] = i; xyvalues[i*2+1] = getValue(x, y); i++; } } // return the number of (index,value) pairs generated return i; } /* * get statistics on specified area of image by calling the function * "iqe" (Image Quality Estimate) and passing it the requested part * of the image as an array of doubles. * * x,y - are the x and y offsets in image coords in the image * w,h - indicate the size of the image square to examine * * The rest of the values are return parameters passed back from 'iqe': * * meanX = mean X position within array, first pixel = 0 * meanY = mean Y position within array, first pixel = 0 * fwhmX = FWHM in X * fwhmY = FWHM in Y * symetryAngle = angle of major axis, degrees, along X = 0 * objectPeak = peak value of object above background * meanBackground = mean background level * * The return value is 0 if all is OK. */ int ImageData::getStatistics(double x, double y, int w, int h, double& meanX, double& meanY, double& fwhmX, double& fwhmY, double& symetryAngle, double& objectPeak, double& meanBackground) { // Get the image data for the area into an array. // Use floats because the midas C routines use them... float* ar = new float[w*h]; getValues(x, y, w, h, ar); float parm[8], sdev[8]; // The old Midas routine had an "array out of bounds" which crashed rtd. // The new one has been checked with Purify. int status = (iqe(ar, NULL, w, h, parm, sdev) != 0); delete []ar; meanX = parm[0]; meanY = parm[2]; fwhmX = parm[1]; fwhmY = parm[3]; symetryAngle = parm[4]; objectPeak = parm[5]; meanBackground = parm[6]; if (status != 0) error("Could not calculate statistics on specified area of image. Please make another selection."); return status; } /* * get noise statistics on specified area of the image. * * x0,y0 - is the lower left corner of the image * w,h - indicate the size of the image to examine * * Returns: * dmin = minimum value * dmax = maximum value * av = average value * rms = RMS value * n = number of samples used * xs, ys = lower left corner (image coordinates) of area * xe, ye = upper right corner (image coordinates) of area * * The return value of the method is 0 if all is OK. */ int ImageData::noiseStatistics(double rx0, double ry0, int w, int h, double *dmin, double *dmax, double *av, double *rms, int *xs, int *xe, int *ys, int *ye) { int ix, iy, numVal = 0; double x0 = 0., y0 = 0., minv, maxv, cv, sum = 0., sumsq = 0.; minv = maxv = getValue(rx0, ry0); for (int y = 0; y < h ; y++) { y0 = ry0 + y; for (int x = 0; x < w; x++) { x0 = rx0 + x; if (getIndex(x0, y0, ix, iy) != 0) continue; if (numVal == 0) { *xs = (int)x0; *ys = (int)y0; } numVal++; cv = getValue(x0, y0); sum += cv; sumsq += cv * cv; if (cv < minv) minv = cv; if (cv > maxv) maxv = cv; } } *xe = (int)x0; *ye = (int)y0; *dmin = minv; *dmax = maxv; *av = sum / numVal; *rms = sqrt(sumsq / numVal - *av * *av); return numVal; } /* * scan the image and generate X,Y values to show the distribution of * pixel values in the image. "numValues" is the max number of X,Y pairs * to put in xyvalues (if there are not enough values, numValues is modified * to reflect the actual, smaller number of values) */ void ImageData::getDist(int& numValues, double* xyvalues) { double n = maxValue_ - minValue_; if (n <= 0) { numValues = 0; return; } // PWD: for integers we have a bin per-value, that requires n+1. double factor; if (n < numValues && ( dataType() != FLOAT_IMAGE && dataType() != DOUBLE_IMAGE ) ) { numValues = int(n + 1); factor = (n + 1)/numValues; } else { // PWD: for floating point values to get from min to max. factor = n/(numValues-1); } // the X values are the pixel values double m = minValue_; for (int i=0; i= 0.0) getPixDist(numValues, xyvalues, factor); } /* * Return the image coords of the visible image area (bounding box) */ void ImageData::getBbox(double *x0, double *x1, double *y0, double *y1) { *x0 = x0_ + 0.5; *x1 = x1_ + 0.5; *y0 = y0_ + 0.5; *y1 = y1_ + 0.5; } /* * Get meander coords of a horizontal line at position y (origin starting at 0.5). * The size of vector xyvalues must be allocated 4 times the size of the line. */ int ImageData::getXline4(int y, int from, int to, double *xyvalues) { int ix, iy, numVal = 0; double cy; for (int x = from; x <= to; x++, numVal++) { if (getIndex(x, y, ix, iy) != 0) continue; cy = getValue(x, y); // y axis value *xyvalues++ = (double) x - 0.5; // x axis value *xyvalues++ = cy; *xyvalues++ = (double) x + 0.5; *xyvalues++ = cy; } return numVal; } /* * Same as getXline4 but with specified x range (start xr0, delta dxr) */ int ImageData::getXline4(int y, int from, int to, double *xyvalues, double xr0, double dxr) { int ix, iy, numVal = 0; double cy, xr = xr0, dx = dxr/2.0; for (int x = from; x <= to; x++, xr += dxr, numVal++) { if (getIndex(x, y, ix, iy) != 0) continue; cy = getValue(x, y); // y axis value *xyvalues++ = (double) xr - dx; // x axis value *xyvalues++ = cy; *xyvalues++ = (double) xr + dx; *xyvalues++ = cy; } return numVal; } /* * Get min/max values on a specified area of the image (origin at (1,1)) */ int ImageData::getMinMax(double rx0, double ry0, int w, int h, double *minval, double *maxval) { int ix, iy, numVal = 0; double x0, y0, minv, maxv, cv; minv = maxv = getValue(rx0, ry0); for (int y = 0; y < h ; y++) { y0 = ry0 + y; for (int x = 0; x < w; x++) { x0 = rx0 + x; if (getIndex(x0, y0, ix, iy) != 0) continue; numVal++; cv = getValue(x0, y0); if (cv < minv) minv = cv; if (cv > maxv) maxv = cv; } } *minval = minv; *maxval = maxv; return numVal; } /* * get meander coords of a vertical line at position x (index starting at 0) */ int ImageData::getYline4(int x, int y0, int y1, double *xyvalues) { int numVal = 0; double cx; if (x < 0 || x >= width_ || y0 < 0 || y0 >= height_ || y1 < 0 || y1 >= height_) return 0; for (int y = y0; y < y1; y++, numVal++) { cx = getValue(x, y); // y axis value *xyvalues++ = (double) y - 0.5; // x axis value *xyvalues++ = cx; *xyvalues++ = (double) y + 0.5; *xyvalues++ = cx; } return numVal; } /* * Initialize flag for speeding up bias subtraction */ void ImageData::initGetVal() { biasINFO* bias = ImageData::biasInfo_; bias->sameTypeAndDims = (bias->width == width_ && bias->height == height_ && bias->type == dataType()); /* * if the byte order of the main- and bias frame is different * then set a flag to swap the bytes of the bias frame. */ bias_swap_bytes_ = (bias->usingNetBO != BIGENDIAN); } skycat-3.1.2-starlink-1b/rtd/generic/ImageData.h000066400000000000000000000523031215713201500213320ustar00rootroot00000000000000#ifndef _ImageData_h_ #define _ImageData_h_ /* * E.S.O. - VLT project * "@(#) $Id: ImageData.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * Image.h - class definitions for drawing images in Tk/Tcl * * See the man page ImageData(3) for a complete description of this class * library. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * * T. Herlin 06/12/95 Added set_object for camera objects * * Allan Brighton 12/03/98 Removed ImageData::read, use makeImage instead, * since it allows different image types through * subclassing. * Moved WSC object (wcs_) to class ImageIO (does not * change the public interface). This makes it easier * to derive new image types or replace the WCS * implementation in a derived class of ImageIORep. * P.W. Draper 03/03/98 Added changes for display depths > 8 bits. * 14/07/98 Added LOOKUP_BLANK to use last bin for * blank pixel (otherwise comes out at * scaled colour). * pbiereic 22/03/99 Added parameters for bias frame * P.W. Draper 12/07/99 Added haveBlank() and getBlank() members * to allow return of blank_ value as a double. * pbiereic 25/05/00 Added method 'fillToFit' * pbiereic 27/06/01 Added method 'noiseStatistics' * pbiereic 10/02/03 Native byte order routines revised * P.W. Draper 16/01/07 Make sure object_ is null terminated. * 24/04/08 Added growAndShrink(). * 19/06/09 Add setBlank member to handle case when BLANK * isn't set, but should be. * 19 Aug 11 Make log and sqrt scalings use different * powers. This differentiates them and makes * them more like other display tools. */ #include #include #include "WCSRep.h" #include "LookupTable.h" #include "ImageIO.h" #include "ImageDisplay.h" #ifndef isnan #define isnan(x) ((x) != (x)) #endif typedef unsigned char byte; // type of XImage data (no longer ...) struct ImageDataParams; // forward ref struct ImageDataHistogram; // forward ref typedef struct { int on; // flag for bias subtraction on/off char* ptr; // pointer to bias data int width; // width of bias frame int height; // height of bias frame int type; // data type int usingNetBO; // byte ordering int sameTypeAndDims; // same image type and dimensions, flag } biasINFO; /* * This is the base class for managing image data. There is a subclass for * each of the base data types (byte, short, ushort, int, float). Most * of the methods are the same for each data type, any many are implemented * in ImageTemplates.icc, which uses macros to avoid duplicating code * for each data type. * * CompoundImageData is used when there are multiple FITS extensions that * should be displayed as a single image. It is a friend class, since it * needs to access some protected members in an array of ImageData objects. */ class ImageData { friend class CompoundImageData; public: // types of color scaling enum ImageColorScaleType { LINEAR_SCALE, // linear scale LOG_SCALE, // logarithmic or exponential scale SQRT_SCALE, // square root scale HISTEQ_SCALE // histogram equalization }; // values for color lookup table (from saoimage) enum { LOOKUP_SIZE = 65536, // default size of buffer (full range of short 0x10000) LOOKUP_WIDTH = 65534, // range of image values allowed in histogram LOOKUP_MIN = -32767, // minimum image value allowed LOOKUP_MAX = 32767, // maximum image value allowed LOOKUP_OFF = 32768, // offset from allocated array to zero (0x8000) LOOKUP_BLANK = -32768 // end bin for blank pixel }; protected: // arbitrary name of this image, used to identify the image in messages char name_[32]; // status after constructor int status_; // pointers to the caller's XImage and data, which this class writes to ImageDisplay* xImage_; byte* xImageData_; // this represents the contents of the image file or other source // (uses reference counting so we can share this with other views) ImageIO image_; // dimensions of image in pixels int width_, height_; // value in "OBJECT" header field: name of astronomical object char object_[81]; // saved x, y values from last call to updateOffset(x, y) double prevX_, prevY_; // saved bounding box in raw image array of last image update // (used later for calculating cut levels) int x0_, y0_, x1_, y1_; // XImage info int xImageBytesPerLine_; int xImageSize_; // size in bytes = width*height*bytesPerPixel int xImageBytesPerPixel_; // Number of bytes per pixel in xImage (1 for 8 // bit displays). // max x image x,y coords scaled to image coords int xImageMaxX_, xImageMaxY_; // lookup table mapping unsigned short to byte LookupTable lookup_; // type of color scaling to do ImageColorScaleType colorScaleType_; // these can be static for now, since all images share a static colormap static int ncolors_; // number of available colors static unsigned long* colors_; // array of color values static unsigned long color0_; // reserved color for black pixels static unsigned long colorn_; // reserved color for saturated pixels static biasINFO* biasInfo_; // description of bias frame int bias_swap_bytes_; // flag: if true, bytes swap is needed int clear_; // flag: if true, clear out the image once // minimum and maximum pixel values double minValue_; double maxValue_; // color cut values and blank pixel value scaled to short (or ushort) // range. Used in color scaling algorithms to generate lookup table int scaledHighCut_; int scaledLowCut_; int scaledBlankPixelValue_; int haveBlank_; // flag: true if the BLANK keyword was found char blankValue_[32]; // character string with BLANK value // color cut values double highCut_; double lowCut_; // min image value scaled to short or ushort range // (used in color scaling algorithms to generate lookup table) int scaledMinValue_; // optional exponents for LOGARITHMIC and SQRT color scale (def: 6 & 2) double logexpo_; double sqrtexpo_; // X,Y amount image should be scaled int xScale_, yScale_; // flag: true if x and y coords should be swapped (rotate 90 deg.) int rotate_; // flag: true if image should be flipped in the X or Y direction int flipX_, flipY_; // values from ESO/VLT FITS keywords used to calculate detector coordinates. int startX_, startY_; int binX_, binY_; int prescanX_, prescanY_; int overscanX_, overscanY_; // CRPIX values from the FITS header double crpix1_, crpix2_; // display width and height (after scaling) int dispWidth_, dispHeight_; // area of image = width_ * height_ int area_; // flag: true when the image needs updating int update_pending_; // flag: if true, do a quick dirty job when shrinking image int subsample_; // sampling method int sampmethod_; // flag: if true, print diagnostic messages int verbose_; protected: // check args and call virtual methods to copy raw data to xImage virtual void toXImage(int x0, int y0, int x1, int y1, int dest_x, int dest_y); // Clip and set the bounds of the visible portion of the image (x0_, y0_, x1_, y1_). virtual void setBounds(int x0, int y0, int x1, int y1, int dest_x, int dest_y); // copy raw data to xImage, pos. with transformations (defined in derived class) virtual void rawToXImage(int x0, int y0, int x1, int y1, int dest_x, int dest_y) = 0; virtual void shrink(int x0, int y0, int x1, int y1, int dest_x, int dest_y) = 0; virtual void grow(int x0, int y0, int x1, int y1, int dest_x, int dest_y) = 0; virtual void growAndShrink(int x0, int y0, int x1, int y1, int dest_x, int dest_y) = 0; // initialize conversion from base type to short, // used by color scaling algorithms as index in lookup table // (defined in a derived class, not needed for byte images) virtual void initShortConversion() = 0; // scan the image for the min and max values virtual void getMinMax() = 0; // flip x,y coords about default or specified image width,height void flip(double& x, double& y, int width = 0, int height = 0); void flip(int& x0, int& y0, int& x1, int& y1); // apply bzero and bscale to the value double scaleValue(double d) {return image_.scaleValue(d);} // reverse the effect of bzero and bscale double unScaleValue(double d) {return image_.unScaleValue(d);} // get pixel value distribution info (internal version) virtual void getPixDist(int numValues, double* xyvalues, double factor) = 0; // Fill the given histogram with the distribution of pixels in the // visible image area virtual void getHistogram(ImageDataHistogram&) = 0; // set default cut levels to min/max pixel values void setDefaultCutLevels(); // initialize a new image, set default cut levels, etc. virtual ImageData* initImage(); // constructor (only called by derived clases) ImageData(const char* name, const ImageIO&, int verbose, int lookup_size = LOOKUP_SIZE); // copy constructor (called by copy() member function) ImageData(const ImageData&); public: // destructor virtual ~ImageData() {} // return class name as a string virtual const char* classname() { return "ImageData"; } // save image to a file int write(const char* filename); // Save the contents of the given region of this image to the given file. // The coordinates are expected in image pixel units. virtual int write(const char* filename, double x0, double y0, double x1, double y1); // return a pointer to a derived class of this class specialized in the given // type of image, as given by the ImageIO reference. // Note: ImageIO is a reference counted class. New image types can be added // by subclassing the internal class ImageIORep. static ImageData* makeImage(const char* name, const ImageIO&, biasINFO* biasInfo, int verbose = 0); // Make a new compound image by combining the given image extensions // in the given ImageIO object and return a pointer to a derived class // of this class specialized in handling compound images, or null // if there is an error. static ImageData* makeCompoundImage(const char* name, const ImageIO& imio, int* hduList, int numHDUs, biasINFO* biasInfo, int verbose); // reinitialize the image after a change (such as moving to a new HDU) int reinit(); // apply/reverse transformations on coordinates (scale, rotate, flip, etc...) void doTrans(double& x, double& y, int distFlag = 0, double xOffset = 0.0, double yOffset = 0.0, int width = 0, int height = 0); void undoTrans(double& x, double& y, int distFlag = 0, double xOffset = 0.0, double yOffset = 0.0, int width = 0, int height = 0); // convert x,y coords to a distance by flipping where needed void coordsToDist(double& x, double& y, int width = 0, int height = 0); // convert distance to coords (reverse of above) void distToCoords(double& x, double& y, int width = 0, int height = 0); // Convert the given image coordinates to detector chip/CCD coordinates. void imageToChipCoords(double& x, double& y); // Convert the given detector chip/CCD coordinates to image coordinates. void chipToImageCoords(double& x, double& y); // single arg versions of the above methods void imageToChipCoords(double& x); void chipToImageCoords(double& x); // get pixel index from image coords int getIndex(double x, double y, int& ix, int& iy); // set the destination X image buffer, dimensions and raw image offset virtual void setXImage(ImageDisplay* xImage); // set the scaling factor virtual void setScale(int xScale, int yScale); // set the scaling factor so that the image will fit in the given box void shrinkToFit(int width, int height); // set the scaling factor so that the image will fill the given box void fillToFit(int width, int height); // update the entire image from the raw image if necessary void update(); // update image from raw data starting at the given x,y offset virtual void updateOffset(double x, double y); // get array with information about the pixel value distribution void getDist(int& numValues, double* xyvalues); // initialize flag for speeding up bias subtraction void initGetVal(); // scan the image along the given line and generate an array // with pixel value information int getSpectrum(double* xyvalues, int x0, int y0, int x1, int y1); // get meander coords of a horizontal line at position y (index starting at 0) int getXline4(int y, int x0, int x1, double *xyvalues); // same as getXline4 but with specified x ranges (start xr0, delta dxr) int getXline4(int y, int x0, int x1, double *xyvalues, double xr0, double dxr); // get meander coords of a vertical line at position x (index starting at 0) int getYline4(int x, int y0, int y1, double *xyvalues); // Return the image coords of the visible image area (bounding box) void getBbox(double *x0, double *x1, double *y0, double *y1); // get min and max values of an image area int getMinMax(double rx0, double ry0, int w, int h, double *minval, double *maxval); // manually set the cut levels (if scaled is true, min and max are "bscaled") virtual void setCutLevels(double min, double max, int scaled); // automatically set the cut levels to leave percent visible virtual void autoSetCutLevels(double percent = 98.0); // automatically set the cut levels using median filtering virtual void medianFilter() {} // set the colors to use for the image virtual void colorScale(int ncolors, unsigned long* colors); // return the type of the raw data virtual int dataType() = 0; // return true if the data type is signed virtual int isSigned() = 0; // return a copy of the image virtual ImageData* copy() = 0; // save/restore transformation parameters virtual void saveParams(ImageDataParams&); virtual void restoreParams(ImageDataParams&, int restoreCutLevels = 1); // print x,y coords and raw data value at x,y coords to buffer virtual char* getValue(char* buf, double x, double y) = 0; // print the values at the given x,y coords to the buffers for display virtual void getValues(double x, double y, double rx, double ry, char* xStr, char* yStr, char* valueStr, char* raStr, char* decStr, char* equinoxStr) = 0; // get array of image pixel values and x,y coords around a point virtual void getValues(double x, double y, double rx, double ry, double* ar, int nrows, int ncols, int flag = 0) = 0; // get array of image pixel values at a given offset with given dimensions virtual void getValues(double x, double y, int w, int h, float* ar, int flag = 0) = 0; // return the value at the x,y coords as a double virtual double getValue(double x, double y) = 0; // Copy raw image data from this image to the given image data area, // starting at the image coordinates (x, y) and with the dimentions (w, h) // in pixels. Since this is a copy from one raw image to another, no // data conversion is done. virtual void copyImageArea(void* data, double x, double y, int w, int h) = 0; // get statistics for "pick object" on a specified area of the image virtual int getStatistics(double x, double y, int w, int h, double& meanX, double& meanY, double& fwhmX, double& fwhmY, double& symetryAngle, double& objectPeak, double& meanBackground); // get noise statistics on a specified area of the image virtual int noiseStatistics(double rx0, double ry0, int w, int h, double *dmin, double *dmax, double *av, double *rms, int *xs, int *xe, int *ys, int *ye); // member access int status() {return status_;} // get the image data or header Mem& data() {return (Mem&)image_.data();} Mem& header() {return (Mem&)image_.header();} // write a (ASCII formatted) copy of the FITS header to the given stream int getFitsHeader(ostream& os) {return image_.getFitsHeader(os); } // set new data or header void data(const Mem& data); void header(const Mem& header); // access the world coordinate info object for the image WCS& wcs() {return image_.wcs();} ImageDisplay* xImage() {return xImage_;} const ImageIO& image() {return image_;} void colorScaleType(ImageColorScaleType t) {colorScaleType_ = t;} ImageColorScaleType colorScaleType() {return colorScaleType_;} int ncolors() {return ncolors_;} unsigned long* colors() {return colors_;} unsigned long color0() {return color0_;} unsigned long colorn() {return colorn_;} virtual void setColors(int ncolors, unsigned long* colors); void setBiasInfo(biasINFO* ptr) {biasInfo_ = ptr;} void logexpo(double e) {logexpo_ = e;} double logexpo() {return logexpo_;} void sqrtexpo(double e) {sqrtexpo_ = e;} double sqrtexpo() {return sqrtexpo_;} int width() {return width_;} int height() {return height_;} int dispWidth() {return dispWidth_;} int dispHeight() {return dispHeight_;} int xScale() {return xScale_;} int yScale() {return yScale_;} int flipX() {return flipX_;} virtual void flipX(int b) {flipX_ = (b != 0); update_pending_++;} int flipY() {return flipY_;} virtual void flipY(int b) {flipY_ = (b != 0); update_pending_++;} int rotate() {return rotate_;} virtual void rotate(int); double crpix1() {return crpix1_;} double crpix2() {return crpix2_;} int startX() {return startX_;} int startY() {return startY_;} void startX(int x) {startX_ = x;} void startY(int y) {startY_ = y;} int binX() {return binX_;} int binY() {return binY_;} void binX(int x) {binX_ = x;} void binY(int y) {binY_ = y;} int prescanX() {return prescanX_;} int prescanY() {return prescanY_;} void prescanX(int x) {prescanX_ = x;} void prescanY(int y) {prescanY_ = y;} int overscanX() {return overscanX_;} int overscanY() {return overscanY_;} void overscanX(int x) {overscanX_ = x;} void overscanY(int y) {overscanY_ = y;} virtual double highCut() {return scaleValue(highCut_);} virtual double lowCut() {return scaleValue(lowCut_);} virtual double minValue() {return scaleValue(minValue_);} virtual double maxValue() {return scaleValue(maxValue_);} virtual void subsample(int b) {subsample_ = b;} virtual int subsample() {return subsample_;} virtual void sampmethod(int b) {sampmethod_ = b;} virtual int sampmethod() {return sampmethod_;} virtual int getNumImages() {return 1;} virtual void verbose(int b) {verbose_ = b;} virtual void name(const char* name) {strncpy(name_, name, sizeof(name_)-1);} char* name() {return name_;} virtual void object(const char *object) { strncpy(object_, object, sizeof(object_)); object_[80] = '\0'; } char* object() {return object_;} int update_pending() {return update_pending_;} void update_pending(int b) {update_pending_ = b;} LookupTable lookupTable() {return lookup_;} virtual int lookupTable(LookupTable); void clear() {clear_ = 1; update_pending_++;} // return the blank value as a double virtual double getBlank() = 0; virtual int haveBlank() = 0; // If there is a special value for blank pixels, get it and set the // values of haveBlankPixel_ and scaledBlankPixelValue_. virtual void initBlankPixel() = 0; // set the blank value string void setBlank(const char* value) { strncpy(blankValue_, value, sizeof(blankValue_)-1); } }; // struct used to save transformation parameters of image for use in new image struct ImageDataParams { int status; // only restore if status is 0 int flipX, flipY; // true if image is flipped int rotate; // true if x,y axis swapped int xScale, yScale; // scale factors int dataType; // data type of image data double lowCut, highCut; // cut levels ImageData::ImageColorScaleType colorScale; // color scale type // constructor ImageDataParams() : status(1) {} }; // struct used to generate a histogram of the image data, where the pixels // are first converted to shorts. struct ImageDataHistogram { int histogram[ImageData::LOOKUP_SIZE]; // count of pixels having this value // after conversion to short int area; // area of image used to create histogram, ImageDataHistogram() { memset(histogram, '\0', sizeof(histogram)); } int size() {return sizeof(histogram);} }; #endif /* _ImageData_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/ImageData.man3000066400000000000000000000404701215713201500217430ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: ImageData.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 20 Jul 95 Created # 21 Feb 96 Renamed from RTI to ImageData # 30 Sep 96 updated # NAME ImageData - C++ Base Class for Managing Image Data SYNOPSIS #include "ImageData.h" class ImageData { ... public: // maximum scale factor enum {MAX_IMAGE_SCALE = 50}; // types of color scaling enum ImageColorScaleType { LINEAR_SCALE, // linear scale LOG_SCALE, // logarithmic or exponential scale SQRT_SCALE, // square root scale HISTEQ_SCALE // histogram equalization }; virtual ~ImageData(); static ImageData* makeImage(const char* name, const ImageIO&, int verbose = 0); int write(const char* filename); void doTrans(double& x, double& y, int distFlag = 0, double xOffset = 0.0, double yOffset = 0.0, int width = 0, int height = 0); void undoTrans(double& x, double& y, int distFlag = 0, double xOffset = 0.0, double yOffset = 0.0, int width = 0, int height = 0); void coordsToDist(double& x, double& y, int width = 0, int height = 0); void distToCoords(double& x, double& y, int width = 0, int height = 0); int getIndex(double x, double y, int& ix, int& iy); void setXImageData(byte* xImage, int width, int height); void setScale(int xScale, int yScale); void shrinkToFit(int width, int height); void update(); void updateOffset(double x, double y); virtual void getDist(int& numValues, double* xyvalues); int getSpectrum(double* xyvalues, int x0, int y0, int x1, int y1); virtual void setCutLevels(double min, double max, int scaled); virtual void autoSetCutLevels(double percent = 98.0); virtual void medianFilter(double* pattern = NULL); virtual void colorScale(int ncolors, unsigned long* colors); virtual int dataType() = 0; virtual ImageData* copy() = 0; void saveParams(ImageDataParams&); void restoreParams(ImageDataParams&); virtual char* getValue(char* buf, double x, double y) = 0; virtual void getValues(double x, double y, double rx, double ry, char* xStr, char* yStr, char* valueStr, char* raStr, char* decStr, char* equinoxStr) = 0; virtual void getValues(double x, double y, double* ar, int nrows, int ncols) = 0; virtual void getValues(double x, double y, int w, int h, float* ar) = 0; virtual double getValue(double x, double y) = 0; virtual int getStatistics(double x, double y, int w, int h, double& meanX, double& meanY, double& fwhmX, double& fwhmY, double& symetryAngle, double& objectPeak, double& meanBackground); Mem& data(); Mem& header(); int getFitsHeader(ostream& os); void data(const Mem& data); void header(const Mem& header); WCS& wcs(); byte* xImage(); const ImageIO& image(); void colorScaleType(ImageColorScaleType t); ImageColorScaleType colorScaleType(); int ncolors(); unsigned long* colors(); unsigned long color0(); unsigned long colorn(); void setColors(int ncolors, unsigned long* colors); void expo(double e); double expo(); int width(); int height(); int dispWidth(); int dispHeight(); int xScale(); int yScale(); int flipX(); void flipX(int b); int flipY(); void flipY(int b); int rotate(); void rotate(int); double highCut(); double lowCut(); double minValue(); double maxValue(); void subsample(int b); void verbose(int b); void name(const char* name); char* name(); void object(const char *object); char* object(); int update_pending(); void update_pending(int b); LookupTable lookup(); int lookup(LookupTable); void clear(); }; DESCRIPTION This class is part of the RTI or Real-Time Image library and is independent of X and Tcl/Tk, so it could, in principle, be used by a separate process from the one displaying the image. Class ImageData is used for managing the image data and the conversion of the raw image data to X image data with transformations (scaling, flipping and rotating). Note that the term "X image", in this case refers to a pointer to an array of bytes and not the XImage struct itself, which is used to actually display the image later. The base class ImageData is the only class visible to the outside, however, there is one subclass for each underlying raw image data type. These subclasses implement the type specific operations on the raw image. Here is the class hierarchy: ImageData Base class, only class visible outside. ShortImageData UShortImageData ByteImageData LongImageData FloatImageData Derived classed for images with the raw data types: short, ushort, byte, long and float XImageData This class is like ByteImageData, except that the raw image is already in XImage format (i.e.: different Y axis direction and no need for color scaling or cut levels). CREATING AN IMAGE OBJECT The ImageData class is designed to work, in principle, independently of the actual image format, although in the end, something resembling FITS format is expected. An ImageData object can be created with the "makeImage()" method. ImageData::makeImage() takes an arbitrary image name, an ImageIO object, and a verbose flag and returns a pointer to an object that is a subclass of ImageData specialized in the data type for that image (ShortImageData, FloatImageData, etc.). The caller creates the ImageIO object and can control how the image is constructed. ImageIO is a reference counted class that can be initialized with a pointer to a subclass of ImageIORep. The astrotcl package currently defines only one subclass called FitsIO, however other packages may add other subclasses to implement support for new image types. You can create an ImageIO object by passing the constructor a pointer to a FitsIO object, and then use this for the ImageData::makeImage() call: ImageIO imio(new FitsIO(width, height, type, 0.0, 1.0, header, data)); image = ImageData::makeImage("myimage", imio, 0); Or you can do it all in one step and let the compiler do the conversion: image = ImageData::makeImage("myimage", new FitsIO(...), 0); Note that the internal image format is always FITS. Other formats may be converted to FITS internally (see ImageIO). WORKING WITH IMAGES The main task of the the ImageData class is to transform raw image data of some type to data that can be displayed in an application window. This includes transformations, such as scaling, rotating and flipping and color scaling, or the mapping of pixel values to a limited number of colormap values. Since applications don't always display the entire image at once, methods are available to transform only a given section of the image. Whenever a part of the raw image is to be copied to the X image, the current transformations and color scaling algorithm are taken into account. The transformations are controlled by flags. These can be accessed through the inline member functions rotate(), flipX(), flipY(), xScale() and yScale(). The color scaling algorithms (linear, logarithmic, square root and histogram equalization) are used to create a lookup table that is used when transforming the image. Basically, the lookup tables (taken from saoimage) convert shorts to bytes. Each subclass defines the method to convert the raw image pixel values to shorts, which are then converted to bytes via the lookup table, according to the current color scaling algorithm. COORDINATES Arguments representing coordinates and dimensions are generally expected to be in image coordinates. Since the caller usually has screen coordinates, these must be converted first to image coordinates by reversing the transformations using the method "undoTrans". METHODS makeImage(name, imageIo, verbose) Return a pointer to a derived class of ImageData specialized in the given type of image. See also above and class ImageIO. write(filename) Save the image to a file. For FITS images, if a header was present, it is reused, otherwise FITS keywords are inserted indicating the image type, width and height along with the date and a number of numbered "blank cards" or FITS keyword fields that can be modified by other applications as needed. The fields have names starting with BLANK followed by 2 digits (from BLANK00 to BLANK28). See FitsIO for more information. doTrans(x, y, dist_flag) undoTrans(x, y, dist_flag) apply (doTrans) or reverse (undoTrans) the transformations on given coordinates (scale, rotate, flipX and flipY). If dist_flag is non-zero, x and y are treated as a distance, so that "flipX" and "flipY" are not done. Note that both methods also reverse the Y axis (when dist_flag is 0), since image coordinates have the origin at lower left rather than upper left as for canvas coordinates. These methods essentially convert between canvas (displayed) coordinates and image coordinates. setXImageData(xImage, width, height) Set the destination XImage buffer and dimensions. This class copies the rawimage to xImage, doing any necessary transformations along the way. setScale(xScale, yScale) Set the scaling factor. The scaling factors are positive or negative integers (default 1). Positive integers are used to zoom in on the image (2 means twice the original size). Negative integers are used to zoom out (-2 means 1/2 the original size). The software imposes an arbitrary limit on the scaling factor of +-MAX_IMAGE_SCALE. shrinkToFit(width, height) Set the scaling factor so that the image will fit within the given dimensions. update() Update the entire image from the raw image if necessary. If nothing has changed since the image was last updated, this call does nothing, otherwise the entire raw image is copied to the X image with transformations. updateOffset(x, y) Update the image area starting at the given offset and continuing to the end of the raw image or the end of the X image data, which ever comes first. The raw data starting at the offset (x,y) is copied to the X image starting at (0,0) with transformations. Note that x and y are in image coordinates. This method is used when the X Image is the same size as the visible window and displays the part of the image at some x,y scroll offset. getDist(numValues, xyvalues) Scan the image and generate X,Y values to show the distribution of pixel values in the image. "numValues" is the max number of X,Y pairs to put in xyvalues (if there are not enough values, numValues is modified to reflect the actual, smaller number of values). This method is used to generate a BLT(n) graph of the pixel value distribution in the image. getSpectrum(xyvalues, x0, y0, x1, y1) Scan the raw image along the line given by x0,y0 and x1,y1 and generate an array of (index, pixel value) information. Return the number of (index,value) pairs generated for the line. This method is used to generate a BLT(n) graph of the pixel values in an arbitrary line in the image. As always, the arguments are expected in image coordinates. setCutLevels(min, max) Manually set the cut levels. This affects color scaling (see colorScale()). autoSetCutLevels(percent) Scan the image to find the distribution of pixel values (using getDist()) and set the cut levels so that the given percent of pixels are within the low and high cut values. medianFilter(pattern) Automatically set the cut levels using a median filtering algorithm. The optional "pattern" parameter may be specified as a pointer to an array containing a fixed pattern of pixels (the same size as the image), which is used by the algorithm. colorScale(ncolors, colors) Create the color scale lookup table for the image. "ncolors" is the number of available colors in the colormap. "colors" is an array of pixel values for the available colors. The color scaling algorithm used is set with the (inline) method colorScaleType(), and defaults to ImageData::LINEAR_SCALE. dataType() Return the type of the raw image data as an enumeration value (see enum ImageDataType above). copy() This virtual method returns an allocated copy of the image. The copy will share the same raw image pointer and color lookup table. Normally, a new X image pointer is assigned after this call, so that the same raw image can be transformed in different ways. This is used by the rtdimage widget to implement "views", such as the panning window and zoom window. copyParamsFrom(image) Copy the cut levels and transformation params from the given image. getValue(buf, x, y) Print the coordinates and raw data value at the given x,y image coords to the given char* buffer. A "-" is printed if the x,y coords are out of range. getValue(x, y) Return the raw image value at the given x,y coordinates as a double. The input x,y is assumed to be in image coordinates. If the coordinates are out of range, 0.0 is returned. getValues(x, y, xStr, yStr, valueStr, raStr, decStr, equinoxStr) Print the values at the given x,y coordinates to the given buffers for display. X and Y are specified in image coordinates and the values written to the buffers are in image and world coordinates, resp. If the given point is out of range, the buffers are set to the empty string. getValues(x, y, ar, nrows, ncols) Fill the given array with the pixel values surrounding the given image coordinate point. nrows and ncols give the dimensions of the array. Any values that are outside of the image are set to HUGE_VAL. Note: it is assumed that nrows and ncols are odd numbers and that the array is one row and column larger (nrows+1 x ncols+1), so that it can hold the X and Y index headings. The X heading is in the first row of the 2 dimensional array and contains the X coordinate values. The Y coordinate values are in the first column. header() data() Return a reference to the class "Mem" object used to represent the FITS image header (or data). header(m) data(m) Set a new (FITS) image header or image data object (of class Mem). xImage() Get a pointer to the X image data. colorScaleType() colorScaleType(type) Get/set the current color scale algorithm (see enum ImageColorScaleType above). ncolors() colors() Get the number of colors in the colormap or the pointer to the color values (set with colorScale() or setColors()). setColors(ncolors, colors) Set the number of colors in the colormap or the pointer to the color values. color0() colorn() These two methods return the color values for blank pixels (color0()) and saturated pixels (colorn()). These two color cells are normally reserved for this purpose and are not otherwise used in the image. color0 is normally black and colorn is normally white. See ImageColor. expo(e) expo() Set/get the exponent used for logarithmic or square root color scaling. width() height() Get the dimensions of the raw image. dispWidth() dispHeight() Get the dimensions of the image after transformations. xScale() yScale() Get the X and Y scale (magnification) factors (Set with setScale()). flipX() flipX(bool) flipY() flipY(bool) rotate() rotate(bool) Turn flipping in the X or Y direction or rotating on or off for the image. highCut() lowCut() Get the high or low cut value (set with setCutLevels()). minValue() maxValue() Get the minimum or maximum raw image value. subsample(bool) Set the subsample flag, to true to use every nth pixel when shrinking an image, or false to use the maximum pixel. verbose(bool) Sets a flag: if true, diagnostic messages are printed out at run time. name(name) name() Set/get the name of the image. This is some arbitrary string used to identify the image. The set routine makes a local copy of the string, wcs() This method returns a reference to the WCS class object for this image. This object provides a number of methods for working with world coordinates and converting between pixel and world coordinates. clear() Temporarilly clear the X image data to make the image blank (until the next call to "update" or "updateOffset"). SEE ALSO rtdimage(n), RtdImage, ImageColor(3C++), ImageDisplay(3C++), WCS, BLT(n) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/rtd/generic/ImageDisplay.C000066400000000000000000000162051215713201500220220ustar00rootroot00000000000000/* * E.S.O. - VLT project * "@(#) $Id: ImageDisplay.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * ImageDisplay.C - member routines for class ImageDisplay, * for managing XImage to Pixmap display including * optional X shared memory extension usage * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * Peter W. Draper 04/03/98 Added putpixel member. Fixed allocation * of data to bytes_per_line*width when not * using shared memory. * 18/06/03 Some changes to attempt cleanup when * shared memory cannot be attached (Solaris * limit is 6 segments!). */ static const char* const rcsId="@(#) $Id: ImageDisplay.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; // #define DEBUG // #define XXXDEBUG #include #include #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" #include "error.h" #include "ErrorHandler.h" #include "ImageDisplay.h" #ifdef NEED_SHM_PROTO // missing prototypes (on SunOS at least) /*extern "C" { // should be in sys/shm.h void *shmat(int shmid, const void* shmaddr, int shmflg); int shmdt(const void* shmaddr); int shmget(key_t, size_t, int); int shmctl(int shmid, int cmd, shmid_ds *buf); }*/ #endif /* * constructor - create an object to manage the XImage * * args: * display, visual, gc - standard X env * width, height, depth - dimensions of image * useXShm - flag: true if we should try to use X Shared Memory * verbose - flag: if true, print diagnostic messages */ ImageDisplay::ImageDisplay(Display *display, Visual *visual, GC gc, int depth, int useXShm, int verbose) : xImage_(NULL), display_(display), visual_(visual), gc_(gc), depth_(depth), bytesPerPixel_(depth/8), useXShm_(useXShm), usingXShm_(0), verbose_(verbose) { if (depth_ == 24) bytesPerPixel_ = 4; } /* * Destructor - clean up XImage */ ImageDisplay::~ImageDisplay() { destroyXImage(); } /* * destroy the XImage and free any allocated shared memory * if necessary */ void ImageDisplay::destroyXImage() { if (xImage_) { if (usingXShm_) { XShmDetach(display_, &shmInfo_); XDestroyImage(xImage_); shmdt(shmInfo_.shmaddr); } else { XDestroyImage(xImage_); } xImage_ = NULL; } } /* * flush X output buffer and wait until all requests were processed * by the X server. */ void ImageDisplay::flushX() { if (! xImage_) return; XSync(display_, False); } /* * do an XPutImage or XShmPutImage, depending on the current flags */ void ImageDisplay::put(Drawable d, int src_x, int src_y, int dest_x, int dest_y, int width, int height) { if (! xImage_) return; // make sure arguments are in range if (src_x < 0) src_x = 0; if (src_y < 0) src_y = 0;; width = min(width, xImage_->width - src_x); height = min(height, xImage_->height - src_y); if (width <= 0 || height <= 0) return; if (usingXShm_) { XShmPutImage(display_, d, gc_, xImage_, src_x, src_y, dest_x, dest_y, width, height, False /*True = send event*/); } else { XPutImage(display_, d, gc_, xImage_, src_x, src_y, dest_x, dest_y, width, height); } return; } /* * create or update the XImage using X shared memory * so that it has the given width and height and return TCL_OK if all * is TCL_OK. */ int ImageDisplay::updateShm(int width, int height) { // use this to catch X errors ErrorHandler errorHandler(display_, verbose_); // create an XImage in shared memory xImage_ = XShmCreateImage(display_, visual_, depth_, ZPixmap, NULL, &shmInfo_, width, height); if (!xImage_) { #ifdef DEBUG if (verbose_) cout << "XShmCreateImage failed\n"; #endif return TCL_ERROR; } // allocate enough shared memory to hold the image // (plus a fudge factor to keep the X server on HP happy) shmInfo_.shmid = shmget(IPC_PRIVATE, (xImage_->bytes_per_line * (height+1)), IPC_CREAT | 0777); if (shmInfo_.shmid < 0) { XDestroyImage(xImage_); xImage_ = NULL; #ifdef DEBUG if (verbose_) { perror("shmget failed for X shared memory"); } #endif return TCL_ERROR; } shmInfo_.shmaddr = (char *) shmat(shmInfo_.shmid, 0, 0); if (shmInfo_.shmaddr == ((char *) -1)) { XDestroyImage(xImage_); shmctl(shmInfo_.shmid, IPC_RMID, 0); shmdt(shmInfo_.shmaddr); xImage_ = NULL; #ifdef DEBUG if (verbose_) perror("shmat failed for X shared memory"); #endif return TCL_ERROR; } xImage_->data = shmInfo_.shmaddr; shmInfo_.readOnly = False; XShmAttach(display_, &shmInfo_); // check for X errors if (errorHandler.errors()) { XShmDetach(display_, &shmInfo_); XDestroyImage(xImage_); shmctl(shmInfo_.shmid, IPC_RMID, 0); shmdt(shmInfo_.shmaddr); xImage_ = NULL; #ifdef DEBUG if (verbose_) cout << "X shared memory error\n"; #endif return TCL_ERROR; } // this will cause the shared memory to be automatically deleted shmctl(shmInfo_.shmid, IPC_RMID, 0); #ifdef XXXDEBUG if (verbose_) cout << "Sharing memory\n"; #endif return TCL_OK; } /* * create or update the XImage so that it has the given width and height */ int ImageDisplay::update(int width, int height) { if (xImage_) { // reuse old XImage if it has the same dimensions if (xImage_->width == width && xImage_->height == height) { return TCL_OK; } destroyXImage(); xImage_ = NULL; } if (useXShm_) { // try to create a shared memory XImage if (updateShm(width, height) == TCL_OK) { usingXShm_ = 1; return TCL_OK; } usingXShm_ = 0; #ifdef DEBUG if (verbose_) cout << "Couldn't create X shared memory: reverting to standard X Image\n"; #endif } // fallback: create a normal XImage xImage_ = XCreateImage(display_, visual_, depth_, ZPixmap, 0, (char *) NULL, width, height, BitmapPad(display_), 0); // now allocate the image data (which must use the appropriate padding). xImage_->data = (char *)malloc(xImage_->bytes_per_line * height); if (xImage_->data == NULL) { #ifdef DEBUG if (verbose_) cout << "out of memory for XImage\n"; #endif XDestroyImage(xImage_); return error("not enough memory for an image this size"); } #ifdef XXXDEBUG if (verbose_) cout << "Not Sharing memory\n"; #endif return TCL_OK; } /* * clear out the image by setting all pixels to the given value */ void ImageDisplay::clear(unsigned long val) { if (!xImage_) return; // byte data if (depth_ == 8) { memset(xImage_->data, val, xImage_->bytes_per_line * xImage_->height); } else { // XImage has depth greater than a byte for (int i=0; iwidth; i++) { for (int j=0; jheight; j++) { XPutPixel(xImage_, i, j, val); } } } } skycat-3.1.2-starlink-1b/rtd/generic/ImageDisplay.h000066400000000000000000000060741215713201500220720ustar00rootroot00000000000000// -*-c++-*- #ifndef _ImageDisplay_H_ #define _ImageDisplay_H_ /* * E.S.O. - VLT project * "@(#) $Id: ImageDisplay.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * ImageDisplay.h - class managing XImage to Pixmap display including * optional X shared memory extension usage * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * T. Herlin 06/12/95 Casted NULL return from ImageDisplay::data * P.W. Draper 04/03/98 Added putpixel member. */ #include #include #include #include #include class ImageDisplay { protected: XImage* xImage_; // XImage for the basic image Display *display_; // X token for the window's display Visual *visual_; // X visual for window GC gc_; // Graphics context for copying to screen int depth_; // bits per pixel int bytesPerPixel_; // bytes per pixel // note: it might be that we can use XShm only on smaller images due to // system limits on shared memory usage (on SunOS, for example) int useXShm_; // flag: true if we WANT to use X shared memory int usingXShm_; // flag: true if we ARE using X shared memory XShmSegmentInfo shmInfo_; // X shared memory Segment info for xImage_ int verbose_; // flag: if true, print diagnostic messages // destroy the XImage and free any shared memory void destroyXImage(); // try to create an XImage in shared memory int updateShm(int width, int height); public: // constructor ImageDisplay(Display *display, Visual *visual, GC gc, int depth, int useXShm, int verbose); // destructor ~ImageDisplay(); // create or update an XImage with the given size int update(int width, int height); // copy the XImage to a Drawable in the X Server void put(Drawable, int src_x, int src_y, int dest_x, int dest_y, int width, int height); // return a pointer to the XImage data unsigned char* data() { return xImage_ ? (unsigned char*)xImage_->data : (unsigned char*)NULL; } // clear out the image by setting all pixels to the given value void clear(unsigned long val); // Assign a value to a pixel (This is the "safe" method for non-byte XImages) void putpixel(int x, int y, unsigned long value) { // assert(xImage_ != NULL); XPutPixel(xImage_, x, y, value); } // flush X output buffer void flushX(); // other info int width() {return xImage_ ? xImage_->width : 0;} int height() {return xImage_ ? xImage_->height : 0;} int bitmapPad() {return xImage_ ? xImage_->bitmap_pad : 0;} int bytesPerLine() {return xImage_ ? xImage_->bytes_per_line : 0;} int depth() {return depth_;} int bitsPerPixel() {return bytesPerPixel_*8;} int bytesPerPixel() {return bytesPerPixel_;} // return true if we are really using X shared memory int usingXShm() {return usingXShm_;} }; #endif /* _ImageDisplay_H_ */ skycat-3.1.2-starlink-1b/rtd/generic/ImageTemplates.h000066400000000000000000000101421215713201500224120ustar00rootroot00000000000000// -*-c++-*- /* * E.S.O. - VLT project * # * # "@(#) $Id: ImageTemplates.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * ImageTemplates.h - template class method definitions for classes derived * from class ImageData and defined in ImageTemplates.C * * This file is included in the header files for the different image data * types. ImageTemplates.C is included in the body files to define some * methods that differ only in the raw image data type. * * See the man page ImageData(3) and the RTD User's Guide for a complete * description of this class hierarchy. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * P.Biereichel 30/06/97 Changed parameters in getValues() for pixel table * Peter W. Draper 12/07/99 Added getBlank(); * 16/04/08 Added growAndShrink() * 19/06/09 Added parseBlank() */ #define SAMP_METHOD_MAX 0 /* max value of all pixels in a NxN box (default) */ #define SAMP_METHOD_MIN 1 /* min value of all pixels in a NxN box */ #define SAMP_METHOD_MEAN 2 /* mean value of all pixels in a NxN box */ #define SAMP_METHOD_MEDIAN 3 /* median value of all pixels in a NxN box */ #define SAMP_METHOD_MAX_CROSS 4 /* max value of pixels on a diagonal cross in a NxN box */ #define SAMP_METHOD_MIN_CROSS 5 /* min value of pixels on a diagonal cross in a NxN box */ #define SAMP_METHOD_MEAN_CROSS 6 /* mean value of pixels on a diagonal cross in a NxN box */ #define SAMP_METHOD_MEDIAN_CROSS 7 /* median value of pixels on a diagonal cross in a NxN box */ #define SAMP_METHOD_MEDIAN_CHESS 8 /* median value of pixels in a chess-board like box */ #define SAMP_METHOD_MEDIAN_9 9 /* median value of a 3x3 box */ #define SAMP_METHOD_RMS 10 /* RMS value of all pixels in a NxN box */ protected: // calculate min and max pixel values void getMinMax(); // print raw data value at x,y coords to buffer char* getValue(char* buf, double x, double y); // return the value at the x,y coords as a double double getValue(double x, double y); // print the values at the given x,y coords to the buffers for display void getValues(double x, double y, double rx, double ry, char* xStr, char* yStr, char* valueStr, char* raStr, char* decStr, char* equinoxStr); // get array of image pixel values and x,y coords around a point void getValues(double x, double y, double rx, double ry, double* ar, int nrows, int ncols, int flag = 0); // get array of image pixel values at a given offset with given dimensions void getValues(double x, double y, int w, int h, float* ar, int flag = 0); // Copy raw image data from this image to the given image data area, // starting at the image coordinates (x, y) and with the dimentions (w, h) // in pixels. Since this is a copy from one raw image to another, no // data conversion is done. void copyImageArea(void* data, double x, double y, int w, int h); // copy raw data to xImage, pos. with transformations (defined in derived class) void rawToXImage(int x0, int y0, int x1, int y1, int dest_x, int dest_y); void grow(int x0, int y0, int x1, int y1, int dest_x, int dest_y); void shrink(int x0, int y0, int x1, int y1, int dest_x, int dest_y); // version of grow that can deal with a shrinked axis void growAndShrink(int x0, int y0, int x1, int y1, int dest_x, int dest_y); // automatically set the cut levels using median filtering void medianFilter(); // get array with information about the pixel value distribution void getPixDist(int numValues, double* xyvalues, double factor); // If there is a special value for blank pixels, get it and set the // values of haveBlankPixel_ and scaledBlankPixelValue_. void initBlankPixel(); // Fill the given histogram with the distribution of pixels in the // visible image area void getHistogram(ImageDataHistogram&); // return the blank value. int haveBlank() {return haveBlank_;} double getBlank() {return (double) blank_;} // set blank value from a string int parseBlank(const char* value); skycat-3.1.2-starlink-1b/rtd/generic/ImageTemplates.icc000066400000000000000000001223071215713201500227300ustar00rootroot00000000000000/* * E.S.O. - VLT project * * "@(#) $Id: ImageTemplates.icc,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * ImageTemplates.C - template member functions for classes derived from * class ImageData (not C++ templates, uses cpp macros) * * See the man page ImageData(3) for a complete description of this class * hierarchy. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * Peter W. Draper 29/01/97 Added FITS_LONG changes (for alpha 64 longs) * P.Biereichel 30/06/97 Changed parameters in getValues() for pixel table * Peter W. Draper 23/02/98 Changed min/max calculations to use more * pixels (too many occurences of "strange" limits). * 06/03/98 Added changes to support XImage depths * greater than one byte. * pbiereic 22/03/99 Added on-the-fly subtraction. * Peter W. Draper 17/08/00 Changed getMinMax slightly. This now * checks if the total height of the image * is shown, rather than just testing * y0_. This could be wrong for zoomed * pbiereic 21/06/00 Fixed "array out of bounds" in getMinMax() * Peter W. Draper 19/03/01 Made sure that x1 and y1 in getMinMax, * never run off the edges of image. * pbiereic 17/02/03 Native byte order routines revised * Peter W. Draper 30/05/03 Skip runs of blank pixels in median estimate * pbiereic 18/06/04 Added experimental sampling methods * Peter W. Draper 01/11/06 Changed getMinMax to deal with images that * have a dimension of 1 (but not both). * 08/01/07 Changed getMinMax to deal with 1x1 case too. * 16/07/07 When first pixel is blank or NaN make sure * failed check for a valid pixel tests both * blank and NaN, not just NaN. * 16/04/08 Added growAndShrink() to allow scales * to have positive and negative values * at the same time. * 19/06/09 Change initBlankValue to use the cached * blankValue_ and make public (allows change). * pbiereic 12/08/07 added support for data types double and long long int * Peter W. Draper 17/05/12 Merged skycat double version created by pbiereic. * * This file is included in the .C files for classes derived from class * ImageData. The file defines a number of member functions that are * always the same, except for the underlying raw image data type. The * member functions are implemented in the derived classes for speed * (otherwise we would have to call virtual functions on each pixel...) * * Before including, the following #defines need to be made: * * #define CLASS_NAME <...> - as the name of the derived class * #define DATA_TYPE as the raw image data type (short, long, float,...) * #define NTOH(x) to be just (x) if you're sure your type never requires * byte-swapping. Otherwise leave it undefined and the * code below should do the right thing. * #define ISNAN(x) Only for floating point types, returns true if x is a NAN */ /* * For all member functions within this file use the inline function getVal() * instead of referencing the raw image directly. getVal() returns the raw * image pixel value or the subtracted value if a bias frame was selected. * Before using getVal() initialize this function with initGetVal(). */ #include #include #include "define.h" // This is a no-op for non-floating point data types. This macro is // defined as isnan(x) for floating point types. #ifndef ISNAN #define ISNAN(x) 0 #endif /* * getVal() is an inline function which subtracts on-the-fly a * bias pixel if a bias frame is selected. * p - is a pointer to the raw image * idx - is an index to the image * * looks "big" but it isn't (gcc assembler code was checked). */ inline DATA_TYPE CLASS_NAME::getVal(DATA_TYPE* p, int idx) { // return pixel value if bias subtraction is off if (! ImageData::biasInfo_->on) return (DATA_TYPE)NTOH(*(p + idx)); if ( ! bias_swap_bytes_) { // return faster if image dimensions and types are the same if (ImageData::biasInfo_->sameTypeAndDims) return ((DATA_TYPE)NTOH(*(p + idx)) - (DATA_TYPE)((DATA_TYPE)(*((DATA_TYPE*)ImageData::biasInfo_->ptr + idx)))); register biasINFO* bias = ImageData::biasInfo_; register int x = idx % width_ + startX_; register int y = idx / width_ + startY_; // if pixel is not within the boundary of the bias image return pixel value if (x < 0 || x >= bias->width || y < 0 || y >= bias->height) return NTOH(*(p + idx)); register int biasIdx = y * bias->width + x; switch (bias->type) { case BYTE_IMAGE: case X_IMAGE: return (DATA_TYPE)NTOH(*(p + idx)) - (DATA_TYPE)((byte)(*((byte *)bias->ptr + biasIdx))); case USHORT_IMAGE: return (DATA_TYPE)NTOH(*(p + idx)) - (DATA_TYPE)((ushort)(*((ushort *)bias->ptr + biasIdx))); case SHORT_IMAGE: return (DATA_TYPE)NTOH(*(p + idx)) - (DATA_TYPE)((short)(*((short *)bias->ptr + biasIdx))); case LONG_IMAGE: return (DATA_TYPE)NTOH(*(p + idx)) - (DATA_TYPE)((int)(*((int *)bias->ptr + biasIdx))); case FLOAT_IMAGE: return (DATA_TYPE)NTOH(*(p + idx)) - (DATA_TYPE)((float)(*((float *)bias->ptr + biasIdx))); case DOUBLE_IMAGE: return (DATA_TYPE)NTOH(*(p + idx)) - (DATA_TYPE)((double)(*((double *)bias->ptr + biasIdx))); case LONGLONG_IMAGE: return (DATA_TYPE)NTOH(*(p + idx)) - (DATA_TYPE)((long long)(*((long long *)bias->ptr + biasIdx))); default: return (DATA_TYPE)NTOH(*(p + idx)); } } else { register biasINFO* bias = ImageData::biasInfo_; register int x = idx % width_ + startX_; register int y = idx / width_ + startY_; // if pixel is not within the boundary of the bias image return pixel value if (x < 0 || x >= bias->width || y < 0 || y >= bias->height) return NTOH(*(p + idx)); register int biasIdx = y * bias->width + x; switch (bias->type) { case BYTE_IMAGE: case X_IMAGE: return (DATA_TYPE)NTOH(*(p + idx)) - (DATA_TYPE)((byte)(*((byte *)bias->ptr + biasIdx))); case USHORT_IMAGE: return (DATA_TYPE)NTOH(*(p + idx)) - (DATA_TYPE)((ushort)SWAP16(*((ushort *)bias->ptr + biasIdx))); case SHORT_IMAGE: return (DATA_TYPE)NTOH(*(p + idx)) - (DATA_TYPE)((short)SWAP16(*((short *)bias->ptr + biasIdx))); case LONG_IMAGE: return (DATA_TYPE)NTOH(*(p + idx)) - (DATA_TYPE)((int)SWAP32(*((int *)bias->ptr + biasIdx))); case FLOAT_IMAGE: return (DATA_TYPE)NTOH(*(p + idx)) - (DATA_TYPE)((float)SWAP_FLOAT(*((float *)bias->ptr + biasIdx))); case DOUBLE_IMAGE: return (DATA_TYPE)NTOH(*(p + idx)) - (DATA_TYPE)((double)SWAP_DOUBLE(*((double *)bias->ptr + biasIdx))); case LONGLONG_IMAGE: return (DATA_TYPE)NTOH(*(p + idx)) - (DATA_TYPE)((long long)SWAP64(*((long long *)bias->ptr + biasIdx))); default: return (DATA_TYPE)NTOH(*(p + idx)); } } } /* * Scan the image to find the min and max values and set the member * variables accordingly. To save time, only the visible area of the * image is examined (x0_, y0_, x1_ and y1_ are set each time the * image is updated, however they are initially set to the entire * image). * The result is that the member variables minValue_ and maxValue_ * are set. */ void CLASS_NAME::getMinMax() { DATA_TYPE* rawImage = (DATA_TYPE*)image_.dataPtr(); int p; register DATA_TYPE value; initGetVal(); // init flag for speeding up bias subtraction // use area of image that is visible. // if we are looking at the whole image, ignore the margin int w = x1_ - x0_ + 1, h = y1_ - y0_ + 1; int xmargin = 0, ymargin = 0; if (w == width_) xmargin = int(w * 0.02); if ( h == height_ ) // PWD: change here, test was y0_ == 0 ymargin = int(h * 0.02); int x0 = x0_ + xmargin; int y0 = y0_ + ymargin; int x1 = min( x1_ - xmargin, width_ - 1 ); // PWD: stop running int y1 = min( y1_ - ymargin, height_ - 1 );// off edges w = x1 - x0 + 1; h = y1 - y0 + 1; if ( w < 1 || h < 1 || ( w == 1 && h == 1 )) { if (area_ > 0) { minValue_ = maxValue_ = getVal(rawImage, 0); } else { minValue_ = maxValue_ = 0; } return; } // set the x, y increments so that not every pixel or line is // examined on large images int xincr = w/256; if (xincr == 0) xincr++; int yincr = h/256; if (yincr == 0) yincr++; if (x1 >= x1_ - xincr) { x1 = x1_ - xincr; if ( x1 < 0 ) { x1 = 1; } } if (y1 >= y1_ - yincr) { y1 = y1_ - yincr; if ( y1 < 0 ) { y1 = 1; } } // try to speed things up a bit on large images: // don't examine every pixel, just look at a few sample lines p = y0*width_+x0; // first pixel in region to examine value = getVal(rawImage, p); // ignore BLANK pixels. For efficiency, we only check the flag once int end = area_; if (haveBlank_) { // make sure starting min/max values are not the BLANK pixel while(value == blank_ || ISNAN(value)) { p += 10; // check another pixel if (p >= end) break; value = getVal(rawImage, p); } if (value == blank_ || ISNAN(value)) value = 0; minValue_ = maxValue_ = value; for (int y = y0; y <= y1; y+=yincr) { p = y*width_+x0; if (p >= end) break; for (int x = x0; x <= x1; x+=xincr, p+=xincr) { if ((value = getVal(rawImage, p)) == blank_ || ISNAN(value)) continue; if (value < minValue_) minValue_ = value; else if (value > maxValue_) maxValue_ = value; } } } else { // note that for non-float types, the ISNAN call is optimized away while(ISNAN(value)) { p += 10; // check another pixel if (p >= end) break; value = getVal(rawImage, p); } if (ISNAN(value)) value = 0; minValue_ = maxValue_ = value; for (int y = y0; y <= y1; y+=yincr) { p = y*width_+x0; if (p >= end) break; for (int x = x0; x <= x1; x+=xincr, p+=xincr) { value = getVal(rawImage, p); if (ISNAN(value)) continue; if (value < minValue_) minValue_ = value; else if (value > maxValue_) maxValue_ = value; } } } } /* * print the coordinates and raw data value at the given x,y image * coords to the buffer * * A "-" is printed if the x,y coords are out of range. * "blank" is printed if the pixel is blank. */ char* CLASS_NAME::getValue(char* buf, double x, double y) { DATA_TYPE* rawImage = (DATA_TYPE*)image_.dataPtr(); DATA_TYPE value; initGetVal(); // init flag for bias subtraction int ix, iy; if (getIndex(x, y, ix, iy) != 0) sprintf(buf, "%.1f %.1f -", x, y); else { value = getVal(rawImage, iy*width_+ix); if (haveBlank_ && value == blank_) sprintf(buf, "%.1f %.1f blank", x, y); else sprintf(buf, "%.1f %.1f %g", x, y, scaleValue(value)); } return buf; } /* * return the value at the x,y image coords as a double. * * The input x,y is assumed to be in image coords. * If the coords are out of range, 0.0 is returned. */ double CLASS_NAME::getValue(double x, double y) { DATA_TYPE* rawImage = (DATA_TYPE*)image_.dataPtr(); int ix, iy; initGetVal(); // init flag for bias subtraction if (getIndex(x, y, ix, iy) != 0) return 0.0; return scaleValue(getVal(rawImage, iy*width_+ix)); } /* * print the X, Y coordinates, raw data value and World Coordinates * at the given x,y image coords to the given buffers. * * rx and ry are the image coordinates to use to access the pixel value. This might * be different than x,y, since x,y are the logical image coordinates, assuming the * image starts at 1,1, which might not actually be the case. * * A blank value is printed if the rx,ry coords are out of range. * * note: x, y and rx,ry are expected in image coords, while in the result, * xStr and yStr are in "chip" coords, since they should be displayed. */ void CLASS_NAME::getValues(double x, double y, double rx, double ry, char* xStr, char* yStr, char* valueStr, char* raStr, char* decStr, char* equinoxStr) { initGetVal(); // init flag for speeding up bias subtraction // display chip coords for x and y double cx = x, cy = y; imageToChipCoords(cx, cy); sprintf(xStr, "%.1f", cx); sprintf(yStr, "%.1f", cy); *raStr = '\0'; *decStr = '\0'; *equinoxStr = '\0'; if (wcs().isWcs()) { char buf[80]; wcs().pix2wcs(x, y, buf, sizeof(buf), 1); sscanf(buf, "%s %s %s", raStr, decStr, equinoxStr); } // get integer index in raw image for pixel value int ix, iy; *valueStr = '\0'; if (getIndex(rx, ry, ix, iy) == 0) { DATA_TYPE* rawImage = (DATA_TYPE*)image_.dataPtr(); DATA_TYPE value = getVal(rawImage, iy*width_+ix); if (haveBlank_ && value == blank_) strcpy(valueStr, "blank"); else sprintf(valueStr, "%g", scaleValue(value)); } } /* * Fill the given array with the pixel values surrounding the given point. * nrows and ncols give the dimensions of the array. Any values that are outside * of the image or are blank (BLANK keyword) are set to -HUGE_VAL (If "flag" * is non-zero, values outside the image are not changed). * * Note: it is assumed that nrows and ncols are odd numbers and that the array * is one row and column larger (nrows+1 x ncols+1), so that it can hold the * X and Y index headings. * * rx and ry are the image coordinates to use to access the pixel value. This might * be different than x,y, since x,y are the logical image coordinates, assuming the * image starts at 1,1, which might not actually be the case. * * note: x, y and rx,ry are expected in image coords, however the coordinates in the * result are "chip" coords, since they should be displayed. * */ void CLASS_NAME::getValues(double x, double y, double rx, double ry, double* ar, int nrows, int ncols, int flag) { DATA_TYPE* rawImage = (DATA_TYPE*)image_.dataPtr(); initGetVal(); // init flag for speeding up bias subtraction int m = ncols/2; int n = nrows/2; int w = ncols+1; int i, j; // get pixel index int ix, iy; // insert the x coord headings for (i = 0; i < ncols; i++) { double cx = x+(i-m); imageToChipCoords(cx); ar[i+1] = cx; // X coord top heading } for (j = 0; j < nrows; j++) { double cy = y+(j-n); imageToChipCoords(cy); ar[(j+1)*w] = cy; // Y coord left heading for (i = 0; i < ncols; i++) { if (getIndex(rx+(i-m), ry+(j-n), ix, iy) == 0) { DATA_TYPE value = getVal(rawImage, iy*width_+ix); if (haveBlank_ && value == blank_) ar[(j+1)*w+i+1] = -HUGE_VAL; else ar[(j+1)*w+i+1] = scaleValue(value); } else if (! flag) { ar[(j+1)*w+i+1] = -HUGE_VAL; } } } } /* * Fill the given array with the pixel values (converted to floats as needed) * at the given x,y image pos, width and height. * * The array should be large enough for at least (w x h) floats. * * Any values that are outside of the image are set to blank or 0, if there * is no blank pixel value defined (If "flag" is non-zero, values outside * the image are not changed). * * Note: x and y are expected in image coordinates */ void CLASS_NAME::getValues(double x, double y, int w, int h, float* ar, int flag) { DATA_TYPE* rawImage = (DATA_TYPE*)image_.dataPtr(); int i, j; int ix, iy; DATA_TYPE value; initGetVal(); // init flag for speeding up bias subtraction getIndex(x, y, ix, iy); for (j = 0; j < h; j++) { for (i = 0; i < w; i++) { int rx = ix+i, ry = iy+j; if (rx >= 0 && ry >= 0 && rx < width_ && ry < height_) { value = getVal(rawImage, ry*width_+rx); if (haveBlank_ && value == blank_) { // ar[j*w+i] = 0; ar[j*w+i] = blank_; } else { ar[j*w+i] = scaleValue(value); } } else if (!flag) { ar[j*w+i] = blank_; } } } } /* * Copy raw image data from this image to the given image data area, * starting at the image coordinates (x, y) and with the dimentions (w,h) * in pixels. Since this is a copy from one raw image to another, no * data conversion is done. */ void CLASS_NAME::copyImageArea(void* data, double x, double y, int w, int h) { DATA_TYPE* fromImage = (DATA_TYPE*)image_.dataPtr(); DATA_TYPE* toImage = (DATA_TYPE*)data; int i, j; int ix, iy; getIndex(x, y, ix, iy); for (j = 0; j < h; j++) { for (i = 0; i < w; i++) { int rx = ix+i, ry = iy+j; if (rx >= 0 && ry >= 0 && rx < width_ && ry < height_) { toImage[j*w+i] = fromImage[ry*width_+rx]; } else { toImage[j*w+i] = blank_; } } } } /* * copy the raw image to the xImage * * The arguments x0, y0, x1 and y1 are the bounding box of the region of * the raw image that needs to be copied (origin at upper left (0,0)). * * dest_x and dest_y give the coordinates in the XImage where copying * should start. These are normally either (x0,y0) or (0,0). */ void CLASS_NAME::rawToXImage(int x0, int y0, int x1, int y1, int dest_x, int dest_y) { // if (verbose_) // printf("%s: rawToXImage: %d,%d %d,%d +(%d,%d), flip: %d,%d, rotate: %d\n", // name_, x0, y0, x1, y1, dest_x, dest_y, flipX_, flipY_, rotate_); register int i, j; // row/col increments register int src_x_inc, src_y_inc; register int dest_x_inc, dest_y_inc; // source/dest images register DATA_TYPE* rawImage = (DATA_TYPE*)image_.dataPtr(); register int src; register byte* dest = xImageData_; initGetVal(); // init flag for speeding up bias subtraction // width of image area to update int w = x1 - x0 + 1; // set loop increments for based on current transformations switch (flipX_<<1|flipY_) { case 0: // none src = (height_ - 1 - y0) * width_ + x0; src_x_inc = 1; src_y_inc = -width_ - w; break; case 1: // flipY src = y0 * width_ + x0; src_x_inc = 1; src_y_inc = width_ - w; break; case 2: // flipX src = (height_ - 1 - y0) * width_ + (width_ - 1 - x0); src_x_inc = -1; src_y_inc = -(width_ - w); break; case 3: // flipX and flipY src = y0 * width_ + (width_ - 1 - x0); src_x_inc = -1; src_y_inc = width_ + w; break; } // need to take care with non-byte depths, so branch according to // this if ( xImageBytesPerPixel_ == 1 ) { // set args for rotate in dest image if (rotate_) { dest_x_inc = xImageBytesPerLine_; dest_y_inc = -(w * xImageBytesPerLine_ - 1); dest += xImageBytesPerLine_ * dest_x + dest_y; } else { dest_x_inc = 1; dest_y_inc = xImageBytesPerLine_ - w; dest += xImageBytesPerLine_ * dest_y + dest_x; } // copy the raw data to the X image... for (i=y0; i<=y1; i++) { for (j=x0; j<=x1; j++) { *dest = lookup(getVal(rawImage, src)); dest += dest_x_inc; src += src_x_inc; } src += src_y_inc; dest += dest_y_inc; } } else { // XImage has depth greater than a byte, need to take care with // these (byte swapping etc. to server format) register int k = dest_x; register int l = dest_y; for (i=y0; i<=y1; i++) { for (j=x0; j<=x1; j++) { if ( rotate_ ) { xImage_->putpixel( l, k, llookup(getVal(rawImage, src))); } else { xImage_->putpixel( k, l, llookup(getVal(rawImage, src))); } src += src_x_inc; k++; } src += src_y_inc; l++; k = dest_x; } } } /* * This method is called to magnify the image by factors >= 2. * * The arguments x0, y0, x1 and y1 are the bounding box of the region * of the raw image that needs to be copied (origin at upper left (0,0)). * * dest_x and dest_y give the coordinates in the XImage where copying * should start. These are normally either (x0,y0) or (0,0). */ void CLASS_NAME::grow(int x0, int y0, int x1, int y1, int dest_x, int dest_y) { register byte *p, *q; register byte c; register int i, j, n, m; register int xs = xScale_, ys = yScale_; // row/col increments register int src_x_inc, src_y_inc; register int dest_x_inc, dest_y_inc; // source/dest images register DATA_TYPE* rawImage = (DATA_TYPE*)image_.dataPtr(); register int src; register byte* dest = xImageData_; register byte* end = xImageData_ + xImageSize_; initGetVal(); // init flag for speeding up bias subtraction // width of image area to update int w = x1 - x0 + 1; // set loop increments based on current transformations switch (flipX_<<1|flipY_) { case 0: // none src = (height_ - 1 - y0) * width_ + x0; src_x_inc = 1; src_y_inc = -width_ - w; break; case 1: // flipY src = y0 * width_ + x0; src_x_inc = 1; src_y_inc = width_ - w; break; case 2: // flipX src = (height_ - 1 - y0) * width_ + (width_ - 1 - x0); src_x_inc = -1; src_y_inc = -(width_ - w); break; case 3: // flipX and flipY src = y0 * width_ + (width_ - 1 - x0); src_x_inc = -1; src_y_inc = width_ + w; break; } // need to take care with non-byte depths, so branch according to // this if ( xImageBytesPerPixel_ == 1 ) { // set args for rotate in dest image if (rotate_) { dest_x_inc = xImageBytesPerLine_ * xs; dest_y_inc = -(w * xs * xImageBytesPerLine_ - ys); dest += xImageBytesPerLine_ * xs * dest_x + dest_y * ys; } else { dest_x_inc = xs; dest_y_inc = xImageBytesPerLine_ * ys - w * xs; dest += xImageBytesPerLine_ * ys * dest_y + dest_x * xs; } // copy the raw data to the X image... for (i=y0; i<=y1; i++) { for (j=x0; j<=x1; j++) { c = lookup(getVal(rawImage, src)); q = p = dest; src += src_x_inc; dest += dest_x_inc; // replicate the source pixel to an xs x ys box in the dest for (n=0; n= end) { break; } *p++ = c; } p = q += xImageBytesPerLine_; } } src += src_y_inc; dest += dest_y_inc; } return; } // XImage has depth greater than a byte. Need to take care with // these (byte swapping etc. to server format, if really // pushed for performance could use ImageByteOrder() and wing it). int k = dest_x * xs; int l = dest_y * ys; unsigned long cl; int width; int height; if ( rotate_ ) { height = xImage_->width(); width = xImage_->height(); } else { width = xImage_->width(); height = xImage_->height(); } for ( i = y0; i <= y1; i++ ) { for ( j = x0; j <= x1; j++ ) { cl = llookup(getVal(rawImage, src)); // replicate the source pixel to an xs x ys box int maxN = min(l+ys,height), maxM = min(k+xs,width); for ( n = l; n < maxN; n++ ) { for ( m = k; m < maxM; m++ ) { if ( rotate_ ) { xImage_->putpixel( n, m, cl ); } else { xImage_->putpixel( m, n, cl ); } } } k += xs; src += src_x_inc; } k = dest_x * xs; l += ys; src += src_y_inc; } } /* * This method is called when the image scales require grow and shrink. * * The arguments x0, y0, x1 and y1 are the bounding box of the region * of the raw image that needs to be copied (origin at upper left (0,0)). * * dest_x and dest_y give the coordinates in the XImage where copying * should start. These are normally either (x0,y0) or (0,0). */ void CLASS_NAME::growAndShrink(int x0, int y0, int x1, int y1, int dest_x, int dest_y) { register int i, j, n, m; register int xs = xScale_, ys = yScale_; register int rxs = xScale_, rys = yScale_; // One of these is negative, the other not. if ( xs < 0 ) xs = 1; if ( ys < 0 ) ys = 1; // row/col increments register int src_x_inc, src_y_inc; // source/dest images register DATA_TYPE* rawImage = (DATA_TYPE*)image_.dataPtr(); register int src; initGetVal(); // init flag for speeding up bias subtraction // width of image area to update int w = x1 - x0 + 1; // set loop increments based on current transformations switch (flipX_<<1|flipY_) { case 0: // none src = (height_ - 1 - y0) * width_ + x0; src_x_inc = 1; src_y_inc = -width_ - w; break; case 1: // flipY src = y0 * width_ + x0; src_x_inc = 1; src_y_inc = width_ - w; break; case 2: // flipX src = (height_ - 1 - y0) * width_ + (width_ - 1 - x0); src_x_inc = -1; src_y_inc = -(width_ - w); break; case 3: // flipX and flipY src = y0 * width_ + (width_ - 1 - x0); src_x_inc = -1; src_y_inc = width_ + w; break; } int k = dest_x * xs; int l = dest_y * ys; unsigned long cl; int width; int height; if ( rotate_ ) { height = xImage_->width(); width = xImage_->height(); } else { width = xImage_->width(); height = xImage_->height(); } // For the axis that is shrank, we need to stop the pick for a number of // times that gets a step along that axis of the right number. int yskip = 0; int xskip = 0; if ( rys < 0 ) { yskip = -rys; } if ( rxs < 0 ) { xskip = -rxs; } // Skip counters. int xc = 0; int yc = 0; for ( i = y0; i <= y1; i++ ) { xc = 0; for ( j = x0; j <= x1; j++ ) { cl = llookup(getVal(rawImage, src)); // replicate the source pixel to an xs x ys box int maxN = min(l+ys,height), maxM = min(k+xs,width); for ( n = l; n < maxN; n++ ) { for ( m = k; m < maxM; m++ ) { if ( rotate_ ) { xImage_->putpixel( n, m, cl ); } else { xImage_->putpixel( m, n, cl ); } } } // When xScale_ < 0 need to use same pixel again... xc++; if ( xc >= xskip ) { k += xs; xc = 0; } src += src_x_inc; } k = dest_x * xs; // When yScale_ < 0 need to use same pixel again... yc++; if ( yc >= yskip ) { l += ys; yc = 0; } src += src_y_inc; } } /* * get samples of a square box * rawImage : input array * idx : offset in array * wbox : width of box * samples : output vector * returns the number of pixels in the output array samples */ inline int CLASS_NAME::getBsamples(DATA_TYPE *rawImage, int idx, int wbox, DATA_TYPE *samples) { int i, k, src; for (k = 0; k < wbox; k++) { src = idx + k * width_; for (i = 0; i < wbox; i++) { *samples++ = getVal(rawImage, src++); } } return (wbox * wbox); } /* * get samples of a square box (only "black" values on chess-board) * rawImage : input array * idx : offset in array * wbox : width of box * samples : output vector * returns the number of pixels in the output array samples */ inline int CLASS_NAME::getCsamples(DATA_TYPE *rawImage, int idx, int wbox, DATA_TYPE *samples) { int i, k, src; for (k = 0; k < wbox; k++) { src = idx + k * width_ + k%2; for (i = 0; i < wbox; i += 2) { *samples++ = getVal(rawImage, src+i); } } return ((wbox * wbox) / 2 + wbox%2); } /* * get samples on a diagonal cross of a square box * rawImage : input array * idx : offset in array * wbox : width of box * samples : output vector * returns the number of pixels in the output array samples */ inline int CLASS_NAME::getXsamples(DATA_TYPE *rawImage, int idx, int wbox, DATA_TYPE *samples) { int i, n = 0, m = wbox/2; int offs = wbox -1; int idxo = idx + offs; int woff = width_ * offs; if (wbox %2 != 0) { n++; *samples++ = getVal(rawImage, idx + width_ * m + m); /* center pixel of cross */ } for (i = 0; i < m; i++) { *samples++ = getVal(rawImage, idx); *samples++ = getVal(rawImage, idxo); *samples++ = getVal(rawImage, idx + woff); *samples++ = getVal(rawImage, idxo + woff); idx += width_ + 1; offs -= 2; idxo = idx + offs; woff = width_ * offs; } return (n + m * 4); } /* * get median value of array samples * samples : data vector * n : number of pixels in vector samples * returns the median value of vector samples */ inline DATA_TYPE CLASS_NAME::getMedian(DATA_TYPE *samples, int n) { int i, k; DATA_TYPE *pi, *pk = samples, tmp; for (k = 0; k < n; k++, pk++) { pi = samples + k+1; for (i = k+1; i < n; i++, pi++) { if (*pk < *pi) { tmp = *pk; *pk = *pi; *pi = tmp; } } } return (*(samples + n/2)); } /* * get RMS value of array samples * samples : data vector * n : number of pixels in vector samples * returns the RMS value of vector samples */ inline DATA_TYPE CLASS_NAME::getRMS(DATA_TYPE *samples, int n) { int i, cnt = 0; double sum = 0.0, sumsq = 0.0; DATA_TYPE value; for (i = 0; i < n; i++) { value = *samples++; cnt++; sumsq += value * value; sum += value; } if (cnt < 2) return ((DATA_TYPE) 0); value = (DATA_TYPE)sqrt((sumsq - ((sum * sum) / cnt)) / (cnt -1)); return (value); } /* * get value of a shrunk image which is not subsampled * rawImage : input array * idx : offset in array * wbox : width of box * samples : allocated temporary array * xs : scale factor * returns the value according to the sampling method */ inline DATA_TYPE CLASS_NAME::getBoxVal(DATA_TYPE *rawImage, int idx, int wbox, DATA_TYPE *samples, int xs) { DATA_TYPE value; DATA_TYPE *psamples = samples; int n, m; double sum; switch (sampmethod_) { case SAMP_METHOD_MIN: m = getBsamples(rawImage, idx, wbox, samples); for (n = 1, value = *psamples++; n < m; n++, psamples++) { if (*psamples < value) value = *psamples; } return (value); case SAMP_METHOD_MEAN: m = getBsamples(rawImage, idx, wbox, samples); for (n = 0, sum = 0.0; n < m; n++) { sum += *psamples++; } return ((DATA_TYPE) (sum / m)); case SAMP_METHOD_MEDIAN: m = getBsamples(rawImage, idx, wbox, samples); return (getMedian(samples, m)); case SAMP_METHOD_RMS: m = getBsamples(rawImage, idx, wbox, samples); return ((DATA_TYPE)getRMS(samples, m)); case SAMP_METHOD_MAX_CROSS: m = getXsamples(rawImage, idx, wbox, samples); for (n = 1, value = *psamples++; n < m; n++, psamples++) { if (*psamples > value) value = *psamples; } return (value); case SAMP_METHOD_MIN_CROSS: m = getXsamples(rawImage, idx, wbox, samples); for (n = 1, value = *psamples++; n < m; n++, psamples++) { if (*psamples < value) value = *psamples; } return (value); case SAMP_METHOD_MEAN_CROSS: m = getXsamples(rawImage, idx, wbox, samples); for (n = 0, sum = 0.0; n < m; n++) { sum += *psamples++; } return ((DATA_TYPE) (sum / m)); case SAMP_METHOD_MEDIAN_CROSS: m = getXsamples(rawImage, idx, wbox, samples); return (getMedian(samples, m)); case SAMP_METHOD_MEDIAN_CHESS: m = getCsamples(rawImage, idx, wbox, samples); return (getMedian(samples, m)); case SAMP_METHOD_MEDIAN_9: wbox = (xs < 3) ? 1 : 3; m = getBsamples(rawImage, idx, wbox, samples); return (getMedian(samples, m)); default: /* SAMP_METHOD_MAX */ m = getBsamples(rawImage, idx, wbox, samples); for (n = 1, value = *psamples++; n < m; n++, psamples++) { if (*psamples > value) value = *psamples; } return (value); } return (0); } /* * This method is called to shrink the image. If subsample_ is 1, just * take every nth pixel as a sample, otherwise take the max of the * surrounding pixels * * The arguments x0, y0, x1 and y1 are the bounding box of the region * of the raw image that needs to be copied (origin at upper left (0,0)). * * dest_x and dest_y give the coordinates in the XImage where copying * should start. These are normally either (x0,y0) or (0,0). * * Note: there is a (non-fatal) bug here that shows up when dest_x,dest_y are non-zero, * (the image display gets split or mixed up somehow...) - needs some * testing to see what the cause is. */ void CLASS_NAME::shrink(int x0, int y0, int x1, int y1, int dest_x, int dest_y) { int p=0, q=0; int i, j, n, m; int xs = -xScale_, ys = -yScale_; initGetVal(); // init flag for speeding up bias subtraction // for odd shrink factors, we have to be carefull about the end conditions x1 -= (x1-x0+1)%xs; y1 -= (y1-y0+1)%ys; int w = x1-x0+1; // row/col increments int src_x_inc, src_y_inc; int dest_x_inc, dest_y_inc; // source/dest images DATA_TYPE* rawImage = (DATA_TYPE*)image_.dataPtr(); int src; byte* dest = xImageData_; byte* end = xImageData_ + xImageSize_ - 1; DATA_TYPE maxval = 0; // set loop increments based on current transformations switch (flipX_<<1|flipY_) { case 0: // none src = (height_ - ys - y0) * width_ + x0; src_x_inc = xs; src_y_inc = -width_ * ys - w; break; case 1: // flipY src = y0 * width_ + x0; src_x_inc = xs; src_y_inc = width_ * ys - w; break; case 2: // flipX src = (height_ - ys - y0) * width_ + (width_ - xs - x0); src_x_inc = -xs; src_y_inc = -(width_ * ys - w); break; case 3: // flipX and flipY src = y0 * width_ + (width_ - xs - x0); src_x_inc = -xs; src_y_inc = width_ * ys + w; break; } if ( xImageBytesPerPixel_ == 1 ) { // use faster methods for byte xImages // set args for rotate in dest image if (rotate_) { dest_x_inc = xImageBytesPerLine_; dest_y_inc = -(w/xs * xImageBytesPerLine_ - 1); dest += xImageBytesPerLine_ * (dest_x/xs) + (dest_y/ys); } else { dest_x_inc = 1; dest_y_inc = xImageBytesPerLine_ - w/xs; dest += xImageBytesPerLine_ * (dest_y/ys) + (dest_x/xs); } // copy the raw data to the X image... if (subsample_) { // use faster "subsample" algorithm for (i=y0; i<=y1; i+=ys) { for (j=x0; j<=x1; j+=xs) { if (dest > end) { break; } *dest = lookup(getVal(rawImage, src)); dest += dest_x_inc; src += src_x_inc; } src += src_y_inc; dest += dest_y_inc; } } else { // don't subsample: take max pixel for (i=y0; i<=y1; i+=ys) { for (j=x0; j<=x1; j+=xs) { if (dest > end) { break; } q = p = src; for (n=0; n maxval) maxval = getVal(rawImage, p); } p = q += width_; } *dest = lookup(maxval); maxval = 0; dest += dest_x_inc; src += src_x_inc; } src += src_y_inc; dest += dest_y_inc; } } return; } // XImage depth greater than a byte. Use careful methods to // keep byte order etc. correct for server. int k = dest_x / xs; int l = dest_y / ys; if (subsample_ || xs < 2 || ys < 2) { // use faster "subsample" algorithm for (i=y0; i<=y1; i+=ys) { for (j=x0; j<=x1; j+=xs) { if ( rotate_ ) { xImage_->putpixel( l, k, llookup(getVal(rawImage, src))); } else { xImage_->putpixel( k, l, llookup(getVal(rawImage, src))); } k++; src += src_x_inc; } src += src_y_inc; k = dest_x / xs; l++; } return; } // don't subsample: take pixel defined by sampling method DATA_TYPE *samples = new DATA_TYPE[xs * ys]; DATA_TYPE vsamp; int wbox = xs < ys ? xs : ys; for (i = y0; i < y1; i += ys, src += src_y_inc, k = dest_x / xs, l++) { for (j = x0; j < x1; j += xs, src += src_x_inc) { vsamp = getBoxVal(rawImage, src, wbox, samples, xs); if ( rotate_ ) xImage_->putpixel(l, k++, llookup(vsamp)); else xImage_->putpixel(k++, l, llookup(vsamp)); } } delete[] samples; } /* * Set the cut levels using a median filtering algorithm. * To save time, only a center area of the visible image is examined. */ void CLASS_NAME::medianFilter() { getMinMax(); // get min/max pixel estimate for visible area DATA_TYPE *rawImage = (DATA_TYPE*)image_.dataPtr(); // image data const int nmed = 7; // length of median filter int xskip = nmed*3, yskip = 3; // skip pixels for speed int x0 = x0_ + 10; // ignore outside areas int y0 = y0_ + 10; int x1 = x1_ - 10; int y1 = y1_ - 10; int i, j, k, l; int p=0; DATA_TYPE tmp; DATA_TYPE val, lcut, hcut, medary[nmed]; // use this value as a default in place of bad pixels (blank, NAN) DATA_TYPE mval = (DATA_TYPE)((minValue_ + maxValue_)/2); initGetVal(); // init flag for speeding up bias subtraction if (x1-x0 <= nmed || y1-y0 <= nmed) return; for (i=y0; i<=y1; i+=yskip) { for (j=x0; j<=x1; j+=xskip) { p = i*width_ + j; // get array for finding meadian for (k=0; k < nmed; k++) { medary[k] = getVal(rawImage, p++); // ignore blank pixels and NANs if (ISNAN(medary[k]) || (haveBlank_ && medary[k] == blank_)) { medary[k] = mval; } } // get median value for (k=0; k < nmed; k++) { for (l=k; l < nmed; l++) { if (medary[k] < medary[l]) { tmp = medary[l]; medary[l] = medary[k]; medary[k] = tmp; } } } val = medary[nmed/2]; if ( val == mval ) { if ( i == y0 ) { lcut = hcut = 0; // To be safe. } continue; // PWD: Skip runs of blank pixels. } if (i == y0) // set initial low and high cut values lcut = hcut = val; else { // compare meadian with lcut, hcut if (val < lcut) lcut = val; if (val > hcut) hcut = val; } } } setCutLevels(lcut, hcut, 0); } /* * Fill the given array (xyvalues) with statistics about the distribution * of pixels in the visible image area (given by x0_, y0_, x1_, y1_). * xyvalues[n*2+1] is set to the number of pixels with value at or near n. * The factor is used to fit the information in the given size aray. */ void CLASS_NAME::getPixDist(int numValues, double* xyvalues, double factor) { DATA_TYPE* rawImage = (DATA_TYPE*)image_.dataPtr(); DATA_TYPE mv = (DATA_TYPE)minValue_; DATA_TYPE value; initGetVal(); // init flag for speeding up bias subtraction // the Y values are the number of pixels in a given range // note: to save time, don't check all the pixels, just a // number of sample lines in the visible area of the image. if (x1_ <= x0_ || y1_ <= y0_) return; for (int i=y0_; i= 0 && idx < numValues) xyvalues[idx*2+1]++; } } } /* * Fill the given histogram with the distribution of pixels in the * visible image area (given by x0_, y0_, x1_, y1_). h.histogram[n] is * set to the number of pixels with a value of n (after conversion to * short if needed). */ void CLASS_NAME::getHistogram(ImageDataHistogram& hist) { DATA_TYPE* rawImage = (DATA_TYPE*)image_.dataPtr(); DATA_TYPE value; initGetVal(); // init flag for speeding up bias subtraction // if we are looking at the whole image, ignore the margin int w = x1_ - x0_ + 1, h = y1_ - y0_ + 1; int xmargin = 0, ymargin = 0; if (w == width_) xmargin = int(w * 0.2); if (y0_ == 0) ymargin = int(h * 0.2); int x0 = x0_ + xmargin; int y0 = y0_ + ymargin; int x1 = x1_ - xmargin; int y1 = y1_ - ymargin; // the array values are the number of pixels in a given range // note: to save time, don't check all the pixels, just a // number of sample lines in the visible area of the image. if (x1 <= x0 || y1 <= y0) { hist.area = 0; return; } hist.area = (x1 - x0) * (y1 - y0); for (int i=y0; i #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" #include "ImageDisplay.h" #include "ImageZoom.h" /* * constructor: create the zoom GC and XImage. * * Args: * * tkwin - the Tk window for displaying the zoomed image * * copyGC - X GC used to copy image to zoom window * * width, height - dimensions of tkwin (should be square and a multiple * of the zoom factor) * * zoomFactor - the zoom magnification factor * * usingXShm - flag: true if using X shared memory * * verbose - flag: if true, print diagnostic messages * */ ImageZoom::ImageZoom(Tk_Window tkwin, GC gc, int width, int height, int zoomFactor, int usingXShm, int verbose) : tkwin_(tkwin), gc_(gc), width_(width), height_(height), zoomFactor_(zoomFactor), zoomStep_(width/zoomFactor), status_(TCL_OK) { // make a graphics context using XOR to draw a box marking the pointer hotspot XGCValues gcValues; gcValues.function = GXcopy; gcValues.graphics_exposures = False; Tk_MakeWindowExist(tkwin_); rect_gc_ = XCreateGC(Tk_Display(tkwin_), Tk_WindowId(tkwin_), GCFunction|GCGraphicsExposures, &gcValues); // create a class object to manage the XImage xImage_ = new ImageDisplay(Tk_Display(tkwin_), Tk_Visual(tkwin_), gc, Tk_Depth(tkwin_), usingXShm, verbose); status_ = xImage_->update(width, height); } ImageZoom::~ImageZoom() { if (xImage_) delete xImage_; } /* * Called for motion events in image window when zooming is on. * * Args: * * data - pointer to data being displayed * x, y - coords in displayed image (XImage coords) * w, h - width (bytesPerLine) and height of displayed image * xs, ys - x and y magnification factors * color0 - color to use for blank areas with no image data */ void ImageZoom::zoom(unsigned char* data, int x, int y, int w, int h, int xs, int ys, unsigned long color0) { if (status_ != TCL_OK) return; char pixval = color0; register unsigned char* zoomData = xImage_->data(); int zs = zoomStep_ >> 1; int incr = width_ * (zoomFactor_ - 1); int xz = x - zs; int yz = y - zs; int i, j, k, l; for (i=0; i= w || (yz + i) < 0 || (yz + i) >= h) { pixval = color0; } else { pixval = data[(yz+i)*w + xz + j]; } for (k=0; kput(Tk_WindowId(tkwin_), 0, 0, Tk_X(tkwin_), Tk_Y(tkwin_), width_, height_); /* draw 2 rectangles around the center pixel(s) */ int size = zoomFactor_; int x0 = width_/2 - size/2; int y0 = height_/2 - size/2; Screen* screen = Tk_Screen(tkwin_); XSetForeground(Tk_Display(tkwin_), rect_gc_, WhitePixelOfScreen(screen)); XSetBackground(Tk_Display(tkwin_), rect_gc_, BlackPixelOfScreen(screen)); XDrawRectangle(Tk_Display(tkwin_), Tk_WindowId(tkwin_), rect_gc_, x0, y0, size, size); XSetForeground(Tk_Display(tkwin_), rect_gc_, BlackPixelOfScreen(screen)); XSetBackground(Tk_Display(tkwin_), rect_gc_, WhitePixelOfScreen(screen)); XDrawRectangle(Tk_Display(tkwin_), Tk_WindowId(tkwin_), rect_gc_, x0-1, y0-1, size+2, size+2); } skycat-3.1.2-starlink-1b/rtd/generic/ImageZoom.h000066400000000000000000000030631215713201500214040ustar00rootroot00000000000000// -*-c++-*- #ifndef _ImageZoom_h_ #define _ImageZoom_h_ /* * E.S.O. - VLT project * "@(#) $Id: ImageZoom.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * ImageZoom.h - class definitions for RtdImage Zoom Window * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created */ #include /* * Class ImageZoom * * This class implements the Zoom window for the RtdImage class */ class ImageZoom { protected: Tk_Window tkwin_; // zoom window GC gc_; // graphics context for copying pixels GC rect_gc_; // graphics context for drawing box aroung center pixels int width_; // width of displayed image int height_; // height of displayed image int zoomFactor_; // zoom factor (1...n) int zoomStep_; // value used to calculate zoom = width/factor ImageDisplay *xImage_; // class object for zoom window's X image int status_; // return value from constructor public: // constructor: initialize the zoom window ImageZoom(Tk_Window tkwin, GC copyGC, int width, int height, int factor, int usingXShm, int verbose); // destructor: clean up resources ~ImageZoom(); // called for motion events in the image to do the zooming void zoom(unsigned char* data, int x, int y, int w, int h, int xs, int ys, unsigned long color0); // return status after constructor for error checking int status() {return status_;} }; #endif /* _ImageZoom_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/LongImageData.C000066400000000000000000000123011215713201500220770ustar00rootroot00000000000000/* * E.S.O. - VLT project * * "@(#) $Id: LongImageData.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * LongImageData.C - member functions for class LongImageData * * See the man page ImageData(3) for a complete description of this class * library. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * Peter W. Draper 24/01/97 Inverted sense of scaled_ test. * Changed to use macro FITS_LONG as long is * 64 bit on alphas and the "long" integers * read in from FITS files are 32 bit. * 12/06/98 Modified derivation of scaled blank value * to avoid problems with bias * over/underflowing the value, when at an * extreme (I set this to -MIN_LONG_INT, * minus the bias and it underflows). * 10/07/98 Stopped convertToShort. Still problems * with blank pixels that I'm able to * resolve. The scaled variant works fine. * 14/07/98 Added checks for blanks in convert and * scale ToShort. * pbiereic 17/02/03 Added 'using namespace std'. * Peter W. Draper 23/06/09 Added parseBlank to get blank value in this type. */ using namespace std; #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" #include "LongImageData.h" /* * convert the given long int to short by adding the integer bias * and checking the range */ short LongImageData::convertToShort(FITS_LONG l) { register FITS_LONG v = l + bias_; short s; // If have blank pixels then test for this as cannot deal with // pixel values at extremes (these wrap and come out in strange // places). if ( haveBlank_ ) { if ( blank_ == l ) { return LOOKUP_BLANK; } } if (v < LOOKUP_MIN ) s = LOOKUP_MIN; else if (v > LOOKUP_MAX ) s = LOOKUP_MAX; else s = (short) v; return s; } /* * convert the given long int to short by adding the integer bias, * scaling, rounding if necessary and checking the range */ short LongImageData::scaleToShort(FITS_LONG l) { // If have blank pixels then test for this as cannot deal with // pixel values at extremes (these wrap and come out in strange // places). if ( haveBlank_ ) { if ( blank_ == l ) { return LOOKUP_BLANK; } } short s; double d = (l + dbias_) * scale_; if (d < 0.0 ) { if((d -= 0.5) < LOOKUP_MIN) s = LOOKUP_MIN; else s = (short)d; } else { if((d += 0.5) > LOOKUP_MAX) s = LOOKUP_MAX; else s = (short)d; } return s; } /* * initialize conversion from base type long to short * and scale the low and high cut levels to short range * * Method: 3 member variables are set here and used later to convert * the long raw image data to short, which is then used as an index * in the lookup table to get the byte value: * * bias_ = offset * dbias_ = double offset, used when scale != 1.0 * scale_ = scale factor for conversion * : */ void LongImageData::initShortConversion() { // PWD: removed this code as under/overflow problems lead to // occasionally strange images. // if ((highCut_ - lowCut_) <= (LOOKUP_WIDTH)) { // // if a simple offset suffices // scale_ = 1.0; // if ((lowCut_ >= LOOKUP_MIN) && (highCut_ <= LOOKUP_MAX)) { // // if possible to truncate to short without bias, do so. // bias_ = 0; // } // else { // // offset by average to center within range // bias_ = (int)(-((lowCut_ + highCut_) / 2.0)); // } // dbias_ = bias_; // scaledLowCut_ = convertToShort((FITS_LONG)lowCut_); // scaledHighCut_ = convertToShort((FITS_LONG)highCut_); // if (haveBlank_) // scaledBlankPixelValue_ = convertToShort(blank_); // } // else { // full-up scaling required. (+/- (tmax-tmin)/2) // offset values to be zero centered scale_ = LOOKUP_WIDTH / (highCut_ - lowCut_); dbias_ = -((lowCut_ + highCut_) * 0.5); bias_ = (int)dbias_; scaledLowCut_ = scaleToShort((FITS_LONG)lowCut_); scaledHighCut_ = scaleToShort((FITS_LONG)highCut_); if (haveBlank_) scaledBlankPixelValue_ = LOOKUP_BLANK; // } // set int flag for later quick check if scale_ != 1.0 scaled_ = (scale_ != 1.0); // Sense inverted - PWD } /* * Set the blank value from a given string. Return 1 if successful. */ int LongImageData::parseBlank(const char* value) { long l; int n = sscanf(value, "%ld", &l); if ( n > 0 ) { blank_ = (FITS_LONG) l; } return n; } /* * Include some standard methods as (cpp macro) templates: * These are methods that are the same for all derived classes of ImageData, * except that they work on a different raw data type */ #define CLASS_NAME LongImageData #define DATA_TYPE FITS_LONG #ifndef NTOH # define NTOH(x) SWAP32(x) #endif #include "ImageTemplates.icc" #undef NTOH #undef CLASS_NAME #undef DATA_TYPE #undef NTOH skycat-3.1.2-starlink-1b/rtd/generic/LongImageData.h000066400000000000000000000062151215713201500221530ustar00rootroot00000000000000// -*-c++-*- /* * E.S.O. - VLT project * * "@(#) $Id: LongImageData.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * $Id: LongImageData.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * LongImageData.h - class definitions for class LongImageData * * See the man page ImageData(3) for a complete description of this class * library. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * Peter W. Draper 24/01/97 Added FITS_LONG macro changes * P.Biereichel 22/03/99 Added definitions for bias subtraction */ #include #include "ImageData.h" // The type "long" may have up to 64 bits on alpha machines. FITS // defines the long we want to use as 32 bits, so use a macro to // replace the long data type with plain int when appropriate. #if SIZEOF_LONG == 8 #define FITS_LONG int #else #define FITS_LONG long #endif // This class is used for images where the raw data is made up of ints class LongImageData : public ImageData { private: // value of blank pixel, if known (if haveBlankPixel_ is nonzero) FITS_LONG blank_; int bias_; // offset for long to short conversion double dbias_; // used when scale != 1.0 double scale_; // factor for long to short conversion int scaled_; // flag, true if scale_ != 1.0 // local methods used to get short index in lookup table short convertToShort(FITS_LONG); // convert long to short by adding bias short scaleToShort(FITS_LONG); // as above, but with scaling inline ushort convertToUshort(FITS_LONG l) { // unsigned return ushort(scaled_ ? scaleToShort(l) : convertToShort(l)); } // return X image pixel value for raw image value inline byte lookup(FITS_LONG l) { return lookup_[convertToUshort(l)]; } inline unsigned long llookup(FITS_LONG l) { return lookup_[convertToUshort(l)]; } // return NTOH converted value evtl. subtracted with corresponding bias value FITS_LONG getVal(FITS_LONG* p, int idx); int getXsamples(FITS_LONG *rawImage, int idx, int wbox, FITS_LONG *samples); int getBsamples(FITS_LONG *rawImage, int idx, int wbox, FITS_LONG *samples); int getCsamples(FITS_LONG *rawImage, int idx, int wbox, FITS_LONG *samples); FITS_LONG getMedian(FITS_LONG *samples, int n); FITS_LONG getBoxVal(FITS_LONG *rawImage, int idx, int wbox, FITS_LONG *samples, int xs); FITS_LONG getRMS(FITS_LONG *samples, int n); protected: // initialize conversion from base type to short, void initShortConversion(); public: // constructor LongImageData(const char* name, const ImageIO& imio, int verbose) : ImageData(name, imio, verbose), blank_(0) {} // return class name as a string virtual const char* classname() { return "LongImageData"; } // return the data type of the raw data int dataType() {return LONG_IMAGE;} // return true if the data type is signed int isSigned() {return 1;} // return a copy of this object ImageData* copy() {return new LongImageData(*this);} // include declarations for methods that differ only in raw data type # include "ImageTemplates.h" }; skycat-3.1.2-starlink-1b/rtd/generic/LongLongImageData.C000066400000000000000000000067221215713201500227310ustar00rootroot00000000000000/* * E.S.O. - VLT project * * "@(#) $Id: LongLongImageData.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * LongLongImageData.C - member functions for class LongLongImageData * * who when what * -------------- -------- ---------------------------------------- * pbiereic 12/08/07 Created * Peter W. Draper 23/06/09 Added parseBlank to get blank value in this type. */ using namespace std; #include #include #include #include #include #include #include "LongLongImageData.h" #include "define.h" /* * convert the given long int to short by adding the integer bias * and checking the range */ short LongLongImageData::convertToShort(FITS_LONGLONG l) { register FITS_LONGLONG v = l + bias_; short s; // If have blank pixels then test for this as cannot deal with // pixel values at extremes (these wrap and come out in strange // places). if ( haveBlank_ ) { if ( blank_ == l ) { return LOOKUP_BLANK; } } if (v < LOOKUP_MIN ) s = LOOKUP_MIN; else if (v > LOOKUP_MAX ) s = LOOKUP_MAX; else s = (short) v; return s; } /* * convert the given long int to short by adding the integer bias, * scaling, rounding if necessary and checking the range */ short LongLongImageData::scaleToShort(FITS_LONGLONG l) { // If have blank pixels then test for this as cannot deal with // pixel values at extremes (these wrap and come out in strange // places). if ( haveBlank_ ) { if ( blank_ == l ) { return LOOKUP_BLANK; } } short s; double d = (l + dbias_) * scale_; if (d < 0.0 ) { if((d -= 0.5) < LOOKUP_MIN) s = LOOKUP_MIN; else s = (short)d; } else { if((d += 0.5) > LOOKUP_MAX) s = LOOKUP_MAX; else s = (short)d; } return s; } /* * initialize conversion from base type long to short * and scale the low and high cut levels to short range * * Method: 3 member variables are set here and used later to convert * the long raw image data to short, which is then used as an index * in the lookup table to get the byte value: * * bias_ = offset * dbias_ = double offset, used when scale != 1.0 * scale_ = scale factor for conversion * : */ void LongLongImageData::initShortConversion() { // full-up scaling required. (+/- (tmax-tmin)/2) // offset values to be zero centered scale_ = LOOKUP_WIDTH / (highCut_ - lowCut_); dbias_ = -((lowCut_ + highCut_) * 0.5); bias_ = (int)dbias_; scaledLowCut_ = scaleToShort((FITS_LONGLONG)lowCut_); scaledHighCut_ = scaleToShort((FITS_LONGLONG)highCut_); if (haveBlank_) scaledBlankPixelValue_ = LOOKUP_BLANK; // set int flag for later quick check if scale_ != 1.0 scaled_ = (scale_ != 1.0); // Sense inverted - PWD } /* * Set the blank value from a given string. Return 1 if successful. */ int LongLongImageData::parseBlank(const char* value) { long l; int n = sscanf(value, "%ld", &l); if ( n > 0 ) { blank_ = (FITS_LONGLONG) l; } return n; } /* * Include some standard methods as (cpp macro) templates: * These are methods that are the same for all derived classes of ImageData, * except that they work on a different raw data type */ #define CLASS_NAME LongLongImageData #define DATA_TYPE FITS_LONGLONG #ifndef NTOH # define NTOH(x) SWAP64(x) #endif #include "ImageTemplates.icc" #undef NTOH #undef CLASS_NAME #undef DATA_TYPE #undef NTOH skycat-3.1.2-starlink-1b/rtd/generic/LongLongImageData.h000066400000000000000000000053641215713201500227770ustar00rootroot00000000000000/* * E.S.O. - VLT project * * "@(#) $Id: LongLongImageData.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * $Id: LongLongImageData.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * LongLongImageData.h - class definitions for class LongLongImageData * * who when what * -------------- -------- ---------------------------------------- * pbiereic 12/08/07 Created */ #include #include "ImageData.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #define FITS_LONGLONG long long // This class is used for images where the raw data is made up of ints class LongLongImageData : public ImageData { private: // value of blank pixel, if known (if haveBlankPixel_ is nonzero) FITS_LONGLONG blank_; int bias_; // offset for long to short conversion double dbias_; // used when scale != 1.0 double scale_; // factor for long to short conversion int scaled_; // flag, true if scale_ != 1.0 // local methods used to get short index in lookup table short convertToShort(FITS_LONGLONG); // convert long to short by adding bias short scaleToShort(FITS_LONGLONG); // as above, but with scaling inline ushort convertToUshort(FITS_LONGLONG l) { // unsigned return ushort(scaled_ ? scaleToShort(l) : convertToShort(l)); } // return X image pixel value for raw image value inline byte lookup(FITS_LONGLONG l) { return lookup_[convertToUshort(l)]; } inline unsigned long llookup(FITS_LONGLONG l) { return lookup_[convertToUshort(l)]; } // return NTOH converted value evtl. subtracted with corresponding bias value FITS_LONGLONG getVal(FITS_LONGLONG* p, int idx); int getXsamples(FITS_LONGLONG *rawImage, int idx, int wbox, FITS_LONGLONG *samples); int getBsamples(FITS_LONGLONG *rawImage, int idx, int wbox, FITS_LONGLONG *samples); int getCsamples(FITS_LONGLONG *rawImage, int idx, int wbox, FITS_LONGLONG *samples); FITS_LONGLONG getMedian(FITS_LONGLONG *samples, int n); FITS_LONGLONG getBoxVal(FITS_LONGLONG *rawImage, int idx, int wbox, FITS_LONGLONG *samples, int xs); FITS_LONGLONG getRMS(FITS_LONGLONG *samples, int n); protected: // initialize conversion from base type to short, void initShortConversion(); public: // constructor LongLongImageData(const char* name, const ImageIO& imio, int verbose) : ImageData(name, imio, verbose), blank_(0) {} // return the data type of the raw data int dataType() {return LONGLONG_IMAGE;} // return true if the data type is signed int isSigned() {return 1;} // return a copy of this object ImageData* copy() {return new LongLongImageData(*this);} // include declarations for methods that differ only in raw data type # include "ImageTemplates.h" }; skycat-3.1.2-starlink-1b/rtd/generic/LookupTable.C000066400000000000000000000230071215713201500216710ustar00rootroot00000000000000/* * E.S.O. - VLT project / ESO Archive * * "@(#) $Id: LookupTable.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * LookupTable.C - method definitions for class LookupTable, managing image * pixel lookup tables for converting pixel values to * XImage bytes, with scaling algorithms applied. * * This class is used to convert image pixel values to bytes, with color * scaling algorithms applied, for displaying in an XImage. For example, * to convert 16-bit shorts to bytes, a lookup table of size 64k is * used. For byte values, a lookup table of size 256 can be used. For * integers, floats and doubles, it is best to scale the values down to * shorts first and then use a 64k sized lookup table to apply the * scaling algorithms (linear, log, sqrt, histeq). Using a large lookup * table takes more memory, but saves time later when converting pixel * values for display. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 09 Aug 96 Created * Peter W. Draper 19 Aug 11 Make log and sqrt scalings use different * powers. This differentiates them and makes * them more like other display tools. */ static const char* const rcsId="@(#) $Id: LookupTable.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" #include "error.h" #include "LookupTable.h" #include "Fits_IO.h" // borrowed this from saoimage extern "C" { #include "histeq.h" } // this is only defined on SUN ? #undef expm1 #define expm1(a) (exp(a)-1) /* * constructor: create new image memory area */ LookupTable::LookupTable(int size) : rep_(new LookupTableRep(size)) { } /* * copy constructor - increment the reference count... */ LookupTable::LookupTable(const LookupTable& im) : rep_(im.rep_) { if (rep_) rep_->refcnt_++; } /* * destructor - delete if there are no more references. */ LookupTable::~LookupTable() { if (rep_ && --rep_->refcnt_ <= 0) delete rep_; } /* * assignment operator */ LookupTable& LookupTable::operator=(const LookupTable& im) { im.rep_->refcnt_++; // protect against "im = im" if (rep_ && --rep_->refcnt_ <= 0) { delete rep_; } rep_ = im.rep_; return *this; } /* ---------- internal rep ----------- */ /* * constructor - internal rep */ LookupTableRep::LookupTableRep(int size) : lookup_(new unsigned long[size]), size_(size), refcnt_(1), status_(0) { if (lookup_ == NULL) status_ = error("no memory for lookup table"); } /* * destructor - internal rep */ LookupTableRep::~LookupTableRep() { delete[] lookup_; } /* * reset to given color */ void LookupTableRep::reset(unsigned long color) { if (lookup_) { for(int i = 0; i < size_; i++) lookup_[i] = color; } } /* -------------- color scaling -------------------- */ /* * fill in the lookup table at the end after the high cut level has been * reached. * * pixval is the color value to use for image values >= imageval. * isSigned is a flag: should be set to true if the pixel values are signed. */ void LookupTableRep::fillLookup(int pixval, int imageval, int isSigned) { // note: unsigned image values fill up the lookup array sequentially // but for signed image values, -1 is at the end due to the cast to // (ushort) to get a positive index. int n = isSigned ? size_/2 : size_; while( imageval < n) { ushort v = (ushort)imageval++; if (v < size_) { lookup_[v] = pixval; } } } /* * local util method: set the values in the lookup table from imageval to * imagelim to the given pixel value and increment imageval to the * new index. * Returns 1 if we've reached the end of the lookup table and should break * the loop. */ int LookupTableRep::setLookup(int& imageval, int imagelim, int pixval) { int ret = 0; // limit to size of lookup table if (imagelim > size_) { imagelim = size_; ret = 1; } while(imageval < imagelim) { ushort v = (ushort)imageval++; if (v < size_) lookup_[v] = pixval; } return ret; } /* * set the color value for a specific pixel value (blank pixel, for example) */ void LookupTableRep::setPixelColor(int pixval, unsigned long color) { ushort v = (ushort)pixval; if (v < size_) lookup_[v] = color; } /* * Set up the color lookup table for linear scaling. * * lcut and hcut are the low and high cut levels (scaled to the short range). * isSigned is a flag: should be set to true if the pixel values are signed. * ncolors is the number of pixel color values in the colors[] array. */ void LookupTableRep::linearScale(int lcut, int hcut, int isSigned, int ncolors, unsigned long* colors) { // input range / output range yields input cells per output cell double scale = (double)(hcut - lcut + 1) / ncolors; // upper bound is ideal edge between colors (offset for rounding) double upper_bound = lcut + 0.5; int maxcolor = ncolors - 1; int imageval = lcut; int level = 0; register int pixval = colors[0]; register int imagelim; while( level++ < maxcolor ) { upper_bound += scale; // limit to size of lookup table imagelim = (int)upper_bound; if (setLookup(imageval, imagelim, pixval)) break; // level was inc'd after loop test, make pixval for next round pixval = colors[level]; } // fill in at top if short of highCut fillLookup(pixval, imageval, isSigned); } /* * set up the color lookup table for logarithmic scaling: * distribute color levels in the map by a logorithmic or * exponential curve (powers of e). * * lcut and hcut are the low and high cut levels (scaled to the short range). * isSigned is a flag: should be set to true if the pixel values are signed. * ncolors is the number of pixel color values in the colors[] array. * expo is the optional exponent (def: 6.0). */ void LookupTableRep::logScale(int lcut, int hcut, int isSigned, int ncolors, unsigned long* colors, double expo) { int level = 0; register int imagelim; register int pixval = colors[0]; int maxcolor = ncolors - 1; int imageval = lcut; double scale; // base distribution on e**n as n goes from 0 to expo if(expo >= 0 ) { scale = (double)(hcut - lcut + 1) / expm1(expo); } else { // negative exponents allocate more levels toward the high values scale = (double)(hcut - lcut + 1) / (1.0 - exp(expo)); } while(level++ < maxcolor) { if (expo > 0) { imagelim = lcut + (int) ((expm1(((double)level / ncolors) * expo) * scale) + 0.5); } else { imagelim = lcut + (int) ((1.0-exp(((double)level / ncolors) * expo) * scale) + 0.5); } // limit map range to image values if (imagelim > hcut) imagelim = hcut; if (setLookup(imageval, imagelim, pixval)) break; // level was inc'd after loop test, make pixval for next round pixval = colors[level]; } // fill in at top if short of highCut fillLookup(pixval, imageval, isSigned); } /* * set up the color lookup table for exponential scaling * * lcut and hcut are the low and high cut levels (scaled to the short range). * isSigned is a flag: should be set to true if the pixel values are signed. * ncolors is the number of pixel color values in the colors[] array. * expo is the optional exponent (def: 2.0). */ void LookupTableRep::sqrtScale(int lcut, int hcut, int isSigned, int ncolors, unsigned long* colors, double expo) { int maxcolor = ncolors - 1; int imageval = lcut; double range = hcut - lcut + 1; int level = 0; register int imagelim; register int pixval = colors[0]; while( level++ < maxcolor ) { imagelim = lcut + (int) ((pow(((double)level / ncolors), expo) * range) + 0.5); // limit map range to image values if ( imagelim > hcut ) imagelim = hcut; if (setLookup(imageval, imagelim, pixval)) break; // level was inc'd after loop test, make pixval for next round pixval = colors[level]; } // fill in at top if short of hcut fillLookup(pixval, imageval, isSigned); } /* * Set up the color lookup table for histogram equalization scaling * * lcut and hcut are the low and high cut levels (scaled to the short * range). * * isSigned is a flag: should be set to true if the pixel values are * signed. * * minval is the min image pixel value. This is needed to map an index in * xyvalues to a pixel value, since xyvalue[0] corresponds to minval. * * ncolors is the number of pixel color values in the colors[] array. * * histogram is an array[SHORT_SIZE] generated from the image and maps * ushort image values to the number of pixels that have that value. * * area is the area (w*h) of the image area examined for the histogram. */ void LookupTableRep::histeqScale(int lcut, int hcut, int isSigned, int ncolors, unsigned long* colors, int* histogram, int area) { // if there are not enought pixel levels to distribute, // (or if it is a small lookup table) do linear scaling instead if ((hcut - lcut) <= ncolors) { linearScale(lcut, hcut, isSigned, ncolors, colors); return; } // Since we don't know how many colours will be used exactly // fill all lookup table with hcut. int llcut = lcut; fillLookup(colors[ncolors-1], llcut, isSigned); // int scaleOffset = SHORT_SIZE/2; // offset from allocated array to zero histogram_equalize(lookup_, histogram, area, lcut, hcut, ncolors, colors); } skycat-3.1.2-starlink-1b/rtd/generic/LookupTable.h000066400000000000000000000106461215713201500217430ustar00rootroot00000000000000// -*-c++-*- #ifndef _LookupTable_h_ #define _LookupTable_h_ /* * E.S.O. - VLT project / ESO Archive * * "@(#) $Id: LookupTable.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * LookupTable.h - declarations for class LookupTable, a class for managing * an image color lookup table used to convert image pixel * values to XImage byte values. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 09 Aug 96 Created * Peter W. Draper 03 Mar 98 Converted to use unsigned long values * (need this to support visuals & depths) */ #include #include #include #include typedef unsigned char byte; /* * This class is used internally for reference counting and subclassing. * The public interface is through the LookupTable class. */ class LookupTableRep { friend class LookupTable; protected: unsigned long* lookup_; // lookup table int size_; // size of lookup table int refcnt_; // reference count int status_; // status after constructor // local util methods void fillLookup(int pixval, int imageval, int isSigned); int setLookup(int& imageval, int imagelim, int pixval); public: // constructor (derived classes call this) LookupTableRep(int size); // destructor virtual ~LookupTableRep(); // normally you use either a lookup table for shorts or for bytes enum {SHORT_SIZE = 65536, BYTE_SIZE = 256}; // color scaling methods void linearScale(int lcut, int hcut, int isSigned, int ncolors, unsigned long* colors); void logScale(int lcut, int hcut, int isSigned, int ncolors, unsigned long* colors, double expo); void sqrtScale(int lcut, int hcut, int isSigned, int ncolors, unsigned long* colors, double expo); void histeqScale(int lcut, int hcut, int isSigned, int ncolors, unsigned long* colors, int* histogram, int area); // reset to given color void reset(unsigned long color); // set the color value for a specific pixel value (blank pixel, for example) void setPixelColor(int pixval, unsigned long color); }; /* * This class defines the public interface. It uses reference counting * with the above class to make it easier to implement different views of * the same image data. */ class LookupTable { private: LookupTableRep* rep_; // internal representation for reference counting public: // constructor LookupTable(int size); // copy constructor LookupTable(const LookupTable&); // constructor, from a pointer to a subclass of LookupTableRep LookupTable(LookupTableRep* rep) : rep_(rep) {} // destructor ~LookupTable(); // assignment LookupTable& operator=(const LookupTable&); // color scaling methods void linearScale(int lcut, int hcut, int isSigned, int ncolors, unsigned long* colors) { if (rep_) rep_->linearScale(lcut, hcut, isSigned, ncolors, colors); } void logScale(int lcut, int hcut, int isSigned, int ncolors, unsigned long* colors, double expo = 6.0) { if (rep_) rep_->logScale(lcut, hcut, isSigned, ncolors, colors, expo); } void sqrtScale(int lcut, int hcut, int isSigned, int ncolors, unsigned long* colors, double expo = 2.0) { if (rep_) rep_->sqrtScale(lcut, hcut, isSigned, ncolors, colors, expo); } void histeqScale(int lcut, int hcut, int isSigned, int ncolors, unsigned long* colors, int* histogram, int area) { if (rep_) rep_->histeqScale(lcut, hcut, isSigned, ncolors, colors, histogram, area); } // reset to given color void reset(unsigned long color) { if (rep_) rep_->reset(color); } // set the color value for a specific pixel value (blank pixel, for example) void setPixelColor(int pixval, unsigned long color) { if (rep_) rep_->setPixelColor(pixval, color); } // look up and return a value (this should be a fast, inline operation) // no check, for speed, not needed if using default lookup size unsigned long operator[](unsigned short i) { #ifdef DEBUG assert(rep_ && isize_); #endif return rep_->lookup_[i]; } // note: if status is non-zero, the other methods are undefined int status() const {return rep_ ? rep_->status_ : 1;} int size() const {return rep_->size_;} }; #endif /* _LookupTable_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/NativeImageData.C000066400000000000000000000033531215713201500224350ustar00rootroot00000000000000/* * E.S.O. - VLT project * * "@(#) $Id: NativeImageData.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * NativeImageData.C - cpp template definitions to support native byte * order images on byte swapped machines (i386, vax, etc.) * * This file uses some #defines to declare native versions of the * ImageData subclasses for use on byte swapped machines. On other * machines, this has no effect and no new classes are created. * * The purpose is to allow derived packages to use image types that are * either in native byte order already or have been read in and * byte-swapped already by a library routine. This can be controlled by a * flag set in a class derived from the ImageIO class (astrotcl/imageio). * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 20/03/98 Created * Peter W. Draper 07/04/05 Added __x86_64 * pbiereic 17/02/03 Native byte order routines revised */ #define NTOH(x) x #define ShortImageData NativeShortImageData #include "ShortImageData.C" #undef ShortImageData #undef NTOH #define NTOH(x) x #define UShortImageData NativeUShortImageData #include "UShortImageData.C" #undef UShortImageData #undef NTOH #define NTOH(x) x #define LongImageData NativeLongImageData #include "LongImageData.C" #undef LongImageData #undef NTOH #define NTOH(x) x #define FloatImageData NativeFloatImageData #include "FloatImageData.C" #undef FloatImageData #undef NTOH #define NTOH(x) x #define LongLongImageData NativeLongLongImageData #include "LongLongImageData.C" #undef LongLongImageData #undef NTOH #define NTOH(x) x #define DoubleImageData NativeDoubleImageData #include "DoubleImageData.C" #undef DoubleImageData #undef NTOH skycat-3.1.2-starlink-1b/rtd/generic/NativeImageData.h000066400000000000000000000023051215713201500224760ustar00rootroot00000000000000#ifndef _NativeImageData_h_ #define _NativeImageData_h_ /* * E.S.O. - VLT project * * "@(#) $Id: NativeImageData.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 20/03/98 Created * pbiereic 17/02/03 Native byte order routines revised * Peter W. Draper 14/11/05 Added double support (back from my patches). * pbiereic 12/08/07 added data types double and long long int * Peter W. Draper 17/05/12 Merged skycat double version created by pbiereic. */ #define ShortImageData NativeShortImageData #include "ShortImageData.h" #undef ShortImageData #define UShortImageData NativeUShortImageData #include "UShortImageData.h" #undef UShortImageData #define LongImageData NativeLongImageData #include "LongImageData.h" #undef LongImageData #define FloatImageData NativeFloatImageData #include "FloatImageData.h" #undef FloatImageData #define LongLongImageData NativeLongLongImageData #include "LongLongImageData.h" #undef LongLongImageData #define DoubleImageData NativeDoubleImageData #include "DoubleImageData.h" #undef DoubleImageData #endif /* _NativeImageData_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/RtdCamera.C000066400000000000000000000172431215713201500213170ustar00rootroot00000000000000/* * E.S.O. - VLT project * "@(#) $Id: RtdCamera.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * RtdCamera.C - member routines for class RtdCamera, * manages realtime image update for class RtdImage * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * D.Hopkinson 02/12/96 Added performance test object and timestamp method * P.Biereichel 17/06/97 Call rtdClose() in case of error * P.Biereichel 10/03/01 Removed check on semId = 0 which is a valid ID. * Added constructor argument 'debug' * Revised the whole source code, in particular the * interface to rtdServer. * Removed performance test object (handled by RtdImage()) * pbiereic 12/08/07 added support for data type long long int */ static const char* const rcsId="@(#) $Id: RtdCamera.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "RtdCamera.h" /* * constructor */ RtdCamera::RtdCamera(const char* name, Tcl_Interp* interp, int verbose, int debug, char* image) : name_(strdup(name)), interp_(interp), verbose_(verbose), debug_(debug), image_(image), eventHndl_(NULL), camera_(camBuf_), connected_(0), attached_(0), was_attached_(-1), shmNum_(-1), semId_(-1), dbl_(NULL) { #ifdef DEBUG debug_ = verbose_ = 1; #endif eventHndl_ = new rtdIMAGE_EVT_HNDL; memset(eventHndl_, '\0', sizeof(rtdIMAGE_EVT_HNDL)); camera(""); dbl_ = new RtdDebugLog((char *)"RtdCamera", (int) (debug_ & verbose_)); dbl_->log("Camera object created. RTD client=%s, rtdimage=%s\n", name_, image_); } /* * destructor */ RtdCamera::~RtdCamera() { pause(); disconnect(); } /* * This static method is called when there is a message to read * from the rtdServer: pass it on to member function fileEvent() * and update the Tcl global variables */ void RtdCamera::fileEventProc(ClientData clientData, int mask) { RtdCamera* thisPtr = (RtdCamera*)clientData; thisPtr->fileEvent(); thisPtr->updateGlobals(); } /* * Read the message from the rtdServer and call a virtual method to * display the image and evaluate the tcl event scripts. */ int RtdCamera::fileEvent() { Mem mem; rtdIMAGE_INFO info; int stat; memset(&info, '\0', sizeof(rtdIMAGE_INFO)); info.semId = info.shmNum = -1; stat = rtdRecvImageInfo(eventHndl_, &info, verbose_, buffer_); semId_ = info.semId; shmNum_ = info.shmNum; if (stat != RTD_OK || checkType(info.dataType) != RTD_OK || info.xPixels <=0 || info.yPixels <= 0) { checkStat(); return TCL_ERROR; } if ( ! attached()) { semDecr(); return TCL_OK; } /* * class Mem takes care of possible reusing previous shared memory areas * and cleanup. Choose the constructor depending on whether the * semaphore fields of the image info have been set. */ int bytes = info.xPixels * info.yPixels * (abs(info.dataType) / 8); if (semId_ > 0) mem = Mem(bytes, info.shmId, 0, verbose_, shmNum_, semId_); else mem = Mem(bytes, info.shmId, 0, verbose_); if (mem.status() != 0) { checkStat(); return TCL_ERROR; } dbl_->log("image event: Id=%d, x=%d, y=%d, width=%d, height=%d, " "shmId=%d shmNum=%d semId=%d\n", info.frameId, info.frameX, info.frameY, info.xPixels, info.yPixels, info.shmId, shmNum_, semId_); /* * before displaying the image delete the file handler. This blocks * new image events which must not be handled between camera pre/post commands. */ fileHandler(0); // call the virtual method in a derived class to display the image int disperr = display(info, mem); // re-install the file handler fileHandler(1); // finally decrement the semaphore semDecr(); return disperr; } /* * After failure of an image event decrement the semaphore * and check status of rtdServer */ void RtdCamera::checkStat() { semDecr(); rtdServerCheck(); } /* * create/delete the Tcl file handler */ void RtdCamera::fileHandler(int create) { if (! eventHndl_->socket) return; if (create) Tcl_CreateFileHandler(RTD_TCL_GETFILE_(eventHndl_->socket), TCL_READABLE, fileEventProc, (ClientData)this); else Tcl_DeleteFileHandler(RTD_TCL_GETFILE_(eventHndl_->socket)); } /* * check connection to rtdServer */ void RtdCamera::rtdServerCheck() { if ( ! connected()) return; if (rtdServerPing(eventHndl_, buffer_) == RTD_OK) return; disconnect(); } /* * start accepting images from the named camera. * "camera" is a string that identifies the camera. */ int RtdCamera::start(const char* cameraName) { if (strlen(cameraName) == 0) return error("start needs a camera name"); camera(cameraName); // new camera name dbl_->log("START camera %s\n", cameraName); // first we need to check the connection to rtdServer if (connected()) rtdServerCheck(); attached(0); if (! connected()) { dbl_->log("Connecting to %s: RTD name=%s\n", RTD_SERVICE, name_); if (rtdInitImageEvt(name_, eventHndl_, buffer_) != RTD_OK) { disconnect(); sprintf(buffer_, "could not initialize image event: check if %s is running!\n", RTD_SERVICE); dbl_->log(buffer_); return error(buffer_); } } connected(1); if (rtdAttachImageEvt(eventHndl_, camera(), buffer_) != RTD_OK) { disconnect(); sprintf(buffer_, "detach image event: check if %s is running!\n", RTD_SERVICE); dbl_->log("%s\n", buffer_); return error(buffer_); } // now we are ready to receive image events attached(1); fileHandler(1); return TCL_OK; } /* * stop accepting images from the camera. * This method is kept for backwards compatability. */ int RtdCamera::stop() { return pause(); } /* * pause receiving image events. Tell rtdServer to DETACH. */ int RtdCamera::pause() { dbl_->log("PAUSE\n"); attached(0); if (! connected()) return TCL_OK; if (rtdDetachImageEvt(eventHndl_, camera(), buffer_) != RTD_OK) disconnect(); return TCL_OK; } /* * continue receiving images from camera after a pause */ int RtdCamera::cont() { dbl_->log("CONTINUE\n"); if (! camera()) return error("no start command received yet"); return start(camera()); } /* * break connection to rtdServer */ void RtdCamera::disconnect() { if( ! connected()) return; dbl_->log("disconnect\n"); semDecr(); fileHandler(0); rtdClose(eventHndl_, NULL); eventHndl_->socket = 0; attached(0); connected(0); return; } int RtdCamera::attached() { if (! attached_ || ! connected_ || eventHndl_->socket == 0) return False; return True; } /* * Decrement the semaphore */ void RtdCamera::semDecr() { if (semId_ < 0 || shmNum_ < 0) return; rtdSemDecrement(semId_, shmNum_); // decrement the semaphore dbl_->log("Semaphore decremented, semId=%d, shmNum=%d, val=%d\n", semId_, shmNum_, rtdSemGetVal(semId_, shmNum_)); semId_ = shmNum_ = -1; } /* * update global variables */ int RtdCamera::updateGlobals() { if (was_attached_ != attached()) { was_attached_ = attached(); sprintf(buffer_, "%d %s", attached(), camera()); Tcl_SetVar2(interp_, image_, "ATTACHED", buffer_, TCL_GLOBAL_ONLY); } return TCL_OK; } int RtdCamera::checkType(int type) { if (type == BYTE || type == XIMAGE || type == SHORT || type == USHORT || type == INT || type == FLOAT || type == DOUBLE || type == LONG64) return RTD_OK; return RTD_ERROR; } skycat-3.1.2-starlink-1b/rtd/generic/RtdCamera.h000066400000000000000000000073241215713201500213630ustar00rootroot00000000000000// -*-c++-*- #ifndef _RtdCamera_h_ #define _RtdCamera_h_ /* * E.S.O. - VLT project * "@(#) $Id: RtdCamera.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * RtdCamera.h - class definitions for managing realtime image update * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * D.Hopkinson 02/12/96 Added performance test object and timestamp method * pbiereic 01/03/01 Removed performance test object */ #include #include #include #include #include #include "error.h" #include "define.h" #include "Mem.h" #include "rtdSem.h" #include "rtdImageEvent.h" #include "ImageIO.h" #include "Mem.h" #include "RtdUtils.h" #include // this call changed in tcl8 #if (TCL_MAJOR_VERSION >= 8) #define RTD_TCL_GETFILE_(x) x #else #define RTD_TCL_GETFILE_(x) Tcl_GetFile((void *)x, TCL_UNIX_FD) #endif /* * Class RtdCamera * */ class RtdCamera { public: // constructor RtdCamera( const char* name, Tcl_Interp*, int verbose, int debug=0, char* image = "RtdCamera"); // destructor virtual ~RtdCamera(); // static file handler, called by Tk file handler for realtime image events static void fileEventProc(ClientData, int mask); // start/stop/pause or continue accepting images int start(const char* cameraName); int stop(); int pause(); int cont(); // return camera name char* camera() {return camera_;} // Add timestamp in performance tool. void timeStamp(char *evDesc); // update global variables int updateGlobals(); // check if camera is attached int attached(); protected: // member called by fileEventProc for image events int fileEvent(); // cleanup image events in the socket queue void cleanup(); // called to display new image from shared memory // (defined in a derived class) virtual int display(const rtdIMAGE_INFO&, const Mem& data) = 0; // set camera name void camera(const char *camera) {strcpy(camBuf_, camera);} // create/delete the Tcl file handler void fileHandler(int create); // disconnect from camera void disconnect(); // Decrement the semaphore void semDecr(); // check if rtdServer is alive void rtdServerCheck(); // check status after image event failure void checkStat(); // start accepting events from the camera int attach(const char* camera); // check image type int checkType(int type); Tcl_Interp* interp_; // Tcl interp (for file events, error handling) rtdIMAGE_EVT_HNDL* eventHndl_; // image event handle char* camera_; // camera name RtdDebugLog *dbl_; // debug log object int connected_; // Flag: connected to rtdServer int attached_; // Flag: attached to rtdServer int was_attached_; // Flag for updateGlobals() int verbose_; // verbose and debug flags int debug_; int semId_; // current semaphore id int shmNum_; // current shared memory number char* name_; // some unique name (name of Tk image...) char* image_; // name of RtdImage instance (view master) char camBuf_[RTD_NAMELEN]; // .. and the buffer char buffer_[1024]; // general purpose character buffer // -- short cuts -- int connected() {return connected_;} void connected(int set) {connected_ = set; } void attached(int set) {attached_ = set; } }; #endif /* _RtdCamera_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/RtdCmds.C000066400000000000000000003321601215713201500210130ustar00rootroot00000000000000/******************************************************************************* * E.S.O. - VLT project * * "@(#) $Id: RtdCmds.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * who when what * -------- -------- ---------------------------------------------- * A. Brighton 05/10/95 Created in RtdImage.C * pbiereic 01/03/01 copied from RtdImage.C * pbiereic 01/04/01 bltgraph subcommand * pbiereic 27/06/01 added "statistics noise" subcommand * pbiereic 14/08/01 added "hdu fits" subcommand * pbiereic 17/02/03 "autocut" uses autoSetCutLevels(99.5) instead of * medianFilter(). This gives much better results * and is also faster. * pbiereic 19/03/03 The previous change was undone (on request) * Peter W. Draper 14/11/05 Merge my RtdImage changes. * Peter W. Draper 26/10/06 Change mbandCmd so that clipping happens in * centre of last pixel, not previous pixel. * 08/01/07 Mark blank images with an OBJECT keyword * with value RTD_BLANK. Do not use image size. * 18/01/07 Back to mband, clip that at 0.5->width/height+0.5 * so that measurement happens to the edge. * 04/06/07 Increase upper limit of zoom factor (supports * adaptive zoom in GAIA for very small, one pixel, * images). * 09/07/07 Reset zoomFactor_ when stopping a zoomed view. * Will be re-used in reference counted copies * (inappropriately when extra high factors are in * use, leading to memory allocation errors). * 14/12/07 Add option to statisticsCmd so that world * coordinates can be reported in degrees (J2000). * 24/04/08 Allow scales to have differing signs. * 21/05/08 Extend statisticsCmd to append the FWHM in arcsecs. * 15/02/12 Round spectrum end points to nearest integers so * that pixel boundaries are respected. * pbiereic 19/06/06 added subcommand "getvals" * pbiereic 14/09/07 Revised biasimageCmd for tile compression */ /************************************************************************ * NAME * * RtdCmds.C - rtd subimage commands * * SYNOPSIS * * * DESCRIPTION * * This file contains all RtdImage member functions which perform * an image subcommand. These functions were originally contained * in RtdImage.C and moved to this file since RtdImage.C were becoming * much too big. * * FILES * * ENVIRONMENT * * CAUTIONS * * SEE ALSO * RtdImage(3), RTD documentation * * BUGS * *------------------------------------------------------------------------ */ static const char *rcsId="@(#) $Id: RtdCmds.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include "RtdImage.h" #include "define.h" // for max function #include /* * declare a table of image subcommands and the methods that handle them. * * NOTE: keep this table sorted, so we can use a binary search on it ! * (select lines in emacs and use M-x sort-lines) */ static class RtdImageSubCmds { public: char* name; // method name int (RtdImage::*fptr)(int argc, char* argv[]); // ptr to method int min_args; // minimum number of args int max_args; // maximum number of args } subcmds_[] = { {(char *)"alloccolors", &RtdImage::alloccolorsCmd, 0, 1}, {(char *)"autocut", &RtdImage::autocutCmd, 0, 2}, {(char *)"biasimage", &RtdImage::biasimageCmd, 0, 3}, {(char *)"bitpix", &RtdImage::bitpixCmd, 0, 0}, {(char *)"bltgraph", &RtdImage::bltgraphCmd, 6, 10}, {(char *)"camera", &RtdImage::cameraCmd, 1, 4}, {(char *)"clear", &RtdImage::clearCmd, 0, 14}, {(char *)"cmap", &RtdImage::cmapCmd, 1, 2}, {(char *)"colorramp", &RtdImage::colorrampCmd, 0, 0}, {(char *)"colorscale", &RtdImage::colorscaleCmd, 0, 1}, {(char *)"convert", &RtdImage::convertCmd, 7, 7}, {(char *)"cut", &RtdImage::cutCmd, 0, 3}, {(char *)"dispheight", &RtdImage::dispheightCmd, 0, 0}, {(char *)"dispwidth", &RtdImage::dispwidthCmd, 0, 0}, {(char *)"dump", &RtdImage::dumpCmd, 1, 5}, {(char *)"fits", &RtdImage::fitsCmd, 1, 2}, {(char *)"flip", &RtdImage::flipCmd, 0, 2}, {(char *)"frameid", &RtdImage::frameidCmd, 0, 0}, {(char *)"get", &RtdImage::getCmd, 3, 5}, {(char *)"getvals", &RtdImage::getvalsCmd, 3, 5}, {(char *)"graphdist", &RtdImage::graphdistCmd, 5, 5}, {(char *)"hdu", &RtdImage::hduCmd, 0, 6}, {(char *)"height", &RtdImage::heightCmd, 0, 0}, {(char *)"info", &RtdImage::infoCmd, 0, 6}, {(char *)"isclear", &RtdImage::isclearCmd, 0, 0}, {(char *)"itt", &RtdImage::ittCmd, 1, 2}, {(char *)"max", &RtdImage::maxCmd, 0, 0}, {(char *)"mband", &RtdImage::mbandCmd, 6, 6}, {(char *)"min", &RtdImage::minCmd, 0, 0}, {(char *)"mmap", &RtdImage::mmapCmd, 0, 7}, {(char *)"motionevent", &RtdImage::motioneventCmd, 0, 1}, {(char *)"object", &RtdImage::objectCmd, 0, 0}, {(char *)"pan", &RtdImage::panCmd, 1, 3}, {(char *)"perftest", &RtdImage::perfTestCmd, 1, 2}, {(char *)"pixtab", &RtdImage::pixtabCmd, 1, 3}, {(char *)"preview", &RtdImage::previewCmd, 1, 1}, {(char *)"radecbox", &RtdImage::radecboxCmd, 3, 3}, {(char *)"remote", &RtdImage::remoteCmd, 0, 1}, {(char *)"remotetcl", &RtdImage::remoteTclCmd, 1, 1}, {(char *)"rotate", &RtdImage::rotateCmd, 0, 1}, {(char *)"scale", &RtdImage::scaleCmd, 0, 2}, {(char *)"shm", &RtdImage::shmCmd, 0, 7}, {(char *)"spectrum", &RtdImage::spectrumCmd, 9, 9}, {(char *)"statistics", &RtdImage::statisticsCmd, 0, 5}, {(char *)"type", &RtdImage::typeCmd, 0, 0}, {(char *)"update", &RtdImage::updateCmd, 0, 1}, {(char *)"userfreq", &RtdImage::maxFreqCmd, 1, 1}, {(char *)"view", &RtdImage::viewCmd, 2, 11}, {(char *)"warp", &RtdImage::warpCmd, 2, 2}, {(char *)"wcscenter", &RtdImage::wcscenterCmd, 0, 2}, {(char *)"wcsdeltset", &RtdImage::wcsdeltsetCmd, 0, 4}, {(char *)"wcsdist", &RtdImage::wcsdistCmd, 4, 4}, {(char *)"wcsequinox", &RtdImage::wcsequinoxCmd, 0, 0}, {(char *)"wcsheight", &RtdImage::wcsheightCmd, 0, 0}, {(char *)"wcsradius", &RtdImage::wcsradiusCmd, 0, 0}, {(char *)"wcsset", &RtdImage::wcssetCmd, 0, 11}, {(char *)"wcsshift", &RtdImage::wcsshiftCmd, 3, 3}, {(char *)"wcswidth", &RtdImage::wcswidthCmd, 0, 0}, {(char *)"width", &RtdImage::widthCmd, 0, 0}, {(char *)"zoom", &RtdImage::zoomCmd, 1, 3}, {(char *)"zoomview", &RtdImage::zoomviewCmd, 1, 5} }; /* * Call the given method in this class with the given arguments * If the method is not defined here, pass on the search to the * parent class. Since this is a virtual function, the search starts * in the most specific class. */ int RtdImage::call(const char* name, int len, int argc, char* argv[]) { if (dbl_) if (dbl_->setlog()) { char buf[4096]; *buf = '\0'; int l = 0; for(int i = 0; i < argc; i++) { l += strlen(argv[i]); if (l < sizeof(buf) + 2) { strcat(buf, argv[i]); strcat(buf, " "); } } if (dbl_) dbl_->log("subcommand: %s %s\n", name, buf); } // since this tcl command has a lot of subcommands, // we do a binary search on the method table int low = 0; int high = sizeof(subcmds_)/sizeof(*subcmds_) - 1; int mid; int cond; while (low <= high) { mid = (low + high) / 2; if ((cond = strcmp(name, subcmds_[mid].name)) < 0) high = mid - 1; else if (cond > 0) low = mid + 1; else { RtdImageSubCmds& t = subcmds_[mid]; if (check_args(name, argc, t.min_args, t.max_args) != TCL_OK) { return TCL_ERROR; } return (this->*t.fptr)(argc, argv); } } // not found ? extend search to parent class return TkImage::call(name, len, argc, argv); } // -- image subcommands -- /* * Implement the "alloccolors" subcommand * * usage: alloccolors ?numColors? * * With no args, return a Tcl list containing the number of * allocated and the number of free colors, * with one arg reallocate up to numColors colors. */ int RtdImage::alloccolorsCmd(int argc, char* argv[]) { if (argc == 0) { char buf[80]; sprintf(buf, "%d %d", colors_->colorCount(), colors_->freeCount()); return set_result(buf); } int numColors; if (Tcl_GetInt(interp_, argv[0], &numColors) != TCL_OK) { return TCL_ERROR; } if (colors_->reallocate(numColors)) return TCL_ERROR; if (image_) { image_->colorScale(colors_->colorCount(), colors_->pixelval()); return updateImage(); } return TCL_OK; } /* * Implement the "autocut" subcommand to set cut levels automatically to * some reasonable values: * * usage: autocut ?-percent number? * * Two different algorithms are supported. The default is median * filtering. * * If -percent is specified, the argument is a number between 0 and 100, * such as 90 for 90%, where that percent of the image should be visible * within the cut values. i.e.: if you look at the graph (see graphdist * command) of the pixel value distribution, you would take the top 90% * of the graph and set the cut levels to left and right ends of the * graph. */ int RtdImage::autocutCmd(int argc, char* argv[]) { if (!image_ || image_->dataType() == X_IMAGE) return TCL_OK; if (argc == 2) { if (strcmp(argv[0], "-percent") == 0) { double percent; if (Tcl_GetDouble(interp_, argv[1], &percent) != TCL_OK || percent < 0.0 || percent > 100.0) return TCL_ERROR; image_->autoSetCutLevels(percent); } else { return error("expected -percent arg for autocut"); } } else if (argc == 0) { // image_->autoSetCutLevels(99.5); image_->medianFilter(); } else { return error("wrong number of args: expected none or -percent followed by arg"); } image_->colorScale(colors_->colorCount(), colors_->pixelval()); // assume the user has not set the cut levels, so we can change them // if a new image is loaded... autoSetCutLevels_ = 1; // make sure the new lookup table is propagated LookupTable lookup = image_->lookupTable(); for(int i = 0; i < MAX_VIEWS; i++) { if (view_[i] && view_[i]->image_ && !view_[i]->isSeparateRapidFrame()) view_[i]->image_->lookupTable(lookup); } // keep status in a global Tcl variable which can be traced by the Tcl code char* var = (viewMaster_ ? viewMaster_->instname_ : instname_); char sts[100]; sprintf(sts, "%g %g", image_->lowCut(), image_->highCut()); Tcl_SetVar2(interp_, var, "CUT", sts, TCL_GLOBAL_ONLY); return updateViews(1) || updateImage(); } /* * biasimage subcommand * * usage: * $image biasimage * * The available commands are * copy $nr - copy current image to bias image "nr" * file $filename $nr - load bias image "nr" from file "filename" * file $nr - return filename of bias image "nr" * clear $nr - clear bias image "nr" * clear all - clear all bias images * on - switch bias subtraction on * off - switch bias subtraction off * status - return status (-1 no bias image loaded, 0 = off, 1 = on) * update - update the global Tcl status variable * display - display the selected bias image * select $nr - select bias image "nr" * maxbias - return max. number of bias images */ int RtdImage::biasimageCmd(int argc, char* argv[]) { char* usage = (char *)"usage: $image biasimage copy|clear|on|off|status|select|display|file|update|maxbias ?filename? ?nr?"; int nr; char buf[1024]; FitsIO *fits = NULL; if (argc < 1) return error(usage); else if (strcmp(argv[0], "update") == 0) { } else if (strcmp(argv[0], "status") == 0) { sprintf(buf, "%d", biasimage_->status()); return set_result(buf); } else if (strcmp(argv[0], "off") == 0) biasimage_->off(); else if (strcmp(argv[0], "maxbias") == 0) { sprintf(buf, "%d", MAXBIAS); return set_result(buf); } else if (strcmp(argv[0], "clear") == 0) { if (Tcl_GetInt(interp_, argv[1], &nr) != TCL_OK) { for (int i=0; iclear(i); } else biasimage_->clear(nr); } else if (strcmp(argv[0], "on") == 0) { if (biasimage_->on() != 0) return TCL_ERROR; } else if (strcmp(argv[0], "select") == 0) { if (argc < 2) { sprintf(buf, "%d", biasimage_->select()); return set_result(buf); } if (Tcl_GetInt(interp_, argv[1], &nr) != TCL_OK) return error("usage: $image biasimage select nr"); if (biasimage_->select(nr) != 0) { sprintf(buf, "biasimage select: number must be in range 0-%d", MAXBIAS-1); return error(buf); } } else if (strcmp(argv[0], "display") == 0) { if (!biasimage_->image()) return error("selected bias image is not loaded"); ImageDataParams p; if (image_) { image_->saveParams(p); delete image_; image_ = NULL; updateViews(); } image_ = biasimage_->image()->copy(); filename(biasimage_->file(biasimage_->select())); image_->restoreParams(p, 1); return initNewImage(); } else if (strcmp(argv[0], "copy") == 0) { if (isclear()) return error("no image loaded"); if (Tcl_GetInt(interp_, argv[1], &nr) != TCL_OK) return error("usage: $image biasimage copy nr"); if (biasimage_->copy(image_, filename(), nr) != 0) return TCL_ERROR; } else if (strcmp(argv[0], "file") == 0) { if (argc == 2) { if (Tcl_GetInt(interp_, argv[1], &nr) != TCL_OK) return error("usage: $image biasimage file nr"); strcpy (buf, biasimage_->file(nr)); return set_result(buf); } if (argc != 3 || Tcl_GetInt(interp_, argv[2], &nr) != TCL_OK) return error("usage: $image biasimage file filename nr"); if (biasimage_->file(argv[1], nr) != 0) return TCL_ERROR; } else return error(usage); // keep status in a global Tcl variable which can be traced by the Tcl code char* var = (viewMaster_ ? viewMaster_->instname_ : instname_); char sts[10]; sprintf(sts, "%d", biasimage_->status()); Tcl_SetVar2(interp_, var, "BIAS", sts, TCL_GLOBAL_ONLY); return TCL_OK; } /* * Implement the "bitpix" subcommand - returns the * BITPIX field of the image header to indicate the * type of the image (8 - byte, 16 = short, etc). */ int RtdImage::bitpixCmd(int argc, char* argv[]) { if (!image_) return TCL_OK; return set_result(image_->dataType()); } /* * This method implements the "camera" subcommand * * usage: camera attach ?cameraName? ?preCommand? ?postCommand? * camera detach * camera pause * camera continue * * The optional "preCommand" argument to "attach" should be a string * containing a Tcl command to be evaluated whenever a new image event * is received and before it is displayed. The "postCommand" argument * is evaluated after the image event is processed. * * note: for backward compat., "start" and "stop" are also accepted * for "attach" and "detach". */ int RtdImage::cameraCmd(int argc, char* argv[]) { int stat = TCL_OK; char buf[128]; if (! camera_) camera_ = new RtdImageCamera(this); if (strcmp(argv[0],"pause") == 0) stat = camera_->pause(); else if (strcmp(argv[0],"continue") == 0) stat = camera_->cont(); else if (strcmp(argv[0],"attach") == 0 || strcmp(argv[0],"start") == 0) { if (argc < 2) { sprintf(buf, "%d", camera_->attached()); stat = set_result(buf); } else{ if (argc > 2) { if (cameraPreCmd_) free(cameraPreCmd_); cameraPreCmd_ = (strlen(argv[2]) ? strdup(argv[2]) : (char*)NULL); } if (argc > 3) { if (cameraPostCmd_) free(cameraPostCmd_); cameraPostCmd_ = (strlen(argv[3]) ? strdup(argv[3]) : (char*)NULL); } stat = camera_->start(argv[1]); } } else if (strcmp(argv[0],"detach") == 0 || strcmp(argv[0],"stop") == 0) { stat = camera_->stop(); } else { return error("invalid camera subcommand: expected: start, stop, pause or continue"); } camera_->updateGlobals(); return stat; } /* * Generate and load a blank image. * * usage: $image clear * * $image clear ?ximage? * * $image clear ?-reuse $reuse * -ra $ra -dec $dec -equinox $equinox -radius $radius \ * -width $width -height $height? * * In the last case, the optional arguments are used to generate a dummy * image that supports world coordinates, so that you can plot objects on * a blank background. Any missing values are set to a default value. * * If "clear ximage" is specified, only the XImage is cleared out * (temporary clear). * * Optional args: * * ximage - flag: if true, only clear out the XImage (temporary clear) * * reuse - flag: if true, reuse previous image, if it is the same * ra, dec - center point for WCS coords (in decimal degrees) * radius - used to initialize WCS coords (CDELT1 and 2) * equinox - equinox for WCS coords * width - width of generated image in pixels * height - height of generated image in pixels */ int RtdImage::clearCmd(int argc, char* argv[]) { if (argc == 1 && strcmp(argv[0], "ximage") == 0) { if (image_) { image_->clear(); imageChanged(); } return TCL_OK; } double ra = -1.0, dec = 0.0, equinox = 2000.0, radius = 1; int reuse = 0, width = 2, height = 2; // parse options for (int i = 0; i < argc; i+=2) { char* opt = argv[i]; char* arg = argv[i+1]; if ((strcmp(opt, "-reuse") == 0 && Tcl_GetBoolean(interp_, arg, &reuse) != TCL_OK) || (strcmp(opt, "-ra") == 0 && Tcl_GetDouble(interp_, arg, &ra) != TCL_OK) || (strcmp(opt, "-dec") == 0 && Tcl_GetDouble(interp_, arg, &dec) != TCL_OK) || (strcmp(opt, "-radius") == 0 && Tcl_GetDouble(interp_, arg, &radius) != TCL_OK) || (strcmp(opt, "-equinox") == 0 && Tcl_GetDouble(interp_, arg, &equinox) != TCL_OK) || (strcmp(opt, "-width") == 0 && Tcl_GetInt(interp_, arg, &width) != TCL_OK) || (strcmp(opt, "-height") == 0 && Tcl_GetInt(interp_, arg, &height) != TCL_OK)) return TCL_ERROR; } // if -ra and -dec were specified, generate an image with world coords, otherwise // just a plain image with image coords if (ra >= 0) { // for world coords, to make it easier, use an equal width and height width = height = max(width, height); // see if we can reuse the current image. // (only if no file or object is loaded and the coords are the same) double image_ra, image_dec, err = .1; if (reuse && image_ && strlen(file()) == 0 && strlen(image_->object()) == 0 && width == image_->width() && height == image_->height() && fabs(radius - image_->wcs().radius()) < err) { image_->wcs().pix2wcs(width/2, height/2, image_ra, image_dec); if (fabs(ra - image_ra) < err && fabs(dec - image_dec) < err) { return TCL_OK; // its all the same, so reuse it } } } // save previous image parameters so we can restore the settings later ImageDataParams p; if (image_) { image_->saveParams(p); delete image_; image_ = NULL; } filename((char *)""); // generate the blank image FitsIO* fits = FitsIO::blankImage(ra, dec, equinox, radius, width, height, colors_->pixelval(0)); if (fits) { image_ = makeImage(fits); // mark a blank image so we can identify it. if ( width == 2 && height == 2 ) { image_->object( "RTD_BLANK" ); } } // restore transformations, cut levels, etc from the previous image if (image_) image_->restoreParams(p, !autoSetCutLevels_); return initNewImage(); } /* * Implement the "cmap" subcommand * * usage: * cmap file ?? * cmap rotate * cmap shift * cmap set * cmap pixels * cmap reset * cmap list * cmap private * cmap isprivate * cmap isreadonly * * where the file, if specified, should contain 256 lines of R, G, B * values. Each line should contain 3 floating point values between 0.0 * and 1.0, for the reg, grean, and blue color scale values. * If the filename is not specified, the current colormap file name is * returned. * * For rotate and shift, the amount and be any integer. The colormap will be * rotated or shifted by that amount. * * "set" sets the image colormap to be the colormap for the given window. This * can be used for popup windows to avoid color flashing when moving between * popup windows and the image. * * "pixels" returns a Tcl list of the colormap pixel values (for use by external * applications using the RTI library (ImageData)). * * "reset" resets the colormap to its original state. * * "list" returns a list of all of the colormap files currently loaded * * "private" says to start using a private colormap. * "isprivate" returns true if the colormap is private. * * "isreadonly" returns true if the colormap is readonly. */ int RtdImage::cmapCmd(int argc, char* argv[]) { int ret = TCL_OK; if (argc == 2) { if (strcmp(argv[0], "file") == 0) { ret = colors_->loadColorMap(argv[1]); } if (strcmp(argv[0], "rotate") == 0) { int amount; if (Tcl_GetInt(interp_, argv[1], &amount) != TCL_OK) { ret = TCL_ERROR; } else { ret = colors_->rotateColorMap(amount); } } if (strcmp(argv[0], "shift") == 0) { int amount; if (Tcl_GetInt(interp_, argv[1], &amount) != TCL_OK) { ret = TCL_ERROR; } else { ret = colors_->shiftColorMap(amount); } } if (strcmp(argv[0], "set") == 0) { Tk_Window w = Tk_NameToWindow(interp_, argv[1], tkwin_); if (w == NULL) { ret = TCL_ERROR; } else { ret = colors_->setColormap(w); } } // Force image update if colour changes do not transfer // automatically (i.e. non-pseudocolor visual). if ( ret == TCL_OK && colors_->readOnly() ) { return colorUpdate(); } else { return ret; } } if (strcmp(argv[0], "file") == 0) { return set_result(colors_->cmap()->name()); } if (strcmp(argv[0], "reset") == 0) { ret = colors_->reset(); if ( ret == TCL_OK ) { return colorUpdate(); } else { return ret; } } if (strcmp(argv[0], "pixels") == 0) { int n = colors_->colorCount(); unsigned long* p = colors_->pixelval(); ostringstream os; for (int i = 0; i < n; i++) os << *p++ << " "; return set_result(os.str().c_str()); } if (strcmp(argv[0], "list") == 0) { ostringstream os; ColorMapInfo::list(os); set_result(os.str().c_str()); return TCL_OK; } if (strcmp(argv[0], "private") == 0) { return colors_->usePrivateCmap(); } if (strcmp(argv[0], "isprivate") == 0) { return set_result(colors_->usingPrivateCmap()); } if (strcmp(argv[0], "isreadonly") == 0) { return set_result(colors_->readOnly()); } return error("unknown rtdimage cmap subcommand"); } /* * colorramp subcommand: generate an image displaying the colors * in the colormap (no arguments required). */ int RtdImage::colorrampCmd(int argc, char* argv[]) { int w = Tk_Width(tkwin_); int h = Tk_Height(tkwin_); if (w == 1 && h == 1) return TCL_OK; // wait for resize event on image window Mem data(w*h, 0), header; if (data.status() != 0) return TCL_ERROR; double scale = 255.0/w; char* p = (char*)data.ptr(); for (int i = 0; i < w; i++) { p[i] = (int)(i * scale); } for (int j = 0; j < h; j++) { memmove(p+(j*w), p, w); } if (image_) delete image_; FitsIO* fits = new FitsIO(w, h, BYTE_IMAGE, 0.0, 1.0, header, data); if (fits) { image_ = makeImage(fits); image_->name("Ramp"); return initNewImage(); } return ERROR; } /* Implement the "colorscale" image subcommand * * usage: colorscale ?scale_type? * * With 1 arg, color scale the image using the given algorithm * (one of: linear, log, sqrt, histeq) * With no args, return the current color scale type. */ int RtdImage::colorscaleCmd(int argc, char* argv[]) { if (!image_) return TCL_OK; if (argc == 0) { switch(image_->colorScaleType()) { case ImageData::LINEAR_SCALE: return set_result("linear"); case ImageData::LOG_SCALE: return set_result("log"); case ImageData::SQRT_SCALE: return set_result("sqrt"); case ImageData::HISTEQ_SCALE: return set_result("histeq"); default: return set_result("none"); } } if (argc != 1) return error("wrong number of args: should be colorscale ?scale_type?"); // set the color scale type if (strcmp(argv[0], "linear") == 0) image_->colorScaleType(ImageData::LINEAR_SCALE); else if (strcmp(argv[0], "log") == 0) image_->colorScaleType(ImageData::LOG_SCALE); else if (strcmp(argv[0], "sqrt") == 0) image_->colorScaleType(ImageData::SQRT_SCALE); else if (strcmp(argv[0], "histeq") == 0) image_->colorScaleType(ImageData::HISTEQ_SCALE); else return fmt_error("unknown color scale algorithm: %s, %s", argv[0], "should be one of: linear, log, sqrt, histeq"); // color scale the image image_->colorScale(colors_->colorCount(), colors_->pixelval()); // make sure the image is regenerated return updateImage(); } /* * implement the "convert" subcommand to convert between different * coordinate representations. * * usage: * $image convert coords inx iny input_coord_type outx outy output_coord_type * $image convert dist inx iny input_coord_type outx outy output_coord_type * * where inx and iny and the input coords (or distance) in the given * input coordinate system. "convert coords" treats x,y as a point, while * "convert dist" treats it as a distance. outx and outy, if not empty, * are the names of variables that will hold the resulting coordinates. * If outx and outy are empty strings, the values are returned as a tcl * list "x y". * * The available coordinate systems are: * * canvas - canvas coordinates (canvas scroll area) * screen - canvas window coords (visible area) * image - basic image pixel coords (at mag 1, no transformations) * wcs - world coordinates in H:M:S * deg - world coordinates in degrees * * The world coordinate types: "wcs" and "deg" may also include the * equinox (default is 2000): Example: * * $image convert coords $ra $dec "wcs 1950" x y canvas * * Note: the coordinate types may be abbrieviated, since only the first * char is actually checked. */ int RtdImage::convertCmd(int argc, char* argv[]) { if (!image_) return error("no image loaded"); char* usage = (char *)"usage: $image convert [coords|dist] inx iny in_coord_type outx outy out_coord_type"; int dist_flag = 0; if (strcmp(argv[0], "dist") == 0) dist_flag++; else if (strcmp(argv[0], "coords") != 0) return error(usage); char outx_buf[32], outy_buf[32]; char* outx_name = argv[4]; char* outy_name = argv[5]; // if no variable names are specified, return the values as a list if (strlen(outx_name) == 0) outx_name = NULL; if (strlen(outy_name) == 0) outy_name = NULL; double x, y; if (convertCoordsStr(dist_flag, argv[1], argv[2], outx_buf, outy_buf, x, y, argv[3], argv[6]) != TCL_OK) return TCL_ERROR; Tcl_ResetResult(interp_); if (outx_name) Tcl_SetVar(interp_, outx_name, outx_buf, 0); else Tcl_AppendElement(interp_, outx_buf); if (outy_name) Tcl_SetVar(interp_, outy_name, outy_buf, 0); else Tcl_AppendElement(interp_, outy_buf); return TCL_OK; } /* * Implement the "cut" subcommand to set cut levels: * * usage: cut ?fromUser? * or: cut * or: * * If the min and max arguments are specified, the cut levels are set. * * The optional ?fromUser? argument indicates whether or not this is * a result of a user action and defaults to 1 (true). Once a user has * set the cut levels, automatic cut level setting is disabled. * * If no args are given, the current cut levels are returned in a list * of {min max}. * */ int RtdImage::cutCmd(int argc, char* argv[]) { int stat = TCL_OK; if (!image_) return TCL_OK; int fromUser = 1; if (argc == 3 && Tcl_GetInt(interp_, argv[2], &fromUser) != TCL_OK) return TCL_ERROR; if (argc >= 2) { // set the cut levels double min, max; if (Tcl_GetDouble(interp_, argv[0], &min) != TCL_OK || Tcl_GetDouble(interp_, argv[1], &max) != TCL_OK) { return TCL_ERROR; } stat = setCutLevels(min, max, 1, fromUser); } else if (argc == 0) { // return the current cut levels char buf[80]; sprintf(buf, "%g %g", image_->lowCut(), image_->highCut()); return set_result(buf); } // keep status in a global Tcl variable which can be traced by the Tcl code char* var = (viewMaster_ ? viewMaster_->instname_ : instname_); char sts[100]; sprintf(sts, "%g %g", image_->lowCut(), image_->highCut()); Tcl_SetVar2(interp_, var, "CUT", sts, TCL_GLOBAL_ONLY); return stat; } /* * Implement the "info" subcommand * * usage: info bbox * or: minmax x0 y0 x1 y1 */ int RtdImage::infoCmd(int argc, char* argv[]) { char* msg = (char *)"invalid arguments for info subcommand"; if (! image_) return set_result(0); if (argc < 1) return error(msg); if (strcmp(argv[0], "bbox") == 0) { double x0, y0, x1, y1; char buf[80]; image_->getBbox(&x0, &y0, &x1, &y1); sprintf(buf, "%.1f %.1f %.1f %.1f", x0, y0, x1, y1); return set_result(buf); } if (strcmp(argv[0], "minmax") == 0) { if (argc < 5) return error(msg); // get image area double x0, y0, minv = 0.0, maxv = 0.0; int w, h; int numval = 0; if (Tcl_GetDouble(interp_, argv[1], &x0) != TCL_OK || Tcl_GetDouble(interp_, argv[2], &y0) != TCL_OK || Tcl_GetInt(interp_, argv[3], &w) != TCL_OK || Tcl_GetInt(interp_, argv[4], &h) != TCL_OK) { return TCL_ERROR; } image_->getMinMax(x0, y0, w, h, &minv, &maxv); // return the min/max values char buf[80]; sprintf(buf, "%g %g", minv, maxv); return set_result(buf); } return error(msg); } /* * Implement the "dispheight" subcommand - returns the * height of the current image after scaling. */ int RtdImage::dispheightCmd(int argc, char* argv[]) { if (!image_) return set_result(0); double rw = reqWidth_, rh = reqHeight_; doTrans(rw, rh, 1); return set_result(rh ? rh : dispHeight()); } /* * Implement the "dispwidth" subcommand - returns the * width of the current image after scaling. */ int RtdImage::dispwidthCmd(int argc, char* argv[]) { if (!image_) return set_result(0); double rw = reqWidth_, rh = reqHeight_; doTrans(rw, rh, 1); return set_result(rw ? rw : dispWidth()); } /* * This method implements the rtd dump subcommand to dump (save) the * current image or a section of it to the given file in FITS format. * * Usage: $image dump $filename ?x0 y0 x1 y1? * * If the coordinates are specified, the given section of the image (in * image coordinates) is saved in the given file, otherwise the entire * image. The FITS header from the original image is reused and the * relevant values are modified if only a section of the image is being * saved. */ int RtdImage::dumpCmd(int argc, char* argv[]) { if (! image_) return error("no image is currently loaded"); if (argc == 1) { // save whole image return image_->write(argv[0]); } // save image section double x0, y0, x1, y1; if (Tcl_GetDouble(interp_, argv[1], &x0) != TCL_OK || Tcl_GetDouble(interp_, argv[2], &y0) != TCL_OK || Tcl_GetDouble(interp_, argv[3], &x1) != TCL_OK || Tcl_GetDouble(interp_, argv[4], &y1) != TCL_OK) { return TCL_ERROR; } return image_->write(argv[0], x0, y0, x1, y1); } /* * Implement the "fits" image subcommand * * usage: fits get ?keyword? * * If "fits get " is specified, this command returns the value * for the keyword in the FITS header, otherwise "get" with no arguments * returns a formatted copy of the entire header. */ int RtdImage::fitsCmd(int argc, char* argv[]) { if (!image_) return TCL_OK; const ImageIO& imio = image_->image(); if (strcmp(argv[0], "get") == 0) { if (argc == 1 && image_->header().size()) { // return a copy of the FITS header, format it in 80 char lines and // replace any NULL chars with blanks ostringstream os; image_->getFitsHeader(os); set_result(os.str().c_str()); return TCL_OK; } // return the value for the given FITS keyword char* s = imio.get(argv[1]); return set_result(s ? s : ""); } return error("unknown argument: expected \"fits get ?keyword?\""); } /* * Implement the "flip" image subcommand * * usage: flip ?bool? * * where direction is one of x, y, xy or "none" for flipping in the x, y * or x and y directions or neither. * * The boolean value turns flipping on (1) or off (0) in the given * direction(s). * * With one arg, return the current value for the given arg. * With no arg. return the current status of flipX and flipY */ int RtdImage::flipCmd(int argc, char* argv[]) { if (!image_) return TCL_OK; if (argc == 0) { char buf[80]; sprintf(buf, "%d %d", image_->flipX(), image_->flipY()); return set_result(buf); } int flipX = 0, flipY = 0, arg = 1; if (argc == 2) { if (Tcl_GetBoolean(interp_, argv[1], &arg) != TCL_OK) return TCL_ERROR; } if (strcmp(argv[0], "x") == 0 || strcmp(argv[0], "X") == 0) { flipX++; } else if (strcmp(argv[0], "y") == 0 || strcmp(argv[0], "Y") == 0) { flipY++; } else if (strcmp(argv[0], "xy") == 0 || strcmp(argv[0], "XY") == 0) { flipX++; flipY++; } else if (strcmp(argv[0], "none") != 0) return error("expected: flip, followed by: x, y, xy or none"); // if the image is rotated, it is more intuitive to exchange the X and Y axis if (image_->rotate()) swap(flipX, flipY); if (flipX && flipY && argc == 1) { return set_result(image_->flipX() && image_->flipY()); } if (flipX) { if (argc == 2) image_->flipX(arg); else return set_result(image_->flipX()); } if (flipY) { if (image_->dataType() == X_IMAGE) { if (argc == 2) image_->flipY(!arg); else return set_result(!image_->flipY()); } else { if (argc == 2) image_->flipY(arg); else return set_result(image_->flipY()); } } // update other views if (updateViews(1) != TCL_OK) return TCL_ERROR; // make sure the image is regenerated if (resetImage() != TCL_OK) return TCL_ERROR; if (panCommand_) { if (Tk_Width(tkwin_) <= 1) { // pause here until window is displayed, so that the pan // window can determine the size of the window updateRequests(); } autoPan(1); } // keep status in a global Tcl variable which can be traced by the Tcl code char* var = (viewMaster_ ? viewMaster_->instname_ : instname_); char sts[10]; sprintf(sts, "%d %d", image_->flipX(), image_->flipY()); Tcl_SetVar2(interp_, var, "FLIP", sts, TCL_GLOBAL_ONLY); return TCL_OK; } /* * return the frame Id of this image. The frame Id is used to * identify the image to the Rtd Server for use with rapid frames. */ int RtdImage::frameidCmd(int argc, char* argv[]) { return set_result(frameId_); } /* * implement the "get" image command to return a Tcl list of image values * at the given X,Y coordinates * * usage: get $x $y coord_type ?nrows ncols? * * x and y are the coordinates in the image window in the given coordinate * system (one of: canvas, image, screen, wcs, deg). * * The return value is a tcl list where each item consists of a list of * {X Y Value}, where X and Y are the image coords in the raw image * and Value is the raw data value there or "-" if out of range. * * If nrows and ncols are greater than 1, return a Tcl list of n rows * x n cols values each (a list of rows...), centered at the given point. */ int RtdImage::getCmd(int argc, char* argv[]) { if (!image_) return TCL_OK; double x, y; int nrows = 1, ncols = 1; char buf[80]; if (convertCoordsStr(0, argv[0], argv[1], NULL, NULL, x, y, argv[2], "image") != TCL_OK) return TCL_ERROR; if (argc == 5) { if (Tcl_GetInt(interp_, argv[3], &nrows) != TCL_OK || Tcl_GetInt(interp_, argv[4], &ncols) != TCL_OK) { return TCL_ERROR; } } if (nrows == 1 && ncols == 1) { return set_result(image_->getValue(buf, x, y)); } int n = nrows/2; int m = ncols/2; for (int j = -m; j <= m; j++) { Tcl_AppendResult(interp_, " { ", NULL); for (int i = -n; i <= n; i++) { Tcl_AppendResult(interp_, " { ", image_->getValue(buf, x+i, y+j), " } ", NULL); } Tcl_AppendResult(interp_, " } ", NULL); } return TCL_OK; } /* * Implement the "getvals" image command to return a Tcl list of image values * at the given X,Y coordinates. * * This command is similar to the "get" subcommand but uses x, y as lower left * corner for the image window and only returns a tcl list with the Y values. * Furthermore, the values are scanned by row order (1'st row first, then * 2'nd row etc.). * * usage: getvals $x $y coord_type ?nrows ncols? * * x and y are the coordinates in the image window in the given coordinate * system (one of: canvas, image, screen, wcs, deg). * * The return value is a tcl list with the Y values in the raw image * or "-" if out of range. */ int RtdImage::getvalsCmd(int argc, char* argv[]) { if (!image_) return TCL_OK; double x, y, val; int nrows = 1, ncols = 1; char buf[80]; int ix, iy; if (convertCoordsStr(0, argv[0], argv[1], NULL, NULL, x, y, argv[2], "image") != TCL_OK) return TCL_ERROR; if (argc == 5) { if (Tcl_GetInt(interp_, argv[3], &nrows) != TCL_OK || Tcl_GetInt(interp_, argv[4], &ncols) != TCL_OK) { return TCL_ERROR; } } for (int j = 0; j < nrows; j++) { for (int i = 0; i < ncols; i++) { if (image_->getIndex(x+i, y+j, ix, iy) != 0) strcpy(buf, "- "); else { val = image_->getValue(x+i, y+j); sprintf(buf, "%g ", val); } Tcl_AppendResult(interp_, buf, NULL); } } return TCL_OK; } /* * implement the graphdist subcommand to display the distribution * of values in the image. * * usage: * pathName graphdist bltGraph bltElem numValues xVector yVector * * * xVector is the name of the BLT x vector * * yVector is the name of the BLT y vector * * The data for the given element in the given graph will be set * directly from here without going through tcl. */ int RtdImage::graphdistCmd(int argc, char* argv[]) { if (!image_) return TCL_OK; int numValues; if (Tcl_GetInt(interp_, argv[2], &numValues) != TCL_OK) { return TCL_ERROR; } // seems like you can't always depend on being allowed to use a variable // for the array bounds... #ifdef __GNUC__ double xyvalues[numValues*2]; #else double* xyvalues = new double[numValues*2]; #endif image_->getDist(numValues, xyvalues); int status = TCL_OK; if (numValues > 0) status = Blt_GraphElement(interp_, argv[0], argv[1], numValues*2, xyvalues, argv[3], argv[4]); else status = error("all image pixels have the same value"); #ifndef __GNUC__ delete[] xyvalues; #endif return status; } /* * This method implements the "hdu" subcommand, to access different * FITS HDUs (header data units). Each HDU may be of type "image", * "binary" table or "ascii" table. * * usage: hdu count * or: hdu list * or: hdu listheadings * or: hdu type ?number? * or: hdu headings ?$number? * or: hdu fits ?$number? * or: hdu get ?$number? ?$filename? ?$entry? * or: hdu create $type $extname $headings $tform $data * or: hdu delete $number * or: hdu set $number * or: hdu ?$number? * or: hdu display ?hduList? * * If the "hdu count" subcommand is specified, it returns the number of * HDUs in the current image. * * The "hdu type" subcommand returns the type of the current or given HDU * as a string "ascii", "binary" or "image". * * If the "hdu list" subcommand is specified, it returns a Tcl list of * FITS HDU information of the form: * * {{number type extname naxis naxis1 naxis2 naxis3 crpix1 crpix2} ...} * * Where: * * - number is the HDU number * - type is the HDU type: one of "image", "binary table", "ascii table". * - extname is the value of the EXTNAME keyword, if set * - naxis, naxis1, naxis2, naxis3 match the FITS keyword values. * * The "hdu listheadings" subcommand returns a list of the column names * returned by the "hdu list" subcommand. This can be used to set the * title of a table listing of the HDUs in a FITS file. * * The "hdu headings" subcommand returns a list of the column names * in the current or given FITS table. * * The "hdu fits" subcommand returns the FITS header * of the current or given HDU. * * The "hdu get" subcommand with no arguments returns the contents of the * current ASCII or binary table as a Tcl list (a list of rows, where * each row is a list of column values). If the HDU number is given, the * contents of the given HDU are returned. If a filename argument is * given, the FITS table is written to the given file in the form of a * local (tab separated) catalog. If optional "entry" argument is given, * it specifies the catalog config entry as a list of {{keyword value} * {keyword value} ...}, as defined in the catalog config file * (~/.skycat/skycat.cfg). The entry is written to the header of the * local catalog file and is used mainly to specify plot symbol * information for the catalog. * * The "hdu create" command creates a new FITS table in the current image * file. $type maye be "ascii" for an ASCII table or "binary" for a * binary FITS table. The name of the table is given by extname. The * table headings and data correspond to the catalog headings and * data. The tform argument is a list of FITS storage formats, one for * each column, of the form {16A 2D 12A ...} (similar to FORTRAN formats, * see the FITS docs). * * The "hdu delete" command deletes the given HDU. The argument is the HDU * number. The other HDUs in the file following the deleted one are moved to * fill the gap. * * If the "hdu" subcommand is specified with no arguments, it returns the * current HDU number. If a number argument is given, the current HDU is * set to that number. * * The "hdu set" subcommand sets the current HDU to the given number. * The keyword "set" is optional (see below). * * The "hdu display ?hduList?" subcommand displays all of the image HDUs * (or the ones specified) at once, combined in one image, using the * world coordinates information in each HDU header as the reference for * the pixel positions. * * An optional numerical argument may be passed to the "hdu" subcommand, * in which case the "current HDU" is set to the given number. */ int RtdImage::hduCmd(int argc, char* argv[]) { if (!image_) return TCL_OK; // HDU operations: make sure it is a FITS file ImageIO imio = image_->image(); if (!imio.rep() || strcmp(imio.rep()->classname(), "FitsIO") != 0) return error("The \"hdu\" subcommand is only supported for FITS files"); FitsIO* fits = (FitsIO*)imio.rep(); // hdu (return the current HDU number) if (argc == 0) return set_result(fits->getHDUNum()); // hdu count if (strcmp(argv[0], "count") == 0) return set_result(fits->getNumHDUs()); // hdu type ?number? if (strcmp(argv[0], "type") == 0) return hduCmdType(argc, argv, fits); // hdu listheadings // (return a list of table headings matching the "hdu list" output) if (strcmp(argv[0], "listheadings") == 0) return set_result("HDU Type ExtName NAXIS NAXIS1 NAXIS2 NAXIS3 CRPIX1 CRPIX2"); // hdu headings ?$number? if (strcmp(argv[0], "headings") == 0) return hduCmdHeadings(argc, argv, fits); // hdu fits ?$number? if (strcmp(argv[0], "fits") == 0) return hduCmdFits(argc, argv, fits); // hdu get ?number? ?$filename? ?$entry? if (strcmp(argv[0], "get") == 0) return hduCmdGet(argc, argv, fits); // hdu create $type $extname $headings $tform $data if (strcmp(argv[0], "create") == 0) return hduCmdCreate(argc, argv, fits); // hdu delete $number if (strcmp(argv[0], "delete") == 0) return hduCmdDelete(argc, argv, fits); // hdu list if (strcmp(argv[0], "list") == 0) return hduCmdList(argc, argv, fits); // hdu set $number if (strcmp(argv[0], "set") == 0) return hduCmdSet(argc, argv, fits); // hdu display $hduList if (strcmp(argv[0], "display") == 0) return hduCmdDisplay(argc, argv, fits); // hdu $number (Set the current HDU) return hduCmdSet(argc, argv, fits); } /* * Implement the "height" subcommand - returns the * unscaled height of the current image. */ int RtdImage::heightCmd(int argc, char* argv[]) { if (!image_) return set_result(0); return set_result(image_->height()); } /* * implement the "isclear" subcommand to return true if the image is * cleared and 0 if there is an image loaded * * usage: $image isclear */ int RtdImage::isclearCmd(int argc, char* argv[]) { // XXX: we should do something with the -file option ?, camera ? return set_result(isclear()); } /* * Implement the "itt" subcommand * * usage: itt file * itt scale * itt list * * where the file should contain 256 intensity values (0.0..1.0), * one per line. * * "file" sets the itt file, * "scale" scales the itt by the given amount * "list" returns a list of itt files loaded */ int RtdImage::ittCmd(int argc, char* argv[]) { if (argc == 2) { int ret = TCL_OK; if (strcmp(argv[0], "file") == 0) { ret = colors_->loadITT(argv[1]); } else if (strcmp(argv[0], "scale") == 0) { int amount; if (Tcl_GetInt(interp_, argv[1], &amount) != TCL_OK) { ret = TCL_ERROR; } else { ret = colors_->scaleITT(amount); } } // Force image update if colour changes do not transfer // automatically (i.e. non-pseudocolor visual). if ( ret == TCL_OK ) { return colorUpdate(); } else { return ret; } } if (strcmp(argv[0], "file") == 0) { return set_result(colors_->itt()->name()); } if (strcmp(argv[0], "list") == 0) { ostringstream os; ITTInfo::list(os); set_result(os.str().c_str()); return TCL_OK; } return error("expected: \"itt file\" or \"itt scale\""); return TCL_OK; } /* * Implement the "max" subcommand - returns the * highest pixel value in the visible image. * * usage: * max */ int RtdImage::maxCmd(int argc, char* argv[]) { if (!image_) return TCL_OK; return set_result(image_->maxValue()); } /* * mband subcommand - draw a measure band on the canvas to show the * distance in world coordinates (diagonal, vertical and horizontal). * * This method was originaly implemented in Tcl/[incr Tcl], but was * redone here for better performance. The canvas tags used correspond to * items created in the itcl class RtdImageMBand: * * mband all items * mband_line diagonal line * mband_angle angle line (horiz. and vert.) * * mband_width_rect boxs around labels * mband_height_rect * mband_diag_rect * * mband_width_text labels * mband_height_text * mband_diag_text * * Usage: * $image mband x0 y0 x1 y1 cord_type show_angle * * Where x0 and y0 are the starting coordinates of the drag, x1 and y1 * are the coordinates from the motion events, both in the given * coordinate system. * * show_angle is a flag: if true, show the horizontal and vertical * distance, otherwise only the diagonal. */ int RtdImage::mbandCmd(int argc, char* argv[]) { if (!isWcs()) return TCL_OK; // get args double x0, y0, x1, y1; int show_angle; char* from_type = argv[4]; char* to_type = (char *)"canvas"; char buf[1024]; if (Tcl_GetInt(interp_, argv[5], &show_angle) != TCL_OK) return TCL_OK; // convert to canvas coords if (convertCoordsStr(0, argv[0], argv[1], NULL, NULL, x0, y0, from_type, to_type) != TCL_OK || convertCoordsStr(0, argv[2], argv[3], NULL, NULL, x1, y1, from_type, to_type) != TCL_OK) { return TCL_OK; } // clip to image bounds (full) double ix0 = 0.5, iy0 = 0.5, ix1 = 0.5 + image_->width(), iy1 = 0.5 + image_->height(); if (imageToCanvasCoords(ix0, iy0, 0) != TCL_OK || imageToCanvasCoords(ix1, iy1, 0) != TCL_OK) return TCL_OK; clip(x0, ix0, ix1); clip(x1, ix0, ix1); clip(y0, iy0, iy1); clip(y1, iy0, iy1); // note: wcs coords are not linear, so we need all 3 points in wcs double ra0 = x0, dec0 = y0, ra1 = x1, dec1 = y1, ra2 = x1, dec2 = y0; if (canvasToWorldCoords(ra0, dec0, 0) != TCL_OK || canvasToWorldCoords(ra1, dec1, 0) != TCL_OK || canvasToWorldCoords(ra2, dec2, 0) != TCL_OK) return TCL_OK; // get distances in world coords double width, height, dist = WorldCoords::dist(ra0, dec0, ra1, dec1)*60.; char widthStr[32], heightStr[32], distStr[32]; formatHM(dist, distStr); if (show_angle) { width = WorldCoords::dist(ra0, dec0, ra2, dec2)*60.; formatHM(width, widthStr); height = WorldCoords::dist(ra2, dec2, ra1, dec1)*60; formatHM(height, heightStr); } // calculate canvas coords for lines and labels and // try to keep the labels out of the way so they don't block anything double mx = (x0 + x1)/2; double my = (y0 + y1)/2; int offset = 10; // offset of labels from lines char* diag_anchor = (char *)"c"; // label anchors char* width_anchor = (char *)"c"; char* height_anchor = (char *)"c"; int diag_xoffset = 0, // x,y offsets for labels diag_yoffset = 0, width_yoffset = 0, height_xoffset = 0; if (fabs(y0 - y1) < 5) { diag_anchor = (char *)"s"; diag_yoffset = offset; show_angle = 0; } else if (y0 < y1) { width_anchor = (char *)"s"; width_yoffset = -offset; } else { width_anchor = (char *)"n"; width_yoffset = offset; } if (fabs(x0 - x1) < 5) { diag_anchor = (char *)"w"; diag_xoffset = offset; diag_yoffset = 0; show_angle = 0; } else if (x0 < x1) { diag_anchor = (char *)"se"; diag_xoffset = -offset; diag_yoffset = offset; height_anchor = (char *)"w"; height_xoffset = offset; } else { diag_anchor = (char *)"nw"; diag_xoffset = offset; diag_yoffset = -offset; height_anchor = (char *)"e"; height_xoffset = -offset; } // evaluate Tk canvas commands in the image's canvas const char* canvas = canvasName_; // set diagonal line coords sprintf(buf, "%s coords mband_line %g %g %g %g\n", canvas, x0, y0, x1, y1); Tcl_Eval(interp_, buf); // adjust labels sprintf(buf, "%s coords mband_diag_text %g %g\n", canvas, mx+diag_xoffset, my+diag_yoffset); Tcl_Eval(interp_, buf); sprintf(buf, "%s itemconfig mband_diag_text -text %s -anchor %s\n", canvas, distStr, diag_anchor); Tcl_Eval(interp_, buf); sprintf(buf, "%s bbox mband_diag_text\n", canvas); Tcl_Eval(interp_, buf); double rx0, ry0, rx1, ry1; if (sscanf(Tcl_GetStringResult(interp_), "%lf %lf %lf %lf", &rx0, &ry0, &rx1, &ry1) != 4) return TCL_OK; sprintf(buf, "%s coords mband_diag_rect %g %g %g %g\n", canvas, rx0, ry0, rx1, ry1); Tcl_Eval(interp_, buf); if (show_angle) { // set angle line coords sprintf(buf, "%s coords mband_angle %g %g %g %g %g %g\n", canvas, x0, y0, x1, y0, x1, y1); Tcl_Eval(interp_, buf); sprintf(buf, "%s coords mband_width_text %g %g\n", canvas, mx, y0+width_yoffset); Tcl_Eval(interp_, buf); sprintf(buf, "%s itemconfig mband_width_text -text %s -anchor %s\n", canvas, widthStr, width_anchor); Tcl_Eval(interp_, buf); sprintf(buf, "%s bbox mband_width_text\n", canvas); Tcl_Eval(interp_, buf); if (sscanf(Tcl_GetStringResult(interp_), "%lf %lf %lf %lf", &rx0, &ry0, &rx1, &ry1) != 4) return TCL_OK; sprintf(buf, "%s coords mband_width_rect %g %g %g %g\n", canvas, rx0, ry0, rx1, ry1); Tcl_Eval(interp_, buf); sprintf(buf, "%s coords mband_height_text %g %g\n", canvas, x1+height_xoffset, my); Tcl_Eval(interp_, buf); sprintf(buf, "%s itemconfig mband_height_text -text %s -anchor %s\n", canvas, heightStr, height_anchor); Tcl_Eval(interp_, buf); sprintf(buf, "%s bbox mband_height_text\n", canvas); Tcl_Eval(interp_, buf); if (sscanf(Tcl_GetStringResult(interp_), "%lf %lf %lf %lf", &rx0, &ry0, &rx1, &ry1) != 4) return TCL_OK; sprintf(buf, "%s coords mband_height_rect %g %g %g %g\n", canvas, rx0, ry0, rx1, ry1); Tcl_Eval(interp_, buf); } else { // hide the width and height labels and lines x1 = x0 + 1; y1 = y0 + 1; sprintf(buf, "%s coords mband_angle %g %g %g %g\n", canvas, x0, y0, x1, y1); Tcl_Eval(interp_, buf); sprintf(buf, "%s itemconfig mband_width_text -text {}\n", canvas); Tcl_Eval(interp_, buf); sprintf(buf, "%s coords mband_width_rect %g %g %g %g\n", canvas, x0, y0, x1, y1); Tcl_Eval(interp_, buf); sprintf(buf, "%s itemconfig mband_height_text -text {}\n", canvas); Tcl_Eval(interp_, buf); sprintf(buf, "%s coords mband_height_rect %g %g %g %g", canvas, x0, y0, x1, y1); Tcl_Eval(interp_, buf); } return TCL_OK; } /* * Implement the "min" subcommand - returns the * lowest pixel value in the image. */ int RtdImage::minCmd(int argc, char* argv[]) { if (!image_) return TCL_OK; return set_result(image_->minValue()); } /* * implement the "mmap" subcommand: * * usage: $image mmap set $data_filename $data_offset $data_owner \ * ?$header_filename $header_offset $header_owner? * $image mmap get data * $image mmap get header * $image mmap create $filename $size * $image mmap delete $filename * $image mmap update * * This subcommand provides access to the mmap shared memory in which the * FITS image data and header are stored. Image files are always mapped * with mmap by default (since it is faster than reading the * file). Applications can take advantage of this to modify the image * data and then notify the application to update the image. This command * makes it posible to put the image data and header in separate files, * so that they can be more easily updated by other applications. If you * want to put both header and data in the same file in the normal way, * just use "$image config -file". Otherwise you can use this command to * quickly update the image data in a separate file. * * The "set" command allow you to set the files to use to for the image * data and header. The data and header in the specified files should be * in FITS format (i.e.:, a FITS file split in 2 parts). If the header * is not specified, the previous header is reused, if there was one. * The offset arguments indicate an offset in the file where the header * or data start. If the file contains only the data or only the header, * the offset argument should be set to 0. * A flag indicating who "owns" the file may be specified (if true, then * the file will be deleted when no longer needed). * * Example: $image mmap set datafile1 0 0 headerfile1 0 0 * $image mmap set datafile2 0 0 * ... * * The "get" command returns mmap information about the data or header. * If the data or header is not currently mapped, an error is returned. * The return value is a list of the form {filename offset owner}, the * same as the arguments to the "$image mmap set" command. * * The "create" command creates a new mmapped file with the given name * and the given size. The mmaped file/memory should be released with the * "delete" subcommand when no longer needed. * * The "delete" command unmaps the given file and deletes it, if it was * created with the "mmap create" subcommand. * * The "update" command causes the display to be updated to reflect any * changes in the image memory. */ int RtdImage::mmapCmd(int argc, char* argv[]) { char* msg = (char *)"invalid arguments for mmap subcommand"; // this is used to keep track of memory areas for the "create" and // "delete" subcommands here static Mem* mem_areas[10]; const int max_mem_areas = sizeof(mem_areas)/sizeof(Mem*); if (strcmp(argv[0], "set") == 0) { // $image mmap set ... if (argc != 4 && argc != 7) return error(msg); char* data_filename = argv[1]; char* header_filename = NULL; int data_offset = 0, data_owner = 0, data_size = 0, header_offset = 0, header_owner = 0, header_size = 0; if (Tcl_GetInt(interp_, argv[2], &data_offset) == TCL_ERROR || Tcl_GetBoolean(interp_, argv[3], &data_owner) == TCL_ERROR) return TCL_ERROR; if (argc == 7) { header_filename = argv[4]; if (Tcl_GetInt(interp_, argv[5], &header_offset) == TCL_ERROR || Tcl_GetBoolean(interp_, argv[6], &header_owner) == TCL_ERROR) return TCL_ERROR; } Mem data(data_filename, verbose()); if (data.status() != 0) return TCL_ERROR; if (data_offset) data.offset(data_offset); if (data_owner) data.owner(data_owner); Mem header; if (! header_filename) { // if there is no header, check that image has right size at least if (! image_) return error("no current image header to go with mmap data"); if (data.length() < image_->data().length()) return error("mmap data file is too small for current image header"); header = image_->header(); } else { header = Mem(header_filename, verbose()); if (header.status() != 0) return TCL_ERROR; if (header_offset) header.offset(header_offset); if (header_owner) header.owner(header_owner); } // used to save and restore image transformation parameters ImageDataParams p; if (image_) { image_->saveParams(p); delete image_; image_ = NULL; updateViews(); } FitsIO* fits = FitsIO::initialize(header, data); image_ = makeImage(fits); if (! image_) return TCL_ERROR; // restore transformations image_->restoreParams(p, !autoSetCutLevels_); filename(data_filename); // keep filename return initNewImage(); } // $image mmap get ... else if (strcmp(argv[0], "get") == 0) { if (argc != 2) return error(msg); if (! image_) return error("no image is currently loaded"); Mem m; if (strcmp(argv[1], "data") == 0) { if (image_->data().filename() == NULL) return error("image data is not mapped"); m = image_->data(); } else if (strcmp(argv[1], "header") == 0) { if (image_->header().filename() == NULL) return error("image header is not mapped"); m = image_->header(); } else { return error(msg); } reset_result(); append_element(m.filename()); append_element((int)m.offset()); return append_element(m.owner()); } else if (strcmp(argv[0], "update") == 0) { return updateImage(); } else if (strcmp(argv[0], "create") == 0) { if (argc != 3) return error(msg); char* filename = argv[1]; int size = 0; if (Tcl_GetInt(interp_, argv[2], &size) == TCL_ERROR) return TCL_ERROR; for (int i = 0; istatus() == 0) { mem_areas[i] = m; return TCL_OK; } return TCL_ERROR; } } return error("too many mmap files for 'mmap create' subcommand"); } else if (strcmp(argv[0], "delete") == 0) { if (argc != 2) return error(msg); char* filename = argv[1]; for (int i = 0; ifilename(), filename) == 0) { delete mem_areas[i]; mem_areas[i] = NULL; return TCL_OK; } } return error("the specified file was not created with the 'mmap create' subcommand"); } else { return error(msg); } return TCL_OK; } int RtdImage::motioneventCmd(int argc, char* argv[]) { if (argc == 0) // return the current values return set_result(saveMotion_); if (argc != 1) return error("wrong number of args: should be motionevent ?0/1"); int value; if (Tcl_GetInt(interp_, argv[0], &value) != TCL_OK) { return error("invalid argument, expected 0 or 1"); } saveMotion_ = value; } /* * Implement the "object" subcommand - returns the * OBJECT field of the image header to indicate the * name of the astronomical object */ int RtdImage::objectCmd(int argc, char* argv[]) { if (!image_) return TCL_OK; return set_result(image_->object()); } /* * pan subcommand: * * usage: * pan start * pan stop * pan update * * start - arrange to have a tcl command evaluated whenever the image size changes * (due to scaling or loading a new image) or whenever the image position has * changed (due to scrolling) * * pan stop - stop evaluating the tcl command... * * pan upadte - force an update of the pan window (normally done whenever * image size or position changes) * * The tclCommand will be called with 5 arguments: x1 y1 x2 y2, which are the coords * of the visible part of the image, scaled by the given shrinkFactor, and a flag * indicating whether the image is new (1) or an update of the existing image (0). * This can be used to draw the panning rectangle on the panning image. */ int RtdImage::panCmd(int argc, char* argv[]) { if (strcmp(argv[0],"start") == 0) { // pan start subcommand if (argc != 3) return error("wrong # of args: should be \"pathName pan start tclCommand shrinkFactor\""); if (panCommand_) free(panCommand_); panCommand_ = strdup(argv[1]); if (Tcl_GetInt(interp_, argv[2], &panFactor_) != TCL_OK) return TCL_ERROR; if (panFactor_ > -2 && panFactor_ != 1 && panFactor_ != -1) return error("pan shrinkFactor should be -2 for 1/2 size, -3 for 1/3, etc. or 1"); if (panFactor_ == 1) panFactor_ = -1; // for calculations, should be negative // cause panning window to be reset panx1_ = pany1_ = panx2_ = pany2_ = 0; if (image_) autoPan(); } else if (strcmp(argv[0],"stop") == 0) { // pan stop subcommand if (panCommand_) free(panCommand_); panCommand_ = NULL; } else if (strcmp(argv[0],"update") == 0) { // pan update subcommand // cause panning window to be reset panx1_ = pany1_ = panx2_ = pany2_ = 0; if (image_) autoPan(); } else { return error("invalid image pan subcommand: should be \"start\" or \"stop\""); } return TCL_OK; } /* * The following function is called when the interactive performance testing * is enabled or disabled. It sets the required flag, and resets the variables * if required. * * Usage: * perftest off - turn performance testing off * perftest on - turn performance testing on * perftest reset - reset the performance parameters * * Arguments: * int argc, char *argv - argument list */ int RtdImage::perfTestCmd(int argc, char *argv[]) { // Check the arguments and act according to the usage instructions if (strcmp(argv[0], "on") == 0 || strcmp(argv[0], "reset") == 0) { // Set the testing on and reset the various parameters rtdperf_->reset(); if (strcmp(argv[0], "on") == 0) { rtdperf_->verbose(verbose()); rtdperf_->debug(debug()); if (argc > 1) rtdperf_->name(argv[1]); else rtdperf_->name(viewMaster_ ? viewMaster_->instname_ : instname_); rtdperf_->on(); } } else if (strcmp(argv[0], "off") == 0) { rtdperf_->reset(); rtdperf_->off(); } else return error("Unknown argument to perftest command"); return TCL_OK; } /* * implement the pixtab subcommand to support displaying a table of * pixel values around a point. * * usage: $image pixtab start nrows ncols * $image pixtab stop * * All this commmand does is set a flag causing Tcl array variables * to be updated on motion events, which can cause the display to be * updated via the "-textvariable" widget option on the table items. * * The array name is fixed as: RtdPixTab and the elements are indexed as * $RtdPixTab(i,j), where the left and top sides of the table (array) are * the X and Y image coordinates, resp. and the rest are image pixel * values. * */ int RtdImage::pixtabCmd(int argc, char* argv[]) { if (strcmp(argv[0], "start") == 0) { if (argc != 3) return error("expected: $image pixtab start nrows ncols"); int nrows, ncols; if ((Tcl_GetInt(interp_, argv[1], &nrows) == TCL_ERROR) || (Tcl_GetInt(interp_, argv[2], &ncols) == TCL_ERROR)) return TCL_ERROR; if (nrows <= 0 || ncols <= 0) return error("number of rows and columns should be positive"); // force value to be odd so we can center it if ((nrows&1) == 0) nrows++; if ((ncols&1) == 0) ncols++; pixTabRows_ = nrows; pixTabCols_ = ncols; if (pixTab_) delete[] pixTab_; // generate an array of pixel values with left and right headings // for the x/y coordinates pixTab_ = new double[++nrows*++ncols]; if (pixTab_) memset((void*)pixTab_, '\0', nrows*ncols*sizeof(double)); } else if (strcmp(argv[0], "stop") == 0) { if (pixTab_) delete[] pixTab_; pixTab_ = NULL; } else { return error("expected image pixtab 'start nrows ncols' or 'stop'"); } return TCL_OK; } /* * This method implements the "preview" subcommand * * usage: preview * * if boolValue is true, enter preview mode, otherwise go back to * real-time mode. In preview mode, the camera is stopped (if it was * running) and a local copy of the shared memory image is made, * so that it can be freed or modified without affecting the image. * */ int RtdImage::previewCmd(int argc, char* argv[]) { //dbg_->log("%s: previewCmd: camera = %x\n", name(), camera_); if (! camera_) return TCL_OK; int flag; if (Tcl_GetBoolean(interp_, argv[0], &flag) != TCL_OK) return TCL_ERROR; if (flag) { // enter preview mode, get local copy of image data if (camera_->attached()) { image_->data().shared(0); image_->data().shared(shm_data()); // in case a diff shared memory was requested // also preview the rapid frame, if any for(int i = 0; i < MAX_VIEWS; i++) { if (view_[i] && view_[i]->rapidFrame_ && view_[i]->image_ ) { view_[i]->image_->data().shared(0); } } if (camera_->pause() != TCL_OK) return TCL_ERROR; // update zoom window with the new data ? processMotionEvent(); } } else { // resume return camera_->cont(); } return TCL_OK; } /* * This method implements the radecbox subcommand. * * usage: * lassign [$image radecbox $ra $dec $radius] ra0 dec0 ra1 dec1 * * ra and dec are the world coords (h:m:s or decimal deg) and radius is expected in * arcmin. * * The return value in Tcl is a list of 4 values {ra0 dec0 ra1 dec1} that form a * ra,dec box with the given center point and radius */ int RtdImage::radecboxCmd(int argc, char* argv[]) { WorldCoords pos(argv[0], argv[1]); if (pos.status() != 0) return TCL_ERROR; double radius; if (Tcl_GetDouble(interp_, argv[2], &radius) != TCL_OK) return TCL_ERROR; WorldCoords pos1, pos2; pos.box(radius, pos1, pos2); ostringstream os; os << pos1 << ' ' << pos2; return set_result(os.str().c_str()); } /* * implement the "remote" subcommand for remote control of the RTD image * widget. * * usage: $image remote ?$port? * * If a port number argument is specified The widget will start listening * for commands on the given port. If port is 0, a port number will be * chosen. * * If no port number is specified, the current port number is returned, * or "" if there is none. This is a way to determine the port number * at the Tcl level. */ int RtdImage::remoteCmd(int argc, char* argv[]) { if (argc == 0) { if (remote_) return set_result(remote_->port()); return TCL_OK; } char* cmd = (char *)""; int port = 0; if (Tcl_GetInt(interp_, argv[0], &port) == TCL_ERROR) return TCL_ERROR; if (remote_) delete remote_; remote_ = new RtdImageRemote(this, port); if (remote_) return remote_->status(); return TCL_ERROR; } /* * implement the "remotetcl" subcommand to evaluate a Tcl command * in the RTD Tcl interpreter. * * usage: $image remotetcl $command */ int RtdImage::remoteTclCmd(int argc, char* argv[]) { Tcl_Eval(interp_, argv[0]); return set_result(Tcl_GetStringResult(interp_)); } /* * Implement the "rotate" image subcommand * * usage: rotate ?bool? * * currently, rotation is only done by swapping x and y axis (-90 deg.) * If bool is specified, rotation is turned on(1) or off(0). * Otherwise, the current setting is returned. */ int RtdImage::rotateCmd(int argc, char* argv[]) { if (!image_) return TCL_OK; int angle = 0; if (argc == 1) { if (Tcl_GetInt(interp_, argv[0], &angle) != TCL_OK) return TCL_ERROR; } else { return set_result(image_->rotate()); } image_->rotate(angle != 0); // update other views if (updateViews(1) != TCL_OK) return TCL_ERROR; // make sure the image is regenerated if (resetImage() != TCL_OK) return TCL_ERROR; if (panCommand_) { if (Tk_Width(tkwin_) <= 1) { // pause here until window is displayed, so that the pan // window can determine the size of the window updateRequests(); } autoPan(1); } // keep status in a global Tcl variable which can be traced by the Tcl code char* var = (viewMaster_ ? viewMaster_->instname_ : instname_); char sts[10]; sprintf(sts, "%d", image_->rotate()); Tcl_SetVar2(interp_, var, "ROTATE", sts, TCL_GLOBAL_ONLY); return TCL_OK; } /* * Implement the "scale" image subcommand * * usage: scale ?sx sy restFlag? * * With 2 args scale (zoom) the image by the specified X and Y * amount. * * With no args, return the current scaling factors. * */ int RtdImage::scaleCmd(int argc, char* argv[]) { if (!image_) return TCL_OK; int xs = image_->xScale() , ys = image_->yScale(); if (argc == 0) // return the current values return set_result(xs, ys); if (argc != 2) return error("wrong number of args: should be scale ?sx sy?"); // set the scale factor: // 2 means twice the normal size, -2 means 1/2 normal size // don't allow zero scale or shrink in X and grow in Y... int xScale, yScale; if (Tcl_GetInt(interp_, argv[0], &xScale) != TCL_OK || Tcl_GetInt(interp_, argv[1], &yScale) != TCL_OK) { return error("invalid arguments, expected x and y scale factors"); } // check arguments if (xScale == -1 || xScale == 0) xScale = 1; if (yScale == -1 || yScale == 0) yScale = 1; #if 0 // add a check for the Tk limit on canvas coords if (xScale > 0 && xScale * image_->width() > 32767 || yScale > 0 && yScale * image_->height() > 32767) return error("sorry, can't scale image to this size without exceeding maximum Tk canvas coordinate range"); #endif int stat; stat = setScale(xScale, yScale); // keep status in a global Tcl variable which can be traced by the Tcl code char* var = (viewMaster_ ? viewMaster_->instname_ : instname_); char sts[100]; sprintf(sts, "%d %d", image_->xScale(), image_->yScale()); Tcl_SetVar2(interp_, var, "SCALE", sts, TCL_GLOBAL_ONLY); return stat; } /* * implement the "shm" subcommand to manipulate image sysV shared memory: * * usage: $image shm set $data_size $data_id $data_owner \ * ?$header_size $header_id $header_owner? * $image shm get data * $image shm get header * $image shm create $size * $image shm delete $Id * $image shm update * * This subcommand provides access to the sysV shared memory in which the * FITS raw image data and header are stored. The raw image is stored in * sysV shared memory if the -shm_data option was specified when creating * the image and the header is stored in sysV shared memory if the * -shm_headr option was specified. * * The "set" command allow you to set the shared memory Ids to use to * access the image data and header. The data and header in the area * specified should be in FITS format. If the header is not specified, * the previous header is reused. For both data and header, the size of * the area (in bytes) and the shared memory Id must be specified. In * addition a flag indicating who "owns" the shared memory is specified * (if true, then the area will be deleted when no longer needed). * * The "get" command returns the shared memory Id of the data or header * as well as the offset in the shared memory area where the header or * data begins, the length of the header or data and the total size of * the shared memory. The result of the "get header" or "get data" * command is a Tcl list of the 4 numbers {shmId offset length size}, * where length is the length of the header or data and size is the total * size of the shared memory area. If the data or header is not currently * in shared memory, an error is returned. (RTD must be started with * option -shm_data 1 and/or -shm_header 1 for this command to work). * * The "create" command creates a new shared memory area with the given * size and returns the Id. The memory should be deleted with the "delete" * subcommand when no longer needed. * * The "delete" command deletes the shared memory with the given Id (which * should have been returned from the "create" subcommand). * * The "update" command causes the display to be updated to reflect any changes * in the image memory. */ int RtdImage::shmCmd(int argc, char* argv[]) { char* msg = (char *)"invalid arguments for shm subcommand"; // this is used to keep track of memory areas for the "create" and // "delete" subcommands here static Mem* mem_areas[10]; const int max_mem_areas = sizeof(mem_areas)/sizeof(Mem*); if (strcmp(argv[0], "set") == 0) { if (argc != 4 && argc != 7) return error(msg); int data_size = 0, data_id = -1, data_owner = 0, header_size = 0, header_id = -1, header_owner = 0; if (Tcl_GetInt(interp_, argv[1], &data_size) == TCL_ERROR || Tcl_GetInt(interp_, argv[2], &data_id) == TCL_ERROR || Tcl_GetBoolean(interp_, argv[3], &data_owner) == TCL_ERROR) return TCL_ERROR; if (argc == 7) { if (Tcl_GetInt(interp_, argv[4], &header_size) == TCL_ERROR || Tcl_GetInt(interp_, argv[5], &header_id) == TCL_ERROR || Tcl_GetBoolean(interp_, argv[6], &header_owner) == TCL_ERROR) return TCL_ERROR; } Mem data(data_size, data_id, data_owner, verbose()); if (data.status() != 0) return TCL_ERROR; Mem header; if (header_id < 0) { // if there is no header, check that image has right size at least if (! image_) return error("no current image header to go with shm data"); if (data_size < image_->data().length()) return error("shared memory area is to small for current image"); header = image_->header(); } else { header = Mem(header_size, header_id, header_owner, verbose()); } if (header.status() != 0) return TCL_ERROR; // used to save and restore image transformation parameters ImageDataParams p; if (image_) { image_->saveParams(p); delete image_; image_ = NULL; updateViews(); } FitsIO* fits = FitsIO::initialize(header, data); image_ = makeImage(fits); if (! image_) return TCL_ERROR; // restore transformations image_->restoreParams(p, !autoSetCutLevels_); return initNewImage(); } else if (strcmp(argv[0], "get") == 0) { if (argc != 2) return error(msg); if (! image_) return error("no image is currently loaded"); char buf[80]; if (strcmp(argv[1], "data") == 0) { if (!image_->data().shared()) return error("rtd was not started with the -shm_data option"); Mem m = image_->data(); sprintf(buf, "%d %d %d %d", m.shmId(), m.offset(), m.length(), m.size()); return set_result(buf); } else if (strcmp(argv[1], "header") == 0) { if (!image_->header().shared()) return error("rtd was not started with the -shm_header option"); Mem m = image_->header(); sprintf(buf, "%d %d %d %d", m.shmId(), m.offset(), m.length(), m.size()); return set_result(buf); } else { return error(msg); } } else if (strcmp(argv[0], "update") == 0) { return updateImage(); } else if (strcmp(argv[0], "create") == 0) { if (argc != 2) return error(msg); int size = 0; if (Tcl_GetInt(interp_, argv[1], &size) == TCL_ERROR) return TCL_ERROR; for (int i = 0; istatus() == 0) { mem_areas[i] = m; return set_result(m->shmId()); } return TCL_ERROR; } } return error("too many shared memory areas for 'shm create' subcommand"); } else if (strcmp(argv[0], "delete") == 0) { if (argc != 2) return error(msg); int shmId = -1; if (Tcl_GetInt(interp_, argv[1], &shmId) == TCL_ERROR) return TCL_ERROR; for (int i = 0; ishmId() == shmId) { delete mem_areas[i]; mem_areas[i] = NULL; return TCL_OK; } } return error("the specified shared memory area was not created with the 'shm create' subcommand"); } else { return error(msg); } return TCL_OK; } /* * This method implements the spectrum subcommand. * * usage: * * spectrum x0 y0 x1 y1 coord_type xVector yVector * * where: * x0, y0, x1 and y1 are the end points of a line in the image in the * given coordinate system (canvas, image, screen, wcs, deg). * * is the path name of a BLT graph widget to display * the plot of the pixel intensities along the line * * is the name of the element in the graph that should * receive the data * * xVector is the name of the BLT x vector * * yVector is the name of the BLT y vector * * The data is sent directly to the graph for display. * The return value in Tcl is the number of points to plot. */ int RtdImage::spectrumCmd(int argc, char* argv[]) { if (!image_) return TCL_OK; // convert to image coords double rx0, ry0, rx1, ry1; if (convertCoordsStr(0, argv[2], argv[3], NULL, NULL, rx0, ry0, argv[6], "image") != TCL_OK || convertCoordsStr(0, argv[4], argv[5], NULL, NULL, rx1, ry1, argv[6], "image") != TCL_OK) return TCL_ERROR; // get distance between endpoints (add a little to be safe) int x0 = int(rx0+0.5), y0 = int(ry0+0.5), x1 = int(rx1+0.5), y1 = int(ry1+0.5); int w = abs(x1-x0) + 1; int h = abs(y1-y0) + 1; int dist = (int)sqrt((double)w*w + h*h) + 2; double* xyvalues = new double[dist*2]; // fill the xyvalues array and set numValues to the actual number of points int numValues = image_->getSpectrum(xyvalues, x0, y0, x1, y1); assert(numValues <= dist); if (Blt_GraphElement(interp_, argv[0], argv[1], numValues*2, xyvalues, argv[7], argv[8]) != TCL_OK) { delete xyvalues; return TCL_ERROR; } delete[] xyvalues; return set_result(numValues); } /* * statistics subcommand: calculate statistics. * * usage: set list [$image statistics] * set list [$image statistics degrees] * or: set list [$image statistics noise x0 y0 nx ny] * * no args - * With no arguments or an argument of degrees the statistics on the * section of the image being displayed is calculated (used for * "pick object"). The return value in Tcl is a list of the * following values: * * {x y ra dec equinox fwhmX fwhmY angle objectPeak meanBackground * fwmhXa fwhmYa} * * where: * * x = X image coordinate * y = Y image coordinate * ra = RA position (calculated from mean X pos) * dec = DEC position (calculated from mean Y position) * equinox = equinox of RA and DEC * fwhmX = FWHM in X pixels * fwhmY = FWHM in Y pixels * angle = angle of major axis, degrees, along X * objectPeak = peak value of object above background * meanBackground = mean background level * fwhmXa = FWHM in X arcsecs * fwhmYa = FWHM in Y arcsecs * * If the single argument is "degrees" then the ra and dec values * are not formatted into sexagesimal. * * Note: compare results with Midas (center/gauss) when changes are done * * noise - * "noise" computes the noise statistics (RMS) on an image area. * x0, y0 is the lower left corner (in image coordinates) and * nx, ny the width and the height. * The return value in Tcl is a list of the following values: * * {min, max, av, rms, n, xs, xe, ys, ye} * * where: * * min = minimum value * max = maximum value * av = average value * rms = RMS value * n = number of samples used * xs, ys = lower left corner (image coordinates) of area * xe, ye = upper right corner (image coordinates) of area */ int RtdImage::statisticsCmd(int argc, char* argv[]) { char* msg = (char *)"invalid arguments for statistics subcommand"; if (!image_) return error("no image loaded"); if (argc == 0 || ( argc == 1 && strcmp(argv[0], "degrees") == 0 ) ) { double w = reqWidth_, h = reqHeight_; undoTrans(w, h, 1); // get only visible area double x = xOffset_, y = yOffset_; // adapt transformations for getStatistics() switch(image_->flipX() << 1 | image_->flipY()) { case 0: // none y += h; // upper left corner for image area to be examined break; case 1: // flipY break; case 2: // flipX x += w; y += h; break; case 3: // flipX and flipY x += w; break; } distToCoords(x, y); // get coords from offsets double meanX=0., meanY=0., fwhmX=0., fwhmY=0., angle=0., objectPeak=0., meanBackground=0.; if (image_->getStatistics(x, y, int(w), int(h), meanX, meanY, fwhmX, fwhmY, angle, objectPeak, meanBackground) != 0) { // if we could not get the FWHM (because the user clicked on the background // of the image), we still want to return the X,Y values of the area clicked. // allan: 22.4.98, by request x += w / 2.0; y += h / 2.0; } else { // get the image coords from the offsets x = meanX + (int)(x - 0.5) + 1.0; y = meanY + (int)(y - 0.5) + 1.0; } double ix = x, iy = y; // get the world coords position from the image coords WorldCoords pos; double dx, dy; double fwhmXa = 0.0; double fwhmYa = 0.0; if (imageToWorldCoords(x, y, 0) == TCL_OK) { pos = WorldCoords(x, y); if (pos.status() != 0) pos = WorldCoords(); // also report in degrees if asked if ( argc == 1 ) { pos.get( dx, dy, 2000.0 ); } // add FWHM in arcseconds, need image scale to do this. WCS& wcs = image_->wcs(); fwhmXa = fwhmX * wcs.secPix(); fwhmYa = fwhmY * wcs.secPix(); } ostringstream os; os << ix << ' ' << iy << ' '; if (pos.status() == 0 && ! pos.isNull()) { if ( argc == 1 ) { // report in degrees, try to keep precision reasonable char cx[TCL_DOUBLE_SPACE], cy[TCL_DOUBLE_SPACE]; sprintf( cx, "%.9g", dx ); sprintf( cy, "%.9g", dy ); os << cx << ' ' << cy << " J2000 "; // ra, dec, equinox, degrees. } else { os << pos << " J2000 "; // ra, dec, equinox: XXX use default equinox ? } } else { os << "{} {} {} "; // no world coords } os << fwhmX << ' ' << fwhmY << ' ' << angle << ' ' << objectPeak << ' ' << meanBackground << ' '; if ( fwhmXa == 0.0 ) { os << "{} {}"; // no world coords } else { os << fwhmXa << ' ' << fwhmYa; } return set_result(os.str().c_str()); } if (argc == 5 && strcmp(argv[0], "noise") == 0) { /* * $image statistics area x0 y0 nx ny */ double x0 = 0., y0 = 0., nx = 0., ny = 0.; double dmin = 0., dmax = 0., av = 0., rms = 0.; int n = 0, xs = 0, xe = 0, ys = 0, ye = 0; if (Tcl_GetDouble(interp_, argv[1], &x0) == TCL_ERROR || Tcl_GetDouble(interp_, argv[2], &y0) == TCL_ERROR || Tcl_GetDouble(interp_, argv[3], &nx) == TCL_ERROR || Tcl_GetDouble(interp_, argv[4], &ny) == TCL_ERROR) return error(msg); char buf[1024]; n = image_->noiseStatistics(x0, y0, int(nx), int(ny), &dmin, &dmax, &av, &rms, &xs, &xe, &ys, &ye); sprintf (buf, "%g %g %g %g %d %d %d %d %d", dmin, dmax, av, rms, n, xs, xe, ys, ye); return set_result(buf); } return error(msg); } /* * bltgraph subcommand: various commands to display 2-D data * in a blt::graph widget * * usage: * bltgraph xline bltGraph bltElem xVector yVector y xr0 dxr * or: bltgraph yline bltGraph bltElem xVector yVector x * * or: bltgraph spectrum bltGraph bltElem x0 y0 x1 y1 coord_type xVector yVector * or: bltgraph graphdist bltGraph bltElem numValues xVector yVector */ int RtdImage::bltgraphCmd(int argc, char* argv[]) { char* msg = (char *)"invalid arguments for bltgraph subcommand"; int stat, numValues; if (argc < 6) return error(msg); if (!image_) return error("no image loaded"); // for compatibility: if (strcmp(argv[0], "spectrum") == 0) { return spectrumCmd(argc - 1, argv++); } if (strcmp(argv[0], "graphdist") == 0) { return graphdistCmd(argc - 1, argv++); } if (strcmp(argv[0], "yline") == 0) { double x = 0; if (Tcl_GetDouble(interp_, argv[5], &x) == TCL_ERROR) return error(msg); double y0 = 0, y1 = image_->height() - 1; if (argc > 6) { if (Tcl_GetDouble(interp_, argv[6], &y0) == TCL_ERROR) return error(msg); } if (argc > 7) { if (Tcl_GetDouble(interp_, argv[7], &y1) == TCL_ERROR) return error(msg); } double *xyvalues = new double[image_->height()*4]; int numValues = image_->getYline4((int)x, (int)y0, (int)y1, xyvalues); stat = Blt_GraphElement(interp_, argv[1], argv[2], numValues*4, xyvalues, argv[3], argv[4]); delete xyvalues; return stat; } if (strcmp(argv[0], "xline") == 0) { double y = 0, xr0 = 0.0, dxr = 1.0; if (Tcl_GetDouble(interp_, argv[5], &y) == TCL_ERROR) return error(msg); double x0 = 0, x1 = image_->width() - 1; if (argc > 6) { if (Tcl_GetDouble(interp_, argv[6], &x0) == TCL_ERROR) return error(msg); } if (argc > 7) { if (Tcl_GetDouble(interp_, argv[7], &x1) == TCL_ERROR) return error(msg); } if (argc > 8) { if (Tcl_GetDouble(interp_, argv[8], &xr0) == TCL_ERROR) return error(msg); } if (argc > 9) { if (Tcl_GetDouble(interp_, argv[9], &dxr) == TCL_ERROR) return error(msg); } double *xyvalues = new double[image_->width()*4]; if (argc > 9) { numValues = image_->getXline4((int)y, (int)x0, (int)x1, xyvalues, xr0, dxr); } else { numValues = image_->getXline4((int)y, (int)x0, (int)x1, xyvalues); } stat = Blt_GraphElement(interp_, argv[1], argv[2], numValues*4, xyvalues, argv[3], argv[4]); delete xyvalues; return stat; } return error(msg); } /* * Implement the "type" subcommand - returns the * data type of the raw image as a string */ int RtdImage::typeCmd(int argc, char* argv[]) { if (!image_) return TCL_OK; switch (image_->dataType()) { case DOUBLE_IMAGE: return set_result("double"); case FLOAT_IMAGE: return set_result("float"); case SHORT_IMAGE: return set_result("short"); case USHORT_IMAGE: return set_result("ushort"); case LONG_IMAGE: return set_result("long"); case BYTE_IMAGE: return set_result("byte"); case X_IMAGE: return set_result("XImage"); default: break; } return TCL_OK; } /* * Implement the "update" subcommand * * usage: $image update * or: $image update idletasks * * With no arguments, just make sure that the image is up to date with * the raw data (which may have changed via shared memory). * * With 1 arg, do the equivalent of the Tk update idletasks command * (this one is for use via the remote interface). * */ int RtdImage::updateCmd(int argc, char* argv[]) { if (argc == 0) return updateImage(); updateRequests(); return 0; } /* * Set the maximum update frequency for the RTD. */ int RtdImage::maxFreqCmd(int argc, char* argv[]) { double maxFreq; if (argc != 1) { return TCL_ERROR; } if (Tcl_GetDouble(interp_, argv[0], &maxFreq) != TCL_OK) { return TCL_ERROR; } // This becomes the maximum update frequency in the main image, unless it // is negative, which indicates that the feature should be turned off. if (maxFreq < 0.) { options_->rtd_options_->fixUpdateRate = 0; options_->rtd_options_->userUpdateTime = 0.; } else { options_->rtd_options_->fixUpdateRate = 1; options_->rtd_options_->userUpdateTime = 1./maxFreq; } return TCL_OK; } /* * view subcommand: specify a viewing image to view the same * image, possibly at a different size. * * The new view will share data with the original and be updated * when the original is updated. * * This can be used, for example, to build a panning window * or a rapid frame. * * usage: * view add ?propagateScale? ?rapidFrame? * view remove * view update xOffset yOffset width height frameX frameY rapidX rapidY coordType * view update width height coordType * view enter * view leave * * must be the name of a second rtdimage image. The two * images will communicate internally to always display the * same image, possibly scaled to different sizes. * * add - adds a new view to this image * If the optional argument "propagateScale" is true, changes in * the scale factors in the master image will propagate to the * view (this is the default behavior). If "rapidFrame" is specified * as true, then the view is treated as a rapid frame and is only updated * from image events and not from the main image. * * remove - removes the view * * update - updates the frame from this image with the given sizes and offsets: * * xOffset, yOffset - X,Y offset of image frame in image canvas * width, height - dimensions of image * frameX, frameY - X,Y offset of image frame in image canvas * rapidX, rapidY - X,Y offset of rapid frame coresponding to main image. * coordType - type of the input coords (canvas, image, screen, etc) * * enter - if 2 images are in the same canvas, make the current one * (receives motion events, ...) * * leave - undo the enter command * */ int RtdImage::viewCmd(int argc, char* argv[]) { RtdImage* view = getView(argv[1]); if (! view) return TCL_ERROR; if (strcmp(argv[0], "update") == 0) { if (! image_) return TCL_OK; // can't update if image doesn't exist if (argc == 5) { // only update width and height of image double width, height; char* from_type = argv[4]; char* to_type = (char *)"image"; if (convertCoordsStr(1, argv[2], argv[3], NULL, NULL, width, height, from_type, to_type) != TCL_OK) return TCL_ERROR; // add 1 so that there is no space left at right and bottom // when only a partial zoomed pixel is displayed on the left or top view->reqWidth_ = width+1; view->reqHeight_ = height+1; return view->updateView(image_, 1); } else if (argc != 11) return error("usage: $image view update $view xOffset yOffset ", "width height frameX frameY rapidX rapidY coordType"); // get image coords and update image offsets double xOffset, yOffset, width, height, frameX, frameY, rapidX, rapidY; char* from_type = argv[10]; char* to_type = (char *)"image"; if (convertCoordsStr(1, argv[2], argv[3], NULL, NULL, xOffset, yOffset, from_type, to_type) != TCL_OK || convertCoordsStr(1, argv[4], argv[5], NULL, NULL, width, height, from_type, to_type) != TCL_OK || convertCoordsStr(1, argv[6], argv[7], NULL, NULL, frameX, frameY, from_type, to_type) != TCL_OK || convertCoordsStr(1, argv[8], argv[9], NULL, NULL, rapidX, rapidY, from_type, to_type) != TCL_OK) return TCL_ERROR; // dbg_->log("%s: update %s: xyOffset(%g,%g), size(%g,%g), frame(%g,%g), rapid(%g,%g)\n", // name(), view->name(), xOffset, yOffset, width, height, frameX, frameY, // rapidX, rapidY); view->xOffset_ = xOffset; view->yOffset_ = yOffset; // add 1 so that there is no space left at right and bottom // when only a partial zoomed pixel is displayed on the left or top view->reqWidth_ = width+1; view->reqHeight_ = height+1; view->frameX_ = frameX; view->frameY_ = frameY; view->rapidX_ = rapidX; view->rapidY_ = rapidY; return view->updateView(image_, 1); } else if (strcmp(argv[0], "add") == 0) { // add the view to the list int propagateScale = 1, rapidFrame = 0; if (argc >= 3) { if (Tcl_GetBoolean(interp_, argv[2], &propagateScale) != TCL_OK) return TCL_ERROR; } if (argc >= 4) { if (Tcl_GetBoolean(interp_, argv[3], &rapidFrame) != TCL_OK) return TCL_ERROR; } // allow the zoom window to be updated from the new view also // note: the check for displaymode() != 0 is to keep the pan window // from using the zoom window, which can be very slow on huge images. if (view->displaymode() != 0) { view->zoomer_ = zoomer_; view->zoomView_ = zoomView_; view->zoomView2_ = zoomView2_; view->zoomSpeed_ = zoomSpeed_; } // set flags view->propagateScale_ = propagateScale; view->rapidFrame_ = rapidFrame; // we only need one event handler per window if (view->tkwin_ == tkwin_) { Tk_DeleteEventHandler(tkwin_, ButtonMotionMask|StructureNotifyMask, eventProc, (ClientData)view); } return addView(view); } else if (strcmp(argv[0], "remove") == 0) { return removeView(view); } else if (strcmp(argv[0], "enter") == 0) { currentView_ = view; } else if (strcmp(argv[0], "leave") == 0) { currentView_ = this; } else { return error("invalid rtdimage view subcommand"); } return TCL_OK; } /* * warp the mouse pointer by the given x and y amounts: * * usage: $image warp $x $y */ int RtdImage::warpCmd(int argc, char* argv[]) { int x, y; if ((Tcl_GetInt(interp_, argv[0], &x) == TCL_ERROR) || (Tcl_GetInt(interp_, argv[1], &y) == TCL_ERROR)) return TCL_ERROR; XWarpPointer(display_, None, None, 0, 0, 0, 0, x, y); return TCL_OK; } /* * implement the "wcscenter" image command to return the world * coordinates of the center of the image. * * usage: wcscenter ?-format $format? * * The optional format option determines the format of the result: * -format 0 ==> H:M:S [+-]D:M:S Equinox (default) * -format 1 ==> RA DEC Equinox (RA and DEC in degrees) * * The return value is a tcl list, formatted according to the format * option, or an empty string if the coordinates are out of range or WCS * is not supported. */ int RtdImage::wcscenterCmd(int argc, char* argv[]) { if (!isWcs()) return TCL_OK; // get the format int format = 0; if (argc == 2) { if (strcmp(argv[0], "-format") == 0) { if (Tcl_GetInt(interp_, argv[1], &format) != TCL_OK) { return TCL_ERROR; } } } // get x and y double x = image_->width()/2., y = image_->height()/2.; // do the conversion and return the result switch(format) { case 0: char buf[80]; return set_result(image_->wcs().pix2wcs(x, y, buf, sizeof(buf))); case 1: double ra, dec; image_->wcs().pix2wcs(x, y, ra, dec); return set_result(ra, dec); default: return error("unknown format for pix2wcs: try 0 or 1"); } return TCL_OK; } /* * wcsdeltset subcommand * * usage: * $image wcsdeltset $cdelt1 $cdelt2 $rotation * * Set rotation and scaling * * Args: * cdelt1 = scale in degrees/pixel (axis 1); degrees = arcsec/3600. * cdelt2 = scale in degrees/pixel (axis 2) * rotation = rotation angle in degrees * */ int RtdImage::wcsdeltsetCmd(int argc, char* argv[]) { if (!isWcs()) return TCL_OK; double cdelt1, cdelt2, rotation; if (Tcl_GetDouble(interp_, argv[0], &cdelt1) != TCL_OK || Tcl_GetDouble(interp_, argv[1], &cdelt2) != TCL_OK || Tcl_GetDouble(interp_, argv[2], &rotation) != TCL_OK) return TCL_ERROR; return image_->wcs().deltset(cdelt1, cdelt2, rotation); } /* * This method implements the wcsdist subcommand. * * usage: * set dist [$image wcsdist x0 y0 x1 y1] * * The arguments are expected in canvas coords (canvasx, canvasy, * doubles). * The return value in Tcl is the WCS distance in arcsec between 2 * points (after transformations). */ int RtdImage::wcsdistCmd(int argc, char* argv[]) { if (!isWcs()) return TCL_OK; double x0, y0, x1, y1; if (Tcl_GetDouble(interp_, argv[0], &x0) != TCL_OK || Tcl_GetDouble(interp_, argv[1], &y0) != TCL_OK || Tcl_GetDouble(interp_, argv[2], &x1) != TCL_OK || Tcl_GetDouble(interp_, argv[3], &y1) != TCL_OK) { return TCL_ERROR; } #if 0 // XXX use new convert command here ??? undoTrans(x0, y0); undoTrans(x1, y1); // convert to WCS double ra0 = 0.0, dec0 = 0.0, ra1 = 0.0, dec1 = 0.0; if (image_->wcs().pix2wcs((int)x0, (int)y0, ra0, dec0) != 0 || image_->wcs().pix2wcs((int)x1, (int)y1, ra1, dec1) != 0) return TCL_ERROR; // check results if (ra0 == 0.0 || dec0 == 0.0 || ra1 == 0.0 || dec1 == 0.0) return TCL_OK; double dist = WorldCoords::dist(ra0, dec0, ra1, dec1)*60.; #else canvasToWorldCoords(x0, y0, 0); canvasToWorldCoords(x1, y1, 0); double dist = WorldCoords::dist(x0, y0, x1, y1)*60.; #endif return set_result(dist); } /* * This method implements the wcsequinox subcommand. * * usage: * set equinox [$image wcsequinox] * * The return value in Tcl is the world coordinate equinox * for the values of RA and DEC returned by the wcs... * commands. */ int RtdImage::wcsequinoxCmd(int argc, char* argv[]) { if (!isWcs()) return TCL_OK; double equinox = image_->wcs().equinox(); if (equinox != 0.0) { char buf[32]; sprintf(buf, "%.2f", equinox); return set_result(buf); } return TCL_OK; } /* * implement the "wcsheight" image command to return the world * coordinates height of the image * * usage: wcsheight * * The return value in Tcl is the height in arcmin or an empty * string if WCS is not supported. */ int RtdImage::wcsheightCmd(int argc, char* argv[]) { if (!isWcs()) return TCL_OK; return set_result(image_->wcs().height()); } /* * implement the "wcsradius" image command to return the world * coordinates radius of the image - the distance in arc-minutes from the * center point to the origin. * * usage: wcsradius * * The return value in Tcl is the radius in arc-minutes or an empty * string if WCS is not supported. */ int RtdImage::wcsradiusCmd(int argc, char* argv[]) { if (!isWcs()) return TCL_OK; return set_result(image_->wcs().radius()); } /* * wcsset subcommand: * * usage: * * $image wcsset $ra $dec $secpix $xrefpix $yrefpix $nxpix $nypix $rotate \ * $equinox $epoch $proj * $image wcsset * * If arguments are specified, this subcommand sets up the WCS structure * from the given information about the image: * * Args: * ra = Center right ascension in degrees * dec = Center declination in degrees * secpix = Number of arcseconds per pixel * xrefpix = Reference pixel X coordinate * yrefpix = Reference pixel Y coordinate * nxpix = Number of pixels along x-axis * nypix = Number of pixels along y-axis * rotate = Rotation angle (clockwise positive) in degrees * equinox = Equinox of coordinates, 1950 and 2000 supported * epoch = Epoch of coordinates, used for FK4/FK5 conversion no effect if 0 * proj = Projection * * With no arguments, the command returns a list of the basic WCS * parameter values: {ra dec secpix nxpix nypix rotate equinox epoch}. * * */ int RtdImage::wcssetCmd(int argc, char* argv[]) { if (!image_) return TCL_OK; // get a reference to the WCS object for the current image WCS& wcs = image_->wcs(); if (argc == 0) { // no args, return list of values char buf[256]; if (wcs.isWcs()) { // get RA and DEC of the center of the image char raStr[32], decStr[32]; raStr[0] = decStr[0] = '\0'; WorldCoords pos = wcs.center(); if (pos.status() != 0) return TCL_ERROR; pos.print(raStr, decStr, wcs.equinox()); // make the result list sprintf(buf, "%s %s %g %g %g %d %d %g %g %g %s", raStr, decStr, wcs.secPix(), wcs.xRefPix(), wcs.yRefPix(), wcs.pixWidth(), wcs.pixHeight(), wcs.rotate(), wcs.equinox(), wcs.epoch(), wcs.projection()); return set_result(buf); } else { // no WCS, return default info sprintf(buf, "{} {} {} {} {} %d %d 0 2000 2000 {}", image_->width(), image_->height()); return set_result(buf); } } else if (argc == 11) { double ra, dec, secpix, xrefpix, yrefpix, rotate, equinox, epoch; int nxpix, nypix; char* proj = (char *)""; // skip over B in B1950 and J in J2000 if (strcmp(argv[8], "B1950") == 0) equinox = 1950.; else if (strcmp(argv[8], "J2000") == 0) equinox = 2000.; else { if (Tcl_GetDouble(interp_, argv[8], &equinox) != TCL_OK) return TCL_ERROR; if (equinox != 2000. && equinox != 1950.) return error("expected equinox to be 2000. or 1950."); } // expect ra and dec in H:M:S D:M:S format WorldCoords pos(argv[0], argv[1], equinox); if (pos.status() != 0) return TCL_ERROR; pos.get(ra, dec, equinox); // get ra and dec in the right equinox // set WCS info if (Tcl_GetDouble(interp_, argv[2], &secpix) != TCL_OK || Tcl_GetDouble(interp_, argv[3], &xrefpix) != TCL_OK || Tcl_GetDouble(interp_, argv[4], &yrefpix) != TCL_OK || Tcl_GetInt(interp_, argv[5], &nxpix) != TCL_OK || Tcl_GetInt(interp_, argv[6], &nypix) != TCL_OK || Tcl_GetDouble(interp_, argv[7], &rotate) != TCL_OK || Tcl_GetDouble(interp_, argv[9], &epoch) != TCL_OK) return TCL_ERROR; proj = argv[10]; return wcs.set(ra, dec, secpix, xrefpix, yrefpix, nxpix, nypix, rotate, int(equinox), epoch, proj); } return error("wrong number of arguments for wcsset subcommand"); } /* * wcsshift subcommand * * usage: * $image wcsshift $ra $dec $coorsys * * This command resets the center of the WCS structure. * * Args: * ra = New center right ascension in degrees * dec = New center declination in degrees * equinox = (must be 2000 or 1950) * */ int RtdImage::wcsshiftCmd(int argc, char* argv[]) { if (!isWcs()) return TCL_OK; double ra, dec, equinox; if (Tcl_GetDouble(interp_, argv[0], &ra) != TCL_OK || Tcl_GetDouble(interp_, argv[1], &dec) != TCL_OK || Tcl_GetDouble(interp_, argv[2], &equinox) != TCL_OK) return TCL_ERROR; return image_->wcs().shift(ra, dec, equinox); } /* * implement the "wcswidth" image command to return the world * coordinates width of the image * * usage: wcswidth * * The return value in Tcl is the width in arcmin or an empty * string if WCS is not supported. */ int RtdImage::wcswidthCmd(int argc, char* argv[]) { if (!isWcs()) return TCL_OK; return set_result(image_->wcs().width()); } /* * Implement the "width" subcommand - returns the * unscaled width of the current image. */ int RtdImage::widthCmd(int argc, char* argv[]) { if (!image_) return set_result(0); return set_result(image_->width()); } /* * zoom subcommand: * usage: * zoom start * zoom stop * * zoom slow * zoom fast * * "$image zoom slow" can be used to slow down the zoom window * updates so they don't drag down performance, otherwise zoom * window updates are forced to be displayed immediately for better * feedback (zoom fast). */ int RtdImage::zoomCmd(int argc, char* argv[]) { int status = TCL_OK; if (strcmp(argv[0], "start") == 0) { // zoom start subcommand if (argc != 3) return error("wrong # of args: should be \"pathName zoom start win factor\""); int zoomFactor; if (Tcl_GetInt(interp_, argv[2], &zoomFactor) != TCL_OK) return TCL_ERROR; if (zoomFactor < 1 || zoomFactor > 160) return error("zoomFactor should be between 1 and 160"); Tk_Window zoomWin = Tk_NameToWindow(interp_, argv[1], tkwin_); if (zoomWin == NULL) return TCL_ERROR; int width = Tk_Width(zoomWin); int height = Tk_Height(zoomWin); // round off size to be a multiple of the zoom factor width += (zoomFactor - width % zoomFactor); height += (zoomFactor - height % zoomFactor); if (zoomer_) delete zoomer_; zoomer_ = new ImageZoom(zoomWin, gc_, width, height, zoomFactor, usingXShm_, verbose()); status = zoomer_->status(); } else if (strcmp(argv[0], "stop") == 0) { // zoom unset subcommand delete zoomer_; zoomer_ = NULL; } else if (strcmp(argv[0], "slow") == 0) { // zoom slow subcommand zoomSpeed_ = -1; } else if (strcmp(argv[0], "fast") == 0) { // zoom fast subcommand zoomSpeed_ = 1; } else { return error("invalid image zoom subcommand: should be \"start\" or \"stop\""); } // tell the other views to use the zoom window too for(int i = 0; i < MAX_VIEWS; i++) { if (view_[i]) { view_[i]->zoomer_ = zoomer_; view_[i]->zoomSpeed_ = zoomSpeed_; } } return TCL_OK; } /* * zoomview subcommand: alternative zoom window, using rtdimage view, so that * zoom is always accurate, even when image is shrunk. * * usage: * zoomview start ?count? * zoomview stop ?count? * zoom slow * zoom fast * * where view is the name of a second rtdimage. * * start - starts zooming using the given zoom factor magnification. * If 4 && Tcl_GetInt(interp_, argv[4], &count) != TCL_OK) return TCL_ERROR; if (zoomFactor < 1 || zoomFactor > 160) return error("zoomFactor should be between 1 and 160"); // allow an optional second zoom view RtdImage*& view = (count == 1) ? zoomView_ : zoomView2_; view = getView(argv[1]); if (view == NULL) return TCL_ERROR; view->propagateScale_ = propagateScale; view->zoomFactor_ = zoomFactor; if (updateViews(2) != TCL_OK) return TCL_ERROR; } else if (strcmp(argv[0], "stop") == 0) { // zoom unset subcommand int count = 1; if (argc > 1 && Tcl_GetInt(interp_, argv[1], &count) != TCL_OK) return TCL_ERROR; RtdImage*& view = (count == 1) ? zoomView_ : zoomView2_; // Reset zoomfactor for reference counted copies. if ( view != NULL ) { view->zoomFactor_ = 1; } view = NULL; } else if (strcmp(argv[0], "slow") == 0) { // zoom slow subcommand zoomSpeed_ = -1; } else if (strcmp(argv[0], "fast") == 0) { // zoom fast subcommand zoomSpeed_ = 1; } else { return error("invalid image zoomview subcommand: should be \"start\", \"stop\", ..."); } // tell the other views to use the zoom window too // note: the check for displaymode() != 0 is to keep the pan window // from using the zoom window, which can be very slow on huge images. for(int i = 0; i < MAX_VIEWS; i++) { if (view_[i] && view_[i]->displaymode() != 0) { view_[i]->zoomView_ = zoomView_; view_[i]->zoomView2_ = zoomView2_; view_[i]->zoomSpeed_ = zoomSpeed_; } } if (zoomView_) { zoomView_->zoomView_ = NULL; zoomView_->zoomView2_ = NULL; } if (zoomView2_) { zoomView2_->zoomView_ = NULL; zoomView2_->zoomView2_ = NULL; } return TCL_OK; } skycat-3.1.2-starlink-1b/rtd/generic/RtdCmds.icc000066400000000000000000000056261215713201500213730ustar00rootroot00000000000000// -*-c++-*- #ifndef _RtdCmds_h_ #define _RtdCmds_h_ /* * E.S.O. - VLT project * "@(#) $Id: RtdCmds.icc,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * RtdCmds.h - definitions for the RtdImage subcommand methods * * who when what * -------------- -------- ---------------------------------------- * pbiereic 01/03/01 Created */ public: int alloccolorsCmd (int argc, char* argv[]); int autocutCmd (int argc, char* argv[]); int biasimageCmd (int argc, char* argv[]); int bitpixCmd (int argc, char* argv[]); int bltgraphCmd (int argc, char* argv[]); int cameraCmd (int argc, char* argv[]); int clearCmd (int argc, char* argv[]); int cmapCmd (int argc, char* argv[]); int colorrampCmd (int argc, char* argv[]); int colorscaleCmd (int argc, char* argv[]); int convertCmd (int argc, char* argv[]); int cutCmd (int argc, char* argv[]); int dispheightCmd (int argc, char* argv[]); int dispwidthCmd (int argc, char* argv[]); int dumpCmd (int argc, char* argv[]); int fitsCmd (int argc, char* argv[]); int flipCmd (int argc, char* argv[]); int frameidCmd (int argc, char* argv[]); int freqCmd (int argc, char* argv[]); int getCmd (int argc, char* argv[]); int getvalsCmd (int argc, char* argv[]); int graphdistCmd (int argc, char* argv[]); int hduCmd (int argc, char* argv[]); int heightCmd (int argc, char* argv[]); int infoCmd (int argc, char* argv[]); int isclearCmd (int argc, char* argv[]); int ittCmd (int argc, char* argv[]); int maxCmd (int argc, char* argv[]); int maxFreqCmd (int argc, char* argv[]); int mbandCmd (int argc, char* argv[]); int minCmd (int argc, char* argv[]); int mmapCmd (int argc, char* argv[]); int motioneventCmd (int argc, char* argv[]); int objectCmd (int argc, char* argv[]); int panCmd (int argc, char* argv[]); int perfTestCmd (int argc, char* argv[]); int pixtabCmd (int argc, char* argv[]); int previewCmd (int argc, char* argv[]); int radecboxCmd (int argc, char* argv[]); int remoteCmd (int argc, char* argv[]); int remoteTclCmd (int argc, char* argv[]); int rotateCmd (int argc, char* argv[]); int scaleCmd (int argc, char* argv[]); int shmCmd (int argc, char* argv[]); int spectrumCmd (int argc, char* argv[]); int statisticsCmd (int argc, char* argv[]); int typeCmd (int argc, char* argv[]); int updateCmd (int argc, char* argv[]); int viewCmd (int argc, char* argv[]); int warpCmd (int argc, char* argv[]); int wcssetCmd (int argc, char* argv[]); int wcsshiftCmd (int argc, char* argv[]); int wcsdeltsetCmd (int argc, char* argv[]); int wcscenterCmd (int argc, char* argv[]); int wcsdistCmd (int argc, char* argv[]); int wcsequinoxCmd (int argc, char* argv[]); int wcsheightCmd (int argc, char* argv[]); int wcsradiusCmd (int argc, char* argv[]); int wcswidthCmd (int argc, char* argv[]); int widthCmd (int argc, char* argv[]); int zoomCmd (int argc, char* argv[]); int zoomviewCmd (int argc, char* argv[]); #endif /* _RtdCmds_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/RtdCoords.C000066400000000000000000000461221215713201500213560ustar00rootroot00000000000000/******************************************************************************* * E.S.O. - VLT project * * "@(#) $Id: RtdCoords.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * pbiereic 01/03/01 created (copied from RtdImage.C) */ /************************************************************************ * NAME * * RtdCoords.C - methods for Rtdimage coordinate conversion * * SYNOPSIS * * * DESCRIPTION * * This file contains all RtdImage member functions needed for * Rtdimage coordinate conversion * * FILES * * ENVIRONMENT * * CAUTIONS * * SEE ALSO * RtdImage(3), RTD documentation * * BUGS * *------------------------------------------------------------------------ */ static const char *rcsId="@(#) $Id: RtdCoords.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include "RtdImage.h" /* * Return the equinox (or coordinate system) portion of the given * coordinate type string. The input arg is of the form * "wcs 2000" or "deg B1950", for example. The return value is the part * after "wcs " or "deg ", and defaults to "2000". */ static const char* getEquinoxStr(const char* coordType) { if (coordType && strlen(coordType) > 4 && (strncmp(coordType, "deg ", 4) == 0 || strncmp(coordType, "wcs ", 4) == 0)) { return coordType+4; } return "2000"; } /* * return the enum CoordinateType value given the string name */ RtdImage::CoordinateType RtdImage::getCoordinateType(const char* s) { switch (*s) { case 'i': return CT_IMAGE; case 's': return CT_SCREEN; case 'w': return CT_WCS; case 'd': return CT_DEG; case 'c': int n = strlen(s); if (strncmp(s, "canvas", n) == 0) return CT_CANVAS; if (strncmp(s, "chip", n) == 0) return CT_CHIP; } error("unknown coord type: ", s); return CT_NONE; } /* * This method converts between different coordinate representations * where the coordinates are passed in string form. * * If dist_flag is non-zero, the coords are treated as a distance, * otherwise as a point. * * inx_buf and iny_buf hold the input coords (or distance) in the given * input coordinate system. If outx_buf and outy_buf are not NULL, they * hold the string form of the resulting coordinates in the target (out) * coordinate system. The decimal result values are written to "x" and * "y". * * The return value is the Tcl status. * * The available coordinate systems are: * * canvas - canvas coordinates (canvas scroll area) * screen - canvas window coords (visible area) * image - basic image pixel coords (at mag 1, no transformations) * chip - detector chip coordinates * wcs - world coordinates in H:M:S * deg - world coordinates in degrees * * The world coordinate types: "wcs" and "deg" may also include the equinox, * for example: "wcs 1950" or "deg 2000". The default equinox is 2000. * * Note: the coordinate types may be abbrieviated. */ int RtdImage::convertCoordsStr(int dist_flag, const char* inx_buf, const char* iny_buf, char* outx_buf, char* outy_buf, double& x, double& y, const char* in_type, const char* out_type) { char in = *in_type, out = *out_type; if (outx_buf) outx_buf[0] = '\0'; if (outy_buf) outy_buf[0] = '\0'; // get x and y as doubles if (in == 'w') { // convert H:M:S to degrees WorldCoords wcs(inx_buf, iny_buf); if (wcs.status() != TCL_OK) return TCL_ERROR; x = wcs.ra_deg(); y = wcs.dec_deg(); } else { if (Tcl_GetDouble(interp_, (char*)inx_buf, &x) != TCL_OK || Tcl_GetDouble(interp_, (char*)iny_buf, &y) != TCL_OK) { return TCL_ERROR; } } if (convertCoords(dist_flag, x, y, in_type, out_type) != TCL_OK) return TCL_ERROR; // format world coords in h:m:s if needed if (out == 'w' && outx_buf && outy_buf) { // Note: don't need equinox here since we are only formatting the coords WorldCoords wcs(x, y); wcs.print(outx_buf, outy_buf); } else { if (outx_buf) sprintf(outx_buf, "%.17g", x); if (outy_buf) sprintf(outy_buf, "%.17g", y); } return TCL_OK; } /* * NOTE: This method should not be called. It is only for backward * compatibility. * * Convert inx,iny in the given coord system to outx,outy in the given * output coord system. The coord types here are single char * abbrieviations: * * c = canvas coords * i = image coords * s = screen coords * w = world coords (in the equinox of the image) * d = world coords in degrees (in the equinox of the image) * * For backward compatibility, this method just calls the more general * version, which checks if the equinox needs to be changed. */ int RtdImage::convertCoords(int dist_flag, double& x, double& y, char in_type, char out_type) { char in[2], out[2]; in[0] = in_type; in[1] = '\0'; out[0] = out_type; out[1] = '\0'; return convertCoords(dist_flag, x, y, in, out); } /* * Convert inx,iny in the given coord system to outx,outy in the given * output coord system. The coord types are the same as for * convertCoordsStr(): * * canvas - canvas coordinates (canvas scroll area) * screen - canvas window coords (visible area) * image - basic image pixel coords (at mag 1, no transformations) * chip - detector chip or CCD coordinates * wcs - world coordinates in H:M:S * deg - world coordinates in degrees * * The world coordinate types: "wcs" and "deg" may also include the equinox, * for example: "wcs 1950" or "deg 2000". The default equinox is 2000. * * To convert coordinates we have to take some or all of the following * into account: * * 1. Transformations: rotate, scale, flipX,Y * These handled by the ImageData methods doTrans() and * undoTrans(). * * 2. Scrolling offsets in canvas * member vars: canvasX_ and canvasY * * 3. Origin of image in image coords * member vars: frameX_, frameY_ * * 4. Image coordinates at origin: * member vars: xOffset_, yOffset_ * * For "chip" coordinates, special fields in the real-time image events, * or for files, the FITS keywords: HIERARCH ESO DET WIN1 STRX and * STRY indicate the chip origin. If this information is not available, * then chip coordinates are the same as image coordinates. */ int RtdImage::convertCoords(int dist_flag, double& x, double& y, const char* in_type, const char* out_type) { CoordinateType in = getCoordinateType(in_type), out = getCoordinateType(out_type); if (in == CT_NONE || out == CT_NONE) return TCL_ERROR; if (in == out) return TCL_OK; char* msg = (char *)"unknown coordinate type"; switch(in) { case CT_CANVAS: // input is canvas coords switch(out) { case CT_SCREEN: // convert canvas to screen coords return canvasToScreenCoords(x, y, dist_flag); case CT_IMAGE: // convert canvas to image coords return canvasToImageCoords(x, y, dist_flag); case CT_CHIP: // convert canvas to chip coords return canvasToChipCoords(x, y, dist_flag); case CT_WCS: // convert canvas to world coords case CT_DEG: if (canvasToWorldCoords(x, y, dist_flag) == TCL_OK) { changeEquinox(dist_flag, x, y, image_->wcs().equinoxStr(), getEquinoxStr(out_type)); return TCL_OK; } return TCL_ERROR; default: return error(msg); } break; case CT_SCREEN: // input is screen coords switch(out) { case CT_CANVAS: // convert screen to canvas coords return screenToCanvasCoords(x, y, dist_flag); case CT_IMAGE: // convert screen to image coords return screenToImageCoords(x, y, dist_flag); case CT_CHIP: // convert screen to chip coords return screenToChipCoords(x, y, dist_flag); case CT_WCS: // convert screen to world coords case CT_DEG: if (screenToWorldCoords(x, y, dist_flag) == TCL_OK) { changeEquinox(dist_flag, x, y, image_->wcs().equinoxStr(), getEquinoxStr(out_type)); return TCL_OK; } return TCL_ERROR; default: return error(msg); } break; case CT_IMAGE: // input is image coords switch(out) { case CT_CANVAS: // convert image to canvas coords return imageToCanvasCoords(x, y, dist_flag); case CT_SCREEN: // convert image to screen coords return imageToScreenCoords(x, y, dist_flag); case CT_CHIP: // convert image to chip coords return imageToChipCoords(x, y, dist_flag); case CT_WCS: // convert image to world coords case CT_DEG: if (imageToWorldCoords(x, y, dist_flag) == TCL_OK) { changeEquinox(dist_flag, x, y, image_->wcs().equinoxStr(), getEquinoxStr(out_type)); return TCL_OK; } return TCL_ERROR; default: return error(msg); } break; case CT_CHIP: // input is chip coords switch(out) { case CT_CANVAS: // convert chip to canvas coords return chipToCanvasCoords(x, y, dist_flag); case CT_SCREEN: // convert chip to screen coords return chipToScreenCoords(x, y, dist_flag); case CT_IMAGE: // convert chip to image coords return chipToImageCoords(x, y, dist_flag); case CT_WCS: // convert chip to world coords case CT_DEG: if (chipToWorldCoords(x, y, dist_flag) == TCL_OK) { changeEquinox(dist_flag, x, y, image_->wcs().equinoxStr(), getEquinoxStr(out_type)); return TCL_OK; } return TCL_ERROR; default: return error(msg); } break; case CT_DEG: // input is world coords case CT_WCS: // convert to image equinox changeEquinox(dist_flag, x, y, getEquinoxStr(in_type), image_->wcs().equinoxStr()); switch(out) { case CT_CANVAS: // convert world to canvas coords return worldToCanvasCoords(x, y, dist_flag); case CT_SCREEN: // convert world to screen coords return worldToScreenCoords(x, y, dist_flag); case CT_IMAGE: // convert world to image coords return worldToImageCoords(x, y, dist_flag); case CT_CHIP: // convert world to chip coords return worldToChipCoords(x, y, dist_flag); case CT_WCS: // no conversion case CT_DEG: changeEquinox(dist_flag, x, y, image_->wcs().equinoxStr(), getEquinoxStr(out_type)); return TCL_OK; default: return error(msg); } break; } return TCL_OK; } /* * Utility method to change the equinox of ra and dec * from in_quinox to out_equinox, if dist_flag is 0. * Note that the equinox values may be a number, such as * 2000 or 1950, or a system name, such as "galactic", "ecliptic", * "J2000", "B1950". */ void RtdImage::changeEquinox(int dist_flag, double& ra, double& dec, const char* in_equinox, const char* out_equinox) { if (!dist_flag) { if (in_equinox && out_equinox && !strcmp(in_equinox, out_equinox) == 0) { WorldCoords wcs(ra, dec, in_equinox); wcs.get(ra, dec, out_equinox); } } } /* * convert canvas to screen coords */ int RtdImage::canvasToScreenCoords(double& x, double& y, int dist_flag) { if (!dist_flag) { x += canvasX_; y += canvasY_; } return TCL_OK; } /* * convert canvas to image coords * * Note: there are 2 cases to handle here: * 1. a frame displaying an image at an offset with the origin at 0,0 * 2. same as above, but with the origin at xOffset,yOffset * * In the normal case, the offset and origin are both zero... */ int RtdImage::canvasToImageCoords(double& x, double& y, int dist_flag) { if (!dist_flag) { double dx = xOffset_, dy = yOffset_; doTrans(dx, dy, 1); if (frameX_ == 0) x += dx; if (frameY_ == 0) y += dy; } undoTrans(x, y, dist_flag); return TCL_OK; } /* * convert canvas to world coords */ int RtdImage::canvasToWorldCoords(double& x, double& y, int dist_flag) { return canvasToImageCoords(x, y, dist_flag) || imageToWorldCoords(x, y, dist_flag); } int RtdImage::canvasToChipCoords(double& x, double& y, int dist_flag) { return canvasToImageCoords(x, y, dist_flag) || imageToChipCoords(x, y, dist_flag); } int RtdImage::chipToImageCoords(double& x, double& y, int dist_flag) { if (! dist_flag) image_->chipToImageCoords(x, y); return TCL_OK; } int RtdImage::chipToCanvasCoords(double& x, double& y, int dist_flag) { return chipToImageCoords(x, y, dist_flag) || imageToCanvasCoords(x, y, dist_flag); } int RtdImage::chipToScreenCoords(double& x, double& y, int dist_flag) { return chipToImageCoords(x, y, dist_flag) || imageToScreenCoords(x, y, dist_flag); } int RtdImage::chipToWorldCoords(double& x, double& y, int dist_flag) { return chipToImageCoords(x, y, dist_flag) || imageToWorldCoords(x, y, dist_flag); } /* * convert image to canvas coords */ int RtdImage::imageToCanvasCoords(double& x, double& y, int dist_flag) { doTrans(x, y, dist_flag); if (!dist_flag) { double dx = xOffset_, dy = yOffset_; doTrans(dx, dy, 1); if (frameX_ == 0) x -= dx; if (frameY_ == 0) y -= dy; } return TCL_OK; } /* * convert image to screen coords */ int RtdImage::imageToScreenCoords(double& x, double& y, int dist_flag) { return imageToCanvasCoords(x, y, dist_flag) || canvasToScreenCoords(x, y, dist_flag); } /* * convert main image coordinates to raw image array coordinates. * * The resulting coordinates can be used to index into the raw image * array, which might begin at a logical offset other than 0,0. This is * only neeeded for rapid frames, since these display coordinates for the * main image, but have smaller data arrays that start at some x,y offset. */ int RtdImage::imageToRawImageCoords(double& x, double& y) { if (rapidFrame_) { // only rapid frames need this... // get offset for rapid frame in main image: // (only one of rapidX_,frameX_ etc. will be non-zero...) double dx = (rapidX_ + frameX_), dy = (rapidY_ + frameY_); if (image_->flipY()) y -= dy; else y -= viewMaster_->image_->height() - image_->height() - dy; if (image_->flipX()) x -= viewMaster_->image_->width() - image_->width() - dx; else x -= dx; } return 0; } /* * convert image to world coords in the equinox of the image */ int RtdImage::imageToWorldCoords(double& x, double& y, int dist_flag) { double ra, dec; if (dist_flag) { if (image_->wcs().pix2wcsDist(x, y, ra, dec) != 0) return TCL_ERROR; } else { if (image_->wcs().pix2wcs(x, y, ra, dec) != 0) return TCL_ERROR; } x = ra; y = dec; return TCL_OK; } int RtdImage::imageToChipCoords(double& x, double& y, int dist_flag) { if (! dist_flag) image_->imageToChipCoords(x, y); return TCL_OK; } /* * convert screen to Ximage coords (index in X Image) */ int RtdImage::screenToXImageCoords(double& x, double& y) { if (displaymode() == 0) { x -= canvasX_; y -= canvasY_; } else { // if the xImage smaller than the window, add the neg. scroll offset double fx = frameX_, fy = frameY_; doTrans(fx, fy, 1); if (canvasX_ > 0) x += -canvasX_ - fx; else if (fx) x -= (fx + canvasX_) ; if (canvasY_ > 0) y += -canvasY_ - fy; else if (fy) y -= (fy + canvasY_); } return TCL_OK; } int RtdImage::screenToChipCoords(double& x, double& y, int dist_flag) { return screenToImageCoords(x, y, dist_flag) || imageToChipCoords(x, y, dist_flag); } /* * convert screen to canvas coords */ int RtdImage::screenToCanvasCoords(double& x, double& y, int dist_flag) { if (!dist_flag) { x -= canvasX_; y -= canvasY_; } return TCL_OK; } /* * convert screen to image coords */ int RtdImage::screenToImageCoords(double& x, double& y, int dist_flag) { return screenToCanvasCoords(x, y, dist_flag) || canvasToImageCoords(x, y, dist_flag); } /* * convert screen to world coords */ int RtdImage::screenToWorldCoords(double& x, double& y, int dist_flag) { return screenToImageCoords(x, y, dist_flag) || imageToWorldCoords(x, y, dist_flag); } /* * convert world to canvas coords */ int RtdImage::worldToCanvasCoords(double& x, double& y, int dist_flag) { return worldToImageCoords(x, y, dist_flag) || imageToCanvasCoords(x, y, dist_flag); } /* * convert world to screen coords */ int RtdImage::worldToScreenCoords(double& x, double& y, int dist_flag) { return worldToCanvasCoords(x, y, dist_flag) || canvasToScreenCoords(x, y, dist_flag); } /* * convert world to image coords */ int RtdImage::worldToImageCoords(double& x, double& y, int dist_flag) { double ra = x, dec = y; if (dist_flag) { if (image_->wcs().wcs2pixDist(ra, dec, x, y) != 0) return TCL_ERROR; } else if (image_->wcs().wcs2pix(ra, dec, x, y) != 0) return TCL_ERROR; return TCL_OK; } int RtdImage::worldToChipCoords(double& x, double& y, int dist_flag) { return worldToImageCoords(x, y, dist_flag) || imageToChipCoords(x, y, dist_flag); } /* * convert Ximage to image coords */ int RtdImage::xImageToImageCoords(double& x, double& y, int dist_flag) { double dx = xOffset_, dy = yOffset_; doTrans(dx, dy, 1); x += dx; y += dy; undoTrans(x, y, dist_flag); return TCL_OK; } /* * convert x,y image coords to a distance */ void RtdImage::coordsToDist(double& x, double& y) { // for image frame in same window, use master coords if (viewMaster_) { if (viewMaster_->tkwin_ == tkwin_) viewMaster_->coordsToDist(x, y); else image_->coordsToDist(x, y, viewMaster_->image_->width(), viewMaster_->image_->height()); } else { image_->coordsToDist(x, y); } } /* * convert x,y distance to coordinates */ void RtdImage::distToCoords(double& x, double& y) { // for image frame in same window, use master coords if (viewMaster_) { if (viewMaster_->tkwin_ == tkwin_) viewMaster_->distToCoords(x, y); else image_->distToCoords(x, y, viewMaster_->image_->width(), viewMaster_->image_->height()); } else { image_->distToCoords(x, y); } } /* * apply the current transformations to the given coordinates * If distFlag is 1, x and y are treated as a distance, otherwise * they are treated as a point and flipped as needed. */ void RtdImage::doTrans(double& x, double& y, int distFlag) { if (distFlag) { image_->doTrans(x, y, distFlag); } else if (viewMaster_) { if (viewMaster_->tkwin_ == tkwin_) { viewMaster_->doTrans(x, y, distFlag); } else { image_->doTrans(x, y, distFlag, rapidX_, rapidY_, viewMaster_->image_->width(), viewMaster_->image_->height()); } } else { image_->doTrans(x, y, distFlag, rapidX_, rapidY_); } } /* * undo the current transformations on the given coordinates. * If distFlag is 1, x and y are treated as a distance, otherwise * they are treated as a point and flipped as needed. */ void RtdImage::undoTrans(double& x, double& y, int distFlag) { if (distFlag) { image_->undoTrans(x, y, distFlag); } else if (viewMaster_) { if (viewMaster_->tkwin_ == tkwin_) { viewMaster_->undoTrans(x, y, distFlag); } else { image_->undoTrans(x, y, distFlag, rapidX_, rapidY_, viewMaster_->image_->width(), viewMaster_->image_->height()); } } else { image_->undoTrans(x, y, distFlag, rapidX_, rapidY_); } } skycat-3.1.2-starlink-1b/rtd/generic/RtdCoords.icc000066400000000000000000000064721215713201500217360ustar00rootroot00000000000000// -*-c++-*- #ifndef _RtdCoords_h_ #define _RtdCoords_h_ /* * E.S.O. - VLT project * "@(#) $Id: RtdCoords.icc,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * RtdCoords.h - definitions for the Rtdimage coordinate conversion methods * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * pbiereic 01/03/01 created (copied from RtdImage.h) */ public: // coordinate conversion types enum CoordinateType { CT_NONE = 0, CT_IMAGE = 'i', CT_CANVAS = 'c', CT_SCREEN = 's', CT_WCS = 'w', CT_DEG = 'd', CT_CHIP = 'C' }; // return the enum CoordinateType value given the string name CoordinateType getCoordinateType(const char* s); // convert coords from string form int convertCoordsStr(int dist_flag, const char* inx_buf, const char* iny_buf, char* outx_buf, char* outy_buf, double& x, double& y, const char* in_type, const char* out_type); // convert coords from doubles int convertCoords(int dist_flag, double& x, double& y, const char* in_type, const char* out_type); // convert coords as doubles (for WCS, assumes equinox of image, // coord type only specifies first letter and no equinox). int convertCoords(int dist_flag, double& x, double& y, char in_type, char out_type); // Utility method to change the equinox of ra and dec if dist_flag is 0 void changeEquinox(int dist_flag, double& ra, double& dec, const char* in_equinox, const char* out_equinox); // utility methods to convert between different coordinate systems int canvasToChipCoords (double& x, double& y, int dist_flag); int canvasToImageCoords (double& x, double& y, int dist_flag); int canvasToScreenCoords (double& x, double& y, int dist_flag); int canvasToWorldCoords (double& x, double& y, int dist_flag); int chipToCanvasCoords (double& x, double& y, int dist_flag); int chipToImageCoords (double& x, double& y, int dist_flag); int chipToScreenCoords (double& x, double& y, int dist_flag); int chipToWorldCoords (double& x, double& y, int dist_flag); int imageToCanvasCoords (double& x, double& y, int dist_flag); int imageToChipCoords (double& x, double& y, int dist_flag); int imageToScreenCoords (double& x, double& y, int dist_flag); int imageToWorldCoords (double& x, double& y, int dist_flag); int screenToCanvasCoords (double& x, double& y, int dist_flag); int screenToChipCoords (double& x, double& y, int dist_flag); int screenToImageCoords (double& x, double& y, int dist_flag); int screenToWorldCoords (double& x, double& y, int dist_flag); int worldToCanvasCoords (double& x, double& y, int dist_flag); int worldToChipCoords (double& x, double& y, int dist_flag); int worldToImageCoords (double& x, double& y, int dist_flag); int worldToScreenCoords (double& x, double& y, int dist_flag); // -- short cuts -- protected: // these coordinate conversion methods are only needed internally int screenToXImageCoords (double& x, double& y); int xImageToImageCoords (double& x, double& y, int dist_flag); int imageToRawImageCoords (double& x, double& y); void coordsToDist (double& x, double& y); void distToCoords (double& x, double& y); void doTrans (double& x, double& y, int distFlag = 0); void undoTrans (double& x, double& y, int distFlag = 0); #endif /* _RtdCoords_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/RtdHDU.C000066400000000000000000000502351215713201500205450ustar00rootroot00000000000000/******************************************************************************* * E.S.O. - VLT project * * "@(#) $Id: RtdHDU.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * who when what * -------- -------- ---------------------------------------------- * A. Brighton 05/10/95 Created * pbiereic 01/03/01 copied from RtdImage.C * pbiereic 14/08/01 added "hdu fits" subcommand * P. W. Draper 20/05/07 pick out special columns in getHDU entry * and examine the properties so that we make * sure there is an id column (when the positional * columns take up column 0) and that any sky * coordinates are convered from radians to degrees. * also delete the fits copy in hduCmdSet when * a table is accessed, stops a leak. * P.W. Draper 16/03/09 Transfer comments from FITS extension to the * local table in getHDU (these can be useful for * provenance and may contain additional meta-data). */ /************************************************************************ * NAME * * RtdHDU.C - methods for Rtdimage subcommand hduCmd() * * SYNOPSIS * * * DESCRIPTION * * This file contains all RtdImage member functions needed for * the Rtdimage subcommand hduCmd() * * FILES * * ENVIRONMENT * * CAUTIONS * * SEE ALSO * RtdImage(3), RTD documentation * * BUGS * *------------------------------------------------------------------------ */ static const char *rcsId="@(#) $Id: RtdHDU.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "RtdImage.h" // Trig conversion factors. static const double pi_ = 3.14159265358979323846; static const double r2d_ = 57.295779513082323; // (180.0/pi_) /* * Implement the hdu headings subcommand: * * hdu headings ?$number? * * See comments for hduCmd() for details. */ int RtdImage::hduCmdHeadings(int argc, char** argv, FitsIO* fits) { int hdu = fits->getHDUNum(); int saved_hdu = hdu; int numHDUs = fits->getNumHDUs(); // check for the optional hdu arg, otherwise use current if (argc >= 2 && sscanf(argv[1], "%d", &hdu) == 1) { if (hdu != saved_hdu) { if (hdu < 1 || hdu > numHDUs) return fmt_error("HDU number %d out of range (max %d)", hdu, numHDUs); // switch to the given HDU, but restore the original before returning if (fits->setHDU(hdu) != 0) return TCL_ERROR; } } // get the info and catch any errors int status = getHDUHeadings(fits); // restore the original HDU before returning if (hdu != saved_hdu && fits->setHDU(saved_hdu) != 0) status = TCL_ERROR; return status; } /* * Implement the hdu fits subcommand: * * hdu fits ?$number? * * See comments for hduCmd() for details. */ int RtdImage::hduCmdFits(int argc, char** argv, FitsIO* fits) { int hdu = fits->getHDUNum(); int saved_hdu = hdu; int numHDUs = fits->getNumHDUs(); int status = TCL_OK; // check for the optional hdu arg, otherwise use current if (argc >= 2 && sscanf(argv[1], "%d", &hdu) == 1) { if (hdu != saved_hdu) { if (hdu < 1 || hdu > numHDUs) return fmt_error("HDU number %d out of range (max %d)", hdu, numHDUs); // switch to the given HDU, but restore the original before returning if (fits->setHDU(hdu) != 0) return TCL_ERROR; } } // get the FITS header ostringstream os; fits->getFitsHeader(os); set_result(os.str().c_str()); // restore the original HDU before returning if (hdu != saved_hdu && fits->setHDU(saved_hdu) != 0) status = TCL_ERROR; return status; } /* * This method is used to implement the "hdu headings" subcommand. * It returns the table headings of the current FITS table as a * Tcl list. An error is returned if the current HDU is not a FITS * table. */ int RtdImage::getHDUHeadings(FitsIO* fits) { // return a list of table headings for the current FITS table char* type = (char*)fits->getHDUType(); if (!type || *type == 'i') return error("HDU is not a FITS table"); long nrows = 0; int ncols = 0; if (fits->getTableDims(nrows, ncols) != 0) return TCL_ERROR; reset_result(); for(int col = 1; col <= ncols; col++) { char* s = fits->getTableHead(col); if (!s) return TCL_ERROR; append_element(s); } return TCL_OK; } /* * Implement the "hdu type" subcommand: * * hdu type ?$number? * * See comments for hduCmd() for details. */ int RtdImage::hduCmdType(int argc, char** argv, FitsIO* fits) { int hdu = fits->getHDUNum(); int saved_hdu = hdu; int numHDUs = fits->getNumHDUs(); // check for the optional hdu arg, otherwise use current if (argc >= 2 && sscanf(argv[1], "%d", &hdu) == 1) { if (hdu != saved_hdu) { if (hdu < 1) return fmt_error("HDU number %d out of range (min 1)", hdu); if (hdu > numHDUs) return fmt_error("HDU number %d out of range (max %d)", hdu, numHDUs); // switch to the given HDU, but restore the original before returning if (fits->setHDU(hdu) != 0) return TCL_ERROR; } } char* type = (char*)fits->getHDUType(); int status = TCL_OK; if (type) set_result(fits->getHDUType()); else status = TCL_ERROR; // restore the original HDU before returning if (hdu != saved_hdu && fits->setHDU(saved_hdu) != 0) status = TCL_ERROR; return status; } /* * Implement the hdu get subcommand: * * hdu get ?$number? ?$filename? ?$entry? * * See comments for hduCmd() for details. */ int RtdImage::hduCmdGet(int argc, char** argv, FitsIO* fits) { int hdu = fits->getHDUNum(); int saved_hdu = hdu; int numHDUs = fits->getNumHDUs(); // check for the optional hdu arg, otherwise use current if (argc >= 2 && sscanf(argv[1], "%d", &hdu) == 1) { argc--; argv++; if (hdu != saved_hdu) { if (hdu < 1 || hdu > numHDUs) return fmt_error("HDU number %d out of range (max %d)", hdu, numHDUs); // switch to the given HDU, but restore the original before returning if (fits->setHDU(hdu) != 0) return TCL_ERROR; } } // check for the filename arg char* filename = NULL; if (argc >= 2) filename = argv[1]; // check for the entry arg char* entry = NULL; if (argc >= 3) entry = argv[2]; // get the info and catch any errors int status = getHDU(fits, filename, entry); // restore the original HDU before returning if (hdu != saved_hdu && fits->setHDU(saved_hdu) != 0) status = TCL_ERROR; return status; } /* * This method implements the main body of the hdu get subcommand. * If filename arg is not NULL, the contents of the current HDU are * written to the file as a local catalog. Otherwise, the contents * of the current HDU are returned as a Tcl list or rows. If the * entry arg is not null and a filename was specified, it specifies * the catalog config entry for the file's header, in Tcl list format * {{key value} {key value} ...}. */ int RtdImage::getHDU(FitsIO* fits, const char* filename, const char* entry) { const char* type = fits->getHDUType(); if (!type || *type == 'i') return error("HDU is not a FITS table"); long nrows = 0; int ncols = 0; if (fits->getTableDims(nrows, ncols) != 0) return TCL_ERROR; if (filename == NULL) { // return the contents of the table as a tcl list of rows reset_result(); for(int row = 1; row <= nrows; row++) { append_result(" {"); for(int col = 1; col <= ncols; col++) { char* s = fits->getTableValue(row, col); if (!s) return TCL_ERROR; append_element(s); } append_result("}"); } return TCL_OK; } // Otherwise write the contents of the table to a local catalog file ofstream os(filename); if (! os) return sys_error("can't open file: ", filename); // output the catalog header os << "QueryResult\n\n"; // PWD: locate special columns and their conversion factors (to degrees // from radians). int idcol = -1; int racol = -1; double rascale = 1.0; int deccol = -1; double decscale = 1.0; // output the catalog config entry, if there is one if (entry != NULL) { os << "# Config entry\n"; int nkeys = 0; char** keys = NULL; const char *p; const char *t; char buf[20]; if (Tcl_SplitList(interp_, (char*)entry, &nkeys, &keys) != TCL_OK) return TCL_ERROR; for(int i = 0; i < nkeys; i++) { int n = 0; char** v = NULL; if (Tcl_SplitList(interp_, keys[i], &n, &v) != TCL_OK) { Tcl_Free((char *)keys); return TCL_ERROR; } if (n != 2) { Tcl_Free((char *)keys); Tcl_Free((char *)v); return fmt_error("Invalid catalog config entry: '%s': Expected {key value}", keys[i]); } // PWD: record ra_col, dec_col and id_col columns. p = v[0]; while ( p && *p && *p == ' ' ) p++; // Trim leading blanks. if ( strncasecmp( p, "ra_col", 6 ) == 0 ) { sscanf( v[1], "%d", &racol ); // If these are radians we need to convert to degrees. sprintf( buf, "TUNIT%d", racol + 1 ); t = fits->get( buf ); while ( t && *t && *t == ' ' ) t++; // Trim leading blanks. if ( t && strncasecmp( t, "radian", 6 ) == 0 ) { rascale = r2d_; } } else if ( strncasecmp( p, "dec_col", 7 ) == 0 ) { sscanf( v[1], "%d", &deccol ); // If these are radians we need to convert to degrees. sprintf( buf, "TUNIT%d", deccol + 1 ); t = fits->get( buf ); while ( t && *t && *t == ' ' ) t++; // Trim leading blanks. if ( t && strncasecmp( t, "radian", 6 ) == 0 ) { decscale = r2d_; } } else if ( strncasecmp( p, "id_col", 6 ) == 0 ) { sscanf( v[1], "%d", &idcol ); } os << v[0] << ": " << v[1] << endl; Tcl_Free((char *)v); } // No id_col, so we fake an index at the end. if ( idcol == -1 ) { os << "id_col: " << ncols << endl; } Tcl_Free((char *)keys); os << "# End config entry\n\n"; } // PWD: add any comment cards so that context is preserved. const char *c; while ( ( c = fits->getComment( "COMMENT*" ) ) != NULL ) { os << "#C" << c << endl; } // output the column headings, if id_col is undefined then create a fake // column at the end (to keep ra_col & dec_col at current settings, which // are written out, could also be x_col and y_col to keep happy). int col; for(col = 1; col <= ncols; col++) { char* s = fits->getTableHead(col); if (!s) return TCL_ERROR; os << s; if (col < ncols) os << '\t'; } if ( idcol == -1 && entry != NULL ) { os << '\t' << "ID"; } os << "\n---\n"; // heading separator (dashed line) // output the data for(long row = 1; row <= nrows; row++) { for(col = 1; col <= ncols; col++) { char* s; if ( col == ( racol + 1 ) ) { s = fits->getTableValue(row, col, rascale); } else if ( col == ( deccol + 1 ) ) { s = fits->getTableValue(row, col, decscale); } else { s = fits->getTableValue(row, col, 1.0); } if (!s) return TCL_ERROR; os << s; if (col < ncols) os << '\t'; } if ( idcol == -1 && entry != NULL ) { os << '\t' << row; } os << endl; } return TCL_OK; } /* * Implement the HDU create subcommand: * * hdu create $type $extname $headings $tform $data * * see comments for hduCmd() for details. */ int RtdImage::hduCmdCreate(int argc, char** argv, FitsIO* fits) { if (argc != 6) { return error("hdu create: wrong number of args"); } char* type = argv[1]; char* extname = argv[2]; char* headings = argv[3]; char* tform = argv[4]; char* data = argv[5]; // save the current HDU number and restore it later, since creating a // new table sets the HDU to the new table. int hdu = fits->getHDUNum(); int asciiFlag = (strncmp(type, "ascii", 5) == 0); // These arrays hold the Tcl list info for the list arguments. // The memory is allocated and must be deleted before returning. char** colHeadings = NULL; char** formats = NULL; char** dataRows = NULL; char** dataCols = NULL;; int status = TCL_OK; // dummy loop used only for error handling while (1) { // get the headings array and number of columns int numCols = 0; if (Tcl_SplitList(interp_, headings, &numCols, &colHeadings) != TCL_OK) { status = TCL_ERROR; break; } // get the column formats array int numFormats = 0; if (Tcl_SplitList(interp_, tform, &numFormats, &formats) != TCL_OK) { status = TCL_ERROR; break; } if (numFormats != numCols) { status = error("Wrong number of column formats"); break; } // get the table data array and number of rows int numRows = 0; if (Tcl_SplitList(interp_, data, &numRows, &dataRows) != TCL_OK) { status = TCL_ERROR; break; } // Create the FITS table if (fits->createTable(extname, numRows, numCols, (char**)colHeadings, (char**)formats, asciiFlag) != 0) { status = TCL_ERROR; break; } // insert the data (FITS rows and cols start at 1!) for(int row = 1; row <= numRows; row++) { int n; if (Tcl_SplitList(interp_, dataRows[row-1], &n, &dataCols) != TCL_OK) { status = TCL_ERROR; break; } if (n != numCols) { status = fmt_error("Wrong number of columns in row %d", row); break; } for(int col = 1; col <= numCols; col++) { if (fits->setTableValue(row, col, dataCols[col-1]) != 0) { status = TCL_ERROR; break; } } if (status != TCL_OK) break; if (dataCols) { Tcl_Free((char *)dataCols); dataCols = NULL; } } break; // once only } // Clean up and return the status if (colHeadings) Tcl_Free((char *)colHeadings); if (formats) Tcl_Free((char *)formats); if (dataRows) Tcl_Free((char *)dataRows); if (dataCols) Tcl_Free((char *)dataCols); // restore the original HDU fits->setHDU(hdu); return status; } /* * Implement the HDU delete subcommand: * * hdu delete $number * * see comments for hduCmd() for details. */ int RtdImage::hduCmdDelete(int argc, char** argv, FitsIO* fits) { int hdu; if (Tcl_GetInt(interp_, argv[1], &hdu) != TCL_OK) return TCL_ERROR; int n = fits->getNumHDUs(); if (hdu <= 1 || hdu > n) return fmt_error("HDU index %d out of range: must be > 1 and <= %d", hdu, n); if (fits->deleteHDU(hdu) != 0) return TCL_ERROR; return TCL_OK; } /* * Implement the hdu list subcommand: * * hdu list * * see comments for hduCmd() for details. */ int RtdImage::hduCmdList(int argc, char** argv, FitsIO* fits) { // return a list of HDUs int numHDUs = fits->getNumHDUs(); if (numHDUs <= 0) return TCL_OK; // empty return list // save current HDU, then loop through all HDUs to get info int curHDU = fits->getHDUNum(); ostringstream os; int status = 0; int count = 0; for (int i = 1; i <= numHDUs; i++) { if (fits->setHDU(i) != 0) { status++; break; } const char* type = fits->getHDUType(); if (!type) { status++; break; } // get these keyword values and default to "" char extName[80], naxis[32], naxis1[32], naxis2[32], naxis3[32]; char crpix1[32], crpix2[32]; fits->get("EXTNAME", extName, sizeof(extName)); fits->get("NAXIS", naxis, sizeof(naxis)); fits->get("NAXIS1", naxis1, sizeof(naxis1)); fits->get("NAXIS2", naxis2, sizeof(naxis2)); fits->get("NAXIS3", naxis3, sizeof(naxis3)); fits->get("CRPIX1", crpix1, sizeof(crpix1)); fits->get("CRPIX2", crpix2, sizeof(crpix2)); // Try avoiding long fractional strings if (strlen(crpix1) != 0 && strlen(crpix2) != 0) { double dcrpix1, dcrpix2; fits->get("CRPIX1", dcrpix1); fits->get("CRPIX2", dcrpix2); os << "{" << i << " " << type << " {" << extName << "}" << " {" << naxis << "}" << " {" << naxis1 << "}" << " {" << naxis2 << "}" << " {" << naxis3 << "}" << " {" << dcrpix1 << "}" << " {" << dcrpix2 << "}" << "} "; } else { os << "{" << i << " " << type << " {" << extName << "}" << " {" << naxis << "}" << " {" << naxis1 << "}" << " {" << naxis2 << "}" << " {" << naxis3 << "}" << " {" << crpix1 << "}" << " {" << crpix2 << "}" << "} "; } count++; } if (count) { if (status == TCL_OK) { set_result(os.str().c_str()); } fits->setHDU(curHDU); } return status; } /* * Implement the hdu set subcommand: * * hdu set $number * or: hdu $number * * see comments for hduCmd() for details. */ int RtdImage::hduCmdSet(int argc, char** argv, FitsIO* fits) { if (strcmp(argv[0], "set") == 0) { argc--; argv++; } if (argc != 1) return error("wrong number of args: expected HDU number"); int num = 0; if (Tcl_GetInt(interp_, argv[0], &num) != TCL_OK) return TCL_ERROR; // get a copy so we can change the HDU without changing the original fits = fits->copy(); if (fits->setHDU(num) != 0) { delete fits; return TCL_ERROR; } const char* hduType = fits->getHDUType(); if (!hduType) return TCL_ERROR; if (*hduType != 'i') { delete fits; // Otherwise just dropped. Note original // FitsIO now positioned ay new HDU anyway. return TCL_OK; // FITS table, not image: don't display } // save image transformation parameters to restore later ImageDataParams p; image_->saveParams(p); // delete old image delete image_; image_ = NULL; updateViews(); // Re-initialize the image from the given HDU ImageData* im = makeImage(fits); if (! im) return TCL_ERROR; image_ = im; // The WCS info will be different in this HDU fits->wcsinit(); // restore transformations image_->restoreParams(p, !autoSetCutLevels_); // update the display return initNewImage(); } /* * Implement the hdu display subcommand: * * hdu display ?$hduList? * * see comments for hduCmd() for details. */ int RtdImage::hduCmdDisplay(int argc, char** argv, FitsIO* fits) { int hduList[256]; int numHDUs = 0; if (!image_) return error("No image to display"); if (argc == 2) { // parse list of HDU indexes char** hdus = NULL; if (Tcl_SplitList(interp_, argv[0], &numHDUs, &hdus) != TCL_OK) return TCL_ERROR; if (numHDUs > sizeof(hduList)/sizeof(int)) return fmt_error("RtdImage::hduCmdDisplay: too many HDUs: %d (max 256)", numHDUs); if (numHDUs == 0) return error("No image HDUs were specified"); for(int i = 0; i < numHDUs; i++) { if (Tcl_GetInt(interp_, hdus[1], &hduList[i]) != TCL_OK) { Tcl_Free((char *)hdus); return TCL_ERROR; } } Tcl_Free((char *)hdus); } else { // use all image extensions, except the primary HDU (1) // Note that the primary HDU is 1. int n = fits->getNumHDUs(); int saved_hdu = fits->getHDUNum(); for(int i = 2; i <= n; i++) { if (fits->setHDU(i) != 0) { fits->setHDU(saved_hdu); return TCL_ERROR; // error } const char* type = fits->getHDUType(); if (type != NULL && *type == 'i') hduList[numHDUs++] = i; } fits->setHDU(saved_hdu); if (numHDUs == 0) return error("No image HDUs found"); } // get a (reference counted) copy of the image ImageIO imio = image_->image(); // used to save and restore image transformation parameters ImageDataParams p; image_->saveParams(p); // delete old image delete image_; image_ = NULL; updateViews(); // Create an image composed of all of the requested image extensions image_ = ImageData::makeCompoundImage(name(), imio, hduList, numHDUs, biasimage_->biasInfo(), verbose()); if (! image_) return TCL_ERROR; // restore transformations image_->restoreParams(p, !autoSetCutLevels_); return initNewImage(); } skycat-3.1.2-starlink-1b/rtd/generic/RtdHDU.icc000066400000000000000000000025471215713201500211240ustar00rootroot00000000000000// -*-c++-*- #ifndef _RtdHDU_h_ #define _RtdHDU_h_ /* * E.S.O. - VLT project * "@(#) $Id: RtdHDU.icc,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * RtdHDU.h - definitions methods for the Rtdimage subcommand hduCmd() * * who when what * -------------- -------- ---------------------------------------- * A. Brighton 05/10/95 Created in RtdImage.h * pbiereic 01/03/01 copied from RtdImage.h */ protected: // these are part of the implementation of the hdu subcommand (see hduCmd()) int hduCmdHeadings (int argc, char** argv, FitsIO* fits); int hduCmdGet (int argc, char** argv, FitsIO* fits); int hduCmdCreate (int argc, char** argv, FitsIO* fits); int hduCmdDelete (int argc, char** argv, FitsIO* fits); int hduCmdList (int argc, char** argv, FitsIO* fits); int hduCmdSet (int argc, char** argv, FitsIO* fits); int hduCmdType (int argc, char** argv, FitsIO* fits); int hduCmdDisplay (int argc, char** argv, FitsIO* fits); int hduCmdFits (int argc, char** argv, FitsIO* fits); // Write the contents of the current HDU (FITS table) to a catalog file // or return it as a Tcl list, if filename is NULL. int getHDU(FitsIO* fits, const char* filename, const char* entry); // Return the column headings for the current FITS table int getHDUHeadings(FitsIO* fits); #endif /* _RtdHDU_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/RtdImage.C000066400000000000000000001775601215713201500211620ustar00rootroot00000000000000/* * E.S.O. - VLT project * "@(#) $Id: RtdImage.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * RtdImage.C - member routines for class RtdImage, * implementation of the TCL rtdimage command * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * * T.Herlin 06/12/95 Setting object name RtdImage::displayImageEvent * * D.Hopkinson 02/12/96 Added timestamp information for performance tool * * P.Biereichel 30/06/97 processMotionEvent()'s call to getValues() changed * Added RtdImage::remoteTclCmd * * Allan Brighton 10/03/98 Minor changes based on changes made by * Peter W. Draper * for GAIA, which defines a subclass of * RtdImage, so that we can use some of the * GAIA features in our own derived classes. * * Added 2 optional arguments to RtdImage * constructor to allow derived classes to * specify thier own list of configuration * options. * * Changed "blank image" size from 10x10 to 2x2 * image, since people really seem to use 10x10 * pixel images. (The size is sometimes used to * determine if the image is "blank"). * * Changed ImageData::read invocation to use * FitsIO::read instead. This decouples the * need for ImageData (and ImageIO) to know * about what type of data they are dealing * with (and hence we can create a derived * class that can deal with other forms of * data, like NDFs). * * Allan Brighton 13/03/98 Define RTD_OPTIONS as a macro, so that derived * classes can add new options more easily. * * 30/03/98 Fixed the -shm_data and -shm_header options to * work again (they were lost in previous changes at * some point). * * Peter W. Draper 13/01/99 Changed to use non 8 bit visuals. * P.Biereichel 22/03/99 Added biasimage subcommand * Allan Brighton 16/05/99 Fixed isClear() method (removed check for empty header) * P.Biereichel 23/08/99 Added HDU methods (copied from skycat) * Pass on the rapid frame event to the first rapid frame when * the frameId in the rtdIMAGE_INFO structure doesn't exists. * Changed RtdImage::Rtd_Init() * 14/09/99 call to initColors() moved from Rtd_Init() to the RtdImage constructor: * colors are only initialized when needed * Allan Brighton 27/09/99 Reversed change, should fix panel editor to only do the package require * if rtd will be used. The colormap has to be initialized before any * widgets are created (each widget inherits the colormap from the * parent widget). * pbiereic 11/10/99 Until the panel editor has been fixed (Feb 2000) we use a compile flag * PANEL_EDITOR_BUG * Added wcsFlags and wcsdeltset command. * pbiereic 13/11/99 More accurate X, Y coords from RtdImage::statisticsCmd() * pbiereic 28/04/00 RtdImage::loadFile() opens the file with reading only * Peter W. Draper 10/05/00 Always update colormap, some private maps * are used when screen visual differs to * requested one and would not otherwise be * installed. * pbiereic 26/05/00 Added options fillWidth / fillHeight * Peter W. Draper 30/05/01 Added "double" as a valid data type. * pbiereic 01/03/01 o Added option 'debug' * o Added static class for performance tests (removed old code) * o Added method updateRequests() which updates X events * before calling updateIdleTasks(); only for image events. * o Since RtdImage.C was becoming too big all member fuctions * dealing with commands were copied to RtdCmds.C * o Removed XSyncSetPriority() since this blocked all * other X applications * pbiereic 28/05/01 Included Allan's changes for tcl8.3.3 * Removed LockMask in motionNotify() (SPR VLTSW20010313) * Allan Brighton 30/07/01 Fixed problem with X shared memory, ssh and X11 forwarding: * (X shm areas are not freed, so don't use them in this case) * pbiereic 17/02/03 Byte order for shm data is determined by the application * (flag shmEndian in the image event info structure). * Peter W. Draper 28/04/03 Added PIXTAB_MINX, MAXX, MINY and MAXY to report * the positions that the minimum and maximum values * are found in a table of values. * Peter W. Draper 21/10/03 Modified processMotionEvent to pass through * long thin images of 2 pixels or less in * either height or width. A blank image is * 2x2, not nx2 or 2xn. * 19/12/05 Undo change that removed LockMask in motionNotify. * I think that's a handy feature. * 08/01/07 Change isclear to check for RTD_BLANK as the * OBJECT value, don't use the size at all. * Change processMotionEvent to work for images * of all sizes (including blank ones). One * pixel images are possible in cube sections. * * Allan Brighton 16/12/05 Added local Tk_CanvasWindowCoordsNoClip method (moved from tclutil) * Allan Brighton 28/12/05 Replaced init script * Peter W. Draper 16/10/08 Record if user set the levels in setCutLevels * even if they are not changed. That's makes more * sense to the user. * 05/08/09 Add optionModified member to test if a * configuration option is given. This functionality * is lost in Tk 8.5. */ static const char* const rcsId="@(#) $Id: RtdImage.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "RtdImage.h" // Tcl procedure to search for an init for Rtd startup file. static char initScript[] = "if {[info proc ::rtd::Init]==\"\"} {\n\ namespace eval ::rtd {}\n\ proc ::rtd::Init {} {\n" #ifdef MAC_TCL " source -rsrc RtdInit.tcl\n" #else " global rtd_library\n\ tcl_findLibrary rtd " PACKAGE_VERSION " " PACKAGE_VERSION " RtdInit.tcl RTD_LIBRARY rtd_library\n" #endif " }\n\ }\n\ ::rtd::Init"; // should be in X11/extensions/XShm.h extern "C" int XShmQueryExtension(Display*); // should be in X11/extensions/sync.h extern "C" int XSyncInitialize(Display *, int *, int *); // extern "C" int XSyncSetPriority(Display *, XID, int); #if 0 #ifdef NEED_GETHOSTNAME_PROTO // should be in unistd.h ? extern "C" int gethostname(char *name, unsigned int namelen); #endif /* NEED_GETHOSTNAME_PROTO */ #endif // local extension to enable postscript printing for images extern "C" void TkCanvasPsImage_Init(); // generated code for bitmaps used in tcl scripts void defineRtdBitmaps(Tcl_Interp*); // generated code for colormap files used void defineColormaps(); // initialize these dependent packages here for backward compat extern "C" int Tclutil_Init(Tcl_Interp *interp); extern "C" int Astrotcl_Init(Tcl_Interp *interp); // these are static members shared by all instances of the image // and used for managing the color map and bias image, etc. ImageColor* RtdImage::colors_ = (ImageColor*) NULL; BiasData* RtdImage::biasimage_ = (BiasData*) NULL; RtdPerf* RtdImage::rtdperf_ = (RtdPerf*) NULL; // pointer to last RtdImage instance to handle motion events // (used to update display on real-time image events) static RtdImage* motionView_ = NULL; // Rtd Record extern "C" int RtdrecordInit(Tcl_Interp *); /* * image config options - used to process command line options and for the * image "configure" subcommand. */ static Tk_ConfigSpec configSpecs_[] = { RTD_OPTIONS, // See RtdImage.h: defines rtd option list {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; /* * Initialize the image control structure with pointers to the handler * functions */ static Tk_ImageType rtdImageType = { (char *)"rtdimage", /* name */ RtdImage::CreateImage, /* createProc */ TkImage::GetImage, /* getProc */ TkImage::DisplayImage, /* displayProc */ TkImage::FreeImage, /* freeProc */ TkImage::DeleteImage, /* deleteProc */ (Tk_ImagePostscriptProc *) NULL, /* postscriptProc, use generic */ (Tk_ImageType *) NULL /* nextPtr */ }; /* * eval the pre- and post- camera commands and display the image event. * "info" contains all we need to know about the image and "data" * gives access to the shared memory for the image. */ int RtdImageCamera::display(const rtdIMAGE_INFO& info, const Mem& data) { int status = TCL_OK; char buf[2048]; RtdPerf *rtdperf = rtdimage_->rtdperf(); rtdimage_->imageEvent(1); // set image event state rtdperf->newCycle(); // start performance test if applicable if (rtdimage_->cameraPreCmd()) { sprintf(buf, "%s %d", rtdimage_->cameraPreCmd(), info.frameId); status |= Tcl_Eval(interp_, buf); rtdperf->TCLtime(); } rtdperf->GENtime(); status |= rtdimage_->displayImageEvent(info, data); rtdperf->GENtime(); if (rtdimage_->cameraPostCmd()) { sprintf(buf, "%s %d", rtdimage_->cameraPostCmd(), info.frameId); status |= Tcl_Eval(interp_, buf); rtdperf->TCLtime(); } rtdperf->endCycle(); // set the performance test variables rtdimage_->imageEvent(0); // unset image event state return status; } /* * C++ "new handler" - called for out of memory errors by operator new * - just report it */ static void rtd_new_handler() { error("Warning: Real-Time DIsplay is out of memory"); } /* * Delete event handler - called to clean up shared memory when main window * is deleted */ static void destroy_notify(ClientData, XEvent*) { // XXX this method seems to be called at the wrong times // XXX (such as when the mouse enters the window!) // Mem::cleanup(); } /* * Tcl command: rtd_load_cmap * For internal use, to pre-load colormaps before startup */ static int rtd_load_cmap(ClientData, Tcl_Interp* interp, int argc, char** argv) { if (argc != 2) return error("usage: rtd_load_cmap cmapfile"); return (ColorMapInfo::get(argv[1]) ? TCL_OK : TCL_ERROR); } /* * Tcl command: rtd_load_itt * For internal use, to pre-load itts before startup */ static int rtd_load_itt(ClientData, Tcl_Interp* interp, int argc, char** argv) { if (argc != 2) return error("usage: rtd_load_itt ittfile"); return (ITTInfo::get(argv[1]) ? TCL_OK : TCL_ERROR); } /* * This static method implements the "rtd_set_cmap" Tcl command. * * usage: rtd_set_cmap $toplevel * * This command can be used to make a top level window use the same colormap * as the rtd images, so that there is less color flashing in popup windows * when we are using a private colormap. */ int RtdImage::rtd_set_cmap(ClientData, Tcl_Interp* interp, int argc, char** argv) { if (argc != 2) return ::error("usage: rtd_set_cmap $toplevel"); Tk_Window w = Tk_NameToWindow(interp, argv[1], Tk_MainWindow(interp)); if (w == NULL) return TCL_ERROR; if (!colors_) return ::error("rtd_set_cmap: colormap is not initialized yet"); return colors_->setColormap(w); // colors_ is a static member } /* * Install two utility Tcl commands for colormaps/itts * * These commands are for internal use (for pre-loading colormap and itt * files for use with unexec to make a single binary with all the stuff * already loaded in memory) */ extern "C" int CmapITT_Init(Tcl_Interp* interp) { Tcl_CreateCommand(interp, "rtd_load_cmap", (Tcl_CmdProc*)rtd_load_cmap, NULL, NULL); Tcl_CreateCommand(interp, "rtd_load_itt", (Tcl_CmdProc*)rtd_load_itt, NULL, NULL); return TCL_OK; } /* * A call to this function is made from the tkAppInit file at startup * to install the RtdImage image type and do global initialization */ extern "C" int Rtd_Init(Tcl_Interp* interp) { // Initialize the local packages that rtd depends on // PWD: enable postscript printing for images (local ext) TkCanvasPsImage_Init(); // initialize the tclutil package if (Tclutil_Init(interp) == TCL_ERROR) { return TCL_ERROR; } // initialize the astrotcl package if (Astrotcl_Init(interp) == TCL_ERROR) { return TCL_ERROR; } char buf[1024]; #ifndef PANEL_EDITOR_BUG // initialize color management (once only per application) if (RtdImage::initColors(interp) != TCL_OK) return TCL_ERROR; #endif // initialize bias image object if (RtdImage::initBias() != TCL_OK) return TCL_ERROR; // initialize the peformance test object if (RtdImage::initPerf(interp) != TCL_OK) return TCL_ERROR; // set up Rtd Tcl package if (Tcl_PkgProvide (interp, "Rtd", PACKAGE_VERSION) != TCL_OK) { return TCL_ERROR; } // define bitmaps used by Tcl library defineRtdBitmaps(interp); // define colormaps used defineColormaps(); // add the rtdimage image type Tk_CreateImageType(&rtdImageType); // add a tcl command to set the colormap on application windows so that // there is no flashing when there is a private colormap Tcl_CreateCommand(interp, "rtd_set_cmap", (Tcl_CmdProc*)RtdImage::rtd_set_cmap, NULL, NULL); // clean up shared memory on exit signal(SIGINT, RtdImage_cleanup); signal(SIGTERM, RtdImage_cleanup); // ignore floating point exceptions //sigignore(SIGFPE); signal(SIGFPE, SIG_IGN); // 11.9.97: allan, need this for linux Tk_CreateEventHandler(Tk_MainWindow(interp), DestroyNotify, destroy_notify, NULL); // initialize the rtdrecorder and rtdplayback image types RtdrecordInit(interp); Tcl_SetVar(interp, "rtd_version", PACKAGE_VERSION, TCL_GLOBAL_ONLY); return Tcl_Eval(interp, initScript); } /* * This static method is called by the Tk image code to create * a new rtdimage image. * * Note: There was an incompatible change made in tk8.3: argv was * replaced with objv. Therefore the #ifdefs. */ int RtdImage::CreateImage( Tcl_Interp *interp, // Interpreter for application containing image. char *name, // Name to use for image. int argc, // Number of arguments. #if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >= 3 Tcl_Obj *CONST objv[], // Argument objects for options (not including image name or type) #else char **argv, // Argument strings for options (not including image name or type) #endif Tk_ImageType *typePtr, // Pointer to our type record (not used). Tk_ImageMaster master, // Token for image, to be used by us in later callbacks. ClientData *clientDataPtr) // Store manager's token (this ptr) for image here // it will be returned in later callbacks. { #if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >= 3 // just generate an argv from the objv argument char* argv[64]; // there shouldn't be more than a few options... for(int i = 0; i < argc; i++) argv[i] = Tcl_GetString(objv[i]); argv[argc] = NULL; #endif RtdImage* im = new RtdImage(interp, name, argc, argv, master, rtdImageType.name, configSpecs_, new RtdImageOptions); if (im && im->status() == TCL_OK) { *clientDataPtr = (ClientData) im; return im->initImage(argc, argv); } return TCL_ERROR; } /* * for backward compat. */ extern "C" int RtdImage_Init(Tcl_Interp* interp) { return Rtd_Init(interp); } /* * Constructor: initialize a new rtdimage with the command line args. * * This constructor is called for each rtd image declared in tk. The destructor * is called when the image image is destroyed. * * Args: * interp - Tk interpreter * instname - instance name of image object * arc, argv - command line args * master - Tk struct with image info * imageType - name of image type ("rtdimage") * specs, options - optional args to be used by derived class. * * The last 2 arguments are optional. They are designed to be used by a derived * class to add new image options. If "specs" is specified, then the * initImage() method must also be called by the caller to process the options, * otherwise initImage() is called here (for backward compatibility). */ RtdImage::RtdImage(Tcl_Interp* interp, const char* instname, int argc, char** argv, Tk_ImageMaster master, const char* imageType, Tk_ConfigSpec* specs, RtdImageOptions* options) : TkImage(interp, imageType, instname, (specs ? specs : configSpecs_), options, master, (char *)"Canvas"), image_((ImageData*)NULL), options_(options), camera_(NULL), cameraPreCmd_(NULL), cameraPostCmd_(NULL), imageEvent_(0), remote_(NULL), frameId_(0), frameX_(0.0), frameY_(0.0), xOffset_(0.0), yOffset_(0.0), rapidX_(0.0), rapidY_(0.0), reqWidth_(0.0), reqHeight_(0.0), propagateScale_(1), autoSetCutLevels_(1), rapidFrame_(0), canvasX_(0), canvasY_(0), prevX_(0), prevY_(0), zoomer_(NULL), motionX_(0), motionY_(0), saveMotion_(1), motionPending_(0), motionState_(0), zoomView_(NULL), zoomView2_(NULL), zoomFactor_(1), zoomSpeed_(1), panFactor_(0), panCommand_(NULL), panx1_(0), pany1_(0), panx2_(0), pany2_(0), displayLocked_(0), canvas_(NULL), canvasName_(NULL), haveXShm_(0), usingXShm_(0), haveXSync_(0), usingXSync_(0), xImage_(NULL), viewMaster_(NULL), currentView_(this), pixTab_(NULL), dbl_(NULL) { if (! options_) { options_ = new RtdImageOptions; } // since gcc 3.2 is complaining about non-POD we use a structure // which holds the options. setOptionsPtr(options_->get_rtd_options()); // errors may have occured in the base class ... if (status() != TCL_OK) return; filename_[0] = '\0'; // debug log object dbl_ = new RtdDebugLog((char *)instname, (int)(debug() & verbose())); // if we are on the console, check for XSHM, X shared memory extension char hostname[64]; gethostname(hostname, sizeof(hostname)); int n = strlen(hostname); char* display = DisplayString(display_); // allan: 7/01: check for screen number "0", since when using X11 forwarding with ssh, // the display is set to something like "host:10:0" - a proxy server, and the X shared // memory is never freed. if (display[0] == ':' || (strncmp(hostname, display, n) == 0 && display[n] == ':' && display[n+1] == '0')) { haveXShm_ = XShmQueryExtension(display_); } #ifdef DEBUG if (verbose()) { int num; char **exts; exts = XListExtensions(display_, &num); fprintf(stderr, "Extension list:-\n"); for (int k = 0; k < num; k++) { fprintf(stderr, "Extension %d is %s\n", k, exts[k]); } XFreeExtensionList(exts); } #endif #if _HAVE_R6 // Check if we have the Sync extension. int ev_br, er_br; // event_base_return, error_base_return. int mjr_opcode; // major opcode. int mj_vr, mn_vr; // Major/minor version number. haveXSync_ = XQueryExtension(display_, "SYNC", &mjr_opcode, &ev_br, &er_br); // Initialise if we haven't and it isn't already. if (haveXSync_) { if (!usingXSync_) { if (XSyncInitialize(display_, &mj_vr, &mn_vr)) { usingXSync_ = 1; } } } #endif // _HAVE_R6 if (haveXShm_) dbl_->log("X Shared memory is supported\n"); else dbl_->log("X Shared memory is not supported\n"); if (haveXSync_) dbl_->log("X Synchronisation is supported\n"); else dbl_->log("X Synchronisation is not supported\n"); // initialize list of views for(int i = 0; i < MAX_VIEWS; i++) view_[i] = NULL; #ifdef PANEL_EDITOR_BUG // initialize color management (once only per application) if (RtdImage::initColors(interp) != TCL_OK) { status_ = TCL_ERROR; return; } #endif // Do first time image configuration. Note: it is better to call this // method from outside the constructor, so that virtual methods can be // overridden. This is kept here for backward compatibility, if "options" // is NULL (default). if (! specs) initImage(argc, argv); } /* * destructor - clean up image when image cmd is destroyed */ RtdImage::~RtdImage() { if (dbl_) { dbl_->log("~RtdImage(): deleting %s (%s)\n", instname(), name()); delete dbl_; dbl_ = NULL; } // there might be more than one image in a canvas window // Tk_DeleteEventHandler(tkwin_, ButtonMotionMask|StructureNotifyMask, // eventProc, (ClientData)this); // if this is a view, remove it from the master's list if (viewMaster_) { if (viewMaster_->currentView_ == this) viewMaster_->currentView_ = viewMaster_; viewMaster_->removeView(this); viewMaster_ = NULL; zoomer_ = NULL; } // reset this static pointer if it points to this instance if (motionView_ == this) motionView_ = NULL; if (image_) { delete image_; image_ = NULL; } deleteXImage(); if (zoomer_) { Tk_CancelIdleCall(motionProc, (ClientData)this); delete zoomer_; zoomer_ = NULL; } if (panCommand_) { free(panCommand_); panCommand_ = NULL; } if (camera_) { delete camera_; camera_ = NULL; } if (cameraPreCmd_) { free(cameraPreCmd_); cameraPreCmd_ = NULL; } if (cameraPostCmd_) { free(cameraPostCmd_); cameraPostCmd_ = NULL; } if (remote_) { delete remote_; remote_ = NULL; } if (pixTab_) { delete[] pixTab_; pixTab_ = NULL; } // remove any views of this image removeViews(); } /* * initialize the color visual and colormap */ int RtdImage::initColors(Tcl_Interp* interp) { // we should only do this once if (colors_) return TCL_OK; int depth = 8; // default, will be set by Tk_GetVisual below Colormap colormap; // make sure the window exists now before setting the colormap Tk_Window tkwin = Tk_MainWindow(interp); // XXX these should be options: min and max number of colors to allocate. // If this many are not available, use private colormap. int min_colors = 30, max_colors = 60; // Use the default visual for now... // Visual* visual = Tk_GetVisual(interp, tkwin, "default", &depth, &colormap); // PWD: use "." here as "default" returns screen visual, not the // "-visual" command-line option. Making this function static has // some drawbacks (the tkwin was previously the parent of the image?). Visual* visual = Tk_GetVisual(interp, tkwin, ".", &depth, &colormap); if (! visual) return TCL_ERROR; Tk_MakeWindowExist(tkwin); colors_ = new ImageColor(Tk_Display(tkwin), visual, depth, max_colors); if (colors_->status() != 0) { return TCL_ERROR; } if (colors_->colorCount() < min_colors) { if (colors_->usePrivateCmap() || colors_->allocate(max_colors)) { return TCL_ERROR; } } // PWD: always set the colormap. This can be "private" when the // default visual doesn't match the one requested, in which case // we still need to set the colormap (I noticed this using a // default truecolor visual when attempting to get a pseudocolor // visual). return colors_->setColormap(tkwin); } /* * set X and Y to values between 0 and $xyscale, where $xyscale * is the scale factor. The values indicate the fraction of the * pixel at the point px,py based on the current scale factor. * i.e.: if the scale factor is 10, x,y = 5,5 means px,py is at * the center of the zoomed pixel. */ void RtdImage::getOffsetInXImage(double px, double py, int& x, int& y) { int xyscale = image_->xScale(); if (xyscale > 1) { x = int((px-int(px))*xyscale); y = int((py-int(py))*xyscale); // printf("%s: getOffsetInXImage: (%.17g,%.17g) ==> (%d,%d) ", instname(), px, py, x, y); if (px < 0) x += xyscale; if (py < 0) y += xyscale; if (image_->rotate()) swap(x, y); // printf("==> (%d,%d)\n", x, y); } } /* * This method is called from the RtdImageCamera class to display the * image from shared memory. "info" contains all we need to know about * the image and "data" gives access to the shared memory for the image. */ int RtdImage::displayImageEvent(const rtdIMAGE_INFO& info, const Mem& data) { // if this event is for us, display it if (info.frameId == frameId_) { int status = TCL_ERROR; // update the x and y offsets // (these are normally 0, when the rapid frame has its own shared memory area) xOffset_ = info.frameX; yOffset_ = info.frameY; // use native byte ordering for data in shared memory, unless // the camera process wants RTD to do the byte swap (eg. RTD // running on a little Endian machine and data are produced // on a big Endian machine). int usingNetBO = ((BIGENDIAN && info.shmEndian == -1) || (info.shmEndian == 0)); // if the image changed, delete it and create a new one, otherwise reuse if (image_ == NULL || image_->data().shared() == 0 || info.xPixels != image_->width() || info.yPixels != image_->height() || usingNetBO != image_->image().usingNetBO() || info.dataType != image_->dataType()) { if (dbl_) dbl_->log("%s: new image received: %d x %d\n", name(), info.xPixels, info.yPixels); // save previous image parameters so we can restore the settings later ImageDataParams p; if (image_) { image_->saveParams(p); delete image_; image_ = NULL; updateViews(); } // make a FitsIO object to represent the new image data and use it to // make a new ImageData object, which manages the image and transformations. Mem header; // empty header (use wcs command to set wcs keywords) FitsIO* fits = new FitsIO(info.xPixels, info.yPixels, info.dataType, 0.0, 1.0, header, data); if (!fits || fits->status() != 0) return TCL_ERROR; fits->usingNetBO(usingNetBO); image_ = makeImage(fits); if (!image_) return TCL_ERROR; // set object name to camera name if (camera_) image_->object(camera_->camera()); // restore transformations, cut levels, etc from the previous image image_->restoreParams(p, !autoSetCutLevels_); // if the image event contains valid cut levels, use them if (autoSetCutLevels_ && info.lowCut != info.highCut) image_->setCutLevels(info.lowCut, info.highCut, 1); // initialize the new image status = initNewImage(); } else { // reuse the current image and just update the image data if (dbl_) dbl_->log("%s: new image data received: %d x %d (size: %d bytes)\n", name(), info.xPixels, info.yPixels, data.length()); // if the image event contains valid cut levels, use them if (info.lowCut != info.highCut) setCutLevels(info.lowCut, info.highCut, 1, 0); // update the image with the new data status = updateImageNewData(data); } // now we have the new image... // set detector parameters setDetParms(image_, info); for(int i = 0; i < MAX_VIEWS; i++) { if (view_[i] && view_[i]->image_ && !view_[i]->isSeparateRapidFrame()) setDetParms(view_[i]->image_, info); } filename(image_->object()); // set WCS info, if available int binningOk = 1; if (info.binningX > 0 || info.binningY > 0) { if (info.binningX != info.binningY) binningOk = 0; } if (info.secpix != 0. && binningOk == 1) { double xrefpix=info.xrefpix, yrefpix=info.yrefpix; double asecpix=info.secpix; if (info.binningX > 1) asecpix = asecpix / info.binningX; image_->chipToImageCoords(xrefpix, yrefpix); if (image_->wcs().set(info.ra, info.dec, asecpix, xrefpix, yrefpix, info.xPixels, info.yPixels, info.rotate, info.equinox, info.epoch, info.proj) != 0) return TCL_ERROR; if (info.wcsFlags & (RTD_WCS_FLIP_RA | RTD_WCS_FLIP_DEC)) { double cdelt1 = - info.secpix / 3600.0; double cdelt2 = info.secpix / 3600.0; if (info.wcsFlags & RTD_WCS_FLIP_RA) cdelt1 = -cdelt1; if (info.wcsFlags & RTD_WCS_FLIP_DEC) cdelt2 = -cdelt2; image_->wcs().deltset(cdelt1, cdelt2, info.rotate); } } // update zoom window and panel labels, etc, if necessary if (motionView_) motionView_->processMotionEvent(); // pause here until image is displayed updateRequests(); // notify the panning window after WCS was set if (panCommand_) autoPan(1); return status; } else { // must be a rapid frame event. Pass it on... int i = info.frameId-1; if (i >= 0 && i < MAX_VIEWS && view_[i] && view_[i]->rapidFrame_) { return view_[i]->displayImageEvent(info, data); } // frameId is wrong: pass the event on to the first rapid frame for (i = 1; i < MAX_VIEWS; i++) { if (view_[i] && view_[i]->rapidFrame_) { rtdIMAGE_INFO infoRapid; memcpy(&infoRapid, &info, sizeof(rtdIMAGE_INFO)); infoRapid.frameId = i+1; return view_[i]->displayImageEvent(infoRapid, data); } } } return TCL_OK; } /* * Set detector paramters */ void RtdImage::setDetParms(ImageData* image, const rtdIMAGE_INFO& info) { image->startX(info.startX); image->startY(info.startY); if (info.binningX > 0) image->binX(info.binningX); if (info.binningY > 0) image->binY(info.binningY); } /* * call updateIdleTasks() if no image event from camera was received. * Otherwise update window and idle events to a) avoid too many * pending X requests and b) set the times for the performance test * */ void RtdImage::updateRequests() { if (! imageEvent_ ) { updateIdleTasks(); // backwards compatible for loaded images return; } if (! dbl_ || ! rtdperf_ || ! xImage_) return; rtdperf_->GENtime(); // update the time stamp xImage_->flushX(); rtdperf_->Xtime(); updateIdleTasks(); } // Fix for Tk clipping coordinates to short range: See CanvasWindowCoordsNoClip() below. #ifdef HAVE_TKCANVAS_H #define MODULE_SCOPE extern #include "tkCanvas.h" #else // The structure we need hasn't changed for a long time, so just include a local copy. #define MODULE_SCOPE extern "C" #include "tkCanvas.h-tk8.4.11" #define HAVE_TKCANVAS_H #endif /* * Hack to work around the tk canvas clipping coordinates to short range: * same as Tk_CanvasWindowCoords, but with no clipping. * Without this fix, there will be problems with very large, or zoomed in images. */ static void Tk_CanvasWindowCoordsNoClip(Tk_Canvas canvas, double x, double y, int* screenXPtr, int* screenYPtr) { #ifdef HAVE_TKCANVAS_H TkCanvas *canvasPtr = (TkCanvas *) canvas; double tmp; tmp = x - canvasPtr->xOrigin; if (tmp > 0) { tmp += 0.5; } else { tmp -= 0.5; } *screenXPtr = (int)tmp; tmp = y - canvasPtr->yOrigin; if (tmp > 0) { tmp += 0.5; } else { tmp -= 0.5; } *screenYPtr = (int)tmp; #else short sx, sy; Tk_CanvasWindowCoords(canvas, x, y, &sx, &sy); if (sx == 32767 || sx == -32768 || sy == 32767 || sy == -32768) { fprintf(stderr, "Warrning: Tk clipped the RTD image coordinates to short range!\n"); } *screenXPtr = sx; *screenYPtr = sy; #endif } /* * This virtual method is invoked indirectly by the Tk image handling * routines to draw the image. * * If displaymode is 0, try to optimize smooth scrolling by copying the * entire image to the X server. If using X shared memory, we can do this * each time otherwise we use an offscreen pixmap and copy the image * there only when needed. * * if displaymode is 1, optimize memory usage by only allocating space for * the visible image. */ void RtdImage::displayImage(Drawable d, int imageX, int imageY, int width, int height, int drawableX, int drawableY) { char buffer[32]; rtdperf_->TCLtime(); if (displayLocked_ || ! initialized_ || ! xImage_ || ! xImage_->data() || ! image_) return; displayLocked_ = 1; // get the canvas X,Y offsets // Note: the Tk routine Tk_CanvasWindowCoords clips the coordinates to "short" range // (-32768 .. 32767), which can cause problems in very large images // and/or at large magnification. The call below is to a replacement defined here. Tk_CanvasWindowCoordsNoClip(canvas_, 0., 0., &canvasX_, &canvasY_); if (displaymode() == 0) { // do entire image, as needed if (xImage_->usingXShm()) { // with X shared memory, should be fast enough to write directly to X server if (update_pending_) image_->update(); xImage_->put(d, imageX, imageY, drawableX, drawableY, width, height); } else { // not using X shared mem, use an offscreen pixmap if (update_pending_) { image_->update(); xImage_->put(pm_, 0, 0, 0, 0, dispWidth(), dispHeight()); } // do a quick copy within the X server if (pm_) XCopyArea(display_, pm_, d, gc_, imageX, imageY, width, height, drawableX, drawableY); } } else { // optimize for fast updates, do only visible area of image double fx = frameX_, fy = frameY_, dx = xOffset_, dy = yOffset_; if (fx || fy) doTrans(fx, fy, 1); // get canvas distance for frameX,Y if (dx || dy) doTrans(dx, dy, 1); // get offset for origin in raw image int x = max(-canvasX_ - int(fx), 0), y = max(-canvasY_ - int(fy), 0); int update = (update_pending_ || x != prevX_ || y != prevY_); prevX_ = x; prevY_ = y; dx += x, dy += y; undoTrans(dx, dy, 1); // get image coord x,y offsets in image coords // if image is zoomed, adjust for correct fraction of pixel at origin int px = 0, py = 0; getOffsetInXImage(dx, dy, px, py); if (xImage_->usingXShm()) { // with X shared memory, should be fast enough to write directly to X server if (update) image_->updateOffset(dx, dy); xImage_->put(d, imageX-x+px, imageY-y+py, drawableX, drawableY, width, height); } else { // not using X shared mem, use an offscreen pixmap if (update) { image_->updateOffset(dx, dy); xImage_->put(pm_, 0, 0, 0, 0, pixw_, pixh_); } // do a quick copy within the X server if (pm_) XCopyArea(display_, pm_, d, gc_, imageX-x+px, imageY-y+py, width, height, drawableX, drawableY); } } // notify the panning window, if necessary if (panCommand_) autoPan(); // reset flags update_pending_ = displayLocked_ = 0; rtdperf_->Xtime(); } /* * This procedure is called to process an argv/argc list, plus * the Tk option database, in order to configure (or reconfigure) * a image. * * redefined here to check which changes were made. */ int RtdImage::configureImage(int argc, char* argv[], int flags) { if (TkImage::configureImage(argc, argv, flags) != TCL_OK) return TCL_ERROR; int status = TCL_OK; int reset = 0; // note if we are using X shared memory usingXShm_ = haveXShm_ && usexshm(); // find out which options were specified and process them // if necessary (note: Tk sets a flag in the config entry when // the option is specified. We use the OFFSET macro defined above // as an efficient way to compare options) for (Tk_ConfigSpec* p=configSpecs_; p->type != TK_CONFIG_END; p++) { if ( optionModified(argc, argv, p->argvName) ) { switch(p->offset) { case RTD_OPTION(usexshm): if (initialized_) { deleteXImage(); reset++; } break; #if _HAVE_R6 case RTD_OPTION(usexsync): if (usingXSync_ && usexsync()) { /* * XSyncSetPriority() was commented out since it can block all * other X-applications when fast image events are received- */ // XSyncSetPriority(display_, None, 65535); // fprintf(stderr, "Raising priority of client %s\n", name()); } break; #endif // _HAVE_R6 case RTD_OPTION(displaymode): case RTD_OPTION(shm_header): case RTD_OPTION(shm_data): if (initialized_) reset++; break; case RTD_OPTION(verbose): case RTD_OPTION(debug): if (dbl_) dbl_->setlog ((int)(debug() & verbose())); break; case RTD_OPTION(fitWidth): case RTD_OPTION(fitHeight): if (initialized_) { if (image_ && fitWidth() && fitHeight()) { image_->shrinkToFit(fitWidth(), fitHeight()); } reset++; } break; case RTD_OPTION(fillWidth): case RTD_OPTION(fillHeight): if (initialized_) { if (image_ && fillWidth() && fillHeight()) { image_->fillToFit(fillWidth(), fillHeight()); } reset++; } break; case RTD_OPTION(file): status = loadFile(); break; case RTD_OPTION(sampmethod): if (initialized_ && image_) { if (image_->sampmethod() != sampmethod()) { image_->sampmethod(sampmethod()); reset++; } } break; case RTD_OPTION(subsample): if (initialized_ && image_) { if (image_->subsample() != subsample()) { image_->subsample(subsample()); reset++; } } break; } } } if (reset) return resetImage(); return status; } /* * test: if an option has been modified during the configureImage * because it is present in the given argv list. */ int RtdImage::optionModified( int argc, char *argv[], const char* option ) { for ( int i = 0; i < argc; i +=2 ) { if ( strcmp( argv[i], option ) == 0 ) { return 1; } } return 0; } /* * util: return true if this is an embedded rapid frame * (i.e.: a rapid frame in the same canvas with the master image) */ int RtdImage::isEmbeddedRapidFrame() { return (rapidFrame_ && viewMaster_ && viewMaster_->tkwin_ == tkwin_); } /* * util: return true if this is a rapid frame that is not embedded * (i.e.: a rapid frame that is not in the same canvas with the master image) */ int RtdImage::isSeparateRapidFrame() { return (rapidFrame_ && viewMaster_ && viewMaster_->tkwin_ != tkwin_); } /* * Set the cut levels to the given min and max values and update the * image and any views of it. If scaled is 1, the values are assumed yo * be already scaled with bzero and bscale. If user is 1, the call is a * result of a user action. */ int RtdImage::setCutLevels(double min, double max, int scaled, int user) { // don't overwrite user's cut levels if (!user && !autoSetCutLevels_) return TCL_OK; // assume the user has set the cut levels, so we wont change them // if a new image is loaded... if (user) autoSetCutLevels_ = 0; // check if there is a change from the previous cut levels if (scaled && min == image_->lowCut() && max == image_->highCut()) return TCL_OK; // no change image_->setCutLevels(min, max, scaled); image_->colorScale(colors_->colorCount(), colors_->pixelval()); // make sure the new lookup table is propagated LookupTable lookup = image_->lookupTable(); for(int i = 0; i < MAX_VIEWS; i++) { if (view_[i] && view_[i]->image_ && !view_[i]->isSeparateRapidFrame()) view_[i]->image_->lookupTable(lookup); } return updateViews(1) || updateImage(); } /* * set the X,Y scale factors for the image and propagate to any views * of the image as needed. */ int RtdImage::setScale(int xScale, int yScale) { // ignore invalid scale values if (xScale == 0 || xScale == -1) xScale = 1; if (yScale == 0 || yScale == -1) yScale = 1; // magnify by zoom factor, if requested if (zoomFactor_ > 1) { if (xScale > 0) { xScale *= zoomFactor_; yScale *= zoomFactor_; } else { xScale = yScale = zoomFactor_; } if (dbl_) dbl_->log("%s: setting scale to (%d, %d), factor %d\n", name(), xScale, yScale, zoomFactor_); } // ignore if the same scale is now in effect int xs = image_->xScale() , ys = image_->yScale(); if (xScale == xs && yScale == ys) { // notify the panning window, if necessary, even if scale didn't change // since it may need to update the panning display if (panCommand_) { panx1_ = pany1_ = panx2_ = pany2_ = 0; autoPan(); } return TCL_OK; } image_->setScale(xScale, yScale); panx1_ = pany1_ = panx2_ = pany2_ = 0; // make sure panning is updated if (resetImage() != TCL_OK) return TCL_ERROR; // also scale any views that don't have a fixed scale return updateViews(2); } /* * This method is called for new images or whenever the image may * have changed size. It updates the size of the pixmap and XImage * as needed and arranges to have the image redrawn. */ int RtdImage::resetImage() { if (! image_) return TCL_OK; // only use a pixmap if not using X shared mem int w = dispWidth(), h = dispHeight(); double rw = reqWidth_, rh = reqHeight_; doTrans(rw, rh, 1); // if an explicit size was requested and it is less than the image // size, use it. if (rw && rw < w) { w = int(rw); } if (rh && rh < h) { h = int(rh); } // size of XImage and pixmap, if used int pixw = w, pixh = h; // if displaymode is 1, the image size is not larger than the window size if (displaymode() == 1) { pixw = Tk_Width(tkwin_); // note: making this any smaller than the window pixh = Tk_Height(tkwin_); // caused problems on HP (X server crash..) if (pixw == 1 && pixh == 1) return TCL_OK; // wait for resize event on image window if (w < pixw) // requested smaller size ? pixw = w; if (h < pixh) pixh = h; // round up the size to the nearest scale factor multiple (+1?), so that no // empty spaces are left around the edges of the image (allan, 10.10.95) int xs = image_->xScale(), ys = image_->yScale(); if (xs > 1) { pixw += (xs - pixw % xs) + xs; pixh += (ys - pixh % ys) + ys; } } // check min size for X image if (pixw <= 0 || pixh <= 0) { pixw = pixh = 1; } // make a new X image if needed and update the size if (!xImage_) xImage_ = new ImageDisplay(display_, visual_, gc_, depth_, usingXShm_, verbose()); if (xImage_->update(pixw, pixh) != TCL_OK) { deleteXImage(); return TCL_ERROR; } // tell that class that manages the image data about the new xImage data image_->setXImage( xImage_ ); // always set Tk's idea of the image size to the full size, // even though the pixmap and XImage may be smaller int status = setImageSize(w, h, !xImage_->usingXShm(), pixw, pixh); // tell Tk we want to redraw the image imageChanged(); return status; } /* * Load a Fits image file and display it. */ int RtdImage::loadFile() { // -file may have been set to "", just clear image then if (strlen(file()) == 0) return clearCmd(0, NULL); // used to save and restore image transformation parameters ImageDataParams p; if (image_) { image_->saveParams(p); delete image_; image_ = NULL; updateViews(); } // if not '-' (stdin) check that it is a file if (strcmp(file(), "-") != 0) { struct stat buf; if (stat(file(), &buf) != 0 || S_ISREG(buf.st_mode) == 0) return error("expected a file, but got: ", file()); } // if sysV shared memory was requested, use it in place of mmap // XXX 18.06.04 shared memory is only used for image event data FitsIO* fits = NULL; if (0 && (shm_header() || shm_data())) { // read the FITS image into shared memory Mem m(file()); if (m.status() != 0) return TCL_ERROR; m.shared(1); fits = FitsIO::initialize(m); } else { // read the FITS image using the default mmap. S_IRUSR is used to cheat // FitsIO.C which assumes that no options are given when 0 // but O_RDONLY is defined as 0. fits = FitsIO::read(file(), O_RDONLY | S_IRUSR); } if (!fits || fits->status() != 0) return TCL_ERROR; image_ = makeImage(fits); if (! image_) return TCL_ERROR; // restore transformations image_->restoreParams(p, !autoSetCutLevels_); filename(file()); // keep filename return initNewImage(); } /* * this method is called to do all the necessary work * after a new image has been loaded from file or shared memory */ int RtdImage::initNewImage() { if (!image_) { return updateViews(); } // reset options image_->subsample(subsample()); image_->sampmethod(sampmethod()); image_->verbose(verbose()); if (fitWidth() || fitHeight()) { image_->shrinkToFit(fitWidth(), fitHeight()); } if (fillWidth() || fillHeight()) { image_->fillToFit(fillWidth(), fillHeight()); } image_->colorScale(colors_->colorCount(), colors_->pixelval()); // update other views if (updateViews(1) != TCL_OK) return TCL_ERROR; if (resetImage() != TCL_OK) return TCL_ERROR; // update the panning window if needed if (panCommand_) { if (Tk_Width(tkwin_) <= 1) { // pause here until window is displayed, so that the pan // window can determine the size of the window updateRequests(); } autoPan(1); } // evaluate the newImageCmd, if there is one if (strlen(newImageCmd())) { return Tcl_Eval(interp_, newImageCmd()); } return TCL_OK; } /* * this method causes the image and its views to be redrawn. */ int RtdImage::updateImage() { imageChanged(); if (image_) image_->update_pending(1); return updateViews(); } /* * This method is called to update an existing image with new * raw data of the same size and type. */ int RtdImage::updateImageNewData(const Mem& data) { if (dbl_) dbl_->log("%s: update image with new data (size: %d)\n", name(), data.length()); if (image_) image_->data(data); // update the data in any views for(int i = 0; i < MAX_VIEWS; i++) { if (view_[i] && view_[i]->image_ && !view_[i]->rapidFrame_ && view_[i] != zoomView_ && view_[i] != zoomView2_) { if (dbl_) dbl_->log("%s: update %s with new data\n", name(), view_[i]->name()); view_[i]->image_->data(data); } } return updateImage(); } /* * delete the XImage used to display the image */ int RtdImage::deleteXImage() { if (xImage_) { delete xImage_; xImage_ = NULL; } // also reset the pointer in the class that manages the XImage data if (image_) image_->setXImage( NULL ); return 0; } /* * this method is called in the master image to update all of the * views. * "flag" is set to 1 if a new image was loaded from file or * shared memory, 2 if the image has be scaled (zoomed) and 0 * otherwise. */ int RtdImage::updateViews(int flag) { int status = TCL_OK; for(int i = 0; i < MAX_VIEWS; i++) { if (view_[i]) status |= view_[i]->updateView(image_, flag); } return status; } /* * add the given image to the list of views, images * that are updated from this one. */ int RtdImage::addView(RtdImage* view) { for(int i = 0; i < MAX_VIEWS; i++) { if (view_[i] == NULL) { view_[i] = view; view->frameId_ = i+1; view->viewMaster_ = this; if (image_) { return view->updateView(image_, 1); } return TCL_OK; } } return error("too many RtdImage views"); } /* * remove the given image from the list of views */ int RtdImage::removeView(RtdImage* view) { if (view) { for(int i = 0; i < MAX_VIEWS; i++) { if (view_[i] == view) { view->viewMaster_ = NULL; view_[i]->zoomer_ = NULL; view_[i]->zoomView_ = NULL; view_[i]->zoomView2_ = NULL; view_[i] = NULL; return TCL_OK; } } } return error("tried to remove nonexistant RtdImage view"); } /* * remove all views from the view list */ void RtdImage::removeViews() { for(int i = 0; i < MAX_VIEWS; i++) { if (view_[i]) { view_[i]->viewMaster_ = NULL; view_[i]->zoomer_ = NULL; view_[i]->zoomView_ = NULL; view_[i]->zoomView2_ = NULL; view_[i] = NULL; } } } /* * This method is called from outside by the master image to update the * view in a slave image. "im" is the master image data, which we make a copy * of here (with reference counting, so the actual data is shared) * * "flag" is set to 1 if a new image was loaded from file or shared * memory, 2 if the image has been scaled (zoomed) and 0 otherwise. */ int RtdImage::updateView(ImageData* im, int flag) { if (!im) { // image was unloaded ? if (image_) delete image_; image_ = NULL; return TCL_OK; } if (image_ && flag != 1) { // this is an existing image, update it // only transformations changed if (flag == 2) { if (propagateScale_ == 0) { // no change - scale is fixed return TCL_OK; } else { // set new x,y scale factors return setScale(im->xScale(), im->yScale()); } } return updateImage(); } // save scale factors, if any int xs = 0, ys = 0; if (image_) { xs = image_->xScale(); ys = image_->yScale(); } if (dbl_) dbl_->log("%s: update view from %s (rapid?: %d)\n", name(), im->name(), rapidFrame_); // if its not a rapid frame in a separate window, copy the image from the master image, // otherwise just copy the transformations if (rapidFrame_) { if (image_ && isEmbeddedRapidFrame()) { ImageDataParams p; im->saveParams(p); image_->restoreParams(p, !autoSetCutLevels_); } } else { // this is a new image, or it changed dimensions or position in some way. // delete old one and copy the new one. if (image_) delete image_; #ifdef XXXDEBUG if (verbose()) printf("%s: copy data from %s\n", name(), im->name()); #endif image_ = im->copy(); image_->name(name()); // reset the name of the slave image image_->sampmethod(sampmethod()); image_->subsample(subsample()); } if (fitWidth() || fitHeight()) { // used for pan window - shrink to fit whole image in window image_->shrinkToFit(fitWidth(), fitHeight()); } else if (zoomFactor_ > 1) { // used for zoom view: make scale relative to main image if (setScale(im->xScale(), im->yScale()) != TCL_OK) return TCL_ERROR; } else if (xs && propagateScale_ == 0) { // if the scale factors should not propagate to the view, restore them here image_->setScale(xs, ys); } if (resetImage() != TCL_OK) return TCL_ERROR; return TCL_OK; } /* * return a pointer to the RtdImage class object for the * given rtdimage tcl instance name, or NULL * if the name is not an rtdimage. */ RtdImage* RtdImage::getView(char* name) { // check that the argument really is an rtdimage... if (strncmp(name, "image", 5) != 0) { error("expected an rtdimage id but got: ", name); return NULL; } // get class instance pointer from name Tcl_CmdInfo info; if (Tcl_GetCommandInfo(interp_, name, &info) == 0) { error("expected an \"rtdimage\" type image"); return NULL; } return (RtdImage*)info.clientData; } /* * This virtual method is called indirectly by the Tk image handling routines * for each use of the image in a widget. * It is redefined here so that we can set up an event handler on the instance * window for autozooming. */ TkImage* RtdImage::getImage(Tk_Window tkwin) { TkImage* ret = TkImage::getImage(tkwin); if (! ret) return ret; // note the name of the canvas window canvasName_ = Tk_PathName(tkwin); // set up event handler for motion events and resizing Tk_CreateEventHandler(tkwin, ButtonMotionMask|StructureNotifyMask, eventProc, (ClientData)this); // get a handle to the canvas and save it for later reference Tcl_CmdInfo info; if (Tcl_GetCommandInfo(interp_, (char*)canvasName_, &info) == 0) { char* msg = (char *)"internal error: couldn't get canvas info"; error(msg); fprintf(stderr, "rtd: %s for %s\n", msg, canvasName_); Tk_BackgroundError(interp_); return NULL; // this crashes Tk, either way... } #if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >= 3 canvas_ = (Tk_Canvas)info.objClientData; #else canvas_ = (Tk_Canvas)info.clientData; #endif // set colormap if needed for image window and add to window list for later colors_->setColormap(tkwin_); return ret; } /* * This static method is called for motion and configure events * in the image window */ void RtdImage::eventProc(ClientData clientData, XEvent* eventPtr) { RtdImage* thisPtr = (RtdImage*)clientData; if (thisPtr) { if (eventPtr->type == MotionNotify) { // use current view as set by view command, which defaults to this // image, in case more than one image is in canvas (motionView_ = thisPtr->currentView_)->motionNotify(eventPtr); } else if (eventPtr->type == ConfigureNotify) { thisPtr->configureNotify(eventPtr); } } } /* * This method is called for MotionNotify events in the image window * Arrange for the zoom window to be updated. */ void RtdImage::motionNotify(XEvent* eventPtr) { // (eventuallY) update zoom window, if shift button not pressed if ((eventPtr->xmotion.state & ( ShiftMask | LockMask ) ) == 0) { if (saveMotion_) { motionX_ = eventPtr->xmotion.x; motionY_ = eventPtr->xmotion.y; } motionState_ = eventPtr->xmotion.state; if (!motionPending_) { if (motionState_ == 0 && zoomSpeed_ >= 0) { // speed up zoom if no keys or mouse buttons are pressed processMotionEvent(); } else { // slow down zoom if buttons are pressed, or zoomSpeed is // negative, since it might drag down the performance for drawing, etc... motionPending_ = 1; Tk_DoWhenIdle(motionProc, (ClientData)this); } } } } /* * This method is called for ConfigureNotify events in the image window * (when the image window is resized). * Make sure it is redrawn. */ void RtdImage::configureNotify(XEvent* eventPtr) { if (image_ && displaymode() == 1) { if (dbl_) dbl_->log("configureNotify: %d, %d\n", eventPtr->xconfigure.width, eventPtr->xconfigure.height); resetImage(); } } /* * This static method is called, if needed, when there is nothing else to do * to update the zoom window and other motion sensitive widgets */ void RtdImage::motionProc(ClientData clientData) { RtdImage* thisPtr = (RtdImage*)clientData; if (thisPtr) { thisPtr->motionPending_ = 0; thisPtr->processMotionEvent(); } } /* * this virtual method is called for motion events to update the zoom window * and set trace variables based on the current mouse position. */ void RtdImage::processMotionEvent() { if (image_ && xImage_ && xImage_->data() ) { double x = motionX_, y = motionY_; screenToImageCoords(x, y, 0); // there are 2 different kinds of zoom windows implemented... if (zoomView_ || zoomView2_) { autoZoomView(x, y); } else if (zoomer_) { double zx = motionX_, zy = motionY_; screenToXImageCoords(zx, zy); zoomer_->zoom(xImage_->data(), int(zx), int(zy), xImage_->bytesPerLine(), xImage_->height(), image_->xScale(), image_->yScale(), colors_->pixelval(0)); } // update a global Tcl array with the current x, y, pixval, ra, dec, equinox // values for speedy trace update in Tk. The array has the same name as // the main image and is indexed by X, Y, VALUE, RA, DEC, EQUINOX. char xStr[32], yStr[32], valueStr[32], raStr[32], decStr[32], equinoxStr[32]; char* var = (viewMaster_ ? viewMaster_->instname_ : instname_); double rx = x, ry = y; imageToRawImageCoords(rx, ry); image_->getValues(x, y, rx, ry, xStr, yStr, valueStr, raStr, decStr, equinoxStr); Tcl_SetVar2(interp_, var, "X", xStr, TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "Y", yStr, TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "VALUE", valueStr, TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "RA", raStr, TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "DEC", decStr, TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "EQUINOX", equinoxStr, TCL_GLOBAL_ONLY); // update the pixtab trace variables, if necessary // (ease up when B3 is pressed, due to measure band...) if (pixTab_ && (motionState_ & Button1Mask & Button3Mask) == 0) { char indexStr[32]; int w = pixTabCols_+1; double d; double sum=0.0, sumsq=0.0, minv, maxv, rms, ave; int npix=0; int maxx = 0, maxy = 0, minx = 0, miny = 0; image_->getValues(x, y, rx, ry, pixTab_, pixTabRows_, pixTabCols_); for(int j = 0; j <= pixTabRows_; j++) { for(int i = 0; i <= pixTabCols_; i++) { sprintf(indexStr, "%d,%d", j, i); // not outside image ? if ((d = pixTab_[j*w+i]) > -HUGE_VAL) { if (i && j) { sprintf(valueStr, "%g", d); // pix value // calculate statistics on pixels if (npix == 0) { minv = d; maxv = d; maxx = minx = j; maxy = miny = i; } npix++; sum += d; sumsq += d * d; if (d < minv) { minv = d; minx = j; miny = i; } if (d > maxv) { maxv = d; maxx = j; maxy = i; } } else sprintf(valueStr, "%.1f", d); // x,y index } else { *valueStr = '\0'; // pixel is outside of image } Tcl_SetVar2(interp_, var, indexStr, valueStr, TCL_GLOBAL_ONLY); } } if (npix > 0) { ave = sum / (double)npix; sprintf(valueStr, "%g", ave); // average Tcl_SetVar2(interp_, var, "PIXTAB_AVE", valueStr, TCL_GLOBAL_ONLY); sprintf(valueStr, "%g", minv); // min Tcl_SetVar2(interp_, var, "PIXTAB_MIN", valueStr, TCL_GLOBAL_ONLY); sprintf(valueStr, "%g", maxv); // max Tcl_SetVar2(interp_, var, "PIXTAB_MAX", valueStr, TCL_GLOBAL_ONLY); sprintf(valueStr, "%d", npix); // npix Tcl_SetVar2(interp_, var, "PIXTAB_N", valueStr, TCL_GLOBAL_ONLY); sprintf(valueStr, "%d", maxx); // maxx Tcl_SetVar2(interp_, var, "PIXTAB_MAXX", valueStr, TCL_GLOBAL_ONLY); sprintf(valueStr, "%d", maxy); // maxy Tcl_SetVar2(interp_, var, "PIXTAB_MAXY", valueStr, TCL_GLOBAL_ONLY); sprintf(valueStr, "%d", minx); // minx Tcl_SetVar2(interp_, var, "PIXTAB_MINX", valueStr, TCL_GLOBAL_ONLY); sprintf(valueStr, "%d", miny); // miny Tcl_SetVar2(interp_, var, "PIXTAB_MINY", valueStr, TCL_GLOBAL_ONLY); } else { Tcl_SetVar2(interp_, var, "PIXTAB_AVE", "\0", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "PIXTAB_MIN", "\0", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "PIXTAB_MAX", "\0", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "PIXTAB_N", "\0", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "PIXTAB_MAXX", "\0", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "PIXTAB_MAXY", "\0", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "PIXTAB_MINX", "\0", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "PIXTAB_MINY", "\0", TCL_GLOBAL_ONLY); } if (npix > 1) { rms = sqrt((sumsq - ((sum * sum) / npix)) / (npix -1)); sprintf(valueStr, "%g", rms); // rms Tcl_SetVar2(interp_, var, "PIXTAB_RMS", valueStr, TCL_GLOBAL_ONLY); } else { Tcl_SetVar2(interp_, var, "PIXTAB_RMS", "\0", TCL_GLOBAL_ONLY); } } } } /* * this virtual method is called for motion events when * a "zoomview" is being used. x and y are the image * coordinates distance from origin. */ void RtdImage::autoZoomView(double x, double y) { if (image_) { coordsToDist(x, y); updateZoomView(zoomView_, x, y); updateZoomView(zoomView2_, x, y); } } /* * update the given zoom view. x and y are the image coordinate offsets */ void RtdImage::updateZoomView(RtdImage* view, double x, double y) { if (view && view->image_) { double rw = view->reqWidth_, rh = view->reqHeight_; view->undoTrans(rw, rh, 1); // get only visible area view->xOffset_ = x - rapidX_ - rw/2.0 - frameX_; view->yOffset_ = y - rapidY_ - rh/2.0 - frameY_; view->updateView(image_, 1); } } /* * This method is called to notify the panning window of the coords * of the visible image. If the size or position of the visible part * of the image has changed, evaluate the panning command with the * new coordinates and a flag indicating whether the image is new or * just an update. * newImageFlag is set to one if a new image was loaded from file or * shared memory. */ void RtdImage::autoPan(int newImageFlag) { int x1 = -canvasX_; if (x1 < 0) x1 = 0; int y1 = -canvasY_; if (y1 < 0) y1 = 0; int w = dispWidth(), h = dispHeight(); int x2 = x1+Tk_Width(tkwin_)-1; if (x2 >= (w-1)) x2 = w-1; if (x2 <= x1) x2 = x1+1; int y2 = y1+Tk_Height(tkwin_)-1; if (y2 >= (h-1)) y2 = h-1; if (y2 <= y1) y2 = y1+1; // if the coords have changed... if (newImageFlag || x1 != panx1_ || y1 != pany1_ || x2 != panx2_ || y2 != pany2_) { // save the coords panx1_ = x1; pany1_ = y1; panx2_ = x2; pany2_ = y2; // make sure the coords are in range and take the scale factors of // both the pan image and the target image into account int xs = image_->xScale(), ys = image_->yScale(); if (xs > 0) { x1 /= (xs * -panFactor_); x2 /= (xs * -panFactor_); } else { x1 = (x1 * xs) / panFactor_; x2 = (x2 * xs) / panFactor_; } if (ys > 0) { y1 /= (ys * -panFactor_); y2 /= (ys * -panFactor_); } else { y1 = (y1 * ys) / panFactor_; y2 = (y2 * ys) / panFactor_; } char buf[1024]; sprintf(buf, "%s %d %d %d %d %d", panCommand_, x1, y1, x2, y2, newImageFlag); if (Tcl_Eval(interp_, buf) != TCL_OK) { Tk_BackgroundError(interp_); panCommand_ = NULL; } } } /* * Make a new image from the given ImageIO object and return a pointer to * a derived class of ImageData specialized in that type of image. * * Note that pointers to ImageIORep subclasses, such as FitsIO are * automatically converted to an ImageIO object through a special * constructor. In this way, you can add new image types by deriving a * new classes in the same way as the FitsIO class (from ImageIORep). * * imio - is a reference to an ImageIO object for the image (or ptr, see * above). */ ImageData* RtdImage::makeImage(ImageIO imio) { return ImageData::makeImage(name(), imio, biasimage_->biasInfo(), verbose()); } /* * Return true if no image is loaded. * * PWD: don't use image size (of 2x2), use OBJECT "RTD_BLANK" value instead. */ int RtdImage::isclear() { if ( image_ ) { const char *object = image_->object(); if ( ! object || object && strcmp( "RTD_BLANK", object ) != 0 ) { return 0; } } return 1; } /* * This method is called to update with new colors if needed. A * forced color update will be necessary when using X visuals which do * not support read-write colour cells. */ int RtdImage::colorUpdate( int force ) { if ( colors_->readOnly() || force ) { if (image_) { image_->colorScale(colors_->colorCount(), colors_->pixelval()); // Make sure new lookup table is propagated. LookupTable lookup = image_->lookupTable(); for(int i = 0; i < MAX_VIEWS; i++) { if (view_[i] && view_[i]->image_ && !view_[i]->isSeparateRapidFrame()) view_[i]->image_->lookupTable(lookup); } } return updateViews(1) || updateImage(); } return TCL_OK; } /* * initialize the bias image object */ int RtdImage::initBias() { // we should do this only once if (biasimage_) return TCL_OK; // create bias image object RtdImage::biasimage_ = new BiasData(); return TCL_OK; } /* * initialize the performance object */ int RtdImage::initPerf(Tcl_Interp* interp) { // we should do this only once if (rtdperf_) return TCL_OK; // create performance object RtdImage::rtdperf_ = new RtdPerf(interp); return TCL_OK; } // RtdImage signal handler void RtdImage_cleanup(int sig) { Mem_RPTcleanup(); // cleanup shm of Rtd Recorder/Playback tool Mem_cleanup(sig); // cleanup shm of RtdImage and exit } skycat-3.1.2-starlink-1b/rtd/generic/RtdImage.h000066400000000000000000000520051215713201500212110ustar00rootroot00000000000000#ifndef _RtdImage_h_ #define _RtdImage_h_ /* * E.S.O. - VLT project / ESO Archive * "@(#) $Id: RtdImage.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * RtdImage.h - class definitions for class RtdImage, a real-time image * display extension for Tk. * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * D.Hopkinson 02/12/96 Added timestamp information for performance tool * Allan Brighton 10/03/98 Added optional args to constructor to allow derived * class to specify its own configuration options. * loadFile now virtual to aid subclassing. * Allan Brighton 13/03/98 Define RTD_OPTIONS as a macro, so that derived * classes can add new options more easily. * Peter W. Draper 13/01/99 Added changes to support non 8 bit * colors (colorUpdate). * Made displayImageEvent virtual (need for UKIRT * quick look updates). * P.Biereichel 22/03/99 Added code for bias subtraction * P.Biereichel 29/06/99 Added HDU includes (copied from skycat) * P.Biereichel 26/05/00 Added options fillWidth / fillHeight * P.Biereichel 01/03/01 Copied the include and definitions from RtdImage.C * P.Biereichel 23/10/02 Made gcc 3.2 happy which complained about RTD_OPTION: * (invalid offsetof from non-POD type `class RtdImageOptions'; use * pointer to member instead). POD means "Plain Old Data". * Peter W. Draper 04/08/09 Added optionModified member to recover * functionality lost in Tk 8.5. * pbiereic 10/08/07 increased MAX_VIEWS from 8 to 64 * */ #define PANEL_EDITOR_BUG #define _HAVE_R6 (XlibSpecificationRelease > 5) //#define DEBUG #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "define.h" #include "error.h" #include "WorldCoords.h" #include "ImageColor.h" #include "ImageDisplay.h" #include "ImageData.h" #include "ImageZoom.h" #include "Fits_IO.h" #include "RtdCamera.h" #include "RtdRemote.h" #include "rtdImageEvent.h" #include "BiasData.h" #include "ImageData.h" #include "RtdPerf.h" #include "RtdUtils.h" #include "TkImage.h" // we use pointers to classes of these types below class ImageColor; class ImageDisplay; class ImageData; class BiasData; class ImageZoom; class RtdCamera; class RtdRemote; class Mem; class RtdImage; class RtdPerf; // RtdImage signal handlers void RtdImage_cleanup (int); // cleanup shm routine of Rtd Recorder/Playback tool void Mem_RPTcleanup(); // from BLT package (now locally because this routine was deleted with blt2.1) extern "C" int Blt_GraphElement( Tcl_Interp *interp, /* Interpreter of the graph widget */ char *pathName, /* Path name of the graph widget */ char *elemName, /* Name of the element to reset */ int numValues, /* Number of values in array */ double *valueArr, /* Array of x,y coordinate pairs */ char *xVector, /* Name of x array */ char *yVector); /* Name of y array */ /* * image options (used for image configuration) */ typedef struct Rtd_Options { int displaymode; // set mode used to display image: // 0 ==> XImage is size of image, update whole image to pixmap // 1 ==> XImage is size of window (default mode) int fitWidth; // fit the image in a window with this width int fitHeight; // and this height by shrinking the image int fillWidth; // fit the image in a window with this width int fillHeight; // and this height by shrinking or expanding the image int subsample; // if true, don't count neighboring pixels when shrinking image int sampmethod; // sampling method int usexshm; // if true, use X shared memory if available. int usexsync; // if true, use X synchronisation if available. int verbose; // if true, print program info to stdout int debug; // if true, print program info to stdout int shm_header; // if true, keep image FITS headers in shared memory int shm_data; // if true, keep image FITS data in shared memory // (see RtdRemote remote access interface) int min_colors; // min (max) number of colors to allocate, if this many are int max_colors; // not available, use private colormap. char* file; // name of image file, if any char* name; // name for image (for debugging) char* newImageCmd; // tcl command to evaluate whenever a new (different) // image is loaded (for updates, see camera command) int fixUpdateRate; // flag: user has specified a fixed update rate, as below. double userUpdateTime; // the minimum time between updates, as specified // by the user. } Rtd_Options; class RtdImageOptions : public TkImageOptions { public: // constructor RtdImageOptions() { rtd_options_ = new Rtd_Options; manage = 1; initialise(); } RtdImageOptions( Rtd_Options *options ) { rtd_options_ = options; manage = 0; initialise(); } struct Rtd_Options *rtd_options_; int manage; // Accessors virtual char *get_rtd_options() {return (char *)rtd_options_;} // destructor virtual ~RtdImageOptions() { if ( manage ) { delete rtd_options_; } } private: void initialise() { memset(rtd_options_, '\0', sizeof(Rtd_Options)); rtd_options_->displaymode=1; rtd_options_->usexshm=1; rtd_options_->usexsync=1; rtd_options_->min_colors=30; rtd_options_->max_colors=60; } }; /* * These options are defined here for use in the Tk_ConfigSpec declaration, so that * derived classes can more easily add to them. See RtdImage.C for usage. */ #define RTD_OPTION(x) Tk_Offset(Rtd_Options, x) #define RTD_OPTIONS \ {TK_CONFIG_BOOLEAN, (char *)"-usexshm", NULL, NULL, "1", RTD_OPTION(usexshm), 0}, \ {TK_CONFIG_BOOLEAN, (char *)"-usexsync", NULL, NULL, "1", RTD_OPTION(usexsync), 0}, \ {TK_CONFIG_BOOLEAN, (char *)"-verbose", NULL, NULL, "0", RTD_OPTION(verbose), 0}, \ {TK_CONFIG_BOOLEAN, (char *)"-debug", NULL, NULL, "0", RTD_OPTION(debug), 0}, \ {TK_CONFIG_BOOLEAN, (char *)"-shm_header", NULL, NULL, "0", RTD_OPTION(shm_header), 0}, \ {TK_CONFIG_BOOLEAN, (char *)"-shm_data", NULL, NULL, "0", RTD_OPTION(shm_data), 0}, \ {TK_CONFIG_INT, (char *)"-displaymode", NULL, NULL, "1", RTD_OPTION(displaymode), 0}, \ {TK_CONFIG_INT, (char *)"-min_colors", NULL, NULL, "1", RTD_OPTION(min_colors), 0}, \ {TK_CONFIG_INT, (char *)"-max_colors", NULL, NULL, "1", RTD_OPTION(max_colors), 0}, \ {TK_CONFIG_INT, (char *)"-fitwidth", NULL, NULL, "0", RTD_OPTION(fitWidth), 0}, \ {TK_CONFIG_INT, (char *)"-fitheight", NULL, NULL, "0", RTD_OPTION(fitHeight), 0}, \ {TK_CONFIG_INT, (char *)"-fillwidth", NULL, NULL, "0", RTD_OPTION(fillWidth), 0}, \ {TK_CONFIG_INT, (char *)"-fillheight", NULL, NULL, "0", RTD_OPTION(fillHeight), 0}, \ {TK_CONFIG_BOOLEAN, (char *)"-subsample", NULL, NULL, "1", RTD_OPTION(subsample), 0}, \ {TK_CONFIG_INT, (char *)"-sampmethod", NULL, NULL, "0", RTD_OPTION(sampmethod), 0}, \ {TK_CONFIG_STRING, (char *)"-file", NULL, NULL, "", RTD_OPTION(file), 0}, \ {TK_CONFIG_STRING, (char *)"-newimagecmd", NULL, NULL, "", RTD_OPTION(newImageCmd), 0}, \ {TK_CONFIG_STRING, (char *)"-name", NULL, NULL, "", RTD_OPTION(name), 0} /* * Class RtdImage * * This class implements the extended Tk image type "rtdimage" for displaying * FITS and other images in a Tk canvas window */ class RtdImage : public TkImage { #include "RtdCmds.icc" // image subcommand methods #include "RtdHDU.icc" // methods for hduCmd() #include "RtdCoords.icc" // methods for coordinate conversion protected: RtdImageOptions* options_; // holds image config options RtdCamera* camera_; // class managing interface to realtime image events RtdRemote* remote_; // class managing remote control interface char* cameraPreCmd_; // Tcl command to evaluate when image event is received (before display) char* cameraPostCmd_; // Tcl command to evaluate after image event has been processed int imageEvent_; // image event received from camera int frameId_; // frame Id, for use with rapid frames static ImageColor* colors_; // class for managing colors and colormaps ImageData* image_; // class object managing the image data RtdDebugLog* dbl_; // class object managing the debug log messages static BiasData* biasimage_;// class for managing the bias image static RtdPerf* rtdperf_; // class object for managing the performance test char filename_[1024]; // filename or object of master image ImageZoom* zoomer_; // class for managing zoom window RtdImage* zoomView_; // rtdimage instance used for "zoomview" RtdImage* zoomView2_; // optional second rtdimage instance used for additional "zoomview" int zoomFactor_; // relative magnification for zoom int zoomSpeed_; // normally 0 (fast), or < 0 (slow updates) int motionX_, motionY_; // saved motion event position int saveMotion_; // save motion event flag int motionPending_; // flag for doWhenIdle handler for motion events unsigned int motionState_; // saved state field from motion event int propagateScale_; // flag: if true and this is a view, propagate changes // in magnification from master image to this image int autoSetCutLevels_; // flag: if true we can set cut levels automatically // on new images, otherwise keep previous cut levels int rapidFrame_; // flag: if true, this is a rapid frame int displayLocked_; // flag: true if image is currently being updated // views (copy of image sharing same raw data) enum {MAX_VIEWS = 64}; // maximum number of views of an image RtdImage* view_[MAX_VIEWS]; // array of views (tkimage widgets) RtdImage* viewMaster_; // the image this image is a view of RtdImage* currentView_; // cur view, when more than one image is in a canvas // The following distances are normally 0, but might be non-zero for the // zoom window or a rapid frame. They are all stored as image coordinate distances // and converted to canvas coords as needed, to be independent of transformations. double frameX_, frameY_; // X,Y offset of image frame in image canvas double xOffset_, yOffset_; // X,Y offset of image origin in raw image. // note: this is needed since rapid frames have a separate memory area starting // at 0,0, but which corresponds to (rapidX_,rapidY_) in the main image double rapidX_, rapidY_; // X,Y offset of rapid frame coresponding to main image. double reqWidth_, reqHeight_; // requested width and height or 0 for entire image // panning window int panFactor_; // shrink (scale) factor for panning window char* panCommand_; // Tcl command to evaluate when image changes size or pos. int panx1_, pany1_; // saved coords of upper left of visible image int panx2_, pany2_; // saved coords of lower right of visible image // Tk canvas window info Tk_Canvas canvas_; // handle for image's canvas window const char* canvasName_; // name of canvas window int canvasX_, canvasY_; // X,Y offset of image in canvas (for scrolling) int prevX_, prevY_; // saved X,Y origin from last display update // X shared memory int haveXShm_; // flag: true if X shared memory is available int usingXShm_; // flag: true if we are using X shared memory // X Sync extension (the XSyncSetPriority function is used). int haveXSync_; // flag: true if X synchronisation is available int usingXSync_; // flag: true if we are using XSync // X image ImageDisplay* xImage_; // class object: manages the X Image // Pixel Table double* pixTab_; // array of pixel values and X,Y indices int pixTabRows_, // dimensions of pixTab_ (minus 1 for x,y headings) pixTabCols_; // -- member functions -- private: // copy constructor: not defined RtdImage(const RtdImage&); protected: // redefined from parent class to check configuration options virtual int configureImage(int argc, char* argv[], int flags); // test if an option has been modified during the configureImage. int optionModified(int argc, char *argv[], const char* option); // return true if this is an embedded (not embedded) rapid frame (in master image) int isEmbeddedRapidFrame(); int isSeparateRapidFrame(); // set the X,Y scale (zoom) factors int setScale(int xScale, int yScale); // set the cut levels to the given min and max values int setCutLevels(double min, double max, int scaled, int user); // called for new image or when image changes size to update pixmap // and XImage and redraw int resetImage(); // call resetImage when idle void eventuallyResetImage(); // Return an ImageData object, given an ImageIO object reference. virtual ImageData* makeImage(ImageIO); // load an image file virtual int loadFile(); // called to initialize a new image from a file or shared memory int initNewImage(); // called to force image to be redrawn int updateImage(); // called to update an existing image with new raw data of the same size and type int updateImageNewData(const Mem&); // delete the XImage created by updateXImage int deleteXImage(); // add/remove views, to be updated with this image int addView(RtdImage* view); int removeView(RtdImage* view); void removeViews(); // update this image with a new view from the master image int updateView(ImageData*, int flag = 0); // update all views int updateViews(int flag = 0); // get class object from instance name RtdImage* getView(char* name); // called when idle for motion events in the image virtual void processMotionEvent(); // zooming methods, when using rtdimage view virtual void autoZoomView(double x, double y); virtual void updateZoomView(RtdImage* view, double x, double y); // called to notify the panning window of the coords of the visible image virtual void autoPan(int newImageFlag = 0); // event methods, called for motion/configure events in image window virtual void motionNotify(XEvent* eventPtr); virtual void configureNotify(XEvent* eventPtr); // these are called indirectly by the Tk imageing routines virtual void displayImage( Drawable, int imageX, int imageY, int width, int height, int drawableX, int drawableY); virtual TkImage* getImage(Tk_Window); // get fraction of zoomed pixel at point void getOffsetInXImage(double px, double py, int& x, int& y); // propagate color change int colorUpdate( int force = 0); // Set detector parameters void setDetParms(ImageData* image, const rtdIMAGE_INFO&); // set or query the filename of the master image void filename(char *file) {strcpy(filename_, file);} char* filename() {return filename_;} public: // initialize the image with the command line args RtdImage(Tcl_Interp*, const char* instname, int argc, char** argv, Tk_ImageMaster master, const char* imageType, Tk_ConfigSpec* specs = (Tk_ConfigSpec*)NULL, RtdImageOptions* options = (RtdImageOptions*)NULL); // destructor - free any allocated resources ~RtdImage(); // call a member function by name virtual int call(const char* name, int len, int argc, char* argv[]); // initialize color map and visual static int initColors(Tcl_Interp* interp); // initialize bias image object static int initBias(); // initialize performance test object static int initPerf(Tcl_Interp* interp); // entry point from tcl to create a image static int CreateImage(Tcl_Interp*, char *name, int argc, #if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >= 3 Tcl_Obj *CONST objv[], #else char **argv, #endif Tk_ImageType*, Tk_ImageMaster, ClientData*); // event procedure for main image window static void eventProc(ClientData clientData, XEvent *eventPtr); // doWhenIdle handler for zoom window static void motionProc(ClientData clientData); // called from the Camera class to display image from shared memory virtual int displayImageEvent(const rtdIMAGE_INFO&, const Mem& data); // utility Tcl command proc to set colormap for popup windows static int rtd_set_cmap(ClientData, Tcl_Interp* interp, int argc, char** argv); // update idle tasks and performance test variables void updateRequests(); // read-only access to configuration options static ImageColor* colors() {return colors_;} static RtdPerf* rtdperf() {return rtdperf_;} int displaymode() const {return options_->rtd_options_->displaymode;} int fitWidth() const {return options_->rtd_options_->fitWidth;} int fitHeight() const {return options_->rtd_options_->fitHeight;} int fillWidth() const {return options_->rtd_options_->fillWidth;} int fillHeight() const {return options_->rtd_options_->fillHeight;} int subsample() const {return options_->rtd_options_->subsample;} int sampmethod() const {return options_->rtd_options_->sampmethod;} char* file() const {return options_->rtd_options_->file;} char* newImageCmd() const {return options_->rtd_options_->newImageCmd;} char* name() const {return ((options_->rtd_options_->name && *options_->rtd_options_->name) ? options_->rtd_options_->name : instname_);} int usexshm() const {return options_->rtd_options_->usexshm;} int usexsync() const {return options_->rtd_options_->usexsync;} int shm_header() const {return options_->rtd_options_->shm_header;} int shm_data() const {return options_->rtd_options_->shm_data;} int min_colors() const {return options_->rtd_options_->min_colors;} int max_colors() const {return options_->rtd_options_->max_colors;} int verbose() const {return options_->rtd_options_->verbose;} int debug() const {return options_->rtd_options_->debug;} // -- short cuts -- // return the dimensions of the image after transformations int dispWidth() {return (image_ ? image_->dispWidth() : 1);} int dispHeight() {return (image_ ? image_->dispHeight() : 1);} // return the type of the raw image data int imageType() {return (image_ ? image_->dataType() : UNKNOWN_IMAGE);} // return true if there is an image and it supports world coordinates int isWcs() {return (image_ ? image_->wcs().isWcs() : 0);} // Return true if no image is loaded. int isclear(); // Return name of instance (= tcl command which corresponds to this image) char* instname() {return instname_;} // member access char* cameraPreCmd() {return cameraPreCmd_;} char* cameraPostCmd() {return cameraPostCmd_;} // Set state of image event (currently true/false) int imageEvent(int state) {return ( imageEvent_ = state );} ImageData* image() {return image_;} }; /* * derive a Camera subclass that handles the image events * for loading images from shared memory */ class RtdImageCamera : public RtdCamera { RtdImage* rtdimage_; // keep this ptr for calling display method public: // constructor RtdImageCamera(RtdImage* rtdimage) : RtdCamera(rtdimage->name(), rtdimage->interp(), rtdimage->verbose(), rtdimage->debug(), rtdimage->instname()), rtdimage_(rtdimage) {} // called from the Camera class to display image from shared memory. // pass on the method in RtdImage class int display(const rtdIMAGE_INFO&, const Mem& data); }; /* * derive a RtdRemote subclass that handles the remote access to * the widget. * * This class is a bit different than the above RtdImageCamera class. It * is designed to be of more general use (not just for real-time updates) * and doesn't make use of the rtdServer daemon. */ class RtdImageRemote : public RtdRemote { RtdImage* rtdimage_; // keep this ptr for calling display method public: // constructor RtdImageRemote(RtdImage* rtdimage, int port) : RtdRemote(rtdimage->interp(), port, rtdimage->verbose()), rtdimage_(rtdimage) {} // call an rtdimage command method by name int call(const char* name, int len, int argc, char* argv[]) { return rtdimage_->call(name, len, argc, argv); } }; #endif /* _RtdImage_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/RtdPerf.C000066400000000000000000000164161215713201500210240ustar00rootroot00000000000000/* * E.S.O. - VLT project * * "@(#) $Id: RtdPerf.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * RtdPerf.C - member functions for class RtdPerf * * RtdPerf is a class for managing the performance test * * who when what * -------------- -------- ---------------------------------------- * P. Biereichel 01/03/01 Created */ /************************************************************************ * NAME * RtdPerf - class for managing the performance test * * SYNOPSIS * #include "RtdPerf.h" * RtdPerf::RtdPerf(Tcl_Interp* interp, int verbose, int debug) * Tcl_Interp* - pointer to a Tcl_Interp structure * verbose - verbose flag * debug - debug flag * * DESCRIPTION * * PUBLIC METHODS * * void RtdPerf::timeInc(double *timevar) * Adds the delta timestamp to 'timevar'. Delta is the time between calls * to this method. * * void RtdPerf::newCycle() * This method is called when a new image event cycle starts. It * initializes the time variables and the start timestamp. * * void RtdPerf::endCycle() * This method is called when a new image event cycle ends. It * calculates the statistics on the time varibales and set the * global Tcl variables which are prefixed with 'PERF_' * * void RtdPerf::reset() * Resets the time variables and Tcl variables * * void RtdPerf::on() * Switches performance test on. It sets the protected member variable * maybeOn_ which indicates that the test will be started as soon as * there is a new image event. * * FILES * * ENVIRONMENT * * CAUTIONS * * SEE ALSO * RtdImage(3) * * BUGS * *------------------------------------------------------------------------ */ #include "RtdPerf.h" RtdPerf::RtdPerf(Tcl_Interp* interp) : interp_(interp), on_(0), verbose_(0), debug_(0), maybeOn_(0), imageCount_(0.0), GENtime_(0.0), TCLtime_(0.0), Xtime_(0.0), FREQtime_(0.0), lastTimeStamp_(0.0), startTime_(0.0), accGENtime_(0.0), accTCLtime_(0.0), accXtime_(0.0), accFREQtime_(0.0) { name((char *)""); dbl_ = new RtdDebugLog((char *)"RtdPerf", (int)0); reset(); } RtdPerf::~RtdPerf() { if (dbl_) { delete dbl_; dbl_ = NULL; } } /* * This routine is called as part of the interactive performance testing. * It evaluates the time between the present and the last timestamp, and * increments the variable pointed to be the argument. * * Arguments: * double *timeval - address of performance indicator to be incremented. */ void RtdPerf::timeInc(double *timevar) { if (! isOn()) // Return immediately if the testing is not activated return; struct timeval currentTime; double curTimeStamp; // Get the current time. gettimeofday(¤tTime, NULL); curTimeStamp = (double)currentTime.tv_sec + (double)currentTime.tv_usec / 1.0e+6; (*timevar) += curTimeStamp - lastTimeStamp_; // Increment the appropriate variable lastTimeStamp_ = curTimeStamp; // Update the last timestamp } /* * This routine is triggered by receipt of an image event, * and sets the timestamp information for the beginning of a cycle. */ void RtdPerf::newCycle() { if (maybeOn()) on(1); if ( ! isOn() ) return; dbl_->setlog(verbose_ & debug_); dbl_->log("Starting image event cycle: %s\n", name()); // Reset the performance variables. GENtime_ = 0.; TCLtime_ = 0.; Xtime_ = 0.; timeInc(&FREQtime_); // set lastTimeStamp_ to current time } /* * This routine sets the variables of the performance test indicator form, * when it is realised. */ void RtdPerf::endCycle() { if ( ! isOn() ) // performance testing is not activated return; char* var = name(); dbl_->log("Ended image event cycle: %s\n", name()); imageCount_++; // Set the frequency Tcl variables. Needs at least two cycles if (imageCount_ > 1) { timeInc(&FREQtime_); // set lastTimeStamp_ to current time FREQtime_ = lastTimeStamp_ - startTime_; accFREQtime_ += FREQtime_; sprintf(buffer_, "%.3f", 1.0 / FREQtime_); Tcl_SetVar2(interp_, var, "PERF_FREQ", buffer_, TCL_GLOBAL_ONLY); sprintf(buffer_, "%.3f", (imageCount_ - 1.0) / accFREQtime_); Tcl_SetVar2(interp_, var, "PERF_FREQ_AVE", buffer_, TCL_GLOBAL_ONLY); } startTime_ = lastTimeStamp_; // Set the total time for the image event. double aveXtime, aveGENtime, aveTCLtime; // Accumulated averages double TOTtime = GENtime_ + Xtime_ + TCLtime_; // Accumulate times (these are total times over all images). accGENtime_ += GENtime_; accTCLtime_ += TCLtime_; accXtime_ += Xtime_; // Average all the totals. Times in % double aveTOTtime = (accGENtime_ + accTCLtime_ + accXtime_) / imageCount_; aveGENtime = accGENtime_ / imageCount_ * 100.0 / aveTOTtime; aveXtime = accXtime_ / imageCount_ * 100.0 / aveTOTtime; aveTCLtime = accTCLtime_ / imageCount_ * 100.0 / aveTOTtime; GENtime_ = GENtime_ * 100.0 / TOTtime; Xtime_ = Xtime_ * 100.0 / TOTtime; TCLtime_ = TCLtime_ * 100.0 / TOTtime; // Set the Tcl variables sprintf(buffer_, "%.0f", imageCount_); Tcl_SetVar2(interp_, var, "PERF_COUNT", buffer_, TCL_GLOBAL_ONLY); sprintf(buffer_, "%6.3f", GENtime_); Tcl_SetVar2(interp_, var, "PERF_GEN", buffer_, TCL_GLOBAL_ONLY); sprintf(buffer_, "%6.3f", Xtime_); Tcl_SetVar2(interp_, var, "PERF_XFUNC", buffer_, TCL_GLOBAL_ONLY); sprintf(buffer_, "%6.3f", TCLtime_); Tcl_SetVar2(interp_, var, "PERF_TCL", buffer_, TCL_GLOBAL_ONLY); sprintf(buffer_, "%8.3f", TOTtime * 1.0e+3); // in msec Tcl_SetVar2(interp_, var, "PERF_TOTAL", buffer_, TCL_GLOBAL_ONLY); // Do the same for the averaged amounts. sprintf(buffer_, "%6.3f", aveGENtime); Tcl_SetVar2(interp_, var, "PERF_GEN_AVE", buffer_, TCL_GLOBAL_ONLY); sprintf(buffer_, "%6.3f", aveXtime); Tcl_SetVar2(interp_, var, "PERF_XFUNC_AVE", buffer_, TCL_GLOBAL_ONLY); sprintf(buffer_, "%6.3f", aveTCLtime); Tcl_SetVar2(interp_, var, "PERF_TCL_AVE", buffer_, TCL_GLOBAL_ONLY); sprintf(buffer_, "%6.3f", aveTOTtime * 1.0e+3); // in msec Tcl_SetVar2(interp_, var, "PERF_TOTAL_AVE", buffer_, TCL_GLOBAL_ONLY); } void RtdPerf::reset() { char* var = name(); dbl_->log("Reset performance data: %s\n", name()); on(0); imageCount_ = 0.0; lastTimeStamp_ = startTime_ = 0.0; GENtime_ = TCLtime_ = Xtime_ = FREQtime_ = 0.0; accGENtime_ = accTCLtime_ = accXtime_ = accFREQtime_ = 0.0; // Clear the Tcl variables. Tcl_SetVar2(interp_, var, "PERF_COUNT", '\0', TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "PERF_FREQ", '\0', TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "PERF_GEN", '\0', TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "PERF_XFUNC", '\0', TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "PERF_TCL", '\0', TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "PERF_TOTAL", '\0', TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "PERF_FREQ_AVE", '\0', TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "PERF_GEN_AVE", '\0', TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "PERF_XFUNC_AVE", '\0', TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "PERF_TCL_AVE", '\0', TCL_GLOBAL_ONLY); Tcl_SetVar2(interp_, var, "PERF_TOTAL_AVE", '\0', TCL_GLOBAL_ONLY); } skycat-3.1.2-starlink-1b/rtd/generic/RtdPerf.h000066400000000000000000000046131215713201500210650ustar00rootroot00000000000000// -*-c++-*- #ifndef _RtdPerf_h_ #define _RtdPerf_h_ /* * E.S.O. - VLT project * * RtdPerf.h - class definitions for managing the performance data. * * who when what * -------------- -------- ---------------------------------------- * pbiereic 01/03/01 Created */ #include #include #include #include #include "RtdUtils.h" class RtdPerf { public: // Constructor RtdPerf(Tcl_Interp* interp); // Destructor ~RtdPerf(); // Add delta time to 'timevar' void timeInc(double *timevar); // Start a new cycle void newCycle(); // End a cycle and set the Tcl global variables void endCycle(); // Reset the time variables and Tcl global variables void reset(); // Switch performance test on void on() {maybeOn_ = 1; on_ = 0;} void on(int set) {on_ = set;} // Switch performance test on void off() {maybeOn_ = 0; on_ = 0;} // Set verbose and debug flag void verbose(int set) {verbose_ = set;} void debug(int set) {debug_ = set;} // Set the instance name of the RtdImage (used for global Tcl variables) void name(char *nam) {strcpy(name_, nam);} // -- short cuts -- void GENtime() {timeInc(&GENtime_);} void TCLtime() {timeInc(&TCLtime_);} void Xtime() {timeInc(&Xtime_);} protected: RtdDebugLog *dbl_; // debug log object Tcl_Interp* interp_; // Tcl interp (for file events, error handling) int on_; // Flag: test is switched on/off int verbose_; // Verbose flag int debug_; // Debug flag int maybeOn_; // Switch test on when a new cycle start double imageCount_; // Image counter double GENtime_; // Time spent in general code processing within a image event cycle double TCLtime_; // Time spent in Tcl code double Xtime_; // Time spent for X updates double FREQtime_; // Frequency of image event cycle double lastTimeStamp_;// Last time stamp double startTime_; // Start time of cycle // Accumulated times double accGENtime_; double accTCLtime_; double accXtime_; double accFREQtime_; char name_[100]; char buffer_[2048]; // -- short cuts -- char* name() {return(name_);} int isOn() {return on_;} int maybeOn() {return maybeOn_;} }; #endif /* _RtdPerf_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/RtdPerformanceTool.C000066400000000000000000000225751215713201500232320ustar00rootroot00000000000000/* * E.S.O. - VLT project * "@(#) $Id: RtdPerformanceTool.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * RtdPerformanceTool.C - member routines for class RtdPerformanceTool, * manages manipulation of performance data * * who when what * -------------- -------- ---------------------------------------- * D.Hopkinson 21/11/96 Created * A.Brighton 08/12/97 added cast and fixed "new" expr for SunPro CC */ #include "RtdPerformanceTool.h" #include "tcl.h" #include #include #include /* * Const array of process type identifiers for performance testing. * e.g. PKT = packet transfer, TCL = tcl code interpretation. */ const char *rtdEventDesc[] = {"PKT_", "MEM_", "GEN_", "TCL_", "X_"}; const int numIdentifiers = 5; /* * Constructor function - just initialise the timeIndex. * * Arguments: * None */ RtdPerformanceTool::RtdPerformanceTool() : timeIndex(0), verbose_(1), active_(0) { } /* * Destructor function. */ RtdPerformanceTool::~RtdPerformanceTool() { } /* * Add a timestamp to the performance test data. This routine is called through * a buffer method in RtdCamera when timestamping RtdImage processes, which * prevents timestamping when the tool is not active. When called directly * from an RtdCamera process, this routine ensures that the tool becomes * active. * * Arguments: * char *evDesc - event description * * Return value: * None */ void RtdPerformanceTool::timeStamp(char *evDesc) { // Activate the tool. active_ = 1; // Timestamp. if (timeIndex < RTD_NUMSHM * RTD_NUMTMSTMPS) { gettimeofday(&timeStamps[timeIndex], NULL); sprintf(evDescs[timeIndex++], "%s", evDesc); } else { fprintf(stderr, "Warning: too many timestamps produced\n"); } } /* * Add a timestamp to the performance test data, as above. This routine is * called when the image information is first received by the RTD, and * examines the image information structure to extract the timestamp. * * Arguments: * rtdIMAGE_INFO *imageInfo - the image information structure * * Return value: * None */ void RtdPerformanceTool::timeStamp(const rtdIMAGE_INFO *imageInfo) { // activate the tool. active_ = 1; // Timestamp if (timeIndex < RTD_NUMSHM * RTD_NUMTMSTMPS) { sprintf(evDescs[timeIndex], "SEND"); memcpy(&timeStamps[timeIndex++], (void *)&imageInfo->timeStamp, sizeof(struct timeval)); } else { fprintf(stderr, "Warning: too many timestamps produced\n"); } } /* * Dump the performance data (held in the timeStamps array) to file. * * Arguments: * rtdIMAGE_INFO *imageInfo - image information structure, used for * output of image data to the browse file. * * Return value: * TCL_OK / TCL_ERROR */ int RtdPerformanceTool::dumpPerformanceData(const rtdIMAGE_INFO *imageData) { int i, j; // Index coutners. FILE *fStr; // Input/output file stream. struct fLine *timeLines; // Ditto from display process. reportRecord *sumData; // Summary data array. int numReceived; // Number of images received. int correctOrdering; // Is the ordering of events correct? // Deactivate the tool. active_ = 0; /* * Copy all the performance data into the timeLines structure * prior to sorting. */ timeLines = new fLine[timeIndex]; for (j = 0; j < timeIndex; j++) { timeLines[j].timeStamp = timeStamps[j].tv_sec + (timeStamps[j].tv_usec / 1000000.); sprintf(timeLines[j].descr, "%s", evDescs[j]); } // End the array with the END event. sprintf(timeLines[timeIndex - 1].descr, "END"); // Now sort the resulting line array in order of increasing time. qsort(&timeLines[0], timeIndex, sizeof(struct fLine), (int(*)(const void*, const void*))sortTime); // added cast to avoid compiler error message // Generate the summary data from the array just created. generateSummary(timeLines, timeIndex, sumData, numReceived, correctOrdering); // Open the output browse file for writing. if ((fStr = fopen(RTD_PTEST_FNAME, "w")) == NULL) { if (verbose_) { fprintf(stderr, "Unable to open performance test browse file\n"); return TCL_ERROR; } } // Write the data. Start with general image information. fprintf(fStr, "**** Performance Test Results ****\n"); fprintf(fStr, "\nImage width/pixels\t%d", imageData->xPixels); fprintf(fStr, "\nImage height/pixels\t%d", imageData->yPixels); fprintf(fStr, "\nImage bytes per pixel\t%d", imageData->bytePerPixel); fprintf(fStr, "\nTotal image size\t%ld", imageData->xPixels * imageData->yPixels * imageData->bytePerPixel); fprintf(fStr, "\nNumber of sent images\t%d", RTD_NUMSHM); fprintf(fStr, "\nNumber of received images\t%d", numReceived); // Write the timestamp list. fprintf(fStr, "\n\n**** Timestamp list ****\n"); for (j = 0; j < timeIndex; j++) { fprintf(fStr, "%lf\t%s\n", timeLines[j].timeStamp, timeLines[j].descr); } // Add some general reporting information here. fprintf(fStr, "\n**** Summary results ****\n"); for (j = 0; j < numIdentifiers; j++) { fprintf(fStr, "Process: %s\tInit_time: %6.4f\tOverall_time: %6.4f\n", sumData[j].procDesc, sumData[j].initTime, sumData[j].overallTime); } fprintf(fStr, "Total processing time: %7.4f\n", getProcTime(sumData)); delete(sumData); // Close the browse file and free memory. fclose(fStr); delete(timeLines); // Signal the end of the testing, and display the number of events received. printf("\n***** Performance Test Ended *****\n"); if (!correctOrdering) { printf("\nImage client fell behind server"); } else { printf("\nAll server events were processed immediately"); } printf("\nNumber of image events skipped: %d\n", RTD_NUMSHM - numReceived); printf("Diagnostic output written to %s\n", RTD_PTEST_FNAME); timeIndex = 0; return TCL_OK; } /* * Generate the summary data from the timestamps. This must be freed by the * caller. * * Arguments: * struct fLine *data - pointer to event timestamp data from which the * summary is to be prepared. * int numLines - the number of entries in the above array * reportRecord* &summaryData - pointer to structure containing the output * summary data. Must be freed by caller. * int numReceived - output, the number of image events received * int correctOrdering - flag True if the ordering of the timestamps is * corrent (RTD did not fall behind in image processing). * * Return value: * None */ void RtdPerformanceTool::generateSummary(const struct fLine *data, int numLines, reportRecord* &summaryData, int& numReceived, int& correctOrdering) { float deltaTime = 0.; // Time difference between sequential events. int i, k; // Index counter. // Initialise the ordering and number received parameters correctOrdering = 1; numReceived = 0; summaryData = (reportRecord *)new reportRecord[numIdentifiers]; // First check that the SEND events do not occur out of order. Just check // that each send is followed by a PKT_ identifier. for (i = 0; i < numLines; i++) { // Count the number of received packets. if (strstr(data[i].descr, rtdEventDesc[0])) { numReceived++; } if (strstr(data[i].descr, "SEND")) { if (!strstr(data[i + 1].descr, "PKT")) { correctOrdering = 0; } } } // Accumulate the data for each process identifier. for (i = 0; i < numIdentifiers; i++) { // Copy across the identifier for the process. strcpy(summaryData[i].procDesc, rtdEventDesc[i]); summaryData[i].initTime = 0.; summaryData[i].overallTime = 0.; for (int j = 1; j < numLines; j++) { if (correctOrdering || strstr(rtdEventDesc[i], "PKT")) { deltaTime = data[j].timeStamp - data[j - 1].timeStamp; } else { /* * If the timestamps are out of order, then we require special * processing. We ignore SEND events apart from the case of * data transmission processes. */ for (k = j - 1; k > 0; k--) { if (!strstr(data[k].descr, "SEND")) { deltaTime = data[j].timeStamp - data[k].timeStamp; break; } } } if (strstr(data[j].descr, rtdEventDesc[i])) { // then add the time on to the total. summaryData[i].overallTime += deltaTime; if (strstr(data[j].descr, "INIT")) { summaryData[i].initTime += deltaTime; } } } } } /* * Get the overall total processing time for the image processing from * the summary data. * * Arguments: * reportRecord *data - pointer to summary data structure with the times * for each processing type. * * Return value: * float, the total processing time for the image. */ float RtdPerformanceTool::getProcTime(const reportRecord *data) { float totalProcTime = 0.; /* * Loop over each process type and add the total time for that processing * to the overall time for all processing. */ for (int i = 0; i < numIdentifiers; i++) { totalProcTime += data[i].overallTime; } return totalProcTime; } /* * Routine required for qsort function call. Orders a set of fLines's in * chronological order. * * Arguments: * struct fLine *a, *b - pointers to two sample structures to be sorted * * Return value: * -1, time (a) less than time (b) * +1, time (b) less than time (a) */ int RtdPerformanceTool::sortTime(const struct fLine *a, const struct fLine *b) { if (a->timeStamp < b->timeStamp) { return -1; } else { return 1; } } skycat-3.1.2-starlink-1b/rtd/generic/RtdPerformanceTool.h000066400000000000000000000046541215713201500232750ustar00rootroot00000000000000// -*-c++-*- #ifndef _RtdPerformanceTool_h_ #define _RtdPerformanceTool_h_ /* * E.S.O. - VLT project * * RtdPerformanceTool.h - class definitions for managing the performance data. * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * D. Hopkinson 21/11/96 Created */ #include #include "rtdImageEvent.h" #define RTD_NUMTMSTMPS 20 // The number of timestamps produced // for every received image event. struct fLine { // Represent each line of the performance file dump. char descr[32]; // Line description. double timeStamp; // Line timestamp. }; // For the summary report. typedef struct { char procDesc[32]; /* Process description line. */ float initTime; /* Time for startup processes. */ float overallTime; /* Overall time over whole test/ */ } reportRecord; class RtdPerformanceTool { protected: // Display diagnostic messages. int verbose_; // Flag that a test is underway. This is required so that timestamp calls // can be added to routines which are called when the client is quiescent // without filling up the timestamp array before the test starts. int active_; // Array of timestamps for eventual output to the performance data file. struct timeval timeStamps[RTD_NUMSHM * RTD_NUMTMSTMPS]; // Same for event descriptions. char evDescs[RTD_NUMSHM * RTD_NUMTMSTMPS][32]; // Index to these arrays. int timeIndex; // Generate data summary. void generateSummary(const struct fLine *data, int numLines, reportRecord* &summaryData, int& numReceived, int& correctOrdering); // Get the total processing time. float getProcTime(const reportRecord *data); // The sort algorithm for qsort. static int sortTime(const struct fLine *a, const struct fLine *b); public: // Constructor RtdPerformanceTool(); // Destructor ~RtdPerformanceTool(); // Add timestamp for send event (take time from image information) void timeStamp(const rtdIMAGE_INFO *imageInfo); // Add timestamp in performance test. void timeStamp(char *evDesc); // Write the performance data to the browse file. int dumpPerformanceData(const rtdIMAGE_INFO *imageData); // Return active status of performance test. int active() {return active_ ? 1 : 0;} }; #endif /* _RtdPerformanceTool_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/RtdRPFile.C000066400000000000000000000653271215713201500212560ustar00rootroot00000000000000/* * E.S.O. - VLT project * * RtdRPFile.C - member routines for class RtdRPFile, RtdFITSCube, * and RtdFITSComp. * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * D.Hopkinson 17/04/97 Created * P.Biereichel 23/07/97 Bug fixed. Revised * pbiereic 10/08/07 RtdFITSCube::writeFITSHeader: using ISO date string (VLTSW20070156) */ /*#include */ #include #include #include #include "RtdRPFile.h" static int cnt = 0; // Shared memory counter /* * Constructor for RtdRPFile class. This opens a file for reading or writing. * * Arguments: * char *fileName - name of the file to open * char *accFlag - usual C access flag, e.g. r+. * double maxFileSize - the maximum allowed file size (Mb) */ RtdRPFile::RtdRPFile(Tcl_Interp* interp, char* instname, char *fileName, char *accFlag, double maxFileSize) : status_(TCL_OK), fPtr(NULL), imageCounter_(0), xPixels_(0), yPixels_(0), bytesPerPixel_(0), startIndex_(0), imageIndex_(0), fileSize_(0.), maxFileSize_(maxFileSize), numFileImages_(0), fileFull_(0), timeStamps_(NULL), hasTimeInfo_(0), instname_(instname), shmSize_(0), interp_(interp), fileName_(0) { fileName_ = fileName; // Open the file in the required access mode. if (accFlag[0] != '\0') { if ((fPtr = fopen(fileName, accFlag)) == NULL) { status_ = TCL_ERROR; } } else { // check that file is a regular file and not write protected struct stat statbuf; if (stat(fileName, &statbuf) == 0) { if (! S_ISREG(statbuf.st_mode) || ! (S_IWUSR & statbuf.st_mode)) { status_ = TCL_ERROR; } } } } /* * Destructor for RtdRPFile object. This just closes the file stream and does * some tidying up of memory. */ RtdRPFile::~RtdRPFile() { cleanup(); } /* * just closes the file stream and does some tidying up of memory. */ void RtdRPFile::cleanup() { // Remove the timestamps array. delete(timeStamps_); timeStamps_ = NULL; // round off file size if (shmSize_ && (imageCounter_ != 0 || fileFull_)) { int n = fileFull_ ? numFileImages_ : imageCounter_; padFile(fPtr, shmSize_ * n); } // Close the file stream (this may take some time if the file is on a remote host) fclose(fPtr); fPtr = NULL; imageCounter_ = 0; } /* * This method takes the subimage coordinates and checks that they are * consistent with the current image information (it is possible, for example, * that the user may set up an edit window on an image which has different * properties to the images received from the camera). * * Arguments: * rtdIMAGE_INFO - image information structure for image * int& x0, y0 - coordinates of bottom left corner of subimage * int& width, height - width and height of subimage * * Return value: * None. */ void RtdRPFile::checkSubImage(rtdIMAGE_INFO *imageInfo, int& x, int& y, int& width, int& height) { // First check the initial coordinates if (x < 0) x = 0; if (y < 0) y = 0; // Check the height and width if (width > imageInfo->xPixels) width = imageInfo->xPixels - 1; if (height > imageInfo->yPixels) height = imageInfo->yPixels - 1; // Finally, make sure the subimage fits into the main image if (x + width > imageInfo->xPixels) { x = imageInfo->xPixels - width - 1; } if (y + height > imageInfo->yPixels) { y = imageInfo->yPixels - height - 1; } } /* * Method to get the time increment between the image just read and the next * image (which the file pointer should be at the start of). * * Arguments: * int direction - forwards through time (1), or backwards (0) * * Return value: * double - the time interval (seconds) */ double RtdRPFile::getTimeIncrement(int direction) { double increment; // Required time increment for return. int tmpIndex; // Temp index - index of last image read. if (!hasTimeInfo_) { // No timestamp information available. Return something. return 2000.; } /* * Strangely, the time increment required here is the same whether we * are going forwards through the file or backwards - the difference * between the previous index and the current index. This is because * when we are going backwards, the current index is already displayed. * This is not the case when going forwards. */ // tmpIndex = (imageIndex_ - 1 < 0) ? numFileImages_ - 1 : imageIndex_ - 1; tmpIndex = (imageIndex_ - 1 < 0) ? imageIndex_ : imageIndex_ - 1; increment = (timeStamps_[imageIndex_] - timeStamps_[tmpIndex]) * 1000.; /* * The increment may be negative if we have reached the end of a file. * Alternatively, it may be zero if the above indices were the same (i.e. * only one imae in the cube). * In either case, just return the default for SLOW speed (or whatever). */ if (increment < 0. || imageIndex_ == tmpIndex) { increment = 1000.; } return increment; } /* * Method to create and initialise a shared memory/semaphore set based on * the image information (that must have already been initialised). * * Arguments: * int numShm - number of shared memory buffers to create * rtdShm *shmInfo - structure to initialise * * Return value: * TCL_OK / TCL_ERROR */ int RtdRPFile::getShm(int numShm, rtdShm *shmInfo) { // Clear any outstanding allocation for the shmInfo memset(shmInfo, '\0', sizeof(rtdShm)); // Check first that the image information is instantiated. if (xPixels_ == 0 || yPixels_ == 0 || bytesPerPixel_ == 0) { return TCL_ERROR; } return rtdShmCreate(numShm, shmInfo, xPixels_, yPixels_, dataType_); } /* * Update tcl variable for current image count and #of images */ void RtdRPFile::update_count() { // Update recorder counter char buffer[64]; int eof=0, bof=0; if (imageCounter_ != imageCounter__ || numFileImages_ != numFileImages__ || \ imageCounter_ == numFileImages_ || imageCounter_ <=1) { if (imageCounter_ <=1) bof = 1; if (imageCounter_ >= numFileImages_) eof = 1; sprintf(buffer, "%d %d %d %d", imageCounter_, numFileImages_, bof, eof); imageCounter__ = imageCounter_; numFileImages__ = numFileImages_; Tcl_SetVar2(interp(), instname(), "COUNT", buffer, TCL_GLOBAL_ONLY); #ifdef DEBUG printf("%d %d %d %d \n", imageCounter_, numFileImages_, bof, eof); #endif } } /* Method to place the file pointer at the start of a certain image which is * indexed by the image count (i.e. the image count starts from zero at the * image which has the lowest timestamp, and this may be in the middle of * the file such that the index is non-zero). This method converts the image * count to an image index and calls a subclass method to actually place the * file pointer. * * Arguments: * int count - the image count where the pointer is to be placed * * Return value: * None */ void RtdRPFile::gotoImageCount(int count) { // Set the image counter to count imageCounter_ = count; // Translate the count into an image index this->gotoImageIndex((count - 1 + startIndex_) % numFileImages_); update_count(); } /* * Method to create an initialised FileObject given a file name. The determines * the type of file that is being loaded and creates the object that * corresponds to that file. It then places the file pointer at the correct * point in the file, ready for playing (or possibly recording in future). * * Arguments: * char *fileName - name of the file to create object from * * Return value: * RtdRPFile * - pointer to new object instance * char *err - error message to return */ RtdRPFile *RtdRPFile::makeFileObject(Tcl_Interp* interp, char* instname, char *fileName, char *err) { FILE *file; // Temporary file pointer. char buffer[16]; // Temporary buffer. // Initialise the instance to return. RtdRPFile *newInstance = (RtdRPFile *)NULL; // Open the file for reading, to check the type of file that we have. if ((file = fopen(fileName, "r")) == NULL) { sprintf(err, "Unable to open file %s", fileName); return NULL; } /* * To check the file type, get the first ten characters. In a compressed * file type, these will be "compressed" (possibly...) */ fgets(buffer, sizeof(buffer), file); fclose(file); if (strncmp(buffer, "compressed", 10) == 0) { newInstance = (RtdFITSComp *)new RtdFITSComp(interp, instname, fileName, (char *)"r", 5.); } else { newInstance = (RtdFITSCube *)new RtdFITSCube(interp, instname, fileName, (char *)"r", 5.); } // Set up the file pointer and timestamp array. if (newInstance) { if (newInstance->open(err) == TCL_ERROR) { delete(newInstance); newInstance = (RtdRPFile *)NULL; } } return newInstance; } /* * round off the file size to the next FITS block. * (size is the current size) */ void RtdRPFile::padFile(FILE* f, int size) { int rest = (size + FITSBLOCK) % FITSBLOCK; if (rest) { fseek(f, 0, SEEK_END); while (rest < FITSBLOCK) { fputc(' ', f); rest++; } } } /* - End of RtdRPFile method definitions - */ /*==========================================================================*/ /* - Start of RtdFITSCube method definitions - */ /* Private methods first. */ /* * This method writes the header to the FITS cube file. It calculates the number * of FITS data files that will fit into the cube before the maximum file size * is reached, and returns this. * * Arguments: * const rtdIMAGE_INFO *imageInfo - image information structure * int subImage - flag true if subimage is to be taken * int x0, y0, width, height - defines subimage bounding box. * * Return value: * TCL_OK / TCL_ERROR */ int RtdFITSCube::writeFITSHeader(const rtdIMAGE_INFO *imageInfo, int subImage, int width, int height) { char buf[81], // Temporary buffers buf2[20]; // Get the size of the image segments. int dataSize = (subImage ? (width * height * abs(imageInfo->dataType / 8)) : (imageInfo->xPixels * imageInfo->yPixels * abs(imageInfo->dataType / 8))); // Calculate the number of images that there will be in the file. numFileImages_ = (int)(maxFileSize_ * 1024. * 1024./ (double)dataSize); // Get the number of keyword lines in the FITS header (including END). int size = FITSBLOCK/80; sprintf(buf, "%-8s= %s", "SIMPLE", "T"); fprintf(fPtr, "%-80s", buf); size--; int bitpix = imageInfo->dataType; if (bitpix == -16) bitpix = 16; sprintf(buf, "%-8s= %d", "BITPIX", bitpix); fprintf(fPtr, "%-80s", buf); size--; sprintf(buf, "%-8s= %d", "NAXIS", 3); fprintf(fPtr, "%-80s", buf); size--; sprintf(buf, "%-8s= %d", "NAXIS1", (subImage ? width : imageInfo->xPixels)); fprintf(fPtr, "%-80s", buf); size--; sprintf(buf, "%-8s= %d", "NAXIS2", (subImage ? height: imageInfo->yPixels)); fprintf(fPtr, "%-80s", buf); size--; if (imageInfo->dataType == -16) { sprintf(buf, "%-8s= %f", "BZERO", (double)32768.0); fprintf(fPtr, "%-80s", buf); size--; sprintf(buf, "%-8s= %f", "BSCALE", (double)1.0); fprintf(fPtr, "%-80s", buf); size--; } // add the date to the cube header. time_t clock = time(0); strftime(buf2, sizeof(buf2), "%Y-%m-%d", localtime(&clock)); sprintf(buf, "%-8s= \'%s\'", "DATE", buf2); fprintf(fPtr, "%-80s", buf); size--; /* * The following blank cards will be used to provide image timestamp * information when the file is closed. */ int i = 0; while (size > 1) { sprintf(buf, "BLANK%02d", i++); fprintf(fPtr, "%-80s", buf); size--; } /* * The number of timestamps available can be smaller than the number * of images */ i--; if (i*3 < numFileImages_) numFileImages_ = i*3; /* * Finally, put on the end card. There will be no need for any padding * before the start of the image data because we should have exactly * filled the FITS block. */ fprintf(fPtr, "%-80s", "END"); // Increment the file count. fileSize_ += FITSBLOCK / (1024. * 1024.); return TCL_OK; } /* * FITSCube object destructor. This goes through the FITS header, changing * BLANK fields into timestamp information - this is in the form: * COMMENT = "TS: ..." (3 timestamps per line). * It also adds a NAXIS3 field. * * The baseclass destructor closes the file down. */ RtdFITSCube::~RtdFITSCube() { char buffer[81]; // Buffer for reading data from file. char buf2[64]; // General purpose buffer. int filePos = 0; // Position of file pointer from beginning of stream. int i; // Index counter int found = 0; // Flag: found BLANK card if (imageCounter_ == 0 && !fileFull_) { // Image file is empty anyway return; } if (!shmSize_) { // Call baseclass destructor. Nothing was recorded. // RtdRPFile::~RtdRPFile; (allan: 8.12.97: this will be called automatically!) return; } // Rewind the file pointer to the beginning of the file. rewind(fPtr); // Loop over the file header, changing fields as detailed in the method // header. do { fgets(&buffer[0], 81, fPtr); if (feof(fPtr)) break; if (strncmp(buffer, "BLANK", 5) == 0) { // Flag that we have found the card found = 1; // Replace this blank field with NAXIS3 count. fseek(fPtr, filePos, SEEK_SET); sprintf(buf2, "%-8s= %d", "NAXIS3", (fileFull_ ? numFileImages_ : imageCounter_)); sprintf(buffer, "%-80s", buf2); fputs(buffer, fPtr); break; } filePos += 80; } while(strncmp(buffer, "END", 3) != 0 && !feof(fPtr)); // If we didn't find the blank card, then either we've got big problems // or we were playing back a FITS file from some other tool. Either way, // get out of here. if (!found) { // Call baseclass destructor. // RtdRPFile::~RtdRPFile; (allan: 8.12.97: this will be called automatically!) return; } /* * Now add the timestamp information below this line. */ char TSBuf[64]; sprintf(TSBuf, "\0"); char buf3[32]; for (i = 0; i < (fileFull_ ? numFileImages_ : imageCounter_); i++) { sprintf(buf3, "%.3lf ", timeStamps_[i]); // Create concatenated timestamp string. strcat(TSBuf, buf3); if (!((i + 1) % 3)) { // Every third string, dump to the FITS header. sprintf(buffer, "%-8s= \"TS: %s/\"", "COMMENT", TSBuf); fprintf(fPtr, "%-80s", buffer); sprintf(TSBuf, "\0"); } } // If there are any timestamps left, dump these to the FITS header. if (TSBuf[0] != '\0') { sprintf(buffer, "%-8s= \"TS: %s/\"", "COMMENT", TSBuf); fprintf(fPtr, "%-80s", buffer); } // Tidy up // RtdRPFile::~RtdRPFile; (allan: 8.12.97: this will be called automatically!) } /* * Given a file pointer in an existing file, this method intialises the * timestamp information so that the images can be played back in real time. * * Arguments: * char *errMsg - error message to return if not all OK * * Return value: * TCL_OK / TCL_ERROR. */ int RtdFITSCube::open(char *errMsg) { char buffer[81]; // Temporary buffer. char *ptr, *vptr; // Temporary pointers. int bzero=0, bscale=0; int foundNAXIS3 = 0, foundNAXIS1 = 0, foundNAXIS2 = 0, foundBITPIX = 0; int i = 0; // Index counter. /* * Loop over the header information to get to the timestamp information. * If the FITS cube was produced with this application, this will be * in COMMENT headers of the form COMMENT = "TS: <> <> <>" in groups * of three timestamps per header. If this information can not be found, * flag that it is missing and let the driver objects sort it out. * * Get the NAXIS3 info first for the timestamp array size. Also, at this * point, get the image information to determine the size of the images * int the file. */ rewind(fPtr); do { fgets(buffer, sizeof(buffer), fPtr); if (feof(fPtr)) break; ptr = strtok(buffer, "="); if (strncmp(buffer, "NAXIS1", 6) == 0) { foundNAXIS1 = 1; vptr = strtok(NULL, "/"); xPixels_ = atoi(vptr); } if (strncmp(buffer, "NAXIS2", 6) == 0) { foundNAXIS2 = 1; vptr = strtok(NULL, "/"); yPixels_ = atoi(vptr); } if (strncmp(buffer, "BITPIX", 6) == 0) { foundBITPIX = 1; vptr = strtok(NULL, "/"); dataType_ = atoi(vptr); bytesPerPixel_ = abs(dataType_) / 8; } if (strncmp(buffer, "NAXIS3", 6) == 0) { // This gives the number of images, and so is also the number of // timestamps in the array. foundNAXIS3 = 1; ptr = strtok(NULL, "/"); numFileImages_ = atoi(ptr); } if (strncmp(buffer, "BSCALE", 6) == 0) { ptr = strtok(NULL, "/"); bscale = atoi(ptr); } if (strncmp(buffer, "BZERO", 5) == 0) { ptr = strtok(NULL, "/"); bzero = atoi(ptr); } } while(strncmp(buffer, "END", 3) != 0 && !feof(fPtr)); // Set BITPIX=-16 if (bscale == 1 && bzero == 32768 && dataType_ == 16) dataType_ = -16; if (feof(fPtr) || !foundBITPIX || !foundNAXIS1 || !foundNAXIS2) { sprintf(errMsg, "Not a FITS file"); return TCL_ERROR; } if (!foundNAXIS3) { numFileImages_ = 1; } timeStamps_ = (double *)new double[numFileImages_]; // Now get the timestamp comments. rewind(fPtr); do { fgets(buffer, sizeof(buffer), fPtr); if (strncmp(buffer, "COMMENT = \"TS:", 14) == 0) { hasTimeInfo_ = 1; // Get the timestamp information by splitting up the line into // constituent timestamps. ptr = &buffer[15]; while (1) { vptr = strchr(ptr, ' '); *vptr = '\0'; timeStamps_[i++] = atof(ptr); ptr = vptr + 1; if (*ptr == '/') { break; } } } } while(strncmp(buffer, "END", 3) != 0); // Get the file pointer at the end of the FITS block FITSHeaderSize_ = ftell(fPtr); // Index i should be the same as the number of file images, or something // is terribly wrong. if (hasTimeInfo_ && i != numFileImages_) { sprintf(errMsg, "Inconsistency between timestamp and image number"); return TCL_ERROR; } /* * Now we set up the image counter and image indices by finding the lowest * of the timestamps (this may not be the first in the array if the image * was cycled when it was recorded). */ imageCounter_ = 0; startIndex_ = 0; if (hasTimeInfo_) { double min = timeStamps_[0]; for (i = 0; i < numFileImages_; i++) { if (timeStamps_[i] < min) { min = timeStamps_[i]; startIndex_ = i; } } } gotoImageIndex(startIndex_); update_count(); return TCL_OK; } /* * This routine sets the file pointer to the start of the image indexed by * the method argument. * * Argument: * int index - index of the image to set the file pointer to * * Return value: * None. */ void RtdFITSCube::gotoImageIndex(int index) { long int offset = (long)((int)((FITSHeaderSize_ - 1) / FITSBLOCK) + 1) * FITSBLOCK; // Go to the start of the images (after the header). fseek(fPtr, offset, SEEK_SET); // Set the image index to the required index. imageIndex_ = index; // Now go to the start of the required index. fseek(fPtr, (imageIndex_ * xPixels_ * yPixels_ * bytesPerPixel_), SEEK_CUR); } /* * Given an image information structure, this method adds the image data to the * FITS cube. If it is the first time round, FITS header information is also * created. * * Arguments: * rtdIMAGE_INFO *imageInfo - image information structure * int subimage - true if sub image is to be taken * int x0, y0 - coordinates of lower left corner of subimage * int width, height - dimensions if subimage * * Return value: * TCL_OK / TCL_ERROR */ int RtdFITSCube::addImage(rtdIMAGE_INFO *imageInfo, int subImage, int x0, int y0, int width, int height) { int shmSize; // Get the byte size of the shared memory. shmSize = imageInfo->xPixels * imageInfo->yPixels * abs(imageInfo->dataType) / 8; shmSize_ = shmSize; if (shmSize <= 0) return TCL_ERROR; // Get a pointer to the start of the shared memory area. Mem shmData = Mem(shmSize, imageInfo->shmId, 0, 0, imageInfo->shmNum, imageInfo->semId); // Check that the memory was attached successfully if (shmData.ptr() == NULL) return TCL_ERROR; /* * If this is the first image to add (file size is still 0), then add a FITS * header to start with. We also initialise an array to deal with all the * timestamps. */ if (!imageCounter_ && !fileFull_) { if ((fPtr = fopen(fileName_, "w+")) == NULL) { return TCL_ERROR; } writeFITSHeader(imageInfo, subImage, width, height); timeStamps_ = (double *)new double[numFileImages_]; } // The timestamp can be given by the timestamp from the image information. timeStamps_[imageCounter_] = (double)imageInfo->timeStamp.tv_sec + (double) imageInfo->timeStamp.tv_usec / 1000000.; /* * If subimaging is not enabled, then just copy across the data into the * file from the shared memory. Otherwise, do a selective copy. */ int bitpix = imageInfo->dataType; if (!subImage) { if (bitpix == -16) { // unsigned short needs to be converted unsigned short *pu = (unsigned short *)shmData.ptr(); int i = shmSize / 2; short *ps_new = new short[i]; short *ps = ps_new; if (ps_new == 0) { fprintf(stderr, "Not enough memory\n"); return TCL_ERROR; } int nn; while (i--) { nn = (int)(*pu++) - 32768; *ps++ = (unsigned int) nn; } fwrite((char*)ps_new, shmSize, 1, fPtr); delete ps_new; } else { fwrite(shmData.ptr(), shmSize, 1, fPtr); // Copy entire buffer } if (!fileFull_) { fileSize_ += shmSize / (1024. * 1024.); } } else { // Get a pointer to the shared memory buffer. char *srcPtr = (char *)shmData.ptr(); int bpp = abs(imageInfo->dataType) / 8; checkSubImage(imageInfo, x0, y0, width, height); // Offset of start of required buffer. srcPtr += bpp * ((imageInfo->xPixels * y0) + x0); // Copy across all lines to the file stream. for (int j = 0; j < height; j++) { if (bitpix == -16) { // unsigned short needs to be converted unsigned short *pu = (unsigned short *)srcPtr; int i = (width * bpp) / 2; short *ps_new = new short[i]; short *ps = ps_new; if (ps_new == 0) { fprintf(stderr, "Not enough memory\n"); return TCL_ERROR; } int nn; while (i--) { nn = (int)(*pu++) - 32768; *ps++ = (unsigned int) nn; } fwrite((char*)ps_new, shmSize, 1, fPtr); delete ps_new; } else { fwrite(srcPtr, width * bpp, 1, fPtr); srcPtr += bpp * (imageInfo->xPixels); } } if (!fileFull_) { fileSize_ += (bpp * height * width) / (1024. * 1024.); } } /* * Increment the image counter. If we have reached the maximum size of the * file, reset the counter to one and reposition the file pointer to the * beginning of the image data segments. */ if (++imageCounter_ == numFileImages_) { update_count(); fseek(fPtr, FITSBLOCK, SEEK_SET); fileFull_ = 1; imageCounter_ = 0; } update_count(); } /* * Method to get the next image from the file and put it into shared memory. * If this is the last image in the file, reset the file pointer to the * start of the images. * * Arguments: * rtdShm *shmInfo - shared memory/semaphore structure to fill * * Return value: * int index - the index of the shared memory buffer in the multi-buffered * scheme that was filled. */ int RtdFITSCube::getNextImage(rtdShm *shmInfo) { char *tmpBuf; // Temporary data buffer. int retIndex = -1; // Return index. int imageSize; // Size of image data. // Calculate the size of the image data. imageSize = xPixels_ * yPixels_ * bytesPerPixel_; // Allocate a temporary buffer for the image data. tmpBuf = new char[imageSize]; // Copy into the shared memory. fread(tmpBuf, imageSize, 1, fPtr); // convert BITPIX=-16 data if (dataType_ == -16) { int nn = imageSize / 2; unsigned short *us = (unsigned short *) tmpBuf; for (int i=0; i < nn; i++) *us++ += 32768; } // Fill up a buffer in the shared memory array by calling a CCD // convenience routine. retIndex = rtdShmFillNext(cnt, tmpBuf, shmInfo); if (retIndex < 0) { delete(tmpBuf); return -1; } cnt = retIndex; // Tidy up local memory. delete(tmpBuf); // Alter imageCounter_ and imageIndex_ as required. if (++imageIndex_ >= numFileImages_) { imageIndex_ = 0; gotoImageIndex(imageIndex_); } if (imageIndex_ > startIndex_) { imageCounter_ = imageIndex_ - startIndex_; } else { imageCounter_ = numFileImages_ - startIndex_ + imageIndex_; } update_count(); return retIndex; } /* * Method to get the previous image from the file and put it into shared memory. * If this is the first image in the file, reset the file pointer to the * end of the images. * * Arguments: * rtdShm *shmInfo - shared memory/semaphore structure to fill * * Return value: * int index - the index of the shared memory buffer in the multi-buffered * scheme that was filled. */ int RtdFITSCube::getPrevImage(rtdShm *shmInfo) { char *tmpBuf; // Temporary data buffer. int retIndex = -1; // Return index. int imageSize; // Size of image data. // Calculate the size of the image data. imageSize = xPixels_ * yPixels_ * bytesPerPixel_; // Allocate a temporary buffer for the image data. tmpBuf = new char[imageSize]; // Rewind the file pointer to just before the required image. if (--imageIndex_ < 0) { imageIndex_ = numFileImages_ - 1; } gotoImageIndex(imageIndex_); // Copy into the shared memory. fread(tmpBuf, imageSize, 1, fPtr); // convert BITPIX=-16 data if (dataType_ == -16) { int nn = imageSize / 2; unsigned short *us = (unsigned short *) tmpBuf; for (int i=0; i < nn; i++) *us++ += 32768; } // Fill up a buffer in the shared memory array by calling a CCD // convenience routine. retIndex = rtdShmFillNext(cnt, tmpBuf, shmInfo); if (retIndex < 0) { delete(tmpBuf); return -1; } cnt = retIndex; // Tidy up local memory. delete(tmpBuf); // After this, the file pointer should be repositioned to the start of the // block of image data that it has just sent. gotoImageIndex(imageIndex_); /* * The image counter should represent the number of the image that is * presently under display. As we have gone backwards to get this, the * image number is one greater than the imageIndex (with an extra * allowance for the fact that the start of the images is at startIndex_). */ if (imageIndex_ >= startIndex_) { imageCounter_ = imageIndex_ - startIndex_ + 1; } else if (imageIndex_ < startIndex_) { imageCounter_ = numFileImages_ - startIndex_ + imageIndex_ + 1; } update_count(); return retIndex; } skycat-3.1.2-starlink-1b/rtd/generic/RtdRPFile.h000066400000000000000000000136341215713201500213150ustar00rootroot00000000000000#ifndef RTDRPFILE_H #define RTDRPFILE_H /* * E.S.O. - VLT project / ESO Archive * * RtdRPFile.h - class definitions for class RtdRPFile, RtdFITSCube, * and RtdFITSComp. * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * D.Hopkinson 17/04/97 Created * A.Brighton 08/12/97 fixed lots of C++ errors found by SunPro CC */ #include #include #include #include #include #include "TclCommand.h" #include "tcl.h" #include "tk.h" #include "rtdImageEvent.h" #include "rtdSem.h" #include "Mem.h" #define RTD_SHMBUFFS 5 // Number of shared memory buffers to create. #define FITSBLOCK 2880 /* * This is an abstract base class from which the main classes for the file * type are derived. This simply sets up virtual chains for the functions * that are to be accessed from the recorder/playback tools. */ class RtdRPFile { protected: FILE *fPtr; // File pointer to file being read/written int imageCounter_; // Count of image from start of record/playback. int imageCounter__; // same for update_count() int xPixels_; // Pixel width of each image. int yPixels_; // Pixel height of each image. int bytesPerPixel_; // Bytes per pixel. int dataType_; // BYTE, SHORT, FLOAT, etc int startIndex_; // Index of first image in file (maybe non-zero) int imageIndex_; // Actual index of image in array. int hasTimeInfo_; // File has included timestamp information. double *timeStamps_; // Array of image event timestamps. double fileSize_; // Current size of file. double maxFileSize_; // Maximum allowed size of file. int numFileImages_; // Number of image segments allowed in file. int numFileImages__; // same for update_count() int fileFull_; // Flag: true if file is at max size int status_; // Object instance status. int shmSize_; // Size of shared memory Tcl_Interp* interp_; // tcl interpreter char* instname_; // name of tcl command created for this object char* fileName_; // filename RtdRPFile(Tcl_Interp* interp, char* instname, char *fileName, char *accFlag, double maxFileSize); // Constructor. virtual int open(char *errMsg) {return 0;} // Initialise props of existing file. // Check that the subimage information is consistent with the image. void checkSubImage(rtdIMAGE_INFO *, int&, int&, int&, int&); public: virtual ~RtdRPFile(); // Destructor. // cleanup void cleanup(); void update_count(); // Get the next segment of image data. virtual int getNextImage(rtdShm *) {return 0;} // Get the previous segment of image data. virtual int getPrevImage(rtdShm *) {return 0;} // Add an image segment onto file end. virtual int addImage(rtdIMAGE_INFO *, int, int, int, int, int) {return 0;} // Goto a particular image index in the file. virtual void gotoImageIndex(int index) {fprintf(stderr, "Don't call\n");} // Goto a particular image count in the file. void gotoImageCount(int count); // round off file size static void padFile(FILE* f, int size); // Given an existing file, make and initialise the required file object. static RtdRPFile *makeFileObject(Tcl_Interp* interp, char* instname, char *fileName, char *errMsg); // Get the time increment between this and the next image. double getTimeIncrement(int direction); // Allocate shared memory and semaphores for the image int getShm(int numShm, rtdShm *shmInfo); // Private member access const double fileSize() {return fileSize_;} const int imageCounter() {return imageCounter_;} const int imageIndex() {return imageIndex_;} const int status() {return status_;} Tcl_Interp* interp() {return interp_;} char* instname() {return instname_;} const int hasTimeInfo() {return hasTimeInfo_;} const int bytesPerPixel() {return bytesPerPixel_;} const int xPixels() {return xPixels_;} const int yPixels() {return yPixels_;} const int dataType() {return dataType_;} const int numFileImages() {return numFileImages_;} const double maxFileSize() {return maxFileSize_;} const int fileFull() {return fileFull_;} }; /* * This class defines the above methods for the case where the file is in * the form of a FITS cube. */ class RtdFITSCube : public RtdRPFile { protected: // Size of the FITS header int FITSHeaderSize_; // Write the header at the top of the FITS cube. int writeFITSHeader(const rtdIMAGE_INFO *, int, int, int); int open(char *); public: int getNextImage(rtdShm *); int getPrevImage(rtdShm *); int addImage(rtdIMAGE_INFO *, int, int, int, int, int); void gotoImageIndex(int index); // Constructor - call base class constructor. RtdFITSCube(Tcl_Interp* interp, char* instname, char *fileName, char *accFlag, double maxFileSize) : RtdRPFile(interp, instname, fileName, accFlag, maxFileSize), FITSHeaderSize_(0) {} // Destructor. ~RtdFITSCube(); }; /* * This class defines the above methods for the case where the file is in * the form of a stack of compressed FITS files. * * NB This is not yet implemented - this class template shows how to implement * a record file type by defining the methods below. */ class RtdFITSComp : public RtdRPFile { protected: int open(char*) {return 0;} public: int getNextImage(rtdShm *){return 0;} int getPrevImage(rtdShm *){return 0;} int addImage(rtdIMAGE_INFO *, int, int, int, int, int){return 0;} void gotoImageIndex(int index) {} // Constructor - call base class contructor. RtdFITSComp(Tcl_Interp* interp, char* instname, char *fileName, char *accFlag, double maxFileSize) : RtdRPFile(interp, instname, fileName, accFlag, maxFileSize) {} // Destructor - call base class destructor. ~RtdFITSComp() {} }; #endif skycat-3.1.2-starlink-1b/rtd/generic/RtdRPTool.C000066400000000000000000000767441215713201500213210ustar00rootroot00000000000000/* * E.S.O. - VLT project * * RtdRPTool.C - member routines for class RtdRPTool, RtdRecorder, * and RtdPlayback. * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * D.Hopkinson 20/02/97 Created * D.Hopkinson 17/04/97 Added playback and recorder tools, * changed names, added inheritance * P.Biereichel 07/07/97 Adapted for shared library. Code improved * and bugs fixed * pbiereic 28/05/01 Included Allan's changes for tcl8.3.3 */ #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "RtdRPTool.h" static rtdShm shmInfo_; // Structure for managing shm/semaphores // Define the image types for the recorder and playback tools. static Tk_ImageType rtdRecorderType = { (char *)"rtdrecorder", /* name */ RtdRecorder::CreateImage, /* createProc */ RtdRecorder::GetImage, /* getProc */ RtdRecorder::DisplayImage, /* displayProc */ RtdRecorder::FreeImage, /* freeProc */ RtdRecorder::DeleteImage, /* deleteProc */ #if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >= 3 (Tk_ImagePostscriptProc *) NULL, /* postscriptProc */ #endif (Tk_ImageType *)NULL }; static Tk_ImageType rtdPlaybackType = { (char *)"rtdplayback", RtdPlayback::CreateImage, RtdPlayback::GetImage, RtdPlayback::DisplayImage, RtdPlayback::FreeImage, RtdPlayback::DeleteImage, #if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >= 3 (Tk_ImagePostscriptProc *) NULL, /* postscriptProc */ #endif (Tk_ImageType *)NULL }; /* * Registers the recorder and playback class types so that they may * be instantiated from the Tcl code. * * Arguments: * Tcl_Interp * interp - pointer to the Tcl interpreter structure * * Return value: * Return value from Tcl_Eval */ extern "C" int RtdrecordInit(Tcl_Interp* interp) { // add the rtdrecorder and rtdplayback image types Tk_CreateImageType(&rtdRecorderType); Tk_CreateImageType(&rtdPlaybackType); // Set the shared memory information structure to NULL memset(&shmInfo_, '\0', sizeof(rtdShm)); return TCL_OK; } /* * These classes are defined as part of the C++/Tcl interface. They * contain a table of Tcl commands, with the addresses of corresponding * C++ methods to call. See the TclCommand man page for more details. */ static class RtdRPToolSubCmds { public: char *name; int (RtdRPTool::*fptr)(int argc, char *argv[]); int min_args; int max_args; } RPsubcmds_[] = { {(char *)"close", &RtdRPTool::close, 0, 0}, {(char *)"cycle", &RtdRPTool::cycle, 1, 1}, {(char *)"filename", &RtdRPTool::filename, 1, 1}, {(char *)"status", &RtdRPTool::status, 0, 0}, // Declared inline in header }; static class RtdRecorderSubCmds { public: char *name; int (RtdRecorder::*fptr)(int argc, char *argv[]); int min_args; int max_args; } Recsubcmds_[] = { {(char *)"camera", &RtdRecorder::camera, 1, 1}, {(char *)"file", &RtdRecorder::file, 2, 2}, {(char *)"record", &RtdRecorder::record, 0, 0}, {(char *)"stop", &RtdRecorder::stop, 0, 0}, {(char *)"subimage", &RtdRecorder::subimage, 1, 5} }; static class RtdPlaybackSubCmds { public: char *name; int (RtdPlayback::*fptr)(int argc, char *argv[]); int min_args; int max_args; } Playsubcmds_[] = { {(char *)"close", &RtdPlayback::close, 0, 0}, {(char *)"filename", &RtdPlayback::filename, 1, 1}, {(char *)"gotoimage", &RtdPlayback::gotoimage, 1, 1}, {(char *)"play", &RtdPlayback::play, 0, 0}, {(char *)"props", &RtdPlayback::props, 2, 2}, {(char *)"hastime", &RtdPlayback::hastime, 0, 0}, {(char *)"reset", &RtdPlayback::reset, 0, 0}, {(char *)"spool", &RtdPlayback::spool, 1, 1}, {(char *)"step", &RtdPlayback::step, 0, 0}, {(char *)"stop", &RtdPlayback::stop, 0, 0} }; /* * Recorder/playback tool object constructor. This does basic * initialisation, and also registers the process with the server daemon. * * Arguments: * Tcl_Interp *interp - pointer to the Tcl interpreter structure * char *instname - the instance name of the itk widget * int arg, char **argv - argument list, unused * Tk_ImageMaster - Tk master */ RtdRPTool::RtdRPTool(Tcl_Interp* interp, char* instname, int argc, char** argv, Tk_ImageMaster master) : TclCommand(interp, instname, instname), eventHndl_(NULL), status_(TCL_OK), cycleMode_(1), fileHandler((RtdRPFile *)NULL), master_(master), tkwin_(Tk_MainWindow(interp)), display(Tk_Display(Tk_MainWindow(interp))) { status_ = RtdRPTool::init(); } /* * Recorder object destructor. */ RtdRPTool::~RtdRPTool() { cleanup(); } /* * init routine: if necessary register to rtdServer */ int RtdRPTool::init() { if (eventHndl_ == NULL) { eventHndl_ = new rtdIMAGE_EVT_HNDL; /* register to rtdServer */ if (rtdInitImageEvt("RTDRPTOOL", eventHndl_, NULL) != RTD_OK) { delete eventHndl_; eventHndl_ = NULL; return TCL_ERROR; } } return TCL_OK; } /* * Overridden TclCommand method for interfacing the C++ with the Tcl code. * This method cycles over the RtdRPToolSubCmds to search for the method * to call. If no method is found (which it should be) control is passed to * the baseclass method). * * Arguments: * const char *name - name of the subcommand to call * int len - length of the subcommand name * int argc, char **argv - argument list for subcommand * * Return value: * Return value from subcommand. */ int RtdRPTool::call(const char *name, int len, int argc, char *argv[]) { for (int i = 0; i < sizeof(RPsubcmds_)/sizeof(*RPsubcmds_); i++) { RtdRPToolSubCmds *t = &RPsubcmds_[i]; if (strcmp(t->name, name) == 0) { if (check_args(name, argc, t->min_args, t->max_args) != TCL_OK) { return TCL_ERROR; } return (this->*t->fptr)(argc, argv); } } return TclCommand::call(name, strlen(name), argc, argv); } /* * Toggle the cycle mode on or off. If cycle is on, then the playback/recorder * object will return to the start of the file when the file is full/completed. * * Usage: * $rtdrecorder/$rtdplayback cycle <1/0> * * Arguments: * int argc, char *argv[] - argument list, * argv[0] - 0,1 (value for cycleMode_) * * Return value: * TCL_OK / TCL_ERROR */ int RtdRPTool::cycle(int argc, char *argv[]) { // Just copy argument into cycleMode_ cycleMode_ = atoi(argv[0]); if (cycleMode_ < 0) { return error("Bad argument for cycle subcommand"); } return TCL_OK; } /* * Close the dialogue. Call the cleanup function. * * Arguments: * int argc, char *argv[] - argument list, unused * * Return value: * TCL_OK */ int RtdRPTool::close(int argc, char *argv[]) { cleanup(); return TCL_OK; } /* * Set the current file name. * * Usage: * $rtdrecorder/$rtdplayback filename * * Arguments: * int argc, char *argv[] - argument list: * argv[0] - file name * * Return value: * TCL_OK */ int RtdRPTool::filename(int argc, char *argv[]) { // Copy across the file name. strncpy(fileName, argv[0], MAXFILENAMELEN); return TCL_OK; } /* * This is invoked when the dialogue is quit, and does basic memory management, * and deinitialises the server. * * Arguments: * None */ void RtdRPTool::cleanup() { // Remove any open file handler objects. if (fileHandler) { delete(fileHandler); fileHandler = (RtdRPFile *)NULL; Mem_RPTcleanup(); } // Remove the event handle. if (eventHndl_) { rtdClose(eventHndl_, NULL); delete(eventHndl_); eventHndl_ = NULL; } } /* - End of RtdRPTool method definitions - */ /*===========================================================================*/ /* - Start of RtdRecorder method definitions - */ /* * This is called when the recorder object is instantiated from the Tcl code. * This simply creates an RtdRecorder object instance. * * Arguments: * Tcl_Interp *interp - pointer to interpreter structure * char *name - instance name * int argc, char *argv[] - argument list, unused * Tk_ImageType *typePtr - Tk image type * Tk_ImageMaster - Tk image master * ClientData *clientDataPtr - client data * * For more information, see Tk_CreateImageType(3). * * Return value: * TCL_OK */ int RtdRecorder::CreateImage( Tcl_Interp *interp, // Interpreter for application containing image. char *name, // Name to use for image. int argc, // Number of arguments. #if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >= 3 Tcl_Obj *CONST objv[], // Argument objects for options #else char **argv, // Argument strings for options #endif Tk_ImageType *typePtr, // Pointer to our type record (not used). Tk_ImageMaster master, ClientData *clientDataPtr) { #if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >= 3 // just generate an argv from the objv argument char* argv[64]; // there shouldn't be more than a few options... for(int i = 0; i < argc; i++) argv[i] = Tcl_GetString(objv[i]); argv[argc] = NULL; #endif RtdRecorder *im = new RtdRecorder(interp, name, argc, argv, master); return TCL_OK; } /* * RtdRecorder contructor. Initialises the recorder properties. * * Arguments: * As for RtdRPTool - arguments are just passed on to baseclass. */ RtdRecorder::RtdRecorder(Tcl_Interp *interp, char *instname, int argc, char **argv, Tk_ImageMaster master) : RtdRPTool(interp, instname, argc, argv, master), fileFormat_(FITS_CUBE), fileSize_(MAXFILESIZE), attached_(0), subImage_(0), x0_(0), y0_(0), width_(0), height_(0) { // Default camera name is RTDSIMULATOR. strcpy(camera_, "RTDSIMULATOR"); } /* * Callback routine, invoked when the socket connection to the server becomes * readable (i.e. an image has been received). * * Arguments: * ClientData clientData - client data from the callback * int mask - Tcl/Tk mask * * Return value: * None. */ void RtdRecorder::fileEventProc(ClientData clientData, int mask) { // Call a processing routine. RtdRecorder* thisPtr = (RtdRecorder *)clientData; thisPtr->processFileEvent(); } /* * Routine to process the incoming file events. Called from the callback * routine: fileEventProc. If the cycleMode is off then this routine also * stops the data acquisition immediately if the maximum file size is * exceeded. * * Arguments: * None. * * Return value: * None. */ int RtdRecorder::processFileEvent() { rtdIMAGE_INFO imageInfo; if (RtdRPTool::init() == TCL_ERROR) return TCL_ERROR; // Get the image information that is waiting. if (rtdRecvImageInfo(eventHndl_, &imageInfo, 0, NULL) == RTD_ERROR) return TCL_ERROR; // Pass control to the image processor. fileHandler->addImage(&imageInfo, subImage_, x0_, y0_, width_, height_); // Service the semaphore contained in the image information. rtdShmServicePacket(&imageInfo); /* * If the file size has exceeded the maximum, then we want to stop * here. Call the stop routine. */ if (fileHandler->fileSize() > fileSize_ && !cycleMode_) { fprintf(stderr, "Full up!\n"); stop(0, NULL); } if (fileHandler->fileFull() && !cycleMode_) { stop(0, NULL); } return TCL_OK; } /* * Overridden TclCommand method for interfacing the C++ with the Tcl code. * This method cycles over the RtdRPToolSubCmds to search for the method * to call. If no method is found (which it should be) control is passed to * the baseclass method). * * Arguments: * const char *name - name of the subcommand to call * int len - length of the subcommand name * int argc, char **argv - argument list for subcommand * * Return value: * Return value from subcommand. */ int RtdRecorder::call(const char *name, int len, int argc, char *argv[]) { for (int i = 0; i < sizeof(Recsubcmds_)/sizeof(*Recsubcmds_); i++) { RtdRecorderSubCmds *t = &Recsubcmds_[i]; if (strcmp(t->name, name) == 0) { if (check_args(name, argc, t->min_args, t->max_args) != TCL_OK) { return TCL_ERROR; } return (this->*t->fptr)(argc, argv); } } return RtdRPTool::call(name, strlen(name), argc, argv); } /* * Method to set image recording going. * * Usage: * $rtdrecorder record * * Arguments: * int argc, char *argv[] - argument list * * Return value: * TCL_OK / TCL_ERROR */ int RtdRecorder::record(int argc, char *argv[]) { char msg[64]; // User error message if (RtdRPTool::init() == TCL_ERROR) return TCL_ERROR; if (!fileFormat_) { fprintf(stderr, "FileFormat object is NULL\n"); } // Set up an object to control the file handling. File will be opened // after the first image event. if (fileFormat_ == COMP_FITS) { fileHandler = (RtdFITSComp *)new RtdFITSComp(interp_, instname_, fileName, (char *)"\0", fileSize_); } else if (fileFormat_ == FITS_CUBE) { fileHandler = (RtdFITSCube *)new RtdFITSCube(interp_, instname_, fileName, (char *)"\0", fileSize_); } else { return error("Unknown file format specified"); } if (fileHandler->status() == TCL_ERROR) { sprintf(msg, "Unable to open file %s", fileName); return error(msg); } // Attach to the current camera to start receiving images, if not already. if (!attached_) { if (rtdAttachImageEvt(eventHndl_, camera_, NULL) != RTD_OK) { return error("Error attaching camera to server"); } } attached_ = 1; // Set up a file handler to detect the incoming image events. Tk_CreateFileHandler(eventHndl_->socket, TK_READABLE, fileEventProc, (ClientData)this); return TCL_OK; } /* * Stop method for the recorder tool. This detaches from the camera, closes * the file handler object, and removes the Tk file handler. * * Usage: * $rtdrecorder/$rtdplayback stop * * Arguments: * int argc, char *argv[] - argument list, unused * * Return value: * TCL_OK */ int RtdRecorder::stop(int argc, char *argv[]) { rtdIMAGE_INFO imageInfo; // Temp image information structure if (RtdRPTool::init() == TCL_ERROR) return TCL_ERROR; // Detach from the camera. if (attached_) { // Delete the Tk file handler. Tk_DeleteFileHandler(eventHndl_->socket); attached_ = 0; rtdDetachImageEvt(eventHndl_, camera_, NULL); // Get any outstanding images from the queue and process their semaphores. if (rtdRecvImageInfo(eventHndl_, &imageInfo, 0, NULL) != RTD_ERROR) { rtdShmServicePacket(&imageInfo); } } // Delete the file handling object. if (fileHandler) { delete(fileHandler); fileHandler = (RtdRPFile *)NULL; Mem_RPTcleanup(); } return TCL_OK; } /* * Method to set the current maximum file size or the file format type * in the recorder. * * Usage: * $rtdrecorder file size * $rtdrecorder file format * where is the maximum file size in Mb and is 0 for * compressed FITS, 1 for FITS cube. * * Arguments: * int argc, char *argv[] - argument list: * argv[0] - size/format * argv[1] - argument to argv[0] * * Return value: * TCL_OK / TCL_ERROR */ int RtdRecorder::file(int argc, char *argv[]) { if (strcmp(argv[0], "size") == 0) { fileSize_ = atof(argv[1]); } else if (strcmp(argv[0], "format") == 0) { fileFormat_ = (enum fileFormat)atoi(argv[1]); } else { return error("Bad argument for $rtdrecorder file"); } return TCL_OK; } /* * Method to set the current camera. * * Usage: * $rtdrecorder camera * where is the camera name to receive images from. * * Arguments: * int argc, char *argv[] - argument list * argv[0] - camera name * * Return value: * TCL_OK */ int RtdRecorder::camera(int argc, char *argv[]) { strncpy(camera_, argv[0], 32); return TCL_OK; } /* * Method to set the subimage facility of the recorder tool. * * Usage: * $rtdrecorder subimage ?x? ?y? ?width? ?height? * where is set to 'on' if the subimage sampling is to be turned on, * and 'off' if turned off. x, y, width, and height are specified if the * facility is being turned on. Note that (x,y) are image coordinates of * the top left corner - FITS data is written from the bottom left and * so the y coordinate must be transformed in this routine. * * Arguments: * int argc, char *argv, argument list, see above. * * Return value: * TCL_OK / TCL_ERROR */ int RtdRecorder::subimage(int argc, char *argv[]) { // Check the first argument. if (strcmp(argv[0], "on") == 0) { subImage_ = 1; } else if (strcmp(argv[0], "off") == 0) { subImage_ = 0; return TCL_OK; } else { return error("Bad first argument to subimage subcommand"); } // Get the subsequent arguments for when the sampling is enabled. x0_ = atoi(argv[1]); y0_ = atoi(argv[2]); width_ = atoi(argv[3]); height_ = atoi(argv[4]); y0_ -= height_; return TCL_OK; } /* - End of RtdRecorder method definitions - */ /*===========================================================================*/ /* - Start of RtdPlayback method definitions - */ /* * This is called when the playback object is instantiated from the Tcl code. * This simply creates an RtdPlayback object instance. * * Arguments: * Tcl_Interp *interp - pointer to interpreter structure * char *name - instance name * int argc, char *argv[] - argument list, unused * Tk_ImageType *typePtr - Tk image type * Tk_ImageMaster - Tk image master * ClientData *clientDataPtr - client data * * For more information, see Tk_CreateImageType(3). * * Return value: * TCL_OK */ int RtdPlayback::CreateImage( Tcl_Interp *interp, // Interpreter for application containing image. char *name, // Name to use for image. int argc, // Number of arguments. #if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >= 3 Tcl_Obj *CONST objv[], // Argument objects for options (not including image name or type) #else char **argv, // Argument strings for options (not including image name or type) #endif Tk_ImageType *typePtr, // Pointer to our type record (not used). Tk_ImageMaster master, ClientData *clientDataPtr) { #if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >= 3 // just generate an argv from the objv argument char* argv[64]; // there shouldn't be more than a few options... for(int i = 0; i < argc; i++) argv[i] = Tcl_GetString(objv[i]); argv[argc] = NULL; #endif RtdPlayback *im = new RtdPlayback(interp, name, argc, argv, master); return TCL_OK; } /* * RtdRecorder contructor. Initialises the recorder properties. * * Arguments: * As for RtdRPTool - arguments are just passed on to baseclass. */ RtdPlayback::RtdPlayback(Tcl_Interp *interp, char *instname, int argc, char **argv, Tk_ImageMaster master) : RtdRPTool(interp, instname, argc, argv, master), direction_(1), playSpeed_(SPEED_SLOW), timer_((Tcl_TimerToken)-1), spool_(0) {} /* * Method to create a file handler from an existing file. This method calls * the makeFileObject static method of the RtdRPFile class to create the * file handler from the file name, and initialises the file pointer and * image counter appropriately. * * Arguments: * char *err - error message to return to caller * * Return value: * TCL_OK / TCL_ERROR */ int RtdPlayback::makeFileHandler(char *err) { // First create the right type of file object for the file name. fileHandler = RtdRPFile::makeFileObject(interp_, instname_, fileName, err); // Test that the file object has been created successfully. if (fileHandler == NULL) { return TCL_ERROR; } if (fileHandler->status() == TCL_ERROR) { sprintf(err, "Unable to read file for playback"); return TCL_ERROR; } // Create the shared memory areas from the file information if (fileHandler->getShm(RTD_SHMBUFFS, &shmInfo_) == TCL_ERROR) { sprintf(err, "Unable to allocate shared memory"); return TCL_ERROR; } return TCL_OK; } /* * This method adds a timeout callback to reinvoke to send image routines * after a certain time. The timeout interval is governed by the setting * chosen by the user. * * Arguments: * None * * Return value: * None */ void RtdPlayback::makeTimeOut() { double timePeriod; // Time interval in msecs. // Determine time interval based on user requirements. switch(playSpeed_) { case SPEED_SLOW: timePeriod = SLOWSPEED; break; case SPEED_FAST: timePeriod = FASTSPEED; break; case SPEED_RT: // In this case, the period reflects the timestamp data recorded // when the images were recorded. timePeriod = fileHandler->getTimeIncrement(direction_); break; default: // Unknown speed type. fprintf(stderr, "Error: unknown replay speed type"); timePeriod = SLOWSPEED; break; } // Invoke callback. timer_ = Tcl_CreateTimerHandler((int)timePeriod, sendEventProc, this); } /* * Static method called from the timer callback for sending images to the * server daemon. This just passes control to the main send routine, * sendImage(). * * Arguments: * ClientData - Tcl/Tk client data. * * Return value: * None. */ void RtdPlayback::sendEventProc(ClientData clientData) { RtdPlayback *thisPtr = (RtdPlayback *)clientData; thisPtr->sendImage(1); } /* * Protected method to retrieve image data from the file handler and send * it to the RTD server daemon. * * Arguments: * int reinvoke - if true, this sets up a timeout to reinvoke the routine * after the user defined time period. * * Return value: * TCL_OK / TCL_ERROR */ int RtdPlayback::sendImage(int reinvoke) { int index; // Index of shm buffer filled with data. if (RtdRPTool::init() == TCL_ERROR) return TCL_ERROR; // Before doing anything, check if we have reached the end of the file // and we want to stop here. if (!cycleMode_) { if (direction_ && (fileHandler->imageCounter() == fileHandler->numFileImages()) || (!direction_ && fileHandler->imageCounter() == 1)) { if (fileHandler->numFileImages() > 1) { fileHandler->update_count(); return TCL_OK; } else reinvoke = 0; } } // Get the image data into a shared memory buffer. if (direction_) { index = fileHandler->getNextImage(&shmInfo_); } else { index = fileHandler->getPrevImage(&shmInfo_); } if (index == -1) { return TCL_OK; // maybe shm is locked } rtdIMAGE_INFO imageInfo; // Image information for send. // Create a image information structure. memset(&imageInfo, '\0', sizeof(rtdIMAGE_INFO)); imageInfo.frameX = 0; imageInfo.frameY = 0; imageInfo.frameId = 0; imageInfo.xPixels = fileHandler->xPixels(); imageInfo.yPixels = fileHandler->yPixels(); imageInfo.dataType = fileHandler->dataType(); // Fill in the remaining fields. rtdShmStruct(index, &imageInfo, &shmInfo_); // Send the shared memory off. if (rtdSendImageInfo(eventHndl_, &imageInfo, NULL) != RTD_OK) return TCL_ERROR;; // Add a timeout callback to reinvoke this routine, if required. if (reinvoke) { makeTimeOut(); } return TCL_OK; } /* * Overridden TclCommand method for interfacing the C++ with the Tcl code. * This method cycles over the RtdRPToolSubCmds to search for the method * to call. If no method is found (which it should be) control is passed to * the baseclass method). * * Arguments: * const char *name - name of the subcommand to call * int len - length of the subcommand name * int argc, char **argv - argument list for subcommand * * Return value: * Return value from subcommand. */ int RtdPlayback::call(const char *name, int len, int argc, char *argv[]) { for (int i = 0; i < sizeof(Playsubcmds_) / sizeof(*Playsubcmds_); i++) { RtdPlaybackSubCmds *t = &Playsubcmds_[i]; if (strcmp(t->name, name) == 0) { if (check_args(name, argc, t->min_args, t->max_args) != TCL_OK) { return TCL_ERROR; } return (this->*t->fptr)(argc, argv); } } return RtdRPTool::call(name, strlen(name), argc, argv); } /* * Playback fast forward or reverse functions. We must ensure that we have a * fileHandler instance created before we start fast-forwarding, as we need * to know the size of the file, etc. * * Usage: * $rtdplayback spool * where is "ff" or "rewind" * * Arguments: * int argc, char *argv[] - argument list, see above * * Return value: * TCL_OK / TCL_ERROR */ int RtdPlayback::spool(int argc, char *argv[]) { char errMsg[64]; // Return error message. if (RtdRPTool::init() == TCL_ERROR) return TCL_ERROR; // Check that we have a file handler if (!fileHandler) { if (makeFileHandler(&errMsg[0]) != TCL_OK) { return error(&errMsg[0]); } } if (strcmp(argv[0], "rewind") == 0) { stop(0, NULL); fileHandler->gotoImageCount(1); if (sendImage(0) == TCL_ERROR) return error("Error sending initial image data segment"); return TCL_OK; } else if (strcmp(argv[0], "ff") != 0) { return error("Bad argument for spool command"); } if (spool_) return TCL_OK; // Flag that we are now doing a spool spool_ = 1; playSpeed_ = SPEED_FAST; if (sendImage(1) == TCL_ERROR) { return error("Error sending initial image data segment"); } return TCL_OK; } /* * Playback play function. We must ensure that we have a fileHandler object * instance created before starting. * * Usage: * $rtdplayback play * * Arguments: * int argc, char *argv[] - argument list, unused * * Return value: * TCL_OK / TCL_ERROR */ int RtdPlayback::play(int argc, char *argv[]) { char errMsg[64]; // Error message buffer if (RtdRPTool::init() == TCL_ERROR) return TCL_ERROR; if (!fileHandler) { if (makeFileHandler(&errMsg[0]) != TCL_OK) { return error(&errMsg[0]); } } // If we have no timestamp information, we can't playback in real-time. if (!fileHandler->hasTimeInfo() && playSpeed_ == SPEED_RT) { playSpeed_ = SPEED_SLOW; } if (sendImage(1) == TCL_ERROR) { return error("Error sending initial image data segment"); } return TCL_OK; } /* * Reset the playback tool - close the file handler. * * Usage: * $rtdplayback reset * * Arguments: * int argc, char *argv[] - argument list, unused * * Return value: * TCL_OK / TCL_ERROR */ int RtdPlayback::reset(int argc, char *argv[]) { // Remove the file handler. if (fileHandler) { delete(fileHandler); fileHandler = (RtdRPFile *)NULL; Mem_RPTcleanup(); } return TCL_OK; } /* * Set the playback object properties, i.e. playback direction, speed. * * Usage: * $rtdplayback props speed * $rtdplayback props direction

* where is the speed number as specified in the enum defined in * the header file, and is 1 for forwards, 0 for reverse. * * Arguments: * int argc, char *argv[] - argument list, see above * * Return value: * TCL_OK / TCL_ERROR */ int RtdPlayback::props(int argc, char *argv[]) { // XXX allan: 10.4.98: increased size of errMsg from 64, // XXX Memory is not that expensive these days, and it avoids crashing... char errMsg[2*1024]; // Error message buffer int direction, count, incr = 0; // Check that we have a file handler if (!fileHandler) { if (makeFileHandler(&errMsg[0]) != TCL_OK) { return error(&errMsg[0]); } } if (strcmp(argv[0], "speed") == 0) { playSpeed_ = (enum playSpeed)atoi(argv[1]); } else if (strcmp(argv[0], "direction") == 0) { direction = atoi(argv[1]); if (direction) { direction = 1; incr = 1; } // after changing the direction goto the right file position if (direction != direction_) { count = incr + fileHandler->imageCounter(); fileHandler->gotoImageCount(count); } direction_ = direction; } else { return error("Bad argument for setprop command"); } return TCL_OK; } /* * Step the current playback image one frame in the current direction. If the * filehandler is not yet initialised, do this first. * * This routine is virtually identical to the play method, but is kept * distinct for simplicity. * * Usage: * $rtdplayback step * * Arguments: * int argc, char *argv[] - argument list, unused * * Return value: * TCL_OK / TCL_ERROR */ int RtdPlayback::step(int argc, char *argv[]) { char errMsg[64]; // Error message buffer if (RtdRPTool::init() == TCL_ERROR) return TCL_ERROR; if (!fileHandler) { if (makeFileHandler(&errMsg[0]) != TCL_OK) { return error(&errMsg[0]); } } // Send an image to the server without reinvoking the send routine after // a timeout. if (sendImage(0) == TCL_ERROR) { return error("Error sending initial image data segment"); } return TCL_OK; } /* * Change the filename of the playback object. * * Usage: * $rtdplayback filename * * Arguments: * int argc, char *argv[] - argument list, * argv[0] - file name * * Return value: * TCL_OK / TCL_ERROR */ int RtdPlayback::filename(int argc, char *argv[]) { /* * Check to see if the file name has changed. If it has, then we want * to remove the current file handler and create a new one when this is * required. If the file name is the same, then nothing has changed so * we call the baseclass method alone. */ if (strcmp(argv[0], fileName) != 0) { if (fileHandler) { delete(fileHandler); fileHandler = (RtdRPFile *)NULL; // Remove the shared memory areas associated with this Mem_RPTcleanup(); } } // Baseclass method. return(RtdRPTool::filename(argc, argv)); } /* * Stop the current playback. * * Usage: * $rtdplayback stop * * Arguments: * int argc, char *argv[] - argument list, not used * * Return value: * TCL_OK / TCL_ERROR */ int RtdPlayback::stop(int argc, char *argv[]) { // If we are stopping a spool, then reset the spool_ flag spool_ = 0; // Remove the timer callback (if it exists) to prevent any more pictures // being displayed. Tcl_DeleteTimerHandler(timer_); timer_ = (Tcl_TimerToken)-1; return TCL_OK; } /* * Close the playback object. * * Usage: * $rtdplayback close * * Arguments: * int argc, char *argv[] - argument list * * Return value: * TCL_OK / TCL_ERROR */ int RtdPlayback::close(int argc, char *argv[]) { // Call the baseclass destructor. RtdRPTool::cleanup(); // Remove the shared memory/semaphore set. Mem_RPTcleanup(); return TCL_OK; } /* * Return whether or not the file has timestamp information (for real-time * playback). * * Usage: * $rtdplayback hastime * * Arguments: * int argc, char *argv[] - argument list * * Return value: * 0 (file not timestamped), 1 (file timestamped). */ int RtdPlayback::hastime(int argc, char *argv[]) { char buf[2]; // Return buffer // Check file handler exists. if (!fileHandler) { return error("File handler is not instantiated"); } // Return the result. sprintf(buf, "%d", fileHandler->hasTimeInfo()); return set_result(buf); } /* * Goto to the image index specified by the argument. * * Usage: * $rtdplayback gotoimage * * Arguments: * int argc, char *argv[] - argument list * - argv[0] - index of image to go to. * * Return value: * TCL_OK / TCL_ERROR */ int RtdPlayback::gotoimage(int argc, char *argv[]) { int index; // Image index to go to. // Check that there is a file handler. if (!fileHandler) { return TCL_OK; } // Check that the image index is in the right range. index = atoi(argv[0]); if (index < 0) { return error("Chosen index is out of range"); } // Go to the appropriate index fileHandler->gotoImageCount(index); return TCL_OK; } void Mem_RPTcleanup() { // Remove the shared memory/semaphore set. rtdShmDelete(&shmInfo_); } skycat-3.1.2-starlink-1b/rtd/generic/RtdRPTool.h000066400000000000000000000154541215713201500213550ustar00rootroot00000000000000#ifndef RTDRPTOOL_H #define RTDRPTOOL_H /* * E.S.O. - VLT project / ESO Archive * * RtdRPTool.h - class definitions for class RtdRPTool, RtdRecorder, * and RtdPlayback. * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * D.Hopkinson 20/02/97 Created * D.Hopkinson 17/04/97 Changed name to RtdRPTool and added * inheritance from this. * pbiereic 28/05/01 Included Allan's changes for tcl8.3.3 */ #include #include #include #include "TclCommand.h" #include "Mem.h" #include "rtdImageEvent.h" #include "tk.h" #include "Fits_IO.h" #include "DCompress.h" #include "rtdSem.h" #include "RtdRPFile.h" #define MAXRECORDS 60 // Maximum number of records in file. #define MAXFILENAMELEN 1024 // Maximum length of file names. (allan: changed from 128) #define MAXFILESIZE 5 // Maximum size of data file in Mb. #define SLOWSPEED 4000. // Time between images when playing slow (in msec) #define FASTSPEED 200. // Time between sends when playing fast (in msec) /* * This is an abstract class that simply acts as the parent of the recorder * and playback objects. It contains the various common properties, and also * carries the definitions for the more abstract Tcl commands executed from * the recorder tool. */ class RtdRPTool : public TclCommand { protected: char fileName[MAXFILENAMELEN]; // Filename to load images into. rtdIMAGE_EVT_HNDL *eventHndl_; // Event handle for server connection. Display *display; // Server connection. Tk_ImageMaster master_; // Tk master. Tk_Window tkwin_; // Tk window. int status_; // Object status int cycleMode_; // Flag: cycle round to start of file. RtdRPFile *fileHandler; // Pointer to file handler object. // Constructor. RtdRPTool(Tcl_Interp* interp, char* instname, int argc, char** argv, Tk_ImageMaster master); // Cleanup routine void cleanup(); public: // Destructor. ~RtdRPTool(); // Overridden subcommand calling method. virtual int call(const char *name, int len, int argc, char *argv[]); // Subcommand definition methods. int close(int argc, char *argv[]); int init(); virtual int filename(int argc, char *argv[]); int cycle(int argc, char *argv[]); int status(int argc, char *argv[]) {return status_;} }; /* * Class definition for the recorder object. This is derived from the general * properties of the RtdRPTool object. */ class RtdRecorder : public RtdRPTool { protected: char camera_[32]; // Camera to attach to. double fileSize_; // Maximum allowed size of saved file. int attached_; // Flag: currently attached to camera. enum fileFormat { COMP_FITS, // Compressed FITS - not implemented FITS_CUBE // FITS cube } fileFormat_; // Format to use in file save. int subImage_; // Flag true if using subimage int x0_, y0_; // Bottom left coords of subimage int width_, height_; // Dimensions of subimage // Function called when image event received by recorder. static void fileEventProc(ClientData clientData, int mask); // Routine to process the incoming image event. int processFileEvent(); public: // Constructor RtdRecorder(Tcl_Interp *interp, char *instname, int argc, char **argv, Tk_ImageMaster master); // Destructor ~RtdRecorder() {} // currently empty // Action routines defined in the Tk_ImageType structure. Most of these // are no-ops. static int CreateImage(Tcl_Interp*, char *name, int argc, #if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >= 3 Tcl_Obj *CONST objv[], #else char **argv, #endif Tk_ImageType*, Tk_ImageMaster, ClientData*); static ClientData GetImage(Tk_Window, ClientData) {return 0;} static void DisplayImage(ClientData, Display*, Drawable, int imageX, int imageY, int width, int height, int drawableX, int drawableY) {} static void FreeImage(ClientData, Display*) {} static void DeleteImage(ClientData) {} // Subcommand calling method. int call(const char *name, int len, int argc, char *argv[]); // Subcommand definitions int record(int argc, char *argv[]); int camera(int argc, char *argv[]); int file(int argc, char *argv[]); int stop(int argc, char *argv[]); int subimage(int argc, char *argv[]); }; /* * Class definition for the playback object. This is derived from the general * properties of the RtdRPTool object. */ class RtdPlayback : public RtdRPTool { protected: int direction_; // Flag: true if playing forwards enum playSpeed { SPEED_SLOW, SPEED_FAST, SPEED_RT } playSpeed_; // Playback speed Tcl_TimerToken timer_; // Timer handler for managing the timer callback int spool_; // Flag: we are doing a fast-forward/rewind. // Called from timer callback. static void sendEventProc(ClientData clientData); // Retrieve data from file and send to rtdServer daemon. int sendImage(int reinvoke); // Add a timeout to send the next image. void makeTimeOut(); // Method to make a file handler object instance from an existing file int makeFileHandler(char *err); // Utility to provide a short time interval for the spool increments void spoolPause(); public: // Constructor RtdPlayback(Tcl_Interp *interp, char *instname, int argc, char **argv, Tk_ImageMaster master); // Destructor ~RtdPlayback() {} // currently empty // Action routines defined in the Tk_ImageType structure. Most of these // are no-ops at the moment. static int CreateImage(Tcl_Interp*, char *name, int argc, #if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >= 3 Tcl_Obj *CONST objv[], #else char **argv, #endif Tk_ImageType*, Tk_ImageMaster, ClientData*); static ClientData GetImage(Tk_Window, ClientData) {return 0;} static void DisplayImage(ClientData, Display*, Drawable, int imageX, int imageY, int width, int height, int drawableX, int drawableY) {} static void FreeImage(ClientData, Display*) {} static void DeleteImage(ClientData) {} // Subcommand calling method. int call(const char *name, int len, int argc, char *argv[]); // Subcommand definitions int close(int argc, char *argv[]); int filename(int argc, char *argv[]); int gotoimage(int argc, char *argv[]); int hastime(int argc, char *argv[]); int play(int argc, char *argv[]); int reset(int argc, char *argv[]); int spool(int argc, char *argv[]); int props(int argc, char *argv[]); int step(int argc, char *argv[]); int stop(int argc, char *argv[]); }; // cleanup shared mem void Mem_RPTcleanup(); #endif skycat-3.1.2-starlink-1b/rtd/generic/RtdRemote.C000066400000000000000000000304621215713201500213600ustar00rootroot00000000000000/* * E.S.O. - VLT project/ESO Archive * "@(#) $Id: RtdRemote.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * RtdRemote.C - member routines for class RtdRemote, manages remote access * to RtdImage (server side, see ../../rtdrmt/... for client access) * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 04/03/96 Created * Peter W. Draper 13/03/98 Now stores Tcl_File handle. This is to * work around a bug in OSF/1 Tcl which * loses this values occasionally. * Allan Brighton 18/03/99 Added #ifdef in RtdRemote.h, since Tcl_File * is no longer supported in tcl8... * Peter W. Draper 11/05/99 Added changes to getsockname calls so * that size_t or int are used for addrSize (this * is needed for OSF/1). * 16/12/05 Change all SOCKLEN_T use to socklen_t. The logic * that guarantees a value is set in define.h. */ static const char* const rcsId="@(#) $Id: RtdRemote.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "error.h" #include "define.h" #ifdef HAVE_SYS_FILIO_H #include #endif #include "RtdRemote.h" // this call changed in tcl8 #if (TCL_MAJOR_VERSION >= 8) #define RTD_TCL_GETFILE_(x) x #else #define RTD_TCL_GETFILE_(x) Tcl_GetFile((void *)x, TCL_UNIX_FD) #endif // should be in sys/shm.h #ifdef NEED_SHM_PROTO /*extern "C" void *shmat(int shmid, const void* shmaddr, int shmflg); extern "C" int shmdt(const void* shmaddr);*/ #endif #ifdef NEED_SOCKET_PROTO // some protos missing in SunOS extern "C" { int socket(int, int, int); int connect(int, const void*, int); int strncasecmp(char*, char*, int); int bind(int s, struct sockaddr *name, int namelen); int listen(int s, int backlog); int ioctl(int fd, int request, void* arg); int select (int width, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, timeval *timeout); int accept(int s, sockaddr *addr, int *addrlen); void bzero(char *b, int length); getsockname(int s, struct sockaddr *name, int *namelen); } #endif /* NEED_SOCKET_PROTO */ #if 0 #ifdef NEED_GETHOSTNAME_PROTO // these are also missing on solaris extern "C" int gethostname(char *name, unsigned int namelen); #endif /* NEED_GETHOSTNAME_PROTO */ #endif /* -- I/O routines for network I/O taken from the book -- * "UNIX Network Programming" by W. Richard Stevens, */ /* * Read "n" bytes from a descriptor. * Use in place of read() when fd is a stream socket. */ static int readn(int fd, char* ptr, int nbytes) { int nleft, nread; nleft = nbytes; while (nleft > 0) { nread = read(fd, ptr, nleft); if (nread < 0) return(nread); /* error, return < 0 */ else if (nread == 0) break; /* EOF */ nleft -= nread; ptr += nread; } return(nbytes - nleft); /* return >= 0 */ } /* * Read the line one byte at a time, looking for the newline. We store * the newline in the buffer, then follow it with a null (the same as * fgets(3)). Not very efficient but usefull for sockets. * * Returns the number of characters up to, but not including, the null * (the same as strlen(3)) or < 0 upon errors. */ static int readline(int fd, char* ptr, int maxlen) { int n, rc; char c; for (n = 1; n < maxlen; n++) { if ( (rc = read(fd, &c, 1)) == 1) { *ptr++ = c; if (c == '\n') break; } else if (rc == 0) { if (n == 1) return(0); // EOF, no data read else break; // EOF, some data was read } else return(-1); // error } *ptr = 0; return(n); } /* * Write "n" bytes to a descriptor. * Use in place of write() when fd is a stream socket. */ static int writen(int fd, const char* ptr, unsigned long nbytes) { int nleft, nwritten; nleft = nbytes; while (nleft > 0) { nwritten = write(fd, ptr, nleft); if (nwritten <= 0) return(nwritten); /* error */ nleft -= nwritten; ptr += nwritten; } return(nbytes - nleft); } /* * write the given buffer to the given file followed by a newline */ static int writeline(int fd, char* ptr) { return writen(fd, ptr, strlen(ptr)) + writen(fd, "\n", 1); } /* * constructor */ RtdRemote::RtdRemote(Tcl_Interp* interp, int port, int verbose) : status_(0), socket_(-1), interp_(interp), verbose_(verbose), clientPtr_(NULL) { // clear out client table memset ((char *)&clients_, 0, sizeof(clients_)); // clear out address structures sockaddr_in addr; // for local socket address socklen_t addrSize = (socklen_t) sizeof(addr); memset ((char *)&addr, 0, addrSize); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons( port ); // Create the listen socket. socket_ = socket (AF_INET, SOCK_STREAM, 0); if (socket_ == -1) { status_ = sys_error("socket"); return; } // Bind the listen address to the socket. if (bind(socket_, (struct sockaddr *)&addr, addrSize) == -1) { status_ = sys_error("bind"); return; } // note port and host info in a file for client use if ((status_ = makeStatusFile(addr)) != 0) return; // note the port number port_ = ntohs( addr.sin_port ); #ifdef DEBUG if (verbose_) printf("RtdRemote: using port number %d\n", port_); #endif // Initiate the listen on the socket so remote users // can connect. The listen backlog is set to 5. 20 // is the currently supported maximum. if (listen(socket_, 5) == -1) { status_ = sys_error("listen"); return; } Tcl_CreateFileHandler(RTD_TCL_GETFILE_(socket_), TCL_READABLE, fileEventProc, (ClientData)this); } /* * destructor */ RtdRemote::~RtdRemote() { } /* * create a file $HOME/.rtd-remote containing these values: * * pid hostname port * * so that the client library can determine how to access this server. */ int RtdRemote::makeStatusFile(sockaddr_in& addr) { socklen_t addrSize = (socklen_t)sizeof(sockaddr_in); if (getsockname(socket_, (struct sockaddr *)&addr, &addrSize) == -1) return sys_error("getsockname"); char filename[1024]; char* home = getenv("HOME"); sprintf(filename, "%s/.rtd-remote", (home ? home : "/tmp")); FILE* f = fopen(filename, "w+"); if (!f) return sys_error(filename); char hostname[80]; if (gethostname(hostname, sizeof(hostname)) != 0) strcpy(hostname, "localhost"); fprintf(f, "%u %s %u\n", getpid(), hostname, ntohs(addr.sin_port)); fclose(f); return 0; } /* * enter client socket in clients table and return the index or * -1 for errors */ int RtdRemote::enterClient(int sock) { for (int i = 0; i < MAX_CLIENTS; i++) { if (clients_[i].socket == 0) { clients_[i].socket = sock; clients_[i].handle = RTD_TCL_GETFILE_(sock); clients_[i].thisPtr = this; return i; } } return -1; } /* * remove the client and close the socket */ void RtdRemote::removeClient(int sock) { for (int i = 0; i < MAX_CLIENTS; i++) { if (clients_[i].socket == sock) { Tcl_DeleteFileHandler(RTD_TCL_GETFILE_(sock)); #if (TCL_MAJOR_VERSION < 8) Tcl_FreeFile( clients_[i].handle ); #endif close(sock); clients_[i].socket = 0; clients_[i].handle = 0; clients_[i].thisPtr = NULL; return; } } } /* * This method is called when there is a new connection on the socket */ int RtdRemote::fileEvent() { fd_set readMask, readFds; FD_ZERO(&readMask); FD_SET(socket_, &readMask); memcpy(&readFds, &readMask, sizeof(fd_set)); timeval timeout; timeout.tv_sec = timeout.tv_usec = 0; #ifdef HAVE_SELECT_FD_SET int status = select(32, (fd_set *)&readFds, 0, 0, &timeout); #else int status = select(32, (int *)&readFds, 0, 0, &timeout); #endif if (status < 0) return sys_error("select"); else if (status == 0) return TCL_OK; if (FD_ISSET(socket_, &readFds) > 0) { struct sockaddr_in addr; // for local socket address socklen_t addrSize = (socklen_t)sizeof(addr); int sock = accept(socket_, (sockaddr *)&addr, &addrSize); if (sock < 0) return sys_error("accept"); int free = enterClient(sock); if (free != -1) { #ifdef DEBUG if (verbose_) printf("RtdRemote: accept on socket: %d, port:%d\n", sock, addr.sin_port); #endif Tcl_CreateFileHandler(RTD_TCL_GETFILE_(sock), TCL_READABLE, clientEventProc, (ClientData)&clients_[free]); } } return TCL_OK; } /* * send the buffer to the client using the given socket. The format is * * status length\n * result[length] * * where status is 0 or 1 (the return status of the command), length is * the length of the result in bytes and result is the result buffer. * status and length are written as ascii integers on a separate line * followed by the result on the second line. */ int RtdRemote::sendToClient(int socket, int status, int length, const char* result) { char buf[80]; sprintf(buf, "%d %d\n", status, length); if (writen(socket, buf, strlen(buf)) <= 0 || writen(socket, result, length) < 0) { return sys_error("error writing to client"); } return 0; } /* * evaluate the command buf as rtdimage subcommands and return the command's * status. * * XXX Note that some commands should probably not be called from a remote client... */ int RtdRemote::evalClientCmd(const char* cmd) { Tcl_ResetResult(interp_); // split command into argc/argv... int argc = 0; char** argv = NULL; if (Tcl_SplitList(interp_, (char*)cmd, &argc, &argv) != TCL_OK) return TCL_ERROR; if (argc <= 0) return TCL_OK; // ignore empty command const char* name = argv[0]; // command name int len = strlen(name); argc--; char** av = argv + 1; // call the RtdImage command method // argv[0] is the subcommand name, the rest are the arguments if (call(name, len, argc, av) != TCL_OK) { Tcl_Free((char *)argv); return TCL_ERROR; } Tcl_Free((char *)argv); return TCL_OK; } /* * This method is called when there is a message to read from one of the * clients. The message should contain * * * * where is a binary integer in network byte order, the length * of the to read. * */ int RtdRemote::clientEvent(Client* clientPtr) { clientPtr_ = clientPtr; // save current client ptr if (clientPtr->socket == 0) return TCL_OK; #ifdef DEBUG if (verbose_) printf("RtdRemote: Input on client socket: %d\n",clientPtr->socket); #endif int readable = 0; ioctl(clientPtr->socket, FIONREAD, &readable); #ifdef DEBUG if (verbose_) printf("RtdRemote: Bytes readable: %d\n",readable); #endif if (readable <= 0) { removeClient(clientPtr->socket); return TCL_OK; } char buf[2*1024]; if (readline(clientPtr->socket, buf, sizeof(buf)) < 0) return sys_error("error reading command from Rtd client"); #ifdef DEBUG if (verbose_) printf("RtdRemote: got: '%s'\n", buf); #endif int status = evalClientCmd(buf); return sendToClient(clientPtr->socket, status, strlen(Tcl_GetStringResult(interp_)), Tcl_GetStringResult(interp_)); } /* * This static method is called when there is a message to read * on the socket. Pass control to the class method. */ void RtdRemote::fileEventProc(ClientData clientData, int mask) { RtdRemote* thisPtr = (RtdRemote*)clientData; if (thisPtr->fileEvent() != TCL_OK) { Tk_BackgroundError(thisPtr->interp_); } } /* * This static method is called when there is a message to read * on a client socket. Pass control to the class method. */ void RtdRemote::clientEventProc(ClientData clientData, int mask) { RtdRemote::Client* clientPtr = (RtdRemote::Client*)clientData; if (! clientPtr) { error("no client data"); return; } if (clientPtr->thisPtr->clientEvent(clientPtr) != TCL_OK) { Tk_BackgroundError(clientPtr->thisPtr->interp_); } } skycat-3.1.2-starlink-1b/rtd/generic/RtdRemote.h000066400000000000000000000055611215713201500214270ustar00rootroot00000000000000// -*-c++-*- #ifndef _RtdRemote_h_ #define _RtdRemote_h_ /* * E.S.O. - VLT project * "@(#) $Id: RtdRemote.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * RtdRemote.h - class definitions for managing remote access to the RTD * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 04/03/96 Created */ #include "tk.h" /* * Class RtdRemote * */ class RtdRemote { protected: int status_; // status after constructor int port_; // port number for communication int socket_; // socket for remote commands int verbose_; // flag: if true, print diagnostic messages Tcl_Interp* interp_; // Tcl interp (for file events, error handling) enum {MAX_CLIENTS = 32}; // max number of client connections struct Client { int socket; // client socket for sending results int callback_socket; // socket used for callback operations #if (TCL_MAJOR_VERSION >= 8) int handle; // file descriptor for events #else Tcl_File handle; // Tcl file handle for events #endif RtdRemote* thisPtr; // hook to get back to class from callback }; Client clients_[MAX_CLIENTS]; // array of client connection sockets Client* clientPtr_; // ptr to current client connection // create a status file with pid/port info int makeStatusFile(struct sockaddr_in& addr); // method called by fileEventProc to accept new client connection int fileEvent(); // method called by clientEventProc to read from client int clientEvent(Client*); // enter client socket in clients table int enterClient(int sock); // remove the client from the table void removeClient(int sock); // command methods virtual int draw() {return 0;} // call an rtdimage command method by name (defined in a derived class) // (see RtdImage.C for local derived class) virtual int call(const char* name, int len, int argc, char* argv[]) = 0; // send a message to the client with "status length result" int sendToClient(int socket, int status, int length, const char* result); // evaluate the command buf as rtdimage subcommands int evalClientCmd(const char* cmd); public: // constructor RtdRemote(Tcl_Interp*, int port, int verbose); // destructor virtual ~RtdRemote(); // static file handler, called by Tk file handler for new connections static void fileEventProc(ClientData, int mask); // static file handler, called to read client socket static void clientEventProc(ClientData, int mask); // open the current client's callback socket on the given host and port int setClientCallbackPort(const char* host, int port); // member access int status() {return status_;} int port() {return port_;} }; #endif /* _RtdRemote_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/RtdUtils.C000066400000000000000000000037301215713201500212230ustar00rootroot00000000000000/******************************************************************************* * E.S.O. - VLT project * * "@(#) $Id: RtdUtils.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * who when what * -------- -------- ---------------------------------------------- * pbiereic 01/03/01 created (copied from RtdImage.C) */ /************************************************************************ * NAME * * RtdUtils.C - RtdImge utilities * * SYNOPSIS * * * DESCRIPTION * * RtdUtils.C contains utility routines commonly used by code in the rtdimg/src * directroy * * FILES * * ENVIRONMENT * * CAUTIONS * * SEE ALSO * RtdImage(3), RTD documentation * * BUGS * *------------------------------------------------------------------------ */ static const char *rcsId="@(#) $Id: RtdUtils.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include "RtdUtils.h" /* * clip x to withing range x0 .. x1 */ void clip(double& x, double x0, double x1) { if (x0 < x1) { if (x < x0) x = x0; else if (x > x1) x = x1; } else { if (x > x0) x = x0; else if (x < x1) x = x1; } } /* * local utility to format a floting point value in arcsec * as minutes and seconds */ void formatHM(double val, char* buf) { int sign = 1; if (val < 0.0) { sign = -1; val = -val; } double dd = val + 0.0000000001; double md = dd / 60; int min = (int)md; double sec = (md - min) * 60; if (min != 0.0) { sprintf(buf, "%02d:%02.2f", min*sign, sec); } else { sprintf(buf, "%02.2f", sec*sign); } // cout << "formatHM: " << val << " == " << buf << endl; } /* * A simple class for debug logs */ RtdDebugLog::RtdDebugLog(char *nam, int debug) : debug_(debug) { strcpy(name_, nam); name_[9] = '\0'; } void RtdDebugLog::log(const char *format, ...) { if (! debug_) return; printf("%s: ", name_); va_list ap; va_start(ap, format); vprintf(format, ap); va_end(ap); } skycat-3.1.2-starlink-1b/rtd/generic/RtdUtils.h000066400000000000000000000015411215713201500212660ustar00rootroot00000000000000// -*-c++-*- #ifndef _RtdUtils_h_ #define _RtdUtils_h_ /* * E.S.O. - VLT project * "@(#) $Id: RtdUtils.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * RtdUtils.h - definitions for the rtdimg utilities * * who when what * -------------- -------- ---------------------------------------- * pbiereic 01/03/01 Created */ #include #include #include #include void clip(double& x, double x0, double x1); void formatHM(double val, char* buf); /* * Class RtdDebugLog */ class RtdDebugLog { public: RtdDebugLog(char *nam, int debug); void log(const char *format, ...); void setlog(int set) {debug_ = set;} int setlog() {return debug_;} protected: char name_[100]; // name of application int debug_; // debug flag }; #endif /* _RtdUtils_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/ShortImageData.C000066400000000000000000000062551215713201500223120ustar00rootroot00000000000000/* * E.S.O. - VLT project * * "@(#) $Id: ShortImageData.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * ShortImageData.C - member functions for class ShortImageData * * See the man page ImageData(3) for a complete description of this class * library. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * T. Herlin 08/12/95 Added color scale functions to avoid sign problem * Peter W. Draper 23/06/09 Added parseBlank to get blank value in this type. * 09/11/09 Use a scaled range for this data type. Previously * values mapped directly into the lookup table. * Now, like other types, they scale between lowCut_ * and highCut_ which can be outside of the range * -32768 to 32767. */ #include #include #include #include #include #include #include #include "ShortImageData.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" /* * convert the given value to short by adding the integer bias, * scaling, rounding if necessary and checking the range */ short ShortImageData::scaleToShort(int l) { // If have blank pixels then test for this using raw value. if ( haveBlank_ ) { if ( blank_ == (short) l ) { return LOOKUP_BLANK; } } // Scale value into range defined by bias_ and scale_. // Keep result in range of lookup table indices. short s; double d = (l + bias_) * scale_; if (d < 0.0 ) { if((d -= 0.5) < LOOKUP_MIN) s = LOOKUP_MIN; else s = (short)d; } else { if((d += 0.5) > LOOKUP_MAX) s = LOOKUP_MAX; else s = (short)d; } return s; } /* * Initialize conversion from data range to short and _scale_ (not clip) * the low and high cut levels to short range. * * Method: member variables are set here and used later to convert the short * raw image data to another short, which is then used as an index in the * lookup table to get the byte value: * * bias_ = offset * scale_ = scale factor * */ void ShortImageData::initShortConversion() { scale_ = LOOKUP_WIDTH / (highCut_ - lowCut_); bias_ = -((lowCut_ + highCut_) * 0.5); scaledLowCut_ = scaleToShort(int(lowCut_)); scaledHighCut_ = scaleToShort(int(highCut_)); if (haveBlank_) scaledBlankPixelValue_ = LOOKUP_BLANK; } /* * Set the blank value from a given string. Return 1 if successful. */ int ShortImageData::parseBlank(const char* value) { long l; int n = sscanf(value, "%ld", &l); if ( n > 0 ) { blank_ = (short) l; } return n; } /* * Include some standard methods as (cpp macro) templates: * These are methods that are the same for all derived classes of ImageData, * except that they work on a different raw data type */ #define CLASS_NAME ShortImageData #define DATA_TYPE short #ifndef NTOH # define NTOH(x) SWAP16(x) #endif #include "ImageTemplates.icc" #undef CLASS_NAME #undef DATA_TYPE #undef NTOH skycat-3.1.2-starlink-1b/rtd/generic/ShortImageData.h000066400000000000000000000055251215713201500223560ustar00rootroot00000000000000// -*-c++-*- /* * E.S.O. - VLT project * * "@(#) $Id: ShortImageData.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * ShortImageData.h - class definitions for class ShortImageData * * See the man page ImageData(3) for a complete description of this class * library. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * T. Herlin 08/12/95 Added color scale functions to avoid sign problem * Allan Brighton 14/12/95 reversed above and fixed the real problem * Peter W. Draper 04/03/98 Added llookup * 14/07/98 Added blank checks in lookup. * P.Biereichel 22/03/99 Added definitions for bias subtraction * Peter W. Draper 03/11/09 Support lowCut_ and highCut_ out of short range. * 09/11/09 Use a scaled value for lookup. */ #include #include "ImageData.h" // This class is used for images where the raw data is made up of shorts class ShortImageData : public ImageData { private: // value of blank pixel, if known (if haveBlankPixel_ is nonzero) short blank_; double bias_; // offset double scale_; // scale factor // local methods used to get short index in lookup table short scaleToShort(int l); // get value as unsigned short ushort convertToUshort(short s) { return ushort(scaleToShort(int(s))); } // return X image pixel value for raw image value byte lookup(short s) { return lookup_[convertToUshort(s)]; } unsigned long llookup(short s) { return lookup_[convertToUshort(s)]; } // return NTOH converted value evtl. subtracted with corresponding bias value short getVal(short* p, int idx); int getXsamples(short *rawImage, int idx, int wbox, short *samples); int getBsamples(short *rawImage, int idx, int wbox, short *samples); int getCsamples(short *rawImage, int idx, int wbox, short *samples); short getMedian(short *samples, int n); short getBoxVal(short *rawImage, int idx, int wbox, short *samples, int xs); short getRMS(short *samples, int n); protected: // initialize conversion from base type to short void initShortConversion(); public: // constructor ShortImageData(const char* name, const ImageIO& imio, int verbose) : ImageData(name, imio, verbose), blank_(0) {} // return class name as a string virtual const char* classname() { return "ShortImageData"; } // return the data type of the raw data int dataType() {return SHORT_IMAGE;} // return true if the data type is signed int isSigned() {return 1;} // return a copy of this object ImageData* copy() {return new ShortImageData(*this);} // include declarations for methods that differ only in raw data type # include "ImageTemplates.h" }; skycat-3.1.2-starlink-1b/rtd/generic/UShortImageData.C000066400000000000000000000066151215713201500224370ustar00rootroot00000000000000/* * E.S.O. - VLT project * * "@(#) $Id: UShortImageData.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * UShortImageData.C - member functions for class UShortImageData * * See the man page ImageData(3) for a complete description of this class * library. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * Peter W. Draper 23/06/09 Added parseBlank to get blank value in this type. * 20/10/09 Don't let lowCut_ and highCut_ wrap when * limits are out of ushort range. * 09/11/09 Use a scaled range for this data type. Previously * values mapped directly into the lookup table. * Now, like other types, they scale between lowCut_ * and highCut_ which can be outside of the range * 0 to 65535. */ #include #include #include #include #include #include #include "UShortImageData.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" /* * convert the given value to ushort by adding the integer bias, * scaling, rounding if necessary and checking the range */ ushort UShortImageData::convertToUshort(int l) { // If have blank pixels then test this against the raw value. if ( haveBlank_ ) { if ( blank_ == (ushort) l ) { return LOOKUP_BLANK; } } // Scale value into range defined by bias_ and scale_. Keep result in // range of lookup table indices. Note this is already unsigned, so // limits are 0, LOOKUP_SIZE-1, not the usual LOOKUP_MIN, LOOKUP_MAX. ushort s; double d = (l + bias_) * scale_; if (d < 0.0) { s = 0; } else { if((d += 0.5) > LOOKUP_WIDTH) { s = LOOKUP_WIDTH; } else { s = (ushort)d; } } return s; } /* * Initialize conversion from data range to ushort and _scale_ (not clip) * the low and high cut levels to ushort range. * * Method: member variables are set here and used later to convert the ushort * raw image data to another ushort, which is then used as an index in the * lookup table to get the byte value (for colour lookup). * * bias_ = offset * scale_ = scale factor * : */ void UShortImageData::initShortConversion() { if ( ( highCut_ - lowCut_ ) > 0.0 ) { bias_ = -lowCut_; scale_ = LOOKUP_WIDTH / (highCut_ - lowCut_); } else { scale_ = 1.0; bias_ = 0.0; } scaledLowCut_ = convertToUshort(int(lowCut_)); scaledHighCut_ = convertToUshort(int(highCut_)); if (haveBlank_) scaledBlankPixelValue_ = LOOKUP_BLANK; } /* * Set the blank value from a given string. Return 1 if successful. */ int UShortImageData::parseBlank(const char* value) { long l; int n = sscanf(value, "%ld", &l); if ( n > 0 ) { blank_ = (ushort) l; } return n; } /* * Include some standard methods as (cpp macro) templates: * These are methods that are the same for all derived classes of ImageData, * except that they work on a different raw data type */ #define CLASS_NAME UShortImageData #define DATA_TYPE ushort #ifndef NTOH # define NTOH(x) SWAP16(x) #endif #include "ImageTemplates.icc" #undef CLASS_NAME #undef DATA_TYPE #undef NTOH skycat-3.1.2-starlink-1b/rtd/generic/UShortImageData.h000066400000000000000000000050421215713201500224750ustar00rootroot00000000000000// -*-c++-*- /* * E.S.O. - VLT project * * "@(#) $Id: UShortImageData.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * UShortImageData.h - class definitions for class UShortImageData * * See the man page ImageData(3) for a complete description of this class * library. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * Peter W. Draper 04/03/98 Added llookup. * 14/07/98 Added check for blanks in lookup. * P.Biereichel 22/03/99 Added definitions for bias subtraction * Peter W. Draper 09/11/09 Use a scaled value for lookup. */ #include "ImageData.h" // This class is used for images where the raw data is made up of // unsigned shorts class UShortImageData : public ImageData { private: // value of blank pixel, if known (if haveBlankPixel_ is nonzero) ushort blank_; double bias_; // offset double scale_; // scale factor // local methods used to get short index in lookup table ushort convertToUshort(int l); // return X image pixel value for raw image value inline byte lookup(ushort s) { return lookup_[convertToUshort(s)]; } inline unsigned long llookup(ushort s) { return lookup_[convertToUshort(s)]; } // return NTOH converted value evtl. subtracted with corresponding bias value ushort getVal(ushort* p, int idx); int getXsamples(ushort *rawImage, int idx, int wbox, ushort *samples); int getBsamples(ushort *rawImage, int idx, int wbox, ushort *samples); int getCsamples(ushort *rawImage, int idx, int wbox, ushort *samples); ushort getMedian(ushort *samples, int n); ushort getBoxVal(ushort *rawImage, int idx, int wbox, ushort *samples, int xs); ushort getRMS(ushort *samples, int n); protected: // initialize conversion from base type to (unsigned) short, void initShortConversion(); public: // constructor UShortImageData(const char* name, const ImageIO& imio, int verbose) : ImageData(name, imio, verbose), blank_(0) {} // return class name as a string virtual const char* classname() { return "UShortImageData"; } // return the data type of the raw data int dataType() {return USHORT_IMAGE;} // return true if the data type is signed int isSigned() {return 0;} // return a copy of this object ImageData* copy() {return new UShortImageData(*this);} // include declarations for methods that differ only in raw data type # include "ImageTemplates.h" }; skycat-3.1.2-starlink-1b/rtd/generic/XImageData.C000066400000000000000000000026621215713201500214200ustar00rootroot00000000000000/* * E.S.O. - VLT project * * "@(#) $Id: XImageData.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * XImageData.C - member functions for class XImageData * * See the man page ImageData(3) for a complete description of this class * library. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * pbiereic 17/02/03 Added 'using namespace std'. * Peter W. Draper 23/06/09 Added parseBlank to get blank value in this type. */ static const char* const rcsId="@(#) $Id: XImageData.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; using namespace std; #include #include #include #include #include #include #include "XImageData.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" /* * Set the blank value from a given string. Return 1 if successful. */ int XImageData::parseBlank(const char* value) { long l; int n = sscanf(value, "%ld", &l); if ( n > 0 ) { blank_ = (byte) l; } return n; } /* * Include some standard methods as (cpp macro) templates: * These are methods that are the same for all derived classes of ImageData, * except that they work on a different raw data type */ #define CLASS_NAME XImageData #define DATA_TYPE byte #define NTOH(x) (x) #include "ImageTemplates.icc" #undef CLASS_NAME #undef DATA_TYPE #undef NTOH skycat-3.1.2-starlink-1b/rtd/generic/XImageData.h000066400000000000000000000052671215713201500214710ustar00rootroot00000000000000// -*-c++-*- #ifndef _XImageData_h_ #define _XImageData_h_ /* * E.S.O. - VLT project * * "@(#) $Id: XImageData.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * XImageData.h - class definitions for class XImageData * * See the man page ImageData(3) for a complete description of this class * library. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * Peter W. Draper 04/03/98 Added llookup. * 14/07/98 Added blank pixel check for lookup. * P.Biereichel 22/03/99 Added definitions for bias subtraction */ #include #include "ImageData.h" // This class is used for images where the raw data is made up of bytes class XImageData : public ImageData { private: // value of blank pixel, if known (if haveBlankPixel_ is nonzero) byte blank_; // get value as unsigned short inline ushort convertToUshort(byte b) { return (ushort)b; } // return X image pixel value for raw image value inline byte lookup(byte b) { if ( !haveBlank_ ) return b; if ( b != blank_ ) return b; return blank_; } inline unsigned long llookup(byte b) { if ( !haveBlank_ ) return b; if ( b != blank_ ) return b; return blank_; } // return NTOH converted value evtl. subtracted with corresponding bias value byte getVal(byte* p, int idx); int getXsamples(byte *rawImage, int idx, int wbox, byte *samples); int getBsamples(byte *rawImage, int idx, int wbox, byte *samples); int getCsamples(byte *rawImage, int idx, int wbox, byte *samples); byte getMedian(byte *samples, int n); byte getBoxVal(byte *rawImage, int idx, int wbox, byte *samples, int xs); byte getRMS(byte *samples, int n); protected: // no conversion necessary void initShortConversion() { scaledLowCut_ = 0; scaledHighCut_ = 255; scaledBlankPixelValue_ = LOOKUP_BLANK; } public: // constructor XImageData(const char* name, const ImageIO& imio, int verbose) : ImageData(name, imio, verbose), blank_(0) { flipY_ = 1; } // return class name as a string virtual const char* classname() { return "XImageData"; } // return the data type of the raw data int dataType() {return X_IMAGE;} // return true if the data type is signed int isSigned() {return 0;} // return a copy of this object ImageData* copy() {return new XImageData(*this);} // set the color scale algorithm for the image (redefined from base class) void colorScale(int ncolors, unsigned long* colors) {} // include declarations for methods that differ only in raw data type # include "ImageTemplates.h" }; #endif /* _XImageData_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/colormaps.C000066400000000000000000013601451215713201500214570ustar00rootroot00000000000000 /* * E.S.O. - VLT project * "@(#) $Id: colormaps.tcl,v 1.1.1.1 2006/01/12 16:37:25 abrighto Exp $" * * Colormap definitions for RTD * * This file was generated by ../colormaps/colormaps.tcl - DO NO EDIT */ #include #include void defineColormaps() { static RGBColor rainbow4_lasc[] = { {0.00000, 0.00000, 0.01176}, {0.00000, 0.00000, 0.02745}, {0.00000, 0.00000, 0.04314}, {0.00000, 0.00000, 0.05882}, {0.00000, 0.00000, 0.07451}, {0.00000, 0.00000, 0.09020}, {0.00000, 0.00000, 0.10588}, {0.00000, 0.00000, 0.12157}, {0.00000, 0.00000, 0.13725}, {0.00000, 0.00000, 0.15294}, {0.00000, 0.00000, 0.16863}, {0.00000, 0.00000, 0.18431}, {0.00000, 0.00000, 0.20000}, {0.00000, 0.00000, 0.21176}, {0.00000, 0.00000, 0.22745}, {0.00000, 0.00000, 0.24314}, {0.00000, 0.00000, 0.25882}, {0.00000, 0.00000, 0.27451}, {0.00000, 0.00000, 0.29020}, {0.00000, 0.00000, 0.30588}, {0.00000, 0.00000, 0.32157}, {0.00000, 0.00000, 0.33725}, {0.00000, 0.00000, 0.35294}, {0.00000, 0.00000, 0.36863}, {0.00000, 0.00000, 0.38431}, {0.00000, 0.00000, 0.40000}, {0.00000, 0.00000, 0.41176}, {0.00000, 0.00000, 0.42745}, {0.00000, 0.00000, 0.44314}, {0.00000, 0.00000, 0.45882}, {0.00000, 0.00000, 0.47451}, {0.00000, 0.00000, 0.49020}, {0.00000, 0.00000, 0.50588}, {0.00000, 0.00000, 0.52157}, {0.00000, 0.00000, 0.53725}, {0.00000, 0.00000, 0.55294}, {0.00000, 0.00000, 0.56863}, {0.00000, 0.00000, 0.58431}, {0.00000, 0.00000, 0.60000}, {0.00000, 0.00000, 0.61176}, {0.00000, 0.00000, 0.62745}, {0.00000, 0.00000, 0.64314}, {0.00000, 0.00000, 0.65882}, {0.00000, 0.00000, 0.67451}, {0.00000, 0.00000, 0.69020}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.72157}, {0.00000, 0.00000, 0.73725}, {0.00000, 0.00000, 0.75294}, {0.00000, 0.00000, 0.76863}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.80000}, {0.00000, 0.00000, 0.81176}, {0.00000, 0.00000, 0.82745}, {0.00000, 0.00000, 0.84314}, {0.00000, 0.00000, 0.85882}, {0.00000, 0.00000, 0.87451}, {0.00000, 0.00000, 0.89020}, {0.00000, 0.00000, 0.90588}, {0.00000, 0.00000, 0.92157}, {0.00000, 0.00000, 0.93725}, {0.00000, 0.00000, 0.95294}, {0.00000, 0.00000, 0.96863}, {0.00000, 0.00000, 0.98431}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.03529, 1.00000}, {0.00000, 0.07059, 1.00000}, {0.00000, 0.10980, 1.00000}, {0.00000, 0.14510, 1.00000}, {0.00000, 0.18039, 1.00000}, {0.00000, 0.21961, 1.00000}, {0.00000, 0.25490, 1.00000}, {0.00000, 0.29412, 1.00000}, {0.00000, 0.32941, 1.00000}, {0.00000, 0.36471, 1.00000}, {0.00000, 0.40392, 1.00000}, {0.00000, 0.43922, 1.00000}, {0.00000, 0.47843, 1.00000}, {0.00000, 0.50196, 1.00000}, {0.00000, 0.52549, 1.00000}, {0.00000, 0.54902, 1.00000}, {0.00000, 0.57255, 1.00000}, {0.00000, 0.59608, 1.00000}, {0.00000, 0.61961, 1.00000}, {0.00000, 0.64314, 1.00000}, {0.00000, 0.66667, 1.00000}, {0.00000, 0.69020, 1.00000}, {0.00000, 0.71373, 1.00000}, {0.00000, 0.73725, 1.00000}, {0.00000, 0.76078, 1.00000}, {0.00000, 0.78431, 1.00000}, {0.00000, 0.80000, 1.00000}, {0.00000, 0.81569, 1.00000}, {0.00000, 0.83137, 1.00000}, {0.00000, 0.84706, 1.00000}, {0.00000, 0.86667, 1.00000}, {0.00000, 0.88235, 1.00000}, {0.00000, 0.89804, 1.00000}, {0.00000, 0.91373, 1.00000}, {0.00000, 0.93333, 1.00000}, {0.00000, 0.94902, 1.00000}, {0.00000, 0.96471, 1.00000}, {0.00000, 0.98039, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 0.97647}, {0.00000, 1.00000, 0.95294}, {0.00000, 1.00000, 0.92941}, {0.00000, 1.00000, 0.90588}, {0.00000, 1.00000, 0.88627}, {0.00000, 1.00000, 0.86275}, {0.00000, 1.00000, 0.83922}, {0.00000, 1.00000, 0.81569}, {0.00000, 1.00000, 0.79608}, {0.00000, 1.00000, 0.77255}, {0.00000, 1.00000, 0.74902}, {0.00000, 1.00000, 0.72549}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.65098}, {0.00000, 1.00000, 0.59608}, {0.00000, 1.00000, 0.54118}, {0.00000, 1.00000, 0.48627}, {0.00000, 1.00000, 0.43137}, {0.00000, 1.00000, 0.37647}, {0.00000, 1.00000, 0.32549}, {0.00000, 1.00000, 0.27059}, {0.00000, 1.00000, 0.21569}, {0.00000, 1.00000, 0.16078}, {0.00000, 1.00000, 0.10588}, {0.00000, 1.00000, 0.05098}, {0.00000, 1.00000, 0.00000}, {0.05098, 1.00000, 0.00000}, {0.10588, 1.00000, 0.00000}, {0.16078, 1.00000, 0.00000}, {0.21569, 1.00000, 0.00000}, {0.27059, 1.00000, 0.00000}, {0.32549, 1.00000, 0.00000}, {0.37647, 1.00000, 0.00000}, {0.43137, 1.00000, 0.00000}, {0.48627, 1.00000, 0.00000}, {0.54118, 1.00000, 0.00000}, {0.59608, 1.00000, 0.00000}, {0.65098, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.72549, 1.00000, 0.00000}, {0.74902, 1.00000, 0.00000}, {0.77255, 1.00000, 0.00000}, {0.79608, 1.00000, 0.00000}, {0.81569, 1.00000, 0.00000}, {0.83922, 1.00000, 0.00000}, {0.86275, 1.00000, 0.00000}, {0.88627, 1.00000, 0.00000}, {0.90588, 1.00000, 0.00000}, {0.92941, 1.00000, 0.00000}, {0.95294, 1.00000, 0.00000}, {0.97647, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {0.99608, 0.97647, 0.00000}, {0.99608, 0.95686, 0.00000}, {0.99608, 0.93333, 0.00000}, {0.99608, 0.91373, 0.00000}, {0.99216, 0.89412, 0.00000}, {0.99216, 0.87059, 0.00000}, {0.99216, 0.85098, 0.00000}, {0.99216, 0.82745, 0.00000}, {0.98824, 0.80784, 0.00000}, {0.98824, 0.78824, 0.00000}, {0.98824, 0.76471, 0.00000}, {0.98824, 0.74510, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.70588, 0.00000}, {0.98824, 0.68627, 0.00000}, {0.98824, 0.66667, 0.00000}, {0.98824, 0.64706, 0.00000}, {0.99216, 0.62745, 0.00000}, {0.99216, 0.60784, 0.00000}, {0.99216, 0.58824, 0.00000}, {0.99216, 0.56863, 0.00000}, {0.99608, 0.54902, 0.00000}, {0.99608, 0.52941, 0.00000}, {0.99608, 0.50980, 0.00000}, {0.99608, 0.49020, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.43137, 0.00000}, {1.00000, 0.39608, 0.00000}, {1.00000, 0.36078, 0.00000}, {1.00000, 0.32549, 0.00000}, {1.00000, 0.28627, 0.00000}, {1.00000, 0.25098, 0.00000}, {1.00000, 0.21569, 0.00000}, {1.00000, 0.18039, 0.00000}, {1.00000, 0.14118, 0.00000}, {1.00000, 0.10588, 0.00000}, {1.00000, 0.07059, 0.00000}, {1.00000, 0.03529, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.05098}, {1.00000, 0.00000, 0.10588}, {1.00000, 0.00000, 0.16078}, {1.00000, 0.00000, 0.21569}, {1.00000, 0.00000, 0.27059}, {1.00000, 0.00000, 0.32549}, {1.00000, 0.00000, 0.37647}, {1.00000, 0.00000, 0.43137}, {1.00000, 0.00000, 0.48627}, {1.00000, 0.00000, 0.54118}, {1.00000, 0.00000, 0.59608}, {1.00000, 0.00000, 0.65098}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.72549}, {1.00000, 0.00000, 0.74902}, {1.00000, 0.00000, 0.77255}, {1.00000, 0.00000, 0.79608}, {1.00000, 0.00000, 0.81569}, {1.00000, 0.00000, 0.83922}, {1.00000, 0.00000, 0.86275}, {1.00000, 0.00000, 0.88627}, {1.00000, 0.00000, 0.90588}, {1.00000, 0.00000, 0.92941}, {1.00000, 0.00000, 0.95294}, {1.00000, 0.00000, 0.97647}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.03529, 1.00000}, {1.00000, 0.07059, 1.00000}, {1.00000, 0.10588, 1.00000}, {1.00000, 0.14118, 1.00000}, {1.00000, 0.18039, 1.00000}, {1.00000, 0.21569, 1.00000}, {1.00000, 0.25098, 1.00000}, {1.00000, 0.28627, 1.00000}, {1.00000, 0.32549, 1.00000}, {1.00000, 0.36078, 1.00000}, {1.00000, 0.39608, 1.00000}, {1.00000, 0.43137, 1.00000}, {1.00000, 0.47059, 1.00000}, {1.00000, 0.48627, 1.00000}, {1.00000, 0.50588, 1.00000}, {1.00000, 0.52157, 1.00000}, {1.00000, 0.54118, 1.00000}, {1.00000, 0.56078, 1.00000}, {1.00000, 0.57647, 1.00000}, {1.00000, 0.59608, 1.00000}, {1.00000, 0.61176, 1.00000}, {1.00000, 0.63137, 1.00000}, {1.00000, 0.65098, 1.00000}, {1.00000, 0.66667, 1.00000}, {1.00000, 0.68627, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.74510, 1.00000}, {1.00000, 0.78824, 1.00000}, {1.00000, 0.83137, 1.00000}, {1.00000, 0.87059, 1.00000}, {1.00000, 0.91373, 1.00000}, {1.00000, 0.95686, 1.00000}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("rainbow4.lasc", rainbow4_lasc); static RGBColor ramp_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00392, 0.00392, 0.00392}, {0.00784, 0.00784, 0.00784}, {0.01176, 0.01176, 0.01176}, {0.01569, 0.01569, 0.01569}, {0.01961, 0.01961, 0.01961}, {0.02353, 0.02353, 0.02353}, {0.02745, 0.02745, 0.02745}, {0.03137, 0.03137, 0.03137}, {0.03529, 0.03529, 0.03529}, {0.03922, 0.03922, 0.03922}, {0.04314, 0.04314, 0.04314}, {0.04706, 0.04706, 0.04706}, {0.05098, 0.05098, 0.05098}, {0.05490, 0.05490, 0.05490}, {0.05882, 0.05882, 0.05882}, {0.06275, 0.06275, 0.06275}, {0.06667, 0.06667, 0.06667}, {0.07059, 0.07059, 0.07059}, {0.07451, 0.07451, 0.07451}, {0.07843, 0.07843, 0.07843}, {0.08235, 0.08235, 0.08235}, {0.08627, 0.08627, 0.08627}, {0.09020, 0.09020, 0.09020}, {0.09412, 0.09412, 0.09412}, {0.09804, 0.09804, 0.09804}, {0.10196, 0.10196, 0.10196}, {0.10588, 0.10588, 0.10588}, {0.10980, 0.10980, 0.10980}, {0.11373, 0.11373, 0.11373}, {0.11765, 0.11765, 0.11765}, {0.12157, 0.12157, 0.12157}, {0.12549, 0.12549, 0.12549}, {0.12941, 0.12941, 0.12941}, {0.13333, 0.13333, 0.13333}, {0.13725, 0.13725, 0.13725}, {0.14118, 0.14118, 0.14118}, {0.14510, 0.14510, 0.14510}, {0.14902, 0.14902, 0.14902}, {0.15294, 0.15294, 0.15294}, {0.15686, 0.15686, 0.15686}, {0.16078, 0.16078, 0.16078}, {0.16471, 0.16471, 0.16471}, {0.16863, 0.16863, 0.16863}, {0.17255, 0.17255, 0.17255}, {0.17647, 0.17647, 0.17647}, {0.18039, 0.18039, 0.18039}, {0.18431, 0.18431, 0.18431}, {0.18824, 0.18824, 0.18824}, {0.19216, 0.19216, 0.19216}, {0.19608, 0.19608, 0.19608}, {0.20000, 0.20000, 0.20000}, {0.20392, 0.20392, 0.20392}, {0.20784, 0.20784, 0.20784}, {0.21177, 0.21177, 0.21177}, {0.21569, 0.21569, 0.21569}, {0.21961, 0.21961, 0.21961}, {0.22353, 0.22353, 0.22353}, {0.22745, 0.22745, 0.22745}, {0.23137, 0.23137, 0.23137}, {0.23529, 0.23529, 0.23529}, {0.23922, 0.23922, 0.23922}, {0.24314, 0.24314, 0.24314}, {0.24706, 0.24706, 0.24706}, {0.25098, 0.25098, 0.25098}, {0.25490, 0.25490, 0.25490}, {0.25882, 0.25882, 0.25882}, {0.26275, 0.26275, 0.26275}, {0.26667, 0.26667, 0.26667}, {0.27059, 0.27059, 0.27059}, {0.27451, 0.27451, 0.27451}, {0.27843, 0.27843, 0.27843}, {0.28235, 0.28235, 0.28235}, {0.28628, 0.28628, 0.28628}, {0.29020, 0.29020, 0.29020}, {0.29412, 0.29412, 0.29412}, {0.29804, 0.29804, 0.29804}, {0.30196, 0.30196, 0.30196}, {0.30588, 0.30588, 0.30588}, {0.30980, 0.30980, 0.30980}, {0.31372, 0.31372, 0.31372}, {0.31765, 0.31765, 0.31765}, {0.32157, 0.32157, 0.32157}, {0.32549, 0.32549, 0.32549}, {0.32941, 0.32941, 0.32941}, {0.33333, 0.33333, 0.33333}, {0.33726, 0.33726, 0.33726}, {0.34118, 0.34118, 0.34118}, {0.34510, 0.34510, 0.34510}, {0.34902, 0.34902, 0.34902}, {0.35294, 0.35294, 0.35294}, {0.35686, 0.35686, 0.35686}, {0.36078, 0.36078, 0.36078}, {0.36471, 0.36471, 0.36471}, {0.36863, 0.36863, 0.36863}, {0.37255, 0.37255, 0.37255}, {0.37647, 0.37647, 0.37647}, {0.38039, 0.38039, 0.38039}, {0.38431, 0.38431, 0.38431}, {0.38823, 0.38823, 0.38823}, {0.39216, 0.39216, 0.39216}, {0.39608, 0.39608, 0.39608}, {0.40000, 0.40000, 0.40000}, {0.40392, 0.40392, 0.40392}, {0.40784, 0.40784, 0.40784}, {0.41176, 0.41176, 0.41176}, {0.41569, 0.41569, 0.41569}, {0.41961, 0.41961, 0.41961}, {0.42353, 0.42353, 0.42353}, {0.42745, 0.42745, 0.42745}, {0.43137, 0.43137, 0.43137}, {0.43529, 0.43529, 0.43529}, {0.43922, 0.43922, 0.43922}, {0.44314, 0.44314, 0.44314}, {0.44706, 0.44706, 0.44706}, {0.45098, 0.45098, 0.45098}, {0.45490, 0.45490, 0.45490}, {0.45882, 0.45882, 0.45882}, {0.46275, 0.46275, 0.46275}, {0.46667, 0.46667, 0.46667}, {0.47059, 0.47059, 0.47059}, {0.47451, 0.47451, 0.47451}, {0.47843, 0.47843, 0.47843}, {0.48235, 0.48235, 0.48235}, {0.48628, 0.48628, 0.48628}, {0.49020, 0.49020, 0.49020}, {0.49412, 0.49412, 0.49412}, {0.49804, 0.49804, 0.49804}, {0.50196, 0.50196, 0.50196}, {0.50588, 0.50588, 0.50588}, {0.50980, 0.50980, 0.50980}, {0.51372, 0.51372, 0.51372}, {0.51765, 0.51765, 0.51765}, {0.52157, 0.52157, 0.52157}, {0.52549, 0.52549, 0.52549}, {0.52941, 0.52941, 0.52941}, {0.53333, 0.53333, 0.53333}, {0.53726, 0.53726, 0.53726}, {0.54118, 0.54118, 0.54118}, {0.54510, 0.54510, 0.54510}, {0.54902, 0.54902, 0.54902}, {0.55294, 0.55294, 0.55294}, {0.55686, 0.55686, 0.55686}, {0.56078, 0.56078, 0.56078}, {0.56471, 0.56471, 0.56471}, {0.56863, 0.56863, 0.56863}, {0.57255, 0.57255, 0.57255}, {0.57647, 0.57647, 0.57647}, {0.58039, 0.58039, 0.58039}, {0.58431, 0.58431, 0.58431}, {0.58823, 0.58823, 0.58823}, {0.59216, 0.59216, 0.59216}, {0.59608, 0.59608, 0.59608}, {0.60000, 0.60000, 0.60000}, {0.60392, 0.60392, 0.60392}, {0.60784, 0.60784, 0.60784}, {0.61177, 0.61177, 0.61177}, {0.61569, 0.61569, 0.61569}, {0.61961, 0.61961, 0.61961}, {0.62353, 0.62353, 0.62353}, {0.62745, 0.62745, 0.62745}, {0.63137, 0.63137, 0.63137}, {0.63529, 0.63529, 0.63529}, {0.63922, 0.63922, 0.63922}, {0.64314, 0.64314, 0.64314}, {0.64706, 0.64706, 0.64706}, {0.65098, 0.65098, 0.65098}, {0.65490, 0.65490, 0.65490}, {0.65882, 0.65882, 0.65882}, {0.66275, 0.66275, 0.66275}, {0.66667, 0.66667, 0.66667}, {0.67059, 0.67059, 0.67059}, {0.67451, 0.67451, 0.67451}, {0.67843, 0.67843, 0.67843}, {0.68235, 0.68235, 0.68235}, {0.68627, 0.68627, 0.68627}, {0.69020, 0.69020, 0.69020}, {0.69412, 0.69412, 0.69412}, {0.69804, 0.69804, 0.69804}, {0.70196, 0.70196, 0.70196}, {0.70588, 0.70588, 0.70588}, {0.70980, 0.70980, 0.70980}, {0.71373, 0.71373, 0.71373}, {0.71765, 0.71765, 0.71765}, {0.72157, 0.72157, 0.72157}, {0.72549, 0.72549, 0.72549}, {0.72941, 0.72941, 0.72941}, {0.73333, 0.73333, 0.73333}, {0.73725, 0.73725, 0.73725}, {0.74118, 0.74118, 0.74118}, {0.74510, 0.74510, 0.74510}, {0.74902, 0.74902, 0.74902}, {0.75294, 0.75294, 0.75294}, {0.75686, 0.75686, 0.75686}, {0.76078, 0.76078, 0.76078}, {0.76471, 0.76471, 0.76471}, {0.76863, 0.76863, 0.76863}, {0.77255, 0.77255, 0.77255}, {0.77647, 0.77647, 0.77647}, {0.78039, 0.78039, 0.78039}, {0.78431, 0.78431, 0.78431}, {0.78824, 0.78824, 0.78824}, {0.79216, 0.79216, 0.79216}, {0.79608, 0.79608, 0.79608}, {0.80000, 0.80000, 0.80000}, {0.80392, 0.80392, 0.80392}, {0.80784, 0.80784, 0.80784}, {0.81176, 0.81176, 0.81176}, {0.81569, 0.81569, 0.81569}, {0.81961, 0.81961, 0.81961}, {0.82353, 0.82353, 0.82353}, {0.82745, 0.82745, 0.82745}, {0.83137, 0.83137, 0.83137}, {0.83529, 0.83529, 0.83529}, {0.83922, 0.83922, 0.83922}, {0.84314, 0.84314, 0.84314}, {0.84706, 0.84706, 0.84706}, {0.85098, 0.85098, 0.85098}, {0.85490, 0.85490, 0.85490}, {0.85882, 0.85882, 0.85882}, {0.86274, 0.86274, 0.86274}, {0.86667, 0.86667, 0.86667}, {0.87059, 0.87059, 0.87059}, {0.87451, 0.87451, 0.87451}, {0.87843, 0.87843, 0.87843}, {0.88235, 0.88235, 0.88235}, {0.88628, 0.88628, 0.88628}, {0.89020, 0.89020, 0.89020}, {0.89412, 0.89412, 0.89412}, {0.89804, 0.89804, 0.89804}, {0.90196, 0.90196, 0.90196}, {0.90588, 0.90588, 0.90588}, {0.90980, 0.90980, 0.90980}, {0.91373, 0.91373, 0.91373}, {0.91765, 0.91765, 0.91765}, {0.92157, 0.92157, 0.92157}, {0.92549, 0.92549, 0.92549}, {0.92941, 0.92941, 0.92941}, {0.93333, 0.93333, 0.93333}, {0.93725, 0.93725, 0.93725}, {0.94118, 0.94118, 0.94118}, {0.94510, 0.94510, 0.94510}, {0.94902, 0.94902, 0.94902}, {0.95294, 0.95294, 0.95294}, {0.95686, 0.95686, 0.95686}, {0.96078, 0.96078, 0.96078}, {0.96471, 0.96471, 0.96471}, {0.96863, 0.96863, 0.96863}, {0.97255, 0.97255, 0.97255}, {0.97647, 0.97647, 0.97647}, {0.98039, 0.98039, 0.98039}, {0.98431, 0.98431, 0.98431}, {0.98823, 0.98823, 0.98823}, {0.99216, 0.99216, 0.99216}, {0.99608, 0.99608, 0.99608}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("ramp.lasc", ramp_lasc); static RGBColor random3_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.47059}, {0.00000, 0.00000, 0.47059}, {0.00000, 0.00000, 0.47059}, {0.00000, 0.00000, 0.47059}, {0.00000, 0.00000, 0.47059}, {0.00000, 0.00000, 0.47059}, {0.00000, 0.00000, 0.47059}, {0.00000, 0.00000, 0.47059}, {0.00000, 0.00000, 0.47059}, {0.00000, 0.00000, 0.47059}, {0.00000, 0.00000, 0.47059}, {0.00000, 0.00000, 0.47059}, {0.00000, 0.00000, 0.47059}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.47059, 1.00000}, {0.00000, 0.47059, 1.00000}, {0.00000, 0.47059, 1.00000}, {0.00000, 0.47059, 1.00000}, {0.00000, 0.47059, 1.00000}, {0.00000, 0.47059, 1.00000}, {0.00000, 0.47059, 1.00000}, {0.00000, 0.47059, 1.00000}, {0.00000, 0.47059, 1.00000}, {0.00000, 0.47059, 1.00000}, {0.00000, 0.47059, 1.00000}, {0.00000, 0.47059, 1.00000}, {0.00000, 0.47059, 1.00000}, {0.00000, 0.78431, 1.00000}, {0.00000, 0.78431, 1.00000}, {0.00000, 0.78431, 1.00000}, {0.00000, 0.78431, 1.00000}, {0.00000, 0.78431, 1.00000}, {0.00000, 0.78431, 1.00000}, {0.00000, 0.78431, 1.00000}, {0.00000, 0.78431, 1.00000}, {0.00000, 0.78431, 1.00000}, {0.00000, 0.78431, 1.00000}, {0.00000, 0.78431, 1.00000}, {0.00000, 0.78431, 1.00000}, {0.00000, 0.78431, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.47059, 1.00000}, {1.00000, 0.47059, 1.00000}, {1.00000, 0.47059, 1.00000}, {1.00000, 0.47059, 1.00000}, {1.00000, 0.47059, 1.00000}, {1.00000, 0.47059, 1.00000}, {1.00000, 0.47059, 1.00000}, {1.00000, 0.47059, 1.00000}, {1.00000, 0.47059, 1.00000}, {1.00000, 0.47059, 1.00000}, {1.00000, 0.47059, 1.00000}, {1.00000, 0.47059, 1.00000}, {1.00000, 0.47059, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("random3.lasc", random3_lasc); static RGBColor isophot_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.03922}, {0.00000, 0.00000, 0.07843}, {0.00000, 0.00000, 0.11765}, {0.00000, 0.00000, 0.15686}, {0.00000, 0.00000, 0.19608}, {0.00000, 0.00000, 0.23529}, {0.00000, 0.00000, 0.27843}, {0.00000, 0.00000, 0.31765}, {0.00000, 0.00000, 0.35686}, {0.00000, 0.00000, 0.39608}, {0.00000, 0.00000, 0.43529}, {0.00000, 0.00000, 0.47451}, {0.00000, 0.00000, 0.51765}, {0.00000, 0.00000, 0.55686}, {0.00000, 0.00000, 0.59608}, {0.00000, 0.00000, 0.63529}, {0.00000, 0.00000, 0.67451}, {0.00000, 0.00000, 0.71765}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {0.00000, 0.00000, 0.87843}, {0.00000, 0.00000, 0.91765}, {0.00000, 0.00000, 0.95686}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.03137, 1.00000}, {0.00000, 0.06275, 1.00000}, {0.00000, 0.09412, 1.00000}, {0.00000, 0.12549, 1.00000}, {0.00000, 0.15686, 1.00000}, {0.00000, 0.18824, 1.00000}, {0.00000, 0.21961, 1.00000}, {0.00000, 0.25490, 1.00000}, {0.00000, 0.28627, 1.00000}, {0.00000, 0.31765, 1.00000}, {0.00000, 0.34902, 1.00000}, {0.00000, 0.38039, 1.00000}, {0.00000, 0.41176, 1.00000}, {0.00000, 0.44314, 1.00000}, {0.00000, 0.47843, 1.00000}, {0.00000, 0.49804, 1.00000}, {0.00000, 0.51765, 1.00000}, {0.00000, 0.53725, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {0.00000, 0.61961, 1.00000}, {0.00000, 0.63922, 1.00000}, {0.00000, 0.65882, 1.00000}, {0.00000, 0.67843, 1.00000}, {0.00000, 0.70196, 1.00000}, {0.00000, 0.72157, 1.00000}, {0.00000, 0.74118, 1.00000}, {0.00000, 0.76078, 1.00000}, {0.00000, 0.78431, 1.00000}, {0.00000, 0.79608, 1.00000}, {0.00000, 0.81176, 1.00000}, {0.00000, 0.82353, 1.00000}, {0.00000, 0.83922, 1.00000}, {0.00000, 0.85490, 1.00000}, {0.00000, 0.86667, 1.00000}, {0.00000, 0.88235, 1.00000}, {0.00000, 0.89412, 1.00000}, {0.00000, 0.90980, 1.00000}, {0.00000, 0.92549, 1.00000}, {0.00000, 0.93725, 1.00000}, {0.00000, 0.95294, 1.00000}, {0.00000, 0.96863, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 0.96078}, {0.00000, 1.00000, 0.94118}, {0.00000, 1.00000, 0.92157}, {0.00000, 1.00000, 0.90196}, {0.00000, 1.00000, 0.88235}, {0.00000, 1.00000, 0.86275}, {0.00000, 1.00000, 0.84314}, {0.00000, 1.00000, 0.82353}, {0.00000, 1.00000, 0.80392}, {0.00000, 1.00000, 0.78431}, {0.00000, 1.00000, 0.76471}, {0.00000, 1.00000, 0.74510}, {0.00000, 1.00000, 0.72549}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.65490}, {0.00000, 1.00000, 0.60784}, {0.00000, 1.00000, 0.56078}, {0.00000, 1.00000, 0.51373}, {0.00000, 1.00000, 0.46667}, {0.00000, 1.00000, 0.41961}, {0.00000, 1.00000, 0.37255}, {0.00000, 1.00000, 0.32549}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 0.13725}, {0.00000, 1.00000, 0.09020}, {0.00000, 1.00000, 0.04314}, {0.00000, 1.00000, 0.00000}, {0.04706, 1.00000, 0.00000}, {0.09412, 1.00000, 0.00000}, {0.14118, 1.00000, 0.00000}, {0.18824, 1.00000, 0.00000}, {0.23529, 1.00000, 0.00000}, {0.28235, 1.00000, 0.00000}, {0.32941, 1.00000, 0.00000}, {0.37647, 1.00000, 0.00000}, {0.42353, 1.00000, 0.00000}, {0.47059, 1.00000, 0.00000}, {0.51765, 1.00000, 0.00000}, {0.56471, 1.00000, 0.00000}, {0.61176, 1.00000, 0.00000}, {0.65882, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.72549, 1.00000, 0.00000}, {0.74510, 1.00000, 0.00000}, {0.76471, 1.00000, 0.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {0.84314, 1.00000, 0.00000}, {0.86275, 1.00000, 0.00000}, {0.88235, 1.00000, 0.00000}, {0.90196, 1.00000, 0.00000}, {0.92157, 1.00000, 0.00000}, {0.94118, 1.00000, 0.00000}, {0.96078, 1.00000, 0.00000}, {0.98039, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {0.99608, 0.98039, 0.00000}, {0.99608, 0.96078, 0.00000}, {0.99608, 0.94118, 0.00000}, {0.99608, 0.92549, 0.00000}, {0.99216, 0.90588, 0.00000}, {0.99216, 0.88627, 0.00000}, {0.99216, 0.87059, 0.00000}, {0.99216, 0.85098, 0.00000}, {0.98824, 0.83137, 0.00000}, {0.98824, 0.81569, 0.00000}, {0.98824, 0.79608, 0.00000}, {0.98824, 0.77647, 0.00000}, {0.98824, 0.76078, 0.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {0.98824, 0.69020, 0.00000}, {0.98824, 0.67059, 0.00000}, {0.98824, 0.65490, 0.00000}, {0.98824, 0.63922, 0.00000}, {0.98824, 0.61961, 0.00000}, {0.99216, 0.60392, 0.00000}, {0.99216, 0.58824, 0.00000}, {0.99216, 0.56863, 0.00000}, {0.99216, 0.55294, 0.00000}, {0.99608, 0.53725, 0.00000}, {0.99608, 0.51765, 0.00000}, {0.99608, 0.50196, 0.00000}, {0.99608, 0.48627, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.43529, 0.00000}, {1.00000, 0.40392, 0.00000}, {1.00000, 0.37255, 0.00000}, {1.00000, 0.34118, 0.00000}, {1.00000, 0.30980, 0.00000}, {1.00000, 0.27843, 0.00000}, {1.00000, 0.24706, 0.00000}, {1.00000, 0.21569, 0.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 0.09020, 0.00000}, {1.00000, 0.05882, 0.00000}, {1.00000, 0.02745, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.04706}, {1.00000, 0.00000, 0.09412}, {1.00000, 0.00000, 0.14118}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 0.00000, 0.32941}, {1.00000, 0.00000, 0.37647}, {1.00000, 0.00000, 0.42353}, {1.00000, 0.00000, 0.47059}, {1.00000, 0.00000, 0.51765}, {1.00000, 0.00000, 0.56471}, {1.00000, 0.00000, 0.61176}, {1.00000, 0.00000, 0.65882}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.72549}, {1.00000, 0.00000, 0.74902}, {1.00000, 0.00000, 0.77255}, {1.00000, 0.00000, 0.79608}, {1.00000, 0.00000, 0.81569}, {1.00000, 0.00000, 0.83922}, {1.00000, 0.00000, 0.86275}, {1.00000, 0.00000, 0.88627}, {1.00000, 0.00000, 0.90588}, {1.00000, 0.00000, 0.92941}, {1.00000, 0.00000, 0.95294}, {1.00000, 0.00000, 0.97647}, {1.00000, 0.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 0.14118, 1.00000}, {1.00000, 0.17647, 1.00000}, {1.00000, 0.21176, 1.00000}, {1.00000, 0.25098, 1.00000}, {1.00000, 0.28627, 1.00000}, {1.00000, 0.32157, 1.00000}, {1.00000, 0.36078, 1.00000}, {1.00000, 0.39608, 1.00000}, {1.00000, 0.43137, 1.00000}, {1.00000, 0.47059, 1.00000}, {1.00000, 0.48627, 1.00000}, {1.00000, 0.50588, 1.00000}, {1.00000, 0.52157, 1.00000}, {1.00000, 0.54118, 1.00000}, {1.00000, 0.56078, 1.00000}, {1.00000, 0.57647, 1.00000}, {1.00000, 0.59608, 1.00000}, {1.00000, 0.61176, 1.00000}, {1.00000, 0.63137, 1.00000}, {1.00000, 0.65098, 1.00000}, {1.00000, 0.66667, 1.00000}, {1.00000, 0.68627, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.74510, 1.00000}, {1.00000, 0.78824, 1.00000}, {1.00000, 0.83137, 1.00000}, {1.00000, 0.87059, 1.00000}, {1.00000, 0.91373, 1.00000}, {1.00000, 0.95686, 1.00000}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("isophot.lasc", isophot_lasc); static RGBColor staircase_lasc[] = { {0.00392, 0.00392, 0.31373}, {0.00784, 0.00784, 0.31373}, {0.01176, 0.01176, 0.31373}, {0.01569, 0.01569, 0.31373}, {0.01961, 0.01961, 0.31373}, {0.02353, 0.02353, 0.31373}, {0.02745, 0.02745, 0.31373}, {0.03137, 0.03137, 0.31373}, {0.03529, 0.03529, 0.31373}, {0.03922, 0.03922, 0.31373}, {0.04314, 0.04314, 0.31373}, {0.04706, 0.04706, 0.31373}, {0.05098, 0.05098, 0.31373}, {0.05490, 0.05490, 0.31373}, {0.05882, 0.05882, 0.31373}, {0.06275, 0.06275, 0.31373}, {0.06667, 0.06667, 0.47059}, {0.07059, 0.07059, 0.47059}, {0.07451, 0.07451, 0.47059}, {0.07843, 0.07843, 0.47059}, {0.08235, 0.08235, 0.47059}, {0.08627, 0.08627, 0.47059}, {0.09020, 0.09020, 0.47059}, {0.09412, 0.09412, 0.47059}, {0.09804, 0.09804, 0.47059}, {0.10196, 0.10196, 0.47059}, {0.10588, 0.10588, 0.47059}, {0.10980, 0.10980, 0.47059}, {0.11373, 0.11373, 0.47059}, {0.11765, 0.11765, 0.47059}, {0.12157, 0.12157, 0.47059}, {0.12549, 0.12549, 0.47059}, {0.12941, 0.12941, 0.62745}, {0.13333, 0.13333, 0.62745}, {0.13725, 0.13725, 0.62745}, {0.14118, 0.14118, 0.62745}, {0.14510, 0.14510, 0.62745}, {0.14902, 0.14902, 0.62745}, {0.15294, 0.15294, 0.62745}, {0.15686, 0.15686, 0.62745}, {0.16078, 0.16078, 0.62745}, {0.16471, 0.16471, 0.62745}, {0.16863, 0.16863, 0.62745}, {0.17255, 0.17255, 0.62745}, {0.17647, 0.17647, 0.62745}, {0.18039, 0.18039, 0.62745}, {0.18431, 0.18431, 0.62745}, {0.18824, 0.18824, 0.62745}, {0.19216, 0.19216, 0.78431}, {0.19608, 0.19608, 0.78431}, {0.20000, 0.20000, 0.78431}, {0.20392, 0.20392, 0.78431}, {0.20784, 0.20784, 0.78431}, {0.21176, 0.21176, 0.78431}, {0.21569, 0.21569, 0.78431}, {0.21961, 0.21961, 0.78431}, {0.22353, 0.22353, 0.78431}, {0.22745, 0.22745, 0.78431}, {0.23137, 0.23137, 0.78431}, {0.23529, 0.23529, 0.78431}, {0.23922, 0.23922, 0.78431}, {0.24314, 0.24314, 0.78431}, {0.24706, 0.24706, 0.78431}, {0.25098, 0.25098, 0.78431}, {0.25490, 0.25490, 0.94118}, {0.25882, 0.25882, 0.94118}, {0.26275, 0.26275, 0.94118}, {0.26667, 0.26667, 0.94118}, {0.27059, 0.27059, 0.94118}, {0.27451, 0.27451, 0.94118}, {0.27843, 0.27843, 0.94118}, {0.28235, 0.28235, 0.94118}, {0.28627, 0.28627, 0.94118}, {0.29020, 0.29020, 0.94118}, {0.29412, 0.29412, 0.94118}, {0.29804, 0.29804, 0.94118}, {0.30196, 0.30196, 0.94118}, {0.30588, 0.30588, 0.94118}, {0.30980, 0.30980, 0.94118}, {0.31373, 0.31373, 0.94118}, {0.31765, 0.31765, 0.95294}, {0.32157, 0.32157, 0.96471}, {0.32549, 0.32549, 0.97647}, {0.32941, 0.32941, 0.98824}, {0.33333, 0.33333, 1.00000}, {0.00392, 0.31373, 0.00392}, {0.00784, 0.31373, 0.00784}, {0.01176, 0.31373, 0.01176}, {0.01569, 0.31373, 0.01569}, {0.01961, 0.31373, 0.01961}, {0.02353, 0.31373, 0.02353}, {0.02745, 0.31373, 0.02745}, {0.03137, 0.31373, 0.03137}, {0.03529, 0.31373, 0.03529}, {0.03922, 0.31373, 0.03922}, {0.04314, 0.31373, 0.04314}, {0.04706, 0.31373, 0.04706}, {0.05098, 0.31373, 0.05098}, {0.05490, 0.31373, 0.05490}, {0.05882, 0.31373, 0.05882}, {0.06275, 0.31373, 0.06275}, {0.06667, 0.47059, 0.06667}, {0.07059, 0.47059, 0.07059}, {0.07451, 0.47059, 0.07451}, {0.07843, 0.47059, 0.07843}, {0.08235, 0.47059, 0.08235}, {0.08627, 0.47059, 0.08627}, {0.09020, 0.47059, 0.09020}, {0.09412, 0.47059, 0.09412}, {0.09804, 0.47059, 0.09804}, {0.10196, 0.47059, 0.10196}, {0.10588, 0.47059, 0.10588}, {0.10980, 0.47059, 0.10980}, {0.11373, 0.47059, 0.11373}, {0.11765, 0.47059, 0.11765}, {0.12157, 0.47059, 0.12157}, {0.12549, 0.47059, 0.12549}, {0.12941, 0.62745, 0.12941}, {0.13333, 0.62745, 0.13333}, {0.13725, 0.62745, 0.13725}, {0.14118, 0.62745, 0.14118}, {0.14510, 0.62745, 0.14510}, {0.14902, 0.62745, 0.14902}, {0.15294, 0.62745, 0.15294}, {0.15686, 0.62745, 0.15686}, {0.16078, 0.62745, 0.16078}, {0.16471, 0.62745, 0.16471}, {0.16863, 0.62745, 0.16863}, {0.17255, 0.62745, 0.17255}, {0.17647, 0.62745, 0.17647}, {0.18039, 0.62745, 0.18039}, {0.18431, 0.62745, 0.18431}, {0.18824, 0.62745, 0.18824}, {0.19216, 0.78431, 0.19216}, {0.19608, 0.78431, 0.19608}, {0.20000, 0.78431, 0.20000}, {0.20392, 0.78431, 0.20392}, {0.20784, 0.78431, 0.20784}, {0.21176, 0.78431, 0.21176}, {0.21569, 0.78431, 0.21569}, {0.21961, 0.78431, 0.21961}, {0.22353, 0.78431, 0.22353}, {0.22745, 0.78431, 0.22745}, {0.23137, 0.78431, 0.23137}, {0.23529, 0.78431, 0.23529}, {0.23922, 0.78431, 0.23922}, {0.24314, 0.78431, 0.24314}, {0.24706, 0.78431, 0.24706}, {0.25098, 0.78431, 0.25098}, {0.25490, 0.94118, 0.25490}, {0.25882, 0.94118, 0.25882}, {0.26275, 0.94118, 0.26275}, {0.26667, 0.94118, 0.26667}, {0.27059, 0.94118, 0.27059}, {0.27451, 0.94118, 0.27451}, {0.27843, 0.94118, 0.27843}, {0.28235, 0.94118, 0.28235}, {0.28627, 0.94118, 0.28627}, {0.29020, 0.94118, 0.29020}, {0.29412, 0.94118, 0.29412}, {0.29804, 0.94118, 0.29804}, {0.30196, 0.94118, 0.30196}, {0.30588, 0.94118, 0.30588}, {0.30980, 0.94118, 0.30980}, {0.31373, 0.94118, 0.31373}, {0.31765, 0.95294, 0.31765}, {0.32157, 0.96471, 0.32157}, {0.32549, 0.97647, 0.32549}, {0.32941, 0.98824, 0.32941}, {0.33333, 1.00000, 0.33333}, {0.31373, 0.00392, 0.00392}, {0.31373, 0.00784, 0.00784}, {0.31373, 0.01176, 0.01176}, {0.31373, 0.01569, 0.01569}, {0.31373, 0.01961, 0.01961}, {0.31373, 0.02353, 0.02353}, {0.31373, 0.02745, 0.02745}, {0.31373, 0.03137, 0.03137}, {0.31373, 0.03529, 0.03529}, {0.31373, 0.03922, 0.03922}, {0.31373, 0.04314, 0.04314}, {0.31373, 0.04706, 0.04706}, {0.31373, 0.05098, 0.05098}, {0.31373, 0.05490, 0.05490}, {0.31373, 0.05882, 0.05882}, {0.31373, 0.06275, 0.06275}, {0.47059, 0.06667, 0.06667}, {0.47059, 0.07059, 0.07059}, {0.47059, 0.07451, 0.07451}, {0.47059, 0.07843, 0.07843}, {0.47059, 0.08235, 0.08235}, {0.47059, 0.08627, 0.08627}, {0.47059, 0.09020, 0.09020}, {0.47059, 0.09412, 0.09412}, {0.47059, 0.09804, 0.09804}, {0.47059, 0.10196, 0.10196}, {0.47059, 0.10588, 0.10588}, {0.47059, 0.10980, 0.10980}, {0.47059, 0.11373, 0.11373}, {0.47059, 0.11765, 0.11765}, {0.47059, 0.12157, 0.12157}, {0.47059, 0.12549, 0.12549}, {0.62745, 0.12941, 0.12941}, {0.62745, 0.13333, 0.13333}, {0.62745, 0.13725, 0.13725}, {0.62745, 0.14118, 0.14118}, {0.62745, 0.14510, 0.14510}, {0.62745, 0.14902, 0.14902}, {0.62745, 0.15294, 0.15294}, {0.62745, 0.15686, 0.15686}, {0.62745, 0.16078, 0.16078}, {0.62745, 0.16471, 0.16471}, {0.62745, 0.16863, 0.16863}, {0.62745, 0.17255, 0.17255}, {0.62745, 0.17647, 0.17647}, {0.62745, 0.18039, 0.18039}, {0.62745, 0.18431, 0.18431}, {0.62745, 0.18824, 0.18824}, {0.78431, 0.19216, 0.19216}, {0.78431, 0.19608, 0.19608}, {0.78431, 0.20000, 0.20000}, {0.78431, 0.20392, 0.20392}, {0.78431, 0.20784, 0.20784}, {0.78431, 0.21176, 0.21176}, {0.78431, 0.21569, 0.21569}, {0.78431, 0.21961, 0.21961}, {0.78431, 0.22353, 0.22353}, {0.78431, 0.22745, 0.22745}, {0.78431, 0.23137, 0.23137}, {0.78431, 0.23529, 0.23529}, {0.78431, 0.23922, 0.23922}, {0.78431, 0.24314, 0.24314}, {0.78431, 0.24706, 0.24706}, {0.78431, 0.25098, 0.25098}, {0.94118, 0.25490, 0.25490}, {0.94118, 0.25882, 0.25882}, {0.94118, 0.26275, 0.26275}, {0.94118, 0.26667, 0.26667}, {0.94118, 0.27059, 0.27059}, {0.94118, 0.27451, 0.27451}, {0.94118, 0.27843, 0.27843}, {0.94118, 0.28235, 0.28235}, {0.94118, 0.28627, 0.28627}, {0.94118, 0.29020, 0.29020}, {0.94118, 0.29412, 0.29412}, {0.94118, 0.29804, 0.29804}, {0.94118, 0.30196, 0.30196}, {0.94118, 0.30588, 0.30588}, {0.94118, 0.30980, 0.30980}, {0.94118, 0.31373, 0.31373}, {0.94902, 0.39216, 0.39216}, {0.96078, 0.52941, 0.52941}, {0.97255, 0.66667, 0.66667}, {0.98431, 0.80392, 0.80392}, {0.99216, 0.80000, 0.80000}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("staircase.lasc", staircase_lasc); static RGBColor red_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00392, 0.00000, 0.00000}, {0.00784, 0.00000, 0.00000}, {0.01176, 0.00000, 0.00000}, {0.01569, 0.00000, 0.00000}, {0.01961, 0.00000, 0.00000}, {0.02353, 0.00000, 0.00000}, {0.02745, 0.00000, 0.00000}, {0.03137, 0.00000, 0.00000}, {0.03529, 0.00000, 0.00000}, {0.03922, 0.00000, 0.00000}, {0.04314, 0.00000, 0.00000}, {0.04706, 0.00000, 0.00000}, {0.05098, 0.00000, 0.00000}, {0.05490, 0.00000, 0.00000}, {0.05882, 0.00000, 0.00000}, {0.06275, 0.00000, 0.00000}, {0.06667, 0.00000, 0.00000}, {0.07059, 0.00000, 0.00000}, {0.07451, 0.00000, 0.00000}, {0.07843, 0.00000, 0.00000}, {0.08235, 0.00000, 0.00000}, {0.08627, 0.00000, 0.00000}, {0.09020, 0.00000, 0.00000}, {0.09412, 0.00000, 0.00000}, {0.09804, 0.00000, 0.00000}, {0.10196, 0.00000, 0.00000}, {0.10588, 0.00000, 0.00000}, {0.10980, 0.00000, 0.00000}, {0.11373, 0.00000, 0.00000}, {0.11765, 0.00000, 0.00000}, {0.12157, 0.00000, 0.00000}, {0.12549, 0.00000, 0.00000}, {0.12941, 0.00000, 0.00000}, {0.13333, 0.00000, 0.00000}, {0.13725, 0.00000, 0.00000}, {0.14118, 0.00000, 0.00000}, {0.14510, 0.00000, 0.00000}, {0.14902, 0.00000, 0.00000}, {0.15294, 0.00000, 0.00000}, {0.15686, 0.00000, 0.00000}, {0.16078, 0.00000, 0.00000}, {0.16471, 0.00000, 0.00000}, {0.16863, 0.00000, 0.00000}, {0.17255, 0.00000, 0.00000}, {0.17647, 0.00000, 0.00000}, {0.18039, 0.00000, 0.00000}, {0.18431, 0.00000, 0.00000}, {0.18824, 0.00000, 0.00000}, {0.19216, 0.00000, 0.00000}, {0.19608, 0.00000, 0.00000}, {0.20000, 0.00000, 0.00000}, {0.20392, 0.00000, 0.00000}, {0.20784, 0.00000, 0.00000}, {0.21176, 0.00000, 0.00000}, {0.21569, 0.00000, 0.00000}, {0.21961, 0.00000, 0.00000}, {0.22353, 0.00000, 0.00000}, {0.22745, 0.00000, 0.00000}, {0.23137, 0.00000, 0.00000}, {0.23529, 0.00000, 0.00000}, {0.23922, 0.00000, 0.00000}, {0.24314, 0.00000, 0.00000}, {0.24706, 0.00000, 0.00000}, {0.25098, 0.00000, 0.00000}, {0.25490, 0.00000, 0.00000}, {0.25882, 0.00000, 0.00000}, {0.26275, 0.00000, 0.00000}, {0.26667, 0.00000, 0.00000}, {0.27059, 0.00000, 0.00000}, {0.27451, 0.00000, 0.00000}, {0.27843, 0.00000, 0.00000}, {0.28235, 0.00000, 0.00000}, {0.28627, 0.00000, 0.00000}, {0.29020, 0.00000, 0.00000}, {0.29412, 0.00000, 0.00000}, {0.29804, 0.00000, 0.00000}, {0.30196, 0.00000, 0.00000}, {0.30588, 0.00000, 0.00000}, {0.30980, 0.00000, 0.00000}, {0.31373, 0.00000, 0.00000}, {0.31765, 0.00000, 0.00000}, {0.32157, 0.00000, 0.00000}, {0.32549, 0.00000, 0.00000}, {0.32941, 0.00000, 0.00000}, {0.33333, 0.00000, 0.00000}, {0.33725, 0.00000, 0.00000}, {0.34118, 0.00000, 0.00000}, {0.34510, 0.00000, 0.00000}, {0.34902, 0.00000, 0.00000}, {0.35294, 0.00000, 0.00000}, {0.35686, 0.00000, 0.00000}, {0.36078, 0.00000, 0.00000}, {0.36471, 0.00000, 0.00000}, {0.36863, 0.00000, 0.00000}, {0.37255, 0.00000, 0.00000}, {0.37647, 0.00000, 0.00000}, {0.38039, 0.00000, 0.00000}, {0.38431, 0.00000, 0.00000}, {0.38824, 0.00000, 0.00000}, {0.39216, 0.00000, 0.00000}, {0.39608, 0.00000, 0.00000}, {0.40000, 0.00000, 0.00000}, {0.40392, 0.00000, 0.00000}, {0.40784, 0.00000, 0.00000}, {0.41176, 0.00000, 0.00000}, {0.41569, 0.00000, 0.00000}, {0.41961, 0.00000, 0.00000}, {0.42353, 0.00000, 0.00000}, {0.42745, 0.00000, 0.00000}, {0.43137, 0.00000, 0.00000}, {0.43529, 0.00000, 0.00000}, {0.43922, 0.00000, 0.00000}, {0.44314, 0.00000, 0.00000}, {0.44706, 0.00000, 0.00000}, {0.45098, 0.00000, 0.00000}, {0.45490, 0.00000, 0.00000}, {0.45882, 0.00000, 0.00000}, {0.46275, 0.00000, 0.00000}, {0.46667, 0.00000, 0.00000}, {0.47059, 0.00000, 0.00000}, {0.47451, 0.00000, 0.00000}, {0.47843, 0.00000, 0.00000}, {0.48235, 0.00000, 0.00000}, {0.48627, 0.00000, 0.00000}, {0.49020, 0.00000, 0.00000}, {0.49412, 0.00000, 0.00000}, {0.49804, 0.00000, 0.00000}, {0.50196, 0.00000, 0.00000}, {0.50588, 0.00000, 0.00000}, {0.50980, 0.00000, 0.00000}, {0.51373, 0.00000, 0.00000}, {0.51765, 0.00000, 0.00000}, {0.52157, 0.00000, 0.00000}, {0.52549, 0.00000, 0.00000}, {0.52941, 0.00000, 0.00000}, {0.53333, 0.00000, 0.00000}, {0.53725, 0.00000, 0.00000}, {0.54118, 0.00000, 0.00000}, {0.54510, 0.00000, 0.00000}, {0.54902, 0.00000, 0.00000}, {0.55294, 0.00000, 0.00000}, {0.55686, 0.00000, 0.00000}, {0.56078, 0.00000, 0.00000}, {0.56471, 0.00000, 0.00000}, {0.56863, 0.00000, 0.00000}, {0.57255, 0.00000, 0.00000}, {0.57647, 0.00000, 0.00000}, {0.58039, 0.00000, 0.00000}, {0.58431, 0.00000, 0.00000}, {0.58824, 0.00000, 0.00000}, {0.59216, 0.00000, 0.00000}, {0.59608, 0.00000, 0.00000}, {0.60000, 0.00000, 0.00000}, {0.60392, 0.00000, 0.00000}, {0.60784, 0.00000, 0.00000}, {0.61176, 0.00000, 0.00000}, {0.61569, 0.00000, 0.00000}, {0.61961, 0.00000, 0.00000}, {0.62353, 0.00000, 0.00000}, {0.62745, 0.00000, 0.00000}, {0.63137, 0.00000, 0.00000}, {0.63529, 0.00000, 0.00000}, {0.63922, 0.00000, 0.00000}, {0.64314, 0.00000, 0.00000}, {0.64706, 0.00000, 0.00000}, {0.65098, 0.00000, 0.00000}, {0.65490, 0.00000, 0.00000}, {0.65882, 0.00000, 0.00000}, {0.66275, 0.00000, 0.00000}, {0.66667, 0.00000, 0.00000}, {0.67059, 0.00000, 0.00000}, {0.67451, 0.00000, 0.00000}, {0.67843, 0.00000, 0.00000}, {0.68235, 0.00000, 0.00000}, {0.68627, 0.00000, 0.00000}, {0.69020, 0.00000, 0.00000}, {0.69412, 0.00000, 0.00000}, {0.69804, 0.00000, 0.00000}, {0.70196, 0.00000, 0.00000}, {0.70588, 0.00000, 0.00000}, {0.70980, 0.00000, 0.00000}, {0.71373, 0.00000, 0.00000}, {0.71765, 0.00000, 0.00000}, {0.72157, 0.00000, 0.00000}, {0.72549, 0.00000, 0.00000}, {0.72941, 0.00000, 0.00000}, {0.73333, 0.00000, 0.00000}, {0.73725, 0.00000, 0.00000}, {0.74118, 0.00000, 0.00000}, {0.74510, 0.00000, 0.00000}, {0.74902, 0.00000, 0.00000}, {0.75294, 0.00000, 0.00000}, {0.75686, 0.00000, 0.00000}, {0.76078, 0.00000, 0.00000}, {0.76471, 0.00000, 0.00000}, {0.76863, 0.00000, 0.00000}, {0.77255, 0.00000, 0.00000}, {0.77647, 0.00000, 0.00000}, {0.78039, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78824, 0.00000, 0.00000}, {0.79216, 0.00000, 0.00000}, {0.79608, 0.00000, 0.00000}, {0.80000, 0.00000, 0.00000}, {0.80392, 0.00000, 0.00000}, {0.80784, 0.00000, 0.00000}, {0.81176, 0.00000, 0.00000}, {0.81569, 0.00000, 0.00000}, {0.81961, 0.00000, 0.00000}, {0.82353, 0.00000, 0.00000}, {0.82745, 0.00000, 0.00000}, {0.83137, 0.00000, 0.00000}, {0.83529, 0.00000, 0.00000}, {0.83922, 0.00000, 0.00000}, {0.84314, 0.00000, 0.00000}, {0.84706, 0.00000, 0.00000}, {0.85098, 0.00000, 0.00000}, {0.85490, 0.00000, 0.00000}, {0.85882, 0.00000, 0.00000}, {0.86275, 0.00000, 0.00000}, {0.86667, 0.00000, 0.00000}, {0.87059, 0.00000, 0.00000}, {0.87451, 0.00000, 0.00000}, {0.87843, 0.00000, 0.00000}, {0.88235, 0.00000, 0.00000}, {0.88627, 0.00000, 0.00000}, {0.89020, 0.00000, 0.00000}, {0.89412, 0.00000, 0.00000}, {0.89804, 0.00000, 0.00000}, {0.90196, 0.00000, 0.00000}, {0.90588, 0.00000, 0.00000}, {0.90980, 0.00000, 0.00000}, {0.91373, 0.00000, 0.00000}, {0.91765, 0.00000, 0.00000}, {0.92157, 0.00000, 0.00000}, {0.92549, 0.00000, 0.00000}, {0.92941, 0.00000, 0.00000}, {0.93333, 0.00000, 0.00000}, {0.93725, 0.00000, 0.00000}, {0.94118, 0.00000, 0.00000}, {0.94510, 0.00000, 0.00000}, {0.94902, 0.00000, 0.00000}, {0.95294, 0.00000, 0.00000}, {0.95686, 0.00000, 0.00000}, {0.96078, 0.00000, 0.00000}, {0.96471, 0.00000, 0.00000}, {0.96863, 0.00000, 0.00000}, {0.97255, 0.00000, 0.00000}, {0.97647, 0.00000, 0.00000}, {0.98039, 0.00000, 0.00000}, {0.98431, 0.00000, 0.00000}, {0.98824, 0.00000, 0.00000}, {0.99216, 0.00000, 0.00000}, {0.99608, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, }; new ColorMapInfo("red.lasc", red_lasc); static RGBColor heat_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.01176, 0.00392, 0.00000}, {0.02353, 0.00784, 0.00000}, {0.03529, 0.01176, 0.00000}, {0.04706, 0.01569, 0.00000}, {0.05882, 0.01961, 0.00000}, {0.07059, 0.02353, 0.00000}, {0.08235, 0.02745, 0.00000}, {0.09412, 0.03137, 0.00000}, {0.10588, 0.03529, 0.00000}, {0.11765, 0.03922, 0.00000}, {0.12941, 0.04314, 0.00000}, {0.14118, 0.04706, 0.00000}, {0.15294, 0.05098, 0.00000}, {0.16471, 0.05490, 0.00000}, {0.17647, 0.05882, 0.00000}, {0.18824, 0.06275, 0.00000}, {0.20000, 0.06667, 0.00000}, {0.21176, 0.07059, 0.00000}, {0.22353, 0.07451, 0.00000}, {0.23529, 0.07843, 0.00000}, {0.24706, 0.08235, 0.00000}, {0.25882, 0.08627, 0.00000}, {0.27059, 0.09020, 0.00000}, {0.28235, 0.09412, 0.00000}, {0.29412, 0.09804, 0.00000}, {0.30588, 0.10196, 0.00000}, {0.31765, 0.10588, 0.00000}, {0.32941, 0.10980, 0.00000}, {0.34118, 0.11373, 0.00000}, {0.35294, 0.11765, 0.00000}, {0.36471, 0.12157, 0.00000}, {0.37647, 0.12549, 0.00000}, {0.38824, 0.12941, 0.00000}, {0.40000, 0.13333, 0.00000}, {0.41176, 0.13725, 0.00000}, {0.42353, 0.14118, 0.00000}, {0.43529, 0.14510, 0.00000}, {0.44706, 0.14902, 0.00000}, {0.45882, 0.15294, 0.00000}, {0.47059, 0.15686, 0.00000}, {0.48235, 0.16078, 0.00000}, {0.49412, 0.16471, 0.00000}, {0.50588, 0.16863, 0.00000}, {0.51765, 0.17255, 0.00000}, {0.52941, 0.17647, 0.00000}, {0.54118, 0.18039, 0.00000}, {0.55294, 0.18431, 0.00000}, {0.56471, 0.18824, 0.00000}, {0.57647, 0.19216, 0.00000}, {0.58824, 0.19608, 0.00000}, {0.60000, 0.20000, 0.00000}, {0.61176, 0.20392, 0.00000}, {0.62353, 0.20784, 0.00000}, {0.63529, 0.21176, 0.00000}, {0.64706, 0.21569, 0.00000}, {0.65882, 0.21961, 0.00000}, {0.67059, 0.22353, 0.00000}, {0.68235, 0.22745, 0.00000}, {0.69412, 0.23137, 0.00000}, {0.70588, 0.23529, 0.00000}, {0.71765, 0.23922, 0.00000}, {0.72941, 0.24314, 0.00000}, {0.74118, 0.24706, 0.00000}, {0.75294, 0.25098, 0.00000}, {0.76471, 0.25490, 0.00000}, {0.77647, 0.25882, 0.00000}, {0.78824, 0.26275, 0.00000}, {0.80000, 0.26667, 0.00000}, {0.81176, 0.27059, 0.00000}, {0.82353, 0.27451, 0.00000}, {0.83529, 0.27843, 0.00000}, {0.84706, 0.28235, 0.00000}, {0.85882, 0.28627, 0.00000}, {0.87059, 0.29020, 0.00000}, {0.88235, 0.29412, 0.00000}, {0.89412, 0.29804, 0.00000}, {0.90588, 0.30196, 0.00000}, {0.91765, 0.30588, 0.00000}, {0.92941, 0.30980, 0.00000}, {0.94118, 0.31373, 0.00000}, {0.95294, 0.31765, 0.00000}, {0.96471, 0.32157, 0.00000}, {0.97647, 0.32549, 0.00000}, {0.98824, 0.32941, 0.00000}, {1.00000, 0.33333, 0.00000}, {1.00000, 0.33725, 0.00000}, {1.00000, 0.34118, 0.00000}, {1.00000, 0.34510, 0.00000}, {1.00000, 0.34902, 0.00000}, {1.00000, 0.35294, 0.00000}, {1.00000, 0.35686, 0.00000}, {1.00000, 0.36078, 0.00000}, {1.00000, 0.36471, 0.00000}, {1.00000, 0.36863, 0.00000}, {1.00000, 0.37255, 0.00000}, {1.00000, 0.37647, 0.00000}, {1.00000, 0.38039, 0.00000}, {1.00000, 0.38431, 0.00000}, {1.00000, 0.38824, 0.00000}, {1.00000, 0.39216, 0.00000}, {1.00000, 0.39608, 0.00000}, {1.00000, 0.40000, 0.00000}, {1.00000, 0.40392, 0.00000}, {1.00000, 0.40784, 0.00000}, {1.00000, 0.41176, 0.00000}, {1.00000, 0.41569, 0.00000}, {1.00000, 0.41961, 0.00000}, {1.00000, 0.42353, 0.00000}, {1.00000, 0.42745, 0.00000}, {1.00000, 0.43137, 0.00000}, {1.00000, 0.43529, 0.00000}, {1.00000, 0.43922, 0.00000}, {1.00000, 0.44314, 0.00000}, {1.00000, 0.44706, 0.00000}, {1.00000, 0.45098, 0.00000}, {1.00000, 0.45490, 0.00000}, {1.00000, 0.45882, 0.00000}, {1.00000, 0.46275, 0.00000}, {1.00000, 0.46667, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47451, 0.00000}, {1.00000, 0.47843, 0.00000}, {1.00000, 0.48235, 0.00000}, {1.00000, 0.48627, 0.00000}, {1.00000, 0.49020, 0.00000}, {1.00000, 0.49412, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.50196, 0.00000}, {1.00000, 0.50588, 0.00000}, {1.00000, 0.50980, 0.00000}, {1.00000, 0.51373, 0.00000}, {1.00000, 0.51765, 0.00000}, {1.00000, 0.52157, 0.00000}, {1.00000, 0.52549, 0.00000}, {1.00000, 0.52941, 0.00000}, {1.00000, 0.53333, 0.00000}, {1.00000, 0.53725, 0.00000}, {1.00000, 0.54118, 0.00000}, {1.00000, 0.54510, 0.00000}, {1.00000, 0.54902, 0.00000}, {1.00000, 0.55294, 0.00000}, {1.00000, 0.55686, 0.00000}, {1.00000, 0.56078, 0.00000}, {1.00000, 0.56471, 0.00000}, {1.00000, 0.56863, 0.00000}, {1.00000, 0.57255, 0.00000}, {1.00000, 0.57647, 0.00000}, {1.00000, 0.58039, 0.00000}, {1.00000, 0.58431, 0.00000}, {1.00000, 0.58824, 0.00000}, {1.00000, 0.59216, 0.00000}, {1.00000, 0.59608, 0.00000}, {1.00000, 0.60000, 0.00000}, {1.00000, 0.60392, 0.00000}, {1.00000, 0.60784, 0.00000}, {1.00000, 0.61176, 0.00000}, {1.00000, 0.61569, 0.00000}, {1.00000, 0.61961, 0.00000}, {1.00000, 0.62353, 0.00000}, {1.00000, 0.62745, 0.00000}, {1.00000, 0.63137, 0.00000}, {1.00000, 0.63529, 0.00000}, {1.00000, 0.63922, 0.00000}, {1.00000, 0.64314, 0.00000}, {1.00000, 0.64706, 0.00000}, {1.00000, 0.65098, 0.01176}, {1.00000, 0.65490, 0.02353}, {1.00000, 0.65882, 0.03529}, {1.00000, 0.66275, 0.04706}, {1.00000, 0.66667, 0.05882}, {1.00000, 0.67059, 0.07059}, {1.00000, 0.67451, 0.08235}, {1.00000, 0.67843, 0.09412}, {1.00000, 0.68235, 0.10588}, {1.00000, 0.68627, 0.11765}, {1.00000, 0.69020, 0.12941}, {1.00000, 0.69412, 0.14118}, {1.00000, 0.69804, 0.15294}, {1.00000, 0.70196, 0.16471}, {1.00000, 0.70588, 0.17647}, {1.00000, 0.70980, 0.18824}, {1.00000, 0.71373, 0.20000}, {1.00000, 0.71765, 0.21176}, {1.00000, 0.72157, 0.22353}, {1.00000, 0.72549, 0.23529}, {1.00000, 0.72941, 0.24706}, {1.00000, 0.73333, 0.25882}, {1.00000, 0.73725, 0.27059}, {1.00000, 0.74118, 0.28235}, {1.00000, 0.74510, 0.29412}, {1.00000, 0.74902, 0.30588}, {1.00000, 0.75294, 0.31765}, {1.00000, 0.75686, 0.32941}, {1.00000, 0.76078, 0.34118}, {1.00000, 0.76471, 0.35294}, {1.00000, 0.76863, 0.36471}, {1.00000, 0.77255, 0.37647}, {1.00000, 0.77647, 0.38824}, {1.00000, 0.78039, 0.40000}, {1.00000, 0.78431, 0.41176}, {1.00000, 0.78824, 0.42353}, {1.00000, 0.79216, 0.43529}, {1.00000, 0.79608, 0.44706}, {1.00000, 0.80000, 0.45882}, {1.00000, 0.80392, 0.47059}, {1.00000, 0.80784, 0.48235}, {1.00000, 0.81176, 0.49412}, {1.00000, 0.81569, 0.50588}, {1.00000, 0.81961, 0.51765}, {1.00000, 0.82353, 0.52941}, {1.00000, 0.82745, 0.54118}, {1.00000, 0.83137, 0.55294}, {1.00000, 0.83529, 0.56471}, {1.00000, 0.83922, 0.57647}, {1.00000, 0.84314, 0.58824}, {1.00000, 0.84706, 0.60000}, {1.00000, 0.85098, 0.61176}, {1.00000, 0.85490, 0.62353}, {1.00000, 0.85882, 0.63529}, {1.00000, 0.86275, 0.64706}, {1.00000, 0.86667, 0.65882}, {1.00000, 0.87059, 0.67059}, {1.00000, 0.87451, 0.68235}, {1.00000, 0.87843, 0.69412}, {1.00000, 0.88235, 0.70588}, {1.00000, 0.88627, 0.71765}, {1.00000, 0.89020, 0.72941}, {1.00000, 0.89412, 0.74118}, {1.00000, 0.89804, 0.75294}, {1.00000, 0.90196, 0.76471}, {1.00000, 0.90588, 0.77647}, {1.00000, 0.90980, 0.78824}, {1.00000, 0.91373, 0.80000}, {1.00000, 0.91765, 0.81176}, {1.00000, 0.92157, 0.82353}, {1.00000, 0.92549, 0.83529}, {1.00000, 0.92941, 0.84706}, {1.00000, 0.93333, 0.85882}, {1.00000, 0.93725, 0.87059}, {1.00000, 0.94118, 0.88235}, {1.00000, 0.94510, 0.89412}, {1.00000, 0.94902, 0.90588}, {1.00000, 0.95294, 0.91765}, {1.00000, 0.95686, 0.92941}, {1.00000, 0.96078, 0.94118}, {1.00000, 0.96471, 0.95294}, {1.00000, 0.96863, 0.96471}, {1.00000, 0.97255, 0.97647}, {1.00000, 0.97647, 0.98824}, {1.00000, 0.98039, 1.00000}, {1.00000, 0.98431, 1.00000}, {1.00000, 0.98824, 1.00000}, {1.00000, 0.99216, 1.00000}, {1.00000, 0.99608, 1.00000}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("heat.lasc", heat_lasc); static RGBColor idl12_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00000, 0.32941, 0.00000}, {0.00000, 0.32941, 0.00000}, {0.00000, 0.32941, 0.00000}, {0.00000, 0.32941, 0.00000}, {0.00000, 0.32941, 0.00000}, {0.00000, 0.32941, 0.00000}, {0.00000, 0.32941, 0.00000}, {0.00000, 0.32941, 0.00000}, {0.00000, 0.32941, 0.00000}, {0.00000, 0.32941, 0.00000}, {0.00000, 0.32941, 0.00000}, {0.00000, 0.32941, 0.00000}, {0.00000, 0.32941, 0.00000}, {0.00000, 0.32941, 0.00000}, {0.00000, 0.32941, 0.00000}, {0.00000, 0.65882, 0.00000}, {0.00000, 0.65882, 0.00000}, {0.00000, 0.65882, 0.00000}, {0.00000, 0.65882, 0.00000}, {0.00000, 0.65882, 0.00000}, {0.00000, 0.65882, 0.00000}, {0.00000, 0.65882, 0.00000}, {0.00000, 0.65882, 0.00000}, {0.00000, 0.65882, 0.00000}, {0.00000, 0.65882, 0.00000}, {0.00000, 0.65882, 0.00000}, {0.00000, 0.65882, 0.00000}, {0.00000, 0.65882, 0.00000}, {0.00000, 0.65882, 0.00000}, {0.00000, 0.65882, 0.00000}, {0.00000, 0.65882, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.32941}, {0.00000, 1.00000, 0.32941}, {0.00000, 1.00000, 0.32941}, {0.00000, 1.00000, 0.32941}, {0.00000, 1.00000, 0.32941}, {0.00000, 1.00000, 0.32941}, {0.00000, 1.00000, 0.32941}, {0.00000, 1.00000, 0.32941}, {0.00000, 1.00000, 0.32941}, {0.00000, 1.00000, 0.32941}, {0.00000, 1.00000, 0.32941}, {0.00000, 1.00000, 0.32941}, {0.00000, 1.00000, 0.32941}, {0.00000, 1.00000, 0.32941}, {0.00000, 1.00000, 0.32941}, {0.00000, 1.00000, 0.32941}, {0.00000, 1.00000, 0.65882}, {0.00000, 1.00000, 0.65882}, {0.00000, 1.00000, 0.65882}, {0.00000, 1.00000, 0.65882}, {0.00000, 1.00000, 0.65882}, {0.00000, 1.00000, 0.65882}, {0.00000, 1.00000, 0.65882}, {0.00000, 1.00000, 0.65882}, {0.00000, 1.00000, 0.65882}, {0.00000, 1.00000, 0.65882}, {0.00000, 1.00000, 0.65882}, {0.00000, 1.00000, 0.65882}, {0.00000, 1.00000, 0.65882}, {0.00000, 1.00000, 0.65882}, {0.00000, 1.00000, 0.65882}, {0.00000, 1.00000, 0.65882}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.50196, 0.00000, 1.00000}, {0.50196, 0.00000, 1.00000}, {0.50196, 0.00000, 1.00000}, {0.50196, 0.00000, 1.00000}, {0.50196, 0.00000, 1.00000}, {0.50196, 0.00000, 1.00000}, {0.50196, 0.00000, 1.00000}, {0.50196, 0.00000, 1.00000}, {0.50196, 0.00000, 1.00000}, {0.50196, 0.00000, 1.00000}, {0.50196, 0.00000, 1.00000}, {0.50196, 0.00000, 1.00000}, {0.50196, 0.00000, 1.00000}, {0.50196, 0.00000, 1.00000}, {0.50196, 0.00000, 1.00000}, {0.50196, 0.00000, 1.00000}, {1.00000, 0.00000, 0.86275}, {1.00000, 0.00000, 0.86275}, {1.00000, 0.00000, 0.86275}, {1.00000, 0.00000, 0.86275}, {1.00000, 0.00000, 0.86275}, {1.00000, 0.00000, 0.86275}, {1.00000, 0.00000, 0.86275}, {1.00000, 0.00000, 0.86275}, {1.00000, 0.00000, 0.86275}, {1.00000, 0.00000, 0.86275}, {1.00000, 0.00000, 0.86275}, {1.00000, 0.00000, 0.86275}, {1.00000, 0.00000, 0.86275}, {1.00000, 0.00000, 0.86275}, {1.00000, 0.00000, 0.86275}, {1.00000, 0.00000, 0.86275}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.50196}, {1.00000, 0.00000, 0.50196}, {1.00000, 0.00000, 0.50196}, {1.00000, 0.00000, 0.50196}, {1.00000, 0.00000, 0.50196}, {1.00000, 0.00000, 0.50196}, {1.00000, 0.00000, 0.50196}, {1.00000, 0.00000, 0.50196}, {1.00000, 0.00000, 0.50196}, {1.00000, 0.00000, 0.50196}, {1.00000, 0.00000, 0.50196}, {1.00000, 0.00000, 0.50196}, {1.00000, 0.00000, 0.50196}, {1.00000, 0.00000, 0.50196}, {1.00000, 0.00000, 0.50196}, {1.00000, 0.00000, 0.50196}, {1.00000, 0.00000, 0.25098}, {1.00000, 0.00000, 0.25098}, {1.00000, 0.00000, 0.25098}, {1.00000, 0.00000, 0.25098}, {1.00000, 0.00000, 0.25098}, {1.00000, 0.00000, 0.25098}, {1.00000, 0.00000, 0.25098}, {1.00000, 0.00000, 0.25098}, {1.00000, 0.00000, 0.25098}, {1.00000, 0.00000, 0.25098}, {1.00000, 0.00000, 0.25098}, {1.00000, 0.00000, 0.25098}, {1.00000, 0.00000, 0.25098}, {1.00000, 0.00000, 0.25098}, {1.00000, 0.00000, 0.25098}, {1.00000, 0.00000, 0.25098}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {0.86275, 0.74510, 0.74510}, {0.86275, 0.74510, 0.74510}, {0.86275, 0.74510, 0.74510}, {0.86275, 0.74510, 0.74510}, {0.86275, 0.74510, 0.74510}, {0.86667, 0.74510, 0.74510}, {0.86667, 0.74510, 0.74510}, {0.86667, 0.74510, 0.74510}, {0.86667, 0.74510, 0.74510}, {0.86667, 0.74510, 0.74510}, {0.87059, 0.74510, 0.74510}, {0.87059, 0.74510, 0.74510}, {0.87059, 0.74510, 0.74510}, {0.87059, 0.74510, 0.74510}, {0.87059, 0.74510, 0.74510}, {0.87451, 0.74510, 0.74510}, {0.86275, 0.86275, 0.86275}, {0.86275, 0.86275, 0.86275}, {0.86275, 0.86275, 0.86275}, {0.86275, 0.86275, 0.86275}, {0.86275, 0.86275, 0.86275}, {0.86275, 0.86275, 0.86275}, {0.86275, 0.86275, 0.86275}, {0.86275, 0.86275, 0.86275}, {0.86275, 0.86275, 0.86275}, {0.86275, 0.86275, 0.86275}, {0.86275, 0.86275, 0.86275}, {0.86275, 0.86275, 0.86275}, {0.86275, 0.86275, 0.86275}, {0.86275, 0.86275, 0.86275}, {0.86275, 0.86275, 0.86275}, {0.86275, 0.86275, 0.86275}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("idl12.lasc", idl12_lasc); static RGBColor random4_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.70588, 0.00000, 0.90196}, {0.70588, 0.00000, 0.90196}, {0.70588, 0.00000, 0.90196}, {0.70588, 0.00000, 0.90196}, {0.70588, 0.00000, 0.90196}, {0.70588, 0.00000, 0.90196}, {0.70588, 0.00000, 0.90196}, {0.70588, 0.00000, 0.90196}, {0.70588, 0.00000, 0.90196}, {0.70588, 0.00000, 0.90196}, {0.70588, 0.00000, 0.90196}, {0.70588, 0.00000, 0.90196}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.78431, 0.47059, 1.00000}, {0.78431, 0.47059, 1.00000}, {0.78431, 0.47059, 1.00000}, {0.78431, 0.47059, 1.00000}, {0.78431, 0.47059, 1.00000}, {0.78431, 0.47059, 1.00000}, {0.78431, 0.47059, 1.00000}, {0.78431, 0.47059, 1.00000}, {0.78431, 0.47059, 1.00000}, {0.78431, 0.47059, 1.00000}, {0.78431, 0.47059, 1.00000}, {0.78431, 0.47059, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("random4.lasc", random4_lasc); static RGBColor smooth_lasc[] = { {0.00000, 0.00000, 1.00000}, {0.01569, 0.00000, 0.98431}, {0.03529, 0.00000, 0.96471}, {0.05098, 0.00000, 0.94902}, {0.06667, 0.00000, 0.93333}, {0.08627, 0.00000, 0.91373}, {0.10196, 0.00000, 0.89804}, {0.11765, 0.00000, 0.88235}, {0.13725, 0.00000, 0.86275}, {0.15294, 0.00000, 0.84706}, {0.16863, 0.00000, 0.83137}, {0.18824, 0.00000, 0.81176}, {0.20392, 0.00000, 0.79608}, {0.21961, 0.00000, 0.78039}, {0.23922, 0.00000, 0.76078}, {0.25490, 0.00000, 0.74510}, {0.27059, 0.00000, 0.72941}, {0.28627, 0.00000, 0.71373}, {0.30588, 0.00000, 0.69412}, {0.32157, 0.00000, 0.67843}, {0.33725, 0.00000, 0.66275}, {0.35686, 0.00000, 0.64314}, {0.37255, 0.00000, 0.62745}, {0.38824, 0.00000, 0.61176}, {0.40784, 0.00000, 0.59216}, {0.42353, 0.00000, 0.57647}, {0.43922, 0.00000, 0.56078}, {0.45882, 0.00000, 0.54118}, {0.47451, 0.00000, 0.52549}, {0.49020, 0.00000, 0.50980}, {0.50980, 0.00000, 0.49020}, {0.52549, 0.00000, 0.47451}, {0.54118, 0.00000, 0.45882}, {0.56078, 0.00000, 0.43922}, {0.57647, 0.00000, 0.42353}, {0.59216, 0.00000, 0.40784}, {0.61176, 0.00000, 0.38824}, {0.62745, 0.00000, 0.37255}, {0.64314, 0.00000, 0.35686}, {0.66275, 0.00000, 0.33725}, {0.67843, 0.00000, 0.32157}, {0.69412, 0.00000, 0.30588}, {0.71373, 0.00000, 0.28627}, {0.72941, 0.00000, 0.27059}, {0.74510, 0.00000, 0.25490}, {0.76078, 0.00000, 0.23922}, {0.78039, 0.00000, 0.21961}, {0.79608, 0.00000, 0.20392}, {0.81176, 0.00000, 0.18824}, {0.83137, 0.00000, 0.16863}, {0.84706, 0.00000, 0.15294}, {0.86275, 0.00000, 0.13725}, {0.88235, 0.00000, 0.11765}, {0.89804, 0.00000, 0.10196}, {0.91373, 0.00000, 0.08627}, {0.93333, 0.00000, 0.06667}, {0.94902, 0.00000, 0.05098}, {0.96471, 0.00000, 0.03529}, {0.98431, 0.00000, 0.01569}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.01176, 0.00000}, {1.00000, 0.01961, 0.00000}, {1.00000, 0.03137, 0.00000}, {1.00000, 0.03922, 0.00000}, {1.00000, 0.05098, 0.00000}, {1.00000, 0.05882, 0.00000}, {1.00000, 0.07059, 0.00000}, {1.00000, 0.08235, 0.00000}, {1.00000, 0.09020, 0.00000}, {1.00000, 0.10196, 0.00000}, {1.00000, 0.10980, 0.00000}, {1.00000, 0.12157, 0.00000}, {1.00000, 0.12941, 0.00000}, {1.00000, 0.14118, 0.00000}, {0.99608, 0.15294, 0.00000}, {0.99608, 0.16078, 0.00000}, {0.99608, 0.17255, 0.00000}, {0.99608, 0.18039, 0.00000}, {0.99608, 0.19216, 0.00000}, {0.99608, 0.20392, 0.00000}, {0.99608, 0.21176, 0.00000}, {0.99608, 0.22353, 0.00000}, {0.99608, 0.23137, 0.00000}, {0.99608, 0.24314, 0.00000}, {0.99608, 0.25098, 0.00000}, {0.99608, 0.26275, 0.00000}, {0.99608, 0.27451, 0.00000}, {0.99608, 0.28235, 0.00000}, {0.99608, 0.29412, 0.00000}, {0.99608, 0.30196, 0.00000}, {0.99608, 0.31373, 0.00000}, {0.99608, 0.32157, 0.00000}, {0.99608, 0.33333, 0.00000}, {0.99608, 0.34510, 0.00000}, {0.99608, 0.35294, 0.00000}, {0.99608, 0.36471, 0.00000}, {0.99608, 0.37255, 0.00000}, {0.99608, 0.38431, 0.00000}, {0.99608, 0.39216, 0.00000}, {0.99608, 0.40392, 0.00000}, {0.99608, 0.41569, 0.00000}, {0.99608, 0.42353, 0.00000}, {0.99608, 0.43529, 0.00000}, {0.99608, 0.44314, 0.00000}, {0.99216, 0.45490, 0.00000}, {0.99216, 0.46667, 0.00000}, {0.99216, 0.47451, 0.00000}, {0.99216, 0.48627, 0.00000}, {0.99216, 0.49412, 0.00000}, {0.99216, 0.50588, 0.00000}, {0.99216, 0.51373, 0.00000}, {0.99216, 0.52549, 0.00000}, {0.99216, 0.53725, 0.00000}, {0.99216, 0.54510, 0.00000}, {0.99216, 0.55686, 0.00000}, {0.99216, 0.56471, 0.00000}, {0.99216, 0.57647, 0.00000}, {0.99216, 0.58431, 0.00000}, {0.99216, 0.59608, 0.00000}, {0.99216, 0.60000, 0.00000}, {0.99216, 0.60784, 0.00000}, {0.99216, 0.61176, 0.00000}, {0.99216, 0.61569, 0.00000}, {0.99216, 0.61961, 0.00000}, {0.99216, 0.62745, 0.00000}, {0.99216, 0.63137, 0.00000}, {0.99216, 0.63529, 0.00000}, {0.99216, 0.64314, 0.00000}, {0.98824, 0.64706, 0.00000}, {0.98824, 0.65098, 0.00000}, {0.98824, 0.65882, 0.00000}, {0.98824, 0.66275, 0.00000}, {0.98824, 0.66667, 0.00000}, {0.98824, 0.67451, 0.00000}, {0.98824, 0.67843, 0.00000}, {0.98824, 0.68235, 0.00000}, {0.98824, 0.68627, 0.00000}, {0.98824, 0.69412, 0.00000}, {0.98824, 0.69804, 0.00000}, {0.98824, 0.70196, 0.00000}, {0.98824, 0.70980, 0.00000}, {0.98824, 0.71373, 0.00000}, {0.98824, 0.71765, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72941, 0.00000}, {0.98824, 0.73333, 0.00000}, {0.98824, 0.73725, 0.00000}, {0.98824, 0.74510, 0.00000}, {0.98824, 0.74902, 0.00000}, {0.98431, 0.75294, 0.00000}, {0.98431, 0.76078, 0.00000}, {0.98431, 0.76471, 0.00000}, {0.98431, 0.76863, 0.00000}, {0.98431, 0.77255, 0.00000}, {0.98431, 0.78039, 0.00000}, {0.98431, 0.78431, 0.00000}, {0.98431, 0.78824, 0.00000}, {0.98431, 0.79608, 0.00000}, {0.98431, 0.80000, 0.00000}, {0.98431, 0.80392, 0.00000}, {0.98431, 0.81176, 0.00000}, {0.98431, 0.81569, 0.00000}, {0.98431, 0.81961, 0.00000}, {0.98431, 0.82745, 0.00000}, {0.98431, 0.83137, 0.00000}, {0.98431, 0.83529, 0.00000}, {0.98431, 0.83922, 0.00000}, {0.98431, 0.84706, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98039, 0.85490, 0.00000}, {0.98039, 0.86275, 0.00000}, {0.98039, 0.86667, 0.00000}, {0.98039, 0.87059, 0.00000}, {0.98039, 0.87843, 0.00000}, {0.98039, 0.88235, 0.00000}, {0.98039, 0.88627, 0.00000}, {0.98039, 0.89020, 0.00000}, {0.98039, 0.89804, 0.00000}, {0.98039, 0.90196, 0.00000}, {0.98039, 0.90196, 0.00000}, {0.96471, 0.88627, 0.00000}, {0.94902, 0.87059, 0.00000}, {0.92941, 0.85490, 0.00000}, {0.91373, 0.83922, 0.00000}, {0.89804, 0.82745, 0.00000}, {0.88235, 0.81176, 0.00000}, {0.86275, 0.79608, 0.00000}, {0.84706, 0.78039, 0.00000}, {0.83137, 0.76471, 0.00000}, {0.81569, 0.74902, 0.00000}, {0.79608, 0.73333, 0.00000}, {0.78039, 0.71765, 0.00000}, {0.76471, 0.70196, 0.00000}, {0.74902, 0.68627, 0.00000}, {0.72941, 0.67451, 0.00000}, {0.71373, 0.65882, 0.00000}, {0.69804, 0.64314, 0.00000}, {0.68235, 0.62745, 0.00000}, {0.66275, 0.61176, 0.00000}, {0.64706, 0.59608, 0.00000}, {0.63137, 0.58039, 0.00000}, {0.61569, 0.56471, 0.00000}, {0.60000, 0.54902, 0.00000}, {0.58039, 0.53333, 0.00000}, {0.56471, 0.52157, 0.00000}, {0.54902, 0.50588, 0.00000}, {0.53333, 0.49020, 0.00000}, {0.51373, 0.47451, 0.00000}, {0.49804, 0.45882, 0.00000}, {0.48235, 0.44314, 0.00000}, {0.46667, 0.42745, 0.00000}, {0.44706, 0.41176, 0.00000}, {0.43137, 0.39608, 0.00000}, {0.41569, 0.38039, 0.00000}, {0.40000, 0.36863, 0.00000}, {0.38039, 0.35294, 0.00000}, {0.36471, 0.33725, 0.00000}, {0.34902, 0.32157, 0.00000}, {0.33333, 0.30588, 0.00000}, {0.31765, 0.29020, 0.00000}, {0.29804, 0.27451, 0.00000}, {0.28235, 0.25882, 0.00000}, {0.26667, 0.24314, 0.00000}, {0.25098, 0.22745, 0.00000}, {0.23137, 0.21569, 0.00000}, {0.21569, 0.20000, 0.00000}, {0.20000, 0.18431, 0.00000}, {0.18431, 0.16863, 0.00000}, {0.16471, 0.15294, 0.00000}, {0.14902, 0.13725, 0.00000}, {0.13333, 0.12157, 0.00000}, {0.11765, 0.10588, 0.00000}, {0.09804, 0.09020, 0.00000}, {0.08235, 0.07451, 0.00000}, {0.06667, 0.06275, 0.00000}, {0.05098, 0.04706, 0.00000}, {0.03137, 0.03137, 0.00000}, {0.01569, 0.01569, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, }; new ColorMapInfo("smooth.lasc", smooth_lasc); static RGBColor random1_lasc[] = { {0.00000, 0.00000, 0.16471}, {0.00000, 0.00000, 0.16471}, {0.00000, 0.00000, 0.16471}, {0.00000, 0.00000, 0.16471}, {0.00000, 0.00000, 0.16471}, {0.00000, 0.00000, 0.16471}, {0.00000, 0.00000, 0.16471}, {0.00000, 0.00000, 0.16471}, {0.23137, 0.00000, 0.31765}, {0.23137, 0.00000, 0.31765}, {0.23137, 0.00000, 0.31765}, {0.23137, 0.00000, 0.31765}, {0.23137, 0.00000, 0.31765}, {0.23137, 0.00000, 0.31765}, {0.23137, 0.00000, 0.31765}, {0.23137, 0.00000, 0.31765}, {0.47059, 0.00000, 0.47451}, {0.47059, 0.00000, 0.47451}, {0.47059, 0.00000, 0.47451}, {0.47059, 0.00000, 0.47451}, {0.47059, 0.00000, 0.47451}, {0.47059, 0.00000, 0.47451}, {0.47059, 0.00000, 0.47451}, {0.47059, 0.00000, 0.47451}, {0.47059, 0.00000, 0.63922}, {0.47059, 0.00000, 0.63922}, {0.47059, 0.00000, 0.63922}, {0.47059, 0.00000, 0.63922}, {0.47059, 0.00000, 0.63922}, {0.47059, 0.00000, 0.63922}, {0.47059, 0.00000, 0.63922}, {0.47059, 0.00000, 0.63922}, {0.23137, 0.00000, 0.80392}, {0.23137, 0.00000, 0.80392}, {0.23137, 0.00000, 0.80392}, {0.23137, 0.00000, 0.80392}, {0.23137, 0.00000, 0.80392}, {0.23137, 0.00000, 0.80392}, {0.23137, 0.00000, 0.80392}, {0.23137, 0.00000, 0.80392}, {0.00000, 0.00000, 0.97647}, {0.00000, 0.00000, 0.97647}, {0.00000, 0.00000, 0.97647}, {0.00000, 0.00000, 0.97647}, {0.00000, 0.00000, 0.97647}, {0.00000, 0.00000, 0.97647}, {0.00000, 0.00000, 0.97647}, {0.00000, 0.00000, 0.97647}, {0.00000, 0.05098, 0.85098}, {0.00000, 0.05098, 0.85098}, {0.00000, 0.05098, 0.85098}, {0.00000, 0.05098, 0.85098}, {0.00000, 0.05098, 0.85098}, {0.00000, 0.05098, 0.85098}, {0.00000, 0.05098, 0.85098}, {0.00000, 0.05098, 0.85098}, {0.00000, 0.19608, 0.69412}, {0.00000, 0.19608, 0.69412}, {0.00000, 0.19608, 0.69412}, {0.00000, 0.19608, 0.69412}, {0.00000, 0.19608, 0.69412}, {0.00000, 0.19608, 0.69412}, {0.00000, 0.19608, 0.69412}, {0.00000, 0.19608, 0.69412}, {0.00000, 0.33333, 0.56471}, {0.00000, 0.33333, 0.56471}, {0.00000, 0.33333, 0.56471}, {0.00000, 0.33333, 0.56471}, {0.00000, 0.33333, 0.56471}, {0.00000, 0.33333, 0.56471}, {0.00000, 0.33333, 0.56471}, {0.00000, 0.33333, 0.56471}, {0.00000, 0.42353, 0.44706}, {0.00000, 0.42353, 0.44706}, {0.00000, 0.42353, 0.44706}, {0.00000, 0.42353, 0.44706}, {0.00000, 0.42353, 0.44706}, {0.00000, 0.42353, 0.44706}, {0.00000, 0.42353, 0.44706}, {0.00000, 0.42353, 0.44706}, {0.00000, 0.50980, 0.35294}, {0.00000, 0.50980, 0.35294}, {0.00000, 0.50980, 0.35294}, {0.00000, 0.50980, 0.35294}, {0.00000, 0.50980, 0.35294}, {0.00000, 0.50980, 0.35294}, {0.00000, 0.50980, 0.35294}, {0.00000, 0.50980, 0.35294}, {0.00000, 0.59216, 0.25882}, {0.00000, 0.59216, 0.25882}, {0.00000, 0.59216, 0.25882}, {0.00000, 0.59216, 0.25882}, {0.00000, 0.59216, 0.25882}, {0.00000, 0.59216, 0.25882}, {0.00000, 0.59216, 0.25882}, {0.00000, 0.59216, 0.25882}, {0.00000, 0.67059, 0.16471}, {0.00000, 0.67059, 0.16471}, {0.00000, 0.67059, 0.16471}, {0.00000, 0.67059, 0.16471}, {0.00000, 0.67059, 0.16471}, {0.00000, 0.67059, 0.16471}, {0.00000, 0.67059, 0.16471}, {0.00000, 0.67059, 0.16471}, {0.00000, 0.74902, 0.05490}, {0.00000, 0.74902, 0.05490}, {0.00000, 0.74902, 0.05490}, {0.00000, 0.74902, 0.05490}, {0.00000, 0.74902, 0.05490}, {0.00000, 0.74902, 0.05490}, {0.00000, 0.74902, 0.05490}, {0.00000, 0.74902, 0.05490}, {0.00000, 0.82353, 0.00000}, {0.00000, 0.82353, 0.00000}, {0.00000, 0.82353, 0.00000}, {0.00000, 0.82353, 0.00000}, {0.00000, 0.82353, 0.00000}, {0.00000, 0.82353, 0.00000}, {0.00000, 0.82353, 0.00000}, {0.00000, 0.82353, 0.00000}, {0.00000, 0.89804, 0.00000}, {0.00000, 0.89804, 0.00000}, {0.00000, 0.89804, 0.00000}, {0.00000, 0.89804, 0.00000}, {0.00000, 0.89804, 0.00000}, {0.00000, 0.89804, 0.00000}, {0.00000, 0.89804, 0.00000}, {0.00000, 0.89804, 0.00000}, {0.00000, 0.97255, 0.00000}, {0.00000, 0.97255, 0.00000}, {0.00000, 0.97255, 0.00000}, {0.00000, 0.97255, 0.00000}, {0.00000, 0.97255, 0.00000}, {0.00000, 0.97255, 0.00000}, {0.00000, 0.97255, 0.00000}, {0.00000, 0.97255, 0.00000}, {0.05490, 0.95294, 0.00000}, {0.05490, 0.95294, 0.00000}, {0.05490, 0.95294, 0.00000}, {0.05490, 0.95294, 0.00000}, {0.05490, 0.95294, 0.00000}, {0.05490, 0.95294, 0.00000}, {0.05490, 0.95294, 0.00000}, {0.05490, 0.95294, 0.00000}, {0.14902, 0.88235, 0.00000}, {0.14902, 0.88235, 0.00000}, {0.14902, 0.88235, 0.00000}, {0.14902, 0.88235, 0.00000}, {0.14902, 0.88235, 0.00000}, {0.14902, 0.88235, 0.00000}, {0.14902, 0.88235, 0.00000}, {0.14902, 0.88235, 0.00000}, {0.41176, 0.80784, 0.00000}, {0.41176, 0.80784, 0.00000}, {0.41176, 0.80784, 0.00000}, {0.41176, 0.80784, 0.00000}, {0.41176, 0.80784, 0.00000}, {0.41176, 0.80784, 0.00000}, {0.41176, 0.80784, 0.00000}, {0.41176, 0.80784, 0.00000}, {0.70980, 0.81176, 0.00000}, {0.70980, 0.81176, 0.00000}, {0.70980, 0.81176, 0.00000}, {0.70980, 0.81176, 0.00000}, {0.70980, 0.81176, 0.00000}, {0.70980, 0.81176, 0.00000}, {0.70980, 0.81176, 0.00000}, {0.70980, 0.81176, 0.00000}, {1.00000, 0.93333, 0.00000}, {1.00000, 0.93333, 0.00000}, {1.00000, 0.93333, 0.00000}, {1.00000, 0.93333, 0.00000}, {1.00000, 0.93333, 0.00000}, {1.00000, 0.93333, 0.00000}, {1.00000, 0.93333, 0.00000}, {1.00000, 0.93333, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 0.70196, 0.00000}, {1.00000, 0.70196, 0.00000}, {1.00000, 0.70196, 0.00000}, {1.00000, 0.70196, 0.00000}, {1.00000, 0.70196, 0.00000}, {1.00000, 0.70196, 0.00000}, {1.00000, 0.70196, 0.00000}, {1.00000, 0.70196, 0.00000}, {1.00000, 0.39216, 0.00000}, {1.00000, 0.39216, 0.00000}, {1.00000, 0.39216, 0.00000}, {1.00000, 0.39216, 0.00000}, {1.00000, 0.39216, 0.00000}, {1.00000, 0.39216, 0.00000}, {1.00000, 0.39216, 0.00000}, {1.00000, 0.39216, 0.00000}, {1.00000, 0.09804, 0.00000}, {1.00000, 0.09804, 0.00000}, {1.00000, 0.09804, 0.00000}, {1.00000, 0.09804, 0.00000}, {1.00000, 0.09804, 0.00000}, {1.00000, 0.09804, 0.00000}, {1.00000, 0.09804, 0.00000}, {1.00000, 0.09804, 0.00000}, {0.97647, 0.00000, 0.00000}, {0.97647, 0.00000, 0.00000}, {0.97647, 0.00000, 0.00000}, {0.97647, 0.00000, 0.00000}, {0.97647, 0.00000, 0.00000}, {0.97647, 0.00000, 0.00000}, {0.97647, 0.00000, 0.00000}, {0.97647, 0.00000, 0.00000}, {0.91373, 0.00000, 0.00000}, {0.91373, 0.00000, 0.00000}, {0.91373, 0.00000, 0.00000}, {0.91373, 0.00000, 0.00000}, {0.91373, 0.00000, 0.00000}, {0.91373, 0.00000, 0.00000}, {0.91373, 0.00000, 0.00000}, {0.91373, 0.00000, 0.00000}, {0.85098, 0.00000, 0.00000}, {0.85098, 0.00000, 0.00000}, {0.85098, 0.00000, 0.00000}, {0.85098, 0.00000, 0.00000}, {0.85098, 0.00000, 0.00000}, {0.85098, 0.00000, 0.00000}, {0.85098, 0.00000, 0.00000}, {0.85098, 0.00000, 0.00000}, {0.78824, 0.00000, 0.00000}, {0.78824, 0.00000, 0.00000}, {0.78824, 0.00000, 0.00000}, {0.78824, 0.00000, 0.00000}, {0.78824, 0.00000, 0.00000}, {0.78824, 0.00000, 0.00000}, {0.78824, 0.00000, 0.00000}, {0.78824, 0.00000, 0.00000}, }; new ColorMapInfo("random1.lasc", random1_lasc); static RGBColor real_lasc[] = { {0.00784, 0.00392, 0.00000}, {0.01569, 0.00784, 0.00000}, {0.02353, 0.01176, 0.00000}, {0.03137, 0.01569, 0.00000}, {0.03922, 0.01961, 0.00000}, {0.04706, 0.02353, 0.00000}, {0.05490, 0.02745, 0.00000}, {0.06275, 0.03137, 0.00000}, {0.07059, 0.03529, 0.00000}, {0.07843, 0.03922, 0.00000}, {0.08627, 0.04314, 0.00000}, {0.09412, 0.04706, 0.00000}, {0.10196, 0.05098, 0.00000}, {0.10980, 0.05490, 0.00000}, {0.11765, 0.05882, 0.00000}, {0.12549, 0.06275, 0.00000}, {0.13333, 0.06667, 0.00000}, {0.14118, 0.07059, 0.00000}, {0.14902, 0.07451, 0.00000}, {0.15686, 0.07843, 0.00000}, {0.16471, 0.08235, 0.00000}, {0.17255, 0.08627, 0.00000}, {0.18039, 0.09020, 0.00000}, {0.18824, 0.09412, 0.00000}, {0.19608, 0.09804, 0.00000}, {0.20392, 0.10196, 0.00000}, {0.21176, 0.10588, 0.00000}, {0.21961, 0.10980, 0.00000}, {0.22745, 0.11373, 0.00000}, {0.23529, 0.11765, 0.00000}, {0.24314, 0.12157, 0.00000}, {0.25098, 0.12549, 0.00000}, {0.25882, 0.12941, 0.00000}, {0.26667, 0.13333, 0.00000}, {0.27451, 0.13725, 0.00000}, {0.28235, 0.14118, 0.00000}, {0.29020, 0.14510, 0.00000}, {0.29804, 0.14902, 0.00000}, {0.30588, 0.15294, 0.00000}, {0.31373, 0.15686, 0.00000}, {0.32157, 0.16078, 0.00000}, {0.32941, 0.16471, 0.00000}, {0.33725, 0.16863, 0.00000}, {0.34510, 0.17255, 0.00000}, {0.35294, 0.17647, 0.00000}, {0.36078, 0.18039, 0.00000}, {0.36863, 0.18431, 0.00000}, {0.37647, 0.18824, 0.00000}, {0.38431, 0.19216, 0.00000}, {0.39216, 0.19608, 0.00000}, {0.40000, 0.20000, 0.00000}, {0.40784, 0.20392, 0.00000}, {0.41569, 0.20784, 0.00000}, {0.42353, 0.21176, 0.00000}, {0.43137, 0.21569, 0.00000}, {0.43922, 0.21961, 0.00000}, {0.44706, 0.22353, 0.00000}, {0.45490, 0.22745, 0.00000}, {0.46275, 0.23137, 0.00000}, {0.47059, 0.23529, 0.00000}, {0.47843, 0.23922, 0.00000}, {0.48627, 0.24314, 0.00000}, {0.49412, 0.24706, 0.00000}, {0.50196, 0.25098, 0.00000}, {0.50980, 0.25490, 0.00000}, {0.51765, 0.25882, 0.00000}, {0.52549, 0.26275, 0.00000}, {0.53333, 0.26667, 0.00000}, {0.54118, 0.27059, 0.00000}, {0.54902, 0.27451, 0.00000}, {0.55686, 0.27843, 0.00000}, {0.56471, 0.28235, 0.00000}, {0.57255, 0.28627, 0.00000}, {0.58039, 0.29020, 0.00000}, {0.58824, 0.29412, 0.00000}, {0.59608, 0.29804, 0.00000}, {0.60392, 0.30196, 0.00000}, {0.61176, 0.30588, 0.00000}, {0.61961, 0.30980, 0.00000}, {0.62745, 0.31373, 0.00000}, {0.63529, 0.31765, 0.00000}, {0.64314, 0.32157, 0.00000}, {0.65098, 0.32549, 0.00000}, {0.65882, 0.32941, 0.00000}, {0.66667, 0.33333, 0.00000}, {0.67451, 0.33725, 0.00000}, {0.68235, 0.34118, 0.00000}, {0.69020, 0.34510, 0.00000}, {0.69804, 0.34902, 0.00000}, {0.70588, 0.35294, 0.00000}, {0.71373, 0.35686, 0.00000}, {0.72157, 0.36078, 0.00000}, {0.72941, 0.36471, 0.00000}, {0.73725, 0.36863, 0.00000}, {0.74510, 0.37255, 0.00000}, {0.75294, 0.37647, 0.00000}, {0.76078, 0.38039, 0.00000}, {0.76863, 0.38431, 0.00000}, {0.77647, 0.38824, 0.00000}, {0.78431, 0.39216, 0.00000}, {0.79216, 0.39608, 0.00000}, {0.80000, 0.40000, 0.00000}, {0.80784, 0.40392, 0.00000}, {0.81569, 0.40784, 0.00000}, {0.82353, 0.41176, 0.00000}, {0.83137, 0.41569, 0.00000}, {0.83922, 0.41961, 0.00000}, {0.84706, 0.42353, 0.00000}, {0.85490, 0.42745, 0.00000}, {0.86275, 0.43137, 0.00000}, {0.87059, 0.43529, 0.00000}, {0.87843, 0.43922, 0.00000}, {0.88627, 0.44314, 0.00000}, {0.89412, 0.44706, 0.00000}, {0.90196, 0.45098, 0.00000}, {0.90980, 0.45490, 0.00000}, {0.91765, 0.45882, 0.00000}, {0.92549, 0.46275, 0.00000}, {0.93333, 0.46667, 0.00000}, {0.94118, 0.47059, 0.00000}, {0.94902, 0.47451, 0.00000}, {0.95686, 0.47843, 0.00000}, {0.96471, 0.48235, 0.00000}, {0.97255, 0.48627, 0.00000}, {0.98039, 0.49020, 0.00000}, {0.98824, 0.49412, 0.00000}, {0.99608, 0.49804, 0.00000}, {1.00000, 0.50196, 0.00000}, {1.00000, 0.50588, 0.00784}, {1.00000, 0.50980, 0.01569}, {1.00000, 0.51373, 0.02353}, {1.00000, 0.51765, 0.03137}, {1.00000, 0.52157, 0.03922}, {1.00000, 0.52549, 0.04706}, {1.00000, 0.52941, 0.05490}, {1.00000, 0.53333, 0.06275}, {1.00000, 0.53725, 0.07059}, {1.00000, 0.54118, 0.07843}, {1.00000, 0.54510, 0.08627}, {1.00000, 0.54902, 0.09412}, {1.00000, 0.55294, 0.10196}, {1.00000, 0.55686, 0.10980}, {1.00000, 0.56078, 0.11765}, {1.00000, 0.56471, 0.12549}, {1.00000, 0.56863, 0.13333}, {1.00000, 0.57255, 0.14118}, {1.00000, 0.57647, 0.14902}, {1.00000, 0.58039, 0.15686}, {1.00000, 0.58431, 0.16471}, {1.00000, 0.58824, 0.17255}, {1.00000, 0.59216, 0.18039}, {1.00000, 0.59608, 0.18824}, {1.00000, 0.60000, 0.19608}, {1.00000, 0.60392, 0.20392}, {1.00000, 0.60784, 0.21176}, {1.00000, 0.61176, 0.21961}, {1.00000, 0.61569, 0.22745}, {1.00000, 0.61961, 0.23529}, {1.00000, 0.62353, 0.24314}, {1.00000, 0.62745, 0.25098}, {1.00000, 0.63137, 0.25882}, {1.00000, 0.63529, 0.26667}, {1.00000, 0.63922, 0.27451}, {1.00000, 0.64314, 0.28235}, {1.00000, 0.64706, 0.29020}, {1.00000, 0.65098, 0.29804}, {1.00000, 0.65490, 0.30588}, {1.00000, 0.65882, 0.31373}, {1.00000, 0.66275, 0.32157}, {1.00000, 0.66667, 0.32941}, {1.00000, 0.67059, 0.33725}, {1.00000, 0.67451, 0.34510}, {1.00000, 0.67843, 0.35294}, {1.00000, 0.68235, 0.36078}, {1.00000, 0.68627, 0.36863}, {1.00000, 0.69020, 0.37647}, {1.00000, 0.69412, 0.38431}, {1.00000, 0.69804, 0.39216}, {1.00000, 0.70196, 0.40000}, {1.00000, 0.70588, 0.40784}, {1.00000, 0.70980, 0.41569}, {1.00000, 0.71373, 0.42353}, {1.00000, 0.71765, 0.43137}, {1.00000, 0.72157, 0.43922}, {1.00000, 0.72549, 0.44706}, {1.00000, 0.72941, 0.45490}, {1.00000, 0.73333, 0.46275}, {1.00000, 0.73725, 0.47059}, {1.00000, 0.74118, 0.47843}, {1.00000, 0.74510, 0.48627}, {1.00000, 0.74902, 0.49412}, {1.00000, 0.75294, 0.50196}, {1.00000, 0.75686, 0.50980}, {1.00000, 0.76078, 0.51765}, {1.00000, 0.76471, 0.52549}, {1.00000, 0.76863, 0.53333}, {1.00000, 0.77255, 0.54118}, {1.00000, 0.77647, 0.54902}, {1.00000, 0.78039, 0.55686}, {1.00000, 0.78431, 0.56471}, {1.00000, 0.78824, 0.57255}, {1.00000, 0.79216, 0.58039}, {1.00000, 0.79608, 0.58824}, {1.00000, 0.80000, 0.59608}, {1.00000, 0.80392, 0.60392}, {1.00000, 0.80784, 0.61176}, {1.00000, 0.81176, 0.61961}, {1.00000, 0.81569, 0.62745}, {1.00000, 0.81961, 0.63529}, {1.00000, 0.82353, 0.64314}, {1.00000, 0.82745, 0.65098}, {1.00000, 0.83137, 0.65882}, {1.00000, 0.83529, 0.66667}, {1.00000, 0.83922, 0.67451}, {1.00000, 0.84314, 0.68235}, {1.00000, 0.84706, 0.69020}, {1.00000, 0.85098, 0.69804}, {1.00000, 0.85490, 0.70588}, {1.00000, 0.85882, 0.71373}, {1.00000, 0.86275, 0.72157}, {1.00000, 0.86667, 0.72941}, {1.00000, 0.87059, 0.73725}, {1.00000, 0.87451, 0.74510}, {1.00000, 0.87843, 0.75294}, {1.00000, 0.88235, 0.76078}, {1.00000, 0.88627, 0.76863}, {1.00000, 0.89020, 0.77647}, {1.00000, 0.89412, 0.78431}, {1.00000, 0.89804, 0.79216}, {1.00000, 0.90196, 0.80000}, {1.00000, 0.90588, 0.80784}, {1.00000, 0.90980, 0.81569}, {1.00000, 0.91373, 0.82353}, {1.00000, 0.91765, 0.83137}, {1.00000, 0.92157, 0.83922}, {1.00000, 0.92549, 0.84706}, {1.00000, 0.92941, 0.85490}, {1.00000, 0.93333, 0.86275}, {1.00000, 0.93725, 0.87059}, {1.00000, 0.94118, 0.87843}, {1.00000, 0.94510, 0.88627}, {1.00000, 0.94902, 0.89412}, {1.00000, 0.95294, 0.90196}, {1.00000, 0.95686, 0.90980}, {1.00000, 0.96078, 0.91765}, {1.00000, 0.96471, 0.92549}, {1.00000, 0.96863, 0.93333}, {1.00000, 0.97255, 0.94118}, {1.00000, 0.97647, 0.94902}, {1.00000, 0.98039, 0.95686}, {1.00000, 0.98431, 0.96471}, {1.00000, 0.98824, 0.97255}, {1.00000, 0.99216, 0.98039}, {1.00000, 0.99608, 0.98824}, {1.00000, 1.00000, 0.99608}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("real.lasc", real_lasc); static RGBColor redlut_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00392, 0.00000, 0.00000}, {0.00784, 0.00000, 0.00000}, {0.01176, 0.00000, 0.00000}, {0.01569, 0.00000, 0.00000}, {0.01961, 0.00000, 0.00000}, {0.02353, 0.00000, 0.00000}, {0.02745, 0.00000, 0.00000}, {0.03137, 0.00000, 0.00000}, {0.03529, 0.00000, 0.00000}, {0.03922, 0.00000, 0.00000}, {0.04314, 0.00000, 0.00000}, {0.04706, 0.00000, 0.00000}, {0.05098, 0.00001, 0.00001}, {0.05490, 0.00001, 0.00001}, {0.05882, 0.00001, 0.00001}, {0.06275, 0.00002, 0.00002}, {0.06667, 0.00002, 0.00002}, {0.07059, 0.00002, 0.00002}, {0.07451, 0.00003, 0.00003}, {0.07843, 0.00004, 0.00004}, {0.08235, 0.00005, 0.00005}, {0.08627, 0.00006, 0.00006}, {0.09020, 0.00007, 0.00007}, {0.09412, 0.00008, 0.00008}, {0.09804, 0.00009, 0.00009}, {0.10196, 0.00011, 0.00011}, {0.10588, 0.00013, 0.00013}, {0.10980, 0.00015, 0.00015}, {0.11373, 0.00017, 0.00017}, {0.11765, 0.00019, 0.00019}, {0.12157, 0.00022, 0.00022}, {0.12549, 0.00025, 0.00025}, {0.12941, 0.00028, 0.00028}, {0.13333, 0.00032, 0.00032}, {0.13725, 0.00035, 0.00035}, {0.14118, 0.00040, 0.00040}, {0.14510, 0.00044, 0.00044}, {0.14902, 0.00049, 0.00049}, {0.15294, 0.00055, 0.00055}, {0.15686, 0.00061, 0.00061}, {0.16078, 0.00067, 0.00067}, {0.16471, 0.00074, 0.00074}, {0.16863, 0.00081, 0.00081}, {0.17255, 0.00089, 0.00089}, {0.17647, 0.00097, 0.00097}, {0.18039, 0.00106, 0.00106}, {0.18431, 0.00115, 0.00115}, {0.18824, 0.00126, 0.00126}, {0.19216, 0.00136, 0.00136}, {0.19608, 0.00148, 0.00148}, {0.20000, 0.00160, 0.00160}, {0.20392, 0.00173, 0.00173}, {0.20784, 0.00187, 0.00187}, {0.21176, 0.00201, 0.00201}, {0.21569, 0.00216, 0.00216}, {0.21961, 0.00233, 0.00233}, {0.22353, 0.00250, 0.00250}, {0.22745, 0.00268, 0.00268}, {0.23137, 0.00287, 0.00287}, {0.23529, 0.00307, 0.00307}, {0.23922, 0.00327, 0.00327}, {0.24314, 0.00349, 0.00349}, {0.24706, 0.00373, 0.00373}, {0.25098, 0.00397, 0.00397}, {0.25490, 0.00422, 0.00422}, {0.25882, 0.00449, 0.00449}, {0.26275, 0.00477, 0.00477}, {0.26667, 0.00506, 0.00506}, {0.27059, 0.00536, 0.00536}, {0.27451, 0.00568, 0.00568}, {0.27843, 0.00601, 0.00601}, {0.28235, 0.00636, 0.00636}, {0.28627, 0.00672, 0.00672}, {0.29020, 0.00709, 0.00709}, {0.29412, 0.00748, 0.00748}, {0.29804, 0.00789, 0.00789}, {0.30196, 0.00831, 0.00831}, {0.30588, 0.00875, 0.00875}, {0.30980, 0.00921, 0.00921}, {0.31373, 0.00969, 0.00969}, {0.31765, 0.01018, 0.01018}, {0.32157, 0.01069, 0.01069}, {0.32549, 0.01122, 0.01122}, {0.32941, 0.01177, 0.01177}, {0.33333, 0.01235, 0.01235}, {0.33725, 0.01294, 0.01294}, {0.34118, 0.01355, 0.01355}, {0.34510, 0.01418, 0.01418}, {0.34902, 0.01484, 0.01484}, {0.35294, 0.01552, 0.01552}, {0.35686, 0.01622, 0.01622}, {0.36078, 0.01694, 0.01694}, {0.36471, 0.01769, 0.01769}, {0.36863, 0.01847, 0.01847}, {0.37255, 0.01926, 0.01926}, {0.37647, 0.02009, 0.02009}, {0.38039, 0.02094, 0.02094}, {0.38431, 0.02181, 0.02181}, {0.38824, 0.02272, 0.02272}, {0.39216, 0.02365, 0.02365}, {0.39608, 0.02461, 0.02461}, {0.40000, 0.02560, 0.02560}, {0.40392, 0.02662, 0.02662}, {0.40784, 0.02767, 0.02767}, {0.41176, 0.02875, 0.02875}, {0.41569, 0.02986, 0.02986}, {0.41961, 0.03100, 0.03100}, {0.42353, 0.03218, 0.03218}, {0.42745, 0.03338, 0.03338}, {0.43137, 0.03463, 0.03463}, {0.43529, 0.03590, 0.03590}, {0.43922, 0.03721, 0.03721}, {0.44314, 0.03856, 0.03856}, {0.44706, 0.03994, 0.03994}, {0.45098, 0.04136, 0.04136}, {0.45490, 0.04282, 0.04282}, {0.45882, 0.04432, 0.04432}, {0.46275, 0.04585, 0.04585}, {0.46667, 0.04743, 0.04743}, {0.47059, 0.04904, 0.04904}, {0.47451, 0.05070, 0.05070}, {0.47843, 0.05239, 0.05239}, {0.48235, 0.05413, 0.05413}, {0.48627, 0.05591, 0.05591}, {0.49020, 0.05774, 0.05774}, {0.49412, 0.05961, 0.05961}, {0.49804, 0.06153, 0.06153}, {0.50196, 0.06349, 0.06349}, {0.50588, 0.06549, 0.06549}, {0.50980, 0.06755, 0.06755}, {0.51373, 0.06965, 0.06965}, {0.51765, 0.07180, 0.07180}, {0.52157, 0.07400, 0.07400}, {0.52549, 0.07625, 0.07625}, {0.52941, 0.07856, 0.07856}, {0.53333, 0.08091, 0.08091}, {0.53725, 0.08331, 0.08331}, {0.54118, 0.08577, 0.08577}, {0.54510, 0.08829, 0.08829}, {0.54902, 0.09086, 0.09086}, {0.55294, 0.09348, 0.09348}, {0.55686, 0.09616, 0.09616}, {0.56078, 0.09890, 0.09890}, {0.56471, 0.10169, 0.10169}, {0.56863, 0.10455, 0.10455}, {0.57255, 0.10746, 0.10746}, {0.57647, 0.11044, 0.11044}, {0.58039, 0.11347, 0.11347}, {0.58431, 0.11657, 0.11657}, {0.58824, 0.11973, 0.11973}, {0.59216, 0.12296, 0.12296}, {0.59608, 0.12624, 0.12624}, {0.60000, 0.12960, 0.12960}, {0.60392, 0.13302, 0.13302}, {0.60784, 0.13651, 0.13651}, {0.61176, 0.14007, 0.14007}, {0.61569, 0.14369, 0.14369}, {0.61961, 0.14739, 0.14739}, {0.62353, 0.15116, 0.15116}, {0.62745, 0.15500, 0.15500}, {0.63137, 0.15891, 0.15891}, {0.63529, 0.16289, 0.16289}, {0.63922, 0.16695, 0.16695}, {0.64314, 0.17109, 0.17109}, {0.64706, 0.17530, 0.17530}, {0.65098, 0.17959, 0.17959}, {0.65490, 0.18395, 0.18395}, {0.65882, 0.18840, 0.18840}, {0.66275, 0.19292, 0.19292}, {0.66667, 0.19753, 0.19753}, {0.67059, 0.20222, 0.20222}, {0.67451, 0.20699, 0.20699}, {0.67843, 0.21185, 0.21185}, {0.68235, 0.21679, 0.21679}, {0.68627, 0.22182, 0.22182}, {0.69020, 0.22693, 0.22693}, {0.69412, 0.23213, 0.23213}, {0.69804, 0.23742, 0.23742}, {0.70196, 0.24280, 0.24280}, {0.70588, 0.24827, 0.24827}, {0.70980, 0.25384, 0.25384}, {0.71373, 0.25949, 0.25949}, {0.71765, 0.26524, 0.26524}, {0.72157, 0.27109, 0.27109}, {0.72549, 0.27703, 0.27703}, {0.72941, 0.28307, 0.28307}, {0.73333, 0.28920, 0.28920}, {0.73725, 0.29544, 0.29544}, {0.74118, 0.30178, 0.30178}, {0.74510, 0.30821, 0.30821}, {0.74902, 0.31476, 0.31476}, {0.75294, 0.32140, 0.32140}, {0.75686, 0.32815, 0.32815}, {0.76078, 0.33500, 0.33500}, {0.76471, 0.34196, 0.34196}, {0.76863, 0.34903, 0.34903}, {0.77255, 0.35621, 0.35621}, {0.77647, 0.36350, 0.36350}, {0.78039, 0.37090, 0.37090}, {0.78431, 0.37841, 0.37841}, {0.78824, 0.38603, 0.38603}, {0.79216, 0.39377, 0.39377}, {0.79608, 0.40163, 0.40163}, {0.80000, 0.40960, 0.40960}, {0.80392, 0.41769, 0.41769}, {0.80784, 0.42590, 0.42590}, {0.81176, 0.43423, 0.43423}, {0.81569, 0.44268, 0.44268}, {0.81961, 0.45126, 0.45126}, {0.82353, 0.45996, 0.45996}, {0.82745, 0.46878, 0.46878}, {0.83137, 0.47773, 0.47773}, {0.83529, 0.48681, 0.48681}, {0.83922, 0.49601, 0.49601}, {0.84314, 0.50535, 0.50535}, {0.84706, 0.51482, 0.51482}, {0.85098, 0.52442, 0.52442}, {0.85490, 0.53415, 0.53415}, {0.85882, 0.54402, 0.54402}, {0.86275, 0.55403, 0.55403}, {0.86667, 0.56417, 0.56417}, {0.87059, 0.57445, 0.57445}, {0.87451, 0.58487, 0.58487}, {0.87843, 0.59543, 0.59543}, {0.88235, 0.60613, 0.60613}, {0.88627, 0.61698, 0.61698}, {0.89020, 0.62798, 0.62798}, {0.89412, 0.63911, 0.63911}, {0.89804, 0.65040, 0.65040}, {0.90196, 0.66184, 0.66184}, {0.90588, 0.67342, 0.67342}, {0.90980, 0.68516, 0.68516}, {0.91373, 0.69705, 0.69705}, {0.91765, 0.70909, 0.70909}, {0.92157, 0.72129, 0.72129}, {0.92549, 0.73365, 0.73365}, {0.92941, 0.74616, 0.74616}, {0.93333, 0.75883, 0.75883}, {0.93725, 0.77167, 0.77167}, {0.94118, 0.78466, 0.78466}, {0.94510, 0.79782, 0.79782}, {0.94902, 0.81115, 0.81115}, {0.95294, 0.82464, 0.82464}, {0.95686, 0.83830, 0.83830}, {0.96078, 0.85213, 0.85213}, {0.96471, 0.86612, 0.86612}, {0.96863, 0.88029, 0.88029}, {0.97255, 0.89464, 0.89464}, {0.97647, 0.90915, 0.90915}, {0.98039, 0.92385, 0.92385}, {0.98431, 0.93872, 0.93872}, {0.98824, 0.95377, 0.95377}, {0.99216, 0.96899, 0.96899}, {0.99608, 0.98441, 0.98441}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("redlut.lasc", redlut_lasc); static RGBColor rainbow_lasc[] = { {0.00000, 0.00000, 0.16471}, {0.02745, 0.00000, 0.18431}, {0.05882, 0.00000, 0.20000}, {0.08627, 0.00000, 0.21961}, {0.11373, 0.00000, 0.23922}, {0.14510, 0.00000, 0.25882}, {0.17647, 0.00000, 0.27843}, {0.20392, 0.00000, 0.29804}, {0.23137, 0.00000, 0.31765}, {0.26275, 0.00000, 0.33725}, {0.29412, 0.00000, 0.35686}, {0.32157, 0.00000, 0.37647}, {0.35294, 0.00000, 0.39608}, {0.38039, 0.00000, 0.41569}, {0.41176, 0.00000, 0.43529}, {0.43922, 0.00000, 0.45490}, {0.47059, 0.00000, 0.47451}, {0.49804, 0.00000, 0.49412}, {0.52941, 0.00000, 0.51373}, {0.55686, 0.00000, 0.53725}, {0.58824, 0.00000, 0.55686}, {0.55686, 0.00000, 0.57647}, {0.52941, 0.00000, 0.59608}, {0.49804, 0.00000, 0.61569}, {0.47059, 0.00000, 0.63922}, {0.43922, 0.00000, 0.65882}, {0.41176, 0.00000, 0.67843}, {0.38039, 0.00000, 0.70196}, {0.35294, 0.00000, 0.72157}, {0.32157, 0.00000, 0.74118}, {0.29412, 0.00000, 0.76471}, {0.26275, 0.00000, 0.78431}, {0.23137, 0.00000, 0.80392}, {0.20392, 0.00000, 0.82745}, {0.17647, 0.00000, 0.84706}, {0.14510, 0.00000, 0.87059}, {0.11373, 0.00000, 0.89020}, {0.08627, 0.00000, 0.91373}, {0.05882, 0.00000, 0.93333}, {0.02745, 0.00000, 0.95686}, {0.00000, 0.00000, 0.97647}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.02353, 0.97647}, {0.00000, 0.04706, 0.95686}, {0.00000, 0.06275, 0.93333}, {0.00000, 0.08235, 0.91373}, {0.00000, 0.09804, 0.89020}, {0.00000, 0.11373, 0.87059}, {0.00000, 0.12941, 0.84706}, {0.00000, 0.14118, 0.82745}, {0.00000, 0.15686, 0.80392}, {0.00000, 0.16863, 0.78431}, {0.00000, 0.18431, 0.76471}, {0.00000, 0.19608, 0.74118}, {0.00000, 0.21176, 0.72157}, {0.00000, 0.22353, 0.70196}, {0.00000, 0.23529, 0.67843}, {0.00000, 0.25098, 0.65882}, {0.00000, 0.26275, 0.63922}, {0.00000, 0.27451, 0.61569}, {0.00000, 0.28627, 0.59608}, {0.00000, 0.29804, 0.57647}, {0.00000, 0.30980, 0.55686}, {0.00000, 0.32157, 0.53725}, {0.00000, 0.33333, 0.51373}, {0.00000, 0.34510, 0.49412}, {0.00000, 0.35686, 0.47451}, {0.00000, 0.36863, 0.45490}, {0.00000, 0.38039, 0.43529}, {0.00000, 0.39216, 0.41569}, {0.00000, 0.40392, 0.39608}, {0.00000, 0.41176, 0.37647}, {0.00000, 0.42353, 0.35686}, {0.00000, 0.43529, 0.33725}, {0.00000, 0.44706, 0.31765}, {0.00000, 0.45882, 0.29804}, {0.00000, 0.46667, 0.27843}, {0.00000, 0.47843, 0.25882}, {0.00000, 0.49020, 0.23922}, {0.00000, 0.49804, 0.21961}, {0.00000, 0.50980, 0.20000}, {0.00000, 0.52157, 0.18431}, {0.00000, 0.52941, 0.16471}, {0.00000, 0.54118, 0.14510}, {0.00000, 0.55294, 0.12941}, {0.00000, 0.56078, 0.10980}, {0.00000, 0.57255, 0.09412}, {0.00000, 0.58431, 0.07451}, {0.00000, 0.59216, 0.05882}, {0.00000, 0.60392, 0.04314}, {0.00000, 0.61176, 0.02745}, {0.00000, 0.62353, 0.01176}, {0.00000, 0.63137, 0.00000}, {0.00000, 0.64314, 0.00000}, {0.00000, 0.65098, 0.00000}, {0.00000, 0.66275, 0.00000}, {0.00000, 0.67059, 0.00000}, {0.00000, 0.68235, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.70196, 0.00000}, {0.00000, 0.70980, 0.00000}, {0.00000, 0.72157, 0.00000}, {0.00000, 0.72941, 0.00000}, {0.00000, 0.74118, 0.00000}, {0.00000, 0.74902, 0.00000}, {0.00000, 0.76078, 0.00000}, {0.00000, 0.76863, 0.00000}, {0.00000, 0.77647, 0.00000}, {0.00000, 0.78824, 0.00000}, {0.00000, 0.79608, 0.00000}, {0.00000, 0.80784, 0.00000}, {0.00000, 0.81569, 0.00000}, {0.00000, 0.82353, 0.00000}, {0.00000, 0.83529, 0.00000}, {0.00000, 0.84314, 0.00000}, {0.00000, 0.85490, 0.00000}, {0.00000, 0.86275, 0.00000}, {0.00000, 0.87059, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.89020, 0.00000}, {0.00000, 0.89804, 0.00000}, {0.00000, 0.90980, 0.00000}, {0.00000, 0.91765, 0.00000}, {0.00000, 0.92549, 0.00000}, {0.00000, 0.93725, 0.00000}, {0.00000, 0.94510, 0.00000}, {0.00000, 0.95294, 0.00000}, {0.00000, 0.96078, 0.00000}, {0.00000, 0.97255, 0.00000}, {0.00000, 0.98039, 0.00000}, {0.00000, 0.98824, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 0.98824, 0.00000}, {0.00000, 0.98039, 0.00000}, {0.00000, 0.97255, 0.00000}, {0.00000, 0.96078, 0.00000}, {0.00000, 0.95294, 0.00000}, {0.00000, 0.94510, 0.00000}, {0.00000, 0.93725, 0.00000}, {0.00000, 0.92549, 0.00000}, {0.00000, 0.91765, 0.00000}, {0.00000, 0.90980, 0.00000}, {0.00000, 0.89804, 0.00000}, {0.00000, 0.89020, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.87059, 0.00000}, {0.00000, 0.86275, 0.00000}, {0.00000, 0.85490, 0.00000}, {0.00000, 0.84314, 0.00000}, {0.00000, 0.83529, 0.00000}, {0.00000, 0.82353, 0.00000}, {0.00000, 0.81569, 0.00000}, {0.00000, 0.80784, 0.00000}, {0.00000, 0.79608, 0.00000}, {0.00000, 0.78824, 0.00000}, {0.00000, 0.77647, 0.00000}, {0.00784, 0.76863, 0.00000}, {0.03529, 0.77647, 0.00000}, {0.06667, 0.78824, 0.00000}, {0.09804, 0.80000, 0.00000}, {0.12941, 0.81176, 0.00000}, {0.16471, 0.82745, 0.00000}, {0.20000, 0.84314, 0.00000}, {0.23529, 0.85882, 0.00000}, {0.26667, 0.87059, 0.00000}, {0.30588, 0.89020, 0.00000}, {0.34118, 0.90196, 0.00000}, {0.37647, 0.92157, 0.00000}, {0.41176, 0.93333, 0.00000}, {0.44706, 0.95294, 0.00000}, {0.48627, 0.96863, 0.00000}, {0.52157, 0.98824, 0.00000}, {0.56078, 1.00000, 0.00000}, {0.59608, 1.00000, 0.00000}, {0.63529, 1.00000, 0.00000}, {0.67059, 1.00000, 0.00000}, {0.70980, 1.00000, 0.00000}, {0.74902, 1.00000, 0.00000}, {0.78431, 1.00000, 0.00000}, {0.82353, 1.00000, 0.00000}, {0.85882, 1.00000, 0.00000}, {0.89804, 1.00000, 0.00000}, {0.93333, 1.00000, 0.00000}, {0.97647, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {0.99608, 1.00000, 0.00000}, {0.98039, 1.00000, 0.00000}, {0.96078, 0.97647, 0.00000}, {0.94510, 0.93725, 0.00000}, {0.92549, 0.89804, 0.00000}, {0.90980, 0.85882, 0.00000}, {0.89412, 0.81961, 0.00000}, {0.87451, 0.78039, 0.00000}, {0.85882, 0.74118, 0.00000}, {0.83922, 0.70196, 0.00000}, {0.82353, 0.66275, 0.00000}, {0.80392, 0.62353, 0.00000}, {0.78824, 0.58431, 0.00000}, {0.76863, 0.54510, 0.00000}, {0.75686, 0.50980, 0.00000}, {0.74118, 0.46667, 0.00000}, {0.72549, 0.43137, 0.00000}, {0.70980, 0.39216, 0.00000}, {0.69412, 0.35294, 0.00000}, {0.68235, 0.31765, 0.00000}, {0.66275, 0.27451, 0.00000}, {0.65098, 0.23922, 0.00000}, {0.63529, 0.20000, 0.00000}, {0.62745, 0.16863, 0.00000}, {0.61569, 0.12941, 0.00000}, {0.60784, 0.09804, 0.00000}, {0.61961, 0.08235, 0.00000}, {0.62745, 0.06275, 0.00000}, {0.63922, 0.04706, 0.00000}, {0.64706, 0.02353, 0.00000}, {0.65882, 0.00000, 0.00000}, {0.66667, 0.00000, 0.00000}, {0.67843, 0.00000, 0.00000}, {0.68627, 0.00000, 0.00000}, {0.69804, 0.00000, 0.00000}, {0.70980, 0.00000, 0.00000}, {0.71765, 0.00000, 0.00000}, {0.72941, 0.00000, 0.00000}, {0.73725, 0.00000, 0.00000}, {0.74902, 0.00000, 0.00000}, {0.75686, 0.00000, 0.00000}, {0.76863, 0.00000, 0.00000}, {0.77647, 0.00000, 0.00000}, {0.78824, 0.00000, 0.00000}, {0.80000, 0.00784, 0.00784}, {0.80784, 0.02745, 0.02745}, {0.81961, 0.05098, 0.05098}, {0.82745, 0.08235, 0.08235}, {0.83922, 0.11373, 0.11373}, {0.84706, 0.14902, 0.14902}, {0.85882, 0.19216, 0.19216}, {0.86667, 0.23137, 0.23137}, {0.87843, 0.27843, 0.27843}, {0.88627, 0.32549, 0.32549}, {0.89804, 0.37647, 0.37647}, {0.90980, 0.43137, 0.43137}, {0.91765, 0.48627, 0.48627}, {0.92941, 0.54118, 0.54118}, {0.93725, 0.60000, 0.60000}, {0.94902, 0.66275, 0.66275}, {0.95686, 0.72549, 0.72549}, {0.96863, 0.79216, 0.79216}, {0.97647, 0.85882, 0.85882}, {0.98824, 0.92941, 0.92941}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("rainbow.lasc", rainbow_lasc); static RGBColor greenlut_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00000, 0.00392, 0.00000}, {0.00000, 0.00784, 0.00000}, {0.00000, 0.01176, 0.00000}, {0.00000, 0.01569, 0.00000}, {0.00000, 0.01961, 0.00000}, {0.00000, 0.02353, 0.00000}, {0.00000, 0.02745, 0.00000}, {0.00000, 0.03137, 0.00000}, {0.00000, 0.03529, 0.00000}, {0.00000, 0.03922, 0.00000}, {0.00000, 0.04314, 0.00000}, {0.00000, 0.04706, 0.00000}, {0.00001, 0.05098, 0.00001}, {0.00001, 0.05490, 0.00001}, {0.00001, 0.05882, 0.00001}, {0.00002, 0.06275, 0.00002}, {0.00002, 0.06667, 0.00002}, {0.00002, 0.07059, 0.00002}, {0.00003, 0.07451, 0.00003}, {0.00004, 0.07843, 0.00004}, {0.00005, 0.08235, 0.00005}, {0.00006, 0.08627, 0.00006}, {0.00007, 0.09020, 0.00007}, {0.00008, 0.09412, 0.00008}, {0.00009, 0.09804, 0.00009}, {0.00011, 0.10196, 0.00011}, {0.00013, 0.10588, 0.00013}, {0.00015, 0.10980, 0.00015}, {0.00017, 0.11373, 0.00017}, {0.00019, 0.11765, 0.00019}, {0.00022, 0.12157, 0.00022}, {0.00025, 0.12549, 0.00025}, {0.00028, 0.12941, 0.00028}, {0.00032, 0.13333, 0.00032}, {0.00035, 0.13725, 0.00035}, {0.00040, 0.14118, 0.00040}, {0.00044, 0.14510, 0.00044}, {0.00049, 0.14902, 0.00049}, {0.00055, 0.15294, 0.00055}, {0.00061, 0.15686, 0.00061}, {0.00067, 0.16078, 0.00067}, {0.00074, 0.16471, 0.00074}, {0.00081, 0.16863, 0.00081}, {0.00089, 0.17255, 0.00089}, {0.00097, 0.17647, 0.00097}, {0.00106, 0.18039, 0.00106}, {0.00115, 0.18431, 0.00115}, {0.00126, 0.18824, 0.00126}, {0.00136, 0.19216, 0.00136}, {0.00148, 0.19608, 0.00148}, {0.00160, 0.20000, 0.00160}, {0.00173, 0.20392, 0.00173}, {0.00187, 0.20784, 0.00187}, {0.00201, 0.21176, 0.00201}, {0.00216, 0.21569, 0.00216}, {0.00233, 0.21961, 0.00233}, {0.00250, 0.22353, 0.00250}, {0.00268, 0.22745, 0.00268}, {0.00287, 0.23137, 0.00287}, {0.00307, 0.23529, 0.00307}, {0.00327, 0.23922, 0.00327}, {0.00349, 0.24314, 0.00349}, {0.00373, 0.24706, 0.00373}, {0.00397, 0.25098, 0.00397}, {0.00422, 0.25490, 0.00422}, {0.00449, 0.25882, 0.00449}, {0.00477, 0.26275, 0.00477}, {0.00506, 0.26667, 0.00506}, {0.00536, 0.27059, 0.00536}, {0.00568, 0.27451, 0.00568}, {0.00601, 0.27843, 0.00601}, {0.00636, 0.28235, 0.00636}, {0.00672, 0.28627, 0.00672}, {0.00709, 0.29020, 0.00709}, {0.00748, 0.29412, 0.00748}, {0.00789, 0.29804, 0.00789}, {0.00831, 0.30196, 0.00831}, {0.00875, 0.30588, 0.00875}, {0.00921, 0.30980, 0.00921}, {0.00969, 0.31373, 0.00969}, {0.01018, 0.31765, 0.01018}, {0.01069, 0.32157, 0.01069}, {0.01122, 0.32549, 0.01122}, {0.01177, 0.32941, 0.01177}, {0.01235, 0.33333, 0.01235}, {0.01294, 0.33725, 0.01294}, {0.01355, 0.34118, 0.01355}, {0.01418, 0.34510, 0.01418}, {0.01484, 0.34902, 0.01484}, {0.01552, 0.35294, 0.01552}, {0.01622, 0.35686, 0.01622}, {0.01694, 0.36078, 0.01694}, {0.01769, 0.36471, 0.01769}, {0.01847, 0.36863, 0.01847}, {0.01926, 0.37255, 0.01926}, {0.02009, 0.37647, 0.02009}, {0.02094, 0.38039, 0.02094}, {0.02181, 0.38431, 0.02181}, {0.02272, 0.38824, 0.02272}, {0.02365, 0.39216, 0.02365}, {0.02461, 0.39608, 0.02461}, {0.02560, 0.40000, 0.02560}, {0.02662, 0.40392, 0.02662}, {0.02767, 0.40784, 0.02767}, {0.02875, 0.41176, 0.02875}, {0.02986, 0.41569, 0.02986}, {0.03100, 0.41961, 0.03100}, {0.03218, 0.42353, 0.03218}, {0.03338, 0.42745, 0.03338}, {0.03463, 0.43137, 0.03463}, {0.03590, 0.43529, 0.03590}, {0.03721, 0.43922, 0.03721}, {0.03856, 0.44314, 0.03856}, {0.03994, 0.44706, 0.03994}, {0.04136, 0.45098, 0.04136}, {0.04282, 0.45490, 0.04282}, {0.04432, 0.45882, 0.04432}, {0.04585, 0.46275, 0.04585}, {0.04743, 0.46667, 0.04743}, {0.04904, 0.47059, 0.04904}, {0.05070, 0.47451, 0.05070}, {0.05239, 0.47843, 0.05239}, {0.05413, 0.48235, 0.05413}, {0.05591, 0.48627, 0.05591}, {0.05774, 0.49020, 0.05774}, {0.05961, 0.49412, 0.05961}, {0.06153, 0.49804, 0.06153}, {0.06349, 0.50196, 0.06349}, {0.06549, 0.50588, 0.06549}, {0.06755, 0.50980, 0.06755}, {0.06965, 0.51373, 0.06965}, {0.07180, 0.51765, 0.07180}, {0.07400, 0.52157, 0.07400}, {0.07625, 0.52549, 0.07625}, {0.07856, 0.52941, 0.07856}, {0.08091, 0.53333, 0.08091}, {0.08331, 0.53725, 0.08331}, {0.08577, 0.54118, 0.08577}, {0.08829, 0.54510, 0.08829}, {0.09086, 0.54902, 0.09086}, {0.09348, 0.55294, 0.09348}, {0.09616, 0.55686, 0.09616}, {0.09890, 0.56078, 0.09890}, {0.10169, 0.56471, 0.10169}, {0.10455, 0.56863, 0.10455}, {0.10746, 0.57255, 0.10746}, {0.11044, 0.57647, 0.11044}, {0.11347, 0.58039, 0.11347}, {0.11657, 0.58431, 0.11657}, {0.11973, 0.58824, 0.11973}, {0.12296, 0.59216, 0.12296}, {0.12624, 0.59608, 0.12624}, {0.12960, 0.60000, 0.12960}, {0.13302, 0.60392, 0.13302}, {0.13651, 0.60784, 0.13651}, {0.14007, 0.61176, 0.14007}, {0.14369, 0.61569, 0.14369}, {0.14739, 0.61961, 0.14739}, {0.15116, 0.62353, 0.15116}, {0.15500, 0.62745, 0.15500}, {0.15891, 0.63137, 0.15891}, {0.16289, 0.63529, 0.16289}, {0.16695, 0.63922, 0.16695}, {0.17109, 0.64314, 0.17109}, {0.17530, 0.64706, 0.17530}, {0.17959, 0.65098, 0.17959}, {0.18395, 0.65490, 0.18395}, {0.18840, 0.65882, 0.18840}, {0.19292, 0.66275, 0.19292}, {0.19753, 0.66667, 0.19753}, {0.20222, 0.67059, 0.20222}, {0.20699, 0.67451, 0.20699}, {0.21185, 0.67843, 0.21185}, {0.21679, 0.68235, 0.21679}, {0.22182, 0.68627, 0.22182}, {0.22693, 0.69020, 0.22693}, {0.23213, 0.69412, 0.23213}, {0.23742, 0.69804, 0.23742}, {0.24280, 0.70196, 0.24280}, {0.24827, 0.70588, 0.24827}, {0.25384, 0.70980, 0.25384}, {0.25949, 0.71373, 0.25949}, {0.26524, 0.71765, 0.26524}, {0.27109, 0.72157, 0.27109}, {0.27703, 0.72549, 0.27703}, {0.28307, 0.72941, 0.28307}, {0.28920, 0.73333, 0.28920}, {0.29544, 0.73725, 0.29544}, {0.30178, 0.74118, 0.30178}, {0.30821, 0.74510, 0.30821}, {0.31476, 0.74902, 0.31476}, {0.32140, 0.75294, 0.32140}, {0.32815, 0.75686, 0.32815}, {0.33500, 0.76078, 0.33500}, {0.34196, 0.76471, 0.34196}, {0.34903, 0.76863, 0.34903}, {0.35621, 0.77255, 0.35621}, {0.36350, 0.77647, 0.36350}, {0.37090, 0.78039, 0.37090}, {0.37841, 0.78431, 0.37841}, {0.38603, 0.78824, 0.38603}, {0.39377, 0.79216, 0.39377}, {0.40163, 0.79608, 0.40163}, {0.40960, 0.80000, 0.40960}, {0.41769, 0.80392, 0.41769}, {0.42590, 0.80784, 0.42590}, {0.43423, 0.81176, 0.43423}, {0.44268, 0.81569, 0.44268}, {0.45126, 0.81961, 0.45126}, {0.45996, 0.82353, 0.45996}, {0.46878, 0.82745, 0.46878}, {0.47773, 0.83137, 0.47773}, {0.48681, 0.83529, 0.48681}, {0.49601, 0.83922, 0.49601}, {0.50535, 0.84314, 0.50535}, {0.51482, 0.84706, 0.51482}, {0.52442, 0.85098, 0.52442}, {0.53415, 0.85490, 0.53415}, {0.54402, 0.85882, 0.54402}, {0.55403, 0.86275, 0.55403}, {0.56417, 0.86667, 0.56417}, {0.57445, 0.87059, 0.57445}, {0.58487, 0.87451, 0.58487}, {0.59543, 0.87843, 0.59543}, {0.60613, 0.88235, 0.60613}, {0.61698, 0.88627, 0.61698}, {0.62798, 0.89020, 0.62798}, {0.63911, 0.89412, 0.63911}, {0.65040, 0.89804, 0.65040}, {0.66184, 0.90196, 0.66184}, {0.67342, 0.90588, 0.67342}, {0.68516, 0.90980, 0.68516}, {0.69705, 0.91373, 0.69705}, {0.70909, 0.91765, 0.70909}, {0.72129, 0.92157, 0.72129}, {0.73365, 0.92549, 0.73365}, {0.74616, 0.92941, 0.74616}, {0.75883, 0.93333, 0.75883}, {0.77167, 0.93725, 0.77167}, {0.78466, 0.94118, 0.78466}, {0.79782, 0.94510, 0.79782}, {0.81115, 0.94902, 0.81115}, {0.82464, 0.95294, 0.82464}, {0.83830, 0.95686, 0.83830}, {0.85213, 0.96078, 0.85213}, {0.86612, 0.96471, 0.86612}, {0.88029, 0.96863, 0.88029}, {0.89464, 0.97255, 0.89464}, {0.90915, 0.97647, 0.90915}, {0.92385, 0.98039, 0.92385}, {0.93872, 0.98431, 0.93872}, {0.95377, 0.98824, 0.95377}, {0.96899, 0.99216, 0.96899}, {0.98441, 0.99608, 0.98441}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("greenlut.lasc", greenlut_lasc); static RGBColor color_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.18431, 0.18431, 0.18431}, {0.18431, 0.18431, 0.18431}, {0.18431, 0.18431, 0.18431}, {0.18431, 0.18431, 0.18431}, {0.18431, 0.18431, 0.18431}, {0.18431, 0.18431, 0.18431}, {0.18431, 0.18431, 0.18431}, {0.18431, 0.18431, 0.18431}, {0.18431, 0.18431, 0.18431}, {0.18431, 0.18431, 0.18431}, {0.18431, 0.18431, 0.18431}, {0.18431, 0.18431, 0.18431}, {0.18431, 0.18431, 0.18431}, {0.18431, 0.18431, 0.18431}, {0.18431, 0.18431, 0.18431}, {0.18431, 0.18431, 0.18431}, {0.37255, 0.37255, 0.37255}, {0.37255, 0.37255, 0.37255}, {0.37255, 0.37255, 0.37255}, {0.37255, 0.37255, 0.37255}, {0.37255, 0.37255, 0.37255}, {0.37255, 0.37255, 0.37255}, {0.37255, 0.37255, 0.37255}, {0.37255, 0.37255, 0.37255}, {0.37255, 0.37255, 0.37255}, {0.37255, 0.37255, 0.37255}, {0.37255, 0.37255, 0.37255}, {0.37255, 0.37255, 0.37255}, {0.37255, 0.37255, 0.37255}, {0.37255, 0.37255, 0.37255}, {0.37255, 0.37255, 0.37255}, {0.37255, 0.37255, 0.37255}, {0.56078, 0.56078, 0.56078}, {0.56078, 0.56078, 0.56078}, {0.56078, 0.56078, 0.56078}, {0.56078, 0.56078, 0.56078}, {0.56078, 0.56078, 0.56078}, {0.56078, 0.56078, 0.56078}, {0.56078, 0.56078, 0.56078}, {0.56078, 0.56078, 0.56078}, {0.56078, 0.56078, 0.56078}, {0.56078, 0.56078, 0.56078}, {0.56078, 0.56078, 0.56078}, {0.56078, 0.56078, 0.56078}, {0.56078, 0.56078, 0.56078}, {0.56078, 0.56078, 0.56078}, {0.56078, 0.56078, 0.56078}, {0.56078, 0.56078, 0.56078}, {0.74902, 0.74902, 0.74902}, {0.74902, 0.74902, 0.74902}, {0.74902, 0.74902, 0.74902}, {0.74902, 0.74902, 0.74902}, {0.74902, 0.74902, 0.74902}, {0.74902, 0.74902, 0.74902}, {0.74902, 0.74902, 0.74902}, {0.74902, 0.74902, 0.74902}, {0.74902, 0.74902, 0.74902}, {0.74902, 0.74902, 0.74902}, {0.74902, 0.74902, 0.74902}, {0.74902, 0.74902, 0.74902}, {0.74902, 0.74902, 0.74902}, {0.74902, 0.74902, 0.74902}, {0.74902, 0.74902, 0.74902}, {0.74902, 0.74902, 0.74902}, {0.93725, 0.93725, 0.93725}, {0.93725, 0.93725, 0.93725}, {0.93725, 0.93725, 0.93725}, {0.93725, 0.93725, 0.93725}, {0.93725, 0.93725, 0.93725}, {0.93725, 0.93725, 0.93725}, {0.93725, 0.93725, 0.93725}, {0.93725, 0.93725, 0.93725}, {0.93725, 0.93725, 0.93725}, {0.93725, 0.93725, 0.93725}, {0.93725, 0.93725, 0.93725}, {0.93725, 0.93725, 0.93725}, {0.93725, 0.93725, 0.93725}, {0.93725, 0.93725, 0.93725}, {0.93725, 0.93725, 0.93725}, {0.93725, 0.93725, 0.93725}, {0.00000, 0.18431, 0.93725}, {0.00000, 0.18431, 0.93725}, {0.00000, 0.18431, 0.93725}, {0.00000, 0.18431, 0.93725}, {0.00000, 0.18431, 0.93725}, {0.00000, 0.18431, 0.93725}, {0.00000, 0.18431, 0.93725}, {0.00000, 0.18431, 0.93725}, {0.00000, 0.18431, 0.93725}, {0.00000, 0.18431, 0.93725}, {0.00000, 0.18431, 0.93725}, {0.00000, 0.18431, 0.93725}, {0.00000, 0.18431, 0.93725}, {0.00000, 0.18431, 0.93725}, {0.00000, 0.18431, 0.93725}, {0.00000, 0.18431, 0.93725}, {0.00000, 0.37255, 0.74902}, {0.00000, 0.37255, 0.74902}, {0.00000, 0.37255, 0.74902}, {0.00000, 0.37255, 0.74902}, {0.00000, 0.37255, 0.74902}, {0.00000, 0.37255, 0.74902}, {0.00000, 0.37255, 0.74902}, {0.00000, 0.37255, 0.74902}, {0.00000, 0.37255, 0.74902}, {0.00000, 0.37255, 0.74902}, {0.00000, 0.37255, 0.74902}, {0.00000, 0.37255, 0.74902}, {0.00000, 0.37255, 0.74902}, {0.00000, 0.37255, 0.74902}, {0.00000, 0.37255, 0.74902}, {0.00000, 0.37255, 0.74902}, {0.00000, 0.49804, 0.49804}, {0.00000, 0.49804, 0.49804}, {0.00000, 0.49804, 0.49804}, {0.00000, 0.49804, 0.49804}, {0.00000, 0.49804, 0.49804}, {0.00000, 0.49804, 0.49804}, {0.00000, 0.49804, 0.49804}, {0.00000, 0.49804, 0.49804}, {0.00000, 0.49804, 0.49804}, {0.00000, 0.49804, 0.49804}, {0.00000, 0.49804, 0.49804}, {0.00000, 0.49804, 0.49804}, {0.00000, 0.49804, 0.49804}, {0.00000, 0.49804, 0.49804}, {0.00000, 0.49804, 0.49804}, {0.00000, 0.49804, 0.49804}, {0.00000, 0.74902, 0.30980}, {0.00000, 0.74902, 0.30980}, {0.00000, 0.74902, 0.30980}, {0.00000, 0.74902, 0.30980}, {0.00000, 0.74902, 0.30980}, {0.00000, 0.74902, 0.30980}, {0.00000, 0.74902, 0.30980}, {0.00000, 0.74902, 0.30980}, {0.00000, 0.74902, 0.30980}, {0.00000, 0.74902, 0.30980}, {0.00000, 0.74902, 0.30980}, {0.00000, 0.74902, 0.30980}, {0.00000, 0.74902, 0.30980}, {0.00000, 0.74902, 0.30980}, {0.00000, 0.74902, 0.30980}, {0.00000, 0.74902, 0.30980}, {0.00000, 0.93725, 0.00000}, {0.00000, 0.93725, 0.00000}, {0.00000, 0.93725, 0.00000}, {0.00000, 0.93725, 0.00000}, {0.00000, 0.93725, 0.00000}, {0.00000, 0.93725, 0.00000}, {0.00000, 0.93725, 0.00000}, {0.00000, 0.93725, 0.00000}, {0.00000, 0.93725, 0.00000}, {0.00000, 0.93725, 0.00000}, {0.00000, 0.93725, 0.00000}, {0.00000, 0.93725, 0.00000}, {0.00000, 0.93725, 0.00000}, {0.00000, 0.93725, 0.00000}, {0.00000, 0.93725, 0.00000}, {0.00000, 0.93725, 0.00000}, {0.30980, 0.62353, 0.00000}, {0.30980, 0.62353, 0.00000}, {0.30980, 0.62353, 0.00000}, {0.30980, 0.62353, 0.00000}, {0.30980, 0.62353, 0.00000}, {0.30980, 0.62353, 0.00000}, {0.30980, 0.62353, 0.00000}, {0.30980, 0.62353, 0.00000}, {0.30980, 0.62353, 0.00000}, {0.30980, 0.62353, 0.00000}, {0.30980, 0.62353, 0.00000}, {0.30980, 0.62353, 0.00000}, {0.30980, 0.62353, 0.00000}, {0.30980, 0.62353, 0.00000}, {0.30980, 0.62353, 0.00000}, {0.30980, 0.62353, 0.00000}, {0.49804, 0.49804, 0.00000}, {0.49804, 0.49804, 0.00000}, {0.49804, 0.49804, 0.00000}, {0.49804, 0.49804, 0.00000}, {0.49804, 0.49804, 0.00000}, {0.49804, 0.49804, 0.00000}, {0.49804, 0.49804, 0.00000}, {0.49804, 0.49804, 0.00000}, {0.49804, 0.49804, 0.00000}, {0.49804, 0.49804, 0.00000}, {0.49804, 0.49804, 0.00000}, {0.49804, 0.49804, 0.00000}, {0.49804, 0.49804, 0.00000}, {0.49804, 0.49804, 0.00000}, {0.49804, 0.49804, 0.00000}, {0.49804, 0.49804, 0.00000}, {0.62353, 0.30980, 0.00000}, {0.62353, 0.30980, 0.00000}, {0.62353, 0.30980, 0.00000}, {0.62353, 0.30980, 0.00000}, {0.62353, 0.30980, 0.00000}, {0.62353, 0.30980, 0.00000}, {0.62353, 0.30980, 0.00000}, {0.62353, 0.30980, 0.00000}, {0.62353, 0.30980, 0.00000}, {0.62353, 0.30980, 0.00000}, {0.62353, 0.30980, 0.00000}, {0.62353, 0.30980, 0.00000}, {0.62353, 0.30980, 0.00000}, {0.62353, 0.30980, 0.00000}, {0.62353, 0.30980, 0.00000}, {0.62353, 0.30980, 0.00000}, {0.93725, 0.00000, 0.00000}, {0.93725, 0.00000, 0.00000}, {0.93725, 0.00000, 0.00000}, {0.93725, 0.00000, 0.00000}, {0.93725, 0.00000, 0.00000}, {0.93725, 0.00000, 0.00000}, {0.93725, 0.00000, 0.00000}, {0.93725, 0.00000, 0.00000}, {0.93725, 0.00000, 0.00000}, {0.93725, 0.00000, 0.00000}, {0.93725, 0.00000, 0.00000}, {0.93725, 0.00000, 0.00000}, {0.93725, 0.00000, 0.00000}, {0.93725, 0.00000, 0.00000}, {0.93725, 0.00000, 0.00000}, {0.93725, 0.00000, 0.00000}, {0.74902, 0.00000, 0.30980}, {0.74902, 0.00000, 0.30980}, {0.74902, 0.00000, 0.30980}, {0.74902, 0.00000, 0.30980}, {0.74902, 0.00000, 0.30980}, {0.74902, 0.00000, 0.30980}, {0.74902, 0.00000, 0.30980}, {0.74902, 0.00000, 0.30980}, {0.74902, 0.00000, 0.30980}, {0.74902, 0.00000, 0.30980}, {0.74902, 0.00000, 0.30980}, {0.74902, 0.00000, 0.30980}, {0.74902, 0.00000, 0.30980}, {0.74902, 0.00000, 0.30980}, {0.74902, 0.00000, 0.30980}, {0.74902, 0.00000, 0.30980}, }; new ColorMapInfo("color.lasc", color_lasc); static RGBColor smooth1_lasc[] = { {0.30980, 0.29020, 0.22353}, {0.32157, 0.30196, 0.23922}, {0.33333, 0.31765, 0.25490}, {0.34510, 0.32941, 0.27059}, {0.35686, 0.34510, 0.29020}, {0.36863, 0.36078, 0.30588}, {0.38039, 0.37647, 0.32549}, {0.39216, 0.38824, 0.34510}, {0.40392, 0.40392, 0.36471}, {0.41569, 0.41961, 0.38431}, {0.42745, 0.43529, 0.40392}, {0.43922, 0.45098, 0.42353}, {0.45098, 0.46667, 0.44314}, {0.46275, 0.48235, 0.46667}, {0.47451, 0.49804, 0.48627}, {0.49020, 0.51765, 0.50980}, {0.50196, 0.53333, 0.53333}, {0.51373, 0.54902, 0.55686}, {0.52549, 0.56863, 0.58039}, {0.54118, 0.58431, 0.60392}, {0.55294, 0.60000, 0.62745}, {0.56863, 0.61961, 0.65098}, {0.58039, 0.63529, 0.67843}, {0.59216, 0.65490, 0.70196}, {0.60784, 0.67059, 0.72941}, {0.61961, 0.69020, 0.75686}, {0.63529, 0.70980, 0.78431}, {0.64706, 0.72549, 0.75686}, {0.66275, 0.74510, 0.72941}, {0.67843, 0.76471, 0.70588}, {0.69020, 0.78431, 0.68235}, {0.70588, 0.80392, 0.65882}, {0.71765, 0.82353, 0.64314}, {0.73333, 0.80392, 0.62353}, {0.74902, 0.78824, 0.60392}, {0.76471, 0.77255, 0.58824}, {0.77647, 0.75686, 0.57255}, {0.79216, 0.74118, 0.55686}, {0.80784, 0.73333, 0.54118}, {0.82353, 0.71765, 0.52941}, {0.83922, 0.70588, 0.51373}, {0.85490, 0.69804, 0.50588}, {0.87059, 0.68235, 0.49412}, {0.85490, 0.67451, 0.48627}, {0.83922, 0.66667, 0.47843}, {0.82745, 0.65882, 0.47059}, {0.81569, 0.65098, 0.46275}, {0.80392, 0.63922, 0.45882}, {0.79216, 0.63529, 0.45490}, {0.78431, 0.62745, 0.45098}, {0.77255, 0.61961, 0.44706}, {0.76078, 0.61176, 0.44706}, {0.74902, 0.60784, 0.44706}, {0.74510, 0.60392, 0.44706}, {0.73333, 0.60000, 0.44706}, {0.72941, 0.59608, 0.45098}, {0.71765, 0.59216, 0.45490}, {0.70980, 0.58824, 0.45882}, {0.70588, 0.58824, 0.46275}, {0.69412, 0.58431, 0.47059}, {0.69020, 0.58039, 0.47843}, {0.68235, 0.58039, 0.48627}, {0.67843, 0.58039, 0.49412}, {0.67451, 0.57647, 0.50588}, {0.66667, 0.58039, 0.51373}, {0.66275, 0.57647, 0.52941}, {0.65490, 0.58039, 0.54118}, {0.65098, 0.58039, 0.55686}, {0.64706, 0.58039, 0.57255}, {0.64314, 0.58431, 0.58824}, {0.63529, 0.58824, 0.60392}, {0.63529, 0.58824, 0.62353}, {0.63137, 0.59216, 0.64314}, {0.62745, 0.59608, 0.65882}, {0.62745, 0.60000, 0.68235}, {0.62353, 0.60392, 0.70588}, {0.62353, 0.60784, 0.72941}, {0.61961, 0.61176, 0.75686}, {0.61961, 0.61961, 0.78431}, {0.61569, 0.62745, 0.75686}, {0.61569, 0.63529, 0.72941}, {0.61176, 0.63922, 0.70588}, {0.61176, 0.65098, 0.68235}, {0.61176, 0.65882, 0.65882}, {0.61176, 0.66667, 0.64314}, {0.61176, 0.67451, 0.62353}, {0.61176, 0.68235, 0.60392}, {0.61176, 0.69804, 0.58824}, {0.61176, 0.70588, 0.57255}, {0.61569, 0.71765, 0.55686}, {0.61569, 0.73333, 0.54118}, {0.61961, 0.74118, 0.52941}, {0.61961, 0.75686, 0.51373}, {0.62353, 0.77255, 0.50588}, {0.62353, 0.78824, 0.49412}, {0.62745, 0.80392, 0.48627}, {0.62745, 0.82353, 0.47843}, {0.63137, 0.80392, 0.47059}, {0.63529, 0.78824, 0.46275}, {0.63529, 0.77255, 0.45882}, {0.64314, 0.75686, 0.45490}, {0.64706, 0.74118, 0.45098}, {0.65098, 0.73333, 0.44706}, {0.65490, 0.71765, 0.44706}, {0.66275, 0.70588, 0.44706}, {0.66667, 0.69804, 0.44706}, {0.67451, 0.68235, 0.44706}, {0.67843, 0.67451, 0.45098}, {0.68235, 0.66667, 0.45490}, {0.69020, 0.65882, 0.45882}, {0.69412, 0.65098, 0.46275}, {0.70588, 0.63922, 0.47059}, {0.70980, 0.63529, 0.47843}, {0.71765, 0.62745, 0.48627}, {0.72941, 0.61961, 0.49412}, {0.73333, 0.61176, 0.50588}, {0.74510, 0.60784, 0.51373}, {0.74902, 0.60392, 0.52941}, {0.76078, 0.60000, 0.54118}, {0.77647, 0.59608, 0.55686}, {0.79216, 0.59216, 0.57255}, {0.80392, 0.58824, 0.58824}, {0.81961, 0.58824, 0.60392}, {0.83922, 0.58431, 0.62353}, {0.85490, 0.58039, 0.64314}, {0.87451, 0.58039, 0.65882}, {0.89804, 0.58039, 0.68235}, {0.92157, 0.57647, 0.70588}, {0.91373, 0.58039, 0.72941}, {0.90588, 0.57647, 0.75686}, {0.89804, 0.58039, 0.78431}, {0.89412, 0.58039, 0.75686}, {0.88627, 0.58039, 0.72941}, {0.88235, 0.58431, 0.70588}, {0.87843, 0.58824, 0.68235}, {0.87451, 0.58824, 0.65882}, {0.87059, 0.59216, 0.64314}, {0.86275, 0.59608, 0.62353}, {0.86275, 0.60000, 0.60392}, {0.85882, 0.60392, 0.58824}, {0.85882, 0.60784, 0.57255}, {0.85490, 0.61176, 0.55686}, {0.85098, 0.61961, 0.54118}, {0.85490, 0.62745, 0.52941}, {0.85098, 0.63529, 0.51373}, {0.85098, 0.63922, 0.50588}, {0.85098, 0.65490, 0.49412}, {0.85098, 0.67059, 0.48627}, {0.85490, 0.68235, 0.47843}, {0.85098, 0.69804, 0.47059}, {0.85490, 0.71373, 0.46275}, {0.85098, 0.74118, 0.45882}, {0.85490, 0.75686, 0.45490}, {0.85882, 0.78039, 0.45098}, {0.86275, 0.80392, 0.44706}, {0.86275, 0.82353, 0.44706}, {0.86667, 0.85098, 0.44706}, {0.87059, 0.87843, 0.44706}, {0.87451, 0.90980, 0.44706}, {0.87843, 0.93725, 0.45098}, {0.88235, 0.97255, 0.45490}, {0.88627, 0.96471, 0.45882}, {0.89020, 0.96078, 0.46275}, {0.89804, 0.95686, 0.47059}, {0.90196, 0.95294, 0.47843}, {0.90588, 0.94902, 0.48627}, {0.91373, 0.94902, 0.49412}, {0.91765, 0.94510, 0.50588}, {0.92549, 0.94118, 0.51373}, {0.92941, 0.94510, 0.52941}, {0.94118, 0.94118, 0.54118}, {0.94902, 0.94510, 0.55686}, {0.95294, 0.94510, 0.57255}, {0.96078, 0.94510, 0.58824}, {0.97255, 0.94902, 0.60392}, {0.98039, 0.94902, 0.62745}, {0.98824, 0.95294, 0.65098}, {0.99608, 0.95686, 0.67451}, {1.00000, 0.95686, 0.70588}, {1.00000, 0.96078, 0.73333}, {1.00000, 0.96863, 0.76863}, {1.00000, 0.97255, 0.80392}, {1.00000, 0.98039, 0.84314}, {1.00000, 0.98431, 0.82353}, {0.98824, 0.99216, 0.80784}, {0.96078, 0.99608, 0.79608}, {0.93333, 1.00000, 0.78431}, {0.90980, 1.00000, 0.77255}, {0.88235, 1.00000, 0.76471}, {0.85882, 1.00000, 0.75686}, {0.83137, 1.00000, 0.74902}, {0.80784, 1.00000, 0.74118}, {0.78039, 1.00000, 0.73725}, {0.75686, 1.00000, 0.73333}, {0.73333, 1.00000, 0.72941}, {0.70588, 1.00000, 0.72941}, {0.69020, 1.00000, 0.72941}, {0.66667, 0.97255, 0.72941}, {0.64314, 0.93725, 0.73333}, {0.62353, 0.90196, 0.73725}, {0.60392, 0.86667, 0.74118}, {0.58431, 0.83137, 0.74510}, {0.56078, 0.79608, 0.75294}, {0.54510, 0.76078, 0.75686}, {0.52941, 0.73333, 0.76863}, {0.51373, 0.69804, 0.77647}, {0.50196, 0.67059, 0.78824}, {0.48627, 0.63922, 0.80392}, {0.47059, 0.61176, 0.81569}, {0.45490, 0.58039, 0.83137}, {0.44314, 0.55294, 0.84706}, {0.43529, 0.52941, 0.86667}, {0.42353, 0.50588, 0.88235}, {0.41569, 0.47843, 0.90196}, {0.41176, 0.45490, 0.92549}, {0.40392, 0.43529, 0.87843}, {0.40000, 0.41569, 0.83922}, {0.39216, 0.39216, 0.79608}, {0.38824, 0.37647, 0.75686}, {0.38431, 0.35686, 0.72157}, {0.38039, 0.34118, 0.67843}, {0.38039, 0.32941, 0.65098}, {0.37255, 0.31765, 0.61569}, {0.37255, 0.30588, 0.58431}, {0.37255, 0.29804, 0.55686}, {0.37255, 0.29412, 0.52549}, {0.37647, 0.28627, 0.50196}, {0.37647, 0.28235, 0.47843}, {0.38039, 0.28235, 0.45882}, {0.38431, 0.27843, 0.43922}, {0.38824, 0.27843, 0.41961}, {0.39608, 0.27843, 0.40784}, {0.40000, 0.28235, 0.40000}, {0.40784, 0.28627, 0.38824}, {0.41569, 0.29020, 0.38431}, {0.42353, 0.29804, 0.38039}, {0.43529, 0.30588, 0.37647}, {0.44706, 0.31765, 0.37647}, {0.45882, 0.32549, 0.38039}, {0.47059, 0.34118, 0.38431}, {0.48235, 0.35294, 0.39216}, {0.50196, 0.37255, 0.40000}, {0.51765, 0.39216, 0.40784}, {0.53725, 0.41176, 0.42353}, {0.55686, 0.43922, 0.43529}, {0.57647, 0.46667, 0.45098}, {0.60000, 0.49804, 0.47451}, {0.62745, 0.52941, 0.49804}, {0.65490, 0.56078, 0.52549}, {0.68235, 0.59216, 0.54902}, {0.70980, 0.62745, 0.58431}, {0.74118, 0.66275, 0.61569}, {0.77255, 0.70196, 0.65098}, {0.80392, 0.74118, 0.69020}, {0.83529, 0.78039, 0.73333}, {0.87059, 0.82353, 0.78431}, }; new ColorMapInfo("smooth1.lasc", smooth1_lasc); static RGBColor random5_lasc[] = { {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 0.99216}, {0.00000, 0.00000, 0.98824}, {0.00392, 0.00000, 0.98431}, {0.00392, 0.00000, 0.98039}, {0.00784, 0.00000, 0.97647}, {0.00784, 0.00000, 0.96863}, {0.01176, 0.00000, 0.96471}, {0.01569, 0.00000, 0.96078}, {0.01569, 0.00000, 0.95686}, {0.01961, 0.00000, 0.95294}, {0.01961, 0.00000, 0.94510}, {0.02353, 0.00784, 0.94118}, {0.02745, 0.01569, 0.93725}, {0.02745, 0.02745, 0.93333}, {0.03137, 0.03922, 0.92941}, {0.03529, 0.05098, 0.92157}, {0.03529, 0.06667, 0.91765}, {0.03922, 0.08235, 0.91373}, {0.04314, 0.09804, 0.90980}, {0.04706, 0.11765, 0.90588}, {0.04706, 0.09804, 0.90196}, {0.05098, 0.08235, 0.89412}, {0.05490, 0.06667, 0.89020}, {0.05490, 0.05098, 0.88627}, {0.05882, 0.03922, 0.88235}, {0.06275, 0.02745, 0.87843}, {0.06667, 0.01569, 0.87059}, {0.07059, 0.00784, 0.86667}, {0.07059, 0.00000, 0.86275}, {0.07451, 0.00000, 0.85882}, {0.07843, 0.00392, 0.85490}, {0.08235, 0.01176, 0.85098}, {0.08235, 0.02353, 0.84314}, {0.08627, 0.03922, 0.83922}, {0.09020, 0.05490, 0.83529}, {0.09412, 0.07059, 0.83137}, {0.09804, 0.09020, 0.82745}, {0.09804, 0.10980, 0.82353}, {0.10196, 0.13333, 0.81569}, {0.10588, 0.15686, 0.81176}, {0.10980, 0.13333, 0.80784}, {0.11373, 0.10980, 0.80392}, {0.11765, 0.09020, 0.80000}, {0.11765, 0.07059, 0.79608}, {0.12157, 0.05490, 0.79216}, {0.12549, 0.03922, 0.78431}, {0.12941, 0.02353, 0.78039}, {0.13333, 0.01176, 0.77647}, {0.13725, 0.00392, 0.77255}, {0.14118, 0.00000, 0.76863}, {0.14118, 0.00392, 0.76471}, {0.14510, 0.01569, 0.75686}, {0.14902, 0.03137, 0.75294}, {0.15294, 0.04706, 0.74902}, {0.15686, 0.06667, 0.74510}, {0.16078, 0.09020, 0.74118}, {0.16471, 0.11373, 0.73725}, {0.16863, 0.13725, 0.73333}, {0.17255, 0.16471, 0.72549}, {0.17255, 0.19608, 0.72157}, {0.17647, 0.16471, 0.71765}, {0.18039, 0.13725, 0.71373}, {0.18431, 0.11373, 0.70980}, {0.18824, 0.09020, 0.70588}, {0.19216, 0.06667, 0.70196}, {0.19608, 0.04706, 0.69804}, {0.20000, 0.03137, 0.69020}, {0.20392, 0.01569, 0.68627}, {0.20784, 0.00392, 0.68235}, {0.21176, 0.00000, 0.67843}, {0.21176, 0.00784, 0.67451}, {0.21569, 0.02353, 0.67059}, {0.21961, 0.04314, 0.66667}, {0.22353, 0.06667, 0.66275}, {0.22745, 0.09412, 0.65490}, {0.23137, 0.12549, 0.65098}, {0.23529, 0.15686, 0.64706}, {0.23922, 0.19608, 0.64314}, {0.24314, 0.23137, 0.63922}, {0.24706, 0.27451, 0.63529}, {0.25098, 0.23137, 0.63137}, {0.25490, 0.19608, 0.62745}, {0.25882, 0.15686, 0.61961}, {0.26275, 0.12549, 0.61569}, {0.26667, 0.09412, 0.61176}, {0.27059, 0.06667, 0.60784}, {0.27451, 0.04314, 0.60392}, {0.27843, 0.02353, 0.60000}, {0.28235, 0.00784, 0.59608}, {0.28627, 0.00000, 0.59216}, {0.29020, 0.00784, 0.58824}, {0.29412, 0.03137, 0.58431}, {0.29804, 0.05490, 0.57647}, {0.29804, 0.08627, 0.57255}, {0.30196, 0.12157, 0.56863}, {0.30588, 0.16078, 0.56471}, {0.30980, 0.20392, 0.56078}, {0.31373, 0.25098, 0.55686}, {0.31765, 0.29804, 0.55294}, {0.32157, 0.35294, 0.54902}, {0.32549, 0.29804, 0.54510}, {0.32941, 0.25098, 0.54118}, {0.33333, 0.20392, 0.53725}, {0.33725, 0.16078, 0.52941}, {0.34118, 0.12157, 0.52549}, {0.34510, 0.08627, 0.52157}, {0.34902, 0.05490, 0.51765}, {0.35294, 0.03137, 0.51373}, {0.35686, 0.00784, 0.50980}, {0.36078, 0.00000, 0.50588}, {0.36471, 0.01176, 0.50196}, {0.37255, 0.03529, 0.49804}, {0.37647, 0.07059, 0.49412}, {0.38039, 0.10588, 0.49020}, {0.38431, 0.14902, 0.48627}, {0.38824, 0.20000, 0.48235}, {0.39216, 0.25098, 0.47843}, {0.39608, 0.30588, 0.47059}, {0.40000, 0.36471, 0.46667}, {0.40392, 0.43137, 0.46275}, {0.40784, 0.36471, 0.45882}, {0.41176, 0.30588, 0.45490}, {0.41569, 0.25098, 0.45098}, {0.41961, 0.20000, 0.44706}, {0.42353, 0.14902, 0.44314}, {0.42745, 0.10588, 0.43922}, {0.43137, 0.07059, 0.43529}, {0.43529, 0.03529, 0.43137}, {0.43922, 0.01176, 0.42745}, {0.44314, 0.00000, 0.42353}, {0.44706, 0.01569, 0.41961}, {0.45098, 0.04314, 0.41569}, {0.45490, 0.08235, 0.41176}, {0.45882, 0.12549, 0.40784}, {0.46275, 0.17647, 0.40392}, {0.46667, 0.23529, 0.40000}, {0.47059, 0.29804, 0.39608}, {0.47843, 0.36471, 0.39216}, {0.48235, 0.43137, 0.38824}, {0.48627, 0.50980, 0.38431}, {0.49020, 0.43137, 0.38039}, {0.49412, 0.36471, 0.37647}, {0.49804, 0.29804, 0.37255}, {0.50196, 0.23529, 0.36471}, {0.50588, 0.17647, 0.36078}, {0.50980, 0.12549, 0.35686}, {0.51373, 0.08235, 0.35294}, {0.51765, 0.04314, 0.34902}, {0.52157, 0.01569, 0.34510}, {0.52549, 0.00000, 0.34118}, {0.52941, 0.01569, 0.33725}, {0.53725, 0.05098, 0.33333}, {0.54118, 0.09412, 0.32941}, {0.54510, 0.14510, 0.32549}, {0.54902, 0.20784, 0.32157}, {0.55294, 0.27059, 0.31765}, {0.55686, 0.34118, 0.31373}, {0.56078, 0.41961, 0.30980}, {0.56471, 0.50196, 0.30588}, {0.56863, 0.58824, 0.30196}, {0.57255, 0.50196, 0.29804}, {0.57647, 0.41961, 0.29804}, {0.58431, 0.34118, 0.29412}, {0.58824, 0.27059, 0.29020}, {0.59216, 0.20784, 0.28627}, {0.59608, 0.14510, 0.28235}, {0.60000, 0.09412, 0.27843}, {0.60392, 0.05098, 0.27451}, {0.60784, 0.01569, 0.27059}, {0.61176, 0.00000, 0.26667}, {0.61569, 0.01961, 0.26275}, {0.61961, 0.05882, 0.25882}, {0.62745, 0.10588, 0.25490}, {0.63137, 0.16863, 0.25098}, {0.63529, 0.23529, 0.24706}, {0.63922, 0.30980, 0.24314}, {0.64314, 0.38824, 0.23922}, {0.64706, 0.47451, 0.23529}, {0.65098, 0.56863, 0.23137}, {0.65490, 0.66667, 0.22745}, {0.66275, 0.56863, 0.22353}, {0.66667, 0.47451, 0.21961}, {0.67059, 0.38824, 0.21569}, {0.67451, 0.30980, 0.21176}, {0.67843, 0.23529, 0.21176}, {0.68235, 0.16863, 0.20784}, {0.68627, 0.10588, 0.20392}, {0.69020, 0.05882, 0.20000}, {0.69804, 0.01961, 0.19608}, {0.70196, 0.00000, 0.19216}, {0.70588, 0.02353, 0.18824}, {0.70980, 0.06275, 0.18431}, {0.71373, 0.12157, 0.18039}, {0.71765, 0.18824, 0.17647}, {0.72157, 0.26275, 0.17255}, {0.72549, 0.34510, 0.17255}, {0.73333, 0.43529, 0.16863}, {0.73725, 0.52941, 0.16471}, {0.74118, 0.63529, 0.16078}, {0.74510, 0.74510, 0.15686}, {0.74902, 0.63529, 0.15294}, {0.75294, 0.52941, 0.14902}, {0.75686, 0.43529, 0.14510}, {0.76471, 0.34510, 0.14118}, {0.76863, 0.26275, 0.14118}, {0.77255, 0.18824, 0.13725}, {0.77647, 0.12157, 0.13333}, {0.78039, 0.06275, 0.12941}, {0.78431, 0.02353, 0.12549}, {0.79216, 0.00000, 0.12157}, {0.79608, 0.02353, 0.11765}, {0.80000, 0.07059, 0.11765}, {0.80392, 0.13333, 0.11373}, {0.80784, 0.20784, 0.10980}, {0.81176, 0.29020, 0.10588}, {0.81569, 0.38039, 0.10196}, {0.82353, 0.47843, 0.09804}, {0.82745, 0.58824, 0.09804}, {0.83137, 0.70196, 0.09412}, {0.83529, 0.82353, 0.09020}, {0.83922, 0.70196, 0.08627}, {0.84314, 0.58824, 0.08235}, {0.85098, 0.47843, 0.08235}, {0.85490, 0.38039, 0.07843}, {0.85882, 0.29020, 0.07451}, {0.86275, 0.20784, 0.07059}, {0.86667, 0.13333, 0.07059}, {0.87059, 0.07059, 0.06667}, {0.87843, 0.02353, 0.06275}, {0.88235, 0.00000, 0.05882}, {0.88627, 0.02745, 0.05490}, {0.89020, 0.07843, 0.05490}, {0.89412, 0.14510, 0.05098}, {0.90196, 0.22745, 0.04706}, {0.90588, 0.31765, 0.04706}, {0.90980, 0.41569, 0.04314}, {0.91373, 0.52549, 0.03922}, {0.91765, 0.64314, 0.03529}, {0.92157, 0.76863, 0.03529}, {0.92941, 0.90196, 0.03137}, {0.93333, 0.76863, 0.02745}, {0.93725, 0.64314, 0.02745}, {0.94118, 0.52549, 0.02353}, {0.94510, 0.41569, 0.01961}, {0.95294, 0.31765, 0.01961}, {0.95686, 0.25882, 0.01569}, {0.96078, 0.23137, 0.01569}, {0.96471, 0.23922, 0.01176}, {0.96863, 0.27843, 0.00784}, {0.97647, 0.35294, 0.00784}, {0.98039, 0.46275, 0.00392}, {0.98431, 0.58431, 0.00392}, {0.98824, 0.71373, 0.00000}, {0.99216, 0.85098, 0.00000}, {1.00000, 1.00000, 0.00000}, }; new ColorMapInfo("random5.lasc", random5_lasc); static RGBColor light_lasc[] = { {0.00000, 0.00392, 0.00000}, {0.00000, 0.00784, 0.01961}, {0.00000, 0.01176, 0.05490}, {0.00000, 0.01569, 0.08627}, {0.00000, 0.01961, 0.10980}, {0.00000, 0.02353, 0.13725}, {0.00000, 0.02745, 0.15686}, {0.00000, 0.03137, 0.18039}, {0.00000, 0.03529, 0.20000}, {0.00000, 0.03922, 0.21569}, {0.00000, 0.04314, 0.23529}, {0.00000, 0.04706, 0.25098}, {0.00000, 0.05098, 0.26275}, {0.00000, 0.05490, 0.28235}, {0.00000, 0.05882, 0.29412}, {0.00000, 0.06275, 0.30588}, {0.00000, 0.06667, 0.31765}, {0.00000, 0.07059, 0.33333}, {0.00000, 0.07451, 0.34118}, {0.00000, 0.07843, 0.35294}, {0.00000, 0.08235, 0.36078}, {0.00000, 0.08627, 0.37255}, {0.00000, 0.09020, 0.38431}, {0.00000, 0.09412, 0.39216}, {0.00392, 0.09804, 0.40000}, {0.00784, 0.10196, 0.41176}, {0.01176, 0.10588, 0.41961}, {0.01569, 0.10980, 0.43137}, {0.01569, 0.11373, 0.43529}, {0.01961, 0.11765, 0.44314}, {0.02353, 0.12157, 0.45098}, {0.02745, 0.12549, 0.45882}, {0.02745, 0.12941, 0.46667}, {0.03137, 0.13333, 0.47059}, {0.03529, 0.13725, 0.48235}, {0.04314, 0.14118, 0.48627}, {0.04706, 0.14510, 0.49412}, {0.05098, 0.14902, 0.50196}, {0.05882, 0.15294, 0.50588}, {0.06667, 0.15686, 0.50980}, {0.07451, 0.16078, 0.51765}, {0.08235, 0.16471, 0.52157}, {0.09020, 0.16863, 0.53333}, {0.09804, 0.17255, 0.53725}, {0.10588, 0.17647, 0.54118}, {0.11765, 0.18039, 0.54902}, {0.12941, 0.18431, 0.55294}, {0.14118, 0.18824, 0.55686}, {0.15294, 0.19216, 0.56078}, {0.16471, 0.19608, 0.56471}, {0.18039, 0.20000, 0.57255}, {0.18824, 0.20392, 0.58039}, {0.20000, 0.20784, 0.58431}, {0.21569, 0.21176, 0.58824}, {0.23137, 0.21569, 0.59216}, {0.24706, 0.21961, 0.59608}, {0.26275, 0.22353, 0.60000}, {0.27843, 0.22745, 0.60392}, {0.29412, 0.23137, 0.60784}, {0.30980, 0.23529, 0.61176}, {0.32941, 0.23922, 0.61569}, {0.34902, 0.24314, 0.61961}, {0.36863, 0.24706, 0.62745}, {0.38431, 0.25098, 0.63137}, {0.40392, 0.25490, 0.63529}, {0.41569, 0.25882, 0.63922}, {0.43529, 0.26275, 0.64314}, {0.45490, 0.26667, 0.64706}, {0.47059, 0.27059, 0.65098}, {0.48627, 0.27451, 0.65490}, {0.50196, 0.27843, 0.65490}, {0.51765, 0.28235, 0.65882}, {0.52941, 0.28627, 0.66275}, {0.54902, 0.29020, 0.66667}, {0.56471, 0.29412, 0.67059}, {0.58039, 0.29804, 0.67843}, {0.59216, 0.30196, 0.67843}, {0.60392, 0.30588, 0.68235}, {0.61961, 0.30980, 0.68627}, {0.63137, 0.31373, 0.69020}, {0.63922, 0.31765, 0.69020}, {0.65098, 0.32157, 0.69412}, {0.65882, 0.32549, 0.69804}, {0.67059, 0.32941, 0.70196}, {0.67843, 0.33333, 0.70196}, {0.69020, 0.33725, 0.70588}, {0.69804, 0.34118, 0.70980}, {0.70588, 0.34510, 0.71373}, {0.71373, 0.34902, 0.71373}, {0.72157, 0.35294, 0.71765}, {0.72941, 0.35686, 0.72157}, {0.73725, 0.36078, 0.72157}, {0.74510, 0.36471, 0.72941}, {0.75294, 0.36863, 0.73333}, {0.76078, 0.37255, 0.73333}, {0.76863, 0.37647, 0.73725}, {0.77647, 0.38039, 0.74118}, {0.78039, 0.38431, 0.74118}, {0.78824, 0.38824, 0.74510}, {0.79608, 0.39216, 0.74510}, {0.80392, 0.39608, 0.74902}, {0.80784, 0.40000, 0.75294}, {0.81176, 0.40392, 0.75294}, {0.81961, 0.40784, 0.75686}, {0.82353, 0.41176, 0.76078}, {0.82745, 0.41569, 0.76078}, {0.83529, 0.41961, 0.76471}, {0.83922, 0.42353, 0.76471}, {0.84314, 0.42745, 0.76863}, {0.84706, 0.43137, 0.76863}, {0.85098, 0.43529, 0.77255}, {0.85490, 0.43922, 0.78039}, {0.85882, 0.44314, 0.78039}, {0.86275, 0.44706, 0.78431}, {0.86667, 0.45098, 0.78431}, {0.87059, 0.45490, 0.78824}, {0.87451, 0.45882, 0.78824}, {0.87843, 0.46275, 0.79216}, {0.88235, 0.46667, 0.79216}, {0.88627, 0.47059, 0.79608}, {0.89020, 0.47451, 0.79608}, {0.89412, 0.47843, 0.80000}, {0.89804, 0.48235, 0.80000}, {0.89804, 0.48627, 0.80392}, {0.90196, 0.49020, 0.80392}, {0.90588, 0.49412, 0.80784}, {0.90980, 0.49804, 0.80784}, {0.91373, 0.50196, 0.81176}, {0.91373, 0.50588, 0.81176}, {0.91765, 0.50980, 0.81569}, {0.92157, 0.51373, 0.81569}, {0.92157, 0.51765, 0.81961}, {0.92549, 0.52157, 0.81961}, {0.92941, 0.52549, 0.82745}, {0.92941, 0.52941, 0.82745}, {0.93333, 0.53333, 0.83137}, {0.93725, 0.53725, 0.83137}, {0.93725, 0.54118, 0.83529}, {0.93725, 0.54510, 0.83529}, {0.94118, 0.54902, 0.83922}, {0.94118, 0.55294, 0.83922}, {0.94510, 0.55686, 0.83922}, {0.94510, 0.56078, 0.84314}, {0.94902, 0.56471, 0.84314}, {0.94902, 0.56863, 0.84706}, {0.95294, 0.57255, 0.84706}, {0.95294, 0.57647, 0.85098}, {0.95294, 0.58039, 0.85098}, {0.95686, 0.58431, 0.85490}, {0.95686, 0.58824, 0.85490}, {0.96078, 0.59216, 0.85490}, {0.96078, 0.59608, 0.85882}, {0.96078, 0.60000, 0.85882}, {0.96471, 0.60392, 0.86275}, {0.96471, 0.60784, 0.86275}, {0.96471, 0.61176, 0.86275}, {0.96863, 0.61569, 0.86667}, {0.96863, 0.61961, 0.86667}, {0.97255, 0.62353, 0.87059}, {0.97255, 0.62745, 0.87059}, {0.97255, 0.63137, 0.87059}, {0.97647, 0.63529, 0.87843}, {0.97647, 0.63922, 0.87843}, {0.98039, 0.64314, 0.88235}, {0.98039, 0.64706, 0.88235}, {0.98039, 0.65098, 0.88235}, {0.98431, 0.65490, 0.88627}, {0.98431, 0.65882, 0.88627}, {0.98431, 0.66275, 0.89020}, {0.98824, 0.66667, 0.89020}, {0.98824, 0.67059, 0.89020}, {0.98824, 0.67451, 0.89412}, {0.99216, 0.67843, 0.89412}, {0.99216, 0.68235, 0.89412}, {0.99216, 0.68627, 0.89804}, {0.99216, 0.69020, 0.89804}, {0.99216, 0.69412, 0.89804}, {0.99608, 0.69804, 0.90196}, {0.99608, 0.70196, 0.90196}, {0.99608, 0.70588, 0.90588}, {0.99608, 0.70980, 0.90588}, {0.99608, 0.71373, 0.90588}, {0.99608, 0.71765, 0.90980}, {0.99608, 0.72157, 0.90980}, {0.99608, 0.72549, 0.90980}, {0.99608, 0.72941, 0.91373}, {0.99608, 0.73333, 0.91373}, {0.99608, 0.73725, 0.91373}, {0.99608, 0.74118, 0.91765}, {0.99608, 0.74510, 0.91765}, {0.99608, 0.74902, 0.91765}, {0.99608, 0.75294, 0.92157}, {0.99608, 0.75686, 0.92157}, {0.99608, 0.76078, 0.92157}, {0.99608, 0.76471, 0.92941}, {0.99608, 0.76863, 0.92941}, {0.99608, 0.77255, 0.92941}, {0.99608, 0.77647, 0.93333}, {0.99608, 0.78039, 0.93333}, {0.99608, 0.78431, 0.93333}, {0.99608, 0.78824, 0.93725}, {1.00000, 0.79216, 0.93725}, {1.00000, 0.79608, 0.93725}, {1.00000, 0.80000, 0.94118}, {1.00000, 0.80392, 0.94118}, {1.00000, 0.80784, 0.94118}, {1.00000, 0.81176, 0.94118}, {1.00000, 0.81569, 0.94510}, {1.00000, 0.81961, 0.94510}, {1.00000, 0.82353, 0.94510}, {1.00000, 0.82745, 0.94902}, {1.00000, 0.83137, 0.94902}, {1.00000, 0.83529, 0.94902}, {1.00000, 0.83922, 0.95294}, {1.00000, 0.84314, 0.95294}, {1.00000, 0.84706, 0.95294}, {1.00000, 0.85098, 0.95686}, {1.00000, 0.85490, 0.95686}, {1.00000, 0.85882, 0.95686}, {1.00000, 0.86275, 0.95686}, {1.00000, 0.86667, 0.96078}, {1.00000, 0.87059, 0.96078}, {1.00000, 0.87451, 0.96078}, {1.00000, 0.87843, 0.96471}, {1.00000, 0.88235, 0.96471}, {1.00000, 0.88627, 0.96471}, {1.00000, 0.89020, 0.96471}, {1.00000, 0.89412, 0.96863}, {1.00000, 0.89804, 0.96863}, {1.00000, 0.90196, 0.96863}, {1.00000, 0.90588, 0.97255}, {1.00000, 0.90980, 0.97255}, {1.00000, 0.91373, 0.97255}, {1.00000, 0.91765, 0.97255}, {1.00000, 0.92157, 0.98039}, {1.00000, 0.92549, 0.98039}, {1.00000, 0.92941, 0.98039}, {1.00000, 0.93333, 0.98039}, {1.00000, 0.93725, 0.98431}, {1.00000, 0.94118, 0.98431}, {1.00000, 0.94510, 0.98431}, {1.00000, 0.94902, 0.98824}, {1.00000, 0.95294, 0.98824}, {1.00000, 0.95686, 0.98824}, {1.00000, 0.96078, 0.98824}, {1.00000, 0.96471, 0.99216}, {1.00000, 0.96863, 0.99216}, {1.00000, 0.97255, 0.99216}, {1.00000, 0.97647, 0.99216}, {1.00000, 0.98039, 0.99608}, {1.00000, 0.98431, 0.99608}, {1.00000, 0.98824, 0.99608}, {1.00000, 0.99216, 0.99608}, {1.00000, 0.99608, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("light.lasc", light_lasc); static RGBColor random2_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00392, 0.47059, 0.00392}, {0.00392, 0.47059, 0.00392}, {0.00392, 0.47059, 0.00392}, {0.00392, 0.47059, 0.00392}, {0.00392, 0.47059, 0.00392}, {0.00392, 0.47059, 0.00392}, {0.00392, 0.47059, 0.00392}, {0.00392, 0.47059, 0.00392}, {0.00392, 0.47059, 0.00392}, {0.00392, 0.47059, 0.00392}, {0.00392, 0.62745, 0.00392}, {0.00392, 0.62745, 0.00392}, {0.00392, 0.62745, 0.00392}, {0.00392, 0.62745, 0.00392}, {0.00392, 0.62745, 0.00392}, {0.00392, 0.62745, 0.00392}, {0.00392, 0.62745, 0.00392}, {0.00392, 0.62745, 0.00392}, {0.00392, 0.62745, 0.00392}, {0.00392, 0.62745, 0.00392}, {0.00392, 0.78431, 0.00392}, {0.00392, 0.78431, 0.00392}, {0.00392, 0.78431, 0.00392}, {0.00392, 0.78431, 0.00392}, {0.00392, 0.78431, 0.00392}, {0.00392, 0.78431, 0.00392}, {0.00392, 0.78431, 0.00392}, {0.00392, 0.78431, 0.00392}, {0.00392, 0.78431, 0.00392}, {0.00392, 0.78431, 0.00392}, {0.00392, 1.00000, 0.00392}, {0.00392, 1.00000, 0.00392}, {0.00392, 1.00000, 0.00392}, {0.00392, 1.00000, 0.00392}, {0.00392, 1.00000, 0.00392}, {0.00392, 1.00000, 0.00392}, {0.00392, 1.00000, 0.00392}, {0.00392, 1.00000, 0.00392}, {0.00392, 1.00000, 0.00392}, {0.00392, 1.00000, 0.00392}, {0.00392, 0.86275, 0.47059}, {0.00392, 0.86275, 0.47059}, {0.00392, 0.86275, 0.47059}, {0.00392, 0.86275, 0.47059}, {0.00392, 0.86275, 0.47059}, {0.00392, 0.86275, 0.47059}, {0.00392, 0.86275, 0.47059}, {0.00392, 0.86275, 0.47059}, {0.00392, 0.86275, 0.47059}, {0.00392, 0.86275, 0.47059}, {0.00000, 0.78431, 0.62745}, {0.00000, 0.78431, 0.62745}, {0.00000, 0.78431, 0.62745}, {0.00000, 0.78431, 0.62745}, {0.00000, 0.78431, 0.62745}, {0.00000, 0.78431, 0.62745}, {0.00000, 0.78431, 0.62745}, {0.00000, 0.78431, 0.62745}, {0.00000, 0.78431, 0.62745}, {0.00000, 0.78431, 0.62745}, {0.00000, 0.70588, 0.78431}, {0.00000, 0.70588, 0.78431}, {0.00000, 0.70588, 0.78431}, {0.00000, 0.70588, 0.78431}, {0.00000, 0.70588, 0.78431}, {0.00000, 0.70588, 0.78431}, {0.00000, 0.70588, 0.78431}, {0.00000, 0.70588, 0.78431}, {0.00000, 0.70588, 0.78431}, {0.00000, 0.70588, 0.78431}, {0.00000, 0.62745, 1.00000}, {0.00000, 0.62745, 1.00000}, {0.00000, 0.62745, 1.00000}, {0.00000, 0.62745, 1.00000}, {0.00000, 0.62745, 1.00000}, {0.00000, 0.62745, 1.00000}, {0.00000, 0.62745, 1.00000}, {0.00000, 0.62745, 1.00000}, {0.00000, 0.62745, 1.00000}, {0.00000, 0.62745, 1.00000}, {0.23529, 0.47059, 1.00000}, {0.23529, 0.47059, 1.00000}, {0.23529, 0.47059, 1.00000}, {0.23529, 0.47059, 1.00000}, {0.23529, 0.47059, 1.00000}, {0.23529, 0.47059, 1.00000}, {0.23529, 0.47059, 1.00000}, {0.23529, 0.47059, 1.00000}, {0.23529, 0.47059, 1.00000}, {0.23529, 0.47059, 1.00000}, {0.23529, 0.00392, 1.00000}, {0.23529, 0.00392, 1.00000}, {0.23529, 0.00392, 1.00000}, {0.23529, 0.00392, 1.00000}, {0.23529, 0.00392, 1.00000}, {0.23529, 0.00392, 1.00000}, {0.23529, 0.00392, 1.00000}, {0.23529, 0.00392, 1.00000}, {0.23529, 0.00392, 1.00000}, {0.23529, 0.00392, 1.00000}, {0.47059, 0.00392, 0.78431}, {0.47059, 0.00392, 0.78431}, {0.47059, 0.00392, 0.78431}, {0.47059, 0.00392, 0.78431}, {0.47059, 0.00392, 0.78431}, {0.47059, 0.00392, 0.78431}, {0.47059, 0.00392, 0.78431}, {0.47059, 0.00392, 0.78431}, {0.47059, 0.00392, 0.78431}, {0.47059, 0.00392, 0.78431}, {0.62745, 0.00392, 0.62745}, {0.62745, 0.00392, 0.62745}, {0.62745, 0.00392, 0.62745}, {0.62745, 0.00392, 0.62745}, {0.62745, 0.00392, 0.62745}, {0.62745, 0.00392, 0.62745}, {0.62745, 0.00392, 0.62745}, {0.62745, 0.00392, 0.62745}, {0.62745, 0.00392, 0.62745}, {0.62745, 0.00392, 0.62745}, {0.78431, 0.00392, 0.47059}, {0.78431, 0.00392, 0.47059}, {0.78431, 0.00392, 0.47059}, {0.78431, 0.00392, 0.47059}, {0.78431, 0.00392, 0.47059}, {0.78431, 0.00392, 0.47059}, {0.78431, 0.00392, 0.47059}, {0.78431, 0.00392, 0.47059}, {0.78431, 0.00392, 0.47059}, {0.78431, 0.00392, 0.47059}, {0.90196, 0.11765, 0.23529}, {0.90196, 0.11765, 0.23529}, {0.90196, 0.11765, 0.23529}, {0.90196, 0.11765, 0.23529}, {0.90196, 0.11765, 0.23529}, {0.90196, 0.11765, 0.23529}, {0.90196, 0.11765, 0.23529}, {0.90196, 0.11765, 0.23529}, {0.90196, 0.11765, 0.23529}, {0.90196, 0.11765, 0.23529}, {1.00000, 0.23529, 0.00000}, {1.00000, 0.23529, 0.00000}, {1.00000, 0.23529, 0.00000}, {1.00000, 0.23529, 0.00000}, {1.00000, 0.23529, 0.00000}, {1.00000, 0.23529, 0.00000}, {1.00000, 0.23529, 0.00000}, {1.00000, 0.23529, 0.00000}, {1.00000, 0.23529, 0.00000}, {1.00000, 0.23529, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {0.99216, 0.59608, 0.00000}, {0.99216, 0.59608, 0.00000}, {0.99216, 0.59608, 0.00000}, {0.99216, 0.59608, 0.00000}, {0.99216, 0.59608, 0.00000}, {0.99216, 0.59608, 0.00000}, {0.99216, 0.59608, 0.00000}, {0.99216, 0.59608, 0.00000}, {0.99216, 0.59608, 0.00000}, {0.99216, 0.59608, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98039, 0.90196, 0.00000}, {0.98039, 0.90196, 0.00000}, {0.98039, 0.90196, 0.00000}, {0.98039, 0.90196, 0.00000}, {0.98039, 0.90196, 0.00000}, {0.98039, 0.90196, 0.00000}, {0.98039, 0.90196, 0.00000}, {0.98039, 0.90196, 0.00000}, {0.98039, 0.90196, 0.00000}, {0.98039, 0.90196, 0.00000}, {0.98039, 0.98039, 0.47059}, {0.98039, 0.98039, 0.47059}, {0.98039, 0.98039, 0.47059}, {0.98039, 0.98039, 0.47059}, {0.98039, 0.98039, 0.47059}, {0.98039, 0.98039, 0.47059}, {0.98039, 0.98039, 0.47059}, {0.98039, 0.98039, 0.47059}, {0.98039, 0.98039, 0.47059}, {0.98039, 0.98039, 0.47059}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("random2.lasc", random2_lasc); static RGBColor pastel_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 1.00000}, {0.01961, 0.00000, 0.98039}, {0.05490, 0.00000, 0.94510}, {0.08627, 0.00392, 0.91373}, {0.10980, 0.00392, 0.89020}, {0.13725, 0.00392, 0.86275}, {0.15686, 0.00392, 0.84314}, {0.18039, 0.00392, 0.81961}, {0.20000, 0.00784, 0.80000}, {0.21569, 0.00784, 0.78431}, {0.23529, 0.00784, 0.76471}, {0.25098, 0.00784, 0.74902}, {0.26275, 0.01176, 0.73725}, {0.28235, 0.01176, 0.71765}, {0.29412, 0.01176, 0.70588}, {0.30588, 0.01176, 0.69412}, {0.31765, 0.01176, 0.68235}, {0.33333, 0.01569, 0.66667}, {0.34118, 0.01569, 0.65882}, {0.35294, 0.01569, 0.64706}, {0.36078, 0.01569, 0.63922}, {0.37255, 0.01961, 0.62745}, {0.38431, 0.01961, 0.61569}, {0.39216, 0.01961, 0.60784}, {0.40000, 0.01961, 0.60000}, {0.41176, 0.02353, 0.58824}, {0.41961, 0.02353, 0.58039}, {0.43137, 0.02353, 0.56863}, {0.43529, 0.02745, 0.56471}, {0.44314, 0.02745, 0.55686}, {0.45098, 0.02745, 0.54902}, {0.45882, 0.02745, 0.54118}, {0.46667, 0.03137, 0.53333}, {0.47059, 0.03137, 0.52941}, {0.48235, 0.03137, 0.51765}, {0.48627, 0.03529, 0.51373}, {0.49412, 0.03529, 0.50588}, {0.50196, 0.03529, 0.49804}, {0.50588, 0.03529, 0.49412}, {0.50980, 0.04314, 0.49020}, {0.51765, 0.04314, 0.48235}, {0.52157, 0.04314, 0.47843}, {0.53333, 0.04706, 0.46667}, {0.53725, 0.04706, 0.46275}, {0.54118, 0.04706, 0.45882}, {0.54902, 0.05098, 0.45098}, {0.55294, 0.05098, 0.44706}, {0.55686, 0.05098, 0.44314}, {0.56078, 0.05490, 0.43922}, {0.56471, 0.05490, 0.43529}, {0.57255, 0.05490, 0.42745}, {0.58039, 0.05882, 0.41961}, {0.58431, 0.05882, 0.41569}, {0.58824, 0.05882, 0.41176}, {0.59216, 0.06275, 0.40784}, {0.59608, 0.06275, 0.40392}, {0.60000, 0.06275, 0.40000}, {0.60392, 0.06667, 0.39608}, {0.60784, 0.06667, 0.39216}, {0.61176, 0.06667, 0.38824}, {0.61569, 0.07059, 0.38431}, {0.61961, 0.07059, 0.38039}, {0.62745, 0.07451, 0.37255}, {0.63137, 0.07451, 0.36863}, {0.63529, 0.07451, 0.36471}, {0.63922, 0.07843, 0.36078}, {0.64314, 0.07843, 0.35686}, {0.64706, 0.08235, 0.35294}, {0.65098, 0.08235, 0.34902}, {0.65490, 0.08235, 0.34510}, {0.65490, 0.08627, 0.34510}, {0.65882, 0.08627, 0.34118}, {0.66275, 0.09020, 0.33725}, {0.66667, 0.09020, 0.33333}, {0.67059, 0.09020, 0.32941}, {0.67843, 0.09412, 0.32157}, {0.67843, 0.09412, 0.32157}, {0.68235, 0.09804, 0.31765}, {0.68627, 0.09804, 0.31373}, {0.69020, 0.10196, 0.30980}, {0.69020, 0.10196, 0.30980}, {0.69412, 0.10588, 0.30588}, {0.69804, 0.10588, 0.30196}, {0.70196, 0.10980, 0.29804}, {0.70196, 0.10980, 0.29804}, {0.70588, 0.10980, 0.29412}, {0.70980, 0.11765, 0.29020}, {0.71373, 0.11765, 0.28627}, {0.71373, 0.12157, 0.28627}, {0.71765, 0.12157, 0.28235}, {0.72157, 0.12549, 0.27843}, {0.72157, 0.12549, 0.27843}, {0.72941, 0.12941, 0.27059}, {0.73333, 0.12941, 0.26667}, {0.73333, 0.13333, 0.26667}, {0.73725, 0.13725, 0.26275}, {0.74118, 0.13725, 0.25882}, {0.74118, 0.14118, 0.25882}, {0.74510, 0.14118, 0.25490}, {0.74510, 0.14510, 0.25490}, {0.74902, 0.14510, 0.25098}, {0.75294, 0.14902, 0.24706}, {0.75294, 0.14902, 0.24706}, {0.75686, 0.15294, 0.24314}, {0.76078, 0.15686, 0.23922}, {0.76078, 0.15686, 0.23922}, {0.76471, 0.16078, 0.23529}, {0.76471, 0.16078, 0.23529}, {0.76863, 0.16471, 0.23137}, {0.76863, 0.16863, 0.23137}, {0.77255, 0.16863, 0.22745}, {0.78039, 0.17255, 0.21961}, {0.78039, 0.17255, 0.21961}, {0.78431, 0.17647, 0.21569}, {0.78431, 0.18039, 0.21569}, {0.78824, 0.18039, 0.21176}, {0.78824, 0.18431, 0.21176}, {0.79216, 0.18824, 0.20784}, {0.79216, 0.18824, 0.20784}, {0.79608, 0.19608, 0.20392}, {0.79608, 0.20000, 0.20392}, {0.80000, 0.20000, 0.20000}, {0.80000, 0.20392, 0.20000}, {0.80392, 0.20784, 0.19608}, {0.80392, 0.20784, 0.19608}, {0.80784, 0.21176, 0.19216}, {0.80784, 0.21569, 0.19216}, {0.81176, 0.21961, 0.18824}, {0.81176, 0.21961, 0.18824}, {0.81569, 0.22353, 0.18431}, {0.81569, 0.22745, 0.18431}, {0.81961, 0.23137, 0.18039}, {0.81961, 0.23137, 0.18039}, {0.82745, 0.23529, 0.17255}, {0.82745, 0.23922, 0.17255}, {0.83137, 0.24314, 0.16863}, {0.83137, 0.24314, 0.16863}, {0.83529, 0.24706, 0.16471}, {0.83529, 0.25098, 0.16471}, {0.83922, 0.25490, 0.16078}, {0.83922, 0.25882, 0.16078}, {0.83922, 0.26275, 0.16078}, {0.84314, 0.26275, 0.15686}, {0.84314, 0.27059, 0.15686}, {0.84706, 0.27451, 0.15294}, {0.84706, 0.27843, 0.15294}, {0.85098, 0.28235, 0.14902}, {0.85098, 0.28627, 0.14902}, {0.85490, 0.29020, 0.14510}, {0.85490, 0.29412, 0.14510}, {0.85490, 0.29804, 0.14510}, {0.85882, 0.29804, 0.14118}, {0.85882, 0.30196, 0.14118}, {0.86275, 0.30588, 0.13725}, {0.86275, 0.30980, 0.13725}, {0.86275, 0.31373, 0.13725}, {0.86667, 0.31765, 0.13333}, {0.86667, 0.32157, 0.13333}, {0.87059, 0.32549, 0.12941}, {0.87059, 0.33333, 0.12941}, {0.87059, 0.33725, 0.12941}, {0.87843, 0.34118, 0.12157}, {0.87843, 0.34510, 0.12157}, {0.88235, 0.34902, 0.11765}, {0.88235, 0.35294, 0.11765}, {0.88235, 0.35686, 0.11765}, {0.88627, 0.36078, 0.11373}, {0.88627, 0.36471, 0.11373}, {0.89020, 0.37255, 0.10980}, {0.89020, 0.37647, 0.10980}, {0.89020, 0.38039, 0.10980}, {0.89412, 0.38431, 0.10588}, {0.89412, 0.38824, 0.10588}, {0.89412, 0.39216, 0.10588}, {0.89804, 0.40000, 0.10196}, {0.89804, 0.40392, 0.10196}, {0.89804, 0.40784, 0.10196}, {0.90196, 0.41176, 0.09804}, {0.90196, 0.41961, 0.09804}, {0.90588, 0.42353, 0.09412}, {0.90588, 0.42745, 0.09412}, {0.90588, 0.43529, 0.09412}, {0.90980, 0.43922, 0.09020}, {0.90980, 0.44314, 0.09020}, {0.90980, 0.45098, 0.09020}, {0.91373, 0.45490, 0.08627}, {0.91373, 0.45882, 0.08627}, {0.91373, 0.46667, 0.08627}, {0.91765, 0.47059, 0.08235}, {0.91765, 0.47843, 0.08235}, {0.91765, 0.48235, 0.08235}, {0.92157, 0.49020, 0.07843}, {0.92157, 0.49412, 0.07843}, {0.92157, 0.50196, 0.07843}, {0.92941, 0.50588, 0.07059}, {0.92941, 0.51373, 0.07059}, {0.92941, 0.51765, 0.07059}, {0.93333, 0.52549, 0.06667}, {0.93333, 0.52941, 0.06667}, {0.93333, 0.53725, 0.06667}, {0.93725, 0.54118, 0.06275}, {0.93725, 0.54902, 0.06275}, {0.93725, 0.55686, 0.06275}, {0.94118, 0.56078, 0.05882}, {0.94118, 0.56863, 0.05882}, {0.94118, 0.57647, 0.05882}, {0.94118, 0.58039, 0.05882}, {0.94510, 0.58824, 0.05490}, {0.94510, 0.59608, 0.05490}, {0.94510, 0.60000, 0.05490}, {0.94902, 0.60784, 0.05098}, {0.94902, 0.61569, 0.05098}, {0.94902, 0.62353, 0.05098}, {0.95294, 0.63137, 0.04706}, {0.95294, 0.63529, 0.04706}, {0.95294, 0.64314, 0.04706}, {0.95686, 0.65098, 0.04314}, {0.95686, 0.65882, 0.04314}, {0.95686, 0.66667, 0.04314}, {0.95686, 0.67451, 0.04314}, {0.96078, 0.68235, 0.03922}, {0.96078, 0.69020, 0.03922}, {0.96078, 0.69804, 0.03922}, {0.96471, 0.70588, 0.03529}, {0.96471, 0.71373, 0.03529}, {0.96471, 0.72157, 0.03529}, {0.96471, 0.72941, 0.03529}, {0.96863, 0.73725, 0.03137}, {0.96863, 0.74510, 0.03137}, {0.96863, 0.75294, 0.03137}, {0.97255, 0.76078, 0.02745}, {0.97255, 0.77255, 0.02745}, {0.97255, 0.78039, 0.02745}, {0.97255, 0.78824, 0.02745}, {0.98039, 0.79608, 0.01961}, {0.98039, 0.80392, 0.01961}, {0.98039, 0.81569, 0.01961}, {0.98039, 0.82353, 0.01961}, {0.98431, 0.83137, 0.01569}, {0.98431, 0.84314, 0.01569}, {0.98431, 0.85098, 0.01569}, {0.98824, 0.86275, 0.01176}, {0.98824, 0.87059, 0.01176}, {0.98824, 0.87843, 0.01176}, {0.98824, 0.89020, 0.01176}, {0.99216, 0.89804, 0.00784}, {0.99216, 0.90980, 0.00784}, {0.99216, 0.91765, 0.00784}, {0.99216, 0.92941, 0.00784}, {0.99608, 0.94118, 0.00392}, {0.99608, 0.94902, 0.00392}, {0.99608, 0.96078, 0.00392}, {0.99608, 0.97255, 0.00392}, {1.00000, 0.98039, 0.00000}, {1.00000, 0.99216, 0.00000}, }; new ColorMapInfo("pastel.lasc", pastel_lasc); static RGBColor aips0_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.47451, 0.00000, 0.60784}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78431}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.37255, 0.65490, 0.92549}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.69412, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, }; new ColorMapInfo("aips0.lasc", aips0_lasc); static RGBColor smooth2_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.06667}, {0.00000, 0.00000, 0.06667}, {0.00000, 0.00000, 0.06667}, {0.00000, 0.00000, 0.06667}, {0.00000, 0.00000, 0.06667}, {0.00000, 0.00000, 0.06667}, {0.00000, 0.00000, 0.06667}, {0.00000, 0.00000, 0.06667}, {0.00000, 0.00000, 0.13333}, {0.00000, 0.00000, 0.13333}, {0.00000, 0.00000, 0.13333}, {0.00000, 0.00000, 0.13333}, {0.00000, 0.00000, 0.13333}, {0.00000, 0.00000, 0.13333}, {0.00000, 0.00000, 0.13333}, {0.00000, 0.00000, 0.13333}, {0.00000, 0.00000, 0.20000}, {0.00000, 0.00000, 0.20000}, {0.00000, 0.00000, 0.20000}, {0.00000, 0.00000, 0.20000}, {0.00000, 0.00000, 0.20000}, {0.00000, 0.00000, 0.20000}, {0.00000, 0.00000, 0.20000}, {0.00000, 0.00000, 0.20000}, {0.00000, 0.00000, 0.26667}, {0.00000, 0.00000, 0.26667}, {0.00000, 0.00000, 0.26667}, {0.00000, 0.00000, 0.26667}, {0.00000, 0.00000, 0.26667}, {0.00000, 0.00000, 0.26667}, {0.00000, 0.00000, 0.26667}, {0.00000, 0.00000, 0.26667}, {0.00000, 0.00000, 0.33333}, {0.00000, 0.00000, 0.33333}, {0.00000, 0.00000, 0.33333}, {0.00000, 0.00000, 0.33333}, {0.00000, 0.00000, 0.33333}, {0.00000, 0.00000, 0.33333}, {0.00000, 0.00000, 0.33333}, {0.00000, 0.00000, 0.33333}, {0.00000, 0.00000, 0.40000}, {0.00000, 0.00000, 0.40000}, {0.00000, 0.00000, 0.40000}, {0.00000, 0.00000, 0.40000}, {0.00000, 0.00000, 0.40000}, {0.00000, 0.00000, 0.40000}, {0.00000, 0.00000, 0.40000}, {0.00000, 0.00000, 0.40000}, {0.00000, 0.00000, 0.46667}, {0.00000, 0.00000, 0.46667}, {0.00000, 0.00000, 0.46667}, {0.00000, 0.00000, 0.46667}, {0.00000, 0.00000, 0.46667}, {0.00000, 0.00000, 0.46667}, {0.00000, 0.00000, 0.46667}, {0.00000, 0.00000, 0.46667}, {0.00000, 0.00000, 0.53333}, {0.00000, 0.00000, 0.53333}, {0.00000, 0.00000, 0.53333}, {0.00000, 0.00000, 0.53333}, {0.00000, 0.00000, 0.53333}, {0.00000, 0.00000, 0.53333}, {0.00000, 0.00000, 0.53333}, {0.00000, 0.00000, 0.53333}, {0.06667, 0.00000, 0.53333}, {0.06667, 0.00000, 0.53333}, {0.06667, 0.00000, 0.53333}, {0.06667, 0.00000, 0.53333}, {0.06667, 0.00000, 0.53333}, {0.06667, 0.00000, 0.53333}, {0.06667, 0.00000, 0.53333}, {0.06667, 0.00000, 0.53333}, {0.13333, 0.00000, 0.53333}, {0.13333, 0.00000, 0.53333}, {0.13333, 0.00000, 0.53333}, {0.13333, 0.00000, 0.53333}, {0.13333, 0.00000, 0.53333}, {0.13333, 0.00000, 0.53333}, {0.13333, 0.00000, 0.53333}, {0.13333, 0.00000, 0.53333}, {0.20000, 0.00000, 0.53333}, {0.20000, 0.00000, 0.53333}, {0.20000, 0.00000, 0.53333}, {0.20000, 0.00000, 0.53333}, {0.20000, 0.00000, 0.53333}, {0.20000, 0.00000, 0.53333}, {0.20000, 0.00000, 0.53333}, {0.20000, 0.00000, 0.53333}, {0.26667, 0.00000, 0.53333}, {0.26667, 0.00000, 0.53333}, {0.26667, 0.00000, 0.53333}, {0.26667, 0.00000, 0.53333}, {0.26667, 0.00000, 0.53333}, {0.26667, 0.00000, 0.53333}, {0.26667, 0.00000, 0.53333}, {0.26667, 0.00000, 0.53333}, {0.33333, 0.00000, 0.53333}, {0.33333, 0.00000, 0.53333}, {0.33333, 0.00000, 0.53333}, {0.33333, 0.00000, 0.53333}, {0.33333, 0.00000, 0.53333}, {0.33333, 0.00000, 0.53333}, {0.33333, 0.00000, 0.53333}, {0.33333, 0.00000, 0.53333}, {0.40000, 0.00000, 0.53333}, {0.40000, 0.00000, 0.53333}, {0.40000, 0.00000, 0.53333}, {0.40000, 0.00000, 0.53333}, {0.40000, 0.00000, 0.53333}, {0.40000, 0.00000, 0.53333}, {0.40000, 0.00000, 0.53333}, {0.40000, 0.00000, 0.53333}, {0.46667, 0.00000, 0.53333}, {0.46667, 0.00000, 0.53333}, {0.46667, 0.00000, 0.53333}, {0.46667, 0.00000, 0.53333}, {0.46667, 0.00000, 0.53333}, {0.46667, 0.00000, 0.53333}, {0.46667, 0.00000, 0.53333}, {0.46667, 0.00000, 0.53333}, {0.53333, 0.00000, 0.53333}, {0.53333, 0.00000, 0.53333}, {0.53333, 0.00000, 0.53333}, {0.53333, 0.00000, 0.53333}, {0.53333, 0.00000, 0.46667}, {0.53333, 0.00000, 0.46667}, {0.53333, 0.00000, 0.46667}, {0.53333, 0.00000, 0.46667}, {0.60000, 0.00000, 0.40000}, {0.60000, 0.00000, 0.40000}, {0.60000, 0.00000, 0.40000}, {0.60000, 0.00000, 0.40000}, {0.60000, 0.00000, 0.33333}, {0.60000, 0.00000, 0.33333}, {0.60000, 0.00000, 0.33333}, {0.60000, 0.00000, 0.33333}, {0.66667, 0.00000, 0.26667}, {0.66667, 0.00000, 0.26667}, {0.66667, 0.00000, 0.26667}, {0.66667, 0.00000, 0.26667}, {0.66667, 0.00000, 0.20000}, {0.66667, 0.00000, 0.20000}, {0.66667, 0.00000, 0.20000}, {0.66667, 0.00000, 0.20000}, {0.73333, 0.00000, 0.13333}, {0.73333, 0.00000, 0.13333}, {0.73333, 0.00000, 0.13333}, {0.73333, 0.00000, 0.13333}, {0.73333, 0.00000, 0.06667}, {0.73333, 0.00000, 0.06667}, {0.73333, 0.00000, 0.06667}, {0.73333, 0.00000, 0.06667}, {0.80000, 0.00000, 0.00000}, {0.80000, 0.00000, 0.00000}, {0.80000, 0.00000, 0.00000}, {0.80000, 0.00000, 0.00000}, {0.80000, 0.00000, 0.00000}, {0.80000, 0.00000, 0.00000}, {0.80000, 0.00000, 0.00000}, {0.80000, 0.00000, 0.00000}, {0.86667, 0.00000, 0.00000}, {0.86667, 0.00000, 0.00000}, {0.86667, 0.00000, 0.00000}, {0.86667, 0.00000, 0.00000}, {0.86667, 0.00000, 0.00000}, {0.86667, 0.00000, 0.00000}, {0.86667, 0.00000, 0.00000}, {0.86667, 0.00000, 0.00000}, {0.93333, 0.00000, 0.00000}, {0.93333, 0.00000, 0.00000}, {0.93333, 0.00000, 0.00000}, {0.93333, 0.00000, 0.00000}, {0.93333, 0.00000, 0.00000}, {0.93333, 0.00000, 0.00000}, {0.93333, 0.00000, 0.00000}, {0.93333, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.06667, 0.00000}, {1.00000, 0.06667, 0.00000}, {1.00000, 0.13333, 0.00000}, {1.00000, 0.13333, 0.00000}, {1.00000, 0.20000, 0.00000}, {1.00000, 0.20000, 0.00000}, {1.00000, 0.26667, 0.00000}, {1.00000, 0.26667, 0.00000}, {1.00000, 0.33333, 0.00000}, {1.00000, 0.33333, 0.00000}, {1.00000, 0.40000, 0.00000}, {1.00000, 0.40000, 0.00000}, {1.00000, 0.46667, 0.00000}, {1.00000, 0.46667, 0.00000}, {1.00000, 0.53333, 0.00000}, {1.00000, 0.53333, 0.00000}, {1.00000, 0.60000, 0.00000}, {1.00000, 0.60000, 0.00000}, {1.00000, 0.66667, 0.00000}, {1.00000, 0.66667, 0.00000}, {1.00000, 0.73333, 0.00000}, {1.00000, 0.73333, 0.00000}, {1.00000, 0.80000, 0.00000}, {1.00000, 0.80000, 0.00000}, {1.00000, 0.86667, 0.00000}, {1.00000, 0.86667, 0.00000}, {1.00000, 0.93333, 0.00000}, {1.00000, 0.93333, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.06667}, {1.00000, 1.00000, 0.06667}, {1.00000, 1.00000, 0.13333}, {1.00000, 1.00000, 0.13333}, {1.00000, 1.00000, 0.20000}, {1.00000, 1.00000, 0.20000}, {1.00000, 1.00000, 0.26667}, {1.00000, 1.00000, 0.26667}, {1.00000, 1.00000, 0.33333}, {1.00000, 1.00000, 0.33333}, {1.00000, 1.00000, 0.40000}, {1.00000, 1.00000, 0.40000}, {1.00000, 1.00000, 0.46667}, {1.00000, 1.00000, 0.46667}, {1.00000, 1.00000, 0.53333}, {1.00000, 1.00000, 0.53333}, {1.00000, 1.00000, 0.60000}, {1.00000, 1.00000, 0.60000}, {1.00000, 1.00000, 0.66667}, {1.00000, 1.00000, 0.66667}, {1.00000, 1.00000, 0.73333}, {1.00000, 1.00000, 0.73333}, {1.00000, 1.00000, 0.80000}, {1.00000, 1.00000, 0.80000}, {1.00000, 1.00000, 0.86667}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("smooth2.lasc", smooth2_lasc); static RGBColor random_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.70588, 0.00000, 0.90196}, {0.70588, 0.00000, 0.90196}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.51765}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98431, 0.81176, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.78431, 0.47059, 1.00000}, {0.78431, 0.47059, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.76863, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 0.89804, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 0.86275, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.70588, 1.00000}, {0.92157, 0.61961, 1.00000}, {0.78431, 0.47059, 1.00000}, {0.78431, 0.47059, 1.00000}, {0.78431, 0.47059, 1.00000}, {0.78431, 0.47059, 1.00000}, {0.78431, 0.47059, 1.00000}, {0.78431, 0.47059, 1.00000}, {0.78431, 0.47059, 1.00000}, {0.78431, 0.47059, 1.00000}, {0.78431, 0.47059, 1.00000}, {0.65882, 0.59608, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.62745, 0.62745, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.47059, 0.78431, 1.00000}, {0.26275, 0.87843, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 0.74118}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.65490}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.36078, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.98431, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {0.99608, 0.97647, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98431, 0.85098, 0.00000}, {0.98824, 0.77647, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.72549, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.36863, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.46667}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {0.91373, 0.00000, 0.97255}, {0.70588, 0.00000, 0.90196}, {0.70588, 0.00000, 0.90196}, {0.70588, 0.00000, 0.90196}, {0.70588, 0.00000, 0.90196}, {0.70588, 0.00000, 0.90196}, {0.70588, 0.00000, 0.90196}, {0.70588, 0.00000, 0.90196}, {0.70588, 0.00000, 0.90196}, {0.70588, 0.00000, 0.90196}, {0.53333, 0.00000, 0.87451}, {0.47059, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.47059, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.80392}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.13725}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, }; new ColorMapInfo("random.lasc", random_lasc); static RGBColor idl15_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.07059, 0.00392, 0.00392}, {0.14118, 0.00784, 0.01176}, {0.21176, 0.01176, 0.01961}, {0.28235, 0.01569, 0.02745}, {0.35294, 0.01961, 0.03529}, {0.42353, 0.02353, 0.04314}, {0.49804, 0.02745, 0.05098}, {0.56863, 0.03137, 0.05882}, {0.63922, 0.03529, 0.06667}, {0.70980, 0.03922, 0.07451}, {0.78039, 0.04314, 0.08235}, {0.85098, 0.04706, 0.09020}, {0.92157, 0.05098, 0.09804}, {0.99608, 0.05490, 0.10588}, {0.97647, 0.05882, 0.11373}, {0.95686, 0.06275, 0.12157}, {0.93725, 0.06667, 0.12941}, {0.91765, 0.07059, 0.13725}, {0.89804, 0.07451, 0.14510}, {0.87451, 0.07843, 0.15294}, {0.85490, 0.08235, 0.16078}, {0.83529, 0.08627, 0.16863}, {0.81569, 0.09020, 0.17647}, {0.79608, 0.09412, 0.18431}, {0.77255, 0.09804, 0.19216}, {0.75294, 0.10196, 0.20000}, {0.73333, 0.10588, 0.20784}, {0.71373, 0.10980, 0.21569}, {0.69412, 0.11373, 0.22353}, {0.67451, 0.11765, 0.23137}, {0.65098, 0.12157, 0.23922}, {0.63137, 0.12549, 0.24706}, {0.61176, 0.12941, 0.25490}, {0.59216, 0.13333, 0.26275}, {0.57255, 0.13725, 0.27059}, {0.54902, 0.14118, 0.27843}, {0.52941, 0.14510, 0.28627}, {0.50980, 0.14902, 0.29412}, {0.49020, 0.15294, 0.30196}, {0.47059, 0.15686, 0.30980}, {0.45098, 0.16078, 0.31765}, {0.42745, 0.16471, 0.32549}, {0.40784, 0.16863, 0.33333}, {0.38824, 0.17255, 0.34118}, {0.36863, 0.17647, 0.34902}, {0.34902, 0.18039, 0.35686}, {0.32549, 0.18431, 0.36471}, {0.30588, 0.18824, 0.37255}, {0.28627, 0.19216, 0.38039}, {0.26667, 0.19608, 0.38824}, {0.24706, 0.20000, 0.39608}, {0.22745, 0.20392, 0.40392}, {0.20392, 0.20784, 0.41176}, {0.18431, 0.21176, 0.41961}, {0.16471, 0.21569, 0.42745}, {0.14510, 0.21961, 0.43529}, {0.12549, 0.22353, 0.44314}, {0.10196, 0.22745, 0.45098}, {0.08235, 0.23137, 0.45882}, {0.06275, 0.23529, 0.46667}, {0.04314, 0.23922, 0.47451}, {0.02353, 0.24314, 0.48235}, {0.00000, 0.24706, 0.49020}, {0.25098, 0.25098, 0.49804}, {0.25490, 0.25490, 0.50588}, {0.25882, 0.25882, 0.51373}, {0.26275, 0.26275, 0.52157}, {0.26667, 0.26667, 0.52941}, {0.27059, 0.27059, 0.53725}, {0.27451, 0.27451, 0.54510}, {0.27843, 0.27843, 0.55294}, {0.28235, 0.28235, 0.56078}, {0.28627, 0.28627, 0.56863}, {0.29020, 0.29020, 0.57647}, {0.29412, 0.29412, 0.58431}, {0.29804, 0.29804, 0.59216}, {0.30196, 0.30196, 0.60000}, {0.30588, 0.30588, 0.60784}, {0.30980, 0.30980, 0.61569}, {0.31373, 0.31373, 0.62353}, {0.31765, 0.31765, 0.63137}, {0.32157, 0.32157, 0.63922}, {0.32549, 0.32549, 0.64706}, {0.32941, 0.32941, 0.65490}, {0.33333, 0.33333, 0.66275}, {0.33725, 0.33725, 0.67059}, {0.34118, 0.34118, 0.67843}, {0.34510, 0.34510, 0.68627}, {0.34902, 0.34902, 0.69412}, {0.35294, 0.35294, 0.70196}, {0.35686, 0.35686, 0.70980}, {0.36078, 0.36078, 0.71765}, {0.36471, 0.36471, 0.72549}, {0.36863, 0.36863, 0.73333}, {0.37255, 0.37255, 0.74118}, {0.37647, 0.37647, 0.74902}, {0.38039, 0.38039, 0.75686}, {0.38431, 0.38431, 0.76471}, {0.38824, 0.38824, 0.77255}, {0.39216, 0.39216, 0.78039}, {0.39608, 0.39608, 0.78824}, {0.40000, 0.40000, 0.79608}, {0.40392, 0.40392, 0.80392}, {0.40784, 0.40784, 0.81176}, {0.41176, 0.41176, 0.81961}, {0.41569, 0.41569, 0.82745}, {0.41961, 0.41961, 0.83529}, {0.42353, 0.42353, 0.84314}, {0.42745, 0.42745, 0.85098}, {0.43137, 0.43137, 0.85882}, {0.43529, 0.43529, 0.86667}, {0.43922, 0.43922, 0.87451}, {0.44314, 0.44314, 0.88235}, {0.44706, 0.44706, 0.89020}, {0.45098, 0.45098, 0.89804}, {0.45490, 0.45490, 0.90588}, {0.45882, 0.45882, 0.91373}, {0.46275, 0.46275, 0.92157}, {0.46667, 0.46667, 0.92941}, {0.47059, 0.47059, 0.93725}, {0.47451, 0.47451, 0.94510}, {0.47843, 0.47843, 0.95294}, {0.48235, 0.48235, 0.96078}, {0.48627, 0.48627, 0.96863}, {0.49020, 0.49020, 0.97647}, {0.49412, 0.49412, 0.98431}, {0.49804, 0.49804, 0.99216}, {0.50196, 0.50196, 1.00000}, {0.50588, 0.50588, 0.98431}, {0.50980, 0.50980, 0.96863}, {0.51373, 0.51373, 0.95294}, {0.51765, 0.51765, 0.93333}, {0.52157, 0.52157, 0.91765}, {0.52549, 0.52549, 0.90196}, {0.52941, 0.52941, 0.88627}, {0.53333, 0.53333, 0.86667}, {0.53725, 0.53725, 0.85098}, {0.54118, 0.54118, 0.83529}, {0.54510, 0.54510, 0.81961}, {0.54902, 0.54902, 0.80000}, {0.55294, 0.55294, 0.78431}, {0.55686, 0.55686, 0.76863}, {0.56078, 0.56078, 0.75294}, {0.56471, 0.56471, 0.73333}, {0.56863, 0.56863, 0.71765}, {0.57255, 0.57255, 0.70196}, {0.57647, 0.57647, 0.68627}, {0.58039, 0.58039, 0.66667}, {0.58431, 0.58431, 0.65098}, {0.58824, 0.58824, 0.63529}, {0.59216, 0.59216, 0.61961}, {0.59608, 0.59608, 0.60000}, {0.60000, 0.60000, 0.58431}, {0.60392, 0.60392, 0.56863}, {0.60784, 0.60784, 0.55294}, {0.61176, 0.61176, 0.53333}, {0.61569, 0.61569, 0.51765}, {0.61961, 0.61961, 0.50196}, {0.62353, 0.62353, 0.48627}, {0.62745, 0.62745, 0.46667}, {0.63137, 0.63137, 0.45098}, {0.63529, 0.63529, 0.43529}, {0.63922, 0.63922, 0.41961}, {0.64314, 0.64314, 0.40000}, {0.64706, 0.64706, 0.38431}, {0.65098, 0.65098, 0.36863}, {0.65490, 0.65490, 0.35294}, {0.65882, 0.65882, 0.33333}, {0.66275, 0.66275, 0.31765}, {0.66667, 0.66667, 0.30196}, {0.67059, 0.67059, 0.28627}, {0.67451, 0.67451, 0.26667}, {0.67843, 0.67843, 0.25098}, {0.68235, 0.68235, 0.23529}, {0.68627, 0.68627, 0.21961}, {0.69020, 0.69020, 0.20000}, {0.69412, 0.69412, 0.18431}, {0.69804, 0.69804, 0.16863}, {0.70196, 0.70196, 0.15294}, {0.70588, 0.70588, 0.13333}, {0.70980, 0.70980, 0.11765}, {0.71373, 0.71373, 0.10196}, {0.71765, 0.71765, 0.08627}, {0.72157, 0.72157, 0.06667}, {0.72549, 0.72549, 0.05098}, {0.72941, 0.72941, 0.03529}, {0.73333, 0.73333, 0.01961}, {0.73725, 0.73725, 0.00000}, {0.74118, 0.74118, 0.01176}, {0.74510, 0.74510, 0.02745}, {0.74902, 0.74902, 0.04314}, {0.75294, 0.75294, 0.05882}, {0.75686, 0.75686, 0.07451}, {0.76078, 0.76078, 0.08627}, {0.76471, 0.76471, 0.10196}, {0.76863, 0.76863, 0.11765}, {0.77255, 0.77255, 0.13333}, {0.77647, 0.77647, 0.14902}, {0.78039, 0.78039, 0.16078}, {0.78431, 0.78431, 0.17647}, {0.78824, 0.78824, 0.19216}, {0.79216, 0.79216, 0.20784}, {0.79608, 0.79608, 0.22353}, {0.80000, 0.80000, 0.23529}, {0.80392, 0.80392, 0.25098}, {0.80784, 0.80784, 0.26667}, {0.81176, 0.81176, 0.28235}, {0.81569, 0.81569, 0.29804}, {0.81961, 0.81961, 0.30980}, {0.82353, 0.82353, 0.32549}, {0.82745, 0.82745, 0.34118}, {0.83137, 0.83137, 0.35686}, {0.83529, 0.83529, 0.37255}, {0.83922, 0.83922, 0.38431}, {0.84314, 0.84314, 0.40000}, {0.84706, 0.84706, 0.41569}, {0.85098, 0.85098, 0.43137}, {0.85490, 0.85490, 0.44706}, {0.85882, 0.85882, 0.45882}, {0.86275, 0.86275, 0.47451}, {0.86667, 0.86667, 0.49020}, {0.87059, 0.87059, 0.50588}, {0.87451, 0.87451, 0.52157}, {0.87843, 0.87843, 0.53725}, {0.88235, 0.88235, 0.54902}, {0.88627, 0.88627, 0.56471}, {0.89020, 0.89020, 0.58039}, {0.89412, 0.89412, 0.59608}, {0.89804, 0.89804, 0.61176}, {0.90196, 0.90196, 0.62353}, {0.90588, 0.90588, 0.63922}, {0.90980, 0.90980, 0.65490}, {0.91373, 0.91373, 0.67059}, {0.91765, 0.91765, 0.68627}, {0.92157, 0.92157, 0.69804}, {0.92549, 0.92549, 0.71373}, {0.92941, 0.92941, 0.72941}, {0.93333, 0.93333, 0.74510}, {0.93725, 0.93725, 0.76078}, {0.94118, 0.94118, 0.77255}, {0.94510, 0.94510, 0.78824}, {0.94902, 0.94902, 0.80392}, {0.95294, 0.95294, 0.81961}, {0.95686, 0.95686, 0.83529}, {0.96078, 0.96078, 0.84706}, {0.96471, 0.96471, 0.86275}, {0.96863, 0.96863, 0.87843}, {0.97255, 0.97255, 0.89412}, {0.97647, 0.97647, 0.90980}, {0.98039, 0.98039, 0.92157}, {0.98431, 0.98431, 0.93725}, {0.98824, 0.98824, 0.95294}, {0.99216, 0.99216, 0.96863}, {0.99608, 0.99608, 0.98431}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("idl15.lasc", idl15_lasc); static RGBColor blue_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00392}, {0.00000, 0.00000, 0.00784}, {0.00000, 0.00000, 0.01176}, {0.00000, 0.00000, 0.01569}, {0.00000, 0.00000, 0.01961}, {0.00000, 0.00000, 0.02353}, {0.00000, 0.00000, 0.02745}, {0.00000, 0.00000, 0.03137}, {0.00000, 0.00000, 0.03529}, {0.00000, 0.00000, 0.03922}, {0.00000, 0.00000, 0.04314}, {0.00000, 0.00000, 0.04706}, {0.00000, 0.00000, 0.05098}, {0.00000, 0.00000, 0.05490}, {0.00000, 0.00000, 0.05882}, {0.00000, 0.00000, 0.06275}, {0.00000, 0.00000, 0.06667}, {0.00000, 0.00000, 0.07059}, {0.00000, 0.00000, 0.07451}, {0.00000, 0.00000, 0.07843}, {0.00000, 0.00000, 0.08235}, {0.00000, 0.00000, 0.08627}, {0.00000, 0.00000, 0.09020}, {0.00000, 0.00000, 0.09412}, {0.00000, 0.00000, 0.09804}, {0.00000, 0.00000, 0.10196}, {0.00000, 0.00000, 0.10588}, {0.00000, 0.00000, 0.10980}, {0.00000, 0.00000, 0.11373}, {0.00000, 0.00000, 0.11765}, {0.00000, 0.00000, 0.12157}, {0.00000, 0.00000, 0.12549}, {0.00000, 0.00000, 0.12941}, {0.00000, 0.00000, 0.13333}, {0.00000, 0.00000, 0.13725}, {0.00000, 0.00000, 0.14118}, {0.00000, 0.00000, 0.14510}, {0.00000, 0.00000, 0.14902}, {0.00000, 0.00000, 0.15294}, {0.00000, 0.00000, 0.15686}, {0.00000, 0.00000, 0.16078}, {0.00000, 0.00000, 0.16471}, {0.00000, 0.00000, 0.16863}, {0.00000, 0.00000, 0.17255}, {0.00000, 0.00000, 0.17647}, {0.00000, 0.00000, 0.18039}, {0.00000, 0.00000, 0.18431}, {0.00000, 0.00000, 0.18824}, {0.00000, 0.00000, 0.19216}, {0.00000, 0.00000, 0.19608}, {0.00000, 0.00000, 0.20000}, {0.00000, 0.00000, 0.20392}, {0.00000, 0.00000, 0.20784}, {0.00000, 0.00000, 0.21176}, {0.00000, 0.00000, 0.21569}, {0.00000, 0.00000, 0.21961}, {0.00000, 0.00000, 0.22353}, {0.00000, 0.00000, 0.22745}, {0.00000, 0.00000, 0.23137}, {0.00000, 0.00000, 0.23529}, {0.00000, 0.00000, 0.23922}, {0.00000, 0.00000, 0.24314}, {0.00000, 0.00000, 0.24706}, {0.00000, 0.00000, 0.25098}, {0.00000, 0.00000, 0.25490}, {0.00000, 0.00000, 0.25882}, {0.00000, 0.00000, 0.26275}, {0.00000, 0.00000, 0.26667}, {0.00000, 0.00000, 0.27059}, {0.00000, 0.00000, 0.27451}, {0.00000, 0.00000, 0.27843}, {0.00000, 0.00000, 0.28235}, {0.00000, 0.00000, 0.28627}, {0.00000, 0.00000, 0.29020}, {0.00000, 0.00000, 0.29412}, {0.00000, 0.00000, 0.29804}, {0.00000, 0.00000, 0.30196}, {0.00000, 0.00000, 0.30588}, {0.00000, 0.00000, 0.30980}, {0.00000, 0.00000, 0.31373}, {0.00000, 0.00000, 0.31765}, {0.00000, 0.00000, 0.32157}, {0.00000, 0.00000, 0.32549}, {0.00000, 0.00000, 0.32941}, {0.00000, 0.00000, 0.33333}, {0.00000, 0.00000, 0.33725}, {0.00000, 0.00000, 0.34118}, {0.00000, 0.00000, 0.34510}, {0.00000, 0.00000, 0.34902}, {0.00000, 0.00000, 0.35294}, {0.00000, 0.00000, 0.35686}, {0.00000, 0.00000, 0.36078}, {0.00000, 0.00000, 0.36471}, {0.00000, 0.00000, 0.36863}, {0.00000, 0.00000, 0.37255}, {0.00000, 0.00000, 0.37647}, {0.00000, 0.00000, 0.38039}, {0.00000, 0.00000, 0.38431}, {0.00000, 0.00000, 0.38824}, {0.00000, 0.00000, 0.39216}, {0.00000, 0.00000, 0.39608}, {0.00000, 0.00000, 0.40000}, {0.00000, 0.00000, 0.40392}, {0.00000, 0.00000, 0.40784}, {0.00000, 0.00000, 0.41176}, {0.00000, 0.00000, 0.41569}, {0.00000, 0.00000, 0.41961}, {0.00000, 0.00000, 0.42353}, {0.00000, 0.00000, 0.42745}, {0.00000, 0.00000, 0.43137}, {0.00000, 0.00000, 0.43529}, {0.00000, 0.00000, 0.43922}, {0.00000, 0.00000, 0.44314}, {0.00000, 0.00000, 0.44706}, {0.00000, 0.00000, 0.45098}, {0.00000, 0.00000, 0.45490}, {0.00000, 0.00000, 0.45882}, {0.00000, 0.00000, 0.46275}, {0.00000, 0.00000, 0.46667}, {0.00000, 0.00000, 0.47059}, {0.00000, 0.00000, 0.47451}, {0.00000, 0.00000, 0.47843}, {0.00000, 0.00000, 0.48235}, {0.00000, 0.00000, 0.48627}, {0.00000, 0.00000, 0.49020}, {0.00000, 0.00000, 0.49412}, {0.00000, 0.00000, 0.49804}, {0.00000, 0.00000, 0.50196}, {0.00000, 0.00000, 0.50588}, {0.00000, 0.00000, 0.50980}, {0.00000, 0.00000, 0.51373}, {0.00000, 0.00000, 0.51765}, {0.00000, 0.00000, 0.52157}, {0.00000, 0.00000, 0.52549}, {0.00000, 0.00000, 0.52941}, {0.00000, 0.00000, 0.53333}, {0.00000, 0.00000, 0.53725}, {0.00000, 0.00000, 0.54118}, {0.00000, 0.00000, 0.54510}, {0.00000, 0.00000, 0.54902}, {0.00000, 0.00000, 0.55294}, {0.00000, 0.00000, 0.55686}, {0.00000, 0.00000, 0.56078}, {0.00000, 0.00000, 0.56471}, {0.00000, 0.00000, 0.56863}, {0.00000, 0.00000, 0.57255}, {0.00000, 0.00000, 0.57647}, {0.00000, 0.00000, 0.58039}, {0.00000, 0.00000, 0.58431}, {0.00000, 0.00000, 0.58824}, {0.00000, 0.00000, 0.59216}, {0.00000, 0.00000, 0.59608}, {0.00000, 0.00000, 0.60000}, {0.00000, 0.00000, 0.60392}, {0.00000, 0.00000, 0.60784}, {0.00000, 0.00000, 0.61176}, {0.00000, 0.00000, 0.61569}, {0.00000, 0.00000, 0.61961}, {0.00000, 0.00000, 0.62353}, {0.00000, 0.00000, 0.62745}, {0.00000, 0.00000, 0.63137}, {0.00000, 0.00000, 0.63529}, {0.00000, 0.00000, 0.63922}, {0.00000, 0.00000, 0.64314}, {0.00000, 0.00000, 0.64706}, {0.00000, 0.00000, 0.65098}, {0.00000, 0.00000, 0.65490}, {0.00000, 0.00000, 0.65882}, {0.00000, 0.00000, 0.66275}, {0.00000, 0.00000, 0.66667}, {0.00000, 0.00000, 0.67059}, {0.00000, 0.00000, 0.67451}, {0.00000, 0.00000, 0.67843}, {0.00000, 0.00000, 0.68235}, {0.00000, 0.00000, 0.68627}, {0.00000, 0.00000, 0.69020}, {0.00000, 0.00000, 0.69412}, {0.00000, 0.00000, 0.69804}, {0.00000, 0.00000, 0.70196}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.70980}, {0.00000, 0.00000, 0.71373}, {0.00000, 0.00000, 0.71765}, {0.00000, 0.00000, 0.72157}, {0.00000, 0.00000, 0.72549}, {0.00000, 0.00000, 0.72941}, {0.00000, 0.00000, 0.73333}, {0.00000, 0.00000, 0.73725}, {0.00000, 0.00000, 0.74118}, {0.00000, 0.00000, 0.74510}, {0.00000, 0.00000, 0.74902}, {0.00000, 0.00000, 0.75294}, {0.00000, 0.00000, 0.75686}, {0.00000, 0.00000, 0.76078}, {0.00000, 0.00000, 0.76471}, {0.00000, 0.00000, 0.76863}, {0.00000, 0.00000, 0.77255}, {0.00000, 0.00000, 0.77647}, {0.00000, 0.00000, 0.78039}, {0.00000, 0.00000, 0.78431}, {0.00000, 0.00000, 0.78824}, {0.00000, 0.00000, 0.79216}, {0.00000, 0.00000, 0.79608}, {0.00000, 0.00000, 0.80000}, {0.00000, 0.00000, 0.80392}, {0.00000, 0.00000, 0.80784}, {0.00000, 0.00000, 0.81176}, {0.00000, 0.00000, 0.81569}, {0.00000, 0.00000, 0.81961}, {0.00000, 0.00000, 0.82353}, {0.00000, 0.00000, 0.82745}, {0.00000, 0.00000, 0.83137}, {0.00000, 0.00000, 0.83529}, {0.00000, 0.00000, 0.83922}, {0.00000, 0.00000, 0.84314}, {0.00000, 0.00000, 0.84706}, {0.00000, 0.00000, 0.85098}, {0.00000, 0.00000, 0.85490}, {0.00000, 0.00000, 0.85882}, {0.00000, 0.00000, 0.86275}, {0.00000, 0.00000, 0.86667}, {0.00000, 0.00000, 0.87059}, {0.00000, 0.00000, 0.87451}, {0.00000, 0.00000, 0.87843}, {0.00000, 0.00000, 0.88235}, {0.00000, 0.00000, 0.88627}, {0.00000, 0.00000, 0.89020}, {0.00000, 0.00000, 0.89412}, {0.00000, 0.00000, 0.89804}, {0.00000, 0.00000, 0.90196}, {0.00000, 0.00000, 0.90588}, {0.00000, 0.00000, 0.90980}, {0.00000, 0.00000, 0.91373}, {0.00000, 0.00000, 0.91765}, {0.00000, 0.00000, 0.92157}, {0.00000, 0.00000, 0.92549}, {0.00000, 0.00000, 0.92941}, {0.00000, 0.00000, 0.93333}, {0.00000, 0.00000, 0.93725}, {0.00000, 0.00000, 0.94118}, {0.00000, 0.00000, 0.94510}, {0.00000, 0.00000, 0.94902}, {0.00000, 0.00000, 0.95294}, {0.00000, 0.00000, 0.95686}, {0.00000, 0.00000, 0.96078}, {0.00000, 0.00000, 0.96471}, {0.00000, 0.00000, 0.96863}, {0.00000, 0.00000, 0.97255}, {0.00000, 0.00000, 0.97647}, {0.00000, 0.00000, 0.98039}, {0.00000, 0.00000, 0.98431}, {0.00000, 0.00000, 0.98824}, {0.00000, 0.00000, 0.99216}, {0.00000, 0.00000, 0.99608}, {0.00000, 0.00000, 1.00000}, }; new ColorMapInfo("blue.lasc", blue_lasc); static RGBColor stairs8_lasc[] = { {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {0.76471, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("stairs8.lasc", stairs8_lasc); static RGBColor backgr_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.01587, 0.01587, 0.01587}, {0.03174, 0.03174, 0.03174}, {0.04761, 0.04761, 0.04761}, {0.06348, 0.06348, 0.06348}, {0.07935, 0.07935, 0.07935}, {0.09522, 0.09522, 0.09522}, {0.11109, 0.11109, 0.11109}, {0.12696, 0.12696, 0.12696}, {0.14283, 0.14283, 0.14283}, {0.15870, 0.15870, 0.15870}, {0.17457, 0.17457, 0.17457}, {0.19044, 0.19044, 0.19044}, {0.20631, 0.20631, 0.20631}, {0.22218, 0.22218, 0.22218}, {0.23805, 0.23805, 0.23805}, {0.25392, 0.25392, 0.25392}, {0.26979, 0.26979, 0.26979}, {0.28566, 0.28566, 0.28566}, {0.30153, 0.30153, 0.30153}, {0.31740, 0.31740, 0.31740}, {0.33327, 0.33327, 0.33327}, {0.34914, 0.34914, 0.34914}, {0.36501, 0.36501, 0.36501}, {0.38088, 0.38088, 0.38088}, {0.39675, 0.39675, 0.39675}, {0.41262, 0.41262, 0.41262}, {0.42849, 0.42849, 0.42849}, {0.44436, 0.44436, 0.44436}, {0.46023, 0.46023, 0.46023}, {0.47610, 0.47610, 0.47610}, {0.49197, 0.49197, 0.49197}, {0.50784, 0.50784, 0.50784}, {0.52371, 0.52371, 0.52371}, {0.53958, 0.53958, 0.53958}, {0.55545, 0.55545, 0.55545}, {0.57132, 0.57132, 0.57132}, {0.58719, 0.58719, 0.58719}, {0.60306, 0.60306, 0.60306}, {0.61893, 0.61893, 0.61893}, {0.63480, 0.63480, 0.63480}, {0.65067, 0.65067, 0.65067}, {0.66654, 0.66654, 0.66654}, {0.68241, 0.68241, 0.68241}, {0.69828, 0.69828, 0.69828}, {0.71415, 0.71415, 0.71415}, {0.73002, 0.73002, 0.73002}, {0.74589, 0.74589, 0.74589}, {0.76176, 0.76176, 0.76176}, {0.77763, 0.77763, 0.77763}, {0.79350, 0.79350, 0.79350}, {0.80937, 0.80937, 0.80937}, {0.82524, 0.82524, 0.82524}, {0.84111, 0.84111, 0.84111}, {0.85698, 0.85698, 0.85698}, {0.87285, 0.87285, 0.87285}, {0.88872, 0.88872, 0.88872}, {0.90459, 0.90459, 0.90459}, {0.92046, 0.92046, 0.92046}, {0.93633, 0.93633, 0.93633}, {0.95220, 0.95220, 0.95220}, {0.96807, 0.96807, 0.96807}, {0.98394, 0.98394, 0.98394}, {0.99981, 0.99981, 0.99981}, {0.00000, 0.00000, 0.99981}, {0.00000, 0.01587, 0.98394}, {0.00000, 0.03174, 0.96807}, {0.00000, 0.04761, 0.95220}, {0.00000, 0.06348, 0.93633}, {0.00000, 0.07935, 0.92046}, {0.00000, 0.09522, 0.90459}, {0.00000, 0.11109, 0.88872}, {0.00000, 0.12696, 0.87285}, {0.00000, 0.14283, 0.85698}, {0.00000, 0.15870, 0.84111}, {0.00000, 0.17457, 0.82524}, {0.00000, 0.19044, 0.80937}, {0.00000, 0.20631, 0.79350}, {0.00000, 0.22218, 0.77763}, {0.00000, 0.23805, 0.76176}, {0.00000, 0.25392, 0.74589}, {0.00000, 0.26979, 0.73002}, {0.00000, 0.28566, 0.71415}, {0.00000, 0.30153, 0.69828}, {0.00000, 0.31740, 0.68241}, {0.00000, 0.33327, 0.66654}, {0.00000, 0.34914, 0.65067}, {0.00000, 0.36501, 0.63480}, {0.00000, 0.38088, 0.61893}, {0.00000, 0.39675, 0.60306}, {0.00000, 0.41262, 0.58719}, {0.00000, 0.42849, 0.57132}, {0.00000, 0.44436, 0.55545}, {0.00000, 0.46023, 0.53958}, {0.00000, 0.47610, 0.52371}, {0.00000, 0.49197, 0.50784}, {0.00000, 0.50784, 0.49197}, {0.00000, 0.52371, 0.47610}, {0.00000, 0.53958, 0.46023}, {0.00000, 0.55545, 0.44436}, {0.00000, 0.57132, 0.42849}, {0.00000, 0.58719, 0.41262}, {0.00000, 0.60306, 0.39675}, {0.00000, 0.61893, 0.38088}, {0.00000, 0.63480, 0.36501}, {0.00000, 0.65067, 0.34914}, {0.00000, 0.66654, 0.33327}, {0.00000, 0.68241, 0.31740}, {0.00000, 0.69828, 0.30153}, {0.00000, 0.71415, 0.28566}, {0.00000, 0.73002, 0.26979}, {0.00000, 0.74589, 0.25392}, {0.00000, 0.76176, 0.23805}, {0.00000, 0.77763, 0.22218}, {0.00000, 0.79350, 0.20631}, {0.00000, 0.80937, 0.19044}, {0.00000, 0.82524, 0.17457}, {0.00000, 0.84111, 0.15870}, {0.00000, 0.85698, 0.14283}, {0.00000, 0.87285, 0.12696}, {0.00000, 0.88872, 0.11109}, {0.00000, 0.90459, 0.09522}, {0.00000, 0.92046, 0.07935}, {0.00000, 0.93633, 0.06348}, {0.00000, 0.95220, 0.04761}, {0.00000, 0.96807, 0.03174}, {0.00000, 0.98394, 0.01587}, {0.00000, 0.99981, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.01587, 1.00000, 0.00000}, {0.03174, 1.00000, 0.00000}, {0.04761, 1.00000, 0.00000}, {0.06348, 1.00000, 0.00000}, {0.07935, 1.00000, 0.00000}, {0.09522, 1.00000, 0.00000}, {0.11109, 1.00000, 0.00000}, {0.12696, 1.00000, 0.00000}, {0.14283, 1.00000, 0.00000}, {0.15870, 1.00000, 0.00000}, {0.17457, 1.00000, 0.00000}, {0.19044, 1.00000, 0.00000}, {0.20631, 1.00000, 0.00000}, {0.22218, 1.00000, 0.00000}, {0.23805, 1.00000, 0.00000}, {0.25392, 1.00000, 0.00000}, {0.26979, 1.00000, 0.00000}, {0.28566, 1.00000, 0.00000}, {0.30153, 1.00000, 0.00000}, {0.31740, 1.00000, 0.00000}, {0.33327, 1.00000, 0.00000}, {0.34914, 1.00000, 0.00000}, {0.36501, 1.00000, 0.00000}, {0.38088, 1.00000, 0.00000}, {0.39675, 1.00000, 0.00000}, {0.41262, 1.00000, 0.00000}, {0.42849, 1.00000, 0.00000}, {0.44436, 1.00000, 0.00000}, {0.46023, 1.00000, 0.00000}, {0.47610, 1.00000, 0.00000}, {0.49197, 1.00000, 0.00000}, {0.50784, 1.00000, 0.00000}, {0.52371, 1.00000, 0.00000}, {0.53958, 1.00000, 0.00000}, {0.55545, 1.00000, 0.00000}, {0.57132, 1.00000, 0.00000}, {0.58719, 1.00000, 0.00000}, {0.60306, 1.00000, 0.00000}, {0.61893, 1.00000, 0.00000}, {0.63480, 1.00000, 0.00000}, {0.65067, 1.00000, 0.00000}, {0.66654, 1.00000, 0.00000}, {0.68241, 1.00000, 0.00000}, {0.69828, 1.00000, 0.00000}, {0.71415, 1.00000, 0.00000}, {0.73002, 1.00000, 0.00000}, {0.74589, 1.00000, 0.00000}, {0.76176, 1.00000, 0.00000}, {0.77763, 1.00000, 0.00000}, {0.79350, 1.00000, 0.00000}, {0.80937, 1.00000, 0.00000}, {0.82524, 1.00000, 0.00000}, {0.84111, 1.00000, 0.00000}, {0.85698, 1.00000, 0.00000}, {0.87285, 1.00000, 0.00000}, {0.88872, 1.00000, 0.00000}, {0.90459, 1.00000, 0.00000}, {0.92046, 1.00000, 0.00000}, {0.93633, 1.00000, 0.00000}, {0.95220, 1.00000, 0.00000}, {0.96807, 1.00000, 0.00000}, {0.98394, 1.00000, 0.00000}, {0.99981, 1.00000, 0.00000}, {1.00000, 0.99981, 0.00000}, {1.00000, 0.98394, 0.00000}, {1.00000, 0.96807, 0.00000}, {1.00000, 0.95220, 0.00000}, {1.00000, 0.93633, 0.00000}, {1.00000, 0.92046, 0.00000}, {1.00000, 0.90459, 0.00000}, {1.00000, 0.88872, 0.00000}, {1.00000, 0.87285, 0.00000}, {1.00000, 0.85698, 0.00000}, {1.00000, 0.84111, 0.00000}, {1.00000, 0.82524, 0.00000}, {1.00000, 0.80937, 0.00000}, {1.00000, 0.79350, 0.00000}, {1.00000, 0.77763, 0.00000}, {1.00000, 0.76176, 0.00000}, {1.00000, 0.74589, 0.00000}, {1.00000, 0.73002, 0.00000}, {1.00000, 0.71415, 0.00000}, {1.00000, 0.69828, 0.00000}, {1.00000, 0.68241, 0.00000}, {1.00000, 0.66654, 0.00000}, {1.00000, 0.65067, 0.00000}, {1.00000, 0.63480, 0.00000}, {1.00000, 0.61893, 0.00000}, {1.00000, 0.60306, 0.00000}, {1.00000, 0.58719, 0.00000}, {1.00000, 0.57132, 0.00000}, {1.00000, 0.55545, 0.00000}, {1.00000, 0.53958, 0.00000}, {1.00000, 0.52371, 0.00000}, {1.00000, 0.50784, 0.00000}, {1.00000, 0.49197, 0.00000}, {1.00000, 0.47610, 0.00000}, {1.00000, 0.46023, 0.00000}, {1.00000, 0.44436, 0.00000}, {1.00000, 0.42849, 0.00000}, {1.00000, 0.41262, 0.00000}, {1.00000, 0.39675, 0.00000}, {1.00000, 0.38088, 0.00000}, {1.00000, 0.36501, 0.00000}, {1.00000, 0.34914, 0.00000}, {1.00000, 0.33327, 0.00000}, {1.00000, 0.31740, 0.00000}, {1.00000, 0.30153, 0.00000}, {1.00000, 0.28566, 0.00000}, {1.00000, 0.26979, 0.00000}, {1.00000, 0.25392, 0.00000}, {1.00000, 0.23805, 0.00000}, {1.00000, 0.22218, 0.00000}, {1.00000, 0.20631, 0.00000}, {1.00000, 0.19044, 0.00000}, {1.00000, 0.17457, 0.00000}, {1.00000, 0.15870, 0.00000}, {1.00000, 0.14283, 0.00000}, {1.00000, 0.12696, 0.00000}, {1.00000, 0.11109, 0.00000}, {1.00000, 0.09522, 0.00000}, {1.00000, 0.07935, 0.00000}, {1.00000, 0.06348, 0.00000}, {1.00000, 0.04761, 0.00000}, {1.00000, 0.03174, 0.00000}, {1.00000, 0.01587, 0.00000}, {1.00000, 0.00000, 0.00000}, }; new ColorMapInfo("backgr.lasc", backgr_lasc); static RGBColor idl11_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00000, 0.00392, 0.00392}, {0.00000, 0.00784, 0.00784}, {0.00000, 0.01176, 0.01176}, {0.00000, 0.01569, 0.01569}, {0.00000, 0.03137, 0.03137}, {0.00000, 0.04706, 0.04706}, {0.00000, 0.06275, 0.06275}, {0.00000, 0.08235, 0.08235}, {0.00000, 0.09804, 0.09804}, {0.00000, 0.11373, 0.11373}, {0.00000, 0.12941, 0.12941}, {0.00000, 0.14902, 0.14902}, {0.00000, 0.16471, 0.16471}, {0.00000, 0.18039, 0.18039}, {0.00000, 0.19608, 0.19608}, {0.00000, 0.21569, 0.21569}, {0.00000, 0.23137, 0.23137}, {0.00000, 0.24706, 0.24706}, {0.00000, 0.26275, 0.26275}, {0.00000, 0.28235, 0.28235}, {0.00000, 0.29804, 0.29804}, {0.00000, 0.31373, 0.31373}, {0.00000, 0.32941, 0.32941}, {0.00000, 0.34902, 0.34902}, {0.00000, 0.36471, 0.36471}, {0.00000, 0.38039, 0.38039}, {0.00000, 0.39608, 0.39608}, {0.00000, 0.41569, 0.41569}, {0.00000, 0.43137, 0.43137}, {0.00000, 0.44706, 0.44706}, {0.00000, 0.46275, 0.46275}, {0.00000, 0.48235, 0.48235}, {0.00000, 0.49804, 0.49804}, {0.00000, 0.51373, 0.51373}, {0.00000, 0.52941, 0.52941}, {0.00000, 0.54902, 0.54902}, {0.00000, 0.56471, 0.56471}, {0.00000, 0.58039, 0.58039}, {0.00000, 0.59608, 0.59608}, {0.00000, 0.61569, 0.61569}, {0.00000, 0.63137, 0.63137}, {0.00000, 0.64706, 0.64706}, {0.00000, 0.66275, 0.66275}, {0.00000, 0.68235, 0.68235}, {0.00000, 0.69804, 0.69804}, {0.00000, 0.71373, 0.71373}, {0.00000, 0.72941, 0.72941}, {0.00000, 0.74902, 0.74902}, {0.00000, 0.76471, 0.76471}, {0.00000, 0.78039, 0.78039}, {0.00000, 0.79608, 0.79608}, {0.00000, 0.81569, 0.81569}, {0.00000, 0.83137, 0.83137}, {0.00000, 0.84706, 0.84706}, {0.00000, 0.86275, 0.86275}, {0.00000, 0.88235, 0.88235}, {0.00000, 0.89804, 0.89804}, {0.00000, 0.91373, 0.91373}, {0.00000, 0.92941, 0.92941}, {0.00000, 0.94902, 0.94902}, {0.00000, 0.96471, 0.96471}, {0.00000, 0.98039, 0.98039}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 0.98431, 1.00000}, {0.00000, 0.96863, 1.00000}, {0.00000, 0.95294, 1.00000}, {0.00000, 0.93725, 1.00000}, {0.00000, 0.92157, 1.00000}, {0.00000, 0.90588, 1.00000}, {0.00000, 0.89020, 1.00000}, {0.00000, 0.87451, 1.00000}, {0.00000, 0.85882, 1.00000}, {0.00000, 0.84314, 1.00000}, {0.00000, 0.82745, 1.00000}, {0.00000, 0.81176, 1.00000}, {0.00000, 0.79608, 1.00000}, {0.00000, 0.78039, 1.00000}, {0.00000, 0.76471, 1.00000}, {0.00000, 0.74902, 1.00000}, {0.00000, 0.73333, 1.00000}, {0.00000, 0.71765, 1.00000}, {0.00000, 0.70196, 1.00000}, {0.00000, 0.68627, 1.00000}, {0.00000, 0.66667, 1.00000}, {0.00000, 0.65098, 1.00000}, {0.00000, 0.63529, 1.00000}, {0.00000, 0.61961, 1.00000}, {0.00000, 0.60392, 1.00000}, {0.00000, 0.58824, 1.00000}, {0.00000, 0.57255, 1.00000}, {0.00000, 0.55686, 1.00000}, {0.00000, 0.54118, 1.00000}, {0.00000, 0.52549, 1.00000}, {0.00000, 0.50980, 1.00000}, {0.00000, 0.49412, 1.00000}, {0.00000, 0.47843, 1.00000}, {0.00000, 0.46275, 1.00000}, {0.00000, 0.44706, 1.00000}, {0.00000, 0.43137, 1.00000}, {0.00000, 0.41569, 1.00000}, {0.00000, 0.40000, 1.00000}, {0.00000, 0.38431, 1.00000}, {0.00000, 0.36863, 1.00000}, {0.00000, 0.35294, 1.00000}, {0.00000, 0.33333, 1.00000}, {0.00000, 0.31765, 1.00000}, {0.00000, 0.30196, 1.00000}, {0.00000, 0.28627, 1.00000}, {0.00000, 0.27059, 1.00000}, {0.00000, 0.25490, 1.00000}, {0.00000, 0.23922, 1.00000}, {0.00000, 0.22353, 1.00000}, {0.00000, 0.20784, 1.00000}, {0.00000, 0.19216, 1.00000}, {0.00000, 0.17647, 1.00000}, {0.00000, 0.16078, 1.00000}, {0.00000, 0.14510, 1.00000}, {0.00000, 0.12941, 1.00000}, {0.00000, 0.11373, 1.00000}, {0.00000, 0.09804, 1.00000}, {0.00000, 0.08235, 1.00000}, {0.00000, 0.06667, 1.00000}, {0.00000, 0.05098, 1.00000}, {0.00000, 0.03529, 1.00000}, {0.00000, 0.01961, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.01569, 0.00000, 1.00000}, {0.03137, 0.00000, 1.00000}, {0.04706, 0.00000, 1.00000}, {0.06275, 0.00000, 1.00000}, {0.07843, 0.00000, 1.00000}, {0.09412, 0.00000, 1.00000}, {0.10980, 0.00000, 1.00000}, {0.12549, 0.00000, 1.00000}, {0.14118, 0.00000, 1.00000}, {0.15686, 0.00000, 1.00000}, {0.17255, 0.00000, 1.00000}, {0.18824, 0.00000, 1.00000}, {0.20392, 0.00000, 1.00000}, {0.21961, 0.00000, 1.00000}, {0.23529, 0.00000, 1.00000}, {0.25098, 0.00000, 1.00000}, {0.26667, 0.00000, 1.00000}, {0.28235, 0.00000, 1.00000}, {0.29804, 0.00000, 1.00000}, {0.31373, 0.00000, 1.00000}, {0.33333, 0.00000, 1.00000}, {0.34902, 0.00000, 1.00000}, {0.36471, 0.00000, 1.00000}, {0.38039, 0.00000, 1.00000}, {0.39608, 0.00000, 1.00000}, {0.41176, 0.00000, 1.00000}, {0.42745, 0.00000, 1.00000}, {0.44314, 0.00000, 1.00000}, {0.45882, 0.00000, 1.00000}, {0.47451, 0.00000, 1.00000}, {0.49020, 0.00000, 1.00000}, {0.50588, 0.00000, 1.00000}, {0.52157, 0.00000, 1.00000}, {0.53725, 0.00000, 1.00000}, {0.55294, 0.00000, 1.00000}, {0.56863, 0.00000, 1.00000}, {0.58431, 0.00000, 1.00000}, {0.60000, 0.00000, 1.00000}, {0.61569, 0.00000, 1.00000}, {0.63137, 0.00000, 1.00000}, {0.64706, 0.00000, 1.00000}, {0.66667, 0.00000, 1.00000}, {0.68235, 0.00000, 1.00000}, {0.69804, 0.00000, 1.00000}, {0.71373, 0.00000, 1.00000}, {0.72941, 0.00000, 1.00000}, {0.74510, 0.00000, 1.00000}, {0.76078, 0.00000, 1.00000}, {0.77647, 0.00000, 1.00000}, {0.79216, 0.00000, 1.00000}, {0.80784, 0.00000, 1.00000}, {0.82353, 0.00000, 1.00000}, {0.83922, 0.00000, 1.00000}, {0.85490, 0.00000, 1.00000}, {0.87059, 0.00000, 1.00000}, {0.88627, 0.00000, 1.00000}, {0.90196, 0.00000, 1.00000}, {0.91765, 0.00000, 1.00000}, {0.93333, 0.00000, 1.00000}, {0.94902, 0.00000, 1.00000}, {0.96471, 0.00000, 1.00000}, {0.98039, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.00000, 0.98431}, {1.00000, 0.00000, 0.96863}, {1.00000, 0.00000, 0.95294}, {1.00000, 0.00000, 0.93725}, {1.00000, 0.00000, 0.92157}, {1.00000, 0.00000, 0.90588}, {1.00000, 0.00000, 0.89020}, {1.00000, 0.00000, 0.87451}, {1.00000, 0.00000, 0.85490}, {1.00000, 0.00000, 0.83922}, {1.00000, 0.00000, 0.82353}, {1.00000, 0.00000, 0.80784}, {1.00000, 0.00000, 0.79216}, {1.00000, 0.00000, 0.77647}, {1.00000, 0.00000, 0.76078}, {1.00000, 0.00000, 0.74510}, {1.00000, 0.00000, 0.72941}, {1.00000, 0.00000, 0.70980}, {1.00000, 0.00000, 0.69412}, {1.00000, 0.00000, 0.67843}, {1.00000, 0.00000, 0.66275}, {1.00000, 0.00000, 0.64706}, {1.00000, 0.00000, 0.63137}, {1.00000, 0.00000, 0.61569}, {1.00000, 0.00000, 0.60000}, {1.00000, 0.00000, 0.58431}, {1.00000, 0.00000, 0.56471}, {1.00000, 0.00000, 0.54902}, {1.00000, 0.00000, 0.53333}, {1.00000, 0.00000, 0.51765}, {1.00000, 0.00000, 0.50196}, {1.00000, 0.00000, 0.48627}, {1.00000, 0.00000, 0.47059}, {1.00000, 0.00000, 0.45490}, {1.00000, 0.00000, 0.43922}, {1.00000, 0.00000, 0.41961}, {1.00000, 0.00000, 0.40392}, {1.00000, 0.00000, 0.38824}, {1.00000, 0.00000, 0.37255}, {1.00000, 0.00000, 0.35686}, {1.00000, 0.00000, 0.34118}, {1.00000, 0.00000, 0.32549}, {1.00000, 0.00000, 0.30980}, {1.00000, 0.00000, 0.29412}, {1.00000, 0.00000, 0.27451}, {1.00000, 0.00000, 0.25882}, {1.00000, 0.00000, 0.24314}, {1.00000, 0.00000, 0.22745}, {1.00000, 0.00000, 0.21176}, {1.00000, 0.00000, 0.19608}, {1.00000, 0.00000, 0.18039}, {1.00000, 0.00000, 0.16471}, {1.00000, 0.00000, 0.14902}, {1.00000, 0.00000, 0.12941}, {1.00000, 0.00000, 0.11373}, {1.00000, 0.00000, 0.09804}, {1.00000, 0.00000, 0.08235}, {1.00000, 0.00000, 0.06667}, {1.00000, 0.00000, 0.05098}, {1.00000, 0.00000, 0.03529}, {1.00000, 0.00000, 0.01961}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, }; new ColorMapInfo("idl11.lasc", idl11_lasc); static RGBColor idl4_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00784}, {0.00000, 0.00000, 0.01569}, {0.00000, 0.00000, 0.02353}, {0.00000, 0.00000, 0.03137}, {0.00000, 0.00000, 0.03922}, {0.00000, 0.00000, 0.04706}, {0.00000, 0.00000, 0.05490}, {0.00000, 0.00000, 0.06275}, {0.00000, 0.00000, 0.07059}, {0.00000, 0.00000, 0.07843}, {0.00000, 0.00000, 0.08627}, {0.00000, 0.00000, 0.09804}, {0.00000, 0.00000, 0.10588}, {0.00000, 0.00000, 0.11373}, {0.00000, 0.00000, 0.12157}, {0.00000, 0.00000, 0.12941}, {0.00000, 0.00000, 0.13725}, {0.00000, 0.00000, 0.14510}, {0.00000, 0.00000, 0.15294}, {0.00000, 0.00000, 0.16078}, {0.00000, 0.00000, 0.16863}, {0.00000, 0.00000, 0.17647}, {0.00000, 0.00000, 0.18431}, {0.00000, 0.00000, 0.19608}, {0.00000, 0.00000, 0.20392}, {0.00000, 0.00000, 0.21176}, {0.00000, 0.00000, 0.21961}, {0.00000, 0.00000, 0.22745}, {0.00000, 0.00000, 0.23529}, {0.00000, 0.00000, 0.24314}, {0.00000, 0.00000, 0.25098}, {0.00000, 0.00000, 0.25882}, {0.00000, 0.01176, 0.26667}, {0.00000, 0.02353, 0.27451}, {0.00000, 0.03529, 0.28235}, {0.00000, 0.04706, 0.29412}, {0.00000, 0.05882, 0.30196}, {0.00000, 0.07059, 0.30980}, {0.00000, 0.08235, 0.31765}, {0.00000, 0.09804, 0.32549}, {0.00000, 0.10980, 0.33333}, {0.00000, 0.12157, 0.34118}, {0.00000, 0.13333, 0.34902}, {0.00000, 0.14510, 0.35686}, {0.00000, 0.15686, 0.36471}, {0.00000, 0.16863, 0.37255}, {0.00000, 0.18039, 0.38039}, {0.00000, 0.19608, 0.39216}, {0.00000, 0.20784, 0.39216}, {0.00000, 0.21961, 0.39216}, {0.00000, 0.23137, 0.39216}, {0.00000, 0.24314, 0.39216}, {0.00000, 0.25490, 0.39216}, {0.00000, 0.26667, 0.39216}, {0.00000, 0.27843, 0.39216}, {0.00000, 0.29412, 0.39216}, {0.00000, 0.30588, 0.39216}, {0.00000, 0.31765, 0.39216}, {0.00000, 0.32941, 0.39216}, {0.00000, 0.34118, 0.39216}, {0.00000, 0.35294, 0.39216}, {0.00000, 0.36471, 0.39216}, {0.00000, 0.37647, 0.39216}, {0.00000, 0.39216, 0.39216}, {0.00000, 0.40392, 0.39216}, {0.00000, 0.41569, 0.39216}, {0.00000, 0.42745, 0.39216}, {0.00000, 0.43922, 0.39216}, {0.00000, 0.45098, 0.39216}, {0.00000, 0.46275, 0.39216}, {0.00000, 0.47451, 0.39216}, {0.00000, 0.49020, 0.39216}, {0.00000, 0.50196, 0.39216}, {0.00000, 0.51373, 0.39216}, {0.00000, 0.52549, 0.39216}, {0.00000, 0.53725, 0.39216}, {0.00000, 0.54902, 0.39216}, {0.00000, 0.56078, 0.39216}, {0.00000, 0.57255, 0.39216}, {0.00000, 0.58824, 0.39216}, {0.00000, 0.58824, 0.37647}, {0.00000, 0.58824, 0.36471}, {0.00000, 0.58824, 0.35294}, {0.00000, 0.58824, 0.34118}, {0.00000, 0.58824, 0.32941}, {0.00000, 0.58824, 0.31765}, {0.00000, 0.58824, 0.30588}, {0.00000, 0.58824, 0.29412}, {0.00000, 0.58824, 0.27843}, {0.00000, 0.58824, 0.26667}, {0.00000, 0.58824, 0.25490}, {0.00000, 0.58824, 0.24314}, {0.00000, 0.58824, 0.23137}, {0.00000, 0.58824, 0.21961}, {0.00000, 0.58824, 0.20784}, {0.00000, 0.58824, 0.19608}, {0.00000, 0.58431, 0.18039}, {0.00000, 0.58039, 0.16863}, {0.00000, 0.58039, 0.15686}, {0.00000, 0.57647, 0.14510}, {0.00000, 0.57255, 0.13333}, {0.00000, 0.57255, 0.12157}, {0.00000, 0.56863, 0.10980}, {0.00000, 0.56863, 0.09804}, {0.00000, 0.56471, 0.08235}, {0.00000, 0.56078, 0.07059}, {0.00000, 0.56078, 0.05882}, {0.00000, 0.55686, 0.04706}, {0.00000, 0.55294, 0.03529}, {0.00000, 0.55294, 0.02353}, {0.00000, 0.54902, 0.01176}, {0.00000, 0.54902, 0.00000}, {0.02745, 0.53725, 0.00000}, {0.05882, 0.52941, 0.00000}, {0.08627, 0.51765, 0.00000}, {0.11765, 0.50980, 0.00000}, {0.14510, 0.49804, 0.00000}, {0.17647, 0.49020, 0.00000}, {0.20392, 0.47843, 0.00000}, {0.23529, 0.47059, 0.00000}, {0.26275, 0.45882, 0.00000}, {0.29412, 0.45098, 0.00000}, {0.32157, 0.43922, 0.00000}, {0.35294, 0.43137, 0.00000}, {0.38039, 0.41961, 0.00000}, {0.41176, 0.41176, 0.00000}, {0.43922, 0.40000, 0.00000}, {0.47059, 0.39216, 0.00000}, {0.49020, 0.36471, 0.00000}, {0.50980, 0.34118, 0.00000}, {0.52941, 0.31765, 0.00000}, {0.54902, 0.29412, 0.00000}, {0.56863, 0.26667, 0.00000}, {0.58824, 0.24314, 0.00000}, {0.60784, 0.21961, 0.00000}, {0.62745, 0.19608, 0.00000}, {0.64706, 0.16863, 0.00000}, {0.66667, 0.14510, 0.00000}, {0.68627, 0.12157, 0.00000}, {0.70588, 0.09804, 0.00000}, {0.72549, 0.07059, 0.00000}, {0.74510, 0.04706, 0.00000}, {0.76471, 0.02353, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00784, 0.00000}, {0.78824, 0.01569, 0.00000}, {0.78824, 0.02353, 0.00000}, {0.79216, 0.03529, 0.00000}, {0.79216, 0.04314, 0.00000}, {0.79608, 0.05098, 0.00000}, {0.79608, 0.06275, 0.00000}, {0.80000, 0.07059, 0.00000}, {0.80000, 0.07843, 0.00000}, {0.80392, 0.09020, 0.00000}, {0.80392, 0.09804, 0.00000}, {0.80784, 0.10588, 0.00000}, {0.80784, 0.11373, 0.00000}, {0.81176, 0.12549, 0.00000}, {0.81176, 0.13333, 0.00000}, {0.81569, 0.14118, 0.00000}, {0.81569, 0.15294, 0.00000}, {0.81961, 0.16078, 0.00000}, {0.81961, 0.16863, 0.00000}, {0.82353, 0.18039, 0.00000}, {0.82353, 0.18824, 0.00000}, {0.82745, 0.19608, 0.00000}, {0.82745, 0.20784, 0.00000}, {0.83137, 0.21569, 0.00000}, {0.83137, 0.22353, 0.00000}, {0.83529, 0.23137, 0.00000}, {0.83529, 0.24314, 0.00000}, {0.83922, 0.25098, 0.00000}, {0.83922, 0.25882, 0.00000}, {0.84314, 0.27059, 0.00000}, {0.84314, 0.27843, 0.00000}, {0.84706, 0.28627, 0.00000}, {0.84706, 0.29804, 0.00000}, {0.85098, 0.30588, 0.00000}, {0.85098, 0.31373, 0.00000}, {0.85490, 0.32549, 0.00000}, {0.85490, 0.33333, 0.00000}, {0.85882, 0.34118, 0.00000}, {0.85882, 0.34902, 0.00000}, {0.86275, 0.36078, 0.00000}, {0.86275, 0.36863, 0.00000}, {0.86667, 0.37647, 0.00000}, {0.86667, 0.38824, 0.00000}, {0.87059, 0.39608, 0.00000}, {0.87059, 0.40392, 0.00000}, {0.87451, 0.41569, 0.00000}, {0.87451, 0.42353, 0.00000}, {0.87843, 0.43137, 0.00000}, {0.87843, 0.44314, 0.00000}, {0.88235, 0.45098, 0.00000}, {0.88235, 0.45882, 0.00000}, {0.88627, 0.46667, 0.00000}, {0.88627, 0.47843, 0.00000}, {0.89020, 0.48627, 0.00000}, {0.89020, 0.49412, 0.00000}, {0.89412, 0.50588, 0.00000}, {0.89412, 0.51373, 0.00000}, {0.89804, 0.52157, 0.00000}, {0.89804, 0.53333, 0.00000}, {0.90196, 0.54118, 0.00000}, {0.90196, 0.54902, 0.00000}, {0.90588, 0.55686, 0.00000}, {0.90588, 0.56863, 0.00000}, {0.90980, 0.57647, 0.00000}, {0.90980, 0.58431, 0.00000}, {0.91373, 0.59608, 0.00000}, {0.91373, 0.60392, 0.00000}, {0.91765, 0.61176, 0.00000}, {0.91765, 0.62353, 0.00000}, {0.92157, 0.63137, 0.00000}, {0.92157, 0.63922, 0.00000}, {0.92549, 0.65098, 0.00000}, {0.92549, 0.65882, 0.00000}, {0.92941, 0.66667, 0.00000}, {0.92941, 0.67451, 0.00000}, {0.93333, 0.68627, 0.00000}, {0.93333, 0.69412, 0.00000}, {0.93725, 0.70196, 0.00000}, {0.93725, 0.71373, 0.00000}, {0.94118, 0.72157, 0.00000}, {0.94118, 0.72941, 0.00000}, {0.94510, 0.74118, 0.00000}, {0.94510, 0.74902, 0.00000}, {0.94902, 0.75686, 0.00000}, {0.94902, 0.76863, 0.00000}, {0.95294, 0.77647, 0.00000}, {0.95294, 0.78431, 0.00000}, {0.95686, 0.79216, 0.00000}, {0.95686, 0.80392, 0.00000}, {0.96078, 0.81176, 0.00000}, {0.96078, 0.81961, 0.00000}, {0.96471, 0.83137, 0.00000}, {0.96471, 0.83922, 0.00000}, {0.96863, 0.84706, 0.00000}, {0.96863, 0.85882, 0.00000}, {0.97255, 0.86667, 0.00000}, {0.97255, 0.87451, 0.00000}, {0.97647, 0.88627, 0.00000}, {0.97647, 0.89412, 0.00000}, {0.98039, 0.90196, 0.00000}, {0.98039, 0.90980, 0.00000}, {0.98431, 0.92157, 0.00000}, {0.98431, 0.92941, 0.00000}, {0.98824, 0.93725, 0.00000}, {0.98824, 0.94902, 0.00000}, {0.99216, 0.95686, 0.00000}, {0.99216, 0.96471, 0.00000}, {0.99608, 0.97647, 0.00000}, {0.99608, 0.98431, 0.00000}, {1.00000, 0.99216, 0.00000}, {1.00000, 1.00000, 0.00000}, }; new ColorMapInfo("idl4.lasc", idl4_lasc); static RGBColor idl14_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00000, 0.16471, 0.00000}, {0.00000, 0.33333, 0.00000}, {0.00000, 0.49804, 0.00000}, {0.00000, 0.66667, 0.00000}, {0.00000, 0.83137, 0.00000}, {0.00000, 1.00000, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.92549, 0.00000}, {0.00000, 0.88627, 0.00000}, {0.00000, 0.84706, 0.00000}, {0.00000, 0.80784, 0.00000}, {0.00000, 0.77255, 0.00000}, {0.00000, 0.73333, 0.00000}, {0.00000, 0.69412, 0.00000}, {0.00000, 0.65490, 0.00000}, {0.00000, 0.61569, 0.00000}, {0.00000, 0.58039, 0.00000}, {0.00000, 0.54118, 0.00000}, {0.00000, 0.50196, 0.00000}, {0.00000, 0.46275, 0.00000}, {0.00000, 0.42353, 0.00000}, {0.00000, 0.38824, 0.00000}, {0.00000, 0.34902, 0.00000}, {0.00000, 0.30980, 0.00000}, {0.00000, 0.27059, 0.00000}, {0.00000, 0.23137, 0.00000}, {0.00000, 0.19608, 0.00000}, {0.00000, 0.15686, 0.00000}, {0.00000, 0.11765, 0.00000}, {0.00000, 0.07843, 0.00000}, {0.00000, 0.03922, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.03137}, {0.00000, 0.00000, 0.06275}, {0.00000, 0.00000, 0.09412}, {0.00000, 0.00000, 0.12549}, {0.00000, 0.00000, 0.16078}, {0.00000, 0.00000, 0.19216}, {0.00000, 0.00000, 0.22353}, {0.00000, 0.00000, 0.25490}, {0.00000, 0.00000, 0.29020}, {0.00000, 0.00000, 0.32157}, {0.00000, 0.00000, 0.35294}, {0.00000, 0.00000, 0.38431}, {0.00000, 0.00000, 0.41569}, {0.00000, 0.00000, 0.45098}, {0.00000, 0.00000, 0.48235}, {0.00000, 0.00000, 0.51373}, {0.00000, 0.00000, 0.54510}, {0.00000, 0.00000, 0.58039}, {0.00000, 0.00000, 0.61176}, {0.00000, 0.00000, 0.64314}, {0.00000, 0.00000, 0.67451}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.00000, 0.74118}, {0.00000, 0.00000, 0.77255}, {0.00000, 0.00000, 0.80392}, {0.00000, 0.00000, 0.83529}, {0.00000, 0.00000, 0.87059}, {0.00000, 0.00000, 0.90196}, {0.00000, 0.00000, 0.93333}, {0.00000, 0.00000, 0.96471}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 0.00000}, {0.02745, 0.00000, 0.01961}, {0.05882, 0.00000, 0.03922}, {0.09020, 0.00000, 0.05882}, {0.12157, 0.00000, 0.08235}, {0.15294, 0.00000, 0.10196}, {0.18431, 0.00000, 0.12157}, {0.21569, 0.00000, 0.14510}, {0.24706, 0.00000, 0.16471}, {0.27451, 0.00000, 0.18431}, {0.30588, 0.00000, 0.20784}, {0.33725, 0.00000, 0.22745}, {0.36863, 0.00000, 0.24706}, {0.40000, 0.00000, 0.27059}, {0.43137, 0.00000, 0.29020}, {0.46275, 0.00000, 0.30980}, {0.49412, 0.00000, 0.33333}, {0.52549, 0.00000, 0.34902}, {0.55686, 0.00000, 0.36863}, {0.59216, 0.00000, 0.38431}, {0.62353, 0.00000, 0.40392}, {0.65882, 0.00000, 0.42353}, {0.69020, 0.00000, 0.43922}, {0.72157, 0.00000, 0.45882}, {0.75686, 0.00000, 0.47451}, {0.78824, 0.00000, 0.49412}, {0.82353, 0.00000, 0.51373}, {0.85490, 0.00000, 0.52941}, {0.88627, 0.00000, 0.54902}, {0.92157, 0.00000, 0.56471}, {0.95294, 0.00000, 0.58431}, {0.98824, 0.00000, 0.60392}, {0.00000, 0.00000, 0.00000}, {0.00392, 0.00000, 0.00000}, {0.00784, 0.00000, 0.00000}, {0.01176, 0.00000, 0.00000}, {0.01569, 0.00000, 0.00000}, {0.01961, 0.00000, 0.00000}, {0.02353, 0.00000, 0.00000}, {0.02745, 0.00000, 0.00000}, {0.03137, 0.00000, 0.00000}, {0.03529, 0.00000, 0.00000}, {0.03922, 0.00000, 0.00000}, {0.04314, 0.00000, 0.00000}, {0.04706, 0.00000, 0.00000}, {0.05490, 0.00000, 0.00000}, {0.06275, 0.00000, 0.00000}, {0.07059, 0.00000, 0.00000}, {0.07843, 0.00000, 0.00000}, {0.09020, 0.00000, 0.00000}, {0.09804, 0.00000, 0.00000}, {0.10588, 0.00000, 0.00000}, {0.11373, 0.00000, 0.00000}, {0.12549, 0.00000, 0.00000}, {0.13333, 0.00000, 0.00000}, {0.14118, 0.00000, 0.00000}, {0.14902, 0.00000, 0.00000}, {0.16078, 0.00000, 0.00000}, {0.17255, 0.00000, 0.00000}, {0.18431, 0.00000, 0.00000}, {0.19608, 0.00000, 0.00000}, {0.20784, 0.00000, 0.00000}, {0.21961, 0.00000, 0.00000}, {0.23137, 0.00000, 0.00000}, {0.24706, 0.00000, 0.00000}, {0.25882, 0.00000, 0.00000}, {0.27059, 0.00000, 0.00000}, {0.28235, 0.00000, 0.00000}, {0.29412, 0.00000, 0.00000}, {0.30588, 0.00000, 0.00000}, {0.32157, 0.00000, 0.00392}, {0.33333, 0.00000, 0.00392}, {0.34902, 0.00000, 0.00392}, {0.36471, 0.00000, 0.00392}, {0.38039, 0.00000, 0.00392}, {0.39608, 0.00000, 0.00392}, {0.41176, 0.00000, 0.00392}, {0.42353, 0.00000, 0.00392}, {0.43922, 0.00000, 0.00392}, {0.45490, 0.00000, 0.00392}, {0.47059, 0.00000, 0.00392}, {0.48627, 0.00000, 0.00392}, {0.50196, 0.00392, 0.00392}, {0.51373, 0.00392, 0.00392}, {0.52941, 0.00392, 0.00392}, {0.54510, 0.00392, 0.00392}, {0.56078, 0.00392, 0.00392}, {0.57647, 0.00392, 0.00392}, {0.59216, 0.00392, 0.00392}, {0.60784, 0.00392, 0.00392}, {0.62353, 0.00392, 0.00392}, {0.63922, 0.00392, 0.00392}, {0.65490, 0.00392, 0.00392}, {0.67059, 0.00392, 0.00392}, {0.68627, 0.00392, 0.00392}, {0.69804, 0.00392, 0.00392}, {0.70980, 0.00392, 0.00392}, {0.72549, 0.00392, 0.00392}, {0.73725, 0.00392, 0.00392}, {0.75294, 0.00392, 0.00392}, {0.76471, 0.00392, 0.00392}, {0.77647, 0.00392, 0.00392}, {0.79216, 0.00392, 0.00392}, {0.80392, 0.00392, 0.00392}, {0.81961, 0.00392, 0.00392}, {0.83137, 0.00392, 0.00392}, {0.84706, 0.00392, 0.00784}, {0.85490, 0.00392, 0.00784}, {0.86275, 0.00392, 0.00784}, {0.87451, 0.00392, 0.00784}, {0.88235, 0.00392, 0.00784}, {0.89020, 0.00392, 0.00784}, {0.90196, 0.00392, 0.00784}, {0.90980, 0.00392, 0.00784}, {0.91765, 0.00392, 0.00784}, {0.92941, 0.00392, 0.00784}, {0.93725, 0.00392, 0.00784}, {0.94510, 0.00392, 0.00784}, {0.95686, 0.00784, 0.00784}, {0.95686, 0.00784, 0.00784}, {0.96078, 0.00784, 0.00784}, {0.96471, 0.00784, 0.00784}, {0.96863, 0.00784, 0.00784}, {0.96863, 0.00784, 0.00784}, {0.97255, 0.00784, 0.00784}, {0.97647, 0.00784, 0.00784}, {0.98039, 0.00784, 0.00784}, {0.98039, 0.00784, 0.00784}, {0.98431, 0.00784, 0.00784}, {0.98824, 0.00784, 0.00784}, {0.99216, 0.00784, 0.00784}, {0.99608, 0.00392, 0.00784}, {0.99608, 0.00392, 0.00784}, {0.99608, 0.01176, 0.00784}, {0.99608, 0.01961, 0.00784}, {0.99608, 0.03137, 0.00784}, {0.99608, 0.03922, 0.00784}, {0.99608, 0.04706, 0.00784}, {0.99608, 0.05882, 0.00784}, {0.99608, 0.06667, 0.00784}, {0.99608, 0.07451, 0.00784}, {0.99608, 0.08627, 0.00784}, {0.99608, 0.09412, 0.00784}, {0.99608, 0.10196, 0.00784}, {0.99608, 0.11373, 0.00784}, {0.99608, 0.12157, 0.00784}, {0.99608, 0.12941, 0.00784}, {0.99608, 0.14118, 0.00784}, {0.99608, 0.14118, 0.00784}, {0.99608, 0.14902, 0.01176}, {0.99608, 0.15686, 0.01569}, {0.99608, 0.16471, 0.01961}, {1.00000, 0.17647, 0.02745}, {1.00000, 0.18824, 0.03529}, {1.00000, 0.20000, 0.04706}, {1.00000, 0.21176, 0.05490}, {1.00000, 0.22745, 0.06667}, {1.00000, 0.23922, 0.07843}, {1.00000, 0.25098, 0.09020}, {1.00000, 0.26275, 0.10588}, {1.00000, 0.27451, 0.11765}, {1.00000, 0.28627, 0.13333}, {1.00000, 0.30196, 0.15294}, {1.00000, 0.32157, 0.17255}, {1.00000, 0.34118, 0.19216}, {1.00000, 0.36078, 0.21569}, {1.00000, 0.37647, 0.23529}, {1.00000, 0.39216, 0.25490}, {1.00000, 0.40784, 0.27843}, {1.00000, 0.42353, 0.29804}, {1.00000, 0.44314, 0.32157}, {1.00000, 0.46667, 0.34902}, {1.00000, 0.49020, 0.38039}, {1.00000, 0.51373, 0.40784}, {1.00000, 0.54118, 0.43922}, {1.00000, 0.56471, 0.47059}, {1.00000, 0.59216, 0.50196}, {1.00000, 0.61569, 0.53333}, {1.00000, 0.64314, 0.56863}, {1.00000, 0.67059, 0.60000}, {1.00000, 0.69804, 0.63529}, {1.00000, 0.72549, 0.67059}, {1.00000, 0.75686, 0.70588}, {1.00000, 0.78431, 0.74118}, {1.00000, 0.81569, 0.77647}, {1.00000, 0.84314, 0.81176}, {1.00000, 0.87451, 0.85098}, {1.00000, 0.89804, 0.87843}, {1.00000, 0.92157, 0.90980}, {1.00000, 0.94902, 0.93725}, {1.00000, 0.97255, 0.96863}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("idl14.lasc", idl14_lasc); static RGBColor rainbow3_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.03922}, {0.00000, 0.00000, 0.07843}, {0.00000, 0.00000, 0.11765}, {0.00000, 0.00000, 0.15686}, {0.00000, 0.00000, 0.20000}, {0.00000, 0.00000, 0.23922}, {0.00000, 0.00000, 0.27843}, {0.00000, 0.00000, 0.31765}, {0.00000, 0.00000, 0.35686}, {0.00000, 0.00000, 0.40000}, {0.00000, 0.00000, 0.43922}, {0.00000, 0.00000, 0.47843}, {0.00000, 0.00000, 0.51765}, {0.00000, 0.00000, 0.55686}, {0.00000, 0.00000, 0.60000}, {0.00000, 0.00000, 0.63922}, {0.00000, 0.00000, 0.67843}, {0.00000, 0.00000, 0.71765}, {0.00000, 0.00000, 0.75686}, {0.00000, 0.00000, 0.80000}, {0.00000, 0.00000, 0.83922}, {0.00000, 0.00000, 0.87843}, {0.00000, 0.00000, 0.91765}, {0.00000, 0.00000, 0.95686}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.03137, 1.00000}, {0.00000, 0.06275, 1.00000}, {0.00000, 0.09412, 1.00000}, {0.00000, 0.12549, 1.00000}, {0.00000, 0.15686, 1.00000}, {0.00000, 0.18824, 1.00000}, {0.00000, 0.21961, 1.00000}, {0.00000, 0.25490, 1.00000}, {0.00000, 0.28627, 1.00000}, {0.00000, 0.31765, 1.00000}, {0.00000, 0.34902, 1.00000}, {0.00000, 0.38039, 1.00000}, {0.00000, 0.41176, 1.00000}, {0.00000, 0.44314, 1.00000}, {0.00000, 0.47843, 1.00000}, {0.00000, 0.49804, 1.00000}, {0.00000, 0.51765, 1.00000}, {0.00000, 0.53725, 1.00000}, {0.00000, 0.55686, 1.00000}, {0.00000, 0.58039, 1.00000}, {0.00000, 0.60000, 1.00000}, {0.00000, 0.61961, 1.00000}, {0.00000, 0.63922, 1.00000}, {0.00000, 0.65882, 1.00000}, {0.00000, 0.68235, 1.00000}, {0.00000, 0.70196, 1.00000}, {0.00000, 0.72157, 1.00000}, {0.00000, 0.74118, 1.00000}, {0.00000, 0.76078, 1.00000}, {0.00000, 0.78431, 1.00000}, {0.00000, 0.79608, 1.00000}, {0.00000, 0.81176, 1.00000}, {0.00000, 0.82745, 1.00000}, {0.00000, 0.83922, 1.00000}, {0.00000, 0.85490, 1.00000}, {0.00000, 0.87059, 1.00000}, {0.00000, 0.88235, 1.00000}, {0.00000, 0.89804, 1.00000}, {0.00000, 0.91373, 1.00000}, {0.00000, 0.92549, 1.00000}, {0.00000, 0.94118, 1.00000}, {0.00000, 0.95686, 1.00000}, {0.00000, 0.96863, 1.00000}, {0.00000, 0.98431, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 0.98039}, {0.00000, 1.00000, 0.96078}, {0.00000, 1.00000, 0.94118}, {0.00000, 1.00000, 0.92157}, {0.00000, 1.00000, 0.90196}, {0.00000, 1.00000, 0.88235}, {0.00000, 1.00000, 0.86275}, {0.00000, 1.00000, 0.84314}, {0.00000, 1.00000, 0.82353}, {0.00000, 1.00000, 0.80392}, {0.00000, 1.00000, 0.78431}, {0.00000, 1.00000, 0.76471}, {0.00000, 1.00000, 0.74510}, {0.00000, 1.00000, 0.72549}, {0.00000, 1.00000, 0.70588}, {0.00000, 1.00000, 0.65882}, {0.00000, 1.00000, 0.61176}, {0.00000, 1.00000, 0.56471}, {0.00000, 1.00000, 0.51765}, {0.00000, 1.00000, 0.47059}, {0.00000, 1.00000, 0.42353}, {0.00000, 1.00000, 0.37647}, {0.00000, 1.00000, 0.32549}, {0.00000, 1.00000, 0.27843}, {0.00000, 1.00000, 0.23137}, {0.00000, 1.00000, 0.18431}, {0.00000, 1.00000, 0.13725}, {0.00000, 1.00000, 0.09020}, {0.00000, 1.00000, 0.04314}, {0.00000, 1.00000, 0.00000}, {0.04706, 1.00000, 0.00000}, {0.09412, 1.00000, 0.00000}, {0.14118, 1.00000, 0.00000}, {0.18824, 1.00000, 0.00000}, {0.23529, 1.00000, 0.00000}, {0.28235, 1.00000, 0.00000}, {0.32941, 1.00000, 0.00000}, {0.37647, 1.00000, 0.00000}, {0.42353, 1.00000, 0.00000}, {0.47059, 1.00000, 0.00000}, {0.51765, 1.00000, 0.00000}, {0.56471, 1.00000, 0.00000}, {0.61176, 1.00000, 0.00000}, {0.65882, 1.00000, 0.00000}, {0.70588, 1.00000, 0.00000}, {0.72549, 1.00000, 0.00000}, {0.74510, 1.00000, 0.00000}, {0.76471, 1.00000, 0.00000}, {0.78431, 1.00000, 0.00000}, {0.80392, 1.00000, 0.00000}, {0.82353, 1.00000, 0.00000}, {0.84314, 1.00000, 0.00000}, {0.86275, 1.00000, 0.00000}, {0.88235, 1.00000, 0.00000}, {0.90196, 1.00000, 0.00000}, {0.92157, 1.00000, 0.00000}, {0.94118, 1.00000, 0.00000}, {0.96078, 1.00000, 0.00000}, {0.98039, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {0.99608, 0.98039, 0.00000}, {0.99608, 0.96078, 0.00000}, {0.99608, 0.94510, 0.00000}, {0.99608, 0.92549, 0.00000}, {0.99608, 0.90588, 0.00000}, {0.99216, 0.89020, 0.00000}, {0.99216, 0.87059, 0.00000}, {0.99216, 0.85098, 0.00000}, {0.99216, 0.83529, 0.00000}, {0.99216, 0.81569, 0.00000}, {0.98824, 0.79608, 0.00000}, {0.98824, 0.78039, 0.00000}, {0.98824, 0.76078, 0.00000}, {0.98824, 0.74118, 0.00000}, {0.98824, 0.72549, 0.00000}, {0.98824, 0.70588, 0.00000}, {0.98824, 0.69020, 0.00000}, {0.98824, 0.67451, 0.00000}, {0.98824, 0.65490, 0.00000}, {0.99216, 0.63922, 0.00000}, {0.99216, 0.62353, 0.00000}, {0.99216, 0.60392, 0.00000}, {0.99216, 0.58824, 0.00000}, {0.99216, 0.57255, 0.00000}, {0.99608, 0.55294, 0.00000}, {0.99608, 0.53725, 0.00000}, {0.99608, 0.52157, 0.00000}, {0.99608, 0.50196, 0.00000}, {0.99608, 0.48627, 0.00000}, {1.00000, 0.47059, 0.00000}, {1.00000, 0.43922, 0.00000}, {1.00000, 0.40784, 0.00000}, {1.00000, 0.37647, 0.00000}, {1.00000, 0.34510, 0.00000}, {1.00000, 0.31373, 0.00000}, {1.00000, 0.28235, 0.00000}, {1.00000, 0.25098, 0.00000}, {1.00000, 0.21569, 0.00000}, {1.00000, 0.18431, 0.00000}, {1.00000, 0.15294, 0.00000}, {1.00000, 0.12157, 0.00000}, {1.00000, 0.09020, 0.00000}, {1.00000, 0.05882, 0.00000}, {1.00000, 0.02745, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.04706}, {1.00000, 0.00000, 0.09412}, {1.00000, 0.00000, 0.14118}, {1.00000, 0.00000, 0.18824}, {1.00000, 0.00000, 0.23529}, {1.00000, 0.00000, 0.28235}, {1.00000, 0.00000, 0.32941}, {1.00000, 0.00000, 0.37647}, {1.00000, 0.00000, 0.42353}, {1.00000, 0.00000, 0.47059}, {1.00000, 0.00000, 0.51765}, {1.00000, 0.00000, 0.56471}, {1.00000, 0.00000, 0.61176}, {1.00000, 0.00000, 0.65882}, {1.00000, 0.00000, 0.70588}, {1.00000, 0.00000, 0.72549}, {1.00000, 0.00000, 0.74902}, {1.00000, 0.00000, 0.77255}, {1.00000, 0.00000, 0.79608}, {1.00000, 0.00000, 0.81569}, {1.00000, 0.00000, 0.83922}, {1.00000, 0.00000, 0.86275}, {1.00000, 0.00000, 0.88627}, {1.00000, 0.00000, 0.90588}, {1.00000, 0.00000, 0.92941}, {1.00000, 0.00000, 0.95294}, {1.00000, 0.00000, 0.97647}, {1.00000, 0.00000, 1.00000}, {1.00000, 0.03529, 1.00000}, {1.00000, 0.07059, 1.00000}, {1.00000, 0.10588, 1.00000}, {1.00000, 0.14118, 1.00000}, {1.00000, 0.18039, 1.00000}, {1.00000, 0.21569, 1.00000}, {1.00000, 0.25098, 1.00000}, {1.00000, 0.28627, 1.00000}, {1.00000, 0.32549, 1.00000}, {1.00000, 0.36078, 1.00000}, {1.00000, 0.39608, 1.00000}, {1.00000, 0.43137, 1.00000}, {1.00000, 0.47059, 1.00000}, {1.00000, 0.48627, 1.00000}, {1.00000, 0.50588, 1.00000}, {1.00000, 0.52157, 1.00000}, {1.00000, 0.54118, 1.00000}, {1.00000, 0.56078, 1.00000}, {1.00000, 0.57647, 1.00000}, {1.00000, 0.59608, 1.00000}, {1.00000, 0.61176, 1.00000}, {1.00000, 0.63137, 1.00000}, {1.00000, 0.65098, 1.00000}, {1.00000, 0.66667, 1.00000}, {1.00000, 0.68627, 1.00000}, {1.00000, 0.70588, 1.00000}, {1.00000, 0.74510, 1.00000}, {1.00000, 0.78824, 1.00000}, {1.00000, 0.83137, 1.00000}, {1.00000, 0.87059, 1.00000}, {1.00000, 0.91373, 1.00000}, {1.00000, 0.95686, 1.00000}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("rainbow3.lasc", rainbow3_lasc); static RGBColor idl6_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.01176, 0.00000, 0.00000}, {0.02745, 0.00000, 0.00000}, {0.04314, 0.00000, 0.00000}, {0.05882, 0.00000, 0.00000}, {0.07451, 0.00000, 0.00000}, {0.08627, 0.00000, 0.00000}, {0.10196, 0.00000, 0.00000}, {0.11765, 0.00000, 0.00000}, {0.13333, 0.00000, 0.00000}, {0.14902, 0.00000, 0.00000}, {0.16078, 0.00000, 0.00000}, {0.17647, 0.00000, 0.00000}, {0.19216, 0.00000, 0.00000}, {0.20784, 0.00000, 0.00000}, {0.22353, 0.00000, 0.00000}, {0.23529, 0.00000, 0.00000}, {0.25098, 0.00000, 0.00000}, {0.26667, 0.00000, 0.00000}, {0.28235, 0.00000, 0.00000}, {0.29804, 0.00000, 0.00000}, {0.30980, 0.00000, 0.00000}, {0.32549, 0.00000, 0.00000}, {0.34118, 0.00000, 0.00000}, {0.35686, 0.00000, 0.00000}, {0.37255, 0.00000, 0.00000}, {0.38431, 0.00000, 0.00000}, {0.40000, 0.00000, 0.00000}, {0.41569, 0.00000, 0.00000}, {0.43137, 0.00000, 0.00000}, {0.44706, 0.00000, 0.00000}, {0.45882, 0.00000, 0.00000}, {0.47451, 0.00000, 0.00000}, {0.49020, 0.00000, 0.00000}, {0.50588, 0.00000, 0.00000}, {0.52157, 0.00000, 0.00000}, {0.53725, 0.00000, 0.00000}, {0.54902, 0.00000, 0.00000}, {0.56471, 0.00000, 0.00000}, {0.58039, 0.00000, 0.00000}, {0.59608, 0.00000, 0.00000}, {0.61176, 0.00000, 0.00000}, {0.62353, 0.00000, 0.00000}, {0.63922, 0.00000, 0.00000}, {0.65490, 0.00000, 0.00000}, {0.67059, 0.00000, 0.00000}, {0.68627, 0.00000, 0.00000}, {0.69804, 0.00000, 0.00000}, {0.71373, 0.00000, 0.00000}, {0.72941, 0.00000, 0.00000}, {0.74510, 0.00000, 0.00000}, {0.76078, 0.00000, 0.00000}, {0.77255, 0.00000, 0.00000}, {0.78824, 0.00000, 0.00000}, {0.80392, 0.00000, 0.00000}, {0.81961, 0.00000, 0.00000}, {0.83529, 0.00000, 0.00000}, {0.84706, 0.00000, 0.00000}, {0.86275, 0.00000, 0.00000}, {0.87843, 0.00000, 0.00000}, {0.89412, 0.00000, 0.00000}, {0.90980, 0.00000, 0.00000}, {0.92157, 0.00000, 0.00000}, {0.93725, 0.00000, 0.00000}, {0.95294, 0.00000, 0.00000}, {0.96863, 0.01176, 0.00000}, {0.98431, 0.02745, 0.00000}, {1.00000, 0.04314, 0.00000}, {0.98431, 0.05882, 0.00000}, {0.96863, 0.07451, 0.00000}, {0.95294, 0.09020, 0.00000}, {0.93725, 0.10588, 0.00000}, {0.92157, 0.12157, 0.00000}, {0.90196, 0.13725, 0.00000}, {0.88627, 0.15294, 0.00000}, {0.87059, 0.16863, 0.00000}, {0.85490, 0.18431, 0.00000}, {0.83922, 0.20000, 0.00000}, {0.82353, 0.21569, 0.00000}, {0.80392, 0.23137, 0.00000}, {0.78824, 0.24706, 0.00000}, {0.77255, 0.26275, 0.00000}, {0.75686, 0.27843, 0.00000}, {0.74118, 0.29412, 0.00000}, {0.72157, 0.30980, 0.00000}, {0.70588, 0.32549, 0.00000}, {0.69020, 0.34118, 0.00000}, {0.67451, 0.35686, 0.00000}, {0.65882, 0.37255, 0.00000}, {0.64314, 0.38824, 0.00000}, {0.62353, 0.40392, 0.00000}, {0.60784, 0.41961, 0.00000}, {0.59216, 0.43529, 0.00000}, {0.57647, 0.45098, 0.00000}, {0.56078, 0.46667, 0.00000}, {0.54118, 0.48235, 0.00000}, {0.52549, 0.49804, 0.00000}, {0.50980, 0.51373, 0.00000}, {0.49412, 0.52941, 0.00000}, {0.47843, 0.54510, 0.00000}, {0.46275, 0.56078, 0.00000}, {0.44314, 0.57647, 0.00000}, {0.42745, 0.59216, 0.00000}, {0.41176, 0.60784, 0.00000}, {0.39608, 0.62353, 0.00000}, {0.38039, 0.63922, 0.00000}, {0.36078, 0.65490, 0.00000}, {0.34510, 0.67059, 0.00000}, {0.32941, 0.68627, 0.00000}, {0.31373, 0.70196, 0.00000}, {0.29804, 0.71765, 0.00000}, {0.28235, 0.73333, 0.00000}, {0.26275, 0.74902, 0.00000}, {0.24706, 0.76471, 0.00000}, {0.23137, 0.78039, 0.00000}, {0.21569, 0.79608, 0.00000}, {0.20000, 0.81176, 0.00000}, {0.18039, 0.82745, 0.00000}, {0.16471, 0.84314, 0.00000}, {0.14902, 0.85882, 0.00000}, {0.13333, 0.87451, 0.00000}, {0.11765, 0.89020, 0.00000}, {0.10196, 0.90588, 0.00000}, {0.08235, 0.92157, 0.00000}, {0.06667, 0.93725, 0.00000}, {0.05098, 0.95294, 0.00000}, {0.03529, 0.96863, 0.00000}, {0.01961, 0.98431, 0.01176}, {0.00000, 1.00000, 0.02745}, {0.00000, 0.98431, 0.04314}, {0.00000, 0.96863, 0.05882}, {0.00000, 0.95294, 0.07451}, {0.00000, 0.93725, 0.09020}, {0.00000, 0.92157, 0.10588}, {0.00000, 0.90588, 0.11765}, {0.00000, 0.89020, 0.13333}, {0.00000, 0.87451, 0.14902}, {0.00000, 0.85882, 0.16471}, {0.00000, 0.84314, 0.18039}, {0.00000, 0.82745, 0.19608}, {0.00000, 0.81176, 0.21176}, {0.00000, 0.79608, 0.22353}, {0.00000, 0.78039, 0.23922}, {0.00000, 0.76471, 0.25490}, {0.00000, 0.74902, 0.27059}, {0.00000, 0.73333, 0.28627}, {0.00000, 0.71765, 0.30196}, {0.00000, 0.70196, 0.31765}, {0.00000, 0.68627, 0.33333}, {0.00000, 0.66667, 0.34510}, {0.00000, 0.65098, 0.36078}, {0.00000, 0.63529, 0.37647}, {0.00000, 0.61961, 0.39216}, {0.00000, 0.60392, 0.40784}, {0.00000, 0.58824, 0.42353}, {0.00000, 0.57255, 0.43922}, {0.00000, 0.55686, 0.45098}, {0.00000, 0.54118, 0.46667}, {0.00000, 0.52549, 0.48235}, {0.00000, 0.50980, 0.49804}, {0.00000, 0.49412, 0.51373}, {0.00000, 0.47843, 0.52941}, {0.00000, 0.46275, 0.54510}, {0.00000, 0.44706, 0.55686}, {0.00000, 0.43137, 0.57255}, {0.00000, 0.41569, 0.58824}, {0.00000, 0.40000, 0.60392}, {0.00000, 0.38431, 0.61961}, {0.00000, 0.36863, 0.63529}, {0.00000, 0.35294, 0.65098}, {0.00000, 0.33333, 0.66667}, {0.00000, 0.31765, 0.67843}, {0.00000, 0.30196, 0.69412}, {0.00000, 0.28627, 0.70980}, {0.00000, 0.27059, 0.72549}, {0.00000, 0.25490, 0.74118}, {0.00000, 0.23922, 0.75686}, {0.00000, 0.22353, 0.77255}, {0.00000, 0.20784, 0.78431}, {0.00000, 0.19216, 0.80000}, {0.00000, 0.17647, 0.81569}, {0.00000, 0.16078, 0.83137}, {0.00000, 0.14510, 0.84706}, {0.00000, 0.12941, 0.86275}, {0.00000, 0.11373, 0.87843}, {0.00000, 0.09804, 0.89020}, {0.00000, 0.08235, 0.90588}, {0.00000, 0.06667, 0.92157}, {0.00000, 0.05098, 0.93725}, {0.00000, 0.03529, 0.95294}, {0.00000, 0.01961, 0.96863}, {0.00000, 0.00000, 0.98431}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 0.98431}, {0.00000, 0.00000, 0.96863}, {0.00000, 0.00000, 0.95294}, {0.00000, 0.00000, 0.93725}, {0.00000, 0.00000, 0.92157}, {0.00000, 0.00000, 0.90588}, {0.00000, 0.00000, 0.89020}, {0.00000, 0.00000, 0.87451}, {0.00000, 0.00000, 0.85882}, {0.00000, 0.00000, 0.84314}, {0.00000, 0.00000, 0.82745}, {0.00000, 0.00000, 0.81176}, {0.00000, 0.00000, 0.79608}, {0.00000, 0.00000, 0.78039}, {0.00000, 0.00000, 0.76471}, {0.00000, 0.00000, 0.74902}, {0.00000, 0.00000, 0.73333}, {0.00000, 0.00000, 0.71765}, {0.00000, 0.00000, 0.70196}, {0.00000, 0.00000, 0.68627}, {0.00000, 0.00000, 0.66667}, {0.00000, 0.00000, 0.65098}, {0.00000, 0.00000, 0.63529}, {0.00000, 0.00000, 0.61961}, {0.00000, 0.00000, 0.60392}, {0.00000, 0.00000, 0.58824}, {0.00000, 0.00000, 0.57255}, {0.00000, 0.00000, 0.55686}, {0.00000, 0.00000, 0.54118}, {0.00000, 0.00000, 0.52549}, {0.00000, 0.00000, 0.50980}, {0.00000, 0.00000, 0.49412}, {0.00000, 0.00000, 0.47843}, {0.00000, 0.00000, 0.46275}, {0.00000, 0.00000, 0.44706}, {0.00000, 0.00000, 0.43137}, {0.00000, 0.00000, 0.41569}, {0.00000, 0.00000, 0.40000}, {0.00000, 0.00000, 0.38431}, {0.00000, 0.00000, 0.36863}, {0.00000, 0.00000, 0.35294}, {0.00000, 0.00000, 0.33333}, {0.00000, 0.00000, 0.31765}, {0.00000, 0.00000, 0.30196}, {0.00000, 0.00000, 0.28627}, {0.00000, 0.00000, 0.27059}, {0.00000, 0.00000, 0.25490}, {0.00000, 0.00000, 0.23922}, {0.00000, 0.00000, 0.22353}, {0.00000, 0.00000, 0.20784}, {0.00000, 0.00000, 0.19216}, {0.00000, 0.00000, 0.17647}, {0.00000, 0.00000, 0.16078}, {0.00000, 0.00000, 0.14510}, {0.00000, 0.00000, 0.12941}, {0.00000, 0.00000, 0.11373}, {0.00000, 0.00000, 0.09804}, {0.00000, 0.00000, 0.08235}, {0.00000, 0.00000, 0.06667}, {0.00000, 0.00000, 0.05098}, {0.00000, 0.00000, 0.03529}, {0.00000, 0.00000, 0.01961}, {0.00000, 0.00000, 0.00000}, }; new ColorMapInfo("idl6.lasc", idl6_lasc); static RGBColor blulut_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.00392}, {0.00000, 0.00000, 0.00784}, {0.00000, 0.00000, 0.01176}, {0.00000, 0.00000, 0.01569}, {0.00000, 0.00000, 0.01961}, {0.00000, 0.00000, 0.02353}, {0.00000, 0.00000, 0.02745}, {0.00000, 0.00000, 0.03137}, {0.00000, 0.00000, 0.03529}, {0.00000, 0.00000, 0.03922}, {0.00000, 0.00000, 0.04314}, {0.00000, 0.00000, 0.04706}, {0.00001, 0.00001, 0.05098}, {0.00001, 0.00001, 0.05490}, {0.00001, 0.00001, 0.05882}, {0.00002, 0.00002, 0.06275}, {0.00002, 0.00002, 0.06667}, {0.00002, 0.00002, 0.07059}, {0.00003, 0.00003, 0.07451}, {0.00004, 0.00004, 0.07843}, {0.00005, 0.00005, 0.08235}, {0.00006, 0.00006, 0.08627}, {0.00007, 0.00007, 0.09020}, {0.00008, 0.00008, 0.09412}, {0.00009, 0.00009, 0.09804}, {0.00011, 0.00011, 0.10196}, {0.00013, 0.00013, 0.10588}, {0.00015, 0.00015, 0.10980}, {0.00017, 0.00017, 0.11373}, {0.00019, 0.00019, 0.11765}, {0.00022, 0.00022, 0.12157}, {0.00025, 0.00025, 0.12549}, {0.00028, 0.00028, 0.12941}, {0.00032, 0.00032, 0.13333}, {0.00035, 0.00035, 0.13725}, {0.00040, 0.00040, 0.14118}, {0.00044, 0.00044, 0.14510}, {0.00049, 0.00049, 0.14902}, {0.00055, 0.00055, 0.15294}, {0.00061, 0.00061, 0.15686}, {0.00067, 0.00067, 0.16078}, {0.00074, 0.00074, 0.16471}, {0.00081, 0.00081, 0.16863}, {0.00089, 0.00089, 0.17255}, {0.00097, 0.00097, 0.17647}, {0.00106, 0.00106, 0.18039}, {0.00115, 0.00115, 0.18431}, {0.00126, 0.00126, 0.18824}, {0.00136, 0.00136, 0.19216}, {0.00148, 0.00148, 0.19608}, {0.00160, 0.00160, 0.20000}, {0.00173, 0.00173, 0.20392}, {0.00187, 0.00187, 0.20784}, {0.00201, 0.00201, 0.21176}, {0.00216, 0.00216, 0.21569}, {0.00233, 0.00233, 0.21961}, {0.00250, 0.00250, 0.22353}, {0.00268, 0.00268, 0.22745}, {0.00287, 0.00287, 0.23137}, {0.00307, 0.00307, 0.23529}, {0.00327, 0.00327, 0.23922}, {0.00349, 0.00349, 0.24314}, {0.00373, 0.00373, 0.24706}, {0.00397, 0.00397, 0.25098}, {0.00422, 0.00422, 0.25490}, {0.00449, 0.00449, 0.25882}, {0.00477, 0.00477, 0.26275}, {0.00506, 0.00506, 0.26667}, {0.00536, 0.00536, 0.27059}, {0.00568, 0.00568, 0.27451}, {0.00601, 0.00601, 0.27843}, {0.00636, 0.00636, 0.28235}, {0.00672, 0.00672, 0.28627}, {0.00709, 0.00709, 0.29020}, {0.00748, 0.00748, 0.29412}, {0.00789, 0.00789, 0.29804}, {0.00831, 0.00831, 0.30196}, {0.00875, 0.00875, 0.30588}, {0.00921, 0.00921, 0.30980}, {0.00969, 0.00969, 0.31373}, {0.01018, 0.01018, 0.31765}, {0.01069, 0.01069, 0.32157}, {0.01122, 0.01122, 0.32549}, {0.01177, 0.01177, 0.32941}, {0.01235, 0.01235, 0.33333}, {0.01294, 0.01294, 0.33725}, {0.01355, 0.01355, 0.34118}, {0.01418, 0.01418, 0.34510}, {0.01484, 0.01484, 0.34902}, {0.01552, 0.01552, 0.35294}, {0.01622, 0.01622, 0.35686}, {0.01694, 0.01694, 0.36078}, {0.01769, 0.01769, 0.36471}, {0.01847, 0.01847, 0.36863}, {0.01926, 0.01926, 0.37255}, {0.02009, 0.02009, 0.37647}, {0.02094, 0.02094, 0.38039}, {0.02181, 0.02181, 0.38431}, {0.02272, 0.02272, 0.38824}, {0.02365, 0.02365, 0.39216}, {0.02461, 0.02461, 0.39608}, {0.02560, 0.02560, 0.40000}, {0.02662, 0.02662, 0.40392}, {0.02767, 0.02767, 0.40784}, {0.02875, 0.02875, 0.41176}, {0.02986, 0.02986, 0.41569}, {0.03100, 0.03100, 0.41961}, {0.03218, 0.03218, 0.42353}, {0.03338, 0.03338, 0.42745}, {0.03463, 0.03463, 0.43137}, {0.03590, 0.03590, 0.43529}, {0.03721, 0.03721, 0.43922}, {0.03856, 0.03856, 0.44314}, {0.03994, 0.03994, 0.44706}, {0.04136, 0.04136, 0.45098}, {0.04282, 0.04282, 0.45490}, {0.04432, 0.04432, 0.45882}, {0.04585, 0.04585, 0.46275}, {0.04743, 0.04743, 0.46667}, {0.04904, 0.04904, 0.47059}, {0.05070, 0.05070, 0.47451}, {0.05239, 0.05239, 0.47843}, {0.05413, 0.05413, 0.48235}, {0.05591, 0.05591, 0.48627}, {0.05774, 0.05774, 0.49020}, {0.05961, 0.05961, 0.49412}, {0.06153, 0.06153, 0.49804}, {0.06349, 0.06349, 0.50196}, {0.06549, 0.06549, 0.50588}, {0.06755, 0.06755, 0.50980}, {0.06965, 0.06965, 0.51373}, {0.07180, 0.07180, 0.51765}, {0.07400, 0.07400, 0.52157}, {0.07625, 0.07625, 0.52549}, {0.07856, 0.07856, 0.52941}, {0.08091, 0.08091, 0.53333}, {0.08331, 0.08331, 0.53725}, {0.08577, 0.08577, 0.54118}, {0.08829, 0.08829, 0.54510}, {0.09086, 0.09086, 0.54902}, {0.09348, 0.09348, 0.55294}, {0.09616, 0.09616, 0.55686}, {0.09890, 0.09890, 0.56078}, {0.10169, 0.10169, 0.56471}, {0.10455, 0.10455, 0.56863}, {0.10746, 0.10746, 0.57255}, {0.11044, 0.11044, 0.57647}, {0.11347, 0.11347, 0.58039}, {0.11657, 0.11657, 0.58431}, {0.11973, 0.11973, 0.58824}, {0.12296, 0.12296, 0.59216}, {0.12624, 0.12624, 0.59608}, {0.12960, 0.12960, 0.60000}, {0.13302, 0.13302, 0.60392}, {0.13651, 0.13651, 0.60784}, {0.14007, 0.14007, 0.61176}, {0.14369, 0.14369, 0.61569}, {0.14739, 0.14739, 0.61961}, {0.15116, 0.15116, 0.62353}, {0.15500, 0.15500, 0.62745}, {0.15891, 0.15891, 0.63137}, {0.16289, 0.16289, 0.63529}, {0.16695, 0.16695, 0.63922}, {0.17109, 0.17109, 0.64314}, {0.17530, 0.17530, 0.64706}, {0.17959, 0.17959, 0.65098}, {0.18395, 0.18395, 0.65490}, {0.18840, 0.18840, 0.65882}, {0.19292, 0.19292, 0.66275}, {0.19753, 0.19753, 0.66667}, {0.20222, 0.20222, 0.67059}, {0.20699, 0.20699, 0.67451}, {0.21185, 0.21185, 0.67843}, {0.21679, 0.21679, 0.68235}, {0.22182, 0.22182, 0.68627}, {0.22693, 0.22693, 0.69020}, {0.23213, 0.23213, 0.69412}, {0.23742, 0.23742, 0.69804}, {0.24280, 0.24280, 0.70196}, {0.24827, 0.24827, 0.70588}, {0.25384, 0.25384, 0.70980}, {0.25949, 0.25949, 0.71373}, {0.26524, 0.26524, 0.71765}, {0.27109, 0.27109, 0.72157}, {0.27703, 0.27703, 0.72549}, {0.28307, 0.28307, 0.72941}, {0.28920, 0.28920, 0.73333}, {0.29544, 0.29544, 0.73725}, {0.30178, 0.30178, 0.74118}, {0.30821, 0.30821, 0.74510}, {0.31476, 0.31476, 0.74902}, {0.32140, 0.32140, 0.75294}, {0.32815, 0.32815, 0.75686}, {0.33500, 0.33500, 0.76078}, {0.34196, 0.34196, 0.76471}, {0.34903, 0.34903, 0.76863}, {0.35621, 0.35621, 0.77255}, {0.36350, 0.36350, 0.77647}, {0.37090, 0.37090, 0.78039}, {0.37841, 0.37841, 0.78431}, {0.38603, 0.38603, 0.78824}, {0.39377, 0.39377, 0.79216}, {0.40163, 0.40163, 0.79608}, {0.40960, 0.40960, 0.80000}, {0.41769, 0.41769, 0.80392}, {0.42590, 0.42590, 0.80784}, {0.43423, 0.43423, 0.81176}, {0.44268, 0.44268, 0.81569}, {0.45126, 0.45126, 0.81961}, {0.45996, 0.45996, 0.82353}, {0.46878, 0.46878, 0.82745}, {0.47773, 0.47773, 0.83137}, {0.48681, 0.48681, 0.83529}, {0.49601, 0.49601, 0.83922}, {0.50535, 0.50535, 0.84314}, {0.51482, 0.51482, 0.84706}, {0.52442, 0.52442, 0.85098}, {0.53415, 0.53415, 0.85490}, {0.54402, 0.54402, 0.85882}, {0.55403, 0.55403, 0.86275}, {0.56417, 0.56417, 0.86667}, {0.57445, 0.57445, 0.87059}, {0.58487, 0.58487, 0.87451}, {0.59543, 0.59543, 0.87843}, {0.60613, 0.60613, 0.88235}, {0.61698, 0.61698, 0.88627}, {0.62798, 0.62798, 0.89020}, {0.63911, 0.63911, 0.89412}, {0.65040, 0.65040, 0.89804}, {0.66184, 0.66184, 0.90196}, {0.67342, 0.67342, 0.90588}, {0.68516, 0.68516, 0.90980}, {0.69705, 0.69705, 0.91373}, {0.70909, 0.70909, 0.91765}, {0.72129, 0.72129, 0.92157}, {0.73365, 0.73365, 0.92549}, {0.74616, 0.74616, 0.92941}, {0.75883, 0.75883, 0.93333}, {0.77167, 0.77167, 0.93725}, {0.78466, 0.78466, 0.94118}, {0.79782, 0.79782, 0.94510}, {0.81115, 0.81115, 0.94902}, {0.82464, 0.82464, 0.95294}, {0.83830, 0.83830, 0.95686}, {0.85213, 0.85213, 0.96078}, {0.86612, 0.86612, 0.96471}, {0.88029, 0.88029, 0.96863}, {0.89464, 0.89464, 0.97255}, {0.90915, 0.90915, 0.97647}, {0.92385, 0.92385, 0.98039}, {0.93872, 0.93872, 0.98431}, {0.95377, 0.95377, 0.98824}, {0.96899, 0.96899, 0.99216}, {0.98441, 0.98441, 0.99608}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("blulut.lasc", blulut_lasc); static RGBColor smooth3_lasc[] = { {0.00000, 0.00000, 0.00784}, {0.00000, 0.00000, 0.01795}, {0.00000, 0.00000, 0.03087}, {0.00000, 0.00000, 0.04434}, {0.00000, 0.00000, 0.05781}, {0.00000, 0.00000, 0.07128}, {0.00000, 0.00000, 0.08475}, {0.00000, 0.00000, 0.09822}, {0.00000, 0.00000, 0.11170}, {0.00000, 0.00000, 0.12231}, {0.00000, 0.00000, 0.13472}, {0.00000, 0.00000, 0.14819}, {0.00000, 0.00000, 0.16166}, {0.00000, 0.00000, 0.17513}, {0.00000, 0.00000, 0.18851}, {0.00000, 0.00000, 0.19862}, {0.00000, 0.00000, 0.21163}, {0.00000, 0.00000, 0.22510}, {0.00000, 0.00000, 0.23857}, {0.00000, 0.00000, 0.25080}, {0.00000, 0.00000, 0.26228}, {0.00000, 0.00000, 0.27885}, {0.00000, 0.00000, 0.28895}, {0.00000, 0.00000, 0.30201}, {0.00000, 0.00000, 0.31308}, {0.00000, 0.00000, 0.32503}, {0.00000, 0.00000, 0.33850}, {0.00000, 0.00000, 0.35197}, {0.00000, 0.00000, 0.36526}, {0.00000, 0.00000, 0.37536}, {0.00000, 0.00000, 0.39146}, {0.00000, 0.00000, 0.40341}, {0.00000, 0.00000, 0.41541}, {0.00000, 0.00000, 0.42754}, {0.00000, 0.00000, 0.43922}, {0.00000, 0.00000, 0.45559}, {0.00000, 0.00000, 0.46570}, {0.00000, 0.00000, 0.47885}, {0.00000, 0.00000, 0.49232}, {0.00000, 0.00000, 0.50579}, {0.00000, 0.00000, 0.51788}, {0.00000, 0.00000, 0.52881}, {0.00000, 0.00000, 0.54228}, {0.00000, 0.00000, 0.55576}, {0.00000, 0.00000, 0.56923}, {0.00000, 0.00000, 0.58016}, {0.00397, 0.00000, 0.59225}, {0.01356, 0.00000, 0.60572}, {0.02791, 0.00000, 0.61919}, {0.04507, 0.00000, 0.63234}, {0.06528, 0.00000, 0.64245}, {0.08235, 0.00000, 0.65569}, {0.10178, 0.00000, 0.66916}, {0.12198, 0.00000, 0.68263}, {0.14219, 0.00000, 0.69462}, {0.16240, 0.00000, 0.70565}, {0.18261, 0.00000, 0.71912}, {0.20281, 0.00000, 0.73259}, {0.21984, 0.00000, 0.74607}, {0.23668, 0.00000, 0.75954}, {0.25559, 0.00000, 0.77093}, {0.27580, 0.00000, 0.78256}, {0.29504, 0.00000, 0.79603}, {0.31063, 0.00000, 0.80909}, {0.31737, 0.00000, 0.81919}, {0.31765, 0.00000, 0.83575}, {0.31765, 0.00000, 0.84992}, {0.31765, 0.00000, 0.86339}, {0.31765, 0.00000, 0.87686}, {0.31765, 0.00000, 0.88932}, {0.31719, 0.00000, 0.89942}, {0.31382, 0.00000, 0.90953}, {0.31373, 0.00000, 0.92291}, {0.31373, 0.00000, 0.93638}, {0.31373, 0.00000, 0.94985}, {0.31373, 0.00000, 0.96332}, {0.31373, 0.00000, 0.97573}, {0.40250, 0.05175, 0.86307}, {0.99189, 0.39528, 0.05813}, {1.00000, 0.40000, 0.04706}, {0.84776, 0.30312, 0.04983}, {0.55402, 0.11438, 0.05319}, {0.38644, 0.00000, 0.05988}, {0.40664, 0.00000, 0.07442}, {0.42685, 0.00000, 0.09799}, {0.44706, 0.00000, 0.12157}, {0.46727, 0.00000, 0.13841}, {0.48466, 0.00000, 0.15806}, {0.50376, 0.00000, 0.17827}, {0.52397, 0.00000, 0.20018}, {0.54417, 0.00000, 0.22261}, {0.56438, 0.00000, 0.24281}, {0.58459, 0.00000, 0.26302}, {0.60480, 0.00000, 0.28323}, {0.62501, 0.00000, 0.30344}, {0.64521, 0.00000, 0.32364}, {0.66542, 0.00000, 0.34385}, {0.68563, 0.00000, 0.36406}, {0.70584, 0.00000, 0.38491}, {0.72604, 0.00000, 0.40840}, {0.74625, 0.00000, 0.42860}, {0.76937, 0.00000, 0.44881}, {0.79059, 0.00000, 0.46667}, {0.81260, 0.00000, 0.48711}, {0.83493, 0.00000, 0.50944}, {0.85513, 0.00000, 0.52964}, {0.87576, 0.00000, 0.54985}, {0.90607, 0.00000, 0.57006}, {0.93933, 0.00000, 0.59027}, {0.96821, 0.00000, 0.61047}, {0.98777, 0.00000, 0.63068}, {0.99737, 0.00000, 0.65089}, {1.00000, 0.00000, 0.67110}, {1.00000, 0.00092, 0.69149}, {1.00000, 0.01776, 0.71506}, {1.00000, 0.03760, 0.73564}, {1.00000, 0.05781, 0.75585}, {1.00000, 0.07802, 0.77606}, {1.00000, 0.09822, 0.79626}, {1.00000, 0.11922, 0.81647}, {1.00000, 0.14279, 0.83668}, {1.00000, 0.16637, 0.85689}, {1.00000, 0.18690, 0.88014}, {1.00000, 0.20960, 0.90122}, {1.00000, 0.23124, 0.92143}, {1.00000, 0.25144, 0.94164}, {1.00000, 0.27165, 0.96185}, {1.00000, 0.29214, 0.98178}, {1.00000, 0.31571, 0.99862}, {1.00000, 0.33310, 0.98454}, {1.00000, 0.35248, 0.96517}, {1.00000, 0.37269, 0.94496}, {1.00000, 0.39290, 0.92332}, {1.00000, 0.41223, 0.89974}, {1.00000, 0.42907, 0.87649}, {1.00000, 0.44591, 0.85628}, {1.00000, 0.46588, 0.83294}, {1.00000, 0.48609, 0.81195}, {1.00000, 0.50630, 0.79174}, {1.00000, 0.52503, 0.77006}, {1.00000, 0.54279, 0.74740}, {1.00000, 0.56263, 0.72720}, {1.00000, 0.57947, 0.70699}, {1.00000, 0.59949, 0.68360}, {1.00000, 0.61707, 0.66265}, {1.00000, 0.62976, 0.64037}, {1.00000, 0.63682, 0.61831}, {1.00000, 0.63922, 0.59811}, {1.00000, 0.63922, 0.57790}, {1.00000, 0.63922, 0.55769}, {1.00000, 0.63922, 0.53425}, {1.00000, 0.63922, 0.51335}, {1.00000, 0.63922, 0.49102}, {1.00000, 0.63922, 0.46902}, {1.00000, 0.63922, 0.44881}, {1.00000, 0.63922, 0.42860}, {1.00000, 0.63922, 0.40839}, {1.00000, 0.63922, 0.38491}, {1.00000, 0.63922, 0.36406}, {1.00000, 0.63922, 0.34168}, {0.99838, 0.63922, 0.31972}, {0.99077, 0.63922, 0.29845}, {0.97241, 0.63922, 0.27589}, {0.94546, 0.63922, 0.25905}, {0.91520, 0.63922, 0.23557}, {0.88489, 0.63922, 0.21476}, {0.85457, 0.63922, 0.19234}, {0.82426, 0.63922, 0.16876}, {0.79395, 0.63922, 0.14629}, {0.76309, 0.63922, 0.12664}, {0.72941, 0.63922, 0.10980}, {0.70583, 0.63922, 0.08622}, {0.69070, 0.63922, 0.06265}, {0.67949, 0.63922, 0.04133}, {0.67793, 0.64092, 0.02113}, {0.68582, 0.64545, 0.00554}, {0.69772, 0.65278, 0.00000}, {0.71793, 0.66307, 0.00000}, {0.73814, 0.68665, 0.00000}, {0.75834, 0.71022, 0.00000}, {0.77855, 0.73380, 0.00000}, {0.79876, 0.75738, 0.00000}, {0.81897, 0.78095, 0.00000}, {0.83982, 0.80517, 0.00000}, {0.86330, 0.83202, 0.00000}, {0.88351, 0.85560, 0.00000}, {0.90372, 0.88208, 0.00000}, {0.92393, 0.90667, 0.00000}, {0.94413, 0.93025, 0.00000}, {0.96434, 0.95382, 0.00000}, {0.98386, 0.97740, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00305}, {1.00000, 1.00000, 0.01638}, {1.00000, 1.00000, 0.03322}, {1.00000, 1.00000, 0.05006}, {1.00000, 1.00000, 0.06773}, {1.00000, 1.00000, 0.08794}, {1.00000, 1.00000, 0.10815}, {1.00000, 1.00000, 0.12526}, {1.00000, 1.00000, 0.14464}, {1.00000, 1.00000, 0.16485}, {1.00000, 1.00000, 0.18506}, {1.00000, 1.00000, 0.20439}, {1.00000, 1.00000, 0.22155}, {1.00000, 1.00000, 0.24176}, {1.00000, 1.00000, 0.25883}, {1.00000, 1.00000, 0.27567}, {1.00000, 1.00000, 0.28642}, {1.00000, 1.00000, 0.28872}, {1.00000, 1.00000, 0.28350}, {1.00000, 1.00000, 0.27229}, {1.00000, 1.00000, 0.25208}, {1.00000, 1.00000, 0.22869}, {1.00000, 1.00000, 0.20511}, {1.00000, 1.00000, 0.18154}, {1.00000, 1.00000, 0.15796}, {1.00000, 1.00000, 0.13536}, {1.00000, 1.00000, 0.11473}, {1.00000, 1.00000, 0.09116}, {1.00000, 1.00000, 0.06435}, {1.00000, 1.00000, 0.04008}, {1.00000, 1.00000, 0.02076}, {1.00000, 1.00000, 0.00706}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.09305}, {1.00000, 1.00000, 0.33136}, {1.00000, 1.00000, 0.60966}, {1.00000, 1.00000, 0.83605}, {0.96674, 1.00000, 0.96343}, {0.75749, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, }; new ColorMapInfo("smooth3.lasc", smooth3_lasc); static RGBColor idl2_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00000, 0.14118, 0.00000}, {0.00000, 0.28235, 0.00000}, {0.00000, 0.29412, 0.00000}, {0.00000, 0.30980, 0.00000}, {0.00000, 0.32157, 0.00000}, {0.00000, 0.33725, 0.00000}, {0.00000, 0.35294, 0.00000}, {0.00000, 0.36471, 0.00000}, {0.00000, 0.38039, 0.00000}, {0.00000, 0.39216, 0.00000}, {0.00000, 0.40784, 0.00000}, {0.00000, 0.42353, 0.00000}, {0.00000, 0.45882, 0.00000}, {0.00000, 0.49412, 0.00000}, {0.00000, 0.52941, 0.00000}, {0.00000, 0.56471, 0.00000}, {0.00000, 0.60000, 0.00000}, {0.00000, 0.63529, 0.00000}, {0.00000, 0.67059, 0.00000}, {0.00000, 0.70588, 0.00000}, {0.00000, 0.74118, 0.00000}, {0.00000, 0.77647, 0.00000}, {0.00000, 0.81176, 0.00000}, {0.00000, 0.84706, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.91765, 0.00000}, {0.00000, 0.95294, 0.00000}, {0.00000, 0.98824, 0.00000}, {0.02353, 0.97647, 0.00000}, {0.04706, 0.96471, 0.00000}, {0.07059, 0.95294, 0.00000}, {0.09412, 0.94118, 0.00000}, {0.11765, 0.91765, 0.00000}, {0.14118, 0.89412, 0.00000}, {0.16471, 0.87059, 0.00000}, {0.18824, 0.84706, 0.00000}, {0.21176, 0.82353, 0.00000}, {0.23529, 0.80000, 0.00000}, {0.25882, 0.77647, 0.00000}, {0.28235, 0.75294, 0.00000}, {0.30588, 0.72941, 0.00000}, {0.32941, 0.70588, 0.00000}, {0.35294, 0.68235, 0.00000}, {0.37647, 0.65882, 0.00000}, {0.40000, 0.63529, 0.00000}, {0.42353, 0.61176, 0.00000}, {0.44706, 0.58824, 0.00000}, {0.47059, 0.56471, 0.00000}, {0.49412, 0.54118, 0.00000}, {0.51765, 0.51765, 0.00000}, {0.54118, 0.49412, 0.00000}, {0.56471, 0.47059, 0.00000}, {0.58824, 0.44706, 0.00000}, {0.61176, 0.42353, 0.00000}, {0.63529, 0.40000, 0.00000}, {0.65882, 0.37647, 0.00000}, {0.68235, 0.35294, 0.00000}, {0.70588, 0.32941, 0.00000}, {0.72941, 0.30588, 0.00000}, {0.75294, 0.28235, 0.00000}, {0.77647, 0.25882, 0.00000}, {0.80000, 0.23529, 0.00000}, {0.82353, 0.21176, 0.00000}, {0.84706, 0.18824, 0.00000}, {0.87059, 0.16471, 0.00000}, {0.89412, 0.14118, 0.00000}, {0.91765, 0.11765, 0.00000}, {0.94118, 0.09412, 0.00000}, {0.95294, 0.07059, 0.00000}, {0.96471, 0.04706, 0.00000}, {0.97647, 0.02353, 0.00000}, {0.98824, 0.00000, 0.00000}, {0.98824, 0.00000, 0.00000}, {0.98824, 0.00000, 0.00000}, {0.98824, 0.00000, 0.00000}, {0.98824, 0.00000, 0.00392}, {0.98431, 0.00000, 0.01176}, {0.98039, 0.00000, 0.01961}, {0.97647, 0.00000, 0.02745}, {0.97255, 0.00000, 0.03529}, {0.97255, 0.00000, 0.03922}, {0.97255, 0.00000, 0.04706}, {0.97255, 0.00000, 0.05490}, {0.97255, 0.00000, 0.06275}, {0.96863, 0.00000, 0.07059}, {0.96471, 0.00000, 0.07843}, {0.96078, 0.00000, 0.08627}, {0.95686, 0.00000, 0.09804}, {0.95294, 0.00000, 0.10588}, {0.94902, 0.00000, 0.11373}, {0.94510, 0.00000, 0.12157}, {0.94118, 0.00000, 0.13333}, {0.94118, 0.00000, 0.13725}, {0.93725, 0.00000, 0.14510}, {0.93333, 0.00000, 0.15294}, {0.92941, 0.00000, 0.16078}, {0.92549, 0.00000, 0.16863}, {0.92549, 0.00000, 0.17647}, {0.92549, 0.00000, 0.18431}, {0.92549, 0.00000, 0.19608}, {0.92157, 0.00000, 0.20392}, {0.91765, 0.00000, 0.21176}, {0.91373, 0.00000, 0.21961}, {0.90980, 0.00000, 0.23137}, {0.90588, 0.00000, 0.23922}, {0.90196, 0.00000, 0.24706}, {0.89804, 0.00000, 0.25490}, {0.89412, 0.00000, 0.26275}, {0.89412, 0.00000, 0.26667}, {0.89412, 0.00000, 0.27451}, {0.89412, 0.00000, 0.28235}, {0.89412, 0.00000, 0.29020}, {0.89020, 0.00000, 0.29804}, {0.88627, 0.00000, 0.30588}, {0.88235, 0.00000, 0.31373}, {0.87843, 0.00000, 0.32549}, {0.87451, 0.00000, 0.33333}, {0.87059, 0.00000, 0.34118}, {0.86667, 0.00000, 0.34902}, {0.86275, 0.00392, 0.36078}, {0.85882, 0.00392, 0.36863}, {0.85490, 0.00392, 0.37647}, {0.85098, 0.00392, 0.38431}, {0.84706, 0.00000, 0.39608}, {0.84706, 0.00000, 0.40000}, {0.84706, 0.00000, 0.40784}, {0.84706, 0.00000, 0.41569}, {0.84706, 0.00000, 0.42353}, {0.84314, 0.00000, 0.43137}, {0.83922, 0.00000, 0.43922}, {0.83529, 0.00000, 0.44706}, {0.83137, 0.00000, 0.45490}, {0.82745, 0.00000, 0.46275}, {0.82353, 0.00000, 0.47059}, {0.81961, 0.00000, 0.47843}, {0.81569, 0.00000, 0.49020}, {0.81176, 0.00000, 0.49804}, {0.80784, 0.00000, 0.50588}, {0.80392, 0.00000, 0.51373}, {0.80000, 0.00000, 0.52549}, {0.80000, 0.00000, 0.52941}, {0.80000, 0.00000, 0.53725}, {0.80000, 0.00000, 0.54510}, {0.80000, 0.00000, 0.55294}, {0.79608, 0.00000, 0.56078}, {0.79216, 0.00000, 0.56863}, {0.78824, 0.00000, 0.57647}, {0.78431, 0.00000, 0.58824}, {0.78039, 0.00000, 0.59608}, {0.77647, 0.00000, 0.60392}, {0.77255, 0.00000, 0.61176}, {0.76863, 0.00000, 0.62353}, {0.76863, 0.00000, 0.62745}, {0.76863, 0.00000, 0.63529}, {0.76863, 0.00000, 0.63922}, {0.76863, 0.00000, 0.64706}, {0.76471, 0.00000, 0.65490}, {0.76078, 0.00000, 0.66275}, {0.75686, 0.00000, 0.67059}, {0.75294, 0.00000, 0.68235}, {0.74902, 0.00000, 0.69020}, {0.74510, 0.00000, 0.69804}, {0.74118, 0.00000, 0.70588}, {0.73725, 0.00000, 0.71765}, {0.73333, 0.00000, 0.72549}, {0.72941, 0.00000, 0.73333}, {0.72549, 0.00000, 0.74118}, {0.72157, 0.00000, 0.75294}, {0.72157, 0.00000, 0.75686}, {0.72157, 0.00000, 0.76471}, {0.72157, 0.00000, 0.77255}, {0.72157, 0.00000, 0.78039}, {0.71765, 0.00000, 0.78824}, {0.71373, 0.00000, 0.79608}, {0.70980, 0.00000, 0.80392}, {0.70588, 0.00000, 0.81569}, {0.70196, 0.00000, 0.82353}, {0.69804, 0.00000, 0.83137}, {0.69412, 0.00000, 0.83922}, {0.69020, 0.00000, 0.84706}, {0.69020, 0.00000, 0.85098}, {0.69020, 0.00000, 0.85882}, {0.69020, 0.00000, 0.86667}, {0.69020, 0.00000, 0.87451}, {0.68627, 0.00000, 0.88235}, {0.68235, 0.00000, 0.89020}, {0.67843, 0.00000, 0.89804}, {0.67451, 0.00000, 0.90980}, {0.67059, 0.00000, 0.91765}, {0.66667, 0.00000, 0.92549}, {0.66275, 0.00000, 0.93333}, {0.65882, 0.00000, 0.94510}, {0.65490, 0.00000, 0.95294}, {0.65098, 0.00000, 0.96078}, {0.64706, 0.00000, 0.96863}, {0.64314, 0.00000, 0.98039}, {0.64314, 0.00000, 0.98431}, {0.64314, 0.00000, 0.98824}, {0.64314, 0.00000, 0.99216}, {0.64314, 0.00000, 1.00000}, {0.63922, 0.00000, 1.00000}, {0.63529, 0.00000, 1.00000}, {0.63137, 0.00000, 1.00000}, {0.62745, 0.00000, 1.00000}, {0.62353, 0.00000, 1.00000}, {0.61961, 0.00000, 1.00000}, {0.61569, 0.00000, 1.00000}, {0.61176, 0.00000, 1.00000}, {0.60784, 0.00000, 1.00000}, {0.60392, 0.00000, 1.00000}, {0.60000, 0.00000, 1.00000}, {0.59608, 0.00000, 1.00000}, {0.59608, 0.00000, 1.00000}, {0.59608, 0.00000, 1.00000}, {0.59608, 0.00000, 1.00000}, {0.59608, 0.00000, 1.00000}, {0.59216, 0.00000, 1.00000}, {0.58824, 0.00000, 1.00000}, {0.58431, 0.00000, 1.00000}, {0.58039, 0.00000, 1.00000}, {0.59216, 0.03137, 1.00000}, {0.60392, 0.06275, 1.00000}, {0.61569, 0.09412, 1.00000}, {0.62745, 0.12549, 1.00000}, {0.63922, 0.15686, 1.00000}, {0.65098, 0.18824, 1.00000}, {0.66275, 0.21961, 1.00000}, {0.67451, 0.25098, 1.00000}, {0.69020, 0.28235, 1.00000}, {0.70588, 0.31373, 1.00000}, {0.72157, 0.34510, 1.00000}, {0.73725, 0.37647, 1.00000}, {0.74902, 0.40784, 1.00000}, {0.76078, 0.43922, 1.00000}, {0.77255, 0.47059, 1.00000}, {0.78431, 0.50196, 1.00000}, {0.79608, 0.52941, 1.00000}, {0.80784, 0.55686, 1.00000}, {0.81961, 0.58431, 1.00000}, {0.83137, 0.61176, 1.00000}, {0.84314, 0.64314, 1.00000}, {0.85490, 0.67451, 1.00000}, {0.86667, 0.70588, 1.00000}, {0.87843, 0.73725, 1.00000}, {0.89412, 0.76863, 1.00000}, {0.90980, 0.80000, 1.00000}, {0.92549, 0.83137, 1.00000}, {0.94118, 0.86275, 1.00000}, {0.95294, 0.89412, 1.00000}, {0.96471, 0.92549, 1.00000}, {0.97647, 0.95686, 1.00000}, {0.98824, 0.98824, 1.00000}, {0.99216, 0.99216, 1.00000}, {0.99608, 0.99608, 1.00000}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("idl2.lasc", idl2_lasc); static RGBColor rainbow2_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.03137, 0.00000, 0.03137}, {0.06275, 0.00000, 0.06275}, {0.09412, 0.00000, 0.09412}, {0.12549, 0.00000, 0.12549}, {0.15686, 0.00000, 0.15686}, {0.18824, 0.00000, 0.18824}, {0.21961, 0.00000, 0.21961}, {0.25098, 0.00000, 0.25098}, {0.28235, 0.00000, 0.28235}, {0.31373, 0.00000, 0.31373}, {0.34510, 0.00000, 0.34510}, {0.37647, 0.00000, 0.37647}, {0.40784, 0.00000, 0.40784}, {0.43922, 0.00000, 0.43922}, {0.47059, 0.00000, 0.47059}, {0.50196, 0.00000, 0.50196}, {0.53333, 0.00000, 0.53333}, {0.56471, 0.00000, 0.56471}, {0.59608, 0.00000, 0.59608}, {0.62745, 0.00000, 0.62745}, {0.65882, 0.00000, 0.65882}, {0.69020, 0.00000, 0.69020}, {0.72157, 0.00000, 0.72157}, {0.75294, 0.00000, 0.75294}, {0.78431, 0.00000, 0.78431}, {0.81569, 0.00000, 0.81569}, {0.84706, 0.00000, 0.84706}, {0.87843, 0.00000, 0.87843}, {0.90980, 0.00000, 0.90980}, {0.94118, 0.00000, 0.94118}, {0.97255, 0.00000, 0.97255}, {1.00000, 0.00000, 1.00000}, {0.96863, 0.00000, 1.00000}, {0.93725, 0.00000, 1.00000}, {0.90588, 0.00000, 1.00000}, {0.87451, 0.00000, 1.00000}, {0.84314, 0.00000, 1.00000}, {0.81176, 0.00000, 1.00000}, {0.78039, 0.00000, 1.00000}, {0.74902, 0.00000, 1.00000}, {0.71765, 0.00000, 1.00000}, {0.68627, 0.00000, 1.00000}, {0.65490, 0.00000, 1.00000}, {0.62353, 0.00000, 1.00000}, {0.59216, 0.00000, 1.00000}, {0.56078, 0.00000, 1.00000}, {0.52941, 0.00000, 1.00000}, {0.49804, 0.00000, 1.00000}, {0.46667, 0.00000, 1.00000}, {0.43529, 0.00000, 1.00000}, {0.40392, 0.00000, 1.00000}, {0.37255, 0.00000, 1.00000}, {0.34118, 0.00000, 1.00000}, {0.30980, 0.00000, 1.00000}, {0.27843, 0.00000, 1.00000}, {0.24706, 0.00000, 1.00000}, {0.21569, 0.00000, 1.00000}, {0.18431, 0.00000, 1.00000}, {0.15294, 0.00000, 1.00000}, {0.12157, 0.00000, 1.00000}, {0.09020, 0.00000, 1.00000}, {0.05882, 0.00000, 1.00000}, {0.02745, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.03137, 1.00000}, {0.00000, 0.06275, 1.00000}, {0.00000, 0.09412, 1.00000}, {0.00000, 0.12549, 1.00000}, {0.00000, 0.15686, 1.00000}, {0.00000, 0.18824, 1.00000}, {0.00000, 0.21961, 1.00000}, {0.00000, 0.25098, 1.00000}, {0.00000, 0.28235, 1.00000}, {0.00000, 0.31373, 1.00000}, {0.00000, 0.34510, 1.00000}, {0.00000, 0.37647, 1.00000}, {0.00000, 0.40784, 1.00000}, {0.00000, 0.43922, 1.00000}, {0.00000, 0.47059, 1.00000}, {0.00000, 0.50196, 1.00000}, {0.00000, 0.53333, 1.00000}, {0.00000, 0.56471, 1.00000}, {0.00000, 0.59608, 1.00000}, {0.00000, 0.62745, 1.00000}, {0.00000, 0.65882, 1.00000}, {0.00000, 0.69020, 1.00000}, {0.00000, 0.72157, 1.00000}, {0.00000, 0.75294, 1.00000}, {0.00000, 0.78431, 1.00000}, {0.00000, 0.81569, 1.00000}, {0.00000, 0.84706, 1.00000}, {0.00000, 0.87843, 1.00000}, {0.00000, 0.90980, 1.00000}, {0.00000, 0.94118, 1.00000}, {0.00000, 0.97255, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 0.96863}, {0.00000, 1.00000, 0.93725}, {0.00000, 1.00000, 0.90588}, {0.00000, 1.00000, 0.87451}, {0.00000, 1.00000, 0.84314}, {0.00000, 1.00000, 0.81176}, {0.00000, 1.00000, 0.78039}, {0.00000, 1.00000, 0.74902}, {0.00000, 1.00000, 0.71765}, {0.00000, 1.00000, 0.68627}, {0.00000, 1.00000, 0.65490}, {0.00000, 1.00000, 0.62353}, {0.00000, 1.00000, 0.59216}, {0.00000, 1.00000, 0.56078}, {0.00000, 1.00000, 0.52941}, {0.00000, 1.00000, 0.49804}, {0.00000, 1.00000, 0.46667}, {0.00000, 1.00000, 0.43529}, {0.00000, 1.00000, 0.40392}, {0.00000, 1.00000, 0.37255}, {0.00000, 1.00000, 0.34118}, {0.00000, 1.00000, 0.30980}, {0.00000, 1.00000, 0.27843}, {0.00000, 1.00000, 0.24706}, {0.00000, 1.00000, 0.21569}, {0.00000, 1.00000, 0.18431}, {0.00000, 1.00000, 0.15294}, {0.00000, 1.00000, 0.12157}, {0.00000, 1.00000, 0.09020}, {0.00000, 1.00000, 0.05882}, {0.00000, 1.00000, 0.02745}, {0.00000, 1.00000, 0.00000}, {0.03137, 1.00000, 0.00000}, {0.06275, 1.00000, 0.00000}, {0.09412, 1.00000, 0.00000}, {0.12549, 1.00000, 0.00000}, {0.15686, 1.00000, 0.00000}, {0.18824, 1.00000, 0.00000}, {0.21961, 1.00000, 0.00000}, {0.25098, 1.00000, 0.00000}, {0.28235, 1.00000, 0.00000}, {0.31373, 1.00000, 0.00000}, {0.34510, 1.00000, 0.00000}, {0.37647, 1.00000, 0.00000}, {0.40784, 1.00000, 0.00000}, {0.43922, 1.00000, 0.00000}, {0.47059, 1.00000, 0.00000}, {0.50196, 1.00000, 0.00000}, {0.53333, 1.00000, 0.00000}, {0.56471, 1.00000, 0.00000}, {0.59608, 1.00000, 0.00000}, {0.62745, 1.00000, 0.00000}, {0.65882, 1.00000, 0.00000}, {0.69020, 1.00000, 0.00000}, {0.72157, 1.00000, 0.00000}, {0.75294, 1.00000, 0.00000}, {0.78431, 1.00000, 0.00000}, {0.81569, 1.00000, 0.00000}, {0.84706, 1.00000, 0.00000}, {0.87843, 1.00000, 0.00000}, {0.90980, 1.00000, 0.00000}, {0.94118, 1.00000, 0.00000}, {0.97255, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 0.98431, 0.00000}, {1.00000, 0.96863, 0.00000}, {1.00000, 0.95294, 0.00000}, {1.00000, 0.93725, 0.00000}, {1.00000, 0.92157, 0.00000}, {1.00000, 0.90588, 0.00000}, {1.00000, 0.89020, 0.00000}, {1.00000, 0.87451, 0.00000}, {1.00000, 0.85882, 0.00000}, {1.00000, 0.84314, 0.00000}, {1.00000, 0.82745, 0.00000}, {1.00000, 0.81176, 0.00000}, {1.00000, 0.79608, 0.00000}, {1.00000, 0.78039, 0.00000}, {1.00000, 0.76471, 0.00000}, {1.00000, 0.74902, 0.00000}, {1.00000, 0.73333, 0.00000}, {1.00000, 0.71765, 0.00000}, {1.00000, 0.70196, 0.00000}, {1.00000, 0.68627, 0.00000}, {1.00000, 0.67059, 0.00000}, {1.00000, 0.65490, 0.00000}, {1.00000, 0.63922, 0.00000}, {1.00000, 0.62353, 0.00000}, {1.00000, 0.60784, 0.00000}, {1.00000, 0.59216, 0.00000}, {1.00000, 0.57647, 0.00000}, {1.00000, 0.56078, 0.00000}, {1.00000, 0.54510, 0.00000}, {1.00000, 0.52941, 0.00000}, {1.00000, 0.51373, 0.00000}, {1.00000, 0.49804, 0.00000}, {1.00000, 0.48235, 0.00000}, {1.00000, 0.46667, 0.00000}, {1.00000, 0.45098, 0.00000}, {1.00000, 0.43529, 0.00000}, {1.00000, 0.41961, 0.00000}, {1.00000, 0.40392, 0.00000}, {1.00000, 0.38824, 0.00000}, {1.00000, 0.37255, 0.00000}, {1.00000, 0.35686, 0.00000}, {1.00000, 0.34118, 0.00000}, {1.00000, 0.32549, 0.00000}, {1.00000, 0.30980, 0.00000}, {1.00000, 0.29412, 0.00000}, {1.00000, 0.27843, 0.00000}, {1.00000, 0.26275, 0.00000}, {1.00000, 0.24706, 0.00000}, {1.00000, 0.23137, 0.00000}, {1.00000, 0.21569, 0.00000}, {1.00000, 0.20000, 0.00000}, {1.00000, 0.18431, 0.00000}, {1.00000, 0.16863, 0.00000}, {1.00000, 0.15294, 0.00000}, {1.00000, 0.13725, 0.00000}, {1.00000, 0.12157, 0.00000}, {1.00000, 0.10588, 0.00000}, {1.00000, 0.09020, 0.00000}, {1.00000, 0.07451, 0.00000}, {1.00000, 0.05882, 0.00000}, {1.00000, 0.04314, 0.00000}, {1.00000, 0.02745, 0.00000}, {1.00000, 0.01176, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.03137, 0.03137}, {1.00000, 0.06275, 0.06275}, {1.00000, 0.09412, 0.09412}, {1.00000, 0.12549, 0.12549}, {1.00000, 0.15686, 0.15686}, {1.00000, 0.18824, 0.18824}, {1.00000, 0.21961, 0.21961}, {1.00000, 0.25098, 0.25098}, {1.00000, 0.28235, 0.28235}, {1.00000, 0.31373, 0.31373}, {1.00000, 0.34510, 0.34510}, {1.00000, 0.37647, 0.37647}, {1.00000, 0.40784, 0.40784}, {1.00000, 0.43922, 0.43922}, {1.00000, 0.47059, 0.47059}, {1.00000, 0.50196, 0.50196}, {1.00000, 0.53333, 0.53333}, {1.00000, 0.56471, 0.56471}, {1.00000, 0.59608, 0.59608}, {1.00000, 0.62745, 0.62745}, {1.00000, 0.65882, 0.65882}, {1.00000, 0.69020, 0.69020}, {1.00000, 0.72157, 0.72157}, {1.00000, 0.75294, 0.75294}, {1.00000, 0.78431, 0.78431}, {1.00000, 0.81569, 0.81569}, {1.00000, 0.84706, 0.84706}, {1.00000, 0.87843, 0.87843}, {1.00000, 0.90980, 0.90980}, {1.00000, 0.94118, 0.94118}, {1.00000, 0.97255, 0.97255}, }; new ColorMapInfo("rainbow2.lasc", rainbow2_lasc); static RGBColor standard_lasc[] = { {0.00392, 0.00392, 0.33333}, {0.00784, 0.00784, 0.34118}, {0.01176, 0.01176, 0.34902}, {0.01569, 0.01569, 0.35686}, {0.01961, 0.01961, 0.36471}, {0.02353, 0.02353, 0.37255}, {0.02745, 0.02745, 0.38039}, {0.03137, 0.03137, 0.38824}, {0.03529, 0.03529, 0.39608}, {0.03922, 0.03922, 0.40392}, {0.04314, 0.04314, 0.41176}, {0.04706, 0.04706, 0.41961}, {0.05098, 0.05098, 0.42745}, {0.05490, 0.05490, 0.43529}, {0.05882, 0.05882, 0.44314}, {0.06275, 0.06275, 0.45098}, {0.06667, 0.06667, 0.45882}, {0.07059, 0.07059, 0.46667}, {0.07451, 0.07451, 0.47451}, {0.07843, 0.07843, 0.48235}, {0.08235, 0.08235, 0.49020}, {0.08627, 0.08627, 0.49804}, {0.09020, 0.09020, 0.50588}, {0.09412, 0.09412, 0.51373}, {0.09804, 0.09804, 0.52157}, {0.10196, 0.10196, 0.52941}, {0.10588, 0.10588, 0.53725}, {0.10980, 0.10980, 0.54510}, {0.11373, 0.11373, 0.55294}, {0.11765, 0.11765, 0.56078}, {0.12157, 0.12157, 0.56863}, {0.12549, 0.12549, 0.57647}, {0.12941, 0.12941, 0.58431}, {0.13333, 0.13333, 0.59216}, {0.13725, 0.13725, 0.60000}, {0.14118, 0.14118, 0.60784}, {0.14510, 0.14510, 0.61569}, {0.14902, 0.14902, 0.62353}, {0.15294, 0.15294, 0.63137}, {0.15686, 0.15686, 0.63922}, {0.16078, 0.16078, 0.64706}, {0.16471, 0.16471, 0.65490}, {0.16863, 0.16863, 0.66275}, {0.17255, 0.17255, 0.67059}, {0.17647, 0.17647, 0.67843}, {0.18039, 0.18039, 0.68627}, {0.18431, 0.18431, 0.69412}, {0.18824, 0.18824, 0.70196}, {0.19216, 0.19216, 0.70980}, {0.19608, 0.19608, 0.71765}, {0.20000, 0.20000, 0.72549}, {0.20392, 0.20392, 0.73333}, {0.20784, 0.20784, 0.74118}, {0.21176, 0.21176, 0.74902}, {0.21569, 0.21569, 0.75686}, {0.21961, 0.21961, 0.76471}, {0.22353, 0.22353, 0.77255}, {0.22745, 0.22745, 0.78039}, {0.23137, 0.23137, 0.78824}, {0.23529, 0.23529, 0.79608}, {0.23922, 0.23922, 0.80392}, {0.24314, 0.24314, 0.81176}, {0.24706, 0.24706, 0.81961}, {0.25098, 0.25098, 0.82745}, {0.25490, 0.25490, 0.83529}, {0.25882, 0.25882, 0.84314}, {0.26275, 0.26275, 0.85098}, {0.26667, 0.26667, 0.85882}, {0.27059, 0.27059, 0.86667}, {0.27451, 0.27451, 0.87451}, {0.27843, 0.27843, 0.88235}, {0.28235, 0.28235, 0.89020}, {0.28627, 0.28627, 0.89804}, {0.29020, 0.29020, 0.90588}, {0.29412, 0.29412, 0.91373}, {0.29804, 0.29804, 0.92157}, {0.30196, 0.30196, 0.92941}, {0.30588, 0.30588, 0.93725}, {0.30980, 0.30980, 0.94510}, {0.31373, 0.31373, 0.95294}, {0.31765, 0.31765, 0.96078}, {0.32157, 0.32157, 0.96863}, {0.32549, 0.32549, 0.97647}, {0.32941, 0.32941, 0.98431}, {0.33333, 0.33333, 0.99216}, {0.00392, 0.33333, 0.00392}, {0.00784, 0.34118, 0.00784}, {0.01176, 0.34902, 0.01176}, {0.01569, 0.35686, 0.01569}, {0.01961, 0.36471, 0.01961}, {0.02353, 0.37255, 0.02353}, {0.02745, 0.38039, 0.02745}, {0.03137, 0.38824, 0.03137}, {0.03529, 0.39608, 0.03529}, {0.03922, 0.40392, 0.03922}, {0.04314, 0.41176, 0.04314}, {0.04706, 0.41961, 0.04706}, {0.05098, 0.42745, 0.05098}, {0.05490, 0.43529, 0.05490}, {0.05882, 0.44314, 0.05882}, {0.06275, 0.45098, 0.06275}, {0.06667, 0.45882, 0.06667}, {0.07059, 0.46667, 0.07059}, {0.07451, 0.47451, 0.07451}, {0.07843, 0.48235, 0.07843}, {0.08235, 0.49020, 0.08235}, {0.08627, 0.49804, 0.08627}, {0.09020, 0.50588, 0.09020}, {0.09412, 0.51373, 0.09412}, {0.09804, 0.52157, 0.09804}, {0.10196, 0.52941, 0.10196}, {0.10588, 0.53725, 0.10588}, {0.10980, 0.54510, 0.10980}, {0.11373, 0.55294, 0.11373}, {0.11765, 0.56078, 0.11765}, {0.12157, 0.56863, 0.12157}, {0.12549, 0.57647, 0.12549}, {0.12941, 0.58431, 0.12941}, {0.13333, 0.59216, 0.13333}, {0.13725, 0.60000, 0.13725}, {0.14118, 0.60784, 0.14118}, {0.14510, 0.61569, 0.14510}, {0.14902, 0.62353, 0.14902}, {0.15294, 0.63137, 0.15294}, {0.15686, 0.63922, 0.15686}, {0.16078, 0.64706, 0.16078}, {0.16471, 0.65490, 0.16471}, {0.16863, 0.66275, 0.16863}, {0.17255, 0.67059, 0.17255}, {0.17647, 0.67843, 0.17647}, {0.18039, 0.68627, 0.18039}, {0.18431, 0.69412, 0.18431}, {0.18824, 0.70196, 0.18824}, {0.19216, 0.70980, 0.19216}, {0.19608, 0.71765, 0.19608}, {0.20000, 0.72549, 0.20000}, {0.20392, 0.73333, 0.20392}, {0.20784, 0.74118, 0.20784}, {0.21176, 0.74902, 0.21176}, {0.21569, 0.75686, 0.21569}, {0.21961, 0.76471, 0.21961}, {0.22353, 0.77255, 0.22353}, {0.22745, 0.78039, 0.22745}, {0.23137, 0.78824, 0.23137}, {0.23529, 0.79608, 0.23529}, {0.23922, 0.80392, 0.23922}, {0.24314, 0.81176, 0.24314}, {0.24706, 0.81961, 0.24706}, {0.25098, 0.82745, 0.25098}, {0.25490, 0.83529, 0.25490}, {0.25882, 0.84314, 0.25882}, {0.26275, 0.85098, 0.26275}, {0.26667, 0.85882, 0.26667}, {0.27059, 0.86667, 0.27059}, {0.27451, 0.87451, 0.27451}, {0.27843, 0.88235, 0.27843}, {0.28235, 0.89020, 0.28235}, {0.28627, 0.89804, 0.28627}, {0.29020, 0.90588, 0.29020}, {0.29412, 0.91373, 0.29412}, {0.29804, 0.92157, 0.29804}, {0.30196, 0.92941, 0.30196}, {0.30588, 0.93725, 0.30588}, {0.30980, 0.94510, 0.30980}, {0.31373, 0.95294, 0.31373}, {0.31765, 0.96078, 0.31765}, {0.32157, 0.96863, 0.32157}, {0.32549, 0.97647, 0.32549}, {0.32941, 0.98431, 0.32941}, {0.33333, 0.99216, 0.33333}, {0.33333, 0.00392, 0.00392}, {0.34118, 0.00784, 0.00784}, {0.34902, 0.01176, 0.01176}, {0.35686, 0.01569, 0.01569}, {0.36471, 0.01961, 0.01961}, {0.37255, 0.02353, 0.02353}, {0.38039, 0.02745, 0.02745}, {0.38824, 0.03137, 0.03137}, {0.39608, 0.03529, 0.03529}, {0.40392, 0.03922, 0.03922}, {0.41176, 0.04314, 0.04314}, {0.41961, 0.04706, 0.04706}, {0.42745, 0.05098, 0.05098}, {0.43529, 0.05490, 0.05490}, {0.44314, 0.05882, 0.05882}, {0.45098, 0.06275, 0.06275}, {0.45882, 0.06667, 0.06667}, {0.46667, 0.07059, 0.07059}, {0.47451, 0.07451, 0.07451}, {0.48235, 0.07843, 0.07843}, {0.49020, 0.08235, 0.08235}, {0.49804, 0.08627, 0.08627}, {0.50588, 0.09020, 0.09020}, {0.51373, 0.09412, 0.09412}, {0.52157, 0.09804, 0.09804}, {0.52941, 0.10196, 0.10196}, {0.53725, 0.10588, 0.10588}, {0.54510, 0.10980, 0.10980}, {0.55294, 0.11373, 0.11373}, {0.56078, 0.11765, 0.11765}, {0.56863, 0.12157, 0.12157}, {0.57647, 0.12549, 0.12549}, {0.58431, 0.12941, 0.12941}, {0.59216, 0.13333, 0.13333}, {0.60000, 0.13725, 0.13725}, {0.60784, 0.14118, 0.14118}, {0.61569, 0.14510, 0.14510}, {0.62353, 0.14902, 0.14902}, {0.63137, 0.15294, 0.15294}, {0.63922, 0.15686, 0.15686}, {0.64706, 0.16078, 0.16078}, {0.65490, 0.16471, 0.16471}, {0.66275, 0.16863, 0.16863}, {0.67059, 0.17255, 0.17255}, {0.67843, 0.17647, 0.17647}, {0.68627, 0.18039, 0.18039}, {0.69412, 0.18431, 0.18431}, {0.70196, 0.18824, 0.18824}, {0.70980, 0.19216, 0.19216}, {0.71765, 0.19608, 0.19608}, {0.72549, 0.20000, 0.20000}, {0.73333, 0.20392, 0.20392}, {0.74118, 0.20784, 0.20784}, {0.74902, 0.21176, 0.21176}, {0.75686, 0.21569, 0.21569}, {0.76471, 0.21961, 0.21961}, {0.77255, 0.22353, 0.22353}, {0.78039, 0.22745, 0.22745}, {0.78824, 0.23137, 0.23137}, {0.79608, 0.23529, 0.23529}, {0.80392, 0.23922, 0.23922}, {0.81176, 0.24314, 0.24314}, {0.81961, 0.24706, 0.24706}, {0.82745, 0.25098, 0.25098}, {0.83529, 0.25490, 0.25490}, {0.84314, 0.25882, 0.25882}, {0.85098, 0.26275, 0.26275}, {0.85882, 0.26667, 0.26667}, {0.86667, 0.27059, 0.27059}, {0.87451, 0.27451, 0.27451}, {0.88235, 0.27843, 0.27843}, {0.89020, 0.28235, 0.28235}, {0.89804, 0.28627, 0.28627}, {0.90588, 0.29020, 0.29020}, {0.91373, 0.29412, 0.29412}, {0.92157, 0.29804, 0.29804}, {0.92941, 0.30196, 0.30196}, {0.93725, 0.30588, 0.30588}, {0.94510, 0.30980, 0.30980}, {0.95294, 0.31373, 0.31373}, {0.96078, 0.31765, 0.31765}, {0.96863, 0.32157, 0.32157}, {0.97647, 0.32549, 0.32549}, {0.98431, 0.32941, 0.32941}, {0.99216, 0.33333, 0.33333}, {1.00000, 0.33725, 0.33725}, }; new ColorMapInfo("standard.lasc", standard_lasc); static RGBColor manycol_lasc[] = { {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.72549, 0.00000, 0.72549}, {0.72549, 0.00000, 0.72549}, {0.72549, 0.00000, 0.72549}, {0.72549, 0.00000, 0.72549}, {0.72549, 0.00000, 0.72549}, {0.72549, 0.00000, 0.72549}, {0.72549, 0.00000, 0.72549}, {0.72549, 0.00000, 0.72549}, {0.72549, 0.00000, 0.72549}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.72549, 0.00000, 0.72549}, {0.72549, 0.00000, 0.72549}, {0.72549, 0.00000, 0.72549}, {0.72549, 0.00000, 0.72549}, {0.72549, 0.00000, 0.72549}, {0.72549, 0.00000, 0.72549}, {0.72549, 0.00000, 0.72549}, {0.72549, 0.00000, 0.72549}, {0.72549, 0.00000, 0.72549}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {1.00000, 1.00000, 1.00000}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.34902, 0.34902, 0.34902}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.44706, 0.78431, 0.92549}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69020, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 0.69020, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.72549, 0.00000, 0.72549}, {0.72549, 0.00000, 0.72549}, }; new ColorMapInfo("manycol.lasc", manycol_lasc); static RGBColor rainbow1_lasc[] = { {0.00000, 0.00000, 0.16471}, {0.02745, 0.00000, 0.18431}, {0.05882, 0.00000, 0.20000}, {0.08627, 0.00000, 0.21961}, {0.11373, 0.00000, 0.23922}, {0.14510, 0.00000, 0.25882}, {0.17647, 0.00000, 0.27843}, {0.20392, 0.00000, 0.29804}, {0.23137, 0.00000, 0.31765}, {0.26275, 0.00000, 0.33725}, {0.29412, 0.00000, 0.35686}, {0.32157, 0.00000, 0.37647}, {0.35294, 0.00000, 0.39608}, {0.38039, 0.00000, 0.41569}, {0.41176, 0.00000, 0.43529}, {0.43922, 0.00000, 0.45490}, {0.47059, 0.00000, 0.47451}, {0.49804, 0.00000, 0.49412}, {0.52941, 0.00000, 0.51373}, {0.55686, 0.00000, 0.53725}, {0.58824, 0.00000, 0.55686}, {0.55686, 0.00000, 0.57647}, {0.52941, 0.00000, 0.59608}, {0.49804, 0.00000, 0.61569}, {0.47059, 0.00000, 0.63922}, {0.43922, 0.00000, 0.65882}, {0.41176, 0.00000, 0.67843}, {0.38039, 0.00000, 0.70196}, {0.35294, 0.00000, 0.72157}, {0.32157, 0.00000, 0.74118}, {0.29412, 0.00000, 0.76471}, {0.26275, 0.00000, 0.78431}, {0.23137, 0.00000, 0.80392}, {0.20392, 0.00000, 0.82745}, {0.17647, 0.00000, 0.84706}, {0.14510, 0.00000, 0.87059}, {0.11373, 0.00000, 0.89020}, {0.08627, 0.00000, 0.91373}, {0.05882, 0.00000, 0.93333}, {0.02745, 0.00000, 0.95686}, {0.00000, 0.00000, 0.97647}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 0.97647}, {0.00000, 0.00784, 0.95686}, {0.00000, 0.01569, 0.93333}, {0.00000, 0.02353, 0.91373}, {0.00000, 0.03137, 0.89020}, {0.00000, 0.03922, 0.87059}, {0.00000, 0.05098, 0.85098}, {0.00000, 0.06275, 0.83137}, {0.00000, 0.07843, 0.81176}, {0.00000, 0.09804, 0.79216}, {0.00000, 0.11765, 0.77255}, {0.00000, 0.13725, 0.75294}, {0.00000, 0.15686, 0.73333}, {0.00000, 0.17647, 0.71373}, {0.00000, 0.19608, 0.69412}, {0.00000, 0.21569, 0.67451}, {0.00000, 0.23529, 0.65882}, {0.00000, 0.25490, 0.64314}, {0.00000, 0.27059, 0.62745}, {0.00000, 0.28627, 0.61176}, {0.00000, 0.30196, 0.59608}, {0.00000, 0.32157, 0.58039}, {0.00000, 0.33333, 0.56471}, {0.00000, 0.34510, 0.54902}, {0.00000, 0.35686, 0.53333}, {0.00000, 0.36863, 0.51765}, {0.00000, 0.38039, 0.50196}, {0.00000, 0.39216, 0.48627}, {0.00000, 0.40392, 0.47059}, {0.00000, 0.41176, 0.45882}, {0.00000, 0.42353, 0.44706}, {0.00000, 0.43529, 0.43529}, {0.00000, 0.44706, 0.42353}, {0.00000, 0.45882, 0.41176}, {0.00000, 0.46667, 0.40000}, {0.00000, 0.47843, 0.38824}, {0.00000, 0.49020, 0.37647}, {0.00000, 0.49804, 0.36471}, {0.00000, 0.50980, 0.35294}, {0.00000, 0.52157, 0.34118}, {0.00000, 0.52941, 0.32941}, {0.00000, 0.54118, 0.31765}, {0.00000, 0.55294, 0.30588}, {0.00000, 0.56078, 0.29412}, {0.00000, 0.57255, 0.28235}, {0.00000, 0.58431, 0.27059}, {0.00000, 0.59216, 0.25882}, {0.00000, 0.60392, 0.24706}, {0.00000, 0.61176, 0.23529}, {0.00000, 0.62353, 0.22353}, {0.00000, 0.63137, 0.21176}, {0.00000, 0.64314, 0.20000}, {0.00000, 0.65098, 0.18824}, {0.00000, 0.66275, 0.17647}, {0.00000, 0.67059, 0.16471}, {0.00000, 0.68235, 0.15294}, {0.00000, 0.69020, 0.14118}, {0.00000, 0.70196, 0.12941}, {0.00000, 0.70980, 0.11765}, {0.00000, 0.72157, 0.10196}, {0.00000, 0.72941, 0.08627}, {0.00000, 0.74118, 0.07059}, {0.00000, 0.74902, 0.05490}, {0.00000, 0.76078, 0.03922}, {0.00000, 0.76863, 0.02353}, {0.00000, 0.77647, 0.00000}, {0.00000, 0.78824, 0.00000}, {0.00000, 0.79608, 0.00000}, {0.00000, 0.80784, 0.00000}, {0.00000, 0.81569, 0.00000}, {0.00000, 0.82353, 0.00000}, {0.00000, 0.83529, 0.00000}, {0.00000, 0.84314, 0.00000}, {0.00000, 0.85490, 0.00000}, {0.00000, 0.86275, 0.00000}, {0.00000, 0.87059, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.89020, 0.00000}, {0.00000, 0.89804, 0.00000}, {0.00000, 0.90980, 0.00000}, {0.00000, 0.91765, 0.00000}, {0.00000, 0.92549, 0.00000}, {0.00000, 0.93725, 0.00000}, {0.00000, 0.94510, 0.00000}, {0.00000, 0.95294, 0.00000}, {0.00000, 0.96078, 0.00000}, {0.00000, 0.97255, 0.00000}, {0.00000, 0.98039, 0.00000}, {0.00000, 0.98824, 0.00000}, {0.00784, 1.00000, 0.00000}, {0.01569, 0.98824, 0.00000}, {0.02353, 0.98039, 0.00000}, {0.03137, 0.97255, 0.00000}, {0.04314, 0.96078, 0.00000}, {0.05490, 0.95294, 0.00000}, {0.06667, 0.94510, 0.00000}, {0.07843, 0.93725, 0.00000}, {0.09020, 0.92549, 0.00000}, {0.10196, 0.91765, 0.00000}, {0.11373, 0.90980, 0.00000}, {0.12549, 0.89804, 0.00000}, {0.13725, 0.89020, 0.00000}, {0.14902, 0.88235, 0.00000}, {0.16471, 0.87059, 0.00000}, {0.20000, 0.86275, 0.00000}, {0.23529, 0.85490, 0.00000}, {0.26667, 0.84314, 0.00000}, {0.30588, 0.83529, 0.00000}, {0.34118, 0.82353, 0.00000}, {0.37647, 0.81569, 0.00000}, {0.41176, 0.80784, 0.00000}, {0.44706, 0.79608, 0.00000}, {0.48627, 0.78824, 0.00000}, {0.52157, 0.77647, 0.00000}, {0.56078, 0.76863, 0.00000}, {0.59608, 0.77647, 0.00000}, {0.63529, 0.78824, 0.00000}, {0.67059, 0.80000, 0.00000}, {0.70980, 0.81176, 0.00000}, {0.74902, 0.82745, 0.00000}, {0.78431, 0.84314, 0.00000}, {0.82353, 0.85882, 0.00000}, {0.85882, 0.87059, 0.00000}, {0.89804, 0.89020, 0.00000}, {0.93333, 0.90196, 0.00000}, {0.97647, 0.92157, 0.00000}, {1.00000, 0.93333, 0.00000}, {1.00000, 0.95294, 0.00000}, {1.00000, 0.96863, 0.00000}, {1.00000, 0.98824, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {0.99608, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 1.00000, 0.00000}, {1.00000, 0.97647, 0.00000}, {1.00000, 0.93725, 0.00000}, {1.00000, 0.89804, 0.00000}, {1.00000, 0.85882, 0.00000}, {1.00000, 0.81961, 0.00000}, {1.00000, 0.78039, 0.00000}, {1.00000, 0.74118, 0.00000}, {1.00000, 0.70196, 0.00000}, {1.00000, 0.66275, 0.00000}, {1.00000, 0.62353, 0.00000}, {1.00000, 0.58431, 0.00000}, {1.00000, 0.54510, 0.00000}, {1.00000, 0.50980, 0.00000}, {1.00000, 0.46667, 0.00000}, {1.00000, 0.43137, 0.00000}, {1.00000, 0.39216, 0.00000}, {1.00000, 0.35294, 0.00000}, {1.00000, 0.31765, 0.00000}, {1.00000, 0.27451, 0.00000}, {1.00000, 0.23922, 0.00000}, {1.00000, 0.20000, 0.00000}, {1.00000, 0.16863, 0.00000}, {1.00000, 0.12941, 0.00000}, {1.00000, 0.09804, 0.00000}, {1.00000, 0.08235, 0.00000}, {1.00000, 0.06275, 0.00000}, {1.00000, 0.04706, 0.00000}, {1.00000, 0.02353, 0.00000}, {1.00000, 0.00000, 0.00000}, {0.99216, 0.00000, 0.00000}, {0.98431, 0.00000, 0.00000}, {0.97647, 0.00000, 0.00000}, {0.96863, 0.00000, 0.00000}, {0.96078, 0.00000, 0.00000}, {0.95294, 0.00000, 0.00000}, {0.94510, 0.00000, 0.00000}, {0.93725, 0.00000, 0.00000}, {0.92941, 0.00000, 0.00000}, {0.92157, 0.00000, 0.00000}, {0.91373, 0.00000, 0.00000}, {0.90588, 0.00000, 0.00000}, {0.89804, 0.00000, 0.00000}, {0.89020, 0.00000, 0.00000}, {0.88235, 0.00000, 0.00000}, {0.87451, 0.00000, 0.00000}, {0.86667, 0.00000, 0.00000}, {0.85882, 0.00000, 0.00000}, {0.85098, 0.00000, 0.00000}, {0.84314, 0.00000, 0.00000}, {0.83529, 0.00000, 0.00000}, {0.82745, 0.00000, 0.00000}, {0.81961, 0.00000, 0.00000}, {0.81176, 0.00000, 0.00000}, {0.80392, 0.00000, 0.00000}, {0.79608, 0.00000, 0.00000}, {0.78824, 0.00000, 0.00000}, {0.78039, 0.00000, 0.00000}, {0.77255, 0.00000, 0.00000}, {0.76471, 0.00000, 0.00000}, {0.75686, 0.00000, 0.00000}, {0.74902, 0.00000, 0.00000}, {0.74118, 0.00000, 0.00000}, {0.73333, 0.00000, 0.00000}, }; new ColorMapInfo("rainbow1.lasc", rainbow1_lasc); static RGBColor green_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00000, 0.00392, 0.00000}, {0.00000, 0.00784, 0.00000}, {0.00000, 0.01176, 0.00000}, {0.00000, 0.01569, 0.00000}, {0.00000, 0.01961, 0.00000}, {0.00000, 0.02353, 0.00000}, {0.00000, 0.02745, 0.00000}, {0.00000, 0.03137, 0.00000}, {0.00000, 0.03529, 0.00000}, {0.00000, 0.03922, 0.00000}, {0.00000, 0.04314, 0.00000}, {0.00000, 0.04706, 0.00000}, {0.00000, 0.05098, 0.00000}, {0.00000, 0.05490, 0.00000}, {0.00000, 0.05882, 0.00000}, {0.00000, 0.06275, 0.00000}, {0.00000, 0.06667, 0.00000}, {0.00000, 0.07059, 0.00000}, {0.00000, 0.07451, 0.00000}, {0.00000, 0.07843, 0.00000}, {0.00000, 0.08235, 0.00000}, {0.00000, 0.08627, 0.00000}, {0.00000, 0.09020, 0.00000}, {0.00000, 0.09412, 0.00000}, {0.00000, 0.09804, 0.00000}, {0.00000, 0.10196, 0.00000}, {0.00000, 0.10588, 0.00000}, {0.00000, 0.10980, 0.00000}, {0.00000, 0.11373, 0.00000}, {0.00000, 0.11765, 0.00000}, {0.00000, 0.12157, 0.00000}, {0.00000, 0.12549, 0.00000}, {0.00000, 0.12941, 0.00000}, {0.00000, 0.13333, 0.00000}, {0.00000, 0.13725, 0.00000}, {0.00000, 0.14118, 0.00000}, {0.00000, 0.14510, 0.00000}, {0.00000, 0.14902, 0.00000}, {0.00000, 0.15294, 0.00000}, {0.00000, 0.15686, 0.00000}, {0.00000, 0.16078, 0.00000}, {0.00000, 0.16471, 0.00000}, {0.00000, 0.16863, 0.00000}, {0.00000, 0.17255, 0.00000}, {0.00000, 0.17647, 0.00000}, {0.00000, 0.18039, 0.00000}, {0.00000, 0.18431, 0.00000}, {0.00000, 0.18824, 0.00000}, {0.00000, 0.19216, 0.00000}, {0.00000, 0.19608, 0.00000}, {0.00000, 0.20000, 0.00000}, {0.00000, 0.20392, 0.00000}, {0.00000, 0.20784, 0.00000}, {0.00000, 0.21176, 0.00000}, {0.00000, 0.21569, 0.00000}, {0.00000, 0.21961, 0.00000}, {0.00000, 0.22353, 0.00000}, {0.00000, 0.22745, 0.00000}, {0.00000, 0.23137, 0.00000}, {0.00000, 0.23529, 0.00000}, {0.00000, 0.23922, 0.00000}, {0.00000, 0.24314, 0.00000}, {0.00000, 0.24706, 0.00000}, {0.00000, 0.25098, 0.00000}, {0.00000, 0.25490, 0.00000}, {0.00000, 0.25882, 0.00000}, {0.00000, 0.26275, 0.00000}, {0.00000, 0.26667, 0.00000}, {0.00000, 0.27059, 0.00000}, {0.00000, 0.27451, 0.00000}, {0.00000, 0.27843, 0.00000}, {0.00000, 0.28235, 0.00000}, {0.00000, 0.28627, 0.00000}, {0.00000, 0.29020, 0.00000}, {0.00000, 0.29412, 0.00000}, {0.00000, 0.29804, 0.00000}, {0.00000, 0.30196, 0.00000}, {0.00000, 0.30588, 0.00000}, {0.00000, 0.30980, 0.00000}, {0.00000, 0.31373, 0.00000}, {0.00000, 0.31765, 0.00000}, {0.00000, 0.32157, 0.00000}, {0.00000, 0.32549, 0.00000}, {0.00000, 0.32941, 0.00000}, {0.00000, 0.33333, 0.00000}, {0.00000, 0.33725, 0.00000}, {0.00000, 0.34118, 0.00000}, {0.00000, 0.34510, 0.00000}, {0.00000, 0.34902, 0.00000}, {0.00000, 0.35294, 0.00000}, {0.00000, 0.35686, 0.00000}, {0.00000, 0.36078, 0.00000}, {0.00000, 0.36471, 0.00000}, {0.00000, 0.36863, 0.00000}, {0.00000, 0.37255, 0.00000}, {0.00000, 0.37647, 0.00000}, {0.00000, 0.38039, 0.00000}, {0.00000, 0.38431, 0.00000}, {0.00000, 0.38824, 0.00000}, {0.00000, 0.39216, 0.00000}, {0.00000, 0.39608, 0.00000}, {0.00000, 0.40000, 0.00000}, {0.00000, 0.40392, 0.00000}, {0.00000, 0.40784, 0.00000}, {0.00000, 0.41176, 0.00000}, {0.00000, 0.41569, 0.00000}, {0.00000, 0.41961, 0.00000}, {0.00000, 0.42353, 0.00000}, {0.00000, 0.42745, 0.00000}, {0.00000, 0.43137, 0.00000}, {0.00000, 0.43529, 0.00000}, {0.00000, 0.43922, 0.00000}, {0.00000, 0.44314, 0.00000}, {0.00000, 0.44706, 0.00000}, {0.00000, 0.45098, 0.00000}, {0.00000, 0.45490, 0.00000}, {0.00000, 0.45882, 0.00000}, {0.00000, 0.46275, 0.00000}, {0.00000, 0.46667, 0.00000}, {0.00000, 0.47059, 0.00000}, {0.00000, 0.47451, 0.00000}, {0.00000, 0.47843, 0.00000}, {0.00000, 0.48235, 0.00000}, {0.00000, 0.48627, 0.00000}, {0.00000, 0.49020, 0.00000}, {0.00000, 0.49412, 0.00000}, {0.00000, 0.49804, 0.00000}, {0.00000, 0.50196, 0.00000}, {0.00000, 0.50588, 0.00000}, {0.00000, 0.50980, 0.00000}, {0.00000, 0.51373, 0.00000}, {0.00000, 0.51765, 0.00000}, {0.00000, 0.52157, 0.00000}, {0.00000, 0.52549, 0.00000}, {0.00000, 0.52941, 0.00000}, {0.00000, 0.53333, 0.00000}, {0.00000, 0.53725, 0.00000}, {0.00000, 0.54118, 0.00000}, {0.00000, 0.54510, 0.00000}, {0.00000, 0.54902, 0.00000}, {0.00000, 0.55294, 0.00000}, {0.00000, 0.55686, 0.00000}, {0.00000, 0.56078, 0.00000}, {0.00000, 0.56471, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.57255, 0.00000}, {0.00000, 0.57647, 0.00000}, {0.00000, 0.58039, 0.00000}, {0.00000, 0.58431, 0.00000}, {0.00000, 0.58824, 0.00000}, {0.00000, 0.59216, 0.00000}, {0.00000, 0.59608, 0.00000}, {0.00000, 0.60000, 0.00000}, {0.00000, 0.60392, 0.00000}, {0.00000, 0.60784, 0.00000}, {0.00000, 0.61176, 0.00000}, {0.00000, 0.61569, 0.00000}, {0.00000, 0.61961, 0.00000}, {0.00000, 0.62353, 0.00000}, {0.00000, 0.62745, 0.00000}, {0.00000, 0.63137, 0.00000}, {0.00000, 0.63529, 0.00000}, {0.00000, 0.63922, 0.00000}, {0.00000, 0.64314, 0.00000}, {0.00000, 0.64706, 0.00000}, {0.00000, 0.65098, 0.00000}, {0.00000, 0.65490, 0.00000}, {0.00000, 0.65882, 0.00000}, {0.00000, 0.66275, 0.00000}, {0.00000, 0.66667, 0.00000}, {0.00000, 0.67059, 0.00000}, {0.00000, 0.67451, 0.00000}, {0.00000, 0.67843, 0.00000}, {0.00000, 0.68235, 0.00000}, {0.00000, 0.68627, 0.00000}, {0.00000, 0.69020, 0.00000}, {0.00000, 0.69412, 0.00000}, {0.00000, 0.69804, 0.00000}, {0.00000, 0.70196, 0.00000}, {0.00000, 0.70588, 0.00000}, {0.00000, 0.70980, 0.00000}, {0.00000, 0.71373, 0.00000}, {0.00000, 0.71765, 0.00000}, {0.00000, 0.72157, 0.00000}, {0.00000, 0.72549, 0.00000}, {0.00000, 0.72941, 0.00000}, {0.00000, 0.73333, 0.00000}, {0.00000, 0.73725, 0.00000}, {0.00000, 0.74118, 0.00000}, {0.00000, 0.74510, 0.00000}, {0.00000, 0.74902, 0.00000}, {0.00000, 0.75294, 0.00000}, {0.00000, 0.75686, 0.00000}, {0.00000, 0.76078, 0.00000}, {0.00000, 0.76471, 0.00000}, {0.00000, 0.76863, 0.00000}, {0.00000, 0.77255, 0.00000}, {0.00000, 0.77647, 0.00000}, {0.00000, 0.78039, 0.00000}, {0.00000, 0.78431, 0.00000}, {0.00000, 0.78824, 0.00000}, {0.00000, 0.79216, 0.00000}, {0.00000, 0.79608, 0.00000}, {0.00000, 0.80000, 0.00000}, {0.00000, 0.80392, 0.00000}, {0.00000, 0.80784, 0.00000}, {0.00000, 0.81176, 0.00000}, {0.00000, 0.81569, 0.00000}, {0.00000, 0.81961, 0.00000}, {0.00000, 0.82353, 0.00000}, {0.00000, 0.82745, 0.00000}, {0.00000, 0.83137, 0.00000}, {0.00000, 0.83529, 0.00000}, {0.00000, 0.83922, 0.00000}, {0.00000, 0.84314, 0.00000}, {0.00000, 0.84706, 0.00000}, {0.00000, 0.85098, 0.00000}, {0.00000, 0.85490, 0.00000}, {0.00000, 0.85882, 0.00000}, {0.00000, 0.86275, 0.00000}, {0.00000, 0.86667, 0.00000}, {0.00000, 0.87059, 0.00000}, {0.00000, 0.87451, 0.00000}, {0.00000, 0.87843, 0.00000}, {0.00000, 0.88235, 0.00000}, {0.00000, 0.88627, 0.00000}, {0.00000, 0.89020, 0.00000}, {0.00000, 0.89412, 0.00000}, {0.00000, 0.89804, 0.00000}, {0.00000, 0.90196, 0.00000}, {0.00000, 0.90588, 0.00000}, {0.00000, 0.90980, 0.00000}, {0.00000, 0.91373, 0.00000}, {0.00000, 0.91765, 0.00000}, {0.00000, 0.92157, 0.00000}, {0.00000, 0.92549, 0.00000}, {0.00000, 0.92941, 0.00000}, {0.00000, 0.93333, 0.00000}, {0.00000, 0.93725, 0.00000}, {0.00000, 0.94118, 0.00000}, {0.00000, 0.94510, 0.00000}, {0.00000, 0.94902, 0.00000}, {0.00000, 0.95294, 0.00000}, {0.00000, 0.95686, 0.00000}, {0.00000, 0.96078, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96863, 0.00000}, {0.00000, 0.97255, 0.00000}, {0.00000, 0.97647, 0.00000}, {0.00000, 0.98039, 0.00000}, {0.00000, 0.98431, 0.00000}, {0.00000, 0.98824, 0.00000}, {0.00000, 0.99216, 0.00000}, {0.00000, 0.99608, 0.00000}, {0.00000, 1.00000, 0.00000}, }; new ColorMapInfo("green.lasc", green_lasc); static RGBColor random6_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00000, 0.14118, 0.00000}, {0.00000, 0.28235, 0.00000}, {0.00000, 0.42353, 0.00000}, {0.00000, 0.56471, 0.00000}, {0.00000, 0.70588, 0.00000}, {0.00000, 0.84706, 0.00000}, {0.00000, 0.98824, 0.00000}, {0.00000, 0.00000, 0.14118}, {0.00000, 0.14118, 0.14118}, {0.00000, 0.28235, 0.14118}, {0.00000, 0.42353, 0.14118}, {0.00000, 0.56471, 0.14118}, {0.00000, 0.70588, 0.14118}, {0.00000, 0.84706, 0.14118}, {0.00000, 0.98824, 0.14118}, {0.00000, 0.00000, 0.28235}, {0.00000, 0.14118, 0.28235}, {0.00000, 0.28235, 0.28235}, {0.00000, 0.42353, 0.28235}, {0.00000, 0.56471, 0.28235}, {0.00000, 0.70588, 0.28235}, {0.00000, 0.84706, 0.28235}, {0.00000, 0.98824, 0.28235}, {0.00000, 0.00000, 0.42353}, {0.00000, 0.14118, 0.42353}, {0.00000, 0.28235, 0.42353}, {0.00000, 0.42353, 0.42353}, {0.00000, 0.56471, 0.42353}, {0.00000, 0.70588, 0.42353}, {0.00000, 0.84706, 0.42353}, {0.00000, 0.98824, 0.42353}, {0.00000, 0.00000, 0.56471}, {0.00000, 0.14118, 0.56471}, {0.00000, 0.28235, 0.56471}, {0.00000, 0.42353, 0.56471}, {0.00000, 0.56471, 0.56471}, {0.00000, 0.70588, 0.56471}, {0.00000, 0.84706, 0.56471}, {0.00000, 0.98824, 0.56471}, {0.00000, 0.00000, 0.70588}, {0.00000, 0.14118, 0.70588}, {0.00000, 0.28235, 0.70588}, {0.00000, 0.42353, 0.70588}, {0.00000, 0.56471, 0.70588}, {0.00000, 0.70588, 0.70588}, {0.00000, 0.84706, 0.70588}, {0.00000, 0.98824, 0.70588}, {0.00000, 0.00000, 0.84706}, {0.00000, 0.14118, 0.84706}, {0.00000, 0.28235, 0.84706}, {0.00000, 0.42353, 0.84706}, {0.00000, 0.56471, 0.84706}, {0.00000, 0.70588, 0.84706}, {0.00000, 0.84706, 0.84706}, {0.00000, 0.98824, 0.84706}, {0.00000, 0.00000, 0.98824}, {0.00000, 0.14118, 0.98824}, {0.00000, 0.28235, 0.98824}, {0.00000, 0.42353, 0.98824}, {0.00000, 0.56471, 0.98824}, {0.00000, 0.70588, 0.98824}, {0.00000, 0.84706, 0.98824}, {0.00000, 0.98824, 0.98824}, {0.00000, 0.00000, 0.00000}, {0.32941, 0.14118, 0.00000}, {0.32941, 0.28235, 0.00000}, {0.32941, 0.42353, 0.00000}, {0.32941, 0.56471, 0.00000}, {0.32941, 0.70588, 0.00000}, {0.32941, 0.84706, 0.00000}, {0.32941, 0.98824, 0.00000}, {0.32941, 0.00000, 0.14118}, {0.32941, 0.14118, 0.14118}, {0.32941, 0.28235, 0.14118}, {0.32941, 0.42353, 0.14118}, {0.32941, 0.56471, 0.14118}, {0.32941, 0.70588, 0.14118}, {0.32941, 0.84706, 0.14118}, {0.32941, 0.98824, 0.14118}, {0.32941, 0.00000, 0.28235}, {0.32941, 0.14118, 0.28235}, {0.32941, 0.28235, 0.28235}, {0.32941, 0.42353, 0.28235}, {0.32941, 0.56471, 0.28235}, {0.32941, 0.70588, 0.28235}, {0.32941, 0.84706, 0.28235}, {0.32941, 0.98824, 0.28235}, {0.32941, 0.00000, 0.42353}, {0.32941, 0.14118, 0.42353}, {0.32941, 0.28235, 0.42353}, {0.32941, 0.42353, 0.42353}, {0.32941, 0.56471, 0.42353}, {0.32941, 0.70588, 0.42353}, {0.32941, 0.84706, 0.42353}, {0.32941, 0.98824, 0.42353}, {0.32941, 0.00000, 0.56471}, {0.32941, 0.14118, 0.56471}, {0.32941, 0.28235, 0.56471}, {0.32941, 0.42353, 0.56471}, {0.32941, 0.56471, 0.56471}, {0.32941, 0.70588, 0.56471}, {0.32941, 0.84706, 0.56471}, {0.32941, 0.98824, 0.56471}, {0.32941, 0.00000, 0.70588}, {0.32941, 0.14118, 0.70588}, {0.32941, 0.28235, 0.70588}, {0.32941, 0.42353, 0.70588}, {0.32941, 0.56471, 0.70588}, {0.32941, 0.70588, 0.70588}, {0.32941, 0.84706, 0.70588}, {0.32941, 0.98824, 0.70588}, {0.32941, 0.00000, 0.84706}, {0.32941, 0.14118, 0.84706}, {0.32941, 0.28235, 0.84706}, {0.32941, 0.42353, 0.84706}, {0.32941, 0.56471, 0.84706}, {0.32941, 0.70588, 0.84706}, {0.32941, 0.84706, 0.84706}, {0.32941, 0.98824, 0.84706}, {0.32941, 0.00000, 0.98824}, {0.32941, 0.14118, 0.98824}, {0.32941, 0.28235, 0.98824}, {0.32941, 0.42353, 0.98824}, {0.32941, 0.56471, 0.98824}, {0.32941, 0.70588, 0.98824}, {0.32941, 0.84706, 0.98824}, {0.32941, 0.98824, 0.98824}, {0.32941, 0.00000, 0.00000}, {0.65882, 0.14118, 0.00000}, {0.65882, 0.28235, 0.00000}, {0.65882, 0.42353, 0.00000}, {0.65882, 0.56471, 0.00000}, {0.65882, 0.70588, 0.00000}, {0.65882, 0.84706, 0.00000}, {0.65882, 0.98824, 0.00000}, {0.65882, 0.00000, 0.14118}, {0.65882, 0.14118, 0.14118}, {0.65882, 0.28235, 0.14118}, {0.65882, 0.42353, 0.14118}, {0.65882, 0.56471, 0.14118}, {0.65882, 0.70588, 0.14118}, {0.65882, 0.84706, 0.14118}, {0.65882, 0.98824, 0.14118}, {0.65882, 0.00000, 0.28235}, {0.65882, 0.14118, 0.28235}, {0.65882, 0.28235, 0.28235}, {0.65882, 0.42353, 0.28235}, {0.65882, 0.56471, 0.28235}, {0.65882, 0.70588, 0.28235}, {0.65882, 0.84706, 0.28235}, {0.65882, 0.98824, 0.28235}, {0.65882, 0.00000, 0.42353}, {0.65882, 0.14118, 0.42353}, {0.65882, 0.28235, 0.42353}, {0.65882, 0.42353, 0.42353}, {0.65882, 0.56471, 0.42353}, {0.65882, 0.70588, 0.42353}, {0.65882, 0.84706, 0.42353}, {0.65882, 0.98824, 0.42353}, {0.65882, 0.00000, 0.56471}, {0.65882, 0.14118, 0.56471}, {0.65882, 0.28235, 0.56471}, {0.65882, 0.42353, 0.56471}, {0.65882, 0.56471, 0.56471}, {0.65882, 0.70588, 0.56471}, {0.65882, 0.84706, 0.56471}, {0.65882, 0.98824, 0.56471}, {0.65882, 0.00000, 0.70588}, {0.65882, 0.14118, 0.70588}, {0.65882, 0.28235, 0.70588}, {0.65882, 0.42353, 0.70588}, {0.65882, 0.56471, 0.70588}, {0.65882, 0.70588, 0.70588}, {0.65882, 0.84706, 0.70588}, {0.65882, 0.98824, 0.70588}, {0.65882, 0.00000, 0.84706}, {0.65882, 0.14118, 0.84706}, {0.65882, 0.28235, 0.84706}, {0.65882, 0.42353, 0.84706}, {0.65882, 0.56471, 0.84706}, {0.65882, 0.70588, 0.84706}, {0.65882, 0.84706, 0.84706}, {0.65882, 0.98824, 0.84706}, {0.65882, 0.00000, 0.98824}, {0.65882, 0.14118, 0.98824}, {0.65882, 0.28235, 0.98824}, {0.65882, 0.42353, 0.98824}, {0.65882, 0.56471, 0.98824}, {0.65882, 0.70588, 0.98824}, {0.65882, 0.84706, 0.98824}, {0.65882, 0.98824, 0.98824}, {0.65882, 0.00000, 0.00000}, {0.98824, 0.14118, 0.00000}, {0.98824, 0.28235, 0.00000}, {0.98824, 0.42353, 0.00000}, {0.98824, 0.56471, 0.00000}, {0.98824, 0.70588, 0.00000}, {0.98824, 0.84706, 0.00000}, {0.98824, 0.98824, 0.00000}, {0.98824, 0.00000, 0.14118}, {0.98824, 0.14118, 0.14118}, {0.98824, 0.28235, 0.14118}, {0.98824, 0.42353, 0.14118}, {0.98824, 0.56471, 0.14118}, {0.98824, 0.70588, 0.14118}, {0.98824, 0.84706, 0.14118}, {0.98824, 0.98824, 0.14118}, {0.98824, 0.00000, 0.28235}, {0.98824, 0.14118, 0.28235}, {0.98824, 0.28235, 0.28235}, {0.98824, 0.42353, 0.28235}, {0.98824, 0.56471, 0.28235}, {0.98824, 0.70588, 0.28235}, {0.98824, 0.84706, 0.28235}, {0.98824, 0.98824, 0.28235}, {0.98824, 0.00000, 0.42353}, {0.98824, 0.14118, 0.42353}, {0.98824, 0.28235, 0.42353}, {0.98824, 0.42353, 0.42353}, {0.98824, 0.56471, 0.42353}, {0.98824, 0.70588, 0.42353}, {0.98824, 0.84706, 0.42353}, {0.98824, 0.98824, 0.42353}, {0.98824, 0.00000, 0.56471}, {0.98824, 0.14118, 0.56471}, {0.98824, 0.28235, 0.56471}, {0.98824, 0.42353, 0.56471}, {0.98824, 0.56471, 0.56471}, {0.98824, 0.70588, 0.56471}, {0.98824, 0.84706, 0.56471}, {0.98824, 0.98824, 0.56471}, {0.98824, 0.00000, 0.70588}, {0.98824, 0.14118, 0.70588}, {0.98824, 0.28235, 0.70588}, {0.98824, 0.42353, 0.70588}, {0.98824, 0.56471, 0.70588}, {0.98824, 0.70588, 0.70588}, {0.98824, 0.84706, 0.70588}, {0.98824, 0.98824, 0.70588}, {0.98824, 0.00000, 0.84706}, {0.98824, 0.14118, 0.84706}, {0.98824, 0.28235, 0.84706}, {0.98824, 0.42353, 0.84706}, {0.98824, 0.56471, 0.84706}, {0.98824, 0.70588, 0.84706}, {0.98824, 0.84706, 0.84706}, {0.98824, 0.98824, 0.84706}, {0.98824, 0.00000, 0.98824}, {0.98824, 0.14118, 0.98824}, {0.98824, 0.28235, 0.98824}, {0.98824, 0.42353, 0.98824}, {0.98824, 0.56471, 0.98824}, {0.98824, 0.70588, 0.98824}, {0.98824, 0.84706, 0.98824}, {0.98824, 0.98824, 0.98824}, }; new ColorMapInfo("random6.lasc", random6_lasc); static RGBColor stairs9_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.19608, 0.19608, 0.19608}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.60784, 0.00000, 0.47451}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.78431, 0.00000, 0.00000}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.92549, 0.65490, 0.37255}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.56863, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 0.96471, 0.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 1.00000, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.69412, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, {0.00000, 0.00000, 1.00000}, }; new ColorMapInfo("stairs9.lasc", stairs9_lasc); static RGBColor idl5_lasc[] = { {0.00000, 0.00000, 0.00000}, {0.00000, 0.00000, 0.01961}, {0.00000, 0.00000, 0.03922}, {0.00000, 0.00000, 0.05882}, {0.00000, 0.00000, 0.07843}, {0.00000, 0.00000, 0.10196}, {0.00000, 0.00000, 0.12157}, {0.00000, 0.00000, 0.14118}, {0.00000, 0.00000, 0.16078}, {0.00000, 0.00000, 0.18039}, {0.00000, 0.00000, 0.20392}, {0.00000, 0.00000, 0.22353}, {0.00000, 0.00000, 0.24314}, {0.00000, 0.00000, 0.26275}, {0.00000, 0.00000, 0.28235}, {0.00000, 0.00000, 0.30588}, {0.00000, 0.00000, 0.32549}, {0.00000, 0.00000, 0.34510}, {0.00000, 0.00000, 0.36471}, {0.00000, 0.00000, 0.38431}, {0.00000, 0.00000, 0.40784}, {0.00000, 0.00000, 0.42745}, {0.00000, 0.00000, 0.44706}, {0.00000, 0.00000, 0.46667}, {0.00000, 0.00000, 0.48627}, {0.00000, 0.00000, 0.50980}, {0.00000, 0.00000, 0.52941}, {0.00000, 0.00000, 0.54902}, {0.00000, 0.00000, 0.56863}, {0.00000, 0.00000, 0.58824}, {0.00000, 0.00000, 0.61176}, {0.00000, 0.00000, 0.63137}, {0.00000, 0.00000, 0.65098}, {0.00000, 0.00000, 0.67059}, {0.00000, 0.00000, 0.69020}, {0.00000, 0.00000, 0.71373}, {0.00000, 0.00000, 0.73333}, {0.00000, 0.00000, 0.75294}, {0.00000, 0.00000, 0.77255}, {0.00000, 0.00000, 0.79216}, {0.00000, 0.00000, 0.81569}, {0.00000, 0.00000, 0.83529}, {0.00000, 0.00000, 0.85490}, {0.00000, 0.00000, 0.87451}, {0.00000, 0.00000, 0.89412}, {0.00000, 0.00000, 0.91765}, {0.00000, 0.00000, 0.93725}, {0.00000, 0.00000, 0.95686}, {0.01569, 0.00000, 0.97647}, {0.03529, 0.00000, 1.00000}, {0.05490, 0.00000, 0.98039}, {0.07451, 0.00000, 0.96078}, {0.09020, 0.00000, 0.93725}, {0.10980, 0.00000, 0.91765}, {0.12941, 0.00000, 0.89412}, {0.14902, 0.00000, 0.87451}, {0.16471, 0.00000, 0.85490}, {0.18431, 0.00000, 0.83137}, {0.20392, 0.00000, 0.81176}, {0.22353, 0.00000, 0.78824}, {0.23922, 0.00000, 0.76863}, {0.25882, 0.00000, 0.74510}, {0.27843, 0.00000, 0.72549}, {0.29804, 0.00000, 0.70588}, {0.31765, 0.00000, 0.68235}, {0.31765, 0.00000, 0.66275}, {0.31765, 0.00000, 0.63922}, {0.31765, 0.00000, 0.61961}, {0.31765, 0.00000, 0.59608}, {0.31765, 0.00000, 0.57647}, {0.31765, 0.00000, 0.55686}, {0.31765, 0.00000, 0.53333}, {0.31373, 0.00000, 0.51373}, {0.31373, 0.00000, 0.49020}, {0.31373, 0.00000, 0.47059}, {0.31373, 0.00000, 0.44706}, {0.31373, 0.00000, 0.42745}, {0.31373, 0.00000, 0.40784}, {0.31373, 0.00000, 0.38431}, {0.30980, 0.00000, 0.36471}, {0.32941, 0.00000, 0.34118}, {0.34902, 0.00000, 0.32157}, {0.36863, 0.00000, 0.29804}, {0.38824, 0.00000, 0.27843}, {0.40784, 0.00000, 0.25882}, {0.42745, 0.00000, 0.23529}, {0.44706, 0.00000, 0.21569}, {0.46667, 0.00000, 0.19216}, {0.48627, 0.00000, 0.17255}, {0.50588, 0.00000, 0.14902}, {0.52549, 0.00000, 0.12941}, {0.54510, 0.00000, 0.10980}, {0.56471, 0.00000, 0.08627}, {0.58431, 0.00000, 0.06667}, {0.60392, 0.00000, 0.04314}, {0.62353, 0.00000, 0.02353}, {0.64314, 0.00000, 0.00000}, {0.66275, 0.00000, 0.00000}, {0.68235, 0.00000, 0.00000}, {0.70588, 0.00000, 0.00000}, {0.72549, 0.00000, 0.00000}, {0.74510, 0.00000, 0.00000}, {0.76863, 0.00000, 0.00000}, {0.78824, 0.00000, 0.00000}, {0.80784, 0.00000, 0.00000}, {0.83137, 0.00000, 0.00000}, {0.85098, 0.00000, 0.00000}, {0.87059, 0.00000, 0.00000}, {0.89412, 0.00000, 0.00000}, {0.91373, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.00000, 0.00000}, {1.00000, 0.01961, 0.00000}, {1.00000, 0.03922, 0.00000}, {1.00000, 0.06275, 0.00000}, {1.00000, 0.08235, 0.00000}, {1.00000, 0.10588, 0.00000}, {1.00000, 0.12549, 0.00000}, {1.00000, 0.14510, 0.00000}, {1.00000, 0.16863, 0.00000}, {1.00000, 0.18824, 0.00000}, {1.00000, 0.21176, 0.00000}, {1.00000, 0.23137, 0.00000}, {1.00000, 0.25098, 0.00000}, {1.00000, 0.27451, 0.00000}, {1.00000, 0.29412, 0.00000}, {1.00000, 0.31765, 0.00000}, {1.00000, 0.33333, 0.01569}, {1.00000, 0.35294, 0.03529}, {1.00000, 0.37255, 0.05490}, {1.00000, 0.39216, 0.07451}, {1.00000, 0.41176, 0.09412}, {1.00000, 0.42745, 0.10980}, {1.00000, 0.44706, 0.12941}, {1.00000, 0.46667, 0.14902}, {1.00000, 0.48627, 0.16863}, {1.00000, 0.50588, 0.18824}, {1.00000, 0.52549, 0.20784}, {1.00000, 0.54118, 0.22353}, {1.00000, 0.56078, 0.24314}, {1.00000, 0.58039, 0.26275}, {1.00000, 0.60000, 0.28235}, {1.00000, 0.61961, 0.30196}, {1.00000, 0.63922, 0.32157}, {1.00000, 0.63922, 0.30196}, {1.00000, 0.63922, 0.27843}, {1.00000, 0.63922, 0.25490}, {1.00000, 0.63922, 0.23137}, {1.00000, 0.63922, 0.20784}, {1.00000, 0.63922, 0.18431}, {1.00000, 0.63922, 0.16078}, {1.00000, 0.63922, 0.14118}, {1.00000, 0.63922, 0.11765}, {1.00000, 0.63922, 0.09412}, {1.00000, 0.63922, 0.07059}, {1.00000, 0.63922, 0.04706}, {1.00000, 0.63922, 0.02353}, {1.00000, 0.63922, 0.00000}, {1.00000, 0.63922, 0.00000}, {1.00000, 0.63922, 0.00000}, {1.00000, 0.63922, 0.00000}, {0.97255, 0.63922, 0.00000}, {0.94118, 0.63922, 0.00000}, {0.90980, 0.63922, 0.00000}, {0.88235, 0.63922, 0.00000}, {0.85098, 0.63922, 0.00000}, {0.81961, 0.63922, 0.00000}, {0.79216, 0.63922, 0.00000}, {0.76078, 0.63922, 0.00000}, {0.72941, 0.63922, 0.00000}, {0.70196, 0.63922, 0.00000}, {0.67059, 0.63922, 0.00000}, {0.63922, 0.63922, 0.00000}, {0.65882, 0.63922, 0.00000}, {0.67843, 0.63922, 0.00000}, {0.69804, 0.66275, 0.01176}, {0.71765, 0.68627, 0.02353}, {0.73725, 0.70980, 0.03529}, {0.75686, 0.73333, 0.04706}, {0.77647, 0.75686, 0.06275}, {0.79608, 0.78039, 0.07451}, {0.81961, 0.80392, 0.08627}, {0.83922, 0.83137, 0.09804}, {0.85882, 0.85490, 0.11373}, {0.87843, 0.87843, 0.12549}, {0.89804, 0.90196, 0.13725}, {0.91765, 0.92549, 0.14902}, {0.93725, 0.94902, 0.16078}, {0.95686, 0.97255, 0.17647}, {0.97647, 1.00000, 0.18824}, {1.00000, 1.00000, 0.20000}, {1.00000, 1.00000, 0.21176}, {1.00000, 1.00000, 0.22745}, {1.00000, 1.00000, 0.23922}, {1.00000, 1.00000, 0.25098}, {1.00000, 1.00000, 0.26275}, {1.00000, 1.00000, 0.27843}, {1.00000, 1.00000, 0.29020}, {1.00000, 1.00000, 0.30196}, {1.00000, 1.00000, 0.31373}, {1.00000, 1.00000, 0.32549}, {1.00000, 1.00000, 0.34118}, {1.00000, 1.00000, 0.35294}, {1.00000, 1.00000, 0.36471}, {1.00000, 1.00000, 0.37647}, {1.00000, 1.00000, 0.39216}, {1.00000, 1.00000, 0.40392}, {1.00000, 1.00000, 0.41569}, {1.00000, 1.00000, 0.42745}, {1.00000, 1.00000, 0.43922}, {1.00000, 1.00000, 0.45490}, {1.00000, 1.00000, 0.46667}, {1.00000, 1.00000, 0.47843}, {1.00000, 1.00000, 0.49020}, {1.00000, 1.00000, 0.50588}, {1.00000, 1.00000, 0.51765}, {1.00000, 1.00000, 0.52941}, {1.00000, 1.00000, 0.54118}, {1.00000, 1.00000, 0.55686}, {1.00000, 1.00000, 0.56863}, {1.00000, 1.00000, 0.58039}, {1.00000, 1.00000, 0.59216}, {1.00000, 1.00000, 0.60392}, {1.00000, 1.00000, 0.61961}, {1.00000, 1.00000, 0.63137}, {1.00000, 1.00000, 0.64314}, {1.00000, 1.00000, 0.65490}, {1.00000, 1.00000, 0.67059}, {1.00000, 1.00000, 0.68235}, {1.00000, 1.00000, 0.69412}, {1.00000, 1.00000, 0.70588}, {1.00000, 1.00000, 0.71765}, {1.00000, 1.00000, 0.73333}, {1.00000, 1.00000, 0.74510}, {1.00000, 1.00000, 0.75686}, {1.00000, 1.00000, 0.76863}, {1.00000, 1.00000, 0.78431}, {1.00000, 1.00000, 0.79608}, {1.00000, 1.00000, 0.80784}, {1.00000, 1.00000, 0.81961}, {1.00000, 1.00000, 0.83529}, {1.00000, 1.00000, 0.84706}, {1.00000, 1.00000, 0.85882}, {1.00000, 1.00000, 0.87059}, {1.00000, 1.00000, 0.88235}, {1.00000, 1.00000, 0.89804}, {1.00000, 1.00000, 0.90980}, {1.00000, 1.00000, 0.92157}, {1.00000, 1.00000, 0.93333}, {1.00000, 1.00000, 0.94902}, {1.00000, 1.00000, 0.96078}, {1.00000, 1.00000, 0.97255}, {1.00000, 1.00000, 0.98431}, {1.00000, 1.00000, 1.00000}, }; new ColorMapInfo("idl5.lasc", idl5_lasc); static double expo_iasc[] = { 0.00458, 0.00689, 0.00920, 0.01152, 0.01386, 0.01620, 0.01855, 0.02091, 0.02328, 0.02565, 0.02804, 0.03044, 0.03285, 0.03526, 0.03769, 0.04012, 0.04257, 0.04502, 0.04748, 0.04996, 0.05244, 0.05493, 0.05743, 0.05995, 0.06247, 0.06500, 0.06754, 0.07010, 0.07266, 0.07523, 0.07781, 0.08041, 0.08301, 0.08562, 0.08824, 0.09088, 0.09352, 0.09618, 0.09884, 0.10152, 0.10420, 0.10690, 0.10960, 0.11232, 0.11505, 0.11779, 0.12054, 0.12330, 0.12607, 0.12885, 0.13164, 0.13445, 0.13726, 0.14009, 0.14293, 0.14578, 0.14863, 0.15151, 0.15439, 0.15728, 0.16019, 0.16310, 0.16603, 0.16897, 0.17192, 0.17488, 0.17786, 0.18084, 0.18384, 0.18685, 0.18987, 0.19290, 0.19595, 0.19900, 0.20207, 0.20515, 0.20824, 0.21135, 0.21447, 0.21760, 0.22074, 0.22389, 0.22706, 0.23024, 0.23343, 0.23663, 0.23985, 0.24308, 0.24632, 0.24957, 0.25284, 0.25612, 0.25942, 0.26272, 0.26604, 0.26937, 0.27272, 0.27608, 0.27945, 0.28283, 0.28623, 0.28964, 0.29307, 0.29651, 0.29996, 0.30342, 0.30690, 0.31039, 0.31390, 0.31742, 0.32095, 0.32450, 0.32806, 0.33164, 0.33523, 0.33883, 0.34245, 0.34608, 0.34973, 0.35339, 0.35707, 0.36076, 0.36446, 0.36818, 0.37191, 0.37566, 0.37942, 0.38320, 0.38699, 0.39080, 0.39462, 0.39846, 0.40231, 0.40618, 0.41006, 0.41396, 0.41788, 0.42180, 0.42575, 0.42971, 0.43368, 0.43767, 0.44168, 0.44570, 0.44974, 0.45379, 0.45786, 0.46195, 0.46605, 0.47017, 0.47430, 0.47845, 0.48262, 0.48680, 0.49100, 0.49522, 0.49945, 0.50370, 0.50797, 0.51225, 0.51655, 0.52087, 0.52520, 0.52955, 0.53392, 0.53830, 0.54270, 0.54712, 0.55156, 0.55601, 0.56048, 0.56497, 0.56948, 0.57400, 0.57855, 0.58311, 0.58768, 0.59228, 0.59689, 0.60153, 0.60618, 0.61085, 0.61553, 0.62024, 0.62496, 0.62970, 0.63447, 0.63925, 0.64404, 0.64886, 0.65370, 0.65855, 0.66343, 0.66832, 0.67323, 0.67817, 0.68312, 0.68809, 0.69308, 0.69809, 0.70312, 0.70817, 0.71324, 0.71833, 0.72344, 0.72856, 0.73371, 0.73888, 0.74407, 0.74928, 0.75451, 0.75977, 0.76504, 0.77033, 0.77564, 0.78098, 0.78633, 0.79171, 0.79711, 0.80253, 0.80797, 0.81343, 0.81891, 0.82442, 0.82994, 0.83549, 0.84106, 0.84665, 0.85226, 0.85790, 0.86356, 0.86924, 0.87494, 0.88066, 0.88641, 0.89218, 0.89797, 0.90379, 0.90963, 0.91549, 0.92137, 0.92728, 0.93321, 0.93916, 0.94514, 0.95114, 0.95716, 0.96321, 0.96928, 0.97538, 0.98150, 0.98764, 0.99381, 0.99888, 1.00000, 1.00000, }; new ITTInfo("expo.iasc", expo_iasc); static double null_iasc[] = { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, }; new ITTInfo("null.iasc", null_iasc); static double gamma_iasc[] = { 0.11285, 0.13544, 0.15416, 0.17045, 0.18502, 0.19831, 0.21059, 0.22206, 0.23284, 0.24304, 0.25275, 0.26202, 0.27090, 0.27945, 0.28768, 0.29564, 0.30334, 0.31081, 0.31807, 0.32513, 0.33201, 0.33872, 0.34526, 0.35167, 0.35793, 0.36406, 0.37007, 0.37596, 0.38173, 0.38741, 0.39298, 0.39846, 0.40385, 0.40915, 0.41437, 0.41952, 0.42458, 0.42957, 0.43449, 0.43935, 0.44414, 0.44887, 0.45353, 0.45814, 0.46270, 0.46720, 0.47165, 0.47604, 0.48039, 0.48469, 0.48894, 0.49315, 0.49732, 0.50144, 0.50552, 0.50957, 0.51357, 0.51754, 0.52146, 0.52536, 0.52922, 0.53304, 0.53683, 0.54059, 0.54432, 0.54801, 0.55168, 0.55531, 0.55892, 0.56250, 0.56605, 0.56958, 0.57307, 0.57655, 0.57999, 0.58342, 0.58681, 0.59019, 0.59354, 0.59686, 0.60017, 0.60345, 0.60671, 0.60995, 0.61317, 0.61637, 0.61955, 0.62271, 0.62584, 0.62896, 0.63206, 0.63515, 0.63821, 0.64126, 0.64429, 0.64730, 0.65029, 0.65327, 0.65623, 0.65918, 0.66211, 0.66502, 0.66792, 0.67080, 0.67367, 0.67652, 0.67936, 0.68218, 0.68499, 0.68778, 0.69057, 0.69333, 0.69609, 0.69883, 0.70156, 0.70427, 0.70697, 0.70966, 0.71234, 0.71501, 0.71766, 0.72030, 0.72293, 0.72555, 0.72815, 0.73075, 0.73333, 0.73591, 0.73847, 0.74102, 0.74356, 0.74609, 0.74861, 0.75112, 0.75361, 0.75610, 0.75858, 0.76105, 0.76351, 0.76596, 0.76840, 0.77083, 0.77325, 0.77566, 0.77806, 0.78046, 0.78284, 0.78522, 0.78759, 0.78994, 0.79229, 0.79464, 0.79697, 0.79929, 0.80161, 0.80392, 0.80622, 0.80851, 0.81079, 0.81307, 0.81534, 0.81760, 0.81985, 0.82210, 0.82434, 0.82657, 0.82879, 0.83101, 0.83322, 0.83542, 0.83762, 0.83980, 0.84198, 0.84416, 0.84633, 0.84849, 0.85064, 0.85279, 0.85493, 0.85706, 0.85919, 0.86131, 0.86343, 0.86553, 0.86764, 0.86973, 0.87182, 0.87391, 0.87598, 0.87806, 0.88012, 0.88218, 0.88424, 0.88628, 0.88833, 0.89036, 0.89239, 0.89442, 0.89644, 0.89845, 0.90046, 0.90246, 0.90446, 0.90645, 0.90844, 0.91042, 0.91240, 0.91437, 0.91634, 0.91830, 0.92025, 0.92221, 0.92415, 0.92609, 0.92803, 0.92996, 0.93189, 0.93381, 0.93572, 0.93763, 0.93954, 0.94144, 0.94334, 0.94523, 0.94712, 0.94901, 0.95088, 0.95276, 0.95463, 0.95649, 0.95836, 0.96021, 0.96206, 0.96391, 0.96576, 0.96760, 0.96943, 0.97126, 0.97309, 0.97491, 0.97673, 0.97854, 0.98035, 0.98216, 0.98396, 0.98576, 0.98755, 0.98934, 0.99113, 0.99291, 0.99469, 0.99646, 0.99823, 1.00000, 1.00000, 1.00000, }; new ITTInfo("gamma.iasc", gamma_iasc); static double equa_iasc[] = { 0.06275, 0.13725, 0.22353, 0.30196, 0.36078, 0.41176, 0.46275, 0.50588, 0.54510, 0.57647, 0.60392, 0.62745, 0.64706, 0.66275, 0.68235, 0.69412, 0.70588, 0.71765, 0.72941, 0.73725, 0.74510, 0.75686, 0.76471, 0.76863, 0.77647, 0.78039, 0.78824, 0.79216, 0.79608, 0.80000, 0.80392, 0.80784, 0.81176, 0.81569, 0.81961, 0.82353, 0.82745, 0.83137, 0.83529, 0.83922, 0.84314, 0.84314, 0.84706, 0.85098, 0.85490, 0.85882, 0.85882, 0.86275, 0.86667, 0.86667, 0.87059, 0.87451, 0.87451, 0.87843, 0.87843, 0.88235, 0.88235, 0.88627, 0.88627, 0.89020, 0.89020, 0.89412, 0.89412, 0.89804, 0.89804, 0.90196, 0.90196, 0.90588, 0.90588, 0.90980, 0.90980, 0.91373, 0.91373, 0.91765, 0.91765, 0.92157, 0.92157, 0.92549, 0.92549, 0.92941, 0.92941, 0.93333, 0.93333, 0.93725, 0.93725, 0.93725, 0.94118, 0.94118, 0.94510, 0.94510, 0.94510, 0.94902, 0.94902, 0.95294, 0.95294, 0.95294, 0.95686, 0.95686, 0.95686, 0.96078, 0.96078, 0.96078, 0.96471, 0.96471, 0.96471, 0.96471, 0.96863, 0.96863, 0.96863, 0.96863, 0.97255, 0.97255, 0.97255, 0.97255, 0.97255, 0.97255, 0.97647, 0.97647, 0.97647, 0.97647, 0.97647, 0.97647, 0.98039, 0.98039, 0.98039, 0.98039, 0.98039, 0.98039, 0.98039, 0.98039, 0.98039, 0.98039, 0.98431, 0.98431, 0.98431, 0.98431, 0.98431, 0.98431, 0.98431, 0.98431, 0.98431, 0.98431, 0.98431, 0.98824, 0.98824, 0.98824, 0.98824, 0.98824, 0.98824, 0.98824, 0.98824, 0.98824, 0.98824, 0.98824, 0.98824, 0.98824, 0.98824, 0.98824, 0.98824, 0.98824, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, }; new ITTInfo("equa.iasc", equa_iasc); static double stairs_iasc[] = { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.05882, 0.05882, 0.05882, 0.05882, 0.05882, 0.05882, 0.05882, 0.05882, 0.05882, 0.05882, 0.05882, 0.05882, 0.05882, 0.05882, 0.05882, 0.11765, 0.11765, 0.11765, 0.11765, 0.11765, 0.11765, 0.11765, 0.11765, 0.11765, 0.11765, 0.11765, 0.11765, 0.11765, 0.11765, 0.11765, 0.17647, 0.17647, 0.17647, 0.17647, 0.17647, 0.17647, 0.17647, 0.17647, 0.17647, 0.17647, 0.17647, 0.17647, 0.17647, 0.17647, 0.17647, 0.23529, 0.23529, 0.23529, 0.23529, 0.23529, 0.23529, 0.23529, 0.23529, 0.23529, 0.23529, 0.23529, 0.23529, 0.23529, 0.23529, 0.23529, 0.29412, 0.29412, 0.29412, 0.29412, 0.29412, 0.29412, 0.29412, 0.29412, 0.29412, 0.29412, 0.29412, 0.29412, 0.29412, 0.29412, 0.29412, 0.35294, 0.35294, 0.35294, 0.35294, 0.35294, 0.35294, 0.35294, 0.35294, 0.35294, 0.35294, 0.35294, 0.35294, 0.35294, 0.35294, 0.35294, 0.41176, 0.41176, 0.41176, 0.41176, 0.41176, 0.41176, 0.41176, 0.41176, 0.41176, 0.41176, 0.41176, 0.41176, 0.41176, 0.41176, 0.41176, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.52941, 0.52941, 0.52941, 0.52941, 0.52941, 0.52941, 0.52941, 0.52941, 0.52941, 0.52941, 0.52941, 0.52941, 0.52941, 0.52941, 0.52941, 0.58824, 0.58824, 0.58824, 0.58824, 0.58824, 0.58824, 0.58824, 0.58824, 0.58824, 0.58824, 0.58824, 0.58824, 0.58824, 0.58824, 0.58824, 0.64706, 0.64706, 0.64706, 0.64706, 0.64706, 0.64706, 0.64706, 0.64706, 0.64706, 0.64706, 0.64706, 0.64706, 0.64706, 0.64706, 0.64706, 0.70588, 0.70588, 0.70588, 0.70588, 0.70588, 0.70588, 0.70588, 0.70588, 0.70588, 0.70588, 0.70588, 0.70588, 0.70588, 0.70588, 0.70588, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.82353, 0.82353, 0.82353, 0.82353, 0.82353, 0.82353, 0.82353, 0.82353, 0.82353, 0.82353, 0.82353, 0.82353, 0.82353, 0.82353, 0.82353, 0.88235, 0.88235, 0.88235, 0.88235, 0.88235, 0.88235, 0.88235, 0.88235, 0.88235, 0.88235, 0.88235, 0.88235, 0.88235, 0.88235, 0.88235, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 1.00000, 1.00000, }; new ITTInfo("stairs.iasc", stairs_iasc); static double jigsaw_iasc[] = { 0.00000, 0.01569, 0.03137, 0.04706, 0.06275, 0.07843, 0.09412, 0.10980, 0.12549, 0.14118, 0.15686, 0.17255, 0.18824, 0.20392, 0.21961, 0.23529, 0.25098, 0.26667, 0.28235, 0.29804, 0.31373, 0.33333, 0.34902, 0.36471, 0.38039, 0.39608, 0.41176, 0.42745, 0.44314, 0.45882, 0.47451, 0.49020, 0.50588, 0.52157, 0.53725, 0.55294, 0.56863, 0.58431, 0.60000, 0.61569, 0.63137, 0.64706, 0.66667, 0.68235, 0.69804, 0.71373, 0.72941, 0.74510, 0.76078, 0.77647, 0.79216, 0.80784, 0.82353, 0.83922, 0.85490, 0.87059, 0.88627, 0.90196, 0.91765, 0.93333, 0.94902, 0.96471, 0.98039, 0.99608, 0.00000, 0.01569, 0.03137, 0.04706, 0.06275, 0.07843, 0.09412, 0.10980, 0.12549, 0.14118, 0.15686, 0.17255, 0.18824, 0.20392, 0.21961, 0.23529, 0.25098, 0.26667, 0.28235, 0.29804, 0.31373, 0.33333, 0.34902, 0.36471, 0.38039, 0.39608, 0.41176, 0.42745, 0.44314, 0.45882, 0.47451, 0.49020, 0.50588, 0.52157, 0.53725, 0.55294, 0.56863, 0.58431, 0.60000, 0.61569, 0.63137, 0.64706, 0.66667, 0.68235, 0.69804, 0.71373, 0.72941, 0.74510, 0.76078, 0.77647, 0.79216, 0.80784, 0.82353, 0.83922, 0.85490, 0.87059, 0.88627, 0.90196, 0.91765, 0.93333, 0.94902, 0.96471, 0.98039, 0.99608, 0.00000, 0.01569, 0.03137, 0.04706, 0.06275, 0.07843, 0.09412, 0.10980, 0.12549, 0.14118, 0.15686, 0.17255, 0.18824, 0.20392, 0.21961, 0.23529, 0.25098, 0.26667, 0.28235, 0.29804, 0.31373, 0.33333, 0.34902, 0.36471, 0.38039, 0.39608, 0.41176, 0.42745, 0.44314, 0.45882, 0.47451, 0.49020, 0.50588, 0.52157, 0.53725, 0.55294, 0.56863, 0.58431, 0.60000, 0.61569, 0.63137, 0.64706, 0.66667, 0.68235, 0.69804, 0.71373, 0.72941, 0.74510, 0.76078, 0.77647, 0.79216, 0.80784, 0.82353, 0.83922, 0.85490, 0.87059, 0.88627, 0.90196, 0.91765, 0.93333, 0.94902, 0.96471, 0.98039, 0.99608, 0.00000, 0.01569, 0.03137, 0.04706, 0.06275, 0.07843, 0.09412, 0.10980, 0.12549, 0.14118, 0.15686, 0.17255, 0.18824, 0.20392, 0.21961, 0.23529, 0.25098, 0.26667, 0.28235, 0.29804, 0.31373, 0.33333, 0.34902, 0.36471, 0.38039, 0.39608, 0.41176, 0.42745, 0.44314, 0.45882, 0.47451, 0.49020, 0.50588, 0.52157, 0.53725, 0.55294, 0.56863, 0.58431, 0.60000, 0.61569, 0.63137, 0.64706, 0.66667, 0.68235, 0.69804, 0.71373, 0.72941, 0.74510, 0.76078, 0.77647, 0.79216, 0.80784, 0.82353, 0.83922, 0.85490, 0.87059, 0.88627, 0.90196, 0.91765, 0.93333, 0.94902, 0.96471, 0.98039, 0.99608, }; new ITTInfo("jigsaw.iasc", jigsaw_iasc); static double log_iasc[] = { 0.00000, 0.01961, 0.05490, 0.08627, 0.10980, 0.13725, 0.15686, 0.18039, 0.20000, 0.21569, 0.23529, 0.25098, 0.26275, 0.28235, 0.29412, 0.30588, 0.31765, 0.33333, 0.34118, 0.35294, 0.36078, 0.37255, 0.38431, 0.39216, 0.40000, 0.41176, 0.41961, 0.43137, 0.43529, 0.44314, 0.45098, 0.45882, 0.46667, 0.47059, 0.48235, 0.48627, 0.49412, 0.50196, 0.50588, 0.50980, 0.51765, 0.52157, 0.53333, 0.53725, 0.54118, 0.54902, 0.55294, 0.55686, 0.56078, 0.56471, 0.57255, 0.58039, 0.58431, 0.58824, 0.59216, 0.59608, 0.60000, 0.60392, 0.60784, 0.61176, 0.61569, 0.61961, 0.62745, 0.63137, 0.63529, 0.63922, 0.64314, 0.64706, 0.65098, 0.65490, 0.65490, 0.65882, 0.66275, 0.66667, 0.67059, 0.67843, 0.67843, 0.68235, 0.68627, 0.69020, 0.69020, 0.69412, 0.69804, 0.70196, 0.70196, 0.70588, 0.70980, 0.71373, 0.71373, 0.71765, 0.72157, 0.72157, 0.72941, 0.73333, 0.73333, 0.73725, 0.74118, 0.74118, 0.74510, 0.74510, 0.74902, 0.75294, 0.75294, 0.75686, 0.76078, 0.76078, 0.76471, 0.76471, 0.76863, 0.76863, 0.77255, 0.78039, 0.78039, 0.78431, 0.78431, 0.78824, 0.78824, 0.79216, 0.79216, 0.79608, 0.79608, 0.80000, 0.80000, 0.80392, 0.80392, 0.80784, 0.80784, 0.81176, 0.81176, 0.81569, 0.81569, 0.81961, 0.81961, 0.82745, 0.82745, 0.83137, 0.83137, 0.83529, 0.83529, 0.83922, 0.83922, 0.83922, 0.84314, 0.84314, 0.84706, 0.84706, 0.85098, 0.85098, 0.85490, 0.85490, 0.85490, 0.85882, 0.85882, 0.86275, 0.86275, 0.86275, 0.86667, 0.86667, 0.87059, 0.87059, 0.87059, 0.87843, 0.87843, 0.88235, 0.88235, 0.88235, 0.88627, 0.88627, 0.89020, 0.89020, 0.89020, 0.89412, 0.89412, 0.89412, 0.89804, 0.89804, 0.89804, 0.90196, 0.90196, 0.90588, 0.90588, 0.90588, 0.90980, 0.90980, 0.90980, 0.91373, 0.91373, 0.91373, 0.91765, 0.91765, 0.91765, 0.92157, 0.92157, 0.92157, 0.92941, 0.92941, 0.92941, 0.93333, 0.93333, 0.93333, 0.93725, 0.93725, 0.93725, 0.94118, 0.94118, 0.94118, 0.94118, 0.94510, 0.94510, 0.94510, 0.94902, 0.94902, 0.94902, 0.95294, 0.95294, 0.95294, 0.95686, 0.95686, 0.95686, 0.95686, 0.96078, 0.96078, 0.96078, 0.96471, 0.96471, 0.96471, 0.96471, 0.96863, 0.96863, 0.96863, 0.97255, 0.97255, 0.97255, 0.97255, 0.98039, 0.98039, 0.98039, 0.98039, 0.98431, 0.98431, 0.98431, 0.98824, 0.98824, 0.98824, 0.98824, 0.99216, 0.99216, 0.99216, 0.99216, 0.99608, 0.99608, 0.99608, 0.99608, 1.00000, 1.00000, 1.00000, }; new ITTInfo("log.iasc", log_iasc); static double lasritt_iasc[] = { 0.05882, 0.12157, 0.18431, 0.24706, 0.30980, 0.37255, 0.43529, 0.49804, 0.56078, 0.62353, 0.68627, 0.74902, 0.81176, 0.87451, 0.93725, 1.00000, 0.05882, 0.05882, 0.05882, 0.05882, 0.05882, 0.05882, 0.05882, 0.05882, 0.12157, 0.12157, 0.12157, 0.12157, 0.12157, 0.12157, 0.12157, 0.12157, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.24706, 0.24706, 0.24706, 0.24706, 0.24706, 0.24706, 0.24706, 0.24706, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.43529, 0.43529, 0.43529, 0.43529, 0.43529, 0.43529, 0.43529, 0.43529, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 0.68627, 0.68627, 0.68627, 0.68627, 0.68627, 0.68627, 0.68627, 0.68627, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.81176, 0.81176, 0.81176, 0.81176, 0.81176, 0.81176, 0.81176, 0.81176, 0.87451, 0.87451, 0.87451, 0.87451, 0.87451, 0.87451, 0.87451, 0.87451, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 0.05882, 0.05882, 0.05882, 0.05882, 0.05882, 0.05882, 0.05882, 0.12157, 0.12157, 0.12157, 0.12157, 0.12157, 0.12157, 0.12157, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.24706, 0.24706, 0.24706, 0.24706, 0.24706, 0.24706, 0.24706, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.43529, 0.43529, 0.43529, 0.43529, 0.43529, 0.43529, 0.43529, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 0.68627, 0.68627, 0.68627, 0.68627, 0.68627, 0.68627, 0.68627, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.81176, 0.81176, 0.81176, 0.81176, 0.81176, 0.81176, 0.81176, 0.87451, 0.87451, 0.87451, 0.87451, 0.87451, 0.87451, 0.87451, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, }; new ITTInfo("lasritt.iasc", lasritt_iasc); static double ramp_iasc[] = { 0.00000, 0.00392, 0.00784, 0.01176, 0.01569, 0.01961, 0.02353, 0.02745, 0.03137, 0.03529, 0.03922, 0.04314, 0.04706, 0.05098, 0.05490, 0.05882, 0.06275, 0.06667, 0.07059, 0.07451, 0.07843, 0.08235, 0.08627, 0.09020, 0.09412, 0.09804, 0.10196, 0.10588, 0.10980, 0.11373, 0.11765, 0.12157, 0.12549, 0.12941, 0.13333, 0.13725, 0.14118, 0.14510, 0.14902, 0.15294, 0.15686, 0.16078, 0.16471, 0.16863, 0.17255, 0.17647, 0.18039, 0.18431, 0.18824, 0.19216, 0.19608, 0.20000, 0.20392, 0.20784, 0.21177, 0.21569, 0.21961, 0.22353, 0.22745, 0.23137, 0.23529, 0.23922, 0.24314, 0.24706, 0.25098, 0.25490, 0.25882, 0.26275, 0.26667, 0.27059, 0.27451, 0.27843, 0.28235, 0.28628, 0.29020, 0.29412, 0.29804, 0.30196, 0.30588, 0.30980, 0.31372, 0.31765, 0.32157, 0.32549, 0.32941, 0.33333, 0.33726, 0.34118, 0.34510, 0.34902, 0.35294, 0.35686, 0.36078, 0.36471, 0.36863, 0.37255, 0.37647, 0.38039, 0.38431, 0.38823, 0.39216, 0.39608, 0.40000, 0.40392, 0.40784, 0.41176, 0.41569, 0.41961, 0.42353, 0.42745, 0.43137, 0.43529, 0.43922, 0.44314, 0.44706, 0.45098, 0.45490, 0.45882, 0.46275, 0.46667, 0.47059, 0.47451, 0.47843, 0.48235, 0.48628, 0.49020, 0.49412, 0.49804, 0.50196, 0.50588, 0.50980, 0.51372, 0.51765, 0.52157, 0.52549, 0.52941, 0.53333, 0.53726, 0.54118, 0.54510, 0.54902, 0.55294, 0.55686, 0.56078, 0.56471, 0.56863, 0.57255, 0.57647, 0.58039, 0.58431, 0.58823, 0.59216, 0.59608, 0.60000, 0.60392, 0.60784, 0.61177, 0.61569, 0.61961, 0.62353, 0.62745, 0.63137, 0.63529, 0.63922, 0.64314, 0.64706, 0.65098, 0.65490, 0.65882, 0.66275, 0.66667, 0.67059, 0.67451, 0.67843, 0.68235, 0.68627, 0.69020, 0.69412, 0.69804, 0.70196, 0.70588, 0.70980, 0.71373, 0.71765, 0.72157, 0.72549, 0.72941, 0.73333, 0.73725, 0.74118, 0.74510, 0.74902, 0.75294, 0.75686, 0.76078, 0.76471, 0.76863, 0.77255, 0.77647, 0.78039, 0.78431, 0.78824, 0.79216, 0.79608, 0.80000, 0.80392, 0.80784, 0.81176, 0.81569, 0.81961, 0.82353, 0.82745, 0.83137, 0.83529, 0.83922, 0.84314, 0.84706, 0.85098, 0.85490, 0.85882, 0.86274, 0.86667, 0.87059, 0.87451, 0.87843, 0.88235, 0.88628, 0.89020, 0.89412, 0.89804, 0.90196, 0.90588, 0.90980, 0.91373, 0.91765, 0.92157, 0.92549, 0.92941, 0.93333, 0.93725, 0.94118, 0.94510, 0.94902, 0.95294, 0.95686, 0.96078, 0.96471, 0.96863, 0.97255, 0.97647, 0.98039, 0.98431, 0.98823, 0.99216, 0.99608, 1.00000, }; new ITTInfo("ramp.iasc", ramp_iasc); static double neglog_iasc[] = { 1.00000, 0.98039, 0.94510, 0.91373, 0.89020, 0.86275, 0.84314, 0.81961, 0.80000, 0.78431, 0.76471, 0.74902, 0.73725, 0.71765, 0.70588, 0.69412, 0.68235, 0.66667, 0.65882, 0.64706, 0.63922, 0.62745, 0.61569, 0.60784, 0.60000, 0.58824, 0.58039, 0.56863, 0.56471, 0.55686, 0.54902, 0.54118, 0.53333, 0.52941, 0.51765, 0.51373, 0.50588, 0.49804, 0.49412, 0.49020, 0.48235, 0.47843, 0.46667, 0.46275, 0.45882, 0.45098, 0.44706, 0.44314, 0.43922, 0.43529, 0.42745, 0.41961, 0.41569, 0.41176, 0.40784, 0.40392, 0.40000, 0.39608, 0.39216, 0.38824, 0.38431, 0.38039, 0.37255, 0.36863, 0.36471, 0.36078, 0.35686, 0.35294, 0.34902, 0.34510, 0.34510, 0.34118, 0.33725, 0.33333, 0.32941, 0.32157, 0.32157, 0.31765, 0.31373, 0.30980, 0.30980, 0.30588, 0.30196, 0.29804, 0.29804, 0.29412, 0.29020, 0.28627, 0.28627, 0.28235, 0.27843, 0.27843, 0.27059, 0.26667, 0.26667, 0.26275, 0.25882, 0.25882, 0.25490, 0.25490, 0.25098, 0.24706, 0.24706, 0.24314, 0.23922, 0.23922, 0.23529, 0.23529, 0.23137, 0.23137, 0.22745, 0.21961, 0.21961, 0.21569, 0.21569, 0.21176, 0.21176, 0.20784, 0.20784, 0.20392, 0.20392, 0.20000, 0.20000, 0.19608, 0.19608, 0.19216, 0.19216, 0.18824, 0.18824, 0.18431, 0.18431, 0.18039, 0.18039, 0.17255, 0.17255, 0.16863, 0.16863, 0.16471, 0.16471, 0.16078, 0.16078, 0.16078, 0.15686, 0.15686, 0.15294, 0.15294, 0.14902, 0.14902, 0.14510, 0.14510, 0.14510, 0.14118, 0.14118, 0.13725, 0.13725, 0.13725, 0.13333, 0.13333, 0.12941, 0.12941, 0.12941, 0.12157, 0.12157, 0.11765, 0.11765, 0.11765, 0.11373, 0.11373, 0.10980, 0.10980, 0.10980, 0.10588, 0.10588, 0.10588, 0.10196, 0.10196, 0.10196, 0.09804, 0.09804, 0.09412, 0.09412, 0.09412, 0.09020, 0.09020, 0.09020, 0.08627, 0.08627, 0.08627, 0.08235, 0.08235, 0.08235, 0.07843, 0.07843, 0.07843, 0.07059, 0.07059, 0.07059, 0.06667, 0.06667, 0.06667, 0.06275, 0.06275, 0.06275, 0.05882, 0.05882, 0.05882, 0.05882, 0.05490, 0.05490, 0.05490, 0.05098, 0.05098, 0.05098, 0.04706, 0.04706, 0.04706, 0.04314, 0.04314, 0.04314, 0.04314, 0.03922, 0.03922, 0.03922, 0.03529, 0.03529, 0.03529, 0.03529, 0.03137, 0.03137, 0.03137, 0.02745, 0.02745, 0.02745, 0.02745, 0.01961, 0.01961, 0.01961, 0.01961, 0.01569, 0.01569, 0.01569, 0.01176, 0.01176, 0.01176, 0.01176, 0.00784, 0.00784, 0.00784, 0.00784, 0.00392, 0.00392, 0.00392, 0.00392, 0.00000, 0.00000, 0.00000, }; new ITTInfo("neglog.iasc", neglog_iasc); static double neg_iasc[] = { 1.00000, 0.99608, 0.99216, 0.98824, 0.98431, 0.98039, 0.97647, 0.97255, 0.96863, 0.96471, 0.96078, 0.95686, 0.95294, 0.94902, 0.94510, 0.94118, 0.93725, 0.93333, 0.92941, 0.92549, 0.92157, 0.91765, 0.91373, 0.90980, 0.90588, 0.90196, 0.89804, 0.89412, 0.89020, 0.88627, 0.88235, 0.87843, 0.87451, 0.87059, 0.86667, 0.86275, 0.85882, 0.85490, 0.85098, 0.84706, 0.84314, 0.83922, 0.83529, 0.83137, 0.82745, 0.82353, 0.81961, 0.81569, 0.81176, 0.80784, 0.80392, 0.80000, 0.79608, 0.79216, 0.78824, 0.78431, 0.78039, 0.77647, 0.77255, 0.76863, 0.76471, 0.76078, 0.75686, 0.75294, 0.74902, 0.74510, 0.74118, 0.73725, 0.73333, 0.72941, 0.72549, 0.72157, 0.71765, 0.71373, 0.70980, 0.70588, 0.70196, 0.69804, 0.69412, 0.69020, 0.68627, 0.68235, 0.67843, 0.67451, 0.67059, 0.66667, 0.66275, 0.65882, 0.65490, 0.65098, 0.64706, 0.64314, 0.63922, 0.63529, 0.63137, 0.62745, 0.62353, 0.61961, 0.61569, 0.61176, 0.60784, 0.60392, 0.60000, 0.59608, 0.59216, 0.58824, 0.58431, 0.58039, 0.57647, 0.57255, 0.56863, 0.56471, 0.56078, 0.55686, 0.55294, 0.54902, 0.54510, 0.54118, 0.53725, 0.53333, 0.52941, 0.52549, 0.52157, 0.51765, 0.51373, 0.50980, 0.50588, 0.50196, 0.49804, 0.49412, 0.49020, 0.48627, 0.48235, 0.47843, 0.47451, 0.47059, 0.46667, 0.46275, 0.45882, 0.45490, 0.45098, 0.44706, 0.44314, 0.43922, 0.43529, 0.43137, 0.42745, 0.42353, 0.41961, 0.41569, 0.41176, 0.40784, 0.40392, 0.40000, 0.39608, 0.39216, 0.38824, 0.38431, 0.38039, 0.37647, 0.37255, 0.36863, 0.36471, 0.36078, 0.35686, 0.35294, 0.34902, 0.34510, 0.34118, 0.33725, 0.33333, 0.32941, 0.32549, 0.32157, 0.31765, 0.31373, 0.30980, 0.30588, 0.30196, 0.29804, 0.29412, 0.29020, 0.28627, 0.28235, 0.27843, 0.27451, 0.27059, 0.26667, 0.26275, 0.25882, 0.25490, 0.25098, 0.24706, 0.24314, 0.23922, 0.23529, 0.23137, 0.22745, 0.22353, 0.21961, 0.21569, 0.21176, 0.20784, 0.20392, 0.20000, 0.19608, 0.19216, 0.18824, 0.18431, 0.18039, 0.17647, 0.17255, 0.16863, 0.16471, 0.16078, 0.15686, 0.15294, 0.14902, 0.14510, 0.14118, 0.13725, 0.13333, 0.12941, 0.12549, 0.12157, 0.11765, 0.11373, 0.10980, 0.10588, 0.10196, 0.09804, 0.09412, 0.09020, 0.08627, 0.08235, 0.07843, 0.07451, 0.07059, 0.06667, 0.06275, 0.05882, 0.05490, 0.05098, 0.04706, 0.04314, 0.03922, 0.03529, 0.03137, 0.02745, 0.02353, 0.01961, 0.01569, 0.01176, 0.00784, 0.00392, 0.00000, }; new ITTInfo("neg.iasc", neg_iasc); } skycat-3.1.2-starlink-1b/rtd/generic/covsrt.c000066400000000000000000000053041215713201500210300ustar00rootroot00000000000000/* @(#)covsrt.c 10.1.1.2 (ES0-DMD) 12/18/95 18:21:09 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COPYRIGHT (c) 1995 European Southern Observatory .IDENT covsrt.c .LANGUAGE C .AUTHOR P.Grosbol, IPG/ESO .COMMENT Algorithm taken from 'Numerical Recipes in C' s14.3, p534 NOTE: Data array is covar[0..ma-1][0..ma-1] FORTRAN order> cvm[ir][ic] = cvm[ir+ic*ma] .KEYWORDS Covariance matrix .VERSION 1.0 1994-Jan-28 : Creation, PJG .VERSION 1.1 1995-Apr-29 : Correct index error, PJG ------------------------------------------------------------------------*/ covsrt(covar,ma,lista,mfit) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE compute covariance matrix .RETURN status, always 0: OK ------------------------------------------------------------------------*/ double *covar; int ma; int lista[]; int mfit; { int i, j; double swap; for (j=0; j lista[i]) covar[lista[j]+lista[i]*ma] = covar[i+j*ma]; else covar[lista[i]+lista[j]*ma] = covar[i+j*ma]; } swap = covar[0]; for (j=0; j b[ir][ic] = b[ir+ic*n] .VERSION 1.0 1994-Jan-28 : Creation, PJG ------------------------------------------------------------------------*/ #include /* Mathematical definitions */ #define MMA 16 /* Max. size of matrix */ #define SWAP(a,b) {double temp=(a);(a)=(b);(b)=temp;} gaussj(a,n,b,m) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Inverse matrix using Gauss-Jordan elimination .RETURN status, 0: OK, -1: Singular matrix 1, -2: Singular matrix 2, -3: matrix too big ------------------------------------------------------------------------*/ double *a; int n; double *b; int m; { int i, icol, irow, j, k, l, ll; int indxc[MMA], indxr[MMA], ipiv[MMA]; double big, dum, pivinv; if (MMA= big) { big = dum; irow = j; icol = k; } } else if (ipiv[k] > 1) return -1; } } ++(ipiv[icol]); if (irow != icol) { for (l=0; l=0; l--) { if (indxr[l] != indxc[l]) for (k=0; k -- -- */ #include #include "histeq.h" /* define SubrangeLink */ static int excess_zgroup(), excess_nzgroup(), range_zgroup(); /* * Subroutine: distribute_levels * Purpose: Distribute the levels among histogram sub-groups * Returns: number of groups with no assigned color levels */ int distribute_levels ( linklist, pixel_area, color_levels, pmin, pmax, ncolor ) SubrangeLink *linklist; int pixel_area, color_levels; int pmin, pmax, ncolor; { int average; int threshold; int excess; int levels, zeroes; int max_z_excess, max_nz_excess, max_z_range; SubrangeLink *subrange; #ifdef DEBUG int census = 0; #endif /* if all one group (no strong peaks), allocation is simple */ if( linklist->next == 0 ) { linklist->color_levels = ncolor; return( 0 ); } /* average is rounded strongly upward to be stingy with levels */ average = (pixel_area / color_levels) + 1; subrange = linklist; zeroes = 0; max_z_excess = max_nz_excess = 0; max_z_range = 0; /* first pass, simple assignment and some note taking */ while( subrange != 0 ) { if( subrange->range > 0 ) { levels = subrange->pixel_area / average; excess = subrange->pixel_area - (levels * average); if( levels >= subrange->range ) { levels = subrange->range; subrange->range = -subrange->range; } else { if( levels == 0 ) { zeroes++; if( excess > max_z_excess ) max_z_excess = excess; if( subrange->range > max_z_range ) max_z_range = subrange->range; } else { if( excess > max_nz_excess ) max_nz_excess = excess; } } subrange->color_levels = levels; subrange->excess_pixels = excess; color_levels -= levels; #ifndef DEBUG } #else census += levels; } else ++census; #endif subrange = subrange->next; } /* second pass groups with no levels and vals or ranges above limits */ if( zeroes > 0 ) { /* groups with counts above 1/4 of average */ threshold = average / 4; while( (zeroes > 0) && (color_levels > 0) && (max_z_excess > threshold) ) { if( excess_zgroup(linklist, &max_z_excess, &max_z_range, average) ) { zeroes--; color_levels--; #ifndef DEBUG } #else census++; } else (void)fprintf(stderr, "Failed to find excess zero.\n"); #endif } /* groups with range above 2 * unequalized distribution */ threshold = MAX(((pmax - pmin) / 8) , 4); while( (zeroes > 0) && (color_levels > 0) && (max_z_range > threshold) ) { if( range_zgroup(linklist, &max_z_excess, &max_z_range, average) ) { zeroes--; color_levels--; #ifndef DEBUG } #else census++; } else (void)fprintf(stderr, "Failed to find range zero.\n"); #endif } } /* third pass, give away any remaining levels by highest excess */ #ifdef DEBUG if( color_levels != (ncolor - census) ) { (void)fprintf(stderr, "Allocation waste: %d level(s)\n", (ncolor - census) - color_levels); } #endif while( color_levels > 0 ) { if( (zeroes > 0) && (max_z_excess > max_nz_excess) ) { if( excess_zgroup(linklist, &max_z_excess, &max_z_range, average) ) { zeroes--; color_levels--; } else { #ifdef DEBUG (void)fprintf(stderr, "Failed to find excess zero.\n"); #endif break; /* allan: break endless loop */ } } else { if( excess_nzgroup(linklist, &max_nz_excess, average) ) color_levels--; else { #ifdef DEBUG (void)fprintf(stderr, "Failed to find excess.\n"); #endif break; /* allan: break endless loop */ } } } return( zeroes ); } /* * Subroutine: excess_zgroup * Purpose: Find subrange with zero allotted levels and specified excess. * Assign it one level */ static int excess_zgroup ( subrange, excess, range, average ) SubrangeLink *subrange; int *excess, *range; int average; { int max_excess, looking; max_excess = -32700; looking = 1; while( subrange != 0 ) { if( (subrange->color_levels == 0) && (subrange->range > 0) ) { if( looking && (subrange->excess_pixels == *excess) ) { if( subrange->range > 1 ) { subrange->color_levels = 1; } else { subrange->color_levels = 1; subrange->range = -1; } subrange->excess_pixels -= average; looking = 0; } else { if( subrange->excess_pixels > max_excess ) max_excess = subrange->excess_pixels; if( subrange->range > *range ) *range = subrange->range; } } subrange = subrange->next; } *excess = max_excess; return( !looking ); } /* * Subroutine: range_zgroup * Purpose: Find group with zero allotted levels and specified range. * Assign it one level. */ static int range_zgroup (subrange, excess, range, average) SubrangeLink *subrange; int *excess, *range; int average; { int max_range, looking; max_range = 0; looking = 1; while( subrange != 0 ) { if( (subrange->color_levels == 0) && (subrange->range > 0) ) { if( looking && (subrange->range == *range) ) { if( subrange->range > 1 ) { subrange->color_levels = 1; } else { subrange->color_levels = 1; subrange->range = -1; } subrange->excess_pixels -= average; looking = 0; } else { if( subrange->excess_pixels > *excess ) *excess = subrange->excess_pixels; if( subrange->range > max_range ) max_range = subrange->range; } } subrange = subrange->next; } *range = max_range; return( !looking ); } /* * Subroutine: excess_nzgroup * Purpose: Find group with non-zero allotted levels and specified * excess value. Assign it one additional level. */ static int excess_nzgroup ( subrange, excess, average ) SubrangeLink *subrange; int *excess; int average; { int looking, max_excess; looking = 1; max_excess = -32767; while( subrange != 0 ) { if( (subrange->color_levels > 0) && (subrange->range > 1) ) { if( looking && (subrange->excess_pixels == *excess) && (subrange->color_levels < subrange->range) ) { subrange->color_levels += 1; subrange->excess_pixels -= average; if( subrange->color_levels == subrange->range ) { subrange->color_levels = subrange->range; subrange->range = -subrange->range; } else { if( subrange->excess_pixels > max_excess ) max_excess = subrange->excess_pixels; } looking = 0; } else { if( subrange->excess_pixels > max_excess ) max_excess = subrange->excess_pixels; } } subrange = subrange->next; } *excess = max_excess; return( !looking ); } skycat-3.1.2-starlink-1b/rtd/generic/histeq.h000066400000000000000000000044311215713201500210120ustar00rootroot00000000000000/* * histeq.h - saoimage header file for histogram equalization functions. * allan: added header, guard, includes, prototypes */ #ifndef _histeq_h_ #define _histeq_h_ #include #ifndef lint static char SccsHistEqId[] = "%W% %G%"; #endif /* Module: HistEq.h * Purpose: Define the structs for histogram equalization * Modified: {0} Michael VanHilst initial version 30 May 1989 * {1} Peter W. Draper converted to use unsigned 20 Jan 1999 * long for scalemap * {n} -- -- */ #ifndef MAX #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #endif /* link describes a section of the histogram to have levels allocated */ typedef struct histogramLink { int low; /* index of lowest histogram entry */ int high; /* index of highest histogram entry */ int range; /* number of histogram entries covered */ int nz_entries; /* number of non-zero histogram entries */ int pixel_area; /* number of image pixels within range */ int max_entry; /* largest area for any single entry */ int excess_pixels; /* pixel area in excess of average */ int color_levels; /* number of color levels allocated */ struct histogramLink *next; /* link list pointer */ int pad; } SubrangeLink; /* list describing details of color level allocation for a histogram range */ typedef struct histogramList { int pixel_area; /* pixel area that is covered by this color level */ int first, last; /* first and last histogram entries cor this color */ int pad; int shrink_area; /* area covered by omitting last non-zero entry */ int shrink_entry; /* index for last to excude last non-zero entry */ int stretch_area; /* area covered by including next non-zero entry */ int stretch_entry; /* index for last to include next non-zero entry */ } SubrangeList; /* allan: added prototype */ void histogram_equalize ( unsigned long *scalemap, /* i/o: scalemap (for signed indexing) */ int *histogram, /* i: histogram (for signed indexing) */ int area, /* i: area in pixels when histogram was made */ int pmin, int pmax, /* i: min and max values in histogram */ int color_levels, /* i: number of levels in color map */ unsigned long *pixels); /* i: map to hardware entries */ #endif /* _histeq_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/histeql.c000066400000000000000000000134551215713201500211670ustar00rootroot00000000000000#ifndef lint static char SccsId[] = "%W% %G%"; #endif /* Module: histeql.c (Histogram Equalize) * Purpose: Fill the scalemap by histogram equalization * Subroutine: histogram_equalize() returns: void * Copyright: 1989 Smithsonian Astrophysical Observatory * You may do anything you like with this file except remove * this copyright. The Smithsonian Astrophysical Observatory * makes no representations about the suitability of this * software for any purpose. It is provided "as is" without * express or implied warranty. * Modified: {0} Michael VanHilst initial version 30 May 1989 * {1} Peter W. Draper converted to use unsigned 20 Jan 1999 * long for scalemap * {n} -- -- */ #include #include "histeq.h" /* define SubrangeLink */ static int count_nonzero_histogram_entries(), rescan_histogram(); static void unmark_peak_links(); /* * Subroutine: histogram_equalize * Purpose: Create a scaling map which equalizes image cells per * output level optimization accounts for large cell counts * for single levels (e.g. half of all pixels with value 0) */ void histogram_equalize ( scalemap, histogram, area, pmin, pmax, color_levels, pixels ) unsigned long *scalemap; /* i/o: scalemap (for signed indexing) */ int *histogram; /* i: histogram (for signed indexing) */ int area; /* i: area in pixels when histogram was made */ int pmin, pmax; /* i: min and max values in histogram */ int color_levels; /* i: number of levels in color map */ unsigned long *pixels; /* i: map to hardware entries */ { SubrangeLink *linklist; /* l: beginning of subrange linklist */ int average_area; /* l: average area covered by each level */ int pixel_area; int map_levels; int nz_entries; /* l: non-zero entries in histogram */ int empties; /* l: subranges with no alloted levels */ char *calloc_errchk(); int distribute_levels(); void generate_scalemap(), scan_histogram_for_peaks(), resolve_zeroes(); /* initialize link list */ linklist = (SubrangeLink *)calloc_errchk(10, sizeof(int), "HElink"); linklist->next = 0; linklist->low = pmin; linklist->high = pmax; linklist->range = (pmax - pmin) + 1; linklist->pixel_area = area; linklist->max_entry = 0; /* if not enough non-zero entries to make distribution, bypass work */ nz_entries = count_nonzero_histogram_entries(histogram, pmin, pmax); if( nz_entries <= color_levels ) { linklist->color_levels = color_levels; linklist->nz_entries = nz_entries; generate_scalemap(histogram, linklist, scalemap, pixels); return; } /* initialize count and level variables */ pixel_area = area; map_levels = color_levels; /* desired number of pixels at each level */ /* average is rounded strongly upward to be stingy with levels */ average_area = (pixel_area / map_levels) + 1; /* go through histogram seeking histogram entries above the map mean */ scan_histogram_for_peaks(linklist, histogram, &pixel_area, &map_levels, &average_area); /* repeat scans until no more treetops emerge */ while( rescan_histogram(linklist, histogram, &pixel_area, &map_levels, &average_area) != 0 ); /* allocate levels */ empties = distribute_levels(linklist, pixel_area, map_levels, pmin, pmax, color_levels); /* make peak and valley links look the same (peaks have range 1) */ unmark_peak_links(linklist, color_levels); if( empties > 0 ) { resolve_zeroes(linklist, empties); } /* make map and free memory */ generate_scalemap(histogram, linklist, scalemap, pixels); } /* * Subroutine: rescan_histogram * Purpose: Repeat scanning for large count levels as saturation level * is modified. Repeats until all large count levels are * marked and residual is stable * Returns: 1 if a range was modified, 0 if nothing was changed */ static int rescan_histogram ( subrange, histogram, pixel_area, map_levels, average_area ) SubrangeLink *subrange; int *histogram; int *pixel_area; int *map_levels; int *average_area; { int process; void scan_histogram_for_peaks(); process = 0; while( subrange != 0 ) { /* if subrange has values that exceed current average */ if( (subrange->range > 1) && (subrange->max_entry >= *average_area) ) { scan_histogram_for_peaks(subrange, histogram, pixel_area, map_levels, average_area); /* indicate that additional processing has taken place */ process = 1; } subrange = subrange->next; } return( process ); } /* * Subroutine: unmark_peak_links * Purpose: Make singularity links non_uniquely marked (range > 0) and * check count against reference * Called by: histogram_equalize() above */ static void unmark_peak_links ( subrange, nlevels ) SubrangeLink *subrange; int nlevels; { #ifdef DEBUG int levels = 0; #endif while( subrange != 0 ) { if( subrange->range <0 ) { subrange->range = -subrange->range; } #ifdef DEBUG if( (subrange->next != 0) && (subrange->next->low != (subrange->high + 1)) ) (void)fprintf(stderr, "Missing Link in list.\n"); if( subrange->color_levels > subrange->range ) (void)fprintf(stderr, "Excess levels in a Link.\n"); levels += subrange->color_levels; #endif subrange = subrange->next; } #ifdef DEBUG if( levels != nlevels ) { (void)fprintf(stderr, "Levels = %d\n",levels); } #endif } /* * Subroutine: count_nonzero_histogram_entries * Called by: histogram_equalize() in HistEqual.c */ static int count_nonzero_histogram_entries ( histogram, pmin, pmax ) register int *histogram; int pmin; register int pmax; { register int i, npix; npix = 0; for( i = pmin; i <= pmax; i++ ) { if( histogram[(ushort)i] > 0 ) /* allan: added ushort cast */ ++npix; } return( npix ); } skycat-3.1.2-starlink-1b/rtd/generic/histlist.c000066400000000000000000000365121215713201500213600ustar00rootroot00000000000000#ifndef lint static char SccsId[] = "%W% %G%"; #endif /* Module: histlist.c (Histogram List) * Subroutine: make_equalized_list() returns: void * Copyright: 1989 Smithsonian Astrophysical Observatory * You may do anything you like with this file except remove * this copyright. The Smithsonian Astrophysical Observatory * makes no representations about the suitability of this * software for any purpose. It is provided "as is" without * express or implied warranty. * Modified: {0} Michael VanHilst initial version 30 May 1989 * {1} MVH constraints based on best history 15 Dec 1989 * {2} JRW limit to get out of infinite loop 19 Jun 1991 * {n} -- -- */ #include #include "histeq.h" /* define SubrangeList */ #define MAXITERATIONS 1000 /* --jrw */ #ifdef DEBUG #define HDEBUG #endif static int equalize_simply(); #ifdef JIGGLE static void adjust_list(); #endif /* * Subroutine: make_equalized_list * Purpose: Distributing levels for a subrange section of the histogram */ void make_equalized_list ( histogram, list, low_entry, high_entry, pixel_area, color_levels ) int *histogram; SubrangeList *list; int low_entry, high_entry; int pixel_area, color_levels; { int shrink_level, stretch_level; int max_shrink, min_stretch; int average_area, end_area, min_area, max_area; int levels_given; /* levels which equalize_simply used */ int correction; /* correction for asymptotic convergence */ int iterations; /* avoid infinite loop --jrw */ int end_error; /* deviation from ideal of last level */ int best_levels_over; /* levels from an equalize worth remembering */ int best_levels_under; int best_average_over = 0; /* average_area used to get best_levels */ int best_average_under = 0; /* else allocation distribution must first be determined */ /* run through histgram section making basic allocation and taking notes */ average_area = pixel_area / color_levels; max_area = max_shrink = 0; min_area = min_stretch = pixel_area + 1; /* use 2*color_levels to allow allocation to exceed limit */ levels_given = equalize_simply(histogram, list, 0, average_area, low_entry, high_entry, color_levels + color_levels, &shrink_level, &stretch_level, &end_area, &min_area, &max_area, &min_stretch, &max_shrink); if( levels_given != color_levels ) { /* make approximation for large errors */ correction = ((color_levels - levels_given) * average_area) / -100; /* default correction if error was relatively small */ if( (correction < 2) && (correction > -2) ) { if( color_levels > levels_given ) correction = -2; else correction = 2; } /* record what has been learned so far */ if( levels_given > color_levels ) { best_levels_over = levels_given; best_average_over = average_area; } else { best_levels_under = levels_given; best_average_under = average_area; } } else /* if first try was good enough, go with it */ correction = 0; end_error = 0; iterations = 0; /* --jrw */ while( (correction != 0) && (iterations++ < MAXITERATIONS) ) { /* --jrw */ average_area += correction; levels_given = equalize_simply(histogram, list, 0, average_area, low_entry, high_entry, color_levels + color_levels, &shrink_level, &stretch_level, &end_area, &min_area, &max_area, &min_stretch, &max_shrink); if( levels_given != color_levels ) { if( levels_given > color_levels ) { /* is this the closest overshoot */ if( (best_average_over == 0) || (levels_given < best_levels_over) ) { best_levels_over = levels_given; best_average_over = average_area; } if( correction < 0 ) { /* went too far, turn back if that is an option */ if( (correction == -1) && (end_error == 0) ) /* done if we never got to a true result */ correction = 0; else /* asymtotic correction to converge on solution */ correction = (correction - 1) / -2; } else if( (best_average_under != 0) && (best_average_under <= (average_area + correction)) ) /* if continue in same direction, don't pass previous best */ correction = (best_average_under - average_area) - 1; } else { /* is this the closest undershoot */ if( (best_average_under == 0) || (levels_given < best_levels_under) ) { best_levels_under = levels_given; best_average_under = average_area; } if( correction > 0 ) { if( (correction == 1) && (end_error == 0) ) /* done if we never got to a true result */ correction = 0; else /* asymtotic correction to converge on solution */ correction = (correction + 1) / -2; } else if( (best_average_over != 0) && (best_average_over <= (average_area + correction)) ) /* if continue in same direction, don't pass previous best */ correction = (best_average_over - average_area) + 1; } } else if( (end_area > max_area) || (end_area < min_area) ) { if( correction < -16 ) correction = -16; else if( correction > 16 ) correction = 16; if( end_area > average_area ) { if( correction < 0 ) { /* this is an overshoot */ correction = correction / -2; if( (end_error == 0) || ((end_area - average_area) > end_error) ) { /* go back if we might do better */ if( correction == 0 ) correction = 1; } end_error = end_area - average_area; } } else { if( correction > 0 ) { /* this is an overshoot */ correction = correction / -2; if( (end_error == 0) || ((average_area - end_area) > end_error) ) { /* go back if we might do better */ if( correction == 0 ) correction = -1; } end_error = average_area - end_area; } } } else correction = 0; } #if 0 if (correction != 0) { (void)printf("SAOimage: histeq could not converge on best distribution,"); (void)printf(" proceeding anyway\n"); (void)fflush(stdout); } #endif /* if no fit yet, force one by making last level stretch */ if( (levels_given != color_levels) && (best_average_over != 0) ) { levels_given = equalize_simply(histogram, list, 0, best_average_over, low_entry, high_entry, color_levels, &shrink_level, &stretch_level, &end_area, &min_area, &max_area, &min_stretch, &max_shrink); } #ifdef JIGGLE /* This section to directly adjust level boundaries for a better fit * is experimental. It is not currently used, because the improvement * is not important relative to the processing time that can occur * in non-stable situations. In some situations, such as when * levels != color_levels coming out of the previous loop, a few * passes could yield worthwhile improvements. */ #ifdef HDEBUG (void)printf("Before adjustment: %d (between: %d %d), end: %d\n", max_area - min_area, min_area, max_area, end_area); (void)fflush(stdout); #endif /* jiggle the allocations for a better fit (reduce maximum error) */ if( (end_area > max_area) && (end_area > min_stretch) ) { /* bunch toward the end to make it smaller */ while( (end_area > max_area) && (end_area > min_stretch) ) { average_area = min_stretch; adjust_list(1, histogram, list, color_levels, low_entry, high_entry, average_area, &stretch_level, &shrink_level, &end_area, &min_area, &max_area, &min_stretch, &max_shrink); } } else if( (end_area < min_area) && (end_area < max_shrink) ) { /* bunch away from the end to make it bigger */ while( (end_area < min_area) && (end_area < max_shrink) ) { average_area = max_shrink; adjust_list(0, histogram, list, color_levels, low_entry, high_entry, average_area, &stretch_level, &shrink_level, &end_area, &min_area, &max_area, &min_stretch, &max_shrink); } } #ifdef HDEBUG (void)printf("After adjustment: %d (between: %d %d), end: %d\n", max_area - min_area, min_area, max_area, end_area); (void)fflush(stdout); #endif #endif } /* * Subroutine: equalize_simply * Purpose: Make a list to describe map using basic allocation method * Note: Allocate levels from "level" to "color_levels" */ static int equalize_simply ( histogram, histlist, level, average_area, low_entry, high_entry, color_levels, shrink_level, stretch_level, end_area, min_area, max_area, min_stretch, max_shrink ) int *histogram; SubrangeList *histlist; int level, average_area; int low_entry, high_entry; int color_levels; int *shrink_level, *stretch_level; int *end_area, *min_area, *max_area; int *min_stretch, *max_shrink; { int entry, neighbor_entry; int area, old_area; int err_low, err_high; int init_next; /* initialize parameters */ init_next = 0; area = 0; histlist[level].first = low_entry; /* reduce by one for indexing to end on last list level */ color_levels--; /* in this pass, assign levels by simple method */ for( entry = low_entry; entry <= high_entry; entry++ ) { if( init_next ) { ++level; histlist[level].first = entry; area = 0; init_next = 0; } old_area = area; area += histogram[(ushort)entry]; /* allan: added ushort cast */ /* while levels last, scan till exceed average area */ if( (level < color_levels) && (area >= average_area) ) { err_low = average_area - old_area; err_high = area - average_area; if( err_high < err_low ) { /* err to excess */ histlist[level].last = entry; histlist[level].pixel_area = area; /* shrink option would be to exclude this entry */ histlist[level].shrink_area = old_area; histlist[level].shrink_entry = entry - 1; /* look for next non-zero entry to include for stretch option */ neighbor_entry = entry; do { ++neighbor_entry; } while( (neighbor_entry <= high_entry) && (histogram[(ushort)neighbor_entry] == 0) ); /* allan: added ushort cast */ if( neighbor_entry > high_entry ) { /* if at high end, exagerate to preclude this option */ histlist[level].stretch_area = 10 * area; histlist[level].stretch_entry = high_entry; } else { histlist[level].stretch_area = area + histogram[(ushort)neighbor_entry]; /* allan: added ushort cast */ histlist[level].stretch_entry = neighbor_entry; } } else { /* err short */ /* exclude this entry */ neighbor_entry = entry - 1; histlist[level].last = neighbor_entry; histlist[level].pixel_area = old_area; /* including this entry is the stretch option */ histlist[level].stretch_area = area; histlist[level].stretch_entry = entry; /* look for previous non-zero entry for shrink option (check limit) */ while( (neighbor_entry >= low_entry) && (histogram[(ushort)neighbor_entry] == 0) ) /* allan: added ushort cast */ --neighbor_entry; if( neighbor_entry < low_entry ) { /* if at low end, preclude this option */ histlist[level].shrink_area = 0; histlist[level].shrink_entry = low_entry; } else { histlist[level].shrink_area = old_area - histogram[(ushort)neighbor_entry]; /* allan: added ushort cast */ histlist[level].shrink_entry = neighbor_entry - 1; } /* leave this entry for the next level */ --entry; } /* check for new champions of excess */ if( histlist[level].pixel_area < *min_area ) *min_area = histlist[level].pixel_area; if( histlist[level].pixel_area > *max_area ) *max_area = histlist[level].pixel_area; if( histlist[level].stretch_area <= *min_stretch ) { *min_stretch = histlist[level].stretch_area; *stretch_level = level; } if( histlist[level].shrink_area >= *max_shrink ) { *max_shrink = histlist[level].shrink_area; *shrink_level = level; } init_next = 1; } } /* mark end of list (level should be last one (color_levels - 1)) */ histlist[level].pixel_area = area; *end_area = area; histlist[level].last = entry - 1; return( level + 1 ); } #ifdef JIGGLE /* * Subroutine: adjust_list * Purpose: Alter a level of the map and remake section above altered level */ static void adjust_list ( stretch_this_entry, histogram, histlist, color_levels, low_entry, high_entry, average_area, stretch_level, shrink_level, end_area, min_area, max_area, min_stretch, max_shrink ) int stretch_this_entry; /* i: stretch an entry, else shrink one */ int *histogram; SubrangeList *histlist; int color_levels; int low_entry, high_entry, average_area; int *shrink_level, *stretch_level; int *end_area, *min_area, *max_area; int *min_stretch, *max_shrink; { int level, j, neighbor_entry; int equalize_simply(); /* make an adjustment */ if( stretch_this_entry ) { /* stretch an entry */ level = *stretch_level; /* shrink returns to what it was */ histlist[level].shrink_area = histlist[level].pixel_area; histlist[level].shrink_entry = histlist[level].last; /* current was stretch option before */ histlist[level].pixel_area = histlist[level].stretch_area; histlist[level].last = histlist[level].stretch_entry; /* find the next non-zero entry for the new stretch option */ neighbor_entry = histlist[level].last; do { ++neighbor_entry; } while( (neighbor_entry <= high_entry) && (histogram[(ushort)neighbor_entry] == 0) ); /* allan: added ushort cast */ if( neighbor_entry > high_entry ) { /* don't go off the edge */ histlist[level].stretch_area *= 10; histlist[level].stretch_entry = high_entry; } else { histlist[level].stretch_area += histogram[(ushort)neighbor_entry]; /* allan: added ushort cast */ histlist[level].stretch_entry = neighbor_entry; } } else { /* shrink an entry */ level = *shrink_level; /* stretch option becomes what it was */ histlist[level].stretch_area = histlist[level].pixel_area; histlist[level].stretch_entry = histlist[level].last; /* current was shrink option before */ histlist[level].last = histlist[level].shrink_entry; histlist[level].pixel_area = histlist[level].shrink_area; /* look for last non-zero entry to exclude for new shrink option */ neighbor_entry = histlist[level].last; while( (neighbor_entry >= low_entry) && (histogram[(ushort)neighbor_entry] == 0) ) /* allan: added ushort cast */ --neighbor_entry; if( neighbor_entry < low_entry ) { /* don't go off the edge */ histlist[level].shrink_area = 0; histlist[level].shrink_entry = low_entry; } else { histlist[level].shrink_area -= histogram[(ushort)neighbor_entry]; /* allan: added ushort cast */ histlist[level].shrink_entry = neighbor_entry - 1; } } /* remake list with this change */ *min_area = *min_stretch = average_area * 3; *max_shrink = *max_area = 0; /* retake notes up to point of change */ for( j = 0; j <= level; j++ ) { if( histlist[j].pixel_area < *min_area ) *min_area = histlist[j].pixel_area; if( histlist[j].pixel_area > *max_area ) *max_area = histlist[j].pixel_area; if( histlist[j].stretch_area <= *min_stretch ) { *min_stretch = histlist[j].stretch_area; *stretch_level = j; } if( histlist[j].shrink_area >= *max_shrink ) { *max_shrink = histlist[j].shrink_area; *shrink_level = j; } } if( (level < color_levels) && (histlist[level].last < high_entry) ) /* make rest of list in normal way */ (void)equalize_simply(histogram, histlist, j, average_area, histlist[level].last + 1, high_entry, color_levels, shrink_level, stretch_level, end_area, min_area, max_area, min_stretch, max_shrink); } #endif skycat-3.1.2-starlink-1b/rtd/generic/histmap.c000066400000000000000000000173021215713201500211560ustar00rootroot00000000000000#ifndef lint static char SccsId[] = "%W% %G%"; #endif /* Module: histmap.c (Histogram Map) * Subroutine: make_HE_scalemap() returns: int * Copyright: 1989 Smithsonian Astrophysical Observatory * You may do anything you like with this file except remove * this copyright. The Smithsonian Astrophysical Observatory * makes no representations about the suitability of this * software for any purpose. It is provided "as is" without * express or implied warranty. * Modified: {0} Michael VanHilst initial version 30 May 1989 * {1} Peter W. Draper converted to use unsigned 20 Jan 1999 * long for scalemap * {n} -- -- */ #include #include #include "histeq.h" /* define SubrangeLink, List */ static void make_subrange_scalemap(); static void make_gapped_list(), list_to_map(); static int first_shortlist_pass(); static void add_level_to_short_list(); /* * Subroutine: generate_scalemap * Purpose: Make scalemap, applying standard histgoram equalization * one subrange group at a time * Note: Value range was broken into groups with an assigned number * of levels for each group. Each group is either a single * value or a range of values with no excessive peaks, such that * standard (non-optimizing) histogram equaliztion algorithm can * safely be applied. * Note: The original link-list of groups is freed. */ void generate_scalemap ( hist, subrange, scalemap, pixels ) int *hist; /* i: histogram (for signed offsets) */ SubrangeLink *subrange; /* i: linklist of subranges */ unsigned long *scalemap; /* i: scalemap (for signed indexing) */ unsigned long *pixels; /* i: map to hardware entries */ { int baselevel; SubrangeLink *trash; baselevel = 0; while( subrange != 0 ) { make_subrange_scalemap(hist, subrange, scalemap, baselevel, pixels); if( subrange->color_levels > 0 ) baselevel += subrange->color_levels; trash = subrange; subrange = subrange->next; free((char *)trash); } } /* * Subroutine: make_subrange_scalemap * Purpose: Make a section of scale map using histgroup link as guide * Called by: make_HE_scalemap() in HistEqual.c */ static void make_subrange_scalemap ( histogram, subrange, scalemap, baselevel, pixels ) int *histogram; SubrangeLink *subrange; unsigned long *scalemap; /* scalemap (for signed indexing) */ int baselevel; unsigned long *pixels; /* i: map to hardware entries */ { int i, color_levels; SubrangeList *list; unsigned long dispval; char *calloc_errchk(); void make_equalized_list(); /* if only one level, make map section */ if( subrange->color_levels <= 1 ) { dispval = pixels[baselevel]; for( i = subrange->low; i <= subrange->high; i++ ) { scalemap[(ushort)i] = dispval; /* allan: added ushort cast */ } return; } color_levels = subrange->color_levels; /* allocate excess space as initial efforts may overshoot number of levels */ list = (SubrangeList *) calloc_errchk(2 * color_levels, sizeof(SubrangeList), "HistList"); /* if normal processing will not work, choose special */ if( color_levels < subrange->nz_entries ) { make_equalized_list(histogram, list, subrange->low, subrange->high, subrange->pixel_area, color_levels); } else { make_gapped_list(histogram, list, subrange->low, subrange->high, color_levels); } #ifdef DEBUG /* check work done */ if( list[color_levels - 1].last != subrange->high ) { (void)fprintf(stderr, "ERROR: histogram list not right\n"); (void)fprintf(stderr, "levels: %d, list: %d, link: %d\n", color_levels, list[color_levels - 1].last, subrange->high); } #endif /* make section of map as defined by list */ list_to_map(scalemap, list, baselevel, color_levels, pixels); /* free the list space */ free( (char *)list ); } /* * Subroutine: list_to_map * Purpose: Make section of map as defined by list * Called by: make_subrange_scalemap() above */ static void list_to_map ( scalemap, histlist, baselevel, levels, pixels ) unsigned long *scalemap; /* scalemap (for signed indexing) */ SubrangeList *histlist; int baselevel, levels; unsigned long *pixels; /* i: map to hardware entries */ { int i, level; int first, last, imageval; unsigned long dispval; level = baselevel; for( i = 0; i < levels; i++ ) { first = histlist[i].first; last = histlist[i].last; dispval = pixels[level]; for( imageval = first; imageval <= last; imageval++ ) { scalemap[(ushort)imageval] = dispval; /* allan: added ushort cast */ } level++; } } /* * Subroutine: make_gapped_list * Purpose: Allocate levels for a histogram subrange. Special process * for situation when more levels than actually used values. */ static void make_gapped_list ( histogram, list, low, high, levels ) int *histogram; SubrangeList *list; int low, high, levels; { int range_j, max_range; int levels_used; levels_used = first_shortlist_pass(histogram, list, low, high, levels, &max_range, &range_j); while( levels_used < levels ) { add_level_to_short_list(list, levels_used - 1, &max_range, &range_j); ++levels_used; } } /* * Subroutine: first_shortlist_pass * Purpose: Make a list to describe map allocation using special * allocation method. Fill the list with each entry ending * at the next actually used value. */ static int first_shortlist_pass ( histogram, list, low_entry, high_entry, levels, max_range, range_j ) int *histogram; SubrangeList *list; int low_entry, high_entry, levels; int *range_j, *max_range; { int i, area, level; /* initialize parameters (index starts at 0) */ level = 0; area = 0; *max_range = -1; list[level].first = low_entry; /* first pass, assign levels by simple method */ for( i = low_entry; i <= high_entry; i++ ) { area += histogram[(ushort)i]; /* allan: added ushort cast */ /* while levels last, scan till value which is used */ if( (area > 0) || (i == high_entry) ) { list[level].last = i; list[level].pixel_area = area; list[level].shrink_entry = (i - list[level].first) + 1; /* find the lowest entry with the highest range */ if( list[level].shrink_entry > *max_range ) { *max_range = list[level].shrink_entry; *range_j = level; } if( i < high_entry ) { /* start for next group */ list[++level].first = i + 1; #ifdef DEBUG if( level > levels ) { (void)fprintf(stderr, "Actual exceeds levels\n"); level--; } #endif } else if (level >= levels) { list[level - 1].last = i; } area = 0; } } return( level+1 ); } /* * Subroutine: add_level_to_short_list */ static void add_level_to_short_list ( list, top, max_range, range_j ) SubrangeList *list; int top; int *max_range, *range_j; { int i, j, mark; mark = *range_j; *max_range = -1; for( i = top, j = top + 1; j > mark; i--, j-- ) { list[j].first = list[i].first; list[j].last = list[i].last; list[j].pixel_area = list[i].pixel_area; list[j].shrink_entry = list[i].shrink_entry; /* find the lowest entry with the highest range */ if( list[j].shrink_entry >= *max_range ) { *max_range = list[j].shrink_entry; *range_j = j; } } i++; j++; list[i].last = list[i].first + ((list[i].shrink_entry / 2) - 1); list[j].first = list[i].last + 1; list[i].pixel_area = 0; list[i].shrink_entry = (list[i].last - list[i].first) + 1; list[j].shrink_entry = (list[j].last - list[j].first) + 1; for( ; j >= 0; j-- ) { /* find the lowest entry with the highest range */ if( list[j].shrink_entry >= *max_range ) { *max_range = list[j].shrink_entry; *range_j = j; } } } skycat-3.1.2-starlink-1b/rtd/generic/histscan.c000066400000000000000000000114351215713201500213260ustar00rootroot00000000000000#ifndef lint static char SccsId[] = "%W% %G%"; #endif /* Module: histscan.c (Histogram Scan) * Subroutine: scan_histogram_for_peaks() returns: void * Copyright: 1989 Smithsonian Astrophysical Observatory * You may do anything you like with this file except remove * this copyright. The Smithsonian Astrophysical Observatory * makes no representations about the suitability of this * software for any purpose. It is provided "as is" without * express or implied warranty. * Modified: {0} Michael VanHilst initial version 30 May 1989 * {n} -- -- */ #include "histeq.h" static SubrangeLink *get_new_subrange_record(); static void fill_subrange_record(); /* * Subroutine: scan_histogram_for_peaks * Purpose: Scan the image histogram picking out large cell count values * make sub-groups of the histogram between the large count levels */ void scan_histogram_for_peaks ( subrange, histogram, pixel_area, map_levels, average ) SubrangeLink *subrange; /* i/o: link (initially covers range) */ int *histogram; /* i: histogram (for signed index) */ int *pixel_area; /* i/o: number of pixels to account for */ int *map_levels; /* i/o: number of levels left to map */ int *average; /* i/o: average pixels per color map level */ { int i; int scan_end; /* l: end of subrange in histogram */ int scan_start; /* l: histogram entry after last peak */ int pixel_count; /* l: number of pixels at histogram entry */ int sr_nzentries; /* l: number of non-zero entries in subrange */ int sr_pixel_area; /* l: number of pixels in current subrange */ int sr_max_peak; /* l: highest peak within current subrange */ /* set initial pixel_count values */ sr_pixel_area = 0; sr_nzentries = 0; sr_max_peak = 0; scan_start = subrange->low; scan_end = subrange->high; /* run through values in histogram mapping excessive entries */ for( i = scan_start; i <= scan_end; i++ ) { pixel_count = histogram[(ushort)i]; /* allan: added ushort cast */ /* if this pixel value alone is enough for one level, mark it */ if( pixel_count >= *average ) { /* take this count out of equalization distribution */ *pixel_area -= pixel_count; *map_levels -= 1; /* compute new average, (peaks in prior range will be rechecked later */ if( *map_levels > 0 ) *average = (*pixel_area / *map_levels) + 1; /* make a subrange between peaks if there was a valley & get new link */ if( i > scan_start ) { fill_subrange_record(subrange, scan_start, i - 1, i - scan_start, sr_nzentries, sr_pixel_area, sr_max_peak); subrange = get_new_subrange_record(subrange); } /* make a subrange of one for this peak */ fill_subrange_record(subrange, i, i, -1, 1, pixel_count, pixel_count); subrange->color_levels = 1; /* if entries remain, put them in a subrange */ if (i < scan_end) { subrange = get_new_subrange_record(subrange); fill_subrange_record(subrange, i + 1, scan_end, scan_end - i, 0, 0, 0); } /* reset scan values */ sr_pixel_area = 0; sr_nzentries = 0; sr_max_peak = 0; scan_start = i + 1; } else { /* update scan values */ if( pixel_count > 0 ) { sr_pixel_area += pixel_count; ++sr_nzentries; if( pixel_count > sr_max_peak ) sr_max_peak = pixel_count; } } } /* mark the final group */ if( scan_start < scan_end ) { fill_subrange_record(subrange, scan_start, scan_end, (scan_end - scan_start) + 1, sr_nzentries, sr_pixel_area, sr_max_peak); } } /* * Subroutine: get_new_subrange_record * Purpose: Create a new link in histogram link list, after one given * Returns: Pointer to new subrange link */ static SubrangeLink *get_new_subrange_record ( old_link ) SubrangeLink *old_link; { SubrangeLink *new_link; char *calloc_errchk(); /* create new record for histogram link list */ new_link = (SubrangeLink *) calloc_errchk(1, sizeof(SubrangeLink), "histeq link"); new_link->next = old_link->next; old_link->next = new_link; new_link->color_levels = 0; new_link->excess_pixels = 0; return( new_link ); } /* * Subroutine: fill_subrange_record * Purpose: Set parameters in subrange link list record */ static void fill_subrange_record ( link, low, high, range, nz_entries, pixel_area, max_entry ) SubrangeLink *link; int low, high; /* i: first and last index in histogram */ int range; /* i: span of histogram entries */ int nz_entries; /* i: non-zero entries in range */ int pixel_area; /* i: sum of histogram entry values (pixels) */ int max_entry; /* i: highest histogram entry value */ { link->low = low; link->high = high; link->range = range; link->nz_entries = nz_entries; link->pixel_area = pixel_area; link->max_entry = max_entry; } skycat-3.1.2-starlink-1b/rtd/generic/histzero.c000066400000000000000000000064001215713201500213550ustar00rootroot00000000000000#ifndef lint static char SccsId[] = "%W% %G%"; #endif /* Module: histzero.c (Histogram Zero) * Subroutine: resolve_zeroes() returns: void * Copyright: 1989 Smithsonian Astrophysical Observatory * You may do anything you like with this file except remove * this copyright. The Smithsonian Astrophysical Observatory * makes no representations about the suitability of this * software for any purpose. It is provided "as is" without * express or implied warranty. * Modified: {0} Michael VanHilst initial version 30 May 1989 * {n} -- -- */ #include #include #include "histeq.h" /* define SubrangeLink */ static void merge_links(); /* * Subroutine: resolve_zeroes * Purpose: Combine groups with zero alloted levels with adjoining groups * Note: Adjoining groups are large count single level groups * Called by: histrogram_equalize() above */ void resolve_zeroes ( PriorLink, zeroes ) SubrangeLink *PriorLink; int zeroes; { SubrangeLink *ThisLink, *NextLink; int a_count, b_count, z1count, z2count; /* if very first entry is a zero allocated link */ if( PriorLink->color_levels == 0 ) { /* merge this and next */ merge_links(PriorLink); zeroes--; } /* scan for the zero allocated links */ while( zeroes > 0 ) { ThisLink = PriorLink->next; #ifdef DEBUG /* if reached the end of the list, we had an error */ if( ThisLink == 0 ) { (void)fprintf(stderr,"Zero error\n"); return; } #endif /* if we are about to hit a zero */ if( ThisLink->color_levels == 0 ) { /* if it is the last zero merge with prior */ NextLink = ThisLink->next; if( NextLink == 0 ) { merge_links(PriorLink); return; } a_count = PriorLink->pixel_area; b_count = NextLink->pixel_area; /* if the preceding link is smaller than the trailing link */ if( a_count > b_count ) { merge_links(PriorLink); zeroes--; } else { /* probe beyond */ if( NextLink->next != 0 ) { if( NextLink->next->color_levels != 0 ) { /* if new competition, merge with next link */ merge_links(ThisLink); zeroes--; } else { z1count = ThisLink->pixel_area; z2count = NextLink->next->pixel_area; /* where would the next one go? */ if( (NextLink->next->next == 0) || (NextLink->next->next->pixel_area > (b_count + z2count)) ) { if( (b_count + z2count) > (a_count + z1count) ) { merge_links(PriorLink); } else { merge_links(ThisLink); } } else merge_links(ThisLink); zeroes--; } } else { merge_links(PriorLink); zeroes--; } } } PriorLink = ThisLink; } } /* * Subroutine: merge_links * Purpose: Combine two links of histogram group list */ static void merge_links ( subrange ) SubrangeLink *subrange; { SubrangeLink *lostlink; lostlink = subrange->next; subrange->next = lostlink->next; subrange->max_entry = MAX(subrange->max_entry, lostlink->max_entry); subrange->pixel_area += lostlink->pixel_area; subrange->high = lostlink->high; subrange->range += lostlink->range; subrange->nz_entries += lostlink->nz_entries; subrange->excess_pixels += lostlink->excess_pixels; subrange->color_levels += lostlink->color_levels; free( (char *)lostlink ); } skycat-3.1.2-starlink-1b/rtd/generic/indexx.c000066400000000000000000000065011215713201500210070ustar00rootroot00000000000000/* @(#)indexx.c 10.1.1.2 (ES0-DMD) 12/18/95 18:21:10 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COPYRIGHT (c) 1990 European Southern Observatory .IDENT indexx.c .LANGUAGE C .AUTHOR P.Grosbol, IPG/ESO .COMMENT Algorithm taken from 'Numerical Recipes in C' p.248 .KEYWORDS heapsort, index .VERSION 1.0 1990-Dec-14 : Creation, PJG .VERSION 1.1 1995-Mar-10 : Split into float/double functions, PJG ----------------------------------------------------------------------*/ void indexx(n,arrin,indx) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE compute indx[] so that arrin[indx[0..n]] is ascenting .RETURN none ----------------------------------------------------------------------*/ int n; float arrin[]; int indx[]; { int l, j, ir, indxt, i; float q; for (j=0; j> 1; ir = n - 1; while(1) { if (l>0) { indxt = indx[--l]; q = arrin[indxt]; } else { indxt = indx[ir]; q = arrin[indxt]; indx[ir] = indx[0]; if (--ir == 0) { indx[0] = indxt; return; } } i = l; j = (l<<1) + 1; while (j<=ir) { if (j> 1; ir = n - 1; while(1) { if (l>0) { indxt = indx[--l]; q = arrin[indxt]; } else { indxt = indx[ir]; q = arrin[indxt]; indx[ir] = indx[0]; if (--ir == 0) { indx[0] = indxt; return; } } i = l; j = (l<<1) + 1; while (j<=ir) { if (j /* Standard ANSI-C library */ #include /* Mathematical definitions */ #include static double hsq2 = 0.7071067811865475244; /* constant 0.5*sqrt(2) */ #define MA 6 /* No. of variables */ #define MITER 64 /* Max. no. of iterations */ static float *pval; static float *pwght; static int mx, mp, winsize; static double w[9]; static double xi[9]; static double yi[9]; /* */ int iqe(pfm, pwm, mx, my, parm, sdev) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Estimate parameters for the Image Quality using a small frame around the object. The following parameters are estimated and given in the array 'parm': parm[0] = mean X position within array, first pixel = 0 parm[1] = FWHM in X parm[2] = mean Y position within array, first pixel = 0 parm[3] = FWHM in Y parm[4] = angle of major axis, degrees, along X = 0 parm[5] = peak value of object above background parm[6] = mean background level Further, estimates of the standard deviation of the parameters are given in 'sdev'. The routine is just a sequence of calls to 'iqebgv', 'iqemnt', 'iqesec' and 'iqefit'. .RETURN status, 0: OK, <0: estimate failed, ------------------------------------------------------------------------*/ float *pfm; float *pwm; int mx; int my; float *parm; float *sdev; { int n, err, nbg; int iqebgv(), iqemnt(), iqesec(), iqefit(); float bgv, bgs, s2f, r2d; float ap[6], cv[6], est[6], sec[6]; s2f = 2.0*sqrt(2.0*log(2.0)); /* Sigma to FWHM constant */ r2d = 45.0/atan(1.0); /* Radian to Degrees */ for (n=0; n<7; n++) parm[n] = sdev[n] = 0.0; winsize = (mx * my) - 1; /* size of sub window */ if ((err=iqebgv(pfm, pwm, mx, my, &bgv, &bgs, &nbg))) return -1; parm[6] = bgv; sdev[6] = bgs; if ((err=iqemnt(pfm, pwm, mx, my, bgv, bgs, est))) return -2; parm[0] = est[1]; parm[1] = s2f*est[2]; parm[2] = est[3]; parm[3] = s2f*est[4]; parm[5] = est[0]; if ((err=iqesec(pfm, pwm, mx, my, bgv, est, sec))) return -3; parm[4] = r2d*sec[5]; if ((err=iqefit(pfm, pwm, mx, my, bgv, sec, ap, cv))<0) return -4; parm[0] = ap[1]; sdev[0] = cv[1]; parm[1] = s2f*ap[2]; sdev[1] = s2f*cv[2]; parm[2] = ap[3]; sdev[2] = cv[3]; parm[3] = s2f*ap[4]; sdev[3] = s2f*cv[4]; parm[4] = fmod(r2d*ap[5]+180.0, 180.0); sdev[4] = r2d*cv[5]; if (sdev[4] > 180.) sdev[4] = 180.0; /* max is: Pi */ parm[5] = ap[0]; sdev[5] = cv[0]; return 0; } /* */ int iqebgv(pfm, pwm, mx, my, bgm, bgs, nbg) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Estimate background level for subimage .RETURN status, 0: OK, -1:no buffer space, -2: no points left ------------------------------------------------------------------------*/ float *pfm; float *pwm; int mx; int my; float *bgm; float *bgs; int *nbg; { int n, m, ns, ms, nt, mt; float *pfb, *pwb, *pf, *pw; float *pf0, *pf1, *pf2, *pf3, *pfs0, *pfs1, *pfs2, *pfs3; float *pw0, *pw1, *pw2, *pw3, *pws0, *pws1, *pws2, *pws3; double val, fks, ba, bm, bs; void hsort(); *bgm = 0.0; *bgs = 0.0; *nbg = 0; pfs0 = pfm; pfs1 = pfm + mx - 1; pfs2 = pfm + mx*(my-1); pfs3 = pfm + mx*my - 1; if (pwm) { pws0 = pwm; pws1 = pwm + mx - 1; pws2 = pwm + mx*(my-1); pws3 = pwm + mx*my - 1; } ns = (mx winsize)) return -99; if (pwm) pw = pwm + ioff; if ((!pwm) || (pwm && 0.0<*pw)) { val = *pf - bgv; am = val; ax = val*x; ay = val*y; axx = val*x*x; ayy = val*y*y; axy = val*x*y; nt++; } else am = ax = ay = axx = ayy = axy = 0.0; ki = ks = kn = 1; while (n--) { k = kn; if (!ki && ks==-1) { if (nx) nx = 0; else break; } ioff = (ki) ? ks : ks*mx; while (k--) { if (ki) x += ks; else y += ks; if (x<0.0 || y<0.0 || xm winsize)) break; if (pwm) pw += ioff; val = *pf - bgv; if ( (dv winsize)) break; dx = x - xc; dy = y - yc; r = sqrt(dx*dx + dy*dy); if (rl winsize)) return -99; pf = pfb; pw = pwb; iy = ny; if (pwm) { pwm += nxs + mx*nys; while (iy--) { ix = nx; while (ix--) { *pf++ = *pfm++ - bgv; psize = pfm - pfmo; if (psize > winsize) return -99; if (0.0<*pwm) *pw++ = *pwm++; else *pw++ = 1.0; } pfm += mx - nx; psize = pfm - pfmo; if ((psize < 0) || (psize > winsize)) return -99; pwm += mx - nx; } } else { while (iy--) { ix = nx; while (ix--) { *pf++ = *pfm++ - bgv; psize = pfm - pfmo; if (psize > winsize) return -99; *pw++ = 1.0; } pfm += mx - nx; psize = pfm - pfmo; if ((psize < 0) || (psize > winsize)) return -99; } } /* initialize parameters for fitting */ ap[0] = est[0]; ap[1] = est[1] - nxs; ap[2] = est[2]; ap[3] = est[3] - nys; ap[4] = est[4]; ap[5] = est[5]; /* perform actual 2D Gauss fit on small subimage */ n = g2efit(pfb, pwb, nx, ny, ap, cm, &chi); /* normalize parameters and uncertainties, and exit */ ap[1] += nxs; ap[3] += nys; free(pfb); return n; } /* */ int g2einit(val, wght, nx, ny) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Initiate gauss fit function, set pointers to data and weights .RETURN status, 0: OK, -1: error - bad pixel no. ------------------------------------------------------------------------*/ float *val; float *wght; int nx; int ny; { double fh, w1, w2, w3; if (nx<1) { /* if NO x-pixel set to NULL */ pval = (float *) 0; pwght = (float *) 0; mx = mp = 0; return -1; } pval = val; /* otherwise initiate static varables */ pwght = wght; mx = nx; mp = (0 a[ir][ic] = a[ir+ic*n] .KEYWORDS Nonlinear Model fit .VERSION 1.0 1994-May-23 : Creation, PJG .VERSION 1.1 1995-Apr-29 : Correct problem when mfit!=ma, PJG ------------------------------------------------------------------------*/ #define MMA 16 /* Max. no. of variables */ static float atry[MMA]; static double da[MMA]; static double oneda[MMA]; static double beta[MMA]; static double cv[MMA*MMA]; static double ochisq; mrqmin(ndata,a,ma,lista,mfit,covar,alpha,chisq,funcs,alamda) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE .RETURN status, 0: OK, -1: Bad permutation LISTA 1, -2: Bad permutation LISTA 2, -3: too many variables, -4: No points (chisq<=0), -5: error in matrix inversion ------------------------------------------------------------------------*/ int ndata; float a[]; int ma; int lista[]; int mfit; double *covar; double *alpha; double *chisq; int (*funcs)(); double *alamda; { int k, kk, j, ihit; int mrqcof(), gaussj(), covsrt(); if (*alamda < 0.0) { if (MMA 1) return -1; } if (kk != ma) return -2; *alamda = 0.001; mrqcof(ndata, a, ma, lista, mfit, alpha, beta, chisq, funcs); if (*chisq<=0.0) return -4; ochisq = (*chisq); } for (j=0; j #include void defineRtdBitmaps(Tcl_Interp *interp) { #include "double_left.xbm" Tk_DefineBitmap(interp, Tk_GetUid("double_left"), (char*)double_left_bits, double_left_width, double_left_height); #include "record.xbm" Tk_DefineBitmap(interp, Tk_GetUid("record"), (char*)record_bits, record_width, record_height); #include "big_right.xbm" Tk_DefineBitmap(interp, Tk_GetUid("big_right"), (char*)big_right_bits, big_right_width, big_right_height); #include "Right.xbm" Tk_DefineBitmap(interp, Tk_GetUid("Right"), (char*)Right_bits, Right_width, Right_height); #include "rect.xbm" Tk_DefineBitmap(interp, Tk_GetUid("rect"), (char*)rect_bits, rect_width, rect_height); #include "double_right.xbm" Tk_DefineBitmap(interp, Tk_GetUid("double_right"), (char*)double_right_bits, double_right_width, double_right_height); } skycat-3.1.2-starlink-1b/rtd/generic/rtd_remote.c000066400000000000000000000252731215713201500216630ustar00rootroot00000000000000/* * E.S.O. - VLT project * "@(#) $Id: rtd_remote.c,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * rtdRemote.c - client library for remote control of an RtdImage * widget, communicates over a socket with a remote * rtdimage widget. See rtdimage/src/RtdRemote.C * for the server side. * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/03/96 Created * Peter W. Draper 09/02/98 Removed sys_errlist and replaced with strerror. * pbiereic 07/04/04 Fixed: variable argument list * Allan Brighton 02/01/06 Renamed rtdRemote.c to rtd_remote.c to avoid * name conflict on file systems that ignore case */ static const char* const rcsId="@(#) $Id: rtd_remote.c,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "rtd_remote.h" /* -- private interface -- */ /* local struct allocated to manage the client's connection */ typedef struct { int socket; /* socket connection with display */ int pid; /* pid of display on host */ char host[64]; /* hostname where dsplay is running */ int port; /* port number to use on host */ char errmsg[10240]; /* copy of last error message */ /* optional error handler, to be called with error message */ RtdRemoteErrorHandler errhandler; } rtdRemote; /* note: compiler initializes static data to all 0's, K&R */ static rtdRemote info; /* this struct holds local info */ /* -- local error routines -- */ /* * Report the error, syntax like printf. * The error message is kept in a local buffer and can be retrieved * with rtdRemoteGetError(). */ static int error(const char *fmt, ...) { va_list args; char buf[sizeof(info.errmsg)]; va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); strcpy(info.errmsg, buf); if (info.errhandler) (*info.errhandler)(buf); return 1; } /* * report the error, including system error code */ static int sys_error(const char *fmt, ...) { va_list args; char buf[sizeof(info.errmsg)]; #ifndef errno extern int errno; #endif va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); strcat(buf, ": "); strcat(buf, strerror(errno)); strcpy(info.errmsg, buf); if (info.errhandler) (*info.errhandler)(buf); return 1; } /* -- I/O routines for network I/O taken from the book -- * "UNIX Network Programming" by W. Richard Stevens, */ /* * Read "n" bytes from a descriptor. * Use in place of read() when fd is a stream socket. */ static int readn(int fd, char* ptr, int nbytes) { int nleft, nread; nleft = nbytes; while (nleft > 0) { nread = read(fd, ptr, nleft); if (nread < 0) return(nread); /* error, return < 0 */ else if (nread == 0) break; /* EOF */ nleft -= nread; ptr += nread; } return(nbytes - nleft); /* return >= 0 */ } /* * Write "n" bytes to a descriptor. * Use in place of write() when fd is a stream socket. */ static int writen(int fd, char* ptr, unsigned long nbytes) { int nleft, nwritten; nleft = nbytes; while (nleft > 0) { nwritten = write(fd, ptr, nleft); if (nwritten <= 0) return(nwritten); /* error */ nleft -= nwritten; ptr += nwritten; } return(nbytes - nleft); } /* * Read the line one byte at a time, looking for the newline. We store * the newline in the buffer, then follow it with a null (the same as * fgets(3)). Not very efficient but usefull for sockets. * * Returns the number of characters up to, but not including, the null * (the same as strlen(3)) or < 0 upon errors. */ static int readline(int fd, char* ptr, int maxlen) { int n, rc; char c; for (n = 1; n < maxlen; n++) { if ( (rc = read(fd, &c, 1)) == 1) { *ptr++ = c; if (c == '\n') break; } else if (rc == 0) { if (n == 1) return(0); /* EOF, no data read */ else break; /* EOF, some data was read */ } else return(-1); /* error */ } *ptr = 0; return(n); } /* * write the given buffer to the given file followed by a newline */ static int writeline(int fd, char* ptr) { return writen(fd, ptr, strlen(ptr)) + writen(fd, "\n", 1); } /* -- other routines -- */ /* * read the ~/.rtd-remote file to get the pid, hostname and port number * of the RTD, if it is running (check that it is running...) */ static int getRtdInfo() { char filename[1024]; char* home = getenv("HOME"); FILE* f; char hostname[64]; sprintf(filename, "%s/.rtd-remote", (home ? home : "/tmp")); f = fopen(filename, "r"); if (!f) return error("can't open status file: %s, is the display application running?", filename); if (fscanf(f, "%u %s %u", &info.pid, info.host, &info.port) != 3) return error("error in Rtd status file: %s", filename); fclose(f); if (kill(info.pid, 0) != 0 || (gethostname(hostname, sizeof(hostname)) == 0 && strcmp(hostname, info.host) != 0)) return error("display application may not be running on this host?"); return 0; } /* -- public interface -- */ /* * write the command to the rtdimage socket and return 0 if all is * OK, otherwise 1. "cmd" should not contain a newline, it will be * added here. */ int rtdRemoteSendOnly(char* cmd) { if (writeline(info.socket, cmd) <= 0) return sys_error("error sending command to RTD"); return 0; } /* * open a connection to a currently running Rtd Display. The pid, hostname * and port number, if not specified (set to 0) are read from the file * $HOME/.rtd-remote, which is created by the Rtd on startup * (see rtdimage/src/RtdRemote.C). * * The return value is 0 for success, 1 for error. The error text * can be retrieved with rtdRemoteGetError(). */ int rtdRemoteConnect(int pid, char* host, int port) { struct hostent *hp; /* pointer to host info */ struct sockaddr_in addr; /* for peer socket address */ if (pid && host && port) { info.pid = pid; strncpy(info.host, host, sizeof(info.host)); info.port = port; } else if (getRtdInfo() != 0) /* get pid, hostname, port from ~/.rtd-remote file */ return 1; /* clear out address */ memset ((char *)&addr, 0, sizeof(struct sockaddr_in)); /* Set up the peer address to which we will connect. */ addr.sin_family = AF_INET; /* Get the host information for the rtd display */ hp = gethostbyname (info.host); if (hp == NULL) return sys_error("gethostbyname"); addr.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr; addr.sin_port = htons(info.port); /* Create the socket. */ info.socket = socket(AF_INET, SOCK_STREAM, 0); if (info.socket == -1) return sys_error("socket"); /* Try to connect to the remote Rtd display */ if (connect(info.socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) == -1) return sys_error("connect"); return 0; } /* * disconnect from the Rtd display */ void rtdRemoteDisconnect() { if (info.socket != -1) { close(info.socket); info.socket = -1; } } /* * set a routine to be called with the text of error messages * when they occur. The argument is a pointer to an error * handler: * * void errhandler(char* msg); * * The return value is a pointer to the previous error handler, or NULL, * if none was defined. */ RtdRemoteErrorHandler rtdRemoteSetErrorHandler(RtdRemoteErrorHandler errhandler) { RtdRemoteErrorHandler old_handler = info.errhandler; info.errhandler = errhandler; return old_handler; } /* * Return the text of the most recent error message. * */ char* rtdRemoteGetError() { return info.errmsg; } /* * read the socket with the answer from the last command sent to the * remote RtdImage display and return the command's status. The command's * result is returned in the "result" argument, which points to local or * static storage. * * The format of the message read from the socket is: * * status length\n * msg[length] * * where status is 0 (OK) or 1 and length is the length of the result that follows. */ int rtdRemoteGetResult(int sock, char** result) { static char buf[1024]; /* use to hold results up to 1024 bytes */ static char* rbuf = buf; /* may be allocated with malloc if needed */ static int rbufsize = sizeof(buf) - 1; int status; /* return status of command */ int length; /* length of result */ if (result) *result = rbuf; buf[0] = '\0'; /* default to empty result */ if (readline(sock, buf, sizeof(buf)) <= 0) return sys_error("error reading result status from rtdimage"); if (sscanf(buf, "%d %d", &status, &length) != 2) return error("unknown result from rtdimage"); if (length == 0) return status; /* empty result */ if (length < 0) return error("bad length received from display application"); if (length >= rbufsize) { /* use static storage or malloc ? */ if (rbufsize != sizeof(buf)) free(rbuf); rbuf = (char*)malloc(rbufsize=length+10); if (!rbuf) { rbuf = buf; rbufsize = sizeof(buf); return error("rtdRemote: could not allocate %d bytes for result", length); } if (result) *result = rbuf; } if (readn(sock, rbuf, length) != length) return sys_error("error reading result from rtdimage"); rbuf[length] = '\0'; return status; } /* * Evaluate the given rtdimage subcommand in the remote rtd application * and return the status of the command. * * The command syntax is the same as for the * "rtdimage" widget (image type), except that the instance name is * missing. Example: * * char* result; * int status = rtdRemoteCmd("wcscenter", &result); * if (status == 0) { * if (sscanf(result, ...) ...) {...} * ... * } * * On success, "result" points to a char buffer containing the result of * the command. The buffer is internal and should not be freed and will * be overwritten in the next call to this routine. * * If the command could not be sent, result is set to a NULL pointer and * an error status (1) is returned. The error message can be retrieved * with rtdRemoteGetError(). */ int rtdRemoteSend(char* cmd, char** result) { if (info.socket == -1) return error("no connection to the image display: rtdRemoteConnect was not called"); if (rtdRemoteSendOnly(cmd) != 0) return 1; return rtdRemoteGetResult(info.socket, result); } skycat-3.1.2-starlink-1b/rtd/generic/rtd_remote.h000066400000000000000000000025471215713201500216670ustar00rootroot00000000000000#ifndef _rtdRemote_h_ #define _rtdRemote_h_ /* * E.S.O. - VLT project * "@(#) $Id: rtd_remote.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * rtd_remote.h - C interface for remote access to rtdimage based * widgets * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 04/03/96 Created * 02/01/06 Renamed rtdRemote.h to rtd_remote.h to avoid * name conflict on file systems that ignore case */ typedef void (*RtdRemoteErrorHandler)(char* message); /* connect to remote Rtd: if args are null, uses ~/.rtd-remote file */ int rtdRemoteConnect(int pid, char* host, int port); /* disconnect from remote Rtd */ void rtdRemoteDisconnect(); /* read the given socket to get the result */ int rtdRemoteGetResult(int socket, char** result); /* send the command to the remote Rtd (don't get result) */ int rtdRemoteSendOnly(char* cmd); /* send a command to the remote Rtd and get the result */ int rtdRemoteSend(char* cmd, char** result); /* set an error handler to be called as: void errorhandler(char* msg); */ RtdRemoteErrorHandler rtdRemoteSetErrorHandler(RtdRemoteErrorHandler); /* return the text of the last error message */ char* rtdRemoteGetError(); #endif /* _rtdRemote_h_ */ skycat-3.1.2-starlink-1b/rtd/generic/saoutil.c000066400000000000000000000015071215713201500211710ustar00rootroot00000000000000/* * This file contains utility functions from saoimage (1.23.2) required for * the histeq code */ #include #include #include static char *errnote = " allocation failure\n"; /* * Subroutine: calloc_errchk * Purpose: Calloc with printf'less error message and exit for failure * Note: If message is given, print it and exit on failure * Note: If no message is given, return 0 on failure */ char *calloc_errchk ( count, size, errmess ) int count; unsigned int size; char *errmess; { char *space; /* char *calloc(); allan: gets error with Sun cc */ if( (space = (char *)calloc((unsigned)count, size)) == NULL ) { if( errmess == NULL ) return(0); else { fputs (errmess, stderr); fputs (errnote, stderr); exit( 100 ); } } return( space ); } skycat-3.1.2-starlink-1b/rtd/generic/sort.c000066400000000000000000000046401215713201500205010ustar00rootroot00000000000000/* @(#)sort.c 10.1.1.2 (ES0-DMD) 12/18/95 18:21:12 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COPYRIGHT (c) 1995 European Soutern Observatory .IDENT hsort.c .LANGUAGE C .AUTHOR P.Grosbol, IPG/ESO .ENVIRON UNIX .KEYWORDS sort, heapsort .COMMENT Algorithm is adapted from 'Numerical Recipes in C' p.247 .VERSION 1.0 1995-Mar-09 : Creation, PJG -----------------------------------------------------------------------*/ void hsort(n, ra) /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE sort array in place using heapsort .RETURN none -----------------------------------------------------------------------*/ int n; /* no. of elements in array */ float *ra; /* pointer to array to be sorted */ { int l, j, ir, i; float rra; l = n >> 1; ir = n - 1; while (1) { if (l>0) rra = ra[--l]; else { rra = ra[ir]; ra[ir] = ra[0]; if (--ir == 0) { ra[0] = rra; return; } } i = l; j = (l << 1) + 1; while (j<=ir) { if (j0, defines a grid for horizontal * scrolling. This is the size of the "unit", * and the left edge of the screen will always * lie on an even unit boundary. */ int yScrollIncrement; /* If >0, defines a grid for horizontal * scrolling. This is the size of the "unit", * and the left edge of the screen will always * lie on an even unit boundary. */ /* * Information used for scanning: */ int scanX; /* X-position at which scan started (e.g. * button was pressed here). */ int scanXOrigin; /* Value of xOrigin field when scan started. */ int scanY; /* Y-position at which scan started (e.g. * button was pressed here). */ int scanYOrigin; /* Value of yOrigin field when scan started. */ /* * Information used to speed up searches by remembering the last item * created or found with an item id search. */ Tk_Item *hotPtr; /* Pointer to "hot" item (one that's been * recently used. NULL means there's no hot * item. */ Tk_Item *hotPrevPtr; /* Pointer to predecessor to hotPtr (NULL * means item is first in list). This is only * a hint and may not really be hotPtr's * predecessor. */ /* * Miscellaneous information: */ Tk_Cursor cursor; /* Current cursor for window, or None. */ char *takeFocus; /* Value of -takefocus option; not used in the * C code, but used by keyboard traversal * scripts. Malloc'ed, but may be NULL. */ double pixelsPerMM; /* Scale factor between MM and pixels; used * when converting coordinates. */ int flags; /* Various flags; see below for * definitions. */ int nextId; /* Number to use as id for next item created * in widget. */ Tk_PostscriptInfo psInfo; /* Pointer to information used for generating * Postscript for the canvas. NULL means no * Postscript is currently being generated. */ Tcl_HashTable idTable; /* Table of integer indices. */ /* * Additional information, added by the 'dash'-patch */ void *reserved1; Tk_State canvas_state; /* State of canvas. */ void *reserved2; void *reserved3; Tk_TSOffset tsoffset; #ifndef USE_OLD_TAG_SEARCH TagSearchExpr *bindTagExprs;/* Linked list of tag expressions used in * bindings. */ #endif } TkCanvas; /* * Flag bits for canvases: * * REDRAW_PENDING - 1 means a DoWhenIdle handler has already been * created to redraw some or all of the canvas. * REDRAW_BORDERS - 1 means that the borders need to be redrawn * during the next redisplay operation. * REPICK_NEEDED - 1 means DisplayCanvas should pick a new * current item before redrawing the canvas. * GOT_FOCUS - 1 means the focus is currently in this widget, * so should draw the insertion cursor and * traversal highlight. * CURSOR_ON - 1 means the insertion cursor is in the "on" * phase of its blink cycle. 0 means either we * don't have the focus or the cursor is in the * "off" phase of its cycle. * UPDATE_SCROLLBARS - 1 means the scrollbars should get updated as * part of the next display operation. * LEFT_GRABBED_ITEM - 1 means that the mouse left the current item * while a grab was in effect, so we didn't * change canvasPtr->currentItemPtr. * REPICK_IN_PROGRESS - 1 means PickCurrentItem is currently * executing. If it should be called recursively, * it should simply return immediately. * BBOX_NOT_EMPTY - 1 means that the bounding box of the area that * should be redrawn is not empty. */ #define REDRAW_PENDING 1 #define REDRAW_BORDERS 2 #define REPICK_NEEDED 4 #define GOT_FOCUS 8 #define CURSOR_ON 0x10 #define UPDATE_SCROLLBARS 0x20 #define LEFT_GRABBED_ITEM 0x40 #define REPICK_IN_PROGRESS 0x100 #define BBOX_NOT_EMPTY 0x200 /* * Flag bits for canvas items (redraw_flags): * * FORCE_REDRAW - 1 means that the new coordinates of some item * are not yet registered using * Tk_CanvasEventuallyRedraw(). It should still * be done by the general canvas code. */ #define FORCE_REDRAW 8 /* * Canvas-related functions that are shared among Tk modules but not exported * to the outside world: */ MODULE_SCOPE int TkCanvPostscriptCmd(TkCanvas *canvasPtr, Tcl_Interp *interp, int argc, CONST char **argv); MODULE_SCOPE int TkCanvTranslatePath(TkCanvas *canvPtr, int numVertex, double *coordPtr, int closed, XPoint *outPtr); /* * Standard item types provided by Tk: */ #endif /* _TKCANVAS */ skycat-3.1.2-starlink-1b/rtd/generic/tkCanvasPsImage.c000066400000000000000000000201771215713201500225350ustar00rootroot00000000000000/* * E.S.O. - VLT project / ESO Archive * * "@(#) $Id: tkCanvasPsImage.c,v 1.2 2005/02/02 01:43:02 brighton Exp $" * * TkCanvasPsImage.C - Implement Tk postscript output for images * * The code here was taken from a version of the Tk canvasps patch, which * was modified by Peter Draper of Starlink to only access the visible * portion of an image (required, to avoid problems with large or zoomed * in images). * * To avoid having to patch the Tk sources, I gathered all the necessary * code in this file, including some private struct typedefs from the Tk * source files, which are not available in any include files. * * NOTE: This code is Tk4.2 specific. If you upgrade to a newer version, * you will have to redo it, based on the latest Tk sources and/or Tk * canvasps patch. * * PWD (again): Redone for tk8.4 as the default printing (at least there is * some now) includes the empty padding once more. Using a new image * postscript proc will not work as there isn't enough information passed in * to determine the canvas viewport. * * To enable this extension, call TkCanvasPsImage_Init(). * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 19/06/98 Created * Peter W. Draper 05/05/06 Added support for tk8.4 as zoomed images * generate massive postscript files full of * padding around the rtdimage. */ #include #ifdef HAVE_TKCANVAS_H #include "tclInt.h" #include "tkCanvas.h" #else // The structure we need hasn't changed for a long time, so just include a local copy. #include "tkCanvas.h-tk8.4.11" #define HAVE_TKCANVAS_H #endif /* Local prototypes */ static int RtdImageToPostscript( Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, int prepass ); /* Private function we add to Tk. */ Tk_ItemType *getTkImageType(); /* * -------------------------------------------------------------- * * TkCanvasPsImage_Init -- * * This procedure is called to initialize the canvas image * postscript extension by setting a field in the canvas * image type control struct, causing our postscript routine * to be called for canvas images. * * Results: * None. * * Side effects: * None. * * -------------------------------------------------------------- */ void TkCanvasPsImage_Init() { /* Need to access the Tk Image type and supercede the Postscript * command. */ Tk_ItemType *tkImageType = getTkImageType(); tkImageType->postscriptProc = RtdImageToPostscript; } /* * Note we do it this way, rather than by defining an image postscript proc, * as we do not have the necessary handles to canvases etc. passed to a * postscript proc. */ /* * The structure below defines the record for each image item (lifted from * tkCanvImg.c). */ typedef struct ImageItem { Tk_Item header; /* Generic stuff that's the same for all * types. MUST BE FIRST IN STRUCTURE. */ Tk_Canvas canvas; /* Canvas containing the image. */ double x, y; /* Coordinates of positioning point for * image. */ Tk_Anchor anchor; /* Where to anchor image relative to * (x,y). */ char *imageString; /* String describing -image option (malloc-ed). * NULL means no image right now. */ char *activeImageString; /* String describing -activeimage option. * NULL means no image right now. */ char *disabledImageString; /* String describing -disabledimage option. * NULL means no image right now. */ Tk_Image image; /* Image to display in window, or NULL if * no image at present. */ Tk_Image activeImage; /* Image to display in window, or NULL if * no image at present. */ Tk_Image disabledImage; /* Image to display in window, or NULL if * no image at present. */ } ImageItem; /* *-------------------------------------------------------------- * * RtdImageToPostscript -- * * This procedure is called to generate Postscript for * image items. * * Results: * The return value is a standard Tcl result. If an error * occurs in generating Postscript then an error message is * left in interp->result, replacing whatever used to be there. * If no error occurs, then Postscript for the item is appended * to the result. * * Side effects: * None. * *-------------------------------------------------------------- */ static int RtdImageToPostscript(interp, canvas, itemPtr, prepass) Tcl_Interp *interp; /* Leave Postscript or error message * here. */ Tk_Canvas canvas; /* Information about overall canvas. */ Tk_Item *itemPtr; /* Item for which Postscript is * wanted. */ int prepass; /* 1 means this is a prepass to * collect font information; 0 means * final Postscript is being created.*/ { ImageItem *imgPtr = (ImageItem *)itemPtr; Tk_Window canvasWin = Tk_CanvasTkwin(canvas); char buffer[256]; double x, y; int width, height; Tk_Image image; Tk_State state = itemPtr->state; int screenX1, screenY1, screenX2, screenY2; TkCanvas *canvasPtr = (TkCanvas *) canvas; if (state == TK_STATE_NULL) { state = ((TkCanvas *)canvas)->canvas_state; } image = imgPtr->image; if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { if (imgPtr->activeImage != NULL) { image = imgPtr->activeImage; } } else if (state == TK_STATE_DISABLED) { if (imgPtr->disabledImage != NULL) { image = imgPtr->disabledImage; } } if (image == NULL) { /* * Image item without actual image specified. */ return TCL_OK; } Tk_SizeOfImage(image, &width, &height); /* Determine region of image that needs to be drawn. For rtdimages only * the part visible on the display screen is done. */ screenX1 = canvasPtr->xOrigin + canvasPtr->inset; screenY1 = canvasPtr->yOrigin + canvasPtr->inset; screenX2 = canvasPtr->xOrigin + Tk_Width(canvasWin) - canvasPtr->inset; screenY2 = canvasPtr->yOrigin + Tk_Height(canvasWin) - canvasPtr->inset; if ( width > screenX2 - screenX1 ) { width = screenX2 - screenX1; } else { screenX1 = 0; } if ( height > screenY2 - screenY1 ) { height = screenY2 - screenY1; } else { screenY1 = 0; } /* * Compute the coordinates of the lower-left corner of the image, * taking into account the anchor position for the image. */ x = imgPtr->x; y = Tk_CanvasPsY(canvas, imgPtr->y); switch (imgPtr->anchor) { case TK_ANCHOR_NW: y -= height; break; case TK_ANCHOR_N: x -= width/2.0; y -= height; break; case TK_ANCHOR_NE: x -= width; y -= height; break; case TK_ANCHOR_E: x -= width; y -= height/2.0; break; case TK_ANCHOR_SE: x -= width; break; case TK_ANCHOR_S: x -= width/2.0; break; case TK_ANCHOR_SW: break; case TK_ANCHOR_W: y -= height/2.0; break; case TK_ANCHOR_CENTER: x -= width/2.0; y -= height/2.0; break; } if (!prepass) { sprintf(buffer, "%.15g %.15g", x, y); Tcl_AppendResult(interp, buffer, " translate\n", (char *) NULL); } return Tk_PostscriptImage(image, interp, canvasWin, ((TkCanvas *) canvas)->psInfo, screenX1, screenY1, width, height, prepass); } skycat-3.1.2-starlink-1b/rtd/images/000077500000000000000000000000001215713201500171735ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/rtd/images/img_ext.fits000066400000000000000000000757001215713201500215270ustar00rootroot00000000000000SIMPLE = T / Standard FITS format (NOST-100.0) BITPIX = 16 / # of bits storing pix values NAXIS = 2 / # of axes in frame NAXIS1 = 100 / # pixels/axis NAXIS2 = 100 / # pixels/axis ORIGIN = 'ESO ' / European Southern Observatory DATE = '1999-06-07T15:23:07.508' / UT date when this file was written CRVAL1 = 1.0 / value of ref pixel CRPIX1 = 1.0 / Ref. pixel of center of rotation CDELT1 = 1.0 / Binning factor CTYPE1 = 'PIXEL ' / Pixel coordinate system CRVAL2 = 1.0 / value of ref pixel CRPIX2 = 1.0 / Ref. pixel of center of rotation CDELT2 = 1.0 / Binning factor CTYPE2 = 'PIXEL ' / Pixel coordinate system BSCALE = 1.0 / pixel=FITS*BSCALE+BZERO BZERO = 0.0 / pixel=FITS*BSCALE+BZERO MJD-OBS = 51336.64107118 / MJD start (1999-06-07T15:23:08.550) DATE-OBS= '1999-06-07T17:23:08.550' / Date of observation EXPTIME = 2.0000 / Total integration time EXTEND = T / Extension may be present END ­ÊÖ¾¿™ÌæÇзæÌÈ ûôûÁ÷™êáôçÍÂð׺ÏâÈÜÆÚÞªÍç¦ãòÇÚ±öÎÌÊÊÑØÃ½¿ØÒÙÖÆÂǶÝç½¶ïÒÈðšÝ½Êá»Î¹Âàò⬪œÝ¢ÆžŸmegupqniqqr}xz{xrxyuw{vspspnwvtuovoptuuvvtrquwp‡sroyysuuoutqqsw|tvwxuovv{}yrwum}xxqqvusuuzyxvsztyijowt{|}}wty{|‚}{zwzvwƒ|zxvw{{}ruzzw~}wutuvy}z€}xxwuz€w†v{ƒxxzz~txs|vt†x}v~x€‚{€ysyxz‚~‚zxrpunrnuyv…€}€z|€†‚|}}~|‚|„€yqt{x„v{rww}…}z|zzs‚…ƒ}x|}tx{‚€{z}{|€„x{}€€z}‚|zrz€ƒƒ‚vv{}€}€€utuzzwu}z„|…ˆ{„€…ƒ‚‚{{~zy€€}}zu|~|z}ƒ}x}u}€€w{‚ƒ€ƒx~|{z‰}†z||~‚|}€w‚€x~}‚}yt~…z|ƒwƒ†}}rorw||~wv~€‚‚~{€z€ˆ~†…}z{|y„~xt{}sy€„ƒy~zzy{z‡}x{w~}„‚~zz}…€ƒ€{}|‚€‡„~{|||‚€~€xx€‚{€}|unnsw}z€|z€…„‚~„~y}…„…€}|{}‚|x€y€{zƒ~xzvz„ƒˆz|yxx}ˆ„y|w|€…€}‚}x|{‚ˆ€€x~y~ƒ„vz{}}€ˆ{zrxvuxvxz€„…|{„†‡€„„|€€|{|ƒ„€z}zszy~…y~y€yy~…z}…v‚‚ƒƒ|~w|ˆ‚…„}y{{}ƒ~|z~t†ƒ‚~~y}{†‚€x{~„~rxuyw{uxxy€ƒˆ‡€}€~‚ƒƒ†‚y~t‚yz}„wwwƒy†{{}zwx~„ƒ€ƒ}{~z‚†‚„|z‰~‰|zy}|~€‚wy}~€†~|‚z€}‡vz†{{}mqtox{~{zx{‚}……ƒxƒ{ƒz€t{|~~ƒx€|v|‚}|z|z{y‚„€z|z}yx}…}|€{~z€~}}~€~€ƒ|…w‚~|€„~}}|€}}}‹~ƒw}€wprsqw|y{„…€u}‚ƒ†ˆ‚‚}x}~}€yzuxz„‡|vzwyxƒƒv|ƒ{}yzƒƒ€z|€„}…‚‡y}€wz†|~€xw€‡~‚}zvƒ‚†}z||…‡…vttytvtt}ƒ„…€†‚}€ƒ†ƒy{€z}~{v|}{{z}‚€}{y~|€ƒ„ƒxy|„€~|}€||€ƒ„y}zwz‚~‚|€y€y|…‚zs|€w€…€}w}z}ƒ„nptx}|yzz~€……‚ƒ~|‚zˆ|zz{|ƒ{zyz~}|}~~ywy€…ƒ}|x{ƒz||x|‚ƒ‚y~w~|{~„yy}‚†~}~{zz‚|‰„†{€y€‚ouvwtx}„u|~€ƒ‡‚…‚{~}~ƒyw{{~„|z||uw}ƒz~z~„{zy{ˆ€~z|yxy‚y‚}y}x~~~‡‚ƒx{|}|ƒ†ƒ|y|z|{}}|‚€‚~|}€vqyqpv|zy‰€~{‚ƒ‡‰€‡{w~{|}‚„€zxy}†{uuu{‚‚‡†}yw‚{€‡{{|ƒ‹ƒ„|u{z…|z‚„„x~‚y~z…‚…|{†~…‚wps{|xwvy}ƒ‚…„‚y€{}†‚}ƒy€u}„€~vyzx…{…zx‚y|€„z…{w‰€}€ƒ}w€~|…‚{}|}{zz‚v~}u|}‚‚x||‚vz„‚~~€~€‚mptxx{~w|}~€€†Š†€‚||€Œ†z{v‚z~€…ƒwv}v‚}€~||w†~|…€„{v~€„‡y{x€|‚~€x}}{{~…†z}|…}„{}x…€…€}y{uvswqtpv€}{€‚|ƒ‘„€…{|ƒ}…€‚€wz‚v€~xss{|}{~}€€{}€|{}y~w}~}y†}}†ƒ{y{†z‡„wwz~„~}xzxz„€…„|{wwwtzww}ˆ„y~€‚€‹„|xƒ~z€zxv|w~€yy|}w|€€€|x|~~…|wxyu|„ƒ||y…~~{‚}vtz|„‹‚yzy€ˆ†ˆz‚}xzyƒ†qtos~wwx{€…‚y‚}Š‚~zv{|‚€{zy~xv|†|{yz€}z{z~€„}}w…‹ƒww€„‡„|vyy}}€‡}ƒy|z„‰z~}„qmkqzw~{|}{ƒ†€{ˆ‚{|…|‡€v}‚}z~{‚z{v}x~{}…{{||‡~v‚~Š€~}v€€€‚w}}|ƒƒ…{~}…|†„‡}ƒvz~|‚ƒ…z}wq{qwsƒ‹€|‚…~~‚‰ˆ€~~y€{…|x}{zx}}{v|‚}}‚zyy‚‡…~‡€z{{„}€€€{|wu}ƒ‹„zv|yz{‚‚y}~~}}‡„{{xz‚{{xwx}wvzwz|‡†‡€€v„‚~†„|€}v~{€‰€|†yz}~€|€y||{y}{u|€}‡‚}|}zz|}€„}v~|v“}|ƒ|~}}‚yy{}‚~~Š{s|}ˆ~rvrv~yt{~€~}ƒ…}€{y€„ƒ„y|y€‚}ƒvwuz~ƒ€ƒy†wwz‚~~€{…|€ˆ}w{‚{…„ƒ†z„z}{ƒz{yƒˆ~~}‚wƒy~†„~y€smntxx~‚‚€†}„…†ˆ‰ƒzv{~{zy|wv€y|{…{{~€}}|zyy|ƒ~z}}}€†„zz}~€ƒ‚}wz}…€€~yzzƒ„}}z}{x†ƒƒ|u}txyuvz|~‡‚„ƒ{ƒ‚ƒ…‚„}}y|…ƒ{y|xwz‚~zyy|{y~Š~zu||}{ƒxy€|…€~ƒ}||ƒ€ƒ~zxy~~„ƒy{y„~{„„‡{‚€|~z„~wqxw|yw{v~~…„†~€†{~zz}w{yxxyvy}‡€|z~|{ƒ„€uzy‚€€~€|~€„{|~y€{€€}€zy}{„}~yyy‡„ƒ}wy|ƒzorlt{€}x†{{‚‡ˆƒ~ƒƒ~„}~u…‚{y}~||}vvv}‚|‚ƒƒ}{~{„}zw}ƒƒ†t}yz}ƒy{{‚}‡ƒ„}|z{~{„}v~x}€|€|€xutvuw{|……‚x‚‰~‚€†‚|{††‡{vtwu†{ƒ~}}wwz€€}|y~|z}ƒ€‚{z~~x†…}{z}|‚…{„{z~…€€|z‚u|…€~}{~‚}ˆƒpmw{yv}{{„Š€ƒ‚z’z~Šƒxz~~„{€…yxvz}~†}wz}|€zˆ†yxƒ~|ˆ}{w{}}€„„†yu|‚„~„|z€y}€„†zyyzzz‰‚€~ˆ}{€~~mkvsxx„{u~{ƒŠ‹…„~|||†}€}|yx|}{wz}€€||uyz{|}…}}~~x€|€„~x{|ƒƒz„}zy€€}€z|x~‚ƒ‚~}~zy~ƒƒ~{zxxqlttz€~€}z}~ˆ‚„ƒ~~€ƒ}ƒƒy„yzyx~}|€~xz€{ƒ‚{z}}|„‡„zxv€‚}|x~Š€…ƒz~}‡‚€‚x}€}†|sy|z{|‡}}€uutwvwt|ƒ~„€€}€‚ƒˆ‡ƒ}{‚{‚„ƒ€wx„‚y€|}zvv||†~}€‚}xr}„‚z}wx{‚‚ƒ|€~|€€ƒ}z€~€‚ƒ}y‡ƒƒ€‚zxz{ƒƒnpryzvyy~v{…‡{†x‚‚…„†€zy€}~€}„}€xv}}‚€‚||}z}‚…~w{|yzˆƒ|€{{€‚~~z{~}„~zvx~yx‚„}}yw€€€~|‚yzƒtjwvt{€{‚„ƒ…„†„yz~~‚‰€y|vw„}}~}|zwwy…„}~€{}z…‚€}ƒ~{†„~zz}zƒƒ‰|yx€{‚…}€y|€…„z€~~xx€‚ƒ{~yunvvq}x†~ƒ†€…~‡ˆ~y~y‚{~}yzv|~‡ƒxz|||y€~‚{x‚„…€‚z}…‚}zz„~€€ƒ}x}y~…„~{‰|zy€}|}}}|€{qvvvvttx|‚…ˆ€{ƒ|}{€‚zx€€|y…„|yzy}{~€|~{}x~{‡„~}u|{€~ƒ}|{~}€|…€€wx|…~|x|}}‚€„{||€zƒ~|}|}…†mpuv|z|y~}}}~…ˆ‚|€y€|{ˆ€zsƒ{{v~ƒ{€~€r€y‚{{~y|w„‚„‚|‚wx{}„„|ƒ€„{{ƒ†ƒzvxz|€†‚„y~~€~ƒ}}zxzƒ‚€~‹€y|pvptrw|~†}|ˆ~~‰†‡{y€}}€{„€xt~x‚{…{{~|~ƒ~‚wyw~t„ƒ‚}}z}w~‡ƒ|r~}~{|Š‚z{}z‚ƒ‚}„u€ƒ|}{|ƒ~}€zwwvuyt|x~w‡ƒ{}{€€‚ƒ†~||‚{€|€{z}vz}‚{z|y|z|„‚~‚}zy|„„||}{z~~{„{|v€z‚€„{…zyy}€€}z{|z€ƒ„~‡~‡…wwvwwwzzzzƒƒz}„Š€…€|xz}}{|z|{…‚|z|ƒ|yw|y{~|„„€xwƒ}„y}{yv‡‚„yzzy|…ƒƒz€zx‚ƒ|{{~…rnlu|}}|„x…„‚‚€}}t„„}y{~t„€ƒ{vyxƒz|ƒ{~~z~~ƒ€€wx{‡~†{}xy~€~|}{|~wy‚‰|{~€‚…}…xz€}z„€ƒ{}zvzturxxwƒ~€~„†ˆ|~~{„}}}y…y|}}„|y{{}ƒ‚y}z|y‚„€‚w€zwzx{ƒ~x‚€~yvx€‚~}}zyƒƒ„ƒƒ‚xƒ…‚€lu{v}vx|v|}…€}|~ƒ„~…‚~w|{ƒ{ƒ|s{|yˆ€}z}}yw„ƒ‡}|xz}„z{y}‚u€€‚ƒt|zy€€ƒ|y}x}€€‡|}€zu{|€…‚ƒ|vx|z‚orrx|{|zz}z‰€Š€|……†}x}}€|€€z}r}ˆy~w{z}…~{zzy€}†wwy{„€‡z‚€y~{}}}„}{vu‚Œ€~z~yz{|†€|~{xkpsxwy}~}zzŠ€„‚ƒ~}y€€}~z€{{}€€x|ww|}„†{w|ƒ‚‚„}}w‚}„}‚y€wy|‹„~~}€€v~€~~{‡|z€……v|~€|~„|wwpxqst{|‚…€ƒ€~~€„†~z~y€€|ty{~€‚}{vzwz„€€|wyzƒ†…wu}€ˆ}{{€}|††|{y{}zz…€y€~„‰x}„|wuƒƒ€ƒqlwxv~|yz~‚†‡~}ƒ~‰x††~~z}{|z€ƒ€ƒwt~€z{‚~ww€€‹ƒv~~}z{|‚€}ƒ~z}~…{€u‚z}†~€€w{„{‡z„zy{‚€‚}€„|w{rrrpq~z|{}}}€„…†|{‚€…‚€~|x}‡|„€{|y|}‚}}z}w|~}€}‚{{|„~y}zz{‚|~z{w{{‚|}||‚}~{|xv…‹~‚}}w|roruuz}ƒ‚x€€†…Œ~uw„€|}zzvvw~x{{z|…}|}}}€}}…zyyz…}}„}u|€‚€‚|yz}~}z|y{…}}ƒ}‡|zsrwzwutx}‚†‚ƒ‚‚~}{†}~y}}z‚y€||{{yyƒ‚€|{Š~€|}z~z~~‚}yzy‚…x~€€‚ˆ}„v€}||„€}yƒzŠ|}„y|||}…nwvw~}y€y}|†€…„€yz|}ƒ‚€}|{z~|{ƒ„{~}}ƒ€~{yw€z~ƒ€{{x€…‡}z}xzyƒzy}x€€‡ƒ{}z}|€~„{vz~{~€€~}v€omtsts~‚{{€{~Œ…~…y€ƒy~†‚{v}…zz…€wyvw}…|‡}y}|x}{{‚}y„‚‚{w}{|†„…xy~|‡}€yz‰|ƒ{€€{xvƒ€Š{{wxtstzyz{ƒ‡€}{}ƒ…{‰‚€zy~}{||yw€‚ƒ|{{zw|}€…{|€{}|€{v€yƒ€„…€wy€~|€…{}|„~„|~z|€‚†ƒy}|x~ˆsru‚z|zw}‚…ƒ‰}‡‡z€‡ƒ…y€zz|„}{||u|z‡}z|x}{{‚ƒ…|‚w…~€}„x{|}}ƒxyw‚„ƒ}€~{~€‚}||}v{ƒ‚†zƒ~ki|t~z|~z~‚Š„‰|}ƒ€z|‡~€~wyx{ƒ{‚xz{„€~„}yvx‚„…~~v†€‚}~{z}ƒ…€z{|~z}€{x||}ƒ‚|z}†€„ƒ€vxƒypvpzw~~‚|‚~}z†…†{}„|w…‰…v||zx‚z}yxv€x‚{z|{z€y††|x|rƒ}…x~z}||ˆƒ~xzzy~‡ƒ€|z{‚}€ƒ}}|zzˆ€|wxuyuu|}~€…€„z‚‚~‡„‚€y}~ƒw‡~yuxy~…|€|www€„ƒ|w}{zu†„…}z~€yx~Šx|€~‚†~yv||~„{„xy‚…|„€}zyx~|‚rlqw~xzvw~‚ƒƒ…Š{{~ƒ„„~~|}~xz{€s|†€~€}‚}~yƒ}~{|}€|}„„{}z~{ƒ~ƒ‚{}w€|„†ƒ~|z{}…}…{€xƒx€ˆ‡|}~rltvvs{|€~{~‚ƒƒ„‚~zzx~…‚zv‚x„}‚~|ƒ„y{…ƒu}xƒ}{‡z€z}y€|ƒ‚yxyx{€~‚{xy}|{~ƒ…€„‚xw}}}}‡ƒz{}svvptvq…‡„y~ƒŠ„†zzy„~€{||yzw€€{x}~y~€„~z{z€{z€}|{zˆ€~{|y{‚‚‡|}|~{{~…†|y‚y|€‰€€{|}†€…‰}uwxvv}}txzˆƒƒ€‚~€„‚†~…~yr{}}{x€{w„}~x}‚€€|€{yx}€‚}„‡y}xxˆƒ|zƒ~~€„…y~~}}€~z…{…x}v~zƒ}tppvzy}}{s{ƒ‡‚„}€x„~€~~yx‚{{…~z|x|z|ƒ……y{{}‚~‚x{}y~‡‰x}|y|z|…‡‚zyx~‚~€€wz€{}Œ{}u|z}z…||~yvlrwwtv†€{‚~„†€‡ƒ|z|€ƒ‚~zz|z~|ƒ|€ƒ}tu}€€„x{yx}…~}€~|{‚ƒ|||||}‚~u|{z}‚€{y}‚ƒ€}~€{…{|ƒ…x}uvt}psw{„~‰€}z……†‚…~}{‚x|{x€|‚|}{}z~ƒ‡„zyz‚}€€…†wyƒ{|ƒ{…€y~{‚~€~|z~‡||}{}}‰‚zz}|‚suvvww{yyy‚€„€„‡~{ƒ„„€~|ywyy„€€|xy|u{€‡{z}€}~xv}€‚„€y}z{~€~}x†xy}xƒ…‚€{||}†}‚w€}zƒƒƒ€€z€lprqv{{}}}{†Š‡€€{~x„…„|v€}{{y}‚|ux}{‚€‚{vy}{…€€ƒy~zv€~‚~yƒz{|€‹ƒ}}|}x…ƒƒx}€€||€z„x}y{}€€‚‚yosouzu~ƒ„€‚ƒ„†‰‚|…€x…„zw{€{y}x{ty}}‡~€}x{zz{‚w‚z~€„‹x{‚†}~vv{‚ƒ~…|€yyƒ‚ƒ€‚~{€{~‚|…zpuyy{vz{{|„„}|ƒ‚€‚}ywz}€ƒ{x€yswy~ˆ‡x{zƒ€„}szw{€ƒ~x€‚„‚‹†„ƒy|Œ€€€~|}}ƒ€||yz„‚z|z~}~ropu{z~{{yz‡‡‚ˆ’€{}†ƒ|ƒ€|€z{‡{}z~vxy|}zzx|€‚€}yz€|‚{‡~{vyz~‚ˆˆzzz…y…‚{yz‡„ƒ€|y}~y„~ƒ€x|x|rnsxxz{€‰}€}„ƒ‡€€zx†‡~†vxz{|~†…}|w€|}€‚†w{t|ƒ€‚wz{{„|ƒ}~y}~‰~{||~~‚‡ƒuxy}v‚‚†yv€ƒ~€wwuzqyswx„„~‡‚‚}{€‚‰~{„~x{ƒ|…zz~{~‚~}{{|‚{~{|}}‚}z}xzzІ~u}}}z‚ƒ~€zx{‚…‡€{v}|ƒ‚‚€z}€z„rsr‚~y{yy‚yˆ†„€~€ƒ‰‚~xx€|}ƒy~{|yz|yƒ}€~ƒyww„~}}€}„{‡„|~u}‚z~|y„‚„…}~|~}‚~{x{}€vxz|}wpquw{{||x‚ƒ~…‡‰„z~}‚‡…ƒƒ{}x{z‚z~z{|}|ƒ„{w~‚€t}‹‚y…|~z…‚{~€€{~€zyzz€{‚|}z€€z„|zz~€|„}†€|vwsrpyt|„†ƒ~€|z„‡…†‚‚|wzƒ€x‚|sy{~}x{w{‚}{}€}ƒƒ‚…||xz…}ƒ‚z|xz|ƒ„{~€z~z‚ƒ‰€{{x}†‚y}~w‚~†|xsvzytyw{‚‹‹~~ƒ‚‰~~|yz|}|„}zxzy{€{…~yw|{{~ƒ~zy{{„€ƒ„„xzvƒ‚~}ƒ~tz€~xy}{|~€}||~~…€‰z{~~„}‡snqz}wz|~yw}‡€‰}ƒ‚€€…‰ˆ|~w}{}{…wyx}}y‚†ƒ€{|z‚…}„xƒzu~u}~~|}y|‚‡s~w€…}~}€~|†ƒ}z|x€€‚}yxxrqsvsx}€ƒ}~ƒƒ††ƒ|{|„„‹ƒ}}wz|‡~„}|}t~z}‚~€~x}~†‚…€~…y}„z{x|}{|‚‚||}}~y„ƒx~yz{…~„zz{v~~{…~}w|rotu|||‚‡€{€€††x~y{€†|„}z}v€}~{|y}€ƒƒ|‚ƒ|{‰ƒzz}{|~~„€}€z{€‚‚‚}…|z}ƒ‚ˆƒ||y…|~€{y€{‚usu}~{wv}}{ƒ€…€}€‡‚‚„}{zvzz‚}v{}~yƒƒx}‚|€‚{„xy|„„wwƒz|…z…|{†€}~}{{|}„€xvƒ|„ƒx€z~vorwx}z€{|w|…„‚ƒ|ƒ|z~€ƒƒ€yz‰|}}|w}{v~~|y|{€|„yx{z…}…„xww…„~}€}€y~€ƒz}|€}{€€x{t€|ˆ…€|zvuoqsz~€~}~‚}~„†€}yyzƒƒ|zz{|z|…€x€{|†„„uxzƒ{~{†€€€z€„ƒƒ€€|€}€€}}y|yz{‚…y}x}}{{‡y|z‚€~|ˆvwutt{uu}~Œ€}}~…‚~Š…‡€{|}ƒ}‚€}vyzz†{€‚{|~|„}{‚€z||{}}}{x}}{‚‚Šz|}{z}‚…€€u}}‚‚‡‡ƒ|t„{‚{„€yzwƒ‚urru||v€}ƒ…†y|€†~€‚{{zz…yƒ}zyzuƒ‡~ƒ{x|w}ˆ„y}{zyzƒƒ~ƒyz|}~‚yx~€ƒ†}wz}ƒ|ƒ|‚zz€…†ƒƒ|zrruxvyz}„€}|‚ƒˆ‡}wz~€…‚}}zv€‚€}{ƒ||}{…~}z|€…|ƒ…~zzy€|„„‚‚zxv}ƒyƒ}zzw„‡‚€z~|z|€}„zy|}}zƒƒ€xuzztvz|…€ƒ}‡€x‚…}z||zx‚†|{yw€€uƒ…‚~vƒ„€†€†}{‚w…}„€€|x€z€‚}z}„y…|…€…|{~~zz…„‰~|yƒ~z‚†…}~z|€~…qtswt{xr{€†~‹}„~‚Šˆ{w|z‚}{|„uzz{ƒ}†‚~yu~z‚ƒ‡|~zy…}„{|~|}{|‚ˆzz‚||{}„u€€}~…ƒƒ~~wy|†{‚€€{zy|tnnzw~z}}{ƒ}‡…zƒz€zƒ}y}~}z}€{wz}‚{‚|x€{|{ƒ€|~}{~~}ƒ‚~€}…yƒ„zyw|{„„‰{}}{}ƒƒ}†€ƒ{y|”„|€ƒ€xuqrutxu‰~{}‚‡€‡‚|}y†‚~y{vy|‚zƒ‚y}xz{€†…|}vx}‚…„‚{ƒ‚{ƒ€{{€€{†~…yzz~~€ƒ€„~zwx}…ˆ~€~|€}{„€}xnzuuvux|…ƒ†{…„€‚‰„„ƒy|y…}~ƒz|{}y~„ƒ{|}}€†wzƒ||€…„~|s‚}~}zxz}„„‚{z{v}{‚‰wƒ}{z‚€‡|}y~y€€‚ponw~~yx|x}}…€‡~„}w„z……€|}{zwˆƒ{|z}z…w~~{|}{€„ƒ~|z{zƒ…€}y|€ƒ‚€|ƒ{|w€}‚y{{}{‚‚†~w‚€w~~}…{}z}vprpux€z}„€†|€†„‡€€~|€}}|vyyx€ƒ€u{{}}€„~~x~€…{}€yzz|ƒ€{€}{}„‡‚{€…}y~~ˆ…}{{|€‚~|ƒ|x|y‚~‰~|z}r{r{uzx…†}„x€€}†‡‚y€yƒ|}…|€z}v{|€{zz€†}€{~ƒy|…„{€w€yz‚…zzxƒ}|€€ƒ‡w}{‚y„‚~zyw€}„‡ƒŠ{‡wz‚€tqy{vyt‚~}‚€„†‚|…‚‡~€y}‚}€{{|xw}}||y|z|{}…„}€€~||~{‰ƒ}€}ƒz†{~…|yy{~…z{xx}~}}zy{€y„ƒ|{~‚|||npss}z€}|v|ƒ‚‚‚„ˆ~|z{ƒ‰‚|}zzvyx€…}y€u~€uy€|}€„…€v|{}~‚}vzy{|†€|}{~|}†‚‚€{|x}ƒ||zy€x~€||~zustvx|ƒ}„}|~€€‡‚|}~‹zy€{{z†~{ƒx}|z…|„t{~~„}|{|‚}ƒ„~z{z€ƒ~}zz{~‚„„v|xz}}y‡‚yw}}||€‚„{{uswvv{xv†‡‚†zz€……„ƒ€}z‚ƒ}yztz€|‚€~{y}„|…}ww€||vy}{„‚}zx||€ƒ‡}u{€}z‚ƒ~xz€‹€„~~ux|~€€shn|xzz{††|‚…Š„ƒƒƒ{‚}„‹ywwz|}‡{|~v|xƒ€€~}yz{z€ƒ‚‚x}z|€‚ƒ|~y€z‚{…}xx~~…€‡}}wz|…ƒ€~}~}ƒ~€z€zz…zppuxtw~‚†}}~……‰‡‚|w‡€}„}|v|{‚}|{zvy„|ƒ||zz|„ƒ‡~zw~{€}„zzzƒ}|~€~}Œ€‚‚}|‚y€„}€€‚~zx„~|v€wyxsqxwx}ƒ‚|€}}‚…„„z{~‚yy}|€||ƒw~{ƒ„{xƒ}€€€‚|{z{€~€w~y}|~|…€{‚{y~†††€{€|x†~€€{€€‚}XTENSION= 'IMAGE ' / Extension first keyword (see SIMPLE) BITPIX = 16 / # of bits storing pix values NAXIS = 2 / # of axes in frame NAXIS1 = 50 / # pixels/axis NAXIS2 = 50 / # pixels/axis ORIGIN = 'ESO ' / European Southern Observatory DATE = '1999-06-07T15:23:07.513' / UT date when this file was written CRVAL1 = 150.0 / value of ref pixel CRPIX1 = 1.0 / Ref. pixel of center of rotation CDELT1 = 1.0 / Binning factor CTYPE1 = 'PIXEL ' / Pixel coordinate system CRVAL2 = 150.0 / value of ref pixel CRPIX2 = 1.0 / Ref. pixel of center of rotation CDELT2 = 1.0 / Binning factor CTYPE2 = 'PIXEL ' / Pixel coordinate system BSCALE = 1.0 / pixel=FITS*BSCALE+BZERO BZERO = 0.0 / pixel=FITS*BSCALE+BZERO MJD-OBS = 51336.64107118 / MJD start (1999-06-07T15:23:08.550) DATE-OBS= '1999-06-07T17:23:08.550' / Date of observation EXPTIME = 2.0000 / Total integration time PCOUNT = 0 / Number of parameters per group GCOUNT = 1 / Number of groups END }wqurut|u|ty|y‚|~|vz~…„…xtxy~‚||~x|y~w~||{z„xyz|rurquwz~zywzvw„…~{|~||w…‚z|{y}z{ƒ~y{z}~„†}„}ysz|y{qrxuvv}‚}zz~}~{€…}|w€‚…~~}xxz}€}}|wzwz{„‚}pvttq|zxpsqxyƒzzƒ}€‰‚€ˆyx{}„†|‚{yxxu~„z}}|~€xwytr|v|||{z}v{~„„z{w{|ˆ€y}~wy‡|€yw„}†„y€zys}ywqswqzz~yzx}xz€|€‡~}{‚ƒ}{vx}ƒzz{{t|ƒƒƒovxuvyztsptyy{|ƒyzv}{„†„€|w‡‚ƒ~xwz{‚|ux~v}€zu}rrrvyyws{zw{|…}z€|x|€Š…{y|{ƒ~…zzy{z}ƒ‚|}yysvszvt}xysy~{{t}v~‚{€}wz|€€~„zyw{}…{€|€}w{u†„ztuv|xzxwstz}€x†{}|‚„ƒv~w|}ƒ€€zy‚}{xƒ~|v€y…}}{susrx{wxvwv}~„…wz€z€Šzz{w}~yz}{zwyy||~z{wx{xwxqswy~vw€~uv{~{ƒx€~€…~‡v}{xyƒƒ|wz|y‚‚|zuzyzuxtu{vvz€zz}}{}…„z{€y~€‡}~xz|{€}~‹{sw€}€{r{vwqv|€wxzu|{€‚~x{|{„ƒƒxƒyv}ƒ‚ƒ€€{xx}‡~v}~|wzx{wysvv{z€|w||xt‚€}†zx„~†}}|~~w~{‚‚su}}ƒ~„{wwwrtxvszurwxz}|z€{ƒ†„ƒy~€~{ƒ~€x~}yx}{‚xu|{‡€yuwsnzy{rsss€€||{{zy€‚‚{ƒzzw|ƒ}{z€zt€„}}|zƒy{wysqywt|€wzuwv}€x€€{w€}ƒ‚|y}{†€‚‰~v{~y|ƒ„~wux|yw‚urovsv{|wy…y{{€‡}}w„~€}…{t{~}}~us~|€ƒyrutuz~ytquvw~€~„||}}‚|z~~yxx„‚w}yz{{€~zvx{}|tvntsx}tzxyu}~…€}…|{‚…ƒƒ‚‚x|xzˆ‚|w{z€w|€~|wyy|||t~u}wps~}yzu{{€„v{}~…€„~rv}z{y|wws|||{vxu{zww{vqoux€{{|}|u€†€€{{y}z‚~|~|€sy}~€zyx{~‚ypwtxv|z{vxxtv€†|x{z}€‚ˆ‚|u|z|}{‚z{x|yx†„|yxwyw{mwvxwvzzux}€}~†{}‚xz‡„~‚z|yw{‚}€x|xzy…}|xyzvsz{yqrvw~y~~~w{y~~{|€~€€…€}}{|x‚~|yw|~z‚ƒuurtoxz~€szvyx…€€|y~‚ƒ|…€u~}ƒ}…|‚€zyy~{€||~{xu}€}vtrzvvy€ztyus€{„€€z€~€}„~}|vu~„}‚}zxv|{z…xzvvywv{tvowuwx|~~€|}‹ƒ|€}z}‚†z|€x~z}|„vvy}~ƒwvssuy€{s|pvp{„€{y‚{{‚ƒƒ|~{~~ƒ|ƒ}|vx€€‚|ƒ~z{xzy€uwq{wyxxƒzswx|…ƒz}€y{~ƒw}~}}z†‚€{{zxz~|}‚|w}{z}vvwwqo}z|xuw{w}€„‚~~~{x€‚y}‚|„yxvy}ƒy†wrrxz{~twz}|z€~}w{~‡‚†}‚{{~}|€}v|z…€|{ƒxw€v|{uuprr~{yy|vwy~‚€||~|~ƒ‡zz~{zx†‚…y{}|}z€…{{||€yywsqsvty€|zyxt|{{ƒƒ€€|ƒ|v„…€yyˆ}|~€|{wx|„€…{}uwvrzyw{nzu}v}zzx~‚}†{…z~zv€}‚}|y{yƒ€~ƒ|yzy‰‚€ytqvrv{wvxx{wt{‹‚|zx{x~Šƒz€z||‚‰}~}v~|{z‚‚zux}zxv{uxstt||{}ww{|€‡}|{‚{ƒ{Švw{|€‚z|xvv‚{z‚}|ttyy{qutu{w€|{zzw€~†€~}w€ƒ…€x€yw}z‚yvw|w{€…zvlpp~y{vwtwrzz€{€€|€€wƒƒˆ}~|‚u}{ƒ~zyy}…z€ƒyvuzw~yxuwqrwu{€yy{|z{~~ƒzzz‚ƒ€†€‚€{u}‡‚‚{€u{~€|x{yuwzz|rsosy}~~}wv}}‰~‡}|yƒ|ƒ„|{}}„u}}€~€yw|wz{rptyw~ywuuz}{‚€z…z~€…‰‚}{x‚}ƒ{yzw€{~}†vz{~‚zwsuuvuyƒwztƒz{|ƒ{€x}{z„„‚yz{w†yƒ†{}zzzƒƒˆv|uwzu{x‡vt{{|{{€|s{v†„~z}‚zx‡„|‚{wy}|‚~twy~|{~zwut}u~xxwywzw{…€z}}|€Š}{w{}ƒz„€€u{|~x~€zx|u€~|unuuwyv}wyu{v}†€{}{x‡€‚~|~{{|ƒz~{|wy…}‚ƒ|w{„xv}w}zuy}|}v„|ww{}‚yw||z}……w|{{~z~{{}‚{z~}€‚~{pru~}szyu{wy†y{y||ˆ‡}z}„~€€|z|wx|~~ƒ~xzs}€€~txvvwtw†zwyzz~yƒ€|}}{}„‚‚|}ww~‡‚„€{}u{…~{|{wskycat-3.1.2-starlink-1b/rtd/images/ngc1275.fits000066400000000000000000007777001215713201500211720ustar00rootroot00000000000000SIMPLE = T /FITS header BITPIX = 16 /No.Bits per pixel NAXIS = 2 /No.dimensions NAXIS1 = 353 /Length X axis NAXIS2 = 353 /Length Y axis DATE = '28/06/95 ' /Date of FITS file creation ORIGIN = 'CASB -- STScI ' /Origin of FITS image PLTLABEL= 'E1618 ' /Observatory plate label PLATEID = '07WS ' /GSSS Plate ID REGION = 'XE198 ' /GSSS Region Name DATE-OBS= '20/12/57 ' /UT date of Observation UT = '05:36:00.00 ' /UT time of observation EPOCH = 1.9579677734375E+03 /Epoch of plate PLTRAH = 3 /Plate center RA PLTRAM = 9 / PLTRAS = 3.2780210000000E+01 / PLTDECSN= '+ ' /Plate center Dec PLTDECD = 42 / PLTDECM = 33 / PLTDECS = 3.1743320000000E+01 / EQUINOX = 2.0000000000000E+03 /Julian Reference frame equinox EXPOSURE= 4.5000000000000E+01 /Exposure time minutes BANDPASS= 8 /GSSS Bandpass code PLTGRADE= 1 /Plate grade PLTSCALE= 6.7200000000000E+01 /Plate Scale arcsec per mm SITELAT = '+33:24:24.00 ' /Latitude of Observatory SITELONG= '-116:51:48.00 ' /Longitude of Observatory TELESCOP= 'Palomar 48-inch Schmidt'/Telescope where plate taken CNPIX1 = 2686 /X corner (pixels) CNPIX2 = 4893 /Y corner DATATYPE= 'INTEGER*2 ' /Type of Data SCANIMG = 'XE198_07WS_00_00.PIM'/Name of original scan SCANNUM = 0 /Identifies scan of the plate DCHOPPED= F /Image repaired for chopping effects DSHEARED= F /Image repaired for shearing effects DSCNDNUM= 0 /Identifies descendant of plate scan image XPIXELSZ= 2.5284450000000E+01 /X pixel size microns YPIXELSZ= 2.5284450000000E+01 /Y pixel size microns PPO1 = 0.0000000000000E+00 /Orientation Coefficients PPO2 = 0.0000000000000E+00 / PPO3 = 1.7747471555000E+05 / PPO4 = 0.0000000000000E+00 / PPO5 = 0.0000000000000E+00 / PPO6 = 1.7747471555000E+05 / AMDX1 = 6.7240987715710E+01 /Plate solution x coefficients AMDX2 = 3.6605616579680E-01 / AMDX3 = -1.3732674154580E+02 / AMDX4 = -2.2170938540070E-05 / AMDX5 = -2.0113447317610E-05 / AMDX6 = -2.1108647953950E-05 / AMDX7 = 0.0000000000000E+00 / AMDX8 = 1.8223387505210E-06 / AMDX9 = -9.7173567076310E-08 / AMDX10 = 2.3013465940930E-06 / AMDX11 = -6.6734677147540E-08 / AMDX12 = 0.0000000000000E+00 / AMDX13 = 0.0000000000000E+00 / AMDX14 = 0.0000000000000E+00 / AMDX15 = 0.0000000000000E+00 / AMDX16 = 0.0000000000000E+00 / AMDX17 = 0.0000000000000E+00 / AMDX18 = 0.0000000000000E+00 / AMDX19 = 0.0000000000000E+00 / AMDX20 = 0.0000000000000E+00 / AMDY1 = 6.7250690753980E+01 /Plate solution y coefficients AMDY2 = -3.6679440186020E-01 / AMDY3 = -3.1235334956310E+02 / AMDY4 = -3.5598357942100E-05 / AMDY5 = 2.4433823111370E-08 / AMDY6 = 4.3754127047740E-07 / AMDY7 = 0.0000000000000E+00 / AMDY8 = 2.0663931384810E-06 / AMDY9 = 2.9377276167040E-09 / AMDY10 = 2.0894436743940E-06 / AMDY11 = -2.4710339600070E-08 / AMDY12 = 0.0000000000000E+00 / AMDY13 = 0.0000000000000E+00 / AMDY14 = 0.0000000000000E+00 / AMDY15 = 0.0000000000000E+00 / AMDY16 = 0.0000000000000E+00 / AMDY17 = 0.0000000000000E+00 / AMDY18 = 0.0000000000000E+00 / AMDY19 = 0.0000000000000E+00 / AMDY20 = 0.0000000000000E+00 / Based on photographic data of the National Geographic Society -- Palomar Observatory Sky Survey (NGS-POSS) obtained using the Oschin Telescope on Palomar Mountain. The NGS-POSS was funded by a grant from the National Geographic Society to the California Institute of Technology. The plates were processed into the present compressed digital form with their permission. The Digitized Sky Survey was produced at the Space Telescope Science Institute under US Government grant NAG W-2166. Investigators using these scans are requested to include the above acknowledgements in any publications. Copyright (c) 1994, Association of Universities for Research in Astronomy, Inc. All rights reserved. DATAMAX = 14733 /Maximum data value DATAMIN = 2806 /Minimum data value OBJECT = 'ngc1275 ' /Object ID OBJCTRA = '03 19 48.168 ' /Object Right Ascension (J2000) OBJCTDEC= '+41 30 42.12 ' /Object Declination (J2000) OBJCTX = 2862.03 /Object X on plate (pixels) OBJCTY = 5069.55 /Object Y on plate (pixels) CTYPE1 = 'RA---TAN' /R.A. in tangent plane projection CTYPE2 = 'DEC--TAN' /DEC. in tangent plane projection CRPIX1 = 176.5 /Refpix of first axis CRPIX2 = 176.5 /Refpix of second axis CRVAL1 = 4.9950707579921E+01 /RA at Ref pix in decimal degrees CRVAL2 = 4.1511441513468E+01 /DEC at Ref pix in decimal degrees CDELT1 = -4.7246758859361E-04 /RA pixel step (deg) CDELT2 = 4.7257498386706E-04 /DEC pixel step (deg) CD1_1 = -4.7215789128263E-04 /CD matrix CD1_2 = 1.6336830291022E-05 /CD matrix CD2_1 = 1.7104033764000E-05 /CD matrix CD2_2 = 4.7229251884081E-04 /CD matrix PC001001= 9.9934451099196E-01 /PC matrix PC001002= -3.4577674078453E-02 /PC matrix PC002001= 3.6193269529500E-02 /PC matrix PC002002= 9.9940228527557E-01 /PC matrix END ü üªªªªSSSSªªªª z z‚( $ $ Ñ Ñ”îîî==ë ==” 9 9” ü ü O O ü ü ü üSS ø ø O O O Oiiiipppl¿tÏØØ#ÈÅÅ ½ j jÅÅnn Á ÁnÈnn™™™™ ? ? ?™XX « « « « « «XX þ þ ’ ì™ ? ì ì ì ìnnnn Á Á Á Á ç ç””ëë l e e » » » » O O ü üSS±WªlÇ„ X*(.7(ÍŸÓÃlÇÇlÃÃiiii====”” ç ç á á á á á ᎎ á ᎎ á á á á È È u u"""""}""""""CCCCCCððÅ jnnnn Á Á   Á Ánn Á Á ì ì™™™™ ì ìnnnn Á Ánn j j jÅCC • • • •CC Ánnnn Á Á jÅn  Á Á Ö Ö Ö Ötttt Ç!!!%Ëtt!|-Ò҇‡%ù(®#ñÒ»‘‘ääàà3 ü üªªªª­S ü ü OªÕ zÕ z Ñ Ñ~~AAîî==== == ç ç”” ü ü ü üª O O O ¦ K ü ü Oªii¿¿¿l|› ´•Ð j j j j j nn  nÈvôô™ô™ ? ì ìXX « « « « « « « «XX ì ì ì ’ ì ì™™nnnn Á Án  Œ ç ç çëëëë¿¿ e e » » » » üW ü ü ¦ ¦ ¦ªªªSS[ÇÖõ.Ž6V7±4ü(ÍâÃÃÇÖÞÏpii » »ii== ë ç ç 9”<<ŽŽ á á á Ꭰ4 4 4 á á á á u u"" u u"}}} uÏÏ*"" • •ð •ððCC j jnnnn Á Á Á Á j j j j Á Á Á Á Á Á Á ì ì™™™™ ì ìnnnn Á Á Á Á j j ½Å jÅ j • •CC • •CCnnnnnn Á Á Á Á Á Á Ö Ö )„ËËËËtttttt!!xx Ç!!!xxÒ-`Êá"– %‘7ääààà ü üªªªªµjbS ü ü_/ÕÕ z Ñ Ñ~~AAîî====ë똘AA””WW ü ü Oªªª ¦ ü ü OªÃÿ¿¿l|P&JÐ j j j jÅ jnnnnnÈv…^^Nôô™ ì ì þ þ « « « « « « « «XX ì ì ì ’ ì ì ? ?nnnn Á Án  Œ ç ç çëëEE¿¿ » » » » üW ü ü ¦ ¦ ¦ªª OªSS[!1#º5R7±9 7±3¡§x|ª(wH%ii » »ii==ë ç ç”îñ<ŽŽ á á á Ꭰ4 4 4 á á á á u u"" u u"}}}Ï**Ï""ððð •ððCCÅÅnnnn Á Á Á Á j j j j Á Á Á Á Á Á Á ì ì™™™™ ì ìnnnn Á ÁÅÅrÅ jÅ j • • è è • •CCnnnnnn Á Á Á Á Á Á Ö Ö )„ËËËËtttttt!!xx Ç!!!xxxÒ»‡Ú%ì‘ääààà ¦ ¦ ü üªªÅbS ü ü± ‚‚((((ÕÕ”î”î””””ëëE ú ò˜ øS ü üªªªª ü ü ü ü ü ü¿¿ÇÇt¿iiiip€à+#ÈrrÅÅÅ j ÁÈ#•"'M%òÌRC • • T T T T T T T T « « þ þ « « «™™ ? ? ì ì ì ìÅÅ Á Á Á Á =˜ò5xi¿¿ ü ü ü üSSSS ü üªªSSSS€" 4ü9 7±8^1šŸËËËÏH X“!Ç¿==== =˜š@ååŽŽŽŽŽ 4 á á á á á á"" u u  yy}×99.ÓyyððCCCCCCnnÈÈ jÅnn Á Á j j Á Á Á Á • •CCCC • • jÅÅÅÅ • • • •CCððÅÅ ½ j jÅÅ Ö Ö„„tt tttttxxËËtttt!!tÏ\!h³??77ŠŠä ¦ ¦ ü üªªµ­S ü ü üW‚‚((((ÕÕîIIîîî””ëëEUt ƒMS ø ü üªªªª ü ü ü üWW¿¿Çæ“Ï¿iiiipvvnÈÅÅÅ j ÁÈØ ´2L604Ö-dø • • T T T T T T T T « « þ þ « « «™™ ? ? ì ì ì ì j j Á Á Á Á =˜M!0+‚'sâll¿¿ ü ü ü üSSSS ü üªªSSSSË&0ì4ü2ô&Æ5ËËËtÏ)ÏÇl¿==== ã=@åå厎éééŽ á á á á á á"" u uyyyy}A h#ò.yyððCCCCCCnnnn jÅnn Á Á j j Á Á Á Á • •CCCC • • jÅÅÅ jÅrr • • • •CCððÅÅr j jÅÅ11„„tt tttttËËtttt!!tϧ·Æ X??77ŠŠä ¦ ¦ ü üªª ¦ ¦ O Oªª((((((//«»XIAA ç ç=˜ t. 0Á"‹§ ¦ ü ü ü üWWªª üWW üll|PýÞtÃiiiiiÅ jÅ j j j j jnnÈ2(%5®886Þ.¿¥ðCC T T T T T T §X þ þ þ « «XX™™™™™ ? ì ì j j j j Á Á Á Á =˜ ,²4ü/’—Çl ü ü OªSSSSªª ü üSSSSp%ù#cT%ppptll¿¿======ëëåååå á áŽŽŽŽ á áŽŽŽŽÏÏÏ u yyyÏX/ù/ù·.&&CCððð •CCnn Á Ánn Á Á j j Á Á Á ÁCC • • • • èCrÅÅÅÅÅÅð •ð • • •CCrrr j jÅÅÅÅ j jÅÅÞ„11!!ttttttttttËË!!tϧ§pp`«‘‘ŠŠŠŠ Ü ¦ ¦ ü üªª ¦ ¦ O O O O((((((ÕŠ%*S$<XAAAA=˜  #8(¢Ö§[[ ¦ ü ü ¢ ¢WW__±WW üll!Ö““„tÃiiiii » » Á Á Á ÁÅ jÅ j j j j jnnn#œ*Ú4)2Î'ú¼¥ðCC T T T T T T §X þ þ þ « «XX™™™™™ ? ì ì j j j j Á Á Á Á =˜úÎ&#câl ü ü OªSSSSªª ü üSSSS »pp€€%Ëpp¿¿¿¿¿======ëëåååå á áŽŽŽŽ á áŽŽŽŽÏÏÏ u yyyÏ9»%%.&&CCððð •CCnn Á Ánn Á Á j j Á Á Á ÁCC • • • •CrÅÅ j jÅÅð •ð • • •CCrrr j j j jÅÅ j jÅÅÞ9‹‹!!ttttttttttËËxx!!tϧ§\``««‘‘ŠŠŠŠ Ü e eÕ z( Í z z z z O O O O Oªª¹"J+Ã"÷WWªªª ÁzÅ[­­ ¦ ¦ ¦ ¦ ¦ ¦ªn#½­ ¦(‚Ýì (6¼è‚‚‚‚ÕÕ(( T T T TXXXX € € € € € € € € Ö1 Ö Ö1‹î "ü GÖ «XX ½ ½ Á ÁnnCC • •™ôGG¯¯³ þ « « Ö Ö | Ö Ö Ö Ö Ö+ Ñ Ñ Ñ~~†•CŽÙ(((( » » iiiii ç ç””AA””~~ÙÙŠŠÝÝÙÙ++~~ Ñ Ñ ü üªªSS øSSSS ø ¦ ¦ ¦ ¦  ººº _ _º  ² ²cccccccc  _ºéC¦õ@åå\\\\\¯ TXX «\¯¯ • • •ðCC • •CC • ; è è • • Ö Ö Ö Ö Ö Ö Ö Ö Ö Ö Ö Ö----CCC™ ? ì ì Á ÁnnˆˆÚÚ € € € €ÚÚÚÚ--Ú5RbÿJ££ööIIII ò ò E E ò òŸŸ7777ŠŠä䎎••CC;;öQ££III e eÕ z( Í z z z z O O O O OªªÁÐɹWWªªª…ŵµSS ¦ ¦ ¦ ¦ ¦ ¦ª# BÌ[(‚Ýì$&,E"ÌCÝ((( z z(( T T T TXX þ þ € € € € € €ÚÚ Ö1 Ö Ö Ö1Þ“· «XX ½ ½ Á ÁnnCCððôN¡¡\\¯¯XX « « Ö Ö | Ö Ö Ö Ö Ö+ Ñ Ñ Ñ~~+†3ÙÙÙ((((i iiii ç ç””AA””~~~~ÕÕ‚‚~~ Ñ Ñ~~ Ñ Ñ ü üªªSS øSSSS ø ¦ ¦ ¦ ¦  _ _º _ _º    cccccccc  _ºŽé<–åååå\\ll ¯XX «\·d¯ • • •ðCCððCC • ; è è • • Ö Ö Ö Ö Ö Ö Ö Ö Ö Ö Ö Ö---- èCCC™ ? ì ìnnˆˆÚÚÚÚÚÚÚÚÚÚˆˆêq#ëÄ¥££ööIIII ò òŸŸ ò òŸŸ7777ŠŠŠŠŽŽ;;èè;;Qö££III¿ e e¿ÕÕ z z Í Í z z O O ¢ üªªª__±±WWªª ü±!µ[SSSSSS ¦ ¦WW Á½[ÕÕ‚7ÿRŽ‚(((((Õ z « « þ þ- Ó € € Ó--ˆ Ö Ö ) ) Ö Ö1‹d   « « « « Á Á   •ððJü f±·\¯¯ « «„„ Ö Ö Ö Ö Ö Ö Ñ Ñ~~~~++~~~~(((( » »iiii ç çAA ç ç”” Ñ Ñ~~Õ/ÕÕ++ Ñ Ñ Ñ+~ $ O O ü ü­S ¦ ¦SS ¦ ¦ ¦ ¦ ¦ ¦      _ºg   cc¾¾¾ccººººŽŽ<<8888¯ Æåíƒ\XX « d\ • •CCCCððCCC è è è • • Ö Ö Ö Ö Ö Ö )„ Ö Ö Ö Ö---- • • • • ì ì ì ì j jÅÅÈÈv55ˆ-ÚÚ-ˆÚÚÚÚˆâêŸy ˆÄ¥££IIIIIIŸŸŸŸMMŸŸ7 ÜŠŠŠŠ Ü ÜŽŽààŽŽ;àö œIIIIö e¿¿ e z z z z(( z z O O ü ¢ O O OªªªWWWWªªWWn[ ¦SSSSSSWWWW­­[ÕÕ(݆à3Ù‚(((((Õ z « « þ þ Ó- € € Ó-- Ó Ö Ö ) ) Ö Ö Ö1 ¯¯¯ « « « « Á Á   •ððJ(þ-":Æ·¯¯„„ Ö Ö Ö Ö Ö Ö Ñ Ñ~~~~ Ñ Ñ~~~~‚‚‚‚iiii ç ç ç ç ç ç”” Ñ Ñ~~Õ///++++ Ñ+~ $ O O ü üS ø ¦ ¦SS ¦ ¦ ¦ ¦ ¦ ¦      º _g   cc¾Í‚Íéé<<8888¯ Æ'¹/+$WÆ\XX «¯ \\ • •CCCC • • è èC è è è • • Ö Ö Ö Ö Ö Ö )„ Ö Ö Ö Ö---- • • • • ì ì ì ì j jÅÅÈ}ÐvÚÚˆ-ÚÚ-ˆÚÚÚÚâòcÄ´ÿJIIIIIIIIŸŸŸŸMMŸŸ7 ÜŠŠŠŠ Ü Ü33ààŽŽ;àö œII££ö · e e $ $ Ñ+ Í Í z z O O O O ¦ ¦ ¦ ¦ ü üWW ¦ ¦SS[[WW­SSS½b† Ñ Ñ+++++ Ñ Ñ Ñ Ñ(((( T T « « þ þ % € € €-- Ó- € € € €--ÚÚ¯¯¯¯ « « ö ö  nn ½™™G¡}0p2x$ïÆ\¯¯XXXX1 Ö Ö Ö„„ Ö Ö(((( z z z z Ñ+++++ÙÙpÃi¿ e== ç ç””((ÕÕ(‚ÕÕ(( zÕ(((( O O ü ü ¦ ¦ ¦ ¦ O O O O ü ü O O        ¶ ¶ ¶ ¶ººÂ†øŽooÅ kkøøCé8888\·Ýíݾ ¯¯ « «CC • • • •CC • • • • • • • •-- Ó Ó )„„„ Ö Ö Ö Ö Ö Ö1 Ö ì ì ? ? ì ì ì ìàïàЄ„1 Ö )„ÞÞÞ„1‹—Æ/V-ü"¡GIIööIIQQöö££ööööŽŽàà † †33 Ü ÜŠŠŽŽààM ò òMQöö · e e $ $ Ñ+ Í Í z z O O O O ¦ ¦ ¦ ¦ ü ü ü ü ¦ ¦SS[[WW[[­SS­b'à+ Ñ+++ Ñ Ñ Ñ Ñ Ñ Ñ((((¯¯ « « þ þ €Ú € €-- Ó- € € € €--ÚÚ T T T T Q Q ö ö Ènn ½™™G¡^}*À\¯¯XX³³1 Ö Ö Ö„„ Ö Ö(((( z z z z Ñ+++++ÙŽ%Ëÿ e== ç ç””((ÕÕ(‚ z z(( zÕ(((( O O ü ü ¦ ¦ ¦ ¦ O O O O ü ü O O         ¶ ¶ººgwÙÙÉkÅkkžSCé8888\ dd¾  ¯¯ « « « «CC • • • •CC • • • • • • • •-- Ó Ó )„„„ Ö Ö Ö Ö Ö Ö Ö1 ì ì ? ? ì ì ì ìrrÅz¤(Ó ´…ÞÞ1 Ö )„ÞÞÞ„ Ö1=¶'7+GסGIIööIIööööþþööööŽŽàà † †3377ŠŠŽŽààM ò òMö œöl · $ $ $ $ Í Í z z O O O OSSSS ü ü O O ¦ ¦SS[[[WW_jrb­­SSSSSSSµÙ~++++ Ñ Ñ~~~~((((¯¯ « « Q « € € € € € €-- € € € €--Ú5 « « Q Qnn   j j ìGôôüü©©\¯¯`Âw@1„„1 Ö Ö Ö(((((( zÕ~~~~+†èR—â€Ë¿¿¿ ã ã ç ç””(((‚ÕÕ(( z zÕ/(((( ü ü O O ¦ ¦ ¦ ¦ O O O O ü ü O O _ _ºº    cc ¶ ¶ººgggg––<<8888¯¯\\  \\ T T þX «CC • •CCðððð • • • • • •--Ú €„„1 Ö ) ) Ö Ö„„ Ö Ö ì ì ? ? ìG™™ÅÅÅz•¤B#11„„„Þ‹‹Þ„„„â—ùT±¡GGööööIIIIöö££££ööŽCè3àà33‘‘ŠŠàààà ò ò ò òIIIll $ $ $ $ Í Í z z O O O OSSSS ü ü O O ¦ ¦SS[jzű±_n!ó*( Üb­SSSSSS­­[Ù~++++++~~~~(((( T T « « Q « € € € € € €-- € € € €-- €Ú « « « «     j j ’ ì™™GGôô\¯¯`‡"¦‹„„1 Ö Ö Ö(((((( zÕ~~ÙÙà;&Û-Š*Õ" 5t¿¿ëë== ç ç””(((‚ÕÕ‚ Í z z zÕ(((( ü ü O O ¦ ¦ ¦ ¦ O O O O ü ü O O _ _ºº    cc ¶ ¶ºº  ººgg<<<<8888¯¯\\¯¯\\ T TX þ «CC • •CCðððð • • • • • •-- €ÚÞÞ Ö1„„ Ö Ö„„ Ö Ö ì ì ? ? ìG™™ÅÅÅzÐ+}È11„„Þ9õõ9Þ„„ˆˆ5¡GGGöö œ œIIIIööIIIIööèè3àà3377ŠŠ † †àà ò ò ò òIII » »SS ¦ ¦ O O O O ø ø K ¦ªª ü ü Í Í z z z z((±+$R~µ[µ/0U74d%ì‚‚‚ ¦ ¦ ¦­3ÙÙÙ++†† ¦ üW ü ü þ þ « « T T ) )„„„„Þ„ € €--- Ó € €¯¯ « « « « j j j j Á Ánn ? ?™™ððCC¯¯X³Ò XXXX ü ü O OªªªªªW± …+Ã5=7Z6/èõÏÇlll¿¿ i » »ªªªª ¦ ¦ ¦ ¦ ¦ ü üªª ¦ ¦SS ¦ ¦SS ¦ ¦ O O O O    ¶ ¶cc88888888c¾¾¾ºººººººº-------- Ö Ö ) )ÚÚ--ÅÅ ½ j j™™ ì ìCCðð„„ Ö1ÞÞ„„ÚÚ-- Ö Ö Ö Önn Á Á™™ôô¡¡ô™XX\l@Ö ³¯¯\·rrÅÅööIIIIIIŽè333333^^^^ ± ^^ Ç Ç Ç Ç Ç Çt » »SS ¦ ¦ªª O O ø ø K ¦ªª ü ü Í Í z z z z((Wf~ɵ[µ/.ú5¿4d(6ì‚‚‚ ¦ ¦ ¦­rŽÙÙ††;; ¦ üW ü ü þ þ « « T T ) ) ) )„„Þ„ € €--- Ó € € T T « « « « j j j j Á Ánn ? ? ? ? • •CC T TX³  d XXXX ü üªªªªªªª± Á ï3â7ò8µ7Z6­)$9Ï!Çll¿¿ i » »ªªªª ¦ ¦ K ¦ ¦ ¦ ¦ ¦ ü üªªSS ¦ ¦SS ¦ ¦ O O O O    ¶ ¶cc888888 Ý Ý c¾¾ ¶ ¶ºººººººº-------- Ö Ö„„ÚÚ-- j j ½ j j™™ ì ìCC • •„„1 Ö„„„„ € €-- Ö Ö Ö Önn™™™™GGô™XX\·!! ³¯¯\rrÅÅööIIIIII3Ž333333^^^^ ± ^^ Ç Ç Ç Ç!!t » » ¦ ¦ ü ü O OS ø øS ü ü O O Í Í z z z z Í(WW_­­[jb$&"ÌRÝ‚ÕÕ ¦ ¦SS­røŽ++++ààSS ¦ ¦ O O ü ü « «XX T T | Ö | Ö Ö Ö„„-- € €-- € € « «X þ j j j j Á Ánn™ ? ? ? • • • • T T T TXX³³¯¯ « «XX ü ü Oªªªªªªª_f:357E886/;"_õ„tÇlliiii ü ü ü ü ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ü üªª­S ¦ ¦SS ¦ ¦ ø ø O O O O _ _ _ _cc cå ‹ Ý8å ‹ ‹ ‹cc ¶ ¶      ºº € €ÚÚÚÚ-ˆ11 )„-- € € j j jÅ™™ ì ìCCCC„„1 Ö„„„ )---- Ö Ö Ö Önn Á™™ ìGNôG ìXX¯¯ d``³X¯¯År p pööIIIIIIàà333333 ± ± ±^^^^ Ç!tt Ç Çt » » ¦ ¦ ¦ ¦ ü ü O OS ø øS ü ü O O Í Í z z z z(‚ ü üª­­[Žè莂( z z ¦ ¦SS­ŽÙ++ Ñ Ñ++SS ¦ ¦ O O ü ü « «XX T T | Ö1 Ö Ö Ö„„-- € €--ÚÚ « «X þ j j j j Á Ánn™ ? ? ? • • • • T T T TXXXX¯¯ « « þ þ ü ü Oªªªªªªªª±%¬1Û5R5R4¥63ø.Ž X)ÇlÇliiii ü ü ü ü ¦ ¦ ¦ ¦ ¦ ¦ ü üªªS ø ¦ ¦SS ¦ ¦ ø ø O O O O _ _ _ _cc cå ‹8’å ‹ ‹ ‹cc ¶ ¶      _ _ € €ÚÚÚÚ-ˆ11„ )-- € € j j jÅrr™™ ì ìCCCC„„1 Ö„„„ )---- Ö Ö Ö Önn Á™™ ìü^NG ìXX¯¯¯ ``³X¯¯zÌrËËööIIIIII † †333333 ±   ^^^^ Ç!tt Ç Ç  » » » » » ü ü ü ü ü ü O O ¦ ¦ ¦ ¦ªªª O z z z z((ÕÕ ü ü ü ü­­+†††~~ Ñ Ñ ¦ ¦ øSªªªª+ Ñ++~ $~~ Oª O O ü ü ü ü « « « « « « þ þ )„„„ Ö Ö„„-- € €„„Þ„ T TXXXXnn   Á Ánn • • • • ì ì™™ « «XXXX` T T O OªªSSSSªªª¹~ B%k( 2G7±7Z6%ÖÃÃÃÿSS ¦ ü ü ü ü ø ø ¦ ¦ ü ü ü ü O Oª OSSSS ü ü ü ü ¦ ¦ ¦ ¦ _ _      å ‹8888å庺ºººº _ _ ¶ ¶ ¶ _ _  Ö Ö„„„„„„„„ Ö Ö---- jÅ Á Á Á Á™ ? ì ìððððÚÚÚÚ----„„ Ö Ö Ö Ö„„nnnnÅÅ ì ì ì¡Nô™\\¯¯¯¯ dd¾·\XX³³ÜëÜrtttt òMŸŸIIII33 †àŠŠŠŠbbtttttt Ç » » » » » ü ü ü ü ü ü O O ¦ ¦ ¦ ¦ O Oª O z z z z Í Í z z ü ü ü üSS Ñ+++~~ Ñ Ñ ¦ ¦ øS O O O O Ñ+++Ù~~~ª Oªª ü ü ü ü « « « « þ þ )„ ) ) Ö Ö„„-- € €„„Þ„ T TXXXXnnnn Á Ánn • • • • ì ì ? ? « «XX þ þ « « « T T O OªªSSSSªªª¹ˆ=#c0ì4¥3K#º1ÃÃii¿SS ¦ ü ü ü üSS ¦ ¦ ü ü ü ü O OªSSSS ü ü ü ü ¦ ¦ ¦ ¦ _ _      å ‹8888å庺ºººº _ _ ¶ ¶ ¶ _ _ Â Ö Ö ) )„„ ) ) ) ) Ö Ö---- jÅ Á Á Á Á™ ? ì ìððððÚÚÚÚ----„„ Ö Ö Ö Ö„„ÈÈÈÈÅÅ ì ì ì ìôôô™¯¯  dsÝ8{l³³³³‘Ürtttt òMŸŸIIII33 †àŠŠŠŠbbtttttt! » »ii » » ü üªªªª ü ü ¦ ¦ ¦ ¦ ü ¢ O O Í Í Í Í( Í(( ü ü ü üSSSS Ñ Ñ~~~~ Ñ Ñ ¦ ¦ ¦ ¦ O O ü ü~~++++++ªªª ü ü ü üXXXX « « þ þ Ö Ö Ö Ö Ö Ö11 € € € € Ö Ö1 Ö T T « « « « Á Ánn Á Á • • • • ì ì ì ì « « þ þ « «XX « « T T ¢ ü O OSSSS ü üªªW±__x-ê ®%Â!²‹!ii¿ eSSSS ü ü ü ü ¦ ¦ ü ü ü ü ü üªªSSSS ü ü ü ü ø ø ¦ ¦  ² ²    888888’’ººg _º  ¶ ¶cc _ _  Ö Ö )„„„ Ö Ö Ö Ö Ö Ö € € € € jÅ Á Á Á Á ì ì ì ìðJJðÚÚ------„„ Ö Ö„„ Ö1È#vvÌr™™ ì ì ì ì™™¯¯ T¯ ¾("ü-Ð,v"üλ`»`ÔzÅtt Ç ÇËËËË òM ò òIIII33337 ÜŠŠµµµbbµµtttt Ç Çt » »ii » »WWªªªª ü ü ¦ ¦ ¦ ¦ ü ¢ O O Í Í Í Í( Í(( ü ü ü üSSSS Ñ Ñ~~~~ Ñ Ñ ¦ ¦ ¦ ¦ªª ü ü~~+++++•n_ªª ü ü ü ü þ þXX « « þ þ Ö Ö Ö Ö Ö Ö Ö Ö € €ÚÚ Ö Ö1 Ö T T « « « « Á Ánn Á Á Á Á • • • • ì ì ì ì « « þ þ « «XX « « T T ¢ ü O OSSSS ü üªª± __Ë%„)!lii¿ eSSSS ü ü ü ü ¦ ¦ ü ü ü ü ü ü O O ø ø ø ø ü ü ü üSS ¦ ¦        88888888ººg _º  ¶ ¶ccºº  Ö Ö )„„„ Ö Ö Ö Ö Ö Ö € € € € jÅ Á Á Á Á ì ì ì ìðJJðÚÚˆˆ----„„ Ö Ö„„1‹#}ÐÐ'Ìrr™™ ì ì ì ì™™¯¯¯  ¾í1à7J8¤4•%±Ê»`ÅÅtt!!ËËËË òMMMIIII33337 ÜŠŠµµµbbµµtttt| Çt Oª ü ü ü ü˜˜==== » » » » e e e e ç ç ç ç=== ã Oª ü ü ¦ ¦ ¦ ¦ ¦ ¦SSSSSS””A ç çAA\M˜˜== T T § T T € € € € € € € € § « « þ þ J¤ ÷ ÷NN    NN     J¤ ÷ ÷N ó     ó ó ó ó Ì Ìyy"""" e eiiii » »)1Öà†††††Ù~W üªª ü ü ü ü › › › › ›õHH › › › › ñ ñ ñ ñ › › › › D D ñ ñssssss Æ Æ T TXXXX--ÚÚ Ö Ö Ö Önnnn Á ÁnnÅÅÅÅû       œ ÷ J J ÷ ÷ ÷ ÷¤¤ J J          ºgÂÂÂ5Úˆˆˆ-ÚÚXXXX¯¯\\¡¡¸±ü¡G Á Á Á Á nnnððô$A5Ú8 8 5X%2#CCJJÖÖ((,‡,,T®®®ªªª, Ò Ò ÒÖÖ(ƒëë>˜ï• ç OªWW ü ü====== » » » » e e e e ç ç ç ç=== ã Oª ü ü ¦ ¦ ¦ ¦ ¦ ¦SSSSSS””A ç çAAœò˜==== T T § T T € € € € € € € € § § § « « þ þ J¤ ÷ ÷NN     ó ó     J¤ ÷ ÷N ó     ó ó ó ó Ì Ìyy"""" e eiiiiÏý'É#ºðà++++Ù~ üWªª ü ü ü ü › › › › ›õHH › › › ›LL ñ ñ › › › › D D ñ ñs(ÎÎss Æ Æ T TXXXX--ÚÚ Ö Ö Ö Önnnn Á ÁÈÈ j jÅÅû       œ ÷ J J ÷ ÷ ÷ ÷¤¤¤¤        ggºÂÑ;;D5ˆˆˆ-ÚÚXXXX¯¯\\¡¡^±ü¡G Á ÁnÈÈÈJJôN¸(Q2£5X/î°}#CCððÖÖƒƒ,‡,,®¾s¾_ªª, Ò,,ÖÖ(ƒëë˜óï• ç üWWWW ü== === ã » » » » e e e e ç ç ç ç== ü ü ü ü ¦ ¦ ¦ ¦SSS­­­­­AA”””îAA˜= == T T T T T T € € € €- Ó € € § § T T¯ T §X þ þ þ J J ÷ ÷    NN ó ó     ÷ ÷ ÷ ÷         ó ó ó ó Ì&&&""""¿¿ii »iÃ1'É1ð(wJ†Ù~~~Ù~ Oª ü ü ü ü ü ü › › › @ ›õõ › › › › › ñ ñ D D › › › › — ñ ñ ñ Îssss Æ Æ¯¯XX « «ÚÚˆ-„„„„n nnnn j jrrû       œ ÷ J J¤¤ ÷ ÷¬QQ¬ººººggºººººÑ!-.*y\∈ÚÚÚÚ³X\\¯¯ôô©VüGG ÁnÈ#}RøJJôôVu#¿%‰ÐvnnCCCC { {ƒƒ,,,,cÝ#ü‚ W ý ý $ $ÖÖÖÖëëFFB ç•W±±±±W== === ã » » » » e e e e ç ç ç ç== ü ü ü ü ¦ ¦ ¦ ¦SSS­bÌöA””IXöA= ã == T T T T T T € € € €- Ó € € § § T T¯ T §X þ þ þ¤¤ ÷ ÷    NNNN     ÷ ÷ ÷ ÷        NNNN Ì&&&""""¿¿ » »ii »iÃ!æ£H•†Ù~~~Ù~ Oª ü ü ü ü ü ü › ›õ › ›õõ › › › › › ñ ñ D D › › › › — ñ ñ ñssssss Æ Æ¯¯XXÚÚ- Ó„„„„Èn Á ÁnnnnÅÅ j jrrû       ÷ œ J J¤¤QQa¬ºººº  ººººº,%1>.‰¶=ˆˆÚÚÚÚ» ³\\¯¯™™ôNü¡ ì ì ÁnÈ#œ¥ðôôüüÜÔzvnnCCCC { {(( Ò Ò,, ‚!G7 W ý ý $ $ÖÖÖÖëëëëB ç•Åjµ˜= ç ç” 9 9 9 9 9 ç ç ç ç » » » » ü ü ü ü O O ü üªªW Ô$¨( 6M===ö»þî ==== T T T T þ þ « «---- Ö | ) ) « « « « « « « «NNNN ÷ ÷¤¤ûûNNQQQQ ÷ ÷¤¤¤¤¤¤ÏÏÏ u u u u u » » » » e e¿¿¿¿t||3ÙÙ~ÕÕ((ª O ü ü ¦ ¦SS › ›HH › ›HH ñ ñ D D › ›HH ñ ñ ñ ñ îHHHÊÊssss¯¯¯¯¯¯¯¯----„„„„ j jnn Á ÁÅ j     ó ó ÷ ÷ J J ÷Q¬a%€ÃYºººº  º _  ººÅäüü£9Þ„ Ö111 d·\\\™™ôôJJððnnnnÈ#+"$ïf¡GGG¡¡##vÅÅCCðð Ò Ò((ƒƒ®cÅÅ®®TTÖ { { {, ÒÖÖÖÖ••BBëëë$¨!ój˜= ç ç” 9 9 9”” ç ç ç ç » » » » ü ü ü ü O O ü üªª±f$¨4æ5“*¿\˜˜˜œöî” ==== T T T T þ þ « «---- Ö | ) ) « « « « « « « «NNNN ÷ ÷¤¤ûûNNQQQQQQ¤¤¤¤¤¤ u uÏ u u u u u » » » » e e e e¿¿¿ÇÇÙ~Ù~ÕÕ((ª O ü üSS › ›HH › ›HH ñ ñ D D › ›HH ñ ñ ñ ñH£HHÊÊssss¯¯¯¯¯¯¯¯---- ) ) ) ) j jnn Á ÁÅ j    NN ÷ ÷¤¤ ÷Q¬) /Í%§i _ºº  º _  ººÅss9„Þ„ Ö111¯ ·\\\\™™™™ððððnnnnnÈv… V¡GGGGGÈÈvÅÅCC • • Ò Ò((((®®[[®®TTÖ {ÖÖ, ÒÖÖÖÖ••œœëëëªj/Ô˜= ç ç” 9 ç ç”” ç ç ç ç e e » » » » ã= ªª ü ü O O ü ü Oª¹ ™/|2Þ( ˜˜˜AA”” ë==¯ T þ þ « «---- Ö Ö Ö Ö « « « « T T T T « « « «NNNN ÷ ÷ ÷QûûNNQQÿÿÿ¤¤¤¤¤¤¤"""" È""" » » e e e e¿ elll¿¿~~ Ñ Ñ z z z z ü ü ü üS­SSHH › ›HH › › D D — — › ›HH ñ ñ D Dõõõõss! Ư¯¯¯ÚÚ-- ) ) Ö ÖÅÅ Á Ánn        ¤¤¤¤ ÷Q¬Ë'®-!—Âgººg ºº    c¾kk„„„„ Ö Ö1‹ dd \\¯¯ ì ì™™ððCCnn Á Á Á ÁvNNô™GG™™ ÁÅÅ • • • • Ò Ò Î(((((ƒÝÙ,, Ò ÒÖÖÖÖœœÿ¤ó˜ëª[µµ[˜= ç ç” 9 ç ç”” ç ç ç ç¿¿ » » » » ã= O O ü ü O O ü ü OªÔÜ'M˜== ç ç”” ë==¯ T þ þ « «---- Ö Ö Ö Ö « « « « T T T T « « « «NNNN ÷ ÷ ÷QûûNNQQÿ´Yÿ¤¤¤¤¤¤"""""}"" » » e e¿¿¿ elll¿¿~~ Ñ Ñ z zÕÕ ü ü ü ü øSSSHH › ›HH › ›ŸŸ ñ ñ › ›HH ñ ñŸŸõõõõwwss! Ư¯¯¯ € €--„„ Ö ÖÅÅ Á Ánn        ¤¤¤¤ ÷QQp%´Âgººg ºº  ggc¾„„„„ Ö Ö1‹¾¾d\\¯¯ ì ì™™ððCCnn Á Á Áôôô™GG™™ ÁÅÅ • • • • Ò Ò Î((((((ƒÙ,,,,ÖÖÖÖœ -!ˆMëÕÕÙÙ++ e e » »   ç ç””==== e e ç ç Œ Œ ¦ ¦ ø ø O OW ü~~~~33ààlliiii · » » » » « « « «\ « « « « « « « «\¯¯ ÷ ÷ ÷ ÷ ÷ ÷QQÏÏÏÏ&úEÛÓyÏÏ""¤¤ ÷ ÷¤¤ J J » » » » » » » » 6==ëëëë~~ Ñ ÑÕÕÕ z z z z z zÕÕÕ Æ! Æ Æss Æ Æ p p Æ Æ   p pÊÊÊ%wwÊÊwwwXXXX T T T T™™ ì ìCCð •™™ ì ì™™ ì ì"" u uyy&&ûû¨¨Yÿggººcc¾¾ ¶ ¶cccc Ö Ö1111Þ9‡"¦–d¯nnnn ÁvNôGGGG™™nnnn Á Á™™™ ?CCCC ì ì ì ì ý ý ý ý ¦ ¦T ù((((((((ªª ý ý ¦TTÖÖƒƒ,,,,u£0–1ñ&ÄÕÕ~~++¿¿ » »ii ç ç””==== e e ç ç ç ç ¦ ¦ ø ø O OW ü~~~~~~++iiii · » » » » « « « «\ « « « « « « « «\¯¯ ÷ ÷ ÷ ÷ ÷ ÷QQÏÏÏÏ ¿.H(ÞUˆ.ÏÏ""¤¤ ÷ ÷ J J J J » » » » » » » »ë ==ëëëë~~ Ñ ÑÕÕÕ z z z z z zÕÕÕ! Æ Æ Æss Æ Æ p p Æ Æ  ÊÊÊÊÊ%ww%%ÒÒÒwXXXX T T T T™™ ì ìCCð •™™ ì ì™™GG""ÏÏyy&&ûûNNQQÿ¤  ººcccc ¶ ¶ ¶ ¶cccc Ö Ö1111Þî%[2ä.Ô‡d¯nnnn ÁvNôGGGG™™nnnn Á Á™™™ ?CCCC ì ì ì ì ý ý ý ý ¦ ¦ ùT((((((((ªª ý ý ¦TTÖÖ(( Ò Ò,,ß'+," &Ä zÕ $ $~~   » » ç ç””==== e e”” ç ç= ã== ¦ ¦ ¦ ¦ O Oª~~~~++~ $ e eiiii¿ e e eiiii « « þ þ T T T T¯¯ « «XXXX T T¯¯¤¤¤¤ÿÿY´„*Ï*Ó˜*85 3²"ã.ÏÏ"" ÷ ÷ ÷ ÷ J¤ J J » » » » » » » »== ==== Ñ Ñ~~‚((((( z z((‚( Æ Æssss Æ Æw Æ Æ  ÊÊÊÊÊ%%%%,Ò³³`XX « « T T™™ ì ì •ðð • ? ? ì ì ìG™™"""" Ì ÌyyNNNN¤¤QQ    cc ¶ ¶cccc ¶ ) )„„„Þ1@D(½&µ,·\ Á Ánn Á ÁnÈ¡¡GGGG™™nnnnnnnnG ì ì ìCCCC ì ì ì ì ý ý ý ýTTTT(( { {ÖÖÖÖªª ý ýTT ¦ {Ö((Ùm"ŒçÛq zÕ $ $~~ii » » ç ç””==== e e”” ç ç= ã ã ã ¦ ¦ O Oª O~~~~ Ñ Ñ~ $ e eiiii¿ e e eiiii þ þ T T T T¯¯ « «XXXX T T¯¯¤¤¤¤ÿ´Óâþ9„*Óã &)'ƒUˆÓÏÏ""QQ ÷ ÷ J¤ J J » » » » » » » »== ==== Ñ Ñ~~‚(((((ÕÕ((‚( Æ Æssss Æ Æw Æ Æ   p pÊÊÊ%Ú444‡,  `XX « «¯¯™™ ì ì •ðð • ? ? ì ì ìG™™"""" Ì ÌyyNNNN¤¤QQ    cc ¶ ¶cccc ¶ ) )„„„Þ‹æpÊw·\ Á Á   Á ÁnÈGG ì ìGG™™nnnnnnnnG ì ì ìCCCC ì ì ì ì ý ý ý ýTTTT((ÖÖÖÖÖÖªª ý ýTT ¦ {Ö((ÙmmÈ"Ì(((( zÕiiii » » » » ç ç””====¿¿¿¿l== ã ã ü üª O ¦ ¦ ¦ ¦ z z zÕ z z(( » » » »¿¿¿¿¿ll¯¯XX « « þXXX T T¯¯XXXX\¯  ¯ûû¨¨´ˆ-Æ4Š-ñXŒ×**ŒA˜ã&ÏÏ""¤¤ ÷ ÷¤¤¤ Jii » »ii » ç ç 9 9 ==+ Ñ Ñ+ÕÕÕÕ Ñ Ñ~~~~ Ñ Ñssss! Æ Æ Æ! Æss p p   Æ ÆÊÊ%%,‡<Kªªš‹¾  ¯ « « « «\ « « ì ì ì ì • •CC • •CCCCCC Ì& Ì Ì Ì Ì& Ì ÷ ÷ J J¤¤QQccccºººº ¶cc1 Ö Ö Ö--ˆâ    ·\ÅÅ Á ÁððCCCC • • j j Á ÁnnððCðððð™™ ì 쪪 ý ýTT(ƒ((,,T®TTTTTT(( { {((ÖÖmmmÄÄi Í Í(( zÕiiii » » » » ç ç””====¿¿Çl== ã ã ü üª O ¦ ¦ ¦ ¦ z z zÕ z z(( » »¿¿¿¿¿|| TXX « « þXXX T T¯¯XXXX\¯  ¯ûû¨¨´"ò4Š8š4µ#Œ×ÏÏ××ÓÓ& Ì u u""¤¤ ÷ ÷¤¤¤ Jiiii » ç ç 9 9 == Ñ++ ÑÕÕÕÕ Ñ Ñ~~~~ Ñ Ñssss Æ! Æ Æ! Æss p pss Æ ÆÊÊ%%,<['Ô,è*3_šd ¯ « « « «\ ì ì ì ì • •CC • •CCCCCC Ì& Ì Ì Ì Ì& Ì ÷ ÷¤¤¤¤QQcccc _ _ _ _ ¶¾¾1 Ö Ö Ö---ˆ³³³³\ÅÅððCC • • j j Á ÁnnððCðð • •™™ ì 쪪 ý ýTT(ƒ((,,T®TTTTTT(( { {((ÖÖmmmÄÄi Í Í((ÕÕ » » » » » » » » ç çî”====tÞ‹Çëëë ã ã ã= ü ü ü ü ¦ ¦SS z zÕÕ(((( e e e e » »ii¿¿lllÇ„„·¯¯X³XX « « «¯¯ « « « «¯ T T T T¯ ¯¨N¨¨.s3Ý0¦ Œ×}}**&&& Ì"""" J J ÷ ÷ ÷ ÷ J Jiiiiiiii ç ç ç ç== $~~ $((((~~ Ñ Ñ Ñ Ñ~~ Æ Æ Æ Æss Æ Æ Æ Æ Æ ÆÊÊsssswwwÒ‡ñ%1N50÷%v¢  ¯ « « « «¯¯³XXX ì ì ì ì • •CCCC • • • • • • Ì&&& Ì Ì Ì Ì¤¤¤¤ J¤¤¤cccc _ _ _ºcc¾¾¾c ¶„„Þ„-- €Ú¯¯\ÅÅ Á ÁnnCCðð • •ð • j j ÁCC •ðððCC™™ ì ì ýWW ýTT(( { { ¦ ¦ ¦ ¦TT((ÖÖ((ÖÖÀÀÀ eiii(((( z z » » » » » » » » ç ç” 9====ll)!²!Öëëë ã ã= ã ü ü ü ü ¦ ¦ ø ø z z z z Í Í(( e e e e » »ii¿t!!Çltt·¯¯X³XX « « « T T « « « «¯ T T T¯ T¯ ]¨¨¬aË5%Ò A×""ÏÏ&&& Ì"""" J J ÷ ÷ ÷ ÷ J JiiiiiiiiAA ç ç== ~ $~ $((((~~ Ñ Ñ Ñ Ñ~~ Æ Æ Æ Æss Æ Æ Æ Æ Æ ÆÊÊsssswwÒ,áK#Å/ó2R.B!fG ¯  Q « «¯¯³XXX ì ì ì ì • •CCCC • • • • • • Ì&&&&& Ì Ì¤¤¤¤ J¤¤¤ccccºº _ºcccc¾ck„„Þ„-- €Ú¯¯\ j jrr Á ÁnnCC • • • •ð • j j ÁCC •ðððCC™™ ì ì ýWW²TT(( { { $ $ ¦ ¦ ¦ ¦TT((ÖÖ((ÖÖÀÀÀ eiii ¦ ¦ ¦ ¦ ¦ ¦ ¦SSªª ü ü Ñ Ñ Ñ Ñ((((ll!æ„t==ë = ã » »ii · · · ã ã== ç ç ç ç == 9 9 çA„““ÖÇ\\    ³X„„1 Ö Ö Ö Ö Ö T TXXXX Ó Ó € € €Ú-ˆCC<<’G¢ $¸"Õkcc¾¾      ggå ‹88ŽŽŽŽªªªªSSSS(((((((( ”” ç ç== ë == ›õHHHH › › Æ!ss´´´´  fÀ.ò%·&»!QŒ}+Å j Á Á Á Á Á ÁÅ j ÁnnCC • • ì ì ì ì Ì Ì&ÏÏ u uNNNNNNNNŽŽ á á á á 4 4 á á<<ŽŽéé™™GGCCðð™™GGCðð„„11---- Ö Ö Ö Ö Ö Ö„„ Á Ánn Á Ánn • •CCCCððXXXX ¦ ¦ªª P P(( { {((((,,((ÖÖ••BB••• ¦ ¦ ¦ ¦ ¦ ¦ ¦SSªª ü ü Ñ Ñ++((((lÇ¿==ë = ã » »iil · · ã ã== ç ç ç ç == 9 9Aœ„# /;/;#ºÖ\\  hh „„1 Ö Ö Ö Ö Ö¯¯XXXX Ó Ó € € €Ú-ˆŽŽ á á’’í¢// kcccc      ggå ‹88ŽŽŽŽªªªªSSSS((((((((ëë ”” ç ç== ë == ›õHHHH › › Æ!ss´´´´   fiÄÓ.2}"ÈÐvÅ j Á Á Á Á Á Á Á ÁÅ ÁnnCC • • ì ì ì ì Ì Ì Ì&ÏÏ u uNNNNNNNNŽŽ á á á á 4 4 á á á áŽŽŽŽ™™ ì ìCC • •™™GGCðð„„11---- Ö Ö Ö Ö Ö Ö„„ Á Ánn Á Ánn • •CCCCððXXXXªª P P(( { {(((( Ò Ò((ÖÖ••BB••• ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦SS ü üªª~~++ÕÕÕÕl¿¿¿¿ëë== ã ã » »ii¿ e · · ã ãëë ç ç ç çë ç çîI“/;6­6­+,9Çl¯  ¾%ÚÊ»„„ Ö Ö Ö Ö Ö Ö « « « « € € €ÚÚ € €ÚŽŽ 4Žåå@šÅÅkc ¶ ¶  _ _    8888 á á á ᪪ªª ¦ ¦ ¦ ¦((((((((ëë ”” ç ç ======HHõ › › ›HHssss´´´´^¸¸¸iqqm#ÈÈnÅÅ Á Ánn Á Ánnr'#nnnð • • • ì ì ?™yyyyÏ u""NNNNNNNNŽŽ á á á á 4 4 4 4 á ᎎ á á ì ì ì ’CCCCGG™ôðð11ÞÞÚÚÚÚ Ö Ö Ö Ö„„ Ö Ö Á Ánn Á ÁnnCCððððCCXXXXTTWWªªÖ { Î Î Ò Ò(((( Ò Ò Ò Ò((ÖÖ••••BBB ¦ ¦ ¦ ¦ ¦ ¦SS ü üªª~~++ÕÕÕÕl e e e eë똘== » »ii¿==ëë ç ç ç çë ç ç”îÞ'1C1C%„Çl¯ ¾Ý*,Í&%9„ Ö Ö Ö Ö Ö Ö « « « « € € €Ú5ÚÚ € 4 4 4Žåå@å ¶¾c ¶ ¶  ºº    8888 á á á ᪪ªª ¦ ¦ ¦ ¦((((((((ëëëë”” ç ç ======HHõ › › ›HHssss´´´´^¸^^´¼¼ff¸ÈnnÈ j j Á ÁnnnnrrÈÈnnð • • • ì ì™ ?yyyy uÏ""NNNNNNNNŽŽ á á á á 4 4ŽŽ<<ŽŽ á á ì ìG ìCCCC ì ì™ôCCðð11ÞÞÚÚÚÚ Ö Ö Ö Ö„„ Ö Ö Á Ánn Á ÁnnCCððððCCXXXXTT ý ýªªÖ {((,,(((( Ò Ò Ò Ò((ÖÖ•••JœœB­S ü ü O O ¦ ¦ ¦ ¦ OªªÙÙÙ~ z z(( e e » » » »====ëë ll”îî””” ç ç” 9 ç ç ç çAAÏ“£ X=\·s%±5B6/+Ýæ1 Ö | Ó--- T T T T ) ) )„11 Ö Ö á á 4Ž8’@庺 ¶cc _ _ººccccŽŽŽŽ8888SSSS ¦ ¦ z z z z~~ Ñ Ñ====== ==ë ====ŸŸ ñ ñ ñ ñ ñ ñ Æ Æ s! Æss^^^^¸^ ± ´´bb¸f Årrnn Á Á Ánnnn Á ÁrrCC èCCC • •"""" uÏ""¤¤ ÷ ÷      û88888888ŽŽŽŽ88 ‹ ‹ ìG™™ ì ì™™CCCC ì ì™ôÚ5ˆˆ„„„„ Ö Ö„„„„ Ö Önn Á Á Á Á Á ÁCCCCCCCC¯¯ªªªªTTÖÖƒ( Ò Ò((((,,BB•¤ûF˜­S ü ü O O ¦ ¦ ¦ ¦ OªªèŽ~ÕÕ(( e e » »==== lÇÇlllîþXI”” ç ç” 9 ç ç ç çAAtÏÏxÃ\·!¢135B0…8æ1 Ö | Ó--- T T T T„„ )„ Ö Ö Ö Ö<< 4Ž’íõšºº ¶ccºº _ _ccccŽŽŽŽ8888SSSS ¦ ¦ z z z z~~ Ñ Ñ====== ==ë ====ŸŸ ñ ñ ñ ñ ñ ñ!!sÎ! Æss^^^^¸^ ± ´´bb¸^ ±Ånn Á Á Ánn Á Á Á Ánn Á Á ½ ½CCC èCC • •"" È È uÏ""¤¤ ÷ ÷      û88888888 4 4ŽŽ88 ‹ ‹ ìG™™GG™™CCCC ì ì™ôÚ5ˆˆ„„„„ Ö Ö„„„„ Ö Önn Á Á Á Á Á ÁCCCCCCCC¯¯\\ªªªªTTÖÖƒ(,,((((,,BBïJ ë˜SS ü ü O O ¦ ¦ ¦ ¦ OªW±CŽ~ÕÕ(( e e » »ii==== e¿ÇÖÞ)tööî”””” 9 ç ç””AAllÇÃÃ\\!å õå!‹1Þ„ € €-- T T T T¯ T Ö Ö Ö Ö„„ Ö ÖŽŽ<<@š¢GÂgººcc    ²cccc á á á á8888S­S ø ¦ ¦((((++++˜˜==ë ëëëë====ùŸ ñ ñ ñ ñ ñ ñssssss Æ Æ^^ ±^^^^´´  ^^rrÅÅ Á Á ÁÈn Á Á Á Á Á ÁnnCC • •C è •ðÏ u u u""""Q ÷ ÷ ÷NNûûåååå ‹ ‹ ‹ ‹Ž 4ŽŽ ‹ ‹88 ìG™™™™™™CCCC ì ì™ô5∄„1111„„ Ö Ö1 Önn Á ÁnnnnCCCCððC\\\\ªªªª[¶[, Ò,,ƒƒ((ÖÖ {Ö Ò,ÙÙBBBBëëëSS ü ü O O ¦ ¦ ¦ ¦ Oª üW3ŽÙ~ z z(( e e » »ii====ëë ¿Ö!'$g“ÏöœœA” 9 9 9” 9 ç ç”” ç ç ·lii\\\·ll‹1Þ„ € €-- T T T T T¯ Ö Ö Ö Ö„„ Ö ÖŽŽ<<@šíGÂgººcc   g cccc á á á á8888S­ ¦ ¦S­ ¦ ¦(((( Ñ Ñ++˜˜==ë ëëëë====Ÿ D ñ ñ ñ ñ ñ ñssss   Æ Æ^^ ±  ^^´´  ^^rrÅÅ Á Á ÁÈn Á Á Á Á Á ÁnnCC • •C è •ðÏ u u u""""Q ÷ ÷ ÷NNûûåååå ‹ ‹ ‹ ‹ 4ŽŽŽ ‹ ‹88 ìG™™™™™™CCCCGGôNù L=ÞÞ1111„„ Ö Ö1 Önn Á ÁnnnnCCCCððC\\\\ªªªª[¶‡,,,ƒƒ((ÖÖÖ0‡,ÙÙBBBBëëë z z Ñ Ñ~~S ø ¦ ¦ ü ü OªWW ü ü O O O O · e e¿¿¿¿ == ã ã=ò!1n6+3v!ÞUÃii e e e e 9 9 9 9==== » »iiiiiiÚÚ-ˆââââ³X « « « « þXXX þ þ « « « « Ö Ö„„ÚÚ-- ¶kÅÍskÅéŽŽŽ á< á Ẻg ºº gcccccc((((ÕÕ zÕ(((( z z zÕ¿¿¿¿ii » »ii » » p pÊÊ Æ Æ Æ! ñ ñŸŸ D D DŸ  ^^  ± ±ðð™™™™™™™™ ? ?™™ • •CC ì ì ?™ ì ì ?™CC • •Ï u""""""}" uÏyyyycccc    8’88 ‹ ‹88CCððCCCCCCCCððø¼&3.R$,£5ÚÚÚ¯¯¯¯ «™™ ì ì™™™™ÅÅÅÅnȈˆ5Ú²WªªWW,,ÖÖÖÖªª ý ýT®,,Ù,,BBBBFë> z z Ñ Ñ~~S ø ¦ ¦ ü üª O ü ü ü ü O O O O · e e e e¿¿ =====ò*ª4Ñ2!ÞUÃii e e e e 9 9 9 9 ã ã== » »iiiiiiÚÚ-ˆˆˆˆˆ³X « « « « þXXXXX « « « « Ö Ö„„ÚÚ--k ä!VGzkéŽŽŽ ‡ á á Ẻg ºº g¾¾¾¾cc((((ÕÕ zÕ(((( z z zÕ¿¿¿¿ii » »ii » » p pÊÊ Æ Æ Æ! ñ ñŸŸ D DŸù^^^^ ± ± ± ±CCðð™™™™™™™™™™™™ • •CC ì ì ?™ ì ì ?™CC • •Ï u""""""}" uÏyyyycccc    ’888åå88CCððCCCCCCððø&/­5/X5ÚÚÚ¯¯¯¯ «™™ ì ì™™™™ÅÅÅÅÈ#==5²Wªª ý ýªª,,ÖÖÖÖªª ý ýT®,,Ù Ò ÒBBBBFë> Í Í Ñ Ñ Ñ Ñ ¦ ¦S ø ü ü ü ü ü ü O O O O O O e e e e e e == ëëE§l!0{\ò e e e e 9 9 ç ç == » »iiiiii €Ú------XXXX « «XX « « « « « « Ö Ö„„-ˆÚÚkŠ+}4I,*äkéŽ< á 4Ž<<ººººº gÅzÍcc(((((((‚ÕÕ((ÕÕÕÕl¿¿ » » »iii   p p Æ Æss ñ ñŸŸ ñ ñŸŸ´´ ­^^^^´´ ± ±^^ • •ðð™™™™™™ ìGGG ì ì • •CC ? ? ì ì ì ì ? ?CC • •""""""""""""yyyycc    88åå88ååCCððððððððððððb É'Ž"$õˆˆ-ˆ¯¯¯¯XX « « ì ì™™™™ ìGrrvПD—â²WWWªª ý ý((ÖÖ ýW ý ýTTTT,,,,,,,,BBBB˜˜ë Í Í Ñ Ñ v v ¦ ¦S ø ü ü ü ü ü ü O O O O O O e e e e e e ã ã ëëEòM§§òò » » e e e e”” ç ç == » »iiiiii €Ú------XXXX « «XX « « « « « « Ö Ö„„ˆâÚÚkz$¸.ß,*?ÅéŽ< á 4Ž<<ºoÉogÂzNGscc(((((((‚ÕÕ‚‚ÕÕ//l¿¿ » » »iii   p p Æ Æss ñ ñŸŸ ñ ñ D D´´ ­  ^^ Z Z ± ±^^ • •ðð™™™™™™G ì ì ì ì ì • •CC™™ ì ì ì ì™™CC • •"""""""""""×yyyy ¶ ¶cc    88åå’’ååCCðððððð • •ððððø›õ›‹ˆˆ-ˆ¯¯¯¯XX « « ì ì™™™™ ìGrrvПùL— ²WWªª ý ýÙÙ((00W ý ý ýTTTT,,,,,,,,BBBB˜˜F(( $ $ $~ ü üª O ¦ ¦ ø ø O O Oª ¦ ¦ ¦ ¦ » »   » » » » ç ç ç ç 똘ëE˜˜˜˜i    e e==== ii » » » » » € €-- | Ö„ ) «XX T T « « « « « « « «„„ Ö ÖÚÚ--c¾ /ääÍ<<< ᎎéCo3ø3†áccccÕÕÕÕ++++ÕÕ/ÕÕ//Š e e¿¿ii » » Æ Æssssss ñ ñŸŸHHHH   ± ±´´´´ • •CCððððððððððCC™™™™ ? ? ì ì™™ô™ ì ì ? ? u u È Èyy&&yyyy""""    cccc 4 4<<ŽéŽŽ ìG™™™™ ì ìððCC™™™ô55ÚÚÚÚ³³¯¯ ì ì™™ððrÌÌ'Ÿùùê ®TT ý ý ý ý Ò Ò,,‡<¶[®TTTÖÖÖÖƒƒƒƒ˜˜˜˜óM¨ Í Í $ $ $~ ü üª O ¦ ¦SSªªª O ¦ ¦ ¦ ¦ » »ii » » » » ç ç ç ç ë== ë==˜˜i    · · e e==== ii » » » € €-- | Ö„ ) «XX T T « « « « « « « «„„11ÚÚ--c¾kÅkkc<< á<ŽŽéC$ R+&!­wgººÂÂÂgcccc z z z z++++//Š/Õ//Špp¿¿¿¿llii » » Æ ÆssssssLLŸŸHHHH^^ ± ±´´bb´´ððððððððððððCC™™™™ ? ? ì ì™™ô™ ì ì ? ? u u""yy&&yyyy""""    cccc 4 4 á á 4ŽŽŽ ìG™™™™ ì ìððCC™™™ô55ÚÚÚÚÚÚ³³¯¯ ì ì™™ððrrÌDêê ®TT ý ý ý ý Ò Ò Ò Ò‡ñŶ®TTTÖÖÖÖƒƒƒƒ˜˜óóM"‹ z z $~~~ ü ü ü ü ¦ ¦SS üW ü ¢ ¦ ¦ a »iiiiii ç ç 9” ã ã =˜ëë » » » » · · e e = ã ii » »ii »- Ó € € Ö1 Ö ÖXX « «¯¯ T TXXX þ « «„„11-ˆÚÚ¾¾¾c á á á<< á<K,†ðáÂgººººººcccc z zÕÕ++++Õ/‚‚‚‚ÝÝppÃll¿¿¿¿¿iii  Æ Æss Æ!ssŸŸŸŸHHHH^^ ± ´´bbb´´JJJ¥øððððððCCCGG™ôô™™™ ì ì™™™™ ì ì u uÏÏ Ì Ì Ì&yyyy u u u u  º _cc¾c á á á á á á<<™ôGG™™ ìGCCðð ì ì™™ˆ-ÚÚÚÚÚÚ³³³³\\\ ì ì™™ððnnnnÅÅrÌââââ[[ Pªª P Ò Ò‡<¾ TTƒ((((ƒÖÖëFMó°%î2É z z $~~~ ü ü ü ü ¦ ¦ ø ø üW ü ¢ ¦ ¦ »ÃÃiiii ç ç 9” ã ã ã=ëë » » e e = ã ii » »ii »ˆ- € € Ö1 Ö Ö þ þ « « T T T TXX « «X þ « «„„ Ö Öˆâkk¾¾¾c á á á<< á–¦wÂg ººººººcccc z zÕÕ++++Õ/ÝÝÝÝÝ’ËËÃll¿¿¿¿¿iii  Æ Æss Æ!ssŸŸŸŸHHHH^^ ± Z Zbbb¥¥¥ÿøððððððCCCGü^¸ô™™ ì ì™™™™ ì ì u uÏÏ Ì Ì Ì&yyyy u u u u  º _ccc á á á á á á<<™ôGGô ? ’ ìCCðð ì ì™™ˆ-ÚÚÚÚÚÚ³³  \\\ ì ì™™ððnnnnÅÅr̈ˆˆˆªª Ò ÒÙÙ,,®®TT(ƒƒƒ(ƒÖÖëFóM°(£5~ Æ Æ p p  ºº ¶ ¶ ¶ ¶cc     ¤ÿÿÿUUNN Ì Ì Ì& Ì&& Ì    ¶ ¶cc ¶ ¶cc       N ó J¤ ÷ ÷  û        N¨ÚÚÚ € Ö Ö ) ) « « « « T T Ö Ö Ö Ö € €--¯¯\·l0{zÅÅn  ì ì™™CCJJvvÈÈÅÅnnnn--Ú5ˆˆˆˆ„Þ9“â=Dùp»`·\¯¯XX¯¯¯ T J J ÷ ÷ ÷QQQûûû          88å ‹ ‹å’ Ý _ _ ggÂoÉ,‡44Òw££HHŸŸŸù¼#¯%  Z Z^^^^ Æ Æ Æ Æ Æ Æ Æ Æss! ÆÊ p › › › › › ›HHss Æ Æwww//ÕÕÕ z((ÕÕ‚‚ Ñ Ñ~~WWWWWWªªÝìG’†+~~ÊÊ!!ssHHHHŸŸùùõõõõNNûûN©ûûNNNN¥ÿRR““ææ—<< âææææ]]e¿Çæ(g Æ Æ p p  ºº ¶ ¶ cc  ggÿY´´  N Ì Ì Ì& Ì&6&    ¶ ¶cc ¶ ¶ccgg     N ó J¤ ÷ ÷  û        N¨ÚÚ €Ú Ö Ö„„ « « « « T T Ö Ö Ö Ö € €--¯¯\\0{zÅÅ Á Án  ì ì™™CCððÈÈÅÅnnnn--Ú5ˆˆ--„Þ9“=—ùcÚÊ»·\¯¯XX¯¯ T¯¤¤ ÷ ÷Q¬¬¬ûûû          88å ‹å ‹88ºº ggÂ$~á<DDé4,Ò££HHŸŸŸù/Þ3í*t&´´^^^^ Æ Æ Æ Æ Æ Æ Æ Æss! Æ%Ê › ›õõ › ›HHss!!wÒÒÒ/// zÕ z((ÕÕ((++ÙÙWWWWWW OG"u'ß ;+~~ÊÊ!!ss££HHŸŸŸŸõõõõNNûû©NûûNNNN¥ÿRR““ææ< â â<ææææ]]e¿llÏ Æ Æ p p _ _ºº ¶ ¶ ¶ ¶ ¶ ¶ ² ºYÃ-xÇm¨yyyy Ì&& Ì    ¶ ¶ ¶ ¶Åooºº         ÷ ÷¤ J ó ó        ûû--ÚÚ Ö Ö„„ « « « « T T Ö Ö Ö | € €--¯ \\  ddrrnn Á Á ì ì™™CC èCnnÅÅ j jnnnn €Ú555ÚÚÚ„„‹@ò\!Í(’$<whd \\XX¯¯¤ÿ¤¤Yii´°ûû          8888å ‹88ººggo$~ñ c®ž‡Òý£õõŸŸLLi.&d.ƒ'¿Ìbb´´b^^^^ss Æ! Æ Æ Æ Æ Æ!s ÊÊHH£HH îHHsssÎÚéñ<7‚ÕÕ((((((((~3;•f±ªªªªô!È'2^3Ù~~ p p!!ssõõHHŸŸ ñLõõõõNNûûNNû ¡ûûûûRRÿ¥ææææ â âææ99]]  e¿ Æ Æ p p _ _ _ _ ¶ ¶ ¶ ¶ ¶ ¶ ¶ ¶ ² º´"ò0{-ÆŒ¨yyÓÓ& Ì Ì&    ¶ ¶ ¶ ¶Å$oºº         ÷ ÷¤ J ó ó        ûû--ÚÚ Ö Ö ) ) « « « « T T Ö Ö1 Ö € €--¯¾\¯¯¯¯nn Á Á ì ì™™CCC#Ø+vÅÅÅÅnnnn €ÚÚÚ5ÚÚÚÞÞ‹@¶&Š2 65™.Ô!Kd \\XX¯¯ J¤¤¤ ='â°Uû        8888 ‹å88ººggoÉ~Ž"j+ä0¡-ì$rù<‡ý£õõŸŸLLiÌbb´´b^^^^ss! Æ Æ Æ Æ Æ Æ!ÎsÊÊHH£H îHHHssÎ(ù)Ü/ó'ÔüÝÕÕ((((((((ÙŽ´&.•ÁªªªªŠ?ô?3Ù~~ p p Æ{ssõõHHŸŸL¦õõõõNNûûNNû ¡ûûûûRRÿ¥@@ææ â âææ““]]°° e· p p p p  _ _ ¶ ¶  _ _ _ _ºo¿'X/w* |¸UU uÏÏÏ"""" ¶  _ _ _ _ gkcc         J J¤ J ÷ ÷ ÷ ÷ œ ÷ ÷Qˆˆ--„„ Ö Ö T T T T T T Ö Ö„ ) € €--»` « « « « j jÅÅnnn  ì ì ì ì • •ðð'Ìvnn j jrÅ--ÚÚ„„„„1‹9H&Š48#8#65B+Ýl· ¯³³XXXX J JQ¬"*º2Ù,!N¨N     á á á á88 ‹ ‹cck /™'Ô485]->é4ªPõõ££HHbbi´´^^ ± ± ± ± ± Æ!ssÊ p pÊ Æ Æss!!!!L ñŸŸHHHHÊÊ%Ú!2¨6¸2¨fÝ‚‚‚(((~~~~+;+˜&Å­­SS[Ù33ÙÙÙ~~ p pss Æ!õõõõHHõõŸŸŸŸûûûûN©NN øRRRûû©©êê<<<<<<@æ““““““]]] p p p p ² ² _ _cc ¶ ¶  _ _ºººo))t¸]ûûÏ u u u"" È È ¶  _ _ _ _ ² ¶cc         J J J¤ ÷ ÷ ÷ ÷ ÷QQ ÷----„„ Ö Ö T T T T T T Ö Ö„ ) € €-- « « « « « j j j jnnn  ì ì ì ì • • • •rÌÌÌvnnÅÅrÅ--ÚÚ„„ÞÞ‹æî²-O8#8#8#7÷65ï(fÖld ³³``XXXX¤¤Q¬¸|"›#ö!ît¨¨Nûû á á á á88 ‹ ‹cck Õ?&z2¨6¸4*‰ÚPõõõHHHHbbbb´´´^^ ± ± ± ± ± Æ!ssÊ p pÊ Æ Æss{{{{¦LŸŸHHHHÊÊÊñ'Ô->)/üÝ‚‚‚(((~~~~+†•ÿµ­­SS[~ÙÙ~~~~3wwÊÊss Æ!õõõõHHõõŸŸŸŸûûûûN©NNR­RRûû©©<<<<<<æ@““““““]]] p p p pÊÊ _ _ _ _ccºº _ _  º¸¸ °UUNNÏ u""Ï u u u ¶ ¶ ¶ ¶ _ _  º _ _ _ ¶ ¶cc ó ó ó ó J J ÷ ÷¤¤¤¤¤¤ ÷ ÷--- Ó Ö Ö„„ T T¯ T„„ ) ) € €-- « « « « « « ½ Á Á ì ì ì ì è è èCÅÅÅÅnn Á ÁrÅÅÅÅÅ jˆˆÚÚ11‹‹9“î .©8#8#6È7J7J5B#ª!l·\X³XXXXQQ¤ÿ° ¿¿]¨NNNûû< ᎎ ‹åååccc¾¾(Ý['Ô+7+7#ÅKá,££PõHHõõbbbb´´´´^^^^  ± ±ssss Æ ÆssÎÎ0å[¦ŸŸõõõõÊÊ%%ÚDùD7‚‚‚‚‚((~~~~+†33­SS~Ù++~~~~ÊÊÊÊ! Æssõõõõ££HHŸŸŸŸûûûû©©N©RRRR©©ûû<<<<<<< â““““ææææ]]] p p p p p p _ _ _ _ ¶ ¶ccºººº  _º¨¨UûûûNNÏ u""Ï u u u ¶ ¶ ¶ ¶ _ _  º _ _ _ ¶ ¶cc ó ó ó ó J J ÷ ÷¤¤¤¤¤¤ ÷ ÷--- Ó Ö Ö„„ T T T¯„„ ) ) € €-- « « « « « « « « ½ Á Á Á Á ì ì ì ì è è èCÅÅÅÅ   Á ÁrÅÅÅÅ jňˆÚÚ1111Þ9“H"{46È8#7J7J/Ø@Æ\·³XXXXX ÷ ÷¤ÿûUUU¨NNNûû< ᎎ ‹åååccc¾¾s(ñK<‡Ò££PõHHõõ´´´´¸¸^^    Î ss Æ Æss΃&# äùùõõõõÊÊÊÊ%%‚‚((((((~~~~ Ñ+ÙÙ­SSS~Ù++~~~~ÊÊ p p! ÆssõõõõHHHHŸŸŸŸûûûû©©N©RRRR©©ûû<<<<<<—<““““ææææ]]] D D î î › ›  _ _cc ¶ ¶8í@ ‹ 4 4 á áNNNNûû    ¤¤ ÷ ÷NNNN _ _ _ _ ¶ ¶ ¶ ¶    ¶ ¶ ¶ ¶     Ì Ì Ì Ì ÷ ÷¤¤NNNN\ € €ÚÚ--ÚÚ T T--ÚÚ Ö Ö ) ) jÅÅ j Á Ánn • • • • • •CC j j j j ìG™™CCCCÞÞÞ„ÚÚÚÚ„Þæ@"{,¡3f4•/+ Gsh³-ˆˆ-----""""ÏÏ}}¨¨ûûNNNN888888@@888’CCCž‹@š@Ú,Òõõ£HHHHH‰‰ Ü666‰‰ ± ± ^´ Z  p p   Æ Æ Æ Æ Æ!%%.™&z<%Ê!!ssŸŸŸŸLLŸŸ­­ ¦ ¦ ¦ ¦SS ü üª OSSS­((((‚(((((ÕÕ(((‚ÊÊ Æ ÆsssssswwÊÊ!!! ÆÐ+ÐÐÐÐÐÐRRRRRR¥¥<<ææææºhhdd.ˆˆˆ222 D D î î › ›  _ _¾¾ ¶ ¶8í@ ‹ 4 4 á áNNNN         J J ÷ ÷ ó óNN _ _ _ _ ¶ ¶ ¶ ¶    ¶ ¶ ¶ ¶  yy Ì Ì Ì Ì ÷ ÷¤¤NNNN\ € €ÚÚ-- € € T T--ÚÚ Ö Ö ) ) jÅÅ j Á Ánn • • • • • •CC ½ ½ j j j j ìG™™CCÞÞÞ„ÚÚÚÚ„Þ1‹=L !Í$Wí(¾h³-ˆˆ-----"""" u u""NNûûNNNN888888åå888’éééC00‹0ÚÚÒwõõ£HHHHH‰‰ Ü666‰‰ ± ± ^´ Z ­ ­  p p   Æ Æ Æ Æ Æ!Ê<Kñ‡%Ê!!ssŸŸŸŸLLŸŸSS ¦ ¦ ¦ ¦SS ü üª OSSS­((((‚(((((ÕÕ(((‚ÊÊ!!sssssswwÊÊ!!! Æ+…ÐÐÐÐÐÐRRRRRR¥¥<<ææææºhhdd.ˆˆˆ222 D D î î › › _ _  c å ‹ ‹ ‹ 4 4 á á         ó ó     J J J J    N¨ _ºº _ ¶ ¶ _ _ _ _ ¶ ¶ ¶ ¶  yy& Ì   J J ÷ ÷NNNN¯¯¯¯¯ TÚ €-- € € € € §Ú € € € ) ) Ö Ö Á Á Á • • • • • • • • ½ ½ j j ì ì™ôJðÞ99„Ú €ÚÚ„„11êŸTÎs¾d`ÚÚÚÚÚÚÚÚ*Ï È"ÏÏ""NNûû    NN8888888888åå<<<–ÖÖƒ(Ò,%%õõõõHHHH Ü Ü Ü Ü Ü Ü‰‰^^^^ ­ Z Z p ps  Æ! Æ Æ Æ!%%ÒÒ%ÊÊss Æ ÆŸŸŸŸLLŸŸ ¦ ¦ ¦ ¦SS ¦ ¦ ü ü OªSSS­ÕÕÕÕÕÕ((ÕÕÕÕ((((ÊÊsÎ!!ssssÊÊÊÊ!!ss####ÐÐ}#¥¥¥¥RR¥¥êê â<““ææººdd.ˆˆˆ222 D D î î › › _ _  c å ‹ ‹ ‹ 4 4 á á         ó ó     J J J J     óNººcc ¶ ¶ _ _ _ _ ¶ ¶ ¶ ¶yyyy& Ì   J J ÷ ÷NNNN¯¯ T T¯ T €Ú-- € € € € §Ú € € € ) ) Ö Ö Á Á Á • • • •ðð • • ½ ½ j j ì ì™ôJ¥£g²“5ÚÚÚ„„115D¾dd `ÚÚÚÚÚÚÚÚÏ u È"ÏÏ""NN         ó ó8888888888åå<<<–{{(ÎwÒõõõõHHHH Ü Ü Ü Ü Ü Ü‰‰^^^^ ­´´ÊÊs  Æ! Æ Æ Æ!ÊÊww%ÊÊÊss Æ ÆŸŸŸŸLLŸŸ ¦ ¦ ¦ ¦SS ¦ ¦ ü ü OªSS­SÕÕÕÕÕÕ((//ÕÕ‚‚((ÊÊsÎ!!ssssÊÊ%%!!ss####ÐÐ}#¥¥¥¥RR¥¥ â<““@@ººll¾¾.ˆˆˆ222 › ›HHõ › ¶ ¶ ¶ ¶g ºº á á á á ‹å88 ÷ ÷ ÷ ÷ ÷ ÷ J J ó óNN    NNggººº _º _ ¶ ¶ _ _  " È u u y Ì Ì        NNNNXXXXÚÚ-- Ó Ó € €\¯¯ T T-- € € € €-- Á Á Á Á j jÅÅ • • • •CC • • f f nCCø¥¥ø#Õ0'7ù5ÚÚÚ„„„„1‹9“h ³³XX1‹Þ„---- Ì q yÏÏ"" ÷ ÷ ÷ ÷ ÷ ÷ ÷ ÷88 ‹ ‹ ‹å88åå’’’’’’wwwwwÒÒHHHHHHHH‰‰‰‰‰‰‰ / ± ± ± V ±  ssss!!!!ss! Æssss ñ ñŸŸHHHH ü ü OªªªªªSSSSªªW ü++++(( zÕ++~~++~~!!ss Æ!ssÊ p!!{!!{!!yy y''' ÌûûûûRR¥¥ææææêêê꺺ÂÂhh2222ˆˆ5 › ›HHõ › ¶ ¶ ¶ ¶g ºº á á á á ‹å88 ÷ ÷ ÷ ÷ ÷ ÷ J J ó ó ó ó    NNggºº _ ¶ ¶ _ _  " È u u y Ì Ì        NNNNXXXXÚÚ---- € €\¯¯¯¯-- € €ÚÚ-- Á Á Á Á j j j j • • • • è è • • Á Á nø¼i­"{+ô'7ù5ÚÚÚ„„„„1‹Þ9 ³XXXX Ö1Þ„---- Ì q yÏÏ"" ÷ ÷ ÷ ÷ ÷ ÷ ÷ ÷88 ‹ ‹ ‹å88åå8888’’wwwwwHHHHHHHH‰‰‰‰‰‰‰ / ± ± ± ±   wwssss Æ Æ!!ss! ÆssssLLŸŸHHHH ü ü OªªªªªSSSSªª üW++++(( zÕ++~~++~~!!ss Æ!ssww%Ê!!{!!{!!yyyÔ''' ÌûûûûRRÿÿææææêêêêÂÂhh2222ˆˆ5HH ›õ£ î ¶ ¶ ¶ ¶    á á á á ‹å88 ÷ ÷ ÷ ÷ ÷ ÷ J J ó ó ó óNNNNÂw$oºº _ ¶ ¶ ² ² ² u u u u Ì Ì&&     ó ó        XXXX € €-- € €ÚÚ\--ÚÚÚ €-- Á Á Á Á ½CCCC • • • • Á ÁnnZ#=, "´ÿ§¶òÚÚÚ1 Ö„„1111XXXXÞÞ„„----&& Ì&"""" ÷ ÷ ÷ ÷ œ ÷ ÷ ÷88 ‹ ‹88888888åå’’ÊÊÊÊÊÊHHõ ›HHõõ‰‰‰‰‰‰ Ü Ü ^^^^^^^ÊÊssss Æ Æssssss!!! ÆŸù ñ ñ ›õHHª O ü üªªªª­SªªWW++++ÕÕÕÕ++++~~ Ñ Ñ Æ!!!!!ssww%Êssss!!!!'''''' Ì ÌN©©NR­ÿÿ“9ææ<—êêhhßß22ˆˆ5HHõ ›HH ¶ ¶ ¶ ¶    á á á á ‹å88 ÷ ÷ ÷ ÷ ÷ ÷ J J ó óNNNN¨¨Ñ"Z%¼èoº _ ¶ ¶ ² ² ² u u u u Ì Ì&&    NN        XXXX € €-- € €ÚÚ §--ÚÚÚ €-- Á Á Á Á ½CCCC • • • • Á Ánnÿy'ú!6Z¥â==âÚÚÚÚ1 Ö„„1111XXXXÞÞ„„----&& Ì&}}"" ÷ ÷ ÷ ÷ ÷Q ÷ ÷88 ‹ ‹88888888 ‹ ‹88ÊÊÊÊÊÊHHPª££õõ‰‰‰‰‰‰ Ü Ü ^^^^^^^ÊÊssss Æ Æssssss!!{!ùŸ ñ ñ ›õHHª O ü üªªªª[[­WW++++ÕÕÕÕ++ Ñ Ñ~~ Ñ Ñ Æ!!! Æ Æssww%ÊssÎÎ!!{{''''''''N©©NR­ÿÿ“9ææ<—êêhh„„22ˆˆ5 Ü Üà …22 ÷ ÷¤¤NNNN""""yy Ì ÌN ó    ¤ J œ œ        NN¨£,–.žÛ& Ì Ì            NNº _  ¶ ¶cccccc  _ _nn nÅÅr Á Á Á Á Á Ánnn  Á Á ½ÅÅr-- € € Ö1 Ö Ö € € € € Ö Ö„ ) « «XX\\d¾(s·‹‹11„„ Ö Ö„„„„Þ„„„ÚÚ € €„„11¯¯¯¯ÏÏ""& Ìyy*Ï""yÓ& ̤¤ ÷ ÷ ÷ ÷ ÷ ÷"""" u u""sssswwsÎ00ÎÎ! ÆHH › › ñ ñ D D‰‰‰ / Ü Ü‰‰´´sssswwÊÊHHõõ ñ ñ ñ ñS ø ¦ ¦SSÙÙà+ÕÕÕÕ====””””iiii    ^^  ‰äää66‰‰£H££dd¾¾hhººhhhhhh““““““îî@æ@@êê——´´´´´ Ü Ü …à22 ÷ ÷¤¤NNNN""""yy Ì Ì óNûû¤ J ÷ ÷        NNN¨ßþöÛ&&&            NNº _  ¶ ¶cccccc  _ _   nÌr Á Á Á Á Á Ánnn  Á Á ½ÅÅ ½-- € € Ö1 Ö Ö € € € € Ö Ö„ ) « «XX¯   ·\1111„„ Ö Ö„„„„„Þ„„ÚÚÚÚ„„11¯¯¯¯ u u"" Ì&yy*Ï""yÓ& ̤¤ ÷ ÷ ÷ ÷ ÷ ÷"""" u u""sssssÎ{{ss! Æ î î › › ñ ñ D D‰‰‰ / Ü Ü‰‰´´sssswwÊÊHHõõ ñ ñ ñ ñS ø ¦ ¦SSÙÙà+ÕÕÕÕ====””””lllliiii    ^^  ‰ä‰‰66‰‰£H££dd¾¾  ººhhhhhh““““““îî@æ@@êê——´´´´aa´ Ü Ü … … …à ÷ ÷¤¤NNNN"""" Ì Ì      û   J J J¤    NN      U„99ßÓyyy        û   óN _ _ _ _ ¶ ¶ccc¾g   Á Á Á ÁÌ'ÜÌ Ánnnn Á Á    ÅÅ-- € € Ö Ö ) ) € € € € Ö Ö Ö ÖXX « «\\\\ ¯„„ÞÞ Ö Ö Ö11111111155ˆˆ1111¯¯\ uÏ uÏyyyy""""&&yy¤¤¤ J ÷ ÷ ÷ ÷"" uÏ u u"" Æ Æ Æ Æ pÊss!!!!ss ›õHHLLŸŸ Ü Ü‰‰‰‰66b¼b´´´´ssssÊÊ › ›õ › ñ ñ ñ ñ ¦ ¦ øSSS[[;•ŽÙÝ‚ÕÕëë˜=AAAA¿lliiii¸¸  ¸¸  6666䉉‰õõ££¾¾hhºººÂhººææ““““î“““@@<ñêê´´´´aaa Ü Ü … … + … ÷ ÷¤¤NNNN"""" Ì Ì      û   J J J¤     ó ó    ûû*ßß„Óyyy        û   óN _ _ _ _ ¶ ¶ ¾cg   Á Á Á ÁrÌ'Ì Ánnnn Á Á     j j-- € € Ö Ö ) ) € € € € Ö Ö Ö ÖXX « «\\ ¯„„„„ Ö Ö Ö1111111‹‹55ˆˆ‹‹11¯¯\ uÏ uÏyyyy""""&&yy¤¤¤ J ÷ ÷ ÷ ÷""Ï u u u"" Æ Æ Æ Æ Â Â pÊss Æ Æ!!ss ›õHHLLŸŸ Ü Ü‰‰‰‰ëëb¼b´´ssssÊÊ › ›õ › ñ ñ ñ ñ ¦ ¦ øSSS[[ðÿRèÝ‚ÕÕëë˜=AAAA¿lliiii^^  ¸¸  6666䉉‰õõ££ddhhºÂhºº@@“““““9““@@——êê´´´´ Ü Ü … …22 J¤ ÷ ÷¤ J ÷ ÷yy Ì Ì   q q œ ÷¤ J J J J J ó ó ó óNNNNÓÓÓÓÏÏ" È         J J œ ÷    ¶ ¶ ¶ ¶ [ [ ¶ ¶ ¶ ¶ ¶ jÅnnÅ jnnnn j j j jÅÅÅÅnn Á Á----„ ) ) )-- € € € € € €XX « «¯¯³³XX Ö Ö Ö Ö--ÚÚ--ÚÚ5=â‹1‹‹@æ9Þ¯¯¯¯\ T T Ì Ì Ì Ì""""ÏÏ""ÏÏÏϤ¤ ÷ ÷¤¤ J¤}}ÏÏ""""ss Æ Æ Æ Æ Æ Æ pÊÊÊÊ p DŸùù¦LŸ D Æ!! Æ2222 …•÷¸  bbb Æ Æssssss › › › › DŸŸ D ¦[µô$}&…±Š/ÕÕë똘ë똘¿¿llii´´´´bb´´ààààHHõõººººhhºh¾¾¾—ññ—Dê<<êêêê<—aa´´´ Ü Ü … …22 J¤ ÷ ÷¤ J ÷ ÷yy Ì Ì   Ì Ì ÷Q¤ J J J J J ó ó ó óNNNNyyyy u u" È         J J œ ÷    ¶ ¶ ¶ ¶ ¶ ¶ ¶ ¶ ¶ ¶ ¶ jÅ Á ÁnnÅ jnnnn j jÅÅÅÅÅÅnn Á Á----„ )„„-- € € € € € €XX « «¯¯XXXX Ö Ö Ö Ö--ÚÚˆˆ55D Læ‹æPo_îÞ¯¯¯¯\ T T Ì Ì Ì Ì""""ÏÏ""ÏÏÏϤ¤QQ¤¤¤ÿ}}ÏÏ""""ss Æ Æ Æ Æ Æ Æ pÊÊÊÊ p DŸùùL ñŸ D Æ!! Æ2222à:÷œ¸  b Æ Æssssssõõ › › DŸùŸ ¦[™#"%*VŠ/ÕÕë똘ë똘¿¿ÇÇii´´´´´´àààࣣõõººººÂºh¾d¾¾—ññ—Dêêê<<êêêê<—aa´´´a Ü Ü … …22¤ J J¤¤ J ÷ ÷ Ì Ì   Ì Ì Ì Ì J J J J J J J J            ûû Ì Ì Ì Ì"" u u         J J J J _ _ _ _ ¶ ¶ ¶ ¶ ¶ ¶c cccc Á Ánn jÅn  Á Árr jÅÅÅÅÅ Á Á Á- Ó--„„„„-- € € € € € € þXXX¯¯XX Ö Ö )„ € €--ÚÚÚ5*š)ìT99ý)–2b*CP毯¯¯ Ì Ì Ì Ì""""ÏÏ}}Ï*Ï*aa¬¬Q ÷QQ}}}""""" Æ Æ   Æ Æ Æ Æ p p ñ ñŸŸ ñ ñŸ DssssÊÊÊÊ2222縸^^´´ss Æ Æssssõõõõ ñ ñLLSSŠ?™äÝÝ‚‚Eëëë==ëëllllii´ Z´´´´´´àà2ààààýýõõºhhºº¾¾¾¾—ñDêêê—<<<<———êêa´´aaa Ü Ü … …22¤ J J¤¤ J ÷ ÷ Ì Ì   Ì Ì Ì Ì J J J J J J J J            ûû Ì Ì Ì Ì"" u u         J J J J _ _ _ _ ¶ ¶ ¶ ¶ ¶ ¶c cccc Á Á   jÅn  Á Á jÅÅÅÅÅ Á Á Áˆ---„„„„-- € € € € € €X þXX¯¯XX Ö Ö )„ € €--ÚÚÚ5—\¾ù99£%†.R+毯¯¯ Ì Ì Ì Ì""""ÏÏ}}*„„”pQ ÷ ÷ ÷}}}""""" Æ Æ   Æ Æ Æ Æ p p ñ ñŸŸ ñ ñŸ DssssÊÊÊÊ2222222¸¸^^´´bbss Æ Æ Îss › ›õõLLLLSS////‚‚77 EEEò=EEllllii´´´´´´´àà2àààࣣõõºhhÂÂhhºº¾¾¾¾<—Dêêê—<<<<—<<êêa´´aaa ± ± ± ± ± ± Ì Ì y u u"" ÷ ÷ J J ÷ ÷ ÷ ÷"" u u""" È ÷ ÷ ÷ ÷ ÷ ÷¤¤ Ì Ìyyy    u u È È È È u u á á á á ‹ ‹ ‹ ‹88 ‹ ‹ á á 4 4 ì ì™™C • • Á Á Á Á Á Á Á Á Á Á Á Á Á ÁnnrrÅÅ « «XX¯d « « þ þ T¯XXXXXX¯¯¯¯ « « « « Ö Ö Ö1‹æ“9‹‹“£@1„„11Ú €ÚÚûûNN¤¤¤¤¨¨ûU¸e„*8(ÞúÛ}}Ï u ÷ ÷¤¤¤¤ ÷ ÷ î îHH ñ ñŸŸ › ›HHHHHH Æ Æss p p › ›õ ›õõHHàà22‰‰ Ü Ü‰‰ Ü ÜààààHH › ›õõHH pÊsÎ0‹†+~~~~ Ñ+WWWWWW__ËËxÃÃîîAA””””ààà:àààà‰‰‰‰çààõõõõ<<<<——êêêê<<<<êêhhhh¾¾¾¾““@@““ææˆˆˆˆßߌ ± ± ± ± ± ± Ì Ì yÏÏ"" ÷ ÷¤¤ ÷ ÷ ÷ ÷"" u u""" È ÷ ÷ ÷ ÷ ÷ ÷ J J Ì Ìyyy    u u È È È È u u á á á á ‹ ‹ ‹ ‹88 ‹ ‹ á á 4 4 ì ì™™C • • Á Á Á Á Á Á Á Á Á Á Á Á Á ÁnnrrÅÅXX¯dsdXX¯ T þ þXXXX¯¯¯¯ « « « « Ö Ö Ö11‹Þ„11Þ9ææ‹1„„ Ö ÖÚ €ÚÚûûNN¤¤¤¤NNûU¸eeU¯ë}}Ï u ÷ ÷¤¤¤¤ ÷ ÷HHHH ñ ñŸŸõõ££HHHH Æ Æss p põõõ › › ›HHàà22‰‰66‰‰ Ü ÜààààHH › ›õõHH pÊsÎ0‹†+~~~~ Ñ+WWWWWWªªppÃi””AA””””ààà:àààà‰‰‰‰çààõõõõ<<<<<<êêêê<<<<êêhhhh¾¾¾¾““ææ““@@ˆˆããßߌ   ± ± ± ± Ì Ì Ì ÌÏÏ"" ÷ ÷ ÷ ÷ J J J J"" u u"" u u J¤ ÷ ÷ ÷ ÷ ÷ ÷   Ì Ì   Ì Ì u u u u u u"" á á á á ‹ ‹ ‹ ‹88 ‹ ‹ 4 4 á á ì ì™™C èC è Á Á Á Á Á Á Á Á Á Á Á Ánn nÅų³¯ ·\XX « «¯¯ « « þX « «\\¯¯¯¯ « « Ö Ö1111„„„„11ÞÞÞÞ„„„ )--ÚÚUUNNQQQ ÷NNûûU°ˆãÛ&"""" ÷ ÷¤¤¤¤ ÷ ÷ › ›£H ñ ñŸŸHHHH£H › › Æ ÆssÊ pw££H£õõ£Hàà22‰ä>䉉 Ü Ü2222HHõõõõHH p p pÊ!{{{†+~~~~~~ªªªªWWªÃÃÃÔ”AA””””àà2àà6666::££££<<—<<<<<ê<<<<êêhÂhhllllîî“9““@@5Û55ßß2   ± ± ± ± Ì Ì Ì Ì u u"" ÷ ÷ ÷ ÷ J J J J"" u u"" u u¤ J ÷ ÷ ÷ ÷ ÷ ÷   Ì Ì   Ì Ì u uÏÏ u u"" á á á áåååå88 ‹ ‹ 4 4 á á ì ì™™C è èC Á Á Á Á Á Á Á Á Á Á Á Ánn nÅų³`` ¯\XX « « T T « «X³ « « « «\\¯¯¯¯ « « Ö Ö Ö Ö Ö Ö„„„„ Ö Ö„„„„„„Þ„--ÚÚ°e¬¬Q ÷NNûûU°¨¨.Ó&&"""" ÷ ÷¤¤¤¤ ÷ ÷ › › îH ñ ñŸŸHH£££H › › Æ ÆssÊ pwHHH£õõ£Hàà22 /‰‰ä‰‰ Ü Ü2222HHõõõõHHÊÊ pÊ Æ!!!†+~~~~~~ªªªªWW_ppÃÃÃÔ”œœ””””àà2àà6666àࣣ££———<<<<<ê——<<êêhÂÂÂllllîîî“îî@@5Û55992^^^^yÓyy Ì Ìyy     óN         Ì Ìyy Ì Ì Ì Ì J J J¤NN     u u u u Ì Ì Ì Ì y Ì Ì Ì Ì Ì ÌŽé á áŽŽŽŽ á á á á 4 4ŽŽ • • • •CC •ðnn j j j jnn ÁÅÅnnnn³ ÂÂd¯¯¯¯¯¯¯ « «XXXX «XXXXXXXX\¯¯„„1 Ö-- €Ú‹1„„ÚÚ--„„„„„„1‹Ç׸]¨¨NN¨¨ûûûû&&yy& Ì Ì&NN  ûNN     ñ ñ ñ ñ î î › › ›õõõ£Hõõ Æ Æ! Æ Æ Æ!!HHHH ñ ñŸŸ22àà‰‰‰äàà …à2222ŸŸ ñ ñŸŸŸŸÎsssÊÊÊÊ((ÕÕ Ñ+ Ñ+W ü üW­bÓÃÃÃÃAAîî””””àà666666䉉‰66õPPPêêêêêDêêêê——@@¾¾¾¾¾llêêDêîî““55ˆãŒŒß^^^^ˆã.y Ì Ìyy     óN         Ì Ìyy Ì Ì Ì Ì J J J¤NN     u u u u Ì Ì&&y  Ì Ì Ì Ì Ì ÌŽé<<ŽŽŽŽ á á ‡ ‡ 4 4 4 4 • • • •CCð •nn j j j jnn ÁÅÅnnnn³ ,,¾ ¯¯¯¯¯¯XXXX «XXXXXXXX\  „„1 Ö-- €Ú1 Ö„„ÚÚ--„„„„„„1‹¸Ç"1×Ǹ¨¨¨¨ûûûû&&yy& Ì Ì&NN   FNN     ñ ñ ñ ñ î î › › ›õõõ£H › › Æ Æ! Æ Æ Æ Æ ÆHHHH ñ ñŸŸ22àà‰‰‰äààà …2222ŸŸ ñ ñŸŸŸŸÎsÎÎÊÊÊÊ((ÕÕ Ñ+ Ñ+W ü üW­­ÃÃÃÃÃÃAA””””””àà226666‘‘䉉‰66õPPPêêêêêDêêêê——››î“¾¾¾¾¾¾llêêDêîî““55ˆãŒŒß Z Z ±  fú ˜Ó Ì Ì Ì ÌNN            &&yÓy  Ì Ì J J ÷QûûNN u u""yÓÓÓÓy Ì Ì Ì ÌyÓ<ñCŽŽŽŽŽ á á 4 4 ‡ ‡ ‡ ‡CCð •CCCC Á Á Á j j j jnnnnÅÅ Ánn`pp·\¯¯¯¯¯ T T¯¯¯ «XX «XX¯ TX³ « « «XX\ )„ Ö Ö---- Ö Ö„„---ˆ„„„„„„ÞÞ]Ç$£0Ñ/w'X"]UûûûNNNNyy&&yy Ì&NN ó ó    NNŸŸ ñLõõ › ›HHõõHH › ›ss Æ Æ Æ ÆssHHõõŸŸ ñ ñ … …àà Ü Ü66à … …à22ŸŸ ñ ñ ñLŸŸ Æ Æ!!(((‚~~ Ñ+WW üW­­pÃÔ”””””îîàààà‰ä66ää66‰‰66££ý£êêêêDD——êêêê››Hî¾¾¾¾¾¾ll——êê@@@@ˆˆˆˆ99Œ Z Z ±  fE ò.&& Ì ÌNNûû         Ì ÌyÓy  Ì Ì J J œ ÷ûûNNÏÏ""yˆ=ˆÓy Ì Ì Ì ÌyÓ–KžéŽŽŽŽ á á 4 4 ‡ ‡ á áCCð •CCCC Á Á ÁÅÅÅÅnnnnÅÅ Ánn «``\¯¯¯¯¯ T¯ T¯¯ «XX «XX¯ T³X « « «XX\ )„ Ö Ö---- Ö Ö„„---ˆ„„„„„„ÞÞ".7–7–4á#öUûûûNNNNyy&&yy Ì&NNNN    NNŸŸ ñLõõõõHHõõHH › ›ss Æ Æ Æ ÆssHH › ›ŸŸ ñ ñ … … … … Ü Ü Ü Ü22à … …à22ŸŸ ñ ñ ñLŸŸ Æ Æ!!(((‚~~ Ñ+ ü ü üWSSpii””””””îîàààà‰ä66ää66‰‰66££ý£êêêêêêññDDêꛛ¾¾¾¾¾ll——êê@@@@ˆˆˆˆ99Œ2222k ¾g   á á á á ‹ ‹ ‹ ‹  ººc ¶ ¶ _ _ _ _    „„ Ö Ö5T—`XX T T T¯GGGG ì ì™™ èCC è ì ì ? ?    ¾c ¶ ¶ ‹ ‹ ‹ ‹ á á á á  º _ _ _  ‹ ‹å厎 á ᯯ¯¯„„ Ö Ö Ö Ö„„CCC ìG™™nn Á    ºº  ¶ ¶    _ _    ºå ‹88’’’’Ut,5Ž6’2‚¨NNNûû¨¨    cccc  ºº ¶ ¶22àààà22222àà22‰‰‰‰2222  ¸^iiii==ë ==SSSSSS[~~~~ÕÕ((===˜ëë==””AA”îAAAA ç ç=˜ëë¿¿¿¿lllWWªªWW‚Ý/Õ++††˜˜˜ò´´´´ ¿i··  ãã55ßß99aaaa´ÂÂlll222222¾c ²  á á á á ‹ ‹ ‹ ‹  _ _c ¶ ¶ _ _ _ _    „„115 ÆL`XX T T T¯ ì ì ì ì ì ì ? ? èCC è ì ì™™    c ¶ ¶ ‹ ‹ ‹ ‹ á á á á  º _ _ _  ‹ ‹å厎 á ᯯ T T„„ Ö Ö Ö Ö„„CCC ìG™™nn Á    ºº  ¶ ¶    _ _    _ºå ‹888888U ×%P+¾'®Ë¬¨NNNûûNN    cccc  ºº ¶ ¶22àààà222àà22‰‰‰‰2222  ¸^iiii== ë ==SSSSSS ¦~~~~ÕÕ((==˜= ==””AA”îAAAA ç ç=˜ëë¿¿¿¿lllWWªªWW‚Ý/Õ++++˜˜˜ò´´´´e||Ãi··eeãã559999aaaa´ooÂÂlll22 … …22º _  á á á á8 Ý ‹ ‹ _ _ _ _ ¶ ¶ ¶ ¶    _º _ _„„„„ˆòTê³³XX ?™ ì ì ì ì ì ì • • • • ì ì ì ì    ¶ ¶cc ‹ ‹ ‹ ‹ 4Ž á á  _ _ _ _  ‹ ‹8’鎎Ž\\¯¯\ Ö Ö„„ )„1 ÖCCC è™™ ì ìnnnn      ººcc¾c gººººº _  _ _ Ý8 ‹ ‹88 ‹å¨etxiQûûNNNNNN    cccc  ººccccààààà …22‰‰‰‰2222^^ ± ´´b » » » »==ëë ëSS­S ¦~~~~ÕÕÕ z==ëëëëëë””AAAAî”AA””==ëë¿¿¿¿llªWWªWW‚‚Ý‚ÙÙ++˜˜ò˜´´æ'º#ªÓû» ee ˆããã99ŒŒaaa»Âh¾22 … …22 ¶ ¶º _  á á á á8 Ý ‹ ‹ _ _ _ _ ¶ ¶ ¶ ¶     _ _ _„„„„ˆˆ55³³XX § § ?™ ì ì ì ì ì ì • • • • ì ì ì ì    ¶ ¶cc ‹ ‹ ‹ ‹ 4Ž á á  ºº _ _  ‹ ‹8’鎎Ž\\\\¯¯\ Ö Ö„„ )„1 ÖCCC è ? ? ì ìnnnn      ººcc c gººººº _  _ _ Ý8 ‹ ‹88 ‹åN¨U°YÿQQûûNNNNNN    cccc  ººcccc::çç::眜œ:à22‰‰‰‰2222^^ ± ¼b » » » »== ë­­­S ¦~~~~ÕÕÕ z==ëëëëëë””AAAAî” ç ç””˜˜ëë¿¿¿¿llªWWªWW‚‚Ý‚ÙÙ++˜˜˜ò´´1&_%Óû» ee ˆããã99ŒŒaaa»Âss2222 … …  ºº _ _ _ _ ‹ ‹88å ‹ ‹ ‹ ¶ ¶ ¶ ¶    ºº  ² ² _ _ Ö Ö„„ÚÚ--³XXX « « « « • • • • ì ì ì ì ì ì™ ? ì ì ì ì  ² cc á á á á ‹ ‹ ‹ ‹ºº  ¶ ¶ ¶ ¶ á á á<<< á á\\ ¯¯¯¯¯ € €Ú € Ö Ö Ö Ö ì ì ?™ ì ì ì ìÅ j jÅccccc ccºº _º  ºº ¶cccccc88å ‹ á ᎎ¤¤QQ¤¤¤¤ ÷ ÷QQ J J ÷ ÷ ¶ ¶cc ¶ ¶  ººg ºç÷»™ä66Ba#-ÃB22‰‰ Ü Ü Ø2 … … Z´bbb¿¿ii » » ç ç ç ç ç çAASSSS Ñ Ñ++ Ñ+~~==ëë”” ç ç ç çAAAAAAëëë똘==llllllllWWWWW üªª‚‚/ÕÙÙÙÙEEEEaa´»pÓÓlee··==9999··ÊÊoossÆ2222 … …  _ _ _ _ _ _ ‹ ‹88å ‹ ‹ ‹ ¶ ¶ ¶ ¶    ºº    _ _11„„ € €-- þX þ³ • • • • ì ì ì ì ì ì™ ? ì ì ì ì  ² cc á á á á ‹ ‹ ‹ ‹ºº  ¶ ¶<< á<<<<<\\ ¯¯¯¯¯ € €Ú € Ö Ö Ö Ö ì ì ?™ ì ì ì ìÅ j jÅccccc cc _ _ _º  ºº ¶cccccc88å ‹ á ᎎ¤¤QQ¤¤¤¤ ÷ ÷ ÷ ÷ J J ÷ ÷ ¶ ¶cc ¶ ¶  ººg ºç¬!%»™ä66BË,§$ˆ÷‰‰ Ü Ü Ø2 … … Z´b¿¿ii ç ç ç ç ç çAASSSS+++++†~~==ëë”” ç ç ç çAAAAAAëëë똘==llllllllWWWWW üªª‚‚/ÕÙÙÙÙEEEEaa´»»ii···ee··ãã9999··oooossÆàà22 Ø Ø _ _ _ _ºº  ‹ ‹88 ‹ ‹ ‹ 0 ¶ ¶ ¶ ¶  _ _gg      „„„„ € € € €XXXX «XX • • • • ì ì ì ì ì ì™ ? ? ? ? ? _ _  ¶ ¶ ¶ ¶ á á á á ‹ ‹ ‹ ‹ _º _ _ ¶<<<<<<éé    \\-- € € Ö Ö Ö Ö™™ ? ? ì ì ì ì ½ j j jÅ ¶ ¶¾cccc   _º ²    ¶cccc8888 á ᎎQ ÷ ÷ ÷¤¤¤¤¤¤ ÷ ÷ J J ÷ ÷ ¶ ¶cccc ¶ ¶ ²     ººB¤J>äääçQBàà‰‰ Ü Ü2222b´´li iiA ç””””AA­­SSSS Ñ+++ÙÙ~~ëëëE”” 9 9””AAAA””ëëë똘EElllllªªªªWWWW/Õ/Õ~Ù††˜˜˜˜aa´aa··  ··ee==ãã9999e ··»»»»ooÎÎsàà2222 _ _ _ _ _ _  ‹ ‹88 ‹ ‹ ‹ 0 ¶ ¶ ¶ ¶ ² ² _ _        „„„„ € € € €XXXX «XX • • • • ì ì ì ì ì ì™ ? ? ? ? ? _ _  ¶ ¶ ¶ ¶ á á á á ‹ ‹ ‹ ‹ _º _ _ ¶<<<<<<éé    \\-- € € Ö Ö Ö Ö™™ ? ? ì ì ì ì ½ j j jÅ ¶ ¶¾cccc   _º ²  ¶cccc ¶ ¶8888 á ᎎQ ÷ ÷ ÷¤¤¤¤¤¤ ÷ ÷ J J ÷ ÷cccc ¶ ¶ ²     ºº:à䉉‰ççàà‰‰ Ü Ü2222b´´lÃiiiA ç”””” ç çSSSSSS Ñ+++~~~~ëëëE”””””” ç ç ç ç””ëëë똘ëë¿¿llÇlllªªªªWWWW/Õ/Õ~Ù††˜˜˜˜aa´aa··  ··ee==ãã9999¿e»»»»oosss ±^^ ± V 4Ž á á ‹ ‹ ‹ ‹ ¶ ¶ ¶ ¶   ² cc ¶ ¶ ¶ ¶        « « « « T T « « « «™™™™CC • •™™ ì ì ì ì ì ìcccc    _ _ _ _º _  á á á á ‹å’’’’å@–––<55ââÞÞÞ„„„1 Ö Ó Ó--™™™ ?™™ ì ì • • • •Cð • á á á á88åå ¶ ¾º _  ‹ ‹ ‹å8888 4ŽŽŽ8888}""" u u"" ÷ ÷ ÷ ÷    û  åå88ŽŽ á á  g   ºº  ¸¸¸^¸^àà::6‘‰‰2222‰‰‰‰àà22àà … … ç ç çA””””ë ==”” ç ç~~ Ñ Ñ~~ Ñ Ñ((ÕÕ~~~~¿¿¿¿¿¿¿¿iiiiîî”ëëiiiÃllll~~~~‚‚‚‚++++++††ÃÃÃÃaa´ãããã=ããã··´´»»»»iiiiDDññDŸŸ ±^^ ± V 4Ž á á ‹ ‹ ‹ ‹ ¶ ¶ ¶ ¶   gcccc ¶ ¶ ¶ ¶        « « « «¯¯ « « « «™™™™CC • • ? ? ì ì ì ì ì ìcccc    _ _ _ _º _  á á á á ‹å’’88@šñññ–55ââÞÞÞ„„„1 Ö----™™ô™™™ ì ì • •ððC è •ð á á á á88åå ¶ccº _  ‹ ‹ ‹å8888 4ŽŽŽ8888}""" u u"" ÷ ÷ ÷ ÷ûûû   ‹ ‹88éé<<ggg   ºº  ¸¸¸^¸^àààà6‘‰‰2222‰‰‰‰àà22àààà ç ç çA”””” ë==”” ç ç~~++~~ Ñ Ñ((ÕÕ~~~~¿¿¿¿¿¿¿¿iiii”””ëëiiiÃllllÙÙÙÙ‚‚ÝÝ++++++++ÃÃÃÃa»a´ãããã˜===»»´´»»iiiiŸŸññŸùŸ^  ± ± ± ± á á á á ‹ ‹ ‹ ‹ ¶ ¶ ¶ ¶   gcc ¶ ¶c cºº      « « « «¯¯¯¯ «XX ì ì™™CC • • ì ì ì ì ?™ ì ì ¶ ¶ ¶ ¶    _º      á ᎎ Ý Ý88ååšO¦Kññââ5ÞÞ‹1 Ö Ö11ˆˆ--GGGG™™ ì ì • •ððCC • • á á á á88ååccccºººº8888 ‹ ‹åå<<ŽŽ8888}}ÏÏ""ÏÏ ÷ ÷ ÷ ÷    NNå ‹88éC鎺ººº  ºº^^^¸f ¸^àà2266‰ /22 …à6 Ü66àà …à222 ç ç””””””==ë ””î”+++++++ Ñ((ÕÕ~~~~¿¿¿¿¿¿llÃiiii ”””îEë==ÃÿllÙÙ++‚‚‚‚++++ÙÙ++pp´´aa´ã==ãeeeeaai»»iiŸùŸŸL¦ù ^ ± ± ± ± á á á á ‹ ‹ ‹ ‹ ¶ ¶ ¶ ¶  ² cc ¶ ¶c cººgg    « « « «¯¯¯¯ «XXGG™™CC • • ì ì ì ì ?™ ì ì ¶ ¶ ¶ ¶    _º      á á 4 488’’@@@õ¦Kññ==599‹111 Ö Ö---- ì ì ì ì™™ ì ì • • • • • • á á á á88ååccccºººº88 Ý Ý ‹ ‹åå<<ŽŽ8888}}ÏÏ""ÏÏ ÷ ÷ ÷ ÷ûûNNå ‹88Žé鎺ººº  ºº^^^¸Àf¸^àà2266‰ /22 …à6 Ü Ü Üàà …à222 ç ç””””””==ë ”””î+++++++ Ñ((ÕÕ~~~~¿¿¿¿¿¿ÃiiiiÃîîî”E똘ÃÿllÙÙ††ÝÝ‚‚++++ÙÙ++pp´´aa´ã==ã55  eeÃû»ÃiiiŸùùùL¦ù   Z´ ‹ååå< á á á ¶ ¶ ¶ ¶     ¶ ¶º _  ººººg _ _ « « « «¯¯¯ TXXXX™ôôôððCC ? ? ?™ðð • •  _ _ ¶ ¶cc _º  ºº _ _ ‡ á á áåå8’@@@šKKžž——ê5â∈ˆˆÚÚ---- • ; èCCCðð ì ì ì ì™™ ì ì á á ‡ á ‹ ‹ ‹ ‹ºººº gg ²88 ‹ ‹8’å厎 á á88’8}}""""}}NNN¨¨NNN á ᎎååå庺ººººººb´´b‰‰‰‰àà22 … …22 Ü Ü Ü Ü Ü Ü Ü Ü2222== ë””””” 9 ç ç””””~~+++++ Ñ~~~~ÕÕÕÕÃi¿¿iiiiÃiAAAAë똘llllllÙÙÙ3ÙÙÙÙ‚‚//++~~ll    a»»aŒç99··ieellÃiLLùùPPý ± ± Z´ ‹ååå< á á á ¶ ¶ ¶ ¶    ¶ ¶ ¶ ¶ _º  ºººº ² _ _ « « « «¯¯¯ TXXXXôÿJCC ? ? ?™ • • • • ² ² _ _ ¶ ¶ccº _  ºººº< á á áåå8’@@@šKKøø—LDâââ∈ÚÚ----ð •CCCðð ì ì ì ì™™ ì ì á á ‡ á ‹ ‹ ‹ ‹ºººº g  88 ‹ ‹ Ý8 ‹ ‹ŽŽ á á88’8""""""""NNN¨¨NNN á ᎎ ‹ ‹å庺ººººººb¼´´b‰‰‰‰àà22àà22 Ü Ü Ü Ü Ü Ü Ü Ü2222== ë””””” 9 ç ç””””~~++ Ñ Ñ Ñ+~~~~ÕÕÕÕÃi¿¿lliiÃÃÃiAAAAë똘llllllÙÙ~ÙÙÙÙÙ‚‚//++ÙÙll    a»aŒç99êê»»ÃieellÃiLLùùPPý ± ±´åå88< á á á ¶ ¶ ¶ ¶     ¶             « « « T T þX «¡u+)«i¥ð • ’ ’ ì ìC è è è _ _ ² ¶ ¶cc    ºº  Ž 4 á á8’å@@@@šøøŸD—=ê55ˆˆÚÚ----CCCCCðð ì ì ì ì ?™G 쎎 á á88 ‹ ‹    ºº  ‹ ‹ ‹ ‹8888 á ᎎåå88""""""""    NNûûNN á ᎎ88 ‹ ‹ _ _ººººbb Z´´´b‰‰ Ü Ü222à … Ü6‰‰ Ü Ü‰‰2222====””””” 9 çAAA çAÙ~~~~~~~++++‚‚ÕÕ¿ÏtiiAA””==ëëllllll++++ÙÙÙÙ‚‚//3Ù++¿ÇÇeee aaß9ŒŒêêê¿¿¿eiiii¿¿ÃiLñùTýýP ± ±´åå88< á á á ¶ ¶ ¶ ¶     ¶          gg «\\¯¯³X «¡À%œ$AJð • ì ì ì ìC è è è _ _ ² ¶ ¶cc    ºº  4Ž á á8’@š@@@šøø[[ùŸò—ê55ˆˆÚÚ----CCCCCðð ì ì ì ì ?™G 쎎 á á88åå    ºº  ‹ ‹åå8888 á ᎎåå88""}}""}}    NNûûNN á ᎎ’’å庺ºº Z´´´b‰‰66222à … Ü6‰‰66‰‰2222====””””î” çA ç ç çAÙ~~~~~~~++++((ÕÕ¿Ïtii » » » » ç ç””==ëëllllll++++ÙÙÙÙ‚‚//3Ù++tÇÇee¿eaa9”ççêêê¿¿¿eÃÃÃÃÃpp¦TùýýªHH ñ ñ ñ ñ ¶ ¶ ¶ ¶ccåå88åååšÓy Ì Ì Ì Ìyy y Ì ÌÏ u"" Á Á Á Á Á Á ÁÅÅrrGü^^RCC ì ì ì ì™™ ? ? ‹ ‹ Ý8 ‹ ‹88 á á á á á Ꭰ4 á á á áåå@@Šц3ŽLùŸ—=ââ³³\nnnnnnCCð • ì ì™™NN    NNNN"""""}""      û J J ÷ ÷¤¤¤¤ûû¨¨ååååŽŽŽŽŽ 4 á áŽŽŽŽ    ûûQ ÷¤¤ ÷QQQ¤¤ ÷ ÷ss!!ÊÊÊ%!!!!´ Zb´´´´àà22 Ü Ü Ü Üëëëëë ==AA ç ç ëëëÃi » »iiÕ/‚(‚‚//ÕÕ((++~~ » »iiiiî”AA˜˜˜˜˜˜˜˜AAAAAAî˜˜œöII~ÙÙ~vv$$zÕ(‚++~ÙÙÙÙ~‚ÝŠ/Ù33ÙŠŠÝ‚‘Fë‘ã>‘HH ñ ñ ñ ñ ¶ ¶ ¶ ¶ccåå’’åå@õÓy Ì Ì Ì ÌyyyÓ Ì ÌÏ u"" Á Á Á Á Á Á Á Á ÁÅÅrrGGôôCC ì ì ì ì™™ ? ? ‹ ‹ Ý8 ‹ ‹88 á á á á á Ꭰ4 á á á áååååÅ ,áèC\Tù—=ââ³³\nn Á ÁnnnnCCð • ì ì™™NN    NNNN"""""}""      û¤¤ ÷ ÷¤¤¤¤ûûNNååååŽŽŽŽŽ 4 á áŽŽŽŽûûûûQ ÷¤¤ ÷QQQ¤¤ ÷ ÷wwss!!ÊÊÊ%!!!!´ Zb´´´´àà Ü Ü66ëëëëë ==AA ç ç ëëëÃi » »iiÕ/‚(‚‚ÕÕÕÕ‚‚++~~ » »iiiiî”AA˜˜˜˜˜˜˜˜AAAAAAî˜˜öœî£CRèÙÑÑ$$zÕ(‚++~Ù~~Ù~Ý왊Ù3Ž3ŠŠ7Ýëëë‘ã>ëHHŸ D ñ ñ ¶ ¶cc ¶ ¶ccåååååå@@y  Ì Ì Ì& Ì Ìyy Ì Ì"""" Á Ánnnn Á Á Á ÁnnÅÅ™™™™ðð •ðô™ ì ì ì ì ì ìå ‹88 ‹ ‹88 á áŽéŽŽ á á á á 4Žåå’íkÅÍ(†– R s¾Lò—=â``³³\ ÁnnnnnnCCCC ì ìGG      û    NNÏÏ u u"" u u    NN¤¤¤¤¤¤¤¤N¨ûûååååŽŽŽŽ á á á áŽŽŽŽûûNN¤¤¤¤¤¤ ÷ ÷¤¤ ÷ ÷ww Æ Æ Æ!wwÊÊ Æ Æss´´´´´b•à6 Ü Ü6========”” çAë똘iiiiiilÃÃÃÃÕÕ‚‚ÕÕÕÕÕÕÕÕ++~~ » »p””AAëëëëë똘AAAAAAAœ˜˜E IîœQÿ#iÙ~$ÑÑzz((~Ù~~++††ä!¸&uüŽ3à†äääŠëëëëë FHHŸ D ñ ñ ¶ ¶cc ¶ ¶cc ‹@ååååååyÓ&& Ì& Ì Ìyy Ì Ì"""" Á Ánnnn Á ÁnnÅÅ™™™™ðð •ðô™ ì ì ì ì ì ìå ‹88 ‹ ‹88 á áŽéŽŽ<< á á 4Ž@@’íkÅ(‚áð#%¼%Ý#(k§—=â``³³\ ÁnnnnnnCCCC ì ì ì ì      ûûûNNÏÏ u u"" u u    NN¤¤¤¤¤¤¤¤N¨ûûååååŽŽŽŽ á á á áŽŽŽŽûûNN¤¤¤¤¤¤ ÷ ÷¤¤ ÷ ÷ Æ Æ Æ!wwÊÊ!!ss´´´´´bàà6 Ü Ü======== 9îA çë똘iiiiiilllÃÃÃÃÕÕ‚‚ÕÕÕÕÕÕÕÕ++~~pîîAAëëëëëë==AAAAAAAœ˜˜E Iîöö†;Ž~~$ÑÑzz((~ÙÙÙ++††ä"f¡Ž3†àäääŠëëFF  FGG š š š š T® ª ªXXÚ4‡‡ÚÚÚ40000ƒƒƒƒ,,,,,,    úMMMMMMMMúúúú§M á ᎎää Š Š µ µbb    å å’’;; Ž Ž Ž Žèè’’ å?||||ÓÓ--`»Ãx1!›) -*(À!üÝ{ƶ⇇‡44 Ú Ú‡‡‡‡ Ú Ú ®  ® ƒ ƒ00ÞÞ00²² X X  \\²²ÞÞ8ÞÞÞÞÞ¨¨¨¨ ú ú¨¨¨¨ ú ú))||))||&&ÓÓ|||| Ç Çtttt!!öö£IM òŸŸI£IIIIööËËËËttttËËtt! ÇËËËËM òŸŸMMŸŸŸúMMúúMMddddººººæ@9999ææûûûûNNûûûVûû©©ûû5ÛÛÛÛÛˆ.Y´´´aaôOOOj½ff¹ÀÀÀnnÔ''Ì'yyyêêDGG š š š š T® ª ªXX Ú,,ÚÚ Ú0000ƒƒ ( (,,,,,,    úMMMMMMMMúúúú§M á ᎎ Š Š Š Š µ µbb    å å’’;; Ž Ž Ž Ž Ž Ž’’ å?||||ÓÓ--`»Ãxæ)º2†3à2:.*& 7{Æk⇇‡44 Ú Ú‡‡‡‡ Ú Ú ® ® ÞÞ00ÞÞ00²² X X\\\\²²ÞÞÞ ƒÞÞÞÞ]]¨¨¨¨ ú ú¨¨¨¨ ú ú))||))||&&ÓÓ|||| Ç Çtttt!!öö£IM òŸŸI£IIIIööËËËËttttËËtt|!ËËËËM òŸŸMMŸŸŸúMMúúMMddddººººæ@9999ææûûûûNNûûûVûû©©ûû5ÛÛÛÛÛˆ.Y´´´ôOOOjb½ff¹ÀÀÐunnÌÌÌ'yÔÔêDDêDGG š š í í ý ýXX,,,,,,,,00 Ö Öƒƒ Ö Ö,,,,ÚÚ,,  úMMMMMMMMúúúúú   á áŽŽä Š Š Š bbb    ’’ å å Ž Ž;; Ž Ž;; å å å å||||Ó-ÛÛ`Ê$P1Ù7C7C5œ02%^åÕÆk4‡‡‡‡44‡‡ Ú Ú‡‡ Ú Ú\\\\ÞÞÞÞ00 ƒ ƒ² X X²  \\²²00 ƒ ƒ00 ƒÞUUU ú¨¨ úU¨ M ú ú¨¨||×||×||&&ÓÓ Ï Ï))!!tttt!!IIIIŸŸŸŸIIööIIööËËËËttttËËtt!!ËËËËMMŸŸMMŸŸúúŸŸúúŸŸddddºººº““ææ99““ûûûû©©ûûN©ûûûûûVˆˆ.ˆˆˆ5Û´´a»´´OO¢¢½bffÀnnuß:ÐnnnÈÌÌÌÌrÌÌ'ÔyÔÔ—ñDDDêêGG š šGGXXXX,,,,,,,,00 Ö Öƒƒ Ö Ö,,,,ÚÚ,,ú  MMMMMMMMU ¯úú   á áŽŽä Š Š Š bbb    ’’ å å Ž Ž;; Ž Ž;; å å å å||||Ó-ÛÛ`Ê$P1Ù7C7C6÷4B)nôÕÆk4‡‡‡‡44‡‡ Ú Ú‡‡ Ú Ú\\\\ÞÞÞÞ00 ƒ ƒ² X X²  \\²²00ÞÞ00 ƒÞUUU ú¨¨U ú¨ M ú ú¨¨×××1Œ1||&&ÓÓ Ï Ï))!!tttt!!IIIIŸŸŸŸIIööII œQ% pËËttttËËtt!!ËËËËMMúúMMŸŸúúŸŸŸŸŸŸddddºººº99ææ““““ûûûû©©ûûN©VVVVV°ãã㈈ˆÛ5´´aaa´´OO¢¢½b¹¹ffÀÈÈÐ: I*nnnÈrrÌÌÌ''.ÔÔÔ—ñDDŸDDGG š šGG ª ª ª ª  ,,ÚÚ‡,ƒƒƒƒ Ö Ö Ö Ö Ö Ö Ö Ö Ö Ö Ö Ö ö ö ö öMMMM£þÂþ££ää Š Š77 Š Š b µ f¹¹??’’ Ž Ž Ž Ž Ž Ž;; Ž Ž Ž ŽÓÓÓÓÓ--ˆÃÊÚ#L2/7™8ô6 2‘'½C,Âg‹‹00‡‡‡‡ Ú Ú Ú Ú‡‡‡‡²² X X²²0000 Ú Ú Ú Ú ® ®\\²²²²```‡‡‡‡‡‡‡âQQ««þþþþþþ ¤ ¤«Qþþ))„“æ×||&&Ó- Ï Ï||ËËËË!!!!IIöö œöööII£I ò òMM!!! ÇËËx!!!!ËËxxxx%%££££úú ò òMMMM ò òŸŸ   hddêêê©©©©RR¥ÿR­RR©^ ÀŸê522ßß  ]]····OO¢¢½½µ¹fÀrÜ6}}2#ÈÈu'Ìy'..DŸŸŸññùGG š šGG ª ª  ,,ÚÚ‡,ƒƒƒƒ Ö Ö Ö Ö Ö Ö Ö Ö Ö Ö Ö Ö ö ö ö öMMMM£þ+½!–³££ää Š Š77 Š Š b µ f??’’ Ž Ž Ž Ž Ž Ž á á Ž Ž Ž ŽÓÓÓÓÓ--ˆÃÊÚ!ñ. 6?7™6 /Ü%C,Âg‹‹00‡‡‡‡ Ú Ú Ú Ú‡‡‡‡²²²²²²000044 Ú Ú ® ®\\²²²²`````º‡‡‡‡‡‡ -‡QQQQþþþþþþþþ«Qþþ)))„1×||&& xÓ))||ËËËË!!!!IIöö œöööII£I ò òMM!!! ÇËËx!!!!ËËxxxx€€X£££úúMMMMMMMMŸŸ   hddêêê©©©© ø ø¥ÿR­RR©^$£(’ ꌌßß  ]]····ôô¢¢½½j¹À‘*/„*œ}ÈnnnuÐÌ'y'..DŸùù¦¦TGG š šGG ª ªXX®®,,  ÚÚ,,00ƒƒƒƒ ( ( Ö Ö Ö Ö ( (0 Ö ö ö££úúMM£þÂá ö ö777777 Š Š µ µf…Ðô å å å; á Ž Ž Ž Ž á; Ž ŽèèÓÓÓÓ--ÛÛhÊÚ"ž-r475‘2‘*r K†oº88ÞÞ‡‡‡‡‡‡‡‡‡‡ Ú Ú²² X X000044‡‡\\ \²²`²²º`²²`‡‡‡‡‡‡‡‡ ¤þþþþþ ¤þþþþYþþ«Q))||×|))&&ÓÓ||||ËË!!!! œöööIIööIIööŸŸMMtt Ç ÇËËËË%%ËË!!!!xxxÒ%%€€³þQQúúúŸúúMM òMŸŸ  hhll<<êêDDD©©¥¥RRÿÿRR©Ï(³+G =ãßßßß   e    ¢¢¢ü½n#&·5›7£3“"þÐÈnuÌ'ÔÔÔ.6ÜÜŸù¦¦TTGG š šGG ª ªXX T T,,    ,, Ö Öƒƒƒƒ ( ( Ö Ö Ö Ö ( ( Ö0QQ££¯¯§§£þþ³«QQ777777 Š Šf…%¤O???; á Ž Ž Ž Ž á; Ž ŽèèÓÓÓÓÓÓÛÛ³%&®.Í0'.&bð,oº88ÞÞ‡‡‡‡‡‡‡‡ - - Ú Ú²² X X000044‡‡\\ \²²`  º`²²`‡‡‡‡‡‡‡‡þ ¤þþ ¤ ¤ ¤þþþþYþþQ«))|||×))&&ÓÓ||||xxËË!!!! œöööIIööIIööŸŸ ò òtt Ç ÇËËËË%%ËË!!!!xxxÒ€€ÚÚ³³««TTúŸŸŸMMM òŸŸhhhh<<êêD®®¸^©¥¥RRÿÿRR©  Ÿ=ãßßßß   e    ¢¢üW'‘rn#ó.Ö3“/„!¤*ÈnÐuyy'...‰ÜÜ66ùT T¦s ,,   Ö Ö Ö Ö ª ª ª ª T T T T Ö Ö Ö Öƒƒ Ö Ö®®XXXX%%%€“9×|xx%%%%%%ŽŽŽŽä Š Ý7  ¹¹fv33Ággn ¹ ¹ ¹;;;;;;;;Ó-ÓÓ))×15Eú\# 'Ý)8& ì0{Êogg```²²² X ® \\\\\\ X X²² Ú Ú Ú Ú ƒÞÞ8‹00044‡â  \\\\\\ÞÞÞÞ0000ÓÓ&& Ï Ï||||||€€€€þþþþQQQ«|||×||||ööIIŸŸMMËËËËŸŸŸŸIIIIxËËËËxx!!ÏÏ||)Ï%%€Ú5<<hh ³¯T§§%%xxxxxx¾¾¾¾ºººº99“îñ[$ä(ôe‘ÐÐÐ+}}ÐÐÔÔ..·· °]·ãˆãã5555øøøm'çÀ¡ììFF© uÀôFFFF¡¡÷÷ÿÿ}}…ßÜÜ66,,ÙÙ Š0ƒs ,,   Ö Ö Ö Ö ª ª ª ª T T T T Ö Ö Ö Öƒƒ Ö Ö®®XXXX%%%€Þ„|"xx%%%%%%ŽŽŽŽä Š Ý7 ± ±¹¹fÁnnÁggg ¹ ¹;;;;;;;;Ó---))×15êŸ"s#Î#Vì0{Êogg```²²² X ® \\\\\\ X X²² Ú Ú Ú Ú ƒÞÞ8‹00044‡â  \\\\\\ÞÞÞÞ0000ÓÓ&& Ï Ï||||||€€€€þþþþQQQ«|11×||||ööIIŸŸMMËËËËŸŸŸŸII££x%%ËËxx!!Ï„‹‹„)€€€Ú5D¦[,,wh¯T§§%%xxxxxx¾¾¾¾ºººº99“îñÅ.^2m$Ï‘ÐÐÐ+}}ÐÐÔÔÔÔ···· °]·ãˆˆˆ5555øøøSN^°Fìììì™NûûNôFFFF¡¡÷÷ÿÿØØ…ß66ë뇇!Ž!Ž!å ŠÝssÉÉÉÉÚ    Ö Ö Ö Ö ª ª ª ª T T T T Ö Ö Ö Ö Ö0 Ö Ö®®XXXX%% Ë ËÏÏÏÏ Ë ËxxxxxxŽŽŽŽ77 Š Š     fffgg ¹ ¹ ¹gg;;;;;;;;ÓÓ€&))„„5êEú d"s& ¡Š{gg ```²² X X\\\\\\ ® ²²²² X X‡‡‡‡ ƒÞÞÞ000‹44‡â  \\    ÞÞ‹0ÞÞÞÞÓÓÓÓ||||||)„€&&€««««þþ ¤ ¤)9A1××|| œöII ò òŸŸËËËËËËËËŸŸŸŸIIööËËxxËËxx||Ö› º º›1€€-â—$s(‚(®$ž,Âd¯Túxx%%%ËË˺ºººææ““D® "/U6.ÔÐÐÐÐÐÐ+ÐÔÔ''   e]]]·ãã555555KK¦¦ìFFì™™™™FFF¡¡FFFFF¡ûR÷÷R}Øß:6‘FF"< á 4"é"’"’#?ssÉÉÉÉÚ    Ö Ö Ö Ö ª ª ª ª T T T T Ö Ö Ö Ö Ö0 Ö Ö®®XXXX Ë Ë Ë ËÏÏÏÏ Ë ËxxxxxxŽŽŽŽ77 Š Š     f  gg ¹gg;;;;;;;;ÓÓ€&))„„Û5êŸú¯ #V ¡0 ggg ``` X X X X\\\\\\ ® ²²²²²²‡‡‡‡Þ8ÞÞ000‹44‡â  \\    ÞÞ‹0ÞÞÞÞÓÓ--××||||)„€&&€««««þþþþ„“›Œ××||öQII ò òŸŸËËËËËËËËŸŸŸŸIIööËËxxËËxx||1_0ø3­'~@€€‡<ñ!-ì4±4Ü0Í%Kw¾ Túxx%%€%Ë˺ºººææ““꟦6.Ô++ÐÐÐÐ+ÐÔÔ''   e]]]·ˆˆ555555KK¦¦‘ìì‘??™™ìììF¡FFF¡¡¡ûR÷R¬}Øß:6‘ë  "<#–"é"é%G%G'OsÍÉÉÉÉ Ö Ö ( ( Ö Ö Ö Ö ª ª ý ý T T T T Ö Ö Ö Ö Ö Ö Ö Ö ª ª ª ªXX t t t t t t""ÏÏ t t""""ŽŽŽŽŽŽŽŽ   µ µ  _¹gg½½’’ å å;;èèÓÓ--€€--Û5==—L§§Ý‚{Æggº```` X²  \\\\\\\\  ÞÞ ƒ ƒ0‹ÞÞ‡‡‡‡‡‡‡â      ¶¶‡â4444‡‡ÓÓ----€€))))€&&€YþþþþþQ«-ˆÛÛ-ÓÓÓMMŸŸI£ö œ Ç!tt!!tÏM§M§QQII Ç!tttÏ!!!|9!g/2R&Ñ9€Úâ<ù'(4±8À7è53'ª{hXþþÏt!!!!tt · ·ººººêêêêDŸD+Ð}}}}ÐÐyÔ'}}++  ·]]·]]ˆˆˆããˆ55KK¦¦è•;;•••Bè•ð™ôôô÷÷J¥ûûVV……ç‘Fó!M#–$ñ&K'¦+)­'¦sÍÉÉÉÉ Ö Ö ( ( Ö Ö Ö Ö ª ª ý ý T T T T Ö Ö Ö Ö Ö Ö Ö Ö ª ª ª ª ª ªXX t t t t t t""ÏÏ t t Ç Ç""ŽŽŽŽŽŽŽŽ   µ µ  _¹ÁÁ½½’’ å å;; Ž ŽÓÓÓÓ€€--Û5ââ=òòòÍsÆÆggº```` X²  \\\\\\\\  ÞÞÞÞ0‹ÞÞ‡‡‡‡ - -‡âcc    ¶¶â<é444ââÓÓ--ÓÓ€€))))€&&€YþþþþþQ«Ó-€€-ÓÓˆúú îIö œ Ç!tt!!tϧM§««££ Ç!tt t!! Ç!)9P£Þ€Ú‡âŸ#0¡7f61#&OÖhXþþÏt!!!!ttººººêêêDŸDê+Ð}}}}ÐÐyÔ'}}++  ·]]···ããˆããˆ55KK¦¦è;•;•••èBð•?™ôôJ¥ûûVVßßœFF!M"¨&K'¦*[+µ/-½-  ww$É Ö Ö Ö Ö Ö Ö Ö Ö ª ª ý ýƒƒ ( ( ( ( ( ( ª ªXX ª ª ª ª"""""" t t"""" t t""ŽŽ á;; ᎎ µ µbb  ¹¹gggg½½’’ 7 7;;;;&€€€€€€Ûˆˆââ==——Æk¾¾ggº```²²\\    c  X X ® ®\\ÞÞ000000‡‡‡‡ Ú Ú44¶¶\\\¶ cž®ù444€€€€ÓÓÓÓ))))Ó xÓÓ««QQ««þþÓ-€€-ÓÓ-TTMMöööötttttÏ!|§§þ£££Ït Ç Ç Ç Ç! ÇtÏ))„„ÖÖ---‡D c(‚,’/&ü0{hX«Q!!tt Ç Ç!!¾dlhhhh—————<}}}}Ð+}#''yyÐ+++    ····55555555žž¦¦;;èè••••BB‘FFFðJ÷÷ûVV°ßßß”    $%])+µ//110r  Ñ$É Ö Ö00 Ö Ö Ö Ö ª ª ý ýƒƒ ( ( ( ( ( ( ª ª²² ª ª ª ª"""""" t t"""" t t""ŽŽ á;; ᎎ µ µbbff¹¹gggg½½’’’’;;;;&€€€€€€Û--ˆ=ââââÆk¾¾ggº```²²\\     ®`` X X ® ®\\ÞÞ000000‡‡‡‡ Ú Ú44¶¶¶¶\¶ cù"'rž4€€€€ÓÓÓÓ))))-ÓÓÓQQQQQQþþÓ-€€-Ó-ÓúúMMöööötttttÏ|Ö\\\\þ£££Ït Ç Ç Ç Ç! ÇtÏÏÏÏÏ||ÒÒ-‡ù c$GÝ!lhX«Q!!ÏÏ!!!!¾dlhhhhêê<<<<—<}}}}Ð+}#''yyÐ+++    ····55555555žžKK;;èè••••BBììFFJ¥÷÷ûVV°ßßß”ë  %]&·+µ.j0r3'3Ô3Ô3'662Œßß P® T    ,,,,ï • • •BB • •BBBB ë ë ë ë t t"" Ë Ë Ë Ë ö ö ö ö££QQää7777 Š Š77ä䎎 3Ž;;;;è Ž;;gg ¹ggQQQQUU€Û55ŒŒÞÞ¬R¤¤÷÷÷÷ÈÈu Äqq ƒÞÞ8‹‹00 ƒÞ0 Ö ƒ ƒ ƒ ƒ‡‡ Ú4ÞÞ000‹‹‹‡‡ââ÷÷÷÷J¤2BBØyÌÌ€€ÓÓ××))))××) Ï))jj½½jjÁgxxxxtt!! ò òM òI££þÅÁÁf Ž33333ààMMMM££££ÒÒ€Ú9îH£¼¥J™™?? ±  µµµµyy''yy''VV©©©©©©ææææ@›@æê—<ê»a´]·  »a´    °e  ‘77‘‘ìììÄͶ¾dºÊwÒÙƒÝ%G'ü-11Ì44Ø625… Û Û2Œßß ª ª ª ª® T    ,,,,ï • • •BB • •BB è è ë ë ë ë t t"" Ë Ë Ë Ë ö ö ö ö££ ö öää7777 Š Š Ý Ýä䎎 3Ž;;;;è Ž;;gg ¹ÁÁQQQQUU¨¨€ÛÛÛ11ÞÞ¬R¤¤÷÷÷÷ÈÈ À Äqq ƒÞ8“‹‹00 ƒÞ0 Ö ƒ ƒ ƒ ƒ‡‡ Ú4ÞÞ000‹‹‹‡‡ââ÷÷÷÷J¤#}}}yqq€€ÓÓ××))))×ׄ)))½½jjjjÁgxxxxtt!! ò òM òI£I£jÅÔvÁf Ž333ŽŽààMMMM££££ÒÒ%€„„9“RRJð???? ±  µµÔÔ''ÔÔVV©©©©©©æææææ@@æê—<êa´]·  »a´        ‘77‘‘ìììnnÀÀÄͶd¾ºo$,‡Ù 4!8"’%G'ü+µ/Å3'5Ü7626à Û62222 ª ª ýX T T,,,,,,,,BB • •BB • •BB • • ë ë ë ë t t"" Ë Ë Ë Ë ö ö ö ö££ ö öää7777 Š Š7777ŽŽ á á;;;;è Ž;;gggÁQQQQ¨¨¨¨€€ÛÛÞ„11RRÿ¤JJ÷÷uu n nqq00‹‹88‹0ÞÞÞ ƒ0000 Ú4‡‡00ÞÞÞÞ‹‹â‡44JJJJ##ÐÐÌÌÓÓÓÓ××))×ׄ„„)×|½½½½½ ¹gggÁËËxx!!ttŸŸŸŸöö££jÅÌÌnffààŽ3ŽŽààMMMMööööË%ÒÒ|ÖÞÞCè??‘‘  ¹¹b½ÔÔÜܰV©©VV“9ææ““““êêêê´´a e··´´a]]]·····ää7‘‘‘ììÀfÀrrr̶ddºÒÙ!Ž"é!Ž!8"’%G)W-½0r3Ô6‰7762 Û62222X ý®®,,,,,,,,BB • •BB • •BB • • ë ë ë ë t t"" Ë Ë Ë Ë ö ö ö ö I I ö öää7777 Š Š7777ŽŽ á á;;;;è Ž;;gg gQQQQ¨¨¨¨€€ÛÛÞ„11÷÷¤JJJÈÈÌÌ0000ÞÞ‹åÞÞÞ ƒ0000 Ú4‡‡00ÞÞÞÞ‹‹â‡44JJJJ##uuÌÌÓÓ--×ׄ Ï "×)))„1×½½½½½ ¹gggÁËË!!ttŸŸúúöö££jnff;;Ž333ààMMMMööööË%xx!|))èèèŽää77  ¹¹b½jj..‘û°°u°©©VV©©“9ææ““îîêêêêêêD´´a° ]]´´»a··]·····ää7‘‘‘‘‘ÀffÀrrÌ'¶ddºÒ!Ž)­+&ø#í"’%G)W,b/3Ô6‰626262 …ßß …22 ª ª ª ª ( ( Ö Ö,,ÚÚ™™™™ > >™ > • • • • ë ë ë ë x%%""""££ I£ ö ö ö öŽŽ á á á á á á7777 á á á á’’ 7’è Ž Žè ggQQQQ ¤ ¤Q«--ÛÛ„„„„J¤÷JJ÷uuuuu00ÞÞ‡‡4400ÞÞ‡‡‡‡‡‡ Ú Ú0000Þ ƒÞÞ44‡‡÷JJóóóóuuuuÈÈ#È|××××ׄ) ËÛ-Ó€€--nggÁÁ½½jjjjÏtttxxxöö££Qö££jj½½½ŽŽàà † †ŽŽŸŸúŸŸŸŸŸ!!!!%%xxääääŽŽŽŽbbjfÁÈÈ…………÷'Ú-ò+=ˆ´­R©©ûûææ@@““@@<<<<“““î  ·]´´ e···  ´´»»ää‘‘èè••ÀÀf##``  ºo,#í-f0*±%ô#?$š(©*.3}2#5Ü766‰ …ßß …22 ª ª ª ªƒƒ00,,ÚÚ™™™™™™™ > • • • • ë ë ë ë x%%""""££ I£ ö ö ö öŽŽ á á á á;;7777 á á á á’’ 7’ Žè ŽèggggQQQQ ¤ ¤Q«ÓÓÛÛ„„„„J¤÷JJ÷uuu00ÞÞ‡‡44‹‹ÞÞ‡‡‡‡‡‡440000Þ88844‡‡÷JJóóóóuuuu###È|×××××)„€Û-Ó€€--nggÁÁ½½jjjjjjtÏttxxxöö££QöIIb½½½ŽŽààààŽŽúúúŸŸŸŸŸ!!!!ËËxxääääŽŽŽŽbbjv…œœï………Q+ê0§(ˆÓ´­R©©ûûææææ““@@<<<<“““î  ·]´´aa e·]··  »»ää‘‘BB••ÀÀÀÀÈÈ``  ºowÝ&¢'ü'ü$š$š%ô'O(©,¹/n+^1Ì5Ü5/22 … … … … ª ª ª ª T T T Tƒƒ00  ,,FFFF™™™™B èïï ë ë ë ëxxÓ-|" t t ö ö££ ö ö ö öŽŽ á á á ᎎ7777 á;ŽŽ’’ å å Ž ŽèCÁÁggggQQQQQQþþ&€ÛÛ××××÷÷÷ÈÈÈÈÈÈÞÞ00 Ú444ÞÞÞ ƒ‡‡‡‡‡‡‡‡Þ ƒÞÞ0å88444 ÚóóóóÈÈ##ÐÐ##×ׄ„„„„„Û€----€€ÁÁÁÁjj½½jjjj!! Ç ÇËËË%öö££££I£½½½bààŽŽŽŽ;;MMúúM òŸŸ!!!!ËËËË77773Žààb½Ð'i2=2=!Ã:àà•ÿY¤´ZRR©©ûûææ““““““<<<<“9““  ]]aaaa    ee·»»»»ää‘‘•••ðnnnnnnu  ³³hhÂ{Õ Š!å!å$š$š'O*±-f.Á03'3'5/22 … … … … ª ª ª ª T T T Tƒƒ00  ,,FFFF™™™™B èïï ë ë ë ëxxxÓ|" t t ö ö££ ö ö ö öŽŽ á á á ᎎ7777 á;ŽŽ’’ å å Ž Ž ŽèÁÁggggQQQQQQ ¤ ¤&€€€××××÷÷÷ÈÈ n nÈÈÞÞ00 Ú444ÞÞ8Þ‡‡‡‡‡‡‡‡8ÞÞÞ‹‹88444 ÚóóóóÈÈ##uu##×ׄ„„„9£E5ˆˆ--€€ÁÁnnÁÁjjjjjj!!!!ËË%Ëöö££££I£½½½bààŽŽŽŽààMMTT§Múú!!!!ËËËË7777Ž3ààb½Ð'i3—3—#•……ààààZÿRR©©ûûææ““““99<<<<“9““  ··aaaa    ee·]aaaaää‘‘••;•nnnnnnu    hh {Õ00!å$š*-f-f-f.Á0r0r1]]]] ° Ö Öƒƒ    ®®®®®®qÄÄmmmmBBïï™™ >™MMMMMM  ú)ÏÏÏ""""  ¹¹    µ µbbbbgÁ ¹ ¹ ¹ ¹ ¹ ¹gg ¹ ¹Ág¨¨¨¨¨ M ú úQQQ«««þYÐÐÈÈu ï ïJJ44‡‡ÞÞÞÞÞÞÞÞÞÞÞÞ``²²²²``²²``¶¶  ÈÈuuuuÈÈuu##]l‹|·¯¯]]]ÁÁÁjjjjÁÁnnööQöŸŸŸŸŸŸMMMMúŸbbbb¹¹ fŽŽŽŽ‘‘77Ò-<—‡xxx££öööQ££ f  bµµŽè;;ì "*"*Mã..……ØØ­­¥¥RRRR<<<<<<h hh¾¾ßß999ßßß55ˆˆ5555ˆˆ5à;èè‘‘??n‡âêêDŸùL[²! &v.•1ø/C+à*†-;.•-è]]]] ° Ö Öƒƒ    ®®®®®®qÌyyÈÈmmBBïï™™ >™MMMMMM  ú)ÏÏÏ""||  ¹¹    µ µbbbbgÁ ¹ ¹ ¹ ¹gg ¹ ¹Ág¨¨¨¨¨ M ú úQQQ«««þY**ÈÈu ï ïJJ44‡‡ÞÞÞÞÞÞÞÞÞÞÞÞ``²²²²``²²``cc##uuuuÈÈuu##]·ll]¯¯]цvÁÁjjjjÁÁnnQQQöŸŸŸŸŸŸMMMMúŸbbbb¹¹ fŽŽŽŽ77 Ü ÜxÒ—ñ‡xxx££öööQ££ f  bµµŽè;;‘Fûû‰ÔÔÔ++}}RR¥¥RRRR<<<<<<êêh hh¾¾ßßßß9ßßß55ãã5555ãã5à;èè‘‘??½½nÀÀ‡âêêDŸù¦²W#Á)+,Ž)Ù*†&v)+*†)Ù ° °  ° ° Ö Öƒƒ,,,,®®\\y=¯ 2" ÀBBïï ë ë™™MMMM    M§)Ï"""")„¹¹      bbbb µ µbbgggggggggg ú ú¨¨ ú ú ú úQQQQ««YYØ}ÈÈÈ n n n ï ï÷‡‡4400000000 ƒ ƒÞÞ²²``²² ²²²``cc  ######ÈÈuuuÐÌÌÌ̯¯¯  ¯¯¯lƒÎJ!Z†vÁÁnnjjjjÁgÁÁQQööŸúM ò òMM§MM§Mb½f ¹¹ŽŽŽŽääääxÒ--€%xx££öööööö^^^^b;àŽŽ77??ÔÔ''}Ø}}¥ÿÿ¥R øRRêê<<<<<<ººhhdd¾¾ßß22ßߌŒˆã==5555ããã=B÷J•™???jÄÄÄÀÀÀ‡‡ââêêêê—ñùùªª!º%É$o#Á#Á%&v&v ° °  ° ° Ö Öƒƒ,,,,®®\\Ó/í.“«} ÀBBïï ë ë™™MMMM    M§Ï t""""Ï)¹¹       bb µ µbbggÁÁÁÁggÁÁUU¨¨ ú ú ú úQQ««««þþ#}ÈÈÈ n n n ï ï÷‡‡4400000000 ƒ ƒÞÞ²²``²²² ²²``    ########uuuÐÌÌÌ̯¯ ¯U¯¯¯]Î;•+ÁÁnnjjjjÁgÁÁQQööŸú§MM§M§§§§Mb½f ¹¹ŽŽŽŽääääxÒÒÒ%Ëxx££öööööö¹¹^^bbb;àŽŽ77ääÔÔ''}Ø}}¥ÿ¥ÿ­RRR<<<<<<ººhh¾¾¾¾ßß22ßߌŒˆããã5555ããã=B¬Zð™???jÄÄÄÀÀÀ‡‡ââêêêêñLùùPPP!º#! ! #Á%% ° °]],,,,ƒƒ Ö Ö\U+Þ*ƒœ}uBB • • • •BB££ I I    MMxx Ë Ëxx Ë%        µ µbbbb µ µgg ¹½½jj½jjgg¨¨U ú¨¨ ú ú««««þ ¤QQ##ÈÈ Ä Äqqóó ™ó÷JJ‹‹‹‹‡‡‡‡00ÞÞ Ú Ú Ú4\\    \¶``²²````ÌÌÌÌ&Ì&&ÌÌÌ&#È##YY«YYQ«YYY³``vÑÉnÅÅnjjjj££££úú§MQQöQ§§úúbbbb¹¹  ŽŽ;àŽŽŽŽ!|)ÏxxxúúMMúúMMbbbbjäŠ777777}}}}ÐÐ}}RRRR©©ûûê<<ææææ¾¾º55ˆˆ5555ßß99ŒŒŒŒŒŒç癩VFFìììÀÀÀÀjÄÄÄ5555ææ““DŸñLTù "¾!c !c"¾ ° °]],,,,ƒƒ Ö Ö\ÌëEç2*BB • • • •BB££ I I    MMxx Ë Ëxx Ë%  ff    µ µbbbb µ µgg ¹½½jjrjgg¨¨U ú¨¨UU««QQþ ¤QQ##ÈÈ Ä Äqqóóó ™÷JJ‹‹00‡‡‡‡00ÞÞ Ú Ú Ú4\\    \¶``²²````ÌÌ&&&ÌÌÌÌÌ&}###YY«YY öQYYþYvÉnÅÅnnnjjjj££££úúM òQQöQ§§úúbbbb¹¹  èè;àŽŽŽŽ|ÖÞ„ÒxxxŸŸMMúúMMbbbbj䊑‘7777}}}}ÐÐ}}­­RR©©ûûê<<ææææ¾¾º55ˆˆ5555ßßßߌŒŒŒŒŒçç™ôFìFìììÀÀÀÀjÄÚÚ55ææ88êD—ñùŸL®®® ® Y Y ° °]],,,, ( ( Ö Ö®®Ì&&6Q!`”uBBB • • • • ö ö ö ö    MMxxx  Ë Ë Ë Ë  ¹¹    µ µbbbbjjjÅ'Ü‚rgg¨¨ úU¨¨¨¨þþQQ ¤ ¤ ¤ ¤Ðuqqóóó ™ ïJ÷ÞÞ00 Ú44 Ú00ÞÞ‡‡44¶\¶¶    ```º````Ì&.‰&&ÌyÔ&Ìuu##YYYYYYYY««nnnnÅÅnnnöö££úúMM££ööúúúŸbbbb f  ;;à;;;ŽèÞýXH-xxxŸŸŸŸúúúúbbbb½½½½ää‘‘ŠŠääÐÐÐÐ#}}}RR¥¥ûû©©ææææhhhh55ˆˆ5555Œ2„ߌç99ŒŒ9”ìVV¡ììì‘ÀÀjjÄÄÚÚ‡â88Þ8ê<——LLLùT¦[® Y Y ° °]],,,, ( ( Ö Ö®®qÌ&6&Ê0D$Ã…BBB • •ïï ö ö ö ö    MMxxx  Ë Ë Ë Ë  ¹¹    µ µbbbbjjÅÔû'# ÜÉÁÁ¨¨ úU¨¨¨¨þþQQ ¤ ¤ ¤ ¤uqqóóó ™J¤÷ÞÞ00 Ú44 Ú00ÞÞ‡‡44¶\¶¶    ```º````Ì&.‰&&Ìy&ÌÐÐ##YYYYYY³³««««nnnnÅÅnÉÉQQ££úúMM££ööúúúŸbbbb f  ;;à;;;Žè9%w.ð%w<ÒxxŸŸŸŸŸŸúúbbbbbb½½ää‘‘ŠŠääÐÐÐÐ#}}}RR¥¥ûû©©æææællÂÂhh55ˆˆ5555Œ2„ߌç99ŒŒ9”ìÀ uVììì‘nnÀÀjjÄÄÚÚ-‡ÞÞÞ8ê<———ññùTL¦¦T ¥ ¥ øRÿÿ£ I ö ö ö ö ö ö        MM  úff#÷$a:莎Ž77ää,,, Ò Ö Ö Ö Ö®® T T®® T T ª ªXXXXXXÈÈÈÈÈÈÐ:*³2Ò)Xû¡¡F²² ® \\\\\\;;;;’’’’;; Ž Ž’ì? 娨 ú úQQQQ¨¨UUUU¨¨€€€€××) ϯ¯««þþnvn?š??ššššyyyy###}}##}}###   g¶¶¶¶¶¾¾c ¶¶ŽŽàà7777Ž333Šä‘‘QQQööööö££öQQQQQ#œ"¬f¹¹Á ¹¹µµµúúTúöQþþ§§TúMMúúšš íGžžøžÛÛˆ.„„„„„ß99AAç2ôôGGCžKKžžKKK¦¦¦øøK¦™^¸NBB;•ô?ä™ð•••rÌyrÌyyyÔØ2…ß‚‚ÕÕ++Ù ¥ ¥ øRÿÿ£ I ö ö ö öQQ        MM  úff¹É~vÁ莎Ž77ää,,, Ò Ö Ö Ö Ö®® T T®® T ª ªXXXXXXÈÈÈÈÈÈu**"”„eû¡¡F²² ® \\\\\\``;;;;’’’’;; Ž Ž’ìš?¨¨ ú úQQ««¨¨UUUU€€€€××)„¯¯««YYnÁÉn?šššššššÔÔyy###}Ø}#}Ø}##   g¶¶¶¶¶¾¾¾c¶¶ŽŽàà7777莎Žä?F‘QQQööööö££QöQQQQnÈÈÁ ¹¹  ¹¹µúúTúQ«XXTúMMúúšš íGžžøžÛÛˆ.„„„„„ßß”««AŒôô¢¢žøKKøøKKK¦¦¦øø¦K?™™™BB•ð????•ðððrÌÄÌ'yyyÔØ2*…''ÕÕÑÑ~ ¥ ¥ ¥ÿ­­QQþ££££þúúúú    úú¹¹ fnnŽŽ á áää77  ,,ƒƒƒƒ\ ª® TXXXXÈ nuÈ#]¸¨¡¡FF²²²² ® \\\\\\  ;; Žè???? Ž Žèè’ì??¨¨¨¨þ ¤þY¨¨UUU¯Ó-€€×ׄ„¯¯YYYYÁÁnnnnìììGššššÔÔ&&##Ð***ÐÐÐÐÐÐ   g¶¶¶¶¶c¾cc¶¶;;ŽŽ777‘è莎ä?F‘QQQööQöö££££QQQQffff¹¹¹¹ f  µMM§þX`\\§§§úúGGššññKKvooÛÛÛÛ„„„„222çIîçŒôô¢¢žøžøKKKKøøK¦øøøøä?‘‘BBBB???™••BByrryyyÌÌ*…**Í'‚'$~Ñ ¥ ¥ ¥ÿR`«þ££££þúúúú    úú¹¹f ¹¹ŽŽ á áää77  ,,ƒƒƒƒ\\ § ª® TXXXXÈ nuÈ#NóNó¡¡FF²² X X ® \\\\\\  ;; Žè????èèèè’ì??¨¨þ ¤ ¤þ¨¨UU¯UÓ-€€×ׄ„¯¯YYYYnnnnGGGìššššyy}}*ÐÐÐÐÐÐÐÐÐ   g¶¶¶c¾cc¶¶;;ŽŽ‘‘‘7ŽŽŽŽä?ììQQQööQQQ££££QQQQff  ¹¹¹¹ fffjMM§Xþ»ÊÆ\§§úúGGôôññññvooÛÛÛÛ„„„„22229ߌ2ôôGGCžžøKKKKžž¦Kžžžžä?‘‘èèBB???™••èèÄÌÌyyyÌÌÐ***rÍ'ÍÉ$Ñ© Nÿÿ­\§MMMMU¯UúúúMMúúff¹¹7777ŽŽŽŽ Ò Ò,,ƒ ( Ö ÖXXXXXX ª ª®®®®®®® T À ÀÈÈÈ#÷ ï ïóóFF\\ ® ® X²\\\\;;;–????’’’’èèèèþþ«« ú úUU¨¨¨¨UU€€€€„)×1««UUU¯nnÁnnðKK–ššGGyyÔÔÔy&&}}ÐÐÐÐÐкº`º¶cccccc``ºº‘7‘‘;;èŽääää;;èè§MM££££úúMMúúMMbbbbbbbb½½jj¹¹¹úTTT\·Æ å"íÎ\«QQQôôôôžžññ ÁoÉÅÅÅÅ2222ˆ...„„„ß„ßßßøøžžžžñK¢GGGôô¢¢ôšG¢7‘‘‘;•è••••••BB½ÄÄuu###ÈuÐÐÐÅzÍÍ zr N©ÿÿ­RMMMMMM¯tdUúúMM      ¹¹ µ µ7777ŽŽŽŽ Ò Ò,, (ƒ Ö ÖXXXX²² ª ª®® T T®® ® À ÀÈÈ nÈ B ï ï ™ ™FF\\ ® ® X²\\\\;;;–?? å å’’’’èèèèþþ««UUUU¨¨¨¨UU€€€€„)|ׯ¯ ¯nnÁnn–ðððššGGyyÔÔÔy&&}}**ÐÐÐкº`º¶¾¾¾¾ccºººº7‘‘‘;;Žèääää;;èè§§§££££úúMMúúMMbbbbbbbbbbjj¹úTTT·{$õ-0v(WÖl«QQôôôôžžññ ÁoÉÅÅÅÅ2222ˆ...„„„ß„ßßßøøøøžžñK¢GGGôô¢¢ôšG¢‘777à;è••••••BB½ÄÄuuÈÈ#ÈuÐÐÐÅÅrr Å ü üÿÿRRM ò    MM§\ úMMMMMM    bb7777 á Ꭰ3     Ö Ö Ö ÖXX ª²²XX®®\\\®®®® À ï ïFFFF ® ®\\ ® ®  ² X² Xè Žèè’’ å å å å’’;;;;QQQQ¨¨¨UU¨¨UU€€€€„)|׳³]]¯¯nnÁÁnnððCGGšš&&.Ô&}}}}}}}}   gkkggºº‘‘??;;•;ääää;;Žè¯¯§««££úŸMMúúŸŸµµµµµµbb½½ÁÁn§\·Ö*_4…7:7:4…+ Ý»«¢¢ôôžžžžooooÅÅÅÅ„ßß„ˆ.ÛÛ22„„22ßßKñKKžøKKG¢ôšôô¢¢¢G¢ü7777;;èèè••••èèjÄnÈuuuu##kkÅÅk ü üÿÿRRM ò    MM§§UúMMMMMM    bb7777 á á 3Ž     Ö Ö Ö ÖXX ª²²XX®®\¶¶¶  ®®u ï ïFFFF ® ®\\ ® ®  ² X X²è Žèè’’ å å å å 7 7;;;;««QQ¨¨¨UU¨¨¯¯€€€€„)×1³³]]¯¯nnnnððC¡¡ôô&&.ÔÛÛ&}}}}}}}}gggÂkkkkkkggºº‘‘??•••;ääää;;èC  \««þþTúMMúúúúµµµµbbbbÁÁn\·Æ&O3Ø7:7:7:7:4…(WÊ``üüôôøøžžÉÉooÅÅÅÅ„ßß„ãˆÛÛ22„„22ßßñ –ññžøKKG¢ôšôô¢¢¢GG¢7777;;èèè;;••èèjÄnÈuuuu##kkkkk'~~ Ð+ Ë Ë Ë Ë""||%%% Ë Ë%% Ë    bb µ µŽŽ á á á á 3Ž,,  ,,,,,,,,00ƒƒ Ö Ö Ö Ö (ƒƒÝ_ÉÙÙÉ_qqqq# n À n n Ä ÄqqÞÞ0000 ƒ ƒ Ú Ú4444 Ú Úgg½½j ¹n&&&€&&Ó-«««QþþþY«««U¯11„„„„××ðððKððððÉÉÉÉûVVVÿYRRÔÔ&.Ô&“í@@““ííoÂg½½jjÅjjjŽŽèèèèC—ùÚ€Ò-Ö|ÏÏÏÏ)t    ääää‘‘?™‡â—!0¡7f7f7f777¼/_›HHäÕ  $$ÉÉžžKKôšššÛÛˆˆˆˆÛÛ´´´´Å ssssssvvÉÉvvÉÉ  ssäääääää?‘‘ä?ì‘??••èèBÈÈuuuu##kkkkÁÁ'~~ Ð+ Ë Ë Ë Ë""||%%% Ë% Ë Ë%    bb µ µŽŽ;; á á 3Ž,,  ,,,,,,‡‡‹‹ƒƒ Ö Ö Ö ÖƒÝƒÝºC,Ì,Ì!øo__ÌÌqqØ#u n nqqÞÞ0000 ƒ ƒ Ú Ú Ú Ú44 Ú Úgg½½jnn&&&€€€Ó-«««QþþþY«««U¯×ׄ„„„11KKKðððððn#ÉÉûVVVYÿRRÔÔÛ.Ô&8“@@ííííoÂg½½jjÅjjjèèèèèèCR¶-?+7 cêÚ-Ò|!ÏÏÏÏÏÏ    ääää‘‘?™-‡<¶0¡7f7f7f777¼/ º")†)†©/zz$$ÉÉžžKKôšššÛÛˆˆˆˆÛÛ´´´´Å ssssssÉÉvvÉÉ  ÍÍäääääää?‘‘ä?ì‘??••BBBBBnnÈÈkkkkÁÁo z z~ # Ð Ð Ë Ë Ë Ë""ÏÏ%% Ë Ë Ë Ë Ë Ë    bb  ŽèŽŽŽŽŽŽ,,ÚÚÚÚÚÚ,,‡á@š8ƒƒƒƒƒƒÝÝÝo'b5˜5˜'bo²²qquuu n n Ä ÄÞÞ00Þ ƒ ƒ ƒ‡‡ Ú Ú‡‡‡‡½½½½½½nn&&&€--€€YþQQ««þYYY««¯¯]1111„„ÞÞøøøøðð##ÉÉÍrrÍVVYÿ¬¬ÔÔÛ.ÔÔÔ““@@íí““¾¾¾¾jj½½èèŽèCCðÿ% 44'Õñ‡-Ò|!Ï)!!||¹^  µµ77Šä77??€ÚâL(‚4±6¸87¼7¼5*3$É2R3­#Šz ÉÉvvžžññGGššÛÛˆˆÛÛ..YYÅÅÅ  ÅssoÉÉÉÉÉ    ääääää‘‘ää‘‘ì‘ä?èBBBBBBBnnnnnnÈÈk½½ooÁ z z~ # Ð Ð Ë Ë Ë Ë"" t t Ë Ë Ë Ë Ë Ë Ë Ë    bbbb 3ŽŽŽŽŽŽŽ,,ÚÚÚÚÚÚ,,‡á_n¢8ƒƒƒƒƒÝÝÝ3((è²²qq À n n Ä ÄÞÞ00Þ ƒ ƒ ƒ‡‡ Ú Ú‡‡‡‡ ¹ ¹½½½½jj½½&&&€--€€Yþ««««Y³YY««¯¯]1111„„ÞÞøøøøKKÉÉ##ÍrrÍVVÿY¬¬..Û.‰..ííššííííoo¾¾¾¾Å޽èèŽèèè•¥)/-?&zñ‡-Ò|!)Ï!!||¹^  µµ77Šä77ää%€-âù'(2©6¸7¼5.C º›õ#o'~/z ÉÉžžññGGššÛÛˆˆÛÛ..´´  Å  ÅssÉ$ÉÉÉÉ    ääääää‘‘ää77‘7ä?èBèèBBBBnnnnnnk½½oog''+ Ð # # Ë Ë Ë Ë""""xx Ë Ë Ë Ë Ë Ë _ _ _ _bbbb77ä Š Š Šä䃃000‹0 ÖÚÚÚ4G¢š‹ƒƒ00Ú4ÚÚ ¾   __qq Ä ÄÈÈÈ#ØØ#ȇ‡44‡‡ Ú Ú‹‹ÞÞ ƒ ƒ00gg½½½½jj½½€€ÓÓ))))¯¯UUYY««««««YY³Y„„„ÞˆˆˆˆøRøøOOOôÉÉvvvvvv]¬YYÛÛÛ‰‰ššššííííkƾ¾¾kkÁÁÁÁÁÁÁf;•èŽèèðJ@ªX£€%%ÏÏ||xxxx      ¹¹ŽŽŽŽŽŽ;;%%€5æª"*3,;%w²î55<—ÝÍ  ÉÉvññžžññññ„„ß߈...a´´ss zÉooÉ$Ù;+ssÅÅÉÉv77ää‘777ääää;•??‘ìBBBBnnÀÀÀÀnggÁÁ'' Ð+~~ Ë Ë Ë Ë""""xx Ë Ë Ë Ë Ë Ë _ _ _ _ ½bb77ä Šäää䃃000‹0 ÖÚÚ ÚÝ8‹0ƒƒ00 ÚÚÚ  ¶¶  qq Ä ÄÈÈÈØ÷÷ØÈ‡‡44‡‡44‹‹ÞÞÞÞ00gg½½½½jj½½€€ÓÓ))))UUUUYY««««««YY³Y„„„ÞˆˆˆˆøøøOOôO##vvvvvv]]]¬YY6ÛÛÛÛÛ‰‰ššššííííÆk¾kkÁÁÁÁÁÁÁf•ð莎Ž;•Ö‹“ÞÚ€%%ÏÏ||xxxx      ^^ŽŽ33ŽŽ;;%%%Ú1‹@ªXH“„€€Ò-(Í  ÉÉvññžžññññ„„ß߈...a´´ssÅ ÉooÉÉ~;àÍÍ  ÉÉv77ää‘777ääää;•ää7‘èèBBÀÀÈn  ººggÔÔ++~~ Ë Ëxx t t Ç"xx Ë Ë Ë Ë p Ë _ _  bb µ7777ää77 Ö Öƒƒ00ƒƒ,, ÚÝ݃ƒ Ö ÖƒƒÚÚ‡,\\\\__²Xqq Ä ÄÈÈu*””ØÈ‡‡444444Þ88Þ‹‹00 ¹ ¹gg½½½½½½½½½½½½ÓÓÓÓ××××UU«««YY««`1×Þ95555K¥øøôOOO#~##ÑÑ##   °¬YY‰‰ÛÛÛÛ66HHššõšíí¾¾kƾnnÁÁÁÁÁCC莎Žèè|Ö1Ö--Òx!!ÏÏxxxx        èŽŽŽŽŽ;;%%Ò-Ö1Þîî9Þ)€€Ò-ÍsssÉÉÉÉžžKKññžC„„22ÛÛˆˆ´´´´aass  É$+Ñ zz ÉÉÉÉŠŠ??77ŠŠŠŠŠä;;äää?èè••fÀÀÀÀ  ºººÔÔ++~~%%xxÏÏ|"xx Ë Ë Ë Ë Ë%¹¹  bb µ7777ää77 Ö Öƒƒ Ö Öƒƒ,, Úƒƒƒƒ Ö ÖƒƒÚÚ‡,\\\\²Xqq Ä ÄÈÈuuÐÐ#ȇ‡4444448“8Þ‹‹00 ¹ ¹gg½½½½½½½½½½--ÓÓ××××UU«««YY`Œ1„Þ5555K¥øøO©©©#~~~ÑÑ~~  e a´´‰‰ÛÛ6666HHõõOõHHs¾k¾n#vÁÁffèèèŽèèèè|ÖÖ|ÒÒÒx!!ÏÏxxxx        ŽèŽŽŽŽ;;%%xÒ|Ö„Þ9„))%%xÒÍsssÉÉÉÉžžKKññžCßß22ÛÛˆˆ´´´´aass  oÉvÅ z ÉÉÉÉŠŠää77ŠŠääŠäèè;;??ä?èè••ÀÀÀÀÀÀ  ºººº_Zÿÿÿ­RúúM§§§§ öQQ ö  úMM"""" Ë ËxxMMMMúúMM ª ªXXXXXX®®®®XXXX Ö Ö Ö Ö‡áÚ XX\\\\ ï ï ï ï ï ï÷÷÷÷RJJ÷÷NNóóóóFF’ 7 å å;;èèèè;;’’?ššš??ììì’nÁÁÁÁÁÁrrzKðKKKKzz''‚‚ÑÑ~~zÔ‚Üõõ¢¢ùùLLžžñññLLLõõ¢¢OšHHHHíí@@íHJ¥RC••èèjjj€€ÒÒÏÏ||§MŸúöö££ŸŸMMQöööxxxxËËxxää77‘ì™™ìì‘‘;;;;žžññGGôôÉÉvv$ÉÉÉvvvssÅÅGGGGGGGGCCžžññCCGGGGôô¢G55㈠       ff^¹bbj§§þþþþ£þ«þþþþËËËÄ´ZZ­RúúM§·!Q öQ öú  MM"""" Ë ËxxMMMMúúMMXXXX²²®®®®XXXX Ö Ö Ö Öá<4ÚXX\\÷ B ï ï ï ï ï ï÷÷JJ÷¬NóóóóFF 7’??;;èèèè;;’’?ššš??ììì’nÁÁÁÁÁÁrrz¥KKKKKzz''‚‚ÑÑ~~Ô/7FO¢¢ùù¦¦ùùLLñLLLõõ¢¢õõHHHHíí@@íHJðC••èèj%%ÒÒ))||§MŸúöö££ŸŸ§§QöööxxxxËËxxää777‘??‘‘77;;ààžžññGGôôÉ~††~$ÉÉvvÑvÍÅÅGGGGGGGGžžžžññžžGGGGôô¢ü55㈠         ^¹bbj§§§§þþþþþX«XXþþËËË=­­­UúúUÆ#õ!\£ IQ öú  MM""""xx%%ú  MMúú§M_XXXX__\\\\XXX²0 Ö Ö Ö44‡,XX_®®J ï ï ï ï ï ï ï ï ïJJR¼ ¡FFóóFF’ìì’èè;;èè Žè????ìììì??ììÁÁÁnnÁÉÉrrzøøKKøø¥Kzzzz''‚‚~~++Ô‰>óOOO¦¦¦¦¦¦¦ùù¦¦¢¢¢HOõõõšõHH@@@OøC••CC½½½½xÒ€%||||§MMM£££þMM§§QöööËËËËxÒxxääääää??ääää;àààžžKKôôôô~ZÿŽ~vvvvv Å í íG¢ôôôôKñññññCžšôGGôô¢¢55ˆˆ      ¹¹ f^¹½½b½§§úúPPþþþX««XþPPqqËË&i­¼UúúU·Æþ£Q ö  úMM""""xx%%ú  MMúú§º_²²XX ª ªXX² ‹0 Ö ÖÚÚ‡,XX ª®® ïJ ï ï ï ïJJ ï ïJJRV¡FFóóFF’ 7ì’èè;;èè Žè????ìììì??ììÁnnÁnnrrzøøKKøø¥Kzzzz''‚‚ØØ††‰‰ä䪪ªª[SS¦[ýýý¢ªOOOõšHHšššõøø••CCjj½r½½xÒÚ€||||§MMM£££þMM§§QöööËËËËxÒxxŠŠääää??ääää;àààžžKKšššOè-3§/˜RÙv ÅssGGG¢ôôôôKñññññCžôšGGôô¢¢55ãã    ff¹¹ f^¹bbb½§§úú««þþ£þPPþ£PPqqËË"^­­QQ£þX³Xþ§MMMMMMM""""ÏÏ|| ö ö££M§\Æ3~ÂX ª ª ª ª\\ ¾8ƒ Ö Ö,,,,XX_óóFF ï ï ï ï ïJ¡¡¡FFF ™ ™¤¤¡¡¡¡FFFFè Ž;–’’’’? å å åèè––––èCCCCvÑ+vÉnnnÅÅrrrÅøøø¡ü¡¡vvvÑ'‚Ô/3ØØ3‰ä‰‰®®SS[[[®Sª_[®®ùùSSOõõšùžññû¡¡FC••½jj½½ÒÒÒÒÒx%€§MM§§Múúúúúú££££ËËËË!!!!77ääää‘ì莎Ž;;莚ôGGGG¢¢;'y1 .ëÿ+ÉÉÅÅsôôGGñññKôšGGññøøGGšôñññK9”ŒŒµµµµ  ^¹bb¹ff£þPP§§úú§§§§§§§Äqquu^­­­­QQ£þX³Xþ§MMMMMMM""""ÏÏ"" ö ö££M§%O/,Ì;g ª ª\\  ƒƒ00,,,,²²_óó¡¡ ï ï ï ï ïJ¡¡¡FFF ™ ™JJ¡¡¡¡FF¡¡è Ž;–’’’’? å??èè––––èCCCC†ÿ"´•#ÉnnjjrrrÅøøøü¡¡¡vvvÑ'‚/ÔØ3Ø3‰äää®®®®[[[¶¶¶c¹__nk[®®SSSSªOšõùžLL û¡FC••½jj--ÒÒÒx%€§MM§§Múúúúúú££þþ%%%%!!!!77ääää‘ì莎Ž;;莚ôGGGG¢¢ÑðRR;ÑÉÉÅÅsššGGñññKôšGGññžžGGšôñññK9”ŒŒµµµµ  ^¹bb¹ffþX««§§úú§§§§§§§ÄqqÀu©ÿÿ­­££Q«ÂÒUúúúMMMM"""""""" ö ö££§Æ,4>2ã º ª ªX²®®\ƒƒ Ö ÖÚÚÚÚ®®®®XXóóóó ï ï ï ïóóFF ™ ™FFóóóóFFóóè Ž;–’’ å å å å??èèCè––––èCðKB.52E&~ÉnnÅÅÅÅK¥¥¥üüü¡ÑÑÑ+ÔÔ‚‚†à7‘ì‘c¶¶¶¶kgggÁŶ[¶[ªOHHžžLLûûôôJð•ðÅÅrÅŽ½ÒÒÒ-ÒÒ%%úúúúúúúTMMMM££Q«xÒËËtt!!ää77ää7ìèŽ;àà;;àGGGGôôOôvÑ++$$ÅÅÅÅššššññžžôšššñKžžššGGñKKK2ç9ßµµb½f   bbb f¹¹P«§úúúúT¯§§§§qqqqÇÇÇ©ÿÿ­­££Q«Ò'Ú`¯UUUMMMM"""""""" ö ö££M§\Ö%Z&µ3ºX²®®\ƒƒ Ö ÖÚÚÚÚ®®®®XXóóóó ï ï ï ïóóFF ™ ™FFóóóóFFóóè Ž;–ìì å å å å??èèCè––––èCðK3"&"~Énnr½ÅÅÅÅK¥¥¥üüü¡ÑÑÑ+ÔÔ‚‚†à‘ìFìccc½kkkkÅkÁÁÁgŶ[¶¶[[[ªO¢¢žžLL¡¡ôôJðð•jjrÅÅÒÒÒ---€€úúúúúúŸúMMMM££öQÒxËËÏÏ!!ää77ää Ü‘èŽ;àà;;àGGGGôôôšvvvÉÉÅÅÅÅššššññžžôšôôñKžžôôGGñKKKŒŒ9ßµµb½f ffbbb f¹¹PP«§LúúúúT¯§§§§qqqqÇÇÇÔÔÔÔ%%€Ú=§—ˆÞތ׀%xx öQ ö ö    MMÏÏ""ÏÏ׌ùžé4‡‡‡‡®® T®XX  ,,,,ÚÚ®®®®\\®®uuÈÈqqqqFF ™ ™ ï ïÈÈÈÈqÌqqè Ž;;èèè Žggèè––’’ššv+Ø~rrrrÅÅÉÉÑÑzzzzÔzÍ''‚//ÜÜÜ‘ììììkÅkÅrrGGšš Kðéé ¹_²WWý¦¦SùLLÌrvnnèè••••ððTT§§««««§§§§úúúú££££QQöö!!ÏÏ%%ËËb½jjnnŽ3ŽŽ‘‘77vÉÉvv  ssooÅÅsoooÉssÅÅCžKKôôGGCžžCñKKKˆˆ5^^  µµjàà;;ääääúú§§PPöö!|)ƒÒx%%œœœœ÷œœÔÔÔÔ''%%%€ˆˆˆ-ÞHöŒ€%xx öQ ö ö    MMÏÏ""ÏÏ||444‡‡,,®® T®XX  ,,,,ÚÚ®®®®\\®®uuÈÈqqqqFF ™ ™ B BJJÈÈÈÈ Ä Ä qqq Ä Äè Ž;;èèè Žggèè––ììššnÉrrrrÅÅ##ÑÑzzzzÔz'‚'‚‰‰777ìFFì¡kÅÅ r Í"' Í ¡ ¡ôô!¥ KCCÁ¹ ²Wý¦[[[SùLLÌrvÈÈCC••••••TT§§QQQQ§§§§úúúú££££öööö!!ÏÏ%%%%b½jjØ#nèŽŽŽ‘‘77vÉÉvv  ssooÅÅsoooÉssÅÅCžKKôôGGCžžCñKKKˆˆ5Û^^  µµjààààää??úúLLöööö!|Î)Òx%%œœœœ÷œœÔ zÔÔxÓ%%%%€€Þ££9€%%% ö ö I I    MM""""""Ï)ÚÚ‡‡ÚÚ,,®® ª ªXX,, Ò,,,ÚÚ\\\\\\®®#ÈÈÈqqFF ™ ™ B B¤ÿÐuÈÈ Ä Äqqqq ÄqÌyè Ž;; Žèèè ¹ ¹gg––èèìì??nnÁÁÅÅrrrÅzÑÑÑvÍÍÍ'''Ô///Ü7‘‘‘FF¡¡ûÅÅÅ Í$Ü#‚#‚"©!O"©"©$Z# ø øÁÁ¹_[®®¦žžÌÌÈÈÈÈððððCèCèTTTúQ««Q§§TúúúúúöQ££öö££ÏÏ||%€%%jà ¤…ÁŽŽŽŽääääÉÉÉÉ  ssoooo zÉÉÅÅssññKK¢GG íCCžžññžžÛÛˆˆ^^  µµµààà;‘ìôô¯TúúööI£!|ÎÎxxxxBBœœIIïÔ z''ÔÔÓx%%%%%%)9“Þ€% Ë Ë ö ö I I    MM""||"" tÏÚÚ,,ÚÚ,,®® ª ªXX,, Ò,,,ÚÚ\\\\\\®®#ÈÈÈÌÌFF ™ ™Y´ÐuÈÈqqqq ÄqÌÔyè Ž;; Žèèè ¹ ¹gg––èè’’??nnÁÁÅÅrrrÅzÑÑÑ+'''Í''Ô/‰‰Ü7‘‘‘FF¡¡û !z#‚$Ü$Ü$Ü$"©$$'%µ#­#­!Ñ!Ñn¹¶[[ùù''ÈÈnnððððCCèTTTúQ««Q§§TúúúúúöQ££öö££ÏÏ||€Ú€€jjjjvvfŽŽŽŽääääÉÉÉÉ  ssÉÉoo zÉÉÅÅssññKKG íG íCCžžññžžÛÛˆˆ^^  µµµààà;ì°!"#׃ úúPP£I!|ÎÎxxxxBBœœïïï''ÔÔÓxxx||ÏÏ%Ú-ˆ-xxxMM  ú££££ Ë%%% t tÏÏÚÚ,,00ƒƒ\\®®ƒƒ Ö Ö  ‡‡XX\\®®ÈÈqÌÌÌóóó󡡨¨qquuÈ nÈÈu…ß*’ 7 å åèèèè½½½½;;––????nnnnÁÁÉÉÅz~~†•3~ÑÑØØ+†‰äää‘‘FF¥ð÷R v#+#Ø%3%Š&ä'‘'‘&b&b'½'½)n(& $±#+#+!Ñ vŶ__¹Wýý¢#}ÐvnnF¡FFC••««XþTTTúúT§§££QQ££ööMMúúÏÏÏÏÖÖ„îzj½½nŽŽŽŽ;;••$ÉÉosÍssoÉÉÉÉos  vÉÉz ssššôôññññññžžžžžž2222µµµµbbbàà;•N%21`4*[Âþ£úúLL!||!!|ÎÎBBïïFFF''ÔÔÓxxx""ÏÏ%%Ó-ÓÓxxMM  ú££££ Ë%%%ÏÏÏÏÚÚ,,00ƒƒ\\®®ƒƒ00ÚÚ‡‡XX®®ÈÈqÌÌÌóó ™N¡¡óóqqÈ nÈÈuÐÐÐì’??èèèèjjjj½½½½––––????nnnnÁÁÉÉÅz~~+;3~++ØØ+†‰äää‘‘FF¥¥R ¬ v#+%3&&ä(?(ì+¡)))))n((À'f#+#+#+!Ñ kk__¹WýýW#ÈÐvnnF¡FFC••««Xþ¯¯¯TTúMM££QQ££QQMMúúÏÏÏÏ||)Þbb¹¹¹è莎;ð¥ZŽ~$ÉsÍssoÉoo$És  vvvÉÉ Åssššôôññññññžžžžžž2222µµµµbbbàà;•©)A6Ê6Ê/Åwþ£úúLL!|!Ç!|ÎÎBBïïFFë zÔÔ/Ü6€%%%ÏÏÏÏxÓ€€%%%%úúMM££££%%xxÏ)|",,ÚÚ00ƒƒ®®®®®®®®0000,,4ÚXX®®®®ÈÈÌÌ¡ûóóóó¡¡ÌÌÈ nÈÈÈÈÈÈÈÈ????;;;;jj½jj½½CC––’’??nnnnnnÉÉnÉÉÉrrÍÍÑÑÑÑÑ+++~ØØ~Ü7ääììF¡!Z!Z"#a#+$†%à';(?*ô*ô,N+)Ä+Ì+Ì*È((À(À';%à#Ø"~!zÅÅ ²_WýýW+Ð##vFFFìC••«³ ¾d\§§§MQQ££QQQQMMúúÏÏÏÏ!|ÏϽ½bbf   ŽŽ;;C#.)ò&¥+vÍsssoÉÉÉ$É ÅÅ $ÉÉÉssÅÅGGGGññññññCCžžžž22„ßµµbµµàà;;FÀ*œ-Q$ñh«P§LLL!!!ÇÎÎttBBïïëë> zÔÔ/Ü6€%%%ÏÏÏÏ x%%%%%%úú§§££££%%xx)Ï|",,ÚÚ00ƒƒ®®®®®®  0000,,Ú4XX®®®®ÈÈÌÌûVNNóó¡¡ÌÌ#ÈÈÈ n nÈÈÈÈ????;;;;jj½jjCC––ìì??nnnnnnÉÉnÉÉÉrrÍÍvvÑÑÑ+ÑÑØ33ØÜ7>>FFF¡!Z!Z"#a%à';)ð+J,N,N-©//.-Ô/Ü-',#,#+u+u(•';%3!#"Õ ÅgÁ²WýW+Ð##vFFFìC••«"–%¢!’l\§QQ££QQQQMMúúÏÏÏÏ|!ÏϽ½bb f  ŽŽ;;ø#Û3l7{6\*.;ÑÍsssoÉ~ÉÉo ÅÅ $ÉÉÉssÅÅGGGGññññññCCžžžž22„ßµµbµµààààìF©^h³Pö§LLL!!!ÇÎÎttBBïïëë>=—òLùùnÁfbb    ½½bb 3Ž;;ŽŽŽŽ;;Žèôäää    bbbbŽè–;èCð–)ÏÏÏ"" tÏQQQ öMMúúaaiiÓÃÀeeeùù¦¦¦K ñKKKKK¢¢¢¢llll›››AEEòò± ±±^^^^^^^±±  mmmÇuuÏ&&ÁÁgÁÁ#~üü©^ f!À!À$u&(»*Ã-x.Ò.Ò0Ú0Ú112‹1Þ1Þ0-.Ò-x-x*A(æ&ß$*"x!¼662}uз °ûûQQQ÷Q÷œ÷8í$~3a5¿- µ–Ž44400ƒÝïïJïïïïïFF˜˜BBBBÀmÈÄÄÄÄÄß(w7[8µ89.¿Å¦KKKÉÉoÉ  ÅÅ]]° »a]]  ññžžGGššžžCCññžžññžždddd  ººhhººkÆÆ¾¾ººæ@ææ“““8vn—òÆ ‚ÍÉÁfbb    bbbb 3Ž á áŽŽŽŽ á áŽè?äää    bbbbŽè;–ø¼j¥)ÏÏÏ"" tÏQQQ öMMúúaaiiÃË€â—âÓÀeeùù¦¦¦KK¦KKKK¢¢¢¢llll›››AEEòò f  ^^^^¹^^^    mmmÇuuuuÏ&&xxgggÁÁ#~üü¹ f!À#%Ð'a*,.Ò.Ò1‡333æ5@4“4“2â1‡0--x,ö+›)”&ß%-#Ó!Ë qëëØ*з]°U¨¨ûûQQQ÷Q÷÷Q’G'3674e ÅñŽ444ÖÖƒÝïïïJïïïïFF˜˜BBBBÀmÄiiÄÄÄÄ* X/<66Þ*°Å¦KKKÉÉoÉ  ÅÅ]]° a]]°°ññžžGGôôžžžžññCCññžždddd  ``hhººk¾¾kk¾¾ººæ@ææ“““8vnDTÍ. 4#1n'Ã…n½bbb    µ µbbŽŽ á áŽŽŽŽŽŽ á á Šää Š¹¹¹¹bbbb;;èÄ-,U„Ï""ÏÏÏÏQQ ö öúúMMaaiq€E(*Î&¾ê"me KKSùKKùùùùK¦¢ H¢¢Æl ¿HH›A———ò  ¹^^^  ^^^^^^  mmmÇuuuÇÇÇÇÓÓ&&Áv#~üü¹"n#È%#)2)h,-x0-0Ú34ê6D5í5í5í5í4ê31‡.Ò.P*A*A'Œ%Û%Û#Ó!˜>Û…*}}·]UUUû÷QQQ¤J÷Qåšf):,ó&/K<ᇇ‡ÖÖ00ïïïïëëBBBBmqqÄ"2Q.5„-eÌS¦KKKÉÉoossss]]° ]]° žžKKOOôôKKžžññññCCññ dº`ºººdd¾¾º8“““““ææÉÉvŸ®(¡6*82823ò ÿ#½bbb    µ µbbŽŽ á áŽŽŽŽŽŽ á á Šää Š¹¹¹¹bbbb;;èÄ-,U„Ï""ÏÏÏÏQQQQúúMMaaiq€"¯1’6ü2í%d1Çe ¦¦SùKKùùùùK¦ý¢¢¢Æltîî›A———ò  ^^^±±^^^^^^  mmmÇuuuÇÇÇÇxx&&¹nÁv#~üü!"n%#&})h,.Ò1‡254ê4ê6D5í5í5í5í6D4ê2â0-.P,ö+›+›(%Û%-"x˜>Û…*}}·]°°Uû÷QQQJ¤Q÷‹‹í¢¦<áᇇ‡0000ïïïïëëBBBBmÄ"}A-45„2ÏÜ­¦KKKÉÉÉÉssss]]° ]]° øøK^©ôôKKžžññññCCññ d¶kº`ºººººddddº`8“““““ææÉÉvL¶)ü6*8293E RÉ µ µ µ f¹ _  ¹ _ Šä Š ŠŽŽ á á77 Š Š á á; á½bbb¹¹¹¹ŽŽ–ðR¼j×|ÏÏÏÏÏÏúú§M££££¸¸mÇ1%º6O7©3š#\„u¸¢¢¢¢KKKK¢¢¢¢SùSùÆÆppÊpAAîH››îîµµ±±^^± ¹¹  ¹^mÇÀÀÇÇÇÇuÏ"|*ϽÅÅn##Ø­!j"Ä"Ä(.+/)2‹2‹34ê5—5—6ñ6ñ5—6ñ5í5í3æ11/T-ú-ú+E(9%„&1#| ó˜>‰ÛÔÔ·· °°°MQQ¤¤÷÷÷÷44Žé’8ÝÝÝÝÝ݃ƒ00˜˜FFœœBBFF˜˜BB••ÀÀÀÀmmÄÈ"2"`*Y'¤#©ôôOôÅ ssÉÉ´´´´´´Y´]]]] °]]¢¢¢W¢GGG¢¢žžžžžCññ  dd¶  ººddºººº¶88““8888ÅÅrrnÉ#ò§Í/f4#2È)ËBÉ µ µ µ f¹ _  ¹ _ Šä Š ŠŽŽ á á77 Š Š á á á;½bbb¹¹¹¹ŽŽ;–CCðð×|ÏÏÏÏÏÏúú§M££££¸¸¸¸mÇ×ö+{/Š* L„um¢¢¢¢KKKK¢¢¢¢S®SùÆÆpAAîH››HHZZ±±^^± ¹¹ff¹^mÇÇÇÇÇuÏ"|*ϽÅÅÉÉ#Øb ½bb!j(.%y(.+,t/Ö2‹34ê5—5—5—5—6ñ5—5í5í3æ110¯/T,Ÿ)ê(9(9'Œ$ט ó˜ãÛÔÔ··°UUU¨¨QQ¤¤÷÷÷÷444Ž8݃ƒÝÝÝ݃ƒ00óóFFœœBBFF˜˜BB••ÀÀÀÀmmÄÈ""2f©OôôôšÅ ssÉÉ´´´´´´Y´]]]]° ]]GG¢¢©¢GGG¢¢žžžžžCññ  ººdd¶  ººddººººk88““8888ÅÅn#—ò®Í#7#7BØn¹bb    ¹¹  _ _ää77ŽŽ;;77 Š ŠŽŽ á;½½bb¹¹¹¹ŽŽ;;––èè|||||"ÏÏúúúúQQ££  ¸¸À"ŒL §EÛ"ÇmO õ¢¢ùùKKOOOOSSùùÆÆÃÃÛ›››îH››ZZZZ^^^^¹ÀÀnn^mmmÇmmÇmÇÇÇ"„„*ϽÉ#Ñ+bbb ½$Ì&'&Ô)‰,t,t-Î1Þ36D4ê6D6D6D6D6D5í4“3æ2‹1\0+ò'â)”,I*A&1!  E>ã6Ûee°°UU¨¨ÿÿQQ¤¤JJ44ŽŽ‹000ÝÝ‹0ƒƒÝÝóó˜˜ïïïïFF˜˜ïïBBmmmmmmÈÈÄÄÄÄÈ"©O¢¢GGôšssssaY´´´°°]] e·]GGôôôôGGGGGGžžžžññžž    dddd  ººdd¾¾ºººº¾d“8ææ8888ÅÅÅÅÁ=—Dùùùɹ¹bbbb  ¹¹  ¹¹ää77ŽŽ;;77 Š Š 3 3; ábbbb¹¹¹¹ŽŽ;;;;ŽŽ|||||"ÏÏúúúú ö ö££  ¸¸eÀm"Ó-€ËÇm¸O õ¢¢ùù¦¦OOOOùùùùÆÆÃÃÃAAAAîH››ZZZZ^^^^¹À* œ œØnmmmÇmmmÇÇÇ"|””„*rÅÅ#~+Ñ­bb ½"#r&Ô)‰,t,t,t0ƒ36D6D7Ÿ6D6D6D6D5í4“3æ2‹0.§+ò'â)”,I+›'Œ!  Eã‰Û   UUUÿÿQQ¤¤JJŽŽ440‹00ÝÝ0‹ÝÝÝÝóó˜˜ïïïï  óóïïBBmmmmmmmmÄÄÄÄÈ"OôGGGGôš Á Á ¬´Y´´°°··¿·GGššôôGGGGGGžžžžññCC    dddd  ººddddºººº¾d“8ææ8888ÅÅÅÅÁêêîîîîèèŽŽŽŽ á á    _¹ffbb½½½½77ä Š7777ä Š Š Š77ää½½ff¯UQQ££xxxÓÏ t tÏãããã6ë뜜œç””猢¢OO¢ýOOùùK¦¦KùùÃÃppppÃÃî “îîòLLòV±^^^^  È#Q0Ú25&#uuuuII¤þ««éCCCK¥ø­†à ;"ð"B"B'¬)*—+ò-L02`56o55—5—4ê6D6D4ê2â1‡0-L,Ÿ)ê'â&ˆ%Û#&Ã!¼a]·· U¨¨ÓyÌÌ""""ºº____²²‡‡‡áÙ4‡‡óóFFœœïJUUó˜ïïBBÀÀÀu˜˜˜˜˜˜˜˜ôôGGššGG í íGGššGG°°  YY..ã=úúãˆssÅÅssssšôôôññññssÅÅ  ``¶¶dd¶¶dd     d¶¶dd¾d8888â<nnrêêîîîîŽŽŽŽŽŽ á á    _¹ff½½bbbb77ä Š7777 Šä Š Š77ää½½ff\Æ)Q££xxxÓÏ t tÏãããã6çççç::猢¢OO¢ýOOùùK¦¦KùùÃÃppî “îî—òLòV±^^^^  È&34ê+pØuuuuuuIII¤ööQQéCCCðKø­+†à!•##'¬))=*—+ò.§/«2`3º2`4<4<34ê3251‡0--L-L,Ÿ)ê%-! q qÃ!¼]··°°¨¨.Ó&&""""______²²‡‡‡á4Ù‡‡óóFFœœïJû°MóïqqÀÀÀÀ˜˜˜˜˜˜˜˜ôôGGššGGGGGGššGG°°  YYˆˆˆãêêãˆssÅÅssssôOOOKKññssÅÅ  ``¶¶dd¶¶dd     d¶¶dd d8888<—nnr==@@ æ@ŽŽ á ᎎ á á _ _¹¹  ¹¹bbbbbbbbääää Š Š Š Š77ääää’’bb½½f!(.É&ªhþ ö ö%%ÓÓ|"ÏÏ66ããããããçç::::::¢¢¢¢¢¢¢¢KKKKùùùùÃÃpppp›A››ŸŸEE±±±±^  2%Y(BÈÇÇuuu***þ¤öö¤¤QQéé––CžøS+†3 è#$÷'¬)*—*—+ò.§.þ0X1125251‡1‡0-0-.%,Ë+E,Ÿ,Ÿ(#Ó! q!Ë!˼aVVe ·]]]¨&yy""uu²²²²²²Ù4‡á‡‡Ù4FFóóJJJJMMMóïïïïÄÄÀÀÀÀ˜˜FëëëëëôôGGGGššššGGGGšš]]°°YYY´ˆˆ555555ÅÅssÅÅ  ôOG¢KKCCss  ºº¶¶ddd dd``ººd¾¾d¶¶8888â<éénnr== æ æ æ@ŽŽ á ᎎ á á _ _¹¹  _ _bbbbbbbbääää Š Š Š Š77ää Š Š77bbbb¹¹Ávå1~43,wXQQ%%ÓÓ"|ÏÏããããããçç:::: ß ß H H¢¢¢¢¢¢KKKKùùùù hpppppp›A››EEEE±±^^±±^  ¹nuunÇÇÏÏ9"X#³Iþ¤öö¤¤ööéé––CžžøÑ+~3 è"B$÷&R)=)=)=+ò*î,I.P.P/€/€0-0-0-0-.%,Ë+E)ê)ê("xà q q¼¼a°°¨¨¿Ï!1Ö]¨&yy""*u  ²²²²Ù4‡á‡‡Ù4  MMJJJJóóó˜ïïïïÄÄÀÀ˜˜FëëëëëôôGGGGššššGGGGšš°°YYY´ˆˆ55ÛÛ55ÅÅssÅÅ  O©ü¢KKCCssss  ºº¾¾d dd``ººd¾¾d¶¶8888â<nnr==== êää Š ŠŽ 3 á á¹¹f       ¹¹ f¹¹ŽŽŽŽ á á á á á á á á 3 3 3 3 bbb fn~"š(&ª‹»X£%%%%ÏÏÏÏŒŒŒŒ: ß::ã㌌::KK¦¦¢¢¢¢¢¢Oª¦KùùÃÃÃÃppppEEEEîî››­­ZµµZ­^^¹¹mmÇ×$ 1’0å$¶YIœöööI¤’’ššôšGü'‚/‰!>!>$¡$¡$€'5)=)=(æ(æ,I,I.%.%0-.Ò.|.|-Î)¿+E)ê'â&ˆ"ÏÀmm¼¼aYRR&ò- - !ˆ´YÿÏÏÏÏyÓÓycc[[[® ‹‹‹‹0‹ÝÝœ÷÷Q¤JJJóMF똘˜˜qiiÄÄ••••BBBBžžžžGGGGññññGGšš ¬ ¬°°]]Œ2ßß„„Œ2sssss([jjôôššssssdddd¶dddd¶¶dd¶¾d¶¶éââ‹‹88ÁÁnnnnÉ==== êää Š ŠŽ 3 á á¹¹ f      ¹¹ f¹¹ŽŽŽŽ á á á á á á á ᎎ 3 3 bbb fØ0{l·««þþ%%%%ÏÏÏÏŒŒŒŒ: ß::ã㌌::KK¦¦¢¢¢¢¢¢Oª¦KùùÃÃppppEEEEîî››­­ZµZµb^^^^¹¹¹¹mmÇ×%d2í4ô(Ƴ¤öœööI¤’’??šôGüÍ'‰äää ‘#F#&%Û%-'â'Œ$×$*&ß(»+p-x,+Ç)(d' ('5&ˆ%-"Ï!u""m¼¼i´¬a&ò4{7Ý7Ý-¶ÃYÿÏÏÏÏyÓÓy  ¶¶[[® ‹‹‹‹0‹88œ÷÷Qÿ¤JJMó Fóó˜˜qÄÄÄÄ••••BBBBžžžžGGGGññññGGšš  ··çŒ„„„„Œ2sssssss(z+]. ‰Oôôssssdddd¶dddd¶¶dd¶¾d¶¶4ââææ88ÁÁnnÉÉÉ======7777 3 3 á á  _¹    _ _  ff¹¹;;ŽŽ á á 3 3ŽŽŽŽŽŽ á á bbbff#l\««`ˆÓÓÓ|||"ŒŒŒŒŒŒ::>>>>::::KKùù õO¢¢¢¢OO¦KK¦ppÊÊppppòòòòîî››­­­ZZµµ^^    ^¹Ç"=$¶'kL«öIII¤öQåå??ššôôzÔ/‰‰ ‘!ì!Ë!Ë#Ó%-$*"Ï"Ï$*$¬'a(»(»)¿' ' ' '5%Û%Û$€""""""mii¼ai*T6‚8Š8Š3 -ÿ*ÏÏÏ&&Ì̶[  [[ cÝÝÝÝÝ8勤¤ÿYÿÿ÷÷óóF  FFFÄÄqqÄÄ••BBBB•ïžCññšôššññññGGšš´´··¿tAŒ222222ss  ssÍÝ%F2Ï4)#ëOôôsssÍdddddddd¶dddd dââ8“88nnÁÁ======7777ŽŽ á á  _¹    _ _    ¹¹ á ᎎ á áŽŽŽŽŽŽŽŽ á á bbb  ¹§§«`%$ù-ÓÓ||×|ŒŒŒŒŒŒ::>óóó””::¦¦ùù õO¢¢ýýOO¦KK¦ppppppppòòòòîî››­ZZµµ^^    ^¹mÇ-ˆÓQœIIïIöQŠŠååššôôzzÔÔÔÜ7 q¼Ã#Ó"Ï!u!u"Ï#Q#Q$¬$¬%¯%¯$U$U$€#&#&!Ë""""""miiYa´Y#/¾4{4{+ÃYÿ*Ï**ÌÌ̶[  [[ cÝÝÝÝÝ8勤Y´YY÷÷óóF  FFFÄÄqqÄÄïïBBBB•ïžCññôOššññññGGšš´´Ï222222ss  ssÍ(!6#ëÌ©ôôôssÍ(dddddddd¶¶¶dd   dââ Þ888nnÁÁ==““î£Xþ££££ ö öxx x Ë%xx    ½b¹¹ffbbbbMMMM££££  úúúúúMM||Ï)|1îXò-%%ÏÏ)„¸¸eeEU¿dúë>>{   ww$ Ê õO¢¢K¦¦¦////………à±±^^7ÜÜÜàà33‰‰Ü܉‰77[µµµŽÙ44††4Ž   ú««Y³]·  hpã>ë! BB œ!÷!÷#Q!÷#Q#Q#Q#Q!÷"""""" ÇÃ!!i¸]¨VV†•$ÿ$ÿèÉg <<<<å‹‹‹ÝÝ‹‹ÙÙ‡‡‡,Ù4‹‹‹‹¨·¿e¬QJJuuÈÈ®®®®®T®® ®WWªªYY]°°„„22ÛÛÛÛÛÛˆˆ5ETòãÛÛÛÛ..ššGGžžK¦(ÝŠÕ(ÍsÍÍ‚Šäoººââââ44¡¡N©¥J÷R####yyy×××111ß==““H² þ££££ ö öÓÓx  Ë%xxÁÁff½b¹¹ffbbbbMMMM££££  úúúúúMM||Ï)||„„-Ó%%ÏÏÞîǸ¸eeÇ %8.²-W"ƒUó>{   ww$ Ê õO¢¢K¦¦¦////………à±±^^Ü777àà33‰‰77‰‰77ªª[[[4444††4Ù   úQQþY]  h`»‰ã EBBB œ œ!÷ œ!÷!÷!÷B œmmm ÇÃiii¸]¨¨NûûvÑÑÑÉ g<<<<å‹‹‹ÝÝ‹‹44‡‡á‡Ù4åå@@]e ¬QïïÄÄmm®®®®®T®® ®WWªªYY]°°„„22ÛÛÛÛ55ˆˆÛ55=ãÛÛÛÛˆˆššGGžžñKÍÍ  sÍsÍ(G%È'"éoÆÆkkââââ44¡¡ ôNJ¥÷R####yyy11×111ß=—““Hý`«££ öQQQ%% Ë ËxxÓÓÁÁf½b¹¹ffúúMM££££MMúúúúMMÏÏÏÏ||)Ï%%ÓÓ|׫%$1meeÏ$‹4É8+6Ñ0ºló>Í s { Ê Êww õOªOùùùS//‚Ü……33µµZZ± ^^7‘>äààä‰7777ääWW[®44†††††á   ú««þY]]¯ »»``66>>çç”””ïï”””””ÀÀÀe¼¼aNû¡ooººŽŽŽé8Ý‹‹‹‹Ý8‡‡‡‡‡‡‡‡8’G¢°°¨Q÷ïJqqÄÄmmÀÀ®®TT®®WWªªYY° °°„„„ßÛÛÛÛˆˆ5555ˆˆˆˆˆ.ÛÛˆˆGGššññžžssss  ÍÍ/%È4«3Q$$Š?0kââ44ââNN¡¡JJ÷÷uu È#yyÌÌ„„„„1ŒŒ=—““îî««££«»»%% Ë Ë  xxf f b½¹¹ffúú§§££££MMúúúúMMÏÏÏÏ||)Ï%%ÓÓ|×ö"oæmeeÀu#16$8+6Ñ4É |ó>Í s {$$ww õOªOùùùS//‚Ü……33µµZZ± ^‘ì>äààä‰7777ääWW[®ÙÙ†††††á   úQQ¤þ¯ ````ÛÛ‰‰22:::”:”::::ee °a¨¨û¡ÁÁÁÁooººŽŽ4Ž8Ý00‹‹ƒÝ‡‡‡‡‡‡‡‡Ý8’íUU¨M÷QJïqqÄÄmmÀÀ®®TT®®WWªªYY U°°°„„„ßÛÛÛÛ..5555ˆˆˆˆˆ.ÛÛ..GGššññžžssss  ÍÍÕN(},Œ!S$š(n?Æââ44ââNN¡¡JJ÷÷uu È#yyÌÌ„„„„1ŒA==““““þ£££³,wXÏÏ"" Ë Ë Ë Ë¹¹  ¹¹ffjúú§§MMúú££££MMMMÏÏ"|ÓÓ% ËxÓ%%%%ˆ=ËieeÀuÃ.[4r4r*¢ E$ ÊwÑ$$ww õOOOùù¦¦……33…………ZZ^^ fìFFì:•:à::®®®®W²_ª0000‚Ý77   úúú¨¨UU  ]·22ß…Ô.‰‰ããÛ62ß…°°]¨¬Rÿÿ¤¤JJkkÅkáá448Ý00‡‡,‡‡‡ÙÙÝÝÝÝ4Žáá  ûû  óóÄÄqqmmÀÀWWWW ýWªªªªTT´´ U U°°ßß„„..ˆˆˆˆˆãßßßß2222„„22ññññGGôôssÅÅÉÉvz/ìG{Ækk,áoââ‹‹‹‹NNNN¥¥÷÷ÌÌÌÌÌÌyy„„„ßßî`==““““£ I££þ  XÏÏ"" Ë Ë Ë Ë¹¹  ¹¹  jjjjjúúMMMMúú££££MMMMÏÏ"|xx% ËxÓ%%%%ÓÓ¼¼ieeÀÀ¤h % %d E$ ÊwÑ$$ww š õ õ õùù¦¦……33…………ZZ^^fÀ¡° ûï•:à::èèèè®®®®W²ÕÕ00‚ÝÝÝ   úúú¨¨¨¨UU¯¯]ØØ…*Ô...‰‰Û62…*û°]N¨R÷ÿÿ¤¤JJkkkáá448Ý‹‹‡‡,‡‡‡ÙÙÝÝÝÝŽ4áá  ûû  óóÄÄqqmmÀÀWWWW ýWªªªªTT´´aa°°°°ßß„„ˆˆˆˆˆˆ.ˆßßßß2222„„22ññññGGôôss  oov  (ÍkkÂÂoââ‹‹‹‹NNNN¥¥÷÷ÌÌÌÌÌÌyy„„„ß9I o== æ æ æ æ ö ö ö öQQ££ÏÏ"" Ë Ë Ë Ë¹¹    ffjÅÌr½½§MúúMM     ö ö ö öMMMM"""" xÓxxxxxxxxxa¼eeÀÀAœöœó>>ã$$ww$$ww õ õ¢¢ùùSùØØØ3…………µµ± ¹È°!u!uVB::èèè••••[[®®Õ0‚‚0Š00   úóMúúúúM¨UUUUuuÐÐÔÔ....Ø2}}VV°ûû¡N¨¤¤÷RJJ÷÷sÅk¶¶Ž4‡‡å‹Ý84Ù‡ááᇇ0000‡‡‡‡    FFóóÄÄmmÀÀWWWWWWWWWWWWTTT®a]]°°22ßßãˆ55ˆˆ55ŒŒ99ßßßߌ222ññCžGGôôssssoooÉssss¾¾ººº`ââ4488‹‹NNNN¥¥¥JyÌÌyyÌÌ11„„ß” == æ æ æ æ ö ö ö ö ö ö I IÏÏ"" Ë Ë Ë Ë¹¹    ffjz‰6'½½§MúúMM     ö ö ö öMMMM"""" xx xxxxxxxxa¼eeeeçAAç>>ã ‰$$ww$$ww õ õ¢¢ùùùSØØ3Ø…………µµ± ¹ÈV ÀVB••èBBB••••[[0Š‚‚Õ000EEE óM  úúM¨úúúúuuÐÐyyÔÔyy}Ø}}ûûVVû¡óNJJ÷R¤¤÷÷¾k¶¶Ž4ááå‹Ý84هᇇ‡‡0000‡‡‡‡    FFóóÄÄÄÄÈÈWWWWWWWWWWWWTTT® ¬]]°°22ß”˜=ãã55ŒŒ””ßßßߌ222ññCžGGôôssssoooÉssssdd¶¶ººº`ââ4488ææNNNN¥¥¥JyÌÌyyÌÌ11„„ßßIhh¿¿ t t t t Ë Ë Ë Ë%%xx""""    ½½;ðZq­–;§M§§úúMM t tÏÏ xxx££Q ö    MMMMMMMM  ú  ¸¸ee¸¸eeee ´ ´KKKK¢¢ õ õww$$$$ww+…ØØØØ……^^  µµb¡°°ûï•èBnnÀÀÀÀ²²_WWÙŽ,,,†4Ùqquu""xxË&*ÏÏÏuu##ÌÌÔÔNNóóN¨ûûNNNNR÷÷÷ÌÌyyÌÌšš@@åå88__  ____    ²W_²²_[® MMMóœœJ¤mmmmÈÈmmƒƒ0ÖÖÖƒƒÖÖÖÖ((ƒƒ2222ÛÛÛÛÛÛ5êêú§§i´ e¿e··  ´´CCCCžžžžoÉ  ssÉoÉÉdd  dddd¶¶¶¶ddddû¡NNûû¡¡J¥÷÷¥¥÷÷]¯¯]]·hh¿¿ t t t t Ë Ë Ë Ë Ë Ëxx""""    ½½;ð¥µø–;M§§§UUMM t t t t xxx££Q ö    MMMMMMMM  ú  ¸¸ÀÀ¸¸eeee ´ ´KKKK¢¢ õ õww$$$$ww+…ØØØØ……  µµ¼¼ìFFFï•BÈÈuuuu  ªWWÙÙ,,†,4Ùqquu||xxË&*ÏÏÏÈÈÌÌyyóóóóóNûûNNóóBqqÄÄqqÄÄ@@åååå88__²²____    ²Wª²²_º¶[® óóóMœœJïmmmmÈÈmmƒƒ0Ö00ƒƒÖÖÖÖƒƒƒƒ2222ÛÛÛÛÛÛ55E#(.ª+õò´ e e··  YYCCCCžžžžoÉÅÅssÉoÉÉdddd¾ dd¶¶ddddû¡NN¡¡¡¡J¥÷÷¥¥÷÷]¯¯]]] » »""Ï t Ë Ë Ë p Ë Ë Ë Ë"""" _ _¹¹½½;–KðèŽM§U¯·úú t t t t xxx ö ö ö ö    MMMMMM§Múú¸¸eemm¸¸¸¸¸aaaaKKKK õ õ¢¢ Ê ÊwÑww$$ØØØØ……33^^µµµä>‘ì•ïJJÐuÐÐ}#À  WWWW††ÙÙÙÙ4ÙqqqËuÏ||xËËÏÏÏÏnnÈÈqqFFóóFFNóóóFFïïÄÄÄÄqq’8’8å‹‹‹²²²²__²²[[[_WW  [[[[FFó󜜜BÀmmmmÀÀÖ0((ƒƒ00ƒƒƒƒÖÖƒƒß„22ˆ.ÛÛˆˆˆãò'å5n4& Ë´  ··· °ññññžž¦KvvÅÅ  Éooo¶dddd dddkddddNNNNNN¡¡÷÷÷÷J¥÷÷¯¯¯¯¯¯] » »ll""Ï t Ë Ë% Ë Ë Ë Ë Ë"""" _ _¹¹½½–;èèð–èŽM§ú \úúÏÏ t t xxx ö ö ö ö    MMMMMM§Múúe|Çm¸¸¸¸aaaaKKKK õ õ¢¢$$wÑww$$ØØØØ……33^^µµµä>‘ìïJ¤Y…ßßߨ}u²²²²WW,,ÙÙÙÙÙ4qqqËuÏ||xËËuuÏÏnnnnÄÄqqFFóóFFó™™™ììJ•BBÄÄÄÄ’8’8å‹‹‹²²²²²²[[ª²²WW[[[[FF˜˜œœœBÀmmmmÖ0((ƒƒÖÖƒƒƒƒÖÖƒƒß„22.ˆÛÛˆˆˆã˜·&‹*šê´  ··· °ññññžž¦KvvÅÅ  Éooo \¶dddd¾ddd¶ddddNNNNNN¡¡÷÷÷÷J¥RR¯¯¯¯¯¯] d d » » »% Ë% Ë Ë Ë Ë Ë Ë Ë Ë Ë   Ë Ë µ µbb¹¹ffää’’èè á ᣣ³Âd¯úúÏÏÏÏ% Ë Ë Ë  ú  ú ö ö ö ö§§úú££ ö öee¸mqiiaaaa  e ¢¢¢¢ õ õOO{ ÍÍwwwwØØ……////VV±±^^± ::•ïJ¤ÿ´”!I!÷ œã.Ìq__²²__WW,,ÙÙÕÕ‚ÝqqxÏÏ„„*ÏÏuÇÇuuÀÀÀÀìì™óFFFìBB••™™ì‘jj¼jjjjéé<áéŽ<á__²²[¶[[®®® [[W²_FF Fóóó˜qăƒÖÖƒƒƒ(00ÖÖ,,ÛÛÛÛÛÛÛÛ2222Œœ)e  ´´aa··]]°°°°ššGGžžøž  ssÉÉsÅ k``    h ³¶ddºº  ¡¡¡¡¥¥÷÷NNNN¡¡NNYYY d d »%€% Ë Ë Ë Ë Ë Ë Ë Ë Ë  %% µ µbb¹¹ffää’’ŽŽ á ᣣXhd¯úúÏÏÏÏ% Ë Ë Ëú    ú ö ö ö öMMúú££ ö ö  ¸¸¼aa¼¼eee ¢¢¢¢OOOO{ ÍÍÑÑwwØØ……////±±±±^^± ::•ïJY"x&³,,Ë(»"Mã&Ì__g²WW††ÙÙÕÕ(‚qqx„î#³&h"X”*ÏÇÇuuÀÀÀÀìì™>ììì‘BB••>>ì‘jj¼jjéé<áŽ4á‡__²²[[[®®® [[[[W²_Fûû óóó˜qÌÄiƒƒÖÖƒƒÝƒ00ÖÖ,,ÛÛÛÛÛÛÛÛ22222ŒAQ   ´´aa]]]]°°°°ššGGžžøžÅÅssÉÉsÅ ``      ¶ddººhh¡¡ûû¥¥÷÷NNNN¡¡NNYYY »hh%€% Ëxxxx Ë Ë Ë Ë p Ëxx µ µbb _¹¹¹ä Šää á;ŽŽ öQ««§§úú""""xxx MMMM ö ö ö ö  úMM ö ö££¸¸ee¼¼¼¼¸¸¢¢O õ õ õ¢¢ÍÍ {$$wwØØ……////± ^^±   èè÷(/€4ê5—0-&]>.yg __ÙÙ{Õ‚‚ËÛ#0Ž5K5K/4!«*Ïuuujj¼¼nÀÀ>™™>ììììBè:•>>7‘¼¼b¼¼<áááááᇲ²®®®® ®®®  ® ___ûe°Móó˜ÄÄÄÄÄÄiÄÖ0ƒ(ÖÖƒÝÝ݃ƒÙÛÛÛÛˆˆˆˆ22„„22çA·  a]]°°°°°°ššGGCžžžÅÅooÅÅÅÅ``      dddd  hh ô ôNN¥¥÷ ¡¡¡¡NNûû¯¯ ¨YYY »hh Ë%% Ëxxxx Ë Ë Ë Ë p Ëxx µ µbb _¹¹¹ä Šää á;ŽŽ öQQQMMúú""""xxx MMMM ö ö ö ö  úMM ö ö££¸¸eeaa¼¼¸¸¢¢O õ õ õ¢¢ÍÍ{ $$wwØØ……////± ¹¹± ffèè÷(38ù6ñ4<*l˜.yg __ÙÙÕ0‚‚ÃÃË+$5ø887S,ßÏÏu¼¼nfä>™>‘‘ììBè:•>>‘ì¼¼¼¼¼¼<ᇇááᇲ²®®®® ®®®  ® ___û$“tóó˜ÄÄÄÄÄÄiÄ0Ö(ƒÖÖƒÝ888ƒÙÛÛÛÛˆˆˆˆ × ×„„222Œ]·  a]]°°°°°°ššGGCžžžssÅÅooÅÅÅÅ``      dddd ³ ³  ô ô ô ôJJ÷ ¡¡¡¡NNûû¯¯ ¨YYY¸¸ ° ]]\XXX ý (ƒƒƒ Ö Ö Ö Ö,, Ú,,ÚÚ Ö Ö Ö Öƒƒƒƒ á á á á’’’’7777 á á á áxx Ë Ë"""" ö ö I£MMMMwwww Ê$ww    wwwwwwww Ê ÊwwÑw$ Ê$$wwÆÆÆÆÆÆòòLLŸŸúúýýý²d¾ƒ&G0n5Ø5+2v'øo`7ÝŠ0ÙÙ††®®®®®®[[cÍ* 697”7”5ã(Zn_²²0000Ý7Š07‚Ý‚†áááóóó󜜜œ˜˜E ëE˜óyyqqÈÈuÈÈÈÈqq®®®®[[[[²²[[[[™N°Vð•莹¹     ftt!!xxxÒ||ÏÏttttRRRRNNNNNNNN©Nûû¾¾    ººººhh `ºšôôôGGGGssssooCCññ‹‹888888ââââââââââ88‹‹      `ºÌÌyy##u]] ° ]]\XXX ý (ƒƒƒ Ö Ö Ö Ö,, Ú,,ÚÚ Ö Ö Ö Öƒƒƒƒ á á;;77’’7777 á á á áxx Ë Ë"""" œ œ£þMMMMwwww Ê$ww    wwwwwwww Ê ÊwwÑw$ Ê$$wwÆÆÆÆÆÆòòLLúúTTýýX d¾Î Ý)©1È1+±%Cº7ÝŠ0ÙÙ,,®®®®®®½‚(°2*4ß/!•n_²²0000‚ÝŠ0ÝÝÝ‚†áááóóóóœœAA˜˜ EE MóyyÌÌÈÈuÈÈÈÈqq®®  [[²²[[[[??F¡Jð莹¹    f tt!!x!!ttttttRRRR©©NNNNNN©Nûû¾¾    ººººhhºšôôôGGGGssssooCCññ‹‹8888 Þ Þââââââââââ88‹‹      º`ÌÌyy##u ° ° ° °  ®®XX ª ªƒÝ0 Ö Ö Ö Ö Ö,,,,  ,, Ö Ö Ö Ö Ö Ö Ö Ö á á;;77’’ää77 á á 3Žxx Ë Ë"""" I IQQú  MM Ê Êwwwwww  s swwwwwwww Ê Êww$$ww$$wwÆÆllÆÆÆÆòòLLúú\««X²kÆÕ$?/-¹%š †º`7Ý‚‚††ÙS®®®®®®®®µÜ#ó%NàÁ¹‚‚Õ0‚‚‚‚‚‚ÝÝÙÙ††EEEEœœœA˜óó˜óóóóÌÌÌÌÈÈmmÈÈq®®[[[[®®²²®®® ‘ìFV¼­Cè¹¹     ±tt!! p pËË!!!!|!ttÿ¥¥¥VVûûûûûûûûûû¾¾ººººººººººÂ íGôôôôôôsssÉÉÉÉKñññææ88 Þ Þ‹‹ââ4488 Þ Þ       ³yyyy##u ° ° ° °  ®®XX ª ªƒÝ0 Ö Ö Ö Ö Ö,,,,  ,, Ö Ö Ö Ö Ö Ö Ö Ö á á á á7777 Š Š77 á á 3Žxx Ë Ë"""" I I ö öúU§§ o owwwwww  ÍÍwwwwwwww Ê Êww$$ww$$wwÆÆÆÆÆÆÆÆòòLL¯ {`X²¶kÆ 0%š$?Õ `7Ý‚‚,áÙS®®SSSSS®®µ½jÅg²ªª‚‚0Õ‚‚‚‚‚‚‚‚ÙÙ††EEEEöööœ˜ó󘘘óóÌÌÌÌuuÈÈmmÈÈq®®[[[[®®²²®®T®‘ììû¼Cè¹¹     ±tt!!ËËËË!!||!|tt¥ J¥¥ûûûûûûûûûûûû¾¾ººººººººººhhG¢ôôôôôôssÍsÉ~ÉÉKñññææ8888ææ44ââ8888       hyy##u] ]¸\ ª ª 4‡,ƒ ( Ö Ö ( (ƒƒ, Ò,,,,,,ÚÚ,, á á 3Žäää Š Š Š7777 Šäxxxxxxx  ö ö ö öMM§wwwwww$$ÍÍÍÍ$$ Ê Ê    $$wwÍÍ  Ê$wwppppÆÆòLú *­0Ä.%Co`ggÎs`XXŠŠ00ÙÙ,,ªOýý¦S®¹ÉÜ[[ªªªÙÙ,,Õ0Ý‚Õ0ÕÕ‚‚‚‚ïïïïööIï󘘘EëëëuuÈÈqqmmÈ"ÀWWWWWWWWWW;••ðèè  ^^µµbbÏÏÏÏÏÏ!!!!tt!!! ÇR ø¥¥NNûû¥¥¥¥¥¥¥¥ºººººººº¾dddººhhKKññKKžž    vÑÉÉGGšš888“‹‹ææââé<<ºº    ººÐu##ÌÌÌ] ]¸\\\ ª ªÚÚ,‡ƒ ( Ö Ö ( (ƒƒ, Ò,,,,,,ÚÚ,, á á 3Žäää Š Š Š7777 Šäxxxxxxx  ö ö ö öMM§Mwwwwww$$ÍÍÍÍ$$ Ê Ê    $$wwÍÍ{{ Ê$wwppppÆÆòLTÎ-b6Ü7‰7‰2Ì"Žº«²²   d«ýý0000,,ªOýý¦S®_n'c®[[ªªª,,Õ0Ý‚Õ0ÕÕ‚‚‚‚””ïïööIï˜>˜˜EëëëuuÈÈqqmmmÈÀWWWWWWWW_ªWW;••;ŽŽèè  ^^µµbbÏÏÏÏÏÏ!!!!tt Ç Ç Ç!R ø¥¥NNûû¥¥¥¥¥¥¥¥ºººººººº¾dddººhhññññKKžž    vÉÉGGšš888“ææææââé<<``    ººÐu##ÌÌÌ ° °  ®®\\²X ª ª,,,, Ö Ö ( ( Ö Ö Ö Ö,,  ,,,,  ÚÚ 3 3 á á777’777777ää Ë%xxxx€% ö ö ö öMMú  wwwwww$${{  wwwwÍÍÍÍwwwwÍÍ{{$$ÑwÃÃÃÃttŸŸ\ 04'8686866Ü,Ê`««««««PP0Õ(‚,ÑýýOªSSS®WW gc®®®®®®WWWW,,‚‚‚‚ÕÕÕ0‚Ý00ïöœœAëëëëEë>>ÈÈÌqÄÄÈmmmWWWW²WWWWWWW²W;;ŽŽàà;;   ±bbb!!!!!!!!!!!!tt Ç!¥¥¥¥©Nûû ø ø J J¥¥¥¥hhºººººd¾hhCCžžñññKss zvvÉÉôôGG‹‹88â<<â888“<ââ⺺ºººº  ####Ì ° °  ®®²X ª ª,,,, Ö Öƒƒ Ö Ö Ö Ö,,  ,,,,ÚÚÚÚŽŽ á á777’’’77’’ää Ë%xxxx Ë% ö ö ö öMMú  wwwwww$${{  wwwwÍÍÍÍwwÑÑÍÍ  $$ÑwÃÃÃߟ§Æ-b6Ü86866Ü.½!4`««PP§§§§PPöö0Õ(‚,ÑýýOªSSS®WW² ®®®®®®®WWýýÙÙ,,((‚‚ÕÕÕ0‚Ý00IIöööœœAëëëëë>>ÈÈqÄÄÈmmmWWWW²WWWWWWW²W;;ŽŽàààà   ±bbb!!!!!!||||!!tt Ç!¥¥¥¥©N ¡ ¡ ø ø¥¥¥¥¥¥hhººººº¾hhžžžž – – –ñÍÍ ÅvvÉÉôôGG‹‹88â<<â888“<ââ⺺ºººº  ####yyÌ]]a»0 ÖƒƒÚÚ   Ö Ö Ö ÖÚÚ,, ª ª ª ª,,,,,‡‡,bb   fää77ää7’xxxx""ÏÏ ö ö ö öMMMM Ê Ê Ê Ê Ê$ÑÑýýOO¢¢¢ýýýO õùù¦¦¦¦ žùùù¦KÃÃÃÃppppH£ý #é06.4Ô1ô,Š"c4))ÎÎPP££ŸŸŸŸ$ÑÑÑѪOýý¦¦ÕÕ00†,,,ªªWWªªýý®®¦SSWWWW®®Ç"*„*Ï"Çii¼¼mÈÈÈÄÄqqïï•˜˜®®[®®®®W²ääää;à;;¹^¹^µµbbI£££MMúú)Ï!!!!tt¥¥RR­ ø ø øyy''''''ººhhººººººº¾¾sÍs ÁÉÉøøKñžžžžG¢GGdd¾¾¶dddddddd8888ââ    hh  N ôNNûûN]]a0 Ö ( (     Ö Ö00ÚÚ,, §\ ª ª,,,,,‡‡, µ µbb   fää77ää7’ÓÓxx""ÏÏ ö öQQMMMM Ê Ê Ê Ê Ê$ÑÑýýOO¢¢¢ý²²ªOùùKKKùSùù¦KÃÃÃÃppppîH£ý`$#;!áLéÚÎÎÎÎöö££ŸŸŸŸ$ÑÑÑÑOªýý¦¦¦¦ÕÕÕÕ,Ñ,,ªªWWªªWWSS¦SSWWWW®®Ç"ߣ"X”×Çii¼¼mÈÈÈÄÄqqïï•˜˜®®[®®®®²Wääääð•;;¹^¹µµbbI£££MMúúÏt Ç Ç!!tt¥¥RR ø ø ø øyy''''''ºº  ººººººº¾¾ss ÁÉÉžžñKžžžžG¢¢¢dd¾¾kdddddddd8888ââ        ©NNNûûN ° ƒ ( ( (   Úƒƒ00,,ÚÚ\®®XXÚÚ,,,,,, µbb _ _¹¹ääää77ä™â-ÓÓ"""" ö ö££MMMMwwww Ê ÊÑ,OýýOOýg~ªOùùùù¦¦ùSùùùùÃÃpppppp›ö£££Xºº4ÚÒÒ!!ttööPöLLòòÑÑÑÑÑÑÑѪªOOùSSS{{((ÑÑOªWWªªSS®S¦WWWW[uß% +Ò þ*uÃÃii¼¼ÈÈÄÄÄÄïïBB˜˜˜˜®®®®[ªWW‘‘‘‘••èŽ    bbµµöQþ£úúúúÏt!!!!ttRR¥¥¥¥ ø øyy'''''  ºººhhhhh ddÅ sžžžøKKžžG¢ôôdddddd¶d¾ææææé麺  ````NN¡¡ûûN ° ƒ ( ( (   Úƒƒ00,,ÚÚ\®®XXÚÚ‡‡,,,, µbb _ _ _ _ Š Šää77äNLâÓÓ||"" ö ö££MMMMwwww$$,†¹ýýOOW n¹ªOùùùùKKùSùùùùppppppö›HH££««%xx!!ttööö›LLòòÑÑÑÑ,,ÑѪªOOùSSS{{((ÑÑ$$Oª²²_ªªªSS®S¦WWWW[uÏ” þI*uii¼¼ÈÈÄÄïïBB˜˜˜˜®®[[®®[ªWW7777;;èŽ ± ±  bbµµöQ£þTTúúÏt!!!!tt ø øÿÿ¥¥ ø øyy'' Ì'''hhºººhhhhh ddÅ sžžøžKKøøG¢ôô¾¾ddddk¾dææææDD  ºº``NNûûûûN]]]]]]     Ö Ö Ö ÖÚ44Ú,,,,®®®®®®®®ÚÚÚÚÚÚ,,¹¹  µ µ   3 3 á á777GŒ×))xÓ% ËMMMM££ ö öÍÍ{  {{0g ýýªOýWOOùùKKùùùùKK žùÆÆlÆttòòEEH£ý£xx!ÆttHHHHŸŸŸE{{((ÕÕ{ÕùùùSSS(({{$ÑѪgvªªªS®®WWªª¦¦SS¦¦mÇÇ|„*ÏuÃÃiiiiÄÄqqÄÄïïBBëëó˜WW²²[ŠŠ77äŠäеµ^^^¹QQQ\úú!!!!xxxNNVV¥¥RRÐÐ}}''yyººhhhhhhhhhhhhººžøKKôô¢¢KKKKhhd¾ddææææ<—ññkdd¶¶¶¶¥¥RRûûN]]]]]]     Ö Ö‹‹é4,,,,®®®®®®®®ÚÚÚÚÚÚ,, _ _  µ µbbŽŽ á á777’||ÏÏxÓ% ËMMMM££ ö öÍÍ {{  Õ ²ýýªO¢ýOOOOùùKKùùùùKK žùllÆ!ttòòEEH££H!ÆttHHHHŸŸŸE{{((ÕÕ{Õ¦¦ùùùSSS(({{$ÑѪ!•~_ªªS®Ü²ªª¦¦SS¦¦mÇmmuuii¼¼iiiiÄÄÄÄïïBBFFó˜[[WWWW[[[ŠŠ77䊊䵵^^^¹QQQp"@!¯ú!!!!xxxNNûû¥¥RRÐÐ}}yyººhhhhhhhhhhhhººžøKKOO¢¢¦¦KKhhkkkk¾ddd@@ææ<—ññkdd¶¶¶¶ÿ´RûûN]]]]]]     Ö00‹KÅ<44ÚÚ\\®   \ÚÚ,,‡‡,,    µ µ µ µ á á á á7777ÏÏÏÏxÓxxMMMM ö ö££    ÍÍÍÍýýý¢¢¢ýýOOOOùùKKKKKK ž ž žùllÆÆÆÆEEEEAöööpÊÃÆÆttö›››òòòòÍ(ÕÕ(({{SSSS¦¦¦(({{$$,,ªª ÁgWªªS®r‚v²WWSS¦¦ÀÀmmmmÃü¼¼¼iiiqqqqïïBB˜˜ëë ®ªªWWWWWW[[®®77ŠŠŠŠŠŠµµ^^¹þ£Q»ÆTú!!!!xûûûûRR¥¥ÐÐ}}Ôy Ì Ì  ººººººººººººhhÉÉÉÉÉÉvKKKKO©OOKKøøhhÆÆkk¾¾kkkd¾@@ææ————¾¾dd¶¶k&ÿûû¡]]]]]]     Ö00‹'ä%/ñ44ÚÚ\\®   \  ,,,,,,    µ µ µ µ á á á á7777ÏÏÏÏxÓxxMMMM ö ö££    ÍÍÍÍ¢¢ý¢¢¢ýýOOOOùùKKKKKKùù žùllllll ê êEE››››pÊÃÆÆ›A››——òòÍ({{(({{SSSS¦¦¦(({{$$ÑÑOOý²²WªªS®®²WWWSS¦¦eeÀÀmmÃü¼¼¼qqÄÄïïBB˜˜ëë®TªªWWWWWW®®77ŠŠŠŠŠŠµµ^^¹þ£QQúŸ!!!!xûûûûRR¥¥ÐÐ}}Ôy Ì Ì  ººººººººººººhhÉÉÉÉÉÉvKKKKôOOO¦¦SSÂÂooÆÆkkkkkd¾@@@@——<<¾¾dd¶¶¶¬iÿ¡¡ Fˆˆ Û Û66 ª ª ª ªXX_ñµ[–4ÚÚÚÈÈÈ"ÌqqBBïï • •BB%%x "" t t    MMú    ú%%xxxxxx££ ö ö ö ö ö ö ß ß ß ß ‰ã66ŒŒ: ß::::::::666  ¸¸ ´aa ê ê—— êEE êllppttttppÃÃÃÃÃÃpp{{{{wwOOOOSS¦¦Sù¦¦OOOO¦¦SS®®SSOOýýýýýýSSªªýý¼¼iiiiee¸¸œœBBë똘ïïBB˜˜ëë®®®®®®TTªªª   ±¹n  ^^  ¹¹¹¹úúúúúúMMÏÏttË pººººdddd<<<<¥¥¥¥NNNNyyyyyy''¢¢OO¢GôôK¦¦Køø¦¦¦¦oÊssÆÆkkk¥¥RRûû©©©Nû¡NNNNÐ**Ðuuuˆˆ Û Û66 ª ªXX_á<<á4ÚÚÚÈ}ŒçqÌqïï • •BB%%x "" t t    MMú    ú%%xxxxxx££ ö ö ö ö ö ö ß ß:: ‰ã66ŒŒ: ß ß ß ß ß::::666  ¸¸ ´aaEE——EŸE êllppppÃÃÃÃÃÃpp{{{{$$wwOOOOSS¦¦Sù¦¦OOOO¦¦SS®®SSOOýýýýýý¦¦SSªªýý¼¼iiii¼¼eeBBBBë똘ïïBB˜˜ëë®®®®®®TTª   ±^  ^^  ¹¹úúúúúúMMÏÏttË pººººdddd â â<<ê 5¥¥¥¥NNNNyyyyyy''GüOO¢GôôK¦¦SS¦[Ê$wwƒÎssÆÆÆÆÆkkk¥¥RRûû©©©Nû¡NNNNuÐÐuuuuˆˆ Û Û Û Û ª ªXXXX²²Ú44ÚÚÚÚ"ç(%(%˜yÌqïïïïBB • • Ë Ë Ë Ë""ÏÏúú òMú    úÓx%%xx Ë% ö ö££ ö ö ö öŒŒ::ãããã::ŒŒ ß ß ß ßŒŒ ß:66ã ‰ ] ]  aaaa————òòE ê ¿tÃpppÃÃpppppp{{{{$$$$OO¢ý¦¦¦¦¦¦¦OOOOSSSSSSOOýýýýýýùS¦¦WWWýiiÃiiÃiieeÀeBBïïë똘ïïBBë똘[[®®TTT®WW¹¹ ±^^¹¹  ¹¹f §MM òŸŸMM!!ttººh dddd â â ø ø ø øû ¡ ¡û''''''ÔÔG¢OOôô¢¢øøøS[[­­[[wwwwÕ{Îssssss¾ÿÿRR©©ûûNNûûû¡©Nuuuuuuuˆˆ Û Û Û Û ª ªXXXX²²ÚDDé444"2$)§ÓÌqïïïïBB • • Ë Ë Ë Ë""ÏÏúúM§ú    úÓx Ë Ëxx Ë% ö ö££ ö ö ö öŒŒ::ãããã ß ßŒŒ::::ŒŒ: ß66 ‰ . ] ]  aaaa——————E êttÃpppÃÃpppppp{{{{$$$$OO¢ý¦¦¦¦¦¦¦ªªªªSSSSSSOOýýýýýýùS¦¦WWWýiiÃiiiieee BBïïë똘ïïBBë똘[[®®TTT®WWªª^^ ±^^¹¹  ¹¹¹¹f §MM òŸŸMM!!ÏϺºh dddd â â ø ø ø øû ¡ ¡û''''''ÔÔ íGOOOO¢¢øøøS[ŵµ,,,,0Õ(ÎÎÎssssÿÿRR©©ûûNNûûû¡N ôuuuuuuuˆˆ22 … …XXXX_áKjÅžá‡Ó˜˜:ÐÈmïïBB ëF™™Ï t""xx%%QQ££££££xx Ë Ëxxxx££ ö ö ö ö I£6666Œ 2 ß ß66ãããã6 ß ß ß ßaa ´ ´  ¸¸îîîîîîîîlÆtÃÃlÆÆÆ$$$$ÍÍÕ ¢¢OOªªýý¦K¦®S®®¦¦ªªªª¦¦SSýýýý¢¢OOSù¼¼¼¼¼¼¼ee¼¼ë똘BBBB>˜˜˜BBBB®®®®®®®®µµ [µ    ¹¹  µµbb££ööŸŸMMttÏÏttÏÏhhº ` `ººº â â â â< âû ¡ ¡ ¡NNNNyyyy''''žžKKžžK¦¦¦¦µ/µµb½8ÝÝÝŽ44$$$ÊwwÂVV©©©©ûû÷÷J¥÷÷JJyyuuuˆˆ22 … …XXXX_<¦)>*™á‡uuÈmïïBB ëF™™Ï t""xx Ë ËQQ££££þþÓÓ%%ÓÓxx££ ö ö ö ö I£6666Œ 2 ß ß66ãã6666ãã6 ß ß …:aa ´ ´  ] ]îîîîîîîîlÆtÃÃÃÃlÆll$$$$ÍÍ  ¢¢OOOOýý¦K¦®ccµµªªOO¦¦SSýýýý¢¢OO¦¦Sù¼¼¼¼¼¼¼mmÀÀ¼¼iië똘BBBB>˜˜˜BBBB®®®®®®®®[[µµµ    ¹¹  bbIIööŸŸMMtttttttthhº ` `ººº â â â—< âû ¡ûû©©NNyyÔÔ''''žžKKCøK¦¦¦¦[j̽’88íC鎎ÙÙÙwwÂVV©©©©ûû÷÷J¥÷÷¥¥yyyyuuu Û Û22 × × ªX²²²Djjž444qqÄÄÈÈïïïï™™FFÏÏÏÏ% Ë Ë Ë£þQQþþþþÚÚ-ÓÓÓ% Ë I I I£ öQ££ ‰ã66ŒŒŒŒãã66ãã ‰ ‰6666 ß ß 2Œaaaa ] ]  › æAAîîA›lltÃÃppllt$$$$ÍÍÍÍ¢¢OOOOý¢ùù¦µÍÍjSOO¢¢¦¦¦¦OOýýOOOªSS¦¦¼¼¼¼ii&|ÇmmiiiiF똘ïïB çFF˜˜BBBB®®®®®®[¶¶®T®®TTµµµµ  ¹¹b½µIIIIŸŸMMtt!!tt Ç Çººh  h  â â â â<<—<NNNNûûN©yÔ'''yyžžKKKKžø¦¦SS­½½½rÌG’šôžC–ñ<áá,$$°V©©©VVR÷¥¥÷÷÷÷ÌÌyy# Èu Û Û × × × × ª ª ªX²²²44<<é444ÄÄÈÈïïJJ™™ ë ëÏÏÏÏ% Ë%% I£QQþþþ³ŸT—ˆˆÓ% Ë I I I£ öQ££ ‰ã66ŒŒŒŒãã66ãã ‰ ‰6666 ß ß 2Œaa¼¼¸¸  AAAAîîA›ll ¿ ¿tÃÃppÆÆÎÎttt$$$$ÍÍÍÍ¢¢OOOO¢ýùù¦µz'V,À(zc®ªªýý¦¦OO¢¢OOOªSS¦¦¼¼¼¼iiÛ1æ1Çiiii F˜˜ïïB çFF˜˜BBBB®®®®®®Õz ®®®TTµµµµ  ¹È#ȽµIIIIŸŸMMtt!!tt Ç Çºº h h  â â<<<<< âNNNNûû©.ÔÜ''ÔÔžžKKKKžø¦¦SS­½rÌ'¢¢ O!©!Sø ¦KK ¦#[ñ4w°V©©©VVR÷¥¥÷÷÷÷ÌÌyy# Èu ¬ ¬ Y Y ª ª ª ª T®®®,‡‡á‡‡ÚÚ ëF™™FF™™mmmm À À§Múú££QQÏÏÏ)€€Úù)_.É%OÆ\§MM t tÏÏxx%%¼¼¼a¸¸¸¸¸¸¸¸ ´66666666  eeaallÆÆîî››îî “ “llÆÆpppp!!0@ÒâýOO H HOO¢¢¢¢O õ¢¢¦¦®®Á"ð1&3Û+Ñ ²ªªýýÑÑÑÑ{{{{ÑÑÑÑ{{{{::::>>ë «phIçç””qqÄĘ˜ëëë똘00݃0‹õ[<Ù $bbµµbbJÄ"¼ð;ŽŽtttttttÏ!!!!ËË p p<<º ` h###}yy'....Ø}}}žžKK¢¢ôO©©üW± CøR­ ü#±#%¹&#[$µ#[!'&‘(™ z ýPõ^°V©©©©RR¥¥NN¡¡¥J÷÷JJ÷ Y Y ª ª ª ª T®®®,‡,‡‡‡4  ëF™™ ë ë™™mmmm§Múú££QQÏÏÏ)ÚÚc2Ø50#{§§ÏÏÏÏxx Ë Ë¼¼¼a¸¸¸¸¸¸¸¸ ´66666666ee  aallÆÆîî››îî “ “llÆÆpppp!!ÖåÒâýOO¢¢OO¢¢¢¢O õ¢¢¦¦SS Ñ#)%¥Ñ ²ªªýýÑÑÑÑ{{{{wwÑÑ{{{{::::ããëëœöI”AA::qqÄĘ˜ëëë똘åš8Ý0Öåš–áÙÙbbµµð)EÌJ•ŽŽttttÏÏtÏ!!!!ËË p p 5 5<<º ` h}}#}yy'.ã‰Ô}Ø}}žžKK¢¢O©OOüW± ¹¹Cø­ #±&f(n+#,Ô,Ô,Ô(Å#Ü#Ü!Õ  ²ªP^°V©©©©RR¥¥NNûû¥J÷÷JJ÷XXXX®®,,ÚÚ,,‡, ëF™™ ë ë ë ë À À§§MM ö öQ«ÏÏ)„=—ò'W.$¢¿¯UUUÏÏ""xx Ë Ëaa¸¸ eee¸aaã ‰ãã6666¸¸¸¸aa ´llÆl ¿ÆlAAîîîîîîÃÃpÊÆÆ{{xpp¢ýOO¢ýý¢¢¢¢¢¢¢O õK¦SS²Á#Ø#²ýOO¢ýÑÑÑÑÕ{ÍÍww$${{{{::::ãã>>AAAçç猌ÄÄÄÄëë>>˜˜˜ó¢±’݃ƒ0‹4,,Ù,‡µbµµ•ZbR•;à;Ït!!!! Ç!ÏÏ!! 5 5<<<< ³ºº¾¾¾d}}ÐÐyyÜ.Ô++++žžKK¢¢O©üüüW^¹n𥠴#i%¹+#-+/à2>2>1‘,''?#/ zÅ ²õ°°©VVûûÿ¥R÷NNNN÷÷÷÷JÿRXXXX®®,,ÚÚ,,‡, ëF™™ ë ë ë ë Àu§§MM ö öQ«))„H%{)Š"ÆLt¿¯UúúúÏÏ""xx%%aa¸¸ eee¸aa>ããã6666 ]¸¸aaillÆl ¿ÆlAAîî “ “ “ “ÃÃpÊÆÆÆÆÃpp¢ýOO¢ýý¢¢¢¢¢ýýªOK¦SSW²¹¹¹_WWOO H¢ÑÑÑÑÕ{ÍÍww$${{{{::::>>>>çççŒççççiiÄÄëë>>˜˜˜ó’í8ƒƒƒÖ0ÙÙ,,Ù Ò,µbµµ;•Cè•;à;Ït!! Ç Ç Ç!tt!! 5 5<<<<h ººdd¾d##ÐÐyy'''ÔyÐÐ++žžKK¢¢ôOW¢üW©^𥠴#i',}1:3ï6N6N5 2ë.)ô$Š g _P°°^VVûûÿ¥R÷NNNN÷÷÷÷¥¥R´´ ª ª ª,,ÚÚƒƒƒƒBBïï ë ë™™ÄÄÄÌqyXþ££  úúúÓ-5c0¥4µ',H`««úúúúxx Ë% Ë Ëxxaaaa  ee¼¼a¼ŒŒ ß ßããã㸸¸¸e ¸¸llÃ×—EEî “AAÃÃÃÃt ¿ÆÆpppp¦KK¦¦ùù¢¢¢ý¦¦¦KùùSSS®[[®®SSOO¢¢$ÑÑÑÑ$$ww$$Í(  ::ŒŒë::çAÄÄ>>˜˜••••Ý݃ƒƒƒÖÖ,,,‡,,µµ^^¹‘ìä䎎ààËË  !|ÏÏ!!tttt â â¾d ·dd¾¾ÐÐÐÐ#}}}''ÐÐ++KKKñG¢¢¢¢¢üü^Gü±#À(n05J6¤6û6û6N4ó1e-V&‘!'ººª^^°°©©VVVV©N÷R÷÷NNNN¥¥¥´´ ª P ª ª,,ÚÚƒƒƒƒBBïï ë ë™™ÄÄÄÌ&ˆ.Xþ££  úúúÓ-ÚŸ#',!ÂH`QQúúúúxx Ë% Ë Ëxxaaii¼¼  ee¼¼a¼ŒŒ::ããã㸸¸¸e ¸¸llÃ×—EEî “››ÃÃÃÃÆÆpp¦KKK¦¦ùù¢¢¢ý¦¦¦KùùSSùSSSSSOO¢¢$ÑÑÑÑ$$ww$$Í({{::ŒŒë::ŒçÄĘ˜˜˜••••ÝÝ((ƒƒÖÖ,, Ò,,,µµ^^^¹7‘ä䎎ààËËtt! ÇÏÏ!!tttt â â¾dldd¾¾ÐÐÐÐ#}}}Ü'ÐÐ++KKKñG¢¢¢¢¢üü©^¹ì¡V"f'/25J6¤6û6û7¨6N40 )F!'oºª¸¸°°VVVV©N ÷÷÷NNNN¥¥ÿ® T ª ª ª ª  ,, Ö Ö Ö ÖBBB ë ë™™ÄÄyã \M³þ££MMúúÓ-ÚP£“³Xþ£úú§M Ë Ë Ë Ë  xx ´¼¼ii¼¼  ¸¸¼¼aaŒŒ::ã㸸¸¸¸¸¸¸ll ¿ ¿Ã×ò——îî››ppÃÃllÆÆÆlÃÃKKKKùùKK¢¢OO¦¦ùùùùùùK¦SSSS¦¦ý¢¢¢ÑÑÑÑÑÑ$$$$ÑÑÍÍÍ(çç::>ããã::ŒŒqqÄÄóó˜˜BBBBƒƒÖÖÖÖ00 Ò,Ùbb^^  䊊Šàà33ËËtttttt!!!!tÏ<< â<¾¾¾dÐÐÐÐ}#++''ÐÐ}}ñKKKG¢¢¢¢¢©©W±^¹?ôV#À(n,}3ï6¤6û6û6û6û40 )F"‚vg_ªe  °©ûûûû÷ ÷÷¡¡NNÿ® T ª ª ª ª  ,, Ö Ö Ö ÖBBB ë ë™™ÄĈ \ X££MMúúÓ-Úö«H9³Xþ£úúM§ Ë Ë Ë ËxxxxiËxxee¸¸aaaaŒŒ ß ß66ã㸸¸¸¸¸¸¸ll ¿ ¿ppÃxò———îî››ppÆÆÆÆÆlÃÃÃÃKKKKùùKK¢¢OO¦¦ùùùùùùK¦SSSS¦¦ý¢¢¢ÑÑÑÑÑÑ$$$$ÑÑ s s sÍçç::>ããã::ŒŒqq.ãMóóBBBBƒƒÖÖÖÖÖÖ Ò,Ùbbbb¹¹  䊊Šàà33ËËtttttt!!!!tÏ<< â<dd¾dÐÐÐÐ}#ÐÐ''''++}}ñKKK¢G¢¢¢¢OOW±^¹?ôü±$^(n1:3ï6û6û5 5 2À.°&‘"‚vgºe  °©NûûûûR÷÷÷ûûNN´.ËGG š š šõˆ . Û Û .ˆˆˆ ° °]] Å ÅssÉÉ Å Å  Í(ÝÝÜÜ''~~++­b¼"Œ"bÿÿRRRR Ð Ð~~''ÔÔôO±Ð& %F½øssÅÅššššCCññv ÁÅÅÅÅ''yyÐÐÐ+Vûûû ôNûû©©ûûRR¥¥ÔÔyyyyyy í íššžžññÅÅÅ ÅÅssˆˆÛÛ2ç”999AAŒ2ßßv  ssššG íššššñKžžGGGGžCññCCžžÉÉ$Ž$Ä+ˆ%qèÑvssssˆˆÛÛÛÛÛÛ´´]]]]RRRRRRRRÐÐÐÐyy'' 5<<ddddddddê<<ddººººNNû ¡ ¡ ¡ûû#}ÐÐ+ÐÐо¾lÆÂÂooÆ!(ƒy6# &t'Î+Þ.“1õ4ª3ý2¢/k+\%E!5)tm¸´YYÿÿ¤÷JJJJ FFFóóFF¨¸]GGõõ šõãˆ Û Û .ˆˆˆ ° °]] Å ÅssÉÉ Å Å  sÍÍÍ''~~++­b¼m"ȸ­ÿÿRRRR Ð Ð~~''ÔÔš©*Y4)2ÏSssÅÅššššCCññvÑvÅÅÅÅ''yyÐÐ vÐVûûûN©ûû©©ûûRR¥¥ÔÔyyÔÔÔÔGGôôžžññÅÅÅ ÅÅssˆˆÛÛ2çî”9î`«çŒßßvÅÅssššG íššššñKžžGGGGžCññCCžžÉÉ$ø2M6\1 øÑvssssˆˆ55ÛÛÛÛ´´]]]]RRRRRRRRÐÐÐÐyy''ê<<ddddddddê<<ddººººNNû ¡ ¡ ¡ûû#}ÐÐ+ÐÐÐhh¾¾lÂÂooÆ!Î(iÄ6) *ƒ&t&t))+0-å.“-8*%ò#êÛ)tm¸´YYÿÿ¤R÷JJJJ F  N™FFóNNGGõõGGˆˆ Û Ûˆãˆ . ° °]]´´´´ss Å ÅÉÉ Å Å Å Å Å ÅssÔÔ''~~~~¼¼¼m^R­­ ¥ ¥RR Ð Ð~~''ÔÔGWn"ç*°'ûŦ ÅÅÅÅÅ k kGGššññCC$3Ž~ÍsyyyÔ}}##NNûûN©©©NNûû¥¥RRÔÔ Ì ÌÔÔÔÔ¢GôšžžžžÅÅÅÅÅÅssÛÛˆˆßßççA`%‡hî922ÉÉÅÅÅÅššššôšGGžžžžGGšôžžññññññÉÉ~)0E+ˆðÑvssÅ 5Ûˆˆ5Û..YY]]°°RRRRRRRR}###yyÔÔ<<êêê â âddhh  NNNNû ¡NNÐÐ##ÐÐ##hhhhlloÆ!ÎÎiÄ.!˜####$l%Æ'!%Æ#=#= ˆ-)tm¸´YÿÿR÷R÷JJ÷FFóN  ó™FF™GG š šGGˆˆ Û Û .ˆˆ . ° °]]´´´´ss Å ÅÉÉ Å Å Å Å Å ÅssÔÔ''ØØ~~bÌÌm^­­RRÿÿRR Ð Ð~~''ÔÔG¢©¹bK ÅÅÅÅÅ k k í íššññCC$~Ù~syyyÔ}}##NNûûN©©©NNûû¥¥RRÔÔ''ÔÔÔÔ¢GôšCCžžÅÅ  ÅÅssÛÛˆˆßß22çœþþî922ÉÉÅÅÅÅššššôšGGžžžžGGšôCCññññññÉÉ$ÙCRð+vssÅ 5ÛˆˆÛ5..YY]]  RRRRRRRR}#}}yyyy<< 5 â âddhh  NNNNû ¡NNÐÐØ#ÐÐ##hhhhoÆ!ÎÎiÓMM \#!· ˆ ˆÓ-Ï]YÿÿÿR÷R÷JJ÷FFóN  NóFF™žž D Džžˆˆ6 Û … … ×2 Y Y´´]]]] o o   Å Å Å Å ''''++Ø3u#¤) ïq¼ZVV© N©©VV''ÔÔ Ð Ð~~ššôOøøžž Á oÅÅššššCCCžssz Å kssyyyy+ÐÐÐ¥¥¥¥¥¥RRNNûû¥¥R­Ð vÐÐ''yÔžCññššGGÅÅÅ ooˆˆˆˆ2222==çŒßßoÉÅÅÅÅššššññññšôôôññžž í íššGGššoooÉsÍ(‚+vÉÉ ÅÅňˆÛÛ„ß22]]]]´´´©©VVRRÿÿ}}+Ð''yy<< ‹ ‹ææººhhººhh99ææddhhººN©ûûû ¡ ¡ûyÔÔyÐÐÐÐhhhh¾¾lllÆww¼qq””ïIQ«!`«&€xm °¬¬ÿ¤NNû ÷÷÷JJFF ëžžžžžžˆˆ6 Û … … ×2 Y Y´´]]]] o o   Å Å Å Å ''''++Ø3Ð*h3â+ÃÌbZZVV© N©©VV''ÔÔ Ð Ð~~šššôžžžž ÁoÉÅÅššššCCCž ÅÅ kssyyyy+ÐÐÐ¥¥¥¥¥¥RRNNûû¥¥R­Ð vÐÐ''yÔC éññššGG  Å ÉɈˆˆˆ222255ããŒ2ßßoÉÅÅÅÅššššññññšôôôññžžGGššGGššoooÉsÍÍsvvÉÉ ÅÅňˆÛÛ„ß22]]]]´´´©©VV­­ÿÿ}}+Ð Ì Ìyy<<ææ@@ººhhººhh““ææddhhºº©ûû ¡û ¡ûyÔÔy++ÐÐhh  ddlllÆÂÂb¼¼¼ßß”ïœö«öqËÃi¸°U¬¬ÿ¤NNû ÷ïïFF ë ñ ñ ñ ñžž Û6ˆˆ … …22]]]]ÉÉ   Å Åss Å Å o oÉÉ z z''~~~3À”&Y”Ä´­­VV©© ü ü©©ÔÔ'' Ð Ð~~ššGGCCžžoÉÅÅššššCCññÅÅÅÅssssyy''}}##¥¥¥¥¥¥¥ JNNûûÿ¥¥ÿ}###''yyCCžC í íššÍsÅÅvÉÉÛÛ55ß„22ˆˆˆãßß22ÅÅÅÅGGGGžžžžššôôžžññGGGGššššoo Á ÁsÍ  ÉÉÉÉ Å  ÛÛ €Û2222]]  ´´´´^­­­­ØØ+Ðyyyy<<““““ººhhhh< â â<ææ“9ddh   ©©NN©ûû''yÔ++Ðкººdd¾¾llooÊo´bb…ß::AœI”iü¸¸UU¬¬RRUû  JJBFF™ ñ ñ ñ ñžž Û6ˆˆßß22]]]]ÉÉss Å Åss Å Å o oÉÉÔÔ''~~ØØ±fÀf´Z­­ ü ü©© ü ü©©ÔÔ'' Ð Ð~~šš í íCCCCÉoÅÅššššCCññÅÅÅÅssssÔÔ''####¥¥¥¥¥¥¥ JNNûûÿ¥¥ÿ}### Ì ÌyyCCžC í íššÍsÅÅvÉÉÛÛ55ß„22ˆˆˆãßß22ÅÅÅÅGGGGžžžžôôôôžžññGGGGššôôoo Á ÁsÍ  ÉÉÉÉ Å  55Û52222··e°´´^ØØ+Ðyyyy<<““““ººººhh  < â< âææ“9ddh   N©©NN©ûû''yÔÐÐÐкºº¾¾¾¾lloooZ´…ßßß2Œ::´a]¨UU¬¬RRû   JJBFF™ss    ]]¸¸]]ˆˆ . . . .66 ñ ñ ñ ñ ñ ñ ñ ñõõ í í šõ š š Ð Ð~~ Ð Ð~~©­­ÿÿÿÿRRRRRR©© ü ü ü ü©©oo Á ÁššG í ?šššCCCCññññv$$ÑvVûNNR øRRÐÐÐÐÔyy  ø ø¥¥¥¥RRû ¡NN¥¥ J¥šôôššš¢¢Ís  ss  222ŒÛÛˆˆ´´ °]]Å ÅÅ ÅÅÅÉÉssssššššôôššñKññññKñooÉÉvvü¢šôññžø5ˆˆßßßßßߌ2ß9çA66‰‰22:àZÿR øVûNNddºhhºººººº hh ddææ99 Ì Ì''ÐÐ##¥¥¥¥ ¡û©Nººººhh¾ÆÆ¾……2×22222…ß]UUUURR¤¤NNó™FFFFïïBFF™wwÍÍ    ]]¸¸]] . . . . . .66 ñ ñ ñ ñ ñ ñ ñ ñ š š í í @ š š š Ð Ð~~ Ð Ð~~©­­ÿÿÿÿRRRRRR©© ü ü ü ü©©oo Á Ášš íGôšššCCCCññññvÑŽCàÑVûNNR øRRÐÐÐÐÔyy  ø ø¥¥¥¥RRû ¡NN¥¥¥ J ?ššôššGGÍs  ss  222ŒÛÛˆˆ´´° ]]Å ÅÅ ÅÅÅÉÉÍÍssššššššôôñKññññKñoooovvü¢šôññøž5ˆˆßßßßßß2Œß9Aœ‘‘ããà…´Z­RVûNNddºººhhºººº hh ddææ99 Ì Ì''ÐÐ##¥¥¥¥ ¡û©Nººººººhh¾ll¾……2}×××××*…¨UUUURR¤¤óóó™FFFFïïBFF™$É    e ]]  ° ° Û Û . .ˆˆ ñ ñ ñ ñ ñ ñžž š š š š š š š š++~~~~ РЩ©VV­­­­ÿÿRRRRRR©©©© ü ü©© Á ÁooššššG íššCCññCCžžÉ$Ñð)*ÛZ†°ûûû¥ÿ­+++Ð' Ì Ì Ì ø ø ø ø¥¥¥¥ûûûûRRÿ J í íšššôGGssssÅÅÅ ßßß„ˆˆÛÛa´Y°°]  ÅÅÍs  GGGGššššññCCññññoo Á$$ôôGGžCññˆˆˆˆ22ßߌŒçççAœQ˜˜˜>•:à…­­­VVûûl hÒÊoÂÂhh  ºº  d¾¾¾ â â““ææyyyy###}¥¥¥¥NNûûººººhhhh¾ll……ØØ***Ð}}**¨¨¨ûûR÷÷FFóóóó™óJïFF™$É    ¿e]]  ° ° Û Û Û Ûˆˆˆˆ ñ ñ ñ ñ ñ ñ D D š š š š š š š š++~~~~ РЩ©VV­­ÿÿRRRRRR©© N N ü ü©© Á ÁooššššG íššCC – –CCCøÉ$†"4U5¯,ãð°ûûû¥ÿ­••…+' Ì ÌRR ø ø¥¥ÿÿûûûûRR¥¥ í íšššôGGssssÅÅÅ ßßß„ˆˆÛÛa´Y°°]ÅÅÅÅssvv(Í  GGGGššššññCCññ – –oovÙŽOšGGžCññˆˆˆˆŒŒßߌŒççAœQ¨¨¨Mï•:à­­­VVûûlh‡¦é$ÂÂhh  ººhh¾d¾¾êê â â““ææyyyy###}¥¥¥¥NNûûººººhhhhd¾ll++ØØÐÐÐu}}ÐÐN¨NNûûR÷R÷  óóóóóNJï  ë™(Í$$wwi´´   ° Û Û6 Û22 …ßžž ñ ñ š š š š íGG í D D ñ ñ~~ Ð ÐÔÔ'' üVȱVÿZ­R©©©©©© ü ü ü ü©© Á Á Á ÁÅÅCCññññññCCCCCCCžÅ Õ©),6"†©ûûûVV Mó‰ÔÔÔÔÔûû ¡ ¡ûû©©ûûûû¥¥¥¥ñ –ññšôôôÅ ss    ßß2222 × ×  °°YYYYoovvvÍÍÍ‚3ÙÑvKKžžžžññññCCššGGoooooÉ+àSžññššššˆˆˆããã555êEŸú\l´¬QœB:à­­­VVûûh ººoé8slllddººhhl¾¾êê<<ææ““ÐÐÐÐ'' Ì ÌNNûû øR¥¥  ººººººººhh¾¾ll}}ØØuu""&ÌyyûûûûNN    û ÷÷JJïJ ûûûNóFFFFF‚($$ww´´´ ° ° ° Û Û6 Û22 …ßžž ñ ñ š š š š íGG í D D ñ ñ~~ Ð ÐÔÔ'' üV^Œ%«× ±ÿZ­R©©©©©© ü ü ü ü©© Á Á Á ÁÅÅCCññññññCCCCCCCžÅ z/CC;Ñ©ûû ¡ûVV.‰.yÔÔÔÔûûûûûû©©ûûûû¥¥¥¥ñ –KKôšššÅ ss  zzßß222222°°°°YYYYoovvv((7¡­àÑKKžžžžññññCCššGGoooooÉvvžžññššššˆˆˆã==5EŸTd!!%0'-#a÷ç:à­­­VVûûh ºººoosll ·ddººhhlŸê<<ææ““ÐÐÐÐ''''NNûû øR¥¥  ººººººººhh¾¾ll}}}}uu""&ÌûûûûNN     FJJJ¤°t°NóFFFFF/Õ~~$$´´a ° ° ° °ˆˆ Û62222žžžž š š š šõõ¢Gžž ñ ñ Ð Ð Ð Ð'''© …#¤* ±­­ÿÿ©©©±±VV©© ü üoooo k k ¾ –ñžCCCCC – – – –CCññssÍÍÑÑÑvûûûûNNVû''ÔÔÔÔyyN©©©ûûNNûûN©ÿÿ¥ÿññžžššššz sssÍzz9ßßßßß22]]]´YÉÉÉ$‚’#À-:.ë*Û!bŽøøKñ –ñžžžžññGGššoooov –ñCC íGôôˆˆ5555ò§d!Î+õ-O,—'-!ô¤:àà­­Zÿûûûûhhººººhhlldd dººhh¾¾ƒL<<9“HîÐÐ##yyyÔûûNN¥¥¥¥ººhhººh ººhhll¾¾}}}}È"uuyyûû¨ûU¨N   Fïï÷÷¬ Þ- *XÏûFóó™óF/ÕÙÙ~É´´a ° ° ° °ˆˆ Û2222 D Džž š š š šõªü¢žž ñ ñ Ð Ð++'''©± Àf±V­­ÿÿ©©^ÀÀVV©© ü üoooo k ks –ñžCCCCC – – – –CCññssssvvvûûûû©©ûV''ÔÔÔÔyyN©©©ûûNNûûN©¥¥¥ÿññCCšššš ÅÍÍÍ(zz”999ßß22]]]´YvvÉÉÉ$’#À3þ88d7 2ú S¦KKñžžžžññGGššoooov –ñCC íGôôˆˆ555êM·#(+G2¹43\-ò%Óÿ•:…­­ÿ¥ûûûûhhººhhddd ººhh¾¾sG$ä¶——“£Âý…Ð##yyyÔûûNN¥¥¥¥ººhhººh ºº Âll¾¾}}ØØmÈuuÄyû°¸¨ûU¨N  F ëïï÷÷a'£3Ñ3Ñ#“U óóó™F¿¿ÇǸsss GG š š ñ ñž D sss Å Å Å ÅõOüG ñ ñ ñ ñ ¥ ¥ÿÿRRRRÿÿ­­VVêê====DŸTŸ——@@““ššG íCC –ñ ÁoooooožC – –šššššššš¢¢ôô hd¾¾¾ººº““99<<CC –ñššGG¢G¢¢O©©©Ù~ÑÑ$ÉÉoññññžžKK㈈ˆßߌA»,ù78z8Ð7v6(’€»a·]]]ÛÛ..ÛÛÛÛššG í – –CžooooÅÅssÛ5ã=”9çç꟯)@46É6É5¤0:&õáÒwºd¾êê<<æææ ‹NN©©ÿÿZĤ•Ø}Ô>  ‰y''yÔÔÔNNNN¥¥¥¥99 ‹æææ99dhhRR­R_X²__<KK–ååå‹88Ý݇‡44¶¶ å'¹+’Óqqmmmeemm¸sss GG š š ñ ñ Dž sss Å Å Å Å šõGG ñ ñ ñ ñ ¥ ¥ÿÿRRRRÿÿ­­©© ü üêê====ê êê== æ æ““ššG íCC –ñ ÁoooooožC – –ššššššššGGôôºº h¾llllll¾¾ººº““““êê<<CCñKôô¢¢¢G¢¢O©¹Ž3++$É$ÉKKññøø¦¦ãˆˆˆßߌA,ù78z8Ð7v6(’%»»a·]]]ÛÛˆˆÛÛÛÛšš íGññžCooooÅÅÛ5òþîççEú #(.ª6É8#8#6ÿ1•'nOáÒº¾dêê<<æææ ‹NN©©¥¥ÿÿ…+Ø}Ô‰ë6.Ô''yÔyyNNNN¥¥¥¥99 ‹æææ99¾¾ººhhRR­R_²X__á<<<‹‹‹0ÝÝÝ݇‡ÚÚ\\ ck Íqqmmm¸¸ee]]ss Å Å oÉÉÉ š š š š ñ ñžžss Å Å Å Å Å Å šõõõ ñ ñ Dž ¥ ¥ ¥ ¥RRRRÿÿRR©©©©==êê====== æ æ““ í í í íCCCC Á ÁooooññCCššššGGGGGGGGhhhhl!ÆlÆl¾¾¾hh `º““@æêêCCžžGGôô¢¢¢¢W± ÁCèà+ÑvvvžžñK¦[=ã㈄„Œçœ"%16r7v61_!!i´´]]°°ÛÛÛÛ....ššššCCžCoÉss  ã=d)í!w£”Æ*š3f7v7v7v5¤-…"å,wÊoohh¾d¾¾llêêê@æ“9N©ûûRRÿ¥}#ÐÐÔÔÔÔÔÔÔÔyyyy©NN©¥¥¥¥999999ææddººººRRZÿ²²²²_Ú444ÝÝ0000ƒƒ‡‡‡‡\\\\cc¶qqqqmmm¸¸  ]]ss Å ÅÉ$Ù$õõ š š ñ ñ D Dss Å Å Å Å Å Å šõ š š ñ ñ Dž ¥ ¥ ¥ ¥RRRRÿÿRR©©==êê====== @@““ í í í íCCCC Á Áoooo – –CCššššGGGGGGGGhhÂÂ{0ÖÆÆll!Îss¾hhºîî@æêêžžžžGGôô¢¢üü± ЭR;†ÑvvvžžK¦Ô'û#ë=㈄„2ŒçQ"%*D-ü)í"{§i´´´]]°°ÛÛÛÛ....ššššCCžCoÉssÅňãT#( þ”Æ'å2 67v7v4J)võ‹ÒÊoohh¾d¾s{llêDDD@æ“9N©ûûRRÿ¥}#ÐÐÔÔyyÔÔÔÔyyyy©NN©¥¥¥¥999999ææddººººRRÿ¥²²²²_Ú444ÝÝ0000ƒƒ‡‡‡‡\\\\  ¶\qqqqmmm´´]]]]ÉÉÉÉ /Šzžž D D Dž ñ ñ zss Å Å Å Å ñ ñ ñ ñK ñ ñ ñ©© ü ü©©©© ¥ ¥ ø­±V©©========== ““ æ æCCCC í í í í k k Á Á Á Ášš í í í í íGññññGGGGººhh¾¾Æ{‹@ÝsÊéõÖÆl¾¾l@@ææ<<êêôôôô¢¢ôôKK¦µjÌ#ë$ C3~$É$ôô¢¢*4×/m`AŒŒˆ.Û5=˜M\l\Ÿêa´´]]°° ×222„„„„GGššññCCoovoo2ŒAöúŸêEö Ê'/32c2c-/!é!ÆlºººhhÊCõ{lîý²XŸD—<¥¥ ø ø¥¥RR}##}''yyÐÐÐÐÐÐÐÐûûûûNNN©ææ99 â â â ⺺ hººh N©û ¡\\\\¶¶¶¶00‹‹8ƒƒƒ00ƒƒ00ƒƒ\\\®®® q´´]]]]ÉÉÉÉ zz žžžž DžKKz ss Å Å Å Å ñ ñ ñ ñ ñK ñ ñ N N ü ü©©©© ¥ ¥RR üV©©========== ““ æ æCCCCGG í í k kšš í í í í íGññññGG í íººhh¾¾l!{0(sÂÂÊéõÖÆl¾¾lææææ<<êêôôôô¢¢OOKK¦µjÜ*°,6(&øèÙ~$Éôô¢¢$™$™çŒŒˆ.Û5ˆã=˜ò˜a´´]]°° ×222„„„„GGššññžžoovoo2ŒŒŒêêEQ`p#(<,K+ž(é#µñÙ$!ƾ¾lºººhho4šÖÆlHÂ'ð#áTD—<¥¥RR¥¥RR}##}''yyÐÐÐÐÐÐÐÐûûûûNNN©ææ99 â â â ⺺ hºº hN©û ¡\\\\\\\\00‹‹Ý݃ƒ00ƒƒ00ƒƒ\¶\\®®® q  ¸]ÉÉÉÉ Å Åss ñ ñ ñK ñ ñ ñK Åss Å Å Å Å D D D Džž ñ ñ ü ü ü ü ü ü ü ü ø øRR©© ü ü======== == æ æ““ – –ññG í í íÅÅvG í í íGGššžžžžšôGGhhºº¾¾ssÎÆÆÂwÎs¾¾¾¾¾ææ““<<——ôôGGôOüWK¦[b%F1t4U,6RèÙ~ÑvGG¢¢ø­b”ßß߈ˆÛÛÛ5ã㈈´´´´]]°°22ßß2222GGššññññoo2Œß9êE«`p"%$,"Ò"%p<‡$Ê!ƾ¾¾¾ººhho$!ÆH !ÙÉùDêꥥÿ¥¥¥RRÐÐ##ÔÔ''ÐÐÐÐ}}++©©VûûûNNææ99 hºº hh NNN©\\®®®®®®0000ƒƒƒƒ00ƒƒƒƒƒÝ¶k\®®\\mmmmÄ i i  ¸]ÉÉÉÉ Å Åss ñ ñ ñK ñ ñ ñK Åss Å Å Å Å D D D Džž ñ ñ ü ü ü ü ü ü ü üRRRR©© ü ü======== == æ æ““ – –ññG í í íÅÅ ÁG í í íGGššžžžžôOGGhhºº¾¾¾¾ll¾¾d¾¾¾¾ææ““<<<<ôô¢¢O©üW¦K¦r'û4)7 1 $CÙ~ÑvGGGGøøøSßßß߈ˆÛÛÛ €ˆˆ55ˆˆ´´´´]]°°22ßß2222GGššññññoo ×2ß9êEö«`Âh`«‡ÒÊoÆl¾¾¾¾ººhhl¾¾“îPõDD¥¥¥ J¥¥RRÐÐ}}ÔÔ''ÐÐÐÐ}}…ïm¸VûûûNNææ99 hºº hh NNN©®®®®®®0000ƒƒƒƒ00ƒƒƒƒƒÝÆk¶®®\\mmmmÄ i i22:”22GGõõKKžž ñ ñ D DGGGG o oÉ o o o''''' z z Ð Ð~~~ # Ð Ðhh » » » » » » 9“@ æ ê CCññGGššÅÅooooÅÅss  ÍÍzz Å<<êê@@ææ““@@““@@hhd¾¾¾ll¾¾É$vvzzzzüü©©^È(Q0p3Ó.i 2OOôvÉÉÉÉ´´´´YY´´ÛÛÛÛˆˆ.ˆÛ5ˆˆˆˆÛÛ2222.ˆˆˆ  ÅÅsoooo°°  a»Ï)11ˆ-%ËùŸDD——<< â<<<<<hhººll  v v##yyyy}}+…..ÔÔ''''yÔë#t!î©RR¥¥hhhh    â â â â â ‡ J¥­R Ö0ƒƒ,,ÚÚ®®®®XX ª‡,,,,,ÚÚ____®®®®ÄÄ iÄmmm22ß:22GG š š ñ ñžžKKžžGGGG o oÉ o o o''''' z z Ð Ð~~ #~++hh » » » » 9“@ æ êêêCCññ í íššs ¾ÅÅoooo  ss  ÍÍzz Å<<êêææææ““@@““ææººhh¾¾¾llÉ$ÑÑzz  üü©©^Ø&÷*Y$ï}^©©OvÉÉÉÉ´´´´´´´´ÛÛÛÛˆˆ.ˆ5Û..ˆˆÛÛ2222.ˆ..ÅÅÅÅsoooo°°°°a»t!!xpŸDêê<<<< â<<<<<hhºººº  v v##yyyy}}…•¨óã.''''Ô.F$Ï%þu©RR¥¥        << â â< â J¥R ø Ö0ƒƒ,,ÚÚ®®®®XX ª‡,,,,,  ®®®®ÄÄÄ immm … … … …22 š š íGž D DžžžžžGGGGÉÉ o oÉÉ o o''''ÔÔÔ z Ð Ð~~~~Ø~ » » » »hhhh æ æ@ æ==êêññCCššššsÅÅ    ÍÍzzzzÍs<<<<ææ““““ææææææhhhh¾¾llllllllvvÑÑ((ÍÍOOO©n 2"çØn^Wü¢¢ÉÉÉÉÉÉaaiiiaa5Û..ÛÛÛÛÛÛÛ5㈈ˆßßßß55ÛÛsssÅÅssoÉvoo]° »»»»¿ÇÇÃûññ<<êêêêêêºh ddddddºººº###}yyyy}ج(Þ&)M‰''''ÔÔÜëm^©©¥¥ ø ø      `º â â<<¥¥¥¥Ýƒ Ö ÖÚÚ‡‡®®®®XXXX,,ÚÚ‡‡,,²X i immm … … … …22 š š íGž D Džžž D DGGGGww o o o oÉÉ o o''''/ä/Ô Ð Ð~~ØØ~ # » » » »hhhh æ æ æ@== ññCCšššš ¾ÅÅ  ÕÕ((ÕÕzz(Í——<<ææî9““ææææææhhhh¾¾llllllllllvvvvÍÍÍÍOOO©^¹È#ÈWü¢¢ÉÉÉÉÉÉ»»=ˆa5Û..55ÛÛÛÛÛ5ã=ããßßßß55ÛÛsssÅÅssoÉvoo]° aa»»¿eii»a——<<êêêêºh ddddddºººº###}yyyy}Ø2Q$Ï$ÏM‰''''yy'©©©¥¥ ø ø      `º â â<<¥¥¥¥Ýƒ Ö ÖÚÚ‡‡®®®®XXXX,,ÚÚ‡‡,,²X i immmˆˆˆ . Û Û š š š šGG š šGGGGžžžž Å Å Å o o o oss Å Å Å Å Å Å Ð+~~…:++''ÔÔ/Ô/Ô d d d  =—ê êG í ?ššôššooo oosÍz Ñ+††//‚ÝÙ~~$@æ““<<<—ê â<<<ºhhÂÂllÍ(zzzz  KKSS[ff WWüOOssssveeÖ"P›t ß„ × ×ßß22ˆˆÛ5A«XIÛÛÛÛÛÛÛooooooooÅÅssoo] °´´´´´´@æææ<<<< â â< â â âd¾ddddddºººººº  Ì ÌyyyyyyÐ+2ç÷÷:+Ôy''yy''ûû©©¥ÿR ø      º ` ‹ ‹ ‹ ‹ â â<<RR¥¥ƒƒ ( (ÚÚÚ ®®XXXXÚ ,,‡á‡‡XXXXXXmm mÄÄĈˆˆ . Û Û š š š šGG š šGGGG D Džž Å Å Å o oÉÉss Å Å Å Å Å Å Ð+~~++++''Ô‰>//Ô¿¿¿ d =—ê êG í ?šôšššoo oÉÉsÍ z+†à•™™ì’3Ù~$›@““<<<—Dê<—<<ºhhÂÂllsÍzzzzzz¦¦SS¦µµ±±WWWüOOÍÍssv°°·!!¿ ß„ × ×„„22ˆˆ5`+ž/ E55ÛÛÛÛooooooooÅÅssoo] °´´´´´´´´@æææ<<<< â â< â â âd¾ddddddºººººº  Ì ÌyyyyyyÐ+ØØ22+ÐÔy Ì Ìyy''ûûNN¥ÿR ø      º ` ‹ ‹ææ â â<<RR¥¥ƒƒƒƒÚÚÚ ®®XXXXÚ ,,,‡‡‡XXXX²²mm mÄÄÄ Û Û Û Û .ˆ š š š šGG š šGGGG ñ ñ ñ ñ Å Åssww   Å Å ÅÍs~~~~~~~~''Üû¨ä/Ô¿l======== í í íGôš í í Á Á ooÉ  Í‚†;C­ ^ ^±¡;à†Ñ››““êê<<êê—<——<<hhhhhhÂÂllÆlÍÍ(Ízz((¦¦¦¦SS[µ^^WWWW©OÍsÅ ÉÉ]]·]·]]Œ2 ×22222ˆˆ5`+ž/® Êꈈ..ÛÛ ÁooooÅÅssoo°°]]aaaaaa´´´Yææ99<<ê â<dddddd hºººº  yy Ì ÌyyyyÐ+}}++}#yy Ì Ìyy''NNNN¥¥¥ J  ºººººº ‹ ‹““¥¥ ø ø Ö ÖƒƒÚÚ,,®®XXÚÚÚÚÚÚÚÚ ª ª ªXXmmqÄ Û Û Û Û .ˆ š š š šGG š šGGGGKK ñ ñ Å Åss   Å Å ÅÍs~~~~~~~~''ëóä‰/tÆl======== í í íGôšGG ooÉ  Í‚†ðR%q+2-ç+ß%¥•à+››““êê<<êê<———<<hhÂÂhhÂÂllÆlÍÍ(Ízz((¦¦¦¦SS[^^WW±f¹©Ís ÅÉÉ]]·]] ¨]Œ22 ×2222ˆˆÛ5œQ5ˆˆˆˆÛÛvv ÁooooÅÅssoo°°]]aa´´´Yææ99 â âê â<êêdddddd hºººº  yy Ì ÌyyyyÐ+}}ÐÐ#}yy Ì Ìyy''NNNN¥¥ J¥  ` `ººººææ99¥¥ ø ø Ö ÖƒƒÚÚ,,®®²²ÚÚÚÚÚÚÚÚ ª ª ªXXmmq ñ ñ š šõõ====== d d¿¿ll¿¿ Ð+Ø~++~~VV ü ü ü ü üVîî›@@@@@==DDHH£XÆÆÆl » »¿¿ÛÛ €Ûßß2 ×°°]]° ÍÍÕŠŽR&0ò6ˆ6ˆ4€,aÜrµ[­­ÿÿ©©VV.ÔÔÔ+Ð}}ÔÔÔ.©­­ZZ—ñññññññDŸŸŸHHHHbbbb.´…+Ø}ÔÔÔÔûûûû© ô ™NRRR øûûûûûûûûV° °ÔÔÐÐ++WüGGššššÅÅs –ñCCššššññžžôôššNNNN ø ø øRÿÿ¥¥¥¥ øR¾d¾dºº hææ99<<ššG íG í íGššGGšš íGÛÛÛÛ..ÛÛYY ¬ ¬°°°°####yy' ÌÐÐÐÐ Ì Ìyydd · ·ƒƒƒƒƒƒƒƒƒƒƒƒ (Ý‹‹²X ª ªXXXX®®®® ªÏÏÏÏ%%- ñ ñ š š š š====== d d d d¿¿+…Ø~++~~VV ü ü ü üV±HHPªõ@@@==êê“H ,0ÆÆl » »¿¿ÛÛÛ €„„2 ×°°]]° ÍÍz/è­+ˆ6\7â7â751Ë#ë̵ÿÿ©©V >ã..+ÐØØÔÔÔ.©­­ZZñLññññññDŸŸŸHHHHiZ…+Ø}ÔÔÔÔûûûû©©NNRRR øûûûûûûûûûVVû''ÔÔÐÐ++WüGGššššÅÅs –ñžžššôôññžžôôššNNNN ø ø øR¥¥¥¥¥¥ øR¾d¾dºº hææ99 â—šš íGG í íGšš í íššG íÛÛÛÛ..ÛÛYY ¬ ¬°°°°####yy' ÌÐÐÐÐ Ì Ìyydd · ·ƒƒÝ݃ƒƒƒƒƒƒƒƒ8šš ²XXXX®®®® ªÏÏ))€€-K ñ í í š šêD êê d d d d¿…+ØØ++~~V ü©©©©^mXýÂѲ==== æ›ýgÖÆ¿¿ » » » »¿¿¿¿¿¿ÛÛ.. × ×„„°°°°°°  ÍÝ• ´.ë7 7â7â5Ú,a ‰ÅµZZ­R©©©^ë‘..+Ð++ÔÔV°ZZŸŸŸŸŸŸŸŸŸùŸŸHH›õZZØ}}}ÔÔÔÔ©©ûVûûûûRR¥¥ûûNN©©ûû©©ûû''''#}}}¢¢GGššššÅÅCCññ í íGGññññGGšš ¡ ¡NN¥¥ ø ø J¥RR¥¥RRl¾ººææ ‹ ‹ â âššššššššš ?ššššššˆ.ÛÛÛÛ..YY°°]####yy Ì Ì####yy Ì Ì · 00‹‹ Ö Öƒƒƒƒ Ö0ÝG!v w ²XXX ýX\\\ ý²²²ÏÏ„„ÓÓÓ ñ – í í š šêDŸDê ¿¿ d d¿…+ØØ++~~ üV©©©©£ý%–ÂH““==== æ æ“Hl¿¿ » »¿¿¿¿¿¿ÛÛ.. × ×„„°°°°°°Åz(‚àJ%q-2x2x,a"ç[ZZ­R©©©^Fë..+Ð++ÔÔ©©V°ZZŸŸŸŸùùùùùTùùHHõ›ZZØ}}}ÔÔÔÔ©©ûVûûûûRR¥¥ûû©©NNûû©©ûû''''}Ø}}GGGGšššš k kCCññ í í í í – –ññ í íššûûNN¥¥ ø ø¥ÿRRÿÿRRl{ƒsººææææ â âššššššššôšššššššˆ.ÛÛÛÛ..YY°°]####   Ì Ì####yy Ì Ì ·dd000000ƒƒƒƒ0 ÖÝG%…&à, ²XXX²X\\¶\XXXX)Þî9ÓÓx D D š šõõ“îH““ 9 æ æhh » »¿'Ô/~~~ # ü ü©© ü üV±H£ºýî““======——hhhh¿¿ d¿l.... × ×„„°°]]°°°°v$~ÝG±#À&÷(Q"çÈf Wü­­ÿÿVûV Qœà++Ð}}ÔÔÔ.++ØØÿÿ­­^^ °ŸùŸù££PPPP££ŸŸLL´´´´­''ÔÔ''ÿÿ¥¥NN©©©©N©¥ÿRRR ø ø øNNûûÜ..''ñKññššGGo oo Á Á Á ÁššššCCCCCCžCšššš ø ø¥¥¥¥R øN©©©­­RRsGO{¾dddææ““ææ99ššššññCCñ – – –CCžž2222....]]]]]]  Ì Ìyy####yyyy Ì Ì Ì Ìdd · ·,,,,ƒƒÝ݃ƒƒƒÝ’üWo_\\\\XX„H`AÓxx D Dõõõõ 9““““ 9 æ æhh » » d¿' zÔ~~Ø~ ü ü©© ü ü üV“î@@î“““========hhhh¿¿ d¿l.... × ×„„°°°°°°v$~‚7ìGÈ#È ±üW­­ÿÿVû°°Bà++Ð}}ÔÔÔ.++ØØZZ¸¸° TùŸù££õõPP££ŸŸLL´´´i¼bÜÜÔÔ¥¥¥¥©©©©©©©ZÿRRR ø ø øNNûû''ÜÔÔ'' –ñññšš í ío oo Á ÁššššCCCCCCžCšššš ø ø¥¥ J J øRN ôNNRRRRƒ@!¾dddææ““ææ99ššššññžžñ – – –CCžž2222....]]]]]]  ''yy##}}yyyy Ì Ì Ì Ìdd · · Ò Ò,,ƒƒƒƒƒƒƒƒÝÝÝ8_\\\\²²)9AŒÓxx ñKO šGG æ æ““““““hh ¿¿''''~~~~ ü ü©©©©©© æ@““““ æ æ==== == » » »¿¿ d d....ß„ *„°°°°°°°°oÉÉ$(‚Ý7 ff±Wü©©ÿÿRRVVVVØ…+Ø}++ÔÔ++ØØ´´   e¦¦¦XýýXXýýýùùLLbb6ÛÜ''Ô.¥¥RRûû©©VV°°Zÿ¥¥¥¥ ø øNN©©yÔ''ÔÔÔÔ – –CCš ? í í Á Á Áoo í í í íCCCC – –Kñšššš ø ø¥¥ ø ø ø øû ¡ûû øRRR¾s¾d99 ‹ ‹99ææššššññžžžCCCññCž„„„„ÛÛ..]···]]yyyy##}}yy Ì'yyyydd · · Ò Ò,,0 Ö Ö ÖƒÝ0 Ö0000²XXX® ®®__  ² ²²))))%%x ñKO šGG æ æ““““““hhhh¿¿''''~~~~ ü ü©©©©©© æ@““““ æ æ==== == »¿¿ d d....„ * *„°°°°°°°°oÉÉoÍ((‚W± WWü©ôÿÿRRûûVV}}…+}Ø++ÔÔ++ØØ´´   e¦[[²XX²²XXXTT¦¦bbbb6 ëq6Ü''Ô.ÿÿ­­ûû©©VV°°Zÿ¥¥¥¥ ø øNNNNyÔ''ÔÔÔÔññCCš ? í í Á Á Áoo í í í íCCCC – –ñKšššš ø ø¥¥ ø øRRû ¡ûû øRRRd¾¾¾99 ‹ ‹99ææššššKKžžžCCCññžC„„„„ÛÛˆˆ!ææ|]]yyyy####yy Ì'yyyydd · ·,,,,0 Ö Ö ÖƒÝ‹00000²XXX®   ºÙð†g ²²ÏÏÏÏ%%xÉÉss Å== æ@ æ æ æ æ““==ê Ð Ð~~Ô z''VV© ü ü ü ü==== æ æ æ æ ê““ 9“îîîîDê==¿¿¿¿ » » » »ÛÛˆˆ € €..YYYY]]Å ssÍÍzz~~~~$$vv++}}}}}}RR¥¥ûû©°°ZZ­­^^ eiiªgÂc  cg²ª¦¦Tù¼¼¼¼Èm¸ã.yÔ..'.ÔÐÐÐ+V°^©©ûûÐÐ##ÐÐ## ¡ ¡NNR ø¥¥ñKžCšš í íšš í íCCCCoooo ? ?šôGGššûû©N¥¥¥¥¥¥RR¥¥¥ÿhhººhºddddddññžžO©ü¢žCCCžžCCYYYY ¬´´Ÿ$ƒ1_1_"ÒîŒ2¥¥¥¥N© ¡ ¡## vÐ##ÐÐ< â 5XXXX®®®®®®®®ÚÚ,,‡‡‡á¢)•0Y)•ü’00úú§MúúM o oss Å== æ@ æ æ æ æ““== 5 Ð Ð~~Ô z''VV© N ü ü ü ü==== æ æ æ æ ê““ 9““H££Dê==¿¿¿¿ » »ÛÛˆˆ € €..YYYY]]Å ssss  $$$$$$vv++}}}}}}RR¥¥ûû©VVZZ^^eÀiiÄÄ_ÂÑscc¾Â _[[ ®¼¼¼¼¸¸¸¸ã..ÔÔÔ'yÔÐÐÐ+ûV©©©ûûÐÐ## v v## ¡ ¡NNR ø¥¥ñKžCšš í íššGGCCCCoooošššôGGššûû©N¥¥¥¥¥¥ ø ø¥¥ J¥hhººhÂoddddddññžS^ üžCCCCCCCYYYY ¬´´ú+G6É6É*ñ£Œ2¥¥¥¥N©ûû## vÐ##ÐÐ< â 5XXXX®®®®®®®®ÚÚ‡‡‡‡‡áü(:0Y&à¢800úú§M    M o o Å Å Å Å == æ æ 9“ æ æ““== Ð Ð~~''''VVVV ü ü ü ü==ê æ æ æ æ== æ æ æ@îýwÂL=êê¿¿¿¿hhÛ €ÛÛÛÛ..YY°°ÅÅss    vvvvvvv}}++ÐÐ++R­RRûû©©VV­ eÄi²ggwÍkkÂg  ¶¶[¼¼´^¸  ÜÔÔÔÔ''ÐÐ}}N©©©©©ûû##ÐÐÐÐÐÐNNû ¡¥¥RRññžžšš í íššššCCñ – ÁooooooGGôôüüôô©©NN¥¥RR ø ø ø ø ø ø ø ø   hoÊÙldd ·ñKSr":$ï 2¹¦ñññ – –CCYYYYYYE¾'å*šA9ߥ¥RRûûNN v v vÐ#### â âXXXX T®®®  ®®®®ÚÚÚÚÚÚÚ4’ü ü’Ý‹0§§§MMMú o o Å Å Å Å == æ æ“î æ æ““== Ð Ð~~'''' ü üVV ü ü ü ü==ê æ æ æ æ== æ æ æ@“£²²ò—êê¿¿¿¿hhÛ €ÛÛÛÛ..YY ¬ ¬ U UÅÅÅÅ  vvvvvvv}}++ÐÐ++R­RRûû©©VV­bb emmy Âgw ( (  ÂÂÂ[i¸  ÜÔÔÔÔÐÐ}}N©©©©©ûû##ÐÐÐÐÐЩ©û ¡ J JRRññžžšš í íššššCCñ – ÁooooooGG©^  ©ô©©NN¥¥ ø ø ø ø ø ø ø ø ø ø   hÙ#CÆlddlñK)U5-5-0p![ñññ – –CCYYYYYYaaŸ§§œçß„¥¥ ø øûûNNÐÐ vÐ}}## â âXXXX T®®®  ®®®®ÚÚÚÚÚÚÚ488’8ÝÝ‹å\§§MMMú Å Å o o æ æ æ æ êê======ê Ð Ð Ð Ð Ð Ð~~ ¥ ¥ÿÿRRRRêê == == ê@@îî@@““¿¿¿¿..ˆˆÛÛÛÛ°°°°°°oo Á ÁÅÅÍÍÉÉsÍssÐ+ÐÐ''''ÿÿ­RÿÿZÿVV°°´b¼Äy&Éw!, Õzz Õ$$wc ÄÄiee  ÜÜÔÔÔÔ}}}}RRRR©©ûû}#ÐÐÔÔyy¥¥¥¥¥¥ ø øšôGGCCñ –ššššCCCC Á ÁoooooožørÜÁ±¢Gûûûû©©NNNNNNNNNN · ·ddÂÒá,hººddGü}3%7â7â6ˆ+´¹ôGGšš í í]·îI”9ŒŒ„„NNNN¥¥ ø ø''''}}##<<< â T®®® T T\XX®®®®ÚÚÚÚƒƒ0‹4Ú‡‡008G`« ö ö    M Å Å o o æ æ æ æêê ======ê Ð Ð Ð Ð Ð Ð~~ ¥ ¥ÿÿRRRRêê ==êê—— ê@@““@@““¿¿¿¿..ˆˆÛÛÛÛ°°°°°°ooÅÅssÉÉsssÐ+ÐÐ''''ÿÿ­ÿÿÿZVV°°´¼Ó$$"†"†$ä#Š#Š"/#3#3!,Ñss¾yÄÄiee  ÜÜÜÜÔÔÔÔ}}}}RRRR©©ûû}#ÐÐÔÔÔÔ¥¥¥¥¥¥RRšôGGCCñ –ššššCCCC Á ÁoooooožøbÁü¢GûûûûNNNNNNNNNNNN · ·ddhÂÂÂhhººddGün,a6ˆ6ˆ5-'¤^OGGšš í í]]9”9ß22„„NNNN¥¥ ø ø''''}}##<<< â T® T T T T\²²®®®®ÚÚÚÚƒƒ0‹4Ú,,00Ý8««QQúúMss o o æ æ“ 9====êê====êê++~~~~~~ ¥ÿÿ ¥ ¥ ¥ ¥ ¥======ê =—Dê ==@@îîî“@@..ˆˆ.ˆÛÛ° U°°oossssooÅÅÅÅÐÐ}}ÔÔ''­RZZÿÿ­­°°´´b¼ÄqqÓ.6 ë ~!Ù%;'ð(G)¡(G&ì(($Ž#3zÅssÌÄÄÀe^.‰‰.ÜÜ.ÔÔ.}}+ÐR ø¥¥©NNN##Ð+.Ô''¥¥¥¥¥ J¥¥ššššññžCššššCCCC Á ÁooooooCž¦©ôGGûûNN ¡ ¡NNûûûûûûûûdd · ·ººººhhh ddšôW$ï*Y&JvW¢GGôššš°°°°22ßß2222NNNN¥¥ ø ø''yy#### â â<<®®®®XXXXÚÚÚÚƒƒƒƒ‡, Ò,ƒƒƒƒ££££MMMss o o æ æ“ 9==== ====êŸ:…ØØ~~ # # ¥ÿÿ ¥ ¥ ¥ ¥ ¥======ê â=êD ==@@HHHî@@..ˆˆ.ˆÛÛ° U°° Á ÁoossssooÅÅÅÅÐÐ}}ÔÔ­ZZÿÿ­­°e´´b¼iiq&.ˆ6 ë#3'C*¥-Z,V-±-±,V,­,­('C$ä"/ (syÄÀe¸^‰ã‰.ÜÜ.ÔÔ.Ü'}}+ÐR ø¥¥©NNN##Ð+Ôy''¥¥¥¥¥ J J JššššññžCššššCCCC Á ÁooooooCžñKšš í¢ûû©©ûû©©ûûûûûûûûdd · ·ºººº  h ddšô¢ü Á W¢¢¢¢ôššš°°°° × ×„„2222NNNN¥¥ ø ø Ì Ìyy#### â â â â®®®®XXXXÚÚÚÚƒƒƒƒ‡,,‡ƒƒƒƒ££££MMMG¢õ šG íhh » »hh » » · ·lÆ@2±V©© N N ü ü ü ü ¥ ¥ ¥ ¥ 9““î êê^^©ÔÔ'' z z''CCžžôOG¢sÅÅooooCCCCžžñKGG í íšššš¥¥RR©° ¼b­©©VVZZZ´¸¸eÀqyÓ„ß ”#I&+~.3.3.à.à1•1•0.µ,)K&?$ä"/ º_TùLLwwwÂllØØØØ''''+Ð}}##ÐÐ¥¥¥¥ûV©Nyyyy####ÛÛÛÛÛÛÛÛ × × × × × × ×2YYYY°°..ÛÛÛÛÛÛ}}ØØÔÔÔÔûûNNNNNNÐÐ###### Ì'yyy  Ì Ìoo zÍÍ¢¢¢¢ññžC°°]YY ¬ ¬ € € €ÛÛÛÛÛ<<9999dd ·dddd9999®®®®ÚÚÚÚ Ö Ö Ö Ö™™™™ïïBBqmmmm ö ö££úúú íGõ šG í » »hh » »lÆ@çȱV©©©© ü ü ü ü ¥ ¥ ¥ ¥ 9““ 9 êê^×'³$þÈ©ÔÔ'' z z''CCžžO©ü¢sÅÅooooCCCCCC –ñGG í íšššš¥¥RR©À9# ¼VVZZZ´¸¸ÀqÌyÓß!î$£'X*#,Ø0è34J4J4J4J42Ä0-Z*N&?#Šzº_®TLLllØØØØ''Ð+}}}}ÐÐ¥¥¥¥ûV©Nyyyy####ÛÛÛÛÛÛÛÛ × × × × × × ×2YYYY°°..ÛÛÛÛÛÛ}}¬]>.y ¡ ¡NNNNNNÐÐ###### Ì'yyy  Ì ÌooÅ ÍÍ¢¢¢¢ññžC°°]YY ¬ ¬ € € €ÛÛÛÛÛ 5 5 â â9999dd ·dddd9999 T T®®  ÚÚ Ö Ö Ö Ö™™™™ïïBBqmmmm ö ö££       š š í í š š » » » »hh » »¿¿l!{m¸VV©© ü ü ü ü ü ü ¥ ¥ ¥ ¥== â â â â æ æ“ 9 —— :-*hu VVÔÔ'' z z''ññžSff^O ÅÅÅooooCCCCCCCCGGššGGGG¥¥¥ÿ©u* /!"ò¼VVZZ  ÈqÌy.ç"œ$£'X*#.31•4J5¤5¤6R4÷5y41j.µ*ü&ì%’!‚Éog²¦LLoollØØ…+ÔÔ++ÐÐÐÐÐÐ¥ J J¥ûûû ¡yyyy####ˆˆÛÛÛÛ.ˆ × × × ×2 × × ×YYYY°°°°..ÛÛ....}Øÿ)â(ÞF Ì ¡ ¡NNN ô ¡ ¡Ð v v v####yyyy' ÌyyooÅÅ zü  üKKññ]°°´Y ¬ ¬ € €Û €ÛÛˆ. 5 599 ‹ædddddddd9999 T®®®   Úƒƒƒƒ™™™™BB • • ¼ÄÄmmmm££ ö ö    M š š í í š š » » » »hh » »¿¿llÆVV©© ü ü ü ü ü ü ¥ ¥ ¥ ¥==êê==== æ æî“ ==±uß*f±VVÔÔ'' z z''ññ­Ì(ÿ+´%œnÕÅÅÅoooožžžžžžžžGGôôGGGG¥¥¥ÿ©eßãÓb­°°´´bb  mmqÌÓÓŒ#ö%þ(³,Ø0è2ï5¤6ÿ6ÿ6R7¬6Ô5y2Ä0-±)¡&ì"Ý$Ég²¦LLwwÊÊllØØ…+ÔÔ++ÐÐÐÐÐÐ¥ J J¥ûûû ¡yyyy####..ÛÛÛÛˆ. × × × ×2 × × ×YYYY°° U U..ÛÛ....#}:´ ¿FÜ'ûûNNN ô ¡ ¡ vÐ v v####yyyy' ÌyyooÅÅ z(ÿ(ÿ…µKññ]°°Y ÿ ¬ ¬ € €Û €ÛÛˆ.99 ‹ædddddddd9999 T®®®   Úƒƒƒƒ™™™™BB • •qÄÄmmmm££ ö öúúM ñ ñ š š š š » »hh¿ dhhhhpZÿÿ ¥ ¥ÿÿÿV ü ü ü ü ü ¡ ¡ æ æ““““@@“îHî—===­b¼¼^©V ü~~ Ð Ð''ÔÔžøb)U4×7Œ2Ï!6/ ÅÅššG¢GGôšššGGGGššNN©©R­´i¼b°°¸ee¼¼qm"}×6"E&U*d,0‘3F5û7U7U6¨6¨6}5"3/ .^(ô&?#ŠÍc®[¦ùù!!!ÆÆl……Ø}ÔÔ.ÔÐÐ#}####¥¥ J¥¥¥¥¥ vÐÐÐ}###..ÛÛ ×22 × €Û......°°°°°°....„„22''Ü6‘ÜÔyûûNNNNNN####yy''ÐÐÐÐÐÐÐÐÅÅÅÅÉ$v/Ã5--¢GGYY * *„ * €ÛÛÛ    ` `h  ª ª ª ª Ú,, Ö0ƒƒBBBBBBB i iÄÄmmmmMMMM ö ö£ ñ ñ š š š š » »hh¿ d » »hhpZÿÿ ¥ ¥ÿÿÿV ü ü ü ü ü ü ü æ æ““““@@HX²£—===­­­­©©V ü # # Ð Ð''ÔÔžø%F4×7Œ4)"‘/ ÅÅšš íGGGôšššGGGGšš©©©©­RZZ­­­°°^¸  ¼¼¼m"}×6"E&U*d,0‘3F5û5û5û6¨6¨6}5"1À-±+©(ô&?#ŠÍ¾ TT{{{!Æ!……2Ø...ÔÐÐ#}####¥¥ÿZ¥¥¥¥ vÐÐÐ}###..ÛÛ ×22 × €Û......°°°°°°....„„ × ×'''ÔyûûNNNNNN È È##yy''ÐÐÐÐÐÐÐÐÅÅÅÅÉ$ ":*Y$ïf¢GG ¬ ¬YY„„„ * €ÛÛêê    ººh Dº ª ª Ú,, Ö0ƒƒBBBBB i iÄÄmmmmMMMM ö ö£ ñ ñ š š š šhh¿ d ` `h hhÂh­­ ø ø øRRR ü ü ü ü ü ü©© æ æ@@ æ æ@@HX_P—===RRRR ü ü©©~~~~'''žøÅ#ë)U"‘½(sss kÅ í íšš íGG íššGGššGG©©©©ÿÿÿZÿZÿÿV°°°^¸¸¸¼¼iÀu"׈"ò'¯*d+'/61ë4 5N6¨5û5û5"3È0f,V+©'™$7!‚s¾ ®®®T(((ÎÆÆ22……ÔÔÔÔ}}}}ÐÐÐÐ¥¥ZiZ¥¥¥ vÐÐÐ}}ÐÐ..ÛÛ ×2„„ÛÛ...... U°°°....„„ × ×yy''ÔÔ''ûûNNNNNN v v##yy Ì Ì####ÐÐ#}ÅÅÅÅoÉOÁf©ôôšY ÿYY]°°„„„„ÛÛˆ=ŸDººh `ººº—o_ ª ª®®\ÚÚ,, Ö ÖƒƒïïïïBB ¼ i immmmMMMM£££ ñ ñ š š š šhhhh¿ d » »h hhh RRRR øRRR ü üVV ü ü©© æ æ æ æ æ æ æ æ“î›@—===RRRR ü ü©©ØØØØ'''žøK¦­b­øssssÅ k í íšš íGG íššGGššGGNN©©ÿÿ¥ÿ¥ÿÿÿV°°°^¸¼¼iÀu"×.!˜$ú'¯(r,0‘0‘2™3ó3F3F2m1/ *ü*N&?$7!‚s¾ ®®TùÎÎÎsÆÆØØ++ÔÔÔÔ}}}}ÐÐÐÐ¥¥ÿZÿÿ¥¥ vÐÐÐ}}ÐÐ..ÛÛ ×2„„ÛÛˆˆ.... U°°°.... * * × ×yy''yy''ûûNNNNNN v v##yy Ì Ì####ÐÐ#}ÅÅÅÅoÉôôü¢ôôôš´YYY]°°„„„„ÛÛˆˆêººh `ººº<ñº®®\44,,00ƒƒïïïïBB ¼ i immmmMMMM I I£ Å Åss Å Å““ æ æ æ æ æ æ““ æ æ æ æ æ æ zÔÔ z zÔÔÔÿÿZ´VV ü ü æ æ““==ê » » » »hh » » Ð+~ #''''©^^­RRRÅÅsssÍssññññCCCCÅÅ g ÁoossÅÅssss''yy+++Ð''''+++…‰‰66ç:•Bœ¤ÿ¬»!Ã$x&Á(-…-….30è0:0:.à,+)v)v&j"[!¦õ@å‹,,$Põ››ññDD……}}}}ÐÐyÔ''ÔyyyRRRR¥¥R ø##ÐÐyy''·°°]·´´´YYYÛÛ Ó.„ßßß°° ÿ ÿ ¬ ¬ÐÐÐÐyyyyyyyy Ì Ì Ì Ìyy Ì ÌÐÐ v vNNNN¥¥ ø øÅÅÅÅooooss  22 × ×„„„„YYYYYY9999    · · · ·99ææ²²XXXXXX ª\\®®ÄyyÄBBïï™™ >™ Ë Ë Ë Ë Ë Ë Ë Å Åss  ““ æ æ æ æ æ æ““ æ æ æ æ æ æ zÔÔ z zÔÔÔÿ´Ä V ü ü æ æ““==ê » » » »hh » » Ð+~ #''''©­RRRÅÅsÍssññññCCCCÅÅ ÁooÅÅssss''ÔÔ+++Ð''''+++…..ÜÜ2à:çBJ¤Qa!Ã"±$ (*Ð*#,Ø,+,+,+)v&Á&Á#µ¦Kñššå‹,,$Põ››ññDD……ØØØØ++yÔ''ÔyyyRR ø ø¥¥R ø##ÐÐyy''·!]]°°]li´´YYYÛÛ Ó.„ß99]]°°YYÐÐÐÐyyyyyyyy Ì Ì Ì Ìyy Ì ÌÐÐ v vNNNN J J ø øÅÅÅÅoooossÅÅ2222„„„„YYYYYY ¬ ¬9999    · · · ·99ææXX ª ªXXXXXX ª®®.òò.ïï™™ >™ Ë Ë Ë Ë Ë Ë%ssssss““î““ 9““““ æ æ æ æ 9 9'''ÔÔRb6¸©©© æ æ““ êêhhhh » »hh~~ Ð Ð z zÔÔ©©VVRRÿÿsÍÅÅCCCCCC –ñ k kÅÅooooÅ kÅÅÅÅss''''}}}}ÔÔ'Ð+ØØ..à:à:çBJJ¤ÿa!W"±$ ((É(É(&Á'n&%f"±!¦žCí’‹0ÒÒ$Ê£H››ññDD……2ØØØ++ÔÔyÔ''' Ì¥¥ ø ø¥¥R ø##ÐÐ' ÌyÔ°°°°°°]´´YY ¬ ¬ÛÛ.ˆ2Œ22]]°°YYÐÐÐÐ' Ìyy Ì Ì Ì Ìyy Ì'yy Ì Ì#}ÐÐ ¡ ¡NN ø ø¥¥ooooÅÅÅÅÉÉvŒ2ŒŒß„„„´´YY ¬ææææ  ` ` · · · · ‹ ‹99XX ª ªXXXXXXXX¶Ó,‹+0MyqqJïBB ë ë™™ Ë Ë Ë Ë Ë Ëxssssss“HHîî“““““ æ æ æ æ““'''''ÔÔR­¼¸©©© æ æ““ êêhhhh » »hh~~ Ð Ð z zÔÔ©© ü üRRÿÿsÅÅCCCCCC –ñ k k k kooÉÉ ÅÅÅÅÅ''''}}}2ÔÔ'Ð+}}..…àà:BœJJJ¤¬¢üü$ $¹"$ "±"#_%füñKCé’80ÖÒÒ$ÊH£õõññDD……2ØØØ++ÔÔÔ.''' Ì¥¥ ø ø¥¥R ø##ÐÐ' ÌÔy°°°°°°YY ÿ ÿÛÛ.ˆ ×222°°YYÐÐÐÐ' Ìyy Ì Ì Ì Ìyy' Ìyy Ì Ì#}ÐÐûûNNRR¥¥ssssooooÅÅÅÅÉÉvŒççç9ß„„YYYY ¬ææææ  ºº · · · · ‹ ‹99XX ª ªXXXXXXXX¶ˆ'!4ª3O#ÓqqïJBB ë ë™™ Ë Ë Ë Ë Ë Ëx o ossÍÍ@õXHî““ 9 æ æ 9 9 â= '' z z'Ô z N©­ÿÿ== ====¿¿ d d d¿ Ð Ð~~'''' ¥ ¥RRRRÿÿoo Áoo Á Ášššššššš Á Á Á Á Á ÁoooÉoooo Á Á' ÌyyÐÐØ2''}}}}…+++.‰66çB•ïBB÷¬ñ¦ñ¦ ª ª"±üøø SCíí’88݃($$$ùùùŸHH››2çï•à…2ØÔÔ..''yy¥¥¥¥ûûNN Ì Ì y####YYYY]]°°YY ¬ ¬]]]]„„„„222 ×°°° ]yyyy}# v v Ì Ìyy####ÐÐÐÐÐ vÐÐ¥¥ ø ø¥¥¥¥ÉÉvvssÅÅvvv”Iþ£î922]]YYYY““ææææææ¾dd¾    â â 5 5XXXX®®®®®®®®® …I%p)¤ÐFF™™ • •BBxxxx t tÏ o o  ss 曣H“ 9“ 9 æ æ 9 9 â= ''ÔÔ' zÔ N©©©­Rÿÿ== ====ll¿¿¿¿¿ Ð Ð~~'''' ¥ ¥RRRRÿÿoo Áoo Á Ášššššššš Á ÁoooÉoooo Á Á' ÌyyÐÐ}Ø''}}ØØ…+++Ô.ÜÜç•ïBB÷÷<<ññššGGžžCé8í8Ý݃(ƒ$$$ùùùŸHHõõ¬$x#¤à2ØÔÔÔÔ''ÔÔ¥¥¥¥ûûNN Ì Ì y####YYYY]]  YY ¬ ¬„„„„22 ×2°°° ]yyyy}# v v Ì Ìyy####ÐÐÐÐÐ vÐÐ¥¥ ø ø¥¥ÿÿÉÉssÅÅvÑ++þ"Ò*ñ)– IŒŒ]]]]YYYY““ææææææ¾dd¾hh  <<XXXX®®®®®®®® ®uÐ2Œ*u ë ë > >ïïBBxxxx t t t Å Å Å Å““““ æ æ 9 9 æ æ 9 9===='''''' z z N N© N ¥ ¥ÿÿ â â â==—¿¿l Ð Ð~~ zÔ'' ¥ ¥RRRR­­oooo Á Á Á ÁGGGGG íššoooo Á Áoooooo Á Ì Ì''}}}Ø'ÔÔ}}ØØ++ØØÔ.‰ãçïï••œœááéé’8@@ééáá‹‹0000ƒ(ÒwwwLLŸŸH£õ›ï(ˆ4¶2 i•2ØÔÔ''''''¥¥¥¥ ¡ûûû' Ìyy}}##YYYY]]YY ¬ ¬„„„„22„„°°°°yyyyÐ v##yy Ì Ì####ÐÐÐÐ##ÐÐRRÿÿÿÿÿ¥ÅÅsoovv†ðÿ&á375Å/³çŒ]]°°99ææ““ææddddºº `º<<XXXX T T®®®®mÈuuÈmmm ë ë™™BBBBxxxx""Ï Å Å Å Å““““ æ æ 9 9 æ æ 9 9===='''''' z z©©© N ¥ ¥ ¥ ¥ â â â==— d dl Ð Ð~~ zÔ'' ¥ ¥RRRRRRoooo Á ÁGGGGG íššoooo Á ÁooooÉÉ Á Ì Ì''}}}Ø'ÔÔ}}}}++ØØÔ.‰ãçïï••œœ‡‡44’8åå44‡‡0000ÖÖƒ(wÒwwLLŸŸîH›õï i/L/L i•2ØÔÔ''''''¥¥¥¥ ¡ûûû' Ìyy}}##YYYY]]YY ¬ ¬„„„„22„„°°°°yyyyÐ v##yy Ì Ì####ÐÐÐÐ##ÐÐRRÿÿZZZÿ  soovvð+ˆ2M5Å78z70[ çŒ]]°°99ææ99ææddddºº `º<<XXXX®®®®®®mÈmÈÈÈ ë ë™™BBBBxxxx||Ï Å Å o o   p Ë Ë Ë t t t t t t""""""£ I ö ö        ÏÏ"" t t t t Ý Ý Š Š á ᎎ  _ _ µ µ µ µbb¹¹¹¹ _ _¹¹bbbbbµ [µµµµµµµµµµbŸŸMM òMM ò pËËË%Ë œö££úúMMMMMMIIöö¹¹fÁjjrÅ'ÌÐÐÐЪªX²_ºººÝ݃ƒ,,ÙÙÖ{Ö{Î((ΣHHH››H£Ò<ññ‡wÊoÂhææ99 â< â âææææB ç•• ç ç••ª Pªª ý ýªªTTTTTT ¦ ¦(((( Ò,ÙÖÖÖÖƒƒÝ’ñ–<‡mmÄÄÌ 0í6W4¦-á0–1ñ'ßuëëëë>>>>ËËtt!!! Çt ŠŠ Ü Ü ¥ ¥ ¥ÿRRRR ü ü ü üV ü ü ü=—————Dê » » »¿¿====êê= Å Å o o   p Ë Ë Ë t t t t t t||""""£ I ö ö         t t"" t t t t77 Š Š á ᎎ  ¹¹ µ µ µ µbb¹¹¹¹¹¹¹¹bbbbbµ [µµµµµµµµµµbŸŸ ò ò òMM ò pËËË%Ë œö££úú§§MMMMIIöö¹¹fÁjj½ÅÌrvvvvªªX²_ƒƒ((ÒÒ{ÖÖ0ƒ((ΣHHH››H£ÒÒÒÒwoÊooÂhææ99 â<êê<<ææææB ç•• ç ç••ª PªªWWªªTTTTTT ¦ ¦(((( Ò,ÙÖÖÖÖƒ8Gf$Ô ÅámmÄÄÌ6" 't$h££þ9Ïuëëëë>>>>ËËtt!!! Çt  / / Ü Ü ¥ ¥ ¥ÿRRRR ü ü ü ü üV ü ü=—————Dê »¿¿====êê=   o o o o Ë Ëxx t t t t""|×||Ï t ö ö ö ö         t t t tÏ t"" Š Š Š Š á ᎎ¹¹¹¹ µ µ µ µ µ µ      ¹¹b½½bµµµµµµµbbbµµŸ E ò ò ò ò ò òËËxËËËËI£££M§§MŸúMMII££¹¹fÁ½½½jÅÈÈvPPªªªªª0ÖÎ(ÒÒÒÒÎ(0šå0(ÎPPý£££PP$$ÊÊÊÊÊ$ÊoÂÂh hhææ99<—““““ ç ç ç ç ç ç••ª PªªTTTTªªªªTTTT ¦ ¦TT((((, Ò Ò ÒÖÖÖÖ0@Á/ÿ52]&/K"ÈmÈÄÄqqqÄÄ.ãß***uuÀëëëë>>>>ËË Ç Çtt Ç Çtt Ü Ü Ü ÜRR ¥ ¥RRRR©©©© N N ü ü êêê——êê¿¿====êê=ssÉÉ o o Ë Ëxx t t t t"""|||Ï t ö ö ö ö         t t t tÏ t"" Š Š Š Š á ᎎ¹¹¹¹ µ µ µ µ µ µ µ µ      ¹¹b½½bµµµµµµµbbbµµŸ E ò ò ò ò ò òËË ÃËËËË£IIIM§§MŸúMM££££¹¹fÁ½½½jÅÅÅÈÈvõõPPPªªªÖ{(ÎwwÒÒ(ƒ‹@@‹ÝƒXýXXªª$$ÊÊ$4C4Âhhhææ99 â<““““ ç ç ç ç ç ç•• PªªªTTTTªªªªTTTT ¦ ¦TT((((, Ò Ò ÒÖÖÖÖ‹š):6Ã7Ç7Ç2][}"ÈmÄÄqqqÄÄÄÄuuÀëëëë>>>>ËË Ç Çtt Ç Çtt Ü Ü Ü ÜRR ¥ ¥RRRR©©©© N N ü ü êêê==êê¿¿====êê= Å Å  """" p ËÓxÏ t tÏxx% Ë    MM ö ö ö ö t t Ç"""""77 Ý77 Ý77        µ µ µ µ µ µ bbb µ^^ ff ¹¹¹¹f  ò ò ò òII œö! Ç Ç ÇËË£IööööIIŸŸM§QQ£þbb¹¹ffrÅÅÈÈLLùŸ¦¦ùù$$$$wÒ,,Ù4Ž88å‹¶¶  __²²ƒÝÖ{Î΃!W(Éõ!lººº<<< â â â“99999““>>>>>>>>mÀ eiiii ý ýªª®T ý ý ý ý ýWªªªªªª ý ý ý ý((((,, $ Ò Ò Ò Ò,,,,‡–$'4e86Ã/RyÄÄmmÈÈqqqqqÀmmë ‘>˜Fë>>xtt Ç Ç Ç Çt  Ç Çtt Ü ÜŠ / ¥ ¥ ¥ ¥ üV©©ÿ ¥ øR ¥ ¥RR=———““““hhhÂêê==““ æ Å Å  """" p ËÓx tÏ tÏxx% Ë    MM ö ö ö ö t t Ç"""""77 Ý77 Ý77        µ µ µ µ µ µ bbb µ¹¹ fÁf¹¹¹¹fÁ½ ò ò ò òII œö! Ç Ç ÇËËI£ööööIIŸŸ òMööI£bb¹¹ff½ÅÅÁÁÈÈLLùŸLLŸŸ$$$$wÒÒ‡Ù4Žéí¢Oõ  ssoogg’80ÖÎÎÎ8Oš!lººº<<< â â â“9999999˜˜>>>>>>mÀiiii ý ýªª®T ý ý ý ý ýWªªªªªª ý ý ý ý(((( Ò Ò $ Ò Ò Ò Ò,,,,‡áø"Ì*•):!ÉšÄÄÄmmÈÈqqÄÄqqqÀmmë ‘>˜Fë>>xtt Ç Ç Ç Çt  Ç Çtt Ü ÜŠ / ¥ ¥ ¥ ¥ üV©©ÿ ¥ øRÿÿRR=———““““ÂÂhÂêê——““@w Å Åss"""" Ë Ë  ""ÏÏ Ë Ë Ë ËMM     I I I I t  t t t t tÏää7777ää¹ _      µ µ µ µ µ µ bbbb½jfÁfÁnÁµµµŸŸŸŸIIIIttt  pËËËööööIIööMMŸŸööööbb¹¹¹¹½½nÈùŸLLLLLL$$wwwÒÒá––ñK!W&Á()v)¡(G'™$ä!Ù$õšíÝÖ{!{(ξhhºº â â â â<<æ ‹ææææ““˜˜ëë>>>> eÀmm ý ý P PTTTT ý ý ý ý ý ýWWW ýªªª ý ý(( {Ö Ò,,‡ÙÙáñOOõåÄqqmmuÈmÈÈÄqqÄÄÄÀÀÀ>>˜˜ëëëëËË!!tttt Ç Çtt Ç Ç Ü7ŠŠRRRR ü ü ü üÿÿRRÿÿÿÿêêòL›@““ÂÂÂÂêêêê æ æ@w Å Åss"""" Ë Ë  "" t t Ë Ë Ë ËMM     I I I IÏ t t t t tÏ)ää7777ää¹ _      µ µ µ µ µ µ bbbb½jÅ'Ü}ÈÁ+}ÁfµµµŸŸŸŸIIIIttt  pËËËööööIIööMMŸŸööööbb¹¹½½nDŸññññLLÊÊwwÒ,‡–!!¦#µ)v.à2ï4J5Ð4u2m/¸+R%è!,!, ªOG80Ö!Æs¾hhºº â â<<<<æ ‹ææææ““˜˜ëë>>>> eÀmm ý ý P PTTTT ý ý ý ý ý ýWWW ýªªª ý ý(( {Ö Ò,4 Ò,ÙÙÙÙ‡áåå‹0ÄqqÈÈu"È""ÄqqÄÄÄuÀÀ˜˜˜˜ëëëëËË!!tttt!!tt Ç Ç Ü7ŠŠRRRR ü ü ü üÿÿRRÿÿÿÿêê—òõ›îîÂÂÂÂêêêê æ æ@KKžžžž ö ö ö ö ö ö ö ö   Ë Ë x Ë Ë ö ö œ œ                 I I ö ö Šä777777b  µ µ µ µ µ    µ µ µ µ7’ä?b".'˜$2¡ììF '”+"!¨bbµµËËËËö œ œ œŸŸŸŸ òMMMŸúúúúúMMöööö¹^ f¹¹¹;•;;‘‘??——ññDŸLñHH££Pªw!,!Ù)ø1À5Ð7×7×7U7U7U4 0è*#&$¹"Ý (sc®ùDDDêêê““ææææææ““““ºººº¾dFFëë ç ç•• ¼Ämm ý ýª P Pª ý ýÖÖ((,,W ýªTT ¦ ¦TTTT ýWWWªªªªT®[[®®    [[ÄÄÈÈuu¤¤÷÷  ó˜  FFFëëëmmiiiitÏ!!ËË pË œöööII œ œ33 † † Ð Ð Ð Ð''ÔÔRRÿÿ©©©©hhpŸDò—››îîÂÂhhKKžžžž ö ö ö ö ö ö ö ö   Ë Ëx  Ë Ë ö ö ö ö                ££ ö ö Šä777777b  µ µ µ µ µ    µ µ µ µ7’?™­%3Ç6|5Ê-«eFìF Ï3Â5ö/1/jbbµµËËËËö œ œ œŸŸŸŸ òMMMŸúŸŸŸŸ ò òöööö¹^ f¹¹¹•;àà‘‘??————DŸñ—HHHHõP_Â!,%è+R1À5Ð7×7×7U7U7U7U4÷0è+~$¹ (s¾®TŸDDDêêê““ææææææ““““ººººd FFëë ç ç•• ¼ÄmmÀÀ ý ýª P Pª ý ý { {(( Ò Ò ýWª PTT ¦ ¦TTTT ýWWWªªªªT®[[®®®®  ¶¶""ÏÏÿÿQQ  Mó    FëëëmmÀÀiiiitÏ!!ËËË p œöööII œ œ33 † † Ð Ð Ð Ð''ÔÔRRÿÿ©©©©ÂÂpttŸùLò››îîÂÂhhKK ñ ñ ñK ö ö£ I ö ö ö ö   Ë Ë Ë Ë x ö ö££M òM ò òM    ££ ö ö Š Šää7777 µ µ µ µ µ µbb  _ _bbbbää’ì¼/ 7Ö9184p"×ô‘F(A-)% Ìbµµ pË œ œII EŸMMŸŸMMŸŸŸŸŸŸŸŸöööö  ¹¹¹¹ff;;ààää‘‘————ñL——››îHPPýXº ~!Ù%è-2m6}7×6¨6¨5N2™0:,+&Á"± ¶ TLñDêêê—<ææ999““9ææææhh · ·ëëëë••• : ¼ ¼iimÀÀ ý ý ý ý ý ý ý ý { {Ö {, Ò ý ý ý ý ¦TTTT ý ý Pªªªªª[[®®[[[[ÌÌÌÌÏ*×2YY¬Uû¨¨MMMF똘ÀÀÀÀiittttxx££ööII œ œ † †33 Ð Ð Ð Ð''ÔÔÿ ¥R­ ü ü©%wÆÆÎ)\ Tõ›@@ÂÂhh[¦KKK ñ ö ö£ I ö ö ö ö   Ë Ë Ë Ë x ö ö££M òM ò òM     I I ö ö Š Šää7777 µ µ µ µ µ µbb ± ± _ _bbbbää’ì,U6|7Ö7%3"×ô‘‘ô6bµµ pË œ œII EŸMMŸŸMMŸŸŸŸúúŸŸöööö  ¹¹¹¹ff;;ààää‘‘<<———ñ——@@îHõõ£ýoÉ#Š(ô-12™2™1>+Ô)v%f"±¢[ TLñDêêê< âææ999““9ææææ  ëëëë••• : ¼ ¼iimÀÀ ý ý ý ý ý ý ý ýÖÖÖ {, Ò ý ý ý ý ¦TTTTWW Pªªªªª[[®®[[[[ÌÌ&&*„2Œ´´a» °¨¨MMM F˜˜ÀÀÀÀÄÄttttxxxx££ööII œ œ † †33 Ð Ð Ð Ð''ÔÔÿ ¥R­ ü ü©%4,!!ƒH"Š'ô$’sõ@@ÂÂhh+ Oõõ š    M ò ö ö ö ö Ë Ë Ë Ëxx Ë Ë    MM I I ö öMMMMMM    777’ä Šääbb µ µ µ µ µ µ  _ _    ŽŽèC¥y*ú0d.¯%6Cää‘‘jjbbbµµ pË p p ò ò ò òŸŸúú òMMMM ò òMMMMMúúŸŸbbbbµµbbää77;;ŽŽ<<êê——ññ——DDHHõõý²_ Å"Ý(G(r$b#!­ Sžéé ®¦››îî““9999 ‹ ‹ææææ“9æædd · ·dd ç ç ç çB ç ç çÀÀm e e®Tªª ý ýƒƒ(ƒªª ý ýWWªªTTTTTTWWªª    Ï*Ï*׌ŒAe¿ll··]¨¨¨¤JJJqqmmÀÀ!!ttÏÏ!!ööIIII œ œ †à33 #~~~''ÔÔ ¥ ¥RRRRZZwÒÎ)š)#2q5&4y,ZÑý››phhÁWOõõ š    M ò ö ö ö ö Ë Ë Ë Ëxx Ë Ë    MM££ ö öMMMMMM    777’?äääbb µ µ µ µ µ µ  ¹¹    3 3Žè–K¼bRC芊77bbbµµ pË p p ò òMMúúŸŸM§§§M ò òMMMMMŸŸŸŸbbbbµµbbŠŠ77;;ŽŽ——êê<<————ŸŸ££õõ£X[¶cžC鎎Ž44®TLñ››îî““““99ææææææ9 Þæædd · ·dd ç çBBB ç ç çÀÀmÀÀT®ªª ý ý(((ƒªª ý ý ý ýªª ù ùTT ¦ ¦TT ý ýªª[[[[  ccÏ**„ŒAAötÏ|!!l·]¨¨ÿ¤JJqqmmÀÀ!!tttt!!ööIIII œ œ †à33 #~~~'' z z ¥ ¥RRRRÿÿhÂ)8'É5R7Û7Û8‰5Ô+ õõphhüü¢G š šMMMM ö ö ö ö% Ë Ë Ëxx Ë ËúúMM££ œ öMMMMMM òMäää?’ì’7bbbb µ _ _  _ _ _ _ á ᎎ––ð;ŽŽ Ü ÜŠŠµµbµ [ pË p p p pŸŸMMMMŸŸM\MMŸŸŸŸŸŸŸŸúúbµµµµ7777ŽŽŽèñ—<<<<êê——Ÿ ²Põ££ýýù®TT‡,,,ÙÙ¦LDê@@“““999ææææææææ99ææ ·dd · ·dd••ï••• ç çÀ e eÀªª ý ý(((( Ò Òªª ý ý ý ý ý ý ¦ ¦ ¦ ¦TTTT ýWªª®®[[__² ccÏÏ}2ŒœQ!!1!1"‹!1 „)·]°UQQÿJqqÀÀÀÀ!!! Ç Ç!ttIII£ööII †àà † Ð Ð~~''''RRR­ÿÿÿÿpÖ@-387Û7Û7.7./¼oPõp¢¢¢G š šMMMM ö ö ö ö Ë p Ë Ëxx Ë ËúúMM££ œ öMMMMMM òMäää?ìGì’bbbb µ¹¹  _ _ _ _ á ᎎ;;èè;;ŽŽ Ü ÜŠŠµµbµ [ pËËË p pŸŸMMMMúú\0"@ÆMŸŸŸŸŸŸŸŸŸŸbµµµµµµ7777ŽŽŽè—<<<——êê——T"Ý*¥!,ª›HH££ùùùùÒwww$$LñDê@@“““999ææææææææ99ææ · \dd · ·dd••ï••• ç çÀ e eÀªª ý ý(((( $ $ Ò Òªª ý ý ý ý ý ý ¦ ¦TTTT ýWªª®®[$o ²cc**׌çAQ#»%@'õ'õ&›$“#9)tÇ· °¬¬ÿJÌÌqqÀÀ!!! Ç Ç!ttIII£ööII †àà † Ð Ð~~''''RRR­ÿÿÿÿp!‹'É5R7Û7Û7.7.+­PõÊpppppŒ22222QQ££MM             ö ö ö öbb   µ µ µ µ¹ _¹¹  _¹%%ÓÓ)„×|MMMM ö ö ö ö7777 á á á á Š Š7777ä䟟M ò œ œIItt Ç!xx [µµ [ ± ±^^ààŽŽ;;èè:,Ó/ˆJbµµàà † † Ü ÜŠŠ¹^^^µµµµŽŽ;;ŽŽŽŽRRRRÿZÿÿã]#´çssÎÒwùŸLLŸŸŸŸØØØ}ÔÔÔÔ©N ¡ ¡NNNN ø ø¥¥NNNN Ì Ìyy v v##ÖÖƒ(ªªªªW ýªª••BBB ç : : ‘ ‘>>>>>>TTTTªªªª Ò Òƒ(((T®®®¶/ ™zc   ºº¾ÅzÙ3 C'*À.Ð.".")¼%­"Jàb­Kñšõí’ ²²²ªªªªbbbµµµµŽŽàààà33 ò ò ò òÔÔ z z'' Ð Ð++~~++ÿÿ­­¼6,6@7š7š20 ï ±//‰>:…+Œ22222QQ££MMúú         ö ö ö öbb   µ µ µ µ¹ _¹¹  _¹%%xxÏ)×|MMMMQQ ö ö7777 á á á á Š Š7777ä䟟M ò œ œIItt Ç! à à [µµ [ ± ±^^ààèè;;ŽŽv ¤$´•bµµ † † † † Ü ÜŠŠ¹^^^µµµµŽŽààŽŽŽŽRRRR¥ÿÿÿ''.‰::2s(‡wŸDññDDDDØØØ}ÔÔyy©NûûNNNN ø ø J JNNNN Ì Ìyy v v##ÖÖƒ(ªªªª ýWªª••BBB ç : : ‘ ‘>>>>>>TTTT P Pªª Ò Òƒ(((T®®®¶Å k c  ººs  3 C$R+0*4:3Œ3Œ0,q'´"Jb­¦Kšõí’g ²²ªªbbbµµµµŽŽ;; † †33 ò ò ò òÔÔ z z'' Ð Ð Ð Ð~~++ÿÿ­­­b¼&,Æ+l#MÐf ±‰‰N#" ÃïàŒ22222£££ IMM§§    úú ö ö ö öbb   µ µ b  ¹¹    xxxxÏÏ××§Múú££££ää77 á á á á Š Š Š Š Š Šää ò ò ò òII œ œt  Ç Ç p p p pb^ ^^3Žð¥CŽà;Áv}ȵµŽ333ŠŠŠ / ± ±^^µµb3Žàà;à33¥¥¥¥RRRR…………llÝŽÊoDDDDDD——ØØ}}''yy ¡û©NNNN ô J J J JNNNN Ì ÌyÔ}###,,Ù((((WWWW ý ýªªBB•• ç ç ç ç>>>> ‘ ‘ ‘ ‘ ¦ ¦ ¦ ¦ P Pªª Ò Ò(( { { ¦TT[¶[¶¶¶² ºs zà ð',q3Œ6A6ï6ï41Û-$ÿ½KGíí’º__WWbbµµà;CŽ3 Ù †à ò òMM''ÔÔ z z'' Ð+ Ð Ð~~Ø~RRÿÿZ´bˆ&( " "¸^Ü6°+î(5R3Œ22222£££ I ò òMM    úú ö ö ö öbb   µ µ b  ¹¹    xxxxÏÏ||§Múú££ I I Š Š77 á á á á Š Šääääää ò ò ò òII œ œt  Ç Ç p p p p ­^ ^^3Ž;ðCŽà;ff¹¹µµµµŽ333ŠŠŠ / ± ±^^µµb3Žàà;à33¥¥¥¥RRRR++++lls$ÊoDDDDDD<<}}}}''yy ¡û©NNN©N J J J JNNNN''yÔ}###,,Ù(((( ý ý ý ý ý ý P PBB•• ç ç ç 瘘>> ‘ ‘ ‘ ‘ ¦ ¦ ¦ ¦ªªªª Ò Ò(( { { ¦TT[[¶¶¶² ºs zà ð'/&4ç7œ6ï6ï7E4/Ó'´!r½[[G¢í’º__WWbbbbbbµµà;CŽŽ3 †à ò òMM''ÔÔ z z'' Ð+ Ð Ð~~Ø~RRÿÿÿZ¼ã/{48.Î2^Ü6‘ûRB؈ˆ Û Û Û Û öQ ö ö£ I£ I œ ö ö ö ö ö££    µ µ µ µ        Ë%xxÏÏÏ)UU§MQ ö ö ö á á á á7777; áèè77ää ò ò ò òIIII p p p pµµŠŠŠŠàà33µµ [µààà † Ü7ŠŠµµ    ŠŠŠŠŠŠŠŠûûûû©©ûû''}}}}oÂ@@õ›êê<<ÔÔ''ÐÐÐÐ ¡û©©©©©N ø ø ø ø ø¥ÿ++## Ì Ìyy,,((((ªª ý ý ¦ ¦TTëëë ‘ ‘ ‘ ‘ë˜>ëë>>>>TTTTªªª P(( { {(( { { ý ý ý ý®ccc c gÁvvvŠ?#N/}4ç7œ8I6ï6ï4:/}*##±WKñéé ®WWbbb  ^^3Ž;;7 Ü Ü ÜIIII~Ø~~+ Ð~~ÔÔ z z''ÿÿÿÿV±±f ï3â7D4縱VÜÜ3؈ˆ Û Û Û Û öQ ö ö£ I£ I œ ö ö ö ö ö££    µ µ µ µ        Ë%xx))Ï)  §MQ ö ö ö;; á á7777; ᎎ77ää ò ò ò òIIII p p p p [ [ŠŠŠŠàà33µµ [µ † †à † Ü7ŠŠµµ    ŠŠŠŠŠŠŠŠûûûû©©ûû''''}}}}ºÂh@@›@êê<<ÔÔ''ÐÐÐÐ ¡ûNNNN©N ø ø øR ø ø¥ÿ……## Ì Ìyy,,((((ªª ý ý ¦ ¦TTëëë ‘ ‘ ‘ ‘ë˜>ëë>>>>TTTTªªª P(( { {((ÖÖ ý ý ý ý®®®® c gÁÁÑŠ?#N,È3Œ6A6ï8I5”2ß,È'^!ɹWGñ–ŽŽ¶¶ ®WWbbb  ^^3Žàà7 Ü Ü ÜIIII~ØØØ+ Ð~~ÔÔÔÔÜ'ÿÿÿÿV±±f*'³-Ê+2¸±V3ØØ Û Û Û Û Û Û ö ö£££ I ö ö ö ö I I ö ö££¹ _  bb µ µ    _ _ _ _ Ë ËxxÏÏÏϯ¯úú ö ö££Ž 3 † á7777ŽŽ á;77ää ò ò ò òIIII p p [µŠŠŠŠàà †àb33à † Ü Ü Ü Üµµ^^ ± Ü Ü77ŠŠŠŠ©NûûûûNNyy''++Ðкhhoooî“@æêê<<ÔyyyÐÐÐÐN©NN©NN© ø ø¥¥¥¥¥¥++## Ì Ìyy‡‡,,(( {Ö ý ý ý ý ¦ ¦TT>> ‘ ‘ ‘ ‘>>>>>>>>>>TTTTªª ýWƒ(( Î { {ÖÖªªªª®®[[®c  gÁgÑÑÝì!ô(¸."223Œ4ç3Œ/}*$©OšCé<<c ¶[ªªªµb^^  ŽŽàà Ü ÜŠŠIIII~~++++~~''ÔÔ//'RRRR©^¸È**m^VVÔÔØØ~66 Û Û Û Û ö ö£££ I ö ö ö ö I I ö ö££¹ _  bb    _ _ _ _ Ë Ë  ÏÏÏÏúúúú ö ö££Ž 3 † á7777 3 3 á;77ää ò ò ò òIIIIxx p p [µŠŠŠŠàà †àb33à † Ü Ü Ü Üµµ^^ ± Ü Ü77ŠŠŠŠ©NûûûûNNyy''++Ðкhhº“9æ@êê<<yÔyyÐÐÐÐN©NN©NN© ø ø J J¥¥¥¥ÐÐ## Ì Ìyy,,,,(( {Ö ý ýWW ¦ ¦TT>> ‘ ‘ ‘ ‘>>>>>>>>>>TTTTªª ý 8(( Î { {ÖÖªªªªTT[[     ggvv(7?#N'^+m."/}/}+m&#N¹ªOšCé<<c ¶[ªªªµb^^  ŽŽàà Ü ÜŠŠIIII~~ Ð Ð Ð Ð~~''ÔÔÔÔ'RRRR©©^  ^VVÔÔ~~~ß:ß …22££££    MM I I I I ö ö ö öbb µ µ _¹¹¹ µ µ µ µ    MM ò ò I£ ö ö% Ëxx Ë Ë Ë Ëbb µ    † †ŽŽ á á;;ö œIIIIIIËËtt Ç Ç^^¹^ ± ±^^^^  µµµµŠŠ Ü Ü †à3333à † Ü ÜŠŠµ [ ­µµb^^^^^^^^¥¥¥¥NNNN¥¥RRÿÿ¥ÿ<<êêê<<<<ææ99''''#}ÐÐN©ûûûûûûÐÐ## vÐÐÐRRR øNNNN Ò Ò,,TT ¦ ¦TT ç ç• : ç ç•• ç ç ç ç ç ç ç çTTT ùªª P Ò Ò Ò Ò Î(((TTTTTT®®[[[[¶¶ccŽéCžK[ !r"J'´)¼,q,( "¡!G;+vÁkkk¶¶  WW^^  µµµµ7 ÜŠŠ Ü Ü Ü ÜŸ E ò ò ü ü ü üRRRR Ð Ð~~ÔÔ+ Ð~~++++ØØ………+Ø~ÔÔÔÔÔß::ß22££££    MM I I I I ö ö ö öbb _¹ _ _ µ µ µ µ    MM ò ò I£ ö ö% Ëxx Ë Ë Ë Ëbb µ    á ᎎ á á á áö œIIIIII p ptt!!^^¹^ ± ±^^^^ ± ±µµµµŠŠ Ü Ü †à3333à † Ü ÜŠŠµ [ ­µµb^^^^^^¹¹¥¥¥¥NNNN¥¥RR¥¥¥ÿ<<êêê<<<<ææ99''''#}++©NûûûûûûÐÐ## vÐÐÐRRR­NNNN Ò Ò,,® ù ¦ ¦TT ç ç• : ç ç•• ç ç ç ç ç ç ç çTT®Tªªªª Ò Ò Ò Ò Î(((TTTTTT®®[[[[¶¶ccŽééCK¦­;#¥%­(b&±"¡ìÝ+Ñg¶¶¶  WW^^ ± ±µµµµ7 Ü / / Ü Ü Ü ÜŸ E ò ò ü ü ü üRRRR Ð Ð~~''ÔÔ+ Ð~~++++ØØ++…+Ø~''ÔÔÔÔÔ::çŒ22££££      ú£ I ö ö ö ö ö ö µ µbb      µ µ        òM ö ö ö öx  Ë Ëxx Ë Ëbbbb _ _  ŽŽŽŽ á á 3 3IIII œ œ œ œ Ç Ç Ç Ç ± ±  ± ±^^ ± ± ± ± Ü ÜŠŠàà † †3333 Ü ÜŠŠ [µ^^^^^^  ¥¥¥¥ûV©N ø øRR¥¥¥ÿ<<<<<<< âææ99''''#}+…VV©©©©ûûÐÐÐÐÐÐ}}RRÿÿNNNNTT ¦ ùTTT ç ç ç ç :••• ç ç• : çB••®®W ýª, Ò Ò Ò { { Î( ¦ ¦ ¦ ¦TT®®[    ¶¶á<ééñKøS3Žè! ™äÝ(Ñvo¶cc¶[[[W²ª^^^^µµµµŠ / ‚ Ü Ü Ü Ü ÜŸ E ò ò ü ü ü ü ¥ ¥ ¥ ¥ Ð Ð~~ÔÔÔÔ Ð+~~++++++++~~ Ð Ð'''''''::çŒ22££££      ú£ I ö ö ö ö ö ö µ µ      bb µ µ        òM ö ö ö öx  Ë Ëxx%%bbbb _ _ffŽŽŽŽ á á 3 3IIII œ œ œ œ Ç Ç Ç Ç ± ± ± ± ± ±^^ ± ± ± ± Ü ÜŠŠàà † †3333 Ü ÜŠŠµ^^^^^^  ¥¥¥¥ ¡û©N ø ø ø ø¥¥ J¥<< â â<<< âææ99''''#}+…°°¸©©VV++ÐÐÐÐ}}RR¥¥NNNNTT¶ ùTTT ç ç ç ç :••• ç ç• : çB••  ²Wª‡, Ò ÒÖÖ( Î ¦ ¦ ¦ ¦TT®®[    ¶¶‡áééñKžø~ÙÙÙ//‚ÍÁº¶  ¶[[[W²_º^^^^µµµµŠ / ‚ Ü Ü Ü Ü ÜŸ E ò ò ü ü ü ü ¥ ¥ ¥ ¥ Ð Ð~~ÔÔÔÔ Ð+~~++++++++~~ Ð Ð'''''''”ïAç:ߣ£ ö öMM  úQ ö££££ ö ö µ µ µ µ µ µbbf ± _ _  bbMM ò ò ö ö ö ö""""""||¹¹¹¹¹¹¹ŽŽ á á Š Š Ý Ý œ œ œ œI î œ œb^^^^ ± ±^^ [ [ààŽŽŠŠ Ü Ü † †3ŽŠŠ Ü Ü^^^^^^ ± ±^^¹^ûVûûN©ûûûûNN¥¥ ø øææ“9 â â@æææææ9“ÔyyyÐ+ØØ¼b°V©''''yy''NN©NNNNN $ Ò Ò Ò Ò ¦ ¦TTTT>>>>>> ‘ ‘ ‘ ‘ ‘ ‘ ç ç••ª$s ®T,,,,ª P ý ý ¦ ¦T®[ ®[[ÝÝåõü¢íGsÍÍÍ$~voº   ²²²[[ªg²  ^^µµµ [33 † † † †33 œ œII ü ü N NRR ¥ ¥ Ð Ð~~~~~~ÔÔ''++Ø~~~++~~ Ð Ð'''' z z'Y³ö”:££ ö öMM  úQ ö££££ ö ö µ µ µ µbb  ¹¹    MM ò ò ö ö ö ö""""""||¹¹¹¹¹¹¹ŽŽ á á Š Š77 œ œ œ œI î œ œb ­b^^^^ ± ±^^µµààŽŽŠŠ Ü Ü † †3ŽŠŠ Ü Ü^^^^^^  ^^¹^ûVûûN©ûûûûNN¥¥ ø øææ“9 â â ‹æææææ9“ÔyÔÔÐ+22Äq °©N''''yy''NNN ôNNNN $ Ò Ò Ò Ò ¦¶TTTT>>>>>> ‘ ‘ ‘ ‘ ‘ ‘ ç ç••ª~(b#ü¾®T,,,,ª P ý ý ¦ ¦T®[c [[ÝÝåõWüGí¾oÉÁºº²²²W²²[[ªWW  ^^µµµ [33 † † † †33 œ œII ü ü N NRR ¥ ¥ Ð Ð~~~~~~ÔÔ''++Ø~~~++~~ Ð Ð'''' z z'%â)ñ%âÃQAQQþ£MMMMQQ ö ö ö öQ ö   µ µbbbb  ¹¹bb  M ò ò ò ö ö ö ö""""""Ï)f ¹¹f 3Ž;;7777 œ œ œ œIIIIË pË˵µµµ ± ± ± ± ± ± ^bµµŽ3àà Ü ÜŠŠ3333ŠŠ /Š ±^^^^^^^^^¹NNN©ûûûû©NNN ø ø¥¥9999 â â9999“9““''''ÐÐ……´i^©©''''yy Ì Ì ¡ûNNN ô ¡ ¡ Ò, Ò ÒT ù[® ¶[ë ‘>> ‘ ‘>>>> ‘ë ç ç••_Ñ•‚c,,,, Ò,,,ª P ý ýTTTTTT[ ®[[‹‹åå’íí’¾¾gÁo__²²®®TTWWWW¹^^^µµ33 † † † † † † œ œII ü ü ü üRR ¥ ¥ Ð Ð++ØØ++ÔÔ'' Ð+…+ Ð Ð++ Ð Ð~~''''ÔÔ'6 7z6 0¶!%ö««þ£MMMMQQ ö ö ö öQ öbb µ µbbbb  _ _bbbbM òMM ö ö ö ö""""""Ï)ÉÉÁf¹¹f 3Ž á á7777 œ œ œ œIIIIË p p p [ [µµ ± ± ± ± ± ±¹^bµµŽ3 † † Ü ÜŠŠ3333ŠŠ /Š ±^^^^^^^^^¹NNN©ûûûû©NNN ø ø¥¥9999 â â99999“99''''ÐÐÐ…ZZbb¸^''''yy Ì Ì ¡ûNNN ô ¡ ¡ Ò, Ò Ò®T ¦¾c¶ë ‘>> ‘ ‘>>>> ‘ë ç ç••ª² c® Ò Ò Ò Ò w Ò,,ª P ý ýTTTTTT ¦T®[[0åšš’88ݶ¶ccgÁº__²²®®TTWWWW¹^^^µµ33 † † † †àà œ œIIVV ü üRR ¥ ¥ Ð Ð Ð Ð~~++ÔÔ'' Ð++…++++ Ð Ð~~''''ÔÔ'887»6`+Œ™³X«QMMMMÏÏ"" Ë Ëxx77 Š Š7777 µ µbb  ¹ _ ¼mm…x-¤Bïï™ > ë ë •ïBB3333àà3333à † Ü Ü Ü Ü Ù Ù † † Ü ÜŠ / ^^^ŸŸ E E ò ò ò òËË33 †àà †33^^^^µµµµCCCCCžKKøžññG í í í í í í í – – –ñššG íšššš99““““““llsÎs“99“æ ‹99 â â â â9999>>>> ‘ëëë ÄÄÄ ‘ ‘>>>>>>xxxxxËËË p Ç ÇttII œ œŸŸ E EtttÏfB÷ÐÁÁ™?ììììììúúöööö£IööMMMMööööööIIIIII E E ò ò Ü Ü Ü Ül » » »hhÔÔÔÔ zÔÔÔ©©VV ü ü ü ü Å ÅsÍss 887»9/œ©³X«QMMMMÏÏ|| Ë Ëxx77 Š Š7777 µ µbb  ¹ _qmmФ/k2 %ò´÷ïï™ > ë ë •ïBB3333àà3333à † Ü Ü Ü Ü33 † † Ü ÜŠ / ^^^ŸŸ E E ò ò ò ò p p33 †àà †33^^^^µµµµCCCCCžKSøññG í í í í í í í – – –ñššG íšššš999999““¾¾¾¾“99“@æ99 â â â â9999>>>> ‘ëëëi&qÄÄmm ‘ ‘>>>>>>xËËË p Ç ÇttII œ œ E E E EtttÏf22vÁff™?‘‘‘‘‘‘§§úúöööö£IööMMMMööööööIIIIII E E ò ò Ü Ü Ü Ül » » »hhÔÔÔÔ zÔÔÔ©© ü ü ü ü ü ü Å ÅsÍsss887»5(×ô`«þþúúM§ÏÏ||Óxxxää77 Š Š Š Š [ µ µ µ  _¹ÄÄ i immФ.¾1s'L´÷ïï™ > ë ëBBB3333Ž333 †àà † Ü Ü Ü Üà †33 Ü Ü Ü Ü   ^µµµµ ò ò ò ò ò ò ò òxxà †333333^^ ± ±µµµµCCCCññøÌøžôš íG í í í íñ – – – í í í íššššææ999 Þ9“¾¾ææææææ99 â â â â9999>>ë ‘ ‘ëëë ¼iÓÄÄiiÀÀÀÀÀÀ ‘ ‘>>ëë˜> p pË p Ç Çttööö œ E E E E p pËËttÏÏfÁnn¹¹‘ìää‘‘‘‘úŸMMII œöööööMMMMööööII££IIII E E EŸ Ü Ü /Šl hhhÂÂÔÔÔÔÔÔ''V ü©©©©©©ssss Å Å /ó2¨2Q,ç^äQ££úúM§))||Óxxxää77 Š Š Š Š [ µ µ µ  _¹ÄÄ i immu*q&ÃÿBïï™ > ë ë èBBB3333Ž333 †àà † Ü Ü Ü Üà †33 Ü Ü Ü Ü   ^µµµµ ò ò ò ò ò ò ò òxxà †333333^^  µµµµžžžžññ­!6)U'SøôšG í í í í íñ – – – í í í íššššææ99“99“ddææææææ99 â â â â9999˜˜Fë ‘ëëë ¼ÄyiiiiÀÀÀÀÀÀ ‘ ‘>>ëë˜>ËËË p Ç Çttööö œŸŸ E E p pËËtttt f¹¹¹¹7‘ää‘‘‘‘úŸMM î î A œööööMMMMööööIIIIIIII E EŸ E Ü Ü /ŠlhÂÂÂpp////ÔÔ''V ü©©©©©©ssss Å Å Å!¼$qèÙþ£££££Q«ˆâ5Ú|"ÏÏ7’ää7 Ý Š Š _ _ ± ±bbb½ À Àmm À ÀmmmmmmuÐûU¨óïïBBBB è è >™ ë ë333333 † †33Ž33333 Ü Ü Ü Ü † † Ù3^^ ± ±µµ EŸ ò òŸ E ò òËËËË Ç ÇtÏ Ü ÜŠŠ77ŠŠµµµµGGššññ}©O¢ í í ’ – –CCCCññññCCššGGææææ< â<<ddææææ““999999FFëë>>>> ¼ ¼iiiiÀÀÀÀ ç ç ç ç çB•• Ç Çtt Ç Ç Ç Çx òMŸŸII œ œËËttttµµbbµ77ää;;ŽŽMMŸ ê ˜ ò E Eöö££MMMMúŸŸŸ òMM ò œöII ò òŸŸ3333hhhhhh¿¿l!)““Þ:…++~~ Ð Ðÿ ¥ øRRRÿÿwwÉ o Å sÙŽè3Ù~þ£££££Q«=!kcê×|ÏÏ7’ää7 Ý Š Š _ _  bbb½u À À Àmm À Àmmmmmmu FóóïïBBBBBB >™ ë ë333333 † †333 Ù3333 Ü Ü Ü Üàà Ù3^^  [ [Ÿ E ò ò EŸ ò òËËËË!!tÏ Ü ÜŠŠ77ŠŠµµµµGGššññK¹W¢ í ’ – –CCCCññññCCššGGææææ< â â âddææææ99999999ëëëë>>>> ¼ ¼ÄyiiiiÀÀÀÀ ç çBB çB•• Ç Çtt!! Ç Çx òMŸŸII œ œËËttttµµbbµµµ77ääààŽŽMMŸ ê ˜ òŸŸööIIMMM úŸŸ òMM ò œöII ò òŸŸ3333hh » »hhhh¿¿Æ{ý,†0•(vÿà++~~++ÿ ¥R­­­ÿÿwwÉ o Å s~Ù†,ÑÑþ£££QQþX=T))×|ä?ää Š Š Š Š  ¹ _bbmmmmmÈ À À À À À À ÀmmóóFFBBïïïïBB ë ë ë ë3333 † † †à33à † Ù3 † † Ü Ü Ü Ü33 Ù3^^f  ò ò E E E E òMËË pË!!tt Ü ÜŠŠä䊊 í íššññžø©%œ&÷n©¢¢øžññC éCC – –CCš ?šš“9“9ddææææ99ææ< â9999ëëëëëë>> ¼ ¼&iiiiÀÀÀÀBB••••B çtt Ç ÇË p! Ç Ç Ç p p ò ò ò òIIöö p p Ç Ç Ç Çbbµµµµbb7 Ü77ààààŸŸ ò ò ò òŸŸööööMM§· ú ò òŸŸŸŸIIII òM ò ò3333 » » hhhhllÞ,†7Z85R#x•…+ Ð+~~ÿ ¥RRRRRRsss$~,ÑÑÑþ£££QQþX-ˆÚ€)ÞAæ™?ää Š Š Š Š  _¹bbmmmmmÈ À À À À À À Àmm™™ ë ëBBïïïïBB ë ë ë ë3333 † † †à33à † Ù3 † † Ü Ü Ü Ü33 Ù3^^f  ò òŸŸ E E òM p p pË!!tt Ü ÜŠŠŠŠŠŠ í íššññ­S©È,a0p 2ü±­žññC éCC – –CC ?ššš“99“ddææææ99ææ< â9999ëë ‘ ‘ ‘ ‘>> ¼ ¼ ¼iiiiÀÀÀÀBB••••B çtt Ç Ç pË Ç! Ç Ç p p ò ò ò òIIöö p p Ç Ç Ç Ç [ [µµ7 Ü77ààààŸŸ ò ò ò òŸŸööööMMM§Tú ò òŸŸŸŸIIII òM ò ò3333 » »hhhhhhllÞ++5ÿ85R&-•…+ Ð+~~ÿ ¥RRRRRRsss¢üSSUúM§¿ˆ-ÓÓ×P%Ñ g#¹¹  _¹ 3 3 3Ž7777ÄÄ ë ë > > ë ë ë ëBBBB ë ë ëFmmmmmmmm † †3 Ù Ü Ü77 ± ±^^ ± ± ^^^¹¹^^ ± ±tttt Ç Ç t Ç ÇttË pËË ± ± ± ±Š / Ü Ü / / Ü Üo$èÙÑàR­ä  Õ¢GššššššÅÅÅÅsººhhhhºº<<ææ““hhºººººº<< â â â âBB ç ç>>>> ç ç çQ•••• ¼ ¼iiii•••• ç ç••ŸŸ E EIIIIx p p Ç ÇttxËË ò ò ò ò òM ò ò Ü Ü Ü ÜŠŠŠŠàààààà33 Ç Ç Ç ÇËËËËŸŸŸúþ£ööööII òMú¯§MŸŸööII ± ±^^hh » »h h““îý~+­0j)¥2¸V ü©©V ü''''~~~~ ñ ñ ñ ñ ñ ñ ñ¢ü®Í"ì 7dUM§§\Þ$¢ò-ÓÓ×P',$wع¹  _¹ 3 3Ž 37777ÄÄ ë ë > > ë ë ë ëBBBB ë ë ‘ ëmmmmmmmm † †3 Ù Ü Ü Ü Ü ± ±^^ ± ±^¹^^^^^^ ± ±tttt Ç Ç t Ç ÇttË pËË ± ± ± ±Š / Ü Ü / / Ü Üo$~$vÑ~Ùz   ¢GššššššÅÅÅÅsºº  hhºº<<ææ““hhºººººº<< â â<<BB ç ç>>>>BB çQï :•• ¼ ¼iiii•••• ç ç••ŸŸŸŸIIII à p p Ç ÇttxËË ò ò ò ò òM ò ò Ü Ü Ü ÜŠŠŠŠàààààà33!! Ç ÇËËËËŸŸŸúþ£ööööIIM§ s·§ŸŸööII ± ±^^hh » »h h““îHP_g V ü©©V ü''''~~~~ ñ ñ ñ ñ ñ ñK¢ü'¨3*+ Uúúú¯ÆÖ€ÓÓ׌›AÉ    _ _ 3 3 á á7777Ì i i ë ë ë ë™™™™ï •BB™ > ë ëmmmmmmmm3333ŠŠ Ü Ü^^^¹ ±^^µµ [µ [µ^^  ^^ ± ±!!tttttt Ç ÇttË%^^^^ Ü7ŠŠ Ü Ü Ü ÜsÅÅÉÉÉÉÉÉ   ÅššššššššÅźºh ººhh<<< â““ææºººººº<<êê<<<<••••>>>>••B÷÷ ç ç çii ¼ ¼iiÄi•••• :•••ŸŸ ò ò£I œ œ p p Ç ÇttŸ E ò òŸ E òM Ü Ü Ü Ü Ü Ü Ü Ü33 †ààà33tÏttxËËŸŸŸúööööööIIM§\§MŸŸ£III^^ ± ±hh » »h » »““îîîHõõ±V©©VV©©''''~~Ø~ ñ ñ ñ ñ ñ ñžG¢[Ô(V"ìUúúúú§€%xx|||×n¹    ¹¹ŽŽ;;7777qq i i ë ë ‘ ‘™™™™ï •BB™ > ë ëmmmmmmmm3333ŠŠ Ü Ü^^^¹ ±   [ [ [µµ [^^  ^^ ± ± Ç Çtttttt Ç Çtt pË^^^^ Ü7ŠŠ77 Ü ÜsÅÅoooooo Á ÁÅÅ ÅššššššššÅźºh ººhh<<< â““ææ——DD——<<••••>>>>•• ç çQB ç çii ¼ ¼iiy•••• :•••ŸŸ ò ò£I œ œ p p Ç ÇttŸ E ò òŸ E òM Ü Ü Ü Ü Ü Ü Ü Ü33 †ààà33tÏttxËËŸŸŸúööööööIIM§§§MŸŸ£III^^ ± ±hh » »h » »îî““î“››V ü©© ü ü©©''''~~~ # ñ ñ ñ ñ ñ ñžõõSr½³þQQ££ öQ%%xxÏÏ||½b µ µ µ µbbŽŽ á á 3 3 á ámm À Àmm À À ë ë ë ëBB •ï ë ë ë ëBB • • iÄàà333333 ± ±¹¹^^ ± ± ± ^µµµµ^^^^ Ç Çtt Ç Ç Ç Ç^^^^ ± ±  33337 Ü Ü Üs k koo Á Á íGG íCCCCoo Á Áooººººhhºº<<<<““@@llH£XýŸDêêëëëë>>ë ‘ëë>>Qœ•• ¼iiiÄÛœB ç ç ç ç••ŸŸ ò òŸŸŸŸ p p Ç Çttx œ œIIIIöö † †33 Ü Ü Ü Ü † †àà Ü ÜŠŠtt!!ËËxxŸúŸŸIIöööööö££££úŸŸŸIIIIµµêê====——RRÿÿ N N©©~~~~'' z z ñKžž ñ ñ ñõõùùùùþþQQ££Q« Ë ËxxÏÏ"" b µ µ µ µbbŽŽ á ᎎ á á   À Àmm ë ëFFBB •ï ë ë ë ë è è • • iÄàà333333 ± ±^^^^ ± ± ±^¹µµµµ^^^^!!tt Ç Ç Ç Ç^^^^ ± ±  3333 Ü7 Ü Üs k koo Á Á íGG íCCCCooooººººhhºº<<<<““››l!²Â&–"† Dêêëëëë˜˜ë ‘ë똘÷B•• ¼iiÄiÌ&œBBB ç ç••ŸŸ ò òŸŸŸŸxx p p Ç ÇÏÏx œ œIIII œ œ † †33 Ü Ü Ü Üàà † † Ü ÜŠŠtt!!ËËxxŸúŸŸIIööööööIIII EŸŸŸIIIIµµllêê======­­ÿÿ©©©©~~~~''ÔÔK ñžž ñ ñ ñõõùžKKQ öQQ££þþxxxxÏÏ t tbbbb µ µbb á á á á á á á ámmmmmmmm ëF™™BBBB ë ë ë ë • : • • i i i iÄÄàà3333à †^  ^   ± ±bµµ ± ±^^bb^^^^tttt p p Ç Ç Ç Ç^^^^ ± ±  àà33ŠŠ / / kÅ k koo Á ÁGGššCCñ – Á Á Á Áooººººººhhêêêê@@@›ÂooÆ!ÆÆXÑ%;#ácŸ—<ëëëë>>ëëëëëëÿ•••iiiiiiBBï• : :••MMMMŸŸŸŸËË pËtt!!Ë p p p œ œ œöIIö œ † †33ŠŠŠŠ3333 /ŠŠŠ!!!!xxÒxŸúŸŸIIööööIIIIIIŸŸŸŸö œIIµµ · d dl d d == ==­­ÿÿV üVV+ Ð~~''''žžžžžž ñõõž D ñ ñQ ö ö ö££££xxxxÏÏ t tbb   µ µbb;; á á á á á ámmmmmmmm ëF > >BBBB ë ë ë ëï • • • i iqqÄÄ i iàà3333à †^  ^   ± ±bµµ  ^^b½½b^^^^ttttËË Ç Ç Ç Ç^^^^ ± ±  ;;33ŠŠŠŠ k  k koo Á Á í íššCCñ – Á Á Á Áooººººººhhêêêê@@›õÂooÆ!!!£²Â²ùŸ—<ëëëë>>ëëëëëëÿ•••iiiiiiBBï•••••MM§§úúúúËËxxË ptt Ç ÇË p p p œ œ œöIIö œ † †33ŠŠŠŠ3333 /ŠŠŠ Ç Ç!!Ò‡ÒxŸúŸŸIIöö œ œIIIIIIŸŸŸŸö œIIµµ · d d · d d == ==RRÿÿV üVV+ Ð~~''''žžžžžžKÉÉssss"""""""" x Ë ËÏÏ"" á á † † á á á á77 Š Š á á á á®®\®®XXXX èBN™™ > À À33 † † Ü Ü Ü Üà †33 Ü Ü Ü Ü!!ttx|æ“)xËËIIII òMŸŸ Ç Çtttttt ò ò ò ò ò òMMÏÏ!!ËËx2 ׄ„ €ÛÛ € U U°°°°°°oooo Á ÁooooooÐÐ#}ÐÐ}}.‰Ü…à222222Ü܉‰°°^VûW ýªªTTcTTTªªªªªª ý ýTT[%€€€Ï)))QöööúŸ ò ò ò ò ò ò ò ò ò ò p pË p [ [ [µb^^^^bäŠää?™ì7^^^^  ^^à †àà3333^^  ^^ ± Ç Ç Ç Ç d d d d == hh » » d¿l » » » »ˆãˆˆˆˆ Û o ossss"""""""" x Ë ËÏÏ"" á á á á á á á á77 Š Š á á á á T T\®®XXXXB÷¬¨ó™ > À À À ÀÄÄ33 † † Ü Ü Ü Üà †33 Ü Ü77!!ttx|›ýÞxËËIIII òMŸŸ!!tttttt ò ò ò òMM ò òtt!!ËËx2 ׄ„ €ÛÛ € U U°°°°°°oooooooooo v v#}ÐÐ}}.‰6Ü…à‘܉‰°°^¸°VW ýªª ù®cTTTªªªªªª ý ýTT[Ú555„)))QöööúŸ ò ò ò ò ò ò ò ò ò ò p pË p [ [ [µb^^^^bäŠŠŠŠä77^^^^  ^^à †àà3333^^  ^^ ± Ç Ç Ç Ç¿¿ d d == hh » » d¿l » » » » » »ãˆˆˆˆˆ Ûss Å"" tÏ"""" Ë Ë Ë Ë"")Ï á ᎎ á á á á Š Š77 á á á á®® T®®®XX ª÷÷÷¬¨ó ë ëmm À À3333 Ü Ü Ü Ü3333 Ü Ü Ü7ÏtttËË)„1Ö%ËxxööIIŸŸM ò!!tttttt ò ò ò òŸúŸŸ Ç Ç Ç Ç„„ × ×.... U°oooooooooo##}}}}}Ø..‰‰::çççë666^©^  ªª®® ¦TT¶ TTTªªªª Pª ý ýTT® —¶![õ‹||Qö œ œŸŸŸŸ ò ò ò ò ò ò ò ò p p pË [µµµµµ ± ± ± ±ŠŠŠŠŠŠ77  ± ± ± ± ± àà333333  ^^^^^^tttt¿¿ d d¿¿¿¿====== hh d d d¿ » » » » » »hhˆˆ66 Û Û Ûss Å"" tÏ"""" Ë Ë Ë Ë""„) á ᎎ á á á á Š Š77 á á á á®® T®®®XX ª÷÷óó ë ëmm À À Ù Ù33 Ü Ü Ü Ü3333 Ü Ü Ü7ÏtttËËtÏ!|%Ëxxöö££ŸŸM ò Ç Çtttttt ò ò ò ò EŸŸŸ Ç Ç Ç Ç * * × ×.... U°ooÉÉoooooo}}}}}}}Ø..‰‰çç••œ÷œœF‘‘‘^©^°°ºº__®® ¦TT¶TTTTªªªªª ý ýTT®¾!.™2©2©+Ž‹ÖQö œ œŸŸŸŸ ò ò ò ò ò ò ò ò p p pË [µµµµµ ± ± ± ±bbŠŠŠŠŠŠ77  ± ± ± ± ± àà333333  ^^^^^^tttt d d d d d d d d====== hhhh d d d¿ » » » » » »hhˆˆ Û Û Ûss Å Å"""""" t t"""" tÏ||Ž 3ŽŽ á á 3 3 á á á á á á † á ý ý ýXXXXX ª ªXXXXóó™™BBBBÄÄÄÄÄÄ † † †à3333 Ü Ü Ü Ü † †33ËË Ç!!!tÏttËËŸŸŸŸö œ œ œ Ãtt Ç Ç ò ò ò ò ò ò ò ò Ç Ç Ç Ç *„„„.... U U ¬ ¬ ¬ ¬ Á Á Á ÁÅ s Á ÁooÅÅÅÅyÔyÔ..…àà:˜˜óMY´¬¬Mó>>b­­ÿÿ²²² ² ýT®¶ªª ý ý ý ýªªW ý ýW ý ýª_gà/G7f884±$sê€TúŸŸŸŸ E EIIII òM ò òtÏ Ç!^^^^µ [ [µµµ3333 Ü ÜŠŠ^^ ± ± ± ± ± ±3333ŠŠŠ /µµµµ Ç!tt · d d== 5 ““ æ æhhhhhhhhhhhh2222ˆˆˆss Å Å""""""ÏÏ"""" tÏ||Ž 3ŽŽ á ᎎ á á á á á á á;XXX ý ª ªXXXX ª ªXXXX™™™™BBBBÄÄÄÄÄÄ † † †à3333 Ü Ü Ü Ü † †33ËË Ç!!!ÏtttËËŸŸŸŸö œ œ œxtt Ç Ç ò ò ò ò ò ò ò ò Ç Ç Ç Ç *„„„....°° ¬ ¬ ¬ ¬ Á Á Á Á kÅsooÅÅÅÅyÔyÔ..à:•ï˜M !Ã%Ó#Ë!·]MMqbb­ÿÿªªWWW²²² ®ªª ý ý ý ýªª ýW ýWWWª_Á;3V8À887f/GT5¯TúúŸŸŸŸIIII òM ò òÏt Ç!^^^^µ [ [µbbµµ3333 Ü ÜŠŠ^^  ± ± ± ±3333ŠŠŠ /µµµµ!|ÏÏl d d== ê““ æ æÂÂhhhhhhhhhh2222ˆˆˆskycat-3.1.2-starlink-1b/rtd/images/ngc1275.gzfits000066400000000000000000002473041215713201500215230ustar00rootroot00000000000000‹Z4ngc1275.fitsì™}påÇ™ “¹´Ò¾Hò[ì8›ÇÁò¾ï*ÀpЬ:Îù Ëiì+CP¤µ­ KF’“8-Cia —´…ô W&@§0C™Ð2LIÉqÜM C`hZ8†2”&Gï÷{ž]ieË/qÔÿ²¿8’v¥ï>/Ÿç÷òl¬§o°7*— Ža¡ók=Ã1aŠ'­\¥oÌ9¶ô öŒTÖ“t¡³?Ü’*ä…)ЛJí³Ò‹èõ‡GzbÂ<퓉^25ieò©l&¿„ö=©¢ž¢)Bg¯•/L#B|_jÉzò¢z£KÕë GñõR¡M6;E½3¤•.¶ ]ñ‚%dÇ2/c©´%$rV¼½¯¬70ÔÓÝÓOô"áØ¡£Cˆ Ç=ŽÞ@.5žÊS“ñqk¡ö ö÷†·D{A/*é’Yvõvå­Üžx!››¦ÒØØt|׳<Ø îéÂö‰ÆŽXùEÐëŽÅb ‚o-~ E»{hG¢RhNûˆÞ5ŽÖŸ\°¯xà|t l‰á|ˆ’Ü©ezÛ‡…¤=%N×ç <àûäÀþj›}³(E±L¯<£^v)zÑÁÈV¢'HÁf„tÃ0U1´è&ø‹Ne¨F'cÑæw(¼užõzt*V¦ x(¼4½¾yôBBçâ-ª #zJP6LQ–Dz@¥eéuE#±~˜Ms.¶Íêo—•Xš^WÅþªòrÛ×WQOQ–Ý_:~’¡*Š|Vã½|{OÿÀêÉAÑ}Pþ¶M§Sñ ¬¸1+ge–0–ÃUg]3Êd÷UЈmŠ‚žÔféAû¢û¦²ùéœEWÉd*3]°ò«[Âý]ƒáX¬"¦í¶Ä3É©x>/$²ÉEÖŒ_÷P¸+ZQOrxÏÅ*éÅ"á^ÔÓƒ†<§¿T/–ˆƒ§çy Cçä䑲„½@íº ñ«­¹Ž0ÒéFÅx.ë&ä#0§¹ &/í$ÝÈo\`2½Šñ\5CÀóhQoiÄððè Ìo[Oÿp´;:t¡\¼ã7<3E†âz|)zKO_w1¾íĨ¹Sá_p°§¯­“5Œ$°ÇÓB>_ ~ ^ÿöÊþE…Ξ$¸¾ÔX å„54éŠlŒvUÔûè‘#gMÅS9+)ŒesBb";5•ÊŒ ÖØ˜•(”¯æ®ØÖhxèŒôò®ææ×‹ôwA‡—Ðß$@he’ñL¡?ɸ“¤À%ÚûGâÿ4ÙTU­lýŽØYn>µÝU"·Hš:ºˆÞèê Hø zâÿ,’ü:L“ŒHF,•Àój‚ž¼ÞBm™GO±õ¤ a¨`’¦iTO[–žZåöiUÖÓm½ªô7Ü×…îO°ã‡*†L ©,~ä³éi2ÅûÀ}-8ɨ' v~¥ë¢¦K:f•¦íXN~€z Ñ낊¡Èº¡Jšª™Ø¾eäC¨§R=9(K†RLMEÛ·ÌñÓ=Q’U5ÉÐ¥³ÐÓ=IM]5BšÒÎBϪÇꙂ͟)ËŠbš¨É¤¿úòôBD¯#4$CÑtC4t…è™ËäYh>©ˆ0ºª•³hŸDòƒ=¨Ceõ‘¤€ÌY´O®î|HJ•õÔ*ëiUÖÓ«¬gTYϬ²^¨ºz²XU½QWüÐD=$à¯ÌÊñcf ñc”ÆŒFHUEÉÔEyùñcTqô$YÑE iÄ¿,7~ŒªŽž¦…L¢›Š›ËöÏ£4~€¿R¡œ6eE‚0b,ß¿ŒÒøõ¯~J’ Q…DõŒåéU9~ŒÚñ⥮+!ERLÕ<‹ø1rôBŠaÈ{!„þ.cˆðìÄÑüÈ8”zí³ãÌ/¤UŠÒE;ßXæüV9~ŒV9~ŒV9~ŒV9~ŒV9~ŒV9~ŒV9~ŒV9~ŒV3~8Ç–xÊoˆSÙBv<ŸšH%pk<îlô“"3žº­âõXIaŸJ8»AöáÞJŠ] Ó¹=ÖŒÐÞßëˆÅ6 Ù]…x*7Îc±·È'&R¡´TÚ9wäû²Óü]P†±Q¶œ°7žƦ3IÐÛ5#Äqêþ±\v²¼ñÎQ¡…,ùj$žNes™T\èÉäq·>¶™l:;>cß»ì Û ya/ÙïÊeVÇ3•±E§rV".DßI|‹×’©ñTZ÷šö¦ ezð£T· 'Sy|6fß³ ”Ú?w *öNÀùxÜ06O¸›XÓÆ~¸Vê[Nغ³{¬\fJǯ?Ü-ìè%].¬%=™=´g‰É—ÈÓ-›¼Ïá.Ñ5Óð%è$Œj*“Hã¶%v6¾ ^®O\ÉîM[Éqk’¤:ÀU<3#LMïJ§„†üߺO ‘ìÔL.5>QÚ)R/Âù< H÷r¸í™LGæÀ±!Žx.1}™}„ó…\6“œ¹†2= §Ó¹A^@ö”äRú‹û}ᑹû‰PtáóŠ¾ø¾Ôäô$õ {âééE¶É‰^O¥ý]ãy_*sFz[¶E#Ãäù[f<É•ëñ*}~¹ÛJ–ö¬ÑÖ‹ …Éó<æAPÍ ¤›³õ†ÈT…qCW£Ð¾ ·ú+ìE½®h÷ïUIPDA•ƒ’<[¯ËJ¤S:Õójõæ>—MÒ#¥¨7B\7ÉõÞ''z£sô°n€tº¨7ºT½nŽ“üªm(ÜÑÑ1îos]î †ƒÈk!žG¿šâ!ñ6žŒ=’_µÁ(ÎÕƒ“g¦74ÏóÉЃÐß!k ú‡Ëm,•Ë}ÌOô*=_˜£—·ÙLr1ÁÈÐ×ý’]/„B$¦T4!Y¢õ  Tqß;ž´©IIkäåéÉ´}JP—BЬ‡4Ö‰xVz²Ý_&ÖÔ ŠhÆòúí_j¤9wœ;ÎçŽsǹãÜQ­Ã{Ú{šyÀ¶˜mögï~ï~ö¦Ý{Øï¼¿cng?Dc.{ßû}4òþvoÈ‚ÿAË;všjy>ó|FÎ1)jl-7…Ʀ±§¸Õ|ÁwÒÿŠÿ¾…=Á«Có<ÿ{w{w“s&ã=æ=Ædà;𞹓š÷24x·Â¶fÄû`Éð³çK°z? ßþ€Ѱ5‰½ë}—¹ì}Ú;lŸ×;j›Ý7ì{{w„ÝÁ<À¹gknF.lí/4ö¿Ä>ÍÖ‚ÁyîY6 Ÿž¦ýgkÉH\jÜïíý}ɘÌ÷+šç„ç„wÚ;ͬwŒ½®ô,â²Àp ÃØ¹ûé÷úéØÂ¸’±¤çÙF¶‘Œ‰3¦³Æ‡¼â<8¿ÅûxQÃ÷ p¬ì^»íyÌÀ]ñó)jÌÛ Ô¼Ï²ëиVæ9ç<|ºÖ×Á½È½è¿©î_›ojý¼ýç-n|±æ¨%÷îìÛìÛÌ[`Š›`2 11J"œyÙ»ÿ½ßd¾É†Á‚Á‚™/’û%õ¼÷yþÁÑsfŽÌ*·šyŠ˜Mû¯müá—õ‡øß²µÎˆyw{8:d,üH0ÛÈía?a?aîÄ?Jå|;Sn‘c{¦ÊfÈë÷|pô.L ÚVFðivéË}hìytÔ¸ó)ÑÜ7¸g§šþ< Ý8¢žn¡î|3R‹çkßô„5KúZÁ0‚ï“»‚`/a/q ïTb×6½ô•½ ÞdNr’óHÒGø†;«öJµÇ‰+³v~G| ® øsÈu^ïÇÔµRŠodnN©JFÞÇîC‚¢ñ3÷¢¯#pUìýýú [ëj`Ö(ü–›`þÑÀnß.J0w>¿“ëd^^ˆ`œeö08³;ì(­œi7Á8£• nÜÐܸ­ÁdÄl‚©±'¸=ïÔ\Ys%ßO9vŒþv1‚‰×^€`. ¶š¶p!‚I_m‚}ëj¥–ǵ!ãHè«Æåžæû}ûøf¾ÙíÚÚ÷6mõ·Î%˜x{âØù?Ÿ9ÁH/ð{’ø`$wÁNì:[‚ÑGÓØÈæÜ{Þó¼÷·$ö¯¬9Ú°¦ù¦5¯Q‚ù\>ø-26Å~®æx‘à#>{æ¶Ë8ÊôÏ62Óüݾ/ø»¹d Öóý}19]2¤ã)_ l£)7¸¾æ-ÿ&’EÔ•ŒÍሡÁˆ‘q;Á·ÔZÏ´õµ~Üø¼oˆ½ËŽfó È-ÑÌ®,fNaÏpq„¿ïdFìÜÇ5+êÖi¾}Ð:’éÉ®ì­ØOû3[¸~ý*õ4òk^)ý¸é0ÿšïdÓVa¤á6ß:è=® Ÿme±Œ½ƒÿ1÷÷Ì;`sÑ‹DÛôz›½ÍÌ 3Ã^Çýg ñAö%ü\$×1²ÖÙ¥h^NVÑS8ýwHt²çwŽÁXqkKçܹ7!ÜóDÉó”ÿžd7‚aæ°ÚE/’ë&ÚÎ2b¸zÒ·ÂE-¿z]Ó·š¾U;áÿxaƒ¹…¹…}ÛM0{ÿh1‹3›`ð=|  lo*ßnà}}H0f¾•FÿL ®ÿo˜Ë“³ &¹ñnÉqëfÙ‚ý¯¿”{uQ=Õ‘l¨ã>cïZ.Áe3è"Ø×·NÜtC[ždiȈ—D0ÿ\ýÁ õâêiù“ ÏÔi”`Ìñ¡Ï ÏG°ç¿˜Km~ ÁìÑJþØM0¡•\&ZÖÔ}Ìç#˜æ¯Õ#ϯ2Áxe>‚Y‰•*Lx]€`î~ߊÀcõÏ Á5^ßÈücdĸOª.œ™ö’q\gàÁú£5#À0d $ò¡ß¸»©ôˆÇÖß꿟Ö3T¯H-¡˜æHf ÍÿWû&úaZ×8ƒQ>‹™Ãq'ÞÑ!׈_©‘Û[µŸ›¦þfð©†:þgtæÜôzîÇ|˜Ôo_:Y„!‹Õœ£^ຯ\ôˆzºó‡«ÿ™oFò¸b†äªxÝDã*ô·Ö\óyKbípýA+­X1âþÚ+a6ÁNFfóûŽSÁ¹«9b'ÑÐÛ Ÿléü¼óóæÇÀ o`7Iú¨Õˈ]„`weæyÏÎBìHXFãqÛ>¢yw±’ËQ¶‹•·ýç3û&s#RLÉœE°«²#4—Œ ×òõSõS«ø±’CzѼ¯—û`’µÞWÜ;p̼ÌßÒÜzaì‚KjFH>Œ¹/!¸î+-fû½kOùï‡ZæÁž{=÷"·üNȧ”ö­ œj¸­á¶šù‚›`’g:#¹ÁL†oYý“ _S7Ê¿iû¢î× ‚}_¬ù͆ú–õÁ”¸Åö¥»,ë×û[ùçÈ~ ÆŒ=Žï­*ÁÐÚ£­­M+ªO0ðx×| ]€àâwÊæCÜ­Ü­K!˜äÀeû¯\…üÎ!jíâˆâÞC»çÜE#6PdæÊ÷«õÛ6=½þÇ·bîóŽÕ­­ß_sè}ˆ}ˆV9ÔðzM¦¾Åÿ\²™vöîÀB]»Þükÿ{˜¥LslX%}„6¬¼®Ÿe§X s)VânõØä]Zè®?åãÙ•6¡ƒa­ììþëä;¡Úëf»I÷0ó0û ;³-ϵÎènš•V­Üw‡j憎ø°¯:«˜¬2Ƶêì=§’%Õî«ì«ü-ü-ÜÜøžÝÄnÂóDÙ•u`½@ ².g¼¼`£ywzwÂ+|ö<ây„IÌ28×Ù?ò‘À}µçùþbç+Ø+c¦ãHÆf~†3”µÜûàm/vª±ÒH”ÓaR+ÃÙû™µ+ÇÞÌÞ̼ƼæÌ¾'†¿}Ó|Cµ»|å¶±?eÊ| ÖCÍû1X ^™ÃÌaÌJYØöˆ?䋸"ÜÅÜÅ̧ÜåDƒþzÉsçŽÕÿ¶öß}¿r\ÛØøšãü£AŸGüÐ,‚ë[„-uÏó‡ÞÙ!ø‚ E×?_áÞ°ÉØ÷-'˜øN½ddl‚ñ•}Ów[ !Ðàã¹Ç"=û ßÏÝÃÝCgÌÙm[€`v÷]^!  ¦y{‰áJÚW¦Mî™LÙ-Ll‚I¶| ÷#ÇwS‚}¼?íOs«h?qlØ+¸Çød9ÁNÎ|&“Ì¢ÁÅìÎ&x¶áyþ ïO«¯iy¿áßøŸU"É­D0¡Fr¹÷ÀðõræÓÁ4²ŽŸ²÷Îö{^°)v=÷:Uî¯aF@sA¹#kþiÝ]ukùG ¡±’‘ý&øúhÿ6Ádf}FÃ_›Ù†!ðn7¸³ ØÞ s*0³—^ÏK8~ìÍt7ÌöÃ|’[…VÜ1sïÞøÁȾ·?]ûÕº±À`Ì®Äy…ïCUQ6W6m”`ê;‰¹.î„ÙkÜw~ÿ2݇D º&PË{óD„TËHììï-ñ±ã%‚Ù'ùzöIöIBðã¶aŇ{Ȧms«Ï4½Óü? ߆Èt]©ìJnŸÄÏîJ­Tõ!¿ÞX‡`'Ãp*ábvp‚îÏs§ÃÔï–hfoæþàûSÍá¦áæ"Á=.;Lícû(ÁÞ×]YÂëH0î›Q’áݧޟû)Éï,{ïÞö½Ž_¤# ý0äÊ;¨9Ÿ£ù¯›`RÕÙßÅìÂ!jÂ7À»½EüÛ"#¹%‚fÁ„áUÄ£>¼Á«Û¿ì`Öo<Ã=挶Áe4ÛÙŽ³í&رÙ£ý?wÿ'U•üÿÃ"Š¢Ó}Ï 'ç<3 a‘UE«®9‹qQQ1»¢* *"æ¬V0£ìŠ ¢¨˜1¡ b„`EüŸªSuî¹wº'»¿ïóP/º{zÌÌ»ë~NE XQ$˜ýn[ƒì¾¿Ð}ÕNÚIá)ÃxE+‚+Ÿj¬-û»÷‚O0<Þ9kr7 ÁÎyöbŒ¢µ5Áb¹÷CÞ‘…ÉÔó±Ç@EèíÁÑfiV¾ÁÛü²Í/*_'²Ñpf³†ˆÛóÏëqrÓ™eßão•T^aI“0ÉúÿÁ*Êø¿‚šÀsœ>Ÿ!åE‘0æ¸y•¡íÏV÷ø˜3îüóäŸ/eãƒ~Bø[ñlb|ÁšÔ$û$ióÝ"q‚8Á]ã®±Y_1Á ¼TzIÁwé%Îz}ËŸ§¾æ„²ÀšH~ÎÒSTcÌ+ðêÆŸe‚Ìh¤(…±e©ïcËì7àsðãäç[KÁàmyf™VøBã¾õëòJ¼®RË !߉*B욀TÁ/ÊØçFÆGƽH1© $y7ÐÖnê3;K0ÿ2 í­Ã&ÁփΩÊXÂ^¦ü‘I¯I0ÿÄu÷u*ÈF°Ž;앳—"˜ê%BÇÉ?¯ &9¯¬D°õ¨´NìL‚øä‰;B°-Ûp‚-a &Ø:Æ=#þAüç%é}O°çÁÎ-±¿™ƒÅ 5ÃPWæÏsc F†C«l“}vÞ]Uo=æ]ŒÔ††Ïsä>QÙ§vHÁ{­ fjÅz±>ÁúT"}1ª-Ê™…K lFð™h] 4 WªdïøDa|´s¨SQDÿ&}°g½”¾d‚Ã:3@ð^òÖ<ÉÕ‡ -Õ!)æº ]Oñ­5rÎö:{sŸsŸäWÅ"º‰ÃÜgãg¸;¨»&Ùˆ"yZ‹ñîŠÔˆô´ÄrïûΆ«LDΧ‚þ¾ŠÔÄü5Ÿ_&‚éü8Áù[Ç r÷@6˜¸V\Tò{;(Vª6ð _Oj¬aXÅq· Áà3|_ª›¦Y,)„¨$F|í³“SóîJ ´KuÆBò‹Q³¥ê-±Ü_›Ü[žDnǘ‘jhYôÁ쇭IÎ ±B) XGÏ–QùeþIÆ:¬N,ôŽÇ8š<ÝÙ‡ÆFÿXãTm“û0ÐĤƒM‚3”*¢‚1:aŒæ’Áª ü°"Ù$8=¡äžô–bb{ctl™Û?o«Šë/«y§¤{¢²È0ÄpÊ&“`ëBŽé>x#æH›I0Л‰`}OCd§£Ãϼ'øN}mj‡`û ·Ö9Ožæˆ`ˆûÆ~Žýl÷S C,B´Ø“¿ŠàÈMÓX€f±Â½Ù$˜}0úäVãÙš£i|² Ÿ,TFæ ƒ¨˜ŠÜk²é )N×–H‘ûñÜÆûôIõ:ª|¬÷-|6ãPR St èãÅx?‡§*ftö~òàÔ«~*ò§Èþ—bßÕ ôǪæòz}î&"–ŸxËKÉ+-ղᩇ¯æ\m •“‡ ‘Ü‹kŸkÐç€Þ›5®ÈûrâX-ÉÙæ(Uë˜5~›g41RÏòÏ9üó6õ/Æú†ìHˆFH#‚uL‚­>h|òÕ1ÙpÝWð0ÑãÔU_]ÿ¥Ñçé]83r=FÚÂH%T ÂéÚAî‰;$ßµ#R©ÁsøŠ³tK~ÈL‚á„6 ùõíe‘‡­¼Ñ·èi™V5WílýÝ™:?þÜð[Ë3½Žªê™àøèøÍ'"I¯Ûßíß‚™âlsýC6‚ÑX÷‘‚툴£ZìÓ«~½yEß7/ïóCßÇ%ÃV—%û9¯C•N6‚á{†Ÿ[&‚UíHç ÎY’³$Ò6ôq{HDr3Œ?#º±×Ð×» c ˜2œêg,fÅ‹ãÅ&Á«î ÁÒëNêÁ*gg¬=û"¬O÷ÕƒIpΫ@0d¥ŸB•àŸDYEÉÂÔ±D]IÍœX# &a/³—~ƒðopö—õÛ¹~Ʀ¤$ô½¡"ðJ"˜kßõuÒȘÀIÎÔݾ3lêŽ,øKsKŸúnÕw+é…û—š÷3dʼnaGG׌“nÀ˜`Š›› "PI€z´F?LÌY"ù•÷`JU°–¢oÑÙÁ<˜¼vË«:¾þYézkÊ›>,@°üLÓ—·"Xù`PXá:D>"‚áç 'Jq˜8Lþ”÷ãk%T¶aÖùäÈÉmLê È<yX“ü¢ÊJ·öÁ˜C;ãyëˆá7Ycq <­¯pW¨L~T€`{kôÀtŠCÜ‚ÍxI0þ–6‚`þIbV~8ž[þ¯ž¶ŒhÑëîÞ›5¯i˜T´ŸWµfPõ"8¤!4Áî ÁѾÖÕ!?3ÁLb˜`ô‡›„`{Vi‡†Ã‹Bûl±Pþ»T¹“`ŽA˜ƒe"8’VµÛ*×dÖòš'º6îa*ô±üC‚¥¡ºãuC~×ÇÒ º³usð¿iT¤#QFT'@0© ÿ¤BƱVFÚü Ál+˜ü ÃOÕkà@·Ä §Rç ,?¡ª¨iHŸ‡A—{Þ»X­=\µƒTRE?¨¢5”16~¦XožŒMŸ ôš~ &ƒ¬±¡Ø'€gyKŸ§N†êˆ^]ÉÃÙa:ÕêÀŒˆ~5®_犌©‰Û½®à…¥Šà¬=ù`ŒêÍR™¸æy%¿ñ>’‡*z029 ­"$µpf£¬Ftk0ëëõȬ ’ ûüf%˜ò¾‚ _lÔË¢ßyÓ1˜kÃñÕ(¡:î7 æè;lFt:Bp ¯ËÌ!/6zæ¸f¸cÞ¿$5 ôÈßöº»yXéìxOî{3 6«Kõ5&@°êJÚT#ÃøyâY}rG?7þÙm"‚1{¼ÀïcÔqáŸTŸŒöµÝߨ©é%y}ç¸'bì]š;6qÕ¦&Ø*æÔ93VŸúºhFù³Å$&:Å:ÃLµ%­É ÖKûj"øqì«u-lœä¬«¥š˜­j%¸ê‡O|¦Θà(dˆ`[[%†Š¡D°y DÓäo`] ]¨ ­»“fbEœ$Ø™“¬*YWÿFݘ’uñ×ì‹Ãà¯(tÙgKúYÃR·lÄwweõ ³Ëƒ Ãcßÿ²&‚ýš³MK°®£ ìM²5 Æjž,óoBÕ¨µO0÷l ‚!CÏ›ýŠ[çUK~Ol`¥†}U¡Ïk”…}u8'×*š–…`Žo ‚±¾,ÁXIU õöN%0ìëh“`å9ßõ\Öghß»zM-8ö2ð+ÎØ¥$ ¹/Î$k":I°8 ÞÃèºÎºÎì|ieÜñx4Wµàgä|ª¿–Y­bææ°‘+ºâÝâ9»ñ¿‰_Ÿ+Ó™ÌP}0¿/lšÌ¡Ñ»"¿F~îÝ=r[ä6¾÷ŸÏùÞÎùQYdad!VŠs·:e×ͪ{Õ‘êUÇ{zïÚË”ÎÇX6dgþN½-LçlÑŸ£»DwÑo¯&ã·K“oGOõ-ò‚4í#ãì9_ÉC*©UÏÄïøÝÞ–s“ün‡JûUYô.ùýË·[½B0†y>ñ,Z‹"XWç'^ÌõÝš7þ¤÷°½²ú•àÒÿ *Yo–ö“×µlÇ–Å}#}#-û•§cMv)Fßäi_+ïF1{dÕ‰ VUÝÛš&¶¤óR]ä­è?}‹¼EoãçYa&鯒œï£S%M{¨3ôFÏÀŸ`qt‡þ½Nœ3]=“`¤t#æZ4çõ‚?*_*[•¾–‡8vG¶†[Ã3lWY¯Y¯mÁ¨GÃ=mŒ®»8FztI°xÖ{3Ý?Ýß Õ‘m;$é2Á¨Ôh~Щ¶w?YµWÓ-û5®,|HznM0êmI¢u‘4"ØšáΉŸêαU ‡ FÊC[׉‰àu\©ÖSL€ÈNŒïLüœ2W‚ÃäèSºÎ˜9A눩³ÈT',‰Õ¿å™>íº›ˆkä5Áô›T¿_“`èͱ*L‚!CÁê<°äø¹xÏÊ—z®ª:#1Tù^•m¦XŠ©ÏœàŸ}ž‘^ –ÞΙF>9¥èe‚uܔޮVäȨˆëwZEGá™Æ«zˆ`ô½òûÿ²ö²öÿâS "—MxޛśÕ7Ôœ•>H,7«Ôñœû(d((S-ÏkÎ}^Ww_{f1rÃ@0( g„XƒËs÷Í=½ô™òtaר¥Xy9Š: {rNäE°2çÈÜ%¥ëÒ:9’Â?"H¯[)3&{— :Œw;[%{SᔢLú“ÿÁαDba,aÿ¢¶wí‡éߨTóoŒ Ö*"D°~_‚ùl1 Ø)N~‘gÞ.ÞÔö VävŒà°Š0 F}Ž'«œ·uf}¡ ̨Vˆàȯ’a"Øuº¹‡;Ý|‚9ÂÇëÊ­žm¸4÷ g@`ûߘWã(f‘íÝÁc "@pú¦‚±±­ g‘«©Ü±ÞGpvcèUgŒç(©€`»{úÂâ!ù}:C0úa$"E0'Â;Þ~œ}¢ªTIRdL*g>˜ä0áf$NŸãœÔ¢²{«¶Éïíì¦^ö/ɻ뭕~g%) ®–äÓ–Ž¨çœ‹‘!®Ì ƒñy&“¯œ¿K“oÃo,pEãÎI6㪻2ŸQ3±ÜsÝsU]‡ê"˜øý~µ$žÆ€]Rxo«ß––³Þ’±¤—¥1Ç3Cfœ¨ÐBšÎMèŠeåô+«ð¼îáéòÜ âÏÙû ¦È|ÛžŸú¬p]áºøªGE~ ƒz; ¢KuB\¡Î}«üù3v©[[-û>1’«w@qØ¥»àI)ÒHEh] Z|ñ çÈØüØ|ÐÂѽ¥½ ŒK?Ršà©Òó´*ŽàDaÙ½Å?zÇg"XÏôÚ@‚ÅÃîȲ{{}Ñ2¥æ™øA8áç:q“ôÀ+å×ý fŒ³Ú ˜z¯°Ï'Ÿ} |o˜`cë ÁÑ]¬;;C°®éÁæ÷¯ŽÇ«»7¾Z>=vœðŒÚ7ƒ`KØóSSí~TBc\Aó+ÿr¯7ÇGù à ¥ø¶î¾L0hãÁ2FŠáUºÁ¨•Û Xž¢n"_ œÇç6¦¹¢ÁÜ=ý4ü›5†IšD>ÕèŠAìf~ªèúÆs›–VmÛ\ÌzØg_U)juЊ`2ŽšJ#ÁðÛ ü'XÀßÅê!gÍÑ£>8VIª’ݯAÓQB®€×Ñ0ª&5é¥[Î4©BDƒÆ@㬪¤×*–*‚Éå×&WäpfÂŒ==šjVIü E‚“¯TΨOOó¢âY¥±{)PÅiÍŠy3Ñ3•W£ZcˆõrÔŒkýŒÈ%ôÉI}¡rsCTõ¥Vüÿå*NŠ/ä¼Fw šòÍÐëíŸâz"èuÿtî’g¹ëÀKÊ„^cùh‡`žuà@­«&TJjQîG©Jˆ&þO v³÷1šiL5ìY 6³êºï8D0ößR ‚ ÆÜ“A°u†uF6‚u Çe7€`PÁ‰“ÓåÉç±Lã©îHUï&ؙ㥜9öQmÌñÌ!QnnSŒ1‡JÕFã½&8Þ­¨¾ø’”#ué7XÍs cÚ(|{\¹Í16Vì‹åûs.Ϲ\“hTª`lƒ²v³´eö2ªäÒµ\ê«åÌâWD+"µN jíð4?z^× ÿê*†×•Yb¬weê·ÄNö‡8aìuš”G'?Ž—êW¦~…æôÖÓHÀ¸ôîêÖ•"ꙀCI"ŸÌ cz²4ˆ”¥¤qM(‡—E9Ò+Á½|”ï×k¨ ™ð+5XÏ s0èm¾7¦Rá U¾‚­{­{nN7xõêÄ‘ªJSå¤%¹ÔÅϹO´¥v?è(¸6–úøïëh >WÍá`bµ¦à(M—Ñ'8Î,ýA燽sÖ&ë :“×r|¿¤UGߔ٧çßÙãÚž«+RÞXëyüÙswyè,Þ‚ÑÚ!8ðõÿ ü=Ó°KÕÒÜ}œKì†0ÁHo‚a®dgVüf'É ,Ê¥½&Þ‚‘"øžà{3ö¯A&‚¹ÿCçõZì®,?°é³†Eé ÿM‚%¿{w„`3v!Òñ+ókëJ¶q+¬çqBp™ªӄ· ¿Ãvf…Q1TFÖ<f/È#”1 é¼þÛá›ùÄ^ U÷£#í\ÙÃW^ºz‚âµ÷—ªaÌ%5ÖÛñëjú¶ä4?R’r?õ Ö¼Í샃ÑEù˜§¡Stµ?T”½L0úU 8 ÁÊì‚9u’áG­G1ûÊñ`þþB«)òz¬».‰ ÒD:SCªŠ£j¾î•>˜«ä‰^|K÷Ä@Ǧ»Cáધ+OÕa}ü_Œ¬=žÞn÷Ïm&Ášä!”qÎB0Ò¹·"#l|R#‚á}VÉÓ9Š`Êo|`ýÃ)I\žü2ö¡8ÅJd"XWút‚`ìx¤ÚW]E˜½Ðq‚Ó#Øy,ývÁòôz¯Pl½í~Z°MEuåEàƒ¥Ž ‚9¶1s\¢#‡U’»ØëæNpê o$Lpàd÷?$XL´¿ðN޽?Ã}Ö$د^µ¹ê_ßx‚5½íŒ§»Xÿ œ{¡•°ÎFs _&‚Ÿñ§×¡¢5²ÏHð:šßξ˜®°º¦8ãx+Ä«P#ë>6®î¡Z5¦Ô 7 /fRo9ë¾Çò/©¡×eõ«óös/ïÁŒh÷òøŽñëÜOÅXyuÍ ƒas:5žép¶º4¢˜kó•fßWxB ÑËjOg@3‘‹åä:wB|»ô°¼ûóîOÞàMäù Š’ç(ª8Õ„g§3! ­   ýêçæ`žZŹ9¡Ö£ÜM€’ÄrìÄ‚Wlž 17È':þ¿“ý: ¿«T«"OmH°<µ1¡T'¡é6}4“îÃÒž—*ø8UkÖ9‚aš(ö&lÁ<Ó‘ †Œèî×lÁ%?ôº¬ï ½/Í‚Q ¿'Þ³Þ–¿YÞE‘`SBk‚U}3ëàìó‰.L°ÖÇšàøvV.ª[QÓ\x¨d8…{ FŠ7€`}]2æ^ Øì5 ƪëÕ§ "XOÉ¥Jž¶ÆiêŠ1õ¿K0þFÂgq¨ÁYÙZEاŗ&&ŠÕùFÑ‹Q5#«Œ~>ã°Ÿçl4ÏC_TbãÄ,Ϊbo U?úWÓÀov¦‘}ÆšÔèLë^yjÁ³wáä†S›—ô¸§0ô~ðÃ*‡,¯°|µ5ª_ÐW´VYsÕYR¦G×xºß Á“œ~;”¹P±Øq’\]^Øs÷–­züZ>&}ôNæ™;Ò+9Dp«©% ù;T¦£jCéQ€`?&ÓØ *¡;¸ëžO•Ô©Ù*ŠÇ96ÚßaNÉÅ(þÿÈÿâÄ@RA`ŽA0Ê•<]P;¨ÊSeðý\0­>Í95†¸°I0ðæU?R¼¥÷®I0Ö8cLÂèéÈL°}šS¬º~íÓìÓÚ"ج¬ëª¶»ÁIM¾RÐRþVa$¾£ôÁtFï,Áþ¤oÒÃØµio9uÞ'éa¥ólÑ0°xdjvÿÃŒ³n8-cƒ fг¬z<ü˜l •Ñh‹`®¿O·Ý0‚Å#™Ɖ%D¯ùþì‡zï1';·š EC¥ ôêêM&x••3™NÎ,´O)FaDÝðm¬µ°véØ8˜†í½ û%¤¦y3 ½ð·fL#Á«ÛæÁ®"œÄ³YåUÏd W;CÜ;R9eO–t½#3äkZUrO˜o% EytþEŸ`‰lŠºqU¥ÎÉIÌrîí1eÖ¶Ö¶b¤=×+H6üP>«âßÅ{¥/ŸçÖÒÕy¾O‚¹©…³ÇzëÄd£zc¹ÚCŸäØŒ-3¼a†÷'áÎŽÊq$wÒ³–§f°·Ê4qG V¡º¼³2¹‡éÎöŒìöÁ:ÛÌU•æóf]ÄT|ÔÁ 3VÓF“,Ã)¯=‚¡>86®4ÒØ¿±élɰA°sl,ß9ÖŽd"ØÔÃa‚ù79â;÷ŽDc¢fä™sw7†`Þ3·)F†sž¿lH5ÅÏ‹•¸   Ñ$8´iˆ…m w†àÀŒøðüM´Ò²›Š`{k‡`]?Ñ&ÁáÙfwŽåÒÉÅß`HFS—ðGÕ—%ÓCûÒpËy1Ô×ö®©)ý{?ØûÁÚºd?<R‡J¢<µ:SÂÝ2ጇ1[Ýãöyûyôs±ƒ}ƒ=&äAÎ)Ò#GÔ•®9¦îý›4&–àÏ¢‚ÍH°KU•ø˜+vBG±ž–}œ{Š´\7×ù‡íÂ'œ]H™ã0j€Si—rO„ÙÉ*y;‹·ÐIµ=‚‰bý9}ÒÑKÍ{"² Uîñ¥•y=õTþ¬<ÅÁΜô’šdÝ«['Ê¡Vª#Cw RŒ¿&8ú¹ŠyÊÛ94ŒsRA0Ú& '<&ÿƒÿ‘6RúcW2½@Õy…Ïôºª=¡¶“ç‚1÷Eã–Ĭ'hC ׌ßâÆIž…¿‰ Ƙ/ˆEtˆ`{(TøH‚Œ&ú©œÍ S3øÏ7£aæŽKs‹ þ6)‚*ã¡÷v]cV qŸ‘ózjJþEû¥ØØÏs˜;µüá–½on¬M/±¿ ‘s®š€-¯Zf5žJ¥®løÄߌü}ô•*B ³͸§ž¬Çª‚¯žÜIISt—<çŒ9ZêÂb¥ŸåJ6ÌdPÕL;€ßÈÃÖ¶¨(Žö¤íŠ‘RWÒ$]óEÓý9zEÏó6,5݈Çò õôPÖ\ÕûüÞªsÔøþq¦ eFtO˜äŪ )0‹Â|lÔªñf™€q¼ŸÕf,$ÍFõ$ÆÕÂ=rìAˆp¥ œ»œßÅÎÒƒ¶A°»&õ°Á7 õÔiLSñ¬•îzØÞ•`µMYÚ™´ç'8ßѳ¹e`‹óú¶G0M–Ñ~ü  *ØùÙ¾!L°Þ±ò?"ûqOµ^kŸ`ùܶ‘‡qß 1Y ÖDõÀ¸1dÏ0¬v/wŒ`öÃa‚uŽí¿@0Ö¹u‚`Ó'›[ßÛCíÛ@„§ª2ÁÐ}”`s³µ®ì9*Áa‡°W tڿĻŻ©jvòĺbk„ Ö›jqI¼8ïó¢Ÿó>‹‰pÕ2&þ±ïÅ ‡¼ ]ÅøªؽÃÂÕ„jŠS¤»Òþn ­4ÁjöÞÀgbîîä^n>½²ª Ÿƒµ6Hp«.¢CˆT"9º•4:Ùáûh2žQ¯˜ËE&źÊRg5`‹€¼RSµ¾®Ý‹:=AA@•oûšHS¬Ô©a>Š9;Í"'¨.Ws_é¬óÊæ)Nžõž%žáÔEh?!„Jv$ó"?³®l‡Ì2~襩G#ÁÐj7ã.ªŒ*Â$X«©½w‹·¬Ì+;övÚ¿ RÙÑï÷Ö«ùñjî ~Xmãqì¶F†Û XzáŒcml«³Ý³ãÝ í,ùœ‰`M&‚#]#]ÿ/L¸]‚ÕlJ{÷øÚÜîñáÎ5«}Óì Éðª›lƒà転~\+‚Õ´}ÊŽþ͘óetáëy³üΞaÎWS9?ä÷Õ»¶yLñRoœØ¹-ÎdPßöÝÆ^ 4šX'–+ƒ˜°?G"hæÖo¾ŠQ/¨˜Ðï¾êœ ÷°ÕUR¤ºRÕÝPÙÍU-T#kTë&Ws%Ç`Œú‰ˆ99²Ç/G_ÖUTÑŽFƒå£­”–ÃlF>ó(¢MºxÏÙdŠ=è“üºO/×í£¢àE8ªSIAà+XÓ2ùœX“øOEsȲºøêäìï1¡œ÷ ­'dÃ+Ô<â$l©Eñ7 ‰-Å–nz£²Gø¬êýFµ;,v†¹ÙÖ]ŒfŠÃ}n@pÊ®¹¿×›Mym¬ãÄYÖ–`½ .#Áâ·(õYñ¾ùC¼³Å LpÎòµ!‚ižôœÿÁÑ[¥Æ b*ˆ~X™™IÈd›š`Å/ÍdËB0¿ªÄšüŠÆ[›¥öÛ‚±€3@ê&˜c!jÒ8.$§øñN¼‚úÓLzÑŽö cœ¡Ð×T±“;=}bq‚sâ‰xbH€`3³"Xe& 3æLš“¢ZL›Ÿ€àäeµçõÚµ®&õ™"½o/Šao9÷ëZÇØó½³a¿U+‚•úÕû0ÑDêP³$ðÕU©ù9ÏrE;ª&˜»‹ ’¶U΃a̳qUv6H°ª]¤:E&ØØÆ‚þ9‹he¼Iœ¿O3šÈô½ý ™usüˆ¢—*'•”Å~V3Qä_îŠâß‹A/þ¿)fBõðoÄnõ»ÓäÕõ£›ê®FË ëlV_ro†6"UÝ7LpΘœ1B°ÎfÁâg7wº;]ü tN†â¨›Š`ÐL°wvÙ“ ×Õän¯TD`û$ç%û$µQE<ë]¸{þçÔ¶æ­¹¸n#F?L›*"r€´6æÛ@=Dx^Y›‹÷tœ˜ëCãTÁ ëÿ,Öx7Æ~ön”§“ &8¾6>Üæä(†M‚ywªT»=¿#Xúa¸J–©w³:ÒŸÌìGøuÿœQùãwQvCRLÉ×ÁoLW¶‡£oF%'²Î›·Î2¡»ž&*‡*{t…Ÿàxæ"ì ,J4¦>K}†¾÷¤¨œì ¶OJ6¬I6;yâY ØÉKŒO~âäé«+ûZÞTóoç~íËÌkJ`Ã7F…»I0gšMŒÔ’Ö¾8´¥%`D.ëbÝ]ô« iòÑ4ÝeÄêi6*Üñ$Û+ÒKe4”Þ2OržÊªÿ]y–›Œ€5Íô‘ZkNPœ>Eqlk´X(:•HðZçk»»ªžÔÝFÔ=$‹ îvŸ˜A‘6î2â^90âKü(½å½èƒ3ìÏÏ5b†öËD°¢SÝ›C†¹-‚‰‹ "ÏÃÁ¼kÍNÊ·_®\±yeE#j+ŠtÏP1 5ïÎ?ÑqüWO‡Enazdìªg‚±2? Á0/-Áj'„O0Îd’¹Þv#fÕÐQ‚u¨›ôv†`•I ½ÁÎ×’ßÉ™f+&ÄVÇæÛO´G°øøM9%ñwVFUÚáú^ÜÐ’swåºêc¸êš÷Õ(ðÅÑo˜t&Ø?M› õDðt)Þ= »mfªZJ=i?êÆ×•&¬ƒ!ƒLÛs8ZÆ»Ãâu‰ñy«’Ÿè(›ApÐKå@iaW= §SÝ}OÓPXMø••TÑCÛV3¬2Ñ­0§Ã,1Ô¾[¬ QÌg*®SøÉ Ì NMp‘ç9®ðÑYfвñ¤ª¨Ôf®Q»^un² àë~µðD@&XWÀ«™(úãøUÈQ58ͦN7à=Umν‘vçHƹúTÄEZÙ]¤¦N‰Ýı‡ÊW6½”`5ß6H0zKš[ÞÁi ‚Ñgq¹ ‚ñ#/¡}D°Žœû/”ö ÆX$tÄÀNúÞl‹k½{Ü3œÄ½ZŒ§í–Tɯ²éÒø•‹ÿ{k­žô–ݭûx"ÚÝ’®Ò¦XS¢_D¿ÓÐû,N&ûB™u°u°}´óŒ÷bÞUÇd"˜ûX‘^"wIb»ó˜»»Ý5H°Û[¾æ³Œµ¸$w)sž­ƒC.Ú$Xå…‚£6ødÇV³rÁÎØªšw$Ô|"ÃÆN>ªC€YO`ÙÖuÉ—†¸HYì|ï“øvÉÁÉÁñ¯¼^Ø}"ØIä^Ù¸´ù»šÓâ@°>v€`Q.6¦j2Á@tŒ 5‚©ÎFEä¬:øGƒ`˜§RrzåÇùÛºý3üÿ³Šˆ`Éïîm ôF–ËkC‚!s=0™ƒj·4Ád¸Ùa¶ðìýãÏåÕ§ÎL¼ÿôóè«T¬¶ìÀW²çÃ>vôíü»ÄÄÈP=ßWÕünN|6 Öýpȯ<çi‚ÕL/Ñ]MøÒ5[\abŒõ/\©8çä&XUjçØ <ÑÝÁû!}Pñ«UW—m–¿]ü çXž%Ø>…Ýþjª•½ì¸ØqÎcöCfŠõVØ—lŸ'WçoVtdþŒÔ-±ÉîIÔ’ø¿òTh—l¨8ªá¢Êg¼…¬å­Ÿ!1ºL9«9m=§bž9HÓ3Õyó5gqü«äêøvN#nÚùv³Ûß›êŽã&Úÿ©xAeSÞ!0ÓU(u´jü3UücDQžj[ù`¸Ü®^é’h ÷ÏèÝL*ð«ée‚ûEûÁb± Pì8a‚ý9­ †àçÔ¿PpyÌa‚uÿï 6 öÊ:O°©"L‚Q!k‚9z_=Xhkj°JкÙ.ußwkÅ=µ?Á`L0äÿàÜ'*.kÚ¶wnËõ ‹Š‡Á¦Ìs?š-PÙ¥`y"m?$õÖïa‚Á ›ƒ‚ˆŸšTr|íg=n¯ÿ¶ltzm|;Épˆ`¨ˆ÷&Æ&Æ:‰l›üÁ8c;D°žþŠüÚUéµÕ5þX¹(¹N,ÉD°õ3)ﱊ†Â©Þ<æwE^æmÿÉÛ>LpäqN˜`ù¿¿§£‹ÄÙÿ GŠ> ‹Yú_%wö4(ßlŸ{¦r¿Æ3j"ésÝ'A «sUòA]*~ž%Ÿ'¯’ªOBª &x(Í¡.Kœ9ÚQ_½©bR÷"“½KQ6"&4ÄM:OãW<ºL€TN¥;Ö+ÏÄ4‘Yw&ŽVÝ;zÓ"Oœ†í'ýb»T\ÖËí[Ú·´÷Í-ksÓKÜÅ,ì~”¶®r¶[~_  R%5³›>¨‹¯Œ=£ú§i·QIÄqGý Åλ¾rQ¯®}–ƒëÿš¿( û~±'üÆùj Ô: 'a‡‘ ‹£r×À{>A¾¬òÛ¾’ ŠOc׿³¸X4ÝÛûɦ{ FÂ6VÌáèNVÕåàö/°j¯«è›³øUª8Ðú&âq¹Rø/ói–‰ÅÊõJD#bQÃyj ²;B) i_KÛÎ7àÉe£T Ù:Ø$6Aé’fWžØí“éÜêÜêäiî“ÎÁø?0j¡°.5Áà¿ñ¹ÁZ ë“ôËá=fí¬gh‚y®n˜`0Y÷ öý°|(hƒ`åí/Ü•éGê÷~û–öùU2ü}ÕÈä»î‰è‡qJ”8LWlà\ñ/÷Éô¹%7–þR¼2yšêžV>§-‚cïän_q6Ô«kÍ¥ù›Å&;‹¿~ïŠZP츋sÈî ŧqvýÏäêÊEõ­nœ™`1Þ›šú3Qh?n Ó”õn@©4x’ag ¶FˆM‚ÁßšË3Ým¬+Rô$ ʲrExD©÷IiÛÀ•QÅ"t% O‘fÝ¡?ÇW%ðõôþ :³¦QÿÊç¼­u°93l&W´ d8ªö[÷øÁ9+À¤’`õ +ÅiSõ|¥Œy?Î/Ÿþ×™â®Ì‹4܇xAŸ¡}†¶ ,½?^ ^vU}°š°-Ï»¹ÛÄž‘æ8#½|r¡ü ª°#¹‹ÚNƪK`úImŸÚ>¥óÓüOœ:ð½H1$º•¨bžjÛÂ]MÚ¿f½æöˆ}î(¯ä扊'¯,NN¯MÌ&çnÍôÒ†óóiæ)Ïw|Y™®è§§Õ‰ŽUÐ*)VXÚ}*6aÒ §9&WŸä2ÖÁæt"åS¥fƒY ûðëçK0žõC·ÊÑÁá}ia‚õì/ƒ`Ü5lÌH)±]JÎéåö^ }°$¸ñý‚¼@}K†å ©üž¤’û^ãb»+ž:D°sj¬ Nr…[n†*ø­0Á:žÌ=ÏOª~;Õû,í5èiÊD°sQÁ¥EŸÅE ªõ²?ƒ"x†÷ ø`¬Ž­ð mFiƒ`à(L°Uë,ÁQk›`˜3¾2g%FXX5°Šè+¾;@%4õ´îîÿ6xÒ²® =: OvÒ Èh¦Œ¦˜¿îæyª›ëM×áMàLvøäw͉òØäò†ë+ÎŽoQ5+ ¢8û ¡uÇ/oˆ”üú5O>åúä'Ÿ¥c«ì:ÏIF5.ß÷†¨¾á›&”ÄÝÒHE0±"&½ç±ÒlËŽ%­"öM`™æéÈÙèY8‰I¿ÚQ‚Uô-;Á&Ã&Áøx# †Þ²lc?Á8Ë|@|xn÷âWËþ^ð]²Ê™ÓÁº>Á(oNùú´z ãïŠoôŨ'J \Z)‰Ð†BÍ'G§HAðt)Tœ=ÒMºá1Ÿà(.l*$xdÎȈ씄Êm¨§kb[•¾Óc‹Ê>ñµ&Á~\Ø™“°°š·ÈçyRþû sNÁ«LxFÅé{ú7Ó¶^†“¼œãߢ’,”ž¬,²ÐÌh Á|bûZ™®„‘šh"þ»%˜ý1 ^Xuòl:‚}ìÌûÖZÙ †H>â-ÖD0úÞ5‰ÿä$sŒmUrNíOÙF…á)’Ô7ò®ê¥Þ‚ÙcŸï6¢J›Ž¬¦XÄ45>CT-Ááúå¶ÆíÅ$˜ý~&‚%¿‹2Œ;ÓB£ÿÍJ°šR'©$Â'°ÌŠgÝ3 ƒ&2%˜Ùà̓ ©’ÂT$@rˆ`í[™ÒP¬BÇ(}°Ò ´CÒœPêV‚½JÔmSreì1çÏÄôÜ'R]¼ìÉ”UîI]L]3c¿àƒÕ¹O¬ªCü-·Áœ£OpF%A³fD#Ï¢£i&¿ %ºj¡L_Å3Ç…5¹¸ÕZ«¶…‘R¹ßßd‰~bf²6÷²ðÚtö/@pðß•VéN‰ÝâjÙ€êÇ)Ñ~ª²GLÓ½xÿ±´ÁüSÚ‚™^ˆyo–PþŸô ÅpÇ6µbG&¼ÉvþÌ;«ò·âÞÞRI,‡nZÕs·1C$-èƒi#n‚õs{Ú÷cF`ŒÞ'´d!*Ñ!‹;³¬g'ë8´A0dUÔ¿+ÿåÊ u–`üø*NË"G›¢M­¢[F¯«z­b€ªœ›¤g1T€u¯Ý5ugݵ ·äw³?¤9â·ù†_6¡šH¸z•悹":8}TgŠ™P£2‡*ÒZS…’ çúŒô&(`<‘Áæ«Ê&–³Ïúm³ï.°I†f]uWYkP4G°gØ r£8L:N²3rˆ¸gܘ0“G¸ë’v˜ónr|ll-ÀJC;â ‰®öú"X“KÔXGˆÿ`õ%×Q˜ñYøx¬x§Wv—©Ó(¨ †¹cPïƒã´Ýè˜y‡sïx S‘a¾ïMöý¯¨FâºØ FþceÏ’B€·¿ðkÑÄJº‚·³WãÙÎ XÎçÔÊÛ XÇ"¤o5ÎÇÎÇö¸Ž ÷¸Ã!D0Ô9•##h@0SÌûS·CôJ…Ákµ± 6ëû˜àœg!;ìÇm7„`ûû&X÷st’àØªÔŸ©¬k4:@0úaÖµ!‚‘Ví…£ý˜`ô¿ÁT›H£ŠÊÛ©(ÓÀ`IoÎ)Òn¢÷‘…cXíþ6oÌY`fŸñsCYæœs tƒïo{RÕÔGÁ]@f6‚kÍZ3]I“…x1ê×0ÁzÓ mžaÒù„H÷Ñ€p ôº;Ø_Øý¤²à©KQ(ï2ê#ô=X`sô.<ñõÕLl+_ü2ÕÌ VýfªJRêˆ(¦À 7)‹\lOMuó~Å©Ú@’ªhÛªÕ< îšL³±îᚨ´ÿTv^ÅŹ«‰L°êCÇ{ÞEEÌtÅ×Ï-Sf]¡LÇTxŸ ÷*Rf§Ô01Í^m¯–·ƒ­¯u¥%EÖàtž×Ž2Å%XÕ1@õ`v‚ÍÞØŽÌa‚µîmƒ`¿*23Á#èÁ:ö"XuE‹78·{¾nÉ= OÊ=Ô]¹a« LÚ»«JõìG—‰¿x¿º71Á8]0ÁÜ3GSÝn5 †c×—–”פ÷m‹`œ"XëîÁ:¦B«¯O°¼&XW»g!ØWøßÅ éJgÒ 64dæI òÿÆo¯Šviº˜0{Í':#+ì „ª÷Á1éþd9:íÕÓ¬l>…ÖÓ'95¹N\mL{¥ž£T—šª¿Mî U‰?ª¯m:¢fPbOû‹V'¹ +JÕ~g÷p÷pè…Øv3ŸÇq7Rk¼½ÖÜâÅ *vsØ$w¡º&Xñ"¾äêKMg“ ‚ù$Ê„§3ÃÐE»Þù f àÌŒŒi³@±q’CŠ¡Fî1À_ù¿a’ÅâE0EÆ(K÷è“ç>˜èUýʪΒU„<¿uk­ƒÿ¯Ìz×$Ø×¼™ ÖubY†9B°;-}PþœøZ 8~gùø†µ7§·ì8Á¢Æg‹]S8¹prâd§Ïõýo¬96Æ+;ûøvÏʽËHo‚UﲚúâôqúØ·‰Ð~ˆ€û0Á¤¶³ìûà Á:¢Æ³D·óý¯I0ûâÁ†Ä²  ˆ¼±50ù•`F†€{ÞH}ÕÓ/5_šÎPn•³¬¼[GOÌ ,ļì†}Ç41Z“ÍѲ™öQ°]PMm•Ôr…|x«m`ÞƒA¢1YNt œ)v?ÐÀΔøé-Ó[º;¨¨›šzE®¤äM°X,öqŸŒ9ÞÑyãjúV-Mýf¨ü²üyUþ˜»[©z05©œñç¬/OTáÎ0:‰éêŸe**Ê}OqpU»Ñ]o*íû½1&¿¬”':Ž+Oûýïq\D^ðmîÙ0¼ª¯Èà1GÕ˜hŽEp>ONùØúX\ž‰`3¯oÆ0Û"IÿL°ß;l;Õ>J¿M]JHóÌ<Ü·!Ïq_À©ÎŸ<˜™`U]É{Gçî“73ö›`M*Wܘ:& àO01Ö5Ä›ˆ`ÌÑáÔ-ÚÚ“›x›ÄÔ·mÌ6$Î'ŸŠO‰`𣍠 Õ)¤L‚‘È¡Á½V|ºoø9ÙæêMÝ=A9+Ú¢—swfDM÷ÏT s ¤âÇo®¦&éêdzÞŒ©ùU>j#•Î(S1ÔÔ?¨&öøÓÿÅ>öCÐqä\â~ Ù³nÂ$è^Ã5cønX$ û2Ì3}Ô•9×[ŸÙU1,$˜•Lj`îT¹^iÁh\‹-¹d {3LQ‡&|LÑ4ññ>É¡ùš@urN ±5y{"ÙJˆ Qµ–è‡ÙÄúˆLTD›±Ílëý’Á¼Ï¡-‚á !z‡±þ åcó&PeЬEÃ×¶E°¹«£u®ÎßC ÛyG©|Z3 Ea7@n®m‚AG˜«ßyf‚5ß!‚#èùÚ%XE8 §YeMÚ"Xlaг;Cæ”öÖÏÁt& ¬Ÿ!‚Ñ ‚a•Ÿó †s‰Õ˜Š–ÊE°àÊu}"ãç';uµÄ÷•;ZS/ô f š[PÃÛù‚õ¼jJÏuÏØÁMUL0EÛ`û¬û¬}”ßíažØ´NF²Á÷†ª9µN¦*NÚŠ¥MÙ¬t¬Ø$Y*Ä‹¹ïŘE {ìw×½rP=H™ =!nJyàÏ2 :{|#÷úRö÷³nÝ*n¥:š9tíþ sÅš9O*Û_ yÛP±*ê|$¿X£æá¾Í ‚ ò+ýMUšÔÞ†}æç£?‹=Á´røZÇË`¤rps|êvúHű$3KRG\..·>6 Æ«\æ!Xý¶Œ8Ì;$™àœ 9ô†T³+sUdꆜªKÕ9s0ÃÖŠà@_q;C­D˜`®UËF°ûdâÅTI~ÏÜ÷/ºO*ŠÛ'8gçŽÌ>ØœÉÓ‚¹j+ÁP5Ô1‚¥ñÖ4ƒ`M/ë`ˆ‚°z¸J\Õ‚íí;O°š‚¯6U§~+Ø&~õ¶&Îìꔦ~৉LŒSÐŒFøX=Ygç4íøÜvöj{ÞC8‰ý/P ÆäêªHîÊ@°9±„³ÏV7q˜w²w²žÌÇ3%÷æ%Êó½îÇ“ÊB)¿ò³´mQW°ë½XKyIPMXKƒ/–ÝÙãÍÆ3*÷K•8&PƇ)f‚Ís¾˜ßy@šÞ62è;I"È>V·Hf?¢~P¸ž/£g ‚ñ߀ÇìË9fÇ›ÆI ~PíÙ³âj¸©"t•øb}‚Sõhº4xÄòVók6ã@°³‹¤4D°Žï Œc "äIÎ 8±SÁ6‰¤Z«P^ÂìTô}p`̵éù\‹å\à\&X\ësná CA‚Q]d éÌ2ç,L00:ØÔ´jª¤b˜ Õ³á‰`Þ™´±Û]S% y}®ísm¯OJ‰9!ØìÒj5!¯ãóÁhÜK‡>yà VÓ¤å)ŽcÄD°Î`l$ÁHíjÈ^(_œÍ·M°™ÇéGvÒ¨ ǨŽwÅû³ÑÈè¤#Z’{çÛî4èˆDbhƒ¡ÚÊ£v›À‰MíSÍY¡wòð–(Úä­7÷ñ И¢‚ÿ¿‰4;„^ ­”ƒ®Ò!òAœ¶YQ—=«~eð÷ÁS^žPS7±Oò´ºXˤÞW7]X8Ùé˜vj"´@W •_×*€3:KìGÉÐøw†U4þV¯p½n`{#<þ›ojj÷«Í¤×é¼›Ž5¨¸/n´äÑÛ(·A1 Œ[@ &ß7ªJx1^žÕö‹tmÙ60{Rþ9ÎŽ‚‰YÒ¶‘ö©4Š5 ¥‡+ƒ±“Ç]GxÎ dqhö9nnÍB°šˆ’`U…˜Û½ð…øð0ÁÆV$Ö$‰Ò¿aúú@p`RÕ‘`œ,ðy°ßBìãn“û^ùžµs*g$_ÿ2 ÆûNL§ú"öšd"j 2 µgúã7``8L0ïD5 ¶öÒ‰sçºÏ)†`ûhûh&èÍD0Ló ÌYe$:í¹]OªËY‚$e›hr(ÍWã+ê%Þɽ¯¹æKG¯¶÷·H™ùôf)£ò;öí©L°ùªQ1e˜¢T ÅÄ6×Õ6<½ªšNd¼I›'øC‚õµFí›ÀýŸzgýÛ0Õp‰ß!„sÙïµ»zG'OK;rÇÑÁúm:˪aHËf"ØÜÇuÀ¼™‘ö—˜ƒq×gÌ@0L½¦×F«˜ƒûå{F¤q Õ¨±ïõ †åíj:ñ{P'ï‹ÊÙ¥÷'ÞvŸ³ÿmÿ¦©J~·Qù ñ©R ârå¡%áŠã;ùN>FŒçØ);e¬8H0“ÛÁÊ3Á鞇–o¹!ÃvÊ9Õ9Õ¯)•„ q"O> ‘ËW[žÚÚjK죹" «Ôƒ¿ŸR}-Im?h¥bôÕLï0Q{“u¥:Ÿá°CÔ¯pls…«ƒ¨Òë¾'ª6¢ÉæÕ>ÐÅ?Žqª'y#µ—®-aaL·õ7å O|éýšûïT7çzur¦/­ÏÎHj‚29ïÓï 7*ªªôÁ¼ãŽ·ƒ}éRÈûXIÐÆs¸E’™`Þ\ÉŸÇíD6oHçÊmþŽìE‚AE| Œê‚vRÝA’É{''Þ–üžˆjØA~AI\i_‰lIE8<+ßO$;/;/ƒ’~íÂkz;A0žî1£Ú.Èàæ¬W™^ÌqmB‚QïО-m›˜`žý½1ª£Ú%8ñ¯âòÜû¾R7½ìïWRYæú_“`ÜÐ×ÁZŸÊsÖÿ‚¥?=NJ˜fÌÃ_&è5¦SBÎû9ïûóÚ‰³vabN“`$öŽZø'9&˜+ÊÍøkV‚Ùõ;A}ëÌz›ø ‘¯¬¯¨g³»ÖÃf×\Œm‚Š`žH•õ@؃bÒøê\ Ó¸|‚‘Dî–'‚¹j2˜æ9ÖߨÍÂHp?سæ«ü*ÁHbZuÁ¿©t°Ÿ…F5ÑH;QÏ—ôêX„üÜñ>²Æ@p ‚(Æ™Á ,ð}ÿ&z¥Žp_s_“*‚Ï¹à‡ ÿÛÁzÖ{$dÿJ°ŽÍÐ,z:mç֓ų,µ¯Ô¼:…ZX|ɧ»Vu[Q7O !Y¢&ÁèO ÿk¬õ°A°ùy¬>˜b¨_$ŽÿK;ÏÈç@e„ìœ 3‹Ô‰ g_>1ibªARËW÷°š`%ÞÜblÓBã}×¼ÉúúàÉ.pÂ1ã¡“¥ÚǦ,ú¹ØA\ fm‡{ˆ–‹åfåœà`îf!h§«þwu6øÉGÆ–œ£Q.èEí¿¢õÄ( —¶¹êÉQç»çµŠ nW=ej’2ÕW1 ˜»$ŸŒ‚Q2¬U”§ºÞâªÀ ŽOtì}–©¼_÷5ßøQ1¤&“è{ž?É?4Þ#­{‘±BÞ2ÁêÙçt¥;Ï|çIðµ¦N‘S6ZñKJNhŸ*SÜÊ{Gé Œ¸±QCqHƒ ˆÊ„8·:·vœ`cÿp;›ÕŒmlúà !XM’¶oÀïfµ¤8 ÁºŽö›«™0WM2œ`u¢Û8‚õ^9º¦á¼`¸ncè°,«¯ö FŠCóŽk“`sJTg ÖÙ·,³Þå-¾&Áh\OÑ " ­ v¯ï+þ0¹L2 ÜÂoܹÕ]ëÜ*Ùõ«+ÃWí sgzcã$׊`#‹«ãÁÆv¬€šàÓU†8sàëÓÕ:g ıeö ÞÞ=î0dvö¶Ø“Õ5õëyiN5ç[LÿŸÁúÅ‘4sJMM ltnBU©éƒ!šÆ9¼¯ìA4¶<à½ÚŠñ¤I™ £R&™¨7­êüÚ3«ÐW{6ÊÉ)îäßOmŒD>GÙcÚºËc¿œä¨F"jš`øÚaÌÏÇi·ºžVÂ;TüA*yJ͈¢ÙQé{™b$WÞ—¿ùµ0{«#£fË@°yšk`¦gcÆJLÊäª,¹ó3Œ˜É*—£&:Іq®kÐÚ;¨"`~ZG †WOg ÖqaÎáA^Ûs%Ãí̽%}g'FE X²ºRé m‚A-pgh&‚ñoãutvŸsŸc? y;7îÆ™`4$˜»±!*ÃJTtUZˆ(ÞõÉWUÝ÷ ]ñê+k¸j÷²Ëë8û=<¿IžhBµVœÑ0"Y˜A˜`TÈ÷e‚íÜaP1äÜâNs§9_“’àÝÈæש9ýU&Ûßx «=CÑ;½9V¾†õ”>ÐßF6_QD0O9Çz&"UðpÔ+üg‡ŒNfpHÅ8CH-èÌÓGAÓê‚²ÈÆ9¬_€jRšà@F#úŽî Eå¿p2ô£jH0œât<‚Uo˜#5¢<•>Om`‡cãpq¹ý%žÙ®T¦¢¿Ž£ˆ•Í'J#ŠÝáÒ$ÁÞžÒþÀ-N$XÇ ²Ôo˜2ílýäuMºI×ùS 5 Ös~93òDPêWÊvÙ v×H›î –^x¹²0ÁªîMÕFt–`üÁ:"Øï:&ËB°®ç 3vÚ"X“¼‘ãœÉ7D‚Íd¥^;F°Ú1ך`|;D0ëa“`çki¬ƒÉ÷vŒ`ܰGgå¶}°Úx˜Éx»›ÙÍq Èl`åãí¹§×v«~ yœ}7ДsuÎÕHÐ µ/+¢7(ÁáÌÉ$ÚHÓ—bL°¤7¾Y|³Ø­Þ`é…8_ƒ–  ß&Á´6L0¼Š bÎ$R×âÿ¾ÙßgFÑtŒ!D°Ö¿\?ÍÏJнóÌpȬñÄ&Ø'Ô¯‘lö#›fK"Á\‘#oõöBÞGv¡š*¥Onψ´óº}šYI‰ª‹hE°© ‚Ñ+ƒ†,ô‹âE¥rÁSµÎÇ”=Vü~í<f­Onò-/í¥}‚íÕîÚØÞÞÒöì,Áf­V€^8WwãÎɨžG†zøQ&89·ü¦²ì]1ê!:H°®@ÿkß`œ80q`|­døPO0þ,2lÎ]ÏD0+ ¸ÏF°Š*¬fÞ+‚uŽÍ 5p‚¹ö6Áª–AÕ“µE0ëáls…öçH°HÛ§1Á@(l÷s®‘^øË0Á ƒÁ€^°X||²´{â]b{K, ŽÝÏ]*h<‘ âßÌçêÔ¬X‡:wêH¢Íˆª"çð[ª:ã­!öºØ!±Cœ\åh\ÅAQ˜Wh"DŸ®Èÿ²Š@v“Òæ»EÞ›‰ñÉæÔ¤T—øp ü0ªê]ÖÓùFÑnûQdTQ¯c$fµ¹9}¶„&ZóÃðFG®ÿe}ëw¡ôÒ”Ã[4»@1Û¡ºšu·½±+Ïi_¡ž_‰{㌞!Uá×ä¨80WC¢²âžS4êÓUirßé&Pã®ÈãªKƒj!Ž ÃgP½g*´™h<ýq&ã&û{W{Wç|÷÷ç|1FŒ±Ë¤í¼ãT¹ºµn­zŸz¿{¡·$v™×è~kŽ5ËÛËä[Kä³W%vŽ}ã]å~û«wU{³¿€3˜`è»´0ÁÒ~R»ƒ6–`|MÁñºä'éyƒòíôAɽãkÛ"ØŸE¼á›ü˜`kh›`Ý/—…`sFG ¿Ì]E›’`­)¦°)¶7Y+;SƒòG$V¸ØoJË@°s¾ºõ–$¿M]» ŽO’K‚ã}$Õ߀)‚cߨm¡‘ÁH0ÇLL†[‘tç&u!q_3ë¾y¡i©æÔèâŒÆ¢« »Èh|îg±ý«´ªÔ,÷RWm©#¾'H~_U%Æç^›sш¢Sóç€F% CÇPL›Ó\5ÁôJÂÞ=+–(6'ЭÀD=Ù„º9Cû¯>ƒàÐç›Se˜`ÝL“ªõ†osª“$èµ§rtM< d×(¡3Á}x"L™½Yë ™kM'ë x£"³Á;Jj±ŽÂ¾ÍÞÕZ)nr÷Êÿ³ô¸ôÍÀ¨¤(>[2\%é•${ã½ññÏŠŸ¬8=oÒ» Þ“Ö¼-±s[G&Jj ŠÕ,rµ+¢=‚YMl*‚¹‚Æ^)"8V¿0ùIÞªÒ­ÊÿS¾¤´ªà„T—ÄôÎŒ¦'Àù}ÿK‚ͽ&ÁÑ?> XmM0š&¸°kÉÈÜÛ`o|l™IpbçÄÎÉÛà!Ñ!‘ÈöŽÎˆv‰v‰Ü¹_mý¬ Öš€×Ëê¡,zYo‘J»-ú[t·ý¦ÌšÝMÿ6?‹~¹LÚã‘Ç£GHËQù<òyôjiý£ý#“”EWH“ÏE>·¶žKövômQ/êÃÜÇžKž™×³øÆêœú¼šÜª¹ÅëRKâç¸/ضõ„˜,&[Ë£À¬^V¯ÈâÈbõVt>ÞRYd†ÕÝꙹ(rQ´‡´¥Òàþ‘è#‘ý"ûéëé=H¼%ß'úâG£‰Í•EïUù-ò›ùت¶ªáÿÏ÷Ñ iò{áï+òbäÅèiÊÚ_¢¿XwFwµv‹ü€ýñ»Â[dò}ÑWÈX?Óçâcx¿Žüšôqüu¬Ý¬Ý¨ßþ7x,oñ÷e‚q|ï éÁú‘Á~¬ßW7>ûê ßðVKôC6y†nˆîù`ì  ÆOöh–s¼›°Ÿ¶GÚ#ÅSŽ‹6×™ëå‚9sÝQî(x+L,JT&*c…Ò&*ãgÅ ãgI›œøþ¦Ç'Ç'·Ep䟒\à6 ÈÇ&Á‘ªHÕ†Œôv`¤¸‚ ¾¨žÝ4¾yYÓ_j*¶Íí;'Øvg†¿šÜ,#½!‚£K%õÁöÁöÁÿ—çʯó€`<ÁÎñ¶%ŽÈDpüØé^®O0+Í X2½ØM œó]Îw@/XÎ9 ® ЋYZ îù=‹émýM^ƒµ&‚·F~5ÁŠTi@-QŒ÷Ÿ+ó –ü~(>t‹Å/§ÿY¶gÏú ê3¨å¦Må‡ä~žx‡ ¶z1±@°&7D°&“½©¤ý1’ª–·€§Æzá}üqx]jící[û(r%³ûÈÛÝ4É@ï{þ-y=ò:PÔš3­4¡D“Û)l¬ÈÕ÷’\ó>L°ÞkÜOÍ,Ó'Q"¶hiª%ͽ¤±@³š±Y 5-èwˆ;ì§%¿–ôÄ’\ Øjc§§?ÎûKü x,^€ôJóFíôÆ‹âgÁÉi©ÕÀ0Pœøš †{&Xg;I0P&úwí™ÿ‚{ÿÚk`õ¨ÂŸþ—ûßš`uïl½f÷t.·{n,Á‘›Ä^¢NÝJ›`šÔ+{E÷²°ˆ®÷-rWä.ùÌ^ð(ã¼)î¦õ@0¾Í¤qôŒˆÜ„Ü"¹ #"?D~@ÕþÁ5ÁH³u¦þ|øZg*ÃÍÜ<;R’«¿Æn -H¥¨ÜÔ±z‡üd6šOrî?¶þÄ †°Iö>çwÛØÜØ­Î×ö•’\ØV“Q!s|°u°ê!³|‚¥YÖã  ßÑ©r{'Ç&ÎKœ—nŠ—ÍRCœêAªà… ~`°Tƒ4É.˜äxuîÚ0ÁÖ–Ö–›’àÜÖ>]|­óh{C^*Á9Ÿä|ÒÁÅ«ŠzoßçúÞ·5~T¾uçÖfÌš9ÁŠbë01;Hp¤^ÞîE¶>h&ÁÀ°ÝÓ'8rfôm­‹ÿ‹ÛØ8ûù3½l!8²&²&Lp"]vgÕչݑaœgÖš`È0Á¨…AKÿ›wUMºq\Mºð¦ÄyÞåc§KMLú7Á¹ks×æÝ“wOþÞa‚Q=ÌP':>¡±J0ãp’ÓäÊǨ/€^ õ7ÒÃàƒŸ-ø$÷ŸN7|_ßø$‡™ê‘Nnâbï û'R ý}js>!51 ƒ_PnÔ;.¹¥~t¯>-W5]U3ºhXj|âŸîINLÌ})R0¡µiAô¢/6Æ’ôbô?F’+ïÅlu~8ü5ï2}/?û3Åú$÷æB'9¦ 4É Ü³–•*OD>øYóóÉû¾ÏÁî£b½Ô{!Á¿)¡|°O0ÏíÅo<Û'œIëjÝaÿ>Ó0&˜T„ޢɓЫ¼¯å!Ë­–þ÷‚h…:‰qŠ`ðÂùÝ Ž*9µbÛ¢ÛÓ—I‚ó€_1 FZMzf¦—ßÏ*ã"“Ly  ÷øX~ RÎ$³Æ1é•ÿSø?Ëÿõ§àXÆ(ªÝ~±aE1ª†]ÕI I}%dᨑË÷è{ßMÞX4»hvòF·'ò[ï-OLËïRvjÕ…U3ÊnɯK<; –˜bê5 ¿©?£¡"i ! ŠJs÷q{Û Ö"E0sLWZ•¬àô¦6ü/Ø01̾ǾGy^ W™Ï,ó oÅOŒ@†G$ÎK¾‘âÜÞyWî\¸sÉvEŸõ*ùªäê’«K·ß”±J0ÞkÿÛ1‚Ň셓¿åÎÌï^ºoÑí©±"à×$èl`4Ö³œ+Þ‚ññžïW³Œ yœ7%~£s¹þø_Ä^K°Û³ðÐkš¬Áÿkl_žWÞnïl+O Ôþ—NŒHþË$8ÿ›¢ÛJ¶+½VòûUùò!•{DOµ^e‚ýS™O0äçZ$#p@ði¾énG~ 6)h‘­¥Af2ʇJ=AG…´§¥Q†饓"¯È*á´x¼±iÉá©éÒ–$/Äšàw¶ûj•‘0³Ã”Ñ`"UŽMrÙê¨Öö„õ>×K~ ÇIèÿ¨¢gÒˆ`:Ó­ç“DáDªÔ½|urT bf¿Dnм¨2*Ó!înb:ü…x’þ"g@äûÔ.—scýŠi¼¹iDÅ›±~¨ –Ç·K¯­¬êõpß¹}V´4WÞŸ{ŽÔû‰õb½õºúÚœIz#³"³4Á“ýiëέö`¤õ<Úãüž%i+Ù…­’j5µ„èŠ/Ñ{³. ¼B\áLµûÛý©`î@{…¼]%½ñO`àycCãwƒ²Hî›Ü7uqêâÜ+ò¾Dücñn¥×–­®VyOíÖÕVÞ³)Ö1Œ,缘óbG¶æIËB°6 v–;˽ñÀb¯z§º/lÁÊ÷ †ØÐ*ŽGš[Ëíí쯈áåÖr&˜ÿí ­¾ø ûgsgsˆpå¬Ûš`ů³9Ä@óû#iõ1ð¶]ë—»gÁ–é;Ý¥@°;Á[žºµ4Ùãö>#{_ѳ´b¼wÛ"8àƒ'›üZ_w†`´Où,ך` — ¶W¸ÝUòÑöÄðÍÞÍ&Á饾¢ð&PÅ»•Ü ôÖXûxc¢þézaI;Ã:C”Á!B±F‚³ÍEccr™b³GÌð½ú1VZý­þTácVö<¥|0Ð Á}"}´Š¨à3þÞ?´/‘¿u$üplæ’çH3ÖÙ ƒT0`‘£h:sažÊB™¤ü.²/ɯàÝ’œ[ ¹k0yÏ'6~¥ÁÑ·!o!ß~s~Þ.@°ôÈå?ü Ùi:Çü:øW8}å’=•™x]EÓÀ0³!?Nžßªqò÷®ý®SæNH.:²êº«s+ÖôP>Ø~@ìÅäªÏ—›¹mq"GÕ —¡6gÑ®,M/œâ¢¥ °Óá ä·VGÍøD×4ëë X\K[¾—ý°ôÄW)ᮊ ?Lø! 8ýqþ5E·ÝV¶yùÁÕ›½‰ž…= {Œ‚£yâM&˜k:J°õˆõÈÆŒ§¸,s­Z&‚Uf΃u†`¬F“ïï,ÁŠbEplmIeáhï¬kƒ`V :gÇy;ƒ`ø«k2 g4÷ emÌšX¼%Þ‚c“Ók »Y6¤`Iº8q¢I0~4ÇC›»67Áà‡³ÌÑ5ð¿™ \~pŬÚÇŽï1º¹²y‘´JÕIh]ý8úqΞ h)«öUêD'Íu\Èb¸Ï»Ïcî‰Ø‰9ñ£â³“±d,ýrîyoåÿ³àƒ‚‹ —ȳۺz!½ïÂ^c{½ß»©åâȇ‘™à@eO ÆãŒ÷!‚qzT†Øhd“`¬õºÏABT5ÁÑÜœ¹&Á¢¯=eS,JíóÀ€`øúÙãHM¾Gz;I0üµ†ã‹¼1A‚­IòQ‚1§!UE¬_|J|D|„äwÐ&XÈ?SÀØîXiY†3¬vÎg'˜-L0ÔA@}°Ipü(ɰ$8uR^YA]á„‚Šz÷-¹–b~seËG}®èÝÔ{YäCîæŽ6)Õ •-Tõ@f9T]i’kÞo(Á:ÇÌ]îY–·ê„ÇW`ª'-ñ¡½ªe¤ö§$x¨4 ítëôȨÈ(¤«PRFLB¶Ù‚Q_Ö¤QL¡‡!C†—«êLøºÀ/2,‹Rioˆ7ÐÿÂ×gõÀ#½`ð8z.úß§E Iæk FfÕGϰÒ^è-tFÙ®)F"µ“Z¬Uä™bP K¥ÝìÞì +€^ÜV(鵞’v„xj™^û#i)‚±v²«Ýv›Õ–êœgTÿp5å6j’5¿­ãÃlŸIC‚ÃЗ¡jÔT=e‚•Nçç½UðAñ¤’¯Š')‚«ÿ^ÿ´Ô‹z_Úç `Ø$XEÅH÷BœwÙUÚFÉ!’Û!¨%~i¹Ò@I0a¬o‘Lñù¦ ^%&Áã"¯GJØ«z4E®¢7Á{3 Æ"XÉpB,ú‹þZId!X½" ËlW‹`’w˜¯ÝGšA°}¼}<’Û`7xW¥~Ï{(ï¡äéöCL0zaƒ`ܯIëýœ8Íê}HÕ¤©™“j>p6‚‘â¹T%¬ø­ \<©úÁÚ­+Ö”~§®;¢1K,-r1ꇋÙêƒ)²¦«Ø©S3ò×È_ñ–'Z3Á*‹¬Ïsà{wUþ 6{ŽX¦™ßÆØƒ¼]¡jyø ɉä˜:ëf0žªjÔ”Ÿ“žn((E\é‘à\d M“ÉïÆÛš5MºRÎ:Þ‹êA~í•é¯+_%¢TÞž«jØY9ä¼¢b½:ú7Jej”jºÁÔÄ`¯s…:© &w/&Š¥Ï”Æ¾72>2#ñ~Å:ŸÐtöø3²IdGHvåW#íyîw}±²ä¯•‹ë¨‰óÖOrE;éÞ1¯§O!¦9šö˜ê*_̰Ғ¦¨ÁÈ.Ÿäæê"-^/;,‘6;uR:¿ ®ô»ú‘=rk.ÿ©tû²ªî«Ù¢Ám>¯©TêˆÞ½/m‹`ˆ=`Eeˆ`ÍñF ‰l½&Á:F"˜kÔ2Œz•fŽÃ£Æ ¬Éƽ!G;£š¬rqí¬é…SÞiÄp‚!ƒ!è^õ ‚•šö[°ë¢Up‚½1É‹ n*¸)þ½"8½Wí×=¦W]’~»5ÁÚ·C0vf š ï ú—æP2Á ‚u§çoAàÜ3 —TÜQ¹®r]Ù e7”ÿT¹GÕ}uO5Žª=¤ç–Zy&"Z(‹ÌóiÎÚY™¦Xžã¢ßËóŒ•ÙÅ{ëM®4Tº‹ˆª% ‚‘â>Ê@9ã|xz5ÄÞ¨<®i@Ó€â缿8Ëœe±©é?óöOÝå:]ÑN õÉíhå‹y‹Lq´Uª¦z‹rc§½Þ£Þ£‰cÇ&Ÿ•:âœüwŠ.+þ¼øs`¸rš‡ëG6Ìë‘Û\)Ïs›œ``xSŒ>¸ ‚Ñs|¸ ‚ñ$×ÁX"˜;èõ©¯‚Ù›»ý’wÆwrZ ëb,F'ö mlÌÄa¥B'f YÈÝ!ÉYFí"¸yZó´Ò‚ØTðÁ@1˜ä÷ÏlcÝZ‚Ñßf }1?o y¹Lƒ1Á¹EÀpaÂÀpÍõ#Á$ã{ŒîY=XYä!k]9ÉQ4>ѱ%¬S¢ÏKûDƒ%ÁJSÈ[£Ãú–E5Õø°ªàÜw×sN²°%EžhTmÕ•–Èò½ºw]uOîÅ.Èq‰ýÁr ,ò}ä{óä¥ÕÀÒ̦3 ÜÇEÇ€¬3~m_ûjr •ñ¼蹘?1u®3KÌ3íƒU¾†ì*_ÌäÙ@,*£ûRGÈ §â28}刑ÚÿB\A’ ù‹øv‰iîŠËù¿¨¯Š¯ƒŒÁåHö·†šüÌà»íoÓÛ–Ô”Ô¤vs?…“P,Þ—ö xPW³ƒ›w0úp¬êéÀ\4ÔeÒd»U¸ÓôEÑ€mÞÐG·Le3b¨îI(ƒzwTbË¡fB@O=ö /<°ð‘✊1 S{®iT»¬f|}ÿ†©õ+:C°uŠXhŸeŸe-°t–`ë\é™;@0»!;5N̓`[þš{èÁά؉±%»’`xÛs<Ç}3>ÞC g *v6„` çN)ÞJLK®î,Áâ*wçØï±ßK©Î·VÕþªŽÎÌcü!ÁŠbŸà@…%ì'Ê@0ôÍ1Á¨‡3œwOA—ÂG þ^:¯º¶nRõ5ã+ÆT×ÖŒ¯þ ò°+é•÷º‹ˆ£g\Á. &©Úg%Î̽-Öd—X¹‘¹L0*ˆë}‚q:ÓnÖt$˜ü¯¨¶Ç™ô¢½šdS1ãW»ósܵ÷>ÁŠaé÷wÞ·ÏSÊ´ƒ4"X+‹ðI£h‘î5ÈŸd®èQ'6}n#Lñ`iš` v¦³³z$6˜{Qòµü¡ÅÃZMh‚ñµ;øýEM"á~NÔê–ã¶#) Æó íLðÂN=TK &;„lk0ùÕú“ ‘¯ÌppFã<ñ>f¡›óO 8² 6²Ìè‡a¦ÔO=JÌ}ÊÐíy ìp˜Ã3î@¨=“êázàWÚñËpŸ×ç¹ Àpl9ð ÝõÐÙ™þý…[Ï.©ì¤Òy¥óÊó*ÆTŒé ÁÎÛ…›7~×0¥à缎 •iZA¼.y µi™¦ëì<“`|†rq&ÁfÍ-äÈ6ÁÌ0ª®* Z[½Ö>Š`ðÀÉ×â©TÿôÔX­òÁíìs‹ÝÓ;J°ÊÃQì!D0|nꀶ!‚ñó3 ©#y*‡ soG&‚Ã>XœüWꨦìÁ’ßáØ›¼'0\êççÃåyÑnÑn@/j &—»ˆº˜fäŽ-اviÍE雜óÄéV®ÎhpFϤÝF“O乎«Ü#¯XåÿRø‰•êÎçýÇ{öÍzŠMqÒôBt-ºûÆÈó‘ç!§­Èõò–¢`*G¬²ÄfæBõI²Íêu¨Þ1µ0‘jWÀ_¸UoÁ¿ŠLËë€Ý L]0f½?>û¨s˜´1î›öK’ÝùÒà‡¯Mƒdcž²‹DË[àNfYeˆAø§9•¹°^·Î¤xwÕó=}>Æ€á÷Yô2}º3*'YENr“•ÖQ5R"&bÑÙò6¬{IÍl0éÚ½>q_r_Õ§FÑ4&9Ö¢,þEü‹Ä”Äœm")Îß;w­êð,™S|dQ÷¢îÅG–Ìé Áb¡;6ùMz§Ä—±&·fÃÆ:´,’öh§03Áà¹Z±-‚‘aƒ`³ælCr™]õ¶3Ö>¼rˆàœ_äÿ H^OÏçIl¬â™ ÑÁ˜c3VÙcgœx‹âɬ£Û ˜O™†“ÜÆÌþ8H0ôÃAZk‚¡.Â]ì.f‚ã}ã}A +%!ñpÉð 0 n#ûK ¬sq&ÁRQˆ…N…Sï¿WñaÉk¤¾™jÓ8³ÁYdƒ`Énî>jç$§þ>Å|¯2þQìB{´ÖÆzuMªîöÈ]òz®Îp\AG¾§ G šF¹73áê&ŸÐ˜È­_+¼º Þ¥’Y¤Xœe/Bš9«A+¿KÞ·¼Î×xZeú`z;Iµ=câHèùL0Èà]†g±þp*s—æþ‘¿_j§Þ'˜3Óæ+@åCÄÓ¸»Y½LúbùXw¿•Ët’Ó“¦xŠI0Uc† –:¢):V›^à~Î5ηP5©z•±Ûˆ&ÿ9Ç“–ãiNÒë-‚å™n»ä´ä4©&ÀÖB—½<Ù4w†`ˆEÁ/÷\öœw±I0êáMH°äwQÁï•éÒmãÙ/Q«‚9ÿ&˜su›š`«P2 $SF#L°ý¨´nÀ¯R;™¶_’^™Æi$Ap¬_ù «Êψo§¼p ¦aúp¢xS ÓQijâÙΜ?·èôä¾L0צ™»õR /3 Ɖi«àÜáÀ0L=‰Ü¹;gMtDôOiwª “D¦¢c „ç•üZvxú/N®µÂïÜĪä?ç-Ý•O'AÌŽÌÀzͽó‰ùÕÁ“ø&Þˆÿ¥æÑ¦·ª÷K¥ÅïÖíÖíѹ33Ü5¯+ع2ȨŒWÓ[­o­í#Ÿë‰¨F…ª]­idHª#¯ó©ŒOŠH(<;óÛ‹`B‹¸ì,2ÔXwiÜKƒ‰)û˜mÌù逷83afÀ.S¤éhŸÌpõ,X¬´à¦’¥¯ps%áRiØóÔ‰OUÿJÕ )ÆY'ð9ë¥Iu‚Ÿ¤4¢7Doˆ|g ÁJô5ò6/hzªê86¥sÝÝí/å 6LÀÖËAª’]W´«Þ¢{°Û^>v¯O’ûd|wìËèïLõ~r¶Ÿ¹×c§dénj|`ÚªºÇÙ'‹’ï§›°ëþÂÜ Óï¤ßÉ­•öA6‚¡"=Áѧ„ç¼;ß#æu–`ѽã[§;5ù5%׌‹ÝÁº® ‚5“`¤Ò XUÌ›‹q&ÁàSQ³ÎSy г»hRS,2 †èžŸ`d8ÁXG†±{{wçÌ“RF³]gVè¹\{¦ª)¢3Áò#pö“¶¹³ùÆl}ì\“| ù€»£ô¸4 >É]C÷Áòv˜êP–†u’ÛíÉ Ã FKEü¼šìœ¬‘ WJ“§ÞL½™>ŽÜýÓzPì%QS&¡«b½1ù÷6|„ ü0Ì'ž®Š¤ªI] Ï3Þ»„Ï‚Tóv?õ‚Ì éVL0f! Qê{ÒíjßKüî¬g;„.˜`ÌFo¯ÌŸ>X¬ÔÌ„’',M0ÄlÅæÜõ£³ÃÛ%U 3£ÀÛyò«J³‡˜ƒ¾Pµ_qjPa°e X ü*‚• èVIì b¸ÁêVW²³© é嬨 &X’êl.=ïzg?·›wt,áÛ|Rÿ))ޮޮFªÙc¢'IãùÖÌ/DΚì/c»º+í/ƒkŠ5ÉäƒÁ>s¶çʤx{ÕwÏÝF@0LûÃjK5µý,˜Á ô&k¤½š®”^¸2U–>?õ&aoå&h`Œ$<…ОêÁ¸SN3œ3½3‹Ý£?Â_“`Õ×Ö1‚‘ÞÁHêzškFcä¶+õàlÿî«g,Ä&¤ß ²›‘`•ëkM0*ˆLò}°ý­ý­I°ÖÌ!‚uÍ/Œ&TôAE˜¥çÝO¬ý;õrò…¸Í 3Á¸5xµ²Ž,îZ7¨"L‚U‡§ºÇ÷Á— ŒÏAŽùyžßîù­IŒ†“¯&^J•¥ÞŒÞÙ„õ ½•s5ÝŸ\mÏûÃ4‹;2ybŸY¡Ž;çßÊyKL'Áý| TmržZ?V$ç̆å­RÂ¥pú¬œÈ€`œT™ÁÝó™u°u­&˜Õ“Œ3$­0–ŒÊAùd¸G_Ì=¤ãÔT+Ž"h?Íäæ‘/^å s†Y×¢ÿ•,Áè‡Á O(`“àÙp*³qÇÇ‘¾©ó¢´«Ðó^…g³~¦B½-VkfQ¶x¯yZƒzbÔÄ®¼ý ê~ì½Ýƒ¼YÉŠ>/ù.ý0 ]ŸøŠø‰LR¦ŽÌ‹žd½„[|`£‹J¢Õ„õ±R’â5¨=nQŸ/Ù½_C´oþ)zƒ5D>âêvè¸ÇÙ¾)l? ':¨òÁJŸR0oLdE›Ÿ:;ùª´¢ÔىђßûÁR u öÌäiÞQÄ0çÙ(–ÀSS³©¢x2O£¢~f“`=õ1Ñ,éEŠ1«&ooŽ ‚#×G®ï,Áz'G‚}í›`¨õU10»çØÂKvW¡µAp@I+ý«ü/Ò ïSü^ű…L£¿ì Á`@°í‚ù{³rÏ)û¹Þë1¦êïyï&Nt»)†7ÁLq[«>9ÑGÕG´M00ŒóÝÇç'FKO\$%#ë"ëð7ÎùOnÖtç w›Ð^ £žÁ$˜66sE>É¡ï•zA8¹±ïE!Uûä\å…ÙteÎÎÊtW¼Þࢶá¦ø»ÂÜ}D³ˆÍn}#ÁÔ²²ÈH0FäL:¬Y½ƒì›‘^ ¸¢mö"TJM˜æ«õÇ9v%È?8|°¸ {Ø ^lª¤Ø ˆvf:3͉'aãSÄÌ÷Me.T5&ô6Ã)>üoÞ»5‡öº¸Ï_úü¥×ŵ9Kbÿv»!ÅH™")<‰ŒV¤Ê[ NuM-#5#ýL hEj‰` æ¯*~¥'îo÷W`îºÇÇS%›rõ4a4ôÇÉx2vBì 9vBv‚­éè;H0ôw–`ë ñZwôÂ3¸¦lCFŸœ`sbŠÎáe c!‘`­‡‰`çvçvû'iD°û¡û!ÆŒC«ynγL/[˜`{*X`Éï ¯»×t+ Ñ03Ž€?Îq3¨ûU£&‚¿É*öh~øU Wý=õ²w˜<×u³×Ùë6V/Iÿ›`˜Á“‰àèêȵè»Û X©ˆÖó ªÎ¬,ZiÅ}oXµ:ó@Õjf*<£îM‚1aö½A·<Ï|ϰA&°½  kç—ˆCc/¥>H}{IŠ'»S”‰R8ÍåÌåêt%6&’`"XÍuhŸ`³çh†s›Ï¯´Qni&‚%¿2Áà™`˜U½!˜éUÇG>Q¿}mŸ¢#ã_;‹z袧™;lí ó{âÛ>&¸hv‰W=¾z|þ}^#ì×ÜTc#D°xUZæHÌûåtApü¤ÈÙ‘³%¿¥‘7¤Ce:{à@V˜ †ÊÈI:§¡Œ;BÙ`ñ‰»ƒwƒÝWÇØÐÿ‚y'UÑr]Ëu•Gx'Ò`R©†<@0úa½±ÐœPâovѵÄÔÍÎF¸³‡ Öó/÷WYiÝã1_ ˜ªÒqùaœ¨²Fúß›í›ÝR"øU{´=Úyéí*MìüËù—I0ÚŸ`|SƧ:îCÆŽzèGÆx0Ð+mUüÏò¢^]{u­|jØ}‚íj5µR¾õTôÀ艻LuÖ£:ÁY–éáUöz¸÷“}Ý>ÿéóŸ–­jš ¶,{©iDóƒ¥nì2ûlI!SÇ':ŽÁQ“'9M°´èþÒPk§òÔ' †S “\Dfð«è¥®£oÉ*Æf˜Ù…„{Â{Ú{:~Rü¤Ø¼lcŸÛ+AkU™ÞšF™…àÜC GÅï0V»^ns•Ueå¯p=“`¥‚}ÑQ‚ÕìlŸ`ÝIÉdg ˜+4¡ŠÁ$;ƒ² žzâ0Á "€`·Aì] ÑïÞàÞàû`ôš`g¾´ ƒÙScwçw©n¬ß¾âl“`¬¦ìÁè‹ËÕDl˜ÆÚt_ï'߆A0-;õséI•çv¬Fê:A0ö'#»>ÁÖKäË;@°šâ#o‰`Ž3Ájçí92öމVJQ+é-•fúàµE Àð¡Ê˜`•MVÛ 1«A¡V1æò>æØøÞ JI &–Ïá{º;sâEñ"÷Y;*'C©|–£¸°ó>è ùxBp³!wËë}Èæüažàj’ÌS¡x"œÞ ªFäú4ÏãˆÝK”9k¼@°»˜<¹ÿãÐëìvuþåmåî/íCˆJH‚åÉλTR|ƒ2&Ø9Á}ÁM½p¢›gL4‘ç9bØYå Mìwþ~é;c“¡ C”ó„?½E Ç0³žz™Õ´k¯%öEÞý%^Ms]ÿò3 I¬ôZ¼è¯ó–È+|,ƨS™¢òÈMÃy<¦’[dŸ­ÎÀ¯ûA¢¿[‹þ¢qôuñ‡ôÒ™Žy¾BMeÅÎ#é‘s&ôÒã󤑎V‚F-ÜA‚#[[O›#½YÆ}ÌKì¾ðŒßûLlw—ö„xÂŽØ>ɵ&Øy?ýkúWçý Áyì›;I°Ž w`ûf僿òü¯A°w0˜¤x+é%Á±ÞÀ®²L«Y›n,ÁöTg×FÍö»ÞÄøw)žäÚ!{1&©Ú “`Qî,v{zÕ«AžÞ¦8ã`Ö;ö'Um<Á¨…‰`ë%çüDÿØ2Ô¾Æ×m`=Ó‡sv4;8`ß\Ž´ÙîlErtQt‘UëŒÔâÔê Á9'+‚ýhš<ÉqFƒ³ÊÔ¥¤÷ÎáɆ“e9àyÚ°¨¢ÁÖAxŠƒx[‚¡Â'qMâ“`=7}©Ú·¥'ùQw¨ÖÁa3çšqEŸàˆdˆ 9‡ÉÛžÖ{öR·ÎÇæÞ #½`¥Þù@±û¦4yÛÌ}ˆ Fj‰àXïXooo ØûYQ¬ü/Ы|±3ÊeÏss™aпš`ÐPÁÞSÍÆúIžžšÉc|k¬bnOwibebe¬Ÿ»TmŒçÅ«t{‰ŒNrŠäè ŽœéÍæá 'ÊKR9 ^¸Ö~ü²V'`—Y—ŸÅ¬ÆelL°Ý_Ÿð(N © ûˆ§¢0Áà‡ÝÙ&Á8ojzáwnØË÷qmo;›ývèo] ™Æ*‰¬C'Ôß¶&Îö%ëoy¾zˆ`]¿«{,ðÿ|p˜`wï>0  †{à7~´¼=ÜÛÊ{L ô2ÁÞÏÞÏñ=ä-<>¸•må‹Q±RoŒ"ëV˜JX 4Õ ×>Á˜× Œ½tòë8ãÜ¥±~¸ñ¨Z?ßÁÜ×Q‚ÁËó`øå0Á¬}ù1Üê¸0Ðm¬¸Õ:b. æ*À|†Ê*crÖt{sk:ÕXþ¢wÖóDkÞðbÌ3WM²q®k#xŒ<Ý¡¾€Œ3ÐK$Cö‚³˜MÆÇÁ9&Ö¯öžM)v‡º2ÈyÀÄwsïU[r%$VL`M™|«%}ãlžË ݳ!r'6E“VϺg{•^eìÂØ…L®|fQìÂøG@gìik¥ ÷nñnqWƒÁ[òmz|é‡wQ†zãò­¡±»ã#œA˜Ï€ÓÛñªˆ+s”¯”ìò„ëé°wß È]E\©§¹šS§°êÍþgCµ×a@ÞÏ8¹anŽbtÃÇ@¤ÖµC‚&½ô ­:àñ3«l QÝžÖ%bÛ ÁÜ?ëñ”86†;Ç»]Ü.öti땉;íõÞ–Îü¶S@ö Xìyû1q€8À$Ø•*ŽÙ’á½€áÈ/zg};óF®…ÈF°øÄÙÏrD0×°Y¿ª:ˆ0ÁÆž›uÏÛ¯òJÝ5H0Ì\S;A7 ÁÒãëÁÞ¢xc²OÞΩ-â{0Áñ{â÷0Éa‚á>3ÁÎ*˜Ê ã²\®¦©¢ßÌB0VN´C02ÌXá-ìõˆ.kM°s¾7ÞFšß”·¯F“™ö«z”~l¯ËF0˜I0Òkl¯w÷‚ÝýÜýZ\8Àµì­°:øAUÇ#öI¼PúsªØ9*Þ3Ì›õóP·6=ºdÖ˜VÔ¶ì[™iÚo z‰^¸i?ŽgÆGgXC™Zßiö§—Ø#âÿ‰mKU—Ú+25¹+h‚ Õª)rU¥%Þ·/Ö•ëÒØSä •ƒ¤è5 FåP«õ%.Mÿ5ïG íeÉ.ê^}ò» ªˆŸA +’‘àä³kÔ„_ 50O™¢ISjì¤ø\²éæÄk±^UOúûû>©÷ó3ßp>„ÎZÓô@ÁP期¾¹ð€ü?㓜óÁ÷*,­Hò›Œ&#ßA=<ÕR¥Ãô™o5xcÌ'•=º Éd÷)iÛ* “O$ÃO½â7ñ›½§4"Øy–á¹SìS^ä¸bsï8 ØÞÊýìÎJ¼€>x=lh­"2lonφ™ªÔ¢!¿vDE(TŒ‚ ¶¶ä™ñÑБ™‰` ¶5Áò¼´o˜àHŸÎ¨3›ç×;t”àØû±÷ãããã—&.M~–ü,q¿²de©Õ}âo‰¿ÅïIÿ,vGâ~E:2L§;¤Y ™`TO»£M‚1±s?\{« œ½GbEý•ÍÓ¯Ëá~€ê«…9Þ;DÕ9d#XÕ¢ Æ™†z0 l Ô²ŠP4ËG­N–؇€ÿµ·’ãfok½½Ÿó¨½ŸµÞ¯&ÓÓKà¤g«wÙc%[â…Üæäùm·4¶ÍA¼¡»3rz1˜Iø–âPM¢áw±Ïøv]ã¾3VZÊ÷ã¶ÛÍ÷HÃÉÙÖµ\U©j,¥.–$[×*ƒ™˜Ê¤:㾫¥xêÀzíÑòÔ7_j†5?»Ý]Õ;õ}øåh†ÍÀ/R<#9he~Áð™ûS[¤¶HŠDÏ€ýG±µHõÊÇÖ*½ûݻݻÝÝYûá„Êo(’¥½Å› %ÉÓ™Y¿º§2Á¼é…'›`¦YjàÆ)O>Ö>SÕßÜ‘è_yVÏÛ¾ÉÿÓ­Å*ȹ%)[ Æí«UW‹oAufB¸b^ ƒ.Oœ„ò¸² z°-ñ”ã"ÕL,ûâ餋ɜñ÷¼S[saÑ•+ÜåYw‰âϦߊǜn “`>Ññž"© /Ôy½þÚôiÑÍölöÀêd§NtØkÄ5Î:óDA>ò©,¬}ù¤Æ•îá)¨¬$ ‚¹º’ ƒB¯r†ålhiÚ©"îO^8)’N!öÂÏG‚‡¹w£­“žâ¾o‚î…Øƒ¤x|bYò i}RW¥¿•·“Ì>¡,Oä‰üäí1`ùó æ§Ÿ²µºãyîE0LßsrÂm-SUevGKrå½ïƒ‰b Ó¤ö7µ‹ŽUts‚z@/L›eôIïÁJA¨³œyò²÷W~ynskÝZ¬ôb¹ÒÝ ˜ûêX®Z­:Š|©ۨ ºî­‘^P #é·µÒ &@UØ{z[âÉ­‹"ÅÞîLÍð)d/‚Eï“ ‡N¿U¹YÞb÷0è3k`¥"rß-? âñÜfE0Ûÿ ‚Aãv„àDsÉVñ’­˜`{tôi ·³¿y;§¿Í=,ïéü[÷óåí<°¼c˜`¸‚ñlG£† ‚að½L0zc"XM÷³/0ùUÓ}‚±—î-ŠCðÎ8ƒàÈGÐIš`ô§tvãÚ†Ž¬úì¨'N« ê˜ÃyA‚Q5A k‚í=¼-%¿Ã;@ð"eÖXiòt&.°Ç¤§Ç§9—8K¥îåâ=qÊt¨Øš1Ñ„gË{ñž{y|mìç+ˆ3(£¸5 T^šSŸO5å:aS5 Í܉@ª“'Ÿâs¼AfáÌÉm&5>"kΘXmì}Éïhž9BBñ[ˆ•;@-ŸàÉÓÝ«êo”öð«LñZ0¿ Y8ºp´¼R8¤à†‚І¬Êû*ï«Â¼ÜP©G’Oþ]žê0^'=Šö¸…îh7×ù9UÑ£ ™ÆéÖb:T¸c•ût£ÏØÐ¿ÜÊÞ^Ï_0÷}G´IOžÊ£óÇ~©ž7ÐqÏïI¨=£ì1Ňõœˆ@ÇgtöÁåŠaÉ®4»ÞYšÜ%ù‹d¸ÃÉΞ q2E0ϾÜGFâþ "òv‘„úxÜY‚ÁGcWÆ z–™`16ÆSœü‹'·>`àÁçߎôÎ/**]ôjIeÑ«E·Ý^øSáOÅwK† *Ì“¾ØË}*7‚Ég æ>`Å3QTÿœ¤û4äW̵izÚ Ï†àN#©&P)Ó N÷+óÞ¡SÔdS½õêvëvû^û^³‡CMFáê÷bïc§F×EpF9TeI½øzžO/ÑeÈDz ‚!矞šhVÕ;ýÕBCEϘ߂»sWåÿZ8¢hLiméûåÍå—U|VyUåUGTQùtåÓÕ£ªÜŠmË–ï­-~³hLÁ|8çÉÝ¡éCsŸ’¾øï*Ó+Ÿ{j{Ü\ ØÝck:ºÜ´&âÜ}ÏP^îþä:Øs?.±2v¶Š+ƒ%lVýà×/S½Ö©TãCÕ9Êày WUî Þ ‚±j¾Or¾q¦»õ9šv„:ÿSã»—7õ<¬W¬æÀä³½`5K†‹5É’``×Þ,Áf—n×z›Þ“…`Ú–Ñ!‚U…»R:Á“àÈõbwŒõÉfG€`5kŒY=zO× S,¢3ÇjSý`Èg'¸ànÉï¿€àòæŠ+*>«Ú¾êÛÚÛ«d’હ•#`d¸HE+‚'ÿ+ut„`èºwfÅ:z¦ÆûÁ臫ݥ^¡ê]V}l—§Z‰þΪØÝÉ {Œ‡ß«žWë "Xwm$Á‰ûªwìýrï—ççž&XG_ÌD°õÔ’_Ñ(>rz³ÞÕDJ] z˜U…Ž ó\*])ªQK°:àúàASÕï*£¨ìÑó"ˆÈBÚ»øÝôÃZ]ô¦ò¬î®7çÀC…å 1ˆc&ÁIƒ)¨£¨ûXõ ½ªT„RXÿp>0,ý²T@0Ä@AP|@ÉV¥‡—Ö–/_VÙ¿jûšŸj~ªÛ½¶°úùÚ…µ kÁ’áþåËJß/9¿ølÐËyNt¨‡‰àDmìX©ª°Dzw¶¿õ v»¹Æ"ñ9±£Œ‰g»™ôf"zd˜¸ ]ø#¹úRù_gPj«Ò†ê* òîvk¡rÇïÔd c=TJ–ùCxªU3 f%Ác<ð äâ½4ŠEx;çÏ­¹©~¯²Õ‰c '‡üï‹Kz­Ó¬Ó˜`ëim‹`ÞÑi •—a‚aãK{CNÎ$;Ú!z¹‚Ò$õr.ÏöÁé>íŒZ—6Orm¬2pŠ`¥"Í…‚ÓMÿü¯I0Ð[½ªvhÝîu»×ßרµ±¡~QãGõ•u¥u¥µ§×ž^5U2Ü\\ZòNQ*‰càT—ÚBE&:Fp*¿äÚò;НNœ ƒ©ØD[sO3¬wÁÞšÒ›OìsNïƒj ÿ&Ø9_©ˆÿ&Á`0Õ=q_úıޣGëÁÑÖ4ñƒ3ÜY묅y”bž5§™@uvZO«®"èìÄm²ÔÙ©[+œŸ¨Ë(Ô ï×ÊZa²W‰kÍí\ œqV&Ô¾q…æáÑí¨8þÚq;îÄÞv ìçÄ\ëh°èÚèZë°è°œÕÑaÚîPf¥”EOTfÝÝÑÚIÚÒ¶·µ¶‡°Y[àíÃð{['í¤í€9/Âc'ížîžî½«ˆU¸nA|^|^ì¸Mæ¥KsÏO¯K¯Ë½¯à¢‘Ås‹ç–^Ñ­êß5ÏÕŸÙðVÃ[=÷XܳgÓÄžK{.íQßðVý™õgÖìXõEÅÇe5%gÆóÿ“eþ•y½ózç6%Ï‹Ÿžx#å$f%¶‰=Û<¶¹ó»ó»»˜ý+ü7Ù¿:}½ïÊÎo>¼å™úÛò÷®u&Ù½ÀDÑúH,±¾·¾·‡Â­2±³ØÙºNÚ@e"kýC,°ž· ìëyevAüãª3úØ÷ñ¾ýžIÍw7ƒ)}x"Sê÷%Õ») =Ø:¶~öï@—'ìñÜFlÌ&KE¡biƒÌn%|ÿQdi³­ÙâXq,ÞÛö NJÚ Î bŽ˜cǬÙð×úÂÞÁúÂúBL³ú 8FäÙcàÖüƺä¾Ptaþ«©+œ—2lö&ë}œ<·(Ý>;ÁVq­»&ýŸÜã½»;J°ä÷9÷•ø©åyÓRËco;iŰIpt˜ºí Á’Ñ‘@*ók?E÷Û*3 vÝÓaE°w¦wfì° Áù[>—æ–¿QyxM¼.øí9¡y²´/Zvè5¥×”¦å='ô¨¯?³î—Ú«¯©ø¸¼¾ôíâWŠN)ø¦à¤øŠÔû©šÄ‰Yñƒcyû¸÷º÷† †[÷êøÊæÞñ>é^GÍ­f‚£ïFße‚M†3u­XÏG‹çìÕí׸]ïÍz/­y¨#‡øí¦ž—fÖ›Ó«Èg"8zXô0“`$÷ºïÁb°·wþ« Ûö*í9ªò¹ÄÅà‡©S¬·L ¬gö`¯§¼}ŠŒ7 ôÿëÜœ÷|ýæuûä%ìq~OŠªä­¯‰`; §ªTÍksr¿öJìH~·ZÅß$Ç@íZ2 ùŽÈ.šà$¹Èq䱋؎N‚¥Ôú¾˜(Öô*ï+=1Zìmi’â¸'MÒ›ÌK1 .Uº ¼´º©úغüú3{Ô÷XÜ<¹××½·|§¬××Í“{NdïY³cÍŽ•——Xþ¡d¸ ðº‚¿æ_™þ0}qª&y^ò< ØÛÇÛ|°·ó;R+͹Ë Ïc7Œ¬þK݉aîvö'bŒ~¨½Iܤ½°¤7úMôŸ`É0œP&N§ÁNI¼©`¯†É-ãêÎ]èü-H0Ä Èˆà¿ÝôóTiïUPmIõ†¢ÀûîÖQ–¼J:£‡»@ªƒç€l W½L¾·¯bù’à—ÄKŠaûÖØŒªÛ{×ômêÛÔüCÑŸ^éÿ–`¬‡ËHpÉÌžW÷^×ô]ùQɞ΋@0xßL[>˜§I_¼2º2L°©:J0ú_ðÃO%F%ó€a“àü-ŠÝ’Qå¥çÁà›Zz}mÜ{p¯¯›–K-±'xáÚ«®” ×—œ™‰`©! luîB?<Ñžè}—¸#½Yòà— z7„`4$Ø=/½c}¯–qM¯~ä>hŒÖA‚Õ¤kw³Ø!Î}í}Â>¸e‚•V#ÅD02ž…`å‡á‰'ª×Áý®hÞ©h„Ôtq"µ90/˜ú“å=г!˜dèî„iŸÀnoù—Ég’åljkíU± "⛉÷TœYõvðÉ0údôIá(Jö,ŸÝ{>÷5ßPzPbœ{ºpä{I-„ÕP ­¤Å'['‹—­“%»;FW‚–KšÅãÒ¶[1½¨~Ÿ’F¾þ]1WÌE Lô‚ŠðJbçÆk¤šx:‘LÌ—6*]š.Í{?ïÁ‚­ÁŠ/y¾äùª†ÚTcuÓĦ‰à[¦µL뽺÷j¸Š›¿èÙ³qïúßê«Ý©ª_ù¸Šž¥çý ç^šþ056¹(¹Hª`¥ƒ‘bg7å¥þ•L*g’û•{µÓW,ñͺHj X Ê)b *m®2Éð?€f&X,/\rXÍþ•wå•*úÀ‹ê)R|j{Ì·èþòö`eR?„÷8ÝÏý{Òõ¶àÉ«j¦»ÖJIHõ€t$KjI3¹&ÑÂŽ>aõU Ã=Ú|k¾-FKñ’S*~p§ç¿Ú8²WiÓ‚êWòn(ÁÀp&‚AËsœ<Éɳ\’âïüR{Nãe5E…Ã`û’á¬Û3L‚£1° Á¨(°ÈD°3Rêc"XàÚ&8ùRò% ¸ðˆ¢§ (<¢øøª†ò³€àºÓßõ VË["¸ÇÌÆ½ën­þºª_U¿ÊËËÞ+¼ÎûÔ$t0háLÃÀ/R"Xü(m †Ó¹‰‘Î}J`¥d F¿ ˆXo ç¾öfbÛ#X*b;ÁVÒJF=k”SŠ'¹ù¯–ö)í“70þ¾=J©œ‹flÏÂYÔU¯ãD°"&†ÃâZy¦[ÓÏ¥<4Œce½´m¥–^Ð+I]^8¼hzþN‰½çE ØÚ#ò32»V) keâo¨-|‚ŸùÑç¢Ï©“ø_E1Œ¶…–sçºs½QÞ(ׂ•Šà[Ò%‰q‰qLpª0Uü¦ßÌ«zâ²…•‹ª/­;­î´ú×z.mž º¡÷`6©„§4Ñ4±çA=ºÔþP¹¼úšº]kv¬èY|[ÑNÍû4¯70,)>:y4ø_MðŸÒ˜â¡Ò¿“쉤$½ðXÓ, FbÃ'9x tÄ?| &¡ hFŠ%½<#+%Í ~¹8œg¤Å‘ïÝÆ>ZÌRë)Úmu€FÈB1 ÖÀìJõ XZtè Œ¦ †Xš´—p;†Ö±ýopŸ…àHs¤T„þ¼ÁËF°®3&‚­£Å\ûÒó½¨_ྡྷø•ÏcL‚fM&}°á‡3œª)º©è¦ÔûÞ(“`Ÿßع¹×ä^ '’ÉÑàƒAçÕJ†T—$JG3Áu§õ¸î=¸Ï­a‚{ti˜Î×ÞXy9œ÷©R`‰mÀ”-&éÅè1 ÔÂcÖ!‚íÛìÛð¹ £…Fï«k„¥N*‹Ì‹Ì‚#ÿâù<Ša X̳œg¼´ãH†9ŠÖÁnƒ`´Îüuôkk%Ù %ª>É `ü(øZô·¡j4·mÀGâ:áÙ›K›)öÑ>WUa¼ ı²âS²ÞÖ•âñs˜õ¥¸F\c}½Ok@ìÖšÜa]ƒÇàwOV†¯ŒLÁÓÜöp{¸õƒµ…µEt_ÿú7¶ t¯‹›Z*º%JUüÌ»»º»zwÅÖ'»%»Åˆ?û*1,5,}wjMÞƒùã –õ/YU2°d`忪·ª™VûCýð]šk‰õ>©%*Bùb8ÉõœÐ£KýpP•Ë+.)ÿ°´¢ð¹â‚üÿäž{pº+˜ÒÁà‘ß{Ý·³ì…öB¸Æ£ÍvfÛ‡*HÃsœý‰õ¤›*â{{(¼i&˜NoJKا#í¦qU$õV¨^dÿm$â¾ûK‚Á7D`Ówü·øoÐE¯3仉e³ ¿Ÿ¢hÑ'¤ÆE%¡î™luÒSÏÁšÜÉÖäèr±5J*`ˆ¤I%!F›‡c ™ÖJÁœ›Æ³ÜY'g!»A«)§[û£}Iöi T°È—~˜Æ8DV‚+ºn­=9õ>¬bÁŠ``ØýÅý%¶—4"8±*5 Ϋ†‹§–Þ\z3\=n˜Þø@Óaͳ›ëµ]¯íàk7OnjÁˆðpEpy}qAÑ)E§ÁÙ0 #Å îÛn…[Á3½a‚í^Ö™v~=äì¦|0<‡Ñ3M°ÔÃí¬slYV“„%Ã_;_g"΃`zîÏ M‚Åvö´Á¤ŽØÁÚ!ò…µƒ-ÃÓh_SE2šø§<¯O.Ò{µu5ûk ×é䦊«¶hx©âþرÖzܺˆ•CÒXUô–ö©oš^2}’ Ÿè8²fŒž²pŠ»UÜŠY y‚ŠÕ½"Øus›Ê÷¯ŠŒ-P'7°x Xl½¢×»Kzb$8öUüÚøµ‰AÉ[Rkrÿ†7­(½¹ìWåƒÁ ë{ì×sËž[6µ¹Ànú†òºWjwª»µîÖª+!\tJñ+ů¿y‡§öMí '–*bVü`0 Ø+é=KÐ{º}:R˶¥ØRù^SÃÇ@¯¤53¨ŽÝÀHE€f,v†x›2óêÏDŠ9s±?2üX`­4]eIS„1¢g9 Ô¼OªV š\ÅéQ@µUCE¬H&‚ÁÿНÄW­ Ž|Ö6Á©«í¬ºXÌsÇ~Þóü^Íu^ê {?Œÿ´ytUõµÇ…¥"È=ó9w̽n’KHÂ` ÈS,¬|¦™"²DD(Z* âÀ ¢â{Ê‚µ Å'+,Ášú¬OXJ©Žú@…ZÞþîßïwîÉ% ,ß•ÜþùdgÏ[Œ.cΓÝmŠàÐ~ÒOEå¢)‚Cc<åE fz%Á*¬6ïLô¦xS˱ß[çÔÅ./^´>Ù?H0ÛáÁ`Ñ\ü×`¸°Oº¾dP‡+¡ŽÇÊŽ”÷¯üyåÏ;Íì4ôf îðU‡¯2 §¦ÞHy°Ây[@pl]l]dEdEtk^]A—ÔÿF-o$¬p`§Ìœbµ·Ú7G0ü^0«f›|<ë+‚9/|k­IŒ¾ßÆ6F±á?ÌRÕdös™Ó ;|:ÁLñcäO(úp—$« ˆAÉ»ž*RkpKÿ©!u‰Šõ[Í‰î¯ e.,Y™œçl¶.6‡‹Î ½pó…À+s«ˆæ÷È_#}†ÅúÏŒ•A/"è +rEeƒx~A{A¿Yaýzí£ˆå(š“Düæ}˜nÛå‰Î‡Òõvk1Ø%Á#~Â}"¼(¼(ò }\ûG¼41+¯SrNA¯‚^ée¤™¥ÝÀpæ³Ìgåý‰ââÊbôDTN¯œ^ñ‡[A0|àºä¶Ô$Oœ§Åj#ƒ"ƒÉ’cm+Ú<ìmpkíSVÔ=äMOlÝbÝbÆH_c¶E…ò£¹Å¢ú,3D0Y`"Ô÷ÂÆd®'sM“3l$Uñð³^9:ŠàÐjËù9ˆùòÌlm6_ð,¾”•qFDÆGÆÛÈÜ\6·áW-KËV1²^…Èû?f|©}Jš§Íc’_Ó^ÅLòŽ3Ì´ž%Áü^Á†ãíÉë›æM°7«p;”ô/ þï™fŠÛ˜7g3R’àâÑ]ÿZõMæíÈzØ^ɰ$ػʻ ƒàèîxirNê ”ÿxQ¿¢ÔÚJ?E®7]V²?³¹ã/*¦–çu|§ƒ•]Ú.³ ´Åp…uS Á)/9.¾!º:qSɱªiÕûª÷UlŒ½ÑÁÄl[s£¹±1‚­VE0ýK‘» Â\*< E°²ÃçB°ªÁÁF—hÕ}O¦9xCƒNÜÛqd¥•?ǹPæ˜Ï‘`­ œö©ÊG(‚¹.çÌRÙe’`Åe#:QÝðo{Ê,™²»§U›%Á"’sм ®iÝ`¶Áö(ϵf/ø}?Ã6?+kôòý`é1„¾E4§&ÉNQ‹C5Nê˜P`Ø^®l >èêÇ¢’áƯLo,½=õïÞ*«¢9w sÈ9$f†¿‰¦b÷Æÿ+œœ“ÿxÁax¶EïW¤Ë ë ëÒeéÕ¥7e6g6wØZÚŽÕ é™…ü'uGr\r\žFb;œW6¸û¬s{̽,?¿"¢Ù§œ2A0¢9ä$À.(Áf[ë–lUŽø=D/·–Û§À¾} ,‹ÈŽsjý87ŒÌ™ŒæÁŠ^zvTUxK‰œ¢?`lZå šûK¾Þ5 µ}»}ÅýºÖUu(úº!ÁÆî`å8K¯¤VõFÈGö/“÷U ¢‹ŸÆæ"#Ø¿íð™s.j4 X|=Es¼ÓÛ£bÅé¿'Z‰ùðËõºÓ¶ŽCœMð¿‚õDN"HpåŒzÜ™澈d¸"ò°û¾;ì/ñk¥ÏD°=מ Šƒƒa(ïãT5üÚÔEïÃÆ’•­+X40½:½ºxmñÚôÒÌ¢’¢’‚ ŽÕÆÛ$nŠoˆÕ=ÖéÕªiUÓ:¶6;e¤ÿ`~[@°[ëmˆhn­[Û‚ý,[ÁˆÀš#Ø¢?^]òHdUs[™h¸ {Ñ×ñ]¢N-Æû¬ì±ŸEÃó¶P–àП¥G|:ÁOjOêG¬ßbÓ”?A„*&ì“Ø‚-g1T¿0gÉD„ÆöXElj3ŠúKUÍBngåù;ÌsX]¼#‰áácD°ô"ŒælôDˆŠ†>Ï­¾ÞøÖØhç„ñ5ÛâiZ>ënín=z×·Å׈žK½“Ôñ¬"›ÕúÇýÍ_ŒËHsŒ9üšÍj³ÚºPj„ýäw®õ®€]c·=Ëë´&qÇÙ+¾Í•„²ªHË´ezñ¼þ¬6@«7éEBZJ¿Ò>„Œ.¬ýŠ`ó§Þ‹N¨!Áb>.”T¯q÷ð­çO°>ÝœMªÓý Øú³wÄz'H°õN´]qÊ+†Þï !K|ÞëƒS³:H0¿V+• ؼÀÞ,ÁD³$˜3kÿ$†G†[+‚££b›ãsòä÷Á` ’ êñš£·;@0¬orœàYˆpMø$éW‘÷ o‡ã¿·5E0×åYl²9?q~â¶öF"#‚¹&'ûع5¸ó$XmOÏÌÖ•Y‚ùýÁ<µ¬îgÜ%¶2±«‹·—Æ¿æ‹Nvô7Fpè½F@ 7B0È ¬ÿ— ØþÁe¬ôʾGyONÔô÷­¸d8‡`ÿÖ}Îß¹®ÞW]•ð:¨IRxƇñUÅéHôKûsêÒóªvôèØý½Î¯$&€`mwè.-_ŸFì¾ ŠA0Åq²ªl\zµYdUÁ/å¬éw¢˜¬ìãv/ó ùˆù(6 rYIÃÌaŠ`ûs¢WÈþ$hƒÁÄðZ"xslstTtæ-È ÷Êû<ïóäB(u4uTËll³§uéžÁU;ò§ ÖÓzúì ¶mâ÷ðÙlî5÷6F0l0ªÍáÖ$"ôB±bÅçºÆ»æõ„’ ŇԘ¼1‰KcëâmØóõ f+L;¯  V½hèƒ`=<9ƒjû 篢#Ⱥ–§:èGÏ•àÐæ÷4‚¹ŠÜÁ|Ûè [$j2÷•Ï/¸Nœ·(31q•õöùìôV^S,}k}¢U"H]é Ôç²äãO#X‘$ÙßREü‚ZÜiì²v¯´wš¦ä˜b"8ñF刪;«î,ûM´ÕW_Ïü‡÷‚«ê2{’\áEÐó62jãˆÍºÕ>ìösûÙ‡­žöSVO"˜H¶zZ=ñÈZ#5ÌzѾ‘<ŠÎBæ,kŸSíT+‚!w…»{C¼!ð$àƒÜøþØ‘?Å*Arâ:'É2?"ÞGåBø ‚ÜèêȠȩȩðòðro€7À¸çvçv÷-çvÛ° ô°s?š$Xx¾Ò†/,ã8PÎ_‹ŠÆIë¤ßÑ£"7Eð0¡Ð‚XTEðèÓ,/»„††U®—éô‰5ðEy&x<ù©È-xGμ×é9»Ú&¼‡pyôo†5É'xžf= /‚´++ö#¿ûýΑĨ Á¸:À3ÈÿtBN¨y‚ýˆŽVj°©µ‚Åø†3Õ[ô-Y‚mÎòøØüâüâØh{ic·_új ÁÄï6oYl]âÒðIçhC‚­/„‚Ã(‚¡\‚!^^Ë>ñžèž· ‚!P¬Æûá“‚àp`82È«oŒ`ÁoC‚Ùƒh‚`îXû‘ÆM"i}‚³ôÂâÒç³ ˜gìx×ØÃ†¨ŽçàÐûûºù:GuçH°u¹×?R¶ªLúNÈïkŠ`™½æ[vÊÞeÝÉ<Ïî-%Éï—»½•§øÕv•€ˆ]M»‰8–›½QM°à â€"7kƒ³Ý–Ü!¼ ìÏd zìn­C–+:Ô]âô¶Wk?%„è «œø5g¿í¹ Ylw®“®³¦`â8üGt«£[Rp«ŒîÁ4rä>îX‡˜Í[Š™Üzâ˜èõê½z7âÝåÛßæFÉ~î!áÿŠfõ“àt‘ò&@®Ÿ;“s4—Cp®@0Çuˇ²ÿù$Rùz‹º‚·¨òU–Ê©ù׫½kjC S-çàD¥6Jy\­È!˜ó)é=H/œ`Ø^˜jŒ`µ­%;÷FæD»»¥gK°ÈÓ5M0ës³·Ù[ÿ\ðšÓÁÌ0ó«íiŠàèÐüXr› ˜‰ýÂé ¶/±/ñ³jD.–˜Ô¢ßD°o‰`E³"8|OøîXÇÜ='v÷ð± ŠA°{<\#È $ƒ`ûUßþJ‚Ak.Á¾ÿÛ‚Ùo'!Ñ‚ɇXÝ`k¡ý´u¥¹À\À70$ÁÖBká¹ì×ß!˜ën-&ØØïõׯ’LÒVm+_\÷wò¨ý” òÁ¤3ÿ¾>™Ê›ì½À{!ž×è|Šå>5ŸÕߪË2rs`@œyó;Üõ1ê‘Ed‡6„6§‹˜^I³"Zë¨? ì° ØŸI&’Í›0¼Ø@ö"@ïDg¢wã˜Ó€Èw ÿ—"9Ñíu5Ë!‘M³&[“±7‚·H’¦:Sín æ7 &¸(\äíòv1½5á÷8XE¤Fª‚÷À¢¯áxôR^Ê]ä.BV Ù1T‰ÑE‰n¿§²­ñ¢≯HvXâq"2³­êEC'%¦CÌcàO#a²Óùúýâ)£eðÚ÷ ù_£z'½áçÂϹIkœ©‘§ÑÎcmÅ\©ÑNùÏ<ÉØpÂÔòV*µAPnâZ›èæQ4gûÔH'‘&Ä3Dt›P^…1Ro­¯Õ×#‘æ¦æöïÆ5C°ólä¥Hû{¬®)ª½ïþ÷;K‚áAü£“Rlm±¶ˆHÎí‚>îw»»ÔA Ùiï´'ßae–`ók–çìNw§çŒïÁßS’ z…d¾Wßô¿/q'»“77Õ£Oo€`PÚÁìÅòßY¯ V‚E/1ÌëG›"XlHÉÌô6I°ÑÍé[”©\ÙñÛÔ17©“E‚`¿ã½ ‚ýžáÁ¢{]ö¤mlØ¡fzÏ@°12´9´™ †x^Ì—”\ WÝ–Y‚ÿ´–XKìkÌ¿ñtǵ ×\ko2[óôPÁ¾‡’C°ï}HjÑa#jR7II‚•÷ òÂú{¾g´¿ˆè.”óD/1úyÐîŵ§œ£ø þ£ô[ï Á ‚… fŠ$v÷ )‚‰á¼… &šwÚ;¿$Øt {JTòÏ ˆ¥GÉîqñäÁL­"8ì„1ƒŒ¿‚!;)ýŽvѕ֊^]„ßþˆÄ¸ãr„”ô¸›}±ÞGÛ&+Ò»ÊÞ*ŠÉül¿ˆÈäx68ÇJu›Xå”´uw ‚Eg±É²xNYvü·ýñľØ˜ðû…w‚ç•ý•–˜':Á5Y1ÁõRŠäµYe Ö'è‚ËLp³‹RúØ(¥ÖNØíпÃD։鋖Œ<°>ÆŠ¹ÓÕd\ó Û{öƒßðòXmìø~^*¬0¼ö鑆±7ËpS‹ÝT‚`–¤2H°{Üy¢ŸŸÃÞü I‚AosƒTA0z+õVÊþr0HÌ=¿Ì=Á‚ƒ¶7—`ä‚ÛOÇ7•Ì+[”÷•íý‡nÈÌSD²/¢%ƒŒA9&m†tÔÉõ•De™¤6Ÿ¨j²œÅÅÜÝùdïug´¹V,¶¸Êï³”o(žðsÊgVUlöÍ;¬ÉÈ ã|rÉ»à=² s&UæÝ¤»¥”÷ «ËÚPÌe'ë‘ö7¼áïpËËXåÛÖÀ[Ξ©¨Í÷&dÎBMÛ«è ÔjR¨rÈž5A¯¬b€eØß@•ùt‚E?„ØLIâü¯»Ä«·Iy™fb3I犒‘É^±JмnsÚ³–Ù4bw>ôi°Áæ,Žâv†?*º¨ó£Ý®évM§ª‚U Xm©…1ÚÎD&¸[[I0l0ýÿ=ÁèÑÀ×:aófÌÿî ‘ëõ3¾Aû ‚×(vÕ#žÑçÁ/Åt'#câ11ÝÉ¿™6ýÁ‹€íU›Õ¶¦w†¾7ØÿÀ T+ÌÏíÞ˜¨g†Õæ¿ ½‚U,dzúòz—AÊ!88u‚Cß ¯GU4BK|›,óðB+#XäÏÎ`®†(ÛzŽ‹ýi-#v¸9‚1{Áö{yr¾ì±ïþUW”MH=ÝÁª²a¾š±ÓݾïqA ª¯+ŸÙ/= tÇ+mdéèÿ;†á{süØ€`¼ƒ¯e–ÓÇçHp<–~2ñK·uã³ÅÍ(;Ì]Ť¦ }úP ;¬”Ù³‹%Ãg د*·àÐúÐz¼Áè‹8ÁúËúË¡uz;m$ bow޵áíexµ¸}!ï!‡fd¯½øïß/¿NN±o ïBÍ|¨é#ùS¼¨ÈulÓI6ô®$2?ÛM”êMƒï€J³_éP{ÓÞ–:&6E`VÙÐDýú¤ÅBæÓæÓ¨_[}éÙqLu¢ Œì—9[H¤&KVìGnŠpùÚzÆ­‰¬ Å5E¾/€k핌[ýÛž¸s?Õø\'Àfl¼Ï7HH«i(ýyú|R;©ãtì«ú«ZHê!}¬>64Šž-ÊÙרùëÍrÞ-;Á™U°ÓÒ¯Ñ=ŽQú+~u—S@n`fø<V»|ZBpûÅí£ ã_M0èµÛƒÁ¯3<Á‰?äïëð|—í]âWüÿ¼ytÕå™ÇADãL~ûÝoVBH‚ ÑS«ƒˆ€ƒkÁ\¡¥Ú±J[¤6RÇQЊhq›q© x\PI¥3±¢ØÜq¡ZÄ*vñ ÎA\8Œó~Ÿç}ÞûÞ_nës’û»7Aþðs¿Ï>¶ª=›L?jLQ\Œ`ì'¿ÁΜ?ì ÁTÃ+"Øy˜ÍûE±\lQüÒ­+¼7½á´p“^.~¢-N°ÞRÅstJgÄ}ðgo_åìšiLÑë\ì\Ü-Á±*3¨¥Í×%NôOžÝÝŸ8#Ù‘ ²ßÏ­¯Ú<ø[#¢aõ·Õü[¾"ý(û`ꃠN©‡Ó‚©ËÒ²huÒOg*·Ö}T?¹êíÔ“‰NSƒ>X*Ф8´ÃÒ¥9NÛh†áw?âïôijDx W!ˆæª Š(¶ü/=KFM"»%ÁûÑñé)ùÇÒ+q½«Ø;«„`gŽ3Ǿy+ô³½îr˜?ÅŸbãzA±k›ÿ[ס ?[Æ5åŒlqå½'î.™Ø$zAèâb³«Ìø"‚¥4æiûZ––f+`/ólÿÛˆþÊ/,¿0NpQ¶¬™&8ñP.[QS9?›T”*‚S¿f†kZêoü­ªÍÙߦÔôä@!8h޶ ÁØŠ)V 8¹&u~zä-ÌluqÔWd1‚y~*‚ &5al¦‚ö`ô5€ààýäg•éüc=L×Â5Á¤$ÔwòÂˉÄp z{#~ÛMâÓM}‰#N°éƒrA­Luâù"‚ýïQDµ[­UÄ!ÊÎr¸g)E|¦Öú6½ÓŽ ³ŠÕ+œF"´QëŠÂ]ÃÂ…Y-¤Z{PìTÅ}¡(OëXå}Û»#8:'=;ßÎ$fpdglþ\7cæÚ&8¸Å?º7‚É ÷BppŽ{_`ÿ(ºQ´;OÃÔ»ý$Xjrq‚é~b&\‚à¢ÜEI‚mAwh!ªAÓ[Ñ®|Ó3";Ù3q+a3½/Û¨dæS£—ë;ͦ²¡´pŒ`ÐYÉi¢í÷øú]Ô4dg]!Pv§gòÌš–Ö†#Û`m[›ËòÏ¥¦C“&îφçðde-\¹š½—@#Oó+:ECL ¦&Ê“³3bêX÷QÁ†ØÍÜ#Oj¾]Ñ L=ÏJ3·ÈDð,¶è_¥„/2[Qé3ͲMpGq‡$õ«Åôºo»oÓ³¨‡2â÷\¡6nL±zÕ¤JäæìQ6Q+ |.› E1Ó{ÜOúI"غB ޹Ã=¸”ªË X6 J$§wQúclÕàßhÞ‹¢xÔ2Pl&?•u!˜TD ‚»æ$bwêaÖnwŽå˜b‰êl‚©~½SN«ˆRÅŠàðžÜzø`&xøšÚV&˜ˆ½G›zöwû»ûBpØ‘(Gwøœ|µ¨ˆFú·t!˜¶§h lìïð®· &Í»ŸÃz"˜.†“.M°óKe{´Oî`ïñ +KOšsL1L³Ê‹`Ý/Œ,š¢Øûgÿ7ˆÚH%ÀŸ*B ±ré»?id‹p( èåâ+^\u6û,á“EAèk0ñx(6©Lo4ѵä/ø½5U¤Ì¹Co¿ÆÖ“ØÞ4ÿ„`YøEÚ©ÛÞ’nÞúêÈ› š‘jš¢¦`c°äË‚e ¬]ÿ½/1Á¢"ð÷ZÐSGè¶d•Á˜x%‚)ãÅ¡xGNûfÉÈaPj¨î§À^úz@¨ygÏÌtÐNo'm"‘½gÖ¤&÷k›ª#:}áÛ?JûàN÷l|‰Šp'нðer11h*VDé©Þ©þJò¾{Üyî<¯¡`F-g!’áq܆Ùú²8]†±.ÓŽ×ûáõFÌj˜Š²mEû‚Á&†SQž&뚪“…`0Ly¨…vmŠ^¹ƒ,—ßcéäÁ¦o¢‚Í}f‹`SÃëÁÈ»šÙdêR úéù¢’cw;NM¯\wTí¶êþ'f¶'¶€^ünOÓ$´&˜î(mfƒŽL¯DnÏgÞª^Fý¯íÁİT8:´.ÖSE×¾#Íp7£–¡pÁÌoi‚íò QžT¸*WÉíKŒüY¡ÿ‡‰.˜Ð+ùb[1þ Ùd?†\“%Zí[œEL¶Eñ)Eµ®`xál©(ÓgÚ>µ 5é ~Þ™C 3µ-v{cØðljÒw9¯`”±€R ÅÀ=jØ!LºAù]<+¢~Q?Eñ…ÑsQ¥²‹£‹A¯,zÂÖ¹þ½0DnºÃ¶) Em™,F°ä@°¿-£4ĶÁáe©kÓïF ¼‹ˆâÛ½Û4Át·(F°Xo“b€?UÛ•`©ÕõF°éuÛO‚å祖Ù!˜^eŸú>Ì‚ݳƒÈ&8ˆþj;ï8ïÃï9£{#Ø|Þ•à¨ü.³õKLSOÏ%'~”øQúŠÄF¢x½sÜÁî\o“á×L¦ý/Üáu¸[Ç ¿êÝ ô»õõÙ[‚y ô’)zAqÑt¾¾:[þ¡Eð+ØøÇKUÙ¦Ø\|‘k\xVŸ Áü¬>£»sÎBç,ç,¢XfšofãNyä't‡”Ã7'¸(óŠ-‚9[Æ$kË,²Ÿ-A0m„E7•ëÎä{ÿ§ð½ˆàµê;hE#F°¼—œƒT3̶(‰è¨›C5èÎÊNè¥ ¾ë•û÷€[çC÷N¥ @°T2*µ‘àì˜,’M¥ã3Ôœ•Ú°ªÞ«ÊƳ6¹hÞ=Lobšbwe´¯ –ÚœœÏ ‹ùÃ'û{•)‚‰]ŠÖ${æþ4vûDpâ¸Äqávpì·ƒ’£'›Ú+ï _é+Á¼C¢@°ìê ÁB­¹£}2v–ïŽ`öÃJKè¬Ú&XçÎîûª+Å{^œ`ÌbïÁ´ƒ’|nW‚aÝL~øŒw­xO² NLKûÙui?Y¦luruº™-Ó’ÚœjLl„ ýŒŠrW‚ÝQî(çJçJCï@TDjRÕùÕë’w(_¼Í»Ê¯ _ÉÞ’½%ýÍ`“÷Œ{¡w‡w¼{«²Kd²“6ªÊL±î¢"0/צíZgÑ«o|êµ×ó³¢W|2´/¶Qi5Ahmû±ˆÖ—ÃíŸ#º“ V*Šô7«ˆROö°÷P!fåÀ¹²Ñ¢ ÁúÏ3åJ·r¿A*9„·k)Šutgîo’zpÞ•-R¥Æþžàל]3Šb5Ó õ‹N}ë¯ÙD0ÌöÁV—»Q/ø_o 6¾97Ì*~¹c‚kvB0ûaÎ?P·2Y–^˦s?Èo¨Ÿ¿¡ò¶ª«î¨[qSå®ü˜ì¶ì¶t3ybEpøp0%Àͧ¶þÉFlž“sža‚A¯ÌZ˜ µÈFˆvÓÊbûý‰ ØÙáì° ¦Í°«R•¹3zêæðjº„x€¤  $ŽÕV‚`ç ‰ë C9PÚ%º†×Á”™6ç.m˜Ò¼¶q@îRÌj˜îJ­* Ñ=œ~#32÷—ÌÈði“a»KÛ‚#?»9siäËîˆÒGÏ$ë¢gÂtß fz K6|°E°wo0 î½lÕ Ã÷@0f~+ªï®¾»æ¤Ú{kO«ÞS³¢zRõ¤šuÓ*wAQÀ ïÁèè) üç•é|°sº®Sµ úÁ»Šz†µZ  Õp{‘¬^µÎZ³ƒr“Ë<ûMþåþåÁ–ìÿ53üÙú“ÒëÃ3ùÖ†ì6º™þû*.ÿ»ØxûªÒ‰m1£}j¼•¼±åS©GBnyªWçFçFS³ÓÑ:|’-Ùc—µ2Ö•k\ /tuò–ñ±Ð¿©'}0rÈ7Þ8Ü˽„Ê·ÑÉÒÕ&aü½ŽH©›}GtWêþÊ9ùïEpH]*:‹f"9l»¦mQÁ5©OªùiÑï÷¼¯Äì¶K^¡+Ÿ´ ÿXøî|/Ö …Þàç‘OsæHÔfò¿JQ€fêýEçNÌ»Œµ¯¿ Îæ¿NuË Áè ü•8\¦&V¥Ê3Q&ÊŽÍï©<µjeÍçu«ê®ïâ×M¼ºnZmÃ%·Ö\š+O~‘<9ú$:;ŠEIPf êAzÒ–ë 1|)F÷¥uG0S¬8nuÚ…`ò·1‚ñÚÁP‰ÅÕ3F½>úç-u¹ùÁA˜ëT¿mjtZ7÷@0å|cëmj»?G¿Kÿ9N°øÏRß&Ês/ÕÝÞthýòž –Y’8Áø Mábóÿ´©d÷Bpøçäm|Æýž7Û„`ìÜ1=hen?¨®jW½!11XjÌÑ[W‚ÑÎ螥ÅG *ß{™fØ"X*ÉBpª3Õ ‚¿‡Ö­òÝÆÙ‡×5¿ k\W·µnkíæêš\y¦#uŸb¸‚yŸZ)‚Ét$g¦î­)Nê`·&[KÜ*ÓOúŽw®û÷Ë­ÎäߥnNXÑ¿aêðŠÁw'ŸÂŽlÿÛråÀ,$’*àí›Ò[¨ %Š";k;+N„B1€`õN…6£*HEøÏæp~8k¤‹ Á…~Œ"Š'1ÁaGêÉ\]Å빺T‚zäÏH_ñfE¯LCéi©.+?L[OŽ…öÞ¥L¡ôk‚‰Ý£%žó?Jß_ÝÀ»Îè6W«â¶w=ñê_…8N1\ÆïK3ÿ”;7u*úÝ1µawSR_»žø”lzéÕ)ÿOtÒž“™Dð&eŠ`tû(†·BIø‡³u!øs˜"øàäÙŠßÙÙ*–×l.žkvùU=çž×Á¸‡=g¼ƒÒoÁ=#!ØyÙkŽŒÙeìˆ,³ÉÅ;|ºLjX×èh.*Bl:ß_UïÔgq‚¡"¢©ŠdEpx/V*BÜ5_6ò›ßØÙ6¹mòè»Fí> éãÁ‹ªkò³råÙs’'ƒ`øáÞæÚûˆ2!¸¿ì‹°æà¶p§;™ôAˆŠx æW¡ºÌó«ä.³\£õ^ †E£«g´,o]ÝМ9!šBWåJ¢T6$Glmü+ì æ|)b6©ÏIÅèŒïè|°V”)K*£Ê†7 ÍRE¾D1¾ÞÊ´‰ªègnŒsW¥ðKî ’©O¹{$• ÞÈÍ]—Ò_Øà7R׳Tet~ždàú]åÓ–a[Ÿ¦7èa²kÒlQ½ð½íì‹EA˜Nž%Áû4w$ÓŸØsRsNŽ6õˆÖê‘›]ŵÎa«w›´Õ±îE ‡/!˜c8\ãâi"òÅÊ 'f‚sã+>¯^U·¶qvËÏGOlû϶ϔMnýhäw†M²¤¶¡âÿi;0©ª#ˆ Âí{Ï}õkzÞü˜g`# ”Dˆ¨l`Á Ÿ ë¢ñƒ:Š‹": / ÙÀfVð±+> Ž‚B4‹DîEƃ²‚ÎVÕ9uútÛèWt34ÓL÷¯ëþëqªüÄS‰§Â5Þxà(æHNf×\ä8M²Ú“ƒ`kM÷ŸÁn`ž_›‹`ñçØò’¼òžEÏK‚唩cÌ}¹6kv'B0éaó,sÁøxÉïñ Æß³kqÇ#˜}p{“'Î"˜Ïf˜gÌ`jÉ÷æ ˜ªrýœ{s,}/xál gj{c¢#»«ƒñþ÷Ã'cÿ›|(tñUå^¯:&¸ß*`8Ñ»[åEå©éÈp¸Æßäo’JBúa&ØZª|¯A°Ó–¡"þb8ã,röt)êÞYŠ E°Ê®‰Â=…ãò†»¿W[AÕôUI°Oâg©ÓãMîïã´ûÔ†1a›hnVÓV ‚åDlŠï&è ³ªÏeG|œ5#z‘ÕìƒTcVîèÑ}ÄéÎúºÑ­Ég¸"¡»ééïTÇgɸÔû;$§Z3"Û;J0ÒÔF÷Ô,ë“å ˜Œ{"N‘`>ÿ–‹`ºUµ8ÒÀÁØ›¦}ðHÔÃi‚QG”ޝ¸†t0ÐÛw(á͵ë{Ü+ N<;Ý$Xö¥I“|°ê•ðšSµñW"C#C­Åh‘C‘yV-uøÔR­yNBIŸÆt±¶X["3ÀòÀZ"-øg»l»¨ðÞñÞqÞvÞŽ”ƒÍ‰Ì±«ÁÖ‰®îDï™Xqê®X±ï¹E×HØ(iÖk>–þÍ‘7PýûòvôXQvAô?œÃÁÉ]—TÍP½øÊ–ÈÜ„S­^ñìyçyôÝÎT±ï‹é`[½¢ "¼5–¿!¿¡dEëÊ_­þKmÓÙ‡ú¬©ÿªîá^WW+;¿¨o~eòºø´pSÐìñǸmn›Xé|a/ŪÙ ¬D€}·î*xìeH0°{ ¶÷¨>µ$82ÃÞN6מ›‹à`Z¬8|ÉÝ$ºÚëŽEpd±»:‘¬Ó§²îµü¹îÅÇ#˜¶MÃ;œ‹`k&¼¢†½Ó@OeÌWù4Áîo·;Gñ{Rëš¾A°ž`§ö å"XnGñ—D¿Ž~}²ë™æY‹Row|pjTü¯š”RÁ¸i3›`Úo‘ƒ`z-¸ R,+o¹ æ~´Žì¼ùM‚ùûeìÛÁ”X~âõ¼áyà :¡Ž+E çÎK½^P“÷Z"sƒË¿Ç$XŒJ^Yf ±†à-rk7ÁVc÷]‘:¬4¹|ȵ¦ƒÅÀ@?HvAEä)+—F âMQ½¾dee¤ðãðZðĶ3Ömެ¶FDVGVÓ}E®&™Þm1’¦cÐUÕzÎòÕ‘l1Xn³‘0ðÏø.«wНjSëx?„&ØY'µ†ŒHˆ|¾ªóFVÓ#Ó‰.cǼP,tºM{W³ ÖŒª)ý¼5Pën¾¶Lç ÚÎv·Â»…øÅùcꓬuðmò¤Õ( ÜTˆŸRœ÷@ô¶aζš>ƒàùÖüÈ`Æ4ºeu1 þ>ƒ`RR…q‡»ôìwÀó0Á*‡¾õ°›rSÞ,o–ÿL^½6¶(¶(þqò§©‹ò×]‘¿6Õ#ÿWy¿LæÇ§ÅÜð,½÷¸÷8*ÔâøÛ¥ …¿ †•Iª‘`ë#"—í[&8¶£êõÿSýBt›;ÑÛ1‚ùêÊk"rŒ_“ïî·Cpdp÷}&ÁÒÿâ.Jé[³ ¦=ï¸ï݈äN„`=O7Á¨Œxæã‰ì¬sÖ™Ó9cƒ`¤Óä j`»ÉnÊE0ö£I~U§°"sL0ùj¥Ÿ™`ÔÃDñDÿ´àÝà]d8±$ùyþÚäç‰k“¯Ä_ˆM~7¿—æ"8Óœ/°.! ¶>•F¾ø-»ôv»×q–Í ˜Ô,•Q TÓ×g[³Ó:XÔû› õS°(xQ4£‚ÃG­£x˪#ÃÓ6§tdCD¨½dÙ‘œ©Q™`R¬"2æ7[êÎ@š«„ï°ê¶âP~.³o$}MÛ¤$I¼);½XnmeUÁ“>ôÿKGlJW/V +ý˯.à®:ÏÁ…ê“£¦O<¿õ+cS!«‡fi¢3š; &{¬ZFrd\-n’&çG¤Î•ý”DoøaΦI.-$Xj1«O>¬'³ò¿£œ0 Ñœû2üjömo"pܼ='zNü<`ø§à‘§Ä_ˆ‡ÑgÂMá&àW<Êå]Šü‚¡¿ýÅ‘K‘‹àÈ»`Ç Xëá,‚ÍHµ°³Á»Êßì]%šÁÿb§È=ÁDïH']ïk f]«â—Ì>ê»&Xï—ÈA0ùæã,óðü| Øèl“!‚# ¦v»JëÁÚÿ"¡çªÓDí,ã‰o¬sOI†u%Ä ˜ôðX·ÿ_H0Y]x’Íá„ kp™»Ê$Xñ›“`¬L(ŒT‰”×=KnåÂsD¬ŒçÈè4þ§™†9Œîû»ïÇL唉šÈÕNg4ŠàÚ”2LѬ‰æ¬™z'9eýÈTéèGòâÌ¥`³Sö _ßQÖa3›$sfV9Ñ™þž#’GÕÉ=åãñJ®r»t«6êˆ=DR´ó*ó¦¯úzŸ°ºFèÈN=˧¼EÝc½Ô‚‚G‡)â#Õá ^Ž$•I#`fÄkðÜ;ÁêÜ:ÿ÷=1>¥ðZð뢯îaå˜leMòc]Œš´1åmT ÎôtêÉÖóX•_W²ÅV±•nE£[çÝíí êØˆæËüÎhD/Ñ»RªÊ90·2|<ÝÆÛ³À0—›ƒ`¦·=‚‘Z$¸û Yù.–žÚ'3Âá‚øàà=`øF†å'E>éàYWòc,Umš`Mq;ãm6Á4²¯X˜M0íÚ|++þÿ^ÿ^oØÝÞÝÀo£Û,Æ‚"•M°9R²üí¬gøðŒwÌ®»7y»´Uù~gwU.‚©rq\‚ÒH Ñ æLVÉ´£ O Íí> &lú_T‹3 #8ÎÅ*b# ¼.³šÁg¨ E0Ñ‹Q ¿Û\œUhAßÿ¤rnÕ[cýÛÅzUÁ…×Ðu²k#5|íÁø´8+ cÊ’Ýs¶n±ÚêǾSå$$3  ¸²ÛY›#ch#k'Ф*óÆ?« ýIÈÖ½êgÑ‘ž"'HãuEoT9’ŒH’ü¯sæ¥ÑÿúK¢…¢? î'ÜH¯šÚ‡±‘ ¤º)ÿ¨M©†ÆO¸ž¤:‚y≊ì´á³æ|%Mz¬SŒ£²ñªÐÄ÷&`îI~‘cw•8"ŽPMgÏÀ˜`ÉógÎ…Å-ÍE°xÖ™œM°¬p¨é‡€u`Ñ«q¹ ¶F€Á´¡<1x% Ø¿½ØîsißßõÜÿ$›ààþà~xͪ±ÿ„ü‡šO®Tp[öœ°S%Xç brš¹¼F83Ý ¥kA0ý\¬"à_y»Ãb$ç‘3 FrM‚%¿‰.‰UhñááÇ’ál‚%¿¨kç£w<–Øç—f,³aŠaUÝ8U‚i[ æ%УÁbšs=L÷GH†eîALSå"“`Ê+‚ØŸ#*ìíN©SŠjBLq"˜=C‚‰ašF%Ï2[Ý¡ßUêA*¬ƒ€FšÑ/3¹¡µG;}/|É÷œ öèHFtiß›­"\¢—ýXVÆ_«ΦUîŸR«+çöl(¶Áwæ|%¾g^·øðègt F™‘ÉÔ挭SŸâþ#ëµ%­ ˆ@ŽØÀpk6æˆÞ1ÊÔäÒ&”íÞ-A½·›tú°ôDþŒŸ‰s0ÓÙì¯:xϽX=Ž?É*r$ÃL¨ ·Õ??X~™—?µ ’jN>ž¸(º$üq.‚¹c£ªàæÄ¾xw†ÌxɬÓG¤+‚)G‘P̪¬\z&5½~9&r~˜ž³{]^ï\/ŠE±ÛÃÙ&n;¢l„¬VPÅ£¸/TÞ—¦›aU™'«ÒÜ[D,ù4ËÝFßÁb|ꮲµ‰]n7gÃwA°˜í÷ŠŽŽþ@ìd‚‘Q|×D­{§¨M÷=dì§l‡`9kQ1c,f‹Ù&Áhz§{;»nEØ/ùPþºÄRÒé'@0å‚—å&˜ª( 1® ‘ߨ%y“ŠŠÊz—×”äçOHu‰}áï=Á’a1Ý¡4ª°6f ª5î.oŸ`ÒÃ'A0QlŒóGrL]‘2j˜‡%%àV ÁÜQÙÁò‘&ù­ÿº¤ÿ¤~gÕ}YØ58ýXN1?5‚%»TÓn ‡'7–TT­{²_?®æ`Ùë‘Dê`ˆ¨6gD¬Fî!S§*† ‚Ý©¡¥=á<à<`7y$Ÿ÷¿'NpÄ¥mŒ*"2Í~ ¦ó=D°¿>Ü”I0Õ‹3'”?R¿³~gI“w©ÒÇÔÝ#žÏzðþ \{uç̰bºJ̽Ô{~cêÜÍsÈé…Çpt‡=gf´÷‘Zʨ!©­`¥9CÄrÿ±Ü~l=(ÒÆQÑ ¾ê9™YÒïì2É-Î4y²Ìè(¡©“Œ3:.Æ”Ê5QÞ~€>›«žWgÓT§¶œ|à®Æ."ò÷¥Tߘ®³z|Âqе(ÊòÎË{ºçÿõ+è?»ÿŽ~3’÷Å~å…âig‚³Q’ObìÐáŽ_ÎÓ§~ZþÉugV±ACà' "8·5Xÿ]A¼rP¿¡¥¡¥ïÊÞçôðS‡bÿíÿÑ›…1XÞ½ù×Â鑬ù²V!¯Ibløb|ep?£#øaþY±îªKSé2ÝéÃcÆMv\PöM>¯±1‘vÕÁï§;—ól(çrœn ‡y¿ï£9óEÑß~Œ¦<€=v¦Ë{¿üÉêdê>÷u'ŸæGMCs&;“Ýiî´ãŒÞ7›`ÒCO°ö±Á‘Vëþ³õõA.‚e_Äñ Ö}½ìS8·©²8ºÛOù“`2~'É·›K ‚ñœW¸b²j¯ Æ_z¶šðœMp¢K&ÁÑ2ñt6Á]ë*ÿ-?ð1¦¸öÆ;Q7ìŸ~™<³¤¢vMCKÿ’þ% mgß_~MÁH$ûL‚å™·Ž̹ÊãÁîÁG^ž¬×u8º¦Ÿ`ÊʱoÏ"wÇ"ÁrNµ{.înqæÛ½‰^E0ïpÎWzW‡…áv?†ž;M0V/bªÁé*1Õˆ[tžLå3èe‚±;ž TšI°™÷•ä#½÷€)‚1›eV•©Âšgøá¬«¼®Ú²ñ;£ûT½"±•zKˆ`—yNü;œn‡ô:ƒ JiU=³œgVŸ>)£¦Î<ñâ‡Á{@ðN¥[ÔÆ?ñ˜ÿñ(h„˜%"o‹Ü†y.IqÙÙg4ü3ò{öåEEA¾;…;Ò)drk•UsI°ê(â|øß¼I•û‹f…¸‹¼ä·V-®¿ªßL´¾+k‹¿?ìéÍÂ\/Öruv̼M•™aÙ l·Òk€W£éði¢72Mwkr…Ù XRœÕ!ß—ê„8ÓŒF ¾øÏj.RÛ[m‚»CÙ8iâJq¥+œ'ÞL‚¹§ûZœRw7Dv‡TµXåsœá£Û!Uıfq<‚µîÁèü£½ƒÿš&z_ìQug¸3$ÁTû<flöï2ÁtZøM$óvä¯KŠþÀ¿Ý$ùõNK½Q~¤ä£x'dXŒµ2±7zQqYÕš£•û‹oŒþVñ{RËÞ4gOì’’ŠÂTôë4Áåï×uoH"Á}.¬œ b>yàv vgø7ª«R«‚Ö‚ͳ,§B0}ß“$˜6¸<÷2Îèžl‘fz½üqfsï0Ñ ”Ú…ð5“b¥ìaªNgÖ×ð>ÐÜý0èà 2Z3É5 &zÑ3¹ŠdÑÉ GºÊÌ&¯¶2f,½Õ¿16?9(úP›Âw4±/uyVQj ì0ÄLMÙS7¬«iÍ¿Åé¡%•F »Æõ †¥ŽP:Uûìê5-yž™sî†kñŠïô ‡c¦61.Xî¶:Ò§‚`k—ÊÊÝ&-û ŠŒêdtH÷ëP›Ÿ‡_âwóÏ>Ot)|¹üž^§Õ;uWÖ]YÓ«è´Ä¾àf¼ò`6Œ+Z5Ák㾜78u†¯ð¿Šþ[øsw9PŒ³)U›ùÀM²r‘yþÐ0#÷C$sõYͼԓ9²£Oˆõ&ò irïê_9ÕA¬n#ß“—³Ðœ3yRír‰æ&Ø™í̶ uö ¶‡ÙÃèk9Ö ›õ5E0Å8zbã;i¬{¾ŽA0ùîŒü£WD>¸ÂAý©9VŠ-'Á¼=Š .x»j}φŠÉÃÑ)¢+•»ÚIeœ–,(ýMéo]°×=M°ÌÝzú½)ûu“BÉA0ÕậHpô¢äÿTrsŹ=‡U/«ØWòïyŸ†»ýR$øÿ‰;èºÊ*+3%4'÷¼ï#77ï4m}ZI­ ¥¥˜Z # ØB¢`ÁA°º "HUÞ¬¶Ã£€ ´ baÊ£R©«eU”Ö™ï¿÷·¿óÓ{Ó4àL÷Z¹7i’6¹¿óýøï½Å[Èì^˜R¾†þ̆ cÞl{9:&!Øô~ÀÓc†`cš`œÁÕëCŒà¨Á­O6ÊÉÔ «n¶•°Cå„ÖÙ´i«{·î][ÁS•^+’#/ˆÔÞ„VUJ¥U>n‰Fw««À’É¡|&<†à?ɇ Ú`)¼ã #ÂЙzž«^CÑ!¼Åë˜ßp^|b1ßqØÄ³§Û3MùL0ú×úuWù»Áíñ‰Êþ–ΛèŒð ×(,‚Eß`j$öl´wúêÕ“í ®ÅnÁ­í=­O·v4QúXþëa»ÿs!Ølì–¼,õü0áT±˜YtZžk|,ø“w(®`SL”OÒ=$ªUÓmå¼ÛÍŠz‹bM°QYôò¬cEC#›í9¤Î^~o³{wðEß㯡¯]¤í!ç甿&ÁY Úû!˜<⃸,Á`Øä"L8>&º•4Ádæüå©¡ÈÝÒü‘Ò™cÞ›2vÿý&^ßž/bLë}¦Úav.îA0ÙÁÑÁp%ªlh<=ÓŠ_Rë˜ûL‚ɤj|•ò#Žô߆/œlÛ"iz+m‚½‹â7âEÁú‘L“¡ö‚`ß  ¾èÞ]ƒàIõ“ÜÞ·¨f¡û–á1*Ah¿6ÝeÄJwê7:ÝdÞ¬.#ÔäЯaT–ç9môüäú“û-›^Uî ÅïåÈ­©·R©WRÔ–’MÊäG)>‚ëe¨>ˆ7`ü[Ê5¸ÉcJ·*9R©xâ™òmIÕ¸LMLÂ̤ң]GM8cò¯úNižT¿Õ{ÊvC™&”:0ñ(]ñ º;4EÃ]ûÚ‹èÓõâ”¶•A©\Ìè8•-ðîâ ŽŸ,Œ-MT¶¢Ø›ïˆ~ü -<ø¬W·w™+ÜʨÉN¯—8K’Š…ŠÔè¬õ.ÂŒ`{Ûbºh{ÛÙ-ƒù*ùÆóHv…;ö xÖ¸Õ}ײiظItÊT3ayNýÚ#ðuk˦ú{ʸ)3Ÿ÷ØUo™cû’;C¶³gBòû%Øiãù 8å¢j“‰NK: ÏBmyw‚mÍn5‚klw6Ê«')ÿÔ]•ÕšÊèû¹Í Á… ²©óqsÛßhüJ!ˆh¶ó§klHÎ,]òÕ¦\„¥m«E0Q¬ KÑÙq‹²s¢JxFƒ_Éñ—à$^`ï¢heé¦ü‚ß(ŠÍÞ"¯/Xû“)|É&XÈãÿƒî{ƳY8ÛU¬8Á˜:iŒ¹Q¼#7Ê&˜&‚Ñ'}qF­“t//K°±Ç˜áÔs!x#õoZg0ºŽÉš\Lç±ò@°É²eò½ü:&ç°ÑÛj­˜ÐKÄAC.û'Å;r…誽´–áüUC‘Cß›öJ¡šQЧ5OjÝZÙT<-PþÅNÊWH¨t-PlÕû§ÀðÜÌuxÁ6øÆI僪2Ť¨9EÉ*M1œêF]æ?–Ÿ…? þCY¬>²ÃÛÁÝœœçE–ßj#U{²mËT”E‡cÍhg‚ÝMÁe ·uýºslñýKìÍ[Þ‹Ñöx‘? ÊaXôÒ6k£¢½ñM1CµU ‹`2M¶ìëFåƒÖ“)¿‘ÿ0,‚m/ú5!˜Oàê»ãýWÝñI2ÏPžD‚Á°ñ‰«\_HÎa›`ÿeŠ4<’fÌé»'õâBR›àÝèÕ'ªH›`Lý*=Zn+= ¢ÁÄU}TiüûÒŠ N¶çìHe˜j#$˜®"Ø;ÉÇuÅP­O~~‹à”€`Ré¨ö'ÛŸ´ 63ÜÿFëLþ_ ÖÚuž—&Š{ J?kÏÈ«Ðýõ†Þl…ã)V¸»3ÈkÐç1h&¢?«Û¯ÞcãH.÷íoKzâ´¾‘ë¡Q~“FLÝÝt‡+Ž. 7#²B~‹3óŠZsçT¯è6=‡ïEI—DwÙ°! ñ"MãªØé§ì ù/ÄuÁq ˜¿'‚>WókÎ:êáõ–ßhKaeñêâÕ…×óWBA‚½UÚçµ&Ïðc|6í‰`£¢“]씎î ׆kÁ¯,ýoB0ù¨÷ø>|SÿÁ„`®Ñ1ÁP•5|¶û{ã?ÔÜ~*3ë|!Áb ‚¡%Cç(ukÉŽ{‹`ÖEÔ&˜U&ÛÁ²ÃÅ&˜vͦ6iûǵ–ʅβÁs QêMÒsOžP?/cð(^,¼W¼‰½ ·Xÿ`îTáWY6»&¹²·tåâ§<³ÇÜMÉ÷U§îÅù©ÜÞ<Ð<д¶áûùF[PëõVy«l¥å%¾£s½:’1š‰,Á¨<“Ž’)†‡";ý@q8O1<˜ ‘w㫨R< Ìo¸'÷ßgíúˆ¥j±Áw4ÿÜ߯ybñ•%kX“à5Ü /‚z¤°™ ˆ(jd“À6k’ª5Eʘcõ*ƒºsB…`“ûý Gx)‚Sʧeî XNñ"¨S„ RõÖ sÎ>Ÿ6³S@¶uêíCõyì7ÁÈId &ЇApny¸=þƒÿªw‰:‡‹ÞÙî#ÃCL™V¼¢U .¾ÙxtÇâîI½[»_êh(ÿ°°’7Uf~‚¥/lo †'!‡k•7q¯3wpZ]õš`å­îSwœbX{áwKW‰òG™îy›€>‚I¬­Áæìµ¦ßÅ –¹íCLYdòÍFÐûv˃`Þç=|‚ÝŠt ‘Ê,«S^+îû¹Su¸ÿC¿¾IgÆà-ÌÎÍNêê½ÁÜ » :6Ö»‡z3½™þêhŽû,wªƒ?ˆè@1< !ZfÒߨî¾û(Ó¯E0 ì™èÒø›GwV&ü~ÚŠi+¦\г éÅÒ™ê?ÏL[ÒÓ—ts#Ý%3¿Ñëã=<‰`F÷2xÇ+ŸcGÊõ¯#›É†y3°B¥ÜW¨øw&êÃtSîæº·F_®î-µ»›¸‹Ï[ŒöÖÐ ô<1缓T'(eÖL6¦ Šw»ST&©Ðûš(îÈæÙi¦#ï? ý©òfÎlQ·rå(=‹Þ·•Hxœ[?׹͹Ít[ɤ"\‘®+ 檀Žþ瞤Z‘6§+·™ªËëN¶ÔK¤gvΚ͛¹¯×î{«F0Q¬IËu»Õ"87Û] Rƒ#Ã[¼·‚)Kv•7³à4÷ÄöL01L~cu‚Ñ—ÿ]åöîÓNØÿeS'þ¢m{Ããy7º ó`‚ƒÑÑÇ‘ÅTÄvcÆ¢bm{;‚Ç"Xfá`c˜SŸ_“`­ÚªA0wñ%]P{C°=½jO§& A0ö& Á\ñLN¦ªÇ`Ñ@¤Í; ¼&¼ÆsX»6ÁØ“E›6{áðÜEð6÷P®.¿‚ݢⷙ±„àDÅã D‹¢9Á®Ò†Ê/ãu¹AR¬ËÕðš»*ØU\>ë>Bg¹dÕ„`1ýÛ‘èG6™|ò"ÂÍ…•Íwömß?<õùžÍ—ÁtŽBAM9 Úþ›!¾Îã剽ê<Ä×›×e U.&Ø[å¿-Ãèß’]–¢œÕÝMÙ.~‰xÌ©M<%Kw@’¦>K°eVŇ>ÏR6mß·fâY¥Ž‡ˆ ­õ!]»Š¶dâê5Y3Ó’t§©•Û¶¦¿ò)£^+‹`¢6ó>ö"9û:ûŠ’Çx8Ÿ…²=êoYÒÜ/ÃLoÝ.å9°2íÃu»x[2ö¾æ}7t+~¿mì]ç*sæ 6ÁFsF}oaà¯v•Ëß.mðf¦ †îÁ›I°&µ¹½%¸þaø§Á…Ñ–†Y‹{¯˜tΤsz´nmhÊ»á¼àCY‚ó‡EÛ‡"˜ÏêÝ þ$ƒ·tþ¾­~Ûó‹³›˜™y¢Í«F0™Ö‘˜9Vß«$‘#ГXÑqjøåø«þY6Ád569¡½$ØiRVƒ`ÊCOH,ÑB(†Áun)ö$S.øV§É™ìŽõ†ÓÁoý92¹„üà«rƒÌž3¨Ó:!˜:8‘Ù­ƒ5ɽu<ªp_°+}ÃÐ'• Ûs€§mb;­ô6‚g¤ùç…›KýØKÖùN×Q­[Kr–ÖÛ)~0‚É þ=·Çöƒõä ú\õ5þ€?¿”Ï\Åìê`ux$žÕ‡‡ûwòä:~T_¹ÜÚŠGñ;¥ßŒ¨•|©Ì[Qdi’y+&ï'¦³X¦P™î{Î…ÛúhQÀ[3Œ_œžª…‡ÿô{Qÿ:º7›>~ÙäÔ¤‹^".Ë¿æ«%é¬%oÅTÁÙÌôW=CÓx ¹†^üxR3Îx¹Íþ•ùÅãÂÓu’¨/G%‚±e³òÙø`ðËs¯PýÛÐ)°íN0‘¦v–Õo4Ub‹`:Õ@ð þ>Y5ð¶Ïa!8¸0Þ¿ðz©_ªdq]¸–ÔÁêd]\ÿÃPËÙ¬Ö#¶Â‰++ŸáíÚ+?øÇÁ‰Þ‹z£š>Û =7Û¦|•ã« ji7¼¾ô¼•Æÿ´}ôpvf)ƒ|íÀ9Bfº£ƒ¾á  e8sÕÞltÄméÙñY‚ëž®{Z¶»ã¼4¿U ¦¾Ž±áôøàà_5Á;rŸr?­3hÒq)‚Õs·݃L–²ÔìDòkºçXëYåýì?¤¢7C²bY~3¨ŒÓÛv:w±Ã“7ÇûÇu¨’¡ÊÀ s·œ­mSp™D[fÿÙF½™z}ž£aáIáâ‡?Roç„»Â]ñ~ w‘G‚Aû‰Á‰q¾2­üBœg~åöú’‰‚ì)P>d ¼;'ÀÓù|nz BÒEåH¾n™3Ä2…k·.¬ocBK2Å,óáxNõ{<‘TÓZaŠÌuf*?Xº‚²9™t@g²zO+ñÅ‹@îEmL¥{¥5•JƬ@óñ ÁðØFwyÂlë$‚s÷%Mû|w¾çÀ³ oEqÊ‹Ø3ÁdÁ¬KÛ3Áà·6Áõ§#kKSú©“kdŠß·„`‰öY[…œ&æèàü–_+¿–ÿßÏœø¿»,^„M0õ(W!æÝW|®éÍÒÅþB&ØÎ¦©SXW‡I½nz‡Ióøš!ZwÇ­ÙFžÕŽlz8¢ÝŠÜÈ8ÜÆ~ ùdˆé3ugrú7ã\à\ ‘Ù><[ÄLÒš4¨!XÁº^ÙÌg,I©»9h”hŠøÄÿUäæSvK~TiaÆâç ûö-~®´PQ<*ºôÂÃàúᣠÿ(ÔÝÈÕ‘÷p.øÅsåôÉDhì³S¾õë_(ÊÊìþ‘Üù¬øÒ¶.ö $:³‰µ'¢Ûr ÞDïé)¨VÍüà‹›i$ö ËôÙË ÷!ذ¬_ç6î–Š®kÿêÄùç·> ¢z“LÌÝL?~Æ%ÉÏLÓµ±‡F²d¢Ô¹#cf=MŒx9¾aìÊ sÇ®Ìïô¯¤èOï„åÍš¢ÐÙÁÎåuS«LÓ'‡I0òþju5‚)71L‚Í,³öĆC0‰š`:ÁáIÑO@oüPüP~Ta~Ʀ_6žUüœâ÷ŲS˜Ÿ…s¹°o|‡ ¿™L,•èµ’™æÊûFíBô[Á¢ÃÁ²•¡Á’1ŠàÄ7fºL}ÌU öÿ‰´xuÞN{^R5‚ã?w÷cÒʸñê,Áôó¾‚MŸ²"8¿³kÆ„¹[â¼l‚ëë™`£Ì±º~@\š`ë ûl¶ÁÛxþƒx2WEn0ØÕ¸´´Á?\W:$‹¦•ï\‘«’­‘hÎîÍ€-IŒÔ溆/=_ãh!X(V§/eÄpþFAÄyeE§äו–V–Vž(¾¨lCiaÑQß]¸;?OùÈà7§üŽE¯ò;ÄïÄîÆ!?ðˆ$ž“W4Õ))›­ä¬´æ¶%“`u䆨*;ÃHO€Ÿzü$c§¿ŸøÃÆ/fÝùÉØj?/3+‘å"šw@‹W:³uFûÍ“â{½qdiüó¹‰áu ?ÑøÀ˜ßŽ»¦c—Pee ]«O™,›l·vŽ‘þMöyÍlÌ‚ E¹ŽN`ö6n„Ñîcu×"÷ü=¬kÉÃ&¸þ*u¼.^çþz´áL5E°s¬s¬Éðë=o6ÁÔ-1Á|&“G«Ž)Sccjѳ•¥Í]Í]•æJsc¹a¬ä–\ŒÏC5.Xµ&¯b˜óÇÕI<Ë™5R‚ÑA×ÅuXgéµ v£ø¹¶”„uÂz "¸˜{ìÔÞ©½Îh¹,œW›`Ò(_]—¿1cø]o+¢osæK^ZïV•Í<#%S¨ü+y•û ï·þ )‚E- Õºu÷ÏN&?ØÌ§D$—2•Tó.7Wƒy¬ßÆ™6θѕ!{I6-5…ÉŽâpËv‚‡y"_²§BOù×ûQM¥€"+Îè#š’ÈŠ#8ìÕÁ†3œ¿ÅsK ËÂÆÇ*K[zšŸiZÖ´L½moj¯,m,— å|cx XyÎ'1Á6ÃÖ9ly1dRÁÈLÙín/&6›=3“ÁÍ.÷ÝÒ™M/~®E5/[ÕÎEQŠXwCøtáå¸ÇoÔÊÙøÒïílüÊäÔ:§­è¾3¾7ñP(²=Ñgê÷A"Œ>‰n˜@ž­ôA4i*6ºo_4ŸšZçl¢çJEª‹Hè¥J‡û wŠö*”áõŸuouþ¨Œ½ˆ* ‰ÁøªB0È}?Ë® £Ë%‚¹»¡Á¨Mñå9ˆŒß™ÌM°z#Ìd:æÍ®þ±ßïêï|½ëÚ®kÛ¿Ù6¹iYùaPܰ¼ð81ü“ð$ä0a3¶‰ã¾D5dviêÍœˆäE¸Ýf‚^rS‡{:kiÐjŒ,Ô÷äAôk‚Aªè#²Š"Éf¥¶X›_ÔWjhcÜÜÎY K‚ãX§!Õe!ØT˜2Óªlg×LÇQ6‚ËFvÁ<}ª¾‡2ÈRûX­ýˆ!NÃÛ¼ë‚ЦñÎd§MÙ®{P %C¿æÍÔžÄ^,¯àpI8w'Xѧ FBñÛYîk\‚Û&9dÜ{ï™Ý»¶wmÏìžÛ{nïºvÌ!í¯¶ŽoîÁ Ëqƒà`½?à_ü&K°÷"Ÿ9Clºu,‚a#!XòÁλ7¤4öŒú³Wœ&“â0åyv™|X‹àTÿI‚³UfÓ}?‚‘[«ApîÌïÃ6SEÖu÷ÔÝÃlåNu)Tž¤÷aX\È„áË3F4j¿S¯ã†¸Áгe[ì•ê%M0Q¿¹³t§½yŬü$2O2mJ^iÑ`QîWÅi?FĦNb©.Oy´;‘ C-¿8Î+øWå¯5¾Ôü­¶Ov†ÝçõMV¶¥oËÄ•WNÈõÝÕ󡱟ê< sdW¼¯0Ÿô>‡+[ s7ðŒ2e›Øäî)ÕlÁ ±˜Î ª³€t×Ü $1EˆÄQâUeú eÂtJíiûO%yÞ)Õ­Ä‘éÛÍèýV¦ 6W”(xt„¬§{¿`æ0Ëô?º2ô†˜|Žý!Æ›ØK‚)Ó3‚©ÊpÆ“`òƒÑïœ?‚É)Ó[ Iãnuçè¹Sý–àËÑ"½½5 K°xu¯°‰WBVU4ç®ÌèmwrþKþhú>Y‚uFjD²Y°Á2!P²þô\jOŠà—Æ9ã[ZŸ%˜óÀÁhÔÕ˜àr_ÓÖÖï2Á}“'®œ2kê¦þ`ÚÑSÞ™z‰ÿÜw׸¯w\ÙraãcåÓQ§ƒzBÆŒS›`ªb‹Š³Ûì(×›ÊÉWÐ[]‚SQ¬ò¤vù1E0L=‰:Kÿ3ö•®_çs—+&ÿ—·s’ªºÒ°F‰¨ußõꪮê®ê÷ƒî¦úè £±µˆ’T¢(ƒLt‚2Ú ˆ Éb ¨#N@^#*J”Ð` ‘” Ö’%,uÄ 2 à#`ÏÞûœ}î­ÛÕ꿺oõíNèUýÕ®ÿì³ÏÞŠàÀQz¼]fh}µcTŽ<+eš}sótKd§o¢)^éÌPô~H0e˸öhŸ$ÁÄ­'#ÁÄ0»&èÕfk³k€à7Tž±D¯›‹è!Á…Õ4.ö®þ( «6öÁæŠÈøü÷b•rªFN‚eñ­åíU+KæÝmÿw6ÁªOš¯Ïo.‚ƒw$ÞK¾Û‰."{‡y`çbÌ#Á±±ÉGŠŽ—|Sþ;ŒÀ™C@o;hhóKMï4N¢(¼¢â™ÒOÒ{ Š[¼£‡°ß´ß<[{c*ÑÁ”÷Œõ4Á‰•…Š´ w]„ s³§Bp,^Þ^Þ^ðPhU6ÁúMö\«ópg™`q¢³#ÁrWÙsÊHu#áñ¼Ó@Wsœy3¯ÜÄ„Yï)¹À3g¼•A"c†õưj{RÖ/³G9kœ5Ö­8)Q;¡¦wɾ";T1¬awó#™m©¦`möŒLo}ëcoU8×å5—q$U£K‚q'3a¸·Ž€ ›—ŽM‰ïN6¥¯,V9ºú—u³ê[ÿÚ<¬yXÓ  )éúxíÅ5·–E{uy^c½Z %ú@R¯xšY)V’ª>¢ˆç‹)®2ë Öo¸“^6Áâl(0û (vQUBÉÕUk:MÁYÀ/fœý>8ëÛÉO‰'šS–Ò*ŽO¨ÝÐØ§‹ËçWqr—ŸVÖTŸÙIü«Oªû‰v­å}qnS[ªÜÄT‘-SݨÐ9\ŽÓ¿…¨»‰—`±‚,ÜDW{}qw“|[W‡n ÿÖ^ì,§Ó¾(¦|†àPï’$¸¡"=+Áâ|Mn‚yÿ‹³h‚½ý²Nñ+ÍC0V²ZC‚çG×GÆP¾#¸A°<7“Umiÿ vÌîr%ÈUçïážù$x°{Ì‘D0²7~ʵhêÜÜ!1uÖ]ÉÖxºL)‚ENÍO°[¬ñWLWI —`®‹`‚½BA§ï;!˜ÎÜ¡äü9$˜:ö. r–™_ºså4‚nV.‚'>/XöŒ•<~‚ókRs‹¿.{¹ü^ŒÂu³2óê?¯o©oÉŒíëÔ^\ys~‚)£ö6ʾ ¦<„<×Áüªê)Áª#J㻹—à=uN“`Q5$'a•\+˜‹`P‡>m 6.µ;AŒÂrƼçv*k­Z+,»˜ÐUV¦{++³˜|@ö¤|@t§D'aÞl­TÕ=þzbßÊPt¥ÒŠT¥<ÍE´n¥Iµ(Þ-æ:ÿ4ZYÕø{wgÃý߀ä_ÏiÏyY¼ÃÿÊþ•Óz§¶†f‡/,Ì{.Ö©à© ÅK×—Çû<Ô硚úºuêÔì«®ª˜P1¡ô®ôˆÔ9KÇâƒò>ŒÎ W‡«CSƒÅÔ=zˆNæƒ0þz©UìrÅ$w™Õ96¦‡‰ûžùªÛaÀ|ÕíF,kô€”ÀNŒ¹rF¹üÙ@»XY©Wʤl©S>Lîv¹¢óí@¨!^9Ë:@Õ‡[ΓVäújÕ¼+9ûàW…¸’^í"ßèŠNÒso÷7hNâ$3 Î3iH1Ò «;m |¼•%I0vß9u‚­•¡7"IÌ.Á”ßð,:®vM°š3Ç_{Vg0rLþô]ë];ãÅ/óL°:Ñ”ƒ`wWÙ|ÅÞYð½ê™Uuùƒ­I8u˼F¸ í v(ö¬OÌ&XÖ,ðYcÁôU™š˜, 6–9kB‘3!XÍÛðL}j:!˜(¾Gœ˜S;»³¶3^‚iÇU œíC‚ÑE ÁÈpü%`øÙ‚'ŠÅ«ÓçÒ+Òç,Sp"ÿ0Dà+bÇžÈë‡ê˜`ûjq¦¹+‚)¯Ö‚)Nûs 7áÚ)ЮêÔN‡Œ…ì8z@°÷¬:±°³áuG§ã$QPÉ0Çþ.¦€§Hpèá²TÃÒú!E–½“æÆ†;%X2ú3hu,t#2ìž¸ÇØ‹:D¥Ü}}#àÑuÂXȉßþj ¹#";ÿü©C…¼z"ÕÿÊ©'Þþ|’q½+ù>·…Ÿm:‘Ιy¬pÿ`‰OaʘLç–ÑOÔ?Œ1Üð¡ðå‹¿ˆ¿”¸` ~.-\š^Qp"ùeòËÂaìÅè›×øÝž*']Q¸§µ{톅fÛûɲ֧FÕh©]eYC†|xv4ØSzÜÅ_y¢]MíÊG*;]$ªAªsµ8ÉÔ¡ƒÊ›É5¤çEcTÀ³~÷/ÎØ¿µF¾ /v>†ù=@¾Òè÷öw§SýðÙ;W£Ñsʈë"²N™Š·–Œ«˜šÿœµ¦nµ-D.în 'ž(¤µimú6:£“±;”½{žÐ£œSÞVö@‚É ,“úæŽBfÞ™¬N8ö€`ªqñÌûe"6 ?Œ+:—àè±Kc—‚Û%¿›¸ ôz‡ØÇyýâŸ"½‚_øÈA0Æb¬I(žX”Ì{b|Æ­°QýÑN`ì¿à=£âæ_Á”¯8‹SÖFõiÎ&g3à<éÈ7镇+æ&B­ä&ø•Õ Á<Fuì‚`<©aŽ·¶‡2áGœJs<Œ±W˜s‚a¬ª”§Œ²œC—`SË\Ѥ—ëaø,÷8ܚѥ'»³ŸñsUÿ€ÜMöL;‰H5oVVïx¾ï=õ(®pw+º=޹H°ÌJ‚U¯žw( ¿¿5C³# ÁQìî¯@n!>(>ã½èLt¿BÈ0NŽ'amõUC7a-*¸á•̹…wBf‚Ë\©ŒgäY ùŠSõkŠ`QAÞÁY]¹øªº¦v‘5óœ—V©Úeþ‘OÒºBøa©ßm{éþz³¹ qcí9±ßáìG¯'7Á¹&ÙÓi›æXû æê&˜¯cÍæx w³¬ä‘î÷è˜`= Úv&K÷{·6ÍO°ê»Ö Á$o<Å粇‹ØÑ5Á|†®+‚#Ó#Ó£ Ñr æ}ˆñÓÚÚ…;÷K†%Áæg¢3`øPáµ×Ö^{¦½ß!Á¢fyæ”dœ÷Ug7nl.è÷@sA݈|­+‚½s•»#8‹\Á¢G0\Al'ô„¶P?n,} ìJo‡ï­6V›c¬õÖ]Ö]vĹ×Þ,—·†¶K- -ÅN'Ñ‘y¯¡„oUƒö„÷Àn2~8o‹½8ÌE( q8¸C¸Èt1[^M ¤nÛÞn§ò/É÷ø]÷rí#}¶>[ûH\uǧ¥ÚõúR}©qn¶´“ÚI¼¯ÿØ•¶D[¢—KMÒvÕÆx´KȘfL3÷:O„ç8—šÓ͘3Æ‚"½a¼amͺîÓ¦á Kú쯛Ó÷pY"üž5ÞŒé¥J½%þz›Þf¤Œ=)m“Þ¦Åôú í]Ðóò]Û³Ã%vÇøÄ0V2 ѯ§¬3DÝLœwB0®hoÖ›ý©¬t ·GzB°ùó7]l®µ#Hpp«sop‚Œ}#"½"½^ds¡©à~'cN"7ÁBÀoO´‹éò̽æÏ”`c¸1üô¶û…¯JŽ)~§pcìkçGšÒ•µÿ,±8±8ùM´¿½ítÖjA]Ì û îÐë)›`XÅñl"™_›è¿Æƒæn­Ûˆ^Ár=(Hž!Ås¬]åŠxDkµH0(‹[Ó4F¡äýEÚ•‚`!ñŒÇ Vâw±1Xð ûk&˜îK‚툹‘.p6;›ƒœ8vúCбw}߀ñV‘ #u¸«Ç·©»åIì ({]SŽM Át¢RÎeõuåÇ t•³ï\VOV¼.•òÒ‹<ÕÚ±, 6낃 Ö×¶7Ú™[Jk#?´Óæfc,|µFÄüGœ´’¡šÈûá÷‚•(k<ñ»®3‚µMH,HÌ_½ ¢Öë _T~Tœû‘2©ßé_ÁYÝz³ÏqbX΃ËE02|6 ¦X| l€çHl,¦hÛê'Xr“`Ìý*™cr kïGç q¸<<-:×x°²AqúFÑ#~~ªÈR~£ ùWD° ^œ îH°ŠÅ=$Xð{ö¶f†æW hÚм©ySæ–øgŠ`ØO0S,Èe}û«Æ]Ì+9̨I·€n‚:[n|’k.¾©&^Tµ‘Ðûnòødp½îç,RÑ{9î-œÆd™!6ߪßjÌ1æ#€´ ⌑ Rä¥äRøÜÀ³“ÁÇ¥eòÍ@ó æ Æbó|-˜ðŸøÿ5Ç/ ÇA@1U­e/¢._9_‰œY°ù;Éá=ц¼Ç03Œ»ËØË;¬EG‚ëÀ>Ó"{…OvÞOK /ß’8æ¤pn±<¬fdÉI-ÿ¦ö_ÅôÆ>9ÆX}v‡~§û]âw9z’%]„ße‚Á;Tƒ‡( “— ™ÓƒsŠËîè—lÚP;4~¾=ÉJ¯à$©›A@2LD#Ù@/þŒ~P›¥4æš-‚bx7L°‹é<ƒ®U+î Þ®=ÕbŠjé"T¥.ü3Y%ÉtSÖ¡+‚etýÎ&f%[E0|µ¶g£WðŒžY| 1ØG°ðÂöFpÆë½sŽÁKppGdºà7öqüÓä³CǨ¯ö’¸O䞨YËëW0$~O &ŠçsýS¬;C‚EìÍE°µ?òezkå슩-¡ù’ßœãýî&Gw«Þ#L•¿’`þ¾1'é)[’DZÍ%µ¤Ì·mS;xƒE·5¬j#µbž¬Å6ýP³>^­ìŽ`r¦y—9–cŽÁˆˆ ûýÝpg½7Mé*IµJµÑóã]½¸rCŒ?/ï½èJøÕÿ¡›€×¾–ô²½ì!¢ûãsâsp‡95«Ø*&`W‰²yŤö'òAÇòçÇ?•q8%u:åÎ"2÷ ú&ü¯˜¨æ@#Ážweˆ¾ë¼++âòzðìNzFÉœÄR³¬MÖw!³¼šŽÂœN×=ÆkèptHtHø˜ý!L”ÁàÈ£/ñ— §W ã.ÿÎ(é"h×&ÿ:L/òü®ÑŒùÿ N‘Û.…çÚØ×be.QúºÇbá1þ"{™uC0ÑÙ ÁÂe0¿fÅé ün •EÞ OŠâ‚`'©Š=ž‚,Ó«ÅC02Œ³‹xŽÅað³‚ßpudz|Nê¬ñ)ZU1¡f_æPÃ5ÛÆgÆÖþ¾jhÉTuªºp)Dæ«dNYÿ…ݦsìN0ÿî¶\‚ENBã°ý!Ð;Ó¬cR)îÁèŠí´f²™`¹Ž[‡¿owóãS%ØxÒ%·n–³3ãxž|v®{u¼g§Ü‹ xs KÁÆÆH±"<]X pÇXä}Ã7æ½FÕô9/3¶iJón< Úx]f^Ý€êªÒõéÉBÌM`7Œã‚^œ‡«²h"ãПIæ)åXyH]ŸøÝx6ñ;@[£­A2€‡ ÎÒdò“U¶Œï/Éζ ÷á®ô8Çãem²·+ƒ»Ã™ÐM¡›‚/…¿fÿ5ô=çç{0 &÷ Üð:t8‚`é&Šf0½#½D±ŸàvÌAËÄé3ó<§$8Õ¾ßJàüLûí`Eø§yVäÂàÉU`ï½,‚椘8>M‚]Ñ5Á¹Ž^P=¬éÁæ]Í%õ!A00|4z^¬)òK;rú£‹8‚Ñ›2ÃtúLÖ-žD'‘ObKÑŒò£}ÎëëdæeæõXõNŬƒO>‹]†ýSßò.¦š-Kv >E‚EV·{‚É!÷`§Ô) V†þ9œ‰<^^¹=ú‡ÈE¡ÿôŒQØO0:/Á¤Ó&8Òª¶vÊN…¦å_žQv´ø‰üûÂ½ä´Ø,‚U¡€9„fqÍÙ²ÀE°[/|0gÓ$±ę̂\á nÑÛJ’RÿNÌk»ÇôÇŒÖÁç &U~]7ºæå’¦¼ ì+˜(ÜýÍÚÑð ïQãTvMÒÊ.‚vœx*#$ÉâÿK8zÿŽÑl4#ÉÆc 9Mœý°pà)dõ$0ü[ðÁdaþÆôÞò«Êï-UÔ;µ¬ðG‰§¨Ž Ï€ž\"b·ù™äµ¿š¸¢\„[ù¢:¢Á¼›»Ëä$Ç«Ýk:-‘L™1ú½>xÆ÷}»ÌL3ßW÷úæÎÌʲÚãJ( {ÏwÝ÷½çÎ\˜Á˜A°ÉCÈ‘A Î<Â!"Ñì@ᓈHcŠøðVxE%”‰PM2ŽlÍd,ME,Œó®õ®õ~ï÷ÍÞ3{ÊÓz‡¹€öíß^ü×]kað½ÒÿÆVÅV%GÇÿ=ñTr^ÂN΋={"úeI±àøë|0™]Fj‚£6¡%¤šà¨Z,ü\æ]ŽÇ¹5­ºaN3§ v¯tþGüSøßÔºê²ú…Ã*†~«vZá^çP 0¼=&±íöÔî¬v¦ä Ø<ùÍJ0ÖàX7„€aóVg|¼OrkrVt’=Æl‡xÉ25¹,ûÅZTãü+Ÿ Xý{ˆ` –{XQà-9º/çܽêpÂÓnNÌNÇ©{¸ úØä>5Á¾F°¢XÓÁg…ä"Ø8ÌO°ü(LèW`ªWt ˜óÆ¡C뚘¿Î>W'Øž- èþèMŽNI3³»ð¿2%™àXcø¸d8Á*‘ÁØ¥ìÿšñs+ceÜêøðÊ]Ã&5½ÒôÊðë‡ýºæ”xØúPh Áæ1󘱾`,NÛk›$À°Š¡L‡‘àÐí~‚AQHnÍs@OÜ„u6Ι™‚aò¿Ø¯FÕgóVóVûaïJ’dæ[PËÝ>PÑ`r…!ˤ<a÷r.µ{eÓ˜—˜åU­ñÝÑDÖŒü¶ƒ×åLûbû®x¿ÔÏcÁT'æ%ð¾n‹˜»»ÖdßT”ïü õêCc×O¯Ö}È[ñ˜bÐÆaÒ@0דŸF/ü´ª&ûö"9`©&¤éú`RÖLk¦ù˜zÓ11z[ú!u{áÄ’ÓKÎ,9³ô†’3‹¿WTJ¦’Èð£îˆîœãÁJM”€AÞŒH–5~OIÁe$§O:p‡8gÓ ÿ&9jPÃð>@pÓà¦Áu[S œ =‚ÉÖƒe'8ü¼ìVë.ÁæÛöX`8H0ûß ÁÆHaíÂìš`Šr; „:—)îÍ¡ö÷] f~ÙÃÇÈäÒýï-©<ýg2»ÆW—¹Óû!XÿæKpø‰Ð¥'ƒàp¹¬·e#ØÑé;f¼<²À †‰`ìÛ "~(9ºpbÙOŒªü°òÊÛÊW—UTþfêBMMìþØý1 º(z±¯í$l—Än` ×´$] Øú¥ùu6Aðª‚z6ÜìN›…}ù2"UA_/C† EeÁ¸PךÍjë{ÐÑ|G¨ï52ˆüô )Eh2.ž Ŷ²ï2<=¼1¼z(0 ö §Ûn¶§FÔ¾T·¢è|Œþ€Qù¼–ó;²ihL0ý^I°0¾À»~–™Ëœßg¾\V˜Ùär¾ {‘ó¢ìŸ´3z;Ýåö`íR¸¶O]Ÿ æÏyŽ˜7‘°ÀÎGÁ&G^\©ÂYeŒvTu5 vúoÆ? ŒTfÐ6§êŠ×Ư¶g Öj·:Û"ñÈ3ñ«“mé†â1•}>=xÏàÒÁ¥Õ[´”žŸ>˜™•l‰¼YýÐý³s3Цþ;uÅGÏ^4P·à¼;ïm%±ö0Èûø(n1Z¬>ÎÖLcm¢qTÓº¦uõCŠGSvs£YgÖY×»ŸÃì5¹Û‚±{~·Y­ î‰ ô†v„vd#Èe ÝÅÅ÷”oJ¯a‚‘Þ.æwN0ïúÁMzƒíëÝîÁo½¬±Eª°ƒ6CÖ—ç”…éãìź ŒÛ+»I°ê{È“`™1îŠàÈ3±b÷rTÀDp$]+Ž¿å“jbCѰªaÕeµ +7•žÇï ÁÎ\bø4¬£d%^•ƒè„`öË:ÁrSdrYE¯Úgkæ•]ßãÌ‚­ë­ëãÊJ‹wD[u‚iÕ8¤î~ã~ŒÎ€äl÷•ù]=2SóK»Ã/ †ùî"o§L›N0|Ïß¹#(¦®¥}ûRfmF¸7’Ø`4ÛïFîµÇ‰æHk»»*Ó qå„ç&l%NÔ)òY4H‚1§?§]eÁûÌtá¦èq›ÉÉïžM†i"ïªPèyk H0LAÑþàZê@çž²©\+¦ŽÁ.+ T\}¾‰Œto`Y]vŸTBoá˜XÇØŒZ¸Õu%Áñ«Ó‹ß­ìS»°aUãèÆÃ‡‡þàÌW–/üYºoò”ØøèX÷Ïèƒ[QIc4ˆÿ¥³èõáì§x²øÚ4„Ú@Ap|­rŠ`£F 7.(¢ƒ}Pö¬H,½¢¢WÕ¥?Œ—ÚOâþÿ}vcêÑšwª†%&Y Ù–™^Ê/ô`ì*ÖÆ ù\Ÿ~ó®µÐÓÑÏè]&û2·O«|@n‚ñYçI°œp†Û‹ ØŒø FÍ›V²ŒŠ"@°ü¹Üû4­ 2H0÷² ªˆ Á2ÜÁuC5Ý77ôu/Un*ùFáÏRÓSÓ£ccës¬ç{˜`xzB02 Jâ÷uß:|ð‹pƒ vnŠÿ-1)r®øù+¯¡¿íïÆjã ZSôÝÁªp°{òyVè…«Í)æ Xþ©Âˆ\VÆÈðkÁ±ŠÐ FŠ)bS‘úNÍV’‘ÎRï}ˆú¦KŒJ˜;JèûXÙ¦~?›~ '1å.S5)ŠóBÖèYÇ_‹ˆ f”9§ßô”;qäŸE7QE„î ë„B©àf*¼@ŸµÔCÆ9ŽÌ8Ÿ€õæêb‚_½Ãܧƒ…&rÁÜ„Jóg³¥Špæºð¿í±Å`é•Eç”M¨[‡^xDÝ’NYY‘›Ú˜œ ZØyK¼ú‰¨ÐG°øÛ ž­ò0Bá5Qg;wdIN—·òÊ1ÓL¡8¢»XhÞΜâà ¯7}~è…‡ì'qwºø)sŸàøûÂÿCìVÁÎÎ:ÁsŒ³y,ðôîŒúë Ö7¦` ­Uμ1ÁÖmæ¨ÎVþ–†;óL0(“ÁX½óÌ=:Áîöh:¾W\ûœTÃÇ »¥þÕÚç*g”ìÊlINŽ…ÉP»ÙnFÞÁgd!M#Xî!1÷e#89°òñA¿¬‰¤ë=‚Á€_ã·Š^$˜HÕ+Ë\ƒ¯s·$U*¹œ£Ì›ôÁ»­G¬GX…àïo7„–{½Â ÌE°êä!ŠÑ¯æ XÕT˜4 ú Œäð 2á8 "4Å>`›è†H#/޾x#_h•} ¨ `Šócµ9ªàM`žv'› 5ÿSßôÁæuæuH1wEjY1$SS æ9ce#¸Ð‹²B˜^U~˜»{d$'ÞîÌ~ã{Sû‹Þ.ù êÉÁ¥õõ «†jX¸|ƒðÀ½ã_Œ¬‹Œþ÷lçlðà ¨eWð DøàóF‘²ÊŽ*‚eĦî’ª€¬¦p#Ô ûÉèsÉÉ‘ùÖ ¼äM‘ ¼ g4=!XŸØÔ ƾb"X^KÊM0Ôä:#˜³hÿßF? ]9Xö|0nïë‚`º¤!oÝk>8H0Fr="Xp9<7Á2¢1]?ʦ †`P‰ªLxáÊ5ó—Ö-©[R3¿â3e2[ž,‚õüƒê }P:ÁŠâþvÐÀ:ÁTÙ{ÕQðjøZ/’“WŽTÿÃ8fU%žéŸàT:âÙjzª" þ™+ôó¡å¡åÒÇ‚ä#”EcÓ¦·±×žÌÇqDFOJÕ(xU/u‚e…$<£ÁŸxOÚgLÖo¯.oÁ o츑»v¸S]V)ÔfÞ¬7!p•‰åÍדä>V•›  5KA¤©ª0v]†G¨îËC~“ü†>–Â<§ŠB/r6Í3_GP¨Š›·"c¢wÆÆ§¦ÇJ¾Qz~å¦ê­µ kSUýKT2¶pd²&¶XhËÁ(„ÞbRÁ×ÔƒzMà5àI]îlçNwŽâØ·Öx™54ákÍkÁà×ÞÏ‘ ‚á| ƹ¶™r[ɉÌ59áV×Ù³Œ¿> c#ÁêFR7ÆýlºOÏI°ÙÒÁÆÃ¡»C0tÿ¨¿ ;.™ø«¸CžªÒTaVýiÍÒ_èòÑ»@ ›¦Mk£‰§ïq&>â¯y–™I¥ZS¬¾Î9 V:Áà; eÜåÌ7+=“›Ù ¶®…v*Áó†T¾þß1ß ˜ Í1Ã÷ÉþI0Ú­òŒDË,›ŠÐ°†'¨¢ {P@±Þ'?wªTªÃý5¡ €á÷bãcG¥2Í…í%w¯Í¼‘ÚŸ¨Šï-Ž,p] ó›å;À˜ U ñžá§©` ¢»ÀÿBï„duƒ`Ì*x½ú½¯gvD'Ú£¡Çø»ºz¯:r0*ƒ_±îå)!®*SµYò›`¬Ñ¹¦+´þøˆýí#)›æ#XË?O=•\“ƒg£© ¬/÷¥®u¨"ëÙŽæ°¦\°t`=–SµUÙô”ñ¼ìíÛ‘óCŠP¡ð"Á¦ÈeÑX4fÏJB'·_«Š]Õö: Å“Ca8‹)þÆ–F$½ÉÞd¨yš53¾·hMò{6ÒIóŽ&ØÑi>غÁº&ï›eßFlÛ„Íu·ƒþ•ýIJ“£·‡1nœÌý¾Î)Êfªî*0`Šä˜`=bS׊÷Èè¿ß¡+®±¸éêÆâ!›K¸Ġ̇:#Xé^`ßÜÛÔO‘ƒ`{—½ËÜ.ØÕÖkt¹öÕäãSÓÖ{ÑþYK†5¼‡žfMÃ;ÎOÂânŒ{y„v¶Aÿ®ðÅ]ŒÚ;Ö¥U¹ˆ+)Ç‘…`Ù+A*bˆý‡ÈºÈ:çf{¸=ÜÜÏ9 ôž…^[uƒP#Ø×›¦LˆšÜ‹ÿT»é§_©Y_k?n]"ž¨úÖy?0×Úh»ª>ÉéùâðL¼AžÍæÌ7Rîµé«ŠÅ ¬{ðÖ(^W 7̯¡íò*Ö1jƒ'&4\Gý=‘wa¬ ¶*ßÍÖ ;L°þv0òPwgŒ;áž»yÔ¸/b…[ŒšÝ &¾ƒ—i;7Ír²q'^M„Ý'«‰ö7åEÞß£Þ •8Í[N c§»Œ&)ƒ›ƒ•Œš±¼JýÀ›ø¸cŠž“z.r.h7ìKÊœ[ôQd윱¶Ûk­s`{›ÝËî…]<9{··YFßË¡OÉI\zM8¢³Œyr+º4µ˜ïxsDÇWßèæ•ŠqCñ^ΈK‚ÏŠÔÝžÞ`ЯùŒ7ÈslíIßSwy}ñ€¿D6™ñ}°î¬ÞÓy¬òÉ="Ø9žÈ<Ú]‚õM~8¼öö€ÁæIpÁeV¡SA;$çãÔr§ûvjä ŸQ‚õ‰zw1nJšã6˜Aü”öÝïÖ.X$ vzÕˉœ¯€Š:§‰ŒûU—äKÔ5Éý½ÔÓš®Ï m°³`'^ÍAðàmg.ªü׎«;æD-wEª©þNä©üLo0@}3+ú`= ¿tÐ˰1Á¾Š,¨5&b©_Eú‚†‹¬p — .xO2¬>g‚ÕT}è2li&Ne%øO²kG ÓöÎKèaO|Ò\š"øOÔå£÷ñ)’5‚‘-`üY æ‹å®:ØVG;n²ÞV»4`Á_i›m^T$ ¦}Í>‚ÏÞ^3¡æäM `º{¬¦è­DtÓn6º$Åuï×?P?±öPÑŒÈöé4£ACÙÉ"ؼ˜\˜©Hì°UD¨î#| ûª wJ‚–’Æê)™JðÃxSXóÃ]̾V'çຠú}a›ˆN°±Óþ–Ú‰“Á”S‚ÕßUÁH±¾Ï(nÔf!8ôްÑÃÙú`ü7æ XÞ£‡==r>:|Àò!8üLQŸ’­å ‹úDÛí6ŒâÈŒ‰æCö çug˜õ;¼CšwAÅt/CDq°ÅDí „ËIO‡ŸÆû3ô‘ .,Ys¦Øï««JÂBí¡ö0\_¬ÑÅÕ¥®“+¾j øPÈ ŸG[¦(sÎÛ©ä+hìVÓFÜÍ£ÏÁte >%U”Ywì ÖÍõÀièfÔšŸVsù29ïƒ8›*D®¢XÛ:¥oÂf‚ÕF2V[Ã[a ”"XM~ÁªžLïY6OóvZи‰–6'ªl¥F°ÚB€“Ü4Ë ó,!΀÷ÿcè¿ÅÓ*ÐÕ5m«oÿ‚i1šð¤ê•dµÀ—èŸ*xʘg—¸Õ‰Õ‰ÕÑ4ÿæeÏx;+u¾WWâÎvá Ùm‘æh»Û`·YKƒG>[ryÑìÈqæ-Á\›Ã”W·Ù 6Rææ1Þ÷Œ·;!&T‚ƒgf‚±ÊÌ}Ã\óa’y·;î1èÁ ƒÝÞnïè–¸ãL†»G0Öír¬TCðq`':ìóÁY–SsÙ æÉឬf¹Áj–P#XíBÂù`v/·Ÿd8‚ÕW"Ø|Öùvá'µË‡¬©Zœ8nôO~Ê>x±­ÁÖR»ÍYnך{ͽL°Ì [—D>›>55Ù½ÔRü†Üe¢fÛ8‚ãnK×ç¤7ö ¿*èÅûŒ|«ü°w/W'Xå_(’Z9‚㈎ î°ã5¼Z´CQme‚áUÑ æßÏŠ¢·;Í£ö†¸3àöŠÿio0× £ÜDÁ˜Ð[òR.½.|R¼šßÉèŒ`"=+ÁD1s*rÌSGr4|Hõð=/µ0oWÙH½{ô|µšâFMÔ}ÊóÆêF0©ó~÷ X}OÛ’ ¯~__ˆÜ¬~…?žgÌ3ѵ˛¦ ï3lRÙUþáã«mi2Ôf¹`ùíH°5È^aýÎü®YmˆŽvß´Öv$õožãeQŒÜþq{ùñÔd&¹ÁÊ:!Øi±/²7$Ÿ«ýê¯×»½­cîF§%;Á’_I02|ëý¿@px«»¬»«½r¿ †ó$XUçI•u‡``Øšœ?ÁÊÿj×Ô ;W êÁÆzó˜u‘u‘Û×íkN‘œÕËêy*–üÂý/'/°·x®[Fua";ÔhJŒ#7ÑÁG¾&ªeÕ€Ÿ _<ßoR9„Ú¸óÜ×ÁÓ[ËšéUá-2Ž?«í '½ýá\× vaFnŸ×èÝv·ÊcíN›µ7r03©°%úÜ´ÿ×\O*ƒ ~–¯gÃAØü5ºúÒª]䫼 ›MëBÕAû¦”Š@ëLdJÕ&@Þ¹FïðÆy^U2®ÒsžÊùb/æ•„)¡Ooéû˜tÞ~KÛÌ¿û¯? Šø«ýˆ¼Æã© Õ TybØÓþŽóIÑÒš–!ÿQ}/Lqô†¹‚AUg¹k• ¶N¾Púvq“ûo‚aœ³·/Í(_û‹Gpemù•Ñßv$æ.zBpè&ñy'£icÍ, Á¾‰“H°½Ô*‡{ÂöRAòÕ@°°<Æ]”= #¿Áòsg¢qXv£åC°oÇ}&´ãd¬tu£¦è—Xä>aÞŸ?ÁÖœ c3sãa×YŒü6ÆÁQ³ò†5ýc ô¬GbϦ~#ðw%ÁΪØmÑÑö.A°>Y„SBÚÜlþJÐ{™0&w-ÙaºMÎyàÁ¾*°êÄë0Þ”mUÖ:¬͂à¤)ÿÚÿ›`žéwo‚Á®¦8ì!Ÿv³þj?a—`ÅïàÁp*¸þ•ÒÉü§Ñ]vžB-Oæ"ers'37U:AÕé´‹S4Ú¿ õ€Ì±ûZ½#²Á&¥­BË”ßëm>Î=;UTØÙq¤8wwjý¸Û '”Èñ´óï³l³‰ÛžªáŠŸÄ ž÷˜žÃÅç¾T ‚¹ê’ÝZÿÔ“3 Êàè–‰»Á8vºçQáse‚-É© >9CvƒökúôLLYŒ vt® ˜t±G°U£$k±O0®…`"·‚ÉSØ!8m.oøöÁ=³ßœ>Õ%XÏÒã:2=åLAÀm[í\àa½Þ81ƒ;u‚uqîîÔúÕHp–‹™`œAøÅæÜ׿àÁÔG÷4­½ÁášDÐA+¯&õÂEŠ&nq—!غGq§¦¿3ÃyÔƒsJžÜRÌhz>㌠ðZ5&AG?[Ùéiâ¬X?xõU æÿO{RµI~»g}‚mƃ2Á¢ºÂlUÄ53Kã í¯rš8‡Y]ɹҚ™ß·,›sµ~}þCš·á¬ÁY¤•°) rž¿7¨Ïˆt„ïø-3̤¢,ÆÇKײšéeÁv'Ç¿ámÆ Ù„¢7¾X…`™O¶sLÌoŠ!8w"L‚ Áð‹ç`g°äò³Í\¬ÆÌDs½ªÊYh‚Õó“´¯ëþ<ˆ Ë*wöà‰`œEøC3ÁÐ̶ž¢F‚m_Å:Lƒ«L°óíU!˜æhÈoÌ!8_ƒÍyñVüJ‚)>Æ*\>×C°=n7¥Í$2;ߪ-Ã"ã1‚µ3pÔ_LߪD°£JF 8Lr'@.?ûÛìq +=ñ S)áT¤C5˜9rVE(Jáñ ýÏx8½ž¤âˆŠIÑótͯ×è@O´?ÚŸuÓk¯tr¹5¹ïËüºŽ8’+É•ü;êgG“£Å´˜¢þýMìÌN×ì‘_ïù³¶™‘a纴$ÛÑ…¤w]z;ËD8!wz Údç±[vÜ´v[‡L&ò™Éãù}Éuµ –]²¸0û>¿rj­q˜áŽÝ :lmÚN–b³ÓSãi"j/ñ§©Â|;úniÆ1mK°e4;kn‚ƒ•ÁÊjƒßx(í£êC0éfs~<Á”£FðôT#xØéš —ô¢Ðu£%˜Ÿ%ÁÚØ%8]¤xU§ïfQèÎFïF~mú%ºA+œ»_¨ÚÎÿ\XˆÈwýw=AtÆJ0ê FKpŠeË/æì\4+8«§ÐjZítZ¬®áåç;”ønªµD3]ÁÁ¡¨.Bh‚ù4æýœ_Áã¼VŸÙW%$­ù®ô‘äǸÅì,X‡'íjóÝOÖnQ€ÞËŠây&&ë Žqu‚ÉAõuëøS2 +ŠA-¹h~GÿH!LïÑAbxZ:Í:IS'¼éŠŸ„Îv—`;ÓS|$™Z~æÍqSgý`aG¼ME‡¹³‹é~õ)gÞéºÓîu­ß° P´¢ïÓï•ówâ–l_å1Á§Lˆ]œ%½RŸ’üRZ‘›¹¥ÕJpÒ·ŽÁP¨ð©D0ºˆFC°ž!©¾)A0UV³|5aöÈ>ÁÁÃ*j ˜3>Á½.ÁDíîâîrïô¡r¯Š§ ÝI0Öcô£Í'ØŸ.·œ~ÕÏÛ7ÿàüƒsßkª+ìP¿ÙãH0Ï~‚YEX5Q`¢x‚ƒþxW¼KLRA`çf¯õy0e½3`¨ãÜD¸&ª‹êX9‡‚C|M••âlª‡3:œŠÿ\ïœÏ*V¸bÒ!Zì¹Ó¡í¢!Vý»è0‚± «0“ŠÁ}&xçv6žEçŬ…MfY;ÿE—È÷]ÑKúw °´´·´·|³¾½ñ¹Ÿ5ô5ôÕ·—o——§ëòSòSâÃñáüšÛþIêf‡#Å´€lò‹õrV{ê×4OëÅô¥Æ¶‹7.I—¤{àÕÒ5¥ˆWŠé¼¢^ÂVÚ𽕧˜öàgë?7$®@ß qÌ™$&]d¤¨·Ö«^å 18‹ õÀJB‘›[¨Èí {0í;«|¯ìØ®•D‚YûV#ØY‹¯jï>³_»#©•×677N[“=‚mߨ &í[`œ´`»W!ôw—n”ö*z'ÏÊ7ŸnùaÎùæRÓ‰/Ô·+Ž·¢“YSLîSD'BsŒ.x9»ˆ Öôò¬dMpᛦe V/ù/ÞØ¶¢q¥Ò߀áŒâjãs‰`[uY`¹ß‹`Ü/±{æ I°â÷šO0Ïí™àû&‰ÇÄcâ1†Ç?3Ñv»Àÿskycat-3.1.2-starlink-1b/rtd/install.sh000077500000000000000000000042121215713201500177320ustar00rootroot00000000000000#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5; it is not part of GNU. # # $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" instcmd="$mvprog" chmodcmd="" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; *) if [ x"$src" = x ] then src=$1 else dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` fi # Make a temp file name in the proper directory. dstdir=`dirname $dst` dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp # and set any options; do chmod last to preserve setuid bits if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi # Now rename the file to the real destination. $doit $rmcmd $dst $doit $mvcmd $dsttmp $dst exit 0 skycat-3.1.2-starlink-1b/rtd/library/000077500000000000000000000000001215713201500173725ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/rtd/library/LabelValue2.tcl000066400000000000000000000035121215713201500221750ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id: LabelValue2.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # LabelValue2.tcl - Widget displaying a label and two values # # who when what # -------------- --------- ---------------------------------------- # pbiereic 01/03/01 Created # This widget displays a label and two values. # Class 'LabelValue' already creates a label and an entry. # This class adds an additional entry widget packed after the LabelValue object itk::usual LabelValue2 {} itcl::class util::LabelValue2 { inherit util::LabelValue constructor {args} { eval itk_initialize $args } protected method init {} { $w_ config -disabledforeground black -state disabled pack $w_ -fill x -expand 0 # add an additional entry itk_component add entry2 { entry $w_.entry2 -justify right -textvariable {} } { keep -textvariable -relief -borderwidth -show rename -font -valuefont valueFont ValueFont rename -width -valuewidth valueWidth ValueWidth } $itk_component(entry) config -textvariable [cget -textvariable] -justify right config -value2 [cget -value2] pack $w_ $itk_component(entry2) \ -anchor w -expand 1 -fill x -padx 1m -ipadx 1m $itk_component(entry2) config -textvariable $itk_option(-textvariable2) } # -- options -- itk_option define -shelp shelp Shelp {} { add_short_help $w_ [cget -shelp] } itk_option define -textvariable2 textvariable2 Textvariable2 {} # set the value displayed in the second entry itk_option define -value2 value2 Value2 {} { if {[info exists itk_component(entry2)]} { $itk_component(entry2) config -state normal $itk_component(entry2) delete 0 end $itk_component(entry2) insert 0 $itk_option(-value2) $itk_component(entry2) config -state disabled } } } skycat-3.1.2-starlink-1b/rtd/library/Rtd.tcl000066400000000000000000000676511215713201500206460ustar00rootroot00000000000000# E.S.O. - VLT project # "@(#) $Id: Rtd.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # Rtd.tcl - real-time image display application class # See man page Rtd(n) for a complete description. # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 11/10/95 created # 23/06/96 added real-time test (../test/tRtd), use -debug 1 option # P.Biereichel 30/06/97 attach to camera in method rapid_frame_command # Added itk_option(-with_warp) # Default itk_option(-disp_image_icon) set to 0 # A.Brighton 22/03/98 Added -float_panel option to allow info panel to be # in a popup window (default is off, no change), # added -panel_layout option to allow changing the # order of the zoom and pan windows in the layout # (default is the same as before, no change). # P.Biereichel 22/03/99 Added bias subtraction to real-time menu # P.Biereichel 04/08/99 Added itk_options -attach, -geometry # Added rtd_status and rtd_about # P.Biereichel 25/05/00 Added auto scale # P.Biereichel 20/04/04 Added $w_ to input_dialog in method set_camera itk::usual Rtd {} # This class defines the top level window for the rtd (real-time image # display) application. The window contains a menubar with rtd related # items, an RtdImageCtrl widget for displaying the image, and related # info and a short help window. # # The easiest way to use this class is via the "start" method (inherited # from TopLevelWidget). This creates an instance of this class and # passes any command line options as public variables to the class and # waits for window to be exited. Alternatively, you can create the # instance in the usual way for itcl classes and withdraw the main # window ".", if it is not being used. # # One global variable is assumed to have been defined: # # rtd_library - dir containing Rtd Tcl sources. itcl::class rtd::Rtd { inherit util::TopLevelWidget # constructor: create a toplevel window constructor {args} { eval itk_initialize $args } destructor { catch {kill $rapid_pid_} } # This method is called after the options have been evaluated. protected method init {} { global ::argv0 ::errorInfo ::rtd_version # set/get X defaults first time through - can be overridden in # subclass and/or in user's .Xdefaults file if {$itk_option(-number) == 1} { setXdefaults } wm protocol $w_ WM_DELETE_WINDOW "[code $this close]" feedback "initializing user interface..." if {"$itk_option(-number)" == "1"} { wm title $w_ "Rtd - Real-Time Display, version $rtd_version" } else { wm title $w_ "Rtd - Real-Time Display, version $rtd_version ($itk_option(-number))" } wm iconname $w_ Rtd # set rtd camera if not set on command line, default to environment var global ::env if {"$itk_option(-camera)" == ""} { if {[info exists env(RTD_CAMERA)]} { config -camera $env(RTD_CAMERA) } else { config -camera RTDSIMULATOR } } feedback "making image window..." # create the rtd image widget and exit on errors, such as no more # colors, no more memory... if {[catch {make_rtdimage} msg]} { puts $errorInfo exit 1 } # display the image also as an icon ? if {$itk_option(-disp_image_icon)} { feedback "icon..." # optional RtdImage image icon itk_component add icon { rtd::RtdImageIcon $w_.icon \ -image $itk_component(image) \ -usexshm $itk_option(-usexshm) \ -usexsync $itk_option(-usexsync) \ -verbose $itk_option(-verbose) \ -subsample $itk_option(-subsample) \ -center 0 } wm iconwindow $w_ $w_.icon } feedback "menubar..." # add the menubar and short help add_menubar pack $itk_component(image) -fill both -expand 1 make_short_help # make a message if we are using a private colormap if {[$image_ cmap isprivate]} { set prog [file rootname [file tail $argv0]] catch { puts "\n$prog: unable to allocate enough colors for image display \ in the default colormap - using a private colormap. If this \ causes any problems with color flashing, try exiting other \ color intensive applications (such as netscape) first\n" } } if {$attach_} { after idle [code $this attach_camera] } else { after idle "$itk_component(image) updateCameraStatus $itk_option(-camera)" } } # this method can be redefined in a subclass to get feedback during # startup public method feedback {msg} { } # set default X resources for colors and fonts, and set some default key # bindings. This is done in a method so that it can be overridden by a subclass. # These are built-in defaults that the user can also override in the ~/.Xdefaults # file. public method setXdefaults {} { rtd::setXdefaults } # create the rtd image widget protected method make_rtdimage {} { set image_ $w_.image # RtdImageCtrl(n) widget containing image and control panel. itk_component add image { rtd::RtdImageCtrl $image_ \ -file $itk_option(-file) \ -usexshm $itk_option(-usexshm) \ -usexsync $itk_option(-usexsync) \ -verbose $itk_option(-verbose) \ -shm_header $itk_option(-shm_header) \ -shm_data $itk_option(-shm_data) \ -min_colors $itk_option(-min_colors) \ -max_colors $itk_option(-max_colors) \ -drag_scroll $itk_option(-drag_scroll) \ -scrollbars $itk_option(-scrollbars) \ -subsample $itk_option(-subsample) \ -sampmethod $itk_option(-sampmethod) \ -use_zoom_view $itk_option(-use_zoom_view) \ -zoom_view_propagate $itk_option(-zoom_view_propagate) \ -with_zoom_window $itk_option(-with_zoom_window) \ -dozoom $itk_option(-dozoom) \ -with_pan_window $itk_option(-with_pan_window) \ -zoom_factor $itk_option(-zoom_factor) \ -zoom_width $itk_option(-zoom_width) \ -zoom_height $itk_option(-zoom_height) \ -pan_width $itk_option(-pan_width) \ -pan_height $itk_option(-pan_height) \ -colorramp_height $itk_option(-colorramp_height) \ -color_scale $itk_option(-color_scale) \ -default_cmap $itk_option(-default_cmap) \ -default_itt $itk_option(-default_itt) \ -with_colorramp $itk_option(-with_colorramp) \ -rapid_frame_command [code $this rapid_frame_command] \ -feedback [code $this feedback] \ -port $itk_option(-port) \ -shorthelpwin $this \ -debug [expr {$itk_option(-debug) != 0}] \ -camera $itk_option(-camera) \ -float_panel $itk_option(-float_panel) \ -panel_layout $itk_option(-panel_layout) \ -panel_orient $itk_option(-panel_orient) \ -with_grid $itk_option(-with_grid) \ -with_warp $itk_option(-with_warp) \ -min_scale $itk_option(-min_scale) \ -max_scale $itk_option(-max_scale) \ -pickobjectorient $itk_option(-pickobjectorient) \ -updatePick $itk_option(-updatePick) \ -xscale $itk_option(-xscale) \ -yscale $itk_option(-yscale) \ -image_directory $itk_option(-image_directory) } # If this is a cloned widget, use a different image name if {[cget -number] > 1} { $itk_component(image) config -name \ "[$itk_component(image) cget -name][cget -number]" } } # add the menubar at the top of the window protected method add_menubar {} { # menu bar TopLevelWidget::add_menubar # add menubuttons and menus add_file_menu add_view_menu add_graphics_menu add_realtime_menu add_help_menu } # add the File menubutton and menu protected method add_file_menu {} { set m [add_menubutton File] add_short_help $itk_component(menubar).file \ {File menu: load, save, print, clear image, new window, exit application} add_menuitem $m command "Open..." \ {Open and display an image file} \ -command [code $this busy "$image_ open"] \ -accelerator "Control-o" add_menuitem $m command "Reopen" \ {Reload the image display after the image has changed on disk} \ -command [code $image_ reopen] \ -accelerator "Control-v" add_menuitem $m command "Save as..." \ {Save the current image to a file} \ -command [code $image_ save_as] \ -accelerator "Control-s" add_menuitem $m command "Save region as..." \ {Save a section of the current image to a file} \ -command [code $image_ save_region_as] \ -accelerator "Control-S" add_menuitem $m command "Print..." \ {Print the current image to a file or printer} \ -command [code $image_ print] \ -accelerator "Control-P" add_menuitem $m command Clear \ {Clear the image display} \ -command [code $this clear] $m add separator add_menuitem $m command "Bias Image..." \ {Control subtraction of a bias image} \ -command [code $image_ set_bias] \ -accelerator "Control-b" $m add separator add_menuitem $m command "New Window" \ {Display up a new main window} \ -command [code $this clone] \ -accelerator "Control-n" add_menuitem $m command "Close" \ {Close the main window and exit if there are no more windows} \ -command [code $this close] $m add separator add_menuitem $m command Exit \ {Exit the application} \ -command [code $this quit] \ -accelerator "Control-q" } # add the VIew menubutton and menu protected method add_view_menu {} { set m [add_menubutton View] add_short_help $itk_component(menubar).view \ {View menu: manipulate colors, cut levels, pixel info} add_menuitem $m command "Colors..." \ {Display a window for manipulating the image colormap} \ -command [code $image_ set_colors] \ -accelerator "Control-c" add_menuitem $m command "Cut Levels..." \ {Display a window for manipulating the image cut levels} \ -command [code $image_ component info cut_level_dialog] \ -accelerator "Control-l" add_menuitem $m command "Cuts..." \ {Display a graph of pixel values along a line drawn interactively over the image} \ -command [code $image_ spectrum] \ -accelerator "Control-u" add_menuitem $m command "Pick Object..." \ {Select an object or star in the image and display statistics} \ -command [code $image_ pick_dialog] \ -accelerator "Control-p" add_menuitem $m command "Fits header..." \ {Display the FITS header for the current image} \ -command [code $image_ view_fits_hdu_header] \ -accelerator "Control-f" # XXX note: the WCS Info impl. still needs work to display the # correct values (setting values is OK) # pbiereic: Let's wait for an SPR add_menuitem $m command "WCS Info..." \ {Set/Display World Coordinate information for the current image} \ -command [code $image_ wcs_info_dialog] add_menuitem $m cascade "Pixel Table..." \ {Display a table of pixel values surrounding the mouse cursor} \ -menu [menu $m.pix] $m.pix add command -label "3x3" -command [code $image_ pixel_table 3 3] $m.pix add command -label "5x5" -command [code $image_ pixel_table 5 5] $m.pix add command -label "7x7" -command [code $image_ pixel_table 7 7] $m.pix add command -label "9x9" -command [code $image_ pixel_table 9 9] add_menuitem $m cascade "Magnification" \ {Set the magnification factor of the image display} \ -menu [menu $m.mag] after idle [code $itk_component(image) component info component trans fill_mag_menu $m.mag] $m add separator if { ! $itk_option(-float_panel) } { add_menuitem $m checkbutton "Hide Control Panel" \ {Toggle the visibility of the upper control panel} \ -variable $w_.hide_control_panel -onvalue 1 -offvalue 0 \ -command [code $image_ hide_control_panel $w_.hide_control_panel] } add_menuitem $m checkbutton "Hide Popup Windows" \ {Toggle the visibility of the popup windows} \ -variable $w_.hide_windows -onvalue 1 -offvalue 0 \ -command [code $this hide_windows $w_.hide_windows] if {0} { add_menuitem $m checkbutton "Show Grid" \ {Toggle the visibility of the image ra,dec grid} \ -variable $w_.image.grid -onvalue 1 -offvalue 0 \ -command [code $image_ show_grid $w_.image.grid] } $m add separator add_menuitem $m checkbutton "Auto scale" \ {Scale the image to the max. visible size} \ -variable $w_.autoscale -onvalue 1 -offvalue 0 \ -command [code $image_ autoscale $w_.autoscale] $m add separator add_menuitem $m command "Select FITS HDU..." \ {Display the available FITS HDUs (header/data units) and select the current HDU} \ -command [code $image_ display_fits_hdus] } # add the Graphics menubutton and menu protected method add_graphics_menu {} { set m [add_menubutton Graphics] add_short_help $itk_component(menubar).graphics \ {Graphics menu: display graphics window or set graphics options} add_menuitem $m command "Toolbox..." \ {Display the graphics toolbox for drawing on the image} \ -command [code $image_ show_toolbox] \ -accelerator "Control-t" $m add separator [$image_ component draw] add_menuitems $m $m add separator add_menuitem $m checkbutton "Hide Graphics" \ {Toggle the visibility of the image line graphics} \ -variable $w_.hide_graphics -onvalue 1 -offvalue 0 \ -command [code $image_ hide_graphics $w_.hide_graphics] } # add the Real-time menubutton and menu protected method add_realtime_menu {} { set m [add_menubutton "Real-time"] add_short_help $itk_component(menubar).real-time \ {Real-time menu: real-time display commands. rapid frame} add_menuitem $m command "Attach Camera" \ {Attach the real-time camera - start receiving images} \ -command [code $this attach_camera] \ -accelerator "Control-a" add_menuitem $m command "Detach Camera" \ {Detach the real-time camera - stop receiving images} \ -command [code $this detach_camera] \ -accelerator "Control-d" add_menuitem $m command "Set Camera..." \ {Set the real-time camera name} \ -command [code $this set_camera] $m add separator add_menuitem $m cascade "Rapid Frame" \ {Create a rapid frame by interactively drawing a rectangle on the image} \ -menu [menu $m.rapid] $m.rapid add command -label "In Canvas" \ -command [code $image_ rapid_frame 0] $m.rapid add command -label "In Separate Window" \ -command [code $image_ rapid_frame 1] $m.rapid add command -label "Delete Rapid Frame" \ -command [code $image_ delete_rapid_frame] $m add separator global ::$w_.preview_mode set $w_.preview_mode 0 add_menuitem $m checkbutton "Preview Mode" \ {Preview mode: copy the real-time image from shared memory to local memory} \ -variable $w_.preview_mode -onvalue 1 -offvalue 0 \ -command [code $image_ preview $w_.preview_mode] $m add separator add_menuitem $m command "Record/Playback Images..." \ {Record and playback real time images} \ -command [code $this record] if {$itk_option(-with_perftest)} { $m add separator add_menuitem $m command "Performance..." \ {Performance test: enable interactive performance test parameters} \ -command [code $image_ perftest] } } # add a menubutton with help items protected method add_help_menu {} { set m [add_menubutton "Help" {} right] add_menuitem $m command "Status..." \ {Display a window with status information} \ -command [code $this rtd_status] add_menuitem $m command "About Rtd..." \ {Display a window with information about this Rtd version} \ -command [code $this rtd_about] add_short_help $itk_component(menubar).help \ {Help menu: display information about this application} } # make a new main window public method clone {} { global ::rtd_usage # use the -noop option to avoid reloading the main image (part of $argv list) after 0 [code util::TopLevelWidget::start Rtd "-noop" "$rtd_usage"] } # close the application public method close {} { delete object $this } # quit the application public method quit {} { delete object $this after idle exit } # attach the current camera public method attach_camera {} { # debug: for testing if {$itk_option(-debug) == 1} { utilReUseWidget rtd::tRtd $w_.tRtd \ -camera $itk_option(-camera) \ -rtdimage $image_ \ -testprog [cget -testprog] \ -interval $itk_option(-interval) } $image_ attach_camera $itk_option(-camera) $itk_component(image) updateCameraStatus $itk_option(-camera) } # detach the current camera public method detach_camera {} { if {$itk_option(-debug) && [winfo exists $w_.tRtd]} { $w_.tRtd close } else { $image_ detach_camera } $itk_component(image) updateCameraStatus $itk_option(-camera) } # popup a window to query for new camera public method set_camera {} { set sts [[$image_ get_image] camera attach] if {$sts} { set s "\"$itk_option(-camera)\" is attached" } else { set s "\"$itk_option(-camera)\" is detached" } set cam [input_dialog "The current camera is: \"$itk_option(-camera)\"\n$s\n\ Please enter a new camera name:" $w_] if { $cam != "" } { configure -camera $cam if {$sts} { attach_camera } } } # Methods for the playing and recording of images. public method record {} { $image_ record $itk_option(-camera) } # add the short help window and add some help texts for the menu buttons protected method make_short_help {} { TopLevelWidget::make_short_help } # Called for "Clear" menu item. Clear the image and delete all graphics public method clear {} { $image_ clear # delete any remaining graphics set canvas [$image_ get_canvas] foreach tag [$canvas find all] { if {"[$canvas type $tag]" != "image"} { $canvas delete $tag } } } # This method is called when the user creates, moves, resizes # or deletes a rapid frame. # # The args are: # # frameId = unique rapid frame id for use with rtdServer # # name = unique name for the frame # # op = {move,resize or delete}, # # x, y = coords of upper left corner of frame in image # # w, h = dimensions of frame. protected method rapid_frame_command {frameId name op x y w h} { if {! $itk_option(-debug)} { return } catch {kill $rapid_pid_} if {"$op" == "delete"} { return } set im [$image_ get_image] $im convert dist $x $y canvas ix iy image $im convert dist $w $h canvas iw ih image if {[catch {set rapid_pid_ [exec $itk_option(-testprog) \ -v $itk_option(-verbose) \ -t $itk_option(-interval) \ -x $ix -y $iy -w $iw -h $ih -f $frameId &]} msg]} { error_dialog "error starting $itk_option(-testprog): $msg" } else { $image_ attach_camera $itk_option(-camera) } } # display a popup window with status information public method rtd_status {} { set t1 "Rtd [package versions Rtd], Status" set s1 "Object:\t\t[[$image_ get_image] object]" set s2 "Camera name:\t[cget -camera]" if {[[$image_ get_image] camera attach]} { set s3 "Camera:\t\tattached" } else { set s3 "Camera:\t\tdetached" } DialogWidget $w_.rtd_status \ -messagewidth 6i \ -justify left \ -text "$t1\n\n$s1\n$s2\n$s3" \ -title "Status" $w_.rtd_status activate } # display a popup window with information about Rtd public method rtd_about {} { global tcl_pkgPath rtd_library tclutil_library astrotcl_library set rtdLoaded {} foreach d [info loaded] { if {[lsearch $d Rtd] != -1} { set rtdLoaded [lindex $d 0] break } } set t1 "Rtd version:\t[package versions Rtd]" set t2 "Rtd shared library:\t[abs_path $rtdLoaded]" set t3 "Rtd library path:\t[abs_path $rtd_library]" set t4 "Tclutil lib path:\t[abs_path $tclutil_library]" set t5 "Astrotcl lib path:\t[abs_path $astrotcl_library]" set t6 "Tcl version:\t[info patchlevel]" set t7 "Tcl package path:\t$tcl_pkgPath" set t8 "Package versions:\t" foreach el "Tclx Itcl Itk Tkx BLT" { set t8 "$t8$el[package versions $el] " } DialogWidget $w_.rtd_about \ -messagewidth 12i \ -justify left \ -text "$t1\n$t2\n$t3\n$t4\n$t5\n$t6\n$t7\n$t8" \ -title "About" $w_.rtd_about activate } # return absolute pathname protected method abs_path { path } { set dir [file dirname $path] set tail [file tail $path] set cwd [pwd] set err [catch {set adir [cd $dir ; pwd]}] cd $cwd if { $err } { return $path } return [file join $adir $tail] } # -- public variables (also program options) -- # image file to display itk_option define -file file File {} # Float the control panel (better real estate control on small displays). itk_option define -float_panel float_panel Float_panel 0 # flag: if true, try to use X shared memory for images itk_option define -usexshm useXshm UseXshm {1} #flag: if true, try to use X synchronisation itk_option define -usexsync useXsync UseXsync {1} # This flag controls whether the FITS image header is kept in # sysV shared memory (see the rtdRemote interface for use of this) itk_option define -shm_header shm_header Shm_header 0 # This flag controls whether the FITS image data is kept in # sysV shared memory (see the rtdRemote interface for use of this) itk_option define -shm_data shm_data Shm_data 0 # specify the min number of colors to allocate before using # a private colormap (not impl.) itk_option define -min_colors min_colors Min_colors 30 # specify the max number of colors to allocate before using # a private colormap (not impl.) itk_option define -max_colors max_colors Max_colors 60 # flag: if true, print diagnostic messages itk_option define -verbose verbose Verbose {0} # flag: if true, use faster subsampling algorithm when shrinking images, # otherwise use a pixel algorithm defined by option -sampmethod itk_option define -subsample subsample Subsample {1} { if {[info exists itk_component(image)]} { $itk_component(image) config -subsample $itk_option(-subsample) } } # sampling method to used when option -subsample is 0 itk_option define -sampmethod sampmethod Sampmethod {0} { if {[info exists itk_component(image)]} { $itk_component(image) config -sampmethod $itk_option(-sampmethod) } } # default (midas) colormap itk_option define -default_cmap default_cmap Default_cmap {real} # default (midas) intensity transfer table itk_option define -default_itt default_itt Default_itt {ramp} # camera name: default: $env(RTD_CAMERA), if set, otherwise RTDSIMULATOR itk_option define -camera camera Camera {} { if {[info exists itk_component(image)]} { $itk_component(image) updateCameraStatus $itk_option(-camera) } } # Panel layout order: set to one of {saoimage reverse default} # to change the layout ordering of the panel windows. # "saoimage" puts the info first, followed by pan and zoom, # "reverse" reverses the default order, which is {zoom info pan}. itk_option define -panel_layout panel_layout Panel_layout {} # Panel orient: one of {horizontal vertical} (default: horizontal) itk_option define -panel_orient panel_orient Panel_orient {} # zooming factor itk_option define -zoom_factor zoom_factor Zoom_factor 4 # Width of zoom window itk_option define -zoom_width zoom_width Zoom_width 152 # Height of zoom window itk_option define -zoom_height zoom_height Zoom_height 152 # height of the colorramp subwindow itk_option define -colorramp_height colorramp_height Colorramp_height 12 # width of panning window itk_option define -pan_width pan_width Pan_width 152 # height of panning window itk_option define -pan_height pan_height Pan_height 152 # flag: if true (default), show the color ramp window itk_option define -with_colorramp with_colorramp With_colorramp 1 # flag: if true, use a "view" of the main image for the zoom window # otherwise zoom directly from the X display. # The advantage of the first approach (-use_zoom_view 1) is that the zoom # is accurate even when the main image is shrunken. # The second (-use_zoom_view 0) is faster and allows more accurate positioning. itk_option define -use_zoom_view use_zoom_view Use_zoom_view 1 # flag: if true, changes in main image scale will propagate to the zoom window, # otherwise controls are displayed so the user can manually change it (ZoomView only) itk_option define -zoom_view_propagate zoom_view_propagate Zoom_view_propagate 1 # flag: if true (default) make a zoom window itk_option define -with_zoom_window with_zoom_window With_zoom_window 1 # flag: if true (default) make a panning window itk_option define -with_pan_window with_pan_window With_pan_window 1 # flag: if true, turn on zoom window itk_option define -dozoom dozoom Dozoom 1 # flag: if true, display a copy (view) of the image as an icon itk_option define -disp_image_icon disp_image_icon Disp_image_icon 0 # flag: if true, set bindings to scroll with the middle mouse button itk_option define -drag_scroll drag_scroll Drag_scroll 1 # flag: if true, display scrollbars to scroll the image itk_option define -scrollbars scrollbars Scrollbars 0 # default port for remote connections (0 means system chooses a port) itk_option define -port port Port 0 # debugging flag: enables real-time simulation with $testProg (below) itk_option define -debug debug Debug 0 { global ::env if {$itk_option(-debug) == 1} { set cam rtdtest if {[cget -number] > 1} { set cam "$cam[cget -number]" } set env(RTD_CAMERA) $cam configure -camera $cam } } # for testing: name of test program used to generate real-time updates itk_option define -testprog testProg TestProg "tRtd" # for testing: interval between updates in ms itk_option define -interval interval Interval 500 # with performance tester utility in menu bar itk_option define -with_perftest with_perftest With_perftest 1 # option to warp the mouse pointer itk_option define -with_warp with_warp With_warp 1 # option to include grid button (default to off, since it doesn't work # well yet on some images) itk_option define -with_grid with_grid With_grid 0 # minimum allowed scale value itk_option define -min_scale min_scale Min_scale -10 # maximum allowed scale value itk_option define -max_scale max_scale Max_scale 20 # Set the default color scale algorithm to one of: {linear log sqrt histeq} itk_option define -color_scale color_scale Color_scale linear # dummy option, used when cloning the main window, in place of "-file" itk_option define -noop noOp NoOp {} # -orient option for Pick Object window itk_option define -pickobjectorient pickObjectOrient PickObjectOrient {vertical} # option to update RtdImagePick after a real-time image event itk_option define -updatePick updatePick UpdatePick {1} # default scaling factor itk_option define -xscale xscale Xscale 1 itk_option define -yscale yscale Yscale 1 # attach to camera itk_option define -attach attach Attach {0} { set attach_ [cget -attach] } # Rtd's window geometry itk_option define -rtd_geometry rtd_geometry Rtd_geometry {} { if {"$itk_option(-rtd_geometry)" != ""} { after idle [code "wm geometry $w_ $itk_option(-rtd_geometry)"] } } # Rtd's window title itk_option define -rtd_title rtd_title Rtd_title {} { if {"$itk_option(-rtd_title)" != ""} { after idle [code "wm title $w_ {$itk_option(-rtd_title)}"] } } # Default directory for loading images itk_option define -image_directory image_directory Image_directory {} # -- protected variables -- # name of main image (class RtdImageCtrl or a derived class) protected variable image_ # pid of test prog used to generate rapid frames (debug) protected variable rapid_pid_ # attach to camera after widget was initialized protected variable attach_ 0 } skycat-3.1.2-starlink-1b/rtd/library/RtdImage.tcl000066400000000000000000001123731215713201500216010ustar00rootroot00000000000000# E.S.O. - VLT project # "@(#) $Id: RtdImage.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImage.tcl - itcl widget wrapper for the rtdimage type extension # # This widget is based on the Tk rtdimage extension, which is implemented # in C++. It simplifies things by creating its own frame, canvas and # scrollbars. # # See man page RtdImage(n) for a complete description. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01/06/98 Created # P.Biereichel 05/08/96 Added itk_option(-with_warp) # Allan Brighton 22/03/98 Added focus_ method to fix focus problems # and conflicts between menu traversal and # mouse cursor warp code (from Peter Draper, # Starlink). # pbiereic 11/10/99 Added 'wm colormapwindows' if private colormaps are used # pbiereic 04/11/03 Workaround bug in tcl 8.4.3 (SourceForge Request ID 835020) # Peter W. Draper 21/07/12 Make cmap_dir a PATH-like list. itk::usual RtdImage {} # The RtdImage widget is an [incr Tk] interface to the rtdimage extended # Tk image type. The widget creates a canvas window with optional # scrollbars and a canvas image item to hold the image. An optional # canvas line graphics editor is also created by default, to manage # drawing on the image. The RtdImage widget can be treated pretty much # like any standard Tk widget and can be inserted in a Tk frame with the # pack(n) command. Applications using the RtdImage widget, can access # the underlying image object and the canvas window to overlay graphics # on the image. # # In addition to the methods below, this class also forwards methods # implemented in the C++ rtdimage code. It is, however, usually more # efficient to use the "get_image" method to get a handle for the # internal rtdimage object and use it directly. itcl::class rtd::RtdImage { inherit util::FrameWidget # create a new RtdImage widget constructor {args} { global ::rtd_library # frame to hold image and scrollbars itk_component add imagef { frame $w_.imagef -background black } { keep -borderwidth -relief } pack $itk_component(imagef) -fill both -expand 1 # vertical scrollbar frame itk_component add vscrollf { frame $itk_component(imagef).vscrollf -background black } pack $itk_component(vscrollf) -side right -fill y # horizontal scrollbar frame itk_component add hscrollf { frame $itk_component(imagef).hscrollf -background black } pack $itk_component(hscrollf) -side bottom -fill x # canvas # note: create canvas in global namespace, to avoid problems in C++ side set cmd \ [list canvas $itk_component(imagef).canvas \ -xscrollincr 1 \ -yscrollincr 1 \ -background black \ -insertofftime 0] # Tk canvas containing the image itk_component add canvas { set canvas_ [uplevel "#0" $cmd] } { rename -relief -canvasrelief canvasRelief CanvasRelief rename -borderwidth -canvasborderwidth canvasBorderwidth CanvasBorderwidth rename -background -canvasbackground canvasBackground CanvasBackground rename -width -canvaswidth canvasWidth CanvasWidth rename -height -canvasheight canvasHeight CanvasHeight } pack $canvas_ -fill both -expand 1 # create the image # note: create (for now) in global namespace to avoid problems in C++ interface set cmd [list image create rtdimage] set image_ [uplevel "#0" $cmd] # put the image in the canvas set imageId_ [$canvas_ create image 0 0 \ -image $image_ \ -anchor nw \ -tags $image_] bind $canvas_ [code $this maybe_center] if {[$image_ cmap isprivate]} { # set the WM_COLORMAP_WINDOWS property wm colormapwindows [winfo toplevel $w_] $canvas_ } eval itk_initialize $args } # destructor - clean up when deleted destructor { catch {$itk_component(draw) deselect_objects} catch {$canvas_ delete $image_} catch {image delete $image_} } # this method is called from the base class (TopLevelWidget or FrameWidget) # after all the options have been evaluated protected method init {} { if {$itk_option(-with_warp)} { # make arrow keys move mouse pointer by one pixel bind $canvas_ "+$image_ warp -1 0" bind $canvas_ "+$image_ warp 1 0" bind $canvas_ "+$image_ warp 0 -1" bind $canvas_ "+$image_ warp 0 1" global ::$w_.focus set $w_.focus {} bind $canvas_ "+[code $this focus_ in]" bind $canvas_ "+[code $this focus_ out]" } # create a blank image and set default scaling factors if {[$image_ isclear]} { $image_ clear } $image_ scale $xscale_ $yscale_ $image_ config -newimagecmd [code $this new_image_cmd] } # Control the focussing of the canvas. Only take focus if the # top-level window associated with this canvas has the focus # (i.e. it's not in another toplevel somewhere). If this isn't # done then mysterious raises of the main image window can occur # with some window managers (mainly CDE, with click-to-focus). # # allan: 19.6.98: disabled the above behavior, since it causes # problems with mouse warping and confuses people. Can't verify # the CDE behavior... protected method focus_ {way} { global ::$w_.focus set top [winfo toplevel $w_] set focus [focus -displayof $top] if { $focus != {} } { #if {[winfo toplevel $focus] == "$top" } { # This toplevel has the focus (or at least a child of it # has), so it's ok to proceed. if { $way == "in" } { set $w_.focus [focus -displayof .] catch {focus $canvas_} } else { catch {focus [set $w_.focus]} } #} } } # utility to update an option in the image # Note: this works automatically with "widgets", but itk doesn't work # with "images"... protected method imageconfig_ {option} { $image_ config $option $itk_option($option) } # return the name of the underlying rtdimage object public method get_image {} { return $image_ } # return the name of the underlying canvas widget public method get_canvas {} { return $canvas_ } # return the canvas Id for the image public method get_imageId {} { return $imageId_ } # return name of global variable which contains the statistics # of the pick window. This allows applications to trace on this variable. public method get_pickVar {} { if {[winfo exists $w_.pick]} { return [$w_.pick get_pickVar] } return "" } # update the allowed interactive drawing area in the canvas protected method set_drawing_area {} { if {[info exists itk_component(draw)] && ! [$image_ isclear]} { $image_ convert coords 1 1 image x0 y0 canvas $image_ convert coords \ [expr {[$image_ width]-1}] \ [expr {[$image_ height]-1}] \ image x1 y1 canvas set cx0 [expr {int([min $x0 $x1])}] set cy0 [expr {int([min $y0 $y1])}] set cx1 [expr {int([max $x0 $x1])}] set cy1 [expr {int([max $y0 $y1])}] $itk_component(draw) configure -bbox "$cx0 $cy0 $cx1 $cy1" } } # make the graphics toolbox and menu protected method make_toolbox {} { # CanvasDraw(n) object, used to manage the canvas graphics itk_component add draw { util::CanvasDraw $w_.draw \ -canvas $canvas_ \ -transient 1 \ -withdraw 1 \ -center 0 \ -shorthelpwin $itk_option(-shorthelpwin) \ -withtoolbox $itk_option(-withtoolbox) \ -defaultcursor $itk_option(-cursor) \ -show_object_menu $itk_option(-show_object_menu) \ -regioncommand $itk_option(-regioncommand) } set_drawing_area # clicking on the image or image background deselects other objects $canvas_ bind $image_ <1> [code $itk_component(draw) deselect_objects] } # display the toolbox window public method show_toolbox {} { if {[$image_ isclear]} { warning_dialog "No image is currently loaded" $w_ return } if {! [info exists itk_component(draw)]} { # user must have deleted window... make_toolbox } else { # $itk_component(draw) center_window wm deiconify $itk_component(draw) wm transient $itk_component(draw) $w_ } } # resize the image and the canvas graphics by the given integer factors # (1 is no scale, -2 = 50%, 2 = 200% etc...) # - deselect canvas graphics (so handles don't get scaled) public method scale {x y} { # don't resize selection grips if {$itk_option(-graphics)} { $itk_component(draw) deselect_objects } save_scroll_pos_ set xscale_ $x set yscale_ $y # note previous scale and position lassign [$image_ scale] xs ys if {"$xs" == ""} { set xs [set ys 1] } else { # scale the image if {[catch {$image_ scale $x $y} msg]} { error_dialog $msg $w_ return } # if we passed the max scale factor, it will be ignored if {"[$image_ scale]" == "$xs $ys"} { return } } # scale the canvas items (need relative floating point factor) if {$xs < 0} { set xs [expr {-1.0/$xs}] set ys [expr {-1.0/$ys}] } if {$x < 0} { set x [expr {-1.0/$x}] set y [expr {-1.0/$y}] } # carefull in case scale factor is zero set fx [expr {double($x)/$xs}] set fy [expr {double($y)/$ys}] $canvas_ scale all 0 0 $fx $fy # set new scrollregion to include all of image set w [$image_ dispwidth] set h [$image_ dispheight] set_scrollregion 0 0 $w $h # notify rapid frame to change size if necessary if {[winfo exists $w_.rapid]} { $w_.rapid notify_cmd scale } restore_scroll_pos_ maybe_center # update interactive drawing area set_drawing_area # update pick window, if needed if {[winfo exists $w_.pick]} { $w_.pick update_scale $fx $fy } } # save the current scrolling positions protected method save_scroll_pos_ {} { lassign [$canvas_ xview] xScroll0_ xScroll1_ lassign [$canvas_ yview] yScroll0_ yScroll1_ # XXX needed for bug in tcl 8.4.3 set bug "$xScroll0_ $xScroll1_ $yScroll0_ $yScroll1_" } # restore the relative scrolling positions protected method restore_scroll_pos_ {} { $canvas_ xview moveto $xScroll0_ $canvas_ yview moveto $yScroll0_ lassign [$canvas_ xview] x0 x1 lassign [$canvas_ yview] y0 y1 $canvas_ xview moveto [expr {$x0-($x1-$xScroll1_)/2.0}] $canvas_ yview moveto [expr {$y0-($y1-$yScroll1_)/2.0}] } # toggle rotation of the image and canvas items public method rotate {bool} { if {$bool != [$image_ rotate]} { $image_ rotate $bool if {[info exists itk_component(draw)]} { $itk_component(draw) rotate all } if {[$image_ dispwidth] != [$image_ dispheight]} { center } # notify rapid frame to move if necessary if {[winfo exists $w_.rapid]} { $w_.rapid notify_cmd rotate $bool } # update interactive drawing area set_drawing_area } } # flip or unflip the image and canvas items about the # x or y axis, as given by $xy public method flip {xy bool} { if {$bool != [$image_ flip $xy]} { set coords [$canvas_ coords $image_] $image_ flip $xy $bool if {[info exists itk_component(draw)]} { if {"$xy" == "x"} { $itk_component(draw) flipx all [expr {[$image_ dispwidth]-1}] } else { $itk_component(draw) flipy all [expr {[$image_ dispheight]-1}] } } eval "$canvas_ coords $image_ $coords" # notify rapid frame to move if necessary if {[winfo exists $w_.rapid]} { $w_.rapid notify_cmd flip $xy $bool } # update interactive drawing area set_drawing_area } } # if the image is smaller than the canvas window, center it public method maybe_center {} { set cw [winfo width $canvas_] set ch [winfo height $canvas_] set dw [$image_ dispwidth] set dh [$image_ dispheight] if {$cw != 1} { if {$dw < $cw && $dw} { set x [expr {(($dw-$cw)/2.0)/$dw}] $canvas_ xview moveto $x } if {$dh < $ch && $dh} { set y [expr {(($dh-$ch)/2.0)/$dh}] $canvas_ yview moveto $y } } else { update maybe_center return } set_scrollregion 0 0 $dw $dh } # set the canvas scrollregion protected method set_scrollregion {x0 y0 x1 y1} { $canvas_ config -scrollregion "$x0 $y0 $x1 $y1" } # center the image in the canvas window public method center {} { set dw [$image_ dispwidth] set dh [$image_ dispheight] set_scrollregion 0 0 $dw $dh set cw [winfo width $canvas_] set ch [winfo height $canvas_] if {$cw != 1 && $dw && $dh} { $canvas_ xview moveto [expr {(($dw-$cw)/2.0)/$dw}] $canvas_ yview moveto [expr {(($dh-$ch)/2.0)/$dh}] } } # arrange to interactively create a rapid frame to display # a section of the image. # If popup is 1, the frame is displayed in a popup window, # otherwise at the selected position in the canvas public method rapid_frame {popup} { if {[$image_ isclear]} { warning_dialog "No image is currently loaded" $w_ return } if {[winfo exists $w_.rapid]} { destroy $w_.rapid } if {[action_dialog \ "Please select and drag out a region of the image with mouse button 1" \ $w_]} { $itk_component(draw) set_drawing_mode region [code $this make_rapid_frame $popup] } } # delete the rapid frame public method delete_rapid_frame {} { if {[winfo exists $w_.rapid]} { destroy $w_.rapid } } # Create a rapid frame to display a section of the image. # If popup is 1, the frame is displayed in a popup window, # otherwise at the selected position in the canvas # "region_id" is the canvas id of the object used to position # and resize the image. protected method make_rapid_frame {popup region_id x0 y0 x1 y1} { set xoffset [expr {int($x0)}] set yoffset [expr {int($y0)}] set width [expr {int($x1-$x0+1)}] set height [expr {int($y1-$y0+1)}] if {$popup} { rtd::RtdImagePopup $w_.rapid \ -target_image $this \ -xoffset $xoffset \ -yoffset $yoffset \ -width $width \ -height $height \ -zoomwin $itk_option(-zoomwin) \ -subsample $itk_option(-subsample) \ -usexshm $itk_option(-usexshm) \ -usexsync $itk_option(-usexsync) \ -withdraw [expr {!$popup}] \ -region_id $region_id \ -verbose $itk_option(-verbose) \ -shorthelpwin $itk_option(-shorthelpwin) \ -transient 1 \ -min_scale $itk_option(-min_scale) \ -max_scale $itk_option(-max_scale) \ -command $itk_option(-rapid_frame_command) \ } else { rtd::RtdImageFrame $w_.rapid \ -target_image $this \ -xoffset $xoffset \ -yoffset $yoffset \ -width $width \ -height $height \ -subsample $itk_option(-subsample) \ -usexshm $itk_option(-usexshm) \ -usexsync $itk_option(-usexsync) \ -region_id $region_id \ -verbose $itk_option(-verbose) \ -command $itk_option(-rapid_frame_command) } } # attach the named camera. public method attach_camera {camera} { # these commands are evaluated before/after real-time events set preCmd [code $this camera_pre_command] set postCmd [code $this camera_post_command] if {[catch {$image_ camera attach $camera $preCmd $postCmd} msg]} { # try again. Maybe rtdServer wasn't started yet. catch {exec rtdServer &} after 2000 } if {[catch {$image_ camera attach $camera $preCmd $postCmd} msg]} { error_dialog $msg } update idletasks } # stop the camera. # note: race conditions might cause display to lag behind the socket data. # force an update here. public method detach_camera {} { $image_ camera detach $image_ update } # This method is called when a new image has been received from # the camera and before it is displayed. # The frameid will be 0 for the main image and non-zero for a rapid frame. public method camera_pre_command {frameid} { if {$frameid != 0} { return } if {"$cameraPreCmd_" != ""} { catch {eval $cameraPreCmd_} } } # This method is called whenever a new image has been received from # the camera and displayed. # Update the widgets that need to display new values # The frameid will be 0 for the main image and non-zero for a rapid frame. public method camera_post_command {frameid} { if {$frameid != 0} { return } if {[winfo exists $w_.spectrum]} { $w_.spectrum notify_cmd } if {"$preview_var_" != ""} { global ::$preview_var_ if {[info exists $preview_var_]} { set $preview_var_ 0 } } # update picked object if {[winfo exists $w_.pick] && $updatePick_ != 0} { $w_.pick update_now } # set up world coordinate info, if needed set_rtd_wcs_info $frameid if {"$cameraPostCmd_" != ""} { catch {eval $cameraPostCmd_} } } # Set up world coordinate info for an image received from the rtdServer. public method set_rtd_wcs_info {frameid} { } # popup a window to display a table of nrows x ncols pixel values # from the image public method pixel_table {nrows ncols} { if {[$image_ isclear]} { warning_dialog "No image is currently loaded" $w_ return } if {[winfo exists $w_.pixtable]} { destroy $w_.pixtable } rtd::RtdImagePixTable $w_.pixtable \ -image $this \ -nrows $nrows \ -ncols $ncols \ -shorthelpwin $itk_option(-shorthelpwin) \ -transient 1 } # arrange to interactively create a spectrum line to display # a graph of the image values along a given line. public method spectrum {} { if {[$image_ isclear]} { warning_dialog "No image is currently loaded" $w_ return } if {[winfo exists $w_.spectrum]} { $w_.spectrum quit } if {[action_dialog \ "Press OK and then drag out a line over the image with button 1" \ $w_]} { $itk_component(draw) set_drawing_mode line [code $this make_spectrum] } } # display a dialog for selecting objects in the image and displaying information # about the selected area of the image public method pick_dialog {{command ""}} { if {[$image_ isclear]} { warning_dialog "No image is currently loaded" $w_ return } utilReUseWidget rtd::RtdImagePick $w_.pick \ -target_image $this \ -command $command \ -verbose $itk_option(-verbose) \ -orient $itk_option(-pickobjectorient) \ -debug $itk_option(-debug) \ -shorthelpwin $itk_option(-shorthelpwin) $w_.pick pick_object } # this method can be used in bindings to cause a selection in the # image (to pick an object/star) to return the given position rather than the # calculated center pos. If the optional args are not specified, they are # calculated. protected method picked_wcs_object {x y ra dec {equinox J2000} {fwhmX ""} {fwhmY ""} \ {angle ""} {object ""} {background ""}} { if {[winfo exists $w_.pick]} { if {"$angle" == ""} { $w_.pick picked_special_object $x $y $ra $dec $equinox } else { $w_.pick picked_wcs_object \ [list $x $y $ra $dec $equinox $fwhmX $fwhmY $angle $object $background] } } } # make a hard copy of the image display public method print {} { if {[$image_ isclear]} { warning_dialog "No image is currently loaded" $w_ return } set object [$image_ object] set file [file tail $itk_option(-file)] set center [$image_ wcscenter] set user [id user] set app [lindex [winfo name .] 0] set date [clock format [clock seconds] -format {%b %d, %Y at %H:%M:%S}] utilReUseWidget rtd::RtdImagePrint $w_.print \ -image $this \ -show_footer 1 \ -whole_canvas 0 \ -transient 1 \ -top_left "ESO\n$object" \ -top_right "$file\n$center" \ -bot_left "$user/$app" \ -bot_right "$date" } # Save the current image or a section of the current image to a file in # FITS format chosen from a file name dialog. If dir and pattern are specified, # they are used as defaults for the file selection dialog. # If x0, y0, x1 and y1 are specified (canvas coordinates), then a section # of the image is saved. # # The return value is the name of the new file, if any, or an empty string. public method save_as {{dir "."} {pattern "*"} {x0 ""} {y0 ""} {x1 ""} {y1 ""}} { if {[$image_ isclear]} { warning_dialog "No image is currently loaded" $w_ return } set file [filename_dialog $dir $pattern $w_] if {"$file" != ""} { if {[file isfile $file]} { if {![confirm_dialog \ "[file tail $file] exists - Do you want to overwrite it ?" $w_]} { return } if {[file isdir $file]} { error_dialog "$file is a directory" $w_ return } } if {"$x0" == ""} { $image_ dump $file } else { if {[catch { $image_ convert coords $x0 $y0 canvas x0 y0 image $image_ convert coords $x1 $y1 canvas x1 y1 image $image_ dump $file $x0 $y0 $x1 $y1 } msg]} { error_dialog $msg return } } return $file } } # save a section of the current image to a file in FITS format # chosen from a file name dialog. public method save_region_as {} { # check if we have an image if {[$image_ isclear]} { warning_dialog "No image is currently loaded" $w_ return } # can't convert DSS plate cooeficients correctly if {"[$image_ fits get PLTRAH]" != ""} { if { ! [confirm_dialog "Can't convert DSS plate coefficients.\ Please get the image from the DSS image server.\n\n\ \tContinue anyway?" $w_] } { return } } # first get the region to save if {[action_dialog \ "Please select and drag out a region of the image with mouse button 1" \ $w_]} { $itk_component(draw) set_drawing_mode region [code $this save_region] } } # save the given section of the current image to a file in FITS format # chosen from a file name dialog. The canvas_id is the id if the canvas # object used to select the region . The canvas coordinates of the region # are also passed as arguments. protected method save_region {canvas_id x0 y0 x1 y1} { save_as . * $x0 $y0 $x1 $y1 $itk_component(draw) delete_object $canvas_id } # Create a graph to display the image data values along the line # just created. # "line_id" is the canvas id of the line. protected method make_spectrum {line_id x0 y0 x1 y1} { if {[winfo exists $w_.spectrum]} { $w_.spectrum quit } rtd::RtdImageSpectrum $w_.spectrum \ -x0 [expr {int($x0)}] \ -y0 [expr {int($y0)}] \ -x1 [expr {int($x1)}] \ -y1 [expr {int($y1)}] \ -image $this \ -transient 1 \ -shorthelpwin $itk_option(-shorthelpwin) \ -line_id $line_id } # toggle the visibility of the line graphics # (The trace variable name is passed here, if 1, hide the graphics...) public method hide_graphics {variable} { global ::$variable if {[set $variable]} { $canvas_ raise $image_ } else { $canvas_ lower $image_ } } # this method is called by the image code whenever a new image is loaded # (for updates, see camera command) protected method new_image_cmd {} { # only runs the first time, if the user chose a different color scale if {"$itk_option(-color_scale)" != "linear"} { if {[catch {$image_ colorscale $itk_option(-color_scale)} msg]} { error_dialog $msg } set itk_option(-color_scale) linear } if {[winfo exists $w_.rapid]} { destroy $w_.rapid } if {[info exists itk_component(draw)]} { $itk_component(draw) clear set_drawing_area } # update biasimage status $image_ biasimage update if {"$itk_option(-newimagecmd)" != ""} { eval $itk_option(-newimagecmd) } center } # set preview mode on or off in the image. In this case, the # arg is the "name" of a global variable controlling the preview # mode. It will be kept up to date by this class. public method preview {var} { global ::$var $image_ preview [set [set preview_var_ $var]] } # set the performance test mode on or off. public method perftest {} { if {[catch {$image_ perftest on} msg]} { error_dialog $msg return } utilReUseWidget rtd::RtdImagePerf $w_.perf \ -target_image $this \ -shorthelpwin $itk_option(-shorthelpwin) } # Methods for the playing and recording of images. public method record {camera} { utilReUseWidget RtdRecorderTool $w_.rec \ -target_image $this \ -server_camera $camera \ -shorthelpwin $itk_option(-shorthelpwin) } # clear the current image display and remove any windows that # access it public method clear {} { $image_ config -file "" set itk_option(-file) "" set w [$image_ dispwidth] set h [$image_ dispheight] set_scrollregion 0 0 $w $h if {[info exists itk_component(draw)]} { $itk_component(draw) clear } $canvas_ delete objects if {[winfo exists $w_.rapid]} { destroy $w_.rapid } if {[winfo exists $w_.spectrum]} { destroy $w_.spectrum } if {[winfo exists $w_.pixtable]} { destroy $w_.pixtable } if {[winfo exists $w_.pick]} { $w_.pick close } } # reload the image file, if there is one public method reopen {} { $image_ update } # load a FITS file (internal version: use -file option/public variable) protected method load_fits_ {} { if {[file exists $itk_option(-file)] || "$itk_option(-file)" == "-"} { if {[catch {$image_ config -file $itk_option(-file)} msg]} { error_dialog $msg $w_ clear } set w [$image_ dispwidth] set h [$image_ dispheight] set_scrollregion 0 0 $w $h } else { error_dialog "'$itk_option(-file)' does not exist" $w_ set file "" clear } } # pass these methods on to the image widget unchanged # (this just generates methods on the fly...) ::foreach i {view cut cmap itt colorscale alloccolors zoom zoomview object convert wcscenter wcsradius isclear dispwidth dispheight freq} { method $i {args} [::format {return [eval "$image_ %s $args"]} $i] } # -- public vars -- # fits image file to display itk_option define -file file File {} { if {"$itk_option(-file)" != ""} { # this code makes it easier to center the image on startup if {[winfo width $w_] <= 1 || [$image_ isclear]} { after 0 [code $this load_fits_] } else { load_fits_ } } } # for compatibility with saoimage itk_option define -fits fits Fits {} { if {"$itk_option(-fits)" != ""} { config -file $itk_option(-fits) } } # set displaymode flag 0 to optimize for smooth scrolling, # 1 for faster updates and less memory (works best for main image) itk_option define -displaymode displayMode DisplayMode {1} { imageconfig_ -displaymode } # X shared memory option. # DISABLED: pbi 01/03/05 # Dynamic re-configuration crashes rtd but has never been used # by any application or by rtd itself. itk_option define -usexshm useXshm UseXshm 1 { ###imageconfig_ -usexshm } # X synchronisation option itk_option define -usexsync useXsync UseXsync 1 { imageconfig_ -usexsync } # -name option itk_option define -name name Name {MainImage} { imageconfig_ -name } # minimum allowed scale value itk_option define -min_scale min_scale Min_scale -10 # maximum allowed scale value itk_option define -max_scale max_scale Max_scale 20 # This flag controls whether the FITS image header is kept in # SysV shared memory (see the rtdRemote interface for use of this) itk_option define -shm_header shm_header Shm_header 0 { imageconfig_ -shm_header } # This flag controls whether the FITS image data is kept in # SysV shared memory (see the rtdRemote interface for use of this) itk_option define -shm_data shm_data Shm_data 0 { imageconfig_ -shm_data } # Specify the min number of colors to allocate before using # a private colormap. Note: this option is currently ignored. itk_option define -min_colors min_colors Min_colors 30 { imageconfig_ -min_colors } # Specify the max number of colors to allocate before using # a private colormap. Note: this option is currently ignored. itk_option define -max_colors max_colors Max_colors 60 { imageconfig_ -max_colors } # if non-zero, shrink image to fit width itk_option define -fitwidth fitWidth FitWidth {0} { if {$itk_option(-fitwidth)} { config -canvaswidth $itk_option(-fitwidth) imageconfig_ -fitwidth } } # if non-zero, shrink image to fit height itk_option define -fitheight fitHeight FitHeight {0} { if {$itk_option(-fitheight)} { config -canvasheight $itk_option(-fitheight) imageconfig_ -fitheight } } # if non-zero, fill image to fit width itk_option define -fillwidth fillWidth FillWidth {0} { if {$itk_option(-fillwidth)} { config -canvaswidth $itk_option(-fillwidth) imageconfig_ -fillwidth } } # if non-zero, fill image to fit height itk_option define -fillheight fillHeight FillHeight {0} { if {$itk_option(-fillheight)} { config -canvasheight $itk_option(-fillheight) imageconfig_ -fillheight } } # flag: if true, print diagnostic messages itk_option define -verbose verbose Verbose {0} { imageconfig_ -verbose } # flag: if true, use quick and dirty algorithm to shrink images itk_option define -subsample subsample Subsample {1} { imageconfig_ -subsample } # sampling method to used when option -subsample is 0 itk_option define -sampmethod sampmethod Sampmethod {0} { imageconfig_ -sampmethod } # flag: if true, display horizontal and vertical scrollbars itk_option define -scrollbars scrollbars Scrollbars 0 { if {$itk_option(-scrollbars)} { # optional vertical scrollbar if {![info exists itk_component(vscroll)]} { itk_component add vscroll { scrollbar $itk_component(vscrollf).vscroll \ -relief sunken \ -command [code $canvas_ yview] } pack $itk_component(vscroll) -side right -fill y $canvas_ config -yscrollcommand "$itk_component(vscroll) set" } if {![info exists itk_component(hscroll)]} { # optional horizontal scrollbar itk_component add hscroll { scrollbar $itk_component(hscrollf).hscroll \ -relief sunken \ -orient horiz \ -command [code $canvas_ xview] } pack $itk_component(hscroll) -side bottom -fill x $canvas_ config -xscrollcommand "$itk_component(hscroll) set" } } else { $canvas_ config -xscrollcommand "" -yscrollcommand "" if {[info exists itk_component(vscroll)]} { destroy $itk_component(vscroll) destroy $itk_component(hscroll) unset itk_component(vscroll) unset itk_component(hscroll) } } } # flag: if true, set bindings to scroll with the middle mouse button itk_option define -drag_scroll drag_scroll Drag_scroll 0 { global EDITING ; # panel editor set pe 0 if {[info exists EDITING]} { set pe $EDITING } if { ! $pe } { if {$itk_option(-drag_scroll)} { bind $canvas_ <2> [code $canvas_ scan mark %x %y] bind $canvas_ [code "$canvas_ scan dragto %x %y; $this maybe_center"] } else { bind $canvas_ <2> { } bind $canvas_ { } } } } # flag: if true, create a CanvasDraw object to manage the canvas graphics itk_option define -graphics graphics Graphics 1 { if {$itk_option(-graphics) && ![info exists itk_component(draw)]} { # create an object to manage the canvas graphics make_toolbox } else { $canvas_ config -cursor $itk_option(-cursor) } } # if true (default) create the GUI interface (toolbox), otherwise don't itk_option define -withtoolbox withToolbox WithToolbox {1} # default cursor itk_option define -cursor cursor Cursor {target} # Tcl command to evaluate whenever a "region" of the image is selected # via the graphic toolbox "region" selection item. Can be used to # select graphic items or a section of the image for an operation. itk_option define -regioncommand regionCommand RegionCommand {} # optional tcl command to be evaluated when a rapid frame is created, moved, # resized or deleted: 6 args will be appended: # # name = unique name for the frame # op = {move,resize or delete}, # x, y = coords of upper left corner of frame in image # width, height = dimensions of frame. itk_option define -rapid_frame_command rapid_frame_command Rapid_frame_command {} # default cmap file itk_option define -default_cmap default_cmap Default_cmap {real} # default ITT file itk_option define -default_itt default_itt Default_itt {ramp} # Set the default color scale algorithm to one of: {linear log sqrt histeq} itk_option define -color_scale color_scale Color_scale linear # Colormap initialization and directory search path for colormap # and ITT files itk_option define -cmap_dir cmap_dir Cmap_dir {} { if {!$colormap_initialized_} { global ::rtd_library if {"$itk_option(-cmap_dir)" == ""} { set itk_option(-cmap_dir) $rtd_library/colormaps } # find default cmap and itt, could be on the search path set basename $itk_option(-default_cmap).$itk_option(-cmap_suffix) set cmap {} set dirlist [split $itk_option(-cmap_dir) {;}] foreach dir $dirlist { set offered_cmap ${dir}/${basename} if { [::file exists $offered_cmap] } { set cmap $offered_cmap break } } if { $cmap == {} } { set cmap [lindex $dirlist 0]/$basename } $image_ cmap file $cmap set basename $itk_option(-default_itt).$itk_option(-itt_suffix) set itt {} foreach dir $dirlist { set offered_itt ${dir}/${basename} if { [::file exists $offered_itt] } { set itt $offered_itt break } } if { $itt == {} } { set itt [lindex $dirlist 0]/$basename } $image_ itt file $itt set colormap_initialized_ 1 } } # suffix for colormap files itk_option define -cmap_suffix cmap_suffix Cmap_suffix {lasc} # suffix for ITT files itk_option define -itt_suffix itt_suffix Itt_suffix {iasc} # flag: if true, display menus over graphic objects when selected with <3> itk_option define -show_object_menu show_object_menu Show_object_menu 0 # name of zoom window to update when mouse enters this window itk_option define -zoomwin zoomWin ZoomWin {} { if {"$itk_option(-zoomwin)" != ""} { bind $canvas_ "+$itk_option(-zoomwin) enter_image $image_" bind $canvas_ "+$itk_option(-zoomwin) leave_image $image_" } } # short help text itk_option define -shelp shelp Shelp "image window" { if {"$itk_option(-shelp)" != ""} { catch {add_short_help $w_ $itk_option(-shelp)} msg catch {add_short_help $canvas_ $itk_option(-shelp)} msg } } # -orient option for Pick Object window itk_option define -pickobjectorient pickObjectOrient PickObjectOrient {vertical} # option to update RtdImagePick after a real-time image event itk_option define -updatePick updatePick UpdatePick {1} { set updatePick_ $itk_option(-updatePick) } # command to eval when a new image is loaded itk_option define -newimagecmd newImageCmd NewImageCmd "" # optionally specify TopLevelWidget to display short help messages itk_option define -shorthelpwin shortHelpWin ShortHelpWin {} # debugging flag itk_option define -debug debug Debug {0} { imageconfig_ -debug } # option to warp the mouse pointer itk_option define -with_warp with_warp With_warp 0 # default scaling factors itk_option define -xscale xscale Xscale {1} { set xscale_ $itk_option(-xscale) if {[winfo width $w_] > 1} { scale $xscale_ $yscale_ } } itk_option define -yscale yscale Yscale {1} { set yscale_ $itk_option(-yscale) if {[winfo width $w_] > 1} { scale $xscale_ $yscale_ } } # commands to be evaluated before/after image events itk_option define -cameraPreCmd cameraPreCmd CameraPreCmd {} { set cameraPreCmd_ $itk_option(-cameraPreCmd) } itk_option define -cameraPostCmd cameraPostCmd CameraPostCmd {} { set cameraPostCmd_ $itk_option(-cameraPostCmd) } # -- protected vars -- # internal rtd image protected variable image_ # canvas widget protected variable canvas_ # canvas Id for image protected variable imageId_ # name of a global variable controlling preview mode protected variable preview_var_ {} # saved x0 relative scrolling position protected variable xScroll0_ 0 # saved x1 relative scrolling position protected variable xScroll1_ 0 # saved y0 relative scrolling position protected variable yScroll0_ 0 # saved y1 relative scrolling position protected variable yScroll1_ 0 # camera pre/post commands protected variable cameraPreCmd_ "" protected variable cameraPostCmd_ "" # values for xscale, yscale protected variable xscale_ 1 protected variable yscale_ 1 # update RtdImagePick after a real-time event protected variable updatePick_ 1 # --- common to all instances -- # flag: true if the colormap has been initialized common colormap_initialized_ 0 } skycat-3.1.2-starlink-1b/rtd/library/RtdImageBias.tcl000066400000000000000000000357521215713201500224050ustar00rootroot00000000000000#****************************************************************************** # E.S.O. - VLT project # "@(#) $Id: RtdImageBias.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImageBias.tcl - class for bias data subtraction # # who when what # -------- -------- ---------------------------------------------- # P.Biereichel 22/03/99 Created itk::usual RtdImageBias {} # RtdImageBias is a class for controlling the subtraction of # a bias frame. itcl::class rtd::RtdImageBias { inherit util::TopLevelWidget constructor {args} { eval itk_initialize $args wm title $w_ "Bias Image" wm protocol $w_ WM_DELETE_WINDOW "$this close" set biasWdg_ $this } public method init {} { set maxbias_ [$image_ biasimage maxbias] add_menubar make_layout update idletasks wm minsize $w_ [winfo reqwidth $w_] [winfo reqheight $w_] update_cuts } # Method to add the menu bar to the top of the dialogue. protected method add_menubar {} { TopLevelWidget::add_menubar # File menu set m [add_menubutton File] add_menuitem $m cascade "Load File" \ {Load a file for bias subtraction} \ -menu [menu $m.biasf] for {set i 0} {$i < $maxbias_} {incr i} { $m.biasf add command -label "Bias [expr {$i+1}]..." \ -command [code $this load $i] } add_menuitem $m cascade "Clear" \ {Clear a bias image} \ -menu [menu $m.biasc] for {set i 0} {$i < $maxbias_} {incr i} { $m.biasc add command -label "Bias [expr {$i+1}]" \ -command [code $this clear $i] } $m.biasc add command -label "All" \ -command [code $this clear all] add_menuitem $m cascade "Copy image to ->" \ {Copy current image to a bias frame} \ -menu [menu $m.biaso] for {set i 0} {$i < $maxbias_} {incr i} { $m.biaso add command -label "Bias [expr {$i+1}]" \ -command [code $this copy $i] } add_menuitem $m command "Close" \ {Close this window} \ -command [code $this close] # View menu set m [add_menubutton View] add_menuitem $m command "Display selected bias image" \ {Display the bias image} \ -command [code $this display] } # make the widget layout protected method make_layout {} { # frames foreach el "bias status cuts buttons" { itk_component add $el { frame $w_.$el -relief groove -borderwidth 2 } pack $itk_component($el) -fill x -expand 1 } itk_component add copy { button $w_.copy \ -text "Copy image -> bias" \ -command [code $this copy] } # checkbutton to turn bias subtraction on/off itk_component add onoff { checkbutton $w_.onoff \ -text "Subtract " \ -variable $w_.onoff \ -onvalue 1 -offvalue 0 \ -anchor w \ -borderwidth 2 -relief raised -pady 3 \ -command [code $this onOff] } { keep -state } blt::blttable $itk_component(bias) \ $itk_component(onoff) 0,0 -pady 3 \ $itk_component(copy) 0,1 -pady 3 set i 0 foreach el "Nr Select Load Copy Clear Filename" { set comp [string tolower $el] itk_component add label$comp { label $w_.label$comp \ -anchor c } blt::blttable $itk_component(status) \ $itk_component(label$comp) 0,$i blt::blttable configure $itk_component(status) c$i -resize none incr i } blt::blttable configure $itk_component(status) c5 -resize expand foreach el "Load Copy Clear" { set s [string tolower $el] catch {bitmap compose $s $el -rotate 90.0 -font $itk_option(-valuefont)} $itk_component(label$s) config -bitmap $s -anchor w } for {set i 0} {$i < $maxbias_} {incr i} { set n [expr {$i+1}] itk_component add labelnr$i { label $w_.labelnr$i \ -text " [expr {$i+1}] " \ -font $itk_option(-labelfont) \ -anchor c } global ::$w_.select itk_component add select$i { radiobutton $w_.select$i \ -variable $w_.select \ -anchor c \ -value $i \ -padx 1 -pady 1 \ -borderwidth 2 \ -command [code $this select] } set select_ [set $w_.select 0] itk_component add choose$i { button $w_.choose$i \ -text "..." \ -width 2 \ -padx 0 \ -anchor c \ -font $itk_option(-valuefont) \ -borderwidth 2 \ -relief raised \ -command [code $this load $i] } itk_component add copy$i { button $w_.copy$i \ -text "->" \ -width 2 \ -anchor c \ -padx 0 \ -font $itk_option(-valuefont) \ -borderwidth 2 \ -relief raised \ -command [code $this copy $i] } itk_component add clear$i { button $w_.clear$i \ -text "C" \ -anchor c \ -width 2 \ -padx 0 \ -font $itk_option(-valuefont) \ -borderwidth 2 \ -relief raised \ -command [code $this clear $i] } itk_component add filename$i { util::LabelValue $w_.filename$i \ -text "" \ -labelwidth 2 \ -valuefont $itk_option(-valuefont) \ -labelfont $itk_option(-labelfont) \ -valuewidth 30 \ -anchor e \ -relief groove \ -orient horizontal } $itk_component(filename$i) component entry config -highlightthickness 0 -takefocus 0 blt::blttable $itk_component(status) \ $itk_component(labelnr$i) $n,0 \ $itk_component(select$i) $n,1 \ $itk_component(choose$i) $n,2 \ $itk_component(copy$i) $n,3 \ $itk_component(clear$i) $n,4 \ $itk_component(filename$i) $n,5 -anchor e -fill x -pady 1 } itk_component add labelcut { label $w_.labelcut \ -text "Cut levels:" \ -font $itk_option(-labelfont) \ -anchor c } foreach el "Low High" { set s [string tolower $el] itk_component add $s { LabelEntry $w_.$s \ -text "$el:" \ -command [code $this set_cut_levels] \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -anchor e \ -relief sunken \ -validate real } { keep -state } } itk_component add autocut { button $w_.autocut \ -text "Auto Set Cut Levels" \ -font $itk_option(-labelfont) \ -command [code $this auto_set_cut_levels] } blt::blttable $itk_component(cuts) \ $itk_component(labelcut) 0,0 -columnspan 3 -pady 4 \ $itk_component(low) 1,0 -anchor w -ipady 3 -pady 2 \ $itk_component(high) 1,1 -anchor w -ipady 3 -pady 2 \ $itk_component(autocut) 1,2 -anchor w -ipady 3 -pady 2 itk_component add close { button $itk_component(buttons).close \ -text Close \ -command [code $this close] } blt::blttable $itk_component(buttons) \ $itk_component(close) 0,0 -pady 3 } # add short help text public method make_short_help {} { add_help $itk_component(copy) "Copy: Copy current image to selected bias image" add_help $itk_component(onoff) "Subtract: Switch subtraction of bias image on/off" for {set i 0} {$i < $maxbias_} {incr i} { set n [expr {$i+1}] add_help $itk_component(labelnr$i) "Number of bias image" add_help $itk_component(select$i) "Select: Select bias image $n for image subtraction" add_help $itk_component(choose$i) "...: Load bias image $n from file" add_help $itk_component(copy$i) "->: Copy current image -> bias image $n" add_help $itk_component(clear$i) "C: Clear bias image $n" add_help $itk_component(filename$i) "File: Filename of bias image $n or env. RTD_CAMERA \ for real-time image" } add_help $itk_component(low) "Low: Image low cut level, hit Return after editing value" add_help $itk_component(high) "High: Image high cut level, hit Return after editing value" add_help $itk_component(autocut) "Autocut: Auto set cut levels" add_help $itk_component(close) "Close: Close this window" } protected method add_help {compo msg} { # XXX would be nice to have an option for TopLevelWidget bind $compo {} bind $compo {} add_short_help $compo $msg } # close this window public method close {} { wm withdraw $w_ } # trace status of a global variable which is set by the rtdimage # subcommand 'biasimage' protected method trace_status {} { global ::$image_ trace variable ${image_}(BIAS) w [code $this updateStatus] } # copy current image -> bias image public method copy {{nr -1}} { if [$image_ isclear] { warning_dialog "No image is currently loaded" $w_ return } if {$nr == -1} { set nr $select_ } if {$nr == $select_ && $onoff_} { set update_ 1 } if {[catch {$image_ biasimage copy $nr} msg]} { error_dialog $msg } } # clear bias image public method clear {nr} { if {$nr == $select_ && $onoff_} { set update_ 1 } $image_ biasimage clear $nr } # select bias image for image subtraction public method select {} { global ::$w_.select if {$select_ == [set $w_.select]} { return } set select_ [set $w_.select] set update_ $onoff_ $image_ biasimage select $select_ } # open and load a new FITS image file via file name dialog public method load {nr {dir "."} {pattern "*.*fit*"}} { set file [filename_dialog $dir $pattern $w_] if {"$file" != ""} { if {[file isfile $file]} { if {$nr == $select_ && $onoff_} { set update_ 1 } if {[catch {$image_ biasimage file $file $nr} msg]} { error_dialog $msg } } else { error_dialog "There is no file named '$file'" $w_ } } } # switch bias subtraction on/off public method onOff {} { global ::$w_.onoff set onoff_ [set $w_.onoff] set update_ 1 if {$onoff_} { if {[catch {$image_ biasimage on} msg]} { set onoff_ [set $w_.onoff 0] error_dialog $msg } } else { $image_ biasimage off } } # display selected bias image public method display {} { if {[catch {$image_ biasimage display} msg]} { error_dialog $msg } } # update status of this widget and all images when necessary public method updateStatus {{args}} { global ::$image_ ::$w_.onoff if {[$image_ biasimage status] == -1} { set onoff_ [set $w_.onoff 0] config -state disabled } else { config -state normal } set isclear [$image_ isclear] set stat normal if {$isclear} { set stat disabled } foreach el "copy low high" { $itk_component($el) config -state $stat } for {set i 0} {$i < $maxbias_} {incr i} { set fn "" set fn [file tail [$image_ biasimage file $i]] # set fn [$image_ biasimage file $i] $itk_component(filename$i) config -value $fn if {"$fn" != ""} { $itk_component(filename$i) config -relief sunken $itk_component(clear$i) config -state normal } else { $itk_component(filename$i) config -relief groove $itk_component(clear$i) config -state disabled } $itk_component(copy$i) config -state $stat } # update all images when requested if {$update_} { foreach el $images_ { $el update } set update_ 0 } } # set the cut levels when the user types them in and hits return public method set_cut_levels {args} { set low [$itk_component(low) get] set high [$itk_component(high) get] if {[catch {expr {$low}} msg] || [catch {expr {$high}} msg]} { error_dialog $msg } else { $image_ cut $low $high if {"$itk_option(-command)" != ""} { eval $itk_option(-command) } } } # set the cut levels automatically using median filtering... public method auto_set_cut_levels {} { busy {$image_ autocut} if {"$itk_option(-command)" != ""} { eval $itk_option(-command) } } # update cut level display public method update_cuts {} { lassign [$image_ cut] low high entry_value low $low entry_value high $high } # write value into entry field protected method entry_value {compo value} { set w [$itk_component($compo) component entry] $w delete 0 end $w insert 0 $value } # add an image object whose bias subtraction is managed # by this class public proc add_image {Img} { set img [$Img get_image] lvarpush images_ $img global ::$img set ${img}(BIAS) 0 } # remove an image object whose bias subtraction is managed # by this class public proc remove_image {Img} { set img [$Img get_image] if {[set idx [lsearch $images_ $img]] == -1} { return } set images_ [lreplace $images_ $idx $idx] set image_ [lindex $images_ 0] global ::$img catch {unset ${img}(BIAS) 0} if {[set idx [lsearch $Images_ $Img]] != -1} { set Images_ [lreplace $Images_ $idx $idx] } set Img [lindex $Images_ 0] if {"$Img" != ""} { $biasWdg_ config -shorthelpwin [[$Img cget -shorthelpwin] component hull] -image $Img } } # called after configuring itk_option(-image) public method newTarget {} { make_short_help update_cuts updateStatus } # -- options -- # target widget itk_option define -image image Image {} { set Img $itk_option(-image) set image_ [$Img get_image] if {[set idx [lsearch $Images_ $Img]] == -1} { lvarpush Images_ $Img set newimg [$Img cget -newimagecmd] # install callback for new image events $Img config -newimagecmd "$newimg; [code $this updateStatus]" trace_status } else { set Images_ [lreplace $Images_ $idx $idx] lvarpush Images_ $Img } after idle [code $this newTarget] } # font used for labels itk_option define -labelfont labelFont LabelFont TkDefaultFont # font used for values itk_option define -valuefont valueFont ValueFont TkDefaultFont # set the width for displaying labels and values itk_option define -labelwidth labelWidth LabelWidth 4 itk_option define -valuewidth valueWidth ValueWidth 8 # set the state to normal/disabled to enable/disable editing itk_option define -state state State {disabled} # tcl command to evaluate when cut levels were changed itk_option define -command command Command {} # display number of main image itk_option define -dsplnr dsplnr Dsplnr {1} { set nr $itk_option(-dsplnr) if {$nr > 1} { set mains_ $nr } if {$mains_} { wm title $w_ "Bias Image ($nr)" } } # -- protected vars -- # max. numbers of bias frames protected variable maxbias_ # copy of ::$w_.select protected variable select_ # copy of ::$w_.onoff protected variable onoff_ 0 # flag for image update request protected variable update_ 0 # set when more than one instances of main windows are used protected variable mains_ 0 # -- common (shared) variables -- # name of current rtd image protected common image_ {} # list of RtdImage objects handled by this class protected common images_ {} protected common Images_ {} # name of this widget protected common biasWdg_ {} } skycat-3.1.2-starlink-1b/rtd/library/RtdImageColorRamp.tcl000066400000000000000000000135431215713201500234170ustar00rootroot00000000000000# E.S.O. - VLT project # "@(#) $Id: RtdImageColorRamp.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImageColorRamp.tcl - itcl widget used to display contents of the # colormap for an RtdImage in a generated image # # See man page RtdImageColorRamp(n) for a complete description. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 95 Created # Peter W. Draper 06 Mar 98 Added viewmaster and associated changes # to support non-pseudocolor visuals # (changes to colorramp do not get to other # images "automagically" any more. itk::usual RtdImageColorRamp {} # This [incr Tk] widget class displays the colors in the colormap from # left to right in a generated rtdimage. In addition, bindings are added # to the colorramp to rotate, shift, stretch and squeeze the colormap by # dragging the mouse pointer with a button pressed. itcl::class rtd::RtdImageColorRamp { inherit util::FrameWidget # constructor: create an RtdImage widget with generated # data to display all the values in the colormap constructor {args} { itk_option add hull.borderwidth hull.relief eval itk_initialize $args # RtdImage item used to display colors in colormap itk_component add image { rtd::RtdImage $w_.image \ -displaymode 0 \ -usexshm $itk_option(-usexshm) \ -borderwidth 2 \ -relief raised \ -scrollbars 0 \ -drag_scroll 0 \ -graphics 0 \ -shelp $itk_option(-shelp) \ -cursor $itk_option(-cursor) \ -canvasheight $itk_option(-height) } { } pack $itk_component(image) -fill x set canvas_ [$itk_component(image) get_canvas] set image_ [$itk_component(image) get_image] # catch resize event: color ramp should always fill width of the window bind $canvas_ [code $this update_colors] # add bindings for rotating the colormap # (these will change later when more functions are available) # Note: need shift of single color ? (see saoimage) bind $canvas_ <1> [code $this mark_for_shift %x] bind $canvas_ <2> [code $this mark %x] bind $canvas_ <3> [code $this reset_colors] bind $canvas_ [code $this shift_colors %x] bind $canvas_ [code $this rotate_colors %x] bind $canvas_ [code $this scale_itt %x] bind $canvas_ " " bind $canvas_ [code $this save_cmap] bind $canvas_ [code $this save_cmap] } # update the colorramp after the window has been resized or the number of # colors has changed (need to delay to always get the correct size) public method update_colors {} { after 0 [code $image_ colorramp] } # mark the given position for later reference protected method mark {pos} { set mark_ $pos } # mark the given position for later reference and set # things up for a shift operation. # (The dummy rotate op causes an internal copy between cmap and itt # that initializes the shift from the current itt.) protected method mark_for_shift {pos} { set mark_ $pos $image_ cmap rotate 0 } # rotate the colormap by the difference between the given # position and the position set with mark. protected method rotate_colors {pos} { set val [expr {$pos-$mark_}] $image_ cmap rotate $val if { $itk_option(-viewmaster) != {} } { $itk_option(-viewmaster) cmap rotate $val } mark $pos } # shift the colormap by the difference between the given # position and the position set with mark. protected method shift_colors {pos} { set val [expr {$pos-$mark_}] $image_ cmap shift $val if { $itk_option(-viewmaster) != {} } { $itk_option(-viewmaster) cmap shift $val } } # scale the current ITT based on the difference between the given # position and the position set with mark. protected method scale_itt {pos} { set val [expr {$pos-$mark_}] $image_ itt scale $val if { $itk_option(-viewmaster) != {} } { $itk_option(-viewmaster) itt scale $val } } # reset the colormap method reset_colors {} { $image_ cmap reset if { $itk_option(-viewmaster) != {} } { $itk_option(-viewmaster) cmap reset } } # Called after a shift or scale operation is done (button up) # to save the colormap state. We just do a null rotate here, # since it does what we want. This prevents the colormap from # reverting to the original state before each shift or scale # operation. The reason it would revert is that otherwise colors # shifted off to the left or right, for example, would be lost. protected method save_cmap {} { $image_ cmap rotate 0 } # -- public vars -- # height of colorramp (width is same as window) itk_option define -height height Height 12 # help text displayed when mouse enters widget itk_option define -shelp shelp Shelp "Colormap display: \ {bitmap dragb1} = shift colormap, \ {bitmap shiftdragb1} = rotate, \ {bitmap dragb2} = stretch, \ {bitmap b3} = reset" # cursor for window itk_option define -cursor cursor Cursor {exchange} # X shared memory option itk_option define -usexshm useXshm UseXshm 1 # "viewmaster" image. This is also updated when colorramp # changes. This allows changes to be propagated, even if using a # read-only visual. itk_option define -viewmaster viewmaster ViewMaster {} # -- protected vars -- # canvas window containing ramp image protected variable canvas_ # internal rtdimage widget for colorramp protected variable image_ # used to save a position for rotating the colormap protected variable mark_ 0 } skycat-3.1.2-starlink-1b/rtd/library/RtdImageColors.tcl000066400000000000000000000260251215713201500227610ustar00rootroot00000000000000#******************************************************************************* # E.S.O. - VLT project # # "@(#) $Id: RtdImageColors.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImageColors.tcl - itcl widget for managing colormap for an rtdimage # # See man page RtdImageColors(n) for a complete description. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 95 Created # pbiereic 04/11/03 Workaround bug in tcl 8.4.3 (SourceForge Request ID 835020) # Peter W. Draper 21/07/12 Make cmap_dir a PATH-like list. itk::usual RtdImageColors {} # This [incr Tk] widget presents a user interface for manipulating # colors and colormaps for an RtdImage widget. The widget creates a new # toplevel window containing items for "color scaling" the image, # loading a MIDAS style colormap or ITT (intensity transfer table) and # for setting the number of color cells allocated in the colormap. itcl::class rtd::RtdImageColors { inherit util::TopLevelWidget # constructor: create a new instance of this class constructor {args} { wm title $w_ "Image Colors" wm iconname $w_ "Image Colors" # evaluate the options eval itk_initialize $args # top frame itk_component add top { frame $w_.top -borderwidth 2 -relief groove } pack $itk_component(top) \ -side top -fill both -ipadx 2m -ipady 2m -expand 1 # LabelChoice(n) widget for choosing a color scale algorithm itk_component add scale { util::LabelChoice $w_.scale \ -text "Color Scale Algorithm:" \ -orient vertical \ -choice {Linear Logarithmic {Square Root} {Histogram Equalization}} \ -command [code $this set_color_scale] } pack $itk_component(scale) -side left -fill x -in $w_.top $itk_component(scale) config -value Linear # choose colormap/ITT set cmap_files [lsort [$image_ cmap list]] set itt_files [lsort [$image_ itt list]] # Chooser(n) widget listing available colormaps itk_component add colormaps { util::Chooser $w_.colormaps \ -title "Colormap" \ -relief groove -borderwidth 2 \ -width 0 \ -suffix $itk_option(-cmap_suffix) \ -files $cmap_files \ -default $itk_option(-default_cmap) \ -command [code $this set_cmap] } # Chooser(n) widget listing available intensity tables. itk_component add itts { util::Chooser $w_.itts \ -title "Intensity" \ -relief groove -borderwidth 2 \ -width 0 \ -suffix $itk_option(-itt_suffix) \ -files $itt_files \ -default $itk_option(-default_itt) \ -command [code $this set_itt] } pack $itk_component(colormaps) $itk_component(itts) \ -side left -fill both -expand 1 -in $itk_component(top) # Frame for displaying allocated/free colors itk_component add alloc { frame $w_.alloc -borderwidth 2 -relief groove } pack $itk_component(alloc) -side top -ipadx 2m -ipady 2m -fill x # if we are using a private colormap, ignore -max_colors if {[$image_ cmap isprivate]} { set itk_option(-max_colors) 128 } # if we are using a read-only colormap, ignore -min and max colors if {[$image_ cmap isreadonly]} { set itk_option(-min_free) 0 set itk_option(-max_colors) 256 } # LabelEntryScale widget displaying the number of allocated colors itk_component add allocated { util::LabelEntryScale $w_.allocated \ -text "Allocated Colors" \ -valuewidth 4 \ -show_arrows 1 \ -increment 1 \ -from $itk_option(-min_free) \ -to $itk_option(-max_colors) \ -value $itk_option(-min_free) \ -validate numeric } pack $itk_component(allocated) \ -in $itk_component(alloc) -side left -fill x -expand 1 # LabelValue(n) widget displaying the number of free colors itk_component add free { util::LabelValue $w_.free \ -text "Free Colors:" \ -valuewidth 4 \ -value 0 } pack $itk_component(free) \ -side left -padx 2m -in $itk_component(alloc) update_allocated $itk_component(allocated) config -command [code $this set_allocated] # Frame for buttons itk_component add buttons { frame $w_.buttons -borderwidth 2 -relief groove } pack $itk_component(buttons) -side top -fill x -padx 1m -pady 1m # Apply button itk_component add apply { button $w_.apply \ -text "Reallocate" \ -command [code $this reallocate] } # Close button itk_component add close { button $w_.close \ -text "Close" \ -command "wm withdraw $w_" } # Defaults button itk_component add defaults { button $w_.defaults \ -text "Defaults" \ -command "[code $this set_defaults]" } pack $itk_component(apply) $itk_component(close) $itk_component(defaults) \ -side left -expand 1 -padx 2m -pady 2m -in $w_.buttons # add short help make_short_help # Default values may have been changed by the command line args set_color_scale [$image_ colorscale] } # set the default colormap and itt public method set_defaults {} { $itk_component(colormaps) set_choice $itk_option(-default_cmap) $itk_component(itts) set_choice $itk_option(-default_itt) $itk_component(scale) config -value Linear set_color_scale Linear } # if flag is true, use a private colormap, otherwise the default public method use_private_colormap {} { $image_ cmap private reallocate } # add a short help window protected method make_short_help {} { # TopLevelWidget::make_short_help add_short_help $itk_component(scale) \ {Color Scaling: {bitmap b1} = apply selected color scaling algorithm} add_short_help $itk_component(colormaps) \ {MIDAS Colormaps: {bitmap b1} = apply selected color map} add_short_help $itk_component(itts) \ {Intensity transfer tables: {bitmap b1} = apply selected ITT} add_short_help $itk_component(allocated) \ {Color allocation: {bitmap dragb1} = use more/less colors (press Reallocate to apply)} add_short_help $itk_component(free) \ {Free colors: displays number of colors not being used} add_short_help $itk_component(apply) \ {Reallocate: {bitmap b1} = reallocate colors to use the selected number of colors} add_short_help $itk_component(close) {Close: {bitmap b1} = close this window} add_short_help $itk_component(defaults) {Defaults: {bitmap b1} = reset to use default values} } # this method is called to set the number of allocated colors protected method set_allocated {num_colors} { set free [expr {$free_ + ($allocated_ - $num_colors)}] if {$free >= 0} { set free_ $free set allocated_ $num_colors $itk_component(free) config -value $free } else { set free_ 0 set allocated_ [expr {$num_colors+$free}] $itk_component(free) config -value $free_ $itk_component(allocated) config -value $allocated_ } set free_ [$itk_component(free) get] set allocated_ [$itk_component(allocated) get] } # called when the scale value is changed to reallocate the colors public method reallocate {} { busy { set free_ [$itk_component(free) get] set allocated_ [$itk_component(allocated) get] foreach i [array names images_] { $images_($i) alloccolors $allocated_ $i update_colors } update_allocated } } # update the display to show the number of free and allocated colors public method update_allocated {} { update idletasks busy { lassign [$image_ alloccolors] allocated_ free_ # XXX needed for bug in tcl 8.4.3 set bug "$allocated_ $free_" set n $itk_option(-min_free) set to [max $n [expr {($free_+$allocated_)-$n}]] $itk_component(allocated) config \ -to $to \ -value $allocated_ $itk_component(free) config -value $free_ } } # this method is called to set the colormap for the image public method set_cmap {cmap} { # strip ./ from front. set cmap [string range $cmap 2 end] $image_ cmap file $cmap # if the colormap is read-only, we need to regenerate the color ramp if {[$image_ cmap isreadonly]} { catch {$itk_option(-image) component colorramp update_colors} } } # this method is called to set the itt for the image public method set_itt {itt} { # strip ./ from front. set itt [string range $itt 2 end] $image_ itt file $itt # if the colormap is read-only, we need to regenerate the color ramp if {[$image_ cmap isreadonly]} { catch {$itk_option(-image) component colorramp update_colors} } } # this method is called to set the color scaling algorithm public method set_color_scale {alg} { # choice variable global ::$w_.scale.choice set var $w_.scale.choice switch $alg { Linear - linear { $image_ colorscale linear set $var Linear } Logarithmic - log { $image_ colorscale log set $var Logarithmic } {Square Root} - sqrt { $image_ colorscale sqrt set $var {Square Root} } {Histogram Equalization} - histeq { $image_ colorscale histeq set $var {Histogram Equalization} } } } # add the given image to the list of images whose colormaps are managed # by this class public proc add_image {im} { set images_($im) [$im get_image] } # remove the given image from the list of images whose colormaps are managed # by this class public proc remove_image {im} { if {[info exists images_($im)]} { set i $images_($im) unset images_($im) if {"$image_" == "$i"} { set i [lindex [array names images_] 0] if {"$i" != ""} { set image_ $images_($i) } } } } # update the display with the values set in the given rtdimage public method update_values {im} { component colormaps set_choice [file rootname [$im cmap file]] component itts set_choice [file rootname [$im itt file]] set_color_scale [$im colorscale] } # -- public vars -- # name of RtdImage itcl widget, set by caller itk_option define -image image Image {} { set image_ [$itk_option(-image) get_image] } # directory path for colormap and ITT files itk_option define -cmap_dir cmap_dir Cmap_dir "" { if {"$itk_option(-cmap_dir)" == ""} { global ::rtd_library set itk_option(-cmap_dir) "$rtd_library/colormaps" } } # suffix for colormap files itk_option define -cmap_suffix cmap_suffix Cmap_suffix {lasc} # suffix for ITT files itk_option define -itt_suffix itt_suffix Itt_suffix {iasc} # max number of colors to allocate itk_option define -max_colors max_colors Max_colors 200 # min number of free colors to leave itk_option define -min_free min_free Min_free 5 # default (midas) colormap itk_option define -default_cmap default_cmap Default_cmap {real} # default (midas) intensity transfer table itk_option define -default_itt default_itt Default_itt {ramp} # -- protected vars -- # number of colors allocated protected variable allocated_ 0 # number of free colors protected variable free_ 0 # -- common (shared) variables -- # name of current internal rtdimage object protected common image_ {} # array (itk RtdImage) of C++ RtdImage objects, for updating clone colors protected common images_ } skycat-3.1.2-starlink-1b/rtd/library/RtdImageCtrl.tcl000066400000000000000000000645571215713201500224400ustar00rootroot00000000000000# E.S.O. - VLT project # "@(#) $Id: RtdImageCtrl.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImageCtrl.tcl - Widget combining an RtdImage with a control panel # zoom and panning windows. # # See man page RtdImageCtrl(n) for a complete description. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01/06/95 Created # P.Biereichel 05/08/96 Added itk_option(-with_warp) # A.Brighton 22/03/98 Added -float_panel option to allow info panel to be # in a popup window (default is off, no change), # added -panel_layout option to allow changing the # order of the zoom and pan windows in the layout # (default is the same as before, no change). # P.W.Draper 22/01/99 Added -viewmaster option to RtdImageColorRamp # instance. # P.Biereichel 22/03/99 Added handling of bias widget # P.Biereichel 29/06/99 Added HDU code (copied from skycat) # pbiereic 25/05/00 Added method 'autoscale' # pbiereic 16/08/01 Added method 'reopen' to update FITS HDU's # Adapted for new widget RtdImageFitsHeader for viewing # FITS HDU headers. # P.W.Draper 05/12/06 Allow autoscale of image whose dimensions are 1. # 27/11/07 Autoscale for all items on canvas, not just image. itk::usual RtdImageCtrl {} # RtdImageCtrl is an itcl widget combining the RtdImage itcl widget with # a control panel, zoom and panning windows. # # RtdImageCtrl inherits all of the features described in # RtdImage(n) and also adds the following user interface components: # Zoom window (see RtdImageZoomView(n)), Panning window (see # RtdImagePan(n)), Colormap display widget (see RtdImageColorRamp(n)), # Image Control panel (see RtdImagePanel(n)). # # Each of the added user interface components is defined in a separate # [incr Tk] widget class. In addition, some methods from RtdImage are # redefined in order to update the user interface display. itcl::class rtd::RtdImageCtrl { inherit rtd::RtdImage # constructor: create a new instance of this class constructor {args} { # register with colormap handler window if it is already there (clones) rtd::RtdImageColors::add_image $this # register with bias image handler rtd::RtdImageBias::add_image $this # set the colormap on this window to the one used by the rtdimage # and arrange for all other top level windows to use that colormap rtd_set_cmap $w_ rtd_set_cmap [winfo toplevel $w_] util::TopLevelWidget::set_command "rtd_set_cmap" # see "init" method for layout eval itk_initialize $args } # destructor destructor { rtd::RtdImageColors::remove_image $this rtd::RtdImageBias::remove_image $this } # this method is called from the base class (TopLevelWidget) after all # the options have been evaluated protected method init {} { RtdImage::init feedback "control panel..." make_control_panel if ($itk_option(-with_colorramp)) { feedback "color ramp..." make_colorramp } # the "measure band" is displayed while the right mouse button # is pressed to show the distance between points rtd::RtdImageMBand $w_.mband \ -image $this \ -defaultcursor $itk_option(-cursor) # Add mouse bindings to select a region in the image $canvas_ bind $imageId_ \ "+$itk_component(draw) set_drawing_mode region" # set short help message to be displayed whenever # the mouse enters the image window (see Toplevel.tcl) set msg "image: \ {bitmap b1} = select object,\ {bitmap dragb2} = scroll image,\ {bitmap dragb3} = measure WCS, \ Control {bitmap dragb1} = select region" config -shelp $msg #set w [winfo toplevel $w_] #$canvas_ bind $imageId_ "+[code $w_ short_help $msg]" #$canvas_ bind $imageId_ "+[code $w_ short_help {}]" # set up remote control if {[catch {$image_ remote $itk_option(-port)} msg]} { error_dialog $msg $w_ } if {"$itk_option(-file)" == ""} { after 0 [code $this clear] } if { $itk_option(-float_panel) } { after 0 [code wm deiconify $itk_component(panel)] } } # make the control panel for operating on the image protected method make_control_panel {} { if { $itk_option(-float_panel) } { # The RTD control panel, may be put in a frame or optionally # in a popup window itk_component add panel { set panel [TopLevelWidget $w_.panel] } wm withdraw $panel # Stop this window from being destroyed. wm protocol $panel WM_DELETE_WINDOW {} wm title $panel "Control Panel ([$panel cget -number])" } else { itk_component add panel { set panel [frame $w_.panel] } if { "$itk_option(-panel_orient)" == "vertical" } { pack $panel -side left -fill y -before $w_.imagef } else { pack $panel -side top -fill x -before $w_.imagef } } # add the subwindows make_panel_subwindows $panel } # add the panel subwindows protected method make_panel_subwindows {panel} { switch -exact -- $itk_option(-panel_layout) { saoimage { make_panel_info $panel make_pan_window $panel make_zoom_window $panel } reverse { make_pan_window $panel make_panel_info $panel make_zoom_window $panel } default { make_zoom_window $panel make_panel_info $panel make_pan_window $panel } } } # make the panel info subwindow protected method make_panel_info {panel} { # add info panel feedback "info panel..." # Info panel, RtdImagePanel(n) object used to display image controls itk_component add info { rtd::RtdImagePanel $panel.info \ -image $this \ -state disabled \ -panel_orient $itk_option(-panel_orient) \ -min_scale $itk_option(-min_scale) \ -max_scale $itk_option(-max_scale) \ -shorthelpwin $itk_option(-shorthelpwin) \ -borderwidth 3 -relief groove } if { "$itk_option(-panel_orient)" == "vertical" } { pack $itk_component(info) -side top -fill y -expand 1 } else { pack $itk_component(info) -side left -fill both -expand 1 } # add an item to control the grid size if {$itk_option(-with_grid)} { make_grid_item } # flash background color of object label for real-time events config -cameraPreCmd "$itk_component(info) flash 1" \ -cameraPostCmd "$itk_component(info) flash 0" } # update camera status display public method updateCameraStatus {camera} { if {[info exists itk_component(info)]} { $itk_component(info) updateCameraStatus $camera [$image_ camera attach] } } # make the pan window protected method make_pan_window {panel} { # panning window if {$itk_option(-with_pan_window)} { feedback "pan window..." # pan window (RtdImagePan(n) widget). itk_component add pan { rtd::RtdImagePan $panel.pan \ -target_image $this \ -width $itk_option(-pan_width) \ -height $itk_option(-pan_height) \ -usexshm $itk_option(-usexshm) \ -usexsync $itk_option(-usexsync) \ -verbose $itk_option(-verbose) \ -borderwidth 3 \ -relief groove } if { "$itk_option(-panel_orient)" == "vertical" } { pack $itk_component(pan) -side top } else { pack $itk_component(pan) -side left -fill y } } } # make the zoom window in the panel protected method make_zoom_window {panel} { if {! $itk_option(-with_zoom_window)} { return } feedback "zoom window..." # set on/off by default global ::$panel.zoom.dozoom set $panel.zoom.dozoom $itk_option(-dozoom) if {$itk_option(-use_zoom_view)} { # Zoom window (RtdImageZoomView(n) widget) itk_component add zoom { rtd::RtdImageZoomView $panel.zoom \ -target_image $this \ -verbose $itk_option(-verbose) \ -width $itk_option(-zoom_width) \ -height $itk_option(-zoom_height) \ -factor $itk_option(-zoom_factor) \ -propagate $itk_option(-zoom_view_propagate) \ -usexshm $itk_option(-usexshm) \ -usexsync $itk_option(-usexsync) \ -borderwidth 3 \ -relief groove } } else { # Zoom window: this version is not really supported any more... itk_component add zoom { rtd::RtdImageZoom $panel.zoom \ -target_image $this \ -width $itk_option(-zoom_width) \ -height $itk_option(-zoom_height) \ -factor $itk_option(-zoom_factor) \ -usexshm $itk_option(-usexshm) \ -usexsync $itk_option(-usexsync) \ -borderwidth 3 \ -relief groove } } if { "$itk_option(-panel_orient)" == "vertical" } { pack $itk_component(zoom) -side top -fill both -expand 0 } else { pack $itk_component(zoom) -side left -fill both -expand 0 } # tell the base class to use this zoom window when entered config -zoomwin $itk_component(zoom) } # create an item in the panel to control the ra,dec grid size protected method make_grid_item {} { # Frame at lower right for the grid checkbutton and size entry itk_component add gridf { set gridf [frame [$itk_component(info) component lrframe].gridf] } pack $gridf -anchor se -padx 1m -pady 1m -fill x # Check button for optional WCS grid itk_component add gridcheck { checkbutton $gridf.gridcheck \ -text "Grid:" \ -font [$itk_component(info) cget -labelfont] \ -variable $w_.grid -command [code $this show_grid $w_.grid] } pack $itk_component(gridcheck) -side left # LabelEntry for grid size itk_component add gridsize { LabelEntry $gridf.gridsize \ -value 60 \ -relief sunken \ -anchor w \ -valuewidth [$itk_component(info) cget -valuewidth] \ -valuefont [$itk_component(info) cget -valuefont] \ -command [code $this set_grid_size] \ -validate real } pack $itk_component(gridsize) -side left add_short_help $itk_component(gridcheck) \ {Grid: Toggle the visibility of the image ra,dec grid} add_short_help $itk_component(gridsize) \ {Grid Size: set space between grid lines in arcseconds of degrees} $itk_component(gridsize) configure -state disabled } # toggle the visibility of the control panel # (argument is the name of the checkbutton variable to use) public method hide_control_panel {variable} { set panel $itk_component(panel) global ::$variable ::$panel.zoom.dozoom if {[set $variable]} { # hide the panel, turn off the zoom window, keep the canvas width set zoom_state_ [set $panel.zoom.dozoom] set $panel.zoom.dozoom 0 set w [winfo width $canvas_] pack forget $panel $canvas_ config -width $w } else { # show the panel, restore the zoom window set $panel.zoom.dozoom $zoom_state_ if { "$itk_option(-panel_orient)" == "vertical" } { pack $panel -side left -fill y -before $w_.imagef } else { pack $panel -side top -fill x -before $w_.imagef } } } # toggle the visibility of the image ra,dec grid # (argument is the name of the checkbutton variable to use) public method show_grid {variable} { if {[$image_ isclear]} { warning_dialog "No image is currently loaded" $w_ return } set grid_var_ $variable global ::$grid_var_ if {[set $grid_var_]} { # show the grid if {![winfo exists $w_.grid]} { rtd::RtdImageGrid $w_.grid -image $this } $w_.grid show $itk_component(gridsize) configure -state normal -value [$w_.grid size] } else { # don't show the grid if {[winfo exists $w_.grid]} { $w_.grid hide } $itk_component(gridsize) configure -state disabled } } # set the size of the grid (space between lines) in arc seconds of dec degrees public method set_grid_size {size} { if {[$image_ isclear]} { warning_dialog "No image is currently loaded" $w_ return } if {[winfo exists $w_.grid]} { global ::$grid_var_ if {[info exists $grid_var_] && [set $grid_var_]} { $w_.grid configure -size $size $w_.grid reset $itk_component(gridsize) configure -state normal -value [$w_.grid size] } } } # add a generated image to display the colors in the colormap protected method make_colorramp {} { # color ramp widget (RtdImageColorRamp(n)) itk_component add colorramp { rtd::RtdImageColorRamp $w_.colorramp \ -height $itk_option(-colorramp_height) \ -usexshm $itk_option(-usexshm) \ -viewmaster $image_ } pack $itk_component(colorramp) -side bottom -fill x -before $w_.imagef } # This method is redefined here to update the scale display. # resize the image and the canvas graphics by the given integer factors # (1 is no scale, -2 = 50%, 2 = 200% etc...) public method scale {x y} { RtdImage::scale $x $y if {[info exists itk_component(zoom)]} { $itk_component(zoom) scale } $itk_component(info) component trans update_trans } # add the given increment to the current zoom factor and re-scale # the image public method inc_zoom {inc} { $itk_component(info) component trans inc_zoom $inc } # this method is called by the image code whenever a new image is loaded. # (for real-time updates, see camera command) protected method new_image_cmd {} { RtdImage::new_image_cmd # display HDU list, if there are multiple HDUs update_fits_hdus if {[info exists itk_component(zoom)]} { $itk_component(zoom) zoom $itk_component(zoom) scale } if {! [$image_ isclear]} { $itk_component(info) config -state normal } autoscale $itk_component(info) updateValues if {[winfo exists $w_.cut]} { $w_.cut update_graph } if {[winfo exists $w_.spectrum]} { destroy $w_.spectrum } if {[winfo exists $w_.draw]} { $w_.draw set_menu_state normal } if {[winfo exists $w_.wcs_info]} { $w_.wcs_info configure -values [$image_ wcsset] } if {[winfo exists $w_.fits_header]} { view_fits_header } if {[winfo exists $w_.fits_hdu_header]} { if { [$image_ hdu count] < 1 } { destroy $w_.fits_hdu_header } else { view_fits_hdu_header } } if {[winfo exists $w_.grid]} { # update grid, if on global ::$grid_var_ if {[info exists $grid_var_] && [set $grid_var_]} { # reset size, since new image may have a much different scale # setting size to {} means it will be chosen based on the image size... $w_.grid configure -size {} $w_.grid reset $itk_component(gridsize) configure -state normal -value [$w_.grid size] } } } # open and load a new FITS image file via file name dialog public method open {{dir "."} {pattern "*.*fit*"}} { if { "$dir" == "." && "[cget -image_directory]" != "" } { set dir [cget -image_directory] } set file [filename_dialog $dir $pattern $w_] if {"$file" != ""} { if {[file isfile $file]} { detach_camera config -file $file } else { error_dialog "There is no file named '$file'" $w_ } } } # view the FITS header in a text window public method view_fits_header {} { set s [$image_ object] if {"$s" == ""} { set s [$image_ cget -file] } if {"$s" == ""} { set s "FITS Header" } else { set s "FITS Header for $s" } set existed [winfo exists $w_.fits_header] utilReUseWidget util::TextDialog $w_.fits_header \ -bitmap {} \ -textwidth 80 \ -buttons "Close" \ -modal 0 \ -text "$s" \ -title "$s" \ -messagewidth 5i \ -contents [$image_ fits get] if {! $existed} { $w_.fits_header activate } } # view the FITS HDU headers public method view_fits_hdu_header {} { if { [$image_ hdu count] < 1 && "[$image_ object]" == "[cget -camera]"} { warning_dialog "No FITS header available for real-time images" $w_ return } utilReUseWidget rtd::RtdImageFitsHeader $w_.fits_hdu_header \ -image $this \ -shorthelpwin $itk_option(-shorthelpwin) update idletasks $w_.fits_hdu_header activate } # pop up a dialog to display/edit the basic world coordinate # parameters public method wcs_info_dialog {} { if {[$image_ isclear]} { warning_dialog "No image is currently loaded" $w_ return } utilReUseWidget util::EntryForm $w_.wcs_info \ -title "Basic WCS Information" \ -labels [list \ "Center right ascension (H:M:S):" \ "Center declination (D:M:S)" \ "Number of arcseconds per pixel:" \ "Reference pixel X coordinate:" \ "Reference pixel Y coordinate:" \ "Number of pixels along x-axis:" \ "Number of pixels along y-axis:" \ "Rotation angle (clockwise positive) in degrees:" \ "Equinox (1950 and 2000 supported):" \ "Epoch (for FK4/FK5 conversion, no effect if 0):" \ "Projection:" ] \ -values [$image_ wcsset] \ -scroll 0 \ -command [code $this set_wcs_info] } # This command is called with a list of values from wcs_info_dialog above # to set new world coordinates information for the current image. public method set_wcs_info {list} { if { "[lindex $list 10]" == "ZPN" } { # $image_ wcsset $list crashes for ZPN projection (bug in WCSLIB?) error_dialog "Setting WCS information for ZPN projection is not yet supported." return } if {[catch "$image_ wcsset $list" msg]} { error_dialog $msg $w_ } } # pop up a window to edit the image colors public method set_colors {} { # note that this window must be shared by all instances utilReUseWidget rtd::RtdImageColors .colors \ -image $this \ -shorthelpwin $itk_option(-shorthelpwin) \ -cmap_dir $itk_option(-cmap_dir) \ -cmap_suffix $itk_option(-cmap_suffix) \ -itt_suffix $itk_option(-itt_suffix) \ -default_cmap $itk_option(-default_cmap) \ -default_itt $itk_option(-default_itt) .colors update_allocated wm transient .colors [winfo toplevel $w_] } # Update the settings in the color popup to reflect those of the image public method update_color_window {} { if {[winfo exists .colors]} { .colors update_values $image_ } } # This method is called when the colormap has been changed to # update the display public method update_colors {} { if {$itk_option(-with_colorramp)} { $itk_component(colorramp) update_colors } } # pop up a window to control bias subtraction public method set_bias {} { # note that this window must be shared by all instances utilReUseWidget rtd::RtdImageBias .bias \ -image $this \ -shorthelpwin $itk_option(-shorthelpwin) \ -dsplnr [[winfo toplevel $w_] cget -number] \ -command [code $itk_component(info) updateValues] wm transient .bias [winfo toplevel $w_] } # clear the current image display and remove an windows that # access it (extend parent class version) public method clear {} { RtdImage::clear $itk_component(info) config -state disabled if {[winfo exists $w_.cut]} { destroy $w_.cut } if {[winfo exists $w_.draw]} { $w_.draw set_menu_state disabled wm withdraw $w_.draw } if {[winfo exists $w_.grid]} { $w_.grid hide $itk_component(gridsize) configure -state disabled } } # this method is called at startup to give feedback while building the interface public method feedback {msg} { eval $itk_option(-feedback) [list $msg] } # reopen file and update HDU's public method reopen {} { rtd::RtdImage::reopen update_fits_hdus } # display a popup window listing the HDUs in the current image, if any public method display_fits_hdus {} { if {[catch {set n [$image_ hdu count]}]} { set n 0 } if {$n <= 1} { warning_dialog "There are no FITS extensions" $w_ return } utilReUseWidget rtd::RtdImageHduChooser $w_.hdu \ -image $this \ -shorthelpwin $itk_option(-shorthelpwin) \ -verbose $itk_option(-verbose) } # Update the popup window listing the HDUs in the current image public method update_fits_hdus {} { if {[catch {set n [$image_ hdu count]}]} { set n 0 } # display and hide window automatically as needed if {[winfo exists $w_.hdu]} { if {$n > 1} { after idle [code $this show_hdu] } else { after idle "destroy $w_.hdu" } } else { # if there is more than one HDU, display the HDU select window if {$n > 1} { display_fits_hdus } } } public method show_hdu {} { if {[winfo exists $w_.hdu]} { $w_.hdu show_hdu_list } else { display_fits_hdus } } # This method is redefined here to update the scale display when # 'autoscale' is set public method maybe_center {} { rtd::RtdImage::maybe_center maybe_autoscale } # This method is redefined here to update the scale display when # 'autoscale' is set public method rotate {bool} { rtd::RtdImage::rotate $bool maybe_autoscale } # auto scale image to the max. visible size public method autoscale { {variable ""} } { if {"$variable" != ""} { global ::$variable set autoscale_ [set $variable] } if {! [catch {$itk_component(info) component trans} trans]} { if { $autoscale_ } { foreach compo "larger smaller choose" { catch {$trans component $compo config -state disabled} } } else { $trans config -state normal } } maybe_autoscale } # if the image does not fill the visible canvas, scale it # # XXX allan: don't use $image_ config -fillwidth ..., # need to use RtdImage itcl widget so graphics are updated # to use the new scale. public method maybe_autoscale {} { if { [$image_ isclear] || ! $autoscale_} { $image_ configure -fillwidth 0 -fillheight 0 } else { set cw [winfo width $canvas_] set ch [winfo height $canvas_] if {[$image_ rotate]} { lassign "$cw $ch" ch cw } #$image_ configure -fillwidth $cw -fillheight $ch fill_to_fit $cw $ch center } } # Use this method instead of $image_ configure -fillwidth $cw -fillheight $ch # so that graphics transformations are handled correctly. # The arguments are the dimensions of the image canvas. protected method fill_to_fit {cw ch} { # Fit to all items on the canvas, not just the image. lassign [$canvas_ bbox all] x0 y0 x1 y1 $image_ convert coords $x0 $y0 canvas x0 y0 image $image_ convert coords $x1 $y1 canvas x1 y1 image set w [expr int(abs($x1-$x0))] set h [expr int(abs($y1-$y0))] set factor [expr {min(150,min($cw/$w, $ch/$h))}] if {$factor == 0} { set factor [expr {-max(($w-1)/$cw+1, ($h-1)/$ch+1)}] if {$factor >= -1} { set factor 1 } } scale $factor $factor } # -- options -- # Panel layout order: set to one of {saoimage reverse default} # to change the layout ordering of the panel windows. # "saoimage" puts the info first, followed by pan and zoom, # "reverse" reverses the default order, which is {zoom info pan}. itk_option define -panel_layout panel_layout Panel_layout {} # Panel orient: one of {horizontal vertical} (default: horizontal) itk_option define -panel_orient panel_orient Panel_orient {} # width of zoom window itk_option define -zoom_width zoom_width Zoom_width 152 # height of zoom window itk_option define -zoom_height zoom_height Zoom_height 152 # zooming factor itk_option define -zoom_factor zoom_factor Zoom_factor 4 # width of panning window itk_option define -pan_width pan_width Pan_width 152 # height of panning window itk_option define -pan_height pan_height Pan_height 152 # height of the colorramp subwindow itk_option define -colorramp_height colorramp_height Colorramp_height 12 # flag: if true (default), show the color ramp window itk_option define -with_colorramp with_colorramp With_colorramp 1 # flag: if true, make zoom window a view of the main image # otherwise do a faster, but less accurate (by shrunken images) zoom # from the xImage itk_option define -use_zoom_view use_zoom_view Use_zoom_view 1 # flag: if true, changes in main image scale will propagate to the zoom window, # otherwise controls are displayed so the user can manually change it (ZoomView only) itk_option define -zoom_view_propagate zoom_view_propagate Zoom_view_propagate 1 # flag: if true (default) make a zoom window itk_option define -with_zoom_window with_zoom_window With_zoom_window 1 # flag: if true (default) make a panning window itk_option define -with_pan_window with_pan_window With_pan_window 1 # flag: if true, turn on zoom window itk_option define -dozoom dozoom Dozoom 1 # default cmap file itk_option define -default_cmap default_cmap Default_cmap {real} # default ITT file itk_option define -default_itt default_itt Default_itt {ramp} # default port for remote connections (0 means system chooses a port) itk_option define -port port Port 0 # command used to display feedback during startup itk_option define -feedback feedback Feedback "#" # option to warp the mouse pointer itk_option define -with_warp with_warp With_warp 0 # option to include grid button (default to off, since it doesn't work # well yet on some images) itk_option define -with_grid with_grid With_grid 0 # Floating panel option (for small displays). itk_option define -float_panel float_panel Float_Panel 0 # default scaling factor itk_option define -xscale xscale Xscale 1 itk_option define -yscale yscale Yscale 1 itk_option define -camera camera Camera {} # Default directory for loading images itk_option define -image_directory image_directory Image_directory {} # -- protected vars -- # saved zoom button state protected variable zoom_state_ 0 # cut values frame protected variable cut_ # name of trace var for grid protected variable grid_var_ # auto scale image protected variable autoscale_ 0 } skycat-3.1.2-starlink-1b/rtd/library/RtdImageCut.tcl000066400000000000000000000363471215713201500222630ustar00rootroot00000000000000#******************************************************************************* # E.S.O. - VLT project # # "@(#) $Id: RtdImageCut.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImageCut.tcl - itcl widget for setting cut levels for an RtdImage widget # # See man page RtdImageCut(n) for a complete description. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01/06/95 Created # # P. Biereichel 09/10/97 Enter cut sets also scale range # # Allan Brighton 24/03/98 Added $initialized_ variable to fix bug # when image is blank (generated for plotting). # Added Peter Draper's (Starlink) fixes, # bindings, -resolution argument. # # Allan Brighton 10/04/98 Moved constructor code to "init" method for # easier subclassing. # Removed bg_set and the code for setting the # color on the "Set" button, as it didn't always # work correctly. # Removed the calls to "update_increment", since it # caused endless event looping in some cases. # (The event code is getting too complex to follow...) itk::usual RtdImageCut {} # This widget displays a toplevel window containing a plot of the pixel # value distribution in the target image and buttons and scales for # manipulating the image cut levels. The cut levels are two values: the # lowest and highest pixel values considered when color scaling the # image, i.e.: mapping image pixel values to color values, and are used # to filter out noise and other extreme values in the image. # # The plot displayed uses the rtdimage "getdist" subcommand to get the # pixel value distribution. This is an array of values that specify, for # example, how many pixel values are between 0 and 100, between 100 and # 200, and so on. This information can also be used to set the cut levels, # by specifying a percent of the total number of pixels that should be within # the cut levels. # # A second, faster algorithm is supported by the "Median Filter" button. # This is a standard algorithm that works very fast to determine # reasonable cut levels. # # After setting the cut levels, either manually or by one of the # buttons, the new pixel value distribution is displayed. The plotting # is done directly from the rtdimage C++ code to the BLT graph over its # C interface. itcl::class rtd::RtdImageCut { inherit util::TopLevelWidget # constructor: create a new instance of this class constructor {args} { eval itk_initialize $args } # destructor - clean up when deleted destructor { global ::tcl_version if {$tcl_version >= 8.0} { blt::vector destroy $xVector_ $yVector_ } } # called after constructors have run method init {} { wm minsize $w_ 10 10 wm title $w_ "Cut Levels ($itk_option(-number))" wm iconname $w_ "Cut Levels ($itk_option(-number))" # get internal image handle set image_ [$itk_option(-image) get_image] make_graph make_controls make_buttons make_short_help incr initialized_ update_graph 0 } # add a short help window protected method make_short_help {} { # TopLevelWidget::make_short_help add_short_help $itk_component(graph) \ {Graph: shows distribution of pixel values in image \ {bitmap b1} ... {bitmap b1} = Zoom in, {bitmap b3} = Zoom out, Cancel zoom} add_short_help $itk_component(percent) \ {Auto set: {bitmap b1} = set so that given percent of pixels are within cut levels} add_short_help [$itk_component(lowcut) component scale] \ {Low cut: {bitmap dragb1} = adjust low cut value} add_short_help [$itk_component(lowcut) component entry] \ {Low cut: enter low cut value and set low cut scale range} add_short_help [$itk_component(highcut) component scale] \ {High cut: {bitmap dragb1} = adjust high cut value} add_short_help [$itk_component(highcut) component entry] \ {High cut: enter high cut value and set high cut scale range} add_short_help $itk_component(set) \ {Set: {bitmap b1} = set cut levels to selected values} add_short_help $itk_component(reset) \ {Reset: {bitmap b1} = apply min, max to set cut levels} add_short_help $itk_component(median) \ {Auto Set Cut Levels: {bitmap b1} = apply median filtering algorithm to set cut levels} add_short_help $itk_component(update) \ {Update: {bitmap b1} = update pixel value distribution (e.g. after a real-time image event)} add_short_help $itk_component(close) \ {Close: {bitmap b1} = close this window} } # make the graph subwindow protected method make_graph {} { global ::tcl_version # BLT graph widget for displaying pixel distribution itk_component add graph { blt::graph $w_.graph \ -width 4i \ -height 3i \ -borderwidth 2 \ -relief groove \ -title "Pixel Value Distribution" } { } set graph_ $w_.graph pack $itk_component(graph) \ -fill both -expand 1 -padx 1m -pady 1m $graph_ xaxis configure -title {} -command [code $this notify_blt_zoom] $graph_ yaxis configure -title {} # tcl8/blt2.4f vector names ust start with a letter, no dots... # Someone also changed the default symbol to circle also - why? regsub -all {\.} v$graph_.xVector _ xVector_ regsub -all {\.} v$graph_.yVector _ yVector_ if {$tcl_version >= 8.0} { $graph_ legend config -hide 1 if {![info exists $xVector_]} { blt::vector create $xVector_ $yVector_ } set symbol {} } else { global ::$xVector_ ::$yVector_ $graph_ legend config -mapped 0 if {![info exists $xVector_]} { blt::vector $xVector_ $yVector_ } set symbol none } $graph_ element create elem -xdata $xVector_ -ydata $yVector_ -symbol $symbol # plot the distribution of pixel values if {[catch {$image_ graphdist $graph_ elem $itk_option(-num_points) \ $xVector_ $yVector_} msg]} { #warning_dialog $msg } # add BLT features ::Blt_ZoomStack $graph_ ::Blt_ActiveLegend $graph_ ::Blt_ClosestPoint $graph_ } # make the control panel protected method make_controls {} { # frame containing scale widgets to adjust cut levels itk_component add scales { frame $w_.scales -borderwidth 2 -relief groove } pack $itk_component(scales) \ -side top -fill x -padx 1m -pady 1m # LabelChoice(n) widget displaying percent values for setting cut levels itk_component add percent { util::LabelChoice $itk_component(scales).percent \ -text "Auto Set:" \ -choice "90% 95% 98% 99% 99.5% 100%" \ -value "" \ -command [code $this set_by_percent] } foreach lab "Low High" { set el [string tolower $lab] # Lowscale and Highscale component frames itk_component add ${el}scale { frame $itk_component(scales).${el}scale -borderwidth 2 -relief groove } global ::$w_.${el}cut # Lowcut and Highcut components (LabelEntryScale(n) widgets) # for displaying and adjusting the cut levels itk_component add ${el}cut { util::LabelEntryScale $itk_component(${el}scale).${el}cut \ -text $lab \ -valuewidth 8 \ -show_arrows 1 \ -validate real \ -value 0 \ -command [code $this setb_${el}cut 0] \ -entrycommand [code $this setb_${el}cut 1] } $itk_component(${el}cut) component scale config -variable $w_.${el}cut pack $itk_component(${el}cut) -padx 1m } blt::blttable $itk_component(scales) \ $itk_component(lowscale) 1,0 -anchor w -fill x -padx 1m -pady 1m \ $itk_component(highscale) 1,1 -anchor w -fill x -padx 1m -pady 1m \ $itk_component(percent) 2,0 -anchor c -fill x -columnspan 2 -padx 1m \ } # make the button frame at the bottom of the window protected method make_buttons {} { # Tk frame for buttons itk_component add buttons { frame $w_.buttons -borderwidth 2 -relief groove } pack $itk_component(buttons) \ -side top -fill x -padx 1m -pady 1m add_button set Set set_cutlevels add_button reset Reset reset_cutlevels add_button median "Median Filter" set_by_median add_button update Update update_graph add_button close Close quit blt::blttable $itk_component(buttons) \ $itk_component(set) 1,0 -anchor w -fill x -padx 1m -pady 2m \ $itk_component(reset) 1,1 -anchor w -fill x -padx 1m -pady 2m \ $itk_component(median) 1,2 -anchor w -fill x -padx 1m -pady 2m \ $itk_component(update) 1,3 -anchor w -fill x -padx 1m -pady 2m \ $itk_component(close) 1,4 -anchor w -fill x -padx 1m -pady 2m } # add a button to the buttons frame public method add_button {compo text command} { # Button components: set, reset, median, update, or close itk_component add $compo { button $itk_component(buttons).$compo \ -text $text \ -command [code $this $command] } } # update the graph after a new image has been loaded or the image has been # modified public method update_graph {{modimg 1}} { # no image is loaded ? if {[$image_ isclear] || ! $initialized_} { quit return } if {$modimg} { lassign [$image_ cut] low high } else { set low_ [set low [$image_ min]] entry_value lowcut $low set high_ [set high [$image_ max]] entry_value highcut $high } if {$low > $high} { lassign "$low $high" high low } lassign [get_cuts] plow phigh if {$plow != $low || $phigh != $high} { $itk_component(percent) config -value "" } # adapt new scale range setb_lowcut [expr {$low <= $low_}] $low setb_highcut [expr {$high >= $high_}] $high update # plot the distribution of pixel values if {[catch { $image_ graphdist $graph_ elem $itk_option(-num_points) \ $xVector_ $yVector_} msg]} { #warning_message $msg } update_increment } # return the current low/high cut values public method get_cuts {} { set low [$itk_component(lowcut) get] set high [$itk_component(highcut) get] if {"$low" == ""} { set low [$image_ min] } if {"$high" == ""} { set high [$image_ max] } return "$low $high" } # this method is called when blt changes the tick labels after a zoom protected method notify_blt_zoom {pathname tickvalue} { if {[$image_ isclear] || ! $initialized_} { quit return } set min [$graph_ xaxis cget -min] set max [$graph_ xaxis cget -max] lassign [get_cuts] low high if {$min != $low || $max != $high} { setb_cut 0 $min $max } return $tickvalue } # update xaxis after rescaling protected method update_xaxis {{value 0}} { lassign [get_cuts] low high if {$low >= $high} { return } set clow [$graph_ xaxis cget -min] set chigh [$graph_ xaxis cget -max] if {$low != $clow || $high != $chigh} { $graph_ xaxis configure -min $low -max $high } } # set low and high cut protected method setb_cut {flg low high} { setb_lowcut $flg $low setb_highcut $flg $high } # write value into entry field protected method entry_value {compo value} { set w [$itk_component($compo) component entry] $w delete 0 end $w insert 0 $value } # update the increment for the slider buttons depending on the range # XXX not currently used - problems with looping in event handlers (allan) protected method update_increment {} { lassign [get_cuts] low high set increment [expr {($high-$low)/100.0}] if {$increment <= 0} { return } set resolution $increment $itk_component(lowcut) configure -increment $increment \ -resolution $resolution $itk_component(highcut) configure -increment $increment \ -resolution $resolution } # set entry values of the lowcut scale widget and update scale widgets protected method setb_lowcut {setlow value} { lassign [get_cuts] low high if {$value >= $high} { set value [expr {$high - 1}] } if {$setlow} { set low_ $value } entry_value lowcut $value update_cut $value $high } # set entry values of the highcut scale widget and update scale widgets protected method setb_highcut {sethigh value} { lassign [get_cuts] low high if {$value <= $low} { set value [expr {$low + 1}] } if {$sethigh} { set high_ $value } entry_value highcut $value update_cut $low $value } # update min, max values of the lowcut and highcut scale widgets protected method update_cut {low high} { foreach el "lowcut highcut" { update_$el $low $high } update_xaxis } # update min, max values of the lowcut scale widget protected method update_lowcut {low high} { global ::$w_.lowcut set from $low_ set to [expr {$high - 1.0}] if {$from > $low} { set from $low } if {$to < $low} { set to $low } $itk_component(lowcut) config -from $from -to $to set $w_.lowcut $low } # update min, max values of the highcut scale widget protected method update_highcut {low high} { global ::$w_.highcut set from [expr {$low + 1.0}] set to $high_ if {$from > $high} { set from $high } if {$to < $high} { set to $high } if {$from == $to} { set from [expr {$from - 1.0}] } $itk_component(highcut) config -from $from -to $to set $w_.highcut $high } # set the cut levels in the image protected method set_cutlevels {} { lassign [get_cuts] low high busy {$image_ cut $low $high} if {"$itk_option(-command)" != ""} { eval $itk_option(-command) } $itk_component(percent) config -value "" } # reset the cut levels to the original min/max values public method reset_cutlevels {} { set low [$image_ min] set high [$image_ max] busy {$image_ cut $low $high} setb_cut 1 $low $high $itk_component(percent) config -value 100 if {"$itk_option(-command)" != ""} { eval $itk_option(-command) } } # automatically set the cut values by percent of distribution # that should be inside the cut levels public method set_by_percent {percent} { scan $percent "%d" percent busy {$image_ autocut -percent $percent} lassign [$image_ cut] low high setb_cut 1 $low $high if {"$itk_option(-command)" != ""} { eval $itk_option(-command) } } # automatically set the cut values by median filtering public method set_by_median {} { busy {$image_ autocut} lassign [$image_ cut] low high setb_cut 1 $low $high if {"$itk_option(-command)" != ""} { eval $itk_option(-command) } $itk_component(percent) config -value "" } # -- public vars -- # target RtdImage itcl class object itk_option define -image image Image {} # number of points to plot itk_option define -num_points num_points Num_points {2048} # tcl command to evaluate when cut levels are changed itk_option define -command command Command {} # -- protected vars -- # internal rtdimage object protected variable image_ # name of graph widget protected variable graph_ # lowest value to display (image(min) or set by user) protected variable low_ 0 # highest value to display (image(max) or set by user) protected variable high_ 1 # set to 1 after widget has been initizlized protected variable initialized_ 0 # x vector for graph protected variable xVector_ # y vector for graph protected variable yVector_ } skycat-3.1.2-starlink-1b/rtd/library/RtdImageFitsHeader.tcl000066400000000000000000000251371215713201500235410ustar00rootroot00000000000000# E.S.O. - VLT project # "@(#) $Id: RtdImageFitsHeader.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImageFitsHeader.tcl - Itcl widget for displaying FITS header HDU's # # See man page RtdImageFitsHeader(n) for a complete description. # # who when what # ---------- --------- ----------------------------------------------------- # pbiereic 14/08/01 Created # pbiereic 17/02/03 fixed problems with tabnotebook, packing order # and labels of tabsets # pdraper 05/04/06 Treat HISTORY like COMMENT # pdraper 20/02/07 Formatting changes: keep empty lines (one anyway) # and print blank COMMENT/HISTORY lines with blanks, do # not fake that they start with COMMENT/HISTORY. itk::usual RtdImageFitsHeader {} # RtdImageFitsHeader is an itcl widget for displaying the FITS header of all # Header Data Units (HDU's) contained in a FITS file. The user can view the # FITS header in different ways, print it, search for keyword etc. # RtdImageFitsHeader uses public methods of class util::TableList itcl::class rtd::RtdImageFitsHeader { inherit util::TopLevelWidget constructor {args} { eval itk_initialize $args wm protocol $w_ WM_DELETE_WINDOW [code $this quit] } # This method is called after the options have been evaluated. protected method init {} { package require Iwidgets # set default table configuration parameters set tconfig_(sort_cols) "" set tconfig_(sort_order) "" set tconfig_(Keyword) 1 set tconfig_(Value) 1 set tconfig_(Comment) 1 add_menubar make_notebook $w_ add_buttons $w_ # tabnotebook's configure event doesn't work (oszillates) bind [$tabnotebook_(w) component canvas] {} # pack the button frame first to ensure that it # doesn't get obscured when the window is resized (shrinked). pack $itk_component(buttons) -side bottom -fill both -expand 0 pack $tabnotebook_(w) -fill both -expand 1 -side top } # Quit this widget public method quit { } { set activated_ 0 destroy $w_ } # add the menubar at the top of the window protected method add_menubar {} { TopLevelWidget::add_menubar # add menubuttons and menus set m [add_menubutton File] add_menuitem $m command "Print..." \ {Print all FITS tables} \ -command [code $this print] add_menuitem $m command "Close" \ {Close this window} \ -command [code $this quit] set m [add_menubutton Header] add_menuitem $m cascade "Sort..." \ {Sort FITS header} \ -menu [menu $m.sort] global $w_.sort set $w_.sort 2 $m.sort add radiobutton -label "Keyword - increasing" \ -command [code $this sort Keyword increasing] \ -variable $w_.sort -value 0 $m.sort add radiobutton -label "Keyword - decreasing" \ -command [code $this sort Keyword decreasing] \ -variable $w_.sort -value 1 $m.sort add radiobutton -label "No sort" \ -command [code $this sort "" ""] \ -variable $w_.sort -value 2 add_menuitem $m cascade "Show / Hide" \ {Configure layout of table} \ -menu [menu $m.show] global $w_.show_keyword $w_.show_value $w_.show_comment set $w_.show_keyword 1 $m.show add checkbutton -label "Keyword" \ -command [code $this show Keyword $w_.show_keyword] \ -variable $w_.show_keyword -onvalue 1 -offvalue 0 set $w_.show_value 1 $m.show add checkbutton -label "Value" \ -command [code $this show Value $w_.show_value] \ -variable $w_.show_value -onvalue 1 -offvalue 0 set $w_.show_comment 1 $m.show add checkbutton -label "Comment" \ -command [code $this show Comment $w_.show_comment] \ -variable $w_.show_comment -onvalue 1 -offvalue 0 } # add the buttons protected method add_buttons { f } { itk_component add buttons { frame $f.buttons } itk_component add close { button $itk_component(buttons).close \ -text Close -width 8 \ -command [code $this quit] } itk_component add search { LabelEntry $itk_component(buttons).search \ -text Search -valuewidth 10 \ -command [code $this search] } pack $itk_component(search) -side left -fill x -expand 1 pack $itk_component(close) -side left -fill none -expand 0 } # Make the layout protected method make_notebook { f } { set tabnotebook_(w) [iwidgets::tabnotebook $f.tab \ -tabpos n -width 400 -height 500 \ -equaltabs false -raiseselect 1 \ -font $itk_option(-labelfont) \ -backdrop [$w_ cget -background]] add_short_help $f.tab \ {Drag {bitmap b2} = Drag mouse button 2 to scroll} } # Sort FITS header protected method sort { sort_cols sort_order } { set tconfig_(sort_cols) $sort_cols set tconfig_(sort_order) $sort_order loop i 0 $num_hdus_ { $tabnotebook_(table$i) config -sort_cols $sort_cols \ -sort_order $sort_order $tabnotebook_(table$i) new_info } } # Show / Hide table column protected method show { label var } { global $var set val [set $var] set tconfig_($label) $val loop i 0 $num_hdus_ { $tabnotebook_(table$i) set_option $label Show $val $tabnotebook_(table$i) new_info } } # Print current selected header protected method print { } { set idx [$tabnotebook_(w) index select] set tbl $tabnotebook_(table$idx) busy { set w $w_.tblprint if {[winfo exists $w]} { $w config -table $tbl wm deiconify $w } else { TableListPrint $w -table $tbl -printcmd [$tbl cget -printcmd] } } } # Search and highlight pattern protected method search { string } { $itk_component(search) select set idx [$tabnotebook_(w) index select] set tbl $tabnotebook_(table$idx) set listbox [$tbl component listbox] set string [string tolower $string] set start_idx $search_idx_ set search_idx_ 0 if { "$string" != "$search_str_" } { set start_idx 0 set search_str_ $string } set end_idx [$listbox index end] if { $start_idx >= $end_idx } { set start_idx 0 } set length [string length [$listbox get 0]] loop n $start_idx $end_idx { set row [string tolower [$listbox get $n]] if {[catch {regexp -indices $string $row indices} idx] } { continue } if { $idx > 0 } { $tbl select_row $n lassign $indices i1 i2 set i1 [expr {double($i1) + ($i2 - $i1) / 2.}] lassign [$listbox bbox $n] x0 y0 w h set offs [expr {double($length) / $w * [winfo width $w_] / 2.0}] set i1 [expr {$i1 - $offs}] $listbox xview moveto [expr {(1.0 - (double($length - $i1) / $length))}] set search_idx_ [incr n] break } } } # Set title protected method set_title { } { set s [$image_ object] if {"$s" == ""} { set s [$image_ cget -file] } if {"$s" == ""} { set s "FITS Header" } else { set s "FITS Header for $s" } wm title $w_ $s wm iconname $w_ $s return $s } # Activate this widget public method activate { } { set activated_ 1 set title [set_title] set w $tabnotebook_(w) set hdu_count [$image_ hdu count] if { $hdu_count > 0 && "[$image_ cget -file]" == "$file_" } { show_hdu_header [$image_ hdu] return } set file_ [$image_ cget -file] if { $num_hdus_ > 0 } { $w delete 0 [expr {$num_hdus_ - 1}] } set num_hdus_ $hdu_count set hlist [$image_ hdu list] set ExtName "HDU 1" loop i 0 $hdu_count { set hdu [expr {$i + 1}] set list [lindex $hlist $i] set tabnotebook_($i) [$w add -label $ExtName -gap overlap \ -command [code $this show_hdu_header [expr {$i + 1}]]] set ExtName " [expr {$hdu + 1}] " set child [$w childsite $i] set tabnotebook_(table$i) $child.tab$i # use TableList(n) widget for displaying the FITS header pack [util::TableList $child.tab$i \ -title $title \ -hscroll 1 -vscroll 1 \ -headings "Keyword Value Comment" \ -sort_cols $tconfig_(sort_cols) \ -sort_order $tconfig_(sort_order)] \ -fill both -expand 1 $tabnotebook_(table$i) set_option Keyword Show $tconfig_(Keyword) $tabnotebook_(table$i) set_option Value Show $tconfig_(Value) $tabnotebook_(table$i) set_option Comment Show $tconfig_(Comment) } show_hdu_header [$image_ hdu] } # Show HDU header info public method show_hdu_header { hdu } { set search_idx_ 0 if { [$image_ hdu count] < 1 || $hdu < 1 } { return } catch {$tabnotebook_(w) select [expr {$hdu -1}]} set idx [expr {$hdu - 1}] set w $tabnotebook_(table$idx) set fits [$image_ hdu fits $hdu] # TableList needs formatting... set lastblank 0 foreach line [split $fits "\n"] { set l [string trim $line] if {"$l" == "END"} { lappend info [list END {} {}] break } if { [lempty $l] } { if { ! $lastblank } { lappend info [list {} {} {}] } set lastblank 1 continue } set lastblank 0 set triple [get_kvc $line] if { [lempty $triple] } { set triple [list INVALID {} $line] } lappend info $triple } if { [info exists info] && ! [lempty $info] } { $w config -info $info } [$w component listbox] xview moveto 0.0 } # return a tcl list with keyword, value and comment (kvc) protected method get_kvc { line } { set key [string range $line 0 6] if { [lempty $key] || "$key" == "COMMENT" || "$key" == "HISTORY" } { return [list $key {} [string trim [string range $line 7 end]]] } lassign [split $line =] l1 l2 if { [lempty $l1] } { return "" } set key [string trim $l1] lassign [split $l2 /] l1 l2 l3 if { [info exists l3] && $l3 !={} } { # value = 'name/name' /comment? set l1 "$l1/$l2" set l2 "$l3" } set val [string trim $l1] set com [string trim $l2] return [list $key $val $com] } # -- options -- # target (main) RtdImage itcl widget itk_option define -image image Image {} { set image_ [$itk_option(-image) get_image] } # Font to use for labels itk_option define -labelfont labelFont LabelFont TkDefaultFont # -- protected vars -- # internal rtdimage object protected variable image_ # array for tabnotebook protected variable tabnotebook_ # array for table configuration protected variable tconfig_ # last file protected variable file_ "" # widget activated, bool protected variable activated_ 0 # number of HDU of last file protected variable num_hdus_ 0 # last serach index protected variable search_idx_ 0 # last serach string protected variable search_str_ "" } skycat-3.1.2-starlink-1b/rtd/library/RtdImageFrame.tcl000066400000000000000000000176001215713201500225510ustar00rootroot00000000000000#******************************************************************************* # E.S.O. - VLT project # # "@(#) $Id: RtdImageFrame.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImageFrame.tcl - itcl widget for displaying a section of an rtdimage # at a given position in a canvas window # # See man page RtdImageFrame(n) for a complete description. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 95 Created # 23 Jun 96 assume rapid frame data has separate mem area # itk::usual RtdImageFrame {} # This widget is used to display rapid frames for an RtdImage widget. A # rapid frame is an instance of a RtdImage widget that displays a small # section of the main image and can be updated faster with real-time # images because it is smaller than the main image. # # The area in the main image being used for the rapid frame is marked # with one black and one white dashed rectangle. The rapid frame can be # moved or resized in in the same way as any other graphic objects by # dragging with the left mouse button over it or on one of the 8 resize # handles displayed around it when it is selected. One of the dashed # rectangles shows the current position of the rapid frame while the # other one shows the new position and size being set. # # Two types of rapid frames are supported. The first type is an # RtdImage "view" of the main image embedded into its canvas window at a # given x,y offset, so that it appears that main image is being updated # more frequently inside the dashed box. In this case, the rapid frame # is a separate rtdimage canvas image item in the same canvas with the # main image, but at a different offset. The second type of rapid frame # is displayed in a popup window and is implemented by the class # RtdImagePopup(n). # # Creating and manipulating a rapid frame usually involves communication # with the rtdServer and camera, to tell the camera to start sending # images at the given rate from the given area. Since this is very # application specific, you can arrange to have your own Tcl command # evaluated whenever a rapid frame is created, moved, resized or # deleted. See the RtdImage(n) -rapid_frame_command option for how to do # this. # # Note that currently, only one rapid frame is allowed at a time. # Creating a second one automatically deletes the first. This may be # changed in a future release. itcl::class rtd::RtdImageFrame { inherit util::FrameWidget # constructor: create a new instance of this class constructor {args} { eval itk_initialize $args } # this method is called from the base class (FrameWidget) after all # the options have been evaluated protected method init {} { # put image in target canvas # note: create in global namespace to avoid problems in C++ side set cmd \ [list image create rtdimage \ -name "rapidFrame" \ -displaymode 1 \ -usexshm $itk_option(-usexshm) \ -usexsync $itk_option(-usexsync) \ -verbose $itk_option(-verbose) \ -subsample $itk_option(-subsample)] set image_ [uplevel "#0" $cmd] set imageId_ [$canvas_ create image $itk_option(-xoffset) $itk_option(-yoffset) \ -image $image_ \ -anchor nw \ -tags $image_] # make sure the stacking order is correct $canvas_ raise $image_ $target_image_ $canvas_ raise $itk_option(-region_id) $image_ # create a dummy rect to get events for image set rectId_ [$canvas_ create rectangle \ $itk_option(-xoffset) $itk_option(-yoffset) \ [expr {$itk_option(-xoffset)+$itk_option(-width)-1}] \ [expr {$itk_option(-yoffset)+$itk_option(-height)-1}] \ -tags imagerect \ -fill black \ -stipple pat7] # add bindings for moving and resizing the rapid frame $draw_ add_object_bindings $rectId_ $itk_option(-region_id) $target_image_ view add $image_ 1 1 set frameId_ [$image_ frameid] # setup callbacks for moving and resizing image $draw_ add_notify_cmd $itk_option(-region_id) [code $this notify_cmd] notify_cmd resize # handle interaction between zoom window and rapid frame $canvas_ bind $rectId_ "+[code $target_image_ view enter $image_]" $canvas_ bind $rectId_ "+[code $target_image_ view leave $image_]" } # return the name of the underlying rtdimage object public method get_image {} { return $image_ } # destructor - clean up when deleted destructor { $canvas_ delete $imageId_ image delete $image_ $draw_ remove_notify_cmd $itk_option(-region_id) $draw_ delete_object $rectId_ $draw_ delete_object $itk_option(-region_id) } # This method is called (from the main image's CanvasDraw(n) widget) # whenever an embedded rapid frame is moved, resized or deleted. # If the "-command" option was given to this class, then that tcl command is # evaluated with the frameId, operation name (move, resize, delete) the x, y coords # and the width and height of the frame. public method notify_cmd {op args} { if {"$op" == "delete"} { if {"$itk_option(-command)" != ""} { eval "$itk_option(-command) $frameId_ $this $op 0 0 0 0" } delete object $this return 0 } lassign [$canvas_ bbox $itk_option(-region_id)] x0 y0 x1 y1 set w [expr {$x1-$x0+1}] set h [expr {$y1-$y0+1}] $canvas_ coords $imageId_ $x0 $y0 $canvas_ coords $rectId_ $x0 $y0 $x1 $y1 # note: we assume here that the rapid frame has its own memory area # starting at 0,0 $target_image_ view update $image_ 0 0 $w $h $x0 $y0 0 0 canvas if {"$itk_option(-command)" != ""} { eval "$itk_option(-command) $frameId_ $this $op $x0 $y0 $w $h" } } # -- public vars -- # target rtdimage itk_option define -target_image target_image Target_image {} { # get internal widget names for target image set target_image_ [$itk_option(-target_image) get_image] set canvas_ [$itk_option(-target_image) get_canvas] set draw_ [$itk_option(-target_image) component draw] } # canvas id of the (region) object used to position and move the image # in the canvas itk_option define -region_id region_id Region_id {} # X offset of image frame itk_option define -xoffset xoffset Xoffset 0 # Y offset of image frame itk_option define -yoffset yoffset Yoffset 0 # Width of image frame itk_option define -width width Width 0 # Height of image frame itk_option define -height height Height 0 # tcl command to be evaluated whenever the frame is created moved, # resized or deleted: 7 args will be appended: # # frameId = unique rapid frame id for use with rtdServer # # name = unique name for the frame # # op = {move,resize or delete} # # x, y = coords of upper left corner of frame in image # # width, height = dimensions of frame. itk_option define -command command Command {} # flag: if true, pan image is "subsampled" when shrinking, # otherwise the pixels are averaged itk_option define -subsample subsample Subsample 1 # X shared memory option itk_option define -usexshm useXshm UseXshm 1 # X synchronisation option itk_option define -usexsync useXsync UseXsync 1 # flag: if true, print diagnostic messages itk_option define -verbose verbose Verbose {0} # -- protected vars -- # target internal rtdimage protected variable target_image_ # CanvasDraw object, for setting up move, resize operations on embedded image protected variable draw_ # internal rtdimage for rapid frame protected variable image_ # canvas window containing rapid frame image protected variable canvas_ # canvas image id protected variable imageId_ # canvas id of rectangle used to get events for moving/resizing image protected variable rectId_ # rapid frame Id, needed to communicate with rtdServer protected variable frameId_ } skycat-3.1.2-starlink-1b/rtd/library/RtdImageGrid.tcl000066400000000000000000000146321215713201500224060ustar00rootroot00000000000000# E.S.O. - VLT project # "@(#) $Id: RtdImageGrid.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImageGrid.tcl - itcl class to display an ra,dec grid over an image. # # See man page RtdImageGrid(n) for a complete description. # # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 24 Oct 96 Created itk::usual RtdImageGrid {} # RtdImageGrid is an itcl class to display an ra,dec grid over # the image. itcl::class rtd::RtdImageGrid { inherit util::FrameWidget # create a new object (the frame only ensures that this class # will be deleted along with its parent) constructor {args} { set canvas_ "" eval itk_initialize $args set image_ [$itk_option(-image) get_image] set canvas_ [$itk_option(-image) get_canvas] } # return ra + inc in deg protected method inc_ra {ra inc} { set ra [expr {$ra+$inc}] if {$ra >= 360} { set ra [expr {$ra-360}] } elseif {$ra < 0} { set ra [expr {360+$ra}] } return $ra } # return dec + inc in deg protected method inc_dec {dec inc} { set dec [expr {$dec+$inc}] if {$dec >= 90} { set dec [expr {180-$dec}] } elseif {$dec <= -90} { set dec [expr {-180-$dec}] } return $dec } # draw a line with the given points protected method draw_line {points} { if {[llength $points] >= 4} { if {[catch "$canvas_ create line $points -tags {grid objects}" msg]} { #puts $msg } } } # show the grid with the current settings public method show {} { if {"[$image_ wcswidth]" == ""} { warning_dialog "Can't create WCS grid, image does not support world coordinates" $w_ return } # display busy cursor over image while drawing grid $itk_option(-image) busy [code $this draw] } # draw the grid based on the current settings protected method draw {} { # get image size in arcsec set wcsw [expr {[$image_ wcswidth]*60}] set wcsh [expr {[$image_ wcsheight]*60}] # puts "wcswidth in arcsec: $wcsw, height: $wcsh" # size of grid box in arcsecs, choose default is not specified # or if specified value would generate too many lines (and be slow # to draw). set maxlines 20 set minlines 10 set size_ $itk_option(-size) if {"$size_" == ""} { set size_ 60 } while {$wcsw/$size_ > $maxlines} { set size_ [expr {$size_*2}] } while {$wcsw/$size_ < $minlines} { set size_ [expr {$size_/2}] if {"$size_" <= 0.0} { return } } # size in deg set size_deg [expr {$size_/3600.}] # get image equinox set equinox [$image_ wcsequinox] set deg_eq "deg $equinox" # start at center of image (in deg) lassign [$image_ wcscenter -format 1] ra0 dec0 # check if at north or south pole, since that is a special case if {90-abs($dec0) < $wcsh/3600} { # at pole set at_pole 1 set nx 13 set ny [expr {int($wcsh/$size_+1)}] set ra0 0 set ra_inc [expr {360./($nx-1)}] if {$dec0 < 0} { # puts "at south pole" set dec0 -90 set dec_inc $size_deg } else { # puts "at north pole" set dec0 90 set dec_inc -$size_deg } # only need to inc in one direction set ra_inc_list $ra_inc set dec_inc_list $dec_inc } else { # not at pole # get max number of ra,dec lines set nx [expr {int($wcsw/$size_+1)}] set ny [expr {int($wcsh/$size_+1)}] # round ra and dec to $size border set ra_inc $size_deg set ra_sec [expr {int($ra0*3600.)}] set ra_sec [expr {$ra_sec + ($size_ - fmod($ra_sec,$size_))}] set ra0 [expr {$ra_sec/3600.}] set dec_inc $size_deg set dec_sec [expr {int($dec0*3600.)}] set dec_sec [expr {$dec_sec + ($size_ - fmod($dec_sec,$size_))}] set dec0 [expr {$dec_sec/3600.}] # make the ra increment relative to dec0 (ra changes faster as dec nears the pole) set ra_inc [expr {$ra_inc/cos(($dec0/180.)*$pi_)}] # start in the center and inc in both directions set ra_inc_list "$ra_inc -$ra_inc" set dec_inc_list "$dec_inc -$dec_inc" } # puts "grid size_ = $size_, nx = $nx, ny = $ny, ra_inc = $ra_inc, dec_inc = $dec_inc" # draw the grid # lines along ra (start in center and extend in both directions) foreach ra_inc $ra_inc_list { foreach dec_inc $dec_inc_list { set dec $dec0 for {set i 0} {$i < $ny} {incr i} { set ra $ra0 set points {} for {set j 0} {$j < $nx} {incr j} { if {[catch {$image_ convert coords $ra $dec $deg_eq x y canvas}]} { set points [draw_line $points] } else { append points " $x $y" } set ra [inc_ra $ra $ra_inc] } set points [draw_line $points] set dec [inc_dec $dec $dec_inc] } } } # lines along dec foreach ra_inc $ra_inc_list { foreach dec_inc $dec_inc_list { set ra $ra0 for {set i 0} {$i < $nx} {incr i} { set dec $dec0 set points {} for {set j 0} {$j < $ny} {incr j} { if {[catch {$image_ convert coords $ra $dec $deg_eq x y canvas}]} { set points [draw_line $points] } else { append points " $x $y" } set dec [inc_dec $dec $dec_inc] } set points [draw_line $points] set ra [inc_ra $ra $ra_inc] } } } $canvas_ itemconfigure grid \ -fill $itk_option(-color) } # hide (stop showing) the grid public method hide {} { $canvas_ delete grid } # reset the grid (redraw it, if needed, probably for a new image) public method reset {} { hide show } # return the actual size of the grid (space between lines) in arcsecs of degrees public method size {} { return $size_ } # -- options -- # main RtdImage widget (set by caller) itk_option define -image image Image {} # grid spacing, size of a grid box in arcsecs # if not specified, a default is chosen based on the image itk_option define -size size Size {} # grid line color itk_option define -color color Color white { if {$canvas_ != ""} { $canvas_ itemconfigure grid -fill $itk_option(-color) } } # -- protected vars -- # internal rtdimage widget for main image protected variable image_ # canvas window for image protected variable canvas_ # const PI protected variable pi_ 3.14159265358979323846 # current size of grid in arc secs of deg (same as -size if specified, # otherwise it is calculated based on the size of the image) protected variable size_ 60 } skycat-3.1.2-starlink-1b/rtd/library/RtdImageHduChooser.tcl000066400000000000000000000537151215713201500235710ustar00rootroot00000000000000# E.S.O. - VLT project # "@(#) $Id: RtdImageHduChooser.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImageHduChooser.tcl - Itcl widget for displaying FITS extensions # (HDU's = Header Data Units) # # See man page RtdImageHduChooser(n) for a complete description. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 09/11/98 Created # Peter W. Draper 08/12/00 Slight corrections for missing CRPIX values. # pbiereic 14/08/01 Added default method display_fits_table() # for binary tables. # Display HDU images only on request (for # faster display of main image) # pbiereic 11/10/08 Break image display loop after failure. # pbiereic 26/11/08 Using 'view update' for HDU images display. # Using a toplevel window for the HDU images display. itk::usual RtdImageHduChooser {} # This class defines a widget for displaying the HDUs in the current FITS # image. The user can select an image extension to display # by clicking on an entry the list or on one of the small images displayed # in a table. itcl::class rtd::RtdImageHduChooser { inherit util::TopLevelWidget # constructor: create a toplevel window constructor {args} { eval itk_initialize $args wm protocol $w_ WM_DELETE_WINDOW [code $this quit] } # This method is called after the options have been evaluated. protected method init {} { wm title $w_ "FITS HDUs ($itk_option(-number))" wm iconname $w_ "FITS HDUs ($itk_option(-number))" set topf $w_.topf itk_component add topf { frame $topf } pack $itk_component(topf) -fill both -expand 1 set cmap [$image_ cmap file] set itt [$image_ itt file] set colorscale [$image_ colorscale] set settings_ "$cmap $itt $colorscale"; # save for later comparison make_buttons $topf make_table $topf show_hdu_list } # Quit this widget public method quit { } { destroy $w_ } # add a row of buttons at bottom protected method make_buttons {f} { global $w_.show set $w_.show $itk_option(-show_images) # Button frame at bottom of window itk_component add buttons { frame $f.buttons -borderwidth 2 } itk_component add open { button $itk_component(buttons).open \ -text Open \ -command [code $this set_hdu] } add_short_help $itk_component(open) \ {Open and display the selected HDU image or table} itk_component add display { button $itk_component(buttons).display \ -text "Display as one Image" \ -state disabled \ -command [code $this display_as_one_image] } add_short_help $itk_component(display) \ {Display the image extensions as a single image using the CRPIX values from the FITS header} itk_component add show { checkbutton $itk_component(buttons).show \ -text "Show HDU images" \ -variable $w_.show \ -onvalue 1 -offvalue 0 \ -borderwidth 2 \ -relief raised \ -state disabled \ -pady 4 \ -highlightthickness 0 \ -command [code $this show_images] } add_short_help $itk_component(show) \ {Show/Hide the display of the miniature versions of the image extensions} itk_component add delete { button $itk_component(buttons).delete \ -text Delete \ -state disabled \ -command [code $this delete_hdu] } add_short_help $itk_component(delete) \ {Delete the selected HDU from the FITS file} itk_component add close { button $itk_component(buttons).close \ -text Close \ -command [code $this quit] } add_short_help $itk_component(close) {Close the selected HDU} pack $itk_component(open) $itk_component(display) $itk_component(show) \ $itk_component(delete) $itk_component(close) \ -side left -expand 1 -fill x -padx 0.5m -ipadx 0.5m pack $itk_component(buttons) -side bottom -fill x -expand 0 } # Make the table component for displaying the HDU info protected method make_table {f} { set headings [$image_ hdu listheadings] # TableList(n) widget for displaying the list of HDUs itk_component add table { util::TableList $f.table \ -title {FITS HDUs} \ -headings $headings \ -width [string length $headings] } add_short_help $itk_component(table) \ {Table: Click to select HDU, double-click to display image or table} pack $itk_component(table) -side top -fill both -expand 1 set listbox [$itk_component(table) component listbox] bind $listbox [code $this select_hdu] bind $listbox [code $this set_hdu] } # Update the list of HDUs and the image displays, if needed public method show_hdu_list {} { set old_filename $filename_ set filename_ [$image_ cget -file] set hdu_list [$image_ hdu list] set headings [$image_ hdu listheadings] # update the table listing $itk_component(table) clear set h [llength $hdu_list] if { $h > 10 } { set h 10 } $itk_component(table) config -height $h -info $hdu_list # avoid endless loop due to new image commands caused by '$image_ hdu set' if { "$filename_" == "$old_filename" && ! [$image_ isclear] } { return } $itk_component(show) config -state disabled $itk_component(display) config -state disabled # cleanup first catch {destroy $itk_component(bintable)} if {"$filename_" == ""} { return } # See if there is more than one image, otherwise skip it. # If there are multiple images and they are the same size, # put them in "crpix" order also. set num_images_ 0 catch {unset ext_} set max_crpix1 [set max_crpix2 0] set naxis1 [set naxis2 0] set first_image -1 set use_crpix 1 foreach hdu $hdu_list { eval lassign [list $hdu] $headings if {"$CRPIX1" == ""} { set CRPIX1 0 } if {"$CRPIX2" == ""} { set CRPIX2 0 } if {"$Type" == "image" && "$NAXIS" >= 2 && "$NAXIS1" > 0 && "$NAXIS2" > 0} { set ext_($num_images_,HDU) $HDU set ext_($num_images_,ExtName) $ExtName set ext_($num_images_,NAXIS1) $NAXIS1 set ext_($num_images_,NAXIS2) $NAXIS2 set ext_($num_images_,CRPIX1) $CRPIX1 set ext_($num_images_,CRPIX2) $CRPIX2 if {$first_image == -1} { set first_image $HDU set max_crpix1 $CRPIX1 set max_crpix2 $CRPIX2 set naxis1 $NAXIS1 set naxis2 $NAXIS2 } else { if {$naxis1 != $NAXIS1 || $naxis2 != $NAXIS2} { # PWD: allow for slight rounding error or trim of a # small number of pixels, let's say 10. set dx [expr abs($naxis1 - $NAXIS1)] set dy [expr abs($naxis2 - $NAXIS2)] if { $dx > 10 || $dy > 10 } { set use_crpix 0 } } if {$CRPIX1 > $max_crpix1} { set max_crpix1 $CRPIX1 } if {$CRPIX2 > $max_crpix2} { set max_crpix2 $CRPIX2 } } incr num_images_ } } if {$num_images_ < 1} { return } # determine the table index for each image if {$use_crpix} { # put images in correct order based on crpix values set max_row_ 0 set max_col_ 0 for {set i 0} {$i < $num_images_} {incr i} { set crpix1 $ext_($i,CRPIX1) set crpix2 $ext_($i,CRPIX2) set naxis1 $ext_($i,NAXIS1) set naxis2 $ext_($i,NAXIS2) set row -1 set col -1 catch { set row [expr {round(($max_crpix2 - $crpix2)/$naxis2)}] set col [expr {round(($max_crpix1 - $crpix1)/$naxis1)}] } if {$row<0 || $col<0 || [info exists check($row,$col)]} { # put in sequential order set use_crpix 0 break } set check($row,$col) 1 set ext_($i,row) $row set ext_($i,col) $col set max_row_ [max $max_row_ $row] set max_col_ [max $max_col_ $col] } } if {! $use_crpix} { # different sized images: put in sequential order set num_cols 4 set num_rows [expr {$num_images_/$num_cols+$num_cols}] set max_row_ 0 set max_col_ 0 set n 0 for {set row 0} {$row < $num_rows} {incr row} { for {set col 0} {$col < $num_cols} {incr col} { if {$n == $num_images_} { break } set ext_($n,row) $row set ext_($n,col) $col incr n set max_row_ [max $max_row_ $row] set max_col_ [max $max_col_ $col] } } } # PWD: XXX commented out for now. Problem when loading cubes # as this causes the cube to load, which displays an NDF (as the # slice) that destroys this object (to make way for the NDF # chooser) before the latter lines are executed. # Select the HDU being displayed, if any #if {$first_image == -1} { # select_image_hdu [$image_ hdu] #} else { # select_image_hdu $first_image #} if { $num_images_ > 1 } { $itk_component(show) config -state normal if { $use_crpix } { $itk_component(display) config -state normal } } show_images } # Switch off the show button and remove all image minature versions protected method quit_images {} { global $w_.show set $w_.show 0 delete_images } # Remove all image minature versions protected method delete_images {} { if {! [info exists itk_component(hduimages)]} {return} save_images_geometry catch {destroy $itk_component(hduimages)} } # Save the geometry of the HDU images window so we can reload it the next time protected method save_images_geometry {} { set svgeoimg_ [wm geometry $itk_component(hduimages)] } # Show all image minature versions (called by checkbutton) protected method show_images {} { global $w_.show if { [set $w_.show] } { busy { if { ![info exists itk_component(hduimages)] || "$svinfo_" != [svinfo] } { delete_images create_images wm protocol $itk_component(hduimages) WM_DELETE_WINDOW [code $this quit_images] set svinfo_ [svinfo] } display_images } } else { delete_images } } # Put the images in the table protected method create_images {} { if { [info exists itk_component(hduimages)] } {return} catch {unset wdg_} set topw [winfo parent $w_] itk_component add hduimages { util::TopLevelWidget $topw.hduimages -transient 0 } set name "FITS HDU images: [file tail $filename_]" wm title $itk_component(hduimages) $name wm iconname $itk_component(hduimages) "FITS HDU images" # Frame (BLT table) used to display images in FITS extensions itk_component add imagetab { frame $itk_component(hduimages).imagetab } for {set i 0} {$i < $num_images_} {incr i} { set f [frame $itk_component(imagetab).f$i -borderwidth 1 -relief raised] set im [RtdImage $f.im \ -graphics 0 \ -displaymode 0 \ -usexshm 0 \ -usexsync 0 \ -fillwidth 100 \ -fillheight 100] pack $im -fill both -expand 1 -padx 1 -pady 1 # save widget names for later reference set wdg_($i,frame) $f set wdg_($i,RtdImage) $im set wdg_($i,image) [$im get_image] } itk_component add butframe { frame $itk_component(hduimages).butframe } itk_component add settings { button $itk_component(butframe).settings \ -text "Use Settings from Main Image" \ -command [code $this use_settings_from_main_image] } add_short_help $itk_component(settings) \ {Set the cut levels and colormap for the preview images to the one used in the main image} itk_component add closeimages { button $itk_component(butframe).closeimages \ -text Close \ -command [code $this quit_images] } add_short_help $itk_component(closeimages) \ {Close the HDU images display window} itk_component add autocut { button $itk_component(butframe).autocut \ -text Autocut \ -command [code $this auto_set_cut_levels] } add_short_help $itk_component(autocut) \ {Auto set cut levels individually to 99% for each HDU image} pack $itk_component(settings) $itk_component(autocut) $itk_component(closeimages) \ -fill x -expand 1 -side left -padx 0.5m -ipadx 0.5m pack $itk_component(butframe) -fill x -expand 0 -side bottom pack $itk_component(imagetab) -fill both -expand 1 -side top # save the geometry of the HDU images window whenever it is resized bind $itk_component(imagetab) [code $this save_images_geometry] if { "$svinfo_" == "[svinfo]" && ![lempty $svgeoimg_] } { wm geometry $itk_component(hduimages) $svgeoimg_ } # Uncomment the following when a transient window is required # tkwait visibility $itk_component(hduimages) # wm transient $itk_component(hduimages) $topw } # Return saved info about the HDUs private method svinfo {} { set list [array get ext_ *NAXIS*] loop i 0 [llength $list] 2 { lappend newlist "[lindex $list $i] [lindex $list [expr {$i+1}]]" } set newlist [lsort -increasing -index 0 $newlist] return $newlist } # Display the images protected method display_images {} { lassign [$image_ cut] low high for {set i 0} {$i < $num_images_} {incr i} { set width $ext_($i,NAXIS1) set height $ext_($i,NAXIS2) # '$image_ view update' is much faster than '$image_ config -file' as used by earlier versions if { [catch {$image_ view update $wdg_($i,image) $width $height image} msg] } { error_dialog "HDU $ext_($i,HDU), Extension '$ext_($i,ExtName)':\n$msg" break } add_image_bindings $wdg_($i,RtdImage) $ext_($i,HDU) $ext_($i,ExtName) $wdg_($i,image) cut $low $high } # position the images in the table catch {blt::blttable forget $itk_component(imagetab)} set hdu [$image_ hdu] set idx [expr {$hdu -1}] if { $ext_(0,HDU) == 2 } { set idx [expr {$idx -1}] } set naxis1 $ext_($idx,NAXIS1) if { $hdu > 0 && [$image_ width] != $naxis1 } { set hdu -1 } for {set i 0} {$i < $num_images_} {incr i} { set row [expr {$max_row_-$ext_($i,row)}] set col $ext_($i,col) blt::table $itk_component(imagetab) ${row},${col} $itk_component(imagetab).f$i -fill both if {"$ext_($i,HDU)" == $hdu} { $wdg_($i,frame) configure -relief sunken -bg red } } } # Set the cut levels and colormap for the image extensions to the ones # used in the main image method use_settings_from_main_image {} { # return if no image if {! [info exists wdg_(0,image)]} { return } lassign [$image_ cut] low high if { "$low" == "" || "$high" == "" || [$image_ isclear] } { return } set cmap [$image_ cmap file] set itt [$image_ itt file] set colorscale [$image_ colorscale] set setflag 0 set settings "$cmap $itt $colorscale" if { "$settings" != "$settings_" } { set settings_ $settings set setflag 1 } $itk_component(hduimages) busy { for {set i 0} {$i < $num_images_} {incr i} { if { $setflag } { $wdg_($i,image) colorscale $colorscale $wdg_($i,image) cmap file $cmap $wdg_($i,image) itt file $itt } $wdg_($i,image) cut $low $high update idletasks } } } # Set the cut levels for the image extensions to the given percent method auto_set_cut_levels {{percent 99}} { $itk_component(hduimages) busy { for {set i 0} {$i < $num_images_} {incr i} { $wdg_($i,image) autocut -percent $percent update idletasks } } } # This method is called when the user clicks on an image HDU icon. # Display the selected image and disable the delete button. protected method select_image_hdu {hdu} { $itk_component(delete) config -state disabled # display only a real image set headings [$image_ hdu listheadings] eval lassign [list [lindex [$image_ hdu list] [expr {$hdu -1}] ]] $headings if {"$Type" == "image" && "$NAXIS" < 1} { return } for {set i 0} {$i < $num_images_} {incr i} { if {[info exists wdg_($i,frame)] && [winfo exists $wdg_($i,frame)]} { if {"$ext_($i,HDU)" == "$hdu"} { $wdg_($i,frame) configure -relief sunken -bg red } else { $wdg_($i,frame) configure -relief raised -bg [$itk_component(imagetab) cget -background] } } } lassign [$image_ cut] low high busy { $image_ hdu $hdu update idletasks $image_ cut $low $high } catch {$itk_component(table) select_row [expr {$hdu-1}]} } # Add bindings to the given RtdImage itcl class object and set it to # display the given HDU when clicked on. # The image's extension name is also given. protected method add_image_bindings {im hdu name} { set image [$im get_image] set canvas [$im get_canvas] # set the HDU for the image $image hdu $hdu # need to add 2 bindings: one for the image, one for the background bind $canvas <1> [code $this select_image_hdu $hdu] # set up a resize handler to change the image size bind $canvas [code $this resize $im %w %h] # add a help message indicating which image it is set s $name if {"$s" != ""} { set s "($s)" } add_short_help $canvas "Click here to display HDU $hdu $s" } # This method is called when the image window is resized. # The RtdImage widget and the new width and height are given. protected method resize {im new_width new_height} { set image [$im get_image] $image config -fillwidth $new_width -fillheight $new_height $im center } # Set the HDU to display. Makes the currently selected HDU the current HDU protected method set_hdu {} { set sel [$itk_component(table) get_selected] if {[llength $sel]} { lassign [lindex $sel 0] hdu type name if {"$type" == "image"} { busy { select_image_hdu $hdu } } elseif {"$type" == "ascii" || "$type" == "binary"} { display_fits_table $name $hdu } } } # This method is called when a line in the HDU list is selected. # Update the states of the buttons depending on the selection. protected method select_hdu {} { set sel [$itk_component(table) get_selected] if {[llength $sel]} { lassign [lindex $sel 0] hdu type name if {"$type" == "image"} { $itk_component(delete) config -state disabled } elseif {"$type" == "ascii" || "$type" == "binary"} { $itk_component(delete) config -state normal } } } # Display all of the image extensions as a single image (combine based # on CRPIX1 and CRPIX2 keywords). protected method display_as_one_image {} { for {set i 0} {$i < $num_images_} {incr i} { if {[info exists wdg_($i,frame)] && [winfo exists $wdg_($i,frame)]} { $wdg_($i,frame) configure -relief raised \ -bg [$itk_component(imagetab) cget -background] } } busy { $image_ hdu display } } # Select an HDU to display. This makes it the current HDU protected method delete_hdu {} { set hdu [$image_ hdu] set selected_hdu [lindex [lindex [$itk_component(table) get_selected] 0] 0] set type [$image_ hdu type $selected_hdu] if {"$type" == "image"} { error_dialog "Deleting image HDUs is not allowed" return } else { append type " table" } if {! [confirm_dialog "Delete the $type at HDU $selected_hdu ?"]} { return } if {"$type" == "image"} { catch {destroy $imagetab.f.im$selected_hdu} } if {[catch {$image_ hdu delete $selected_hdu} msg]} { error_dialog $msg } set n [$image_ hdu count] if {$hdu == $selected_hdu || $n <= 0 || $hdu > $n} { $itk_option(-image) clear return } # current HDU my have moved up... $image_ hdu $hdu # update the list show_hdu_list } # Display the current FITS table. Needs to be redefined by parent class # when other tables than binary are to be displayed. protected method display_fits_table {name hdu} { set sel [$itk_component(table) get_selected] lassign [lindex $sel 0] hdu type name if {"$type" != "binary"} { return } set bintbl $w_.bintable # toggle the visibility of the binary table if { [winfo exists $bintbl] && $hdu == $hdu_bin_ } { destroy $bintbl return } if { ! [winfo exists $bintbl] } { # TableList(n) widget for displaying the binary table itk_component add bintable { util::TableList $bintbl \ -hscroll 1 } pack $itk_component(bintable) -fill both -expand 1 } set hdu_bin_ $hdu set headings [$image_ hdu headings $hdu] busy { set info [$image_ hdu get $hdu] } $itk_component(bintable) config -title $name -headings $headings -info $info } # -- options -- # target SkyCatCtrl itcl class object itk_option define -image image Image {} { set image_ [$itk_option(-image) get_image] } # flag: if true, images are "subsampled" when shrinking, # otherwise the pixels are averaged itk_option define -subsample subsample Subsample {1} # X shared memory option itk_option define -usexshm useXshm UseXshm {0} # X synchronisation option itk_option define -usexsync useXsync UseXsync {0} # flag: if true, print diagnostic messages itk_option define -verbose verbose Verbose {0} # Default: show image extensions, bool itk_option define -show_images show_images Show_images {0} # optionally specify TopLevelWidget to display short help messages itk_option define -shorthelpwin shortHelpWin ShortHelpWin {} # -- protected vars -- # internal rtdimage object protected variable image_ # name of image file protected variable filename_ {} # number of image HDUs in the current FITS file protected variable num_images_ 0 # array(HDUIndex,keyword) of image keyword protected variable ext_ # array(HDUIndex,keyword) of widget info protected variable wdg_ # max row and column protected variable max_row_ 0 protected variable max_col_ 0 # HDU number of last binary table protected variable hdu_bin_ -1 # saved info for images display protected variable svinfo_ {} protected variable svgeoimg_ {} protected variable settings_ {} } skycat-3.1.2-starlink-1b/rtd/library/RtdImageIcon.tcl000066400000000000000000000040211215713201500224000ustar00rootroot00000000000000#******************************************************************************* # E.S.O. - VLT project # # "@(#) $Id: RtdImageIcon.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImageIcon.tcl - itcl widget to display current image in icon window # # See man page RtdImageIcon(n) for a complete description. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 08 Jun 96 Created itk::usual RtdImageIcon {} # RtdImageIcon is an itcl widget used to display the current image in the # icon window. itcl::class rtd::RtdImageIcon { inherit util::TopLevelWidget # constructor: create a new instance of this class constructor {args} { eval itk_initialize $args # RtdImage widget itk_component add image { rtd::RtdImage $w_.image \ -name "IconImage" \ -scrollbars 0 \ -graphics 0 \ -drag_scroll 0 \ -displaymode 0 \ -fitwidth $itk_option(-width) \ -fitheight $itk_option(-height) \ -subsample $itk_option(-subsample) \ -verbose $itk_option(-verbose) \ -usexsync $itk_option(-usexsync) \ -usexshm $itk_option(-usexshm) \ -show_object_menu 0 } pack $itk_component(image) -side right -anchor n [$itk_option(-image) get_image] view add [$itk_component(image) get_image] 0 bind $this [code $itk_component(image) center] } # -- public vars -- # target RtdImage (itcl widget) itk_option define -image image Image {} # dimensions of pan frame itk_option define -width width Width 48 itk_option define -height height Height 48 # flag: if true, pan image is "subsampled" when shrinking, # otherwise the pixels are averaged itk_option define -subsample subsample Subsample 1 # X shared memory option itk_option define -usexshm useXshm UseXshm 1 # X synchronisation option itk_option define -usexsync useXsync UseXsync 1 # flag: if true, print diagnostic messages itk_option define -verbose verbose Verbose {0} } skycat-3.1.2-starlink-1b/rtd/library/RtdImageMBand.tcl000066400000000000000000000116751215713201500225060ustar00rootroot00000000000000# E.S.O. - VLT project # "@(#) $Id: RtdImageMBand.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImageMBand.tcl - itcl class to display a "measure band" # showing the distance between 2 points in world coordinates # # See man page RtdImagMBand(n) for a complete description. # # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 95 Created itk::usual RtdImageMBand {} # RtdImageMBand is an itcl widget class used to display a "measure band" # showing the distance between two points in world coordinates. itcl::class rtd::RtdImageMBand { inherit util::FrameWidget # create a new object (the frame only ensures that this class # will be deleted along with its parent) constructor {args} { eval itk_initialize $args set image_ [$itk_option(-image) get_image] set canvas_ [$itk_option(-image) get_canvas] bind $canvas_ <3> "+[code $this start %x %y]" } # start displaying the measure band public method start {x y} { $canvas_ delete mband if {"[$image_ wcscenter]" == ""} { return } set x_ $x set y_ $y set x [$canvas_ canvasx $x] set y [$canvas_ canvasy $y] # create diagonal line with arrows $canvas_ create line $x $y $x $y \ -width $itk_option(-line_width) \ -fill $itk_option(-line_color) \ -arrow $itk_option(-arrow_type) \ -arrowshape $itk_option(-arrow_shape) \ -tags {mband mband_line} # dashed angle line shows width and height $canvas_ create line $x $y $x $y $x $y \ -width $itk_option(-line_width) \ -fill $itk_option(-line_color) \ -stipple pat8 \ -tags {mband mband_angle} # create labels for width, height, diagonal foreach i {width height diag} { $canvas_ create rectangle $x $y [expr {$x+1}] [expr {$y+1}] \ -fill $itk_option(-fill_color) \ -outline $itk_option(-outline_color) \ -tags "mband mband_${i}_rect" $canvas_ create text $x $y \ -fill $itk_option(-text_color) \ -font $itk_option(-text_font) \ -anchor w \ -tags "mband mband_${i}_text" } # save and set cursor $canvas_ config -cursor $itk_option(-cursor) # save and set bindings set saved_bindtags_ [bindtags $canvas_] # use a unique name set tag mband$w_ bind $tag <3> [code $this stop] bind $tag [code $this check_stop %x %y] bind $tag [code $this mband %x %y 1] bind $tag { } bind $tag [code $this mband %x %y 0] bind $tag [code $this mband %x %y 0] #bind $tag [code $this mband %x %y 0] bind $tag { } # make arrow keys move mouse pointer by one pixel bind $tag "$image_ warp -1 0" bind $tag "$image_ warp 1 0" bind $tag "$image_ warp 0 -1" bind $tag "$image_ warp 0 1" bindtags $canvas_ $tag } # stop displaying the measure band and restore cursor and bindings public method stop {} { $canvas_ delete mband $canvas_ config -cursor $itk_option(-defaultcursor) bindtags $canvas_ $saved_bindtags_ } # stop displaying the mband if the user has moved the mouse since it was # created public method check_stop {x y} { if {$x != $x_ && $y != $y_} { stop } } # update the display of the measure band to show the distance # between the endpoints in WCS public method mband {x y show_angle} { $image_ mband $x_ $y_ $x $y screen $show_angle update idletasks } # -- public vars -- # main RtdImage widget (set by caller) itk_option define -image image Image {} # line width option for measure band itk_option define -line_width line_width Line_width 1 # line color option for measure band itk_option define -line_color line_color Line_color white # line arrow type option for measure band itk_option define -arrow_type arrow_type Arrow_type both # line arrow shape option for measure band itk_option define -arrow_shape arrow_shape Arrow_shape {8 10 3} # outline color for label rectangle itk_option define -outline_color outline_color Outline_color {grey90} # fill color for label rectangle itk_option define -fill_color fill_color Fill_color {yellow} # text color for label itk_option define -text_color text_color Text_color {blue} # font to use for labels itk_option define -text_font text_font Text_font TkFixedFont # default cursor when drawing itk_option define -cursor cursor Cursor {draft_small} # default cursor when not drawing itk_option define -defaultcursor defaultCursor DefaultCursor {} # -- protected vars -- # internal rtdimage widget for main image protected variable image_ # canvas window for image protected variable canvas_ # X starting point of line protected variable x_ 0 # Y starting point of line protected variable y_ 0 # saved canvas bindings, restored later protected variable saved_bindtags_ } skycat-3.1.2-starlink-1b/rtd/library/RtdImagePan.tcl000066400000000000000000000306441215713201500222400ustar00rootroot00000000000000#******************************************************************************* # E.S.O. - VLT project # # "@(#) $Id: RtdImagePan.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImagePan.tcl - itcl widget managing the RtdImage panning window # # See man page RtdImagePan(n) for a complete description. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 95 Created # Peter W. Draper 15 Feb 01 Changed notify_cmd method to deal with # very narrow images (spectra). # pbiereic 14/12/04 Fixed: Panning while image events are received # Peter W. Draper 02 Apr 05 Slight correction to logic of above. Make sure # panning changes are always seen for new images # and images with orientation changes (pan with # changed=1) # 02 Nov 06 Make the compass a fixed size of the width, not # some size that depends on the image scale. More # consistent. # pbiereic 30/03/05 Fixed: pan image width for long, narrow spectra # in method notify_cmd itk::usual RtdImagePan {} # This widget displays a "view" of another RtdImage widget at a # smaller magnification, so that the entire image is visible in # a small window. A rectangle displayed over the image can be # used to pan or move the image when the target image is to # large to be viewed at all at once in its window. The rectangle # is always notified of changes in the target image or its # window, so it always displays the relative size of the visible # image to the entire image. The pan window is based on the # rtdimage "pan" subcommand and uses canvas graphics to display # the rectangle. # # Since it is not known ahead of time how large or small an # image will be, the pan window is given a maximum size when # created. When an image is loaded, it shrinks the image by # equal integer factors until it fits in the window. Then it # fits the window around the image, so as not to leave a blank # (black) space around it. Rotated and flipped images are also # displayed as rotated and flipped in the pan window. Only the # scale factor remains fixed. itcl::class rtd::RtdImagePan { inherit util::FrameWidget # constructor: create a new RtdImagePan widget constructor {args} { itk_option add hull.borderwidth hull.relief # evaluate the options eval itk_initialize $args # RtdImage(n) widget for displaying a copy of the image itk_component add image { rtd::RtdImage $w_.image \ -name "Panner" \ -scrollbars 0 \ -drag_scroll 0 \ -displaymode 0 \ -show_object_menu 0 \ -withtoolbox 0 \ -graphics 1 \ -fitwidth $itk_option(-width) \ -fitheight $itk_option(-height) \ -subsample $itk_option(-subsample) \ -shelp $itk_option(-shelp) \ -zoomwin $itk_option(-zoomwin) \ -cursor $itk_option(-cursor) \ -verbose $itk_option(-verbose) \ -usexsync $itk_option(-usexsync) \ -usexshm $itk_option(-usexshm) \ } { keep -subsample -zoomwin -cursor -verbose rename -fitwidth -width width Width rename -fitheight -height height Height } pack $itk_component(image) -side right -fill y -anchor n set image_ [$itk_component(image) get_image] set canvas_ [$itk_component(image) get_canvas] # create a rectangle to mark previos position set marker_ [$canvas_ create rectangle 0 0 0 0 \ -outline black \ -width 2] # create the panning rectangle for resizing and positioning set panner_ [$canvas_ create rectangle 0 0 0 0 \ -outline white \ -fill black \ -stipple pat7 \ -width 1] # get name of CanvasDraw widget for image set draw_ [$itk_component(image) component draw] # don't allow resize for now (difficult to implement right) $draw_ config -show_selection_grips 0 # add bindings for moving and resizing the panning rect $draw_ add_object_bindings $panner_ # setup callbacks for moving and resizing image $draw_ add_notify_cmd $panner_ [code $this notify_cmd] # zoom in and out with mouse 2 and 3 (1 is for panning) bind $canvas_ <2> "$itk_option(-target_image) inc_zoom 1" bind $canvas_ <3> "$itk_option(-target_image) inc_zoom -1" # make this image a "view" of the target image $target_image_ view add $image_ 0 # center image on resize bind $w_ [code $itk_component(image) center] add_short_help $w_ $itk_option(-shelp) # only start panning after the image is displayed after 0 [code $this init_panning] } # Initialize the pan window after a new image has been loaded and # arrange to be notified of changes in the position and size of the # visible image. public method init_panning {} { set panImageWidth_ [$image_ dispwidth] set panImageHeight_ [$image_ dispheight] if {$panImageWidth_ == 0} { $target_image_ pan start [code $this pan] 1 return } # just center image in canvas window $itk_component(image) center # max pan factor is -1 (no shrink, -2 is 1/2 size...) set panFactor_ [lindex [$image_ scale] 0] if {"$panFactor_" == "" || $panFactor_ >= 0} { set panFactor_ -1 } $target_image_ pan start [code $this pan] $panFactor_ # set the valid area to move the panning rect $draw_ configure -bbox [$canvas_ bbox $image_] # draw a compass indicating N and E catch draw_compass } # stop the panning callback public method stop_panning {} { $target_image_ pan stop } # update the panner rectangle to display the current position and size # of the target image # x1 y1 x2 y2 give the visible portion of the image # if "changed" is 1, there is a new image with pos. different dimensions. # PWD: if changed is true always do this, includes cases when orientation # is changed (want to see the compass update). protected method pan {x1 y1 x2 y2 changed} { set scale [lindex [$image_ scale] 0] if { [info exists coords_] && ! $changed } { if { $x1 == $coords_(pan_x1) && $y1 == $coords_(pan_y1) && \ $x2 == $coords_(pan_x2) && $y2 == $coords_(pan_y2) && \ "$scale" == "$coords_(scale)" && \ $panImageHeight_ == $coords_(panImageHeight) && \ $panImageWidth_ == $coords_(panImageWidth) && $panImageWidth_ > 1 } { return } } set coords_(pan_x1) $x1 set coords_(pan_y1) $y1 set coords_(pan_x2) $x2 set coords_(pan_y2) $y2 set coords_(scale) $scale set coords_(panImageWidth) $panImageWidth_ set coords_(panImageHeight) $panImageHeight_ if {$changed} { init_panning } else { if {$x1 == 0 && $y1 == 0 && abs($x2-$panImageWidth_)<3 && abs($y2-$panImageHeight_)<3} { $itk_option(-target_image) center } $canvas_ coords $marker_ [incr x1 -2] [incr y1 -2] [incr x2 2] [incr y2 2] $canvas_ coords $panner_ $x1 $y1 $x2 $y2 } } # this method is called when the user moves or resizes the panning rect. # op is set to "resize" or "move" (resize not currently supported) # PWD: changed to deal with very narrow images (i.e. spectra). public method notify_cmd {op} { if {$panImageWidth_ == 0 && $panImageHeight_ == 0} { return } lassign [$canvas_ coords $panner_] x1 y1 x2 y2 if {"$op" == "move" } { if {$panImageWidth_ > 1} { $target_canvas_ xview moveto [expr $x1/($panImageWidth_-1)] } else { $target_canvas_ xview moveto $x1 } if { $panImageHeight_ > 1 } { $target_canvas_ yview moveto [expr $y1/($panImageHeight_-1)] } else { $target_canvas_ yview moveto $y1 } $target_image_ pan update $itk_option(-target_image) maybe_center } return 0 } # draw an ra,dec compass indicating N and E by following lines along ra and dec # near the center of the image protected method draw_compass {} { $canvas_ delete compass # get image size in arcsec if {[$image_ isclear] || "[$image_ wcswidth]" == ""} { return } set wcsw [expr {[$image_ wcswidth]*60}] set wcsh [expr {[$image_ wcsheight]*60}] # set initial size of compass to percent of the image size in arcsecs set size_ [expr {[min $wcsw $wcsh]/4}] # size in deg set size_deg [expr {$size_/3600.}] # get image equinox set equinox [$image_ wcsequinox] set deg_eq "deg $equinox" # start at center of image (in deg) lassign [$image_ wcscenter -format 1] ra0 dec0 # check if at north or south pole, since that is a special case if {90-abs($dec0) < $wcsh/3600} { # skip this if at the pole (for now) return } # get end points of compass so we can determine the directions set ra1 [expr {$ra0+$size_deg/cos(($dec0/180.)*$pi_)}] if {$ra1 < 0} { set ra1 [expr {360+$ra1}] } set dec1 [expr {$dec0+$size_deg}] if {$dec1 >= 90} { set dec1 [expr {180-$dec1}] } # end points in canvas coords $image_ convert coords $ra0 $dec0 $deg_eq cx0 cy0 canvas $image_ convert coords $ra1 $dec0 $deg_eq cx1 cy1 canvas $image_ convert coords $ra0 $dec1 $deg_eq cx2 cy2 canvas # directions set t1 [expr atan2($cy1-$cy0,$cx1-$cx0)] set t2 [expr atan2($cy2-$cy0,$cx2-$cx0)] # make sure lengths are 0.25 of the width pixels set w [expr 0.25*$itk_option(-width)] set cx1 [expr $cx0+$w*cos($t1)] set cy1 [expr $cy0+$w*sin($t1)] set cx2 [expr $cx0+$w*cos($t2)] set cy2 [expr $cy0+$w*sin($t2)] # East line $canvas_ create line $cx0 $cy0 $cx1 $cy1 \ -tags {compass objects} \ -fill white \ -arrow last # North line $canvas_ create line $cx0 $cy0 $cx2 $cy2 \ -tags {compass objects} \ -fill white \ -arrow last # factor for positioning N and E labels set f 0.25 # label "E" $canvas_ create text [expr {$cx1+($cx1-$cx0)*$f}] [expr {$cy1+($cy1-$cy0)*$f}] \ -text E \ -anchor c \ -font $compassfont_ \ -fill white \ -tags {compass objects} # label "N" $canvas_ create text [expr {$cx2+($cx2-$cx0)*$f}] [expr {$cy2+($cy2-$cy0)*$f}] \ -text N \ -anchor c \ -font $compassfont_ \ -fill white \ -tags {compass objects} } # -- public vars -- # target RtdImage (itcl widget) itk_option define -target_image target_image Target_image {} { # save name of target image and canvas window it is in set target_image_ [$itk_option(-target_image) get_image] set target_canvas_ [$itk_option(-target_image) get_canvas] } # width of pan frame itk_option define -width width Width 150 # height of pan frame itk_option define -height height Height 150 # flag: if true, pan image is "subsampled" when shrinking, # otherwise the pixels are averaged itk_option define -subsample subsample Subsample 1 # X shared memory option itk_option define -usexshm useXshm UseXshm 1 # X synchronisation option itk_option define -usexsync useXsync UseXsync 1 # flag: if true, print diagnostic messages itk_option define -verbose verbose Verbose {0} # default cursor itk_option define -cursor cursor Cursor {} # zoom window to update itk_option define -zoomwin zoomWin ZoomWin {} # help text displayed when mouse enters widget itk_option define -shelp shelp Shelp {Pan window: \ {bitmap dragb1} = position image, \ {bitmap b2} = zoom in, \ {bitmap b3} = zoom out} # -- protected vars -- # internal target image being panned (rtdimage) protected variable target_image_ # target image's canvas window protected variable target_canvas_ # panning image protected variable image_ # canvas for panning image protected variable canvas_ # name of CanvasDraw widget for image protected variable draw_ # canvas id of the panning rectangle protected variable panner_ # canvas id of a second rectangle used to mark old position protected variable marker_ # width of the panning image, after shrinking protected variable panImageWidth_ # height of the panning image, after shrinking protected variable panImageHeight_ # amount panning image was shrunk (=2 = 1/2, -4 = 1/4, ...) protected variable panFactor_ # const PI protected variable pi_ 3.14159265358979323846 # compass label fonts protected variable compassfont_ TkTooltipFont # current pan coords protected variable coords_ } skycat-3.1.2-starlink-1b/rtd/library/RtdImagePanel.tcl000066400000000000000000000435761215713201500225710ustar00rootroot00000000000000# E.S.O. - VLT project # "@(#) $Id: RtdImagePanel.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImagePanel.tcl - widget for displaying relevant image information # in tabular (blt_table) format # # # See man page RtdImagePanel(n) for a complete description. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 12 Oct 95 Created # P.Biereichel 22/03/99 Added code for bias subtraction # P.Biereichel 09/08/99 Added camera status # pbiereic 19/03/03 Always update lcut/hcut (method updateValues) # Peter W. Draper 20/07/09 Use unicode values for greek alpha and delta. # Switch to modern fonts. itk::usual RtdImagePanel {} # RtdImagePanel is a display and control panel for the RtdImageCtrl(n) widget. # It displays the following information: # # the object name, the name of the file or camera being viewed # # the x,y pixel and world coordinates and pixel value under the # mouse pointer # # the minimum and maximum image pixel values # # the image data type # # the low and high cut levels # # the scale (magnification), flip(X,Y) and rotate settings # # In addition to displaying the current image information, the cut # levels can be set by editing them and hitting return, the scale factor # can be selected from a menu and the rotation and flip X/Y settings can # be toggled with checkbuttons. itcl::class rtd::RtdImagePanel { inherit util::FrameWidget # constructor constructor {args} { itk_option add hull.borderwidth hull.relief # do this first so we can use the option values eval itk_initialize $args make_layout } # do the widget layout, aligning the items in rows and colums protected method make_layout {} { blt::blttable $w_ add_short_help $w_ {Image information area} # frame at the lower right of the panel that optionally # holds the "Auto Set Cut Levels" button, ... itk_component add lrframe { frame $w_.lrframe } # auto cut button if {$itk_option(-showcut)} { # "Auto Set Cut Levels" button itk_component add autocut { button $w_.autocut \ -text "Auto Set Cut Levels" \ -font $itk_option(-labelfont) \ -command [code $this auto_set_cut_levels] } pack $itk_component(autocut) \ -anchor ne -padx 1m -pady 1m -fill x -in $itk_component(lrframe) } # the RtdImage code sets this array for us to speed up the panel # update by using the -textvariable option set var $image_ global ::$var set row -1 # XXX should probably use blt table for labels and values here... # display object name if {$itk_option(-showobject)} { # LabelValue(n) object displaying object name or file name itk_component add object { util::LabelValue $w_.object \ -text "Object:" \ -valuefont $itk_option(-valuefont) \ -orient horizontal \ -labelfont $itk_option(-labelfont) \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -anchor e \ -relief groove } if { "$itk_option(-panel_orient)" == "vertical" } { blt::blttable $w_ $itk_component(object) [incr row],0 -fill x -anchor e } else { blt::blttable $w_ $itk_component(object) [incr row],0 -fill x -anchor e -columnspan 3 } add_short_help $itk_component(object) \ {Object name (file or camera name, if object not known)} } # X and Y if {$itk_option(-showxy)} { # LabelValue(n) widget for X image coordinate itk_component add x { util::LabelValue $w_.x \ -text "X:" \ -textvariable ${var}(X) \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -relief groove \ -anchor e } # LabelValue(n) widget for Y image coordinate itk_component add y { util::LabelValue $w_.y \ -text "Y:" \ -textvariable ${var}(Y) \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -relief groove \ -anchor e } # LabelValue(n) widget for pixel value itk_component add value { util::LabelValue $w_.value \ -text "Value:" \ -textvariable ${var}(VALUE) \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -relief groove \ -anchor e } if { "$itk_option(-panel_orient)" == "vertical" } { blt::blttable $w_ \ $itk_component(x) [incr row],0 -fill x -anchor w \ $itk_component(y) [incr row],0 -fill x -anchor w \ $itk_component(value) [incr row],0 -fill x -anchor w } else { blt::blttable $w_ \ $itk_component(x) [incr row],0 -fill x -anchor w \ $itk_component(y) $row,1 -fill x -anchor w \ $itk_component(value) $row,2 -fill x -anchor w } # workaround for bug in itcl2.0 $itk_component(x) config -textvariable ${var}(X) $itk_component(y) config -textvariable ${var}(Y) $itk_component(value) config -textvariable ${var}(VALUE) add_short_help $itk_component(x) \ {X image coordinate at mouse pointer (or X detector chip coordinate, if known)} add_short_help $itk_component(y) \ {Y image coordinate at mouse pointer (or Y detector chip coordinate, if known)} add_short_help $itk_component(value) \ {Raw image value at X,Y coordinates} } # ra and dec if {$itk_option(-showwcs)} { # LabelValue(n) widget for RA coordinate itk_component add ra { util::LabelValue $w_.ra \ -text "\u03b1:" \ -textvariable ${var}(RA) \ -labelfont $itk_option(-wcsfont) \ -valuefont $itk_option(-valuefont) \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -relief groove \ -anchor e } # LabelValue(n) widget for DEC coordinate itk_component add dec { util::LabelValue $w_.dec \ -text "\u03b4:" \ -textvariable ${var}(DEC) \ -labelfont $itk_option(-wcsfont) \ -valuefont $itk_option(-valuefont) \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -relief groove \ -anchor e } itk_component add equinox { # LabelValue(n) widget for the equinox util::LabelValue $w_.equinox \ -text "Equinox:" \ -textvariable ${var}(EQUINOX) \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -relief groove \ -anchor e } if { "$itk_option(-panel_orient)" == "vertical" } { blt::blttable $w_ \ $itk_component(ra) [incr row],0 -fill x -anchor w \ $itk_component(dec) [incr row],0 -fill x -anchor w \ $itk_component(equinox) [incr row],0 -fill x -anchor w } else { blt::blttable $w_ \ $itk_component(ra) [incr row],0 -fill x -anchor w \ $itk_component(dec) $row,1 -fill x -anchor w \ $itk_component(equinox) $row,2 -fill x -anchor w } # workaround for bug in itcl2.0 $itk_component(ra) config -textvariable ${var}(RA) $itk_component(dec) config -textvariable ${var}(DEC) $itk_component(equinox) config -textvariable ${var}(EQUINOX) add_short_help $itk_component(ra) {World Coordinates RA value} add_short_help $itk_component(dec) {World Coordinates DEC value} add_short_help $itk_component(equinox) {World Coordinates equinox (default: J2000)} } # min max values if {$itk_option(-showminmax)} { # LabelValue(n) widget for the min pixel value itk_component add min { util::LabelValue $w_.min \ -text "Min:" \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -relief groove \ -anchor e } # LabelValue(n) widget for the max pixel value itk_component add max { util::LabelValue $w_.max \ -text "Max:" \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -relief groove \ -anchor e } # LabelValue(n) widget for the FITS bitpix value itk_component add bitpix { util::LabelValue $w_.bitpix \ -text "Bitpix:" \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -relief groove \ -anchor e } if { "$itk_option(-panel_orient)" == "vertical" } { blt::blttable $w_ \ $itk_component(min) [incr row],0 -fill x -anchor w \ $itk_component(max) [incr row],0 -fill x -anchor w \ $itk_component(bitpix) [incr row],0 -fill x -anchor w } else { blt::blttable $w_ \ $itk_component(min) [incr row],0 -fill x -anchor w \ $itk_component(max) $row,1 -fill x -anchor w \ $itk_component(bitpix) $row,2 -fill x -anchor w } add_short_help $itk_component(min) {Estimated minimum raw image value} add_short_help $itk_component(max) {Estimated maximum raw image value} add_short_help $itk_component(bitpix) {Raw image FITS data type code} } # cut level controls if {$itk_option(-showcut)} { # LabelEntry(n) widget for the low cut level itk_component add low { LabelEntry $w_.low \ -text "Low:" \ -command [code $this set_cut_levels] \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -anchor e \ -relief sunken \ -validate real } { keep -state } # LabelEntry(n) widget for the high cut level itk_component add high { LabelEntry $w_.high \ -text "High:" \ -command [code $this set_cut_levels] \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -anchor e \ -relief sunken \ -validate real } { keep -state } if { "$itk_option(-panel_orient)" == "vertical" } { blt::blttable $w_ \ $itk_component(low) [incr row],0 -fill x -anchor w \ $itk_component(high) [incr row],0 -fill x -anchor w \ $itk_component(lrframe) [incr row],0 -fill x -anchor w } else { blt::blttable $w_ \ $itk_component(low) [incr row],0 -fill x -anchor w \ $itk_component(high) $row,1 -fill x -anchor w \ $itk_component(lrframe) $row,2 -fill x -anchor w } add_short_help $itk_component(low) \ {Image low cut value, type return after editing value} add_short_help $itk_component(high) \ {Image high cut value, type return after editing value} add_short_help $itk_component(autocut) \ {Set the image cut levels using median filtering} } # image transformation controls if {$itk_option(-showtrans)} { # RtdImageTrans(n) widget displaying the rotate, flip and zoom controls itk_component add trans { rtd::RtdImageTrans $w_.trans \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -labelwidth [max $itk_option(-labelwidth) 5] \ -relief flat \ -panel_orient $itk_option(-panel_orient) \ -min_scale $itk_option(-min_scale) \ -max_scale $itk_option(-max_scale) \ -image $itk_option(-image) } { keep -state } blt::blttable $w_ \ $itk_component(trans) [incr row],0 -fill x -anchor w -columnspan 2 } # canvas for real-time status display itk_component add cameraStatus { canvas $w_.status -height 0 -width 0 } if { "$itk_option(-panel_orient)" == "vertical" } { blt::blttable $w_ \ $itk_component(cameraStatus) [incr row],0 -fill both -anchor nw } else { blt::blttable $w_ \ $itk_component(cameraStatus) $row,2 -fill both -anchor nw } blt::blttable configure $w_ c2 -padx 1m } public method camSts { args } { set var $image_ global ::$var lassign [set ${var}(ATTACHED)] sts camera updateCameraStatus $camera $sts } # update camera status display public method updateCameraStatus {camera status} { if {$status == 0} { set sts Detached } else { set sts Attached } $itk_component(cameraStatus) delete cameraStatus if {"$camera" == "RTDSIMULATOR"} { return } $itk_component(cameraStatus) create text 6 3 \ -text "Camera: \t$camera\n\t$sts" \ -anchor nw -font $itk_option(-labelfont) -tags cameraStatus } # Flash a green circle for real-time image events public method flash {onoff} { if {$onoff == 1} { $itk_component(cameraStatus) create oval 25 17 35 27 -fill green -tags flash } else { $itk_component(cameraStatus) delete flash } } # set the cut levels when the user types them in and hits return protected method set_cut_levels {args} { set low [$itk_component(low) get] set high [$itk_component(high) get] if {[catch {expr {$low}} msg] || [catch {expr {$high}} msg]} { error_dialog $msg } else { $image_ cut $low $high updateValues } } # set the cut levels public method cut_level_dialog {} { if {[$image_ isclear]} { warning_dialog "No image is currently loaded" $w_ return } utilReUseWidget rtd::RtdImageCut $w_.cut \ -image $itk_option(-image) \ -shorthelpwin $itk_option(-shorthelpwin) \ -transient 1 \ -command [code $this updateValues] } # update the cut level display window, if needed public method update_cut_window {} { if {[winfo exists $w_.cut] && [winfo viewable $w_.cut]} { $w_.cut update_graph } } # update the HDU window with the latest cut levels, if needed public method update_hdu_window {} { lassign [$image_ cut] low high if {"$low" == "" || "$high" == ""} { return } set l [$itk_component(low) cget -value] set h [$itk_component(high) cget -value] if {$low != $l || $high != $h} { set w [utilNamespaceTail $itk_option(-image)].hdu if {[winfo exists $w] && [winfo viewable $w]} { $w set_cut_levels $low $high } } } # set the cut levels automatically using median filtering... public method auto_set_cut_levels {} { busy {$image_ autocut} updateValues } # update the display with the current image values public method updateValues {} { if {$itk_option(-showobject)} { set s [$image_ object] if {"$s" == ""} { set s [file tail [$image_ cget -file]] } $itk_component(object) config -value $s } if {$itk_option(-showminmax)} { $itk_component(min) config -value [$image_ min] $itk_component(max) config -value [$image_ max] $itk_component(bitpix) config -value [$image_ bitpix] } #update_hdu_window if {$itk_option(-showcut)} { # avoid conflict with user typing lassign [$image_ cut] low high $itk_component(high) config -value $high $itk_component(low) config -value $low # set f [focus] # if {"$f" != "[$itk_component(low) component entry]"} { # $itk_component(low) config -value $low # } # if {"$f" != "[$itk_component(high) component entry]"} { # $itk_component(high) config -value $high # } } update_cut_window # update the bias display window, if needed if {[winfo exists .bias]} { .bias update_cuts } if {$itk_option(-showtrans)} { $itk_component(trans) update_trans } } # -- options -- # main RtdImage widget (set by caller) itk_option define -image image Image {} { set image_ [$itk_option(-image) get_image] set var $image_ global ::$var set ${var}(ATTACHED) "0 0" trace variable ${var}(ATTACHED) w [code $this camSts] } # Flag: if true, display the object name itk_option define -showobject showObject ShowObject 1 # Flag: if true, display x,y coordinates itk_option define -showxy showXy ShowXy 1 # Flag: if true, display ra,dec coordinates itk_option define -showwcs showWcs ShowWcs 1 # Flag: if true, display the min and max pixel values itk_option define -showminmax showMinMax ShowMinMax 1 # Flag: if true, display the image cut levels. itk_option define -showcut showCut ShowCut 1 # Flag: if true, display the transformation widgets (zoom factor, etc). itk_option define -showtrans showTrans ShowTrans 1 # Font to use for labels itk_option define -labelfont labelFont LabelFont TkDefaultFont # Font to use for values. itk_option define -valuefont valueFont ValueFont TkDefaultFont # Font to use for RA,DEC (a, b) labels (symbol). itk_option define -wcsfont wcsFont WcsFont TkDefaultFont # set the width for displaying labels itk_option define -labelwidth labelWidth LabelWidth 6 # set the width for displaying values itk_option define -valuewidth valueWidth ValueWidth 10 # set the state to normal/disabled to enable/disable editing itk_option define -state state State {normal} # optionally specify TopLevelWidget to display short help messages itk_option define -shorthelpwin shortHelpWin ShortHelpWin {} # minimum allowed scale value itk_option define -min_scale min_scale Min_scale -10 # maximum allowed scale value itk_option define -max_scale max_scale Max_scale 20 # Panel orient: one of {horizontal vertical} (default: horizontal) itk_option define -panel_orient panel_orient Panel_orient {} # -- protected vars -- # internal rtdimage widget for main image protected variable image_ # saved x coordinate for update after image event protected variable x_ 0 # saved y coordinate for update after image event protected variable y_ 0 } skycat-3.1.2-starlink-1b/rtd/library/RtdImagePerf.tcl000066400000000000000000000147561215713201500224240ustar00rootroot00000000000000# E.S.O. - VLT project # # RtdImagePerf.tcl - itcl widget to show current performance statistics. # # See man page RtdImagePerf(n) for a complete description. # # who when what # -------------- --------- ---------------------------------------- # D. Hopkinson 31 Jan 97 Created # P.Biereichel 21/07/97 % display is the default + some bug fixes # P.Biereichel 01/03/01 Only % display suported + code revised itk::usual RtdImagePerf {} # RtdImagePerf is an itcl widget to show current performance statistics. itcl::class rtd::RtdImagePerf { inherit util::TopLevelWidget constructor {args} { eval itk_initialize $args wm title $w_ "Performance Test ($itk_option(-number))" wm protocol $w_ WM_DELETE_WINDOW "[code $this cancel]" make_layout } # make the window layout protected method make_layout {} { # main controls frame pack [set topf [frame $w_.topf]] -fill both -expand 1 # frame for labels pack [set labelf [frame $topf.labelf -borderwidth 2 -relief groove]] \ -fill x -expand 0 make_labels $labelf add_buttons } protected method new_field {w label txtvar txtvar2 shelp} { set var $target_image_ global ::$var util::LabelValue2 $w \ -text $label \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -valuewidth $itk_option(-valuewidth) \ -labelwidth $itk_option(-labelwidth) \ -relief groove \ -justify right \ -orient horizontal \ -shelp $shelp \ -anchor w if {[lempty $label]} { $w config -value $txtvar -value2 $txtvar2 -relief flat } else { $w config -textvariable ${var}($txtvar) $w config -textvariable2 ${var}($txtvar2) } } # make the window to display the statistics in the given frame protected method make_labels {w} { set var $target_image_ global ::$var new_field $w.actual "" "Actual" "Average" "" new_field $w.freq "Update Frequency:(Hz)" PERF_FREQ PERF_FREQ_AVE \ "Image Update Frequency (Hz)" new_field $w.gen "Processing time:\t(%)" PERF_GEN PERF_GEN_AVE \ "General Code Processing" new_field $w.tclf "Tcl code:\t\t(%)" PERF_TCL PERF_TCL_AVE \ "TCL code interpretation" new_field $w.xf "X Function calls:\t(%)" PERF_XFUNC PERF_XFUNC_AVE \ "X function calls" new_field $w.tf "Total time/image\t(msec):" PERF_TOTAL PERF_TOTAL_AVE \ "Total time spent per image event (msec)" itk_component add count { LabelValue $w.count \ -textvariable ${var}(PERF_COUNT) \ -text "Image counter:\t\t" \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -valuewidth $itk_option(-valuewidth) \ -labelwidth $itk_option(-labelwidth) \ -relief groove \ -justify right \ -anchor w } pack $itk_component(count) \ -side bottom -padx 1m -pady 0m -anchor w -fill none -expand 1 [$itk_component(count) component entry] config -justify right add_short_help $itk_component(count) "Number of image events:" } # add a row of dialog buttons at the bottom of the window protected method add_buttons {} { # dialog buttons frame itk_component add buttons { frame $w_.buttons -borderwidth 2 -relief groove } pack $itk_component(buttons) \ -side top -fill x -expand 1 -padx 1m -pady 1m foreach {btn text shelp} { \ save "Save..." "Save: save the current performance settings to file" \ attach "Attach" "Attach: attach to camera" \ reset "Reset" "Reset: start new averaging" \ cancel "Close" "Close: close the test window"} { itk_component add $btn { button $w_.$btn \ -text $text \ -command [code $this $btn] } add_short_help $itk_component($btn) $shelp pack $itk_component($btn) \ -side left -expand 1 -padx 2m -pady 2m -in $itk_component(buttons) } } # attach to camera public method attach {} { global env if {! [catch {$itk_option(-target_image) attach_camera $env(RTD_CAMERA)} msg]} { return } error_dialog $msg } # Save the current performance parameters and image information to file. public method save {} { set var $target_image_ global ::$var set genvalue [set ${var}(PERF_GEN)] set tclvalue [set ${var}(PERF_TCL)] set xvalue [set ${var}(PERF_XFUNC)] set timevalue [set ${var}(PERF_TOTAL)] # Check that there is something to save before doing anything else. if {$genvalue == "" || $tclvalue == "" || $xvalue == ""} { return } # Get the required filename to save to. set imageFile [filename_dialog [pwd] * $w_] if {$imageFile == ""} { return } set file [open $imageFile w] puts $file "Performance Statistics Output" puts $file "" puts $file "STATS: Units - percentage of total time/image event" puts $file "General processing: $genvalue" puts $file "TCL code interpretation: $tclvalue" puts $file "X function calls: $xvalue" puts $file "Total time/image event (msecs): $timevalue" puts $file "" puts $file "IMAGE INFORMATION:" puts $file "Image width: [$target_image_ width]" puts $file "Image height: [$target_image_ height]" puts $file "Bytes/pixel: [expr {abs([$target_image_ bitpix])}]" puts $file "Image size (bytes): [expr {[$target_image_ width] * \ [$target_image_ height] * abs([$target_image_ bitpix]) / 8}]" puts $file "" puts $file "DISPLAY INFORMATION:" puts $file "Unscaled height: [$target_image_ height]" puts $file "Unscaled width: [$target_image_ width]" puts $file "Scaled height: [$target_image_ dispheight]" puts $file "Scaled width: [$target_image_ dispwidth]" puts $file "Scaling (x y): [$target_image_ scale]" puts $file "Flip (X): [$target_image_ flip x]" puts $file "Flip (Y): [$target_image_ flip y]" puts $file "Rotation: [$target_image_ rotate]" close $file } public method reset {} { $target_image_ perftest reset } # close this window public method cancel {} { $target_image_ perftest off destroy $w_ } # -- options -- # target (main) RtdImage itcl widget itk_option define -target_image target_image Target_image {} { set target_image_ [$itk_option(-target_image) get_image] } # font used for labels itk_option define -labelfont labelFont LabelFont TkDefaultFont # font used for values itk_option define -valuefont valueFont ValueFont TkDefaultFont # set the width for displaying labels itk_option define -labelwidth labelWidth LabelWidth 21 # set the width for displaying values itk_option define -valuewidth valueWidth ValueWidth 8 # -- protected vars -- # internal target image protected variable target_image_ } skycat-3.1.2-starlink-1b/rtd/library/RtdImagePick.tcl000066400000000000000000000706561215713201500224170ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id: RtdImagePick.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImagePick.tcl - widget to select an object in an image using a centroid alg. # # See man page RtdImagePick(n) for a complete description. # # who when what # -------- -------- ---------------------------------------------- # Allan Brighton 25 Jun 96 Created # Peter Biereichel 01 Jul 97 modified for SOFI/ISAAC # Allan Brighton 23 Apr 98 Merged in Peter's changes, which include using # RtdImageZoomView for the image. # Fixed bug in "scale_changed" method (need to handle # width and height, not just width of image). # Added -orient option to change layout and changed # default to vertical. # Use init {} method, added "initialized_" flag. # Fixed comments for itcldoc and added public and # protected keywords to methods (for doc). # pbiereic 14/12/99 Apply transformations when a picked object is zoomed # pbiereic 04/11/03 Workaround bug in tcl 8.4.3 (SourceForge Request ID 835020) # Peter W. Draper 21/05/08 Add FWHM estimates in arcseconds. # 21/11/08 Add get_stats_ method to make access to image # statistics uniform for subclassing. itk::usual RtdImagePick {} # RtdImagePick is an itcl widget to select an object (a star, for example) in an # image and get statistics for it. It is based on the rtdimage(3) "statistics" # subcommand, which uses a centroid algorithm to locate the center of the object. itcl::class rtd::RtdImagePick { inherit util::TopLevelWidget # constructor: create a new RtdImagePick widget constructor {args} { eval itk_initialize $args } # destructor destructor { catch {cancel} catch {$target_image_ view remove $image_} } # This method is called after the options have been evaluated. protected method init {} { wm title $w_ "Pick Object ($itk_option(-number))" wm iconname $w_ "Pick Object ($itk_option(-number))" make_layout update_scale incr initialized_ wm resizable $w_ 0 0 } # This method is responsible for the window layout protected method make_layout {} { # main controls frame pack [set mainf [frame $w_.mainf]] \ -side top -fill both -expand 0 -padx 2 -pady 2 -ipadx 0 -ipady 0 pack [set topf [frame $mainf.topf]] \ -side top -fill both -expand 1 if {"$itk_option(-orient)" == "horizontal"} { make_labels $topf left make_rect $topf left } else { make_rect $topf top make_labels $topf top } add_buttons } # Create the window for displaying the statistics in the given frame. # The optional "side" arg is used for packing. protected method make_labels {w {side left}} { # frame for labels set labelf [frame $w.labelf -bd 2 -relief groove] pack $labelf -side $side -fill both -expand 1 # title for label area pack [label $labelf.title -text "Image Statistics:" ] \ -side top -pady 1m # LabelValue(n) widget: "Image X" itk_component add x { util::LabelValue $labelf.x \ -text "Image X:" \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -relief groove \ -anchor e } # LabelValue(n) widget: "Image Y" itk_component add y { util::LabelValue $labelf.y \ -text "Image Y:" \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -relief groove \ -anchor e } # LabelValue(n) widget for RA (alpha) itk_component add ra { util::LabelValue $labelf.ra \ -text "a:" \ -labelfont $itk_option(-wcsfont) \ -valuefont $itk_option(-valuefont) \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -relief groove \ -anchor e } # LabelValue(n) widget for DEC (delta) itk_component add dec { util::LabelValue $labelf.dec \ -text "d:" \ -labelfont $itk_option(-wcsfont) \ -valuefont $itk_option(-valuefont) \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -relief groove \ -anchor e } # LabelValue(n) widget for equinox itk_component add equinox { util::LabelValue $labelf.equinox \ -text "Equinox:" \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -valuewidth $itk_option(-valuewidth) \ -labelwidth $itk_option(-labelwidth) \ -relief groove \ -anchor e } # LabelValue(n) widget for "Peak object level above bg" itk_component add object { util::LabelValue $labelf.object \ -text "Peak above bg:" \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -valuewidth $itk_option(-valuewidth) \ -labelwidth $itk_option(-labelwidth) \ -relief groove \ -anchor e } # LabelValue(n) widget for "Background level" itk_component add background { util::LabelValue $labelf.background \ -text "Background level:" \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -valuewidth $itk_option(-valuewidth) \ -labelwidth $itk_option(-labelwidth) \ -relief groove \ -anchor e } # LabelValue(n) for "FWHM X:Y pixels" in pixels. itk_component add fwhm { util::LabelValue $labelf.fwhm \ -text "FWHM X:Y pixels:" \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -valuewidth $itk_option(-valuewidth) \ -labelwidth $itk_option(-labelwidth) \ -relief groove \ -anchor e } # LabelValue(n) for FHWM in "arcsecs". itk_component add fwhmarc { util::LabelValue $labelf.fwhmarc \ -text "arcsecs:" \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -valuewidth $itk_option(-valuewidth) \ -labelwidth $itk_option(-labelwidth) \ -relief groove \ -anchor e } # LabelValue(n) widget for "Angle of X axis" itk_component add angle { util::LabelValue $labelf.angle \ -text "Angle of X axis:" \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -valuewidth $itk_option(-valuewidth) \ -labelwidth $itk_option(-labelwidth) \ -relief groove \ -anchor e } # LabelValue(n) widget for number of "Pixels in x,y" itk_component add nsize { util::LabelValue $labelf.nsize \ -text "Pixels in x,y:" \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -valuewidth $itk_option(-valuewidth) \ -labelwidth $itk_option(-labelwidth) \ -relief groove \ -anchor e } foreach el {x y ra dec equinox object background fwhm angle nsize fwhmarc} { [$itk_component($el) component entry] config -justify right -highlightthickness 0 pack [$itk_component($el) component label] [$itk_component($el) component entry] \ -ipadx 0 -ipady 0 -pady 1 -padx 0 } pack \ $itk_component(x) \ $itk_component(y) \ $itk_component(ra) \ $itk_component(dec) \ $itk_component(equinox) \ $itk_component(object) \ $itk_component(background) \ $itk_component(fwhm) \ $itk_component(fwhmarc) \ $itk_component(angle) \ $itk_component(nsize) \ -side top -padx 0.0m -pady 0.0m -fill x -expand 1 add_short_help $itk_component(x) \ {X image pixel coordinate (or X detector chip coord if known)} add_short_help $itk_component(y) \ {Y Image pixel coordinate (or Y detector chip coord if known)} add_short_help $itk_component(ra) \ {World Coordinates RA value} add_short_help $itk_component(dec) \ {World Coordinates DEC value} add_short_help $itk_component(equinox) \ {World Coordinates equinox (default: J2000)} add_short_help $itk_component(object) \ {Object: peak value of object above background} add_short_help $itk_component(background) \ {Background: mean background level} add_short_help $itk_component(fwhm) \ {FWHM: full width half maximum in pixels along X and Y} add_short_help $itk_component(fwhmarc) \ {FWHM: full width half maximum in arcsecs along X and Y} add_short_help $itk_component(angle) \ {Angle: angle of major axis, degrees, along X = 0} add_short_help $itk_component(nsize) \ {Number of pixels: along x and y-axis } } # Create the window used to display the part of the image being examined. # $w is the parent frame. # The optional "side" arg is used for packing. protected method make_rect {w {side left}} { # frame for rect pack [set rectf [frame $w.rectf -bd 2 -relief groove]] \ -side $side -fill both -expand 0 # add a frame to show the size of the square selected by the scale pack [label $rectf.label -text "Area of image to be examined:" ] \ -side top -padx 0 -pady 1m set rf [frame $rectf.rf \ -bd 0 -relief flat \ -width $itk_option(-maxsize) \ -height $itk_option(-maxsize)] pack $rf -fill none -expand 1 -anchor c # This component displays the section of the image that will be used for # the centroid algorithm and statistics. itk_component add zoomView { rtd::RtdImageZoomView $rf.zoomView \ -target_image $itk_option(-target_image) \ -verbose $itk_option(-verbose) \ -width $itk_option(-maxsize) \ -height $itk_option(-maxsize) \ -factor $itk_option(-factor) \ -propagate 0 \ -usexshm 1 \ -usexsync 1 \ -borderwidth 0 \ -relief groove \ -shelp {PickImage: displays section of image being examined} } set zoomImage [$itk_component(zoomView) component image] set image_ [$zoomImage get_image] set canvas_ [$zoomImage get_canvas] catch {pack forget [$itk_component(zoomImage) component hscrollf] \ [$itk_component(zoomImage) component vscrollf]} catch {destroy [$itk_component(zoomView) component check]} global ::$itk_component(zoomView).dozoom set $itk_component(zoomView).dozoom 1 $itk_component(zoomView) inc_zoom 0 pack [$itk_component(zoomView) component larger] -expand 1 pack [$itk_component(zoomView) component smaller] -expand 1 pack $itk_component(zoomView) -anchor c -fill none -expand 0 $itk_component(zoomView) inc_zoom 0 } # add a row of dialog buttons at the bottom of the window protected method add_buttons {} { # dialog buttons frame itk_component add buttons { frame $w_.buttons -borderwidth 2 -relief groove } pack $itk_component(buttons) \ -side top -fill x -expand 1 -ipadx 2 -padx 0 -pady 0 # "Pick Object" button itk_component add pick { button $w_.pick \ -text "Pick Object" \ -padx 0.1m \ -command [code $this pick_object] } # Cancel button itk_component add cancel { button $w_.cancel \ -text "Cancel" \ -padx 0.1m \ -command [code $this cancel] } # Close button itk_component add close { button $w_.close \ -text "Close" \ -padx 0.1m \ -command [code $this close] } pack \ $itk_component(pick) \ $itk_component(cancel) \ $itk_component(close) \ -side left -fill x -expand 1 -padx 0.5m -pady 0.5m -in $itk_component(buttons) add_short_help $itk_component(pick) \ {Pick Object: {bitmap b1} = select object in image and display center and other statistics} add_short_help $itk_component(cancel) {Cancel: cancel the current pick operation} add_short_help $itk_component(close) {Close: close the pick window} } # Let the user select a point in the image and get the statistics on # the area. The optional argument "parms" may be set to {x0, y0}, the # size of the image box. If given, pick_object returns the result without # user interaction. public method pick_object {{parms ""} {wait 0}} { if {! $initialized_} { after 1000 [code $this pick_object] return } cancel set waiting_ $wait $itk_component(zoomView) config -command {} $itk_component(zoomView) enter_image $target_image_ $itk_component(zoomView) config -command [code $this scale_changed] $w_ configure -cursor cross_reverse $itk_component(pick) config -state disabled set_values {} if {"$parms" == ""} { # wait for user to click in image set list_ [pick_object_in_image] } else { lassign $parms imageX_ imageY_ n # XXX needed for bug in tcl 8.4.3 set bug "$imageX_ $imageX_" set scale [expr {double($itk_option(-maxsize)) / $n}] set scale [round $scale] lassign [$image_ scale] cscale $itk_component(zoomView) inc_zoom [expr {$scale - $cscale}] update } $itk_component(pick) config -state normal $w_ configure -cursor {} $target_image_ zoomview stop #utilRaiseWindow $w_ ; # too slow if already raised (on Linux guest) if { $waiting_ } { return } if {[llength $list_] == 12} { set_values $list_ } } # This method is called to allow the user to pick an object in the main image. # The return value is a list of: # "ra dec equinox fwhmX fwhmY angle objectPeak meanBackground fwhmXa fwhmYa" # as returned from the rtdimage "statistics" subcommand, # or an error. protected method pick_object_in_image {} { set cursor [$target_canvas_ cget -cursor] $target_canvas_ configure -cursor cross_reverse set bindtags [bindtags $target_canvas_] set tag pick$w_ bind $tag [code $this picked_object] bindtags $target_canvas_ $tag global ::$w_.picked set $w_.picked {} tkwait variable $w_.picked bindtags $target_canvas_ $bindtags $target_canvas_ configure -cursor $cursor set ret [set $w_.picked] if {"$itk_option(-command)" != ""} { eval $itk_option(-command) [list $ret] } return $ret } # this method is called when the user clicks in the image to select an object # or star for the "pick_object" method. public method picked_object {} { # display busy cursor in image and pick window... $itk_option(-target_image) busy { busy { if {[catch {set list [get_stats_]} msg]} { error_dialog $msg cancel_pick } else { picked_wcs_object $list } } } } # This method can be called when the user has selected an object # or star for the "pick_object" method. # The argument should be the value returned from the rtdimage # "statistics" subcommand public method picked_wcs_object {retval} { global ::$w_.picked set $w_.picked $retval } # return the center image coordinates of the blinking marker or # -1 if the marker is not active. If user defined coordinates # are defined then return them instead. protected method getMarkCoords {} { if {$imageX_ > 0 && $imageY_ > 0} { return "$imageX_ $imageY_" } lassign [$target_canvas_ coords $pickc_] cx cy if {"$cx" == "" || "$cy" == ""} { return -1 } $target_image_ convert coords $cx $cy canvas x y image return "$x $y" } # callback from isrtdZoomView when the scaling was changed protected method scale_changed {} { set width [set height $itk_option(-maxsize)] $image_ convert dist $width $height canvas nxsize nysize image $itk_component(nsize) config -value [format_val $nxsize] lassign [getMarkCoords] imageX imageY set_values {} cancel 0 # update the view if fwhm has been calculated if {$imageX < 1} { return } # handle transformations for updating the view set flip [expr {[$target_image_ flip X] << 1 | [$target_image_ flip Y]}] switch $flip { 0 { #; none set xc [expr {$imageX - ($nxsize/2.0)}] set yc [expr {[$image_ height] - $imageY - ($nysize/2.0)}] } 1 { #; flipY set xc [expr {$imageX - ($nxsize/2.0)}] set yc [expr {$imageY - ($nysize/2.0)}] } 2 { #; flipX set xc [expr {[$image_ width] - $imageX - ($nxsize/2.0)}] set yc [expr {[$image_ height] - $imageY - ($nysize/2.0)}] } 3 { #; flipX and flipY set xc [expr {[$image_ width] - $imageX - ($nxsize/2.0)}] set yc [expr {$imageY - ($nysize/2.0)}] } } $target_image_ view update $image_ $xc $yc $width $height 0 0 0 0 image set list_ {} if { $waiting_ } { return } $itk_option(-target_image) busy { busy { if {! [catch {set list_ [get_stats_]} msg]} { if {[llength $list_] == 12} { set_values $list_ 0 } } } } } # format a floating point value (which may also be empty) protected method format_val {val} { if {"$val" == ""} { return } return [format {%.1f} $val] } # set the values of the labels from the list (results of "pick_object" call). # If list is empty the labels are cleared. # If the list is not empty, mark the ra,dec spot in the image. protected method set_values {list {with_rmt 1}} { lassign $list x y ra dec equinox fwhmX fwhmY angle object background fwhmXa fwhmYa # create a dot which is used to mark the center pixel $target_canvas_ delete $pickc_ if {"$x" != "" && "$y" != ""} { $target_image_ convert coords $x $y image xc yc canvas $target_canvas_ create oval $xc $yc $xc $yc \ -tags "$pickc_ objects" } # display x,y in chip coords if {"$x" != "" && "$y" != ""} { $target_image_ convert coords $x $y image xc yc chip } else { set xc $x set yc $y } $itk_component(x) config -value [format_val $xc] $itk_component(y) config -value [format_val $yc] $itk_component(ra) config -value $ra $itk_component(dec) config -value $dec $itk_component(equinox) config -value $equinox $image_ convert dist 0 $itk_option(-maxsize) canvas 0 nsize image $itk_component(nsize) config -value [format_val $nsize] $itk_component(object) config -value [format_val $object] $itk_component(background) config -value [format_val $background] if {"$fwhmX" == "" || $fwhmX > 0 && $fwhmY > 0} { $itk_component(fwhm) config -value "[format_val $fwhmX] : [format_val $fwhmY]" [$itk_component(fwhm) component entry] config -foreground black $itk_component(angle) config -value [format_val $angle] } else { $itk_component(fwhm) config -value "Can't do" [$itk_component(fwhm) component entry] config -foreground red $itk_component(angle) config -value "" } if { "$fwhmXa" != {} } { $itk_component(fwhmarc) config -value "[format_val $fwhmXa] : [format_val $fwhmYa]" } else { $itk_component(fwhmarc) config -value "" } if {"$x" != "" && "$y" != ""} { set imageX_ $x set imageY_ $y } if {"$x" != "" && "$y" != "" && $fwhmX < 50 && $fwhmY < 50} { mark_spot $x $y $image_ $canvas_ $angle $fwhmX $fwhmY mark_spot $x $y $target_image_ $target_canvas_ $angle $fwhmX $fwhmY 1 if {$set_result_ && $with_rmt} { if {$x < 0 || $y < 0 || $x > [$image_ width] || $y > [$image_ height]} { set_result -1 } else { set_result "$x $y $fwhmX $fwhmY" } set set_result_ 0 } } } # set the set_result_ variable to 1 protected method set_result_value {} { set set_result_ 1 } # mark the given x,y image coordinate point in the given image/canvas with # a cross with the given width, height (image pixels) and angle (deg). protected method mark_spot {xc yc image canvas angle w h {blink 0}} { # convert to radian set rad [expr {$angle/57.2958}] # deltas for X and Y axis set dxX [expr {cos($rad) * $w/2.0}] set dyX [expr {sin($rad) * $w/2.0}] set dxY [expr {cos($rad) * $h/2.0}] set dyY [expr {sin($rad) * $h/2.0}] # compute end points for X-axis and convert them to canvas coordinates $image convert coords [expr {$xc + $dxX}] [expr {$yc + $dyX}] image x1X y1X canvas $image convert coords [expr {$xc - $dxX}] [expr {$yc - $dyX}] image x2X y2X canvas # the Y-axis is rotated "by hand" so that it appears perpendicular to the X-axis $image convert coords [expr {$xc + $dyY}] [expr {$yc - $dxY}] image x1Y y1Y canvas $image convert coords [expr {$xc - $dyY}] [expr {$yc + $dxY}] image x2Y y2Y canvas # draw X and Y axis lines with an outer thick black line # and inner thin white line set bg black set tags "mark objects" $canvas delete $tags foreach width {5 2} { $canvas create line $x1X $y1X $x2X $y2X \ -fill $bg \ -width $width \ -tags "$tags $bg" $canvas create line $x1Y $y1Y $x2Y $y2Y \ -fill $bg \ -width $width \ -tags "$tags $bg" set bg white } if {$blink} { blink_mark $canvas $tags } } # This method is used to make the marker given by "tags" blink on # and off. protected method blink_mark {canvas tags {color 0}} { catch {after cancel $afterId_} set tag [lindex $tags 0] if {"[$canvas gettags $tag]" == ""} { return } set idx1 $color set cols "black white" set col1 [lindex $cols $idx1] set idx2 [expr {! $color}] set col2 [lindex $cols $idx2] $canvas itemconfigure white -fill $col2 $canvas itemconfigure black -fill $col1 set afterId_ [after 500 [code $this blink_mark $canvas $tag $idx2]] return } # cancel the current pick operation public method cancel {{with_pick 1}} { $canvas_ delete mark $target_canvas_ delete mark $pickc_ if {$with_pick} { cancel_pick set imageX_ -1 set imageY_ -1 set waiting_ 0 } } # close this window public method close {} { cancel if {$set_result_} { set set_result_ 0 set_result -1 } after idle "wm withdraw $w_" } # this method is called when the user clicks in the image to select an object # or star for the "pick_object" method. In this case, the x,y and ra,dec position # are fixed and only the other info should be calculated (used). public method picked_special_object {x y ra dec equinox} { # display busy cursor in image and pick window... $itk_option(-target_image) busy { busy { if {[catch {set list [get_stats_]} msg]} { error_dialog $msg cancel_pick } else { lassign $list {} {} {} {} {} fwhmX fwhmY angle object background fwmhXa fwhmYa picked_wcs_object \ [list $x $y $ra $dec $equinox $fwhmX $fwhmY $angle $object $background $fwhmXa $fwhmYa] } } } } # cancel the wait for the pick_object method and reset the cursor public method cancel_pick {} { global ::$w_.picked set $w_.picked "" } # dummy (called by RtdImage.tcl which assumes that the scaling is propagated) public method update_scale {{fx 1} {fy 1}} { } # returns statistics after image event public method update_now {} { global ::$w_.picked if [$image_ isclear] { return } if {! $waiting_ } { if {"[set $w_.picked]" == ""} { return } } set waiting_ 0 if {[catch {set list [get_stats_]} msg]} { return } $canvas_ delete mark $target_canvas_ delete mark set_values $list } # return name of global variable which contains the statistics public method get_pickVar {} { return $w_.picked } # return the image statistics. protected method get_stats_ {} { return [$image_ statistics] } # -- options -- # target (main) RtdImage itcl widget itk_option define -target_image target_image Target_image {} { set img [cget -target_image] set target_image_ [$img get_image] set target_canvas_ [$img get_canvas] } # X shared memory option itk_option define -usexshm useXshm UseXshm 1 # X synchronisation option itk_option define -usexsync useXsync UseXsync 1 # flag: if true, print diagnostic messages itk_option define -verbose verbose Verbose {0} # font to use for labels itk_option define -labelfont labelFont LabelFont TkDefaultFont # font to use for values itk_option define -valuefont valueFont ValueFont TkDefaultFont # font to use for ra,dec labels (alpha, delta) itk_option define -wcsfont wcsFont WcsFont {Symbol -14} # set the width for displaying labels and values itk_option define -labelwidth labelWidth LabelWidth 16 # set the width for displaying labels and values itk_option define -valuewidth valueWidth ValueWidth 11 # set the max size of the image sample area (screen dist) itk_option define -maxsize maxSize MaxSize 200 # command to evaluate when a selection is made or canceled itk_option define -command command Command {} # debugging flag itk_option define -debug debug Debug 0 # default zoom magnification factor itk_option define -factor factor Factor {10} { set factor_ [cget -factor] } # Specify the orientation of image and panel, one of {vertical horizontal} itk_option define -orient orient Orient "vertical" # -- protected vars -- # internal target image protected variable target_image_ # internal target canvas protected variable target_canvas_ # internal canvas widget protected variable canvas_ # internal zoomView rtd image protected variable image_ protected variable set_result_ 0 # output of last statistics command after scaling and pick object command protected variable list_ # id for blink after job protected variable afterId_ # waiting for image event before returning result protected variable waiting_ 0 # set to 1 after init {} was called protected variable initialized_ 0 # requested X coordinate protected variable imageX_ -1 # requested Y coordinate protected variable imageY_ -1 # tag Id for dot in canvas protected variable pickc_ "pickc" } skycat-3.1.2-starlink-1b/rtd/library/RtdImagePick2.tcl000066400000000000000000000721401215713201500224670ustar00rootroot00000000000000#************************************************************************* # E.S.O. - VLT project/ ESO Archive # # "@(#) $Id: RtdImagePick2.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImagePick2.tcl - Pick object with a given sample size # # See the man page for a complete description. # # who when what # -------- -------- ---------------------------------------------- # pbiereic 01/07/01 created # RtdImagePick2 is used to pick an object with a given sample size which # can be changed interactively with a slider. # Two pick modes are implemented: pick object and pick cursor (that's why # it is called RtdImagePick2). # Pick object uses a centroiding algorithm for finding the object center # and displays the statistics likewise RtdImagePick does. # Pick cursor simply displays the picked x, y coordinates. # # The itk option -pickedCmd is evaluated whenever an object was picked. # It returns a tcl list with the following values: # # { x y ra dec equinox fwhmX fwhmY angle peak background } { nsamples } # # The command option -newSizeCmd is evaluated whenever the sample # size is changed. It returns the number of samples. # # The command option -newImageCmd is evaluated whenever a new image (i.e. an image with # a different type or size) is loaded and also when it is cleared. # # RtdImagePick2 uses the second zoom provided by RTD via class RtdImagePickView. # # It can co-exist with RtdImagePick, i.e. it checks the X cursor font to # determine if the click in the canvas is assigned to this widget. # # RtdImagePick2 listens to image events which are either a new image or # real-time image events. When the option -postImageEvent is true then # the statistics is updated with every new image event (which may slow down # the display rate). # # Applications (like tcscam) can inherit this class and add their own widgets. # With method 'add_my_button' one can add a control button. # The main frame components are public (i.e. the component name will not # change). They are: # # $itk_component(infof) - info frame # $itk_component(zoomf) - zoom frame # $itk_component(sliderf) - slider frame # $itk_component(choicef) - choice frame # $itk_component(buttonf) - button frame # # The frames (and all other widgets) are packed with the blt::blttable geometry # manager. The 'pack' geometry manager should not be used (see LIMITATIONS # on man page of table(BLT 2.4). # # There are options like -with_info, -with_choice which are set to 1 by default # to show all frames (see options). They can be set to 0 and the application # can re-arrange the frames (via blt::blttable) as required. # # NOTES # - In contrast to RtdImagePick, RtdImagePick2 does not use tkwait which may # cause problem for an inheriting class due to nested calls to tkwait. itk::usual RtdImagePick2 { } itcl::class rtd::RtdImagePick2 { inherit util::TopLevelWidget constructor { args } { eval itk_initialize $args } destructor { catch { close } } # init is called by the TopLevelWidget after the itk options # have been evaluated. protected method init { } { wm protocol $w_ WM_DELETE_WINDOW [code $this close] wm title $w_ "Pick Object" config -samplesize 40 ; # sample size at start if { [cget -with_menu] } { make_menu ; # Make the menu } make_layout ; # Make the window layout $itk_component(smaller) config -command [code $this inc_zoom -1] $itk_component(larger) config -command [code $this inc_zoom 1] # set canvas and widget bindings $canvas_ bind all "+[code $this picked_object]" $canvas_ bind $image_ "+[code $this config_cursor]" bind enter$w_ "+[code $this this_entered 1]" bind leave$w_ "+[code $this this_entered 0]" bindtags $w_ "enter$w_ leave$w_" wm resizable $w_ 0 0 ; # resizing is possible but makes layout worse } # Make the menu. Add menubar and menus protected method make_menu { } { add_menubar set m [add_menubutton File] add_menuitem $m command "Close" \ {Close this window} \ -command [code $this close] set m [add_menubutton View] add_menuitem $m checkbutton "Update after image events" \ {Update statistics after every new real-time image event} \ -variable $w_.postImageEvent -onvalue 1 -offvalue 0 \ -command [code $this setPostImageEvent] global ::$w_.postImageEvent set $w_.postImageEvent [cget -postImageEvent] set magMenu_ $m.mag add_menuitem $m cascade "Magnification" \ {Set the magnification factor of the zoom} \ -menu [menu $magMenu_] loop i 2 31 { $m.mag add radiobutton -label " ${i}x" \ -command [code $this scaleZoom $i] \ -variable $magMenu_ } } # Make the window layout protected method make_layout { } { if { [cget -with_menu] } { set w $w_.mainf # use same geometry manager as for the menubar pack [frame $w] -expand 1 -fill both } else { set w $w_ } if { "[cget -panel_orient]" == "horizontal" } { add_mframe $w infof make_info [cget -with_info] raised 0,0 "-fill both" add_mframe $w zoomf make_zoom 1 raised 0,1 "-fill both" add_mframe $w sliderf make_sldframe [cget -with_slider] raised 1,0 "-fill both" add_mframe $w choicef make_choice [cget -with_choice] raised 1,1 "-fill both" add_mframe $w buttonf make_buttons [cget -with_buttons] groove 2,0 \ "-columnspan 2 -fill x" } else { add_mframe $w infof make_info [cget -with_info] raised 2,0 "-fill both" add_mframe $w zoomf make_zoom 1 raised 0,0 "-fill both" add_mframe $w sliderf make_sldframe [cget -with_slider] raised 3,0 "-fill both" add_mframe $w choicef make_choice [cget -with_choice] raised 1,0 "-fill both" add_mframe $w buttonf make_buttons [cget -with_buttons] groove 4,0 "-fill x" } } # Add a frame to the main blt table of this mega widget. # Add frame component, execute the method which create the widgets # within the component and add the component to the blt table. protected method add_mframe { w compo methd map relief idx opts } { itk_component add $compo { frame $w.$compo -borderwidth 2 -relief $relief } eval $methd $itk_component($compo) if { $map } { eval blt::blttable $w $itk_component($compo) $idx $opts } } # Add short help text for a component protected method add_shelp { compo text } { add_short_help $itk_component($compo) $text } # Add a LabelValue widget to a blt table protected method add_label { w compo text idx { font labelfont } } { set wdg $w.$compo itk_component add $compo { util::LabelValue $wdg \ -text $text \ -labelfont $itk_option(-$font) \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -relief groove \ -anchor e } catch { [$wdg component entry] config -justify right -highlightthickness 0 [$wdg component label] config -pady 0 } blt::blttable $w $wdg $idx -fill x -anchor e } # Create the widgets for displaying the statistics protected method make_info { w } { set idx -1 add_label $w x "Image X:" [incr idx],0 add_label $w y "Image Y:" [incr idx],0 add_label $w ra "a:" [incr idx],0 wcsfont add_label $w dec "d:" [incr idx],0 wcsfont add_label $w equin "Equinox:" [incr idx],0 add_label $w peak "Peak above bg:" [incr idx],0 add_label $w back "Background level:" [incr idx],0 add_label $w fwhm "FWHM X:Y:" [incr idx],0 add_label $w angle "Angle of X axis:" [incr idx],0 add_label $w nsize "Pixels in x,y:" [incr idx],0 add_shelp x "X image pixel coordinate (or X detector chip coord if known)" add_shelp y "Y Image pixel coordinate (or Y detector chip coord if known)" add_shelp ra "World Coordinates RA value" add_shelp dec "World Coordinates DEC value" add_shelp equin "World Coordinates equinox (default: J2000)" add_shelp peak "Object: peak value of object above background" add_shelp back "Background: mean background level" add_shelp fwhm "FWHM: full width half maximum in X and Y" add_shelp angle "Angle: angle of major axis, degrees, along X = 0" add_shelp nsize "Number of pixels: along x and y-axis " } # Create a zoom window used to display the part of the # image to be examined. protected method make_zoom { w } { itk_component add zoomView { rtd::RtdImagePickView $w.zoomView \ -target_image $itk_option(-target_image) \ -factor $itk_option(-zoomFact) \ -command [code $this zoomScaledCb] } blt::blttable $w $itk_component(zoomView) 0,0 } # Add a button and add to blt table protected method add_button { w compo text idx command } { itk_component add $compo { button $w.$compo -text $text -command $command } blt::blttable $w $itk_component($compo) $idx -fill x } # Add an application specific button public method add_my_button { idx compo text command shelp } { set w $itk_component(buttonf) if { "[cget -panel_orient]" == "horizontal" } { # add button and redo packing set names [blt::blttable search $w -pattern *] add_button $w $compo $text 0,$idx $command set names [linsert $names $idx $itk_component($compo)] set i -1 foreach name $names { blt::blttable $w $name 0,[incr i] -fill x } } else { add_button $w $compo $text 1,$idx $command } add_shelp $compo $shelp return $itk_component($compo) } # Add control buttons protected method make_buttons { w } { set idx -1 add_button $w pick "Pick Object" 0,[incr idx] [code $this pick_object] add_button $w cancel "Cancel" 0,[incr idx] [code $this cancel 1] add_button $w close "Close" 0,[incr idx] [code $this close] add_shelp pick \ {Pick Object: {bitmap b1} = select object in image and display \ center and other statistics} add_shelp cancel {Cancel: cancel the current pick operation} add_shelp close {Close: close the pick window} } # Create the slider widget protected method make_slider { w } { itk_component add slider { util::LabelEntryScale $w.slider \ -show_arrows 1 -increment 1 -valuewidth 4 \ -text "Sample size (in image pixels):" \ -orient vertical \ -length $itk_option(-maxSsize) \ -value [cget -samplesize] \ -from $itk_option(-minSsize) \ -to $itk_option(-maxSsize) \ -validate numeric \ -scaleWidth 10 } add_shelp slider \ {Slider: set the size of the image area to examine (in image pixels)} # configure slider widget and change the layout set sldWdg $itk_component(slider) $sldWdg config -command [code $this update_rect] \ -entrycommand [code $this update_rect] [$sldWdg component label] config -justify left blt::blttable $sldWdg \ [$sldWdg component label] 0,0 -anchor w -fill x \ [$sldWdg component entry] 0,1 -anchor e \ [$sldWdg component scaleframe] 1,0 -fill x -columnspan 2 -padx 1m } # add slider widget protected method make_sldframe { w } { make_slider $w blt::blttable $w $itk_component(slider) 0,0 -anchor w -fill x } # Create pick control frame protected method make_choice { w } { # pick mode choice set rbChoice $w.rbChoice itk_component add rbChoice { util::LabelChoice $rbChoice \ -text "Select pick mode" \ -orient vertical \ -choice {"Pick Object" "Pick Cursor"} \ -variable $w_.pickMode \ -value "Pick Object" \ -anchor c \ -command [code $this set_pickmode] } # cross marker checkbutton and zoom buttons set zoomctrlf $w.zoomctrlf itk_component add zoomctrlf { frame $zoomctrlf } # button to show cross markers set var $w_.pickMark global ::$var itk_component add pickMark { checkbutton $zoomctrlf.pickMark -text "X" -variable $var \ -command [code $this toggleMarker $var] } set $var $itk_option(-showMarker) add_shelp pickMark {Show/hide cross marker when object was picked} # Zoom buttons itk_component add larger { button $zoomctrlf.larger -bitmap magnify -command [code $this inc_zoom 1] } itk_component add smaller { button $zoomctrlf.smaller -bitmap shrink -command [code $this inc_zoom -1] } add_shelp larger {Zoom larger: {bitmap b1} = increase magnification of zoom image} add_shelp smaller {Zoom smaller: {bitmap b1} = decrease magnification of zoom image} # label for scale factor itk_component add scalelab { label $zoomctrlf.label -text "" -width 3 -font $itk_option(-labelfont) } blt::blttable $zoomctrlf \ $itk_component(pickMark) 0,0 -fill y -anchor w -columnspan 3 \ $itk_component(larger) 1,0 -fill x \ $itk_component(smaller) 1,1 -fill x \ $itk_component(scalelab) 1,2 -fill x blt::blttable $w \ $itk_component(rbChoice) 0,0 -fill both \ $itk_component(zoomctrlf) 0,1 -fill both } # activate / de-activate the widget. protected method activate { bool } { if { $bool == $activated_ || ( $bool != 0 && [$image_ isclear] ) } { return } set im $itk_option(-target_image) if { $bool } { # use the "new image" callback for initialization newImageCb # expand zoom window to fill the zoom frame (minus the borderwidth) set bd 6 set width [expr {[winfo width $itk_component(zoomf)] - $bd}] set height [expr {[winfo height $itk_component(zoomf)] - $bd}] $itk_component(zoomView) change_size $width $height # activate the zoom view widget $itk_component(zoomView) activate 1 # install callbacks for new images and image events set cmd [$im cget -newimagecmd] set newImgCmd_ " ; [code $this newImageCb]" $im config -newimagecmd "$cmd$newImgCmd_" set cmd [$im cget -cameraPostCmd] set postCmd_ " ; [code $this updateImageCb]" $im config -cameraPostCmd "$cmd$postCmd_" } else { # de-activate the zoom view widget $itk_component(zoomView) activate 0 # remove callbacks for new images and image events set cmd [$im cget -newimagecmd] regsub $newImgCmd_ $cmd "" cmd $im config -newimagecmd $cmd set cmd [$im cget -cameraPostCmd] regsub $postCmd_ $cmd "" cmd $im config -cameraPostCmd $cmd } set activated_ $bool } # newImageCb is called whenever a new image (i.e. an image with # a different type or size) is loaded and also when it is cleared. protected method newImageCb { args } { if { [$image_ isclear] } { cancel if { "$itk_option(-newImageCmd)" != ""} { eval $itk_option(-newImageCmd) } return } updateMarker 0 # check that the last picked coords are within the range # of the new image. If not, use the center coords. set width [$image_ width] set height [$image_ height] # check if there was one pick if {"$pickx_" == ""} { $image_ convert coords \ [expr {$width / 2.0}] [expr {$height / 2.0}] image \ pickx_ picky_ chip } $image_ convert coords $pickx_ $picky_ chip x y image # check if center coords are in bounds if { $x > $width || $y > $height } { $image_ convert coords $x $y image pickx_ picky_ chip set_values {} } $itk_component(zoomView) moveTo $pickx_ $picky_ # check sample size set size [cget -samplesize] set maxsize [min $width $height] if { $size > $maxsize } { set size $maxsize config -samplesize $size } $itk_component(slider) config -value $size $itk_component(zoomView) config -ssize $size if { "$itk_option(-newImageCmd)" != ""} { eval $itk_option(-newImageCmd) } } # updateImageCb is called after an image event protected method updateImageCb { args } { catch { # check if the statistics of the actual image can be updated if { ! [cget -postImageEvent] || $picking_ || ! $activated_ || \ $pickMode_ == 1 || [ $image_ isclear ] } { return } if { [lempty $pickx_] } { return } set result [$itk_component(zoomView) statistics $pickx_ $picky_] $itk_component(zoomView) moveTo $pickx_ $picky_ set_values $result 1 } } # setup new center coords and sample size for method pick_object public method setup_pick { xref yref sampleSize } { update_rect $sampleSize set_values "$xref $yref" set pickx_ $xref set picky_ $yref $itk_component(zoomView) moveTo $xref $yref } # pick an object in the image and get the statistics on # the area. Currently the args list is not used. public method pick_object { args } { if { $picking_ || [$image_ isclear] } { return } # update and raise is needed for method activate raise $w_ update idletasks updateMarker 0 # prepare for event which calls method picked_object activate 1 ; # activate zoom picking 1 ; # change mode to "picking" } # picked_object is called when the user has clicked in the image # to select an object or star for the "pick_object" method. protected method picked_object { } { # return if the mouse click is not for us set cs [lindex "$cs_pick_ $cs_click_" $pickMode_] if { ! $picking_ || "$cs" != "[$canvas_ cget -cursor]" } { return } # get chip coordinates at cursor position set by the rtdimage code global ::$image_ lassign "[set ${image_}(X)] [set ${image_}(Y)]" x y picking 0 ; # stop the zoom if { [$image_ isclear] } { return } # set result according to the current pick mode if { $pickMode_ == 0 } { # get statistics $itk_option(-target_image) busy { set result [$itk_component(zoomView) statistics $x $y] } } else { # set result to the displayed x,y coords set result "$x $y" } lassign $result xc yc set pickx_ $xc set picky_ $yc # move to new center of image $itk_component(zoomView) moveTo $xc $yc raise $w_ set_values $result if { "$itk_option(-pickedCmd)" != "" } { eval $itk_option(-pickedCmd) {"[list $result [cget -samplesize]]"} } } # close this window protected method close { } { cancel 1 ; # cleanup activate 0 ; # de-activate the zoom and events wm withdraw $w_ } # set pick mode protected method set_pickmode { args } { global ::$w_.pickMode if { "[set $w_.pickMode]" == "Pick Object" } { set pickMode_ 0 } else { set pickMode_ 1 } $itk_component(pick) config -text \ [lindex [$itk_component(rbChoice) cget -choice] $pickMode_] config_cursor } # cancel pick operation public method cancel { { eval_cmd 0 } } { if { $eval_cmd } { updateMarker 0 if { "$itk_option(-cancelCmd)" != ""} { eval $itk_option(-cancelCmd) } } picking 0 } # Show image at last picked coords when mouse ptr. enters this widget. # Otherwise: switch zoom on when picking is active, else off. public method this_entered { bool } { if { ! $bool && $picking_ } { $itk_component(zoomView) zoom 1 } else { $itk_component(zoomView) zoom 0 if { [lempty $pickx_] } { return } $itk_component(zoomView) moveTo $pickx_ $picky_ } } # change cursor when mouse pointer enters or leaves the image. # This is only done when the default cursor is displayed. protected method config_cursor { } { set cursor [$canvas_ cget -cursor] set cs [lindex "$cs_pick_ $cs_click_" $pickMode_] if { $picking_ } { if { "$cursor" == "" || "$cursor" == "$cs_pick_" || \ "$cursor" == "$cs_click_"} { $canvas_ configure -cursor $cs $w_ configure -cursor $cs } } else { if { "$cursor" == "$cs_pick_" || "$cursor" == "$cs_click_"} { $canvas_ configure -cursor {} $w_ configure -cursor {} } } } # set state picking / zooming and configure the widgets protected method picking { bool } { if { $bool == $picking_ } { return } if { $bool } { $itk_component(zoomView) zoom 1 $itk_component(pick) config -state disabled } else { $itk_component(zoomView) zoom 0 $itk_component(pick) config -state normal } set picking_ $bool config_cursor } # set the values of the labels from the list (results of "pick_object" call). # If list is empty the labels are cleared. protected method set_values { list { imgEvt 0 } } { set list_ "" foreach wdg [winfo children $itk_component(infof)] { catch { $wdg config -value "" } } if { [lempty $list] } { return } set pickOk 1 lassign $list x y ra dec equin fwhmX fwhmY angle peak back $itk_component(x) config -value [format_val $x] $itk_component(y) config -value [format_val $y] $itk_component(nsize) config -value [format_val [cget -samplesize]] if { $pickMode_ == 0 } { if {"$fwhmX" == "" || $fwhmX > 0 && $fwhmY > 0} { $itk_component(ra) config -value $ra $itk_component(dec) config -value $dec $itk_component(equin) config -value $equin $itk_component(peak) config -value [format_val $peak] $itk_component(back) config -value [format_val $back] $itk_component(angle) config -value [format_val $angle] $itk_component(fwhm) config -value "[format_val $fwhmX] : [format_val $fwhmY]" set fgcol black } else { # "Can't do" was displayed by the first astronomical image processing # system in the world, named IHAP. if { ! $imgEvt } { $itk_component(fwhm) config -value "Can't do" } $itk_component(angle) config -value "" set fgcol red set pickOk 0 } [$itk_component(fwhm) component entry] config -foreground $fgcol } lappend list_ $list "$pickMode_ $pickOk" updateMarker } # update the size of the square in the zoom canvas from the slider widget. # "size" is the size of the sample image in image pixels public method update_rect { {size 0} } { # check requested size if {$size < $itk_option(-minSsize) || \ $size > $itk_option(-maxSsize) || \ $size > [min [$image_ width] [$image_ height]]} { $itk_component(slider) select ; # just select - no warning message return } config -samplesize $size $itk_component(zoomView) config -ssize $size $itk_component(zoomView) update_rect $itk_component(slider) config -value $size if { "$itk_option(-newSizeCmd)" != "" } { eval $itk_option(-newSizeCmd) $size } } # increment or decrement the zoom factor protected method inc_zoom { inc } { $itk_component(zoomView) inc_zoom $inc updateMarker } # display the scale factor of the zoom widget protected method zoomScaledCb { args } { set f [$itk_component(zoomView) get_scale] $itk_component(scalelab) config -text "${f}x" } # scale the zoom widget protected method scaleZoom { scale } { $itk_component(zoomView) set_scale $scale zoomScaledCb updateMarker } # format a floating point value (which may also be empty) protected method format_val { val } { if {"$val" == ""} { return } return [format {%.1f} $val] } # configure the -postImageEvent option protected method setPostImageEvent { args } { global ::$w_.postImageEvent config -postImageEvent [set $w_.postImageEvent] } # toggle the visibility of the blinking marker protected method toggleMarker { var } { global ::$var config -showMarker [set $var] updateMarker } # show/hide blinking marker when object was picked. In pick # cursor mode a simple cross is displayed and in pick object # mode the cross marking the fwhm values. protected method updateMarker { {show -1} } { if { [lempty $list_] && $show != 0 } { return } set zoomIm [$itk_component(zoomView) get_image] set zoomCv [$itk_component(zoomView) get_canvas] if { $show == -1 } { set show [cget -showMarker] } lassign [lindex $list_ 0] x y ra dec equinox fwhmX fwhmY angle peak background lassign [lindex $list_ 1] pickMode pickOk if { $show && $pickOk } { $image_ convert coords $x $y chip x y image if { $pickMode == 0 } { mark_spot $x $y $zoomIm $zoomCv $angle $fwhmX $fwhmY mark_spot $x $y $image_ $canvas_ $angle $fwhmX $fwhmY 1 } else { $image_ convert coords 5 5 image nx ny image mark_spot $x $y $zoomIm $zoomCv 0 $nx $ny mark_spot $x $y $image_ $canvas_ 0 $nx $ny 1 } } else { catch {$zoomCv delete mark$zoomIm} catch {$canvas_ delete mark$image_} } } # mark the x,y image coordinate point in the canvas with # a cross with the width, height (image pixels) and angle (deg). protected method mark_spot {xc yc image canvas angle w h {blink 0}} { set tags "mark$image objects" catch { $canvas delete mark$image } if { $xc > [$image width] || $yc > [$image height] || \ $xc < 1 || $yc < 1 || [catch {expr {$angle / 2.0}}] } { return } # convert angle to radian set rad [expr {$angle / 57.2958}] # deltas for X and Y axis set dxX [expr {cos($rad) * $w/2.0}] set dyX [expr {sin($rad) * $w/2.0}] set dxY [expr {cos($rad) * $h/2.0}] set dyY [expr {sin($rad) * $h/2.0}] # compute end points for X-axis and convert points to canvas coordinates $image convert coords [expr {$xc + $dxX}] [expr {$yc + $dyX}] image x1X y1X canvas $image convert coords [expr {$xc - $dxX}] [expr {$yc - $dyX}] image x2X y2X canvas # the Y-axis is rotated "by hand" so that it appears perpendicular to the X-axis $image convert coords [expr {$xc + $dyY}] [expr {$yc - $dxY}] image x1Y y1Y canvas $image convert coords [expr {$xc - $dyY}] [expr {$yc + $dxY}] image x2Y y2Y canvas # draw X and Y axis lines with an outer thick black line # and inner thin white line foreach width {3 1} bg {black white} { set opts "-fill $bg -width $width -tags {$tags $bg}" eval $canvas create line $x1X $y1X $x2X $y2X $opts eval $canvas create line $x1Y $y1Y $x2Y $y2Y $opts } if { $blink } { blink_mark $canvas $tags } } # blink a cross in the main image, showing the marker created # by method mark_spot protected method blink_mark { canvas tags { color 0 } } { catch {after cancel $afterId_} set tag [lindex $tags 0] if { "[$canvas gettags $tag]" == "" } { return } set cols "black white" if { $color } { set cols "white black" } $canvas itemconfigure white -fill [lindex $cols 0] $canvas itemconfigure black -fill [lindex $cols 1] set afterId_ [after 700 [code $this blink_mark $canvas $tag [expr {! $color}]]] } # -- options -- # target (main) RtdImage itcl widget itk_option define -target_image target_image Target_image { } { set image_ [[cget -target_image] get_image] set canvas_ [[cget -target_image] get_canvas] } # actual sample size itk_option define -samplesize sampleSize SampleSize {} # min. and max. values for slider itk_option define -minSsize minSsize MinSsize 5 itk_option define -maxSsize maxSsize MaxSsize 100 # command to evaluate when a an object was picked itk_option define -pickedCmd pickedCmd PickedCmd {} # command to evaluate when the sample size changed itk_option define -newSizeCmd newSizeCmd NewSizeCmd {} # command to evaluate after a new image itk_option define -newImageCmd newImageCmd NewImageCmd {} # command to evaluate when the pick was canceled itk_option define -cancelCmd cancelCmd CancelCmd {} # cursors to use itk_option define -pick_cursor pick_cursor Pick_cursor {target} { set cs_pick_ [cget -pick_cursor] } itk_option define -click_cursor click_cursor Click_cursor {plus} { set cs_click_ [cget -click_cursor] } # update statistics after every image event, bool itk_option define -postImageEvent postImageEvent PostImageEvent 1 # default: show marker (blinking cross) when object was picked, bool itk_option define -showMarker showMarker ShowMarker 1 # default zoom factor itk_option define -zoomFact zoomFact ZoomFact 4 # "show" options: menubar, slider, info, ... itk_option define -with_menu with_menu With_menu 0 itk_option define -with_slider with_slider With_slider 1 itk_option define -with_info with_info With_info 1 itk_option define -with_choice with_choice With_choice 1 itk_option define -with_buttons with_buttons With_buttons 1 # Specify the orientation of image and panel, one of {vertical horizontal} itk_option define -panel_orient panel_orient Panel_orient {horizontal} # fonts, widths, etc. itk_option define -labelfont labelFont LabelFont TkDefaultFont itk_option define -valuefont valueFont ValueFont TkDefaultFont itk_option define -wcsfont wcsFont WcsFont {Symbol -14} itk_option define -labelwidth labelWidth LabelWidth 15 itk_option define -valuewidth valueWidth ValueWidth 11 # -- protected vars -- protected variable image_ ;# internal target image protected variable canvas_ ;# target canvas protected variable picking_ 0 ;# user is picking object, bool protected variable pickMode_ 0 ;# pick mode (0=object, 1=cursor) protected variable afterId_ ;# id for blink after job protected variable list_ {} ;# result of last pick operation protected variable activated_ 0 ;# widget activated, bool protected variable newImgCmd_ ;# our callback for a new image cmd protected variable postCmd_ ;# our callback for a post image cmd protected variable magMenu_ ;# widget name of magnification menu protected variable cs_pick_ ;# cursor used for picking object protected variable cs_click_ ;# cursor used for clicking object protected variable pickx_ {} ;# last picked x coord protected variable picky_ {} ;# last picked y coord } skycat-3.1.2-starlink-1b/rtd/library/RtdImagePickView.tcl000066400000000000000000000232641215713201500232430ustar00rootroot00000000000000#************************************************************************* # E.S.O. - VLT project # # "@(#) $Id: RtdImagePickView.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImagePickView.tcl - itcl widget for zooming and computing statistics # # See the man page for a complete description. # # who when what # -------- -------- ---------------------------------------------- # pbiereic 01/07/01 created # # RtdImagePickView handles a zoom window which is used to display # a magnified area of the main image at mouse pointer position # (=mode zooming) and to compute the statistics on an area with a given # sample size (=mode picking). The mode is set with method update_view. # The area is surrounded by a rectangular box and can be changed # with the option -ssize. The center coords for the statistics area # are in chip coordinates. # # RtdImagePickView uses the second zoom view provided by RTD, so that the # main zoom window should not be effected. # itk::usual RtdImagePickView {} itcl::class rtd::RtdImagePickView { inherit util::FrameWidget constructor {args} { eval itk_initialize $args itk_component add image { rtd::RtdImage $w_.image \ -name ZoomWin \ -scrollbars 0 \ -graphics 0 \ -canvaswidth $cwidth_ \ -canvasheight $cheight_ \ -borderwidth 0 \ -fillwidth 0 \ -fillheight 0 \ -shelp $itk_option(-shelp) } catch {pack forget [$w_.image component hscrollf] \ [$w_.image component vscrollf]} blt::blttable $w_ \ $itk_component(image) 0,0 -fill both set image_ [$itk_component(image) get_image] set canvas_ [$itk_component(image) get_canvas] # add help text displayed when mouse enters widget add_short_help $w_ {Zoom Image: displays section of image being examined \ {bitmap b2} = zoom in, \ {bitmap b3} = zoom out} # disable configure events bind $canvas_ {} # create a box to show the area for computing the statistics # (will be resized later) $canvas_ create rectangle 0 0 1 1 -outline white -tags rect1 $canvas_ create rectangle 0 0 1 1 -outline black -tags rect2 # add canvas bindings $canvas_ bind all "+[code $this inc_zoom 1]" $canvas_ bind all "+[code $this inc_zoom -1]" } # return canvas width and height (dimensions) of the visible image protected method get_canvas_dims { } { set cw [expr {double(min($cwidth_, [$image_ width] * $factor_))}] set ch [expr {double(min($cheight_, [$image_ height] * $factor_))}] return "$cw $ch" } # center the image protected method center { } { dbg "center" lassign [get_canvas_dims] cw ch # canvas scroll region is set to twice the canvas set xscroll [expr {0.5 - 0.25 * (1.0 - $cw / $cwidth_)}] set yscroll [expr {0.5 - 0.25 * (1.0 - $ch / $cheight_)}] $canvas_ xview moveto $xscroll $canvas_ yview moveto $yscroll } # increment or decrement the zoom factor public method inc_zoom { inc } { if { ! [checkInit] } { return } dbg "inc_zoom $inc" set f $factor_ incr f $inc if {$f < 2} { set f [max 2 $factor_] } set f [min $f 50] $image_ scale $f $f config -factor $f center ; # center the image update_view ; # update the view update_rect ; # update the rectangular box if {"$itk_option(-command)" != ""} { eval $itk_option(-command) $f } } # change the size of the zoom window (in canvas coords) public method change_size { cw ch } { set cwidth_ $cw set cheight_ $ch $canvas_ config -width $cwidth_ -height $cheight_ $canvas_ config -scrollregion "-$cwidth_ -$cheight_ $cwidth_ $cheight_" center } # set the zoom factor public method set_scale { sx } { if { ! [checkInit] } { return } dbg "set_scale $sx" inc_zoom [expr {$sx - $factor_}] } # update the view of the image. If parameter $picking is 1 then # set the size of the view equal to the sample size (for computing # the statistics), else to the size of the visible image. public method update_view { { picking 0 } } { if { ! [checkInit] } { return } dbg "update_view $picking" lassign [cget -pickc] xc yc # "view update" requires offsets in canvas coords $target_image_ convert coords $xc $yc chip x0 y0 canvas # get scale factor of target image ("ti_" means "target image") $target_image_ convert dist 1 1 image ti_xs ti_ys canvas set f [expr {double($factor_)}] set iw [$image_ width] set ih [$image_ height] # compute offsets and image dimension in canvas coords: # - when picking compute coords for the sample area. # - when zooming compute coords for the zoom window. if { $picking } { # compute values for updating the view for the sample area set ssize [expr {double([cget -ssize])}] set cw [expr {$ssize * $f}] set ch [expr {$ssize * $f}] set nx $ssize set ny $ssize } else { # compute values for updating the view for the zoom image lassign [get_canvas_dims] cw ch set nx [expr {$cw / $f}] set ny [expr {$ch / $f}] } # compute offsets in target image (canvas coords) set x0 [expr {$x0 - $nx / 2.0 * $ti_xs}] set y0 [expr {$y0 - $ny / 2.0 * $ti_ys}] # update the view $target_image_ view update $image_ $x0 $y0 \ [expr {$cw * $ti_xs}] [expr {$ch * $ti_ys}] 0 0 0 0 canvas } # compute statistics on the image currently viewed public method statistics { xc yc } { if { ! [checkInit] } { return } dbg "statistics $xc $yc" config -pickc "$xc $yc" update_view 1 ; # set picking mode # compute statistics on the image currently viewed if { [catch {$image_ statistics} result] } { error_dialog $result return {} } # convert x,y to chip coords $target_image_ convert coords [lindex $result 0] [lindex $result 1] image \ xc yc chip set result [lreplace $result 0 1 $xc $yc] return $result } # move the zoom view to xc, yc public method moveTo { xc yc } { dbg "moveTo $xc $yc" config -pickc "$xc $yc" $image_ scale $factor_ $factor_ center update_view } # display a rectangular box showing the area for computing # the statistics public method update_rect { } { if { ! [checkInit] } { return } dbg "update_rect" set hsize [expr {double([cget -ssize]) / 2.0}] lassign [get_canvas_dims] cw ch set xc [expr {$cw / $factor_ / 2.0}] set yc [expr {$ch / $factor_ / 2.0}] $image_ convert dist [expr {$xc - $hsize}] [expr {$xc + $hsize}] image x0 x1 canvas $image_ convert dist [expr {$yc - $hsize}] [expr {$yc + $hsize}] image y0 y1 canvas $canvas_ coords rect1 $x0 $y0 $x1 $y1 $canvas_ coords rect2 \ [expr {$x0 - 1.1}] [expr {$y0 - 1.1}] [expr {$x1 + 1.1}] [expr {$y1 + 1.1}] } # activate / de-activate zoom public method activate { bool } { if { $bool == $activated_ } { return } dbg "activate $bool" if { $bool } { # add view without propagating the scale factor of the main image $target_image_ view add $image_ 0 } else { $target_image_ view remove $image_ } set activated_ $bool } # start / stop zoom public method zoom { bool } { if { $bool == $zooming_ } { return } dbg "zoom $bool" if { $bool } { if { ! $activated_ } { return } # start zoomview: scale 1, don't propagate scale factor, 2'nd zoom $target_image_ zoomview start $image_ 1 0 $zoomNr_ # set scale, update view and rectangular box inc_zoom 0 } else { $target_image_ zoomview stop $zoomNr_ } set zooming_ $bool } # clear zoom image public method clear { } { dbg "clear" $image_ clear ximage } # check that this widget is properly initialized. # Returns 1 for yes and 0 for no. protected method checkInit { } { lassign [cget -pickc] xc yc if { "$xc" == "" || "$yc" == "" || "[cget -ssize]" == "" || \ [$image_ isclear] } { return 0 } return 1 } # return name of the rtdimage object public method get_image { } { return $image_ } # return canvas pathname of zoom image public method get_canvas { } { return $canvas_ } # return scale factor public method get_scale { } { return $factor_ } # debug for development protected method dbg { msg } { return puts "RtdImagePickView: $msg" } # -- options -- # target (main) RtdImage itcl widget itk_option define -target_image target_image Target_image {} { set target_image_ [[cget -target_image] get_image] } # help text when mouse enters the widget itk_option define -shelp shelp Shelp {} # eval command after scale changed itk_option define -command command Command {} # default zoom magnification factor itk_option define -factor factor Factor {4} { set factor_ [cget -factor] } # sample size for computing statistics itk_option define -ssize ssize Ssize {} { set ssize [cget -ssize] if { ! [lempty $ssize] } { dbg "config -ssize [cget -ssize]" update_rect } } # picked target image coords itk_option define -pickc pickc Pickc {} # -- protected vars -- protected variable target_image_ ; # target image protected variable canvas_ ; # ZoomView's canvas protected variable image_ ; # ZoomView's canvas image tag protected variable zoomNr_ 2 ; # use the second view zoom of RtdImage protected variable cwidth_ 185 ; # default width of zoom frame protected variable cheight_ 185 ; # default height of zoom frame protected variable activated_ 0 ; # ZoomView activated, bool protected variable zooming_ 0 ; # zooming started / stopped, bool # Scale factor: we cannot rely on the scale factor of the image # since the main image propagates always the scale factor when there was # a new image. protected variable factor_ 4 ; # scale factor } skycat-3.1.2-starlink-1b/rtd/library/RtdImagePixTable.tcl000066400000000000000000000224361215713201500232320ustar00rootroot00000000000000#******************************************************************************* # E.S.O. - VLT project # # "@(#) $Id: RtdImagePixTable.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImagePixTable.tcl - itcl widget for displaying a table of pixel values # for an RtdImage widget # # See man page RtdImagePixTable(n) for a complete description. # # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 95 Created # Peter Biereichel 22/07/97 Added statistics # Peter W. Draper 24/04/03 Added high-lighting for maximum and minimums itk::usual RtdImagePixTable {} # This widget displays a variable sized table of raw image pixel # values from an RtdImage widget with the given pixel at the # center. This is meant to be bound to mouse motion events to # display pixel values as the mouse moves across the image. itcl::class rtd::RtdImagePixTable { inherit util::TopLevelWidget # constructor: create a new instance of this class constructor {args} { eval itk_initialize $args # Tk label "Pixel Table" itk_component add label { label $w_.label -text "Pixel Table" } pack $itk_component(label) -side top make_table make_buttons global ::pixtstat if {![info exists pixtstat]} { make_statistics set pixtstat 1 } elseif {$pixtstat} { make_statistics set pixtstat 1 } $image_ pixtab start $itk_option(-nrows) $itk_option(-ncols) $image_ zoom slow } # destructor destructor { $image_ pixtab stop $image_ zoom fast } # make the table of pixel values with the X,Y coords at the # top and left resp. protected method make_table {} { set var $image_ global ::$var # BLT table frame itk_component add tab { set f [frame $w_.tab] } pack $f -side top -fill both -expand 1 blt::blttable $f set ncols $itk_option(-ncols) set nrows $itk_option(-nrows) for {set col 0} {$col <= $ncols} {incr col} { set trow $nrows for {set row 0} {$row <= $nrows} {incr row} { blt::blttable $f \ [label $f.p$row,$col \ -font $itk_option(-valuefont) \ -borderwidth 1 \ -relief groove \ -width 6 \ -textvariable ${var}($row,$col)] \ $trow,$col -fill both incr trow -1 } } # use different font for X and Y values for {set row 0} {$row <= $nrows} {incr row} { $f.p$row,0 config -font $itk_option(-labelfont) -borderwidth 2 -relief raised } for {set col 0} {$col <= $ncols} {incr col} { $f.p0,$col config -font $itk_option(-labelfont) -borderwidth 2 -relief raised } # trace pixel showing maximum and minimum values trace variable ${var}(PIXTAB_MAXX) w [code $this update_max_pixel_] trace variable ${var}(PIXTAB_MAXY) w [code $this update_max_pixel_] trace variable ${var}(PIXTAB_MINX) w [code $this update_min_pixel_] trace variable ${var}(PIXTAB_MINY) w [code $this update_min_pixel_] # 0,0 unused $f.p0,0 config -relief flat -textvariable RtdPixTab(xy) set RtdPixTab(xy) {Y\X} # highlight center pixel and X,Y values set col [expr {$ncols/2+1}] set row [expr {$nrows/2+1}] $f.p$row,$col config -relief raised -foreground red $f.p0,$col config -relief raised -foreground red $f.p$row,0 config -relief raised -foreground red # standard background colour set bgcol_ [$f.p$row,$col cget -background] blank_values add_short_help $itk_component(tab) {Shows pixels around the last cursor position in the image} } # statistics on pixels protected method make_statistics {} { set var $image_ global ::$var set ncols $itk_option(-ncols) set nrows $itk_option(-nrows) # Tk label "Statistics" itk_component add slabel { label $w_.slabel -text "Statistics" } pack $itk_component(slabel) -side top -before $itk_component(buttons) # statistics Tk frame itk_component add stat { set sf [frame $w_.stat -relief raised -borderwidth 1] } pack $sf -side top -fill both -expand 1 -before $itk_component(buttons) set col 0 set row 1 foreach el {Min Max Ave RMS N} { set lel [string tolower $el] # LabelValue(n) widgets: pixtab_Min, pixtab_Max, pixtab_Ave, # pixtab_RMS, pixtab_N itk_component add pixtab_$lel { util::LabelValue $sf.$lel \ -text "$el:" \ -textvariable ${var}(PIXTAB_[string toupper $el]) \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -labelwidth $itk_option(-labelwidth) \ -valuewidth $itk_option(-valuewidth) \ -relief groove \ -anchor w} blt::blttable $sf $itk_component(pixtab_$lel) \ $row,$col -fill both incr col if {$col >= $ncols} { set col 0 incr row } } # Max and min match highlight colours as visual clue $itk_component(pixtab_max) configure \ -foreground $itk_option(-maxhighlight) $itk_component(pixtab_min) configure \ -foreground $itk_option(-minhighlight) add_short_help $itk_component(pixtab_min) {Min: Shows the min value of the pixel table} add_short_help $itk_component(pixtab_max) {Min: Shows the max value of the pixel table} add_short_help $itk_component(pixtab_ave) {Min: Shows the average value of the pixel table} add_short_help $itk_component(pixtab_rms) {Min: Shows the RMS value of the pixel table} add_short_help $itk_component(pixtab_n) {N: Shows the number of pixels in the pixel table} } # set the background of one of the tabel cells protected method set_cell_bg_colour_ {x y colour} { catch { $itk_component(tab).p${x},${y} configure -background $colour } } # update the cell coloured to show that it has the maximum value protected method update_max_pixel_ { args } { set var $image_ global ::$var set_cell_bg_colour_ $maxx_ $maxy_ $bgcol_ set maxx_ [set ${var}(PIXTAB_MAXX)] set maxy_ [set ${var}(PIXTAB_MAXY)] set_cell_bg_colour_ $maxx_ $maxy_ $itk_option(-maxhighlight) } # update the cell coloured to show that it has the minimum value protected method update_min_pixel_ { args } { set var $image_ global ::$var set_cell_bg_colour_ $minx_ $miny_ $bgcol_ set minx_ [set ${var}(PIXTAB_MINX)] set miny_ [set ${var}(PIXTAB_MINY)] set_cell_bg_colour_ $minx_ $miny_ $itk_option(-minhighlight) } # make the button frame at the bottom of the window protected method make_buttons {} { # button frame itk_component add buttons { frame $w_.buttons -borderwidth 0 -relief flat} pack $itk_component(buttons) -side top -fill none -expand 0 pack \ [button $w_.close \ -text "Close" \ -command [code delete object $this]] \ -padx 2m -pady 2m -side right -in $w_.buttons global ::pixtstat pack \ [checkbutton $w_.statistics \ -text "Statistics" \ -variable pixtstat \ -anchor w \ -font $itk_option(-labelfont) \ -command [code $this statistics]] \ -padx 2m -pady 2m -side left -in $w_.buttons add_short_help $w_.close {Close: {bitmap b1} = Close this window} add_short_help $w_.statistics {Statistics: {bitmap b1} = Switch statistics info on/off} } # method to switch statistics window on/off public method statistics {} { global ::pixtstat if {$making_stat_} { if {[winfo exists $itk_component(stat)]} { set pixtstat 1 } else { set pixtstat 0 } return } set making_stat_ 1 if {$pixtstat} { blank_values catch {make_statistics} update idletasks } else { catch { destroy $itk_component(slabel) destroy $itk_component(stat) } } set making_stat_ 0 } # method to blank out all pixel values public method blank_values {} { set var $image_ global ::$var set ncols $itk_option(-ncols) set nrows $itk_option(-nrows) for {set col 0} {$col <= $ncols} {incr col} { for {set row 0} {$row <= $nrows} {incr row} { set ${var}($row,$col) "" } } } # -- public vars -- # caller's RtdImage itcl object itk_option define -image image Image {} { # get internal image object and canvas set image_ [$itk_option(-image) get_image] set canvas_ [$itk_option(-image) get_canvas] } # number of rows/columns of pixels to display itk_option define -nrows nrows Nrows 3 itk_option define -ncols ncols Ncols 3 # fonts used itk_option define -labelfont labelFont LabelFont TkDefaultFont itk_option define -valuefont valueFont ValueFont TkDefaultFont # set the width for displaying labels and values itk_option define -labelwidth labelWidth LabelWidth 4 itk_option define -valuewidth valueWidth ValueWidth 8 # maximum and minimum highlight colours itk_option define -maxhighlight maxhighlight MaxHighlight lightblue itk_option define -minhighlight minhighlight MinHighlight lightgreen # -- protected vars -- # internal rtdimage object protected variable image_ # canvas for image protected variable canvas_ # flag for "making statistics widget" protected variable making_stat_ 0 # indices of last cells to hold the maximum and minimum colours protected variable maxx_ 1 protected variable maxy_ 1 protected variable minx_ 1 protected variable miny_ 1 # background colour of a cell that isn't highlighted protected variable bgcol_ lightgrey } skycat-3.1.2-starlink-1b/rtd/library/RtdImagePopup.tcl000066400000000000000000000261441215713201500226250ustar00rootroot00000000000000#******************************************************************************* # E.S.O. - VLT project # # "@(#) $Id: RtdImagePopup.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImagePopup.tcl - A toplevel widget for displaying rapid frames for RtdImage # # See man page RtdImagePopup(n) for a complete description. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 13 Mar 96 Created # 23 Jun 96 assume rapid frame data has separate mem area # starting at 0,0 itk::usual RtdImagePopup {} # This widget is used to display rapid frames in a popup window for an # RtdImage widget. A rapid frame is an instance of a RtdImage widget # that displays a small section of the main image and can be updated # faster with real-time images because it is smaller than the main # image. # # The area in the main image being used for the rapid frame is marked # with one black and one white dashed rectangle. The rapid frame can be # moved or resized in in the same way as any other graphic objects by # dragging with the left mouse button over it or on one of the 8 resize # handles displayed around it when it is selected. One of the dashed # rectangles shows the current position of the rapid frame while the # other one shows the new position and size being set. # # Creating and manipulating a rapid frame usually involves communication # with the rtdServer and camera, to tell the camera to start sending # images at the given rate from the given area. Since this is very # application specific, you can arrange to have your own Tcl command # evaluated whenever a rapid frame is created, moved, resized or # deleted. See the RtdImage(n) -rapid_frame_command option for how to do # this. # # Note that currently, only one rapid frame is allowed at a time. # Creating a second one automatically deletes the first. This may # be changed in a future release. itcl::class rtd::RtdImagePopup { inherit util::TopLevelWidget # constructor: create a new instance of this class constructor {args} { eval itk_initialize $args } # add bindings and callbacks after the constructor was called protected method init {} { wm title $w_ "Rapid Frame ($itk_option(-number))" wm iconname $w_ Rapid # RtdImage(n) widget to display in a popup window itk_component add image { rtd::RtdImage $w_.image \ -name "RapidFrame" \ -canvasheight $itk_option(-height) \ -displaymode 1 \ -graphics 0 \ -drag_scroll 0 \ -zoomwin $itk_option(-zoomwin) \ -usexshm $itk_option(-usexshm) \ -verbose $itk_option(-verbose) \ -subsample $itk_option(-subsample) \ -scrollbars 1 \ -newimagecmd [code $this new_image_cmd] } set canvas_ [$itk_component(image) get_canvas] set image_ [$itk_component(image) get_image] add_menubar make_panel pack $itk_component(image) -fill both -expand 1 # create a dummy rect to get events for image set rectId_ [$target_canvas_ create rectangle \ $itk_option(-xoffset) $itk_option(-yoffset) \ [expr {$itk_option(-xoffset)+$itk_option(-width)-1}] \ [expr {$itk_option(-yoffset)+$itk_option(-height)-1}] \ -tags imagerect \ -fill black \ -stipple pat7] # set help text displayed when mouse enters widget add_short_help $canvas_ $itk_option(-shelp) $target_image_ view add $image_ 0 1 set frameId_ [$image_ frameid] # RtdImageMBand(n) widget: # The "measure band" is displayed while the right mouse button # is pressed to show the distance between points. itk_component add mband { rtd::RtdImageMBand $w_.mband -image $itk_component(image) } bind $w_ [code $itk_component(image) center] # handle interaction between zoom window and rapid frame $canvas_ bind [$itk_component(image) get_imageId] \ "+[code $target_image_ view enter $image_]" $canvas_ bind [$itk_component(image) get_imageId] \ "+[code $target_image_ view leave $image_]" notify_cmd resize # add bindings for moving and resizing the rapid frame $draw_ add_object_bindings $rectId_ $itk_option(-region_id) # setup callbacks for moving and resizing image $draw_ add_notify_cmd $itk_option(-region_id) [code $this notify_cmd] } # destructor - clean up when deleted destructor { $draw_ remove_notify_cmd $itk_option(-region_id) $draw_ delete_object $rectId_ $draw_ delete_object $itk_option(-region_id) } # return the name of the underlying rtdimage object public method get_image {} { return $image_ } # add the menubar at the top of the window protected method add_menubar {} { # menu bar TopLevelWidget::add_menubar set image $itk_component(image) # File menu set m [add_menubutton File] add_menuitem $m command "Save as..." \ {Save the current image to a (FITS) file} \ -command [code $image save_as] add_menuitem $m command "Print..." \ {Print the current image to a file or printer} \ -command [code $image print] #add_menuitem $m command Clear \ # {Clear the image display} \ # -command [code $image clear] add_menuitem $m command "Close" \ {Close the window} \ -command "destroy $w_" add_short_help $itk_component(menubar).file \ {File menu: save, clear, print image, close window} # View menu set m [add_menubutton View] add_menuitem $m command "Cut Levels..." \ {Display a window for manipulating the image cut levels} \ -command [code $w_.info cut_level_dialog] add_short_help $itk_component(menubar).view \ {View menu: manipulate image cut levels} } # make the upper panel protected method make_panel {} { # RtdImagePanel(n) widget, control panel itk_component add info { rtd::RtdImagePanel $w_.info \ -image $itk_component(image) \ -showobject 0 \ -showxy 0 \ -showwcs 0 \ -showminmax 0 \ -shorthelpwin $itk_option(-shorthelpwin) \ -state normal \ -min_scale $itk_option(-min_scale) \ -max_scale $itk_option(-max_scale) \ -borderwidth 3 -relief groove } pack $itk_component(info) \ -side top -fill x } # set the cut levels public method set_cut_levels {} { if {[$image_ isclear]} { warning_dialog "No image is currently loaded" $w_ return } utilReUseWidget rtd::RtdImageCut $w_.cut \ -image $this \ -transient 1 \ -command "$itk_component(info) updateValues" } # this method is called by the image code whenever a new image is loaded # (for updates, see camera command) protected method new_image_cmd {} { $itk_component(info) updateValues } # This method is called (from the main image's CanvasDraw(n) # widget) whenever an embedded rapid frame is moved, resized # or deleted. # If the "-command" option was given to this class, then that tcl command is # evaluated with the frameId, operation name (move, resize, delete) the x, y coords # and the width and height of the frame. public method notify_cmd {op args} { if {"$op" == "delete"} { if {"$itk_option(-command)" != ""} { eval "$itk_option(-command) $frameId_ $this $op 0 0 0 0" } delete object $this return 0 } elseif {"$op" == "flip"} { eval $itk_component(image) flip $args $itk_component(info) component trans update_trans } elseif {"$op" == "rotate"} { eval $itk_component(image) rotate $args $itk_component(info) component trans update_trans after idle [code $itk_component(image) center] } elseif {"$op" == "resize" || "$op" == "move"} { lassign [$target_canvas_ bbox $itk_option(-region_id)] x0 y0 x1 y1 set w [expr {$x1-$x0+1}] set h [expr {$y1-$y0+1}] $target_canvas_ coords $rectId_ $x0 $y0 $x1 $y1 # note: we assume here that the rapid frame has its own memory area # starting at 0,0 $target_image_ view update $image_ 0 0 $w $h 0 0 $x0 $y0 canvas if {"$itk_option(-command)" != ""} { eval "$itk_option(-command) $frameId_ $this $op $x0 $y0 $w $h" } } after idle [code $itk_component(image) center] } # -- public vars -- # target rtdimage itk_option define -target_image target_image Target_image {} { # get internal widget names for target image set target_image_ [$itk_option(-target_image) get_image] set target_canvas_ [$itk_option(-target_image) get_canvas] set draw_ [$itk_option(-target_image) component draw] } # canvas id of the (region) object used to position and move the image # in the canvas itk_option define -region_id region_id Region_id {} # X offset of image frame itk_option define -xoffset xoffset Xoffset 0 # Y offset of image frame itk_option define -yoffset yoffset Yoffset 0 # width of image frame itk_option define -width width Width 0 # height of image frame itk_option define -height height Height 0 # This tcl command is evaluated whenever the frame is created # moved, resized or deleted: 7 arguments will be appended to the # command before it is evaluated: # # frameId: Unique rapid frame id for use with rtdServer. # # name: Unique name for the frame. # # op: Operation: one of: move,resize or delete. # # x, y: Coordinates of upper left corner of frame in main image. # # width, height: Dimensions of rapid frame. itk_option define -command command Command {} # flag: if true, pan image is "subsampled" when shrinking, # otherwise the pixels are averaged itk_option define -subsample subsample Subsample 1 # X shared memory option itk_option define -usexshm useXshm UseXshm 1 # X synchronisation option itk_option define -usexsync useXsync UseXsync 1 # flag: if true, print diagnostic messages itk_option define -verbose verbose Verbose {0} # zoom window to update itk_option define -zoomwin zoomWin ZoomWin {} # text of short help message to be displayed whenever # the mouse enters the image window (see Toplevel.tcl) itk_option define -shelp shelp Shelp "image window: {bitmap b1} = select graphics, \ {bitmap b2} = scroll image, \ {bitmap dragb3} = measure world coordinates" # optionally specify TopLevelWidget to display short help messages itk_option define -shorthelpwin shortHelpWin ShortHelpWin {} # minimum allowed scale value itk_option define -min_scale min_scale Min_scale -10 # maximum allowed scale value itk_option define -max_scale max_scale Max_scale 20 # -- protected vars -- # target internal rtdimage protected variable target_image_ # canvas widget for main image and region object marking frame. protected variable target_canvas_ # CanvasDraw object, for setting up move, resize operations on embedded image protected variable draw_ # internal rtdimage for rapid frame protected variable image_ # canvas window containing rapid frame image, # different than target_canvas for popup frames protected variable canvas_ # canvas id of rectangle used to get events for moving/resizing image protected variable rectId_ # rapid frame Id, needed to communicate with rtdServer protected variable frameId_ } skycat-3.1.2-starlink-1b/rtd/library/RtdImagePrint.tcl000066400000000000000000000321671215713201500226200ustar00rootroot00000000000000#******************************************************************************* # E.S.O. - VLT project # # "@(#) $Id: RtdImagePrint.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImagePrint.tcl - popup dialog for printing an RTD image # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 95 Created # P. Biereichel 05/08/97 Modified for xgrabsc (screen dump) # Allan Brighton 21 Nov 97 Renamed to RtdImagePrint, since it is # now rtd specific, pass image as option. # Peter W. Draper 14 May 98 Added changes to use Canvas postscript # printing with a suitably patched Tk. # Now only get a footer. # Peter W. Draper 21 Aug 02 Added swap of width and height values # when toggling between portrait and landscape # 05 Aug 09 Tweak footer positions for new fonts. itk::usual RtdImagePrint {} # RtdImagePrint defines a popup dialog for printing an RTD image. # This class extends the PrintDialog class. itcl::class rtd::RtdImagePrint { inherit util::PrintDialog # constructor constructor {args} { eval itk_initialize $args } # this method is called after all options have been evaluated protected method init {} { util::PrintDialog::init # get internal image handle and canvas set image_ [$itk_option(-image) get_image] set canvas_ [$itk_option(-image) get_canvas] wm title $w_ "RTD Postscript print ($itk_option(-number))" global ::$w_.color ::$w_.rotate ::$w_.fit_to_page ::$w_.footer \ ::$w_.whole # print options frame itk_component add options { frame $w_.options -borderwidth 3 -relief groove } pack $w_.options -side top -fill x -expand 1 -in $w_.config # title for option frame itk_component add title { label $w_.options.title -text "Postscript Options" } pack $w_.options.title -side top # color options pack [frame $w_.color -borderwidth 5] \ -side top -fill x -expand 1 -in $w_.options pack [radiobutton $w_.color.color -text "Color" \ -variable $w_.color \ -value color] \ [radiobutton $w_.color.gray -text "Gray-Scale" \ -variable $w_.color \ -value gray] \ [radiobutton $w_.color.mono -text "Black & White" \ -variable $w_.color \ -value mono] \ -side left -fill x -expand 1 ::set $w_.color color # rotate options pack [frame $w_.rotate -borderwidth 5] \ -side top -fill x -expand 1 -in $w_.options pack [radiobutton $w_.rotate.yes -text "Landscape" \ -variable $w_.rotate \ -value yes \ -command [code $this toggle_rotate_] ] \ [radiobutton $w_.rotate.no -text "Portrait" \ -variable $w_.rotate \ -value no \ -command [code $this toggle_rotate_] ] \ -side left -fill x -expand 1 ::set $w_.rotate no set last_rotate_ no # Capture whole of displayed canvas. pack [frame $w_.whole -borderwidth 5] \ -side top -fill x -expand 1 -in $w_.options pack [checkbutton $w_.whole.yes -text "Print whole window" \ -variable $w_.whole \ -onvalue 1 -offvalue 0 \ -command [code $this set_whole_canvas] ] \ -side left ::set $w_.whole $itk_option(-whole_canvas) # page size options pack [frame $w_.pagesize -borderwidth 5] \ -side top -fill x -expand 1 -in $w_.options checkbutton $w_.pagesize.fit -text "Encapsulated Postscript" \ -variable $w_.fit_to_page \ -command [code $this toggle_fit_pagesize] checkbutton $w_.pagesize.footer -text "Footer text" \ -variable $w_.footer LabelEntry $w_.pagesize.width \ -text "Page width " \ -value $itk_option(-pagewidth) \ -valuewidth 6 LabelEntry $w_.pagesize.height \ -text "Page height" \ -value $itk_option(-pageheight) \ -valuewidth 6 blt::blttable $w_.pagesize \ $w_.pagesize.fit 1,0 -anchor w \ $w_.pagesize.footer 1,1 -anchor e \ $w_.pagesize.width 2,0 -anchor w \ $w_.pagesize.height 2,1 -anchor e ::set $w_.fit_to_page $itk_option(-fit_to_page) ::set $w_.footer $itk_option(-show_footer) add_short_help } # add short help texts protected method add_short_help {} { global ::env set tp [winfo parent $w_] $tp add_short_help $w_.color.color \ "Write output in Postscript format for color printers" $tp add_short_help $w_.color.gray \ "Write output in Postscript format for greyscale printers" $tp add_short_help $w_.color.mono \ "Write output in Postscript format in black and white" $tp add_short_help $w_.rotate.yes \ "Use landscape layout (with page width and height exchanged) for \ Postscript output" $tp add_short_help $w_.rotate.no \ "Use portrait layout for Postscript output" $tp add_short_help $w_.pagesize.width \ "Paper width in inches (default for A4: $itk_option(-pagewidth))" $tp add_short_help $w_.pagesize.height \ "Paper height in inches (default for A4: $itk_option(-pageheight))" $tp add_short_help $w_.pagesize.fit \ "Encapsulated Postscript for including the image into a document \ (e.g. LaTeX/FrameMaker). No translation or scaling!" $tp add_short_help $w_.whole.yes \ "Print whole of main image region (needed to keep off-image \ graphics, e.g. grid plots)" $tp add_short_help $w_.pagesize.footer "Add footer to image" } # called when the "Encapsulate" button is pressed protected method toggle_fit_pagesize {} { global ::$w_.fit_to_page if {![set $w_.fit_to_page]} { $w_.pagesize.width config -state normal $w_.pagesize.height config -state normal } else { $w_.pagesize.width config -state disabled $w_.pagesize.height config -state disabled } } # switch the "width" and "height" when changing between landscape # and portrait mode protected method toggle_rotate_ {} { global ::$w_.rotate if { $last_rotate_ == [set $w_.rotate] } { return } set width [$w_.pagesize.width get] $w_.pagesize.width configure -value [$w_.pagesize.height get] $w_.pagesize.height configure -value $width set last_rotate_ [set $w_.rotate] } # print the contents of the canvas to the open filedescriptor protected method print {fd} { global ::$w_.color ::$w_.rotate $w_.colormap ::$w_.footer global ::$w_.fit_to_page ::$w_.whole set cmd [list $canvas_ postscript \ -colormode [set $w_.color] \ -rotate [set $w_.rotate]] # Get the offsets that correct for the apparent shift of the # image when zoomed. set xoff [expr {int([$canvas_ canvasx 0])}] set yoff [expr {int([$canvas_ canvasy 0])}] set xoff [max $xoff 0] set yoff [max $yoff 0] if { $itk_option(-x0) == {} } { # no prefered canvas section so adjust things to the size # of the displayed rtd image if available. If not then # use a bounding box that encompasses all the displayed items. if { ! [set $w_.whole] } { # The origin of the image is always 0,0 for a canvas # print to work. set x0 0 set y0 0 set x1 [min [winfo width $canvas_] [$image_ dispwidth]] set y1 [min [winfo height $canvas_] [$image_ dispheight]] } else { # Use whole printing surface. set x0 [min 0 [$canvas_ canvasx 0]] set y0 [min 0 [$canvas_ canvasy 0]] set x1 [expr {$x0+[winfo width $canvas_]}] set y1 [expr {$y0+[winfo height $canvas_]}] } } # Set the background (use a filled rectangle to simulate this). if { [set $w_.whole] } { set_background } # Now add footer. if {[set $w_.footer]} { add_footer } # Set the width, height and corner. lappend cmd \ -width [expr {$x1-$x0+1}] \ -height [expr {$y1-$y0+1}] \ -x $x0 \ -y $y0 if {! [set $w_.fit_to_page]} { lappend cmd \ -pagewidth [$w_.pagesize.width get] \ -pageheight [$w_.pagesize.height get] } if {"[set $w_.color]" == "mono"} { # you can add to this array, see canvas(n) man page set $w_.colormap(grey) "0.0 0.0 0.0 setrgbcolor" lappend cmd -colormap $w_.colormap } # Shift all canvas items so that they align to the image # with its origin of 0,0. $canvas_ move all [expr {-1.0*$xoff}] [expr {-1.0*$yoff}] $canvas_ move $image_ $xoff $yoff $canvas_ move print $xoff $yoff # Write postscript into file stream. puts $fd [eval $cmd] # Shift everything back to original position. $canvas_ move all $xoff $yoff $canvas_ move $image_ \ [expr {-1.0*$xoff}] [expr {-1.0*$yoff}] # Remove footer. if {[set $w_.footer]} { rm_footer } # Remove background. if { [set $w_.whole] } { remove_background } } # add footer labels below draw area by temporarily inserting # the text protected method add_footer {} { set hy0 [expr {$y1+25}] set hy1 [expr {$y1+50}] # white background for labels $canvas_ create rect $x0 $y1 $x1 $hy1 \ -outline white \ -fill white \ -tags print set hx0 $x0 set hy0 [expr {$y1+30}] set hx1 $x1 set hy1 [expr {$y1+40}] if {"$itk_option(-top_left)" != ""} { $canvas_ create text $hx0 $hy0 \ -text $itk_option(-top_left) \ -font $itk_option(-footer_font) \ -anchor sw \ -tags print } if {"$itk_option(-top_right)" != ""} { $canvas_ create text $hx1 $hy0 \ -text "$itk_option(-top_right)" \ -font $itk_option(-footer_font) \ -anchor se \ -justify right \ -tags print } if {"$itk_option(-bot_left)" != ""} { $canvas_ create text $hx0 $hy1 \ -text $itk_option(-bot_left) \ -font $itk_option(-footer_font) \ -anchor nw \ -tags print } if {"$itk_option(-bot_right)" != ""} { $canvas_ create text $hx1 $hy1 \ -text "$itk_option(-bot_right)" \ -font $itk_option(-footer_font) \ -anchor ne \ -justify right \ -tags print } # add margin set y1 [expr {$y1+50}] set x1 [expr {$x1+15}] } # remove the footer, if any and restore the original state protected method rm_footer {} { $canvas_ delete print } # modify capture all canvas items protected method set_whole_canvas {} { global ::$w_.whole configure -whole_canvas [set $w_.whole] } # modify show_footer protected method set_show_footer {} { global ::$w_.footer configure -show_footer [set $w_.footer] } # set/remove the background of the canvas. protected method set_background {} { set xlow [$canvas_ canvasx 0] set ylow [$canvas_ canvasy 0] set xhigh [$canvas_ canvasx [winfo width $canvas_]] set yhigh [$canvas_ canvasy [winfo height $canvas_]] set xlow [expr {round($xlow-1)}] set ylow [expr {round($ylow-1)}] set xhigh [expr {round($xhigh+1)}] set yhigh [expr {round($yhigh+1)}] $canvas_ create rectangle $xlow $ylow $xhigh $yhigh \ -fill white \ -outline white \ -tags ${this}_back $canvas_ lower ${this}_back all } # remove the background of the canvas. protected method remove_background {} { $canvas_ delete ${this}_back } # -- options -- # name of Itcl RtdImage or derived widget, set by caller itk_option define -image image Image {} # flag, it true whole canvas is captured, this includes any # graphics that extends outside the image. itk_option define -whole_canvas whole_canvas Whole_Canvas 1 # flag, if true, scale output to fit on page itk_option define -fit_to_page fit_to_page Fit_to_page 0 # page width, used when fit_to_page is 1 itk_option define -pagewidth pageWidth Pagewidth 8.268i # page height, used when fit_to_page is 1 itk_option define -pageheight pageHeight Pageheight 11.693i # flag, if true (1), insert footers before printing itk_option define -show_footer show_footer Show_footer 1 # alias for -show_footer, for backward compatibility itk_option define -show_headers show_headers Show_headers -1 { if {$itk_option(-show_headers) >= 0} { config -show_footer $itk_option(-show_headers) } } # footer text to appear at top left itk_option define -top_left top_left Top_left {} # footer text to appear at top right itk_option define -top_right top_right Top_right {} # footer text to appear at bottom left itk_option define -bot_left bot_left Bot_left {} # footer text to appear at bottom right itk_option define -bot_right bot_right Bot_right {} # footer fonts itk_option define -footer_font footer_font Footer_font TkFixedFont # upper left X coordinate of area of canvas to print (default bbox all) itk_option define -x0 x0 X0 {} {set x0 $itk_option(-x0)} # upper left Y coordinate itk_option define -y0 y0 Y0 {} {set y0 $itk_option(-y0)} # bottom right X coordinate itk_option define -x1 x1 X1 {} {set x1 $itk_option(-x1)} # bottom right Y coordinate itk_option define -y1 y1 Y1 {} {set y1 $itk_option(-y1)} # -- protected variables -- # x0 of area to print protected variable x0 {} # y0 of area to print protected variable y0 {} # x1 of area to print protected variable x1 {} # y1 of area to print protected variable y1 {} # internal rtdimage object protected variable image_ # canvas widget protected variable canvas_ # last/initial rotate value protected variable last_rotate_ no } skycat-3.1.2-starlink-1b/rtd/library/RtdImageSpectrum.tcl000066400000000000000000000164171215713201500233260ustar00rootroot00000000000000#******************************************************************************* # E.S.O. - VLT project # # "@(#) $Id: RtdImageSpectrum.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImageSpectrum.tcl - itcl widget for displaying graph of image data values # along a line # # See man page RtdImageSpectrum(n) for a complete description. # # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 95 Created # Allan Brighton 28 Jun 96 Changed GUI name to "Cuts", # (suggested by M. Albrecht) # pbiereic 22/07/97 Added value display at cursor position # pbiereic 27/06/03 VLTSW20030157: Motion bindings itk::usual RtdImageSpectrum {} # This [incr Tk] widget is used to display a BLT graph in a # popup window plotting the raw image pixel values along a given # line drawn interactively on the image. Once created, the graph # can be continuously updated as the line is moved or resized. # This widget only sets up the layout. The real work is done in # the rtdimage spectrum subcommand (see rtdimage(3)), that communicates # directly with the BLT graph using its C interface. itcl::class rtd::RtdImageSpectrum { inherit util::TopLevelWidget # constructor: create a new instance of this class constructor {args} { eval itk_initialize $args wm minsize $w_ 10 10 wm title $w_ "Cuts ($itk_option(-number))" make_graph make_buttons $draw_ add_notify_cmd $itk_option(-line_id) [code $this notify_cmd] 1 } # destructor - clean up when deleted destructor { global ::tcl_version $draw_ remove_notify_cmd $itk_option(-line_id) $draw_ delete_object $itk_option(-line_id) if {$tcl_version >= 8.0} { global $xVector_ $yVector_ blt::vector destroy $xVector_ $yVector_ } } # make the graph subwindow protected method make_graph {} { global ::tcl_version # Note: make the graph in the global namespace for now so that # the old blt utils (features.tcl) still work. Shouldn't be needed # with blt-2.0 or later... set cmd \ [list blt::graph $w_.graph \ -width 5i \ -height 3i \ -borderwidth 3 \ -relief groove \ -title "Pixel Values" ] # BLT graph of pixel values itk_component add graph { set graph_ [uplevel "#0" $cmd] } { } pack $itk_component(graph) \ -fill both -expand 1 -padx 1m -pady 1m add_short_help $itk_component(graph) \ {Graph: plot image pixel values along line, {bitmap dragb1} = zoom, {bitmap b2} = restore} $graph_ yaxis configure -title {} # blt2.4f vector names must start with a letter, no dots... # someone also changed the default symbol to circle. Why? regsub -all {\.} v$graph_.xVector _ xVector_ regsub -all {\.} v$graph_.yVector _ yVector_ if {$tcl_version >= 8.0} { $graph_ legend config -hide 1 if {![info exists $xVector_]} { blt::vector create $xVector_ $yVector_ } set symbol {} } else { global $xVector_ $yVector_ $graph_ legend config -mapped 0 if {![info exists $xVector_]} { blt::vector $xVector_ $yVector_ } set symbol none } $graph_ element create elem -xdata $xVector_ -ydata $yVector_ -symbol $symbol # plot the distribution of pixel values notify_cmd # add BLT features ::Blt_ZoomStack $graph_ ::Blt_ActiveLegend $graph_ ::Blt_Crosshairs $graph_ ::Blt_ClosestPoint $graph_ if {$tcl_version >= 8.3} { bind $graph_ "catch {$this dispXY %x %y; %W crosshairs configure -position @%x,%y}" } else { bind bltCrosshairs "catch {$this dispXY %x %y; %W crosshairs configure -position @%x,%y}" } # Tk frame for X,Y positions. itk_component add fpos { frame $w_.fpos -relief flat } # Tk label for X position. itk_component add xpos { label $itk_component(fpos).xpos -width 20 -anchor w } # Tk label for Y position. itk_component add yval { label $itk_component(fpos).yval -width 20 -anchor w } pack $itk_component(xpos) $itk_component(yval) -fill x -expand 0 -side left pack $itk_component(fpos) -fill none -expand 0 } # make a hard copy of the graph display public method print {} { utilReUseWidget util::GraphPrint $w_.print \ -graph $graph_ } # display x, y values at cursor position public method dispXY {x y} { global ::tcl_version if {$tcl_version < 8.0} { global $yVector_ } if {![$graph_ element closest $x $y "" -interpolate 1 -halo 10000]} { return } lassign [$graph_ invtransform $x $y] x y set x [expr {int(round($x))}] if {$x < 1 || $x >= $numValues_} { return } set yval [$yVector_ range $x $x] $itk_component(xpos) config -text "X: $x" $itk_component(yval) config -text "Value: $yval" } # make the button frame at the bottom of the window protected method make_buttons {} { pack [set b [frame $w_.buttons -borderwidth 2 -relief groove]] \ -side bottom -fill x pack \ [button $b.print -text "Print..." -command [code $this print]] \ [button $b.close -text "Close" -command [code $this quit]] \ -side left -expand 1 -padx 2m -pady 2m add_short_help $b.print \ {Print: Display a dialog window for printing the graph} add_short_help $b.close \ {Close: Close this window} } # quit the window public method quit {} { catch {$draw_ delete_object $itk_option(-line_id)} catch {destroy $w_} } # This method is called whenever the spectrum line is moved, resized # or deleted or when the image changed and the graph should be updated. # It updates the graph to show the image values along the line. public method notify_cmd {{op update}} { global ::tcl_version if {"$op" == "delete"} { destroy $w_ return 0 } lassign [$canvas_ coords $itk_option(-line_id)] x0 y0 x1 y1 # plot the distribution of pixel values if {$tcl_version < 8.0} { global $xVector_ $yVector_ } if {[catch {set numValues_ [$image_ spectrum $graph_ elem $x0 $y0 $x1 $y1 canvas \ $xVector_ $yVector_]}]} { return 0 } $graph_ xaxis configure -max $numValues_ return 0 } # -- options -- # name of RtdImage itcl widget, set by caller itk_option define -image image Image {} { # get internal widgets set canvas_ [$itk_option(-image) get_canvas] set image_ [$itk_option(-image) get_image] set draw_ [$itk_option(-image) component draw] } # canvas id of the spectrum line itk_option define -line_id line_id Line_id {} # x0 canvas coordinate of the spectrum line itk_option define -x0 x0 X0 0 # y0 canvas coordinate of the spectrum line itk_option define -y0 y0 Y0 0 # x1 canvas coordinate of the spectrum line itk_option define -x1 x1 X1 0 # y1 canvas coordinate of the spectrum line itk_option define -y1 y1 Y1 0 # -- protected vars -- # name of graph widget protected variable graph_ # name of image's canvas widget protected variable canvas_ # name of internal rtdimage object protected variable image_ # name of RtdImage's CanvasDraw object protected variable draw_ # number of values displayed protected variable numValues_ 0 # x vector for graph protected variable xVector_ # y vector for graph protected variable yVector_ } skycat-3.1.2-starlink-1b/rtd/library/RtdImageTrans.tcl000066400000000000000000000204771215713201500226140ustar00rootroot00000000000000#******************************************************************************* # E.S.O. - VLT project # # "@(#) $Id: RtdImageTrans.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImageTrans.tcl - itcl widget for scaling, rotating and flipping an RtdImage widget # # See man page RtdImageTrans(n) for a complete description. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 95 Created # Peter W. Draper 15 Apr 08 Don't assume X and Y scales are already set # to the same value itk::usual RtdImageTrans {} # RtdImageTrans is an [incr Tk] widget class for setting and displaying # image transformation states, such as rotation, flipX, flipY and scale # (magnification). The widget displays a menubutton with a selection of # image scale factors (from 1/5x to 9x magnification), 2 optional # buttons for incrementing and decrementing the scale factor, and buttons # for setting rotation, flipX and flipY. itcl::class rtd::RtdImageTrans { inherit util::FrameWidget # constructor: create a new instance of this class constructor {args} { itk_option add hull.borderwidth hull.relief # do this first so we can use the option values eval itk_initialize $args set image_ [$itk_option(-image) get_image] # LabelMenu(n) widget to choose scale factor itk_component add choose { set m [util::LabelMenu $w_.choose \ -text "Scale:" \ -relief groove \ -labelfont $itk_option(-labelfont) \ -valuefont $itk_option(-valuefont) \ -labelwidth $itk_option(-labelwidth) \ -valuewidth 5 \ -anchor e] } { keep -state -background -foreground } if { "$itk_option(-panel_orient)" == "vertical" } { pack $itk_component(choose) -side top -fill x -ipadx 0.5m -ipady 0.5m } else { pack $itk_component(choose) -side left -fill x -ipadx 0.5m -ipady 0.5m } # help text displayed when mouse enters widget add_short_help $w_ {Image Scale: {bitmap b1} = select the magnification of the image} frame $w_.trans_frame if {$itk_option(-show_Zz_buttons)} { # Tk button to zoom in itk_component add larger { button $w_.larger \ -bitmap magnify \ -command [code $this inc_zoom 1] } { keep -state -background -foreground } # Tk button to zoom out itk_component add smaller { button $w_.smaller \ -bitmap shrink \ -command [code $this inc_zoom -1] } { keep -state -background -foreground } pack $itk_component(larger) $itk_component(smaller) \ -side left -fill x -padx 0.5m -ipadx 0.5m -ipady 0.5m -in $w_.trans_frame add_short_help $itk_component(larger) {Zoom larger: {bitmap b1} = zoom in on the image} add_short_help $itk_component(smaller) {Zoom smaller: {bitmap b1} = zoom out on the image} } if {$itk_option(-show_trans)} { # Tk checkbutton to rotate (swap X/Y axis) itk_component add rotate { checkbutton $w_.rotate \ -bitmap rotate \ -selectcolor {} \ -indicatoron 0 \ -variable $w_.var(rotate) \ -command [code $this rotate] } { keep -state -background -foreground } # Tk checkbutton to flip the X axis itk_component add flipx { checkbutton $w_.flipx \ -bitmap flipx \ -selectcolor {} \ -indicatoron 0 \ -variable $w_.var(flipx) \ -command [code $this flip x] } { keep -state -background -foreground } # Tk checkbutton to flip the Y axis itk_component add flipy { checkbutton $w_.flipy \ -bitmap flipy \ -selectcolor {} \ -indicatoron 0 \ -variable $w_.var(flipy) \ -command [code $this flip y] } { keep -state -background -foreground } pack $itk_component(rotate) \ -side left -fill x -padx 1m -ipadx 1.5m -ipady 0.5m -in $w_.trans_frame pack $itk_component(flipx) $itk_component(flipy) \ -side left -fill x -padx 0.5m -ipadx 0.5m -ipady 0.5m -in $w_.trans_frame add_short_help $itk_component(rotate) \ {Exchange: {bitmap b1} = swap the image X and Y axes} add_short_help $itk_component(flipx) \ {Flip X: {bitmap b1} = flip the image about the X axis} add_short_help $itk_component(flipy) \ {Flip Y: {bitmap b1} = flip the image about the Y axis} } if { "$itk_option(-panel_orient)" == "vertical" } { pack $w_.trans_frame -side top -fill x -pady 0.5m } else { pack $w_.trans_frame -side left -fill x } for {set i $itk_option(-min_scale)} {$i<=-2} {incr i 1} { $m add -label "1/[expr {-$i}]x" -command "$itk_option(-image) scale $i $i" } for {set i 1} {$i<=$itk_option(-max_scale)} {incr i} { $m add -label " ${i}x" -command "$itk_option(-image) scale $i $i" } $m config -value { 1x} } # add the given increment to the current zoom factor and re-scale # the target image public method inc_zoom {inc} { lassign [$image_ scale] xs ys if {"$xs" == ""} { return } incr xs $inc incr ys $inc # PWD: treat xs and ys independently if {$xs == 0 || $xs == -1} { if {$inc == -1} { set xs -2 } else { set xs 1 } } elseif {$xs < $itk_option(-min_scale)} { set xs $itk_option(-min_scale) } elseif {$xs > $itk_option(-max_scale)} { set xs $itk_option(-max_scale) } if {$ys == 0 || $ys == -1} { if {$inc == -1} { set ys -2 } else { set ys 1 } } elseif {$ys < $itk_option(-min_scale)} { set ys $itk_option(-min_scale) } elseif {$ys > $itk_option(-max_scale)} { set ys $itk_option(-max_scale) } $itk_option(-image) scale $xs $ys update_trans } # fill the given menu with radiobuttons for changing the magnification # of the image and keep them updated with the other controls public method fill_mag_menu {m} { global ::$w_.mag for {set i $itk_option(-min_scale)} {$i<=-2} {incr i 1} { $m add radiobutton \ -label "1/[expr {-$i}]x" \ -command "$itk_option(-image) scale $i $i" \ -variable $w_.mag } for {set i 1} {$i<=$itk_option(-max_scale)} {incr i} { $m add radiobutton \ -label " ${i}x" \ -command "$itk_option(-image) scale $i $i" \ -variable $w_.mag } set $w_.mag { 1x} } # update the display based on the image scale factors # (note that the menu values are referenced to here by their labels) public method update_trans {} { global ::$w_.var ::$w_.mag if {$itk_option(-show_trans)} { set $w_.var(rotate) [$image_ rotate] set $w_.var(flipx) [$image_ flip x] set $w_.var(flipy) [$image_ flip y] } lassign [$image_ scale] xs ys if {"$ys" == ""} { return } if {$xs >= 0} { $itk_component(choose) config -value [set $w_.mag " ${xs}x"] } else { $itk_component(choose) config -value [set $w_.mag "1/[expr {-$xs}]x"] } } # toggle rotation of the image public method rotate {} { global ::$w_.var $itk_option(-image) rotate [set $w_.var(rotate)] } # flip or unflip the image about the x or y axis, as given by $xy public method flip {xy} { global ::$w_.var $itk_option(-image) flip $xy [set $w_.var(flip$xy)] } # -- public vars -- # target RtdImage (itcl widget) itk_option define -image image Image {} # font for label and value itk_option define -labelfont labelFont LabelFont TkDefaultFont itk_option define -valuefont valueFont ValueFont TkDefaultFont # set the width for displaying the label itk_option define -labelwidth labelWidth LabelWidth 5 # set the width for displaying the value itk_option define -valuewidth valueWidth ValueWidth 12 # flag: if true, display buttons for zooming the image in and out itk_option define -show_Zz_buttons show_Zz_buttons Show_Zz_buttons 1 # flag: if true, display the rotate, flipxy items itk_option define -show_trans show_trans Show_trans 1 # minimum allowed scale value itk_option define -min_scale min_scale Min_scale -10 # maximum allowed scale value itk_option define -max_scale max_scale Max_scale 20 # set the state to normal/disabled to enable/disable editing itk_option define -state state State {normal} # Panel orient: one of {horizontal vertical} (default: horizontal) itk_option define -panel_orient panel_orient Panel_orient {} # -- protected vars -- # internal rtdimage protected variable image_ } skycat-3.1.2-starlink-1b/rtd/library/RtdImageZoom.tcl000066400000000000000000000072121215713201500224410ustar00rootroot00000000000000#******************************************************************************* # E.S.O. - VLT project # # "@(#) $Id: RtdImageZoom.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImageZoom.tcl - itcl widget managing the RtdImage zoom window # # See man page RtdImageZoom(n) for a complete description. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 95 Created itk::usual RtdImageZoom {} # Note: It is better to use the RtdImageZoomView class, since this # class is outdated and being phased out. # # This [incr Tk] widget class can be used to display a magnified portion # of the image while tracking mouse motion events in the image window. # There are two versions of this widget, see RtdImageZoomView(n) for the # other one. This version takes a caller supplied Tk frame and zooms # directly from the main image's XImage to the frame, but does not # display an accurate image when the main image is "subsampled" # (shrunk). # # The main part of this widget is implemented in C++ by the # rtdimage subcommand "zoom". # # This widget is a subclass of FrameWidget, so it inherits its # methods and options. In addition the options and methods below # are defined. itcl::class rtd::RtdImageZoom { inherit util::FrameWidget # constructor: create a new instance of this class constructor {args} { itk_option add hull.borderwidth hull.relief eval itk_initialize $args # zoom frame itk_component add frame { set zoom_ [frame $w_.frame \ -background black \ -borderwidth 3 \ -relief groove \ -width $itk_option(-width) \ -height $itk_option(-height)] } { } pack $itk_component(frame) -side top global ::$w_.dozoom # checkbutton to turn zoom on/off itk_component add check { checkbutton $w_.check -text Zoom \ -variable $w_.dozoom \ -onvalue 1 -offvalue 0 \ -anchor w \ -borderwidth 2 \ -relief raised \ -command [code $this zoom] } { } pack $itk_component(check) -side bottom -fill both # add help text displayed when mouse enters widget add_short_help $w_ $itk_option(-shelp) } # called when the zoom checkbutton is pressed public method zoom {} { global ::$w_.dozoom if {[winfo width $zoom_] <= 1} { update } if {[set $w_.dozoom]} { $itk_option(-target_image) zoom start $zoom_ $itk_option(-factor) } else { $itk_option(-target_image) zoom stop } } # called when the main image is scaled. public method scale {} { } # This method is called when the mouse ptr enters an RtdImage. # Set the target scale factor from the given rtdimage public method enter_image {image} { } # This method is called when the mouse ptr leaves an RtdImage. # clear out the zoom image. public method leave_image {image} { } # -- public vars -- # target RtdImage itcl widget itk_option define -target_image target_image Target_image {} # width of zoom frame itk_option define -width width Width 128 # height of zoom frame itk_option define -height height Height 128 # zoom factor (window size should be a multiple of this) itk_option define -factor factor Factor 4 # help text displayed when mouse enters widget itk_option define -shelp shelp Shelp \ {Image Zoom: magnified section of image. {bitmap b1} = toggle on/off} # X shared memory option itk_option define -usexshm useXshm UseXshm 1 # X synchronisation option itk_option define -usexsync useXsync UseXsync 1 # -- protected vars -- # internal zoom frame protected variable zoom_ } skycat-3.1.2-starlink-1b/rtd/library/RtdImageZoomView.tcl000066400000000000000000000215261215713201500233000ustar00rootroot00000000000000#******************************************************************************* # E.S.O. - VLT project # # "@(#) $Id: RtdImageZoomView.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdImageZoomView.tcl - itcl widget managing the RtdImage zoom window # # See man page RtdImageZoomView(n) for a complete description. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 95 Created # 16 Sep 96 added code from P. Biereichel to clear # zoom win when leaving window # Peter W. Draper 11 Dec 01 Stopped zoom window retaining a reference # to an image that has been closed in the # main window (i.e. keep the view master current). itk::usual RtdImageZoomView {} # This [incr Tk] widget class can be used to display a magnified portion # of the image while tracking mouse motion events in the image window. # There are two versions of this widget, see RtdImageZoom(n) for the # other one. This version uses an rtdimage "view" of the main image and # changes the x and y offsets as needed. This has the advantage that it # always displays the correct pixels, even when the main image is # "subsampled" and there are no restrictions on the size or shape of the # zoom window. The main part of this widget is implemented in C++ by the # rtdimage subcommand "zoomview". This widget is a subclass of # FrameWidget, so it inherits its methods and options. In addition the # options and methods below are defined. itcl::class rtd::RtdImageZoomView { inherit util::FrameWidget # constructor: create a new instance of this class constructor {args} { itk_option add hull.borderwidth hull.relief global ::$w_.dozoom # evaluate arguments (the following code depends on them) eval itk_initialize $args # RtdImage(n) widget for zoom itk_component add image { rtd::RtdImage $w_.image \ -name "ZoomWin" \ -verbose $itk_option(-verbose) \ -displaymode 1 \ -scrollbars 0 \ -drag_scroll 0 \ -show_object_menu 0 \ -graphics 0 \ -canvaswidth $itk_option(-width) \ -canvasheight $itk_option(-height) \ -usexshm $itk_option(-usexshm) \ -usexsync $itk_option(-usexsync) \ -shelp $itk_option(-shelp) \ -relief groove \ -borderwidth 2 } { rename -canvaswidth -width width Width rename -canvasheight -height height Height } pack $itk_component(image) -side top -fill both -expand 1 set image_ [$itk_component(image) get_image] set canvas_ [$itk_component(image) get_canvas] # draw a box around the center pixel $canvas_ create rectangle 0 0 1 1 \ -outline white -tags rect1 $canvas_ create rectangle 0 0 1 1 \ -outline black -tags rect2 # frame with on/off button and scale menu itk_component add f { frame $w_.f } { keep -background } pack $itk_component(f) -side bottom -fill both # checkbutton to turn zooming on/off itk_component add check { checkbutton $w_.check \ -text Zoom \ -variable $w_.dozoom \ -onvalue 1 -offvalue 0 \ -anchor w \ -borderwidth 2 -relief raised \ -command [code $this zoom] } { keep -background rename -font -labelfont labelFont LabelFont } pack $itk_component(check) \ -side left -fill x -expand 1 -padx 0.5m -ipadx 0.5m -ipady 0.5m -in $w_.f # if the scale factor doesn't propagate automatically, add buttons to set it if {! $itk_option(-propagate)} { # optional button to increase zoom factor itk_component add larger { button $w_.larger \ -bitmap magnify \ -command [code $this inc_zoom 1] } # optional button to decrease zoom factor itk_component add smaller { button $w_.smaller \ -bitmap shrink \ -command [code $this inc_zoom -1] } # optional label for zoom factor itk_component add label { label $w_.label \ -text "" \ -width 3 \ -font $itk_option(-labelfont) } pack $itk_component(larger) $itk_component(smaller) $itk_component(label) \ -side left -fill x -padx 0.5m -ipadx 0.5m -ipady 0.5m -in $w_.f add_short_help $w_.larger \ {Zoom larger: {bitmap b1} = increase magnification of zoom image} add_short_help $w_.smaller \ {Zoom smaller: {bitmap b1} = decrease magnification of zoom image} } # add help text displayed when mouse enters widget add_short_help $w_.check {Zoom On/Off: {bitmap b1} = turn zooming on/off} add_short_help $w_ $itk_option(-shelp) } # increment or decrement the zoom factor public method inc_zoom {inc} { lassign [$image_ scale] xs if {"$xs" == ""} { return } incr xs $inc if {$xs < 2} { set xs 2 } elseif {$xs > 50} { set xs 50 } $image_ scale $xs $xs config -factor $xs scale if {"$itk_option(-command)" != ""} { eval $itk_option(-command) } } # called when the main image is scaled to draw a box around the center pixel. public method scale {} { if {$itk_option(-propagate)} { set f [expr {$target_scale_*$itk_option(-factor)}] } else { set f [lindex [$image_ scale] 0] if {"$f" != ""} { $w_.label config -text "${f}x" } else { # no image loaded... return } } if {$f <= 1} { # box around pixel set x0 [expr {$itk_option(-width)/2.0}] set y0 [expr {$itk_option(-height)/2.0}] } else { # box part of pixel set x0 [expr {$itk_option(-width)/2.0-$f/2.0}] set y0 [expr {$itk_option(-height)/2.0-$f/2.0}] } set x1 [expr {$x0+$f}] set y1 [expr {$y0+$f}] $canvas_ coords rect1 $x0 $y0 $x1 $y1 $canvas_ coords rect2 [expr {$x0-1}] [expr {$y0-1}] [expr {$x1+1}] [expr {$y1+1}] } # This method is called when the mouse ptr enters an RtdImage. # Set the target scale factor from the given rtdimage public method enter_image {image} { lassign [$image scale] target_scale_ if {$target_scale_ < 1} { set target_scale_ 1 } zoom scale } # This method is called when the mouse ptr leaves an RtdImage. # clear out the zoom image. public method leave_image {image} { #$image_ clear ximage zoom 1 } # called when the zoom checkbutton is pressed public method zoom {{clear 0}} { global ::$w_.dozoom if {[set $w_.dozoom] && ! $clear} { catch {$target_image_ view remove $image_} $target_image_ view add $image_ $itk_option(-propagate) $target_image_ view update $image_ 0 0 $itk_option(-width) $itk_option(-height) 0 0 0 0 image if {$itk_option(-propagate)} { $target_image_ zoomview start $image_ $itk_option(-factor) $itk_option(-propagate) } else { $image_ scale $itk_option(-factor) $itk_option(-factor) $target_image_ zoomview start $image_ 1 0 } scale } else { $target_image_ zoomview stop $image_ clear ximage # PWD: remove this line. This removes the zoom image as a # view of the main image, which is fine in principle, # however this doesn't clear the zoom image, which # therefore retains a copy of the image displayed in the # main image, until it receives a new image or is # cleared. This is bad for NDF access, as we need to # really close the file when the main image is # closed. Otherwise reloading files of the same name can # be very bad. #catch {$target_image_ view remove $image_} } } # -- options -- # target (main) RtdImage itcl widget itk_option define -target_image target_image Target_image {} { set target_image_ [$itk_option(-target_image) get_image] } # width of zoom frame itk_option define -width width Width 152 # height of zoom frame itk_option define -height height Height 152 # zoom magnification factor itk_option define -factor factor Factor 4 # flag: if true, make scale of zoom window relative to target window itk_option define -propagate propagate Propagate 1 # X shared memory option itk_option define -usexshm useXshm UseXshm 1 # X synchronisation option itk_option define -usexsync useXsync UseXsync 1 # fonts used itk_option define -labelfont labelFont LabelFont TkDefaultFont # help text displayed when mouse enters widget itk_option define -shelp shelp Shelp \ {Image Zoom: magnified section of image. {bitmap b1} = toggle on/off} # flag: if true, print diagnostic messages itk_option define -verbose verbose Verbose {0} # optional command to evaluate when the zoom factor changes itk_option define -command command Command {} # -- protected vars -- # internal target image protected variable target_image_ # scale of the target (or current target) image protected variable target_scale_ 1 # internal canvas widget protected variable canvas_ # internal rtd image protected variable image_ } skycat-3.1.2-starlink-1b/rtd/library/RtdInit.tcl000066400000000000000000000010331215713201500214500ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: RtdInit.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdInit.tcl # # script which is executed by RtdImage.C to initialize tcl # # who when what # -------- --------- ---------------------------------------------- # pbiereic 24/08/99 created # What we depend on. package require Tclutil package require Astrotcl if {![lcontain $auto_path $rtd_library]} { lappend auto_path $rtd_library } namespace eval rtd {namespace export *} namespace import -force rtd::* skycat-3.1.2-starlink-1b/rtd/library/RtdRecorder.tcl000066400000000000000000000554451215713201500223320ustar00rootroot00000000000000#****************************************************************************** # E.S.O. - VLT project # # RtdRecorderTool.tcl - class for recording or playback of images. # # who when what # -------- -------- ---------------------------------------------- # D.Hopkinson 19/02/97 Created # P.Biereichel 15/07/97 Bugs fixed - revised itk::usual RtdRecorderTool {} # RtdRecorderTool is a class for controlling the recording or playing # back of images. # # This widget doubles as a recorder and playback tool. As a recorder, # it acts as an effective RTD, receiving images from the camera named # in the camera_ variable. As a playback, the camera becomes # hardwired to RTDRPTOOL. itcl::class rtd::RtdRecorderTool { inherit util::TopLevelWidget constructor {args} { eval itk_initialize $args global ::recorder_init set rtdplayback_ [image create rtdplayback] set rtdrecorder_ [image create rtdrecorder] wm title $w_ "Video Record/Playback Images ($itk_option(-number))" wm resizable $w_ 0 0 wm protocol $w_ WM_DELETE_WINDOW "" # Widget layout add_menubar make_layout make_shorthelp trace_counts set recorder_init 1 } destructor { # Stop any recordings/playings before closing. stop $rtdrecorder_ close $rtdplayback_ close # Set back to the original camera before going. $mainwidg_ config -camera $itk_option(-server_camera) } # make the widget layout protected method make_layout {} { global ::$w_.comp ::$w_.pbspeed ::$w_.direction ::$w_.protect ::recorder_init ::$w_.cmode # Tk frame for status itk_component add status { frame $w_.status -relief groove -borderwidth 2 } # Tk label: "File Position:" itk_component add progressLabel { label $itk_component(status).progressLabel \ -text "File Position:" \ -width 11 \ -font $itk_option(-labelfont) \ -anchor w } # Tk scale for progress bar itk_component add progressBar { scale $itk_component(status).progressBar \ -orient horizontal \ -sliderlength 0 \ -from 0 \ -to 1 \ -showvalue 0 \ -width 8 \ -highlightthickness 0 } { keep -width -length } # LabelEntry(n) widget, image count itk_component add imagecount { util::LabelEntry $itk_component(status).imagecount \ -disabledforeground black \ -text "Image Count:" \ -labelfont $itk_option(-labelfont) \ -labelwidth 12 \ -valuewidth 8 \ -validate integer \ -valuefont $itk_option(-valuefont) \ -relief sunken \ -command [code $this gotoImage] \ -borderwidth 2 \ -orient horizontal } { keep -state } # LabelEntry(n) widget "of:" itk_component add ncounts { util::LabelEntry $itk_component(status).ncounts \ -text "of:" \ -labelfont $itk_option(-labelfont) \ -labelwidth 3 \ -valuewidth 5 \ -valuefont $itk_option(-valuefont) \ -relief groove \ -disabledforeground black \ -state disabled \ -borderwidth 2 \ -orient horizontal } # Tk frame for file name itk_component add fileframe { frame $w_.file -relief groove -borderwidth 2 } # LabelEntry(n) widget File Name:" itk_component add filename { util::LabelEntry $itk_component(fileframe).filename \ -text "File Name:" \ -value $imageFile_ \ -labelwidth 12 \ -justify right \ -labelfont $itk_option(-labelfont) \ -valuewidth 28 \ -valuefont $itk_option(-valuefont) \ -relief sunken \ -borderwidth 2 \ -command [code $this chooseFile] \ -orient horizontal } { keep -state } # Set the default camera set camera_ $itk_option(-server_camera) # LabelEntry(n) widget "Camera Name:" itk_component add cameraname { util::LabelEntry $itk_component(fileframe).cameraname \ -text "Camera Name:" \ -labelwidth 12 \ -command [code $this chooseCamera] \ -labelfont $itk_option(-labelfont) \ -valuewidth 28 \ -valuefont $itk_option(-valuefont) \ -relief sunken \ -borderwidth 2 \ -value $camera_ \ -orient horizontal } { keep -state } # action frame itk_component add action { frame $w_.action -relief groove -borderwidth 2 } # Tk frame pbaction1 itk_component add pbaction1 { frame $itk_component(action).pbaction1 -relief flat -borderwidth 2 } # checkbutton "Reverse direction" itk_component add direction { checkbutton $itk_component(pbaction1).direction \ -text "Reverse direction" \ -command [code $this stop] \ -variable $w_.direction \ -anchor w \ -font $itk_option(-labelfont) } { keep -state } # checkbutton "Protect" itk_component add protect { checkbutton $itk_component(pbaction1).protect \ -text "Protect" \ -command [code $this protect] \ -variable $w_.protect \ -anchor e \ -font $itk_option(-labelfont) } { keep -state } set $w_.protect 1 # Tk frame pbaction2 itk_component add pbaction2 { frame $itk_component(action).pbaction2 -relief raised -borderwidth 2 } # Play button itk_component add play { button $itk_component(pbaction2).play \ -bitmap big_right \ -command [code $this play] } { keep -state } # Rewind button itk_component add rewind { button $itk_component(pbaction2).rewind \ -bitmap double_left \ -command [code $this spool "rewind"] } { keep -state } # fast forward button itk_component add ff { button $itk_component(pbaction2).ff \ -bitmap double_right \ -command [code $this spool "ff"] } { keep -state } # single step button itk_component add single { button $itk_component(pbaction2).single \ -bitmap Right \ -command [code $this single] } { keep -state } # Record button itk_component add record { button $itk_component(pbaction2).record \ -bitmap record \ -foreground red \ -disabledforeground red \ -command [code $this record] } # Stop button itk_component add stop { button $itk_component(pbaction2).stop \ -bitmap rect \ -command [code $this stop] } # Set the defaults if {![info exists recorder_init] || $recorder_init != 1} { set $w_.direction 0 set $w_.pbspeed 1 set $w_.cmode 1 } # do the packing blt::blttable $itk_component(status) \ $itk_component(progressLabel) 1,0 -anchor w -fill x \ $itk_component(progressBar) 1,1 -anchor e -fill x -columnspan 2 \ $itk_component(imagecount) 2,0 -anchor w -fill x -columnspan 2 \ $itk_component(ncounts) 2,2 -anchor w -fill x blt::blttable $itk_component(fileframe) \ $itk_component(filename) 1,0 -anchor w -fill x \ $itk_component(cameraname) 2,0 -anchor w -fill x blt::blttable $itk_component(pbaction1) \ $itk_component(direction) 1,0 -anchor w -fill x \ $itk_component(protect) 1,1 -anchor e -fill x blt::blttable $itk_component(pbaction2) \ $itk_component(play) 1,0 -anchor w -fill none \ $itk_component(rewind) 1,1 -anchor w -fill none \ $itk_component(ff) 1,2 -anchor w -fill none \ $itk_component(single) 1,3 -anchor w -fill none \ $itk_component(record) 1,4 -anchor w -fill none \ $itk_component(stop) 1,5 -anchor w -fill none pack $itk_component(status) $itk_component(fileframe) $itk_component(action) \ $itk_component(pbaction1) -side top -anchor w -fill x -expand 0 -padx 5 -pady 5 pack $itk_component(pbaction2) \ -side top -anchor c -fill none -expand 0 -padx 5 -pady 5 } # add short help text protected method make_shorthelp {} { add_short_help $itk_component(progressBar) {Displays the proportion of the maximum file size that has been recorded or proportion played back} add_short_help $itk_component(imagecount) {Image counter when playing back images from file} add_short_help $itk_component(ncounts) {Number of images in file} add_short_help $itk_component(filename) {Displays the name of the file to record/play. Use after editing.} add_short_help $itk_component(cameraname) {Sets the camera from which images are to be received} add_short_help $itk_component(direction) {Reverse the playback direction} add_short_help $itk_component(protect) {Set write protect/unprotect file} add_short_help $itk_component(play) {Playback images from file} add_short_help $itk_component(rewind) {Rewind image file} add_short_help $itk_component(ff) {Fast-forward image file} add_short_help $itk_component(single) {Single-step through file} add_short_help $itk_component(record) {Record images from camera to file} add_short_help $itk_component(stop) {Stop record/playback} } # Method to add the menu bar to the top of the dialogue. protected method add_menubar {} { global ::$w_.cmode ::$w_.pbspeed TopLevelWidget::add_menubar # File menu set m [add_menubutton File] add_menuitem $m command "Load File..." \ {Load a file for recording or playing} \ -command [code $this chooseFile] add_menuitem $m command "Exit" \ {Exit the application} \ -command [code $this close] # Options menu set m [add_menubutton "Options"] # Change the maximum allowed file size add_menuitem $m command "Maximum File Size..." \ {Alter the minimum possible interval between image send events} \ -command [code $this set_max_filesize] # Image cycle mode add_menuitem $m checkbutton \ "Cycle Mode" \ {Turn the image cycling on or off} \ -variable $w_.cmode -onvalue 1 -offvalue 0 \ -command [code $this stop] # Change the playback speed add_menuitem $m cascade "Playback Speed" \ {Set the speed at which to play back images} \ -menu [menu $m.pb] # NB the values given to these compression types correspond to the # ENUM which defines the Playback speed in RtdRPTool.h. $m.pb add radiobutton \ -label "Real Time" \ -command [code $this stop] \ -variable $w_.pbspeed \ -value 2 $m.pb add radiobutton \ -label "Slow" \ -command [code $this stop] \ -variable $w_.pbspeed \ -value 0 $m.pb add radiobutton \ -label "Fast" \ -command [code $this stop] \ -variable $w_.pbspeed \ -value 1 $m add separator # Edit the window add_menuitem $m command "Edit Record Window..." \ {Edit the region of the image to record} \ -command [code $this edit_window] add_menuitem $m command "Reset Record Window" \ {Reset the region of the image to record to full image} \ -command [code $this reset_window] } # inititialize trace variables protected method trace_counts {} { set var1 $rtdrecorder_ global ::$var1 set var2 $rtdplayback_ global ::$var2 set ${var1}(COUNT) 1 set ${var2}(COUNT) 1 trace variable ${var1}(COUNT) w [code $this update_progress] trace variable ${var2}(COUNT) w [code $this update_progress] } # update progress bar and image count public method update_progress {args} { global ::$w_.cmode ::$w_.direction if {$recording_} { set var $rtdrecorder_ } else { set var $rtdplayback_ } global ::$var lassign [set ${var}(COUNT)] count ncount bof eof if {[set $w_.direction] != 0 && !$recording_} { lassign "$bof $eof" eof bof } $itk_component(imagecount) config -value $count $itk_component(ncounts) config -value $ncount set w $itk_component(progressBar) $w config -state normal $w config -from 0 -to $ncount -sliderlength 25 -troughcolor blue -bg grey80 $w set [expr {$count -1}] update $w config -state disabled # puts "$count,$ncount bof=$bof eof=$eof" if {([set $w_.cmode] == 0 && $eof != 0)} { # return to interpreter. Do not send commands to a subimage! after idle "$this stop" } } # method to set/reset cycle mode public method set_cycle_mode {} { global ::$w_.cmode $rtdrecorder_ cycle [set $w_.cmode] } # Reset the window to send to full image. public method reset_window {} { stop set subimage_ 0 if {[winfo exists $w_.subimage]} { destroy $w_.subimage } } # Set the recorder properties prior to starting recording. public method recorder_props {} { global ::$w_.cmode $rtdrecorder_ file size $maxFile_ $rtdrecorder_ cycle [set $w_.cmode] $rtdrecorder_ filename $imageFile_ $rtdrecorder_ camera $camera_ set attached_ 0 if {$subimage_ == 0} { $rtdrecorder_ subimage off } else { $rtdrecorder_ subimage on $x0_ $y0_ $width_ $height_ } } # Set the playback props prior to starting a playback. public method playback_props {} { global ::$w_.cmode ::$w_.pbspeed ::$w_.direction if {[set $w_.direction] == 1} { set dir 0 } else { set dir 1 } $rtdplayback_ filename $imageFile_ $rtdplayback_ cycle [set $w_.cmode] if {[catch {$rtdplayback_ props speed [set $w_.pbspeed]} msg]} { error_dialog $msg return 1 } $rtdplayback_ props direction $dir return 0 } # Set file protect mode public method protect {} { global ::$w_.protect if {[set $w_.protect]} { $itk_component(record) config -state disabled } else { $itk_component(record) config -state normal } } # Edit the record window public method edit_window {} { stop if {[$target_image_ isclear]} { warning_dialog "No image is currently loaded" $w_ return } if {$playing_ == 1 || $spooling_ == 1} { warning_dialog "Stop playback before selecting record window" $w_ return } if {[winfo exists $w_.subimage]} { destroy $w_.subimage } if {[action_dialog \ "Please select and drag out a region of the image with mouse button 1" \ $w_]} { [$target_image_ component draw] set_drawing_mode region [code $this make_rapid_frame] } } # create a rapid frame. protected method make_rapid_frame {region_id x0 y0 x1 y1} { set xoffset [expr {int($x0)}] set yoffset [expr {int($y0)}] set width [expr {int($x1-$x0+1)}] set height [expr {int($y1-$y0+1)}] set subimage_ 1 RtdImageFrame $w_.subimage \ -target_image $target_image_ \ -xoffset $xoffset \ -yoffset $yoffset \ -width $width \ -height $height \ -region_id $region_id \ -verbose 0 \ -command [code $this set_subimage] } # set the values of x0_, y0_, width_ and height_ from # the subimage coordinates protected method set_subimage {frameId name op x y w h} { set im [$target_image_ get_image] $im convert coords $x $y canvas x0_ y0_ image $im convert dist $w $h canvas width_ height_ image } # Set the maximum allowed file size in recording images public method set_max_filesize {} { utilReUseWidget InputDialog $w_.maxfsize \ -title "Maximum File Size" \ -text "Set maximum recording file size in Mb (currently $maxFile_ Mb)" \ -modal 1 \ -bitmap information \ -buttons {OK Cancel} set val_returned [$w_.maxfsize activate] if {$val_returned != ""} { set maxFile_ $val_returned } } # Creates the dialog for choosing the file to record to or to # play from public method chooseFile {{file ""}} { global ::$w_.protect if {"$file" == ""} { set file [filename_dialog [pwd] * $w_] if {"$file" == ""} { $itk_component(filename) config -value $imageFile_ return } } set file [fits_pathname $file] if {[file isdir $file]} { error_dialog "$file is a directory" $w_ return } if {[llength $file] != 0} { set $w_.protect 1 stop $rtdplayback_ reset set imageFile_ $file } $itk_component(filename) config -value $imageFile_ } # return 'globbed' pathname for a fits file. If the extension is # not set in $file then .fits is used public method fits_pathname {file} { set dirname [lindex [file dirname $file] 0] if {[catch {glob $dirname} dirname]} { return $file } set basename [file split $file] set basename [lindex $basename [expr {[llength $basename] -1}]] set ext [file extension $file] if {"$ext" == ""} { set file [file join $dirname $basename.fits] } else { set file [file join $dirname $basename] } if {[catch {glob $file} gfile]} { return $file } return $gfile } # Set camera name public method chooseCamera {camera {stop 0}} { set recflg 0 if {($stop && ! $recording_) || ([llength $camera] != 0 && "$camera_" != "$camera")} { if {$recording_} { set recflg 1 } stop set camera_ $camera $rtdplayback_ reset } $itk_component(cameraname) config -value $camera_ if {$recflg} { # resume recording after camera name has changed after idle "$this record" } } # Loads the file into the recorder object property table, and starts # recording. public method record {} { global ::$w_.protect ::$w_.direction if {$recording_ == 1} { return } if {[set $w_.protect]} { error_dialog "Unset 'Protect' in order to write to file $imageFile_" return } stop 0 if {[check_file]} { return } if {$camera_ == ""} { error_dialog "You must choose a camera name" return } $rtdplayback_ reset recorder_props if {[catch {$rtdrecorder_ record} msg]} { error_dialog $msg return } set recording_ 1 set $w_.direction 0 $itk_component(filename) config -value $imageFile_ $itk_component(imagecount) config -value "" $itk_component(ncounts) config -value "" config -state disabled $itk_component(menubar).file config -state disabled $itk_component(menubar).options config -state disabled $itk_component(record) config -relief sunken } # start playback. public method play {} { global ::$w_.pbspeed if {[winfo exists $w_.subimage]} { destroy $w_.subimage } set err 0 if {[catch {set err [playcmd $itk_component(play) play]} msg] || $err} { if {! $err} { warning_dialog "$msg" } return } set playing_ 1 if {![$rtdplayback_ hastime] && [set $w_.pbspeed] == 2} { warning_dialog "File does not include timestamp information for real-time playback" } } # check that the image file name is valid public method check_file {} { if {[llength $imageFile_] == 0} { error_dialog "You must choose a file name" return 1 } return 0 } # set the spool mode ("rewind", "ff"). public method spool {arg} { set widg "" if {"$arg" == "ff"} { set widg $itk_component(ff) } if {[playcmd $widg spool $arg] != 0} { return } if {"$arg" == "ff"} { set spooling_ 1 } } # single step image public method single {} { playcmd "" step } # start playing back images public method playcmd {widg cmd args} { # Check the current state of the dialogue if {$recording_} { return 1 } set_normal if {[winfo exists $widg]} { $widg config -relief sunken } stop 0 if {[check_file]} { return 1 } # Attach the RTD camera to the recorder/playback tool. if {[attach_to_camera] != 0} { return 1 } # Reset the playback properties before starting if {[playback_props]} { return 1 } # Execute command set cmd "$rtdplayback_ $cmd [set args]" if {[catch {eval $cmd} msg]} { stop warning_dialog $msg return 1 } return 0 } # stop the recorder public method stop {{hardstop 1}} { if {$hardstop} { catch {$target_image_ detach_camera} set attached_ 0 } # Call the appropriate stop method if {$recording_ == 1} { $rtdrecorder_ stop } if {$playing_ == 1 || $spooling_ == 1} { $rtdplayback_ stop } # Configure the original server camera $mainwidg_ config -camera $itk_option(-server_camera) set recording_ 0 set playing_ 0 set spooling_ 0 if {![winfo exists $w_]} { return } if {$hardstop} { set_normal } } # set the state to normal. public method set_normal {} { config -state normal $itk_component(menubar).file config -state normal $itk_component(menubar).options config -state normal foreach el {play ff rewind single record} { $itk_component($el) config -relief raised } } # stop all actions and delete window. public method close { } { stop destroy $w_ } # This method attaches the RTD to the RTDRPTOOL camera for the purposes # of image playback. A check is made to see if the RTD is already # attached. public method attach_to_camera {} { # If we are already attached then return immediately. if {$attached_ == 1} { return 0 } # Attach the RTD to RTDRPTOOL. if {[catch {$target_image_ attach_camera "RTDRPTOOL"} msg]} { if {"$smg" != ""} { #warning_dialog $msg } return 1 } set attached_ 1 # Allow the re-attachment of the RTD to RTDRPTOOL to complete before # the next action takes place; occasionally an image would be sent to # the rtdServer between detachment and re-attachment and so would be lost. update idletasks return 0 } # go to the selected image public method gotoImage {arg} { global ::$w_.cmode ::$w_.direction if {$arg == ""} { return } set cmodesv $w_.cmode if {![set $w_.cmode]} { set $w_.cmode 1 } if {[set $w_.direction]} { incr arg } playcmd "" gotoimage $arg single if {$cmodesv != [set $w_.cmode]} { set $w_.cmode $cmodesv playback_props } } # set global parameters public method set_globals {vars value} { foreach el [set vars] { global ::$w_.$el set $w_.$el $value } } #-------------------------------------------------------------------- # variables #-------------------------------------------------------------------- # target (main) RtdImage itcl widget itk_option define -target_image target_image Target_image {} { set target_image_ $itk_option(-target_image) set mainwidg_ [winfo parent [$target_image_ component hull]] } # font used for labels itk_option define -labelfont labelFont LabelFont TkDefaultFont # font used for values itk_option define -valuefont valueFont ValueFont TkDefaultFont # server camera name itk_option define -server_camera server_camera Server_camera {} # set the state to normal/disabled itk_option define -state state State {normal} # main widget name protected variable mainwidg_ # name of target rtd image protected variable target_image_ # name of rtdrecorder image object for recording images protected variable rtdrecorder_ # name of rtdplayback image object for playback of images protected variable rtdplayback_ # flag: true if playing back images protected variable playing_ 0 # flag: true if recording images protected variable recording_ 0 # flag: true if spooling (rewind, ff) protected variable spooling_ 0 # max record file size in MB protected variable maxFile_ 5 # name of rtdimage camera for receiving images from the rtdserver protected variable camera_ # file for recording images protected variable imageFile_ "RTDRPTOOL.fits" # Variables pertaining to the subimage sampling facility protected variable subimage_ 0 protected variable x0_ 0 protected variable y0_ 0 protected variable width_ 0 protected variable height_ 0 # Variable for indicating whether RTD is currently attached to RTDRPTOOL. protected variable attached_ 0 } skycat-3.1.2-starlink-1b/rtd/library/RtdRemoteTcl.tcl000077500000000000000000000027511215713201500224560ustar00rootroot00000000000000#******************************************************************************* # E.S.O. - VLT project # # "@(#) $Id: RtdRemoteTcl.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # RtdRemoteTcl.tcl - procedures for the Rtd remote Tcl interface # # who when what # -------------- --------- ---------------------------------------- # Peter Biereichel 11/08/99 created # connect to a running Rtd process and return the file descriptor # for the connection socket. proc connect_to_rtd {} { global env # get the hostname and port info from the file ~/.rtd-remote, # which is created by rtdimage when the remote subcommand is used if {[catch {set fd [open $env(HOME)/.rtd-remote]} msg]} { puts "can't open ~/.rtd-remote: make sure rtd is running: $msg" return 0 } lassign [read $fd] pid host port #puts ".rtd-remote: pid=$pid, host=$host, port=$port" close $fd if {[catch {exec kill -0 $pid} msg]} { return 0 } set fd [server_connect -nobuf $host $port] return $fd } # send the command to rtd and return the result proc send_to_rtd {rtd_fd cmd} { puts $rtd_fd $cmd lassign [gets $rtd_fd] status length set result {} if {$length > 0} { set result [read $rtd_fd $length] } if {$status != 0} { #puts $result } return $result } # execute tcl command proc etcl {rtd_fd cmd} { #puts "Tcl command: $cmd" set ret [send_to_rtd $rtd_fd "remotetcl {$cmd}"] #puts "Reply: $ret" return $ret } skycat-3.1.2-starlink-1b/rtd/library/main.tcl000066400000000000000000000124551215713201500210310ustar00rootroot00000000000000# -*-tcl-*- # # E.S.O. - VLT project # # "@(#) $Id: main.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # rtd - main entry point for real-time image display application # # Usage: rtd ?options? # # where ?options? are the same as the "public" variables in the main # itcl class Rtd and take the form: -option value ...` # # See man page rtd(1) for a complete description. # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 20/05/95 created # pbiereic 16/08/99 added option -help # pbiereic 05/02/03 added rtd_versionId so that the version can # be printed with ´what rtd´ (see SPR). # A.Brighton 29/12/05 rewrote for new setup package require Rtd set rtd_versionId {@(#) $Id: main.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $} set rtd_usage { Usage: rtd ?fitsFile? ?-option value ...? Options: -attach bool - attach to camera -camera - camera name: def: \$RTD_CAMERA, if set, otherwise \$RTDSIMULATOR -colorramp_height - height of colorramp window (default: 12) -colorramp_height - height of color bar -debug bool - debug flag: turn on real-time simulation -default_cmap - default colormap -default_itt - default intensity transfer table -disp_image_icon bool - display a copy of the image in the icon (default) -dozoom bool - turn on zoom window (default) -file - fits file to load ('-' for stdin) -float_panel bool - put info panel in a popup window (default: 0) -help - print this text -image_directory - default directory for loading images -interval - for real-time simulation: update interval in ms (def: 500) -max_scale - maximum scale for magnification menu (default: 20). -min_scale - minimum scale for magnification menu (default: -10). -pan_height - height of pan window (default: 152) -pan_width - width of pan window (default: 152) -panel_layout - panel layout, one of: "saoimage", "reverse", "default" -panel_orient - panel orientation, one of: "horizontal", "vertical" -port - listen for remote cmds on port (default: 0 = choose port) -subsample bool - use subsampling when shrinking the image (default: 1 = on). -sampmethod - sampling method when subsample=0 (default: 0 = max value). -rtd_geometry - window geometry -rtd_title - string for title bar -scrollbars bool - display scrollbars (not displayed by default) -testprog - prog to use for real-time simulation (default: tRtd) -usexshm bool - use X shared mem, if available (default) -verbose bool - print diagnostic messages -with_colorramp bool - display the color bar (default) -with_grid bool - Include a WCS grid button (default: 0 = off). -with_pan_window bool - display the pan window (default)) -with_warp bool - add bindings to move mouse ptr with arrow keys (default: 1). -with_zoom_window bool - display the zoom window (default)) -xscale - default scaling factor -yscale - default scaling factor -zoom_factor - zooming factor (default: 4) -zoom_height - height of zoom window (default: 152) -zoom_width - width of zoom window (default: 152) } if {[info exists argv]} { if {[regexp -- "-help" $argv]} { puts $rtd_usage exit 0 } } set tk_strictMotif 1 catch {tk appname Rtd} tk_focusFollowsMouse if { [catch {utilPrintErrors} msg ] } { puts "Error when autoloading 'utilPrintErrors'.\nauto_path=$auto_path\nCheck installation:\n\n$msg" exit 1 } # XXX temp hack until panel editor is fixed to only require Rtd when needed image delete [image create rtdimage] # Start the application class Rtd: # # Note that "start" is a "member" proc in the TopLevelWidget class # (of which Rtd is a subclass). It creates an instance of the Rtd # application class and handles options and error checking. # Specify a list of valid options (workaround for tcl or itcl bug (?) that # crashes app if option is unknown...) set optlist [list \ -attach \ -camera \ -color_scale \ -colorramp_height \ -debug \ -default_cmap \ -default_itt \ -disp_image_icon \ -dozoom \ -drag_scroll \ -feedback \ -file \ -float_panel \ -image_directory \ -interval \ -max_scale \ -min_scale \ -pan_height \ -pan_width \ -panel_layout \ -panel_orient \ -pickobjectorient \ -port \ -rapid_frame_command \ -regioncommand \ -remote \ -rtd \ -rtd_geometry \ -rtd_title \ -scrollbars \ -shm_data \ -shm_header \ -shorthelpwin \ -subsample \ -sampmethod \ -testprog \ -updatePick \ -use_zoom_view \ -usexshm \ -usexsync \ -verbose \ -with_colorramp \ -with_grid \ -with_pan_window \ -with_perftest \ -with_warp 1 \ -with_zoom_window \ -xscale \ -yscale \ -zoom_factor \ -zoom_height \ -zoom_view_propagate \ -zoom_width \ ] util::TopLevelWidget::start Rtd "-file" "$rtd_usage" "" 1 $optlist skycat-3.1.2-starlink-1b/rtd/library/mkIndex.tcl000077500000000000000000000003231215713201500214760ustar00rootroot00000000000000#!../bin/rtdimage_wish # # mkIndex.tcl - generate a tclIndex file in the current directory # "@(#) $Id: mkIndex.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" package require Itcl auto_mkindex . *.tcl exit 0 skycat-3.1.2-starlink-1b/rtd/library/rtd_defaults.tcl000066400000000000000000000012711215713201500225570ustar00rootroot00000000000000# E.S.O. - VLT project # "@(#) $Id: rtd_defaults.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # defaults.tcl - set widget defaults # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 11 Oct 95 created # set general widget defaults proc rtd::setXdefaults {} { util::setXdefaults option add *RtdImage.canvasBackground black option add *RtdImageCtrl.canvasBackground black option add *RtdImageCtrl.canvasWidth 520 option add *RtdImageCtrl.canvasHeight 520 option add *RtdImagePan.background black option add *RtdImageTrans.relief flat option add *RtdImageColorRamp.cursor exchange } skycat-3.1.2-starlink-1b/rtd/library/tRtd.tcl000066400000000000000000000137021215713201500210160ustar00rootroot00000000000000# E.S.O. - VLT project # "@(#) $Id: tRtd.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # tRtd.tcl - itcl widget for starting tRtd # # This class starts the camera test task tRtd with user defined options. # If the name of the testprogram is not tRtd then the testprogram is # started in a backwards compatible way. # # who when what # -------------- --------- ---------------------------------------- # pbiereic 01/03/01 Created itk::usual tRtd {} itcl::class rtd::tRtd { inherit util::TopLevelWidget constructor {args} { eval itk_initialize $args wm protocol $w_ WM_DELETE_WINDOW [code $this close] wm title $w_ "tRtd Control" } destructor { if { $tRtdPid_ > 0 } { catch { kill $tRtdPid_ } } } protected method init {} { # compatible to previous versions (maybe this option was never used) if { "$itk_option(-testprog)" != "$tRtd_" } { wm withdraw $w_ if { $tRtdPid_ > 0} { catch {kill $tRtdPid_} } if {[catch {set tRtdPid \ [exec $itk_option(-testprog) \ -v $itk_option(-verbose) \ -t $itk_option(-interval) &]} msg]} { error_dialog "error starting $itk_option(-testprog): $msg" } return } make_layout start } protected method make_layout {} { global ::$rtdimage_ set optf [frame $w_.optf -borderwidth 2 -relief groove] pack $optf -fill both -expand 1 foreach {opt text validate default} { \ v "Verbose flag" numeric 0 \ c "Camera name" alphanumeric rtdtest \ t "Update interval in msecs" numeric 500 \ W "Main frame width" numeric 255 \ H "Main frame height" numeric 255 \ x "Rapid frame start x" numeric 0 \ y "Rapid frame start y" numeric 0 \ w "Rapid frame width (N/A)" numeric 255 \ h "Rapid frame height (N/A)" numeric 255 \ f "Rapid frame Id" numeric 0 \ b "#of shared memory buffers" numeric 2 \ l "Use semaphore locking" numeric 1 \ I "File ngc1275.fits. Directory:" none ""} { set wdg $optf.tRtd$opt set var ${rtdimage_}(tRtd$opt) itk_component add $opt { LabelValue $wdg \ -textvariable $var \ -text $text \ -relief groove \ -justify right \ -state normal \ -valuewidth 10 \ -labelwidth 22 \ -validate $validate \ -command [code $this start] \ -anchor w } { keep -state } lappend vars_ "-$opt [$wdg cget -textvariable]" set $var $default [$wdg component entry] config -state normal \ -relief sunken pack $wdg -fill both -expand 1 } set butf [frame $w_.butf -borderwidth 2 -relief groove] pack $butf -fill both -expand 1 foreach {but} {start stop rapid default close} { itk_component add $but { button $butf.$but -text [string toupper $but] \ -command [code $this $but] -padx 1 } { keep -state } pack $butf.$but -fill none -expand 1 -side left -ipadx 2 -padx 2 } } # start process tRtd with options. Before make sure that the previous # process has terminated. public method start {args} { stop if {$tRtdPid_ > 0 } { after 100 [code $this start] return } global ::$rtdimage_ foreach el $vars_ { if {! [lempty [set [lindex $el 1]]]} { append opts "[lindex $el 0] [set [lindex $el 1]] " } } # puts $opts $rtdimage attach_camera $itk_option(-camera) if { [set ${rtdimage_}(tRtdv)] } { set tRtdPid_ [eval exec xterm -e $itk_option(-testprog) $opts &] } else { set tRtdPid_ [eval exec $itk_option(-testprog) $opts &] } } public method stop {args} { if {"[cget -state]" == "disabled"} { return } $rtdimage detach_camera if { $tRtdPid_ > 0 } { catch { kill $tRtdPid_ } config -state disabled tRtdWait } } public method tRtdWait {args} { if { [catch {wait -nohang $tRtdPid_} msg]} { config -state normal set tRtdPid_ -1 } else { update after 100 [code $this tRtdWait] } } public method default {args} { stop destroy $w_.optf $w_.butf make_layout } public method rapid {args} { stop $rtdimage config -rapid_frame_command [code $this rapid_frame_command] $rtdimage rapid_frame 1 } public method rapid_frame_command {f name op x y w h} { global ::$rtdimage_ stop if {"$op" == "delete"} { return } set y [expr {[$rtdimage_ height] - $y - $h}] $rtdimage_ convert dist $x $y canvas x y image $rtdimage_ convert dist $w $h canvas w h image if {$x < 0} { set x 0 } if {$y < 0} { set y 0 } foreach el "f x y w h" { set ${rtdimage_}(tRtd$el) [set $el] } start } public method close {} { stop # compatible to previous versions: if { "$itk_option(-testprog)" != "$tRtd_" } { return } wm withdraw $w_ } # -- public variables (also program options) -- # camera name itk_option define -camera camera Camera {} # Main Rtd image itk_option define -rtdimage rtdimage Rtdmage {} { if {[winfo exists [cget -rtdimage]]} { set rtdimage [cget -rtdimage] set rtdimage_ [$rtdimage get_image] } } # for testing: name of test program used to generate real-time updates itk_option define -testprog testProg TestProg {} # default interval between updates in ms itk_option define -interval interval Interval {} # flag: if true, print diagnostic messages itk_option define -verbose verbose Verbose {0} itk_option define -buttons buttons Buttons {start stop cancel} itk_option define -state state State {normal} # -- protected variables -- # pathname of main image protected variable rtdimage # name of main image object protected variable rtdimage_ # pid of test prog used to generate frames (debug) protected variable tRtdPid_ -1 # default name of test program protected variable tRtd_ "tRtd" # variables used by entries protected variable vars_ } skycat-3.1.2-starlink-1b/rtd/man/000077500000000000000000000000001215713201500165015ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/rtd/man/ColorMapInfo.man3000066400000000000000000000065461215713201500216240ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: ColorMapInfo.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 20 Jul 95 Created NAME ColorMapInfo - A C++ class for reading and managing color map files SYNOPSIS #include "ColorMapInfo.h" enum {MAX_COLOR=256}; /* work with 8 bit color */ // one of these is used to hold colormap info for each colormap // file read class ColorMapInfo { ... public: ColorMapInfo(char* name, ColorMapInfo* next = NULL); ~ColorMapInfo(); // create and return ColorMap from a file description static ColorMapInfo* read(char* filename, ColorMapInfo* next = NULL); // member access char* name(); ColorMapInfo* next(); // set the red, green and blue values from the colormap data // and interpolate based on the count of available colors void interpolate(XColor* colorCells, int colorCount); // rotate the colormap by the given amount void rotate(int amount, XColor* src, XColor* dest, int colorCount); // shift the colormap by the given amount void shift(int amount, XColor* src, XColor* dest, int colorCount); }; DESCRIPTION This class is used by class ImageColor to read in and manage a single colormap file. The constructor is not normally called from outside the class. To create an object of this class, the static "read" member function reads in a colormap file (256 lines of RGB values between 0.0 and 1.0) and returns a pointer to a new ColorMapInfo instance for the file. Reading in the colormap only stores the values in memory, To apply the colormap file to the default colormap, the interpolate method is called. Most methods take a colorCount argument, which is the number of colors allocated in the colormap. The rotate and shift methods take an integer "amount" argument, which is typically the difference in mouse movements in some widget and is used to rotate (with wrap around) or shift (without wrap around) the colormap by the given amount. METHODS static ColorMapInfo* read(char* filename, ColorMapInfo* next = NULL) Create and return a ColorMapInfo from a file description. The next argument is used to build a list of loaded colormaps. char* name() Return the name (file name) of the colormap loaded. ColorMapInfo* next() Return a pointer to the next colormap in the list. void interpolate(XColor* colorCells, int colorCount) Set the red, green and blue values in the colormap (in the colorCells array) from the loaded colormap data and interpolate based on the count of available colors. void rotate(int amount, XColor* src, XColor* dest, int colorCount) Rotate the colormap by the given amount. "src" is the source colormap, dest is the destination colormap and colorCount gives the number of colors in src and dest. void shift(int amount, XColor* src, XColor* dest, int colorCount); Shift the source colormap by the given amount, putting the result in dest. colorCount is the number of colors in src and dest. FILES $RTD_LIBRARY/../colormaps/*.lasc - MIDAS colormap files SEE ALSO ImageColor, ITTInfo(3C++) -------------------------------------------------------------------- skycat-3.1.2-starlink-1b/rtd/man/ITTInfo.man3000066400000000000000000000054311215713201500205400ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: ITTInfo.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 20 Jul 95 Created NAME ITTInfo - C++ class for reading and managing MIDAS ITT (intensity transfer table) files SYNOPSIS #include "ITTInfo.h" // one of these is used to hold ITT info for each ITT // file read class ITTInfo { ... public: ITTInfo(char* name, ITTInfo* next = (ITTInfo*)NULL); ~ITTInfo(); // create and return ITT from a file description static ITTInfo* read(char* filename, ITTInfo* next = (ITTInfo*)NULL); // member access char* name() {return name_;} ITTInfo* next() {return next_;} // Copy the rgb color values from colorCells to copyCells and interpolate based // on the ITT table and the count of available colors void interpolate(XColor* src, XColor* dest, int colorCount); // Copy the rgb color values from colorCells to copyCells as above, // and also scale the ITT values by the given amount void scale(int amount, XColor* src, XColor* dest, int colorCount); }; DESCRIPTION This class is used to read in and manage an ITT (intensity transfer table) file in MIDAS format, which is 256 lines of values between 0.0 and 1.0, which are applied to the colormap color values to modify the colormap. Most methods take a colorCount argument, which is the number of colors allocated in the colormap. The scale method take an integer "amount" argument, which is typically the difference in mouse movements in some widget and is used to stretch or squeeze the ITT (and colormap) by the given amount. METHODS static ITTInfo* read(char* filename, ITTInfo* next = NULL) Create and return an ITTInfo from a file description. The next argument is used to build a list of loaded ITTs. char* name() Return the name (file name) of the ITT loaded. ITTInfo* next() Return a pointer to the next ITT in the list. void interpolate(XColor* src, XColor* dest, int colorCount) Copy the rgb color values from src to dest and interpolate based on the ITT table and the count of available colors. void scale(int amount, XColor* src, XColor* dest, int colorCount); Copy the rgb color values from src to dest as above, and also scale the ITT values by the given amount. Values greater than 1.0 "stretch" the ITT/colormap, values between 0.0 and 1.0 "sqeeze" it. FILES $RTD_LIBRARY/../colormaps/*.iasc - MIDAS ITT files SEE ALSO ImageColor, ColorMapInfo(3C++) -------------------------------------------------------------------------------------------- skycat-3.1.2-starlink-1b/rtd/man/ImageColor.man3000066400000000000000000000117671215713201500213160ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: ImageColor.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 20 Jul 95 Created NAME ImageColor - A C++ class for managing image colors SYNOPSIS #include "ImageColor.h" /* * An instance of this class is used to manage colors and colormaps * for RtdImage and derived widgets */ class ImageColor { ... public: // constructor ImageColor(Display*, Visual*, int numColors); // member functions int numFreeColors(); int allocate(int numFreeColors); int reallocate(int numFreeColors); // load (reload) a color map from the given file int loadColorMap(char* filename); // load (reload) an ITT from the given file int loadITT(char* filename); // rotate the colormap by the given amount int rotateColorMap(int amount); // shift the colormap by the given amount int shiftColorMap(int amount); // scale the current colormap/ITT by the given amount int scaleITT(int amount); // reset colormap to original state int reset(); // start using a private colormap int usePrivateCmap(); // return true if we are using a private colormap int usingPrivateCmap() {return (colormap_ != defaultCmap_);} // if we are using a private colormap, set it for the given window int setColormap(Tk_Window); // member access int freeCount() {return freeCount_;} int colorCount() {return colorCount_;} unsigned long* pixelval() {return pixelval_;} unsigned long pixelval(int i) {return pixelval_[i];} XColor* colorCells() {return itt_ ? ittCells_ : colorCells_;} }; DESCRIPTION This class is used to manage the colormap for an image display application. This is normally the default colormap, however, if not enough colors can be allocated, a private colormap can be created and an attempt is made to reduce color flashing by copying the colors from the default colormap to the new one. Normally, only a single instance of the ImageColor class is required per application. Class ImageColor modifies the colormap by allocating a given number of color cells and assigning color values to cells based on MIDAS colormap and ITT (intensity transfer table) files. Methods are also available for rotating, shifting, stretching and squeezing the colormap. MIDAS COLORMAP FILES The colormap files used here were taken in ascii form from the MIDAS distribution. A colormap file has 256 lines of red, green, blue floating point values between 0.0 and 1.0. The values are scaled to the size of the colormap (the number of allocated colors) at run time. MIDAS ITT FILES An ITT file is like a colormap file, except that there is only one value per line (256 lines). Each value is between 0.0 and 1.0 and is used to modify the colormap. For example, to get a negative of an image, a negative ITT would have values starting at 1.0 and ending at 0.0, equally spaced. CONSTRUCTOR The constructor takes as arguments, a pointer to the X display (for colormap operations) and the number of colors to allocate. If there are not that many colors available, then the actual number allocated will be less. METHODS int numFreeColors() Return the number of free color cells available (uses a binary search between 0 and MAX_COLOR). int allocate(int numFreeColors) Allocate at most numColors color cells. If there are not that many colors available, then the actual number allocated will be less. int reallocate(int numFreeColors) Free and then re-allocate at most numColors color cells. int loadColorMap(char* filename) Load a color map from the given file, where file contains 256 lines of (r g b) values. int loadITT(char* filename) Load an intensity transfer table (ITT) from the given file where file contains 256 ITT values, one per line. int rotateColorMap(int amount) Rotate the colormap by the given amount. int shiftColorMap(int amount) Shift the colormap by the given amount. int scaleITT(int amount) Scale (squeeze or stretch) the current colormap/ITT by the given amount. int reset() Reset colormap to original state. int freeCount() Return the number of free colors available. int colorCount() Return the number of colors allocated. unsigned long* pixelval() Return the array of pixel values for the allocated colors in the colormap. unsigned long pixelval(int i) Return the colormap pixel value at the given index. XColor* colorCells() Return pointer to array of XColors used for colormap. int usePrivateCmap() Start using a private colormap. int usingPrivateCmap() Return true if we are using a private colormap. int setColormap(Tk_Window) If we are using a private colormap, set it for the given window. SEE ALSO ColorMapInfo, ITTInfo(3C++) ----------------------------------------------------------------------------- skycat-3.1.2-starlink-1b/rtd/man/ImageDisplay.man3000066400000000000000000000047101215713201500216330ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: ImageDisplay.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 20 Jul 95 Created NAME ImageDisplay - A C++ class for managing the display of an XImage SYNOPSIS #include "ImageDisplay.h" class ImageDisplay { ... public: // constructor ImageDisplay(Display *display, Visual *visual, GC gc, int depth, int useXShm, int verbose); // destructor ~ImageDisplay(); // create or update an XImage with the given size int update(int width, int height); // copy the XImage to a Drawable in the X Server void put(Drawable, int src_x, int src_y, int dest_x, int dest_y, int width, int height); // return a pointer to the XImage data unsigned char* data(); // inline query methods int width(); int height(); int bitmapPad(); int bytesPerLine(); // return true if we are really using X shared memory int usingXShm(); }; DESCRIPTION This class manages the creation, display and disposal of an XImage, optionally using X shared memory, if available. CONSTRUCTOR The constructor takes as arguments: the X display, visual, GC and image depth, all for later reference in X calls. In addition, 2 flags may be specified: "useXshm" is set to true if X shared memory should be tried for and "verbose" is set to true if diagnostic messages should be printed out at run time. METHODS There are two main methods. One to create or update an XImage and one to copy it to the X server: int update(int width, int height) Create or update the XImage so that it has the given width and height, using X shared memory, if applicable. void put(Drawable d, int src_x, int src_y, int dest_x, int dest_y, int width, int height) Copy the contents of the XImage to the given drawable with the given arguments, using X shared memory, if applicable. In addition, there are inline methods defined to query the XImage width and height, bytes per line and padding. Note: always use "bytesPerLine()" rather than width() in calculations, since padding in X shared memory can make the two different. SEE ALSO RtdImage --------------------------------------------------------------------------- skycat-3.1.2-starlink-1b/rtd/man/ImageZoom.man3000066400000000000000000000054761215713201500211640ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: ImageZoom.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 20 Jul 95 Created NAME ImageZoom - C++ class for RtdImage Zoom Window SYNOPSIS #include "ImageZoom.h" /* * This class implements the Zoom window for the RtdImage class */ class ImageZoom { protected: Tk_Window tkwin_; // zoom window GC gc_; // graphics context for copying pixels GC rect_gc_; // graphics context for drawing box aroung center pixels int width_; // width of displayed image int height_; // height of displayed image int zoomFactor_; // zoom factor (1...n) int zoomStep_; // value used to calculate zoom = width/factor ImageDisplay *xImage_; // class object for zoom window's X image int status_; // return value from constructor public: // constructor: initialize the zoom window ImageZoom(Tk_Window tkwin, GC copyGC, int width, int height, int factor, int usingXShm, int verbose); // destructor: clean up resources ~ImageZoom(); // called for motion events in the image to do the zooming void zoom(unsigned char* data, int x, int y, int w, int h, int xs, int ys); // return status after constructor for error checking int status() {return status_;} }; DESCRIPTION This class is used to implement one version of the RtdImage zoom window, a small window displaying a magnified area of the main image while tracking mouse pointer motion events. See RtdImageZoomView(n) for the other, which is implemented as "view" of an RtdImage widget. This simple class gets the necessary X window information from the constructor arguments. The "zoom()" method is then called for mouse pointer motion events with a pointer to the XImage data for the main image, the mouse coordinates, the width of the zoom image and the zoom factor. The zoom is done at the given factor directly from the given X Image data and a rectangle is drawn in the middle to indicate the size of a pixel in the main image. METHODS void zoom(unsigned char* data, int x, int y, int w, int h, int xs, int ys) Called for motion events in image window when zooming is on. Args: data - pointer to data being displayed x, y - coords in displayed image (XImage coordinates) w, h - width (bytesPerLine) and height of displayed image xs, ys - x and y magnification factors int status() Return status after constructor for error checking. SEE ALSO RtdImage, RtdImageCtrl(n), RtdImageZoom(n), RtdImageZoomView(n) ----------------------------------------------------------------------- skycat-3.1.2-starlink-1b/rtd/man/RtdCamera.man3000066400000000000000000000101351215713201500211230ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: RtdCamera.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 20 Jul 95 Created NAME RtdCamera - A C++ class for managing realtime image updates SYNOPSIS #include "RtdCamera.h" class RtdCamera { protected: char* name_; // some unique name (name of Tk image...) int verbose_; // flag: if true, print diagnostic messages Tcl_Interp* interp_; // Tcl interp (for file events, error handling) rtdIMAGE_EVT_HNDL* eventHndl_; // image event handle int evtError_; // error count for image events char* eventScript_; // tcl script to evaluate for each event void* shmPtr_; // pointer to shared memory area for image int shmId_; // shared memory ID for image event char* camera_; // camera name int attached_; // flag: true if we are attached to the image event // server int width_, height_; // image dimensions int type_; // image type // member called by fileEventProc for realtime image events int fileEvent(); // called to display new image from shared memory // (defined in a derived class) virtual int display(int frameId, int type, int width, int height, void* data) = 0; // start accepting events from the camera int attach(const char* camera); // stop accepting events from the camera int detach(); public: // constructor RtdCamera(const char* name, Tcl_Interp*, int verbose); // destructor ~RtdCamera(); // static file handler, called by Tk file handler for realtime image events static void fileEventProc(ClientData, int mask); // start/stop/pause or continue accepting images int start(const char* camera); int stop(); int pause(); int cont(); // make a allocated copy of the shared memory image data void* copyImage(); // return the current status of the camera int paused(); int attached(); int stopped(); void* shmPtr(); }; DESCRIPTION RtdCamera is the abstract base class for managing real-time images coming from a CCD camera. It is designed as a base class, so that it doesn't have to know anything about how to actually display an image. Class RtdImage derives a simple class from this base class and redefines the "display" method to display the incoming image. An instance of this class (actually a derived class) is created for the rtdimage(n) "camera start" command. It opens a connection to the RtdServer(1) daemon process and sets up a Tk file event handler to listen for image events. When an image event is received, this class decodes it and calls the virtual "display" method to display the image. METHODS int fileEvent() This method is called when there is a message to read from the realtime event server. Read the message and call a virtual method to display the image and evaluate the tcl event script, if there is one (not currently used, see rtdimage(n) camera command). void* copyImage() return a malloc'ed copy of the shared memory image data. void fileEventProc(ClientData clientData, int mask) This static method is called when there is a message to read from the realtime event server: pass it on to a member function. int attach(const char* camera) Start accepting events from the camera. int detach() Stop accepting events from the camera. int start(const char* camera) Start accepting images from the named camera. The "name" argument is some string that identifies the caller, such as the image name. "camera" is a string that identifies the camera. int stop() Stop accepting images from the camera. int pause() This is like stop, but keeps the camera around so that you can use "cont" to continue. int cont() Continue the camera after a pause. SEE ALSO RtdImage, rtdImageEvt, RtdServer(1), rtdimage(n) ----------------------------------------------------------------------- skycat-3.1.2-starlink-1b/rtd/man/RtdImage.man3000066400000000000000000000617711215713201500207710ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: RtdImage.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 20 Jul 95 Created # Allan Brighton 10 Apr 96 updated NAME RtdImage - The C++ class implementing the rtdimage Tk image type PARENT CLASS TkImage SYNOPSIS #include "RtdImage.h" class RtdImageOptions : public TkImageOptions {...}; #define RTD_OPTIONS ... class RtdImage : public TkImage { ... public: RtdImage(Tcl_Interp*, const char* instname, int argc, char** argv, Tk_ImageMaster master, const char* imageType, Tk_ConfigSpec* specs = (Tk_ConfigSpec*)NULL, RtdImageOptions* options = (RtdImageOptions*)NULL); ~RtdImage(); virtual int call(const char* name, int len, int argc, char* argv[]); static int CreateImage(Tcl_Interp*, char *name, int argc, char **argv, Tk_ImageType*, Tk_ImageMaster, ClientData*); static void eventProc(ClientData clientData, XEvent *eventPtr); static void motionProc(ClientData clientData); int displayImageEvent(int frameId, int type, int width, int height, int xoffset, int yoffset, const Mem& data); static int rtd_set_cmap(ClientData, Tcl_Interp* interp, int argc, char** argv); int alloccolorsCmd(int argc, char* argv[]); int autocutCmd(int argc, char* argv[]); int bitpixCmd(int argc, char* argv[]); int cameraCmd(int argc, char* argv[]); int clearCmd(int argc, char* argv[]); int cmapCmd(int argc, char* argv[]); int colorrampCmd(int argc, char* argv[]); int colorscaleCmd(int argc, char* argv[]); int convertCmd(int argc, char* argv[]); int cutCmd(int argc, char* argv[]); int dispheightCmd(int argc, char* argv[]); int dispwidthCmd(int argc, char* argv[]); int dumpCmd(int argc, char* argv[]); int fitsCmd(int argc, char* argv[]); int flipCmd(int argc, char* argv[]); int frameidCmd(int argc, char* argv[]); int freqCmd(int argc, char *argv[]); int getCmd(int argc, char* argv[]); int graphdistCmd(int argc, char* argv[]); int heightCmd(int argc, char* argv[]); int isclearCmd(int argc, char* argv[]); int ittCmd(int argc, char* argv[]); int maxCmd(int argc, char* argv[]); int maxFreqCmd(int argc, char* argv[]); int mbandCmd(int argc, char* argv[]); int minCmd(int argc, char* argv[]); int mmapCmd(int argc, char* argv[]); int motioneventCmd(int argc, char* argv[]); int objectCmd(int argc, char* argv[]); int panCmd(int argc, char* argv[]); int perfTestCmd(int argc, char *argv[]); int pixtabCmd(int argc, char* argv[]); int previewCmd(int argc, char* argv[]); int radecboxCmd(int argc, char* argv[]); int remoteCmd(int argc, char* argv[]); int remoteTclCmd(int argc, char* argv[]); int rotateCmd(int argc, char* argv[]); int scaleCmd(int argc, char* argv[]); int shmCmd(int argc, char* argv[]); int spectrumCmd(int argc, char* argv[]); int statisticsCmd(int argc, char* argv[]); int typeCmd(int argc, char* argv[]); int updateCmd(int argc, char* argv[]); int viewCmd(int argc, char* argv[]); int warpCmd(int argc, char* argv[]); int wcssetCmd(int argc, char* argv[]); int wcsshiftCmd(int argc, char* argv[]); int wcscenterCmd(int argc, char* argv[]); int wcsdistCmd(int argc, char* argv[]); int wcsequinoxCmd(int argc, char* argv[]); int wcsheightCmd(int argc, char* argv[]); int wcsradiusCmd(int argc, char* argv[]); int wcswidthCmd(int argc, char* argv[]); int widthCmd(int argc, char* argv[]); int zoomCmd(int argc, char* argv[]); int zoomviewCmd(int argc, char* argv[]); CoordinateType getCoordinateType(const char* s); int convertCoordsStr(int dist_flag, char* inx_buf, char* iny_buf, char* outx_buf, char* outy_buf, double& x, double& y, char* in_type, char* out_type); int convertCoords(int dist_flag, double& x, double& y, char in_type, char out_type); int canvasToScreenCoords(double& x, double& y, int dist_flag); int canvasToImageCoords(double& x, double& y, int dist_flag); int canvasToWorldCoords(double& x, double& y, int dist_flag); int screenToCanvasCoords(double& x, double& y, int dist_flag); int screenToImageCoords(double& x, double& y, int dist_flag); int screenToWorldCoords(double& x, double& y, int dist_flag); int imageToCanvasCoords(double& x, double& y, int dist_flag); int imageToScreenCoords(double& x, double& y, int dist_flag); int imageToWorldCoords(double& x, double& y, int dist_flag); int worldToCanvasCoords(double& x, double& y, int dist_flag); int worldToImageCoords(double& x, double& y, int dist_flag); int worldToScreenCoords(double& x, double& y, int dist_flag); int imageToChipCoords(double& x, double& y, int dist_flag); int canvasToChipCoords(double& x, double& y, int dist_flag); int screenToChipCoords(double& x, double& y, int dist_flag); int worldToChipCoords(double& x, double& y, int dist_flag); int chipToImageCoords(double& x, double& y, int dist_flag); int chipToCanvasCoords(double& x, double& y, int dist_flag); int chipToScreenCoords(double& x, double& y, int dist_flag); int chipToWorldCoords(double& x, double& y, int dist_flag); static ImageColor* colors(); int displaymode() const; int fitWidth() const; int fitHeight() const; int subsample() const; char* file() const; char* newImageCmd() const; char* name() const; int usexshm() const; int usexsync() const; int shm_header() const; int shm_data() const; int min_colors() const; int max_colors() const; int verbose() const; int dispWidth(); int dispHeight(); int imageType(); int isWcs(); char* cameraPreCmd(); char* cameraPostCmd(); ImageData* image(); }; DESCRIPTION The RtdImage C++ class implements the rtdimage Tk image type. It is a subclass of class TkImage, which implements the more general, Tk image related interface, while RtdImage implements the more specific real-time display features (see TkImage). Class RtdImage is not normally accessed from other classes (other than derived classes) directly, only via the Tcl command interface (see RtdImage(n)) and the remote control interface (see rtdRemote), so this description is aimed at those who want to understand the class inorder to modify it or subclass from it. The main interface is to the Tcl interpreter and the Tk image code. The main entry point is through the initialization routine: extern "C" int Rtd_Init(Tcl_Interp* interp) This routine is declared extern "C", since the C routine tclAppInit() needs to call it (note: tclAppInit() is usually found in the file tkAppInit.c and is required in any Tcl/Tk application for adding extensions). To add the rtdimage extension to an application, the following lines are added to its tclAppInit() routine: if (Rtd_Init(interp) == TCL_ERROR) return TCL_ERROR; Note that, since the rtdimage extension is implemented in C++, main() also needs to be compiled and linked with a C++ compiler. Since main() is also included in the tkAppInit.c file in the standard Tk distribution, you either have to compile tkAppInit.c with a C++ compiler (rename it to tkAppInit.C first) or you have to extract the main() routine and put it in a separate file (say, main.C) and compile it with a C++ compiler (In this case, main() is a very simple two-liner that simply calls Tk_Main() and returns). Rtd_Init() installs the new image type "rtdimage" so that static RtdImage member functions are called (from a table of function pointers) whenever an rtdimage is created, displayed or deleted. The static member functions are passed a pointer to client data, which is actually a pointer to the RtdImage class instance (set in the image create procedure). This pointer is used to access the class member functions to implement the image display and subcommands. IMAGE CREATION When an image of type rtdimage is created (by the Tk "image create" command), the static method "CreateImage" is called. It creates an instance of the RtdImage class and sets the client data pointer to the class instance for later reference (in the display and delete static methods). IMAGE DISPLAY HANDLING Once an image has been created, a static method in the parent class (TkImage::DisplayImage) is called whenever the image needs to be displayed or redisplayed. It, in turn calls the non-static RtdImage method displayImage() with the coordinates of the area of the image that needs to be redrawn and the X "drawable" to draw to. The display method updates the XImage for the given area and displays it in the given X drawable (see class ImageDisplay). X SHARED MEMORY RtdImage attempts to use X shared memory, if the "-usexshm" option is on (default). This improves performance, but is only available when working on the workstation console. This is taken into consideration in the display routine, when deciding whether or not to use X pixmaps to cache image data in the X server. DISPLAY MODES Two different display modes are supported: In displaymode 0, the image is always copied completely to the X server as needed. This makes scrolling smoother, since fewer trips to the X server are needed, but is not practical for large images or greatly magnified images due to memory and bandwidth constraints. This mode is however used for example, by the pan window, since it must always display the entire image (at a small size). In displaymode 1 (default), only the part of the image that is visible in the image window is considered. This generally means more frequent trips to the X server, but with less data, so in the end the performance remains acceptable for any size image. The "-displaymode" option in the Tcl command controls the setting of the display mode. UPDATING THE DISPLAY Image redisplay can be forced at any time by calling the parent class method imageChanged(). This is done, for example, when an rtdimage subcommand modifies the image in some way, for example by rotating or scaling it. The imageChanged() method tells Tk the "logical" size of the image, which is independent of the window size or the size of the XImage and/or Pixmap being used. SCROLLING AND CANVAS WINDOW An image of type rtdimage can only be displayed in a canvas window. The RtdImage class keeps track of the canvas window's scrolling offsets and uses them to help determine which part of the image to display. The image handling code (TkImage::GetImage) gets called for each widget in which the image is displayed, and this is where the check is made and the canvas window handle is saved for later reference. VIEWS Normally, a Tk image can be displayed in multiple widgets and changes in size, etc. are propagated. For the rtdimage, a different scheme was needed for sharing images, since changes in size should not be propagated to all instances of the image. For example, a panning window should display the same image, but at a smaller size and a zoom window should display the same image at a larger size, etc. The concept of a "view" of an rtdimage was implemented. This is a simple array of pointers to RtdImage objects that is updated whenever the main image is updated. ADDING NEW OPTIONS The return value from the "image create rtdimage" command in Tk is the name of the image and also the name of a new Tcl command. The options to the create command are the same as the options to the image "configure" subcommand. These options are kept in a table and can be fairly easily extended by adding entries to the table and to a simple class. Derived classes can also use the RTD_OPTIONS macro to avoid duplicating code. #define RTD_OPTION(x) Tk_Offset(RtdImageOptions, x) #define RTD_OPTIONS \ {TK_CONFIG_BOOLEAN, "-usexshm", NULL, NULL, "1", RTD_OPTION(usexshm), 0}, \ {TK_CONFIG_BOOLEAN, "-usexsync", NULL, NULL, "1", RTD_OPTION(usexsync), 0}, \ {TK_CONFIG_BOOLEAN, "-verbose", NULL, NULL, "0", RTD_OPTION(verbose), 0}, \ {TK_CONFIG_BOOLEAN, "-shm_header", NULL, NULL, "0", RTD_OPTION(shm_header), 0}, \ {TK_CONFIG_BOOLEAN, "-shm_data", NULL, NULL, "0", RTD_OPTION(shm_data), 0}, \ {TK_CONFIG_INT, "-displaymode", NULL, NULL, "1", RTD_OPTION(displaymode), 0}, \ {TK_CONFIG_INT, "-min_colors", NULL, NULL, "1", RTD_OPTION(min_colors), 0}, \ {TK_CONFIG_INT, "-max_colors", NULL, NULL, "1", RTD_OPTION(max_colors), 0}, \ {TK_CONFIG_INT, "-fitwidth", NULL, NULL, "0", RTD_OPTION(fitWidth), 0}, \ {TK_CONFIG_INT, "-fitheight", NULL, NULL, "0", RTD_OPTION(fitHeight), 0}, \ {TK_CONFIG_BOOLEAN, "-subsample", NULL, NULL, "1", RTD_OPTION(subsample), 0}, \ {TK_CONFIG_STRING, "-file", NULL, NULL, "", RTD_OPTION(file), 0}, \ {TK_CONFIG_STRING, "-newimagecmd", NULL, NULL, "", RTD_OPTION(newImageCmd), 0}, \ {TK_CONFIG_STRING, "-name", NULL, NULL, "", RTD_OPTION(name), 0} For each rtdimage configuration option, you need an entry in the above table (from RtdImage.C) and a member in the RtdImageOptions class in RtdImage.h: class RtdImageOptions : public TkImageOptions { public: int displaymode; // set mode used to display image: // 0 ==> XImage is size of image, update whole image to pixmap // 1 ==> XImage is size of window (default mode) int fitWidth; // fit the image in a window with this width int fitHeight; // and this height by shrinking the image int subsample; // if true, don't count neighboring pixels when shrinking image int usexshm; // if true, use X shared memory if available. int usexsync; // if true, use X synchronisation if available. int verbose; // if true, print program info to stdout int shm_header; // if true, keep image FITS headers in shared memory int shm_data; // if true, keep image FITS data in shared memory // (see RtdRemote remote access interface) int min_colors; // min (max) number of colors to allocate, if this many are int max_colors; // not available, use private colormap. char* file; // name of image file, if any char* name; // name for image (for debugging) char* newImageCmd; // tcl command to evaluate whenever a new (different) // image is loaded (for updates, see camera command) int fixUpdateRate; // flag: user has specified a fixed update rate, as below. double userUpdateTime; // the minimum time between updates, as specified // by the user. // constructor RtdImageOptions() : displaymode(1), fitWidth(0), fitHeight(0), subsample(0), usexshm(1), usexsync(1), verbose(0), shm_header(0), shm_data(0), min_colors(30), max_colors(60), file(NULL), name(NULL), newImageCmd(NULL), fixUpdateRate(0), userUpdateTime(0.) {} }; The values in this class are treated as read-only for the most part by RtdImage. They are normally only set by Tk_ConfigureWidget when the image is created or configured. RtdImage accesses these options through inline functions defined at the end of RtdImage.h: // read-only access to configuration options static ImageColor* colors() {return colors_;} int displaymode() const {return options_->displaymode;} int fitWidth() const {return options_->fitWidth;} int fitHeight() const {return options_->fitHeight;} int subsample() const {return options_->subsample;} char* file() const {return options_->file;} char* newImageCmd() const {return options_->newImageCmd;} char* name() const {return ((options_->name && *options_->name) ? options_->name : instname_);} int usexshm() const {return options_->usexshm;} int usexsync() const {return options_->usexsync;} int shm_header() const {return options_->shm_header;} int shm_data() const {return options_->shm_data;} int min_colors() const {return options_->min_colors;} int max_colors() const {return options_->max_colors;} int verbose() const {return options_->verbose;} Where options_ is the name of the RtdImageOptions class object. ADDING NEW IMAGE SUBCOMMANDS The rtdimage subcommands are also defined in a table. In the TclCommand class hierarchy, there is a scheme that allows subcommands to be inherited and extended at any level of the inheritance hierarchy. (Options can also be inherited by deriving a subclass of RtdImageOptions and using the #define RTD_OPTIONS in the option array.) The following table is used to declare rtdimage subcommands in RtdImage.C: /* * declare a table of image subcommands and the methods that handle them. * * NOTE: keep this table sorted, so we can use a binary search on it ! * (select lines in emacs and use M-x sort-lines) */ static class RtdImageSubCmds { public: char* name; // method name int (RtdImage::*fptr)(int argc, char* argv[]); // ptr to method int min_args; // minimum number of args int max_args; // maximum number of args } subcmds_[] = { {"alloccolors", &RtdImage::alloccolorsCmd, 0, 1}, {"autocut", &RtdImage::autocutCmd, 0, 2}, {"bitpix", &RtdImage::bitpixCmd, 0, 0}, {"camera", &RtdImage::cameraCmd, 1, 4}, {"clear", &RtdImage::clearCmd, 0, 14}, {"cmap", &RtdImage::cmapCmd, 1, 2}, {"colorramp", &RtdImage::colorrampCmd, 0, 0}, {"colorscale", &RtdImage::colorscaleCmd, 0, 1}, {"convert", &RtdImage::convertCmd, 7, 7}, {"cut", &RtdImage::cutCmd, 0, 2}, {"dispheight", &RtdImage::dispheightCmd, 0, 0}, {"dispwidth", &RtdImage::dispwidthCmd, 0, 0}, {"dump", &RtdImage::dumpCmd, 1, 5}, {"fits", &RtdImage::fitsCmd, 1, 2}, {"flip", &RtdImage::flipCmd, 1, 2}, {"frameid", &RtdImage::frameidCmd, 0, 0}, {"get", &RtdImage::getCmd, 3, 5}, {"graphdist", &RtdImage::graphdistCmd, 5, 5}, {"height", &RtdImage::heightCmd, 0, 0}, {"isclear", &RtdImage::isclearCmd, 0, 0}, {"itt", &RtdImage::ittCmd, 1, 2}, {"max", &RtdImage::maxCmd, 0, 0}, {"mband", &RtdImage::mbandCmd, 6, 6}, {"min", &RtdImage::minCmd, 0, 0}, {"mmap", &RtdImage::mmapCmd, 0, 7}, {"motionevent", &RtdImage::motioneventCmd, 0, 1}, {"object", &RtdImage::objectCmd, 0, 0}, {"pan", &RtdImage::panCmd, 1, 3}, {"perftest", &RtdImage::perfTestCmd, 1, 2}, {"pixtab", &RtdImage::pixtabCmd, 1, 3}, {"preview", &RtdImage::previewCmd, 1, 1}, {"radecbox", &RtdImage::radecboxCmd, 3, 3}, {"remote", &RtdImage::remoteCmd, 0, 1}, {"remotetcl", &RtdImage::remoteTclCmd, 1, 1}, {"rotate", &RtdImage::rotateCmd, 0, 1}, {"scale", &RtdImage::scaleCmd, 0, 2}, {"shm", &RtdImage::shmCmd, 0, 7}, {"spectrum", &RtdImage::spectrumCmd, 9, 9}, {"statistics", &RtdImage::statisticsCmd, 0, 0}, {"type", &RtdImage::typeCmd, 0, 0}, {"update", &RtdImage::updateCmd, 0, 1}, {"userfreq", &RtdImage::maxFreqCmd, 1, 1}, {"view", &RtdImage::viewCmd, 2, 11}, {"warp", &RtdImage::warpCmd, 2, 2}, {"wcscenter", &RtdImage::wcscenterCmd, 0, 2}, {"wcsdist", &RtdImage::wcsdistCmd, 4, 4}, {"wcsequinox", &RtdImage::wcsequinoxCmd, 0, 0}, {"wcsheight", &RtdImage::wcsheightCmd, 0, 0}, {"wcsradius", &RtdImage::wcsradiusCmd, 0, 0}, {"wcsset", &RtdImage::wcssetCmd, 0, 11}, {"wcsshift", &RtdImage::wcsshiftCmd, 3, 3}, {"wcswidth", &RtdImage::wcswidthCmd, 0, 0}, {"width", &RtdImage::widthCmd, 0, 0}, {"zoom", &RtdImage::zoomCmd, 1, 3}, {"zoomview", &RtdImage::zoomviewCmd, 1, 5} }; The above table maps subcommand name to class method that implements the command. The additional fields indicate the minimum and maximum number of arguments the subcommand expects (for the subcommands, argc is the number of arguments and argv[0] the first argument after the subcommand name). The parent class (and any future derived classes) also declare a similar table and also the virtual method "call", that calls a method in a class, given the method name: /* * Call the given method in this class with the given arguments * If the method is not defined here, pass on the search to the * parent class. Since this is a virtual function, the search starts * in the most specific class. */ int RtdImage::call(const char* name, int len, int argc, char* argv[]) { ... } DERIVING A SUBCLASS OF RTDIMAGE If you want to derive a class from RtdImage, in order to modify or extend its behavior in some way, this is the way you would do it: In tkAppInit.C, replace the call to Rtd_Init with your own copy of that function: say MyRtd_Init(), so that you can install your own derived class. The new function and declarations would look something like this: class MyRtdImage : public RtdImage { ... } // image structure needed for Tk images static Tk_ImageType myRtdImageType = { "rtdimage", /* name */ MyRtdImage::CreateImage, /* createProc */ TkImage::GetImage, /* getProc */ TkImage::DisplayImage, /* displayProc */ TkImage::FreeImage, /* freeProc */ TkImage::DeleteImage, /* deleteProc */ (Tk_ImageType *) NULL /* nextPtr */ }; // called from tkAppInit extern "C" int Rtd_Init(Tcl_Interp* /* interp */) { Tk_CreateImageType(&myRtdImageType); return TCL_OK; } /* * This static method is called by the Tk image code to create * a new (MyRtdImage) image. */ int RtdImage::CreateImage( Tcl_Interp *interp, // Interpreter for application containing image. char *name, // Name to use for image. int argc, // Number of arguments. char **argv, // Argument strings for options // (not including image name or type) Tk_ImageType *typePtr, // Pointer to our type record (not used). Tk_ImageMaster master, // Token for image, to be used by us in // later callbacks. ClientData *clientDataPtr)// Store manager's token (this ptr) // for image here, // it will be returned in later callbacks. { MyRtdImage* im = new MyRtdImage(interp, name, argc, argv, master); *clientDataPtr = (ClientData) im; return im->status(); } After this, you can define methods for new image commands (to be called from Tcl level), redefine some existing behavior or add interfaces to C/C++ code or other processes. To add new Tcl image subcommands, declare a table like the one described above (each class in the hierarchy that defines subcommands declares one of these). For example: /* * declare a table of image subcommands and the methods that handle them. */ static class MyRtdImageSubCmds { public: char* name; // method name int (MyRtdImage::*fptr)(int argc, char* argv[]); // ptr to method int min_args; // minimum number of args int max_args; // maximum number of args } subcmds_[] = { {"foo", &MyRtdImage::fooCmd, 1, 3}, {"bar", &MyRtdImage::barCmd, 2, 4}, .... }; Now we need to declare the virtual member function "call" to call the method to handle the Tcl subcommands (this is the same in every class, but still needs to be redefined - it probably could also be defined as a macro): /* * Call the given method in this class with the given arguments * If the method is not defined here, pass on the search to the * parent class. Since this is a virtual function, the search starts * in the most specific class. */ int MyRtdImage::call(const char* name, int len, int argc, char* argv[]) { ... } The rtdimage options can also be extended, if needed, for example: class MyRtdImageOptions : public RtdImageOptions { public: char *grid_tag; // canvas tag for all grid items char *component; // NDF component to display MyRtdImageOptions() : grid_tag(NULL), component(NULL) {} }; #define MYRTD_OPTION(x) Tk_Offset(MyRtdImageOptions, x) #define MYRTD_OPTIONS \ RTD_OPTIONS, \ {TK_CONFIG_STRING, "-grid_tag", NULL, NULL, "ast_grid_item", MYRTD_OPTION(grid_tag), 0}, \ {TK_CONFIG_STRING, "-component", NULL, NULL, "data", MYRTD_OPTION(component), 0} Each class in the hierarchy should follow these conventions and define the options as above, so that derived classes can access them and add to them. SEE ALSO TkImage, RtdImage(n), image(n), canvas(n) -------------------------------------------------------------------- skycat-3.1.2-starlink-1b/rtd/man/RtdRemote.man3000066400000000000000000000044521215713201500211730ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: RtdRemote.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 10 Apr 96 Created NAME RtdRemote - C++ class supporting remote access to an rtdimage SYNOPSIS #include "RtdRemote.h" class RtdRemote { ... public: RtdRemote(Tcl_Interp*, int port, int verbose); virtual ~RtdRemote(); static void fileEventProc(ClientData, int mask); static void clientEventProc(ClientData, int mask); int status() {return status_;}}; DESCRIPTION This class is used internally (through subclassing) by the RtdImage C++ class to support remote access via a socket interface. See rtdRemote for a description of that interface. When a remote process wants access a running rtdimage application, rtdimage commands are sent via the socket interface. A subclass of this class defines the "call" virtual method to determine the correct method to call for each message. In this case, RtdImage defines a local class that is a subclass of RtdRemote and passes the "call" method on to its own "call" method that it uses for image subcommands. This class keeps a table of client connections (there could be multiple connections at once, although this is probably not the norm). For each client, there is a socket connection used to send commands and receive results and an additional socket connection used for callbacks. A socket message contains the length of the command (as a binary int in network byte order), a one byte flag indicating whether the answer should be immediate or via the callback socket and finally the contents of the command. EXTENDING THE COMMAND SET There are a number of ways to extend the available commands for the remote interface. One is through subclassing of class RtdImage at the C++ level (and extending the "call" method). Another way is by adding a command to the rtdimage Tcl interface to allow for a Tcl command to be evaluated for any "unknown" remote commands. SEE ALSO RtdImage, rtdRemote ----------------------------------------------------------------------- skycat-3.1.2-starlink-1b/rtd/man/rtd.man1000066400000000000000000000110671215713201500200550ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: rtd.man1,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 20 Jul 95 Created # Allan Brighton 10 Nov 97 Updated # NAME rtd - real-time image display application SYNOPSIS rtd ?options? ?filename? DESCRIPTION The rtd application is used to diplay FITS images in real-time. The application is based on "rtdimage", a Tk image extension for displaying FITS images. OPTIONS -file name "name" specifies a FITS format file to load and display. -subsample bool If bool is true, subsampling is used when shrinking the image, i.e.: if the image is shrunk by 1/3, only every third pixel is displayed. Otherwise, the maximum value is taken from the group of pixels. -sampmethod n (experimental) If option 'subsample' is false, the following methods can be used for displaying a shrunk image (i.e. an image with a scale factor < 1): SAMP_METHOD_MAX 0 /* max value of all pixels in a NxN box (default) */ SAMP_METHOD_MIN 1 /* min value of all pixels in a NxN box */ SAMP_METHOD_MEAN 2 /* mean value of all pixels in a NxN box */ SAMP_METHOD_MEDIAN 3 /* median value of all pixels in a NxN box */ SAMP_METHOD_MAX_CROSS 4 /* max value of pixels on a diagonal cross in a NxN box */ SAMP_METHOD_MIN_CROSS 5 /* min value of pixels on a diagonal cross in a NxN box */ SAMP_METHOD_MEAN_CROSS 6 /* mean value of pixels on a diagonal cross in a NxN box */ SAMP_METHOD_MEDIAN_CROSS 7 /* median value of pixels on a diagonal cross in a NxN box */ SAMP_METHOD_MEDIAN_CHESS 8 /* median value of pixels in a chess-board like box */ SAMP_METHOD_MEDIAN_9 9 /* median value of a 3x3 box */ -usexshm bool If bool is true (default), attempt to use X shared memory for the image display, if available. This improves performance considerably, but is only available when working on the system console. -usexsync bool If true, try to use X synchronisation. -verbose bool If bool is true, diagnostic messages are printed out to show what is going on internally (for debugging use). -default_cmap This option sets the default colormap file to use when starting up. Only the root of the filename should be specified for this option, for example: "ramp" for a grey level colormap. For a list of available colormap files, see the colormaps directory in the rtd release. -min_colors n -max_colors n Specify the min and max number of colors to allocate before using a private colormap. -default_itt This option is similar to -default_cmap, except it sets the default ITT (intensity transfer table) file to use at startup. ITT files are also stored in the colormaps directory. -xscale xs -yscale ys Set the default scaling factors (default: 1). -camera name Set the camera name for real-time image events: default: taken from the RTD_CAMERA environment variable, if set, otherwise set to RTDSIMULATOR, for simulation test mode. -zoom_factor number Set the scale factor for the zoom window (default 5 x the original image). -colorramp_height h Set the height of the colorramp subwindow (default: 20). -with_zoom_window bool If bool is true (default), add a zoom window. -with_pan_window bool If bool is true (default), add a panning window. -dozoom bool If true, turn on zoom window. -disp_image_icon bool If true, display a copy (view) of the image as an icon. -drag_scroll bool If true, set bindings to scroll with the middle mouse button. -scrollbars bool If true, display scrollbars to scroll the image. -port port Default port for remote connections (0 means system chooses a port). -debug bool Debugging flag: enables real-time simulation with testProg (below). -testprog path For testing: name of test program used to generate real-time updates (tRtd). -interval n For testing: interval between updates in ms. -with_perftest bool If true, display performance tester utility in menu bar. -with_warp bool Option to warp the mouse pointer. FILES $RTD_LIBRARY/../demos/rtd.tcl SEE ALSO rtdimage(n), RtdImageCtrl(n), rtdimage_wish(1), rtdServer(1), RtdServerTool(n), RtdImageZoom(n), RtdImageZoomView(n) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/rtd/man/rtd_remote.man3000066400000000000000000000101361215713201500214260ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: rtd_remote.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 10 Apr 96 Created # NAME rtdRemote - C interface for remote access to rtdimage based widgets SYNOPSIS #include "rtdRemote.h" typedef void (*RtdRemoteErrorHandler)(char* message); int rtdRemoteConnect(int pid, char* host, int port); void rtdRemoteDisconnect(); int rtdRemoteSend(char* cmd, char** result); int rtdRemoteGetResult(int socket, char** result); RtdRemoteErrorHandler rtdRemoteSetErrorHandler(RtdRemoteErrorHandler); char* rtdRemoteGetError(); DESCRIPTION This man page describes a simple remote interface to rtdimage based applications. With this interface, a client application can connect to a running application displaying an rtdimage, send commands and get results. REMOTE COMMANDS The commands are sent as ASCII strings via socket and have the same syntax as the rtdimage Tcl commands, except that no instance name is required. The command strings are not "evaluated" by Tcl, but are interpreted by the rtdimage code. Any commands that are not handled directly by the rtdimage C++ code may be passed on to a registered Tcl handler proc or [incr Tk] method. In this way, the list of available remote commands can be extended in the Tcl/Tk application. INTERFACE rtdRemoteConnect(pid, hostname, port) Connect to a remote rtdimage application. If pid, hostname and port are zero (null), they are read from the file $HOME/.rtd-remote, if it exists. This file is created by by an rtdimage widget when it starts to listen for a remote connection (see rtdimage, "remote" subcommand). Otherwise, if you know the pid, hostname and port, you can specify them here. This routine initializes an internal static structure with information about the connection. rtdRemoteDisconnect() Disconnect from remote rtdimage. rtdRemoteSend(cmd, result) The routine sends the given command to the remote rtdimage for evaluation and returns the status of the command. The result argument is set to point to the command results. The result pointer points to an internal buffer that is only valid until the next call to this routine. The command syntax is the same as for the "rtdimage" widget (image type), except that the instance name is missing. Example: char* result; int status = rtdRemoteCmd("wcscenter", &result); if (status == 0) { ... } If the command could not be sent, result is set to a NULL pointer and an error status (1) is returned. The error message can be retrieved with rtdRemoteGetError(). rtdRemoteSetErrorHandler(errorHandler) Set an error handler to be called when errors occur, format: void errorhandler(char* msg). rtdRemoteGetError(); Return the text of the last error message. EXAMPLE /* * The following example demonstrates the use of the remote rtd interface: */ /* * this routine is used for convenience in testing below * Send the command to the rtdimage, then print and return the result. */ static char* send_rtd(char* cmd) { char* result = NULL; int status = rtdRemoteSend(cmd, &result); printf("%s ==> %s: %s\n", cmd, (status ? "FAILED" : "OK"), result); return result; } main() { int data_id, header_id; /* * connect to running rtd. * uses default args taken from ~/.rtd-remote file */ if (rtdRemoteConnect(0, NULL, 0) != 0) exit(1); /* send some commands to RTD to be evaluated */ send_rtd("wcscenter"); send_rtd("bitpix"); send_rtd("scale"); send_rtd("width"); send_rtd("height"); send_rtd("config -file ngc1316r.fits"); send_rtd("width"); send_rtd("height"); data_id = atoi(send_rtd("shm get data")); header_id = atoi(send_rtd("shm get header")); exit(0); } SEE ALSO rtdimage, RtdRemote ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/rtd/man/rtdimage.mann000066400000000000000000001001531215713201500211500ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: rtdimage.mann,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 20 Jul 95 Created # Allan Brighton 10 Apr 96 updated for recent changes # Allan Brighton 24 Oct 96 updated for recent changes # Allan Brighton 22 Jan 98 updated for recent changes NAME rtdimage - Real-Time Display Image, a Tk Image Type SYNOPSIS image create rtdimage ?option value ...? DESCRIPTION Tk4.0 introduced a new "image" command and a C interface for adding new image types. A Tk image is much like a Tk widget in that it is both an object and a Tcl command. "rtdimage" is an extended Tk image type designed for real-time image display. Images can be loaded from shared memory or FITS format files, over sockets or HTTP. For real-time usage, a background daemon process rtdServer(1) communicates with the rtdimage software over a socket interface to display and update images rapidly from shared memory. A more general purpose remote control interface is also available (see rtdRemote(3)). CREATING RTDIMAGES An "rtdimage" is created with the "image create" Tk command. After this, you can use the image in a Tk canvas by specifying it with the "-image" option. For example: set image [image create rtdimage ...] $canvas create image 0 0 -image $image ... Most Tk image types may be used in any Tk widget, however, for our purposes, it was necessary to restrict the use to canvas widgets only. This was necessary in order to handle scrolling efficiently. OPTIONS The following options may be specified when creating or configuring an rtdimage: -displaymode mode The rtdimage supports two different display modes: 0 and 1. In display mode 0, space is allocated in the X server for the entire image. This makes scrolling faster, but uses enormous amounts of memory when the image is very large or is scaled to a large size. Still, this mode is useful in cases where the entire image is always displayed, such as in a panning window. In displaymode 1 (default), space is only allocated for the visible part of the image. This makes scrolling somewhat slower, but uses much less memory. -file name "name" specifies a FITS format file to load and display. -fitwidth winwidth -fitheight winheight These two options specify the size of the window into which the image must fit. The image will be scaled (shrunk) equally in the X and Y directions to fit as closely as possible inside the window. -newimagecmd command The given tcl command is evaluated every time a new image is loaded. This command is not called for real-time image updates, unless the image dimensions or data type changed. See the "camera" subcommand for getting notification of real-time image updates. -subsample bool If bool is true, subsampling is used when shrinking the image, i.e.: if the image is shrunk by 1/3, only every third pixel is displayed. Otherwise, the maximum value is taken from the group of pixels. -usexshm bool If bool is true (default), attempt to use X shared memory for the image display, if available. This improves performance considerably, but is only available when working on the system console. -verbose bool If bool is true, diagnostic messages are printed out to show what is going on internally (for debugging use). shm_header bool shm_data bool If bool is true, the image FITS header (or data) is kept in shared memory so that it can be accessed from a remote process (see rtdRemote(3)). COORDINATES The rtdimage subcommands support the following types of coordinates: canvas - canvas coordinates (canvas scroll area) screen - canvas window coordinates (visible area) image - basic image pixel coords (at mag 1, no transformations) chip - detector chip/CCD coordinates wcs - world coordinates in H:M:S D:M:S deg - world coordinates in degrees For image coordinates, the origin of the image is at (1,1) (or .5,.5 if the image is zoomed). Detector chip coordinates may be the same as image coordinates, but can also have an additional offset and/or binning factor. The FITS keywords "HIERARCH ESO DET WIN1 STRX" and "...STRY" are used for the offset, if present. The rtdimage "convert" subcommand can be used to convert between any two coordinate systems. In addition, most rtdimage subcommands accept coordinates using the following syntax: $x $y coord_type For example: set val [$image get $x $y canvas] set val [$image get $ra $dec "wcs 1950"] set val [$image get 42.1 38.3 "deg 2000"] For world coordinates, the equinox may be optionally specified as part of the coordinate type. The default is 2000. IMAGE FORMATS An rtdimage can load and display FITS format images or images written to shared memory via rtdServer(1). The following FITS image data types are supported: float, long, short, ushort, byte or XImage. Except for XImage, The order of lines is the same as for FITS files, with the origin at lower left. XImage is a special image type, which is taken to be already in a format that can be displayed with no color scaling. Support for other image types is planned, however the internal image type will remain FITS. New image types can be added by deriving a new subclass from the ImageIO(3) class. COLOR ALLOCATION All rtdimages in an application share the same default colormap. On startup, the rtdimage attempts to allocate as many color cells as possible, leaving about 10 free for other applications. The number of color cells allocated can be changed with the "alloccolors" subcommand. If another application (netscape, for example) has already grabbed all of the colors, a private colormap will be used. An attempt is made to keep most of the window manager colors intact, to avoid color flashing, at least in the GUI elements. MOTION EVENTS Since handling pointer motion events in Tcl code is fairly slow, the rtdimage code does some of the common work internally by setting values in a global array called "RtdImage". These values can be best accessed by specifying the "-textvariable" option to a Tk label or entry widget. The global "RtdImage" array contains the following values, which are updated on motion events: RtdImage(X) X image coordinate RtdImage(Y) Y image coordinate RtdImage(VALUE) pixel value at X,Y RtdImage(RA) world coordinate RA value RtdImage(DEC) world coordinate DEC value RtdImage(EQUINOX) world coordinate equinox The world coordinate values are set to empty strings if the image header does not support world coordinates. The same motion handler that sets the above variables also contains support for zoom windows (zoom and zoomview commands) and pixel tables (pixtab command). IMAGE COMMANDS The return value from the "image create rtdimage" command is the name of the image and also the name of a new Tcl command that can be used to operate on the image. The Tcl command has the following subcommands: alloccolors ?numColors? With no arguments, this command returns a Tcl list containing the number of allocated and the number of free colors. With one argument, the command attempts to reallocate numColors colors. The number of colors actually allocated depends on what other applications are running (see COLOR ALLOCATION). autocut ?-percent number? This command automatically sets the cut levels (the lowest and highest image pixel values considered in colormap scaling). Two different algorithms are supported. The default (and fastest version) is median filtering. If -percent is specified, the argument is a number between 0 and 100, such as 90 for 90%, where that percent of the image pixels should be within the cut values. i.e.: if you look at the graph (see graphdist command) of the pixel value distribution, you would take the top 90% of the graph and set the cut levels to left and right ends of the graph. Note: if this command is called, it is assumed that cut levels can be set automatically when a new image is loaded. See also the "cut" command. camera start cameraName ?tclCommand? camera stop camera pause camera continue The "camera start" command sends a message to the rtdServer daemon process telling it to start sending images from the given camera. Actually the server sends only image events, short messages over a socket interface, while the images are written to and read from shared memory. Camera is the name of a camera that must be known to the rtdServer (see rtdServer(1) for more information). The optional ?tclCommand? argument to "start" should be a string containing a Tcl command to be evaluated whenever a new image event is received and displayed. The "camera stop" command tells the rtdServer to stop sending image events. The "pause" and "continue" subcommands can be used to temporarily stop the image events and restart them, without having to know the name of the camera. clear clear ximage clear ?-reuse $reuse -ra $ra -dec $dec -equinox $equinox -radius $radius -width $width -height $height? This command is used to blank out the display by generating and loading a blank image. With no arguments a small blank image is generated with a default header. If "-ximage" is specified, the image is only cleared temporarily, until the next image update. In the last case, the optional arguments are used to generate a dummy image that supports world coordinates, so that you can plot objects on a blank background. Any missing values are set to a default value. Optional arguments: reuse - flag: if true, reuse previous image, if it is the same ra, dec - center point for WCS coords (in decimal degrees) radius - used to initialize WCS coords (CDELT1 and 2) equinox - equinox for WCS coords width - width of generated image in pixels height - height of generated image in pixels cmap file ?? cmap rotate cmap shift cmap pixels cmap reset cmap list cmap private cmap isprivate This command performs operations and queries on the colormap. If a colormap file is specified, it should contain 256 lines of red, green and blue values between 0.0 and 1.0 (MIDAS colormaps are saved in this format). The values will be distributed among the available colors and installed as a new colormap. For rotate and shift, the amount can be any integer. The colormap will be rotated (or shifted) by that amount. "pixels" returns a Tcl list of the colormap pixel values (for use by external applications using the RTI library, class ImageData). To get the number of colors in the colormap, you can use the "alloccolors" subcommand with no arguments or "llength" on the result of the pixels subcommand. "reset" resets the colormap to its original state. The RTD release includes a large number of MIDAS colormap files in the colormap directory. For "cmap file", if the filename is not specified, the current colormap file name is returned. "cmap list" returns a list of all of the colormap files currently loaded. "cmap private" says to start using a private colormap. "cmap isprivate" returns true if the colormap is private. colorramp This command generates an rtdimage displaying the colors in the colormap as a ramp or colorbar. This image will have the same size as the window containing it. This command should be called again from Tcl if the window is resized. colorscale ?scale_type? This command sets or queries the algorithm to be used for assigning the limited number of available colors to image pixels. If scale_type is specified, it should be one of: linear, log, sqrt or histeq, indicating the color scaling algorithm: linear scaling, logarithmic, square root or histogram equalization, resp. With no arguments, the current color scale type is returned. convert coords inx iny in_coord_type outx outy out_coord_type convert dist inx iny in_coord_type outx outy out_coord_type This command is used to convert between different coordinate representations. inx and iny and the input coords (or distance) in the given input coordinate system. "convert coords" treats x,y as a point, while "convert dist" treats it as a distance. outx and outy, if not empty, are the names of variables that will hold the resulting coordinates. If outx and outy are empty strings, the values are returned as a tcl list "x y". The available coordinate systems are: canvas - canvas coordinates (canvas scroll area) screen - canvas window coords (visible area) image - basic image pixel coords (at mag 1, no transformations) wcs - world coordinates in H:M:S deg - world coordinates in degrees The world coordinate types: "wcs" and "deg" may also include the epoch: Example: $image convert coords $ra $dec "wcs 1950" x y canvas Note: the coordinate types may be abbrieviated, since only the first char is actually checked. cut cut low high cut low high fromUser This command sets or queries the cut levels. If low and high are specified, then the cut levels are set so that pixels below the low value will all have the lowest color while those above high will all have the highest color value. The optional fromUser argument indicates whether or not this is a result of a user action and defaults to 1 (true). Once a user has set the cut levels, automatic cut level setting is disabled. If the fromUser argument is 1, it is assumed that they should not be changed automatically when a new image is loaded. Calling the autocut subcommand resets this again (see the autocut subcommand). If no arguments are given, the current cut values are returned in a Tcl list {min max}. dispwidth dispheight These commands return the logical width and height of the image after transformations (scaling and rotating). This is the size of the displayed image, assuming the window is large enough. This command also takes the image's "requested width" into account (set by by "view update" subcommand). dump This command dumps the current image to the given file in FITS format. If a FITS header is present, it is used, otherwise FITS keywords are inserted indicating the image type, width and height along with the date and a number of numbered "blank cards" or FITS keyword fields that can be modified by other applications as needed. The fields have names starting with BLANK followed by 2 digits (from BLANK00 to BLANK28). flip ?bool? With two arguments, flip (or stop flipping) the image in the given direction, where direction is one of x, y, xy or "none" for flipping in the x, y, or x and y directions or neither. The boolean value turns flipping on (1) or off (0) in the given direction(s). With one argument, the command returns the current value for the given argument. frameid This command returns the frame Id of this image. The frame Id is a unique number used to identify the image to the rtdServer for use with rapid frames. get x y coord_type ?nrows ncols? Returns a Tcl list of image values at the given X,Y coordinates. X and Y are interpreted in the given coordinate system (see COORDINATES above). The return value is a tcl list where each item consists of a list of {X Y Value}, where X and Y are the adjusted coordinates in the raw image and Value is the raw data value at that point or "-" if out of range. If nrows and ncols are greater than 1, the command returns a Tcl list of nrows x ncols values, each a list of rows, centered at the given point. graphdist bltGraph bltElem numValues This command displays the distribution of pixel values in the image in the given BLT graph widget. The data for the given BLT graph element will be set directly to the graph without going through tcl (see blt_graph(n)). The number of points to plot is given by the numValues argument. itt file itt scale This command operates on MIDAS style intensity transfer tables or ITTs. If an ITT file is specified, it should contain 256 intensity values in the range 0.0 to 1.0, one per line. The colormap will be modified by applying the intensities to it. The colormap can also be stretched or squeezed by applying an integer scale factor to the ITT. The RTD release contains a number of ITTs in the colormaps directory. max Returns the highest pixel value in the image. mband x0 y0 x1 y1 cord_type show_angle Draw a measure band on the canvas to show the distance in world coordinates (diagonal, vertical and horizontal). This method was originaly implemented in Tcl/[incr Tk], but was redone here for better performance. x0 and y0 are the starting coordinates of the drag, x1 and y1 are the coordinates from the motion events and show_angle is a flag: if true, show the horizontal and vertical distance, otherwise only the diagonal. The coordinates are accepted in the given coordinate system "coord_type", see COORDINATES above. min Returns the lowest pixel value in the image. mmap set $data_filename $data_offset $data_owner ?$header_filename $header_offset $header_owner? mmap get data mmap get header mmap create $filename $size mmap delete $filename mmap update This subcommand provides access to the mmap shared memory in which the FITS image data and header are stored. Image files are always mapped with mmap by default (since it is faster than reading the file). Applications can take advantage of this to modify the image data and then notify the application to update the image. This command makes it posible to put the image data and header in separate files, so that they can be more easily updated by other applications. If you want to put both header and data in the same file in the normal way, just use " config -file". Otherwise you can use this command to quickly update the image data in a separate file. The "set" command allow you to set the files to use to for the image data and header. The data and header in the specified files should be in FITS format (i.e.:, a FITS file split in 2 parts). If the header is not specified, the previous header is reused, if there was one. The offset arguments indicate an offset in the file where the header or data start. If the file contains only the data or only the header, the offset argument should be set to 0. A flag indicating who "owns" the file may be specified (if true, then the file will be deleted when no longer needed). Example: mmap set datafile1 0 0 headerfile1 0 0 mmap set datafile2 0 0 ... The "get" command returns mmap information about the data or header. If the data or header is not currently mapped, an error is returned. The return value is a list of the form {filename offset owner}, the same as the arguments to the " mmap set" command. The "create" command creates a new mmapped file with the given name and the given size. The mmaped file/memory should be released with the "delete" subcommand when no longer needed. The "delete" command unmaps the given file and deletes it, if it was created with the "mmap create" subcommand. The "update" command causes the display to be updated to reflect any changes in the image memory. pan start pan stop This command supports a panning image, which is, in this case, a second rtdimage image or "view" of the main image, scaled to a small size with a rectangle indicating the visible portion of the image. If "start" is specified, the given tcl command will be evaluated whenever the image size changes, due to scaling or loading a new image, or whenever the image position has changed due to scrolling. The tcl command will be called with 5 arguments: x1 y1 x2 y2, which are the coordinates of the visible part of the image, scaled by the given "shrinkFactor", and a flag indicating whether the image is new (1) or an update of the existing image (0). This can be used to draw the panning rectangle on the panning image. To stop the command from being called, use the "pan stop" subcommand. pixtab start pixtab stop This command supports displaying a table of pixel values around a point. All this commmand does is set a flag causing Tcl array variables to be updated on motion events, which can cause the display to be updated via the "-textvariable" widget option on the table items. The array name is fixed as: RtdPixTab and the elements are indexed as $RtdPixTab(i,j), where the left and top sides of the table (array) are the X and Y image coordinates, resp. and the rest are image pixel values. preview If bool is true and real-time images are being displayed, the viewing mode is set to "preview mode", otherwise, it is set back to "real-time mode". In preview mode, the camera is stopped (if it was running) and a local copy of the shared memory image is made, so that it can be freed or modified without affecting the image. radecbox ra and dec are the world coords (h:m:s or decimal deg) and radius is expected in arcmin. The return value in Tcl is a list of 4 values {ra0 dec0 ra1 dec1} that form a ra,dec box with the given center point and radius. remote ?$port? This command implements a remote control of the RTD image. If a port number argument is specified The widget will start listening for commands on the given port. If port is 0, a port number will be chosen. If no port number is specified, the current port number is returned, or "" if there is none. This is a way to determine the port number at the Tcl level. remotetcl ?$command? Evaluate a Tcl command in the RTD Tcl interpreter. rotate ?bool? Rotate (or stop rotating) the image. Currently, rotation is only done by swapping the x and y axis. If bool is specified, rotation is turned on(1) or off(0). Otherwise, the current setting is returned. scale ?sx sy? With 2 arguments, the image is scaled (magnified) by the given X and Y amount. With no arguments, the current scaling factors are returned (as a tcl list of 2 integers). The scaling factors are positive or negative integers (default 1). Positive integers are used to zoom in on the image (2 means twice the original size). Negative integers are used to zoom out (-2 means 1/2 the original size). The software imposes an arbitrary limit on the minimum and maximum scaling factor allowed. shm set $data_size $data_id $data_owner ?$header_size $header_id $header_owner? shm get data shm get header shm create $size shm delete $Id shm update This subcommand provides access to the shared memory in which the FITS raw image data and header are stored. The raw image is stored in shared memory if the -shm_data option was specified when creating the image and the header is stored in shared memory if the -shm_header option was specified. The "set" command allow you to set the shared memory Ids to use to access the image data and header. The data and header in the area specified should be in FITS format. If the header is not specified, the previous header is reused. For both data and header, the size of the area (in bytes) and the shared memory Id must be specified. In addition a flag indicating who "owns" the shared memory is specified (if true, then the area will be deleted when no longer needed). The "get" command returns the shared memory Id of the data or header. If the data or header is not currently in shared memory, it is copied to a new shared memory area and the Id for this area is returned. The "create" command creates a new shared memory area with the given size and returns the Id. The memory should be deleted with the "delete" subcommand when no longer needed. The "delete" command deletes the shared memory with the given Id (which should have been returned from the "create" subcommand). The "update" command causes the display to be updated to reflect any changes in the image memory. spectrum x0 y0 x1 y1 coord_type This command is used to display a graph of a "cut" of the image along a given line. x0, y0, x1 and y1 are the end points of a line in the image (in the given coordinate system, see COORDINATES above). is the path name of a BLT graph widget to display the plot of the pixel intensities along the line. is the name of the element in the graph that should receive the data. The data is sent directly to the graph for display. The return value in Tcl is the number of points to plot. statistics statistics subcommand: calculate statistics on the section of the image being displayed. The return value in Tcl is a list of the following values: {x y ra dec equinox fwhmX fwhmY angle objectPeak meanBackground} where: x = adjusted X image coordinate y = adjusted Y image coordinate ra = RA position (calculated from mean X pos within array) dec = DEC position (calculated from mean Y position within array) equinox = equinox of RA and DEC fwhmX = FWHM in X fwhmY = FWHM in Y angle = angle of major axis, degrees, along X = 0 objectPeak = peak value of object above background meanBackground = mean background level type Returns the data type of the raw image as a string: one of: float, long, short, ushort, byte or XImage. The last type, XImage is a special pseudo type, the same as a byte image, except that the Y axis is reversed and it is assumed to not need color scaling. update This command makes sure that the image is up to date with the raw data (which may have changed via shared memory, mmap, etc). view add ?propagateScale? view remove view update x y width height viewx viewy coord_type view enter view leave The view command is used to specify a viewing image to view the same image, possibly at a different size. The new view will share data with the original and be updated when the original is updated. This can be used, for example, to build a panning window or a rapid frame. must be the name of a second rtdimage image. The two images will communicate internally to always display the same image, possibly scaled to different sizes. The subcommands are: add Adds a new view to this image. remove Removes the view. update Updates the view from this image with the given image x,y offset, width and height and the position of the image view origin in the given coordinate type. This command can be used to implement a zoom window or rapid frame, since it controls which portion of the image is displayed. enter If 2 images are in the same canvas, make the current one (receives motion events, ...). leave Undo the enter command. If the optional "add" argument "propagateScale" is true, changes in the scale factors in the master image will propagate to the view (this is the default behavior). warp Warp (move) the mouse pointer by the given x and y amounts (pixels). wcscenter ?-format ? This command returns the world coordinates of the center of the image. The optional format option determines the format of the result: -format 0 ==> H:M:S [+-]D:M:S (default) -format 1 ==> RA DEC (in degrees) The return value is a tcl list, formatted according to the format option, or an empty string if the coordinates are out of range or WCS is not supported. wcsdist x0 y0 x1 y1 This command returns the world coordinate distance between 2 points after transformations. The arguments are expected in canvas coords (canvasx, canvasy, doubles). The return value in Tcl is the WCS distance between the given points after transformations. wcsheight This command returns the height of the image in arcmin or the empty string if WCS is not supported. wcswidth This command returns the width of the image in arcmin or the empty string if WCS is not supported. wcsradius This command returns the radius (distance from center to corner) of the image in arcmin or the empty string if WCS is not supported. wcsset wcsset If arguments are specified, this subcommand sets up the WCS structure from the given information about the image: Arguments: ra = Center right ascension in H:M:S dec = Center declination in D:M:S secpix = Number of arcseconds per pixel xrefpix = Reference pixel X coordinate yrefpix = Reference pixel Y coordinate nxpix = Number of pixels along x-axis nypix = Number of pixels along y-axis rotate = Rotation angle (clockwise positive) in degrees equinox = Equinox of coordinates, 1950 and 2000 supported epoch = Epoch of coordinates, used for FK4/FK5 conversion no effect if 0 proj = Projection With no arguments, the command returns a list of the basic WCS parameter values: {ra dec secpix nxpix nypix rotate equinox epoch}. wcsshift This command resets the center of the WCS structure. Arguments: ra = New center right ascension in degrees dec = New center declination in degrees equinox = must be 2000 or 1950 width height These commands return the width and height of the raw image in pixels. zoom start zoom stop (Note: This command is no longer supported: please use zoomview (below) instead.) This command is used to implement a zoom window, a window displaying a magnified section of the image at the location of the mouse pointer. There are currently two versions of this command (see the zoomview subcommand below). In this version, a Tk frame is specified to hold the zoomed image, which is copied directly from the XImage whenever the mouse pointer moves over the image. This version is faster, but when the main image is shrunk, the zoom will not be very accurate. If "start" is specified, zooming begins in the given window, and can be stopped with the "zoom stop" subcommand. zoomview start zoomview stop This command can be used as an alternative to the zoom command above. It uses a "view" of the main rtdimage, so the zoom image is always accurate, even when main image is shrunk. The "view" argument to "zoomview start" should be the name of a second rtdimage, which is a "view" of the main image, added with the rtdimage "view" subcommand. The zoomFactor is the magnification relative to the main image. For example, if the zoomFactor is 5 and the main image is scaled to 1/2, the zoom window scale factor would be 4. Once started, the main image will automatically track mouse movements and update the zoom window's x and y offsets as needed to display the relevant magnified section of the image. ENVIRONMENT VARIABLES RTD_LIBRARY - If set, this should point to the directory containing the rtdimage Tcl library files. FILES $RTD_LIBRARY/ - Tcl/Itcl library files $RTD_LIBRARY/colormaps - MIDAS colormap/ITT files $RTD_LIBRARY/images - sample FITS images $RTD_LIBRARY/bitmaps - X bitmaps used at runtime $RTD_LIBRARY/demos - rtdimage demo application SEE ALSO RtdImage(n), rtdServer(1), rtdImageEvt(3), BLT(n), canvas(n) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/rtd/man/rtdimage_wish.man1000066400000000000000000000034351215713201500221120ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: rtdimage_wish.man1,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 20 Jul 95 Created # NAME rtdimage_wish - a Tk wish shell with the rtdimage extension SYNOPSIS rtdimage_wish ?fileName arg arg ...? DESCRIPTION rtdimage_wish is the Tk wish shell created by the RTD package to demonstrate the real-time display widget features. This version of wish(1) contains, in addition to the rtdimage extension, the BLT, [incr Tk] and TclX extensions. BLT is required for displaying graphs and tables, [incr Tk] is used for its class system and TclX is used for various utility commands and interprocess communication (rtdServer(1). ADDING THE RTDIMAGE EXTENSION The rtdimage extension can be included in a Tk application shell in the standard way, by adding a call to RtdImage_Init(interp) in the Tcl_AppInit() routine, which every Tk application must define: /* initialize the rtdimage type */ if (RtdImage_Init(interp) == TCL_ERROR) { return TCL_ERROR; } Note that since the rtdimage extension is implemented in C++, it is required that main() also be compile with C++. Normally, main() is included in the same C file with Tcl_AppInit(), so you have 2 choices: you can rename the file tkAppInit.c to tkAppInit.C and compile and link it with a C++ compiler, or you can put main() in a separate file and compile and link it with a C++ compiler. SEE ALSO rtdimage(n), wish(1), BLT(n), incrTcl(n), TclX(n) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/rtd/pkgIndex.tcl.in000066400000000000000000000002151215713201500206060ustar00rootroot00000000000000# Tcl package index file, version 1.0 package ifneeded Rtd @PACKAGE_VERSION@ [list load [file join [file dirname $dir] @PKG_LIB_FILE@] Rtd] skycat-3.1.2-starlink-1b/rtd/rtd.in000077500000000000000000000027561215713201500170640ustar00rootroot00000000000000#!/bin/sh # Start script for rtd # # "@(#) $Id: rtd.in,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 28 Jan 06 created # pbiereic 29/12/08 ignore error output from 'ps -x' # Determine rtd base dir, following any symbolic links, if needed. PRG="$0" cwd=`pwd` cd `dirname "$PRG"` while [ -h "$PRG" ]; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '.*/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`/"$link" fi done DIR=`dirname "$PRG"`/.. RTD_BASE=`(cd $DIR; pwd)` cd $cwd # If we're NOT ssh'd in if [ ! ${SSH_TTY} ]; then # make sure X is running (on Mac OS X) if [ `uname` = "Darwin" -a "`ps -x 2>/dev/null | awk '{print $5}' | grep X11`" = "" ]; then for i in /Applications/Utilities $HOME/Desktop ; do if [ -e $i/X11.app ] ; then open $i/X11.app & fi done fi # Make sure DISPLAY is set if [ x${DISPLAY} = x ]; then export DISPLAY=:0 fi fi # Make sure we can find the shared libs @LD_LIBRARY_PATH_VAR@="$RTD_BASE/lib:@BLT_LIB_DIR@:${@LD_LIBRARY_PATH_VAR@}" export @LD_LIBRARY_PATH_VAR@ # and the Tcl packages TCLLIBPATH="$RTD_BASE/lib" export TCLLIBPATH # Make sure we start the correct wish binary PATH=$RTD_BASE/bin:$PATH export PATH test -d $HOME/.rtd || mkdir $HOME/.rtd exec wish8.4 $RTD_BASE/lib/rtd@PACKAGE_VERSION@/main.tcl ${1+"$@"} | tee $HOME/.skycat/log 2>&1 skycat-3.1.2-starlink-1b/rtd/rtdConfig.sh.in000066400000000000000000000031501215713201500206050ustar00rootroot00000000000000# E.S.O. - VLT project # $Id: rtdConfig.sh.in,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # rtdConfig.sh -- # # This shell script (for sh) is generated automatically by Rtd's # configure script. It will create shell variables for most of # the configuration options discovered by the configure script. # This script is intended to be included by the configure scripts # for Rtd extensions so that they don't have to figure this all # out for themselves. This file does not duplicate information # already provided by tclConfig.sh, so you may need to use that # file in addition to this one. # # The information in this file is specific to a single platform. # Rtd's version number. rtd_VERSION='@PACKAGE_VERSION@' # The name of the Rtd library: rtd_LIB_FILE=@rtd_LIB_FILE@ # String to pass to linker to pick up the Rtd library from its # build directory. rtd_BUILD_LIB_SPEC='@rtd_BUILD_LIB_SPEC@' # Rtd build directory. rtd_BUILD_DIR='@rtd_BUILD_DIR@' # String to pass to linker to pick up the Rtd library from its # installed directory. rtd_LIB_SPEC='@rtd_LIB_SPEC@' # Location of the top-level source directories from which Rtd # was built. This is the directory that contains generic, unix, etc. # If Rtd was compiled in a different place than the directory # containing the source files, this points to the location of the sources, # not the location where Rtd was compiled. rtd_SRC_DIR='@rtd_SRC_DIR@' # List of object files used to build the library (for merging packages). rtd_PKG_OBJECTS='@rtd_PKG_OBJECTS@' # List of header filesinstalled for this library (for merging packages). rtd_PKG_HEADERS='@rtd_PKG_HEADERS@' skycat-3.1.2-starlink-1b/rtd/rtd_version.tcl.in000066400000000000000000000001551215713201500213760ustar00rootroot00000000000000# This file is generated by configure: DO NOT EDIT BY HAND proc rtd_version {} { return @PACKAGE_VERSION@ } skycat-3.1.2-starlink-1b/rtd/rtdctrl000077500000000000000000000012741215713201500173360ustar00rootroot00000000000000#!/bin/sh # -*-tcl-*- # # E.S.O. - VLT project # # "@(#) $Id: rtdctrl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # Start the rtd image server as a standalone program # # Usage: rtdctrl # # who when what # -------- -------- ------------------ # abrighto 11/10/95 created # abrighto 29/12/05 adapted for new setup # Make sure the shared libraries can be found # The next line is executed by sh, the rest by tcl: \ LD_LIBRARY_PATH="/home/abrighto/work/eso/skycat/src/install/lib:${LD_LIBRARY_PATH}" TCLLIBPATH="/home/abrighto/work/eso/skycat/src/install/lib" exec /usr/bin/wish8.4 "$0" ${1+"$@"} # -*-tcl-*- package require Rtd setXdefaults util::TopLevelWidget::start RtdServerTool skycat-3.1.2-starlink-1b/rtd/rtdevt/000077500000000000000000000000001215713201500172365ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/rtd/rtdevt/rtdCLNT.C000066400000000000000000000117721215713201500206240ustar00rootroot00000000000000/******************************************************************************* * E.S.O. - VLT project * * "@(#) $Id: rtdCLNT.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * who when what * -------- -------- ---------------------------------------------- * pbiereic 01/03/01 created */ /************************************************************************ * NAME * rtdCLNT - class to handle a client which has connected to rtdServer * * SYNOPSIS * * * DESCRIPTION * An instance of this class handles all functions for the connection * to a rtdServer client which can be either a camera (CCD) or RTD * application. * * PUBLIC METHODS * * rtdCLNT::~rtdCLNT() * Destructor: close socket and cleanup the semaphores used by client * * void rtdCLNT::Cleanup() * Cleanup the semaphores used by client * * void rtdCLNT::Attach(char* reqName, char *camName) * Attach: keep name of producer and requestor * * void rtdCLNT::Detach() * Detach: clear name of producer and requestor * * int rtdCLNT::Accept(int listenSocket) * Accept connection from port 'listenSocket' * * int rtdCLNT::Forward(rtdPACKET *rtdPacket, int numbyte) * Forward the image event to the RTD client * * int rtdCLNT::AttachedToCamera(char *camera) * Are we attached to camera 'camera'? * * Other methods which just store/return data can be found in * the include file. * * FILES * * ENVIRONMENT * * COMMANDS * * RETURN VALUES * * CAUTIONS * * EXAMPLES * * SEE ALSO * * BUGS * *------------------------------------------------------------------------ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_SYS_FILIO_H #include #endif #include "rtdCLNT.h" static const char *rcsId="@(#) $Id: rtdCLNT.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; rtdCLNT::rtdCLNT(int verbose, int index) : rtdLOG(verbose), reqName_(reqNameBuf_), camName_(camNameBuf_), semId_(-1), type_(-1), shmNum_(0), index_(index), socket_(0) { BufClear(reqNameBuf_); BufClear(camNameBuf_); } rtdCLNT::~rtdCLNT() { if (socket_) close(socket_); Cleanup(); } void rtdCLNT::Cleanup() { // Clear semaphores used by client for (int i = 0; i <= shmNum(); i++) rtdSemReset(semId(), i); shmNum_ = 0; } void rtdCLNT::SetSemPar(int semId, int shmNum) { /* * if a client uses a different shared memory than before, * reset the previously set semaphores first. */ if (semId_ != semId && semId_ >= 0) Cleanup(); semId_ = semId; shmNum_ = max(shmNum, shmNum_); } void rtdCLNT::Attach(char* reqName, char *camName) { ReqName(reqName); CamName(camName); } void rtdCLNT::Detach() { BufClear(reqName_); BufClear(camName_); } int rtdCLNT::AttachedToCamera(char *camera) { if (ReqName() == '\0') return RTD_ERROR; // not attached to any requestor if (strcmp(camera, CamName()) == 0) return RTD_OK; // that's it ! return RTD_ERROR; // not my camera to which I am attached to } int rtdCLNT::Accept(int listenSocket) { struct sockaddr_in sockAddr; // used by accept() socklen_t addrLen = sizeof(sockAddr); int optval; // used by setsockopt() int socket; // socket file descriptor // Accept connection from client socket = accept(listenSocket, (struct sockaddr *)&sockAddr, &addrLen); if (socket <= 0) { log("Unable to accept socket connection\n"); return RTD_ERROR; } // Set socket options optval = 1; setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (const char *)&optval, sizeof optval); log("Connection request accepted on port: %d\n", sockAddr.sin_port); // init this object Socket(socket); Port(sockAddr.sin_port); return RTD_OK; } int rtdCLNT::Forward(rtdPACKET *rtdPacket) { rtdIMAGE_INFO *info = &(rtdPacket->body.data.rtdImageInfo); log("frameId=%d, dataType=%d, bytePerPixel=%d, shmId=%d, semId=%d, shmNum=%d,\n\t\t" "frameX=%d, frameY=%d, xPixels=%d, yPixels=%d, highCut=%d, lowCut=%d,\n\t\t" "ra=%g,dec=%g, secpix=%g, xrefpix=%g, yrefpix=%g,\n\t\t" "rotate=%g, equinox=%d, epoch=%g, proj=%s, wcsFlags=%d\n", info->frameId, info->dataType, info->bytePerPixel, info->shmId, info->semId, info->shmNum, info->frameX, info->frameY, info->xPixels, info->yPixels, info->highCut, info->lowCut, info->ra, info->dec, info->secpix, info->xrefpix, info->yrefpix, info->rotate, info->equinox, info->epoch, info->proj, info->wcsFlags); // Pass the UTC in the packet gettimeofday(&info->timeStamp, NULL); if (write(Socket(), (char *)rtdPacket, sizeof(rtdPACKET)) == sizeof(rtdPACKET)) return RTD_OK; log("socket write error\n"); return RTD_ERROR; } char *rtdCLNT::TypeName() { switch(Type()) { case RTDWIDGET: return((char *)"RTDWIDGET"); case IMAGETRANS: return((char *)"IMAGETRANS"); case EAVESDROP: return((char *)"EAVESDROP"); case OTHER: return((char *)"OTHER"); default: return((char *)"UNKNOWN"); } } skycat-3.1.2-starlink-1b/rtd/rtdevt/rtdCLNT.h000066400000000000000000000061031215713201500206610ustar00rootroot00000000000000#ifndef rtdCLNT_H #define rtdCLNT_H /******************************************************************************* * E.S.O. - VLT project * * "@(#) $Id: rtdCLNT.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * who when what * -------- -------- ---------------------------------------------- * pbiereic 01/03/01 created */ /************************************************************************ * *---------------------------------------------------------------------- */ #ifndef _POSIX_SOURCE #define _POSIX_SOURCE 1 #endif #include "rtdImageEvent.h" #include "rtdSem.h" #include "rtdLOG.h" #include "define.h" #include #include #include #include #include #include #include #include #include #include class rtdCLNT : rtdLOG { public: // constructor and destructor rtdCLNT(int verbose, int index); ~rtdCLNT(); // store/return the name of the requestor char *ReqName() { return reqName_; } void ReqName(char *name) { strncpy (reqNameBuf_, name, RTD_NAMELEN); } // store/return the name of the camera char *CamName() { return camName_; } void CamName(char *name) { strncpy (camNameBuf_, name, RTD_NAMELEN); } // store/return the name of the socket file descriptor int Socket() { return socket_; } void Socket(int socket) { socket_ = socket; } // return the semaphore params set by the requestor int semId() { return semId_; } // return the number of semaphores int shmNum() { return shmNum_; } // set the values for semId and shmNum void SetSemPar(int semId, int shmNum); // store/return the index int Index() { return index_; } void Index(int index) { index_ = index; } // store/return the port number int Port() { return port_; } void Port(int port) { port_ = port; } // store/return the type number int Type() { return type_; } void Type(int type) { type_ = type; } // clear a buffer void BufClear(char *name) { memset (name, '\0', RTD_NAMELEN); } // are we attched? int Attached() { return (*reqName_ == '\0' || *camName_ == '\0'); } void Attach(char* reqName, char *camName); void Detach(); int Forward(rtdPACKET *rtdPacket); void Cleanup(); int Accept(int listenSocket); int AttachedToCamera(char *camera); char *TypeName(); private: char *reqName_; // name of requestor char *camName_; // name of camera char reqNameBuf_[RTD_NAMELEN]; // name of requestor char camNameBuf_[RTD_NAMELEN]; // name of camera int socket_; // socket file descriptor int index_; // socket file descriptor index int port_; // port number int type_; // type number int semId_; // semaphore Id int shmNum_; // number of semaphores protected: }; #endif /*!rtdCLNT_H*/ skycat-3.1.2-starlink-1b/rtd/rtdevt/rtdClient.c000066400000000000000000000100151215713201500213270ustar00rootroot00000000000000/************************************************************************* * E.S.O. - VLT project * "@(#) $Id: rtdClient.c,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * rtdClient.c * * who when what * -------- -------- ---------------------------------------------- * T.Herlin 08/02/95 Created * P.W. Draper 16/12/97 Modified to use fd_set as a type rather than * struct. */ /************************************************************************ * NAME * rtdClient * * SYNOPSIS * * rtdClient [-v] * * DESCRIPTION * * FILES * * ENVIRONMENT * * RETURN VALUES * * CAUTIONS * * EXAMPLES * * SEE ALSO * * BUGS * *------------------------------------------------------------------------ */ static const char* const rcsId="@(#) $Id: rtdClient.c,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; /* * System Headers */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_SYS_FILIO_H #include #endif /* * Local Headers */ #include "rtdImageEvent.h" static int verbose=0; static void usage(void) { printf("rtdClient [-v]\n"); exit(1); } /* */ int main(int argc, char *argv[]) { char c,*buf, camera[RTD_NAMELEN],reqName[RTD_NAMELEN]; int readable; int status=0,attach=0,image=0; rtdIMAGE_EVT_HNDL eventHndl; rtdPACKET rtdPacket; rtdIMAGE_INFO imageInfo; fd_set readFds; extern char *optarg; extern int optind; strcpy(reqName,"rtdClient"); while ((c = getopt(argc,argv,":cvsia:r:")) != -1) { #ifndef SYSV char* optopt = argv[optind]; #endif switch(c) { case 'v': verbose++; break; case 's': status++; break; case 'i': image++; break; case 'a': attach++; strcpy(camera,optarg); break; case 'r': strncpy(reqName,optarg,RTD_NAMELEN); break; case ':': fprintf(stderr,"Option -%s requires an argument\n",optopt); usage(); break; case '?': fprintf(stderr,"Invalid argument -%s \n",optopt); usage(); break; } } if (rtdInitImageEvt(reqName,&eventHndl,NULL) == RTD_ERROR) { printf("Could not initialize image event !\nCheck if rtdServer is running !\n"); exit(1); } if (attach) { rtdAttachImageEvt(&eventHndl,camera,NULL); } if (status) { rtdPacket.opcode = STATUS; strncpy(rtdPacket.body.data.hdr.reqName,reqName,RTD_NAMELEN); write(eventHndl.socket,&rtdPacket,sizeof(rtdPACKET)); } if (image) { memset(&imageInfo,'\0',sizeof(rtdIMAGE_INFO)); imageInfo.dataType = FLOAT; imageInfo.xPixels = 512; imageInfo.yPixels = 512; /* send to server */ rtdSendImageInfo(&eventHndl,&imageInfo,NULL); sleep(2); exit(0); } FD_ZERO(&readFds); FD_SET(eventHndl.socket, &readFds); for (;;) { if (select(32,(fd_set *)&readFds, 0, 0, NULL) == -1) { if (verbose) printf("Select fails\n"); continue; } if (FD_ISSET(eventHndl.socket, &readFds) > 0) { if (verbose) printf("Input on client socket: %d\n",eventHndl.socket); ioctl(eventHndl.socket,FIONREAD,&readable); if (verbose) printf("Bytes readable: %d\n",readable); if (readable) { if (readable == sizeof(rtdPACKET)) { memset(&rtdPacket,'\0',sizeof(rtdPACKET)); read(eventHndl.socket,&rtdPacket, sizeof(rtdPACKET)); if (verbose) printf("Packet received: %d, %s, %s\n", rtdPacket.opcode, rtdPacket.body.data.hdr.reqName, rtdPacket.body.data.hdr.camName); } else { buf = malloc(readable+1); read(eventHndl.socket,buf,readable); buf[readable] = '\0'; printf("Read from server:\n%s\n",buf); free(buf); } } if (status) exit(0); } } } /*___oOo___*/ skycat-3.1.2-starlink-1b/rtd/rtdevt/rtdCubeDisplay.c000066400000000000000000000207501215713201500223240ustar00rootroot00000000000000/************************************************************************* * E.S.O. - VLT project * "@(#) $Id: rtdCubeDisplay.c,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * rtdClient.c * * who when what * -------- -------- ---------------------------------------------- * T.Herlin 08/02/95 Created * P.W. Draper 16/12/97 Modified to use fd_set as a type rather than * struct. * 12/09/01 Added UKIRT Quick Look member initialisations, should * be harmless to other uses. */ static const char* const rcsId="@(#) $Id: rtdCubeDisplay.c,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; /************************************************************************ * NAME * rtdCubeDisplay - simple FITS cube display program * * SYNOPSIS * * rtdCubeDisplay -f -c [-t ] [-l] [-v] * * DESCRIPTION * * rtdCubeDisplay displays FITS cube images for the real-time display. * By specifying a FITS cube file (option -f) and a camera name (option -c) * the images are extracted from the file and an image event is sent to * the rtdServer. In order to display the image a rtd widget application * e.g. 'rtd' must register to the same camera name as specified above. * For the 'rtd' application this is done by setting the RTD_CAMERA * environment. * * Options: * * -f FITS cube images * -c Camera name to identify real time source * -v Enables verbose mode * -t Delay time between images (default 500msec) * -l Loop (forever) * * SEE ALSO * rtdServer(1) * *------------------------------------------------------------------------ */ /* * System Headers */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_SYS_FILIO_H #include #endif typedef void (*MySigFunc)(int); /* allan: prototype cast to keep Sun cc quiet */ /* * Local Headers */ #include "rtdImageEvent.h" static int verbose=0; static int shmId; static void usage() { printf("rtdCubeDisplay -f -c [-t ] [-l] [-v]\n"); printf("-l = loop indefinetly\n"); printf("-t = delay time between cube images (in msec) default 500 ms\n"); printf("-v = switch on verbose\n"); exit (1); } static int readFitsCube(FILE *fptr, int *type, int *width, int *height, int *count, float *bscale, float *bzero, int *fileoffset) { char buffer[81],*ptr,*vptr; int cnt=0; do { fgets(buffer,sizeof(buffer),fptr); ptr = strtok(buffer,"="); while(*ptr == ' ') ptr++; if (strncmp(ptr,"NAXIS1",6) == 0) { vptr = strtok(NULL,"/"); *width = atoi(vptr); } if (strncmp(ptr,"NAXIS2",6) == 0) { vptr = strtok(NULL,"/"); *height = atoi(vptr); } if (strncmp(ptr,"NAXIS3",6) == 0) { vptr = strtok(NULL,"/"); cnt = atoi(vptr); } if (strncmp(ptr,"BITPIX",6) == 0) { vptr = strtok(NULL,"/"); *type = atoi(vptr); } if (strncmp(ptr,"BZERO",5) == 0) { vptr = strtok(NULL,"/"); *bzero = (float)atof(vptr); } if (strncmp(ptr,"BSCALE",6) == 0) { vptr = strtok(NULL,"/"); *bscale = (float)atof(vptr); } } while(strncmp(ptr,"END ",4) !=0); *fileoffset = ((ftell(fptr)/2880L) + ((ftell(fptr)%2880)?1:0))*2880; if (!cnt) { printf("Warning: NAXIS3 not specified - hmm I'm not shure this is a cube !\n"); cnt = 1; } *count = cnt; return RTD_OK; } static void cleanup() { if (shmId) shmctl(shmId,IPC_RMID,NULL); if (verbose) printf("Exiting !\n"); exit(0); } main(int argc, char *argv[]) { char c,camera[RTD_NAMELEN],reqName[RTD_NAMELEN],fileName[256]; int count,fileoffset,typeSize=0; int loop=0,timer=500,type,i,j; rtdIMAGE_EVT_HNDL eventHndl; rtdIMAGE_INFO imageInfo; extern char *optarg; extern int optind; int shmWidth,shmHeight,shmImageType=0; char *shmPtr; FILE *fptr; float bscale = 0, bzero = 0; signal(SIGINT,(MySigFunc)cleanup); signal(SIGTERM,(MySigFunc)cleanup); signal(SIGHUP,(MySigFunc)cleanup); while ((c = getopt(argc,argv,":vlf:c:t:")) != -1) { #ifndef SYSV char* optopt = argv[optind]; #endif switch(c) { case 'v': verbose++; break; case 'l': loop++; break; case 't': timer = atoi(optarg); break; case 'r': strncpy(reqName,optarg,RTD_NAMELEN); break; case 'f': strncpy(fileName,optarg,256); break; case 'c': strncpy(camera,optarg,RTD_NAMELEN); break; case ':': fprintf(stderr,"Option -%s requires an argument\n", optopt); usage(); break; case '?': fprintf(stderr,"Invalid argument -%s \n",optopt); usage(); break; } } if (strlen(camera) == 0) { printf("camera name not specified - unable to continue !\n"); usage(); } if (rtdInitImageEvt(camera,&eventHndl,NULL) == RTD_ERROR) { printf("Could not initialize image event !\nCheck if rtdServer is running !\n"); usage(); } if (strlen(fileName) == 0) { printf("filename not specified - unable to continue !\n"); usage(); } fptr = fopen(fileName,"r"); if (fptr == NULL) { printf("invalid filename specified: %s\n",fileName); usage(); } if (readFitsCube(fptr,&type,&shmWidth,&shmHeight,&count, &bscale,&bzero,&fileoffset) == RTD_ERROR) { printf("Error in readFitsCube \n"); usage(); } if (verbose) printf("Filename: %s type:%d width:%d height:%d\n", fileName,type,shmWidth,shmHeight); switch (type) { case 8: shmImageType = BYTE; typeSize = 1; break; case -16: shmImageType = USHORT; typeSize = 2; break; case 16: shmImageType = SHORT; typeSize = 2; break; case 32: shmImageType = INT; typeSize = 4; break; case -32: shmImageType = FLOAT; typeSize = 4; break; } /* remove previous shm area */ if (shmId) shmctl(shmId,IPC_RMID,NULL); shmId = shmget(IPC_PRIVATE,shmWidth*shmHeight*typeSize,0666); if (verbose) printf("Shared Memory area created, id: %d size:%d \n", shmId,shmWidth*shmHeight*typeSize); shmPtr = (void *)shmat(shmId,NULL,0); if (shmPtr != NULL && shmPtr != (void *)-1) { /* read though file */ do { /* set correct file pointer */ rewind(fptr); fseek(fptr,fileoffset, SEEK_SET); for (i=0;i * #include * #include "rtdImageEvent.h" * * rtdIMAGE_EVT_HNDL eventHndl; * rtdIMAGE_INFO imageInfo; * char errMsg[256]; * int shmId; * char *shmPtr; * * if (rtdInitImageEvt("My_CCD_Camera",&eventHndl,errMsg) == RTD_ERROR) * { * fprintf(stderr,"rtdInitImageEvt error:%s",errMsg); * ... handle error ... * } * * shmId = shmget(IPC_PRIVATE,512*512*sizeof(short),0666); * * shmPtr = (char *)shmat(shmId,NULL,0); * if (shmPtr == -1) * { .. handle error ... } * * ... generate the image ... * * memset(&imageInfo, '\0', sizeof(rtdIMAGE_INFO)); * imageInfo.dataType = SHORT; * imageInfo.shmId = shmId; * imageInfo.xPixels = 512; * imageInfo.yPixels = 512; * * // send image event * if (rtdSendImageInfo(&eventHndl,&imageInfo,errMsg) == RTD_ERROR) * { * fprintf(stderr,"rtdSendImageInfo error:%s",errMsg); * ... handle error ... * } * * // if finishing close connection and delete shared memory * rtdClose((&eventHndl,errMsg); * * if (shmId) shmctl(shmId,IPC_RMID,NULL); * * WARNINGS * If you are not using semaphore locking then set semId=-1 in the * image event structure (see rtdImageEvent.h). Since semId=0 is * a valid number it can happen that rtdServer decrements a * semaphore created by another process which can lead to serious * problems! * * SEE ALSO * * rtdServer(1) * *------------------------------------------------------------------------- */ static const char* const rcsId="@(#) $Id: rtdImageEvent.c,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; /* * System Headers */ #include #include #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_SYS_FILIO_H #include #endif #include #include #include #include #include #include /* * Local Headers */ #include "rtdImageEvent.h" int rtdInitImageEvt(char *requestor, rtdIMAGE_EVT_HNDL *eventHndl, char *error) { char *subr = "rtdInitImageEvt"; int s; /* connected socket descriptor */ struct hostent *hp; /* pointer to host info for remote host */ struct servent *sp; /* pointer to service information */ char *ctime(); /* declare time formatting routine */ struct sockaddr_in rtdClientAddr; /* for local socket address */ struct sockaddr_in rtdServerAddr; /* for peer socket address */ #if HAVE_SOCKLEN_T socklen_t addrlen; #else int addrlen; #endif int optval; char buf[256]; /* clear out address structures */ memset ((char *)&rtdClientAddr, 0, sizeof(struct sockaddr_in)); memset ((char *)&rtdServerAddr, 0, sizeof(struct sockaddr_in)); /* check input parameters */ if (eventHndl == NULL) return RTD_ERROR; /* This version only supports the local host connection */ gethostname(buf,sizeof(buf)); /* Set up the peer address to which we will connect. */ rtdServerAddr.sin_family = AF_INET; /* Get the host information for the hostname that the * user passed in. */ hp = gethostbyname (buf); if (hp == NULL) { rtdSetError(subr, error, RTD_ERR_GETHOSTNAME); return RTD_ERROR; } rtdServerAddr.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr; /* Assign the rtdServer port number: * 1: check the environment RTD_SERVER_PORT * 2: else read in the /etc/services * 3: if everything fails try the fallback RTD_FALLBACK_PORT */ if (getenv(RTD_SERVER_PORT)) rtdServerAddr.sin_port = htons(atoi(getenv(RTD_SERVER_PORT))); /* Find the information for the rtdServer * in order to get the needed port number. */ if (rtdServerAddr.sin_port == 0) { sp = getservbyname (RTD_SERVICE, "tcp"); if (sp != NULL) rtdServerAddr.sin_port = sp->s_port; else { /*fprintf(stderr, "%s: service not found ",RTD_SERVICE); */ rtdServerAddr.sin_port = htons(RTD_FALLBACK_PORT); } } /* Create the socket. */ s = socket (AF_INET, SOCK_STREAM, 0); if (s == -1) { rtdSetError(subr, error, RTD_ERR_CREAT_SOCKET); return RTD_ERROR; } optval = 1; setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char *)&optval, sizeof optval); /* Try to connect to the remote server at the address * which was just built into rtdServerAddr. */ if (connect(s, (struct sockaddr *)&rtdServerAddr, sizeof(struct sockaddr_in)) == -1) { rtdSetError(subr, error, RTD_ERR_CONNECT_SOCKET); close(s); return RTD_ERROR; } /* */ addrlen = sizeof(struct sockaddr_in); if (getsockname(s, (struct sockaddr*)&rtdClientAddr, &addrlen) == -1) { close(s); return RTD_ERROR; } /* printf("Connected to %s on port %u at %s", RTD_SERVICE, ntohs(rtdClientAddr.sin_port), ctime(&timevar)); */ /* Insert event handle data */ eventHndl->socket = s; memcpy(&eventHndl->clientAddr,&rtdClientAddr,sizeof(rtdClientAddr)); strncpy(eventHndl->reqName,requestor,RTD_NAMELEN); return RTD_OK; } /* * rtdSetError prints an error message on stdout if the error pointer * is NULL; otherwise it just returns. */ void rtdSetError(char *subr, char *error, char *msg) { if (error) strcpy(error, msg); else fprintf(stderr,"%s:%s !\n",subr, msg); } int rtdInitServer(int *listenSocket, int portNumber, char *error) { char *subr = "rtdInitServer"; int ls; /* listen socket descriptor */ struct servent *sp; /* pointer to service information */ struct sockaddr_in rtdServerAddr; /* for local socket address */ int optval; /* check output parameters */ if (listenSocket == NULL) { rtdSetError(subr, error, RTD_ERR_NULL_PTR); return RTD_ERROR; } /* clear out address structures */ memset ((char *)&rtdServerAddr, 0, sizeof(struct sockaddr_in)); rtdServerAddr.sin_family = AF_INET; rtdServerAddr.sin_addr.s_addr = INADDR_ANY; /* Assign the rtdServer port number: * 1: check if portnumber set by user * 2: else read in the /etc/services * 3: if everything fails try the fallback RTD_FALLBACK_PORT */ if (portNumber != 0) rtdServerAddr.sin_port = htons(portNumber); if (rtdServerAddr.sin_port == 0) { sp = getservbyname (RTD_SERVICE, "tcp"); if (sp != NULL) rtdServerAddr.sin_port = sp->s_port; else rtdServerAddr.sin_port = htons(RTD_FALLBACK_PORT); } /* Create the listen socket. */ ls = socket (AF_INET, SOCK_STREAM, 0); if (ls == -1) { rtdSetError(subr, error, RTD_ERR_CREAT_SOCKET); return RTD_ERROR; } /* set socket options (for HP set all bytes to 1!) */ optval = 0x1111; setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, (const char *)&optval, sizeof optval); /* Bind the listen address to the socket. */ if (bind(ls, (struct sockaddr *)&rtdServerAddr, sizeof(struct sockaddr_in)) == -1) { rtdSetError(subr, error, RTD_ERR_BIND_SOCKET); return RTD_ERROR; } /* Initiate the listen on the socket so remote users * can connect. The listen backlog is set to 5. 20 * is the currently supported maximum. */ if (listen(ls, 5) == -1) { rtdSetError(subr, error, RTD_ERR_LISTEN_SOCKET); return RTD_ERROR; } *listenSocket = ls; return RTD_OK; } /* * Write nbyte to socket. If the pipe is broken (i.e. when rtdServer was * killed) ignore the signal for backwards compatibility, so that the * client can continue. */ int rtdWrite(int fd, void* buf, int nbyte) { signal(SIGPIPE, SIG_IGN); return write(fd, buf, nbyte); } int rtdSendImageInfo(rtdIMAGE_EVT_HNDL *eventHndl, rtdIMAGE_INFO *imageInfo, char *error) { char *subr = "rtdSendImageInfo"; static rtdPACKET *rtdPacket; /* check input parameters */ if (eventHndl == NULL || imageInfo == NULL) { rtdSetError(subr, error, RTD_ERR_NULL_PTR); return RTD_ERROR; } if (rtdPacket == NULL) rtdPacket = calloc(1, sizeof(rtdPACKET)); if (eventHndl->socket == 0) { rtdSetError(subr, error, RTD_ERR_NO_SOCKET); return RTD_ERROR; } /* setup protocol packet */ rtdPacket->opcode = IMAGEINFO; rtdPacket->body.data.hdr.reqType = IMAGETRANS; /* IT SW */ strncpy(rtdPacket->body.data.hdr.reqName,eventHndl->reqName, RTD_NAMELEN); memcpy(&rtdPacket->body.data.rtdImageInfo, imageInfo, sizeof(rtdIMAGE_INFO)); rtdPacket->body.data.rtdImageInfo.version = RTD_EVT_VERSION; /* use unbuffered write operation */ if (rtdWrite(eventHndl->socket, rtdPacket,sizeof(rtdPACKET)) != sizeof(rtdPACKET)) { rtdSetError(subr, error, RTD_ERR_DATAWRITE); return RTD_ERROR; } return RTD_OK; } /* * read a message from the rtd server and return it in imageInfo. * - "eventHndl" is the handle initialized by rtdInitImageEvt. * - if "verbose" is non-zero, print diagnostic messages to stdout. * - "error" is reserved for future use. */ int rtdRecvImageInfo(rtdIMAGE_EVT_HNDL *eventHndl, rtdIMAGE_INFO *imageInfo, int verbose, char *error) { char *subr = "rtdRecvImageInfo"; rtdPACKET rtdPacket; long nbytes = 0; int n = 0; /* check input parameters */ if (eventHndl == NULL || imageInfo == NULL) { rtdSetError(subr, error, RTD_ERR_NULL_PTR); return RTD_ERROR; } if (eventHndl->socket == 0) { rtdSetError(subr, error, RTD_ERR_NO_SOCKET); return RTD_ERROR; } while (1) { /* If there is more than one message to read, skip all but the last unless * the shm buffer is locked */ if (ioctl(eventHndl->socket, FIONREAD, &nbytes) != 0) { if (verbose) rtdSetError(subr, error, "rtdRecvImageInfo: ioctl failed\n"); return RTD_ERROR; } if (nbytes == 0) break; memset(&rtdPacket,'\0',sizeof(rtdPACKET)); n = read(eventHndl->socket, &rtdPacket, sizeof(rtdPACKET)); if (n < 0) { rtdSetError(subr, error, strerror(errno)); return RTD_ERROR; } if (n == sizeof(rtdPACKET)) { if (rtdPacket.body.data.rtdImageInfo.semId) { break; } } if (nbytes > sizeof(rtdPACKET)) { if (verbose) printf("%s: ignoring unread packets\n", subr); } else break; } if (n < 32) /* hardcoded! We need at least the info struct until binningY */ { rtdSetError(subr, error, RTD_ERR_UNKNOWN_SIZE); return RTD_ERROR; } if (rtdPacket.body.data.rtdImageInfo.version != RTD_EVT_VERSION) rtdSetError(subr, error, RTD_ERR_INCOMPAT); /* setup protocol packet */ if (rtdPacket.opcode == IMAGEINFO || rtdPacket.body.data.hdr.reqType == IMAGETRANS) { memcpy(imageInfo, &rtdPacket.body.data.rtdImageInfo, sizeof(rtdIMAGE_INFO)); return RTD_OK; } rtdSetError(subr, error, RTD_ERR_UNKNOWN_OPCODE); return RTD_ERROR; } int rtdAttachImageEvt(rtdIMAGE_EVT_HNDL *eventHndl, char *camera, char *error) { char *subr = "rtdAttachImageEvt"; rtdPACKET rtdPacket; memset(&rtdPacket,'\0',sizeof(rtdPACKET)); /* check input parameters */ if (eventHndl == NULL || camera == NULL) { rtdSetError(subr, error, RTD_ERR_NULL_PTR); return RTD_ERROR; } if (eventHndl->socket == 0) { rtdSetError(subr, error, RTD_ERR_NO_SOCKET); return RTD_ERROR; } /* setup protocol packet */ rtdPacket.opcode = ATTACH; rtdPacket.body.data.hdr.reqType = RTDWIDGET; /* RTD SW */ strncpy(rtdPacket.body.data.hdr.reqName,eventHndl->reqName, RTD_NAMELEN); strncpy(rtdPacket.body.data.hdr.camName,camera, RTD_NAMELEN); /* use unbuffered write operation */ if (rtdWrite(eventHndl->socket, &rtdPacket,sizeof(rtdPACKET)) != sizeof(rtdPACKET)) { rtdSetError(subr, error, RTD_ERR_DATAWRITE); return RTD_ERROR; } return RTD_OK; } int rtdDetachImageEvt(rtdIMAGE_EVT_HNDL *eventHndl, char *camera, char *error) { char *subr = "rtdDetachImageEvt"; rtdPACKET rtdPacket; memset(&rtdPacket,'\0',sizeof(rtdPACKET)); /* check input parameters */ if (eventHndl == NULL) { rtdSetError(subr, error, RTD_ERR_NULL_PTR); return RTD_ERROR; } if (eventHndl->socket == 0) { rtdSetError(subr, error, RTD_ERR_NO_SOCKET); return RTD_ERROR; } /* setup protocol packet */ rtdPacket.opcode = DETACH; rtdPacket.body.data.hdr.reqType = RTDWIDGET; /* RTD SW */ strncpy(rtdPacket.body.data.hdr.reqName,eventHndl->reqName, RTD_NAMELEN); strncpy(rtdPacket.body.data.hdr.camName,camera, RTD_NAMELEN); /* use unbuffered write operation */ if (rtdWrite(eventHndl->socket, &rtdPacket,sizeof(rtdPACKET)) != sizeof(rtdPACKET)) { rtdSetError(subr, error, RTD_ERR_DATAWRITE); return RTD_ERROR; } return RTD_OK; } int rtdServerPing(rtdIMAGE_EVT_HNDL *eventHndl, char *error) { char *subr = "rtdServerPing"; rtdPACKET rtdPacket; memset(&rtdPacket,'\0',sizeof(rtdPACKET)); /* check input parameters */ if (eventHndl == NULL) { rtdSetError(subr, error, RTD_ERR_NULL_PTR); return RTD_ERROR; } if (eventHndl->socket == 0) { rtdSetError(subr, error, RTD_ERR_NO_SOCKET); return RTD_ERROR; } /* setup protocol packet */ rtdPacket.opcode = PING; rtdPacket.body.data.hdr.reqType = RTDWIDGET; /* RTD SW */ strncpy(rtdPacket.body.data.hdr.reqName,eventHndl->reqName, RTD_NAMELEN); /* use unbuffered write operation */ if (rtdWrite(eventHndl->socket, &rtdPacket,sizeof(rtdPACKET)) != sizeof(rtdPACKET)) { rtdSetError(subr, error, RTD_ERR_DATAWRITE); return RTD_ERROR; } return RTD_OK; } int rtdClose(rtdIMAGE_EVT_HNDL *eventHndl, char *error) { /* check input parameters */ if (eventHndl == NULL || eventHndl->socket == 0) { return RTD_OK; } /* simply close the connection */ close(eventHndl->socket); eventHndl->socket = 0; return RTD_OK; } void rtdSleep(int msec) { struct timeval time; time.tv_sec = msec / 1000; time.tv_usec = (msec % 1000) * 1000; select(0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &time); } skycat-3.1.2-starlink-1b/rtd/rtdevt/rtdImageEvent.h000066400000000000000000000202131215713201500221430ustar00rootroot00000000000000/************************************************************************* * E.S.O. - VLT project * * "@(#) $Id: rtdImageEvent.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * rtdImageEvent.h * * who when what * --------- -------- ---------------------------------------------- * T.Herlin 11/05/95 Created * T.Herlin 05/12/95 Added rtdClose() * D.Hopkinson 02/12/96 Added multi-buffering shared memory with semaphores * P.Biereichel 17/06/97 Added function prototype for rtdClose() * pbiereic 11/10/99 Added wcsFlags * pbiereic 25/11/99 Rotation angle is anticlockwise positive (changed comment) * pbiereic 10/10/02 Added a remark that semId must be set to -1 if * semaphore locking is not used. Note that semaphore Id=0 * is indeed a valid number. * pbiereic 05/02/03 Added shmEndian flag to image event structure. * pbiereic 12/08/07 added support for data types double and long long int */ /************************************************************************* * * ************************************************************************* */ #ifndef RTD_IMAGE_EVENT_H #define RTD_IMAGE_EVENT_H /* POSIX hack for solaris platforms */ #ifdef _POSIX_SOURCE #define rtdEVT_POSIX 1 #undef _POSIX_SOURCE #endif /* * Required system headers */ #include #include #include #include #ifdef rtdEVT_POSIX #define _POSIX_SOURCE 1 #undef rtdEVT_POSIX #endif #ifdef __cplusplus extern "C" { #ifndef CONST #define CONST const #endif #else /* __cplusplus */ #ifndef CONST #define CONST #endif #endif /* __cplusplus */ /* * DEFINES */ #define RTD_EVT_VERSION 2 /* increment when rtdIMAGE_INFO is not backwards compat */ #define RTD_SERVICE "rtdServer" #define RTD_FALLBACK_PORT 5555 #define RTD_SERVER_PORT "RTD_SERVER_PORT" #define RTD_PTEST_FNAME "/tmp/perftest.txt" #define RTD_PERFTEST "RTDPERFTEST" #define RTD_EAVESDROPCAMERA "RTDEAVESDROP" #define RTD_SIMULATOR "RTDSIMULATOR" #define RTD_ENDPROC 127 /* Data type for end-of-process */ #define RTD_NAMELEN 32 #define RTD_OK 0 #define RTD_ERROR 1 #define RTD_NUMSHM 1 /* Number of shm buffers in simulator. */ #define RTD_WCS_FLIP_RA 1 /* flip display for RA */ #define RTD_WCS_FLIP_DEC 2 /* flip display for DEC */ #define RTD_HAVE_SHMENDIAN 1 /* info structure has shmEndian */ /* * Image types (also corresponds to FITS BITPIX field) */ typedef enum rtdIMAGE_TYPE { BYTE = 8, /* 8 bit images */ XIMAGE = -8, /* prescaled ximage */ SHORT = 16, /* 16 bit signed */ USHORT = -16, /* 16 bit unsigned */ INT = 32, /* 32 bit integer */ FLOAT = -32, /* 32 bit floating point */ LONG64 = 64, /* 64 bit integer (long long int) */ DOUBLE = -64 /* 64 bit double precision */ } rtdIMAGE_TYPE; /* * STRUCTURES */ typedef struct { char version; /* protocol version (filled by rtdSendImageInfo) */ char frameId; /* Frame Id */ char dataType; /* BYTE, SHORT, FLOAT etc. */ char bytePerPixel; /* No. of bytes used per pixel */ int shmId; /* ID for the shared memory block */ short frameX; /* X Coord. for upper left corner */ short frameY; /* Y Coord. for upper left corner */ short xPixels; /* Pixels in horisontal direction */ short yPixels; /* Pixels in vertical direction */ short blockLines; /* NOT USED! Number of lines contained in block. If 0 no block mode */ short blockOffset; /* NOT USED! Y offset on image */ int highCut; /* High cut level when auto cut */ int lowCut; /* Low cut level when auto cut */ /* The binning factors in X and Y must be the same for WCS display */ short binningX; /* Binning factor applied on image */ short binningY; /* Binning factor applied on image */ struct timeval timeStamp; /* UTC time when image was aquired */ /* * The following fields were added to support World Coordinates * Set all fields to 0 if World Coordinates are not supported */ double ra; /* Center right ascension in degrees */ double dec; /* Center declination in degrees */ double secpix; /* Number of arcseconds per pixel */ double xrefpix; /* Reference pixel X coordinate */ double yrefpix; /* Reference pixel Y coordinate */ double rotate; /* Rotation angle (anticlockwise positive) in degrees */ int equinox; /* Equinox of coordinates, 1950 and 2000 supported */ double epoch; /* Epoch of coordinates, used for FK4/FK5 conversion, no effect if 0 */ char proj[8]; /* Projection: one of: "-SIN", "-TAN", "-ARC", "-NCP", "-GLS", "-MER", "-AIT", "-STG", "PLATE", "LINEAR", "PIXEL" */ /* The following fields were added to support image synchronization */ int semId; /* ID of semaphore set. Set to -1 if not used! */ int shmNum; /* Number of semaphore in the set */ /* *These fields were added to support detector "chip" coordinates for real-time * images. The chip origin is assumed by be at lower left, as for FITS. */ short startX; /* First window pixel in X (Y) direction within the */ short startY; /* detector physical system. */ unsigned short wcsFlags; /* flags for WCS display: see RTD_WCS defines above */ short shmEndian; /* Byte order of shm data: 0=big Endian, 1=little Endian, -1 native byte order */ int reserved[8]; /* reserved for future use */ } rtdIMAGE_INFO; typedef struct { int socket; struct sockaddr_in clientAddr; char reqName[RTD_NAMELEN]; } rtdIMAGE_EVT_HNDL; #ifdef STATUS #undef STATUS #endif typedef enum rtdSERVER_CMDS { ATTACH = 1, /* RTD Widget Event Attachment */ DETACH, /* RTD Widget Event Detachment */ IMAGEINFO, /* IMAGE Update Event */ CONTROL, /* Control of rtdServer (N/A) */ STATUS, /* Status of rtdServer */ PING /* PING rtdServer */ } rtdSERVER_CMDS; typedef enum rtdCLIENT_TYPE { /* Client types */ RTDWIDGET = 1, /* RTD Widget */ IMAGETRANS, /* Image Transfer SW */ EAVESDROP , /* Eaves Drop Servers */ OTHER /* Other's e.g. control panels */ } rtdCLIENT_TYPE; typedef struct { rtdCLIENT_TYPE reqType; /* requestor type */ char reqName[RTD_NAMELEN]; /* requestor type */ char camName[RTD_NAMELEN]; /* requestor name */ } rtdHEADER; typedef struct { rtdHEADER hdr; rtdIMAGE_INFO rtdImageInfo; } rtdFORMAT_DATA; typedef union { rtdFORMAT_DATA data; char text[sizeof(rtdFORMAT_DATA)]; } rtdDATA; typedef struct { rtdSERVER_CMDS opcode; rtdDATA body; } rtdPACKET; /* * ERROR DEFINES */ #define RTD_ERR_DATAWRITE "Not all data written to rtdServer" #define RTD_ERR_NULL_PTR "Null pointer passed as argument" #define RTD_ERR_NO_SOCKET "No socket connection in eventHndl" #define RTD_ERR_CREAT_SOCKET "Could not create socket" #define RTD_ERR_LISTEN_SOCKET "Could not listen on socket" #define RTD_ERR_CONNECT_SOCKET "Could not connect socket" #define RTD_ERR_BIND_SOCKET "Could not bind socket" #define RTD_ERR_UNKNOWN_SIZE "Packet received with unknown size" #define RTD_ERR_UNKNOWN_OPCODE "Packet received with unknown opcode" #define RTD_ERR_GETHOSTNAME "Hostname not found in /etc/hosts" #define RTD_ERR_INCOMPAT "Incompatible version of rtdIMAGE_INFO structure received" /* * Real Time Display Image Event external function prototypes */ int rtdInitImageEvt(CONST char *requestor, rtdIMAGE_EVT_HNDL *eventHndl, char *error); int rtdInitServer(int *listenSock, int portNo, char *error); int rtdSendImageInfo(rtdIMAGE_EVT_HNDL *imageEvtHndl, rtdIMAGE_INFO *imageInfo, char *error); int rtdRecvImageInfo(rtdIMAGE_EVT_HNDL *imageEvtHndl, rtdIMAGE_INFO *imageInfo, int verbose, char *error); int rtdAttachImageEvt(rtdIMAGE_EVT_HNDL *imageEvtHndl, char *camera, char *error); int rtdDetachImageEvt(rtdIMAGE_EVT_HNDL *imageEvtHndl, char *camera, char *error); int rtdServerPing(rtdIMAGE_EVT_HNDL *eventHndl, char *error); int rtdClose(rtdIMAGE_EVT_HNDL *imageEvtHndl, char *error); void rtdSetError(char *subr, char *error, char *msg); void rtdSleep(int msec); #ifdef __cplusplus } #endif #endif /*!RTD_IMAGE_EVENT_H*/ skycat-3.1.2-starlink-1b/rtd/rtdevt/rtdLOG.C000066400000000000000000000023701215713201500204770ustar00rootroot00000000000000/******************************************************************************* * E.S.O. - VLT project * * "@(#) $Id: rtdLOG.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * who when what * -------- -------- ---------------------------------------------- * pbiereic 01/03/01 created */ /************************************************************************ * NAME * * * SYNOPSIS * rtdLOG::rtdLOG(int verbose) : * verbose: 0 don't log, 1 print logging messages * * DESCRIPTION * rtdLOG is a class for printing logging messages * * PUBLIC METHODS * void rtdLOG::log(const char *format, ...) * Prints logs on stdout * * FILES * * ENVIRONMENT * * COMMANDS * * RETURN VALUES * * CAUTIONS * * EXAMPLES * * SEE ALSO * * BUGS * *------------------------------------------------------------------------ */ #define _POSIX_SOURCE 1 #include "rtdLOG.h" static const char *rcsId="@(#) $Id: rtdLOG.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; rtdLOG::rtdLOG(int verbose) : verbose_(verbose) { } rtdLOG::~rtdLOG() {} void rtdLOG::log(const char *format, ...) { if (! verbose_) return; printf("rtdServer: "); va_list ap; va_start(ap, format); vprintf(format, ap); va_end(ap); } skycat-3.1.2-starlink-1b/rtd/rtdevt/rtdLOG.h000066400000000000000000000014031215713201500205400ustar00rootroot00000000000000#ifndef rtdLOG_H #define rtdLOG_H /******************************************************************************* * E.S.O. - VLT project * * "@(#) $Id: rtdLOG.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * who when what * -------- -------- ---------------------------------------------- * pbiereic 01/03/01 created */ /************************************************************************ * *---------------------------------------------------------------------- */ #include #include class rtdLOG { public: // constructor and destructor rtdLOG(int); ~rtdLOG(); void log(const char *format, ...); int Verbose() { return verbose_; } private: int verbose_; protected: }; #endif /*!rtdLOG_H*/ skycat-3.1.2-starlink-1b/rtd/rtdevt/rtdSERVER.C000066400000000000000000000264161215713201500210730ustar00rootroot00000000000000/******************************************************************************* * E.S.O. - VLT project * * "@(#) $Id: rtdSERVER.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * who when what * -------- -------- ---------------------------------------------- * pbiereic 01/03/01 created (adapted from previous rtdServer) */ /************************************************************************ * NAME * rtdSERVER - class which manages all clients which connect to the rtdServer * * SYNOPSIS * #include "rtdSERVER.h" * rtdSERVER::rtdSERVER(int verbose, int socketFd, int delay) * verbose - verbose flag * socketFd - socket file descriptor as returned by rtdInitServer() * delay - delay after each client request in msec * * DESCRIPTION * * rtdSERVER accepts client connections and serves requests from connected * clients such as forwarding image events, attach/detach etc. For each * client which connect to the rtdServer, a "client object" is created * which executes the requests from the client. * The main loop enables new connection requests and requests from clients * already connected (via a select() call). Then it processes all active requests * within another loop, so that all clients are served with the same priority, * in particular, no client can block another client. * Clients which use an incompatible info package structure are simply * disconnected. * rtdSERVER "knows" the number of attached RTD clients and sets the semaphore * accordingly. It also provides for multicasting of event notification. * * PUBLIC METHODS * * int rtdSERVER::Loop() * The main loop which accepts connections and forwards image events to * RTD clients which are attached to the image producer (camera). Cameras * use rtdSendImageInfo() for sending image events. * The command opcodes currently provided are: * ATTACH / DETACH: used by RTD to receive or block image events * IMAGEINFO: used by camera clients to send image events * * rtdCLNT *rtdSERVER::Accept() * Accept connection from RTD or camera (i.e. rtdServer clients). * The Accept() sets the required socket options and creates a * "client object" for handling all requests coming from the client * socket. * * void rtdSERVER::DisconnectClient(rtdCLNT *client) * Dsiconnect a client which either sent a wrong event request or died * * void rtdSERVER::ServImageCmd(rtdPACKET *rtdPacket, int numbyte) * This methods serves the image event. It first increments the semaphore * according to the number of RTD clients attached. The semaphore is released * by the RTD client when the image was displayed. * Then it calls the client object for actually forwarding the image event. * * int rtdSERVER::IncrSem(rtdPACKET *rtdPacket, int increment) * Increment the semaphore: this is done only when the camera client has * implemented the semaphore (see rtdSem.c). * * rtdCLNT *rtdSERVER::GetCurrClient() * Return the object for a client which has sent a request. * * FILES * * ENVIRONMENT * * COMMANDS * * RETURN VALUES * * CAUTIONS * * EXAMPLES * * SEE ALSO * rtdInitImageEvt(3), rtdSendImageInfo(3), rtdSem(1) * * BUGS * *------------------------------------------------------------------------ */ #include "rtdSERVER.h" static const char *rcsId="@(#) $Id: rtdSERVER.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; rtdSERVER::rtdSERVER(int verbose, int socketFd, int delay) : rtdLOG(verbose), socketFd_(socketFd), delay_(delay), numClnt_(0), reqClnt_(0), reqCount_(0) { for (int i = 0; i <= MAX_CLNT; i++) clnt_[i] = NULL; } rtdSERVER::~rtdSERVER() { for (int i = 0; i < numClnt_; i++) delete clnt_[i]; } int rtdSERVER::Loop() { fd_set readFd; // file descriptor for port RTD_SERVER_PORT (default 5555) readFd_ = (fd_set *) &readFd; time_t timeVal; rtdPACKET rtdPacket; // copy of the standard info package structure int packetSize = sizeof(rtdPACKET); rtdHEADER *hdr = &(rtdPacket.body.data.hdr); int socket; int n; timeVal = time(NULL); strcpy(startTime_, ctime(&timeVal)); log("Entering main loop and waiting for client connections...\n"); while ( 1 ) { /* * sleep a bit to give the RTD clients more time. A delay can * be used to slow down the image event rate from ultra-fast cameras * provided the camera process is using semaphore locking. */ if (delay_ > 0) rtdSleep(delay_); FD_ZERO(readFd_); // enable read for connection requests FD_SET(socketFd_, readFd_); // Enable read for all clients connected. for (int i = 0; i < numClnt_; i++) FD_SET(clnt_[i]->Socket(), readFd_); ///////////////////////////////////////////// int status = select(32, readFd_, 0, 0, NULL); ///////////////////////////////////////////// if (status <= 0) { log("Select error !!!\n"); return RTD_ERROR; // timeout or error (signals) should not happen } log("*** Handling new event (%d) ....\n", reqCount_++); // total number of requests // check if a client wants to connect if (FD_ISSET(socketFd_, readFd_) > 0) { Accept(); continue; // accept or refuse, anyway continue the loop... } /* * service clients on all active client sockets i.e. the ones which are * currently in the readFd set. This ensures that all clients are * serviced even when there is a client which sends events at very * high speed. */ rtdCLNT *currClient = NULL; // current client object while ((currClient = GetCurrClient()) != NULL) { socket = currClient->Socket(); n = read(socket, &rtdPacket, packetSize); // check if client died or sent a wrong event structure if (n < 0 || n != packetSize) { if (n > 0) log("Client sent a wrong request. Will be disconnected.\n"); else log("Client apparently closed the connection.\n"); DisconnectClient(currClient); // Disconnect the client continue; } currClient->Type(hdr->reqType); // keep the requestor type // execute command given in the event info structure switch (rtdPacket.opcode) { case ATTACH: currClient->Attach(hdr->reqName, hdr->camName); log("ATTACH command received from %s, %s\n", currClient->ReqName(), currClient->CamName()); break; case DETACH: log("DETACH command received from %s, %s\n", currClient->ReqName(), currClient->CamName()); currClient->Detach(); break; case IMAGEINFO: log("IMAGEINFO command received (port %d)\n", currClient->Port()); ServImageCmd(&rtdPacket); break; #ifdef STATUS #undef STATUS #endif case STATUS: log("STATUS command received (port %d)\n", currClient->Port()); ServStatusCmd(socket); break; case PING: log("PING command received (port %d)\n", currClient->Port()); break; default: log("Unknown opcode received: %d. Client will be disconnected.\n", rtdPacket.opcode); DisconnectClient(currClient); // Disconnect the client } } } } /* * Accept connection from RTD or camera */ rtdCLNT *rtdSERVER::Accept() { rtdCLNT *client; reqClnt_++; // for statistics // Create a new object for handling the request for this connection client = clnt_[numClnt_++] = new rtdCLNT(Verbose(), numClnt_); if (client->Accept(socketFd_) == RTD_OK && numClnt_ < MAX_CLNT) return client; if (numClnt_ >= MAX_CLNT) log("Too many cameras and RTD's connected to rtdServer\n"); DisconnectClient(client); return NULL; } void rtdSERVER::DisconnectClient(rtdCLNT *client) { int idx = client->Index(); log("Closing connection (port %d)\n", client->Port()); delete client; clnt_[idx] = NULL; numClnt_--; /* * shuffle up the clnt_[] pointer buffer to simplify programatic access. * The last pointer of the buffer is not used but set to NULL. */ for (int i = idx; i < MAX_CLNT; i++) clnt_[i] = clnt_[i+1]; } /* * return a client object for which a request is pending */ rtdCLNT *rtdSERVER::GetCurrClient() { for (int i = 0; i < numClnt_; i++) { if (FD_ISSET(clnt_[i]->Socket(), readFd_) <= 0) continue; FD_CLR(clnt_[i]->Socket(), readFd_); // needed for next FD_ISSET clnt_[i]->Index(i); // client index return clnt_[i]; } return NULL; } void rtdSERVER::ServImageCmd(rtdPACKET *rtdPacket) { int numClients = 0; // number of RTD clients attached to the camera char *camera = rtdPacket->body.data.hdr.reqName; rtdIMAGE_INFO *info = &(rtdPacket->body.data.rtdImageInfo); log("Image event received from: %s\n", camera); if (*camera == '\0') return; // Get the number of RTD clients which are currently attached to the camera for (int i = 0; i < numClnt_; i++) { if (clnt_[i]->AttachedToCamera(camera) == RTD_OK) numClients++; } /* * Increment the shared memory semaphore with (numClients - 1). One * increment was already done by the camera. */ if (IncrSem(rtdPacket, numClients - 1) != RTD_OK) return; if (! numClients) { log("No RTD clients are currently attached to '%s'\n", camera); return; } /* * Now loop over the clients to send the packets to all attached RTD's. */ for (int i = 0; i < numClnt_; i++) { if (clnt_[i]->AttachedToCamera(camera) != RTD_OK) continue; /* * The attached RTD client object needs to cleanup semaphores * when it's associated RTD terminates. */ clnt_[i]->SetSemPar(info->semId, info->shmNum); log("Forwarding event to: %s\n", clnt_[i]->ReqName()); if (clnt_[i]->Forward(rtdPacket) != RTD_OK) log("Forwarding event message failed\n"); } return; } void rtdSERVER::ServStatusCmd(int socket) { char buf[4096], buf2[256]; sprintf(buf, "rtdServer info:\n" "rtdServer was started: %s" "Delay was set to: %d\n" "Total number of connections: %d\n" "Total number of requests: %d\n", startTime_, delay_, reqClnt_, reqCount_); strcat(buf, "Current rtdServer clients:\n"); for (int i=0; i < numClnt_; i++) { if (socket == clnt_[i]->Socket()) continue; sprintf(buf2, "Entry: %d \tName: %s\tCamera: %s\t Type: %s\t\n", i, clnt_[i]->ReqName(), clnt_[i]->CamName(), clnt_[i]->TypeName()); if (strlen(buf) + sizeof(buf2) + 1 < sizeof(buf)) strcat(buf, buf2); } log(buf); write(socket, buf, strlen(buf)+1); } int rtdSERVER::IncrSem(rtdPACKET *rtdPacket, int increment) { rtdIMAGE_INFO *rtdImageInfo = &(rtdPacket->body.data.rtdImageInfo); int semId = rtdImageInfo->semId; int shmNum = rtdImageInfo->shmNum; /* * First thing is to check that semaphores were implemented by the camera. * Note that semId=0 is a valid id. */ int val = rtdSemGetVal(semId, shmNum); if (val < 0) return RTD_OK; // for applications not using semaphores log("Semaphores implemented: semId = %d, shmNum=%d, val = %d\n", semId, shmNum, val); /* * Check also that the semaphore given in the image information * is set to one. */ if (val != 1) { log("Warning: sending image event without semaphore set to 1\n"); return RTD_OK; } /* * Now increment the semaphore by increment. First set the required * semaphore to change in the sembuf structure. */ if (increment != 0) rtdSemIncrement(semId, shmNum, increment); return RTD_OK; } skycat-3.1.2-starlink-1b/rtd/rtdevt/rtdSERVER.h000066400000000000000000000036541215713201500211370ustar00rootroot00000000000000#ifndef rtdSERVER_H #define rtdSERVER_H /******************************************************************************* * E.S.O. - VLT project * * "@(#) $Id: rtdSERVER.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * who when what * -------- -------- ---------------------------------------------- * pbiereic 01/03/01 created */ /************************************************************************ * *---------------------------------------------------------------------- */ #define MAX_CLNT 300 // max. number of clients which can connect #include "rtdCLNT.h" // includes almost all we need #include "rtdLOG.h" #include #include // This class is handling semaphores, not rtdCLNT #ifndef HAVE_UNION_SEMUN // argument type needed by semctl - not used here union semun { int val; // used for SETVAL only struct semid_ds *buf; // for IPC_STAT and IPC_SET ushort *array; // used for GETALL and SETALL }; #endif class rtdSERVER : public rtdLOG { public: // constructor and destructor rtdSERVER(int, int, int); ~rtdSERVER(); int Loop(); protected: rtdCLNT *GetCurrClient(); void ServImageCmd(rtdPACKET *rtdPacket); void ServStatusCmd(int socket); int IncrSem(rtdPACKET *rtdPacket, int increment); rtdCLNT *Accept(); void DisconnectClient(rtdCLNT *client); private: int socketFd_; // listen socket int delay_; // delay in msec int numClnt_; // number of clients which are currently connected rtdCLNT *clnt_[MAX_CLNT+1]; // pointer array to camera objects int reqCount_; // total number of requests int reqClnt_; // total number of clients which connected fd_set *readFd_; // read file descriptor mask char startTime_[256]; // start time }; #endif /*!rtdSERVER_H*/ skycat-3.1.2-starlink-1b/rtd/rtdevt/rtdSem.c000066400000000000000000000556471215713201500206610ustar00rootroot00000000000000/******************************************************************************* * E.S.O. - VLT project * * rtdSem.c * * who when what * -------- -------- ---------------------------------------------- * D.Hopkinson 21/01/97 Created. * D.Hopkinson 27/02/97 Updated to include shared memory creation/ * destruction. * pbiereic 14/06/97 Added rtdShmFillNext() * pbiereic 22/10/99 Bug fixed in rtdShmDelete * pbiereic 01/03/01 Added: rtdSemIncrement(), rtdSemGetVal() * pbiereic 28/05/01 Removed SEM_UNDO in rtdShmFill (see system parameter * semaem on HP which specifies the maximum amount the value * of a semaphore can be changed by an undo operation) * * Description: * This module contains several utility routines for the creation, * activation, and destruction of semaphores and associated shared * memory areas. */ /************************************************************************ * NAME * rtdSem - utility routines for semaphores and shared memory * * rtdShmCreate - Initialise shared memory and semaphore set. * * rtdShmFill - Fill chosen piece of shared memory with data. * * rtdShmStruct - Fill image information structure prior to send. * * rtdShmDelete - Remove the shared memory/semaphore set. * * rtdShmLocked - Detect if a particular shm segment is locked. * * rtdShmFillFirst - Fill the first free segment of shared memory. * * rtdShmFillNext - Fill the next free segment of shared memory. * * rtdShmServicePacket- Clear a semaphore given image event information. * * rtdSemDecrement - Decrement the chosen semaphore. * * rtdSemReset - Reset the chosen semaphore to zero. * * SYNOPSIS * #include "rtdSem.h" * * int rtdShmCreate(int num, * rtdShm *shmPtr, * int width, * int height, * int type) * * int rtdShmFill(int index, * char *data, * rtdShm *shmPtr, * int verbose) * * int rtdShmStruct(int index, * rtdIMAGE_INFO *imageInfo, * rtdShm *shmPtr) * * int rtdShmDelete(rtdShm *shmPtr) * * int rtdShmLocked(rtdShm *shmPtr, * int index) * * int rtdShmFillFirst(char *data, * rtdShm *shmPtr) * * int rtdShmFillNext(int index, * char *data, * rtdShm *shmPtr) * * void rtdShmServicePacket(rtdIMAGE_INFO *imageInfo) * * void rtdSemDecrement(int semId, * int semNum) * * void rtdSemReset(int semId, * int semNum) * * * DESCRIPTION * * These routines are (mostly) for the benefit of CCD software * developers who wish to interface with the shared memory/ * semaphore locking implemented within the RTD. The exception * to this are the routines rtdSemDecrement and rtdSemReset, * which are currently used by the RTD and rtdServer, although * there may be a use for them in the future on the CCD side. * * These routines all use a structure (defined in rtdSem.h): * typedef struct rtdShm { * int *shmId; Array of shared memory Ids * int semId; Semaphore Id * int num; Number of shared memory buffers * int shmWidth; Width of image (pixels) * int shmHeight; Height of image (pixels) * int shmImageType; Type of image (BYTE, SHORT, etc) * double *timestamp; Array of semaphore timestamps * } rtdShm; * The use of this structure should be transparent when using the * following convenience routines, although the fields of the * structure should be self-explanatory. * * - rtdShmCreate() allocates the required number of buffers of shared * memory of the required size, given the height, width, and data * type of the FITS image that is to be created. It also creates a * single semaphore set, the number of items in the set being equal * to the number of shared memory buffers. This means that each shared * memory area correspnds to, and can be locked by, a single semaphore * item from the set. The information is stored in the rtdShm structure, * shown above. * * If the shared memory has already been allocated, this routine returns * immediately. * * - rtdShmFill() is used to fill a particular piece of shared memory * (specified by the index argument) with data. Before doing so, the * semaphore corresponding to the shared memory is set to one. * * If the shared memory is currently locked, the routine returns * immediately. The exception to this is when the routine detects * that the semaphore is in a 'zombie' state, i.e. it has not been * set by the CCD for a period of time longer then RTD_SEM_TIMEOUT * (defined in rtdSem.h). In this case, the semaphore is reset and * the processing continues. * * If the data pointer is NULL then it is assumed that the data in * shared memory will be filled by the camera process after successful * call to rtdShmFill(). This is usually done when the camera process * transfers huge images (or image arrays) directly to shared memory. * * - rtdShmStruct() fills the image information structure with the * information that is specific to the shared memory/semaphore * locking, i.e. the shared memory ID, the semaphore ID, and the * number of the shared memory in the multi-buffered cycle * (...imageInfo->shmNum). * * - rtdShmDelete() removes the shared memory areas and semaphore, and * frees the memory associated with their storage. * * - rtdShmLocked() is used to detect whether or not a particular piece * of shared memory is currently locked, and returns the semaphore state. * As with rtdShmFill, if it detects a semaphore timeout it resets the * semaphore, and returns the new value. * * - rtdShmFillFirst() cycles over the shared memory buffers and fills the * first free (unlocked) buffer with the data supplied in the argument. * The number of the filled buffer is returned. * * - rtdShmFillNext() cycles over the shared memory buffers and fills the * next free (unlocked) buffer with the data supplied in the argument. * The index starts at index+1. * The number of the filled buffer is returned. * * The following routines are only used within the RTD software at the * moment. * * - rtdShmServicePacket() processes an image event with respect to the * semaphore information that it holds, but does no more. This is used * (for example) in situations where image events may be skipped by the * RTD, but the skipped packets must still be serviced to free up the * shared memory. * * - rtdSemDecrement() decrements the chosen semaphore by one. * * - rtdSemReset() resets the chosen semaphore to zero. * * RETURN VALUES * * Depends on routine. See individual functions. * * NOTES * * The scheme that has been chosen for the shared memory locking is as * follows. In a multi-buffered system, each piece of shared memory is * made to correspond to a single item from a semaphore set. If the state * of this item is high, then the CCD does not write to that piece of * memory. The RTD is never prevented from reading memory. * * When a CCD writes into shared memory, it sets the semaphore for that * piece of memory to one. It then passes the semaphore/shared memory * information as fields in the image event structure. The server adds * to the semaphore a value equal to the number of RTD clients minus one. * When a client has finished reading the shared memory, it decrements * the corresponding semaphore by one. Thus when all clients have finished * reading the shared memory, the semaphore returns to zero and the CCD * is free to write once again. * * If the update rate of the CCD is too fast for the RTD such that the * RTD skips some image events, it is up to the RTD to service the skipped * events so that the semaphores unlock. If an RTD crashes (so leaving a * semaphore in a high state), a timeout mechanism resets the semaphore * after a certain amount of time (e.g. 20 seconds). * * The RTD/rtdServer code is semaphore transparent, i.e. if the CCD * developer chooses not to implemented semaphores, there should be * no effect on the operation of the RTD. * * EXAMPLE * * This is the simplest possible application that could send data to the * server using semaphore locking. It is not necessary to use all the * functions offered above; the idea was simply to allow the CCD developer * some flexibility in their choice of functionality. * * // sample application which sends locked CCD data to the server * #include "rtdSem.h" * #include "rtdImageEvent.h" * * #define WIDTH 128 // Width of image * #define HEIGHT 128 // Height of image * #define DATASIZE 16 // Size of pixel * #define NUM_BUF 5 // Number of shm buffers * * static void generate_data(char *); // General data generation routine * * void main() * { * rtdIMAGE_EVT_HNDL eventHndl; * rtdIMAGE_INFO imageInfo; * rtdShm shmInfo; // Required for CCD library routines * char *data; * unsigned int i = 0; * * memset(&imageInfo, '\0', sizeof(rtdIMAGE_INFO)); * * if (rtdInitImageEvt("My_CCD_Camera", &eventHndl, NULL) == RTD_ERROR) { * // ... handle error ... * } * * if (rtdShmCreate(NUM_BUF, &shmInfo, WIDTH, HEIGHT, DATASIZE) == -1) { * // ... handle error ... * } * * while ( [some condition] ) { * generate_data(data); * * // Fill up the first available (unlocked) shm buffer * // (rtdShmFillFirst has the same effect, except always starts * // from zero). * while (rtdShmFill(i, data, &shmInfo, 0) == -1) { * sleep(1); * } * * imageInfo.dataType = DATASIZE; * imageInfo.xPixels = WIDTH; * imageInfo.yPixels = HEIGHT; * imageInfo.frameX = 0; * imageInfo.frameY = 0; * imageInfo.frameId = 0; * * // Fill up the image information fields with semaphore/shm info * rtdShmStruct(i, &imageInfo, &shmInfo); * * // forward image event * rtdSendImageInfo(&eventHndl, &imageInfo, NULL); * * i = (i + 1) % NUM_BUF; * } * * // Free up the semaphore/shared memory allocation * rtdShmDelete(&shmInfo); * free(data); * } * * WARNINGS * If you are not using semaphore locking then set semId=-1 in the * image event structure (see rtdImageEvent.h). Since semId=0 is * a valid number it can happen that rtdServer decrements a * semaphore created by another process which can lead to serious * problems! * * SEE ALSO * * rtdServer(1), rtdImageEvent(3) * *------------------------------------------------------------------------- */ #include #include #include #include #include "rtdSem.h" #include "rtdImageEvent.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef HAVE_UNION_SEMUN /* argument type needed by semctl - not used here */ union semun { int val; /* used for SETVAL only */ struct semid_ds *buf; /* for IPC_STAT and IPC_SET */ ushort *array; /* used for GETALL and SETALL */ }; #endif static union semun semun_; /* * rtdShmCreate * * Description: * This routine creates a unique semaphore, along with an array of shared * memory areas if these do not already exist. * * Arguments: * int num * The number of semaphores to create in the set (this should be * equal to the number of shared memory areas in a multi-buffered * system). * rtdShm *shmPtr * Pointer to the shared memory/semaphore information structure. * int width * Width of the image (pixels) * int height * Height of the image (pixels) * int type * Image data type (SHORT, FLOAT,...) * * Return value: * The ID of the created semaphore, or -1 if an error occurred. */ int rtdShmCreate(int num, rtdShm *shmPtr, int width, int height, int type) { int i, shmSize, shmId, semId; /* * Check if the shared memory Ids have been allocated. If so, return. */ if (shmPtr->shmId) return 0; shmPtr->shmWidth = width; shmPtr->shmHeight = height; shmPtr->shmImageType = type; shmPtr->num = num; shmSize = width * height * (abs(type) / 8); /* * Create new shared memory areas and allocate memory for the IDs. */ if ((shmPtr->shmId = (int *)calloc(num, sizeof(int))) == NULL) { fprintf(stderr, "Unable to allocate memory\n"); return -1; } for (i = 0; i < num; i++) { shmId = shmget(IPC_PRIVATE, shmSize, RTD_PERMS | IPC_CREAT); if (shmId == -1) { perror("rtdShmCreate"); fprintf(stderr, "Error in creating shared memory #%d\n", i); return -1; } shmPtr->shmId[i] = shmId; } /* * Create the set of semaphores (one for each shared memory area) */ semId = semget(IPC_PRIVATE, num, RTD_PERMS | IPC_CREAT); if (semId == -1) { perror("Unable to create semaphore"); return 0; } shmPtr->semId = semId; /* * Allocate an array of timestamps for the semaphores */ if ((shmPtr->timestamp = (double *)calloc(num, sizeof(double))) == NULL) { fprintf(stderr, "Unable to allocate timestamp data\n"); return -1; } return semId; } /* * This routine fills the required shared memory area with the data. The * shared memory is 'locked' during the fill process by implementing the * semaphore for the shared memory. * * Arguments: * int index * The index of the shared memory area. This is not the shared * memory Id, but the position of the shared memory in the * buffering order (indices start at 0). * char *data * Pointer to the data to fill the shared memory with. * rtdShm *shmPtr * Structure containing the shared memory/semaphore information. * * Return value: * 0 if OK, -1 for error/shared memory locked. */ int rtdShmFill(int index, char *data, rtdShm *shmPtr, int verbose) { char *ptr; /* Pointer to shared memory area */ int shmSize; /* Size of shared memory area */ struct timeval tm; /* Timestamp structure for semaphore */ struct sembuf semLock[2] = { 0, 0, 0, /* Wait for [#] to equal zero */ 0, 1, 0 /* Increment [#] by one */ }; shmSize = shmPtr->shmWidth * shmPtr->shmHeight * abs(shmPtr->shmImageType) / 8; /* Check if the semaphore is locked. Return immediately if it is */ if (rtdShmLocked(shmPtr, index)) { if (verbose) printf("Semaphore %d is already locked\n", index); return -1; } /* Get the current timestamp information */ gettimeofday(&tm, NULL); /* * Set the required semaphore to one, if the semaphore was created * successfully. This will be reset to zero * when all the RTDs have finished reading the image information. * * At the same time as locking the semaphore, timestamp the operation * so that we can detect semaphore zombies. */ semLock[0].sem_num = (unsigned short)index; semLock[1].sem_num = (unsigned short)index; if (shmPtr->semId != -1) { semop(shmPtr->semId, &semLock[0], 2); shmPtr->timestamp[index] = tm.tv_sec + (tm.tv_usec / 1000000.); if (verbose && rtdSemGetVal(shmPtr->semId, index)) fprintf(stderr, "Semaphore %d locked\n", (index + 1)); } /* * Fill the shared memory up. First attach to the memory, then simply * copy the data across. */ if (data == NULL) return 0; ptr = (char *)shmat(shmPtr->shmId[index], NULL, 0); if (ptr != NULL && ptr != (void *)-1) { if (memcpy(ptr, data, shmSize) == NULL) { fprintf(stderr, "Unable to copy memory for segment %d", index); rtdSemReset(shmPtr->semId, index); return -1; } } else { if (verbose) fprintf(stderr, "Unable to attach to shared memory %d\n", shmPtr->shmId[index]); rtdSemDecrement(shmPtr->semId, index); return -1; } /* Finally, detach from the shared memory. */ shmdt(ptr); return 0; } /* * This is a convenience routine for the CCD software; given an rtdShm * structure, this fills up the first available (unlocked) buffer. * * Arguments: * char *data * Pointer to the data to fill the shared memory with. * rtdShm *shmPtr * Structure containing the shared memory/semaphore information. * * Return value: * the buffer number if OK, -1 for error/all shared memory locked. */ int rtdShmFillFirst(char *data, rtdShm *shmPtr) { int i; /* Index counter */ int status = -1; /* Return status */ /* * Cycle over all the buffers, chcking to see if they're locked. * When an unlocked buffer is found, fill it with the data. */ for (i = 0; i < shmPtr->num; i++) { if ((status = rtdShmFill(i, data, shmPtr, 0)) == 0) break; } return (status == -1 ? status : i); } /* * This is a convenience routine for the CCD software; given an rtdShm * structure, this fills up the next available (unlocked) buffer. * * Arguments: * int index * The current index of the shared memory area. * char *data * Pointer to the data to fill the shared memory with. * rtdShm *shmPtr * Structure containing the shared memory/semaphore information. * * Return value: * the buffer number if OK, -1 for error/all shared memory locked. */ int rtdShmFillNext(int index, char *data, rtdShm *shmPtr) { int i, j; /* Index counters */ int status = -1; /* Return status */ /* * Cycle over all the buffers, checking to see if they're locked. * When an unlocked buffer is found, fill it with the data. */ for (i = 0; i < shmPtr->num; i++) { j = (index+i) % shmPtr->num; if ((status = rtdShmFill(j, data, shmPtr, 0)) == 0) break; } return (status == -1 ? status : j); } /* * This routine fills in the image information structure with all the * information pertaining to the shared memory/semaphore Ids. This should * be invoked before the rtdPACKET is sent to the server. * * Arguments: * int index * The index of the shared memory area to send. See note in the above * routine. * rtdIMAGE_INFO *imageInfo * Image information structure for send. * rtdShm *shmPtr * Structure containing the shared memory/semaphore Id. * * Return value: * 0 if OK, -1 if error. */ int rtdShmStruct(int index, rtdIMAGE_INFO *imageInfo, rtdShm *shmPtr) { /* Fill in the required fields of the image information structure. */ imageInfo->shmId = shmPtr->shmId[index]; imageInfo->semId = shmPtr->semId; imageInfo->shmNum = index; return 0; } /* * This routine checks if a semaphore is locked. If it is locked, and it is * detected that the semaphore has been locked for a time longer than * RTD_SEM_TIMEOUT, then it is cleared and OK is returned. * * Arguments: * rtdShm *shmPtr * Structure containing shared memory/semaphore information. * int index * Element of semaphore set to check. * * Return value: * 0 if OK, 1 if locked. */ int rtdShmLocked(rtdShm *shmPtr, int index) { struct timeval tm; /* Current timestamp */ double tmStamp; /* 'Expanded' current timestamp */ int semval; gettimeofday(&tm, NULL); tmStamp = tm.tv_sec + (tm.tv_usec / 1000000.); /* * If the semaphore was not created successfully, then just return * "locked". */ if (shmPtr->semId == -1) return 1; /* * First check the current state of the semaphore. If it is high (1) * then return without doing anything. The exception to this is if * the semaphore appears to be a 'zombie' (no operations have been carried * out on the semaphore for over RTD_SEM_TIMEOUT), in which case clear * the semaphore and continue. */ semval = rtdSemGetVal(shmPtr->semId, index); if (semval < 0) return 1; if (semval == 0) return 0; if (tmStamp - shmPtr->timestamp[index] > RTD_SEM_TIMEOUT) { while(rtdSemGetVal(shmPtr->semId, index) > 0) rtdSemDecrement(shmPtr->semId, index); return 0; } return 1; } /* * This routine services an rtdPacket by decrementing the appropriate * semaphore. This routine is used in the image event library to remove * (decrement) the semaphores of missed image events when the CCD update * rate is too fast for the RTD. * * Arguments: * rtdIMAGE_INFO *imageInfo * The image information packet that requires treatment. * * Return value: * None. */ void rtdShmServicePacket(rtdIMAGE_INFO *imageInfo) { /* Simply decrement the semaphore specified in the image information */ if (imageInfo->semId != -1) rtdSemDecrement(imageInfo->semId, imageInfo->shmNum); } /* * This routine removes the semaphore and deletes the shared memory areas. * * Arguments: * rtdShm *shmPtr * Structure containing shared memory/semaphore information. * * Return value: * 0 if OK, -1 if error. */ int rtdShmDelete(rtdShm *shmPtr) { int i; if (shmPtr == NULL) return 0; if (shmPtr->num < 1) return 0; /* Delete the shared memory first. */ if (shmPtr->shmId) { for (i = 0; i < shmPtr->num; i++) shmctl(shmPtr->shmId[i], IPC_RMID, NULL); free(shmPtr->shmId); shmPtr->shmId = NULL; } /* Delete the semaphore. */ if (shmPtr->semId != -1) { if (semctl(shmPtr->semId, 0, IPC_RMID, semun_) != 0) return -1; } /* Delete the timestamp allocation */ free(shmPtr->timestamp); return 0; } /* * This routine decrements the chosen semaphore from a given set. * This is presently only used by those applications that have to reset * semaphores (in particular, the RTDs) - however, it is included in this * module in case this becomes useful to CCD software. * * Arguments: * int semId * The ID number of the semaphore set concerned. * int semNum * The number of the semaphore set to be decremented. * * Return value: * None. */ void rtdSemDecrement(int semId, int semNum) { int cnt; struct sembuf semDec = { 0, -1, IPC_NOWAIT }; /* Check the semaphore was created successfully */ if (semId == -1) return; /* Perform the decrementation */ semDec.sem_num = (unsigned short)semNum; cnt = rtdSemGetVal(semId, semNum); if (cnt > 0) semop(semId, &semDec, 1); } /* * This routine return the current value of a semaphore */ int rtdSemGetVal(int semId, int semNum) { if (semId == -1) return -1; return semctl(semId, semNum, GETVAL, semun_); } /* * This routine resets the semaphore to zero. * * Arguments: * int semId * The ID number of the semaphore set concerned. * int semNum * The number of the semaphore set to be decremented. * * Return value: * None. */ void rtdSemReset(int semId, int semNum) { struct sembuf semDec[1] = { 0, 0, IPC_NOWAIT | SEM_UNDO }; /* Check the semaphore was created successfully */ if (semId == -1) return; /* Perform the reset */ semDec[0].sem_num = (unsigned short)semNum; semDec[0].sem_op = -(short)rtdSemGetVal(semId, semNum); semop(semId, &semDec[0], 1); } int rtdSemIncrement(int semId, int semNum, int increment) { struct sembuf semInc; semInc.sem_num = 0; semInc.sem_op = increment; /* Increment [#] by increment */ semInc.sem_flg = SEM_UNDO; if (semId == -1) return RTD_ERROR; if (increment != 0) { semInc.sem_num = (unsigned short)semNum; semop(semId, &semInc, 1); } return RTD_OK; } skycat-3.1.2-starlink-1b/rtd/rtdevt/rtdSem.h000066400000000000000000000036461215713201500206560ustar00rootroot00000000000000#ifndef RTDSEM_H #define RTDSEM_H /*+ * E.S.O. - VLT project * * * rtdSem.h * * This header contains prototypes for the semaphore manipulation routines * of rtdSem.c * * See rtdSem(1) for more information. * * who when what * --------- -------- ---------------------------------------------- * D.Hopkinson 21/01/97 Created. -*/ #include #include #include #include "rtdImageEvent.h" #define RTD_PERMS 0666 /* Access permissions for shared memory */ #define RTD_SEM_TIMEOUT 20 /* Timeout period for an un-reset semaphore */ /* * This structure is provided for use with the multibuffering/semaphore * convenience routines. */ typedef struct rtdShm { int *shmId; /* Array of shared memory Ids */ int semId; /* Semaphore Id */ int num; /* Number of shared memory buffers */ int shmWidth; /* Width of image (pixels) */ int shmHeight; /* Height of image (pixels) */ int shmImageType; /* Type of image (BYTE, SHORT, etc) */ double *timestamp; /* Array of semaphore timestamps */ } rtdShm; #ifdef __cplusplus extern "C" { #endif int rtdShmCreate (int num, rtdShm *shmPtr, int width, int height, int type); int rtdShmFill (int index, char *data, rtdShm *shmPtr, int verbose); int rtdShmFillFirst (char *data, rtdShm *shmPtr); int rtdShmFillNext (int index, char *data, rtdShm *shmPtr); int rtdShmStruct (int index, rtdIMAGE_INFO *imageInfo, rtdShm *shmPtr); int rtdShmDelete (rtdShm *shmPtr); int rtdShmLocked (rtdShm *shmPtr, int index); int rtdSemGetVal (int semId, int semNum); int rtdSemIncrement (int semId, int semNum, int increment); void rtdSemDecrement (int semId, int semNum); void rtdSemReset (int semId, int semNum); int rtdSemGetVal (int semId, int semNum); void rtdShmServicePacket(rtdIMAGE_INFO *imageInfo); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* RTDSEM_H */ skycat-3.1.2-starlink-1b/rtd/rtdevt/rtd_server.C000066400000000000000000000134411215713201500215240ustar00rootroot00000000000000/******************************************************************************* * E.S.O. - VLT project * * "@(#) $Id: rtd_server.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * rtdServer.C * * who when what * -------- -------- ---------------------------------------------- * pbiereic 01/03/01 Adapted from previous version * pbiereic 11/09/07 VLTSW20070184: rtdServer should not ignore SIGTERM */ static const char* const rcsId="@(#) $Id: rtd_server.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; /************************************************************************ * NAME * rtdServer - image event dispatcher for RTD * * SYNOPSIS * * rtdServer [-v ] [-p ] [-t ] * * DESCRIPTION * * rtdServer is the process that manages all image events from cameras * which are forwared to RTD client(s) which display the images. * "Cameras" are acquisition processes like a CCD, IRACE-DCS, etc. which readout the * detector image. * * Clients register (and connect) to the rtdServer via the rtdInitImageEvt() call. * * Connected RTD clients will receive image events from a camera if they are attached * to this camera. If not, then image events are simply discarded. * * Cameras use the rtdSendImageInfo() call when there is a new image to be displayed. * * Several RTD clients can attach to the same camera as the multicasting * of event notification is supported by the rtdServer. * RTD clients can also attach to cameras that not have registered yet * as the rtdServer supports a independence between image event producer * and image event consumer. * * The rtdServer also implements semaphore locking of shared memory, to * avoid the possibility of the RTD client reading the shared memory * at the same time as the camera writes (this is known as "image jitter"). * * The rtdServer expects the camera software to lock the semaphore. * * The rtdServer will then increment this semaphore by the number of RTD * clients less one (one was already set by the camera). If semaphores * are not implemented in the incoming image event, no action is taken. * The overall locking scheme is discussed in more detail in rtdSem(3). * * CAUTIONS * * o The rtdServer must not be killed when other clients are still * connected to it. * o rtdServer should not be started when there is another instance running on * the same machine, since there is only one standard server port to which * clients can connect to. If it is nevertheless started, then it will delay * for some seconds before terminating. * * ENVIRONMENTS * * The rtdServer (and RTD clients) use 5555 as the default, standard port number. * The port number can be changed within a user session by setting the * environment variable RTD_SERVER_PORT before starting rtdServer and it's * clients. * * SEE ALSO * rtdInitImageEvt(3), rtdSendImageInfo(3), rtdSem(3) *------------------------------------------------------------------------ */ /* * System Headers */ #include #include #include #include #include /* * Local Headers */ #include "rtdSERVER.h" #include "rtdLOG.h" #define DELAY 5 // default time to sleep before new events are read typedef void (*MySigFunc)(int); // prototype cast to keep Sun cc quiet /* * Globals needed for cleanup() after signals */ static int socketFd = 0; static rtdSERVER *mainLoop = NULL; // rtdSERVER object void usage(void) { printf("Usage: rtdServer ?-v -p -s?\n" " -v verbose mode\n" " -p port number, default %d. Set with RTD_SERVER_PORT\n" " -t delay between image events in msec (default %d)\n", RTD_FALLBACK_PORT, DELAY); exit(1); } /* * cleanup resources before terminating. Note that rtdServer does not * create any "global resources" such as shared memory or semaphores. */ void cleanup(int sig=0) { close(socketFd); if (mainLoop != NULL) delete mainLoop; if (sig >= 0) fprintf(stderr, "rtdServer: signal received\n"); exit(0); } int main(int argc, char *argv[]) { extern char *optarg; extern int optind; int portNo = 0; int delay = DELAY; char c; int verbose = 0; /* * rtdServer is a central server for all cameras and RTD's on * a host machine. It only terminates after certain signals, such as * an interrupt from keyboard and signals which cannot be caught. * See the list of signals and their action below. */ // signals which are ignored: //signal(SIGTERM, SIG_IGN); /* VLTSW20070184 */ signal(SIGHUP, SIG_IGN); signal(SIGUSR1, SIG_IGN); signal(SIGUSR2, SIG_IGN); // signals which must terminate rtdServer: signal(SIGINT, (MySigFunc)cleanup); // parse command line options while ((c = getopt(argc, argv, "v:p:t:")) != -1) { #ifndef SYSV char* optopt = argv[optind]; #endif switch(c) { case 'v': verbose = 1; break; case 'p': portNo = atoi(optarg); break; case 't': delay = atoi(optarg); break; case ':': fprintf(stderr,"Option -%s requires an argument\n",(char *)optopt); usage(); case '?': usage(); case 'h': usage(); } } // Check argument parameters if (portNo < 0 || delay < 0) usage(); rtdLOG logs = rtdLOG(verbose); // create log object if (getenv(RTD_SERVER_PORT) != NULL) portNo = atoi(getenv(RTD_SERVER_PORT)); if (rtdInitServer(&socketFd, portNo, NULL) == RTD_ERROR) { fprintf(stderr, "Could not initialize server (maybe it is already running ?)\n" "Now sleeping for 10 seconds to avoid an automatic, immediate restart\n"); sleep(10); exit (1); } logs.log("rtdServer started.\n"); mainLoop = new rtdSERVER(verbose, socketFd, delay); mainLoop->Loop(); cleanup(-1); } skycat-3.1.2-starlink-1b/rtd/tests/000077500000000000000000000000001215713201500170705ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/rtd/tests/all.tcl000066400000000000000000000005531215713201500203470ustar00rootroot00000000000000#!/bin/sh # The next line restarts using tclutil.sh \ exec wish $0 ${1+"$@"} set n 0 foreach testfile [lsort [glob t*.tcl]] { if {"$testfile" != "test.tcl"} { incr n set name [string range [file rootname $testfile] 1 end] pack \ [button .b$n \ -text $name \ -command "exec wish $testfile -geometry +300+300 &"] \ -side top -fill x } } skycat-3.1.2-starlink-1b/rtd/tests/tImageEvent.C000066400000000000000000000115421215713201500214070ustar00rootroot00000000000000/* * E.S.O. - VLT project * $Id: tImageEvent.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * tImageEvent.C - simulate a moving star within the ngc1275 image * * tImageEvent is an auxiliary tool to test RtdImagePick with * image events. The image data are read from file ../images/ngc1275.fits * and a rectangular around a star is shifted randomly while image events * are being sent. * * For using it: * o start rtdServer in background * o start rtd * o attach rtd to camera (defined by RTD_CAMERA) * o pick object at 230, 250 * o run tImageEvent and enjoy ... * * who when what * -------------- -------- ---------------------------------------- * pbiereic 14/12/99 Created */ // window size of the rectangular which contains the star #define WINSIZE 50 // start point of the rectangular which contains the star #define XS 200 #define YS 230 // max. shift of the rectangular (+/- MAXSHIFT) #define MAXSHIFT 5 // parameters for ngc1275 #define DFILE "../images/ngc1275.fits" #define TYPE short #define XSIZE 353 #define YSIZE 353 #define NUMBYTE 2 #define DTYPE 16 #define OFFSET 11520 // update rate in msec #define DELAY 2000 #include #include #include #include #include #include #include #include "rtdSem.h" #include "rtdImageEvent.h" extern "C" { void *shmat(int shmid, void *shmaddr, int shmflg); int shmdt(void *shmaddr); } static rtdShm main1; /* * cleanup and exit */ static void cleanup(int i=0) { i=1; sleep(1); rtdShmDelete(&main1); exit(1); } void errexit(char *msg1, char *msg2) { printf("%s %s\n", msg1, msg2); cleanup(); } void copyArrayToImage(TYPE *array, TYPE *image, int xs, int ys) { TYPE *s1, *s2; for (int idx = 0; idx < WINSIZE; idx++) { s1 = array + idx * WINSIZE; s2 = image + (ys - 1 + idx) * XSIZE + xs - 1; memcpy(s2, s1, WINSIZE * NUMBYTE); } } void copyImageToArray(TYPE *image, TYPE *array, int xs, int ys) { TYPE *s1, *s2; for (int idx = 0; idx < WINSIZE; idx++) { s1 = array + idx * WINSIZE; s2 = image + (ys - 1 + idx) * XSIZE + xs - 1; memcpy(s1, s2, WINSIZE * NUMBYTE); } } /* * sleep for some msec. */ void msecSleep(int msec) { timeval t; t.tv_sec = msec / 1000; msec -= t.tv_sec * 1000; t.tv_usec = msec * 1000; select(0, NULL, NULL, NULL, &t); } /* * get a random shift with a size of -MAXSHIFT to +MAXSHIFT */ int getRandomShift() { int random = rand(); double shift, r; r = (double)(RAND_MAX / 2.); shift = ((random - r) / r) * MAXSHIFT; return (int)shift; } /* * Main: */ main(int argc, char** argv) { rtdIMAGE_EVT_HNDL eventHndl; rtdIMAGE_INFO info; // name of camera char* rtd_camera = getenv("RTD_CAMERA"); if (! rtd_camera) errexit("please set the environment RTD_CAMERA first", ""); memset(&info, '\0', sizeof(rtdIMAGE_INFO)); if (rtdInitImageEvt(rtd_camera, &eventHndl, NULL) != 0) errexit("Could not initialize image event: check if rtdServer is running", ""); // clean up shared memory on exit signal(SIGINT, cleanup); signal(SIGTERM, cleanup); signal(SIGHUP, cleanup); // create shared memory area if (rtdShmCreate(1, &main1, XSIZE, YSIZE, DTYPE) == -1) errexit("error creating shared memory", ""); /* * fill image event info */ info.shmId = main1.shmId[0]; info.frameId = 0; info.dataType = DTYPE; info.bytePerPixel = NUMBYTE; info.xPixels = XSIZE; info.yPixels = YSIZE; // attach to shm TYPE *ptrInfo = (TYPE *)shmat(info.shmId, NULL, 0); if (ptrInfo <= NULL) errexit("Unable to attach to shared memory", ""); // get data from FITS file int fd = open(DFILE, O_RDONLY); if (fd < 0) errexit("error opening file", DFILE); if ((read(fd, ptrInfo, OFFSET)) < 0) errexit("error reading file", DFILE); if ((read(fd, ptrInfo, XSIZE * YSIZE * NUMBYTE)) < 0) errexit("error reading file", DFILE); close(fd); // allocate buffers for saving and copying data int arraySize = WINSIZE * WINSIZE * NUMBYTE; TYPE *array = (TYPE *)malloc(arraySize); TYPE *array2 = (TYPE *)malloc(arraySize); // save the rectangular around the star into array copyImageToArray(ptrInfo, array, XS, YS); int xs = XS, ys = YS; for (;;) { ys = YS + getRandomShift(); xs = XS + getRandomShift(); // copy array starting at xs,ys to the area starting at XS, YS copyImageToArray(ptrInfo, array2, xs, ys); copyArrayToImage(array2, ptrInfo, XS, YS); // send image event to rtdServer if (rtdSendImageInfo(&eventHndl, &info, NULL) != 0) errexit("error from rtdSendImageInfo", ""); msecSleep(DELAY); // restore the area starting at XS, YS copyArrayToImage(array, ptrInfo, XS, YS); } // ... and loop exit(0); } skycat-3.1.2-starlink-1b/rtd/tests/tRemote.tcl000077500000000000000000000033701215713201500212210ustar00rootroot00000000000000#!/usr/local/bin/tcl # # tRemote.tcl # # test the remote RTD interface # # open a socket to a running Rtd application and return the file # descriptor for remote commands proc connect_to_rtd {} { global env # get the hostname and port info from the file ~/.rtd-remote, # which is created by rtdimage when the remote subcommand is used if {[catch {set fd [open $env(HOME)/.rtd-remote]} msg]} { puts "can't open ~/.rtd-remote: make sure rtd is running: $msg" exit 1 } lassign [read $fd] pid host port close $fd if {[catch {exec kill -0 $pid} msg]} { puts "could it be that rtd is not running? ($msg)" exit 1 } set fd [server_connect -nobuf $host $port] return $fd } # send the command to rtd and return the results or generate an error proc send_to_rtd {args} { global rtd_fd puts $rtd_fd $args lassign [gets $rtd_fd] status length set result {} if {$length > 0} { set result [read $rtd_fd $length] } if {$status != 0} { error $result } return $result } puts "testing the RTD remote interface..." # open the connection set rtd_fd [connect_to_rtd] # this allows us to use the remote rtdimage as if it were local set image send_to_rtd # send some commands to RTD to be evaluated puts "WCS image center is: [$image wcscenter]" puts "image type: [$image bitpix]" puts "current scale factor: [$image scale]" puts "image dimensions: [$image width] x [$image height] pixels" puts "loading a new file: ngc1316r.fits [$image config -file ngc1316r.fits]" puts "setting cut levels: [$image autocut]" puts "new image dimensions: [$image width] x [$image height] pixels" puts "shared memory Id for image data: [$image shm get data]" puts "shared memory Id for image header: [$image shm get header]" skycat-3.1.2-starlink-1b/rtd/tests/tRtd.C000066400000000000000000000225121215713201500201130ustar00rootroot00000000000000/* * E.S.O. - VLT project * $Id: tRtd.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * tRtd.C - test RTD real-time updates by sending image and rapid frame * * * who when what * -------------- -------- ---------------------------------------- * pbiereic 05/02/03 Complete new version which supports all * data types implemented in RTD. */ /************************************************************************ * * DESCRIPTION * tRtd is used as a "test camera" for testing RTD image events. * The options for tRtd can be set either via command line options * or the RTD widget (tRtd.tcl) which is shown when RTD is started with the * "-debug 1" option. * tRtd generates image events at a defined speed (option -t). By default, * it uses semaphore locking to avoid "image jitters" and other (nasty) * side effects which can be seen when the option "-l 0" is set. * tRtd generates the images in a sort of "movie" style, i.e. images continuously * change so that image updates can be seen in the RTD image. A reference * point at the position REF_PIXEL is generated which is used for analysis. * Another point moves continuously across the image. * * All data types which are implemented in RTD are supported (option -D). * Byte swapped images can be generated with option (-E); this allows to * test eg. images which were produced on a Linux-PC and which are transferred * to a HP/Sun machine for display via RTD. * * Three different images can be generated with tRtd: * o a continuously changing image pattern * o a Fits image (eg. ngc1275.fits) with a moving area at the star position * (XS, YS). This image is used for tests with "pick object" * o a rapid frame. The rapid frame is displayed at a higher frequency * than the main image (option "-t" value / 5). * * * The sequence to generate images is: * - Attach to rtdServer. * - Create shared memory area(s). * - Install signal handlers which cleanup the shared memory area(s). * - Create an object which handles data of type dataType. * - Loop start - * - Generate data for the image. * - Wait until the next shared memory buffer is unlocked. * - Copy data to shared memory and lock it. * - Fill the image event info structure. * - Fill the image information fields with semaphore/shm info. * - Send the image information to rtdServer. * - Delay before next event. * - Cycle shm index and goto Loop * * * For the implementation tRtd uses classes since there are two image frames * (main and rapid) and the images can be of any data type supported by RTD. * Class tRtdEvt handles one image event cycle and loads Fits images when * required. * Class tRtdEvtData generates the data type specific classes via tRtdEvtTemplate.icc * and creates an data handling object required for the image. * The Template contains the code for all data type dependent classes, oa. byte * swap simulation (native and non-native) for all data types. * */ #include #include #include #include #include #include #include "error.h" #include "define.h" #include "rtdSem.h" #include "tRtd.h" #include "tRtdEvt.h" extern char *optarg; // structures for multibuffering/semaphore convenience routines static rtdShm shmMain; static rtdShm shmRapid; // the "big" data buffer static char data[MAX_NX * MAX_NY * 4]; /* * Main: */ int main(int argc, char** argv) { rtdIMAGE_EVT_HNDL eventHndl; // image event handle struct opts opt; // structure holding the options tRtdEvt *mainObj; // object which handles the main frame tRtdEvt *rapidObj; // object which handles the rapid frame ZERO(eventHndl); parseInput(argc, argv, &opt); // parse the user's input if (opt.verbose && ! opt.useFits) // print arguments usage(&opt); set_error_handler(&errprint); // error handler (see rtd/tclutil/util/src/error.C) if (rtdInitImageEvt(opt.rtd_camera, &eventHndl, NULL) != 0) { errexit("Could not initialize image event: check if rtdServer is running"); } // clean up shared memory on exit signal(SIGINT, cleanup); signal(SIGTERM, cleanup); signal(SIGHUP, cleanup); // create the object which handles the main image mainObj = new tRtdEvt((char *)"Main", &shmMain, (char *)&data, &opt, opt.main_width, opt.main_height, 0); // create the object which handles the rapid frame if (opt.rapid_id != 0 && ! opt.useFits) rapidObj = new tRtdEvt((char *)"Rapid", &shmRapid, (char *)&data, &opt, opt.rapid_width, opt.rapid_height, opt.rapid_id); // Loop until tRtdEvt gets aborted by the user while ( 1 ) { rtdSleep(opt.delay); mainObj->start(&eventHndl); if (opt.rapid_id == 0 || opt.useFits) continue; for (int i = 0; i < RAPIDS; i++) { rapidObj->start(&eventHndl); rtdSleep(opt.delay / RAPIDS); } } // -- end while( 1 ) return 0; } /* * cleanup and exit */ void cleanup(int i) { rtdShmDelete(&shmMain); rtdShmDelete(&shmRapid); exit(i); } /* * error message handler */ void errprint(const char* buf) { #ifdef DEBUG printf("errprint: %s\n", buf); #endif } /* * print error message and exit */ void errexit(const char* msg1, const char* msg2) { printf("%s %s\n", msg1, msg2); cleanup(1); } /* * print usage */ void usage(opts *opt) { printf("tRtdEvt \n" "\t -v Verbose flag..................(%d)\n" "\t -c Camera name...................(%s)\n" "\t -t Update interval in msecs......(%d)\n" "\t -W Main frame width..............(%d)\n" "\t -H Main frame height.............(%d)\n" "\t -w Rapid frame width.............(%d)\n" "\t -h Rapid frame height............(%d)\n" "\t -x Rapid frame start x...........(%d)\n" "\t -y Rapid frame start y...........(%d)\n" "\t -f Rapid frame Id................(%d)\n" "\t -l Use semaphore locking.........(%d)\n" "\t -b # of shared memory buffers....(%d)\n" "\n" "\t -I FITS image pathname...........(%s)\n" "\t -0 FITS image star center x......(%d)\n" "\t -1 FITS image star center y......(%d)\n" "\t -2 FITS image star bbox..........(%d)\n" "\t -3 FITS image star max. jitter...(%d)\n" "\n" "\t -E Endian flag...................(%d)\n" "\t -D Data type (16 short, -16 ushort, 32 int, -32 float, else byte...(%d)\n", opt->verbose, opt->rtd_camera, opt->delay, opt->main_width, opt->main_height, opt->rapid_width, opt->rapid_height, opt->rapid_x, opt->rapid_y, opt->rapid_id, opt->lock, opt->numShm, opt->fitsFile, opt->starx, opt->stary, opt->starbbox, opt->starjitter, opt->shmEndian, opt->dataType); } /* * parse input */ void parseInput(int argc, char** argv, opts *opt) { /* * set defaults */ opt->rapid_x = opt->rapid_y = opt->verbose = opt->rapid_id = opt->useFits = 0 ; opt->main_width = opt->main_height = opt->rapid_width = opt->rapid_height = 255; opt->shmEndian = -1; opt->delay = 500; opt->rtd_camera = getenv("RTD_CAMERA"); opt->fitsFile = (char *)"../images/ngc1275.fits"; opt->dataType = 16; opt->lock = 1; opt->numShm = 2; opt->starx = 252; opt->stary = 171; opt->starbbox = 50; opt->starjitter = 3; int c; while ((c = getopt(argc, argv, "x:y:w:h:W:H:f:v:c:t:b:l:I:E:D:0:1:2:3:")) != -1) { switch(c) { case 'x': opt->rapid_x = atoi(optarg); break; case 'y': opt->rapid_y = atoi(optarg); break; case 'W': opt->main_width = atoi(optarg); break; case 'H': opt->main_height = atoi(optarg); break; case 'w': opt->rapid_width = atoi(optarg); break; case 'h': opt->rapid_height = atoi(optarg); break; case 'f': opt->rapid_id = atoi(optarg); break; case 'v': opt->verbose = atoi(optarg); break; case 'c': opt->rtd_camera = optarg; break; case 't': opt->delay = atoi(optarg); break; case 'b': opt->numShm = atoi(optarg); break; case 'l': opt->lock = atoi(optarg); break; case 'I': opt->fitsFile = optarg; opt->useFits = 1; break; case 'E': opt->shmEndian = atoi(optarg); break; case 'D': opt->dataType = atoi(optarg); break; case '0': opt->starx = atoi(optarg); break; case '1': opt->stary = atoi(optarg); break; case '2': opt->starbbox = atoi(optarg); break; case '3': opt->starjitter = atoi(optarg); break; default: usage(opt); exit(1); } } // check arguments int dt = opt->dataType; if (dt != 8 && dt != 16 && dt != -16 && dt != 32 && dt != -32) errexit("wrong data type"); if (opt->rapid_x < 0 || opt->rapid_y < 0 || opt->rapid_width < 0 || opt->rapid_height < 0 || opt->main_width <= 0 || opt->main_height <= 0 || opt->rapid_id < 0 || opt->delay < 0 || opt->numShm <= 0) errexit("wrong argument"); // limit ranges opt->main_width = min(opt->main_width, MAX_NX); opt->main_height = min(opt->main_height, MAX_NY); opt->rapid_width = min(opt->rapid_width, MAX_NX); opt->rapid_height = min(opt->rapid_height, MAX_NY); opt->rapid_x = min(opt->rapid_x, MAX_NX); opt->rapid_y = min(opt->rapid_y, MAX_NY); if (! opt->rtd_camera) errexit("please use '... -c camera' or 'setenv RTD_CAMERA ...' first"); } skycat-3.1.2-starlink-1b/rtd/tests/tRtd.h000066400000000000000000000032271215713201500201620ustar00rootroot00000000000000#ifndef tRtd_h #define tRtd_h /* * E.S.O. - VLT project * "@(#) $Id: tRtd.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * tRtd.h - definitions for tRtd * * who when what * -------------- -------- ---------------------------------------- * pbiereic 05/02/03 Created */ #define MAX_NX 1500 // max #of pixels in x #define MAX_NY 1500 // max #of pixels in x // default FITS file (for option -I). #define DFILE "../images/ngc1275.fits" /* struct for command line options */ typedef struct opts { int rapid_x; // rapid frame start x int rapid_y; // rapid frame start y int main_width; // image width int main_height; // main image height int rapid_width; // rapid image width int rapid_height; // rapid image height int rapid_id; // rapid frame id int verbose; // verbose flag char *rtd_camera; // name of camera int delay; // delay between updates int numShm; // number of shm buffers to use int lock; // Flag: use semaphore locking char *fitsFile; // FITS file to use for image updates int starx; // FITS image star center x int stary; // FITS image star center y int starbbox; // FITS image star box length (and width) int starjitter; // FITS image star max. jitter int shmEndian; // native byte order, big or little Endian data int useFits; // use Fits file for generating the image int dataType; // image data type } opts; void errexit(const char* msg1, const char* msg2 = ""); void cleanup(int i=0); void errprint(const char* buf); void usage(opts *opt); void parseInput(int argc, char** argv, opts *opt); #endif /* tRtd_h */ skycat-3.1.2-starlink-1b/rtd/tests/tRtdEndian.tcl000077500000000000000000000261301215713201500216350ustar00rootroot00000000000000#!/bin/sh #\ exec rtdimage_wish "$0" ${1+"$@"} # E.S.O. - VLT project # "@(#) $Id: tRtdEndian.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # tRtdEndian.tcl - automatic test procedure for Rtd byte swap handling # # Test anything which is releated to Big/Little/Native Endian # and this for every data type supported by RTD (with special attention # to float data). # Eg. data are produced by a detector system on a Sparc and transferred # (without byte swap) to a Linux-PC where RTD is running on. # # # who when what # -------------- --------- ---------------------------------------- # P. Biereichel 11/08/99 Created # # -------------------------------------------------------------- # Common procedures # -------------------------------------------------------------- # proc feedback { args } { global debug if {$debug != 0} { puts $args } } proc startRtd {} { feedback "starting rtd ..." return [exec rtd -rtd_geometry -0+0 -attach 1 \ -rtd_title {RTD TEST ** RTD TEST ** RTD TEST} &] } proc connectToRtd {} { global ::rtd_fd while {1} { feedback "connecting to Rtd..." # open the connection set rtd_fd [connect_to_rtd] if {$rtd_fd > 0} { break } sleep 2 } feedback "connected to rtd." } proc sendTclCmd {cmd} { global ::rtd_fd # feedback "sending rtd tcl command: $cmd" set ret [etcl $rtd_fd $cmd] # feedback "received reply: $ret\n" return $ret } proc sendRtdCmd {cmd} { global ::rtd_fd # feedback "sending rtd subimage command: $cmd" set ret [send_to_rtd $rtd_fd $cmd] # feedback "received reply: $ret\n" return $ret } # run tRtd for some seconds and abort it afterwards proc run_tRtd {endian dataType} { set pid [exec tRtd -E $endian -D $dataType -t 200 &] after 2000 kill $pid after 500 } # get min,max values of the reference pixel proc getRefPix { } { set minvalues [sendRtdCmd "get 11 11 image"] set maxvalues [sendRtdCmd "get 11 12 image"] lassign $minvalues x y minvalue lassign $maxvalues x y maxvalue return "$minvalue $maxvalue" } # # -------------------------------------------------------------- # Test procedures # -------------------------------------------------------------- # # # run tRtd check the value of the reference pixel # proc Test1 { text endian dataType minval maxval } { global TestError run_tRtd $endian $dataType lassign [getRefPix] minvalue maxvalue if {$minvalue != $minval || $maxvalue != $maxval} { feedback "FAILED... $text\: Expected values $minval, $maxval .. got .. $minvalue, $maxvalue" set TestError 1 return 1 } feedback "OK... $text\: values at ref. (11,11-12) = $minvalue, $maxvalue" return 0 } # # write shm image to disk, clear image and load shm image from disk. Then test ref. pixel. # proc Test2 { text endian dataType minval maxval } { global TestError fitsfile run_tRtd $endian $dataType sendRtdCmd "dump $fitsfile" sendRtdCmd "clear" after 100 sendRtdCmd "config -file $fitsfile" after 500 lassign [getRefPix] minvalue maxvalue if {$minvalue != $minval || $maxvalue != $maxval} { feedback "FAILED... $text\: Expected values $minval, $maxval .. got .. $minvalue, $maxvalue" set TestError 1 return 1 } feedback "OK... $text\: values at ref. (11,11-12) = $minvalue, $maxvalue" return 0 } # # run tRtd, store bias frame, subtract and check that the # image is zero # proc Test3 { text endian dataType } { global TestError sendRtdCmd "biasimage off" sendRtdCmd "biasimage select 0" run_tRtd $endian $dataType sendRtdCmd "camera pause" sendRtdCmd "update" sendRtdCmd "biasimage copy 0" sendRtdCmd "biasimage on" sendRtdCmd "update" after 100 set val1 [sendRtdCmd "get 10 40 image"] set val2 [sendRtdCmd "get 10 41 image"] sendRtdCmd "camera continue" lassign $val1 x y val1 lassign $val2 x y val2 if {$val1 != 0 || $val2 != 0} { feedback "FAILED... $text\: Expected values 0, 0 .. got .. $val1, $val2" set TestError 1 return 1 } feedback "OK... $text\: image is cleared" return 0 } # # run tRtd, load bias frame from disk, subtract and check the # reference pixels # proc Test4 { text endian dataType1 dataType2 minval1 maxval1 minval2 maxval2 } { global TestError fitsfile sendRtdCmd "biasimage off" run_tRtd $endian $dataType2 sendRtdCmd "dump $fitsfile" sendRtdCmd "update" sendRtdCmd "biasimage file $fitsfile 0" sendRtdCmd "biasimage on" sendRtdCmd "biasimage select 0" run_tRtd $endian $dataType1 lassign [getRefPix] val1 val2 set expmin [expr $minval1 - $minval2] set expmax [expr $maxval1 - $maxval2] # take into account the tcl_precision if {[format "%.6g" $expmin] != $val1 || [format "%.6g" $expmax] != $val2} { feedback "FAILED... $text\: Expected values $expmin, $expmax .. got .. $val1, $val2" set TestError 1 return 1 } feedback "OK... $text" return 0 } # # run tRtd, copy images of different data types to bias images, # generate a main image of type dataType, subtract # # proc Test5 { text endian dataType nr minval1 maxval1 minval2 maxval2} { global TestError Test5Inititialized if {! $Test5Inititialized } { sendRtdCmd "biasimage off" set Test5Inititialized 1 set i 0 foreach type "-32 32 -16 16 8" { run_tRtd $endian $type sendRtdCmd "biasimage copy $i" incr i } sendRtdCmd "biasimage on" } run_tRtd $endian $dataType sendRtdCmd "biasimage select $nr" lassign [getRefPix] val1 val2 set expmin [expr $minval1 - $minval2] set expmax [expr $maxval1 - $maxval2] # take into account the tcl_precision if {[format "%.6g" $expmin] != $val1 || [format "%.6g" $expmax] != $val2} { feedback "FAILED... $text\: Expected values $expmin, $expmax .. got .. $val1, $val2" set TestError 1 return 1 } feedback "OK... $text (bias number $nr)" return 0 } # # -------------------------------------------------------------- # Procedures which call the test programs # -------------------------------------------------------------- # proc callTest1 { } { feedback "\nTest 1: Checking that RTD handles byte-swapped data in shm correctly..." foreach nameTypeype {"Little Endian" "Big Endian" "Native"} endian {1 0 -1} { Test1 "$nameTypeype, Byte Data" $endian 8 0 255 Test1 "$nameTypeype, Short Data" $endian 16 -10000 10000 Test1 "$nameTypeype, UShort Data" $endian -16 0 30000 Test1 "$nameTypeype, Int Data" $endian 32 -100000 100000 Test1 "$nameTypeype, Float Data" $endian -32 -1.E7 1.E7 } } proc callTest2 { } { feedback "\nTest 2: Write shm image to disk, clear image and load shm image from disk. Then test ref. pixel." foreach nameTypeype {"Little Endian" "Big Endian" "Native"} endian {1 0 -1} { Test2 "$nameTypeype, Float Data" $endian -32 -1.E7 1.E7 Test2 "$nameTypeype, Int Data" $endian 32 -100000 100000 Test2 "$nameTypeype, UShort Data" $endian -16 0 30000 Test2 "$nameTypeype, Short Data" $endian 16 -10000 10000 Test2 "$nameTypeype, Byte Data" $endian 8 0 255 } } proc callTest3 { } { feedback "\nTest 3: Generate image, store as bias frame, subtract. Then test that ref. pixel. is zero" foreach nameTypeype {"Little Endian" "Big Endian" "Native"} endian {1 0 -1} { Test3 "$nameTypeype, Byte Data" $endian 8 Test3 "$nameTypeype, Short Data" $endian 16 Test3 "$nameTypeype, UShort Data" $endian -16 Test3 "$nameTypeype, Int Data" $endian 32 Test3 "$nameTypeype, Float Data" $endian -32 } } proc callTest4 { } { feedback "\nTest 4: Generate image, load bias frame from disk, subtract. Then test ref. pixel." foreach nameTypeype {"Little Endian" "Big Endian" "Native"} endian {1 0 -1} { Test4 "$nameTypeype, Float - Float " $endian -32 -32 -1.E7 1.E7 -1.E7 1.E7 Test4 "$nameTypeype, Float - Int " $endian -32 32 -1.E7 1.E7 -100000 100000 Test4 "$nameTypeype, Float - UShort" $endian -32 -16 -1.E7 1.E7 0 30000 Test4 "$nameTypeype, Float - Short " $endian -32 16 -1.E7 1.E7 -10000 10000 Test4 "$nameTypeype, Float - Byte " $endian -32 8 -1.E7 1.E7 0 255 Test4 "$nameTypeype, Int - Int " $endian 32 32 -100000 100000 -100000 100000 Test4 "$nameTypeype, Int - UShort" $endian 32 -16 -100000 100000 0 30000 Test4 "$nameTypeype, Int - Short " $endian 32 16 -100000 100000 -10000 10000 Test4 "$nameTypeype, Int - Byte " $endian 32 8 -100000 100000 0 255 Test4 "$nameTypeype, UShort- UShort" $endian -16 -16 0 30000 0 30000 Test4 "$nameTypeype, UShort- Byte " $endian -16 8 0 30000 0 255 Test4 "$nameTypeype, Short - Short " $endian 16 16 -10000 10000 -10000 10000 Test4 "$nameTypeype, Short - Byte " $endian 16 8 -10000 10000 0 255 Test4 "$nameTypeype, Byte - Byte " $endian 8 8 0 255 0 255 } } proc callTest5 { biasEndianName biasEndian } { feedback "\nTest 5: Test subtraction of different bias frame numbers (bias: $biasEndianName)" sendRtdCmd "biasimage off" set i 0 foreach type "-32 32 -16 16 8" { run_tRtd $biasEndian $type sendRtdCmd "biasimage copy $i" incr i } sendRtdCmd "biasimage on" foreach nameTypeype {"Little Endian" "Big Endian" "Native"} endian {1 0 -1} { Test5 "$nameTypeype, Float Data" $endian -32 0 -1.E7 1.E7 -1.E7 1.E7 Test5 "$nameTypeype, Float Data" $endian -32 1 -1.E7 1.E7 -100000 100000 Test5 "$nameTypeype, Float Data" $endian -32 2 -1.E7 1.E7 0 30000 Test5 "$nameTypeype, Float Data" $endian -32 3 -1.E7 1.E7 -10000 10000 Test5 "$nameTypeype, Float Data" $endian -32 4 -1.E7 1.E7 0 255 Test5 "$nameTypeype, Int Data" $endian 32 1 -100000 100000 -100000 100000 Test5 "$nameTypeype, Int Data" $endian 32 2 -100000 100000 0 30000 Test5 "$nameTypeype, Int Data" $endian 32 3 -100000 100000 -10000 10000 Test5 "$nameTypeype, Int Data" $endian 32 4 -100000 100000 0 255 Test5 "$nameTypeype, UShort Data" $endian -16 2 0 30000 0 30000 Test5 "$nameTypeype, UShort Data" $endian -16 4 0 30000 0 255 Test5 "$nameTypeype, Short Data" $endian 16 3 -10000 10000 -10000 10000 Test5 "$nameTypeype, Short Data" $endian 16 4 -10000 10000 0 255 Test5 "$nameTypeype, Byte Data" $endian 8 4 0 255 0 255 } } # # -------------------------------------------------------------- # "Main" # -------------------------------------------------------------- # lappend auto_path ../library package require Rtd # debug flag for development set debug 0 set rtdPid [startRtd] connectToRtd set TestError 0 set Test5Inititialized 0 set fitsfile /tmp/$env(USER)tRtdEndian.fits callTest1 callTest2 callTest3 callTest4 callTest5 "Little Endian" 1 callTest5 "Big Endian" 0 callTest5 "Native" -1 if {$TestError} { puts "\ntRtdEndian Test FAILED !" } else { feedback "tRtdEndian OK" } catch {kill $rtdPid} catch {exec rm -f $fitsfile"} catch {exec rm -f "$fitsfile.BAK"} exit 0 skycat-3.1.2-starlink-1b/rtd/tests/tRtdEvt.C000066400000000000000000000104431215713201500205720ustar00rootroot00000000000000/* * E.S.O. - VLT project * $Id: tRtdEvt.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * tRtdEvt.C - test RTD real-time updates by sending image and rapid frame * * * who when what * -------------- -------- ---------------------------------------- * pbiereic 05/02/03 Created */ /************************************************************************ * * DESCRIPTION * tRtdEvt is class for generating image events (RTD main * or rapid frame) * */ #include #include #include "tRtdEvt.h" /* * constructor */ tRtdEvt::tRtdEvt(char *id, rtdShm *rtdShm, char *data, opts *opt, int width, int height, int frameId) { id_ = id; rtdShm_ = rtdShm; data_ = data; opt_ = opt; width_ = width; height_ = height; frameId_ = frameId; count_ = COUNT_INC+1; countM_ = 0; countMSign_ = 1; index_ = 0; dataType_ = opt->dataType; shmEndian_ = opt->shmEndian; int nbytes; // check if Fits file is specified if (opt->useFits) { fits_ = FitsIO::read(opt->fitsFile); if (fits_ == NULL) errexit("cannot open file"); shmEndian_ = 0; // get parameters from image dataType_ = fits_->bitpix(); width_ = fits_->width(); height_ = fits_->height(); nbytes = width_ * height_ * abs(dataType_ / 8); if (nbytes > MAX_NX * MAX_NY * 4) errexit("not enough memory allocated"); if (width_ < 3 || height_ < 3) errexit("image too small (HDU?)"); memcpy(data_, (char *)fits_->data().ptr(), nbytes); delete fits_; } // create main shared memory area if (rtdShmCreate(opt->numShm, rtdShm, width_, height_, dataType_) == -1) errexit("error creating shared memory"); // create an object of type dataType dataObj_ = DataObj_.makeImage(width_, height_, rtdShm, dataType_, shmEndian_); if (opt->useFits) dataObj_->initArea(data_, opt->starx - opt->starbbox/2, opt->stary - opt->starbbox/2, opt->starbbox, width_, height_); } tRtdEvt::~tRtdEvt() {}; void tRtdEvt::start(rtdIMAGE_EVT_HNDL *eventHndl) { if (! opt_->useFits) { dataObj_->genImage(data_, width_, height_, count_); } else { dataObj_->jitterArea(opt_->starjitter); } while (rtdShmFill(index_, data_, rtdShm_, 0) == -1) rtdSleep((int)LOCK_DELAY); int cnt = count_ + countMSign_ * COUNT_INC; if (cnt >= width_ || cnt <= COUNT_INC) countMSign_ = -countMSign_; count_ = count_ + countMSign_ * COUNT_INC; fillImageInfo(); if (rtdShmStruct(index_, &imageInfo_, rtdShm_) == -1) errexit("rtdShmStruct failed"); if ( ! opt_->lock) rtdSemReset(imageInfo_.semId, index_); printImageInfo(++countM_); if (rtdSendImageInfo(eventHndl, &imageInfo_, NULL) == RTD_ERROR) errexit("rtdSendImageInfo failed"); if (opt_->useFits) dataObj_->restoreArea(); index_ = (index_ + 1) % opt_->numShm; } /* * print image event info */ void tRtdEvt::printImageInfo(int count) { if (! opt_->verbose) return; printf("update #%d %s frame: frameId=%d, %dx%d+%d+%d, semId=%d, buffer %d(%d)\n", count, id_, imageInfo_.frameId, imageInfo_.xPixels, imageInfo_.yPixels, imageInfo_.frameX, imageInfo_.frameY, imageInfo_.semId, imageInfo_.shmNum + 1, opt_->numShm); } /* * fill image event info structure */ void tRtdEvt::fillImageInfo() { // clear info in rtdIMAGE_INFO ZERO(imageInfo_); imageInfo_.dataType = dataType_; imageInfo_.frameX = 0; imageInfo_.frameY = 0; imageInfo_.xPixels = width_; imageInfo_.yPixels = height_; imageInfo_.frameId = frameId_; imageInfo_.shmEndian = shmEndian_; // add some dummy world coordinates for testing imageInfo_.ra = 49.951; imageInfo_.dec = 41.5117; imageInfo_.secpix = 1.70127; imageInfo_.xrefpix = width_/2.0; imageInfo_.yrefpix = height_/2.0 ; imageInfo_.rotate = double(count_ % 360); imageInfo_.equinox = 2000; imageInfo_.epoch = 1957.97; strcpy(imageInfo_.proj, "-TAN"); #ifdef DEBUG // add some dummy detector information if (frameId == 0) { imageInfo_.startX = count_; imageInfo_.startY = count_; imageInfo_.binningX = 2; imageInfo_.binningY = 2; imageInfo_.lowCut = 0; imageInfo_.highCut = 100; } #endif } skycat-3.1.2-starlink-1b/rtd/tests/tRtdEvt.h000066400000000000000000000032271215713201500206410ustar00rootroot00000000000000#ifndef tRtdEvt_h #define tRtdEvt_h /* * E.S.O. - VLT project * "@(#) $Id: tRtdEvt.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * tRtdEvt.h - definitions for tRtdEvt * * who when what * -------------- -------- ---------------------------------------- * pbiereic 05/02/03 Created */ #include "Fits_IO.h" #include "rtdSem.h" #include "tRtd.h" #include "rtdSem.h" #include "rtdImageEvent.h" #include "tRtdEvtData.h" #define LOCK_DELAY 50 // delay when all shm buffers are locked (in msec) #define RAPIDS 5 // number of rapid frames displayed before main image #define ZERO(x) memset((void *)(&x), '\0', sizeof(x)) class tRtdEvt { public: // public member functions tRtdEvt(char *id, rtdShm *rtdShm, char *data, opts *opt, int width, int height, int frameId); ~tRtdEvt(); void start(rtdIMAGE_EVT_HNDL *eventHndl); private: char *id_; // id, e.g "Main" or "rapid" rtdShm *rtdShm_; // rtdShm struct char *data_; // ptr to static ("big") data buffer opts *opt_; // tRtd options struct int width_; // image width int height_; // image height int frameId_; // frame Id (eg. 0=main, 1=rapid) int count_; // counter int countM_; // counter int countMSign_; // counter sign void fillImageInfo(); void printImageInfo(int count); rtdIMAGE_INFO imageInfo_; // image info structure tRtdEvtData DataObj_; // data object tRtdEvtData *dataObj_; // data handling object int index_; // index for shared memory buffer FitsIO *fits_; // FITS I/O object int dataType_; // data type int shmEndian_; // shmEndian }; #endif /* tRtdEvt_h */ skycat-3.1.2-starlink-1b/rtd/tests/tRtdEvtData.C000066400000000000000000000075471215713201500213770ustar00rootroot00000000000000/* * E.S.O. - VLT project * $Id: tRtdEvtData.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * tRtdEvtData.C - data class for tRtd * * * who when what * -------------- -------- ---------------------------------------- * pbiereic 05/02/03 Created */ /************************************************************************ * * DESCRIPTION * class tRtdEvtData contains methods for handling classes of different * data types. * */ #include "tRtdEvt.h" #include "tRtdEvtData.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" /* * ----------------------------------------------------------- * Include the Template code for each supported data type * ----------------------------------------------------------- */ /* * data classes which need byte swap. */ #define DATA_TYPE unsigned char #define CLASS_NAME ByteSubs #define SWAP(x) x #include "tRtdEvtTemplate.icc" #undef DATA_TYPE #undef CLASS_NAME #undef SWAP #define DATA_TYPE short #define CLASS_NAME ShortSubs #define SWAP(x) SWAP16(x) #include "tRtdEvtTemplate.icc" #undef DATA_TYPE #undef CLASS_NAME #undef SWAP #define DATA_TYPE unsigned short #define CLASS_NAME UShortSubs #define SWAP(x) SWAP16(x) #include "tRtdEvtTemplate.icc" #undef DATA_TYPE #undef CLASS_NAME #undef SWAP #define DATA_TYPE int #define CLASS_NAME IntSubs #define SWAP(x) SWAP32(x) #include "tRtdEvtTemplate.icc" #undef DATA_TYPE #undef CLASS_NAME #undef SWAP #define DATA_TYPE float #define CLASS_NAME FloatSubs #define SWAP(x) SWAP_FLOAT(x) #include "tRtdEvtTemplate.icc" #undef DATA_TYPE #undef CLASS_NAME #undef SWAP /* * data classes which do not need byte swap. */ #define SWAP(x) x #define DATA_TYPE short #define CLASS_NAME NativeShortSubs #include "tRtdEvtTemplate.icc" #undef DATA_TYPE #undef CLASS_NAME #define DATA_TYPE unsigned short #define CLASS_NAME NativeUShortSubs #include "tRtdEvtTemplate.icc" #undef DATA_TYPE #undef CLASS_NAME #define DATA_TYPE int #define CLASS_NAME NativeIntSubs #include "tRtdEvtTemplate.icc" #undef DATA_TYPE #undef CLASS_NAME #define DATA_TYPE float #define CLASS_NAME NativeFloatSubs #include "tRtdEvtTemplate.icc" #undef DATA_TYPE #undef CLASS_NAME #undef SWAP /* * ----------------------------------------------------------- * Class tRtdEvtData * ----------------------------------------------------------- */ /* * constructor */ tRtdEvtData::tRtdEvtData() : ref_pixel_(11), ref_size_(3) {}; /* * create and initialize the objects which handle data of type dataType */ tRtdEvtData* tRtdEvtData::makeImage(int width, int height, rtdShm *shm, int dataType, int shmEndian) { tRtdEvtData *obj; // data type object /* * make the image which handles the data of type dataType. * BIGENDIAN = 1 for Hp/Sun..., 0 for Linux-PC... * shmEndian = 0: produce big endian data, 1: little endian data, -1 native data */ int native = ((BIGENDIAN == ! shmEndian) || (shmEndian == -1)); if (native) { if (dataType == 16) obj = new NativeShortSubs(-10000, 10000); else if (dataType == -16) obj = new NativeUShortSubs(0, 30000); else if (dataType == 32) obj = new NativeIntSubs(-100000, 100000); else if (dataType == -32) obj = new NativeFloatSubs(-1.E7, 1.E7); else obj = new ByteSubs(0, 255); } else { if (dataType == 16) obj = new ShortSubs(-10000, 10000); else if (dataType == -16) obj = new UShortSubs(0, 30000); else if (dataType == 32) obj = new IntSubs(-100000, 100000); else if (dataType == -32) obj = new FloatSubs(-1.E7, 1.E7); else obj = new ByteSubs(0, 255); } return obj; } /* * get a random shift with a size of +/- starjitter */ int tRtdEvtData::getRandomShift(int starjitter) { int random = rand(); double shift, r; r = (double)(RAND_MAX / 2.); shift = ((random - r) / r) * starjitter; return (int)shift; } skycat-3.1.2-starlink-1b/rtd/tests/tRtdEvtData.h000066400000000000000000000026101215713201500214260ustar00rootroot00000000000000#ifndef tRtdEvtData_h #define tRtdEvtData_h /* * E.S.O. - VLT project * "@(#) $Id: tRtdEvtData.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * tRtdEvt.h - definitions for tRtdEvtData * * who when what * -------------- -------- ---------------------------------------- * pbiereic 05/02/03 Created */ #include #include "rtdSem.h" #define COUNT_INC 3 // count increment after an image was displayed class tRtdEvtData { public: // public member functions tRtdEvtData(); int getRandomShift(int starjitter); tRtdEvtData* makeImage(int width, int height, rtdShm *shm, int dataType, int shmEndian); virtual void genRef(char *p, int width, int height, int ref) {}; virtual void genImage(char *p, int width, int height, int count) {}; virtual void copyArrayToImage(char *array, char *image, int xs, int ys, int width) {}; virtual void copyImageToArray(char *image, char *array, int xs, int ys, int width) {}; virtual void initArea(char *ptr, int xs, int ys, int winsize, int width, int height) {}; virtual void jitterArea(int starjitter) {}; virtual void restoreArea() {}; int ref_pixel() {return ref_pixel_;}; // center of reference pixel int ref_size() {return ref_size_;}; // size of reference area (must be an odd number) protected: int ref_pixel_; int ref_size_; }; #endif /* tRtdEvtData_h */ skycat-3.1.2-starlink-1b/rtd/tests/tRtdEvtTemplate.icc000066400000000000000000000121471215713201500226450ustar00rootroot00000000000000/* * E.S.O. - VLT project * $Id: tRtdEvtTemplate.icc,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * tRtdEvtTemplate.icc - data type dependent class for tRtd * * * who when what * -------------- -------- ---------------------------------------- * pbiereic 05/02/03 Created */ /************************************************************************ * * DESCRIPTION * Type dependent class for tRtdEvt.C. The routines are included * by tRtdEvtData.C with the following definitions: * * CLASS_NAME - class name * DATA_TYPE - data type (short, float...) * SWAP - bytes swapping routine for non-native byte order * * The definitions are undef'd at the end of this file. */ #include #include #include #include #include "define.h" #include "tRtdEvtData.h" /* * -------------------------------- * Template Class definitions * -------------------------------- */ class CLASS_NAME : tRtdEvtData { friend class tRtdEvtData; public: // public member functions CLASS_NAME(DATA_TYPE valmin, DATA_TYPE valmax); void genRef(char *p, int width, int height, int ref); void genImage(char *p, int width, int height, int count); void copyArrayToImage(char *array, char *image, int xs, int ys, int width); void copyImageToArray(char *image, char *array, int xs, int ys, int width); void initArea(char *ptr, int xs, int ys, int winsize, int width, int height); void jitterArea(int starjitter); void restoreArea(); DATA_TYPE valmin_; DATA_TYPE valmax_; char *array_; char *array2_; char *aptr_; int awinsize_; int awidth_; int aheight_; int axs_; int ays_; }; /* * -------------------------------- * Template Class code * -------------------------------- */ // constructor CLASS_NAME::CLASS_NAME(DATA_TYPE valmin, DATA_TYPE valmax) : valmin_(valmin), valmax_(valmax) {}; /* * generate a reference pixel */ void CLASS_NAME::genRef(char *ptr, int width, int height, int ref) { DATA_TYPE *p = (DATA_TYPE *)ptr; int refPixel = ref_pixel() / 2; // generate a n x n area around the reference pixel if (ref <= refPixel || width < ref + refPixel || height < ref + refPixel) return; ref--; // for indexing for (int k = ref - refPixel; k <= ref + refPixel; k++) for (int i = ref - refPixel; i <= ref + refPixel; i ++) *(p + k * width + i) = (DATA_TYPE)SWAP(valmax_); *(p + ref * width + ref) = (DATA_TYPE)SWAP(valmin_); } /* * generate some dummy image data based on the given count. */ void CLASS_NAME::genImage(char *ptr, int width, int height, int count) { DATA_TYPE *p = (DATA_TYPE *)ptr; DATA_TYPE lineBuffer[MAX_NX * 3]; // generate a line with color values DATA_TYPE *ptmp = lineBuffer; DATA_TYPE v = -width / 2; if (abs(v) != width /2) // for unsigned short v = width / 2; for (int i = 0; i < MAX_NX * 3; i++, v++) *ptmp++ = SWAP(v); for (int k = 0; k < height; k++) { int cnt = (count + COUNT_INC) % width; memcpy(p + k * width, lineBuffer + cnt, width * sizeof(DATA_TYPE)); } // we need some reference pixels for tests genRef(ptr, width, height, ref_pixel()); genRef(ptr, width, height, count); genRef(ptr, width, height, width - count); } void CLASS_NAME::copyArrayToImage(char *ptr1, char *ptr2, int xs, int ys, int width) { DATA_TYPE *array = (DATA_TYPE *)ptr1; DATA_TYPE *image = (DATA_TYPE *)ptr2; DATA_TYPE *s1, *s2; for (int idx = 0; idx < awinsize_; idx++) { s1 = array + idx * awinsize_; s2 = image + (ys - 1 + idx) * width + xs - 1; memcpy(s2, s1, awinsize_ * sizeof(DATA_TYPE)); } } void CLASS_NAME::copyImageToArray(char *ptr1, char *ptr2, int xs, int ys, int width) { DATA_TYPE *image = (DATA_TYPE *)ptr1; DATA_TYPE *array = (DATA_TYPE *)ptr2; DATA_TYPE *s1, *s2; for (int idx = 0; idx < awinsize_; idx++) { s1 = array + idx * awinsize_; s2 = image + (ys - 1 + idx) * width + xs - 1; memcpy(s1, s2, awinsize_ * sizeof(DATA_TYPE)); } } void CLASS_NAME::initArea(char *ptr, int xs, int ys, int awinsize, int width, int height) { awinsize_ = awinsize; axs_ = xs; ays_ = ys; awidth_ = width; aheight_ = height; aptr_ = ptr; // allocate buffers for saving and copying data int arraySize = awinsize * awinsize * sizeof(DATA_TYPE); array_ = (char *)malloc(arraySize); array2_ = (char *)malloc(arraySize); if (array_ == NULL || array2_ == NULL) errexit("not enough memory for malloc()"); // save the rectangular around the star into array copyImageToArray(ptr, array_, xs, ys, width); } void CLASS_NAME::jitterArea(int starjitter) { int y = ays_ + getRandomShift(starjitter); int x = axs_ + getRandomShift(starjitter); // copy array starting at xs,ys to the area starting at XS, YS copyImageToArray(aptr_, array2_, x, y, awidth_); copyArrayToImage(array2_, aptr_, axs_, ays_, awidth_); } void CLASS_NAME::restoreArea() { // restore the area starting at xs, ys copyArrayToImage(array_, aptr_, axs_, ays_, awidth_); } skycat-3.1.2-starlink-1b/rtd/tests/tRtdImage.tcl000077500000000000000000000010061215713201500214540ustar00rootroot00000000000000source test.tcl set w [RtdImage .rtd \ -file ../images/ngc1275.fits \ -canvaswidth 100 -canvasheight 100 \ -scrollbars 1 \ -drag_scroll 1 \ ] pack $w -fill both -expand 1 tkwait visibility $w #puts "getting shared memory id..." #puts "id = [[$w get_image] shm get data]" #[$w component draw] center_window #update #puts "image name: [$w get_image], canvas name: [$w component canvas]" #puts "image cget -file: [[$w get_image] cget -file]" #puts "canvas config: [[$w component canvas] config]" skycat-3.1.2-starlink-1b/rtd/tests/tRtdImageCtrl.tcl000077500000000000000000000012451215713201500223060ustar00rootroot00000000000000source test.tcl set w [RtdImageCtrl .rtd \ -scrollbars 1 \ -drag_scroll 1 \ -with_zoom_window 1 \ -with_pan_window 1 \ -with_colorramp 1 \ -zoom_view_propagate 1 \ -pan_width 180 \ -pan_height 180 \ ] pack $w -fill both -expand 1 update $w config -file ../images/ngc1275.fits #after 2000 [code [$w component pan] config -width 200 -height 200] #after 4000 [code [$w component zoom] config -width 200 -height 200] #[$w component draw] center_window #update #puts "image name: [$w get_image], canvas name: [$w component canvas]" #puts "image cget -file: [[$w get_image] cget -file]" #puts "canvas config: [[$w component canvas] config]" skycat-3.1.2-starlink-1b/rtd/tests/tRtdImageCut.tcl000077500000000000000000000002721215713201500221340ustar00rootroot00000000000000source test.tcl set w [RtdImage .rtd \ -file ../images/ngc1275.fits \ -scrollbars 1 \ -drag_scroll 1 \ ] pack $w -fill both -expand 1 update RtdImageCut $w.cut -image $w skycat-3.1.2-starlink-1b/rtd/tests/tRtdImageGraphics.tcl000077500000000000000000000010011215713201500231300ustar00rootroot00000000000000source test.tcl set w [RtdImage .rtd \ -file ../images/ngc1275.fits \ -canvaswidth 100 -canvasheight 100 \ -scrollbars 1 \ -drag_scroll 1 \ ] pack $w -fill both -expand 1 tkwait visibility $w #puts "getting shared memory id..." #puts "id = [[$w get_image] shm get data]" [$w component draw] center_window update puts "image name: [$w get_image], canvas name: [$w component canvas]" puts "image cget -file: [[$w get_image] cget -file]" puts "canvas config: [[$w component canvas] config]" skycat-3.1.2-starlink-1b/rtd/tests/tRtdImagePick.tcl000077500000000000000000000003061215713201500222650ustar00rootroot00000000000000source test.tcl set w [RtdImage .rtd \ -file ../images/ngc1275.fits \ -scrollbars 1 \ -drag_scroll 1 \ ] pack $w -fill both -expand 1 update RtdImagePick $w.pick -target_image $w skycat-3.1.2-starlink-1b/rtd/tests/tRtdImageSpectrum.tcl000077500000000000000000000007471215713201500232120ustar00rootroot00000000000000proc make_spectrum {line_id x0 y0 x1 y1} { RtdImageSpectrum .rtd.spectrum \ -x0 [expr int($x0)] \ -y0 [expr int($y0)] \ -x1 [expr int($x1)] \ -y1 [expr int($y1)] \ -image .rtd \ -transient 1 \ -line_id $line_id } source test.tcl set w [RtdImage .rtd \ -file ../images/ngc1275.fits \ -scrollbars 1 \ -drag_scroll 1 \ -graphics 1 \ ] pack $w -fill both -expand 1 update .rtd.draw set_drawing_mode line make_spectrum skycat-3.1.2-starlink-1b/rtd/tests/test.tcl000066400000000000000000000011761215713201500205600ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: test.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # test.tcl - tcl defs to set up environment for test scripts # # Usage: source test.tcl # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 08 Apr 97 created proc tkerror {msg} { global errorInfo puts stderr "$errorInfo" tkerror__ "error: $msg" } # for debugging: print all errors on stderr catch {tkerror} rename tkerror tkerror__ #lappend auto_path ../library package require Rtd set tk_strictMotif 1 tk appname Tclutil utilPrintErrors util::setXdefaults skycat-3.1.2-starlink-1b/rtd/tests/trtdRemote.c000066400000000000000000000062331215713201500213710ustar00rootroot00000000000000/* * E.S.O. - VLT project / ESO Archive * "@(#) $Id: trtdRemote.c,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * trtdRemote.C - test cases for remote interface to the RTD * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 6 Mar 96 Created */ #include #include #include #include #include #include "rtd_remote.h" /* * declare an optional error handler to print out error messages * automatically. */ static void errorHandler(char* msg) { /* this part is just added for the sake of testing */ if (strcmp(rtdRemoteGetError(), msg) != 0) { printf("errorHandler test failed\n"); } printf("trtdRemote: %s\n", msg); } /* * this routine is used for convenience in testing below Send the command * to the rtdimage, then print and return the result. */ static char* send_rtd(char* cmd) { char* result = NULL; int status = rtdRemoteSend(cmd, &result); printf("%s ==> %s: %s\n", cmd, (status ? "FAILED" : "OK"), result); return result; } /* * return a shared memory pointer given the id */ static void* get_shm(int shmId) { void* ptr = shmat(shmId, NULL, 0); if (ptr == NULL || ptr == (void *)-1) { printf("Invalid shared memory id specified: %d", shmId); return NULL; } printf("shmId %d ==> %x\n", shmId, ptr); return ptr; } /* * do some tests on the shared memory from the Rtd image header and data * The arguments should be the shared memory Ids. */ static void test_shm(int data_id, int header_id) { void* data = get_shm(data_id); char* header = (char*)get_shm(header_id); char buf[81]; int i, j, n, w, h, bitpix; char* p; short* rawimage; if (header) { printf("got image header (%d):\n", header_id); p = header; for(i = 0; i < 10; i++) { for (j=0; j<80; j++) { printf("%c", *p++); } printf("\n"); } printf("...\n"); } if (data) { printf("got image data (%d)\n", data_id); /* do something to the data... */ w = atoi(send_rtd("width")); h = atoi(send_rtd("height")); bitpix = atoi(send_rtd("bitpix")); if (bitpix == 16) { printf("modifying 'short' raw data (mult by 2):\n"); rawimage = (short*)data; for(i = 0; i < w; i++) { for (j=0; j

SKYCAT FAQ
FREQUENTLY ASKED QUESTIONS

Return to skycat Main Page


FEATURES
  1. What command-line options does skycat support?
  2. Where can I get the source code for skycat?
  3. Where can I get a binary release of skycat?
  4. How can I add my own catalogs to skycat?
  5. What are the special MORE and PREVIEW catalog columns?
  6. What remote interfaces are there to access skycat?
  7. What commands can I send to skycat with Tk send?
  8. How does the remote socket interface to skycat work?
  9. How can I access skycat images in shared memory?

PROBLEMS
  1. Why do I sometimes get color flashing when using skycat?
  2. skycat uses up all of the colors in my colormap. How do I make it stop?
  3. What does the catalog window take so long to pop up?


What command-line options does skycat support?

In general, the syntax is:
skycat fileName -option value ...
An argument not starting with "-" is taken to be a FITS image file to load. A "-" by itself means: read the FITS file from the standard input. A file with the suffix ".hfits" is taken to be an H-compressed FITS file and is decompressed automatically. A ".gfits" or ".gzfits" suffix indicates that the FITS file is GZIP compressed and a suffix of ".cfits" is assumed to be UNIX compressed. Image formats other than FITS are not currently supported, but will be in a future release.

The following options are supported:

-file FITSfile Specify a FITS file to load. The '-file' part is optional, so you can also simply specify a file name, as described above.
-cat bool If bool is 1, include 'Data-Servers' menu in the menubar (This is the default). The 'Data-Servers' menu gives you access to the ESO/Archive extensions for browsing astronomical catalogs, plotting objects in the image window and getting images over the network from the image servers, such as the Digitized Sky server.
-rtd bool If bool is 1, include the Real-Time menu in the menubar (default is 0). The Real-Time menu gives you access to the VLT Real-Time Display features, such as camera control and rapid frames. To use these features, the rtdServer daemon must be running on the local host. A client application, linked with the Rtd image event library can then send images via shared memory to be displayed in rapid succession.
-port portnum Specify a port number to ue for the remote socket interface. The default is 0, which means choose an unused port. See the RTD User's Guide for a description of the remote socket interface.
-disp_image_icon bool If bool is 1 (default), display a miniature version of the image in the tool's icon window.
-default_cmap cmap Specify the default colormap. This should be one of the names listed in the 'Colors' popup window (default is 'real').
-default_itt itt Specify the default intensity transfer table. This should be one of the names listed in the 'Colors' popup window (default is 'ramp').
-colorramp_height pixels This option can be used to change the height of color bar (the widget at the bottom of the screen displaying the image colors).
-with_colorramp bool If bool is true, display the color bar (default).
-with_zoom_window bool If bool is true, display the zoom window (default).
-with_pan_window bool If bool is true, display the pan window (default).
-dozoom bool If bool is true, turn the zoom window on automatically (default).
-debug bool If bool is true (default: false) turn on debugging features. This also enables the real-time simulation (when the -rtd option was specified).
-verbose bool If bool is true (default: false) display debugging messages at run-time (for debugging).
-display dpy Specify the X server to use.

Arguments which are not switches are interpreted as image files.

Where can I get the source code for skycat?
The software is available as source code for research and other non-profit organizations. If you are interested to obtain the package send us a note.

Where can I get a binary release of skycat?
Single binary versions of skycat are available for Solaris, HP-UX and SunOS. These binaries were built using code borrowed from GNU emacs (unexec) that makes it possible to include interpreted sources and other files in an executable.

How can I add my own catalogs to skycat?
First of all, you should have a look at the skycat config file This file lists the catalogs available by default. You can use a different list by setting the environment variable SKYCAT_CONFIG to a valid URL on an http server. If you want us to add your catalog to the default list, send us an email.
More about catalog servers can be found in the note written by Clive Davenhall (Starlink).

To include your own catalog in skycat, you have to implement a catalog server, and add an entry to the skycat config file for it.

Note that there has been some discussion about standards for catalog servers and the URL syntax used to access them. Please see Astronomical Server URL for more information on that.

A catalog server is called via HTTP as a cgi-bin application. The syntax for the URL is taken from the skycat config file. The URL contains the query parameters, such as RA, DEC, RADIUS, etc. The format of the return value is a tab separated table with column headings separated from data by a dashed line "---".

TableTitle # comments, text, etc... ... ID RA DEC OtherCols ---- ---- ---- --------- someId1 42.331 43.233 etc... ...

skycat expects the first three columns to always be: ID, RA and DEC. The following columns can be anything. RA and DEC should be in degrees, J2000. In the the query arguments, RA and DEC are specified in HH:MM:SS.sss format and the radius in arcmin.

What are the special MORE and PREVIEW catalog columns?
There are two special (optional) catalog column names: MORE and PREVIEW. They are expected to contain a URL in the format M=http://... for MORE and P=http://... for PREVIEW.

The MORE URL should point to an HTML page with more information on the object. skycat passes the URL to netscape for display.

The PREVIEW URL should point to either a FITS image (possibly compressed) of the selected object or a tab table with data to plot as an X,Y graph. The Content-type of the HTTP result is used to determine whether the data is a FITS image or a tab table and whether or not it is compressed. The Astronomical Server URL document mentioned above describes the allowed Mime-type/Content-type values. These have been implemented in skycat.

If the Content-type of the PREVIEW data returned from an HTTP server is recognized as a tab table (text/x-starbase, etc., or even text/plain), it it should be an ASCII tab table with 2 columns. The first column is plotted as X and the second as Y and the column headings are displayed as the X and Y graph labels.

What remote interfaces are there to access skycat?
There are a number of ways to access skycat data or commands from an external process:

  • Tk send, plus a collection of simple Tcl procs defined by Skycat
    (see below and also the comments at end of skycat/interp/library/Skycat.tcl)

  • Remote socket interface
    (see rtd/rtdrmt module for examples)

  • SysV shared memory for image header and data
    (see rtdimage "shm" subcommand)

  • MMAP shared file/memory for image header and data
    (mmap is used by default to read the image files)

  • Rtd real-time interface (rtdServer)

What commands can I send to skycat with Tk send?
If Skycat is compiled with Tk send enabled (you have to edit the Tk Makefile to do this if you compile yourself) there are some simple Tcl procedures defined that can easily be called from another Tk based application:

  • get_catalog_info {}
    - return contents of catalog listing in the format {{selected_row} {{row1} {row2} ...}}

  • display_image {ra dec width height {equinox 2000}}
    - display image from DSS

  • mark_image {ra dec width height}
    - draw a rectangle on the image, return id

  • unmark_image {id}
    - remove the rectangle given by id

  • load_image {filename}
    - load and display an image file

  • pick_object {{cmd ""}}
    - display the "PickObject" dialog window to allow the user to select an object/star and return the info for it in the form: {$x $y $ra $dec $equinox $fwhmX $fwhmY $angle $object $background}

See also the comments at end of source file: cat/tclcat/library/SkyCat.tcl. The PickObject interface is (or will be) described in the man page RtdImagePick(n).

How does the remote socket interface to skycat work?
The remote socket interface is an RTD feature described in the RTD User's Guide, which can be found in the doc directory of the skycat ftp dir.

Basically, what you can do is open a socket connection and send ASCII strings to Skycat (since it is based on the RTD). The port number can be specified on the Skycat command line with the -port num option.

The strings are interpreted as RTD subcommands. The command method is called with the given arguments and the result is returned via socket again. It is similar to Tk send, except that it is more secure (you can only access RTD subcommands) and can easily be used by a C application (or any other language).

The format to send a command is:

command\n (command followed by newline) where command is one of the RTD subcommands (without an instance name). The result read from the socket has the format: status length \n result[length] That is, 2 lines: the first line contains 2 numbers: the command status (0 is OK) and the length of the result. The next line contains the result, which has the given length.

Check out RTD User's Guide and the rtd/rtdrmt directory in the Skycat source tree for examples of how to use the remote interface.

How can I access skycat images in shared memory?
Skycat doesn't put images in sysV shared memory by default, since some systems have a very low default limit on the number of available sysV shared memory areas. However, there are commands (rtdimage subcommands) to tell skycat to use shared memory for the internal FITS image header or data or both. (Note: by default skycat maps the image files using mmap(2).)

  • You can use the -shm_header 1 and -shm_data 1 options when starting skycat, so that shared memory is used automatically.

  • Use the rtdimage subcommand "shm" (also available via the remote socket interface) to tell skycat to use shared memory and to get the shared memory ids.

See the RTD User's Guide for a description of the rtdimage subcommands.

Why do I sometimes get color flashing when using skycat?
If you are running other applications, such as netscape, that use many colors, you may have this problem. Try running netscape with the "-ncols 60" option, to limit the number of colors it uses to 60. You can limit the number of colors skycat uses via the View menu (Colors item).

skycat uses up all of the colors in my colormap. How do I make it stop?
Select Colors... from the skycat View menu. There you can adjust the number of colors skycat uses by moving the slider and pressing the Allocate button.

What does the catalog window take so long to pop up?
When you display the catalog (Data-Server or Image-Server) window for the first time, it reads the skycat configuration file over HTTP for the list of catalogs. You can specify a local configuration file by setting the environment variable SKYCAT_CONFIG to a valid URL (http://... or file:/... for a local file). The default URL is: http://archive.eso.org/skycat/skycat2.0.cfg


Please send questions or comments to abrighto@eso.org.
Copyright © 1996 ESO - European Southern Observatory

Last modified: Thu Aug 6 20:37:07 MEST 1998 skycat-3.1.2-starlink-1b/skycat/htmldoc/skycat-list.html000066400000000000000000000026341215713201500232270ustar00rootroot00000000000000 The SkyCat Tool Mailing List

The SkyCat Tool Mailing List

This mailing list is managed by the majordomo mailing manager. You can include one or more of the following command in a message to the ESO majordomo. Commands should be sent in the BODY of an email message to majordomo@eso.org.

Commands in the "Subject:" line are NOT processed.

If you have any questions or problems, please contact don't hesitate to contact Miguel Albrecht <malbrech@eso.org>

A Hypermail archive is also available.


Last update: Dec 9, 1996 skycat-3.1.2-starlink-1b/skycat/htmldoc/skycat-logo.gif000066400000000000000000000131241215713201500230110ustar00rootroot00000000000000GIF89aÆ;¢ÿÿÿÿ½ÿÿcÆÿ9kÖ1¥R{!ùÿ,Æ;@ÿHªÓ#0B§ ±8ßmðÕÝB ââ4ÒÔT]ë¾p–ô™ Ô'ï¼Eÿ¶ ޤëa?Ÿ õhP¤È³t WÅh”ãÚŒN`–VËí2À¹q4 ÆÝ$¹ÚhÊ©+ÑxÔ[EüÑ[eT$lsV7N%JŠFƒ„m‡‰tIP &˜…z’ni^J>—Ks%“X¬£š~ABqH¢c~¦±N}j1‡’º8ÂÆpxá"6¿žMnÈȲy|ƒ ‹_Õá‘ÆÙWyÊ,^à¾ÔãÇËÌÃ-èS€g†çï{'™Ê»Ìäs·íWÁÚäÏ[ fòäC•"Ž)…÷^D“ÈAÿØg–…B!`‹åøˆð Kg'ˆuÒ‡ÃHaX„ÉS€R%=›ÌFsH–§+‡±3èñ&E°ì£N+)’ZÅ3áæ—!>mF„äyÏœ-‹Èu·£×ÈÊk¦sî<ˆºæ¹Ðéìc½!@ZUrÙÀjÖî(ŒkßOWš ékÀÏ¥î–×ÅÌ+ ¸#€2@9Ó@;vÚtJst#‹º,߯¿||A)ŠÚnq >Ф/nÚ®³é©:ì€Vœˆà GE]\àÉ8Ë‘ ÚâjOØD(Çu-`êǬƒW“MeÔí1Ÿ¼l½íaÅÈÃ1Úó>³§ÿ­A•”M’¼f_MÄ÷ÔQÅ93Þ$I5‚æ Ñž{ö%GžUÍl°›z¸¶]!uHUh=³À0P!“¢NØ]•y¨!sPŒ-µÔÔŽ;NuÓlZæ”UV‘vm×| ä^ÏØ4B‹–™BÂq’ë É—N¶ˆdP@©hZ‡(wYwM¾Ò‰.þ¸ÌdX}׋/MöyZ¾x†’o¸¥jB:‡[T(@˜a!„Р¶Ãš†º@“Ri¤•Fêe—v*餠z**ÈÚ"¤¡Z:ê¥H¶¶j§•fú*¤X² H ºšœ¬Éêi«¥²Ê©†¼ÎÚe6Gþš¬±ÿÆÞ0,­Tê*ª¯Âhš¬±îjiªÛRZìµÛ~{)äzëi¨èšK,¸åΚ©¸àªÚí¹ó»®ªâ¾{ï¸ñjÊì¨éÂ:o¯Ïîë.³Ånúï SËðì®Ð Mˆ`aÇ:¬T`f%íIq*ª¬rDßœµÐ)}Z¼Ê’j¼ÒÇDž#/RÜR…5ºŽ*±ÚRØOMO-5@”ó=uIÞNAbAÇ âvRÚ¦UD<NÞ}ÑEYTz¾‘ÒNò4ù .ÙŠ–¬2žÜ`‡=‘Ê•¦!˜</‚[ˆâ¢%œèĨþÒ¤"FÙ(-{QÀ`,P‘p4I< ³Ð$œS¢â]¯L)ôšü²@ب (ï3P*ÌÒ•¨i£iÙÛX¤Áb…s  OÔ*Ôˆ„SÂOüÊÃ#½'>Ä 6ÿ²´(RõƒHFŽ|¤E²(Ð%·J[’¢-Æ&Ð2£N¼dy¬ÆuÄσÜ(€0Õ'7ñ±"’ÎÈ&ð á#VÔ ûÔ¤Þ §+Ja_J¶C»NLÒITÇ g#ºC‡” ZÆÂGüq¨ƒŠûÄR¦)òþBU¼ìµ*…IëXô’³°´GhL[[…|)É]Ö’Êêa=h­i!«€©N³nYFg%‘JÂt˜¿JÍÁ/•À†©Ž]Ò‹[ܼ´iN~•+`˜b×±ØÙN~á«_¹œ'Ä VO`ârh*ÌËžOfJ*ޝy;iIO‚5qœûtf1!ÿÑja#lK…Ö2ÆQPh¬neÈ…(Ñ·AIjƒbN4¨Ýá¹àÃÓ\ʸÜqBo4­™Í á´’ íbTXÊ>|š´¢Ô{iÈi=î–¸~¨Ìf!AT'6¡¢íß Eä³¶“m¯„„©ÈLZ æý­baUÚLÉš ›‚å‡-ݪ-ÚªÒâf­?íÙÚCR¥ÊG>#^yŽXŒ.mèËÙ¾QX¢m ù¸ÇI¹j6âs#jh¦wÖ«êu°~;KǸæÙJÐ`d¡I)ÞT µu0¢p iuîúQÆmu¥È,¢*#±(ïó¦·'›W|W·3]cø[™æöm4Tˆ³£¡JØ,;ý*Κ:ºËðÔÂÍÃÙùÎvÕ¿u×µâÛð6 )ð66#Dñ\a;½Íî¤ÛKÇ è’án„ybhÏ$庾¬Î;¾•Ydg>!Ên'ÿQÜñXÛ7­©9ðy ,›ò‹!êhª£ŒH7˜–+ËŽ8fâòÂ4६ ®ß[ôß¾,9ÃãmqŸä4›Ü.€:R3ƒV &½h†ÿÍBõ‘)¶ä˜NVòAvȼ5×n2 ð͸º‘ʾÀínèxô†~ŸTàT4=eSz$uÔû$(ã</!-µàZ3Ñ^6`gN(é&¡R(«L›Ïa ‡LnèŠ(23¡ËкZ™* ‰BH‘½™å/‡©ØÍuö >Ó ;>VºÑÁ§TW ‡¦$o‚ν!‰–(V9M>03Zœ•cÍI\¶nœƒ¢EÏÄ’„$¾¯!¤0mEO0ŒŠžEÁêo‡.wlUoæáé`Ô€Ä 5r&7~ô’¥·Z“Àac€ï<à~3ÿ¯^w$zcˆÁq–“«¶´íl Š“ Ñeì51 Mî†z€â8ñ®L…Ž¯ÎœyPY›{÷E_N 2‰ÐS@oºcT¬þ›×ûÊiyM“¢m¿-ç9•üzÂF=öÇY”¹Í©þ¿•ºÇîý:Pµ)žôz@]0Ò‚wÚH%!ß·Qÿµ‚•ßNz¼XÁãÊd‡RÇY YŒ »~â@ÕéhG£åïæ(  lžö z/lîÝhFµOKà¡yïî\¸ÇŸ†¤qï^nóEÐY¸^åUÂæTÕ:’5U0scJ51V%?»`‘Å[(f“} åÙ DùR™…@ìÆ6E9ûE}ÿÅ‘yD Z4s’WDU•‘#W4…U^à‘]™•c:)VZÃjÙQÔs8äT‘;Y”É•hécÅìbw©Usu”ó*•ƒóU#áWPõ]ƒö’9Å’®=U“.Fb–¶^VÙ ê€T¡¡yŸPS,s\½c–@9•úu’°Uc —bP9ÀV£õc‚ 9fP ·…>6åxŠE d)–\”C˜§•šc¹›=€^qc“éé³Yjg™6Ság7^EzÚðYT‰\œµ™þµ8·€ZK¡ (#_"™8¶?6R™¶2Ðp[Ñ™ž?ó›jE›à ˜ð©bŒÿY7k0iU! 8„°œ(µ<+¦Ipõ“—¶šRà6Ž¥8É)Zæu^ štX¹7º *–4¶Sªa27ón­e9…s ²%,…–pš¶ › B9j‰U;ð¢*`2#D6‡ÁŸ_eC7š>J©¤8ªé“ÖC7HÅT: ^i¢^ ]!:4F^ Z†šU¡‘Ã7dU^X_8 Yÿð¤º6nY…X$êé< 04^hàrFµ£‹©av5iz‘03`”é Õe]——hÊ…D- Ò]<“bÙÕÿicI…¡i ”‚žW¤9™¨ädz ¤sÀ$>ÿ‚q3¦AJ¡`§À"§aÀ$uµ‹iMÒ¨y–Ö5]õuÄ›[¥˜wÚŸ ÃÒ%›Pš’\Á9.ªqU6<ª;,Ñlq`bƒYhÿ1¤fº¤ÃC­Aš¤ i××cÃS¥°np³kDM¬Ê !4­š úSD¸ºbê$çÆ&½gf†J a;vb±I¤+·&Q£ßSšNY™j]™µj§~j:y2–ge=¢à‰Ê°Ý–Be¤9)ÙÓXÆÅI”í² 7~VdŠ‚EB¤Cm³cð®Id’¶®Å÷#‹&sp@1q%nxiÕI¯ çrY_ÿ "I<ꦘ”ñRôðžs C AÉÇ#/"(?³;ÚÆ´ ³Û}t• iguA¯…Z/7Zñ•52D£:ªu’‚ÕƒlwÖ ®w£´dàZ³“\gd„o“k£Jz´A`äx7–qJV×}~Æ„…—¨÷ºK…”œ9gŒt¨U†Ik¬!$j’ƒy·ƒ·HV™Š¡œ«ºzH„¨Éç<.ç ±äWjrªk¸*'^§eñŠrŸ“? =Šwn»CNÁÁå.Á«ùðg¯³ D¾©¯3ë9;2°”4„”¨kváSªÑPGe U …´AAelä(ÿ0Jý%3ªñ¬¸¹žžÁ¸(Š…Á‡H”–¶±ENÂwõÜ&¥[;~52@¨çt¢ç’/±H±€$äD‡º îIÒ«[d¢÷yÄÐw|yÚá#ÀU »¶zýž(b¡º%I‹ø[Ñ3&šF"oi‚ˆ4–ÆcyÚ ì»nßôÌÛÄ^³'5b÷ Å:úÆ©*¤ ΄‹&ÁZX1pDnXFW´r`s£vk0=!Ðô«Ó²dç~|¹·/Ê~AÓ5d×ómj÷º†,çÛ!êc^l4HÑŠÇ„UVJ|¼¤±qµÓõ‡±Hÿ÷v·fÌŸ°fG]ŒœÉZN5h¬£AuøÄ$Çsþ‘Ið'¸‚&nörü±B¬³¯§lÿ†lËÆl¼ÁUuzp<x¦QG20G— ,·i€ä Lºûö@5Bav@«Í—¥oÔ$–t$ë¡Ö{AÊ„‹“8ƒ&Â…Ât,zF$ÃT˜ûkË®’§žÄsp< mZèŸ0LΓëËíÐ%­ep2sHL΂$"rÌ–p—ê§ø|=VÔÂBKfÙá£pÌbN»=!eæÉ¬a5­f L;ju(mšæJê=模æy”t‚úD½´]Ìvz?òÿ|f0kotÄ›=¹)u´«AÌ×sP4áinï»ËœüIѧ»u€}äi­ëÊTbhf"û·«-ÜàâNe°ø±§šCÛ­ÿC{SÛL·Dxs¸K(ý+NÄR)؇ö¦)y3ê겇¦âM¤¨ÎÚD.¼2ˆ{(L¢žç*Þ °NÒ2b?‡ûÑŽ»‡6šçŒ˜xòʽB…(º{)Qx7Ÿp|>zMª¨-X˜…®¸†àŽkÈëH¸ˆINQü…·¾îã4‡è^žA‹ÐžMdlОУh-NûŽîؤt 5‡Íâí¸×ÎÓ.^¸ìçïʾ‰¯NøÔ0ᄺ¢‰S+·ŽÛMÒYètöýOÆ4ï:ôðeÔˆcމïëÛ$ð—ÈN«íòʸ‹áž†ŒQ¹èˆó²®ñ!¯ê­(ÿ/µÂ°—ÿa”¨-ÿ‚ åî¯ø(…‡°Xâ¿Äí}¨òSäŽê.¤.ŽðN‹ý8†ö„ñÃðE¿ˆC¯õH¨ÍcÓ,áüèö˜HˆáQ<õéP…Ýï #‹Ùç-ïÔõº>÷ãhŒOoîÂhø‹o÷å>÷¤ˆÄˆPjN½Xó£â§¡ë²ÂŒºTh¸÷ øû4ú+ïOõ×Âù³Nô…oŽåû<ù²Ž]ßú ô«~ù¸ïO%hO´ûº¿/¢Hö®¿÷ôTüb¿ü0)ˆ{¿ñÃòúcx‹éøˆæxójß…ØrùÓxóšXøÅhóÀx…»BꨌæÞ´¯îþXûŒoüŠ?ÿ\ù¼búßžö¦¨ü£ˆ¡Ëí#*;skycat-3.1.2-starlink-1b/skycat/htmldoc/skycat-server.html000066400000000000000000000422031215713201500235560ustar00rootroot00000000000000 SkyCat Server

CCLRC / RUTHERFORD APPLETON LABORATORY
Particle Physics & Astronomy Research Council
Starlink Project

Clive Davenhall
Institute for Astronomy, University of Edinburgh & Starlink
27th October 1996

Notes on Writing an AstroCatalog Server
(DRAFT)
Version 1.0

These notes are an incomplete draft. Queries, asides and things I'm unsure about are shown in a sans serif font like this.

Contents

Introduction

The ESO AstroCatalog library allows applications to access remote databases, catalogues and archives across the internet. It is used by the ESO skycat image display tool and various other applications. In order to make a database accessible to the AstroCatalog library a `server' must be provided for it. This server will accept remote queries sent in a standardised format, interrogate the database and return a table of results corresponding to the objects in the database which satisfied the query. These notes are intended to assist in writing such a server. They should be used in conjunction with listings for one or more existing servers.

The communication between the remote application and the server uses the Hyper-Text Transfer Protocol (HTTP) developed for the World Wide Web. The servers are, strictly speaking, gateways using the Common Gateway Interface (CGI). One way of thinking of the remote application is as a very specialised Web browser. One consequence of this approach is that if a site is to provide an AstroCatalog server it must also be running a Web server. The HTTP and CGI protocols are, of course, enormously flexible and there are additional protocols and conventions for communicating between an AstroCatalog application and server. These protocols and conventions are described in subsequent sections. The format for queries is described in Section 3 and that for the returned results in Section 4.

Though the protocols for communicating between an AstroCatalog application and server are (reasonably) well defined, there are an unlimited number of ways in which a server could be written to accept standard queries and return standard results. Thus, these notes cannot prescribe how a server must be written, but merely suggest some alternatives. An AstroCatalog server is a CGI script and CGI scripts are usually (but not necessarily) written in Perl. For the rest of these notes I shall assume that the server is to be implemented as a Perl script. The entire server could be written in Perl, with the database being accessed directly from the Perl script. However, it is more likely that the Perl script will invoke a Database Management System (DBMS) or special-purpose program to interrogate the database.

This document assumes that you have some familiarity with the AstroCatalog library or, at least, skycat. The AstroCatalog library is documented in Astronomical Catalog Library Interface Specification by Allan Brighton. It also assumes that you are familiar with HTTP, writing CGI scripts and Perl. There are numerous books describing the HTTP and CGI protocols. The HTML Source Book by Ian Graham seems to be a particularly good one. Similarly there are various books on Perl. Learning Perl by Randall Schwartz and Programming Perl by Larry Wall and Randall Schwartz are comprehensive and easy to use.

Accessing a New Server with the AstroCatalog Library

It might seem perverse to describe how to access a new server with the AstroCatalog library before describing how to write the server. However, access to the new server will often be the first thing that you set up, so that you can try it out during development and debugging.

The servers for catalogues, databases and archives are identified to the AstroCatalog library using a syntax of the form:

name@location

where name is an abbreviation for the name of the catalogue and location an abbreviation for the institution where it is held. By convention both name and location are usually quite short. For example:

ppm@eso

is the abbreviation for the version of Bastian and Roeser's accents? Positions and Proper Motion catalogue available at ESO.

A list of all the catalogues, databases and archives which the AstroCatalog library can access is held in a configuration file. You must take a copy of this configuration file, add details for your new server and then instruct your copy of the AstroCatalog library to access this modified file.

By default the AstroCatalog library uses a configuration file kept at ESO. You can retrieve a copy of it from URL:

http://archive.eso.org/skycat/skycat2.0.cfg

To access your own copy of this file you must place it in a directory accessible to your local HTTP server (that is, one which is `visible to the Web'). Then set environment variable SKYCAT_CONFIG to a URL which points to this file.

You must now add an entry for your catalogue to this file. The file is simply a text file which can be modified with a text editor. It contains extensive comments which should be read in conjunction with these notes.

For example, the entry for the PPM catalogue is:

serv_type:      catalog
long_name:      PPM at ESO
short_name:     ppm@eso
url:            http://archive.eso.org/skycat/servers/ppm-server...
symbol:         mag circle 15-$mag

The purposes of the various items are as follows.

serv_type:
The alternatives are: catalog, archive, namesvr or imagesvr. catalog is the simplest and most common option; it used for simple catalogues and tables. A serv_type of catalog is assumed in the rest of these notes. See Section 2 of the Astronomical Catalog Library Interface Specification for a discussion of the alternatives.

long_name:
A name or short (one-line) description of the catalogue. It is intended to be read by humans rather than interpretted by computer.

short_name:
The name used to identify the server to the AstroCatalog library.

url:
The URL used to access the server. Following the usual conventions for a CGI gateway it consists of the directory specification and file name of the server followed by parameters passed to the server to define the query (see Section 3).

symbol:
Defines the plotting symbol to be used; see the comments in the configuration file for details.

symbol is optional; the other items are mandatory.

Finally, if you want your server to become generally available then remember to send either the details or your modified configuration file to the skycat/AstroCatalog library team at ESO.

Query parameters

 

The parameters at the end of the server URL pass values which define the query which objects in the catalogue must satisfy if they are to be selected. The types of queries which are currently supported are mostly concerned with selecting objects within a specified region of sky. The region may be either:

  • `circular' - within a given angular distance of a specified central point,
  • `annular' - within an annulus defined by a minimum and maximum angular distance from a specified central point,
  • `rectangular' - within a region bounded by specified great circles of Right Ascension and parallels of Declination.

The query parameters are as follows.

%ra
Right Ascension of the central position specified as sexagesimal hours check in J2000 coordinates.

%dec
Declination of the central position specified as sexagesimal degrees in J2000 coordinates.

%r1
The minimum radius for an annular query, in minutes of arc. For a circular query it should be set 0.0.

%r2
The maximum radius for an annular query or the radius for a circular query, in minutes of arc.

%w
The width or Right Ascension range of a rectangular query, in minutes of arc.

%h
The height or Declination range of a rectangular query, in minutes of arc.

%m1
The minimum (brightest) magnitude for an object to be selected,

%m2
The maximum (faintest) magnitude for an object to be selected,

%n
The maximum number of objects to be selected.

%cols
A list of columns to return. The list comprises a set of column names separated by commas, for example:

col1,col2,...coln

%id
ID field of item to return (if supported).

%mime-type
Value for HTTP mime-type field.

It is not always necessary (or possible) for a server to support all sorts of queries. For example, the minimum and maximum magnitude has no meaning in the case of the UK Schmidt Plate Catalogue.

Example

The query parameters to select objects within 120 minutes of arc of 10:00:00, +30:00:00 in the PPM catalogue was:

http://archive.eso.org/skycat/servers/ppm-server
 ?ra=10:00:0.00&dec=+30:00:0.00&radius=120&nout=101

Generalised queries

The query parameters used by the AstroCatalog library are special cases of a proposed general format for exchanging information between remote astronomical information services. A working document describing this proposal is available at URL:

http://archive.eso.org/~amicol/asu_94.html

Note that there seem to be differences between the query parameters currently implemented and the proposal.

Tab-separated list

 

The server must return the list of selected objects as a tab-separated list. The tab-separted list format is described in Section 2.3 of Astronomical Catalog Library Interface Specification. Briefly, it is a file or other stream of bytes, in which the values for individual fields in the list are separated by a tab character (ASCII character 9). A file in tab-separated list format can be modified with a text editor. The details of the format are as follows.

  1. The first line of a tab-separated list must be a header. Usually this header will be:

    Content-type: text/plain
  2. The next line gives the names of all the columns in the list, separated by tabs.
  3. The following line is a list of dashes (and tabs) which indicate that the table of values will follow immediately.
  4. The table follows, with one row (or object) per line.
  5. Within each line the fields corresponding to each column occur in the same order as the column names (given in 2 above) and are separated by tabs.
  6. The following two additional constraints apply:
    • the first column must be a name or identifier,
    • the second and third columns must be respectively be the Right Ascension and Declination in decimal degrees and J2000 coordinates.

The optional special columns MORE and PREVIEW can be used within information and image servers (see Section ???)

Example

A tab-separated list corresponding to a some columns in a subset of the PPM catalogue is listed below.

Content-type: text/plain

Id      ra      dec     mag
--      --      ---     ---
+29 1956        148.028620833333        29.2643666666667        9.2
+31 2059        148.081295833333        30.3859694444444        9.5
+29 1958p       148.092170833333        28.5661469444444        9.8
+32 1947        148.121254166667        31.5426083333333        8.6
+29 1959        148.179058333333        29.0041111111111        9.6

Hints

  1. When developing a server it is often useful to see the query that has been sent by the remote application. If you are using skycat as the remote application then the last query sent to the server is included in the skycat log, which is file:

    ~/.skycat/log

    If you are using some application of your own rather than skycat then the AstroCatalog library is easily modified to echo the query when it sends it. Proceed as follows.

    1. Locate and edit file AstroCatalog.C.
    2. Locate the lines:

      // send the query
      result_buf = http_.get(buf, nlines);
    3. Print out the value of buf by inserting something like:

      cout << buf << endl;

      between these two lines.

    4. Regenerate the execution module for your application.

  2. Special columns MORE and PREVIEW.
  3. plus others?

Related Documents

Specific references

  • The AstroCatalog library is documented in Astronomical Catalog Library Interface Specification, issue 2.1 by Allan Brighton, 26/6/96, ESO Very Large Telescope Data Management Division, document number GEN-SPE-ESO-0-0949.
  • The proposals for a format for the exchange of information between remote astronomical data services are described in Astronomical Server URL by Miguel Albrecht et al. It is available at URL:

    http://archive.eso.org/~amicol/asu_94.html

General references

There are numerous books about the HTTP and CGI protocols and the Perl language. I have found the following useful, though they are not necessarily the best. They are included for completeness.

The HTML Sourcebook
by Ian S. Graham, 1995 (John Wiley and Sons: New York).

Learning Perl
by Randal L. Schwartz, 1993 (O'Reilly and Associates Inc: Sebastopol, California). An introductory text for learning the language.

Programming Perl
by Larry Wall and Randal L. Schwartz, 1991 (O'Reilly and Associates Inc: Sebastopol, California). A reference manual.



ESO Archive
Mon Jun 2 11:27:07 MET DST 1997
skycat-3.1.2-starlink-1b/skycat/htmldoc/skycat.cfg000066400000000000000000000171271215713201500220540ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: skycat.cfg,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # -------------------------------------------------------------------- # skycat.cfg - config file for Astronomical Catalogs # # This file is read via http by the skycat software to get # the necessary information about the available catalogs. # # The syntax for each catalog entry is: # # serv_type: service type, one of: catalog, namesvr, imagesvr # (see Service Types below) # # long_name: long name of service for displaying # short_name: short name of service # url: URL used to access catalog, %ra,%dec, etc. expanded (see below) # # symbol: the symbol to use to plot the given column value # (see Plotting below) # copyright: any copyright notice applicable to this service # # Service Types #--------------- # # The valid service types are: # # catalog - server returns a tab separated table of row/col values # archive where the headings are followed by a dashed line # # namesvr - same as catalog or archive, except server returns a single # object with id, ra and dec to resolve the given object name # # imagesvr - server returns an image file # # # Syntax for "url" field: # -------------------------- # # The url field is used to build a URL to get the results via HTTP. # The syntax is like this: # # http://host:port/cgi-bin/server?arg1&arg2&...argn # # (if ":port" is missing, it defaults to 80.) # # Substitutions are performed on the URL as follows: # # %ra, %dec - coordinates of center point # # %w, %h - width and height in arcmin around center point # # %r1, %r2 - min and max radius (for circular query) # # %m1, %m2 - min and max magnitude # # %n - max number of rows to return # # %cols - list of columns to return (col1,col2,...coln) # # %id - ID field of item to return (if supported) # # %mime-type - value for http mime-type field # # Name servers only need the %id field, which is set to the object name. # # Plotting column values # ---------------------- # # The syntax for the "symbol:" field is as follows: # # symbol: col-name symbol expr : col-name symbol expr : ... # # where # col-name - is the name of the column to plot # # symbol - is the symbol to use, one of: # square, circle, triangle, cross, plus, diamond # # expr - is an expression in terms of the column used to # determine the size of the symbol at standard # magnification. The column name can be used as a # variable in the expression using "$". # example: # symbol: mag circle 15-$mag : xyz square (1-$xyz)*2.5 # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 11 Oct 95 created # M.Naumann 24 Jul 96 Updated URLs for catalog servers at the ESO # Science Archive (archive.eso.org and cgi-bin) # -- catalogs -- # GSC serv_type: catalog long_name: Guide Star Catalog at ESO short_name: gsc@eso #url: http://archive.eso.org/skycat/servers/gsc-server?%ra%dec&obj=%id&r=%r1,%r2&m=%m1,%m2&n=%n&f=8&s=R&F=* url: http://archive.eso.org/skycat/servers/gsc-server?%ra%dec&r=%r1,%r2&m=%m1,%m2&n=%n&f=8&s=R&F=* symbol: mag square 15-$mag serv_type: archive long_name: HST Archive at CADC short_name: hst@cadc url: http://cadcwww.dao.nrc.ca/cadcbin/hst-server?ra=%ra&dec=%dec&radius=%r2&nout=%n symbol: ra plus 2 copyright: Preview data provided courtesy of CADC/DAO/NRC serv_type: archive long_name: CFHT Archive at CADC short_name: cfht@cadc url: http://cadcwww.dao.nrc.ca/cadcbin/cfht-server?ra=%ra&dec=%dec&radius=%r2&nout=%n symbol: ra plus 3 copyright: Preview data provided courtesy of CADC/DAO/NRC serv_type: archive long_name: NTT Archive at ESO short_name: ntt@eso url: http://archive.eso.org/skycat/servers/ntt-server?ra=%ra&dec=%dec&radius=%r2&nout=%n symbol: ra plus 4 serv_type: catalog long_name: SAO at CADC short_name: sao@cadc url: http://cadcwww.dao.nrc.ca/cadcbin/sao-server?ra=%ra&dec=%dec&radius=%r2&nout=%n symbol: {V MAGNITUDE} circle {15-${V MAGNITUDE}/100.0} serv_type: catalog long_name: PPM at ESO short_name: ppm@eso url: http://archive.eso.org/skycat/servers/ppm-server?ra=%ra&dec=%dec&radius=%r2&nout=%n&mime=skycat symbol: mag circle 15-$mag serv_type: catalog long_name: PPM1 at ESO short_name: ppm1@eso url: http://archive.eso.org:8123/general-server/bin/general-server-V0.2?-source=ppm&-c.ra=%ra&-c.dec=%dec&-c.bm=%r2&-out.max=%n&-mime=skycat symbol: VMag circle 15-$VMag serv_type: archive long_name: HST Archive at ESO/ECF short_name: hst@eso url: http://archive.eso.org:8123/general-server/bin/general-server-V0.6?-source=hstscience&-c.ra=%ra&-c.dec=%dec&-c.bm=%r2&-out.max=%n&-mime=skycat&-pv_type_i=HFITS&-pv_type_s=ASCII symbol: RA plus 3 copyright: Preview data provided courtesy of CADC/DAO/NRC serv_type: catalog long_name: IRAS PSC at ESO short_name: iras_psc@eso url: http://archive.eso.org/skycat/servers/iras-server?ra=%ra&dec=%dec&radius=%r2&nout=%n symbol: ra triangle 2 serv_type: catalog long_name: ZCAT at CADC short_name: zcat@cadc url: http://cadcwww.dao.nrc.ca/cadcbin/zcat-server?ra=%ra&dec=%dec&radius=%r2&nout=%n symbol: VHELIO cross $VHELIO/100.0 serv_type: catalog long_name: QSO at CADC short_name: qso@cadc url: http://cadcwww.dao.nrc.ca/cadcbin/qso-server?ra=%ra&dec=%dec&radius=%r2&nout=%n symbol: REDSHIFT diamond 5-$REDSHIFT serv_type: catalog long_name: RC3 at CADC short_name: rc3@cadc url: http://cadcwww.dao.nrc.ca/cadcbin/rc3-server?ra=%ra&dec=%dec&radius=%r2&nout=%n symbol: ra square 3 serv_type: catalog long_name: ABELL at CADC short_name: abell@cadc url: http://cadcwww.dao.nrc.ca/cadcbin/abell-server?ra=%ra&dec=%dec&radius=%r2&nout=%n symbol: ra square 3 serv_type: catalog long_name: SIMBAD short_name: simbad@eso url: http://archive.eso.org/skycat/servers/sim-server?%ra%dec&r=%r2&n=%n symbol: mv circle 15-$mv : mb circle 15-$mb copyright: Provided by courtesy of CDS serv_type: namesvr long_name: SIMBAD Names short_name: simbad_ns@eso url: http://archive.eso.org/skycat/servers/sim-server?&o=%id serv_type: catalog long_name: NED short_name: ned@eso url: http://archive.eso.org/skycat/servers/ned-server?%ra%dec&r=%r2&n=%n symbol: Obj-Type square 2 copyright: Provided by courtesy of NASA/IPAC serv_type: catalog long_name: USNO at ESO short_name: usno@eso url: http://archive.eso.org/skycat/servers/usnoa-server?%ra%dec&radius=%r1,%r2&mag=%m1,%m2&format=8&sort=mr symbol: mag circle 15-$mag copyright: Provided by courtesy of the US Naval Observatory serv_type: namesvr long_name: NED Names short_name: ned_ns@eso url: http://archive.eso.org/skycat/servers/ned-server?&o=%id # -- image servers -- # DSS serv_type: imagesvr long_name: Digitized Sky at ESO short_name: dss@eso url: http://archive.eso.org/dss/dss?ra=%ra&dec=%dec&mime-type=%mime-type&x=%w&y=%h copyright: Digitized Sky Survey (c) by AURA, provided online by ESO # UKST serv_type: catalog long_name: UK Schmidt Plate Catalogue short_name: ukst@roe url: http://www.roe.ac.uk/cgi-bin/ukstsrv.wrap?%ra%dec&r=%r1,%r2&m=%m1,%m2&n=%n&f=8&s=R&F=* copyright: Provided by courtesy of ROE skycat-3.1.2-starlink-1b/skycat/htmldoc/skycat.html000066400000000000000000000253021215713201500222530ustar00rootroot00000000000000 the ESO SkyCat Tool  [the ESO SkyCat tool logo]

SkyCat is a tool that combines visualization of images and access to catalogs and archive data for astronomy.

See the SkyCat FAQ and the SkyCat Programmer's Manual for more information.

You can download the latest Skycat version here.

SkyCat features

  • Display FITS images, with support for the World Coordinate System (WCS), interactive measurement of offsets, and other standard visualization functions (SAOimage-like).

  • Overlay and edit color graphic objects on the image, `tagging' sources with text, arrows, circles, or other graphic elements.

  • Display a compass indicating where north and east are in the image, based on the world coordinates information.

  • PostScript color printing of the display (image + graphics).

  • Access and load images from network image servers, such as the Digitized Sky Survey (DSS).

  • Select previously viewed images from a history menu and catalog. The cut levels, color scale algorithm and colormap settings are remembered for each image.

  • Access and load catalog information from a number of popular astronomical catalogs, such as the HST Guide Star Catalog and many others.

  • Create, search and edit local user catalogs.

  • Save catalog data locally.

  • Overlay catalog sources on an image, taking object size and orientation into account.

  • Interact with Netscape to display more object information when available

  • Access the observations catalog from the NTT, HST and CFHT Science Archives.

  • Access to SIMBAD and NED both as name resolvers as well as for information on known objects.

  • Retrieve preview and other compressed images and decompress them on the fly.

  • Retrieve and plot tabular preview data for a selected object as an X/Y graph.

  • Calculate, display and plot the center position, FWHM, angle and other information for a selected star/object.

  • Load and save compressed images in hcompress, gzip or UNIX compress format.

  • Access SkyCat features from a remote process via socket interface or Tk "send".

  • Access image header and data (FITS format) via SysV shared memory or mmap.

  • Interact with WWW browser to access catalog documentation and other documents.

  • Support for dynamically loaded skycat plugins, such as the GAIA plugin, that add new features or modify existing ones.

  • Load lists of catalogs from other sites (ESO, CADC, CDS, local) and and allow users to select a preferred default catalog list.

Things we are working on

  • Save canvas graphics as a fits extension on the image file.

  • User customizable symbols to "label" objects on the canvas.

  • Add a user preferences dialog.

  • Add or edit WCS parameters for a given image.

  • Add support for 16 and 24 bit color currently requires that the display support an 8-bit pseudocolor X visual).

Caveats

  • Astrometry: SkyCat handles the astrometric positions by translating pixel positions into equatorial coordinates (RA, DEC). This translation is based on WCS (World Coordinate System) FITS keywords that are included in the image header and that give the astrometric solution for the image. The accuracy of the solution varies because, in many cases, an approximation is used.

  • Colors: If you are running netscape or some other color intensive applications before you start SkyCat, you may get some color flashing when you move the mouse in and out of the SkyCat image window. This is because SkyCat is using a private colormap to get enough colors to display the image. You can get around this problem by starting netscape with the "-ncols" option: for example:
          netscape -ncols 60 &.
    	
    You can also control how many colors SkyCat uses via the color dialog in the View menu.

About the software

SkyCat was developed by ESO's Data Management and Very Large Telescope (VLT) Project divisions with contributions from the Canadian Astronomical Data Center (CADC).

The tool was originally conceived as a demo of the capabilities of the class library that we are developing for the VLT.

The Skycat sources currently consist of five packages:

  • Tclutil - Generic Tcl and C++ utilities

  • Astrotcl - Astronomical Tcl and C++ utilities

  • RTD - Real-time Display classes and widgets (see The Messenger, 81, 1995)

  • Catlib - Catalog library and widgets

  • Skycat - Skycat application and library package
You can get the sources from the skycat ftp directory. All of the required packages are always included in the tarfile.

Java vs Tcl/Tk

Some users might wonder why we did this development in the Tcl/Tk environment rather than in Java. The main reason was the pragmatic need to get the functionality implemented in time for the VLT to come on-line (mid 1998). However, great care has been taken to develop as much as possible with object oriented languages (C++, [incr Tcl]), having in mind that the future lies in tele-scripting rather in the distribution of binary code.

SkyCat mailing list

A mailing list has been setup to support a wide collaboration on the SkyCat/RTD/CatLib project. Many people have shown interest in participating in such a venture. You can sign up with that list here. A hypermail archive is also available.

Distribution and support

The SkyCat binaries are freely available to any users who want to download and use the software at their own risk. Users who wish to modify the source code should contact malbrech@eso.org.

SkyCat is available as an executable for these platforms:

Solaris (SunOS-5.5.1)
HP-UX-10.20
Linux

ESO will maintain the Sun Solaris and HP versions in the longer term. They are the platforms on which VLT software will run. ESO does not have the resources to port to and maintain SkyCat on any other platforms. We will be glad to redistribute any port that other people or groups may support but decline any responsibility for them.

The software is available as source code for research and other non-profit organizations. If you are interested to obtain the package send us a note.

Please report problems or send suggestions to malbrech@eso.org or to abrighto@eso.org

Acknowledgments

We very much appreciated practicing wishful programming at large, i.e. wishing a utility, a function or just a code fragment that would just do that bit you badly need, then surfing the net, fetching it and re-using it in our code. Here is an incomplete list of packages that we either partially re-used or gave a source of inspiration.

  • STARCAT contributed many of its internals.

  • Tcl/Tk, TclX, BLT, Tix, ET and Itcl give the glue around the C++ classes, Tk provides the canvas graphics.

  • SAOimage lent the WCS lib (now a separate package, provided by courtesy of Doug Mink).

  • GSC server provided by courtesy of A. Preite-Martinez &. F. Ochsenbein.

  • SIMBAD and NED client routines allow name resolving.

  • The CADC press library is used to automatically compress and decompress (hcompress, gzip, ...) images.

  • Midas routines are used to calculate the centroid position, FWHM and angle of selected stars/objects.

Authors

Allan Brighton (ESO), Thomas Herlin (ESO), Miguel Albrecht (ESO), Daniel Durand (CADC), Peter Biereichel (ESO)


SkyCat is copyright by ESO, 1996. All rights reserved.

Send comments to malbrech@eso.org
Last modified: Thu Oct 1 20:26:01 MEST 1998
skycat-3.1.2-starlink-1b/skycat/install000077500000000000000000000042121215713201500200260ustar00rootroot00000000000000#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5; it is not part of GNU. # # $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" instcmd="$mvprog" chmodcmd="" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; *) if [ x"$src" = x ] then src=$1 else dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` fi # Make a temp file name in the proper directory. dstdir=`dirname $dst` dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp # and set any options; do chmod last to preserve setuid bits if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi # Now rename the file to the real destination. $doit $rmcmd $dst $doit $mvcmd $dsttmp $dst exit 0 skycat-3.1.2-starlink-1b/skycat/install.sh000077500000000000000000000042121215713201500204370ustar00rootroot00000000000000#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5; it is not part of GNU. # # $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" instcmd="$mvprog" chmodcmd="" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; *) if [ x"$src" = x ] then src=$1 else dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` fi # Make a temp file name in the proper directory. dstdir=`dirname $dst` dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp # and set any options; do chmod last to preserve setuid bits if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi # Now rename the file to the real destination. $doit $rmcmd $dst $doit $mvcmd $dsttmp $dst exit 0 skycat-3.1.2-starlink-1b/skycat/library/000077500000000000000000000000001215713201500200775ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/skycat/library/SkyCat.tcl000066400000000000000000000625731215713201500220160ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # "@(#) $Id: SkyCat.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # SkyCat.tcl - image display application class with catalog extensions # # This class defines a top level window for the skycat application. # # The easiest way to use this class is via the "startSkyCat" method # # See man page SkyCat(1) for a complete description. # # who when what # -------- --------- ---------------------------------------------- # pbiereic 11/12/08 config -file after SkyCat was fully constructed # A.Brighton 11 Oct 95 created # P.W.Draper 19 Jan 00 added concat to bindtags, itk ones were # being lost. Removed extra ] from ]] in title string. # 18 Nov 03 Now accepts a list of catalogues to display. # 04 Apr 06 Catch {wm deiconify $w_.init} as init window maybe # embedded in GAIA # set skycat_usage { Usage: skycat ?fitsFile? ?-option value ...? Options: -cat - Include ESO/Archive catalog extensions (default). -catalog \" \" - Open windows for the given catalogs on startup. -colorramp_height - height of colorramp window (default: 12). -float_panel - put info panel in a popup window (default: 0). -panel_layout - panel layout, one of: "saoimage", "reverse", "default" . -panel_orient - panel orientation, one of: "horizontal", "vertical" -pickobjectorient - orientation for pick object win: "horizontal", "vertical" -min_scale - minimum scale for magnification menu (default: -10). -max_scale - maximum scale for magnification menu (default: 20). -remote - Use existing skycat process, if available, with Tk send. -debug - debug flag: run bg processes in fg. -default_cmap - default colormap. -default_itt - default intensity transfer table. -file - fits file to load ('-' for stdin). -port - Listen for remote cmds on port (default: 0 = choose port). -rtd - Include ESO/VLT Real-Time Features. -scrollbars - Display scrollbars (not displayed by default). -shm_data - Put image data in sysV shared memory. -shm_header - Put image header in sysV shared memory. -usexshm - Use X shared mem, if available (default). -use_zoom_view - Use a "view" of the image for the zoom window (default). -verbose - Print diagnostic messages. -with_colorramp - Display the color bar (default). -with_warp - add bindings to move mouse ptr with arrow keys (default: 1). -with_grid - Include a WCS grid button (default: 0 = off). -with_pan_window - Display the pan window (default). -with_zoom_window - Display the zoom window (default). -zoom_factor - zooming factor (default: 4). } set about_skycat "\ Skycat version $skycat_version Copyright (C) 1996-2009 ESO - European Southern Observatory Please send any comments, suggestions or bug reports to: archive@eso.org " itk::usual SkyCat {} # This class defines a top level window for the skycat application. The # easiest way to create an instance this class is via the "startSkyCat" # proc. It sets up the environment, creates an instance of the class and # then waits for the application to exit. # # The SkyCat widget supports the same options as the Rtd widget, its # base class, and adds some of its own options. The widget options are # the same as the skycat command line options, since these are passed # unchanged to the widget. itcl::class skycat::SkyCat { inherit rtd::Rtd # constructor: create a toplevel window constructor {args} { eval itk_initialize $args if { "$itk_option(-panel_orient)" == "" } { config -panel_orient "vertical" } } # called after the options have been evaluated protected method init {} { global ::skycat_version Rtd::init load_toplevel_geometry wm title $w_ "Skycat - version $skycat_version ($itk_option(-number))" wm iconname $w_ feedback "catalog and help menu..." add_go_menu add_graphics_save_menu_item if {$itk_option(-cat)} { cat::AstroCat::add_catalog_menu \ $w_ [code $image_] ::skycat::SkySearch $itk_option(-debug) } if {"$itk_option(-dhshost)" != ""} { add_olaf_menu } add_help_menu if {[winfo exists $w_.init]} { # destroy init window destroy $w_.init # the logo uses up colors: the update forces the destroy and frees the colors update $itk_component(image) alloccolors 60 # Sometimes $w_.init is an embedded window. catch {wm deiconify $w_} } if {"$itk_option(-catalog)" != ""} { # make sure we use full path name for local catalogs # and process option as a list foreach f "$itk_option(-catalog)" { if {[file exists $f] && "[string index $f 0]" != "/"} { set $f [pwd]/$f } cat::AstroCat::open_catalog_window $f \ [code $image_] ::skycat::SkySearch $itk_option(-debug) $w_ } } # check the main window size to make sure it is not too large bind SkyCat::resize [code $this resize %w %h] bindtags $w_ [concat SkyCat::resize [bindtags $w_]] #bindtags $w_ SkyCat::resize after 0 [code $image_ config -file $itk_option(-file)] } # destructor - delete C++ based objects destructor { save_toplevel_geometry catch {$w_.cat delete} # kill any catalog windows referring to this image window foreach w [cat::AstroCat::instances all] { catch { if {"[$w cget -id]" == "[code $image_]"} { destroy $w } } } # remove this window from the list of skycat windows global ::skycat_images if {[info exists skycat_images]} { set tmp {} foreach w $skycat_images { if {[winfo exists $w] && "$w" != "$w_"} { lappend tmp $w } } set skycat_images $tmp } } # save the position of the top level window so we can reload it the next # time. protected method save_toplevel_geometry {} { set s [wm geometry $w_] # check for case where window was not initialized... if {"$s" != "1x1+0+0"} { if {[catch {set fd [::open $toplevel_geometry_ w]}]} { return } puts $fd $s ::close $fd } } # restore the position of the top level window from the previous session protected method load_toplevel_geometry {} { if {[catch {set fd [::open $toplevel_geometry_]}]} { return } catch {wm geometry $w_ [gets $fd]} ::close $fd } # Called when the main window is resized: # Check the geometry to make sure it fits on the screen. protected method resize {w h} { bind SkyCat::resize { } set sw [winfo screenwidth $w_] set sh [winfo screenheight $w_] if {$w > $sw || $h > $sh} { wm geometry $w_ "[min $w $sw]x[min $h $sh]+0+0" } } # Add the Real-time menubutton and menu, if the -rtd option was given. protected method add_realtime_menu {} { # add/remove some menus if {$itk_option(-rtd)} { Rtd::add_realtime_menu } else { # hide the realtime status #[[$itk_component(image) component info] component cameraStatus] config \ #-width 0 -height 0 } } # Add a "Go" menu with shortcuts to view images previously viewed protected method add_go_menu {} { set m [add_menubutton "Go" "Go: menu with shortcuts to view images previously viewed"] $m config -postcommand [code $image_ update_history_menu $this $m] } # Add a menu item to the Graphics menu for saving the line graphics in a FITS # table in the image. protected method add_graphics_save_menu_item {} { if {[catch {[$image_ get_image] hdu count} msg]} { # might be a plugin, such as GAIA that doesn't have the HDU features... return } set m [get_menu Graphics] $m add separator add_menuitem $m command "Save graphics with image" \ {Save line graphics in a FITS binary table in the image} \ -command [code $image_ save_graphics_with_image] } # set default X resources for colors and fonts, and set some default key # bindings. This method is called from the parent class and overridden here. # These are built-in defaults that the user can also override in the ~/.Xdefaults # file. protected method setXdefaults {} { # read rtd defaults Rtd::setXdefaults # read cat lib defaults cat::setXdefaults # read skycat defaults skycat::setXdefaults # since we know this method gets called early, this is a good place to # create window to display while starting up make_init_window } # add a menubutton with OLAF items protected method add_olaf_menu {} { set m [add_menubutton "OLAF" "OLAF menu: On-Line Archive Facility functions"] add_menuitem $m checkbutton "Subscribe to DHS on $itk_option(-dhshost)" \ {Subscribe/Unsubscribe to DHS images} \ -variable $w_.subscribe -onvalue 1 -offvalue 0 \ -command [code $image_ subscribe $w_.subscribe \ $itk_option(-dhshost) $itk_option(-dhsdata)] } # add a menubutton with help items protected method add_help_menu {} { set m [add_menubutton "Help" {} right] add_menuitem $m command "About Skycat..." \ {Display a window with information about this Skycat version} \ -command [code $itk_component(image) about] add_menuitem $m command "Help..." \ {Display information about Skycat in netscape (if netscape is available)} \ -command [code $itk_component(image) send_to_browser $itk_option(-help_url)] add_short_help $itk_component(menubar).help \ {Help menu: display information about this application} } # make a new main window (redefined from parent class) public method clone {} { global ::skycat_usage # use the -noop option to avoid reloading the main image (part of $argv list) after 0 [code util::TopLevelWidget::start skycat::SkyCat "-noop" "$skycat_usage"] } # create the rtd image widget with catalog extensions # (redefined from parent class to use class with catalog # features added) protected method make_rtdimage {} { set image_ $w_.image # SkyCatCtrl(n) widget (derived from RtdImageCtrl), for displaying # image and control panel itk_component add image { SkyCatCtrl $image_ \ -usexshm $itk_option(-usexshm) \ -shm_header $itk_option(-shm_header) \ -shm_data $itk_option(-shm_data) \ -drag_scroll $itk_option(-drag_scroll) \ -scrollbars $itk_option(-scrollbars) \ -verbose $itk_option(-verbose) \ -subsample $itk_option(-subsample) \ -use_zoom_view $itk_option(-use_zoom_view) \ -with_zoom_window $itk_option(-with_zoom_window) \ -with_pan_window $itk_option(-with_pan_window) \ -zoom_factor $itk_option(-zoom_factor) \ -colorramp_height $itk_option(-colorramp_height) \ -color_scale $itk_option(-color_scale) \ -default_cmap $itk_option(-default_cmap) \ -default_itt $itk_option(-default_itt) \ -with_colorramp $itk_option(-with_colorramp) \ -rapid_frame_command [code $this rapid_frame_command] \ -feedback [code $this feedback] \ -port $itk_option(-port) \ -shorthelpwin $this \ -debug $itk_option(-debug) \ -with_grid $itk_option(-with_grid) \ -with_warp 1 \ -regioncommand [code $this select_region] \ -float_panel $itk_option(-float_panel) \ -panel_layout $itk_option(-panel_layout) \ -panel_orient $itk_option(-panel_orient) \ -min_scale $itk_option(-min_scale) \ -max_scale $itk_option(-max_scale) \ -pickobjectorient $itk_option(-pickobjectorient) } # keep a list of skycat instances global ::skycat_images lappend skycat_images $itk_component(image) } # This method is called when a region of the image has been selected # (via -regioncommand option when creating image above). # The arguments are the bounding box of the region in canvas coords. # pass it on to any catalog windows to select any catalog symbols # in the region. protected method select_region {x0 y0 x1 y1} { foreach w [cat::AstroCat::instances] { $w select_region $x0 $y0 $x1 $y1 } } # display a window while the application is starting up protected method make_init_window {} { global ::about_skycat ::skycat_library set skycat_logo [image create photo -file $skycat_library/skycat-logo.xpm] set w [util::TopLevelWidget $w_.init -center 1] #catch {rtd_set_cmap $w} wm title $w " " wm withdraw $w_ pack \ [label $w.logo -image $skycat_logo \ -borderwidth 2 -relief groove] \ [message $w.msg -text $about_skycat \ -width 6i \ -justify center \ -borderwidth 2 -relief groove] \ [ProgressBar $w.progress \ -from 0 -to 10 -value 0 \ -borderwidth 2 -relief groove] \ -side top -fill x -padx 1m -pady 2m tkwait visibility $w } # this method is redefined here to get feedback during startup public method feedback {msg} { if {[winfo exists $w_.init.progress]} { $w_.init.progress config -text $msg -value [incr percent_done_] update idletasks } } # This method is called for the -remote option. If another skycat is running, # use it to display the image and exit, otherwise do it in this process. # Try Tk send, and if that fails, fall back on the RTD socket interface. protected method start_remote {} { global ::argc ::argv ::env set name [winfo name .] foreach interp [winfo interps] { if {"$interp" != "$name" && [string match "Skycat*" $interp]} { # command to eval in the remote skycat application set cmd [list skycat::SkyCat::remote_start $argc $argv] # try Tk send if {[catch {send $interp $cmd}]} { # failed: try rtd remote socket interface # (rtd creates the file below on startup with pid, host and port info) set file $env(HOME)/.rtd-remote if {[catch {set fd [open $env(HOME)/.rtd-remote]}]} { return } set s [gets $fd] close $fd set status 0 if {[scan $s {%d %s %d} pid host port] != 3} { return } if {[catch { # see if the process is still running exec kill -0 $pid set fd [server_connect -nobuf $host $port] }]} { return } if {[catch { # use the rtdimage "remotetcl" subcommand # (see rtd/rtdimg/src/RtdImage.C) puts $fd [list remotetcl $cmd] lassign [gets $fd] status length set result {} if {$length > 0} { set result [read $fd $length] } }]} { close $fd return } if {$status != 0} { return } } # looks like we were successful, so we can exit exit } } } # start the application with the above class as the main window # This proc is called from tkAppInit.c when we are running the single # binary version. # Note that the binary version doesn't need to set auto_path or look for # Tcl sources or colormaps at run-time, since they are already loaded in # the binary. public proc startSkyCat {} { global ::rtd_library ::skycat_library ::skycat_usage ::tk_strictMotif \ ::argv ::argc ::env # print errors also on stderr utilPrintErrors if {! [info exists rtd_library]} { set rtd_library . } # where to look for catalog config file: # use ~/.skycat/skycat.cfg if it exists, since it may contain user's # preferences, otherwise use $SKYCAT_CONFIG if set, or $CATLIB_CONFIG. set config_file $env(HOME)/.skycat/skycat.cfg if {[file exists $config_file]} { set env(CATLIB_CONFIG) "file:$config_file" } elseif {[info exists env(SKYCAT_CONFIG)]} { set env(CATLIB_CONFIG) $env(SKYCAT_CONFIG) } tk appname Skycat set tk_strictMotif 0 tk_focusFollowsMouse # insert some default options set argv [linsert $argv 0 -disp_image_icon 1] set argc [llength $argv] # specify a list of valid options (workaround for tcl or itcl bug (?) that # crashes app if option is unknown...) set optlist [list \ -cat \ -catalog \ -color_scale \ -colorramp_height \ -debug \ -default_cmap \ -default_itt \ -dhsdata \ -dhshost \ -disp_image_icon \ -drag_scroll \ -feedback \ -file \ -float_panel \ -help_url \ -max_scale \ -min_scale \ -panel_layout \ -panel_orient \ -pickobjectorient \ -port \ -rapid_frame_command \ -regioncommand \ -remote \ -rtd \ -scrollbars \ -shm_data \ -shm_header \ -shorthelpwin \ -subsample \ -use_zoom_view \ -usexshm \ -verbose \ -with_colorramp \ -with_grid \ -with_pan_window \ -with_warp 1 \ -with_zoom_window \ -zoom_factor \ ] # start the application util::TopLevelWidget::start skycat::SkyCat "-file" "$skycat_usage" "" 1 $optlist } # -- external interface via Tk send -- # This proc returns the instance name of the catalog (or image server) # widget # If more than one is open, it asks the user to select which one. # If it can't find one, it reports an error and returns "" public proc get_catalog {{what "catalog"}} { # get list of catalog windows if {"$what" == "catalog"} { set list [cat::AstroCat::instances] } else { set list [cat::AstroCat::instances imagesvr] } if {[llength $list] == 0} { error_dialog "There are no $what windows open" return } if {[llength $list] == 1} { return [lindex $list 0] } # need to choose which catalog set names {} set n 0 foreach w $list { lappend names "[incr n] [$w cget -catalog]" } set w [ChoiceDialog .d \ -text "Please specify which $what to use:" \ -cols 1 \ -messagewidth 3i \ -choice $names \ -value [lindex $names 0] \ ] set result [$w activate] if {"$result" == ""} { return } lassign $result n name incr n -1 return [lindex $list $n] } # This proc returns the instance name of the image server # widget # If more than one is open, it asks the user to select which one. # If it can't find one, it reports an error and returns "" public proc get_imagesvr {} { return [skycat::SkyCat::get_catalog "image server"] } # This proc can be called via send from another application to return the contents # of the catalog window as a Tcl list. # # The format of the return value is {{selected_row} {{row1} {row2} ...}} # where each row is a list of column values. The selected_row is empty if there is # no selection, otherwise it is a list of column values in the selected row. public proc get_catalog_info {} { if {"[set w [skycat::SkyCat::get_catalog]]" == ""} { return } set table [$w component results] return [list [lindex [$table get_selected] 0] [$table get_contents]] } # This proc can be called via send from another application to display an image # given the coordinates and a width and height in arcmin public proc display_image {ra dec width height {equinox 2000} {catalog "Digitized Sky at ESO"}} { global ::skycat_images set w [lindex $skycat_images 0] cat::AstroCat::open_catalog_window $catalog \ $w ::skycat::SkySearch 0 [winfo toplevel $w] update if {"[set w [get_imagesvr]]" == ""} { return } $w getimage_from_args $ra $dec {} $equinox $width $height } # This proc can be called via send from another application to display a catalog # given the catalog's name (long name or short name). public proc display_catalog {{catalog "Guide Star Catalog at ESO"}} { global ::skycat_images set w [lindex $skycat_images 0] cat::AstroCat::open_catalog_window $catalog \ $w ::skycat::SkySearch 0 [winfo toplevel $w] } # This proc can be called via send from another application to display a rectangle # on the image at the given center coords with the given width and height # and return the item's canvas tag or id public proc mark_image {ra dec width height} { global ::skycat_images #return [[winfo command [lindex $skycat_images 0]] mark_image $ra $dec $width $height] return [[lindex $skycat_images 0] mark_image $ra $dec $width $height] } # remove the given mark from the image (id returned from mark_image) public proc unmark_image {id} { global ::skycat_images # [winfo command [lindex $skycat_images 0]] unmark_image $id [lindex $skycat_images 0] unmark_image $id } # This proc can be called via send to load a fits image for viewing public proc load_image {filename} { global ::skycat_images #if {[catch {[winfo command [lindex $skycat_images 0]] config -file $filename} msg]} { # error_dialog $msg #} if {[catch {[lindex $skycat_images 0] config -file $filename} msg]} { error_dialog $msg } } # pop up a window, ask the user to select an object in the image, # wait for the selection and return the info for it in the form: # {$x $y $ra $dec $equinox $fwhmX $fwhmY $angle $object $background} # # An optional Tcl command may be specifed to be called whenever a new # object is selected. The command can include a "send ..." prefix to # call a proc in another application public proc pick_object {{cmd ""}} { global ::skycat_images set var [lindex $skycat_images 0].pick.picked global ::$var catch {unset $var} #if {[catch {[winfo command [lindex $skycat_images 0]] pick_dialog $cmd} msg]} { # error_dialog $msg # return #} if {[catch {[lindex $skycat_images 0] pick_dialog $cmd} msg]} { error_dialog $msg return } if {! [info exists $var]} { tkwait variable $var } return [set $var] } # return a list of SkyCatCtrl class instances in this process (there might be # multiple cloned instances...) public proc get_skycat_images {} { global ::skycat_images if {[info exists skycat_images]} { return $skycat_images } } # This proc is called via Tcl send from a remote skycat application when the # -remote option is used. The arguments are the argc and argv of the remote # skycat application. We extract the file and catalog arguments and ignore # the rest, since we are reusing the same window. public proc remote_start {ac av} { # get the image file option from the argv list set file {} set catalog {} for {set i 0} {$i < $ac} {incr i} { set opt [lindex $av $i] if {"[string index $opt 0]" == "-" && "$opt" != "-"} { set arg [lindex $av [incr i]] } else { set arg $opt set opt "-file" } if {"$opt" == "-file"} { set file $arg } elseif {"$opt" == "-catalog"} { set catalog $arg } } # open a new main window using the new arguments foreach w [get_skycat_images] { if {[winfo exists $w]} { if {"$file" != ""} { if {[file exists $file]} { $w configure -file $file } else { error_dialog "File does not exist: $file" return } } if {"$catalog" != ""} { # open a window for the given catalog cat::AstroCat::open_catalog_window $catalog \ $w ::skycat::SkySearch 0 [winfo toplevel $w] } return } } } # -- options -- # flag: if true, display the data-servers menu (catalog features) itk_option define -cat cat Cat 1 { if {$itk_option(-cat) != 0 && $itk_option(-cat) != 1} { set itk_option(-cat) 1 puts "The -cat option requires a value of 1 (true) or 0 (false)" exit 1 } } # flag: if true, display the real-time menu (VLT features) itk_option define -rtd rtd Rtd 0 { if {$itk_option(-rtd) != 0 && $itk_option(-rtd) != 1} { set itk_option(-rtd) 1 puts "The -rtd option requires a value of 1 (true) or 0 (false)" exit 1 } } # Specify a catalog (may be a local file) to load on startup itk_option define -catalog catalog Catalog {} # For OLAF (On-Line Archive Facility): name of DHS host machine itk_option define -dhshost dhshost DhsHost {} # directory used to hold image files from OLAF/DHS itk_option define -dhsdata dhsdata DhsData {} # url to use for the help menu - link to skycat WWW page itk_option define -help_url help_url Help_url {http://archive.eso.org/skycat} # if another skycat application is running on this display, use # it rather than this process (saves memory and colors in the colormap). itk_option define -remote remote Remote 0 { if {"$itk_option(-remote)" == "1"} { start_remote } } # -- protected variables -- # used in startup dialog protected variable percent_done_ 0 # name of the file used to save the positions of the top level windows global ::env protected common toplevel_geometry_ $env(HOME)/.skycat/geometry } # The following procs are now member procs of the SkyCat class, but are # defined here as wrappers for backward compatibility. See the member procs # above for the definitions. proc startSkyCat {} { skycat::SkyCat::startSkyCat } proc get_catalog {{what "catalog"}} { return [skycat::SkyCat::get_catalog $what] } proc get_imagesvr {} { return [skycat::SkyCat::get_imagesvr] } proc get_catalog_info {} { return [skycat::SkyCat::get_catalog_info] } proc display_image {ra dec width height {equinox 2000} {catalog "Digitized Sky at ESO"}} { return [skycat::SkyCat::display_image $ra $dec $width $height $equinox $catalog] } proc display_catalog {{catalog "Guide Star Catalog at ESO"}} { return [skycat::SkyCat::display_catalog $catalog] } proc mark_image {ra dec width height} { return [skycat::SkyCat::mark_image $ra $dec $width $height] } proc unmark_image {id} { return [skycat::SkyCat::unmark_image $id] } proc load_image {filename} { return [skycat::SkyCat::load_image $filename] } proc pick_object {{cmd ""}} { return [skycat::SkyCat::pick_object $cmd] } proc get_skycat_images {} { return [skycat::SkyCat::get_skycat_images] } skycat-3.1.2-starlink-1b/skycat/library/SkyCatCtrl.tcl000066400000000000000000000462561215713201500226430ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: SkyCatCtrl.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # SkyCatCtrl.tcl - image display widget with catalog extensions # # See man page SkyCatCtrl(1) for a complete description. # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 11 Oct 95 created itk::usual SkyCatCtrl {} # This class extends the RtdImageCtrl class (see RtdImageCtrl(n)) by # adding image catalog extensions and user interface dialogs for use # with astronomical catalogs. itcl::class skycat::SkyCatCtrl { inherit rtd::RtdImageCtrl # constructor constructor {args} { eval itk_initialize $args } # destructor destructor { catch {kill $subscribe_pid_} } # this method is called from the base class (TopLevelWidget) after all # the options have been evaluated protected method init {} { RtdImageCtrl::init # make sure at least an empty history catalog is created add_history {} } # display the skycat logo in the center of the image window # with some copywrite text # Note that we assume here that the logo was created previously # and the name of the image is in the global var skycat_logo. protected method display_logo {} { global ::about_skycat ::skycat_library set skycat_logo [image create photo -file $skycat_library/skycat-logo.xpm] # center logo $canvas_ config -scrollregion "0 0 1 1" $canvas_ create image 0 0 \ -image $skycat_logo \ -tags "objects logo logo_image" \ -anchor c # place text under logo lassign [$canvas_ bbox logo_image] x0 y0 x1 y1 set y0 $y1 set iw [expr $x1-$x0] set ih [expr $y1-$y0] set x [expr ($x0+$x1)/2] set y [expr $y1+10] $canvas_ create text $x $y \ -tags "objects logo logo_text" \ -justify center \ -anchor n \ -fill lightblue \ -font -Adobe-Helvetica-Bold-R-Normal--*-120-*-*-*-*-*-* \ -text $about_skycat # center the whole thing lassign [$canvas_ bbox logo] x0 y0 x1 y1 set w [expr $x1-$x0] set h [expr $y1-$y0] $canvas_ move logo 0 [expr -($h/2-$ih/2)] # clicking in it deletes it $canvas_ bind logo <1> "$canvas_ delete logo" } # display a popup window with information about this application public method about {} { global ::about_skycat ::skycat_library set skycat_logo [image create photo -file $skycat_library/skycat-logo.xpm] DialogWidget $w_.about \ -image $skycat_logo \ -messagewidth 6i \ -justify center \ -text $about_skycat $w_.about activate } # send a URL to be displayed by a web browser (firefox, mozila, netscape) public method send_to_browser {url} { if {"[exec uname]" == "Darwin"} { if {[catch {exec open $url}]} { warning_dialog "Could not open $url" } } elseif {[catch {exec firefox $url &}]} { if {[catch {exec mozilla $url &}]} { if {[catch {exec netscape $url &}]} { warning_dialog "Could not start web browser to view $url" } } } } # This method is called by the image code whenever a new image is loaded. protected method new_image_cmd {} { RtdImageCtrl::new_image_cmd # check for saved line graphics after idle [code $this load_graphics_from_image] # delete temp files once they are loaded # PWD: let's not GAIA relies of access to the image for other reasons # (like the various toolboxes and catalogue access). These images # should be deleted by AstroCat. #set filename [$image_ cget -file] #if {[string match {/tmp/cat[0-9]*} $filename]} { # catch {file delete $filename} #} } # display a popup window listing the HDUs in the current image, if any public method display_fits_hdus {} { if {[catch {set n [$image_ hdu count]}]} { set n 0 } if {$n <= 1} { warning_dialog "There are no FITS extensions" $w_ return } utilReUseWidget skycat::SkyCatHduChooser $w_.hdu \ -image $this \ -shorthelpwin $itk_option(-shorthelpwin) \ -usexshm $itk_option(-usexshm) \ -usexsync $itk_option(-usexsync) \ -verbose $itk_option(-verbose) } # update the toplevel window header and icon name to include the name # of the file being displayed protected method update_title {} { global ::skycat_version set file "[file tail $itk_option(-file)]" set w [winfo toplevel $w_] wm title $w "Skycat - version $skycat_version: $file ([$w cget -number])" wm iconname $w $file } # If the current image is not saved in a file (came from a server, ...) # check if it should be saved before loading a new image. Then, if the # file exists, add image info for it to the history catalog. protected method check_save {} { if {"$filename_" != ""} { if {! [file exists $filename_] && ! [$image_ isclear]} { # XXX this doesn't always work as expected... # #set s [choice_dialog \ # "Do you want to save the current image to a file\ # and add it to the history list first before loading\ # a new one?" \ # {Yes No} \ # {No} \ # $w_] #if {"$s" == "Yes"} { # save_as #} else { # don't add to history set filename_ $itk_option(-file) return #} } add_history $filename_ } # set the new file name set filename_ $itk_option(-file) } # This method is redefined here from the base class to include the # file name in the window header and note the filename. protected method load_fits_ {} { check_save RtdImage::load_fits_ update_title apply_history $itk_option(-file) component colorramp update_colors } # Save the current image or a section of the current image to a file in # FITS format chosen from a file name dialog. If dir and pattern are specified, # they are used as defaults for the file selection dialog. # If x0, y0, x1 and y1 are specified (canvas coordinates), then a section # of the image is saved. # # The return value is the name of the new file, if any, or an empty string. # (redefined from parent class to set filename_, used in check_save). public method save_as {{dir "."} {pattern "*"} {x0 ""} {y0 ""} {x1 ""} {y1 ""}} { set file [RtdImage::save_as $dir $pattern $x0 $y0 $x1 $y1] if {"$x0" == ""} { set filename_ $file } return $file } # convert the given coordinates from $from_units to $to_units and return # the result. $coords may be a list of an even number of values # {x1 y1 x2 y2 x3 y3 ...}. The result is the same list, converted to the # output coordinates. public method convert_coords {coords from_units to_units} { set result {} set len [llength $coords] for {set i 0} {$i < $len} {incr i 2} { set ix [lindex $coords $i] set iy [lindex $coords [expr $i+1]] $image_ convert coords $ix $iy $from_units x y $to_units lappend result $x $y } return $result } # Save the current line graphics in a FITS binary table in the image. # The table has 3 columns: "type", "coords", and "config". # "type" gives the shape and is one of the Tk canvas item types. # "coords" is a list of coordinates for the item. # "config" is a Tcl list of configuration options for the item. # There can be one graphics table for each image extension. For each # image extension, the graphics table is called "${extname}.GRAPHICS". public method save_graphics_with_image {} { busy { save_graphics_with_image_ } } public method save_graphics_with_image_ {} { # deselect any objects $w_.draw deselect_objects # table headings set headings {type coords config} # table data set info {} # max table column widths set width(type) 0 set width(coords) 0 set width(config) 0 # loop through the canvas items foreach item [$canvas_ find all] { set type [$canvas_ type $item] if {"$type" == "image"} { continue } # get item coords and convert from canvas to image coords set coords [convert_coords [$canvas_ coords $item] canvas image] # add a special tag to this item so we can delete it before reloading it $canvas_ addtag "graphics" withtag $item # get list of configuration options for the item set config {} foreach cfg [$canvas_ itemconfigure $item] { lappend config [list [lindex $cfg 0] [lindex $cfg 4]] } set width(type) [max $width(type) [string length $type]] set width(coords) [max $width(coords) [string length $coords]] set width(config) [max $width(config) [string length $config]] lappend info [list $type $coords $config] } # set table column formats (FITS style: 16A, for char[16], etc...) set tform "$width(type)A $width(coords)A $width(config)A" set listheadings [$image_ hdu listheadings] set hdu_list [$image_ hdu list] set extname [$image_ fits get EXTNAME] set table "${extname}.GRAPHICS" # Look for an existing graphics table and delete it, so we can # replace it with a new one foreach row $hdu_list { eval lassign [list $row] $listheadings if {"$ExtName" == "$table"} { $image_ hdu delete $HDU break } } # create a new binary table and insert the info if {[catch { $image_ hdu create binary $table $headings $tform $info } msg]} { error_dialog "error creating FITS table '$table': $msg" return } # update and display the HDU window update_fits_hdus } # Check if there is a FITS table with the same name as the current # image extension, but with ".GRAPHICS" appended. # If found, restore the previously saved line graphics from the table. # This method is called automatically when a new image extension is # loaded. public method load_graphics_from_image {} { busy { load_graphics_from_image_ } } public method load_graphics_from_image_ {} { # only do this for image extensions if {[catch {set type [$image_ hdu type]}]} { return } if {"$type" != "image"} { return } # get the name of the graphics table set extname [$image_ fits get EXTNAME] set name "${extname}.GRAPHICS" # get the hdu set headings [$image_ hdu listheadings] if {[catch {set hdu_list [$image_ hdu list]}]} { # avoid problem when image and header are in separate files... return } set hdu 0 foreach i $hdu_list { eval lassign [list $i] $headings if {"$ExtName" == "$name"} { set hdu $HDU break } } if {$hdu == 0} { return } # make sure we don't create 2 of each object $canvas_ delete "graphics" # Now we have the hdu number of the graphics table. Read it and # restore the graphics set headings {type coords config} foreach row [$image_ hdu get $hdu] { eval lassign [list $row] $headings # convert from image to canvas coords if {[catch {set coords [convert_coords $coords image canvas]} msg]} { puts $msg continue } set id [eval $canvas_ create $type $coords] foreach cfg $config { lassign $cfg opt arg $canvas_ itemconfigure $id $opt $arg } # add bindings so that the items may be edited and saved again $w_.draw add_object_bindings $id } } # Add the current image to the history catalog under the given filename. # The current FITS header is used to extract information about the image # to put in the catalog. The file basename is assumed to be the unique id. public method add_history {filename} { skycat::SkySearch::add_history $this $filename if {"$filename" != "" && [file exists $filename]} { lappend back_list_ $filename } } # Check if the given filename is in the history catalog, and if so, # apply the cut levels and color settings for the file. public method apply_history {filename} { skycat::SkySearch::apply_history $this $filename } # Update the given menu with image history items. $w is the TopLevelWidget # containing the menubar public method update_history_menu {w m} { $m delete 0 end $w add_menuitem $m command "Back" \ {Go back again to the previous image} \ -command [code $w busy "$this previous_image"] \ -state disabled if {[llength $back_list_]} { $m entryconfig Back -state normal } $w add_menuitem $m command "Forward" \ {Go forward again to the next image} \ -command [code $w busy "$this forward_image"] \ -state disabled if {[llength $forward_list_]} { $m entryconfig Forward -state normal } $m add separator skycat::SkySearch::add_history_menu_items $w $this $m 20 } # go back to the previous image public method previous_image {} { while {[set n [llength $back_list_]]} { set filename [lindex $back_list_ end] if {"$filename" != "$itk_option(-file)" && [file exists $filename]} { lappend forward_list_ $itk_option(-file) configure -file $filename set back_list_ [lrange $back_list_ 0 [expr $n-2]] break } set back_list_ [lrange $back_list_ 0 [expr $n-2]] } } # go forward again to the next image public method forward_image {} { while {[set n [llength $forward_list_]]} { set filename [lindex $forward_list_ end] if {"$filename" != "$itk_option(-file)" && [file exists $filename]} { configure -file $filename set forward_list_ [lrange $forward_list_ 0 [expr $n-2]] break } set forward_list_ [lrange $forward_list_ 0 [expr $n-2]] } } # This method is also redefined from the parent class to set the window # header info public method clear {} { check_save set filename_ {} RtdImageCtrl::clear update_title } # subscribe to (or unsubscribe from) the OLAF DHS server images # (ESO/Archive On-Line Archive Facility project: use the -dhshost and # -dhsdata options to add this feature.) # The first argument is the name of the trace variable used in the checkbutton menuitem. # dhshost is the name of the host running the DHS server, to which we subscribe. # dhsdata is the directory to use to hold the images files (temporary files). public method subscribe {variable dhshost dhsdata} { global ::$variable catch {exec kill $subscribe_pid_} if {[set $variable]} { # subscribe set port [$image_ remote] if {[catch {set subscribe_pid_ \ [exec rtdSubscribe \ -rtdport $port \ -dhshost $dhshost \ -dhsdata $dhsdata \ -logpath /tmp >& /dev/null &] \ } msg]} { error_dialog "Couldn't exec rtdSubscribe: $msg" } # try to handle errors written to stderr #set subscribe_fd_ [::open "| tail -f $subscribe_tmpfile_"] #fileevent $subscribe_fd_ readable [code $this rtdSubscribeError $subscribe_fd_] } } # display a rectangle on the image at the given center coords # with the given width and height and return the items tag or id. public method mark_image {ra dec width height} { # get radius from width and height set a $width/2.0 set radw [expr sqrt(2.0*$a*$a)] set a $height/2.0 set radh [expr sqrt(2.0*$a*$a)] # combine 2 square boxes to get the rectangle lassign [$image_ radecbox $ra $dec $radw] wr0 wd0 wr1 wd1 lassign [$image_ radecbox $ra $dec $radh] hr0 hd0 hr1 hd1 set eq [$image_ wcsequinox] if {[catch { $image_ convert coords $wr0 $hd0 "wcs $eq" x0 y0 canvas $image_ convert coords $wr1 $hd1 "wcs $eq" x1 y1 canvas } msg]} { error_dialog $msg $w_ return } set id [$canvas_ create rectangle \ $x0 $y0 $x1 $y1 \ -width 2 \ -tags objects \ -fill yellow \ -outline white \ -stipple pat6] $itk_component(draw) add_object_bindings $id return $id } # remove the given mark from the image public method unmark_image {id} { $canvas_ delete $id } # Ask the user to select an area of the image by dragging out a region # and return as a result a list of the form {x0 y0 x1 y1} in pixels. public method select_area {{shape rectangle}} { if {[$image_ isclear]} { warning_dialog "No image is currently loaded" $w_ return } # if {[action_dialog \ # "Please select and drag out a region of the image with mouse button 1" \ # $w_]} global ::$w_.select_area set $w_.select_area {} $itk_component(draw) set_drawing_mode $shape [code $this selected_area] tkwait variable $w_.select_area return [set $w_.select_area] } # This method is called when the user has selected an area of the image. # The results are in canvas coordinates, clipped to the area of the image. public method selected_area {id x0 y0 x1 y1} { global ::$w_.select_area # make sure the coordinates don't go off the image if {"$x0" != ""} { set w [$image_ width] $image_ convert coords $x0 $y0 canvas x0 y0 image $image_ convert coords $x1 $y1 canvas x1 y1 image foreach i {x0 y0 x1 y1} { set v [set $i] if {$v < 1} { set $i 1 } elseif {$v > $w} { set $i $w } } $image_ convert coords $x0 $y0 image x0 y0 canvas $image_ convert coords $x1 $y1 image x1 y1 canvas } set $w_.select_area "$x0 $y0 $x1 $y1" after 0 [code $w_.draw delete_object $id] } # Draw a symbol on the image with the given shape at the given coordinates # (in the given x,y units), with the given radius (in radius_units), # bg and fg color, canvas tags list, x/y ratio and rotation angle. # # shape may be one of "circle", "square", "plus", "cross", "triangle", # "diamond", "ellipse", "compass", "line", "arrow". # # x and y are the coordinates in "xy_units", which is one of the units # accepted by the Rtd commands (canvas, image, screen, "wcs $equinox", # "deg $equinox"). # # The radius value is interpreted in radius_units. # # bg and fg are X color names for the symbol (may be the same). # # symbol_tags should be a Tcl list of canvas tags for the symbol. # # ratio and angle are optional and used to stretch/shrink and # rotate the symbol. The default ratio is 1, default angle 0. # # label is an optional text for a label to place near the symbol. # # label_tags should be a Tcl list of canvas tags for the label, or # an empty or null string, if there is no label. # # Returns an error if the coordinates or part of the symbol are off # the image. # # Uses world coordinates, if available, for the rotation and orientation, # for symbols that support it (i.e.: rotation is relative to WCS north). public method draw_symbol {shape x y xy_units radius radius_units bg fg symbol_tags {ratio 1} {angle 0} {label ""} {label_tags ""}} { $image_ symbol $shape $x $y $xy_units $radius $radius_units \ $bg $fg $symbol_tags $ratio $angle $label $label_tags } # -- options -- # flag: if true, run queries in the foreground for better debugging itk_option define -debug debug Debug 0 # see parent class for other options... # -- protected variables -- # pid of rtdSubscribe process (OLAF) protected variable subscribe_pid_ {} # const PI protected variable pi_ 3.14159265358979323846 # const PI/180. protected variable rad_ [expr 3.14159265358979323846/180.] # the name of the image file, if any protected variable filename_ {} # used for the Go=>Back/Forward menu itemes protected variable back_list_ {} protected variable forward_list_ {} } skycat-3.1.2-starlink-1b/skycat/library/SkyCatHduChooser.tcl000066400000000000000000000061461215713201500237740ustar00rootroot00000000000000# E.S.O. - VLT project # "@(#) $Id: SkyCatHduChooser.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # SkyCatHduChooser.tcl - Itcl widget for displaying FITS extensions # # See man page SkyCatHduChooser(n) for a complete description. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 09/11/98 Created itk::usual SkyCatHduChooser {} # This class defines a widget for displaying the HDUs in the current FITS # image. The user can select a FITS table or image extension to display # by clicking on an entry the list or on one of the small images displayed # in a table. itcl::class skycat::SkyCatHduChooser { inherit rtd::RtdImageHduChooser # constructor: create a toplevel window constructor {args} { eval itk_initialize $args } # Display the current FITS table protected method display_fits_table {name hdu} { # build the name from the catalog name and the file base name set file [file tail [file rootname [$image_ cget -file]]] if {[string first "$file-" $name] == 0} { set filename /tmp/$name } else { set filename "/tmp/$file-$name" } # get the catalog config entry from the $catinfo table set entry [get_config_entry_from_fits_table $name $filename] # copy the FITS table to a temporary local catalog if {[catch {$image_ hdu get $hdu $filename $entry} msg]} { error_dialog $msg return } # display the catalog cat::AstroCat::new_catalog $filename $itk_option(-image) ::skycat::SkySearch } # Return the catalog config entry for the named FITS table, if # available, or a default entry. If the current FITS file contains # an HDU named $catinfo, with an entry for the named catalog ($extname), # then extract and return that entry as a Tcl keyed list. protected method get_config_entry_from_fits_table {extname filename} { set headings [$image_ hdu listheadings] # the first part of the catalog config entry is always the same set entry {} lappend entry [list serv_type local] lappend entry [list short_name $extname] lappend entry [list long_name $extname] lappend entry [list url $filename] foreach row [$itk_component(table) cget -info] { eval lassign [list $row] $headings if {"$ExtName" == "$catinfo"} { # found table set headings [$image_ hdu headings $HDU] foreach row [$image_ hdu get $HDU] { eval lassign [list $row] $headings if {"$SHORT_NAME" == "$extname"} { # found entry foreach key $headings { set value [set $key] set key [string tolower $key] if {"[string trim $value]" != ""} { lappend entry [list $key $value] } } return $entry } } break } } # no entry found, use default (no plotting) foreach i {id_col ra_col dec_col x_col y_col} { lappend entry [list $i -1] } return $entry } # -- options -- # name of the FITS table containing catalog config info public variable catinfo "CATINFO" # -- protected vars -- # C++ astrocat object use here to access catalog entries common astrocat_ [astrocat ::cat::.cataloginfo] } skycat-3.1.2-starlink-1b/skycat/library/SkyQuery.tcl000066400000000000000000000165571215713201500224150ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # @(#) $Id: SkyQuery.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # SkyQuery.tcl - Widget for searching catalogs and plotting the results in an image. # # See man page SkyQuery(n) for a complete description. # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 6 Jan 98 created itk::usual SkyQuery {} # A SkyQuery widget is a frame containing entries for search # options (inherited from class AstroQuery) with added support # for plotting objects in an image. itcl::class skycat::SkyQuery { inherit cat::AstroQuery # constructor constructor {args} { eval itk_initialize $args } # add (or update) the search options panel # (redefined from parent class AstroCat to add buttons) protected method add_search_options {} { AstroQuery::add_search_options if {[$astrocat iswcs] || [$astrocat ispix]} { frame $search_opts_.buttons pack \ [set setfromimg \ [button $search_opts_.buttons.setfromimg \ -text "Set From Image" \ -command [code $this set_from_image]]] \ [set selectarea \ [button $search_opts_.buttons.selectarea \ -text "Select Area..." \ -command [code $this select_area]]] \ -side right -padx 1m -pady 2m if {$iscat_} { # put it on the same row with the last entry: "Max Objects" incr search_opts_row_ -1 } add_search_option {} $search_opts_.buttons add_short_help $setfromimg {Set default values from the current image} add_short_help $selectarea \ {Select and drag out a region of the image with mouse button 1} } } # Set the default search values to the center position and radius of the image, # (for catalogs) of width and height of image (for image servers). public method set_from_image {} { if {$iscat_} { set_pos_radius [get_image_center_radius [$astrocat iswcs]] } else { set_pos_width_height [get_image_center_width_height [$astrocat iswcs]] } } # return a list of values indicating the center coordinates and radius # of the current image. # If wcs_flag is 1, the return list is {ra dec equinox radius-in-arcmin}, # otherwise {x y radius-in-pixels}. If no image is loaded, an empty # string is returned. public method get_image_center_radius {wcs_flag} { if {[$image_ isclear]} { return } if {$wcs_flag} { # using world coords set center [$image_ wcscenter] if {[llength $center] >= 2} { lassign $center ra dec equinox set radius [format "%.2f" [$image_ wcsradius]] if {$radius} { return [list $ra $dec $equinox $radius] } } } else { # using image coords set w [$image_ width] set h [$image_ height] set x [format "%.2f" [expr $w/2.]] set y [format "%.2f" [expr $h/2.]] set radius [format "%.2f" [expr sqrt($x*$x+$y*$y)/2.]] return [list $x $y $radius] } } # return a list of values indicating the center coordinates and the # width and height of the current image. # If wcs_flag is 1, the return list is {ra dec equinox width height}, # width and height in arcmin, # otherwise {x y width height} in pixels. If no image is loaded, an empty # string is returned. public method get_image_center_width_height {wcs_flag} { if {[$image_ isclear]} { return } if {$wcs_flag} { # using world coords set center [$image_ wcscenter] if {[llength $center] >= 2} { lassign $center ra dec equinox set width [$image_ wcswidth] set height [$image_ wcsheight] return [list $ra $dec $equinox $width $height] } } else { # using image coords set w [$image_ width] set h [$image_ height] set x [format "%.2f" [expr $w/2.]] set y [format "%.2f" [expr $h/2.]] set width [$image_ width] set height [$image_ height] return [list $x $y $width $height] } } # Ask the user to select an area to search interactively # and insert the resulting radius and center pos in the # catalog window. public method select_area {} { if {$iscat_} { set_pos_radius [select_image_area [$astrocat iswcs]] } else { set_pos_width_height [select_image_area [$astrocat iswcs]] } } # convert the given input coordinates in the given input units to the # given output units and return a list {x y} with the new values. # The units may be one of {canvas image wcs deg "wcs $equinox", "deg $equinox"} public method convert_coords {in_x in_y in_units out_units} { return [$image_ convert coords $in_x $in_y $in_units {} {} $out_units] } # Ask the user to select an area of the image by dragging out a region # on the image return the resulting center pos and radius as a list of # {x y radius-pixels}, or {ra dec equinox radius-in-arcmin} if wcs_flag # is 1. If we are dealing with an image server, the radius value is replaced # by width and height, i.e.: {ra dec equinox width height}, where width and # height are in arcmin for wcs or pixels otherwise. # An empty string is returned if there is no image or the user cancels # the operation. public method select_image_area {wcs_flag} { if {"$image_" == ""} { return } if {[$image_ isclear]} { error_dialog "No image is currently loaded" return } # get canvas coords of selected area set list [$skycat select_area] if {[llength $list] != 4} { return } lassign $list x0 y0 x1 y1 # get center and radius in canvas coords set x [expr ($x0+$x1)/2.] set y [expr ($y0+$y1)/2.] if {$wcs_flag} { # using world coords set equinox [get_catalog_equinox] if {[catch { lassign [convert_coords $x $y canvas "wcs $equinox"] ra dec } msg]} { error_dialog "error converting canvas ($x, $y) to world coordinates: $msg" $w_ return } if {$iscat_} { set radius [expr [$image_ wcsdist $x0 $y0 $x $y]/60.] return [list $ra $dec $equinox $radius] } else { set width [expr [$image_ wcsdist $x0 $y0 $x1 $y0]/60.] set height [expr [$image_ wcsdist $x0 $y0 $x0 $y1]/60.] return [list $ra $dec $equinox $width $height] } } else { # using image coords if {[catch { lassign [convert_coords $x $y canvas image] xi yi } msg]} { error_dialog "error converting canvas ($x, $y) to world coordinates: $msg" $w_ return } if {[catch { lassign [convert_coords $x0 $y0 canvas image] xi0 yi0 } msg]} { error_dialog "error converting canvas ($x0, $y0) to world coordinates: $msg" $w_ return } if {[catch { lassign [convert_coords $x1 $y1 canvas image] xi1 yi1 } msg]} { error_dialog "error converting canvas ($x1, $y1) to world coordinates: $msg" $w_ return } set w [expr abs($xi1-$xi0)] set h [expr abs($yi1-$yi0)] if {$iscat_} { set radius [expr sqrt($w*$w+$h*$h)/2.] return [list $x $y $radius] } else { return [list $x $y $w $h] } } } # Set the default values for the search panel entries: # (redefined from parent class AstroCat to set values from the image) public method set_default_values {} { AstroQuery::set_default_values set_from_image } # -- public variables -- # name of SkyCat itcl widget public variable skycat {} { if {"$skycat" != ""} { set image_ [$skycat get_image] } } # -- protected members -- # internal rtdimage image for main image protected variable image_ {} } skycat-3.1.2-starlink-1b/skycat/library/SkyQueryResult.tcl000066400000000000000000000157061215713201500236070ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # @(#) $Id: SkyQueryResult.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # SkyQueryResult.tcl - Widget for viewing query results with skycat image support. # # See man page SkyQueryResult(n) for a complete description. # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 5 Jan 98 created # A SkyQueryResult widget is defined as a QueryResult (see cat package) # with some added support for skycat image access, used for selecting objects # to add to a local catalog. itcl::class skycat::SkyQueryResult { inherit cat::QueryResult # constructor constructor {args} { eval itk_initialize $args } # pop up a dialog to enter the data for a new object for a local catalog # The command is evaluated after the users enters the new data. # (redefined from parent class to add image support) public method enter_new_object {{command ""}} { catch {delete object $w_.ef} EnterObject $w_.ef \ -title {Please enter the data for the object below:} \ -labels $headings_ \ -center 0 \ -image $skycat \ -command [code $this enter_object $command] } # pop up a window so that the user can edit the selected object(s) # The optional command is evaluated with no args if the object is # changed. # (redefined from parent class AstroCat to add image support) public method edit_selected_object {{command ""}} { catch {destroy $w_.ef} set values [lindex [get_selected] 0] if {[llength $values] == 0} { error_dialog "No rows are selected" $w_ return; } EnterObject $w_.ef \ -title {Please enter the data for the object below:} \ -image $skycat \ -labels $headings_ \ -values $values \ -command [code $this enter_object $command] } # save the current data as a FITS table in the current image file. # The argument is the catalog config entry. public method save_with_image {entry} { set image [$skycat get_image] # make sure file exists set file [$image cget -file] set suffix [file extension $file] switch -exact -- "$suffix" { ".gz" - ".gzfits" - ".gfits" - ".Z" - ".cfits" - ".hfits" { error_dialog "Can't save catalog data to compressed image file." return } } set headings [$image hdu listheadings] # get the short name of the catalog and use it as the table name set extname "" foreach i $entry { lassign $i key value if {"$key" == "short_name"} { set extname $value break } } # build the name from the catalog name and the file base name set file [file tail [file rootname $file]] if {[string first "$file-" $extname] == 0} { set extname [string range $extname [expr [string length $file]+1] end] } if {"$extname" == ""} { set extname [input_dialog "Please enter a name for the FITS table"] } if {"$extname" == ""} { return } # use all ASCII formats (use inherited size_ array) set tform {} if {$num_cols_ <= 1} { error_dialog "No data to save" return } if {! [info exists size_]} { error_dialog "No column size info" return } for {set i 1} {$i <= $num_cols_} {incr i} { lappend tform "$size_($i)A" } # If there is aleady a table by this name in the file, delete it # and replace it with the new one. set hdu_list [$image hdu list] foreach hdu $hdu_list { eval lassign [list $hdu] $headings if {"$extname" == "$ExtName"} { if {[catch {$image hdu delete $HDU} msg]} { error_dialog $msg } } } # save the current HDU number and restore it before returning set saved_hdu [$image hdu] # create a new binary table if {[catch { $image hdu create binary $extname $headings_ $tform $info_ } msg]} { error_dialog "error creating FITS table '$extname': $msg" return } # create/update catalog config info to a special FITS table if {[catch { save_config_info_to_fits_table $extname $entry } msg]} { after idle [list error_dialog $msg] } # restore saved HDU set numHDUs [$image hdu count] if {$saved_hdu <= $numHDUs} { $image hdu $saved_hdu } else { # shouldn't happen, but if the HDU was deleted, use the new last one $image hdu $numHDUs } # update/display the HDU window $skycat update_fits_hdus } # Save the given catalog config entry in a FITS table with the name # $catinfo. The hdu arg gives the HDU number of the $catinfo table, # or 0 if it does not exist. protected method save_config_info_to_fits_table {extname entry} { set image [$skycat get_image] # Look for an existing $catinfo table set headings [$image hdu listheadings] set hdu_list [$image hdu list] set hdu 0 foreach row $hdu_list { eval lassign [list $row] $headings if {"$ExtName" == "$catinfo"} { set hdu $HDU break } } # If the table exists, get the data and remove it, so that # we can recreate it, with possibly new columns or column # widths set rowNum 0 if {$hdu} { if {[catch { set headings [$image hdu headings $hdu] set info [$image hdu get $hdu] $image hdu delete $hdu } msg]} { error_dialog $msg return } # scan the current info, allow for future additions to headings foreach row $info { eval lassign [list $row] $headings foreach i $headings { set ar($rowNum,$i) [set $i] } if {"$SHORT_NAME" == "$extname"} { # replace this entry with the new one continue } incr rowNum } } # set headings for catalog config table set headings "SHORT_NAME ID_COL RA_COL DEC_COL X_COL Y_COL EQUINOX SYMBOL \ SEARCH_COLS SORT_COLS SORT_ORDER SHOW_COLS HELP COPYRIGHT" # initialize min column widths foreach i $headings { set width($i) 1 } # get values from config entry foreach i $entry { lassign $i key value if {"$key" == "symbol" || "$key" == "search_cols"} { # special treatment needed here (see CatalogInfo.tcl) set value [join $value " : "] } set ar($rowNum,[string toupper $key]) $value } set ar($rowNum,SHORT_NAME) $extname # build table data list and get max col widths for FITS formats set info {} set numRows [incr rowNum] for {set rowNum 0} {$rowNum < $numRows} {incr rowNum} { set row {} foreach i $headings { if {[info exists ar($rowNum,$i)]} { lappend row $ar($rowNum,$i) set width($i) [max $width($i) [string length $ar($rowNum,$i)]] } else { lappend row {} } } lappend info $row } # build the tform argument set tform {} foreach i $headings { lappend tform "$width($i)A" } # create a new binary table and insert the info if {[catch { $image hdu create binary $catinfo $headings $tform $info } msg]} { error_dialog "error creating FITS table '$catinfo': $msg" return } } # -- public variables -- # name of SkyCatCtrl itcl widget public variable skycat {} # name of the FITS table containing catalog config info public variable catinfo "CATINFO" } skycat-3.1.2-starlink-1b/skycat/library/SkySearch.tcl000066400000000000000000000577501215713201500225150ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # @(#) $Id: SkySearch.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # SkySearch.tcl - Widget for searching a catalog and plotting the results # in the skycat image viewer. # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 10 Dec 97 created # P.W.Draper 08 Jan 07 only check for image isclear, don't use blank # name and image size < 10 pixels in plot, that # is no longer true # 03 Mar 08 change add_history to deal with images without # a WCS (fix from GAIA). # 16 Mar 09 Add a imgplot_ method for subclassing the plot # method (so that the call to the real imgplot # may be tweaked). itk::usual SkySearch {} # This class extends the AstroCat catalog widget browser class (see # AstroCat(n) to add support for plotting objects and displaying images. itcl::class skycat::SkySearch { inherit cat::AstroCat # constructor constructor {args} { eval itk_initialize $args } # called after options have been evaluated protected method init {} { AstroCat::init # these are the supported plot symbols foreach i "circle square plus cross triangle diamond ellipse compass line arrow" { set symbols_($i) 1 } # add a menu item to the File menu to save the catalog as a FITS table if {$iscat_} { set m [get_menu File] insert_menuitem $m "Add to..." command "Save with image" \ {Save the listed objects to the current FITS file as a binary table} \ -command [code $this save_with_image] } # this unique canvas tag is used for all symbols (see also SkySearch.C) set tag_ $w_.cat set object_tag_ $tag_.objects set label_tag_ $tag_.labels # add bindings for symbols $canvas_ bind $object_tag_ <1> "[code $this select_symbol current 0]" $canvas_ bind $object_tag_ "[code $this select_symbol current 1]" $canvas_ bind $object_tag_ "[code $this select_symbol current 1]" $canvas_ bind $object_tag_ "$canvas_ config -cursor tcross" $canvas_ bind $object_tag_ "$draw_ reset_cursor" # symbols can't be moved, but labels can (but not edited). # (See SkySearch.C:plot_symbol() for origin of tag name) $draw_ add_object_bindings $label_tag_ current $canvas_ bind $label_tag_ "+$canvas_ focus {}" # add short help for canvas objects set msg "Catalog symbol: {bitmap b1} = select object" set w [winfo toplevel $canvas_] $canvas_ bind $object_tag_ "+[code $w short_help $msg]" $canvas_ bind $object_tag_ "+[code $w short_help {}]" } # save the current data as a FITS table in the current image file. public method save_with_image {} { busy { $results_ save_with_image [$w_.cat entry get] } } # insert the id for the given object in the image near the object # and return a string containing status info. name identifies the # source catalog (short_name). public method label_object_in_image {id name} { if {"$canvas_" == ""} { return } if {[llength [set box [$canvas_ bbox cat$id]]]} { lassign $box x0 y0 x1 y1 make_label $name $id [expr ($x1+$x0)/2.0] [expr ($y1+$y0)/2.0] canvas $id white return "labeled object '$id' in image" } else { return "object '$id' is not visible" } } # remove any items in the query result list that have not been plotted # because they were not in the image (circular search/rectangualr image). public method filter_query_results {} { $w_.progress config -text "Filtering out off-image objects..." set new_info {} set n 0 busy { foreach row $info_ { set id [lindex $row [$w_.cat id_col]] if {[llength [$canvas_ find withtag cat$id]]} { lappend new_info $row incr n } } set t [$results_ total_rows] if {$n != $t} { $results_ config \ -info [set info_ $new_info] \ -title "Search Results ($n*)" plot $w_.progress config -text "Removed [expr $t-$n] objects from the list." } else { $w_.progress config -text "No change." } } } # add a label to the image at the given coordinates (in the given units) # with the given text and color. The id arg should be a unique id for the # label in the catalog and $name should be the short name of the catalog. # $units may be any of the units supported by the RTD {image canvas screen # "wcs $equinox" "deg $equinox"} public method make_label {name id x y units text color} { if {[catch {lassign [convert_coords $x $y $units canvas] x y} msg]} { return } set tags [list objects $tag_ label$id $name] $canvas_ delete label$id set cid [$canvas_ create text $x $y \ -text $text \ -anchor sw \ -fill $color \ -font $itk_option(-canvasfont) \ -tags $tags] $draw_ add_object_bindings $cid ct_add_bindings $canvas_ $cid } # display the given image file public method display_image_file {filename} { $skycat_ config -file $filename } # retun the width of the image display canvas public method get_display_width {} { return [winfo width $canvas_] } # retun the height of the image display canvas public method get_display_height {} { return [winfo height $canvas_] } # return the name (file or object name) of the currently loaded image, # or empty if no image is loaded. public method get_image_name {} { set name [$image_ cget -file] if {"$name" == ""} { set name [$image_ object] } return $name } # generate a blank image that supports world coordinates for the purpose # of plotting catalog objects. # ra_deg, dec_deg and equinox give the center of the image (in deg), # radius the radius in arcmin. # Returns "0" if all is OK. public method gen_wcs_image {ra_deg dec_deg equinox radius} { if {"$ra_deg" == "" || "$dec_deg" == ""} { info_dialog "please specify values for RA and DEC." $w_ return } if {"$radius" == ""} { info_dialog "please specify a radius value." $w_ return } if {"$equinox" == ""} { set equinox 2000 } elseif {[string match {[jJbB]} [string index $equinox 0]]} { set equinox [string range $equinox 1 end] } $image_ clear \ -reuse 1 \ -ra $ra_deg \ -dec $dec_deg \ -equinox $equinox \ -radius $radius \ -width [get_display_width] \ -height [get_display_height] # enable the options panel, since we now have an image catch {[[$skycat_] component info] configure -state normal} return 0 } # generate a blank image without WCS. radius is radius of the image in # pixels, # Returns "0" if all is OK. public method gen_pix_image {radius} { if {"$radius" == ""} { info_dialog "please specify a radius value." $w_ return } $image_ clear \ -reuse 1 \ -radius $radius \ -width [get_display_width] \ -height [get_display_height] # enable the options panel, since we now have an image catch {[[$skycat_] component info] configure -state normal} return 0 } # This method is called when the user clicks on a graphic symbol for a star. # The user might be selecting this star, so call the RtdImage method to do that public method picked_wcs_object {x y units} { if {[catch { lassign [convert_coords $x $y $units "wcs [$image_ wcsequinox]"] ra dec lassign [convert_coords $x $y $units image] ix iy } msg]} { return } catch {$skycat_ picked_wcs_object $ix $iy $ra $dec} } # deselect any objects in the image public method deselect_objects {} { $canvas_ delete grip } # delete any graphic objects in the image belonging to this catalog public method delete_objects {} { catch {$canvas_ delete $tag_} } # convert the given input coordinates in the given input units to the # given output units and return a list {x y} with the new values. # The units may be one of {canvas image wcs deg "wcs $equinox", "deg $equinox"} public method convert_coords {in_x in_y in_units out_units} { return [$image_ convert coords $in_x $in_y $in_units {} {} $out_units] } # add the dialog button frame # (redefined from parent class AstroCat to add Plot button) protected method add_dialog_buttons {} { AstroCat::add_dialog_buttons # only do this for catalogs, not for image servers... if {$iscat_} { pack \ [button $w_.plot \ -text "Plot" \ -command [code $this plot_again]] \ [button $w_.filter \ -text "Filter" \ -command [code $this filter_query_results]] \ -side left -expand 1 -pady 2m -in $w_.buttons -after $w_.search if {[llength [$w_.cat symbol]] == 0} { $w_.plot config -state disabled $w_.filter config -state disabled } } } # add a short help window and set the help texts # (redefined from parent class AstroCat) protected method make_short_help {} { AstroCat::make_short_help add_short_help $w_.plot \ {{bitmap b1} = Plot the listed objects again in the image} add_short_help $w_.filter \ {{bitmap b1} = Filter out off-image objects from the listing (circular search/rectangular image...)} } # insert the Id for the object selected in the Table in the image # near the object. protected method label_selected_object {} { set id [lindex [lindex [$results_ get_selected] 0] [$w_.cat id_col]] if {"$id" == ""} { return } set name [$w_.cat shortname $itk_option(-catalog)] $w_.progress config -text [label_object_in_image $id $name] } # add the search options panel # (redefined from parent class AstroCat to add image support) protected method add_search_options {} { # SkyQuery(n) widget (derived from AstroQuery(n)) for displaying # search options. itk_component add searchopts { set searchopts_ [SkyQuery $w_.searchopts \ -relief groove \ -borderwidth 2 \ -debug $itk_option(-debug) \ -astrocat [code $w_.cat] \ -skycat $skycat_ \ -searchcommand [code $this search] \ -feedbackcommand [code $this set_feedback] \ -command [code $this query_done]] } pack $itk_component(searchopts) \ -side top -fill x } # add the table for displaying the query results # (redefined from parent class AstroCat to add image support) protected method add_result_table {} { # SkyQueryResult(n) widget to display the results of a catalog query. itk_component add results { set results_ [SkyQueryResult $w_.results \ -astrocat [code $w_.cat] \ -skycat $skycat_ \ -title "Search Results" \ -hscroll 1 \ -height 12 \ -sortcommand [code $this set_sort_cols] \ -layoutcommand [code $this set_show_cols] \ -selectmode extended \ -exportselection 0] } { } pack $itk_component(results) -side top -fill both -expand 1 bind $results_.listbox [code $this select_result_row] $results_ set_options {MORE PREVIEW more preview} Show 0 # for history catalog, double-click opens file if {"[$w_.cat longname]" == "$history_catalog_"} { bind $results_.listbox [code $this preview] } else { bind $results_.listbox [code $this label_selected_object] } } # set/reset widget states while busy # (redefined from parent class AstroCat) public method set_state {state} { AstroCat::set_state $state if {$iscat_} { if {[llength [$w_.cat symbol]] == 0} { set state disabled } $w_.plot config -state $state $w_.filter config -state $state } } # re-plot the listed objects public method plot_again {} { busy {plot} } # plot the stars/objects found in the previous search in the image window. # The symbols to use are taken from the config file. public method plot {} { # can't plot with no coordinates if {![$w_.cat iswcs] && ![$w_.cat ispix]} { return } # can't plot without symbol info if {"[$w_.cat symbol]" == ""} { return } # if we have an image display, but no image is loaded, generate dummy image if {[$image_ isclear]} { if {[gen_blank_image] != 0} { return } } # if any objects are selected, deselect them first deselect_objects delete_objects $w_.progress config -text "Plotting objects..." update idletasks set equinox [$w_.searchopts get_equinox] imgplot_ $equinox } # Call the imgplot method with the local settings and the given # equinox. The equinox is that of the catalogue positions (and # should be matched to those of the image, iff different). protected method imgplot_ {equinox} { # the plot method was reimplemented in C++ for better performance # See SkySearch.C for the implementation of the astrocat plot subcommand. if {[catch {$w_.cat imgplot $image_ $info_ $equinox $headings_} msg]} { error_dialog $msg } } # Called when a row in the table is selected. Redefined from parent # clas to also select the plot symbol. protected method select_result_row {} { AstroCat::select_result_row # clear symbol selection deselect_symbol $w_.selected # select symbols matching selected rows foreach row [$results_ get_selected_with_rownum] { lassign $row rownum row set id [lindex $row [$w_.cat id_col]] if {"$id" == ""} { continue } select_symbol cat$id 1 $rownum } } # Select a symbol, given the canvas id and optional row number # in the table listing. If $toggle is 0, deselect all other symbols # first, otherwise toggle the selection of the items given by $id. public method select_symbol {id toggle {rownum -1}} { set tag [lindex [$canvas_ gettags $id] 0] if {$rownum < 0} { set rownum [get_table_row $id] if {$rownum < 0} { return } } if {$toggle} { # toggle selection if {[$draw_ item_has_tag $tag $w_.selected]} { deselect_symbol $tag $results_ deselect_row $rownum return } } else { # clear selection deselect_symbol $w_.selected } if {"$rownum" >= 0} { $results_ select_row $rownum [expr !$toggle] $results_ select_result_row } foreach i [$canvas_ find withtag $tag] { set width [$canvas_ itemcget $i -width] $canvas_ itemconfig $i -width [expr $width+2] } $canvas_ addtag $w_.selected withtag $tag $canvas_ raise $tag $image_ } # deselect the given symbol, given its canvas tag or id public method deselect_symbol {tag} { foreach i [$canvas_ find withtag $tag] { set width [$canvas_ itemcget $i -width] $canvas_ itemconfig $i -width [expr $width-2] } $canvas_ dtag $tag $w_.selected } # Return the table row index corresponding the given symbol canvas id. # Note: The plot subcommand in SkySearch.C adds a canvas tag "row#$rownum" # that we can use here. # Also: cat$id is first tag in the tag list for each object. public method get_table_row {id} { set tags [$canvas_ gettags $id] # look for row# tag (but only if not sorted!) if {[llength [$w_.cat sortcols]] == 0} { foreach tag $tags { if {[scan $tag "row#%d" rownum] == 1} { return $rownum } } } # search for $id in query results (slow way) set tag [lindex $tags 0] set rownum -1 foreach row [$results_ get_contents] { incr rownum set id [lindex $row [$w_.cat id_col]] if {"cat$id" == "$tag"} { return $rownum } } # not found return -1 } # This method is called when a region of the image has been selected # (From class SkyCat, via -regioncommand option when creating the image). # The arguments are the bounding box of the region in canvas coords. # Select any catalog symbols in the region. public method select_region {x0 y0 x1 y1} { # clear symbol selection first deselect_symbol $w_.selected $results_ clear_selection # make sure its is one of our objects foreach id [$canvas_ find enclosed $x0 $y0 $x1 $y1] { if {[$draw_ item_has_tag $id $object_tag_]} { set rownum [get_table_row $id] if {[info exists got_it($rownum)]} { continue } set got_it($rownum) 1 # select the object in the image and table if {$rownum >= 0} { select_symbol $id 1 $rownum } } } } # generate a dummy blank image for the purpose of plotting catalog # objects on it. Return 0 if OK, otherwise 1. public method gen_blank_image {} { if {[$w_.cat iswcs]} { # using world coords lassign [$w_.searchopts get_pos_radius] ra dec equinox radius if {"$equinox" == ""} { set equinox 2000 } if {"$ra" == "" || "$dec" == ""} { # can't create a blank image with no center # use coords from first row, if any set row [lindex $info_ 0] set ra [lindex $row [$w_.cat ra_col]] set dec [lindex $row [$w_.cat dec_col]] if {"$ra" == "" || "$dec" == ""} { return 1 } } if {[catch {lassign [$wcs_ hmstod $ra $dec] ra_deg dec_deg} msg]} { warning_dialog "$msg (ra = $ra, dec = $dec)" return 1 } # generate dummy image return [gen_wcs_image $ra_deg $dec_deg $equinox $radius] } else { # generate dummy image lassign [$w_.searchopts get_pos_radius] x y radius return [gen_pix_image $radius] } return 0 } # clear the table listing (done in base class) and remove any plot # symbols from the display. public method clear {} { AstroCat::clear # remove any catalog symbols (since table is also empty now) delete_objects } # Add the current image file to the history catalog under the given filename. # $skycat is the handle of the SkyCatCtrl itcl class object to use to extract image # infomation to put in the catalog. public proc add_history {skycat filename} { set catalog $history_catalog_ set image [$skycat get_image] # check if the directory for the catalog exists set dir [file dirname $catalog] if {! [file isdirectory $dir]} { if {[catch {exec mkdir $dir} msg]} { warning_dialog $msg return } } # make sure at least an empty catalog exists if {! [file exists $catalog] || [file size $catalog] == 0} { # If it doesn't exist yet, create an empty catalog file if {[catch {set fd [::open $catalog w]} msg]} { warning_dialog "can't create image history catalog: $msg" return } puts $fd "Skycat History Catalog v1.0" puts $fd "" puts $fd "ra_col: -1" puts $fd "dec_col: -1" puts $fd "x_col: -1" puts $fd "y_col: -1" puts $fd "show_cols: file ra dec object NAXIS NAXIS1 NAXIS2 NAXIS3" puts $fd "sort_cols: timestamp" puts $fd "sort_order: decreasing" puts $fd "" puts $fd [join $history_cols_ "\t"] puts $fd "----" ::close $fd # get the catalog into the list of known catalogs $astrocat_ open $catalog } if {"$filename" == "" || [string first /tmp $filename] == 0 \ || ! [file exists $filename]} { # ignore temporary and non-existant files return } # add an entry for the given image and filename set id [file tail $filename] lassign [$image wcscenter] ra dec equinox if { $ra == "" } { set ra "00:00:00" set dec "00:00:00" } set object [$image fits get OBJECT] set naxis [$image fits get NAXIS] set naxis1 [$image fits get NAXIS1] set naxis2 [$image fits get NAXIS2] set naxis3 [$image fits get NAXIS3] lassign [$image cut] lowcut highcut set colormap [$image cmap file] set itt [$image itt file] set colorscale [$image colorscale] set zoom [lindex [$image scale] 0] if {"$zoom" == ""} { set zoom 1 } set timestamp [clock seconds] # get full path name of file for preview URL if {"[string index $filename 0]" == "/"} { set fullpath $filename } else { set fullpath [pwd]/$filename } set preview file:$fullpath set data [list [list $id $ra $dec $object $naxis $naxis1 $naxis2 $naxis3\ $lowcut $highcut $colormap $itt $colorscale $zoom \ $timestamp $preview]] $astrocat_ open $catalog catch { $astrocat_ save $catalog 1 $data $equinox } # update history catalog window, if it is showing set w [cat::AstroCat::get_instance [file tail $catalog]] if {"$w" != "" && [winfo viewable $w]} { $w search } } # Check if the given filename is in the history catalog, and if so, # apply the cut levels and color settings for the file. # $skycat is the handle of a SkyCatCtrl itcl class object to use. public proc apply_history {skycat filename} { if {"$filename" == "" || [string first /tmp $filename] == 0 \ || ! [file exists $filename]} { # ignore temporary and non-existant files return } set catalog $history_catalog_ set image [$skycat get_image] if {[catch {$astrocat_ open $catalog}]} { # no catalog yet return } set list [$astrocat_ query -id [file tail $filename]] if {[llength $list] == 0} { # not in catalog return } set row [lindex $list 0] eval lassign {$row} $history_cols_ if {[catch {$image cut $lowcut $highcut 0}]} { # must be something wrong with this entry, remove it $astrocat_ remove $catalog return } $image cmap file $colormap $image itt file $itt $image colorscale $colorscale # after 1000 [list $skycat scale $zoom $zoom] # update the main panel and color window $skycat component info updateValues $skycat update_color_window } # Add at most $n image history entries to the given menu $m. # w is the TopLevelWidget containing the menubar and $skycat is # the handle to the SkyCatCtrl class to use to load an image. public proc add_history_menu_items {w skycat m n} { set catalog $history_catalog_ if {[catch {$astrocat_ open $catalog}]} { # no catalog yet return } set list [$astrocat_ query -nrows $n -sort timestamp -sortorder decreasing] foreach row $list { eval lassign {$row} $history_cols_ set filename [string range $PREVIEW 5 end] $m add command \ -label $file \ -command [list after idle $w busy \"$skycat config -file $filename\"] } } # -- options -- # Optional unique id, used in searching for already existing catalog widgets. itk_option define -id id Id "" { # in SkyCat.tcl, we passed the name of the SkyCatCtrl Itcl image widget as -id. set skycat_ $itk_option(-id) set canvas_ [$skycat_ get_canvas] set image_ [$skycat_ get_image] set draw_ [$skycat_ component draw] } # font used in canvas to mark objects itk_option define -canvasfont canvasFont CanvasFont -*-courier-medium-r-*-*-*-120-*-*-*-*-*-* # -- protected members -- # SkyCatCtrl widget instance protected variable skycat_ {} # internal rtdimage image for main image protected variable image_ {} # canvas window containing main image protected variable canvas_ {} # CanvasDraw object for drawing on image protected variable draw_ # array containing supported symbol names protected variable symbols_ # canvas tag used to identify all symbols for this instance protected variable tag_ # canvas tag used to identify all objects for this instance protected variable object_tag_ # canvas tag used to identify all labels for this instance protected variable label_tag_ # name of wcs object for converting between hh:mm:ss and double deg protected variable wcs_ ::skycat::.wcs # -- common class variables -- # name of the history catalog global ::env protected common history_catalog_ $env(HOME)/.skycat/history # list of columns in the history catalog protected common history_cols_ \ [list file ra dec object NAXIS NAXIS1 NAXIS2 NAXIS3 \ lowcut highcut colormap itt colorscale zoom timestamp PREVIEW] } # C++ wcs object used by procs below. wcs ::skycat::.wcs # convert a value in hh:mm:ss format to floating point format # (can be used in plot symbol expressions) proc hmstod {hms} { return [::skycat::.wcs hmstod $hms] } # convert a floating point format value to hh:mm:ss format # (can be used in plot symbol expressions) proc dtohms {d} { return [::skycat::.wcs dtohms $d] } skycat-3.1.2-starlink-1b/skycat/library/SkycatInit.tcl000066400000000000000000000011131215713201500226610ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: SkycatInit.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # SkycatInit.tcl # # script which is executed by Skycat.C to initialize the package # # who when what # -------- --------- ---------------------------------------------- # abrighto 02/01/06 created package require img::xpm package require Tclutil package require Astrotcl package require Cat if {![lcontain $auto_path $skycat_library]} { lappend auto_path $skycat_library } namespace eval skycat {namespace export *} namespace import -force skycat::* skycat-3.1.2-starlink-1b/skycat/library/main.tcl000066400000000000000000000003241215713201500215260ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # "@(#) $Id: main.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # main.tcl - main entry point for skycat application # package require Skycat skycat::SkyCat::startSkyCat skycat-3.1.2-starlink-1b/skycat/library/mkIndex.tcl000077500000000000000000000003211215713201500222010ustar00rootroot00000000000000#!../bin/skycat_wish # # mkIndex.tcl - generate a tclIndex file in the current directory # "@(#) $Id: mkIndex.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" package require Itcl auto_mkindex . *.tcl exit 0 skycat-3.1.2-starlink-1b/skycat/library/skycat-logo.xpm000066400000000000000000000651631215713201500230740ustar00rootroot00000000000000/* XPM */ static char * skycat_logo_xpm[] = { "454 59 8 1", " c #186130C2A699", ". c #38E369A6D75C", "X c #6185C71BFFFF", "o c #0000000079E7", "O c #BEFBFFFFFFFF", "+ c #000000005144", "@ c #000000000000", "# c #FFFFFFFFFFFF", " ....XXXXXXXX... o o o oo oo o o oo o oo oo oo . .....XXXXXX... oooooooooooooooooooooooooooooo ....XXXXXX... oooooooooooooooooooooooooooooo ....XXX.X.. oooooooooooooooooooooooooooooooo o ...X.X.X.. ooooooooooooooooooooooooooooooooo o o .....X.... oooooooooooooooooooooooooooooooooo o ooooo o .......... oooooooooooooooooooooooooooooooooo o oooooo ......... oooooooooooooooooooooooooooooooo", ". . .....XXXXXX... o o o o o o o o o oo oo o o . . . ...X.XXX.XX.. oo o o o o o o o o o oo oooo o .....X.X.X... oooooooooooooooooooooooooooooo . ..X..XX.... ooooooooooooooooooooooooooooooo o .....XX.X... ooooooooooooooooooooooooooooooo o o ...X.XX... ooooooooooooooooooooooooooooooooo o o ...XX.X.. ooooooooooooooooooooooooooooooooo o o o oo o ....X... ooooooooooooooooooooooooooooooo", " . . . ...X.XXXXXXX.. o o o o o o o o o o o ooo . . . . . ...X.XXXX.X.. oooooooooooooooooooo oooo oo . . ..X.XXXXXX... oooooooooooooooooooooooooooo . ....XXX.XX... ooooooooooooooooooooooooooooooo ....XX.X... oooooooooooooooooooooooooooooooo ...X..X... oooooooooooooooooooooooooooooooo o o o o o .....X..... oooooooooooooooooooooooooooooooooo o o oo ......... ooooooooooooooooooooooooooooooo", ". . . .....XXXXXXX.X.. o o o o ooo o o ooo oo o . . . . .....XXXXXXXX.. oo o o o o o o o ooo o oooo . . ....X.XXXX.X.. oooooooooooooooooooooooooooo . . ....X.XX.X.. ooooooooooooooooooooooooooooo ....XX.XXX... oooooooooooooooooooooooooooooo o o .....XX.X... oooooooooooooooooooooooooooooooo o o ...X.XX... ooooooooooooooooooooooooooooooo o oo o . ..X.XX... oooooooooooooooooooooooooooooo", ".. . . ...X.XXXXXXXX... o o o o o o o o o o ooo ... . .. ...X.XXXXXX.... oo oooooooooooooooo oooooo .. . . . ...XXXXXXX... o ooo oo ooooooooooooooooooo . . ....X.XXXXX.... oooooooooooooooooooooooooooo ...X.XX.X.... ooooooooooooooooooooooooooooo ...X.X.XX.X. oooooooooooooooooooooooooooooo o o ....X.X.X... ooooooooooooooooooooooooooooooo o o ....X..X... ooooooooooooooooooooooooooooo", "... . . ...X.XXXXXXXX... o o o o oo o oo o o o o . ..... . ....XXXXXXXXX... oo o o o o ooo o oooo . . . ...X.XXXXXXX... oo oo oo o ooooooooooooooo .. ...XXXXXXXX... oooooooo ooooooooooooooooooo . . ...XXXXXXX.. ooooooooooooooooooooooooooooo ...X.XXX..... ooooooooooooooooooooooooooooo o ....X.X.X... oooooooooooooooooooooooooooooo o o o ....XX.X... oooooooooooooooooooooooooooo", "..... ......XXXXXXXXXX... o oo o oo ooo o . .. ... . .....XXXXXXXX... o oo oooooo ooooo oo .. .. . . ...X.XXXXXXX... oooo o ooooooooooooooo . .... . . .....XXXXXX... ooooo o ooooooooooooooooo . ...X..XXX.X... oooooooo oooooooooooooooooo . ...XX.XXXX.. ooooooooooooooooooooooooooooo ..X.XXX.X.. oooooooooooooooooooooooooooooo o ...X..X.X... ooooooooooooooooooooooooooo", "....... ....XXXXXXXXX.X... o o o o oo oo ....... . ....XXXXXXXXX.X... o o oo oooo o ooo ..... . . .....XXXXXXXXX... o o ooooooooooooo .. . ...XXXXXXXXX... ooo o o o ooooooooooooooo ... . ....XXXXXXX... oooo o ooooooooooooooooo . . ....X.XXXX.... ooooooo o oooooooooooooooooo ....X.X.XX... oooooooooooooooooooooooooooo o ...XX.XX... oooooooooooooooooooooooooo", "..... .....X.XXXXXXXXXX... . . o o o o o o ...............XXXXXXXXXX... o ooo o oooo o . ..... . . ...X.XXXXXXX.X.. o ooooooooooooo o . ...... . .....X.XXXXX.X.. o ooooooooooooooo . . . . ...XX.XXXX.X... o o o o oooooooooooooo .. . . ...XXXXXXX... o ooo o o o ooooooooooooooo . ....XXXX.X... oooooo o oooooooooooooooooo .....XXX.X... ooooooooooooooooooooooooo", "............X.XXXXOXXXXX.... . . . oo o o oo oo ........ . .....XXXXXXXXXX... . oooooo ooooo ....... . . ...X.XXXXXXX.X.. oooooooooooo .... . . . ....XXXXXXXX.X... o ooooooooooooo ..... . . ...XXXXXXXX... oo ooooooooooooooo . . . ...X.XXXX.X.... o ooo o o ooooooooooooooo . ...X.X.XX.X... oooo o o oooooooooooooooo . ...X.X.XX.... ooooooo ooooooooooooooo", ".............XXXXXXXXXXXX.. . . . .... o oo o o ..............X.XXXXXXXXXX.... ... oo oooo oo ......... .....XXXXXXXXXX... . . oooooooooooo . ...... . . .....XXXXXXXX... oooooooooooo . .. ... . ......XXXXXXX... o ooooooooooooo . .... . . .....X.XXXXXX.. o o oooooooooooooo . ... ....XXXXX.X.. o oo ooooooooooooooo .. ....XXXXXX... ooo ooo oooooooooooo", ".X.X........X.XXXXXOXXXX.X... . ...... . oo o o oo ....X...........XXXXXOXXXX.X... . .... .. ooo oooooo ......... .....X.XXXXXXXX.X.... . .. . ooooooooo .......... ....XXXXXXXXX.X... . . oooooooooooo ...... . . ..X.XXXXXXXXX... . oooooooooooo .... .. ...XXXXXXXX..... o ooooooooooooo . ... ....XX.XXXXX... o o oooooooooooooo .. . ....X.X.X.X... o oo o ooooooooooo", "..X.X........XXXXXOXXOXXX..... .. ....... o o o o ......X........X.XXXXXXOXXXX.... . . . ... . oooo oo o ............ ...XXXXXXXXXXX... . . .. .. oooooooooo ......... ......X.XXXXXXXX... .. . oooooooooo .......... .....X.XXXXXX.X... . . . ooooooooooo . ..... .. .......XXXXXXXX.. . oooooooooooo .. .... . .....XXXXX.X... o oooooooooooo . ... . ...XXXXX.X... o o oooooooooo", "X.X.X.X........XXXXOXXXXXXX.... ........ ++oo o oo o ...X.X.X........X.XXXOXXXXXXX.... . ......... ooooooo ....X.X..........XXXXXXXXXXX... . . . ...... oooooooo ........... ....XXXXXXXXXXX. oooooo. ... ooooooooo ........ .. ....XXXXXXXXXX.... . .. . oooooooooo ....... . ...X.XXXXXXX.X... . . . ooooooooooo . .... .. . ...X.XXXXXX.X... . . oooooooooooo .. ..... . ... .......... o ooooooooo", ".X.X.X.X....X.XXXXXXOXOXXXXX..... ... ++++++oo+oo o o ...X.X.X........XXXXXXXOXXXXX...... ......... oo ooo ......X.......X..XXXXOXXXXXX... . . ......... oooooo ...X.X............XXXXXXXXX oooo o oo....... ooooooo ......... .. .....XXXXXXXXX.... . .... oooooooo ............ ...X.XXXXXXXX.... .. . ooooooooo ...... .. . ...X.XXXXXXX... . . oooooooooo ...... . ooo++++++ ... o . . ooooooo", "X.XXXX.X..X....o++.XXOXXXXX..........++++++++++ o o ...X.XX.X.X.....X.XXXXXOXXXXXX..... ............ o oooo ....XXX.X........XXXXXXXXXXX.X... . .......... o oooo .....X.X.........XXXXXXXXXX o++++oooo........ oooooooo ...X.X...........XXXXXXXXX.X... . . ......... oooooooo ............ .....XXXXXX.++@ . . ....... oooooooo oooo ...... ... .....XXXXXX.X.... ..... . oooooooooo ......... . oooo++@+@++++.... . . . ooooooo", ".XX.XXX.X...X.++++.OXXXOXXXXX........ +oo+++++o o ....X.XXX.X.X..X.X.XXXOXXOXXXX.X.........XX.... . o ...X.X.X.X......X.XXXXOXOXXXX.................. oo o ....XX.X.X.......X.XXXXOXXXX ++o+++ooo......... oooo .....X.X.........X.XXXXXXXXXX.... . ....... . ooooo ...X.X...........X.XXX.+@@@ ... . . . ...... oooooooo+oo ........ ....XXXXXXXXXX... . ... ooooooo ......... o o++@+++++ +..... .... . ooooo", "..XXXXXXXX.X. +o++.XOXOXOXXXXX.......... oooo++ ...XXXX.XX.X.X...XXXXXXOXXOXXXX............XX.... o o ...X.XXXX.X....... .. ..X.+ .... . ..... . ... o o ....XX.X.X.......X.XXXXXOXXX...++++oo.....X.... oooo ....X.XX.........X.XXXXXXXXX...... . ......... ooooo .....X.X..........XXXXX.@+@@..... . ........ ooooooo+++o..X.X...... .....XXXXXXXXX.... . ........ ooooooo ............ o + +++++ X.... . . ... . ooooo", "XXXXXXXX.XX.. o++ XXXOXXXXXXX.X......X.XX ooo+ . .....XXXXXX.X..X...XXXXXXOXXXXXXX......X.X.X.XX... ..........X.X. ++@++@@.++@++X..... +++++++ ...X.XXXX.XX......XXXXXXXXXXXX.+++ooo...X..X..... ...X.XX.XX........XXXXXXXXXXXX... . ............ o ...X.X.XX..........XXX.+++ .X...... ........... ooo++++o....X.X...........XXXXXXXXX.... . . ........ ooooo ..X.XX....... ....oo+++ XX..... ...... . ooo", "..XXXXXXXX.X. ++++XXXXOXOOXXXXX........XX.oooo+ ... ....XXXXXXXXXXXX..XXXXXXXOXXOXXXX.X........XXX. o+ o+++o+ .XX. +@+@++ +++@@++++X.... +@+++@++++@+ ...X.XXXXXXX.........XXXXXXXXXXX + +oo....X.X.X.... o ...X.XX.XXX.X.....X.XXXXOXXXXX.X... .. ....XX..... o ...X.XXXX.X........XXXX.+++ .XX... . .....X..... o o@+oo..XXX.X........X.XXXXXXXXX.... . . .......... o o o .....X..X...........oo+o+.X.X... . .......... o", "XXXXXXXXXXX..+@@@@ .XXXXXXXXX..X....X.X.X.ooo++... . . ....XXXXXXXXX.X.X....XX...XXXXXXX.......XX.X..++@+@@+@+@++++++@@@@@+...++@++++++++++++@ .XX.. +@+++@+++@+@++@ ....XXXXX... o++oo .. @@@.XXXX++++++.......X..... ...XX.XXX.X..X..X.X.XXXXXOXXXX..... ....X...... . ....X..X.X.X.....X.....++++++.... . . ...X.X..... oo++++oo....X..X........X.XXXXX. . ......X.... oo++ ...X.XX.X........X.o+o++.XXX..... . .......... o ", ".XXXXXXXX.o+@@@@@+@@@++.@++ + ..X.X...XX..++++@ . ooo o...XXXXXXXXXXX.. ++@@@++ .XXXXXX.......XXX.+++++++++++@++@++++++@ . @+++++ ....+++++.XX.X +++@+++ +++++++ . . .....XXX..+++++++++++++++++XXXXX +++ ..++o o ......XXXXXXXX..X...XXXXXXXXXXXXXX.. +@o . +++o . . . ...X.X....X. o+++++++@+++ +++++@ ..X.XX.... ooo++@+++oo o ooo+ ....XXXX.. ++++++ooo .....X.... o++++@+++ ..XXX.X.........+ ++.XXXX... . . ...X.X.... ", "X.XXXOXOX.++@@@@@@++++@@@+@+++ .X...X..XXX++++++ ++++++++++.XXXXXXXXXX ++++++++ ++ +o.XXXX.X.X..X.XXX.. +++@+++++++ + ++++@. +++@++.XXXXXO++@+.XXX. +@++++.X.X. ++@+@+ . . ...XXXX +++o++ ++++++++++@.OXXX.+++@+..o++++o+ +oo. . ...XXXXXXXXXXX.X.X..XXXXOXOXXX.. o++++@+++++ +oo .... oo oo++++++o .X.X... o+@+++@++@+@@@++++@+..X.X.X... ooooo++o+o+o+++o++++ .....X..++@++@+ooo o+oo ....X.XX. ++++++++++oo+++ .XX.X........o+ooo XXX.X... .. .......X.... ", ".XXXXXXXO +@+@+@+++@+@++++@++@.XX. ..X.X.++++++@+++++ +ooo+.XOXOOXX. +++o+++++ + + o.X.X.....X.XXXXXX.@++@ ......X.+@++ @+@+++.X.XXXXX.++++XXX +@++@ .X.XXXX +++++ ......X.X.+@++o++ + . +++++o+@.XOXX @+++o..o+++o+oooo+ooo.. ....X.XXXXXXXXX.X.X..XXXXXXXXXX.+ o+++++++@+o+ +oo.... oooooo+ +++++o ...X oo+++@+++@+@+@++++++ .X.XXX.X.. +ooooooo oooo+o+o+++ ..X.X..@++ooo++ooooo+++++..X..X. +oo++++++++++++@o.XXX.X....X ooooo.XXXXX..... ......XX.X.....", "XXXXXOXOX @+@@+@+@+++++....+..XXXX...X.XX.o+++++++.. ++ ++ XXXXXOX +++oo++o .+.++++ooo XX.X.X.X.XXXXXX @+++ .....XXX.+++@++++++.XXXXXXXO.@+@++X.+@+++ ...XXXXXX @+@++.......XX.++++++ ..X..X +o+o .XOXXX+++++ .. ++++o++++ +o ........XXXXXXXXXXX....X.X.XXXOXOX ++oo+++ ++o+o++oo.X...+o+oooo++ ++++@+ooo.X.. oo+++++@+++++ + + ...X.X.XXX. +oooooooooo+ ..X.....+++oo .X...oo+@++++ .XX..+++oooo . +o+++o .XXX.X.X...+oooo.XXXX.X... . ....X..X.X... ", ".XXXXXOXOXXX.+@+@++.XXXXXXXOXOXXXXX.X.X.X.o +++++ XX... +++oo.XOOXX o+++ooo..XXX..+++++++.XX...X.XXXXXXX ++@+ .... ...@+++@++@+..XXXXXXXX++++.X.@+++ ..X.X.XXXX. +++@ .....X.X.++@++.XXXXXXX.... + XXOXO.@+++o...o+++ooo++ ... .XXXXX. oo .OX +o o . .. +++ +o XX.. + @++o ..X +++ooooXXX.... +++++.X.X.........X.XXXX.X.... ooooo..X.XXXXX.XX.XX. +@++ .XXXXXX. ++@+@+ ....o++ooo . ... oo++o+ .XXX.X.X.. ooo.XXXXXXX..... ....XX.X.X...", "XXXXXOXOXOXOX.@@+@+.XXXOOOOXOXOXXXXX.X.XX.+++++o .XXXX..+oooo.XXXOX o+@+++ XXXXXOO.@+@+@+ XXXXX..X.XXXXX @++@.X..+++++..+++++@++@ .XXXXXXXX..XXXX++++@..X.X.XXXXXX.+@++ ......XX. ++@@XXOXXXXXXXXX+++XOXOX +@++oX.. o+oooo ...XX. oo ++++++@+OOXOX.++++++++@+@.. o+ooo .X...... +++o+..XX..++++ ..XXXXXX +oo .X.XXXX.oo++@XXXXXX........X.XXXXXXX... ooo o.XXXXXXXXXXXX.X ++++oo.XXOXXXXX. ++++++.X.o+++oo ..... ... oooooo.XXXX.X.X.++ ++.XXXXXXX.........X..XXXXXX.", ".XXXOXXOXOOXO.+++@+XXXOXXOXOOXOXXXX.XX.X..+@++o XXXXXXX.+ ooo XOOX o++++.XXXXXXXXO.+++++ XXX...X.XXXXXX.++++ .X @++@+..@.+. ++++@ .X.XXXXOXOOXO.@+@++.X....XXXXXX.@++@ .X.X.XXX. +@+++.OXXXXXXXX. .XXOXO.+++++..o+o ooo.XXXXXX. ooo++++ooo.XXXOX.+++++++++++. +++oo.XX..X.....++o + XXXX..+ ....XXXXXO.@+ o .XXXX.X.oo+++XOXXXXXX.....X.XXXXXXXXXX. ooooo.XXXOXOXOXXXXXX.+++oo.XXOXXXXXX.. +@+++ .. oooo XX........X ooooo.XXXXX.X..+.+++.XOXXXX.X..........XXXX.X..", "XXXXXOOXOOXOX.@++@ XXXXOXOXOXOXOXXXXX.X.X.@+++ XXXXXX.X.+oooo XXXX +++++ XXXXXXXOXOX@o+ XXXXXX.XXXXXXX+@+@++..+++@++XXOXOOX+@+++++ ....XXXXXOX.@++++.X.XXX.XXXXX.@++++..X.X.XX. +++++.XXXXXXXX...XXOXXOX.+++++.++ o o #XXOXXXXX ++ooo++o .XOOXOXX+++o+oooo+ @+++o XXXXX..X.X.++oo+ .XXXX.........XXXX.@ + o.XX.XXX oo++.XXOXXX........X.XXXXXXX.X. ooooo.XXXXXXOXXXXXXX..+o XXOXOXOXXXX..+++++ XX.+oo.XX.X......X..ooooo XXXXXXXX +@+++XXXOXXXXX.X......XX.XXXXXXX", "XXXXXXOOXOOOX.@++@+XXOXXOXOOOXOXOXXXXXXX..++++.OXOXXXXX.+ooo+ XOO.++o+++ . ++++ .XXX.X.X.XXXXX.@++++@++@+++@.XXOXOOX @+@+@@+@+@@@++XOO.++@+ .X...XXXXXXX.++@++.X.X.X.XX.++++++++ X. .XXXXOXOXOX.+ oo++ooo o.XXXXXXXXXX. +ooo+++.XXXOXOOOO.o+oo+ .OXX++++o.XXXX.X..... ++o+ XXXXXXX... @+@@@@@++++o .XXXXXX +++@+OXXOXXXXX...X..XXXXXXXXXXX +++o .XXXXOXXOOXXXXX @+ XXXXXXOXXXXXX. ++++ ..oooo.XXX.X......XX.oooo+XOXXXXXX ++.++.XOXOXXXXX.........X.XXXXXX", "XXXXXOXXOOXOO++@+@.XXXOXOXOXOOOOXOXXXX.XX.oo++.XOXOXXXX.++ +++XXX.+++++@+++oooo + +++ +++.XXXXXX.XXXXXX +++@++@+++++@.OXXOXOOO.+++++++++++@+@ O @++@+.XXXX..XXXXO.@+++@.XXX.XXXXO.++o+++@++. +++++ .XXOXO.oo oo+o o XXXXXXXOXXXXX. +oo++.OXOXOXOXO o++o+.XXXOOX.+oXOXXXXX.X.X.. . .XXXXXXX + o+++++++++++++.XXXXXX o+++ XOOXXXX.X.X..X.X.XXXXXXXX. ++++ .XXXXXXOXXOOXXX @++ XXXOXOXXOXXXX..oo+++ .ooo XXXXX.X.X..X.X.ooo+@.XOXXXXX.++@+@.XXXXOXXXXX........XXXXXXXX", "XXXXOXXOOOOOO+@++++XXOXXXOXOXOXOXOXXXXXX. o+o+.OXOXXOXXX++++++XXO++ ++++++++oooo++ +++.XXXXXX.X.XXXXX.@+@+++++@+@++.XXOXOOOXOX.+++@++++++++@.++++++XX.X..XXXXXX.++@++.XX.XXXXXXOX ++o+oo +++@+++@+XXOO.+ oooooooo+.XXXXXOXXXXXXX.. + XXOXOXOXOX++++++XXXX. ++ OXOXXX.X.X.XX.XXXXXXXX. ++o+o++@+@+@+++++ XXXXXXX +++++XXXXOXXXXX....X.XXXXXXXXXX +++oo.XXXXOOXOOXXOXX++++ XXXXXXOXOXXXXX.oooo+.oo o.XXXXXX.X..X.XX.ooo++XOXOXXXX.@.++@.XOXOXXXXXX.X....X.X.XXXXXX", "XXXXXOOOXOOOX+++++.OXXXOOXOOOOOXOXOXXXXXX ooo+.XOXOOXXXX+++ +.XOX+++++@+@+++++oo o+++ ..XOOXXXXXXXXXXXX.@+++@.X.++++@.XOXOXOOOOOXXX..XXX.+@+++@ @+@++.XXXXXX.XXXX.@+++@.XXXXX.XXXXX..X.X.. oo+@++++++.OXO. ++++oooo++ .XXXXXOXOXXXXX. + .XXOXOOOX@+@+@+XXXXX @+++.OXXOXXXX..X.XXXXXXOXO. ++oooo ..@+++ +XOXXXXX+++++.OOOOXXXXX.XX.X.XXXXXXOXXXX++++o.XXXXXXXOXOOOXO @+o+.XXXOXOXOXOXXXX.oo oo +ooo.XXXXXXXX.X.X.X.+++++XXOXOXXX.+@.@ .OXOXOXOXXXX......X.XXXXXXX", "XXXXXXXOOOOOO+++++.XOXOXXOXOXOOOOXOXXXXXX.oo++XOXOXXOOXX++o +XXO.++++++.. . . .X..OOXOXOXOXXXX.XXXXXX.@++++XXX.+@++.XXXXX.XX.XOOOOOXXXO.++@++.@++++.XXX.X.XXXXO.@++++XXXXXXXXX.. +.XOOOO.X...+++@+@.OOXO + +X. ++++ .XXOXXOXOXXXXX oo++ XOXOXO.@++++.XXXXX ++++.OOXXXXXXX.X.X.XXXXXX.+++++o ..X.XXO.++++o.XOXXXX ++o+ XXXOOXOXXX.X..X.XXXXXXOXXX +++ .XXXOXOXOXOXOX+++o+ XXXXOXOXOXOXXX. oooooooo+ XXXXXXXXX.X.XX.+@+o+XOOXOXOX..@@+@.XXXOXOXOXXXXX.....X.XXXXXX", "XXXOXOXOXOOOO++ ++@XXOXXOXOOOOXOOOXOOXXXX.o++@.XOXOOXXOX + + .OXX + ++.XOOXOOXXOXOOOXOOOOOOXOXXXX.XXXXX.+@+@+XOOX.++@.X..+@+@+@+XOOXXOXOXX++++@ ++@+@+XXXXXXXXXXX.++@++XXXXXXXX.+++++XOOOOOOOOOXO +@.OXOO.+ + XO. ++++ .XXXOXXXOOXXX. o+++ XOOOO ++++@XOXOXO +++@+XXOOOXXXXX.X.XXXXXOX @+++++.XXXXXXOXX o+.OXOOXX ++++ XOOXXOXXXXX.XX.X.XXXXXXXOX ++++ .XXXXOXOOOOOOO.+ooooXXOXXOXOXOXOXX oooo oo+++.XOXXXXXXXXX.X.+++o+XXOOXOXO.@.+ +.OXOXOXOXXXXX.X.X.X.XXXXXXX", "OXOXXXOXOOOOX.++++.XOOXOXOXOXOOXOXOOXXXXXXo++@XXOXOXOOOX++oo+ XXOX+++oo@OOOOOXXOOXOXOOXXXXXOXOXXXXXXXXXO.@++++XXXXX.. XX@@@++++++XOOOOXOXOX @++@X++++++XXXXX.XXXXX+@++@.XOOXXXXX.+o++XOOOOOOOOOXOXO. +.XOOX + + OXX. ++XXOXXOOXXOXXX.o+@++.XXO.+ooo+XOXOXXX.++@++XOOXXOXXXXXXX...XXXX.++++ .XXXXXXXXX++ooo .OOXXOX +++o+XOXOOOXOXXXX..X.XXXXXOXOXX oo+++.XXXXXOXOXOXXX.++oo .XXXOXXOXOXOXX++o++ .o+++@.OXXOXXXXX.XXX++@ +.XOOXOXOX.+@@ +.XOXXOXOXOXXXX.X.X..XXXXXOX", "XXXXOXOOOOOOO.@ +++XOXOXOXOOOX +.OOXOOXXX.++++.OXOXOXOXX@++ + XOXO.+ooo+.OOOXOOXXOXOXX.@@.OOOXOXXXXXXXXX.@++@ XOOOXXXXXX++++@+@++OOOXOOXOX.@++@+XX+@+++.XXXXXXXXX @++++XOXXOXXXXX ++++.OOOOOOXOXOX.++ XOOX.+ ++.OXOX.+ +++.XXOXOXOXXOXXXo+++ +XOX++ooo XOXXOXOX.@++++XOOOXXXXX.X..@+ XOX.+++o XXXXXXXX.++oo o+XOXOOXX.++++ XOOXOXOXOX. + .XX.XXXXOXOX.o+ ++XXXXOXXOXOX.+.X.@oo++XXXXOOXOXOXX.+++++.. +++o .XOXXOXXXXXX @++o+XOOOOOOXO+@ o+o.XXOOXOXOXOXXXX.X.XX.XXXXXO", "OOXOXOXXOOOOO.+++++XOOXOXO. o+.@+XOOXOXOX.+@+@.OXOOOOXOX ++++ XXOOX oo++@.OOOXOOXOXX.@@+o XOOOXOXXXXXXXX.+@++@XOXXOOXOX.@++++++++.XOOOOXOX++++++OO.@+@+@XOXXXXXX @++@+ XOOXXOXXXX.o+@+@.XOOOOOOX.@+ o XOXOX.+++.OXXXX. +@@.XXOXOXOXXOXXX.++o +XX.+oooXOOOXOXXO.+++++oXXOOOXXXXX ++@@ XOX +++ XXXXXXX.+o+oo o+.OOXOOX.o++@+.XOOOOXX.++ ++..XXXXXXXOXO.o +++.XXXXOXX.++ ++X.++++++XOXXOXOOOX +oo++ XX.++++ .XXOXXXXXX. ++++o OOXOOXOOX.++ooo.OXXOXOOXOXOXXXX.X..XXXXXXX", "XXOXXXOOXOOOOO+++ ++XXXOOX. +@+++.OOOXOXX.++++.XOXOXOOOX ++ ++XOXOO. +++++.XOOOXOX.+@+++oo OXOOXOXXXXXXX.+++@.XOOOXXXXOX+@+@++@+@@++ .XX ++@+@+XOOX +++++..XXX.++++++@XOOXOOXOXOX.oo+++++..X.. +@+@+oXXXXX. +@@.OOOOX.+++o+@+XXXXOXOOXOXOXXooo+ ++++ XOOOXOXOXX.++oo+o.XXXOXX. ++++++.XX +++++..XX. ooooo oo++XXOXXOX o++++XXXXOO.@+@+@+ XXXXXOXOXXO. ++++ .XXXXX.+++++@XO.++++@+ .XXOX.o ooooo@..X..++ ++ ..XOXX. +@+@+++XXOOOOOOOO.+o+++.XOXOXOXOXOXXXXXX.XX.XXXXXO", "OOOXOOOXOOOOOO.@++++ ...+@++++ .OOOOXXX.+o+ ..XXOX ..+++++ ....XO.o+@+++..XX. +@+++++o .OOOOOXOXXX. .+@+@ @.+...XXX.+@++++@+++++++@+@@+@+++ OOOO.+@+@++@.. +++@+@+XOOXOOXOXOXXooo ooo ++ ++@++++o.OXo+ +++++XOXXX. ++++ +@++XOOXOXOXXX oo ++++++XOOOOOOXOXOX oooo + .XX. +++++ .XOO o++++o o++ooooooo +.+.OOX.o++++ ..X.@++++++ X.XXXXXXXOOX.+ +++@++.X.+++++++XOO.++++++@++o+.. oooo+.XXXXX +++ ++++ +@.++++@+.XXOXOXOXXX.o+o+++.....XXXXOXOXXXXXX.XXXXXOX", "OXXOXXXOOOOOOOX@++oo+ o +@+++o..XXOOO. +..+ oo+ ++XO +++++o +++XOOXX ++++++ @+++++++ ..OOOOOXOOXOXX+@@++++++@@+@@+++@+++@++++@++@+@++++++++.XOOOOO.+++++++.@++@++ XOXOOXOXOXXO oo oo oooo+++oo+ .XOO.+oo+ +oo OOXOX.@++++oo++++.XOXOXXOXX.++++ +++ OOOOOXOOXOXOX+o o++++o o ++++ .XXOXXX.+++oooooo+++ooooooo+ ++XOOXX +++++++ +@++++...XXXXXXXOXOXXOX ++++++@++@++++ ..OOOX.+++ +++++ .. oo XXXXXXX..+++ +++++++..++@ .XOO.. .. +++ + + ++@@@@@.XOOXOXXXX.XX.XXXXO", "OOOXOOOXOXOOOO#X.@oo+++++++.XXXOOOOOO.@+@++oo +o +.O +o+++oo +@.OOOOX+ ++++@+@+. + .OOOOOOOOOOXOXOX ++@++++++++++@+++@+++@+++++ +++++++++..XOOXOOOOX++++++++@+ ..XOXOXOOOOXOOX.oooo o .XOOXO.+ .+ .XOOXOX.+ +oo o+++ XOOXOOXOO.++++++++.OOOOOOOXOXOOOX +o+++++oo+++o .XXXXOOOX.+++oo++++oo +oo o o + XOOOOX +++++++++ .X.XXXXXXXXXXXOXOOXOX+o+o++++++ ..XXOOOOOOO..+ @@+.@+ .X .XOXXXXXXXX..+ +o+++.@@XX .XXOXX+@@@@+++ + +o o o++++@@XOOOXOXXXXXXXXXXXX", "OOOOOXXOOOOOOOO#XX....+..XOOOOOOOOOOOX+++ + @.X o + oo +.+XOOOO#X. ++ +XX.XOXOOOOOOOOOOOXOX. + ++ ++++++ +++++++ ++ +XOOX.+..XXXOOOOOOOOOOOOX.X..++ XXOXOXOOOOXOOOXOX. o.XX......O#OOOOOOOXXXO.OOOOOOOOOXO.XX. +.XXOOOXOXOX++o++++ XOOOOOOOOOOOXOO#. ++ + + + XXXXXXXXOOOOX. + XX...... .+XOOXOOX. +..XXOOOOOOXXXXXXXXXXOXOOOX. .+.XXOOOOOOOOOOOOOX.. +@ XOOOOXOOXXXXXXXXX.. @ +.XOXXXXXO.+++++@++ o o o +@XOOXOXOXXXXXXXXXXO", "OOXOXOOOXOOOOOOO#O#OOOOOOOOOOOOOOOOOOX. .XXXX..X..XO...X.XXXX.XOXXOOOOOOO##OOXX.XOOOOOOOOOOOOOOOOXOOXOXOXOOOOOOOOOOOXXXX.XOXOOOOOOO#O##OOOOOOXOXOOOOOOOOOOOOOXXOXXXXXOXOXOOOOOOXOOXXXOOOOOOO###OOOOOXOXOOOOOOOOOOOOXOXOXOXXOOOXOXOOOOOXOOXOX ooooo+X#OOOOOOOOOXOXOOOOOOXX......XXXXXXXXOXOXOOOOOXXXX.XOOOOOOO#O#O#OOOOOXOOOOOOOOOOOOOOOXXOXXXXXXXOOXOOXOOOOOOOXOOXOXOOOOOOOOOOOOOOOOX.XXOOOOOOOOOXXXXXXXXXXXOOXX.XXOOOXXXOXOX @+++..XX.X.X.XX.X... XOOXOOXOXXXXXXXXXOX", "OOOOOOXOOOOOOO#OO#OO#OOOOOOOOOOOOOOOOOOOOOOOXOOXOOOXOOOOOOOOOOOXOOOOOOOOOOO#OO#OOOOOOOOOOOOOOOOOOOOXOXOXXXXOXOXOOOOOOOXOOOXOOOOOOOOO#OOOOOOOOOOOOOOOOOOOOOOOXOXXOXOXOXOOOOOOOXOOXOOXOXOOOOOOOOOOOOOOOOOOXOOOOOOOOOOOOOXOXXOXXXOOOOOOOOOOXOXX.+oooo.#OOOOOOOOOOOOOXOXOOOOOOOOOOOOXOXXXOXXOXOOXOOOOOOXOOXXXOOOOOOOOOOOOOOOOXOXOOOOOOOOOOXOOXXXXXXXOXXOXOOOOOXOXXOXXOXOOOOOOOOOOOOOXOXOXOOOXOOOOOOXOXOXXXXXXXOXOXOOOOOOXXOXOXOXOXXOOOOOOOOOOOOOXOOOOOOOOOOOOOXOXXXXXXXXXX", "OOOOOOOXOOOOOOO#O##OOOOOOOOOOOOOOOOOOOOOOOXOOXXOXXOOOOOOOOOOOOOOXOXOOOOO#O#O#OOOOOOOOOOOOOOOOOOOOOOOXOXOXOXOOOOOOOOOOOOOXOOXOOOOOO#OO#OOOOOOOOXOOOOOOOOOOOOOOXOXXXXOXOXOOOOOOOOOOXOOXOXOOOOOO#OOOOOOOOXOOOOOOOOOOOOOOXOXOXXXOXXOXOOOOOOOOOOX@oooo.OOOOO#OOOOOOOXOOOOOOOOOOOOOOXOXXOXXXOXXOXOOOOOOOOOXOXOOXOOOOOOOOOOOOOOOOXOXOXOOOOOOOOOXOOXOXXXXOXOOXOXOOOXOXOXOXOXOOOOOOOOOOOOOOOXOXOOOOOOOOOOOOXOXXXXXXXOXOXOOXOXOOXOXXXOXOOOOOOOOOOOOOOOOXXXOXOOOOOOXOOXOXXXXXXXOX", "OOOOOOOOOXOOOOOO#OO###OOOOOOOOOOOOOOOOOOOOOOXOOXOXOXOOOOOOOOOOXOOOOOOOOOO#OO#O#OOOOOOOOOOOOOOOOOOOOOOXOXOXOXOXOOOOOOOOOOOXOOXOOOOOO#O#O#OOOOOOOOXOOOOOOOOOOOOOXOOOXXOXOOXOOOOOOOOOOXOOOOOOOOOO#O#OOOOOOOXOXOOOOOOOOOOOOOXOXOXXOXOOXOOOOOOOX.+ooooXOOOOOOOOOOOOOOOXOXOOOOOOOOOOOOOOXXOXXXOXOXOOOOOOXOXOXOXOXOOOOOO#OOOOOOXOOOOOOOOOOOOOOOOOXOXXXOXXOXOOOOOOOOOOXOXOXOXOOOOOOOOOOOOOOOOOOXOOOOOOOOXOOXOOXXXXXXOXOXOOOOXOXOXOOXOXOOOOOOOOOOOOOOXOOOXOOXOOOOOOOOXOXXXXXXXO", "OOOOOOOOOOOOOOOO#O##OO#OOOOOOOOOOOOOO#OOOOOXOOXXOXOOOOOOOOOOOOOOOXOXOOOOOOO#O#O#OOOOOOOOOOOOOOOOOOOOOOXOXOXOXOOOOOOOOOOOOOOOOOOOOOOO#OO#OOOOOOOOOOOOOOOOOOOOOOOOXXOXOXOXOOOOOOOOOOXOXOXOOOOO#OO#OOOOOOOOOOOOOOOOOOOOOOOXOXOXXOOXOXOOOOOOOO.@++ooOOOOOOO#O#OOOOOOOOOOOOOOOOOOOOOOXOXOXXOXOXOOOXOOOOOOOXOOXOOOOOOOOOOOOOOOOOXOXOXOOOOOOOOOOXOXOXOXXOXXOXOOOOOOOXOOXOXOOOOOOOOOOOOOOOXOXOXOOXOOOOOOOOXOXXXOXOXOXXOOOOOOOOOXOXXOXOOOOOOOOOOOOOOOOXOXOOXOOOOOOOOXOOXOXXXOXX", "OOOOOOOOOOOOOOO#O#OO#OOOOOOOOOOOOOO#OOOOOOOOOXOOXOOXOOOOOOOOOOOOOOOOOOOOO##O#O#OOOOOOOOOOOOOOOOOOOOOOOOXOXOXOOOOOOOOOOOOOOXOOOOOOOO#O#OO#OOOOOOOOOOOOOOOOOOOOOXOXOXOXOOOOOOOOOOOOOOOOOOOOOOOOO#OO#OOOOOOOOOOOOOOOOOOOOOOOXOXOXXOOOOOOOOXXX+++++o.OXOOOOOOOO#OOOOOOOOXOOOOOOOOOOOOOXOXOXOXOXOOOOOOOOOOOXOOXOOOOOOO#OOOOOOOOOOOOOOOOOOOOOOOOOXOXXXOXOOXOOOOOOOOOOXOXOOXOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOXXXXXXOOXOOOOOOOOOXOOXOXOXOOOOOOOOOOOOOOOOXOOOOOOOOOOOOXOXOXXXXO", "OOOOOOOOOOOOOOOO#O#O####OOOOOOOOOOOO#O#OOOOOOOXOOXOOOOOOOOOOOOOOOOOOOOOOOOO#O#O##OOOOOOOOOOOOO#OOOOOOOOOXOXOXOXOOOOOOOOOOOOOXOOOOOOO#O#OO#OOOOOOOOOOOOOOOOOOOOOOOXOXOXXOOOOOOOOOOOOOXOXOOOOOO#O#OO#OOOOOOOOOOOOOOOOOOOOOOOXOXOXXOXXX.X...+++ooo .OOO#O#OOOOOOOOOOOOOOOOOOOOOOOOOOXOXXXOXOXOOOOOOOOOOOXOOXOOOOOOOO#OOOOOOOOOXOOOOOOOOOOOOOOXOOXXXXOOOOOOOOOOOOOOOXOOOOOOOOOOOOOOOOOOXOXOOOOOOOOOOOOXOOXOXOXXOOXOOOOOOXOOXOOXOOOOOOOOOOOOOOOOXOOOXOOOOOOOOOOOOXOXOXOXX", "O#OOOOOOOOOOOOOOO#O#OOOO#OOOOOOOOOOOOOO#OOOOOOOXOOXOXOOOOOOOOOOOOOOOOOOOOO#O#O#OO#OOOOOOOOOOOOOO#OOOOOOOOXOOOOOOOOOOOOOOOOOOOOOOOO#OOO#O#O#OOOOOOOOOOOOOO#OOOOOOOOXOXOOOXOOOOOOOOOOOOOOOOOOOOOOO#OO#OOOOOOOOOOOOOOOOOOOOOOOXOXOXOO.++++@@+ooo+ooo+ XOOOOOO#O#OOOOOOOOOOOOOOOOOOOOOOOXOOXOXOOOOOOOOOOOOOOXOOOOOOOOOOO#OOOOOOOOOOOOOOOOOOOOOOOOXXOXOOXOXOOOOOOOOOOXOOOXOOOOOOO#OOOOOOOOOOOXOOOOOOOOOOOOOXOXOXXOXXOOOOOOOOOOOOXOOXOOOOOOOOOOOOOOOOXOOOXOOOOOOOOOOOXOXXXXO", "OOO#OOOOOOOOOOO#O#O#O###O#OOOOOOOOO#O##O#OOOOOOOOXOOOOOOOO#OOOOOOOOOOOOOO#O#OO#O#O#OOOOOOOOOOOO#OOOOOOOOOOOXOXOOOOOOOOOOOOOOOOOOOOOO##OO#OO#OOOOOOOOOOOO#OOOOOOOOOOOOXOXOOOOOOOOOOOOOOOOOOOOO#O#OO#O#OOOOOOOOOOOOOOOOOOOOOOOXOXOOX ooo+++oooooooo+ OOOO#O#OOOOOOOOOOOOOOOOOOOOOOOOOOOOXOXOOXOOOOOOOOOOOOOOOXOOOOO#OOOO#OOOOOOOOOOOOOOOOOOOOOOOOXOXXOXOOOOOOOOOOOOOOXOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOXOXXOXOOOXOOOOOOOOOXOOXOOOOOOOOOOOOOOOOOOOXOOOOOOOOOOOXOOOXOXOX", "O#OOOOOOOOOOOOOO#O#O#OOO#O#OOOOOOOOOOOO#O#OOOOOOOOOXOOOOOOOO#OOOOOOOOOOOOO#O##O#O#O#OOOOOOOOO#OO#O#OOOOOXOXOOOOOOOOO#OOOOOOOOOOOOOO#OO#OO#OO#OOOOOOOOOOOOO#OOOOOOOXOXOOOOOOOOOOOOOOOOOOOOOOOOOOO#OOOOO#OOOOOOOOOOO#OOOOOOOXOOXOXOX.ooo+++ . +.OOOOOOOO#O#OOOOOOOOOOOOOOO#OOOOOOXOXOXOXOOOOOOOOOOOOOOOXOOOOOOOO#OOOOOOOOOOOXOOOOOOOOOOOOOXOXOXOXOOOOOOOOOOOOOOXOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOXOXOOXOXOOOOOOOOOOOOOOXOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOXOXOXXO", "O####O#OOOOOOOOO#O#O###O#O#OOOOOOOOO##O#O#OOOOOOOXOOOOOOOO#OO#OOOOOOOOOOOOO#OO#O#O#O#OOOOOOOOO#OO#O#OOOOOOOOXOOOOOOOO#O#OOOOOOOOOOOO#OO#OO#OO#OOOOOOOOO#O#O#O#OOOOOOOXOXOOOOOOO#OOOOOOOOOOOOO#O#O#O#O#OOOOOOOOOOOOO#O#OOOOOOOOOOOO...OXOO####OOOOXOOOOO#O#OOOO#OOOOOOOOOOOOOOOOOOOOOOOOXOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO#OOOOOOOOOOOOOOOOOOOOOOOOXOXOXOOOOOOOOOOOOOOOOOOOOOOOO#OOOOOOOOOOOOOOOOOOOOOOOOOOOXOXOXOXOOOOOOOOOOOOOOXOOOOOOOOOOOOOOOOOOOXOOOOOOOOOOOOOOOXOXO", "OOOOO#OOOOOOOO#OO#O#OOO#O#O##OOOOOOOOO#O#O##OOOOOOOOOOOOOOO##O##OOOOOOOOO#O#O#O#O#O#O#OOOOOOOOOO#O#OOOOOOOOOOXOOOOO#OO#O#OOOOOOOOOOOOO#O#O#O#OOOOOOOOOOOOO#O#OOOOOOOOOOOOOOOO#OO#OOOOOOOOOOOOOOOOO#OOO#OOOOOOOOOOOOO#OOOOOOOXOXOXOOOOO#OOOOOOOOOOOOOOOOOOOOO#OO#OOOOOOOOOOOO#O#OOOOOOOOOOXOXOOOOOOOOOOOOOOOOOOOOO#OOO#OOOOOOOOOOOOOOOOOOOOOOOOXOOXOOOXOOOOOOOOOOOOOOOOOOOOOOOOO#OOOOOOOOOOOOOOOOOOOOOOOOOOOXOXOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOXOX", "O#####O##OOOOOOOO#O#O###O#O#OO#OOOO#O#O#O#OO#OOOOOOOOOOOOO#OOO#OO#OOOOOOOO#O#O#O#O#O#OOOOOOOOOO#O#OO##OOOOOOOOOOOOOOO#O#OO#OOOOOOOOO##O#O#O#OO##OOOOOOOOO#OOOO#OOOOOOOXOOOOOOOO#OO#OOOOOOOOOOO#O#OO#O#OO#OOOOOOOOOO#OOO#OOOOOOOOOOOOOOOO#O#O#OOOOOOOOOO#O#O#OOOOOOOOOOOOOOOOOOOOOOOOOOOOXOOOOOOOOO#OOOOOOOOOOOOOOOO#OOOOO#OOOOOOOOOOOOO#OOOOOOOOOOXOXOOOOOOOOOOOOOOOOOOOOOO#OOOOOOOOOOOOOOOOOOOOOOOOOOOOXOXOXOOXOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOXOOXO", "O#OOOO#OO#OOOO#O#O#O#OOO#O#O##OOOOOOOO#O#O##OOOOOOOOOOOOOOO###O##OOOOOOOOOO#O#O#O#O#O##OOOOOO#OO#O##OOOOOOOOOOOOOOOO#OOO#OOOOOOOOOO#OO#OOO#O#OOOOOOOOOOO#O#O#OO#OOOOOOOOOOOOOO#OO#OO#OOOOOOOO#OOO#OOOOO#OOOOOOOOOO#OO#OOOOOOOOOXOOOOOOOOOOOOOOOOOOOOOOOOOOOOO#O#O#OOOOOOOOOO#O#O#OOOOOOXOOXOOOOOOOOO#OOOOOOOOOOOOOOOOOO#OOOOOOOOOOOOOOOOO#OOOOOOXOOXOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOXOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX", "OO###O##O#O#OOOO#O#O###O#O#OO#O#O#OO#O#O#OO###OOOOOOOOOOO#OOO#OO#O##OOOO#O#O#O#O#OOO#OO##OOOOO#OO#OO###OOOOOOOOOOOOOO##O####O#OOOOOO#OO##OOOO##O#OOOOOOOOOO#O#OO#OOOOOOOOOOOOOO#OO#OOOOOOOOOOO#OOO#O#O#OO#OOOOOOOOO#OO#O#OOOOOOOOXOOOOOO#O#O#O#OOOOOOOO#O#O#OOOOOOO#OOOOOOOOOOOOO#OOOOOOOOOOOOOOOO#OOOOOOOOOOOOOO#OO#OOOOO#OOOOOOOOOOOOOOOOOOOOOOOOOOXOOOOOO#OOOOOOOOOOOOOOOO#OO#OOOOOOOOOOOOOOOO#OOOOOOOOOXOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOXOO", "O#OOO#O#O#O#O#O#O#O#OOO#O#O#O#O#OO#OOOO#O##OOO##OOOOOOOOOOO##O##O#OO#O#OOOO#O#O#O##O#O#OO#O#OOO#O#O#OOO#OOOOOOOOOOOO#OOOOOOO#O#OOO#OO##OO#O##OO#O##OOOOO#O#OO#O#OOOOOOOOOOOOOO#OO#OO#O#OOOOOOOOO#OO#OOO#OO#OOOOOOOOOO#OOO#OOOOOOOOOOOOOOOOOOOOO#OOOOOOOOOOOOO#O#O#OOOOOOOOOOO#O#OO#OOOOOOOOXOOOOOOOOOO#OOOOOOOOOOOOOOOOO#OOOOOOOOOOOOOO#OO#OOOOOOOOXOOOOOOOOOOO#OOOOOOOOOOOOOOOOOO#OOOOOOOOOOOOOOOOOOOOOOOOOOXOXOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO"}; skycat-3.1.2-starlink-1b/skycat/library/skycat_defaults.tcl000066400000000000000000000017511215713201500237740ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # @(#) $Id: skycat_defaults.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # catdefaults.tcl - X defaults for itk catalog widgets # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 20 May 96 created # itk widget defaults (normally you'd put these in the itk sources, but # putting them here makes it easier to "pre-load" the classes for the single # binary version... proc skycat::setXdefaults {} { option add *SkyCatCtrl.canvasBackground black option add *SkyCatCtrl.canvasBackground black option add *SkyCatCtrl.canvasWidth 520 option add *SkyCatCtrl.canvasHeight 520 option add *SkyQueryResult.relief sunken option add *SkyQueryResult.borderwidth 3 option add *SkyQueryResult.font TkFixedFont option add *SkyQueryResult.headingFont TkDefaultFont option add *SkyQueryResult.headingLines 1 option add *SkyQueryResult.titleFont TkDefaultFont } skycat-3.1.2-starlink-1b/skycat/linux/000077500000000000000000000000001215713201500175725ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/skycat/linux/make_rpm.sh000077500000000000000000000012071215713201500217240ustar00rootroot00000000000000#!/bin/sh # These commands need to be run as root to build the skycat RPM dir=/usr/src/redhat test -d $dir || dir=/usr/src/packages if test ! -d $dir ; then echo "Can't build RPM since there is no /usr/src/redhat or /usr/src/packages dir." exit 1 fi if test ! -f skycat.spec ; then echo "skycat.spec does not exist: Please run configure to generate." exit 1 fi version=`cat ../VERSION` src=../release/$version.tar.gz if test ! -f $src ; then echo "$src does not exist: Please run 'make release' to generate." exit 1 fi (cp $src $dir/SOURCES/ && cp skycat.spec $dir/SPECS/ && cd $dir/SPECS && rpmbuild -ba skycat.spec) skycat-3.1.2-starlink-1b/skycat/linux/skycat.spec.in000066400000000000000000000040151215713201500223510ustar00rootroot00000000000000Summary: FITS Image Display and Catalog Search Tool for Astronomy Name: skycat Version: @PACKAGE_VERSION@ Release: 1 License: GNU General Public License Group: Applications/Engineering URL: http://archive.eso.org/skycat/ Source0: %{name}-%{version}.tar.gz Requires: tcl, tk, itcl, tclx, blt, tkimg BuildRequires: %{_includedir}/tk.h, %{_includedir}/tcl.h BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root %description SkyCat is a tool that combines visualization of images and access to catalogs and archive data for astronomy. Note: There is also a Java version of Skycat called JSkycat available as part of the JSky package. Authors: -------- Allan Brighton (abrighto@eso.org) Thomas Herlin (therlin@eso.org) Miguel Albrecht (malbrech@eso.org) Daniel Durand (durand@dao.nrc.ca) Peter Biereichel (pbiereic@eso.org) %prep %setup -q -n %name-%version %build export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing" mkdir build cd build ../configure \ --prefix=%_prefix \ --exec-prefix=%_prefix \ --libdir=%_libdir \ --mandir=%_mandir \ --with-tcl=%_libdir \ --with-tk=%_libdir make %install cd build make install DESTDIR=%buildroot %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root,-) %doc CHANGES COPYING README %{_bindir}/skycat %{_bindir}/rtd %{_bindir}/tRtd %{_bindir}/rtdServer %{_bindir}/rtdClient %{_bindir}/rtdCubeDisplay %{_libdir}/tclutil@tclutil_VERSION@ %{_libdir}/astrotcl@astrotcl_VERSION@ %{_libdir}/rtd@rtd_VERSION@ %{_libdir}/cat@cat_VERSION@ %{_libdir}/skycat@PACKAGE_VERSION@ %{_libdir}/@tclutil_LIB_FILE@ %{_libdir}/@astrotcl_LIB_FILE@ %{_libdir}/@rtd_LIB_FILE@ %{_libdir}/@cat_LIB_FILE@ %{_libdir}/@PKG_LIB_FILE@ %{_libdir}/librtdImgEvt.a %{_libdir}/librtdRemote.a %{_libdir}/tclutilConfig.sh %{_libdir}/astrotclConfig.sh %{_libdir}/rtdConfig.sh %{_libdir}/catConfig.sh %{_libdir}/skycatConfig.sh %{_includedir}/tclutil %{_includedir}/astrotcl %{_includedir}/rtd %{_includedir}/cat %{_includedir}/skycat %changelog * Mon Jan 30 2006 Allan Brighton - - Initial rpm build. skycat-3.1.2-starlink-1b/skycat/mac/000077500000000000000000000000001215713201500171735ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/skycat/mac/Info.plist000066400000000000000000000015661215713201500211530ustar00rootroot00000000000000 CFBundleDevelopmentRegion English CFBundleExecutable skycat CFBundleGetInfoString Skycat 3.0, © 2006 ESO CFBundleIconFile skycat CFBundleIdentifier org.eso.skycat CFBundleInfoDictionaryVersion 6.0 CFBundleName Skycat CFBundlePackageType APPL CFBundleShortVersionString 3.0 CFBundleSignature MOZM CFBundleVersion 3.0 NSAppleScriptEnabled skycat-3.1.2-starlink-1b/skycat/mac/PkgInfo000066400000000000000000000000111215713201500204430ustar00rootroot00000000000000APPL???? skycat-3.1.2-starlink-1b/skycat/mac/skycat.icns000066400000000000000000001660711215713201500213620ustar00rootroot00000000000000icnsì9ICN#p¿ðÿðÿðÿðÿð ð7 ðððððððÿðÿðÿðWÿúô?ÿsÿþÿÁþc>ùøÿÿøÿÿøÿÿøÿÿøÿÿøÿÿøÿÿøÿÿøÿÿøÿÿøÿÿøÿÿøÿÿøÿÿøÿÿøÿÿøÿÿø_ÿÿúÿÿÿÿÿÿþÿÿþ>icl4ÌÌÀÌÌ ÍîÜÌÀ ÍîÀÍÝÝÞîîÝÝÝîÿþÀÍÝÞîîîÝÝÞîïúÀÍÝÝîîîÌÝÝîîþÀÍÝÝÝîîÌÝÝîîúÀÍÝÝÝÝîÜÝÝîîþÀÝÝÝÝÝÞÝÝÝÞîúÀÝÝÝÝÝÝÍÝÝÞîþÐÝÝÝÝÝÝÍÝÝîêúÐÝÝÜÌÍÝÌÝÝîîþÐÝÝÜÌÌÝÌÝÝîêúÐÝÝÜÌÌÝÌÝÝîîþÐÝÝÝÝÝÞÜÝÝîêúÐÝÝÝÝÝÝÝÝíîêþÐÝÝÝÝÝîÝÜÌÞ¯úÐÝÝÝíÞîÝÀ ÞªúÐÝÝÞîîîÜÌÜïþÐ ÞîíîîÞÐ ÌÜïþàðÿýÝÜÍÝÞíÐ ÌÌÞ®ïÿýÍÞÿÿîÝÜ îíïðÿÿÿÿÿÿÿý ÿÿÿðìÌïÿÿðicl8õõõ+øõõö÷÷÷ø÷öõõ+øúûüVø÷+öõöøúü¬øøùúúúùüüüüüVVùùúû¬ýþêýøøùùúúûûûüüüVVùùúü¬¬ýþýøøùùúúûûûûûûøøVùúü¬ü¬ý¬øøùùúú€ûûûøøVùúûüü¬þýøøùùùúúúûûVøVùúûûü¬ý¬øøùùùùú€úúûVVVùúùúûü¬þýøøùùùùù€úzúøVVVùùúüü¬ý¬VVúùùùVVùzz€ú÷øVVúûü¬ýþýVøùùùùUU÷øùùú+÷Vùúúûü¬ýý¬VVúúùùUø++øùú÷÷Vùúû¬¬ýþýVVùùùVUU÷÷øúúOOVùúûü¬ýýýVVúúúzVVøøùúVUVúúü¬ýýþýVVúúúzùzzzúVVVú€û¬¬ýýýVVúú€€€ûûøùzU÷ø¬ýýþýVùúúúûûûùVöõöUûýýþýVõVûûûûüûùöõ+1UU¬þþýùÿúVûûûúûüüûüùõõ+1UU+ûêþýüÿÿÿÿúVúVøøùúúúûüVõõ*÷1÷öúüý¬üÿÿÿÿÿú+V¬þÿÿþ¬ûVöõö¬üûúüÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿþþúÿÿÿÿÿÿÿÿûO*Oûÿÿÿÿÿÿil32Ðÿÿ¾ÿþøùôç€ÿ÷ïàÇ­èùû÷ðÿÿûöìÙ¾¹ƒÿü¯¨¾ÓáêðÍ wSIž«°ÃÕçðÕ¥sE=¯ƒÿü¡~yv{†gKD@AKž›‡}noX0+­ƒÿü¡~xn_NOPKHMžœŒr^<0)'©ƒÿü¤…ypgXSYTMR¤¡…qaE>=+.¨ƒÿü¡~{vo``_[QW¢¤“†uiTKE1)¥ƒÿü¢„ƒ|tkgff`YT“¦—‰xkWNE6,¢ƒÿûŸ~|~uhqqi_^‘˜—‰y…vQD0* ƒÿüŸ‚~€‚vrxsgh§‘•”}…pKA..žƒÿüœ}}~‚‹Šˆ|{on¶œŠ”}kQB3&*œƒÿûœ€†’—«¤…wt¸¬ˆ„}nTB4(,šƒÿü˜y||…•¢¾Ã¢xu¹¯‘{wjQ>0#*—ƒÿû˜{||†“·¼¦|pª¯šrhP@2',–ƒÿû“tvw‹Šš„u_ˆ™’}ofK;+"(•ƒÿû“stpu€y|}p`f–…‡y^gL;/$*“ƒÿûlmlfmnjgbWX™|œ·¢^/'&“„ÿ‹jjkjdZb]UQP„’ÝäøÜ’V%"%˜ƒÿæŒ``a`]OLUQDL…Ðÿêʳ¡3+‰ÿÿyZUU_oXF@HXF…ïîɱŸ•ÆP,Lÿÿ€q–y•¨¬Œy~mQHXŠæãʽ²¸ÚuC'6G€$ÿpË–o?>Wcl“ÕýæáâõÞ?L^vHÿÿ†bÿýu ÿQ¯Ä¤K—ÿÆÿÿÿ¾ÿþøùôç€ÿ÷ïàÇ­èùû÷ðÿÿûöìÙ¾¹ƒÿü°¨¾ÔâêðÍ¡wUIž¬¯ÄÕçðÕ¦tF>¯ƒÿü¤‚}y~ˆjLJDFMŸž‰nr\4#/­ƒÿü¢ƒ€|rdUTULKMŸž‹ƒscA80")©ƒÿü§‰…|sj\U_XSU¦¥’‰pbHBB3"1¨ƒÿû¤„€~|ygdc[TY£¥’‡umYPI6+¥ƒÿü¥‡‡xtrjne_Y©˜ymXRI<$0¢ƒÿû¢€ƒ|t|vmd_–Ÿ–Šx…UF5+ ƒÿû£††…†Š~}…ynl«œš›†rOE4!1ƒÿûž‚‡“”‡†ws»¢•›~lPD7(,œƒÿû „…‡ £²©‚yÀ´Œ~rVE9-!0šƒÿûš|~¢«ÃÄ¥ƒ¾´’…xkP?2&+—ƒÿûœ€‚‚‘£¨½¾«}·´†|lSB6, /–ƒÿû•vy}ˆ˜–¢£Œ|c–¥”woL<.%*•ƒÿû—xy{„ކˆˆwjm™–‘}axR=4) .“ƒÿûnppkz{rog\_¢‡Š¦¶§g1* '“„ÿŽnprpjcmf[WSŠ—ÝíøØŒX+''˜ƒÿæcbfcbSQ_XJPˆÓÿèÆ­‰Ÿ5.‰ÿÿy’^Z\fv^JEPfJ„ïíÆª™ÄR.Lÿÿ€qš{˜ª¬Œz~pRNg‘äãȵ«°ÖuF*8G€$ÿpË–o?>Wbm›×ÿåÚÛðÜ>M^vHÿÿ†b‚ÿy ÿS¾Û¹R—ÿ Æÿÿÿ¿ÿùùôç€ÿöïàȰêùû÷ðÿÿûöìÙ¿ºƒÿü³«ÁÖãëðЦ{\M ¯°Æ×êðØ©xKC¯ƒÿü¨„€}‚ŽqRRIKP¢¢‹ƒova:)"3­ƒÿü¥…ƒxj][\OOP¡¡…tfE91$,ªƒÿü«ŒŠxpd\e\YY©ª•rcH=@3&6¨ƒÿü§†„…ƒ„pki`Y^¦©”‰wpWOG4.¥ƒÿüª‹Œˆ~~rwnh`¦­›‘zmTPH;&5£ƒÿü¦…†‡‹†‚‹ƒypf¦˜Žx~‡WC2 / ƒÿü¨‹ŒšŽ–‡}x²§ž˜nNE4&6žƒÿü£ƒ†‰’¥¦š”“‚}뜕}oOA6*/œƒÿü¦ŠŒž´²¶¨•Ž‚Ê¾›•vYH<1'5›ƒÿüŸ„‰œµµÁÁ¢ŠŠÇ¿™{mSA4)/—ƒÿü¡†‰Œ¡¶³¼»ª„‹ÇÀ¥„qXE81%3—ƒÿüš{€‡–¬¥¨¤†l§µ›„yN=0)-•ƒÿû~€‚‘¡—–“wz£¦„i‡V?9.$1”ƒÿû•rvvtˆ‹~uhk®Ž›·Àºz2.$+”„ÿ“tx{ytn|ufb[’¨æôýë¹h.+!*˜ƒÿç•fhmkiZYkbRW’àÿïÜ̹¼92Šÿÿz—cadogQKYsOöõÞÍÀ¹Ý]0Lÿÿ€q €ž¯°|vWUs£òñâ×ÐÔê„I/=H€$ÿpÍ—o?=Wdn¦æÿôóóþåEL_xIÿÿ†f‚ÿz ÿWÈëÈ[—ÿÆÿl8mk^°i2 V’ÔÖšc-At»juÿÿüÞ¨s‡ÆôÿÿÿÿÿÿúÛ¢½ëþÿÿ€uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€wÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‚3žÿÿÿÿîÍÛûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¦4G´ôα”|puˆ¦Ääüþþÿÿÿÿÿû¶µÓú»Iÿÿ@þ?ÿÿàü00@à€€øðøÿÿ¿àÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿàÿÿÿÿà'ÿÿÿÿôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿþ?ÿÿÿÿü?ð@à€ich4ˆÌÌÌÌÀÀÌÝÌÌÝÀÍÜÌ ÝîîÝÝÌÀ ÍêúÀÍÝÝÝÍîîîîÌÝÝÝÝîÿÿþÀÍÝÝÝîîîîîÌÝÝÝîîîïþÀÍÝÝÝÞîîîîÜÝÝÝÞîêÿúÀÍÝÝÝîîîîîÌÝÝÝîîêïþÀÍÝÝÝÞîîîîÌÝÝÝÞîîêþÀÍÝÝÝÝíÝîîÌÝÝÝÞîîïúÀÍÝÝÝÝÝÝîîÜÍÝÝÞîîïþÀÍÝÝÝÝÝÝÝîÜÍÝÝÞîîê®ÀÍÝÝÝÝÝÝÝîÝÝÝÝÝÞîïúÀÍÝÝÝÝÝÝÝÝÍÝÝÝÝîî¯þÀÍÝÝÝÝÝÝÝÝÌÝÝÝÝîîêþÀÍÝÝÝÝÝÝÝÝÌÝÝÝÞîîïúÐÝÝÝÝÝÜÝÝÝÌÍÝÝÞîê¯úÐÍÝÝÝÌÌÍÝÝÌÍÝÝÞîîêþÐÝÝÝÝÌÌÌÝÝÌÍÝÝÞîêïþÐÝÝÝÝÌÌÌÍÝÌÍÝÝÞúÐÝÝÝÜÌÌÌÝÝÌÍÝÝÞîîêþÐÝÝÝÝÝÜÍÝÞÜÝÝÝîîêïþÐÝÝÝÝÝÝÝÝÝÝÝÝíÞúÐÝÝÝÝÝÝÝÝÝÍÝÝÞÞîîêþÐÝÝÝÝÝÝÝÞíÌÝÝÝÝîï¯þÐÝÝÝÝÝÝÝîîÝÝÌÍê¯ÿúÐÝÝÝÝÞÝÞîîÝÐÌÞêïúÐÝÝÝíîîÞîîÝÀÌÍݯ¯þÐÝîíÝîîîîîÝ ÌÍÜïÿúÐð ÝíîîîîîíîÜÌÌÍÌßÿúßÿÿüÞîíÜÍÞîîÝÜÌÌÌÀßÿþßÿÿÿÿüÝÜÌÍíÝÝîíÜÌÌÌÀÝÞ®ßÿÿÿüÍïÿÿÿîÝÝÜ îÝÝßÿðÿþêÿÿÿÿÿÿÿíÞÀ ÿÿþïÿðÿÿÿÿÿÿÿÿÿÿÿÿàÏÿÿÿÿÿððþÀÍÿþîïðÿÿðich8 öö++õõö+÷÷öõõöõõ+øù÷öõõõö÷Vù÷øùVø+öõõ+øúû¬¬¬VVVVø÷+õõ+øúüýþý÷øùúúúúúVøùûüüü¬üüûøøVùùúúúúûýþþýþþ¬÷øùùùùùûüüûûûûüüüøøVVVùúúû¬ý¬¬ý¬ýþ¬øøùúùúúúúûûûüüüüüVøVùùùúúüü¬¬ýýþþýøøùùùúúúûûûüûûüüûûøøVùùúûü¬¬¬ýýþþ¬øøVùùùùúúûûûûûøøøVVùúúüüûûü¬ýý¬øøùúùúùúz€ûûûûøøVVVùúúûüüü¬¬þþýøøùùùúúúú€ûûûûøøøVVùúúûüü¬¬¬ýþ¬øøVùùùzùúzú€ûVUøVVùúúúûûüüüýý¬øøùúùùùúùúzúúúûVVVVVùúúúùüü¬¬þþýøøùùùúùúùú€úzúúøVVVVùúúWùûüü¬ýþþýøøùùVùùzVùzzúzzú€÷øVVøVùùúûûü¬¬ýý¬øøùùùùùùVVVVùùzùúúú÷÷VVøVúúûüü¬ýýþþýVøùúùúùùVVVøøVùzúúú÷+øùVùúúûü¬¬ýýþþýVøùùùùùùUUUø÷÷Vùzúú++÷VVùùùúûûü¬¬¬ýý¬VøùúùúùùUUU÷++÷Vùzú++øVùzúúûüü¬ýýþþýVVúúùúúùVUU÷++÷øù€z÷÷øVùùúúûü¬ýýýþþýVøùùùùzVUUU÷÷÷÷øùzO÷÷øVúùúûüü¬¬¬ýý¬VVúúùúùzVVVøøøVVùúûVUøVVúúzûüü¬¬ýýþþýVVúúúúzúVVùVVVùúúùVVùùúzüü¬ýýýþþýVVúúùúùzzzzzzzùúøùVVVúzûüü¬¬¬ýþýVVúúúúú€z€€€€úûøUúVzùùúz¬¬ýýýþþ¬VVúúú€€ûûûûVøúùOö+yüýýþýþþýVVú€ú€ú€ûú€ûûûûûùùVõõõõöUùûýýýþþýVVúûûüû€ûüûûûVùöö+÷UUVýýýýý¬VõùûûûüüûüüüùVõö÷1UUU+üþýþþýVÿøVûûûüüüûüû€üüú÷õö+1UUUUöþýþþýÿÿÿÿÿÿÿøVûûûù÷÷Vúûüü¬û€ú+õö+÷UUU÷õêþþþ¬ÿÿÿÿÿÿÿÿÿÿøVúV÷öö÷ùûùVVúû¬¬úz÷õõö*++++öõùú¬ý¬ÿÿÿÿÿÿÿÿÿ÷õ+Vûþÿÿÿÿÿþ¬ûúùúø+õ*õö¬üúùùùúÿÿÿÿÿÿÿÿûûýÿÿÿÿÿÿÿÿÿÿÿÿÿþ¬ùüöøÿÿÿÿþüüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿû+ýÿÿÿÿÿÿÿÿÿÿÿÿÿÿü+*zþÿÿÿÿü¥¥ýÿÿÿÿÿÿÿih32¢ÿÿÿÿþÿþÿýôˆÿÞØÍÅûÿþùô†ÿäáÙϾº†ÿþÝåõûøíÝ€ÿ÷õîáɨƒi¸ÒâðûüøòåÿüùöíÚ¾œƒ´‡ÿ%þ¤‰”ªÁÛìñõüåÄžsV>8@——–¥»ÏåôüìΤvL''²‡ÿ%þªˆ{pu{–§…]CA?>BEN¡¦˜‰ƒwin{yO,6±‡ÿ%þ¨Š‡‡}zjdSFHNTMMJDK ¢™‘ƒukR4*-+')1¯‡ÿ%þ§…ƒywqrcYSQRLIIGKŸ¢–Œˆ€ro`G:2* +¬‡ÿ%þ§ˆ‚‚yvmn^VQOVTNKLS¦§šŠ}qj\A864%&.«‡ÿ%þª††}vse[\X^\WSMQ¤¨”Ž„xrdMGKK=1#3©‡ÿ þ¦†‚{{rzmb_€`WROZ£ªŸ“ŽƒwpfZMHE=.,¨‡ÿ%þ§‡‚„yxsmnabbcb\XRW–«¢–‘‚urhUOF@:0.¦‡ÿ%þªŠ„‡~{vfpiikfa]WRŠŸ¤š•‡{zq]ZQGA7% 4¥‡ÿ þ¥„~}~{~sbs€pe`[]•Žœ˜‘…}w~u^ME>0,£‡ÿ%þ£…z~{€{mjwwvmg_d§’™“ˆzw QJA7)/ ‡ÿ%þ§‡„‡€‚†„zpzxtldi³¤Š’œ—‚|wfQLB70#5 ‡ÿ%þ¢ƒ}€‰Œ‡‹‚x}zrgn·´ˆ™–ukVIB7,)-ž‡ÿ%þŸ{}{Œ’— ’€xloº· „‰ˆzviTD;/%%,‡ÿ%þ£„‚ƒ€„„•”¥²´œ‚}sv¹¹©‹‚…ylXKC8., 2›‡ÿ%þŸ{~|ƒ—œ°À¹”zsp»·ª˜~}ysiVI>3('.š‡ÿ%þœ{y|w|Ž—±Ãº¨€nw¸º©›‡ytsdQB9.%#+™‡ÿ%þŸ~{…–—¨¸¼±ž‰dw ´«•xureVJC7,-"2˜‡ÿ%þ›xxzwz|Š‹˜£¨—…~kUˆ˜Ÿ•Œylu\OC<0#&,—‡ÿ%þ—truqyw„ˆ€†Ž‘†rpeb‰Šˆ{a^NC7, #*–‡ÿ%ý™wvysqrwyy{wn^ae¦†‡†ˆxc_yLD<4+) ,–‡ÿ%ý™sprmm`luoonmhe]Qa£›v€x…Šu{\86+!0–‡ÿ%þ‘niminkedlidf_\ZROŠ—~‚¤ÒûñÈ@,'&•‡ÿ%ý’ljnlmkndTbf[XVSMQ‰ƒéðÓïçÝ „K(%'(•ˆÿ$‘meead_e_SKSbTJKIP’‚ÛÿýðÞ˹–œ%!-˜‡ÿ%ïŽb`_]``b_SOEGXQAAJƒÿûíÕ¾³¦ŽÄ@(’„ÿ-ÿÿ«™`]a][SXSHGHI>PlB@xºÿïÞÁµ«ž‘£Öe,kÿÿÿ‚&§—]VVUl†±¸‘qSG=1JkXtÉóèÒÁµ­£»âe2i†&§•s”»ÓÚ¿Z`†™’|\;6bv»æêØÍÈÄÀÁ×à…yb:!0jÿ³ñáÆ•[7_|Š|fš¸âúîáàßàæøÚ!¦ÿ‚ÿÿšÿÿÿÿÿþÿþÿýôˆÿÞØÍÆûÿþùô†ÿäáÙϾº†ÿþÝåõûøíÝ€ÿ÷õîáÉ©„i·ÓâñûûøñåÿüùöíÚ¿ƒ´‡ÿ%þ¤Œ“«ÂÛìðõüåÄ sU?;>”Ÿ–”¦¼ÏæôüìÎ¥wO)&²‡ÿ%þ®~pw|˜¨‡_AEB?EMP£¬šˆ†wfq|yR/!9±‡ÿ%þª‰ƒ‚mhUKLS^TQMIK ¦›““‡xrT5/53.2$2¯‡ÿþ§ˆ~†{|uzhc[SYMG€Jž¥–‰‰qteLB92%#*¬‡ÿ%þ©Œƒ…yymq_ZTOZUONRV©­œŽ{mkZ@=97*.0«‡ÿ%þ®“‰ƒ„{ygbc]gbZXUR¤®¢—•ˆyxfOPPQC<)'6©‡ÿ%þ¦ˆ~†}€t‡yle`ebUSS[£¬žƒtrh`QKI?4,¨‡ÿ%þ©‹‚‡z|sq{ieahd]\X\¡­£•”€prfTOI?96!0¥‡ÿ%þ®’ˆŽ†‡‚~l‚sovngfbV•«§œœ‹}vc_YMGB-)8¤‡ÿ%þ¦†}†€ƒ~„yj„vxugc`]•œœ”•†{{|€hPJ@6,£‡ÿ%þ¥ˆ€‚{|…sqƒyokef¨šœ”–‰wy–VHA5// ‡ÿ%þªˆ†Œ‡’Ž‹ƒzƒ{uln¸ª˜š§¡ˆ„{jZRI>:)&7 ‡ÿ%þ£†€‡€‡„‘“‘•ˆ€xpq¹º“•¡œylUMG>0/,ž‡ÿ%þ z|„‚’𛡦—ŠŽts¾Á¡‹–‡vxgPD:1$(,‡ÿ%ý¦Œ‡‹†Ÿ¤¢®¹ºŸŒz{Àı‘Š€€q[PG>33%&5›‡ÿ%ý¡ƒ|„…Šœ¤¦¸ÅÄ»—…‚uÀÀ®™…ŠwxiUK@5*,/š‡ÿ%þ}x€xˆœ¤¦¸ÆÂº«ƒy‡»¿ª›‰‚wudQC8.%'*™‡ÿ%þ£‰ƒŠ‚Š’ ¥¢±¼¾µ£i‰³»²¢}ƒ{lZOG=26''6˜‡ÿ%þ}y{€…–™–¡ª­„pY™¬£˜’yq‡\MC=3%,-—‡ÿ%þ™vqys†‘“’–˜Œw{meŠœ›Ž{^gMD7, '*–‡ÿ%ý›}{‚yƒ“Œ…‡†‡‚tenk§‹œ”~fg‘QH@:01%-–‡ÿ%ýypxpsbw…zxwxpjcYl¬¥z“ˆ„Šu…j87."&3–‡ÿ%þ‘pgqirnkm|sflc_]VP’ ~¸ÜúðŃA.(#&•‡ÿ%ý•plwrwsyj\psg_ZXUR‹Ž“æóàîåÙ™€Q.*.)•ˆÿ$•ugkdj_h`WNZr[NRRU˜ŠÜÿýïÛÈ³Ž‹( & %0˜‡ÿ%ïe^b^fdhfZSELcZCEK„žÿûìÒ¹¬ ‡ˆÂA (’„ÿ-ÿÿ«še]ideZaWONLQBYJ?x¹ÿîܾ¯¥˜Š Õf$,kÿÿÿ‚&§›f[\Xo‡³¹“rTM@4S~ewÆòçÑ¿±§ž•µàe5i†&§—u“½ÔÛ¿Z`†™“}\<9p‡¹äìÚËÀº··ÑÞ„zc;#1jÿ³ñâÆ”Z7_|Š}e£ÃáûñܨרàõÖ;Lp†ˆŒsÿÿ€]_ ˆ?h€LÙÿýòððóûÿ®€HB€€ÿ•Zøÿýþ€ÿÆ ‡…ÿ‹ÿ€ÿ MËôûôÜ‚ÿžÿ A[R+¦ÿ‚ÿÿšÿÿÿÿÿþÿþÿýóˆÿÞ×ÍÇüÿþùô†ÿäáÙϾº†ÿþàè÷üøìÝ€ÿ÷ôîâË®ŠnºÖåóüüøñäÿüøöíÛ¡ˆµˆÿ$§Ž–°ÆßïñõýçǦz[EA=”¢—•«¿ÓéöþîÓª}V-*³ˆÿ$±€‚r{ž­fEMGBJST¥°ˆ‰weu€Y4&$>²ˆÿ$­’’‡ˆrnZRSYg[VROM¡©•˜ŠyvV72;:39)$6°ˆÿ$ª‰ˆ~{olcXbQIMOKŸ©˜ŠŒqvhRF82%'.­ˆÿ$­„‰{~qvd`[TaXSRXZ­²Ÿ’}mnYA:43&0#4¬‡ÿ%þ²—“‰Œ‚mkmeoh`^\T¦³§š›Œ}~hNOPQB>,-:ªˆÿ$ª‹Š‚†z’„vnfmfYWX_¦¯Ÿ’„tvk_OIF<3/¨‡ÿ%þ¬…‹}‚xxˆtmgojcb`c«°¥––€ntdMKF<45 !4¦‡ÿ%þ³—•Їt“xƒyrpl[Ÿ¶¬ ¢„u`aYMEC//=¥‡ÿ%þ©‰€Œ…‹…Žƒv–ƒ‡‚snjb™¨ •™‰{}q‰xLI=5/¤‡ÿ%þªŒƒˆ€ˆƒ‹ƒ~•އ|xro®£§•˜‰vz‡\C>0. 3¡‡ÿþ¯•˜Ž–‘€ •‰¡’Š„{y²¥¢§™ˆŠzdVRI=>.,<¡‡ÿ%þ§‹ƒŽ†¡¦¥¦“ž„{yÁš ¡’~mULC;.4! /Ÿ‡ÿ%þ¥†}‡€Œ£¬¬­­œ‘›ˆ|ÆË¨“ ‡wzgOE:2%,/ž‡ÿ%þ­“”Ž˜›²¸³·¹¸’šƒ‚Ëм— ‘„‡t^UJB6:+,:œ‡ÿ%þ§‰€Œ†—°¶³»ÁÁ¸”}É˺Ÿ•x|jWN@7,2"#2›‡ÿ%þ¢{‡}ˆ”¯·²»Â¹¨„„•Å˵¡Ž‹}weSF8/&+-š‡ÿ%ýªŠ”Œ– ´¸°·ºº³£’q˜Èʾ¬§ƒŽƒr_TJA7=--:™‡ÿ%þ¢‚~ˆ‚Ѝ¬¥ª¬¬—‹z`ªÂ® ›}y–_OG?5)1"#1—ˆÿ$zsx“Š¢¦ŸŸžŸ‘}‡yo“®­””` rOG7.$+-—‡ÿ%þ¡„€Š…¦Ÿ˜˜”•p|w²•¯¤˜„jm¤WLB?67*$0–‡ÿ%ý£t€vzi„–‰‡…ˆ~woeyº±€¤š’š…šy793&,$7–‡ÿ%þ–ujwnzvtx„t{qkiaX«ƒ‘ÎêÿùÞ±M/,'(–‡ÿ%þšuq€{‚}…tfƒumfc_Y‘™¨òõéôïèéW3/4 -–ˆÿ$œ|kqjrfqg_UcfV[\]žšìÿûòèÝй¼¯,$,$*4™‡ÿ%ï”haibnkroc[KSodILQ‰¯ÿûðäÔÌĵµÙH#*“„ÿ-ÿÿ¬Ÿiaqlobl_XWSYHbSB€ËÿóëÚÏÈÀ¶Ãës )/lÿÿÿ‚&¨ k^c^xº¾™yZTF7[q‚ÚúòèÝÒËÅÀÓóv%!9k†&¨œz—ÂÙÝÀZ`†›–‚aA>~šÎõôìåÞÜÚÜéî—|h?(5kÿ´õäÇ”Z 7_|Œ€gªØõü÷ò€ñ ôýæDKp‡Šsÿÿ€]_ ˆ >hOäÿþý€þÿÿ²€GB€€ÿ•[ûÿ€þÿÿÆ!‡…ÿ‹ÿ€ÿPÔ€ÿïŸ"‚ÿžÿJkd3¦ÿ‚ÿÿšÿh8mk {ŠNRŽÏÒ–^*+\•²ÿÿï½J?y¹îÿÿÿÿÿÿ÷Ñ•^* 2e›Ô÷ÿÿ¿ªÿÿÿÿÿÿì·ƒ£âþÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ѯÛúÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸!¶ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÂ%  'L_ÌÿÿÿÿÿöÜ»™¯ÔñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕbN* HlÜÿùáŦˆzssry…¢ÂáúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ²ÏëüÿäpJ (L““p`XVYZZZ[[[YYar–¼¿»üÿÿÿÿÿÿÿÿåoTZdw›O)  +œÿÿÿÿÿÿÿñm ŽíÿÿÿÿÚiPª¦€;  ics#H<<<<<<_ÿðþþþþþþþþþþÿÿðics4ˆÌÀÍÌÍÀÝÞîÝÞúÀÝÞîÝÞîÀÝÝÞÝÞîÐÝÝÝÝÞîÐÝÜÍÍÞ®ÐÝÜÍÍÞªÐÝÝÝÝުРÝîîÐͪÐÝÝîÀÌî úêÿ®Ð ®ÿþßics8öööõ÷ù+öõõ÷ù÷VúúüüVùúüýýøVúúûûûøùü¬ýøVùú€VVú¬ýVVùùùùúøVúû¬ýVVúV÷øù÷VúüýýVùúVøøúUùüýýVùúúz€VVVüýýV÷ùûûûøõ*\ýý¬ùúúûû+õ1÷ü¬ýÿýûýÿÿý¬ú+ý¬þÿÿüúþis32<®ÿüÒÓÞ㲆ÅÖàå´†²ÿÿú”|y\GF”‰qF!¨ÿÿû—zjYUVžjF0)£ÿÿû–|tjg]–’{^8*žÿÿú”|„wpŸ~V-*šÿÿúz¬£{¯‹qI((—ÿÿúŒvˆ£¡sœ‰eE'(“ÿÿü…lrul`‡’H %—ÿÿ.¹‚`_URKžåÍ‚#%mÿÿ?‡yyaRRÃè²¾M.'ÿ"Y.%5zñüÀ'3…ÿIh‘ÿ®ÿüÓÔÞ㳇Å×à嶈²ÿÿû–{`KH•ŠsJ%$§ÿÿû™}p_XY ŽlJ6-£ÿÿû™{tla›“}c@þÿÿÿÿÿÿÿÿÿÿÿE@þÿÿÿÿÿÿÿÿÿÿÿE@þÿÿÿÿÿÿÿÿÿÿÿE@þÿÿÿÿÿÿÿÿÿÿÿE@þÿÿÿÿÿÿÿÿÿÿÿE@þÿÿÿÿÿÿÿÿÿÿÿE@þÿÿÿÿÿÿÿÿÿÿÿE@þÿÿÿÿÿÿÿÿÿÿÿE^ÿÿðôÿÿÿÿÿÿÿÿcTkSXu“¹þÿãyWj–9it32j›ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿŒþcýüúø÷õóóîíèéæåÞèØ×ÙÑÕÔÔÎòüù÷õóòïîëèæäààÚÚ×ÔÒÎÍÉÁÆüÿýüûùö÷öõôôõñëëçíêéëìàÝãùûù÷öôñïïðéæåäáÞâÛÖÔÓÐÓÊÅÀŠ¿ÿ0þýûøõóòííèéæåÞèØ×ÙÑÕÔÔÎòüù÷õóòïîëèæäààÚÚ×ÓÏÊÅÁ¼Æþ€ÿ-þûø÷öôóôõñëëçíêéëìàÝãùûù÷öôñïïðéæåäáßâÛÕÐÌÆÁ¼¸‹·‘ÿ.ýúøòîèèååÞèØ×ÙÑÕÔÔÎòüù÷õóòïîëèæäàߨÕÑÍÉÈÆÀ´²ïùþÿ*þýú÷õõðêëçíêéëìàÝãùûù÷öôñïïðéæåãßÚ×ÑÌÉÆÅÁ¼¸‹·ÿòôþ‚ÿ-ý÷óêåÝç×ÖÙÑÕÔÔÎòüù÷õóòïîëèåáÜÙÖÔÓÏÆ´Ÿ‹snºÍ×âíúƒÿ%ýùñìçìééëìàÝãùûù÷öôñïïðèãßÜÙÕÔÒÎǽ¨Ÿ¹¹‹·ŒÿþѸÌÚèôü‚ÿ.ùñïÞØ×ÎÓÔÔÎòüù÷õóòîìèåâáàÚÑò›ƒi]D3G£¤¨¯»ÅÓàì÷þÿþøõï€ëÞÜãùûù÷öôðíëèåãâߨÐijœ„kSe¸¹‹¶ÿ ˉ‡™£«¿Îßíøþÿ.øðãÜÔÓËñüùöôñïííëåÜ̶ ˆlXBM:336I¤£™š¬š˜ž§³ÅÔâðú‚ÿúöêããùûøõóòðïíèáÕ®•t[A:&O»·‹µÿ̈ƒ“ˆ~…Ž¢«ÀÕæñûÿ/øïãôúøööõñäÒ¾¥‡iUUJ833L>:=;I¢¡›§˜”˜ŽˆŠ¤¶ÊØèóýÿûûúùù÷ðãÒ©†dZ3 $Rº·‹µÿˉ…“Š‚~|t€vuƒ—¦¹Ñæôþÿ.þûóæÏ²’x_SN48E@FE9O?=:5OŸ¢œ§“‘‘Š…Œyˆ‡–§ºÔêø€ÿøðßĦ‰qP,-  % R¹·‹´ÿQˈƒŠ‚†}z…xsnlr{ˆ˜®ÈÛíìѸ {`NB@9CQ=C>?BC9L@8AC@FRDH==>==QKGIFZ¬¬­¬ª•‰…|{jddlMNPW67*#)&7  &"\¶µ‹³ÿaÍ––¢ž‡„{„wzswywifddlaVH@?RMGEIKCKS>@LOKUQXNC@@Y±¡¡£«¡ ¢¢“ƒuxrkgmmSTME'9-#+*(!. %9B+5 V¶´‹²ÿ+͈‚•–ˆ’…}{usyhmleld]NEBUMGCCPITbTP]YOIEPB€<2P¢¢ž¤““š–—•™ŽxulggnSRPG*;.#",'"*.G3./)( R¶´‹±ÿaʈ…’…}{ƒŒ‚ƒ…ƒ…pmlcmd^NNBWPJOUh[Y]GFIHBBFUG@>:V£¤ŸŸ¥•——Œ‹†„’‰‹‹†~zxt\YLI2910-5GA460'= # Qµ³‹±ÿaʈ‡Ž‡~„Œytuzw€yywv}odUVZj\X[OLFJSAEJJEHOOJE>>]¢¦¡ ¦–”‘Ž’Š…ƒ€vrss|€miffNSHDA453 3( P´²‹¯ÿaʇ†•ˆ€ƒ„{yzqw}nhgpyxyj^Q^OGGLQNLWLMLKHEITJA?=X£¥¢ ¨—–“ŽŽˆ‚ŽxzrollqXYUS;D5(''80#!7%&P´²‹¯ÿaʇ†—ˆ‚……‡}vspv{oljfskePQTZOJNSVRMXKMNMMGERJHB9.0,96' 4% P³±‹¯ÿ&Ɇ‰”†‚|…yuxsw{mjmfqibSSW`QLMNSKO_TLPL€I7SHFF=V¥­ª£¦œ›“Žˆ„’„{yvoilqZZVN4?A3.+>6'%#:#*O²°‹­ÿaɆ…†€~‡z}€|q|mkppqhiUPQbSNVPNP\]PNUNJIHWKFGGZª«¤¥§—˜”‹Š……zwywmlr\dZW4FH/..D?51#!8#-P±¯‹­ÿaÍ—˜š”ˆƒ~{„w{zws„qjrotifUPQ_ZTTQQS_]MPUPONN[VQOJa°°¬­¯§£—“Šƒ„|vttknt]eZQ7D;47@JBB=/#3$!52&#Y°¯‹­ÿQÉŒŠ•–““Ž•„}~zspkjnvpjXUYdUQPSTYZc\c^Y\WPWNHH@U¤ª§£«› ›•‘š‘…€v{lir\[US>H@4C,.Tªª‹§ÿa˘’™”‹‘†„€{yusrswf[R‰z^ehdfkhhkfifca]_c]VRKSˆ—ˆž«¨¥¨¢œ›˜žŠ†~yrt{hgrgK\ZQQHKHGFDCRD812.9.&"V©©‹§ÿɆ‡†€Y‰…ˆŒŠ‹„ƒ†€qiYW’vanrppo}ofij`][_^ZVPLWŽ’ˆ§¢žœœ›’š‘Š‘Œˆƒ…yxrnWi_]cZ][ZTJBT8" ( Rª©‹§ÿaƃ–ƒ~ƒ}|tv|ƒxy{‚{hUWŒrdmnknnmfhca`_Z^XUUO\š‹“‡”ŸŸž™•“”Š€~{rz€ytsp^o_UNNTF<968G0  / Lª¨‹¥ÿÆ†Š‘„~}{„}~vx{wyxu|€yi_T^rdrp>mwheeb]e^W[Q`§—Š›ƒ—Ÿ¢›•“Ž“‰„~z{}~gereY€kPOJOF?>=7E)! ( K©§‹¥ÿ5Ɔ‡ˆ€z„|~|x…{x€zylg`Xa•llsqqtyzigdbegh[WSc®¢Œ‰”…€œ–’Ž—Š‚‚€y|k¸©llPNHKM@>C6D(% T§§‹¥ÿaÆ„ƒ’†ˆ}|…{z|}}‚|z|€‚€|rqjeXm”lktwxuomkhece`][Uf³¬–…˜…‘£™™—Ž”Œ‹{wuw}x­ÉÚ{`[SMHHJ>=<6B("*N§§‹¤ÿaƆ‚Šˆˆ‚‚…y|yw|{{y}…‚}vwvoi]k‘os~uwyppnkfc_]_Vf²±¡Š–ƒŸ™˜–‘–—Œƒ|€|‚{k¤ÆÌs[XOQKGD<;93=&+M§¥‹£ÿaÆ}ŠŠ}}~}ƒ{{x{~„xxz…ƒxvwzxo_m‘msy|ztoljnmeb_\iµµ©›‹‰†•–”–‘„}yv€~iu–”X]RIMINJ:88.:$# J§¥‹£ÿaÈ’’˜‹ˆŠ‹~€|€‡{{|ƒˆ„„{x{~ul^v’jtyyutrkjgefc\l¸»²ª ‰–’››˜››‰†{‚…~pjd`P[PDILQM@;58F1/-('7.)"S¤¥‹£ÿaƈ‹‘ˆ…ƒ„…“ˆ…†„ˆ‹„ƒ…†‹ŠŽ‚‡ˆƒwnd{mx{wtqnlifgg^l·º´²¥„”€•›¢£«˜‘…‚€†y}vmdhZSONRLF@=;G3%%"$+ X£¤‹¡ÿVÄ~‹„|}zxƒ~wvy|ƒy{‚…ŠˆŽ…‚ƒƒˆ†‚{sdzŽozzxsrpkgghbn¸»µ²¬™ƒŽŒ‘’¡¤”…xsuxklhgVWLG@?A7**)%8"€) M¥£‹¡ÿaÆ…Š…~z„{€zŠ€‚†‹’—‡ƒ‰†Œ‹Œ‡€ti„Œo}xupsjhl`o¾º»··ŸŒ{’~‹–—’‹€yuuxjkb`OQF@?BF;19-%9"- M¤£‹¡ÿaÄ‚‹‘}…|}…yz{}}†€~€‰”‡‡Šˆ‘‘ŽƒynЇr~|ysnklhcqÀÀ¹´¸¥–‚€Žˆ™•‡‰|rxzpg`\KRH>?=EA2+%#8%+L¤£‹ ÿaÄ€‹ˆ|~zy…{yzƒ}}€†Œ’•‡Œœ‹“–—Ÿš“Š}pŽŠs~vqokf`r¾Å·´²¬©}‹†“ŒŽŠ}yu{zkoa^PWQ=<;D7(*%!8() M£¢‹ŸÿaÃ}‰„|yzwƒzyzy|ƒ|Šš–ˆ“”™œž¢¤¤›‘€q‹‡szuqnieq¼¾º¶±­ª–‡y’y‹Šƒ€}xxtykjd[NZH><7>7(,'!7#& J¢¢‹ŸÿaÀ}‡€}x€„xyxƒƒ‚‡Ž––ŒŒ–œ¡¤¨«ª§ €u“t}}rqqeq¼¾»µ·¯¦ž{‚’}ˆŠ„{xwv{nf`[JPB=:6?=-'$"7 %I¢¡‹ŸÿaÄ…ƒ“†„‹}ˆ‚„ƒ†„……Œ’™˜“𠩬®±±°­¡’€x“‚rzwsyqs¿¿»·´®¨¡—†tŽ„~ˆ‹‚|}{}pkeaRYKEC?IC50+-?'%",L¡¡‹ŸÿVÅŒ”މŒˆƒ‹…‡ƒ†Š‰„†Ž”’››’‘—ž¤­±µ¸º¹¶°¥“s‘nvsvnt¾¾»¹µ°ª§¡“€v‘z…‹‡~|sspgY]YPMGKK<::6C2€-,8,'$TŸ ‹žÿaÂ~zƒ‚zxyvƒyzw||ƒ|ƒˆ””œ”“›¡ª²¶¼¿À¿½¸°£xn’{msnhuÀ¾ºº³±ª¦¤”†r‚t{zxurvcjlXMPX?96F:&%(!2$ H¡ ‹ÿaÁ‚{†„yww{‡|v{~†„ƒŠ—•™’—Ÿ¤®³º¿Ãÿ»µ¬œ†to‘shlfs¾Âº¹³«¨¥ ˜}ruw‚xqtydd^\OPH@B7>81)%!=(% I Ÿ‹ÿaÂ}z‰x}|u~wxyvz„ƒˆ‰˜›”–Ÿ¦®´¼ÂÆÅ¾»¸±¥”ƒok‘rccr¾¾¸¸¶­¦¥¥˜ƒwslxtvuwieaZGOG?>6A:).'"7"' I Ÿ‹ÿaÃy†}wxy„uxwvy€|ƒˆ’™›’–¤¬´¼ÂÆÄÁ¾º¸²©›|eg’sZn¼¿¼»»®§¥Ÿ™’Šƒi…‰isrtufeaWGLD>96A9(')$1& KŸž‹œÿaÂ{y†€wu}ˆvw|yz€yƒ„‹‘˜›–•›£¯³»ÁÄÃÀ¼º·²©“…r_d’cj»Â½¾µ­©¤ž›˜‘rh“qkvtgf[TQTC<:5<8)&#):( JŸž‹œÿaÀ{yˆ|zzyz~xsvwxƒ‚‹˜œ“–›¡«±·½ÁÁ¿»¹´®¥œ’ˆzhWe§žº¶¿¶«©§Ÿ—•“~fmŒfqsyg\WTHNG8;496'$" <#&Gžž‹›ÿaÀwwƒ~{}|ƒƒ|z|ƒƒŠ‘ˆ‰‘™˜‘˜ž¥­±¶»½½¹µ¯¨ ˜“‰~o_O†¯{™³¶¹­¬§ —“žŒsc„|nx|nklha[UMRJJD>4,'6)$"& Gž‹›ÿaÄ‘Œ‘‘„…„‡‚||{{‚‹—œŽ’›¡¦¬°µ¶¶³­§™˜’Ž…}rfSIвu™³µ¬¬£ Ÿ—š™Œ~pdggzia\XORF@K;@@9477F62.--:70-T›‹›ÿaÀ}‚~vrsmzqwstvwz…ˆ™–‹ŒŽ”𢥩«­­«£š•‰‰†ƒ{siZEOš¦vª©¤Ÿ˜’ދބ}xZq†Xq^Y[`GJA;97<9'#!/'Jœ‹šÿaÁyt|qu{s}t|zszu{}„‹’’††‰”™ £¥¥¢˜Œ…Š{{wri`PIwš£q•¨Ÿ›•†yrbV‰b]\\WCKD;:7:6($ 2 "* Fœ‹šÿaÀxsƒxwtv{rpmw€vxz‡Ž’‚ƒˆ‰•ššš“‰{uƒ|osngaWYxœ¦s‘œ˜–‘…Š€}uhY_³yT^[XFLF=A7:6($ /#& Gœœ‹šÿaÃyrxvt|pzuom}pyvv}„†‰‘~ƒƒˆ‹Ž‘’––’‡}ni‚vhkfaZf“y£¤nŽ”•—‹„‹€~€q`P¡PQWXGLB?>496*%2%$ Hœ›‹™ÿa¾tr|oommxsnlŒxhwy~†…Š~}ƒ}ƒˆŠ‰‹‰…}pe`xs]a_^f¢“xt¡œn’ˆ„zun`MY«zHPXEP>873<5)#!/ "" Fœ›‹™ÿaÀvq}uoolm€noi_f†€ho}І‰~yxz|€€‚„‚‚~}xsj^XsnY\Ye¬¥qs¤˜o‡‰‡‰|xslbUJ€­\M_JNH=7152#!1!3$ F›š‹™ÿ¾v€xvspn€syup{n}vv‚„…zwvvz€yBz|}wwuqkaYPpuUUf³­ …ro¨—g€„Œ€ywu{o_Xž—SWRXOJJKPG>3*$6*% Kšš‹™ÿ¼}ƒ„ƒƒ~yƒ{~|tyiZl†yp|…wqtvts€tAuvtpqslia]RNmmNd­¯«•‚gy°‘kˆˆ„€|utjZIa¸t@@I<787>?7411?1**)&2!Kšš‹™ÿa¿ƒ}‚xrpstthffkik]UY}†otnnowqopqpqmlkkhfea]UOJfl]¨®©¢–zer«Žfy„wsled[YP7„­S8G?76400",#+$$"O˜š‹™ÿa»lqxslmlnyiflknqd_ZYnŠakowspmnpnjhegebba\YUNE^w𥡥œƒo[n­‰^xnmppwtpcCHž’8CI>4016 -! Fššˆ™šœœðð‹ÿ»npxpjhovhdnmptgda][]…_`€k9lkjnigcc`aba\\WOG>d‘˜›ŒkXu³‚g¯ÈÛãäàÑ®x¬_BA5386;"1€!Ešš†™šŸH±‰ÿ=»miyvjggjukengfwifebf]Ym„ncddggilfec`^`^\]YSTQBK˜›Ž‹yiS­ƒÄ…ÿ꫇d.01.240! E™š…™œŸy6 O߇ÿ>ºjmxkilefuidehlqijedne]LU}€_[ccbfa`]]ZYWWZVRTQFM†ŽŒŒšŽŒ}i~ÊĦˆÕÿ÷âÒξŽh{\+*(36",$'D™š„™ž“?… ̆ÿa¼spuqmlchvc`muimrtjz|rn\NPo`W[]`^^XXaWWVTSQNLIXŒ„‡Šˆ„rŽãÿÿÀ¢èÿöÓÎÜæçàÑmˆh%*2.!+$ F™šƒ™ ‹!ˆÉ…ÿ8½mlwqja`gqhjsyrwoonkrii\OJK]ƒuWZ]`]WTVSRSWXLLJGWŒ€†Œ|râ€ÿ%ù¼±èêÙáñïçàÓ¾ ~z¿z,><2.(!0  D™š‚™¡ˆŠ˜„ÿ7¸gmxnptvvysqhchr`^a_ljg[SURDHtƒ_OX\VWWUSOMQKLEDS”™†y…Œãƒÿ#ôæçóîåß×βž…s”ÒY(-+,/.=1.& & D™š™¡l‘ƒÿ6¼zx‚{ngd`j\[]Z]n_]_^hhd]VTVKEC[oPSOQQNMOQRLKKHT–›…z|Ѓÿ$óéòñèÝÖÑÊÁ·ª˜‡v{ÃË7$!,!#&4("P—š€™¢kŽ«‚ÿ6¹idsma]a]i]^b\]h[ZeegfcUQPYRIC=E|‚VHONJHJHLGHQHX¡¢“„tžù‚ÿ*ôêôíâØÎÇÁ¼¶®¢’†}€§ç}0"-# G™š™™¤z  ›ÿ5·ccue]]eil[Wf_]l[_`_fcbSNN[VJGC@<\‚aGEGFECIECG>L‘”{€Õ‚ÿ*óìñçÝÒÉÀ½º´®§š„ƒ†ŸÛÂ% -$ E™š™¡q“€ÿ5¹e`qf__[`gZ\\[\nWb^Wf][SMMXRKIHEA9IuwL?CDGQB>D=M’†n÷ÿ*ðëòä×Ξº¹³®­¤–††¦ÍäR .#$ F™š¡j•›ÿÿ¸l_nhlaaUfWbrVXe]dWVecmjUPUMIFC>2\‡[>>CKA@E:L‹|n¾ÿ*òéöæ×Íľ¹·²­©£Ÿ•ˆ‡’¬Éì)# D™ q–7 Úÿ·eajckaXTcWWVPZf]cehrh_ZUQYUPJLIEHE7-E}gC8C@=D=Nˆy|Ù€ÿ*øãõìÜÑÆ¾º·´¯«¦¥ž”ŽŒŒ˜¯Êê¡)  D›•—eÉÿ¶e]h_^YSRe^bbdhp_WZW_\XHDDPLKNQQNNL>900n«l>><>9J‹ƒq‹êÿÿýàñðãÕÊÀ½¹³³¯ª¤¡š”‘““ »Ïê¸5)$* Dœ—eËÿ¸eaf]^fjirkdXTX^LNPMXVSG@EOJBDEHJFRLCC75lªˆA4;7F…lžóÿÿÞåöçÝÑÆÁ¾¸²±®ª¤ ›––—¼ÅÓë¾;(*8+$#$  Cœ‘ —eËÿ¹dixtsm\TaVNMLP]IHMQju]NQJ>@CACDI@><;7/U§S32C~h¯ôÿôÔùïãÙÐÈ¿·²¯®ª¥ œ•”—ØÂ»Ùì¹7,+-&. Eœ‘ —eËÿºpfke\YTN^YJKNTihz‘±ËãõѲŸ‹p]SH@:>G;>::33#;†®w9A„ˆw¼òÿØèóçÞÕÎÈ¿¹µ³®¬ª¤¢œ­·ÉÞì«* * *$Mš‘ —Ëÿ´VSc_V_RMaT`v¤¾ÖëúÿKÒÑÓź©—…mZOMD;8941/+&U¢—[zxnÀòñËôëãÛÔÏÊÆÁ½º¸¶³±´°«­±·ÈÙææ G..) Fœ‘ —ËÿµZO^\TWp€™¬Çâó‚ÿOô¸q=(Q‡¶Ãȸ¯¢’{iWJ<75-5-$6Š®x^XºôÔÔòêæàÚÔÎËÈÅÄÃÂÀ¿¾¼¼¿ÃËÙåíÞ“t‚}iYD3  Dœ‘ — Ëÿ²Yey‡›³ËßïüÿîÀ‰Y$ƒH@j«·ºµ«ž‘ƒp]P@?0)-s¬‰L¨ÿ¾ÞîìêçáÚÓÒÐÏÎÍÍÌËÉÉÊÍÑÙæîïÑ… ª¤—}iR?9Cœ‘ —ËÿªÅÕè÷‚ÿéµ}K‰E@d†¢¬°ª¡—mZI9,*fš–ˆä¾áîðòðëâÜÛÚÚÙØØ××ÖרÜàèñôíÄxKxž¬²®¦Ÿ˜pbKZ˜‘ —Êÿøú‚ÿã«uB’>a‚§¤ ›”Šx`S{ƒšŸ¿Äæï÷ûúôì€ã€âáâäèìòøôâ¿P8Vr‘£§£Ÿœ˜’› —ÌÿòÉIš Ts¤¡œ‘ǹ ”¨ÈìðúÿÿûñéèççèèéêìðôøùïÜÏ)ƒ 4Zwœ£¢Ÿž‘ —ËïÀˆT#¡1Uu‘™§öàµ}\¾úøüÿÿýöìêéêëëíîñõùûûöþ™†/Liˆ›– —6¨ 3_ŠU]ÿÿþ€ÿþúøöõ€ô õö÷ùûýþÿþÿå Œ $:ÏÌÿõøûüþ‹ÿýøëZäCóýïðñóõ÷÷øøùùúúø÷úùöîÝsæNâýîëêëíïðñóôö÷öö÷àÄÄuç0Æúóð€ï ñòôö÷öôëѪŸeé¡äìêðòôõõòéÞŦ“ˆUëA”¶³¼¸´¬¥ Œvz\ð #OcrsnngT9õ ÿÿÿ¢ÿÿÿÿÿÿÿÿÿÿóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿŒþcýüúø÷õóóîíèéæåÞèØ×ÙÑÕÔÔÎòüù÷õóòïîëèæäààÚÚ×ÔÒÎÍÉÁÆüÿýüûùö÷öõôôõñëëçíêéëìàÝãùûù÷öôñïïðéæåäáÞâÛÖÔÓÐÓÊÅÀŠ¿ÿ0þýûøõóòííèéæåÞèØ×ÙÑÕÔÔÎòüù÷õóòïîëèæäààÚÚ×ÓÏÊÅÁ¼Æþ€ÿ-þûø÷öôóôõñëëçíêéëìàÝãùûù÷öôñïïðéæåäáßâÛÕÐÌÆÁ¼¸‹·‘ÿ.ýúøòîèèååÞèØ×ÙÑÕÔÔÎòüù÷õóòïîëèæäàߨÕÑÍÉÈÆÀ´³ïúþÿ*þýú÷õõðêëçíêéëìàÝãùûù÷öôñïïðéæåãßÚ×ÑÌÉÆÅÁ»¸‹·ÿóõþ‚ÿ-ý÷óêåÝç×ÖÙÑÕÔÔÎòüù÷õóòïîëèåáÜÙÖÔÓÏÅ´ ŒtoºÎØãíûƒÿ%ýùñìçìééëìàÝãùûù÷öôñïïðèãßÜÙÕÔÒÎǽ© º¹‹·ŒÿþÒ¹ÍÛéôü‚ÿ.ùñïÞØ×ÎÓÔÔÎòüù÷õóòîìèåâáàÚÑòœ†k]D3E¡¢§°ÀÅÔáí÷þÿþøõï€ëÞÜãùûù÷öôðíëèåãáߨÑų†lTf¸¹‹¶ÿ ˈ†ž¥¬ÀÏßíø‚ÿ.øðãÜÔÓËñüùöôñïííëåÛÍ·¢‰lX@[>224G¢¡—›µ—–§´ÆÕâñú‚ÿúöêããùûøõóòðïíèáÖ¯–v[BC)P»·‹µÿ̇‚™Š~…Ž¥¬Á×çñûÿ/øïãôúøööõñäÒ¿§ŠiUVJ730YA8;9G  ™ž°•“–Œ‡‰‹¢¦·ËÙéôýÿûûúùù÷ðãÓë‡fb6 .Sº·‹µÿ͈„™Œ~|t‡wu„˜§»Òçõþÿ.þûóçг“y_W[27E@FD7]A:94M šž°ˆƒ|–z‡Ž‡–¨¼Õêø€ÿøðßŧŒuP-<  / S¹·‹´ÿaˈ‚•Œ‚†}yysnktˆ{‰™¯ÉÜîìÓº£|`NA?8G_;C>?BC6YB59MU£¤› ¬–“Œˆƒ~˜€stldal‹€”­É½¤~]E*3-B .Q¸µ‹³Œÿ%þÎ’‹™Š|‚}{xxsnt‚f`cdw~Šy^HaE:>AB>J_BH€=99:`TPURdµ´³¶·–Œ‰†‚~˜ƒz}yhbhwKNPV7A-#/-F#0#+aµµ‹³ŒÿbþΞŸ±­–Š…zŠwysw{€jfddscUG@=_PFEIKBN`;>NSSf_mZFA?V¯¡¢§¹¨©°®–€—rvqiepxQSLE&B0$,1/!; #/KZ:A(Y¶´‹²ÿa͇€œ•–Ÿ˜’£Ž~usgmldte]ME?bPFBBOJ\u_]kgYOE[D:;;O¡¡› ®‘œšŸ˜ªšƒzvjchwPQPG)D0#"2-!&09^C<=4!4 R¶´‹±ÿaˇ„˜‡|z‚ƒ–‰‘Œ–uqn`se\ML>bVMUavhjrJKJE@ADbJ?<9U£¤¡®’•”‰ˆ‚Ž‘–ˆ…„^ZJG.A331=[TAD=/N" - R¶³‹±ÿaˈ†•‰~€‚“yst{|ƒ…ƒŽxhX^flfgUPGM`?EJIDHM\MD=>]¢§ ¢¯““Œ‘ˆ‚˜ƒ}rottƒ“wurqZhXQN;A>#@2 Qµ²‹¯ÿEˇ…›‹€~‚Œ{yzpx…lfhs…ˆŒ}oVnTEFMRNQeJMKJGDGaM@?=X£¤¡¢±”•’‡˜uxomimzS€X@O9&&(A:(&#D(0Q´²‹¯ÿVʇ…Š€…ƒŽ~vspx„nlid{kdPORgTKOTWRSeILMLLFC^NFANE>;/$B)#!%E@20^¯¯‹­ÿaÊŽ ¡—˜¥}v‡njjnsjYVXpYQPRW\btfnjehcVgUIG=T£¨¦¦·žŸ©¨¤Ÿ›­‰€x|ih{VYSQ=TE<@:LWFBDIbLB?<6I"R°®‹«ÿaÉ‹‡—‡€ƒ‚”ˆŽŽ›‰„‚z}njYVUvmkpmootz]`^QLPIaOHNAW¦©£¨²™–™›Š‰ Ž’Ž‹…‰“qhaZMcUX]]jn\Y[HZ0)' 0 S°­‹«ÿaˆ‡ŸŽ‚|y’€rzu{Œw€‘•’‡„vss€hef]S]p\h[QOSPcQHFEZ¦«¥§²š™—“‹„š‰ztronyƒv…„{l}v^IFWO:8<5Q'&#4"O¯­‹«ÿaÉ……šŠ€‚}‚wyuwŠspjo¡xmgk[v`WYbaXdoUcZTRYSbRJVGU¨¨¤¦¸¢Ÿ–’Œ›‰||zqin}X]TgOUIB?AUT:;78W,!0 P®­‹ªÿaɇŒ”ˆ„|xwut}qrmg›ªhXYZ{iZ]`f[cqX]Z[UTMdUYRN‘£¥§§Á£ž—˜‹ž‡{xtuopƒ^a`bD_TFDAXW3<9O¯›£§³›œ˜—”‰¢‹ƒzxtlr„f_a\L_ODJEPL>646S/&"0M¬«‹¨ŒÿbþË’‰žŽ‚}y€yuyˆtsuusdU”™Utkdmdecixda\\^dYk`Z\TV­š¯¸¢£¢›‘ކzxurmvƒgbjhK_ULPCPK79;3O-; Xªª‹§ŒÿbþÍ¡œ¨¡™˜˜•£‘Œ†~‰tsrsi[Q™˜nhhdhoos€qwsqojkxl_XOU‡¥££»°¯²¬§¥¡±œ‹‚zpt‚bcqhKaYLPHQOIKLOhRF@@:L=0-Z©©‹§ÿaÉ…„”‡‚„„–•Ÿ¡œ ‘‘“‹Žxm^Y¦™o|~ƒ„‘…mmpfa]_k_VQMWŽŒ­”­žš™››•¦—“ ž˜˜„ƒ|u^wjgqhppmeXKd=(& 2Rª©‹§ÿaÇ‚Œœ…~}}‹}zsu~}~€…”‘‰ua^¡irsnor{fjecbb[k^XVP\š‰›©žœœ—“‘‰ŸŠ}|zwp~Œyvz|jƒgTQT^L9758R3#  9 Mª¨‹¥ÿadž‰˜†}|zŒ€€wy~‹xyxu†ƒzj`Uh§Šdssrvmxjggd^ocX]Sa¨—ˆ¯œ” ™’’‹ž‹|wx}‡aaobc£{LLJXN@?@7P,%$2L©§‹¥ÿadž†”‹€y~~y‚|yŒ~|pkbdd®ˆlvsxƒz}lifefum\XTe¯£ˆ±™šš”Œ¡‹€|€vw{†fƒªž{§}LKESVB@C3N- . U§§‹¥ÿaÇ…‚™‰ˆ~}|Ž}{}}}{|‚„€vvlr]o°ƒlv}„tqonjgdsf^\Ug´­—†¨ ¢˜—•‹Ÿ‰~xusyˆsž¼Ò|z`OIDMP=<93N/"$4N§§‹¤ÿaƆ‘‹‡||yxŒ||z‡‚{{x}o^lª‚r„ƒx{rrolfqe_`Wg³²¢“‘«•œ˜–“Ž¢›…|~y„†g—¶ÁmdYLNGLI8961L,!5M§¥‹£ÿaÆ€{‹|{||‹}{x|€xy|€‰…|z{Š|o`p­y‡xspmnxgba^k¶·©”ŠªŠ’“¥™”‡~xrƒˆdp‹ŠWfVGIDQN746/H)+ K§¥‹£ÿaʨ›“‘“•—ˆƒ„€‡”€€…”‹‡~}~†|sd}µ‚€‚€€~xw}snnjxÅÆ½·­ªš™¤¥ ¯§˜’‹€„Œ‹nib\NdUGKLWU@=:AY<9731I<5.X¤¥‹£ÿaÇ‹›ˆ‰ŒŽ£”“”’— ’’”–¡Ÿ“‘™™‘†zn…¯‡…‚~ywrxolibp»¾¸¹±‘…²“˜¥£·²¶§¢”ŽŽ›„‡ylzja\[c_SOLH\?-+('8"$[£¤‹¡ÿaÅ€}’†{|zwŒ~uux}z}†Š™’—‰Š•‘Œˆwg€«|}ywtxokleo¼¾·¸¸˜ƒ’ª†’“­¦¢–‰xot‚gjggT_PH?=E>+-+'D#3 N¥£‹¡ÿaÇ…~‘‡~€~zŽ}€{‚•‚„„‰—˜šŠŠŽ–•’“ކzn¬{„}zu|rmperÀ¾½»Ã y¢—Œ—§œ’‘…{rxƒeh_\KVF@ABLC4<1'D#7 N¤£‹¡ÿÅ‚‰˜ƒ|…}}{z}~€‘‚ƒ…•–—Ž˜™€—B”‰~r•©‚~w{tqmhuÂü¹Ä§˜‚ª’™£—’Œ‹{oz…me]YFWG<=:&$ >##2 Gœ‹šÿaÁxrŠ{wt€vŠ|srlxŒx€„ˆš˜›Ž’˜—˜¡¡££ ˜Ž€x“szslf[\ƒz¥Í”’ž›˜““…—ƒ{uhX^РS]ZWCRF:@5?:'$ <%/ Hœœ‹šÿaÃyq†{uu~p„wonŽ€ƒx}‡˜•™Œˆ”““–™™˜”ƒsk‘‡ppjf^i—z®Ë‰——™Œƒ˜ƒ}€q_P˜Ê`MUVCSB<<1=:'%>(-  Hœ›‹™ÿa¿tq†nonmƒuol‡¦‘ky‡—’††‹ŒŒ’‘“•‘Œˆƒujc…‰dedbi¦”yw®Ä…Œ‘“‰„™‚ytn`LY¿¢JMVAW=550@9'$":#"* Gœ›‹™ÿÁvp„wnoml‰oni\n ™rw‰žšˆ…ŽŒŠ€‰AŠŠ‹„„xnb[‚‚^`\h®¦’t|°Á…‡ŠŽ†–wrj_QHˆÍxLcLWK=7-84!!1!?!- G›š‹™ÿa¿uvytqqoŒy|}~›Ž«–Š›—”†„ˆ‘‹ŒŽŒŠ‡‰€{uoe\Y‹YWh²¯¡ˆ{p·Å|„Œšˆ{{~Šqi¨Ål_[i[TX[dXH9.(D/ - Kšš‹™ÿa¾€„‘‘‘‹†˜Š‹ˆ~~[n™“ƒ„xy†}€ƒ„…~|wtnfaUzRb¯²¯k€Â»€’”§”Š€{naSbÑš?=S?5540A(M™š‹™ŒÿbþÁކtswt~heejku]VY‡¤„}vvw…|xyzyzx|qqnmmief[Qs‚h´»¶²ªƒku¼»wv‘ypjcbY\Z5ŠÐl3M>44254 7"%8/..T—š‹™ÿa¼kouklkmƒkgmlr|e`\Yy¢›mpv…{wuvxvtxjljgge^fYLDhŒ¢¦¢ª©ƒp[pÀ´kƒqlnmtqoe?Fª¼?GI;3/7;! 9) Fššˆ™šœœðð‹ÿ½oo€‚pigojeomtgeb_e`’ nd}vq€r6sqtfheffd^g[PJ>l¨œ£¬€lXxʱw‹«ÅÚâãßΪzuÃHA338;@"<€* Fšš†™šŸH±‰ÿ=¼mhyjggi€nfogi‚igfcpaZt…rkjmkkmkqddab_^\eYUSDK•¤•œªŽŒyiRƒÄ¬Ë…ÿç§z—s./1-78<* F™š…™œŸy6 O߇ÿ>»jlnhkdekefio}jkecvkcQX‹œl\fgeihm__^]ZZ\bWURHO‡“Ÿ•§Ž}g{ÇÇ¿±Üÿ÷âÑ̺ˆ`x[+*(8;"7&1E™š„™ž“?… ̆ÿ%¾so}ullbfeamsjzwxrŒ˜†|g[]ƒ«tY^`bdjZ[d€Z8V`UONKZŽ…‹¦™‡…qŠáÿÿý«ëÿöÓÌÛåæÝ¿‹g„g(+62 6 - F™šƒ™ ‹!ˆÉ…ÿ8¾mjti_]f~np}‡‚~~|t€oj]ROYe˜’ifikl[XXTTUXdRMLIY’Ž‹¤‚qà€ÿ%øÂÎðéØàîíåÜйšwu¾‚6ML<5+$=( E™š‚™¡ˆŠ˜„ÿ7¹fmƒvwƒƒŽƒqhn`]b_umh]UT\HHŸrScpbecb]UR_QLGEU•™†zŽ–áƒÿ#óäçòíâÛÔɽ¬—m‘ÐX/505;:P>9/'!0 E™š™¡l‘‚ÿ7þ¿†„•Šwlgat[Z^[`y__`_rke^XUaOFC^•ˆZ\PUWTW[\e[WVPX›£š’Œ΃ÿ$óèòðæÜÓÍż°£‘pwÂÊ;)!7%*/F3,+T—š€™¢kŽ«‚ÿ6»lczn_]`[s^_c\`s[[ffrjcURPeWJE>E‰¡fGQPMJKIYOLYVg³´Ššø‚ÿ*ôêóëàÖËĽ·°¨›‹€w~§æ 1"7 * H™š™™¤z  ›ÿ5¹cb}h\]dhv]Wf``w\`a`qgcTONg[LIEBM‘“‰Ò‚ÿ*óëñåÚÏÆ¼¹´®¨¡“†}}„ÙÂ(!8- E™š™¡q“€ÿ5¹e_yh^_[_q[[][_zXc^XpaZQMLbVLJIGB;Q„‘X>DEH]G?E?N“‘†p öÿ*ïêðâÔʹ´´®§¦ˆ~‹¡ËãP!9$, F™š¡j•"›ÿÿ¹k^vkkbaToYasV[p]cVXrm€}]RaOHIJJ€G0b¡o>=BVEAF:JŒ…r‰éÿÿýßðïâÔȾ¹³­¬¨¤›“‹Œ »Íéµ;1( 6 ' Fœ—JËÿ¸e_m_anwv‡{p]W[hLNPMc[UGADZNBDDJMOdUML=7qÁ±R2;7F‡ƒl˜òÿÿÝäõåÜÏÄ¿»´­«¨£ž™”€¸ÁÍÐê¼ADBCHT>A?DC6\¸Æn50D‚}g§òÿôÓùîáØÎÆ¿»´­ª¨£ž›—ŽÌ¾º×êµ687<1?*Gœ‘ —eËÿ½}mxk[WSLh[IKMVsi{’²ÌãõÒ³ Œq^TIA;BR;>::34%A‘Ì›GDŠ“µïÿ×èóçÞÕÌÆ¿¼µ±®¨¥§¥Ÿ•“”¤±ÆÜê§* 5 5,(*R™‘ —Ëÿ´SQkaU_RMkV`vަ¿×ìúÿKÒÑÓĺª˜†o[SUD<8:52/3(Vµ¾y„{q·íñÊôëãÜÕÏÉÄÀ»¶°®©©²ª¡¤¨¯ÂÖåäžF//4 &Fœ‘ —ËÿµZNg`SXqœ®Èãô‚ÿOô¸q=(Q‡¶Ãȸ¯¢’|jYK=76,>/#5’ÏžeV²ìÓÕóëæáÜÖÐÌȽ¹·¶´´²±µºÃÔãìÜrƒ~j]E4 & Dœ‘ — Ëÿ³Zd}‰œ´ÍàïýÿîÀ‰Y$ƒH@j«·ºµ«ž‘„q^Q@G4),yů^¡õºßðíëèãÜÖÑËÆÅÄÂÁÁÀ¿ÀÄÉÓáëï·… ª¤—Ž~jS??!Dœ‘ —ËÿëÆÕé÷‚ÿéµ}K‰!@d†¢¬°ª¡—Žo\J:,)f§»¤ã·âðóõòíåÝÖ€ÑÐÏÍÐÔÙâîòëÀrKxž¬²®¦Ÿ˜qcL[˜‘ —Êÿøú‚ÿã«uB’>a‚§¤ š”ŠyaT|ƒŸ»Ö¾åòùýüöîäßÜ€ÚÙÛÞâèïöóà·L8Vr‘£§£Ÿœ˜’› —ÌÿòÉIš Ts¤¡œ‘ǹŸ—³Æéóüÿÿýôêã„â ãåèìñ÷ùì×É)ƒ 4Zwœ£¢Ÿž‘ —ËïÀˆT#¡1Uu‘™§öàµ}[½úùý€ÿ÷íçæçæ€ç èêìðô÷ûúõü™†/Liˆ›– —6¨ 3_ŠU]ÿÿþ€ÿýû÷öô€ó ôõöùûýþÿþÿë"Œ $:ÏÍÿúüýþþ‹ÿþýøbäDöÿö€÷úûûƒüûúüüûùð}æ Oæÿôòðóõö÷øùúù€úüèÎÝ€ç2Ëÿû÷õöö÷øùúúùøóá´§ké§îù÷øøùúùôíæãÓÄ WëC›ÒáçãßÛÖÒÇ´¡gð $[{“›š–‚e=õÿÿÿ£ÿÿÿÿÿÿÿÿÿÿóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿŒþcýüúø÷õóóîíèéæåÞèØ×ÙÑÕÔÔÎòüù÷õóòïîëèæäààÚÚ×ÔÒÎÍÉÁÆüÿýüûùö÷öõôôõñëëçíêéëìàÝãùûù÷öôñïïðéæåäáÞâÛÖÔÓÐÓÊÅÀŠ¿ÿ0þýûøõóòííèéæåÞèØ×ÙÑÕÔÔÎòüù÷õóòïîëèæäààÚÚ×ÓÏÊÅÁ¼Åþ€ÿ-þûø÷öôóôõñëëçíêéëìàÝãùûù÷öôñïïðéæåäáßâÛÕÐÌÆÁ¼¸‹·‘ÿ-ýúøòîèèååÞèØ×ÙÑÕÔÔÎòüù÷õóòïîëèæäàߨÕÑÍÉÈÆÀµ·òû‚ÿ*þýú÷õõðêëçíêéëìàÝãùûù÷öôñïïðéæåãßÚ×ÑÌÉÆÄÀ»¸‹·ÿõ÷ƒÿ-ý÷óêåÝç×ÖÙÑÕÔÔÎòüù÷õóòïîëèåáÜÙÖÔÓÏÆ¸§•xÀÖßéðüƒÿ%ýùñìçìééëìàÝãùûù÷öôñïïðèãßÜÙÕÓÑÎÈÀ®¦º¹‹·ŒÿþØÀÓàîøý‚ÿ.ùñïÞØ×ÎÓÔÔÎòüù÷õóòîìèåâàßÚÒǸ£‘teK6F¡£ªµÈÌÛæòúþÿþøõï€ëÞÜãùûù÷öôðíëèäâáÞØÒɹ¥v\p¹¹‹¶ÿ щ‡¢ª²Ç׿ñú‚ÿ.øðãÜÔÓËñüùöôñïíìêåÝѾ«”vaFfC535H£¢—œ»–˜ ¬ºÎÜçõüÿþúöêããùûøõóñïîìèâÙÇ· €eIM-V½·‹µÿÒ‡œ‹~‚ˆ’­´ÈÞìôüÿ/øïãôúøöõôðæ×Dz–r^[N:63dG:<:I¡¡š ¶•“–‹†‰Œª®¾Ôàî÷þÿúûùùøöñåØË´’oo=6 Z»·‹µÿÒ‰„œŽ‚}syv‰ °ÅÚìøÿþýûóê×½ „h`f4;HDIH9gF;:4N¡›¡¶€)ˆ‚zœ{†Šž²ÆÜïûÿÿþøóåͳ™Y2G  8 Z»·‹´ÿaш‚˜Ž‚‡~y’{tolv€¡¹ÒâóñÚð‡iUFB;Nj=FACFF7bF59NX¦¥›¢²–“Žˆƒ}žqsjccp•‡·ÑDZŠgM/:3M6 Xºµ‹³ŒÿbþÔ•Œ‹|‚~{“zztov‰gbeg…“…gMkK=AFFCPjDK@A@;;kZX]Ykºº¹½Àž—Œ‰‡ƒ}ž„x}xfakJNRZ;J2&!63P& 9'1k¶µ‹³ŒÿbþÕ¢¥ºµ›‹ˆzx{ux~‡ligg{gXKC?jWJIMOFUk=ASYZqi|cJEAW¯¢¤ªÃ­°·µš‚qunhcq€QUME&G4'0!86"D#%"6UhCH-a·´‹²ÿaÓ‡ ™›¤ž™¬“„vuˆinog|j`QICnVIFEROe‚iiupaUGeH<==Q£¢œ¢´Ž“žŸ¤¤¶¡†{wi`hQRQH)J1$&73$*5AmLDD;&> Y¸´‹±ÿaш„œ‰}zƒ…Ž”—“™¢zuqc{i_QPAm]R\lswQRNFABElN@?;V¤¥Ÿ¤¶“––Šˆƒ¥’–œ–ŽŠŠ‰_\KH.F544EgaJNF4Y& 5Y·³‹±ÿaщ‡™‹‚‚ƒ™{tu~‚–‹ŽŒ‹œn^fp‘zqr]WLSkCHLKFJNfRF?@^£§¡¥·”•‘’‰Ÿ†|qntt‡ž{~{ybt`YU@HD"K: X¶²‹¯ÿaш… ‚‚’~{|r|nilx”™‹|]{[IJQVRXqMONMJGHkSBA?Z¤¦¢¥¹•–“ŽŽˆŸ…uxpmhnOY\]DW=&#!?<#" N+8X¶²‹¯ÿ#ч…¡€†„”€xvs|Œromh„ogTSVs\OTY[WZrKO9IDhSID>U§¦¡¦¹™˜‘“Œ‡ …wsnfp‚TTPJ.M=-.(A@(!!J$7 W´°‹¯ÿaЈˆž‹‚€‚|“}wzu}oopi‚rgYY[y]RSUZR\vSNRNKKHjPGH?W¥­ª¨¸›œ”‘Žˆƒ£‰ywumfpSWRN5NE0,(G>&'%P'< W´°‹­ÿaІ‚—Š€•~‚vŽqoutƒpo[WT{`T\WUWgtOQWQLKFlQHNOe³±¨¬·”—”ŒŠƒ¡ŠyvwvjqƒUbWV5UK-,*IC-/$"M'>X³¯‹­ŒÿbþÖ§§®ž‡€yy||yy”unwt†rkZVUygZ[XWWhsKPVWVW\odc_q½¿»Á̶±¡™•ŽŸˆytrrir…XbWN5S>228MC86* G&#(!PH97f°®‹­ÿaЧ¨£¤ž °•††{qoorˆyo^\]}bVUX]bhnysnql\r[LJ?U¥ª§©À £®°¬§¡º¦Žƒ|~jkTWQP8UA6;3KXC@DLnQDEC=T'Y±®‹«ÿÐŒ‡œ‰€†…œ–™—™ª”ŽŠ€†sn_\Z…yw}€y@€ˆbebUORJjTKPDY¨«¥«»š˜šœŽŒ‹©’”š–“’ vkbXFfWYaaqt_]^Ib1&$ 7 Z±®‹«ÿaшˆ£ƒƒ~{˜ƒt|y—~‰¢¡’„€€¡qlmaUbz^k]USWSmVLIH\©®§«»››—”‹‚¡‹ytspqŒ|Ž€pˆ`HDWO4262W%";% U±¬‹«ÿaφ†ž„‚—†{}y|’wtns´„tosa‚g]`ge\jzXg^XV\VlXNYJXªª¦ªÀ¢ –“‹¢‹z{ypiq…W\RbJTD<:PK246,T*D%#`«©‹§ŒÿþÕ¨¡±©¡ ¡®™“†„“y€wMˆpaU§±rokpxy€~…~|vwˆxh`UX‰²¹©Æ·¶¹³®­§¾¤•…|qwˆ]]f\@^SDLCRPHKMPsZIECBWF63bª©‹§ÿaχ†™‹„ˆˆ…Ÿ— «®©¯œ•œ‚wf`·µ~‰Œ”–£—xyzpkfexg\VPYŽÂŸ³ž›šœ˜’®™§©¡™˜¤‰‡znW~njvmyztl[Lk>'$8Y«¨‹§ÿa΄¢‰€‚€’}wy…›……ˆŽ£ –‚ng³§s~zx~Šqupnlkdzh_\U`ž‹¢Ã¨Ÿž™”’Ч|{xwq€”wvxx|§€SNR_K31/2U1 "@S«¨‹¥ÿPÍˆŠ‰€‚€}•„ƒ|~„•}~~{’‹‚ti]s¼ o~„y„vtroi~macYf«šŠ¿°• ¢›”’‹¦Ž}ww}Œ]^cX|·–PDEXN€; 1S*"!:!S«§‹¥ÿaΈˆšƒ‚ƒ|•ƒƒ‚~ˆš†ˆ™‰†|wmsn¢xƒ‡”…ˆyvsqp„xe`[j´§‹Èššœœ–’Œ©€}€vt{‹cr…„·˜QD@TV=NQ885.R+#<U©¦‹¤ÿả‚—ŽŠ…‚„—€~}†—‚ƒ‚ˆž”‰Š‡‘~ivÁ™~’•†‰€|yrsijaoº¸§˜˜¼¤›˜–Ž©œ‹„|~w„Œb{“¡ay\CHALI452,O(!<T©¥‹£ÿaÍ|•Ž~~€~”‚}€‡™…ŠŸ—”Œ‹‹ž‹|m|׆™Œ‹†€}zy‡tljgu¿¿¯£œŽÁ“–’Œ¨•Œ{xqƒahtrHaM@C>QN201)K%2 Q¨¤‹£ÿaÒ¢¥³¤›™šœ¢Š‹ˆ¡‡‰Š£™—ޤ˜‹‚q‰Ï˜“’މ‡ƒ}|y†ÒÓÉù”º± ¬ª¡µ¢Šˆ†’lhaYE`OBFGYW>;7>_;>?:6SF>4_¥¤‹£ÿaÏ£–“–¯žžŸ¤±Ÿ £¥¶²´©¤§²­¤˜Š|‘ÇŸ‘–’ˆ…€Š}xulyÄÇÁ½•‰È¤›©¥¾¬¥£¤™–—§‡Ž‡~plc_\igVQOKdB42,*A(&a¥¤‹¡ÿṼ˜Š€}z”ƒzz}ƒ˜†–«¥© ž«¢›—p‹Ã†‹‰…ƒ€ˆ|uumxÄÆ¿Àć˜Á‹‘­˜‰†€tnw‰cheeR`KB86C<%'% I%€:T¦£‹¡ÿa͇€—Œ‚ƒ‚~—‚†…€‰¡‰Ž”ª¨«›œŸ¬¥  š‘ƒu™ÆŠ‰‰†ŒwyozÈÇÆÅϧ’}¯«Œ”ª”‡‡ysz‹cg]ZHZE;9:JC.7,%L&! > T¦¢‹¡ÿÌ…‹žˆ€‰€˜‚ƒ‡Š‹Ž’€©J  ¡®¨££¢‘‡{ ÄŒ‰‹ˆ‚Š€{wq~ÊËÄÃЮ‡…À›–¨•Œ‡‰|q}ke]YE[H<:5IH1*$#K* <S¥¢‹ ÿ〘ƒ}—‚‡‹š‰Š˜¬«­¥§±°«¨©­§Ÿ–‹v£ÃŠˆ…Œ‚zup~ËÎÅÉδ²–¹€§’މ}xs€fm^ZI`S::7JA)*%!K-:T¤¢‹Ÿÿ&Ë‚~–Œ~€{•‚†›ˆ’œ±³³§««´¯¬­¯¯­¤›…tžÀ€‡7Žƒ|wrÊÊËÓ϶´žŒyº¢œ‚}xvyŒehaXHdJ;:2C?(-'!J( 7 Q¤¡‹ŸÿaË‚~”‡€ƒ|ƒ–€}~ˆŠšŽŽ“š±²³ª§¨µ±¯°²³²¯¨•…w¬º‚…’ƒ~|rÊËÇÊÓ¸±¦•~ˆÇ¡‹ˆ‚zvtzhb\UCYC:71ED+&#!I%6P¤ ‹ŸÿÍ‹¦“—‰Š¡ŽŒ’–¥˜œŸ©½»¼²­¯¹¶€·B¸·µ²¥–…y²¼‚‡€xÏÑÊËÓ½¹°¤‘z¥¾†”‰ƒ„‰˜urlhVkVLIDWR=835X3/,(%B+'V¢ ‹ŸÿСŸ°¦Ÿ£ž™¬ž›ž¥¯ ¥¯¹Âß´¶½»¼¼€½@º¸²¨—„v¬¸‰‰‡…~Š×ÙÕÔÚÊÆÁ¹¨’ƒº§”ž™“”¡„wevm^]TaaMLJGcHAA@>UA:8bŸŸ‹žÿÉx‡{z{w•}|…›‡— ¶³¸­«¯¸·º¼€¿@¾¼¸°¤‘|o¯µw|ztÌÌÆÆÎº´®ª™‰q”Åwwxuqv‡[fhRF[X;51K>$#&C"2 O£Ÿ‹ÿaÊ…}•‹}|}š„|‚†‰Ÿ”š£ºµ¸®®²ºº»¾ÁÂÂÁ¾º´¬žŠxq¹£qyuÍÑÈÈÏ·´®©Ÿ“~²rxpzŒ_a[YK^K=@4E?0*&!Q/6" P¡ž‹ÿ?Ë€{—Š{‚y’€~}†ž•Ÿ£·¹¹¯­±ºº»¿ÂÄľ»·°¦—‡ss½¥oq€ÍÍÆÈѹ²°®Ÿ•…‰y¿…€tzŠcb]WF]J=<2G@(/("K)8%" P¡ž‹ÿaË‚{•…{}„}—~}}…š‰“›£¸¹¹­­¯¹¹»¿ÂÄÄÁ¾º·±©ž’poº¤f|ÌÎÉÊѹ³°¨¡™˜n‘Äoqpyˆac]WFYF<72G?'()$E#7  R ž‹œÿaÊ~z”‡„|{€›}ƒ€‡š‡–œ£·¸¹°¬®¹º»¾ÁÃÂÀ½º¶±© —Š}hhÁvÉÐÊÌϸ´¯§£“¤zd²šfu…ˆbc[VOaF:81B>('#*O&9# Q ‹œÿaÉ~y•ƒ~}}‘y{|‚šŒ“—¢¶¸»®­­¶·¸»¾ÀÀ¿¼·³®§ž—ކr_oÜdzÆÅÍж´°¨Ÿ™’¨„dm½ujwŠ_ZVUFZG37.=;$$!!P)6NŸ‹›ÿDÇyx’ˆƒ‡†ŒœŒŠ˜ ±¯®±ºÃÆÅ´±µº¹¹º»¼¼»¸´®§£œ˜zhW˜èÊ®¾ÅÒ·¸³­©£›µ˜{jœ±~’¢€ƒrxj_c[aWJ?40O5,* 8 MŸœ‹›ŒÿbþÑ®¢±¯¥›žš©œ“ŽŸ’™§©¶¸ºª§©µ³²´µ·¶¶³¬³²š™˜’’‰|h[žè·ÕßÐÉÁ¼¹¯°¾¦Ž}i¸Œp•ojd^QcNCN=LNBCFJhKDDB>XRHCc›œ‹›ÿaʆ€’†xuvnŒw{yz˜„Žš ±µ´¦¤£°­®¯°±±°­¤ž³£‹ŠƒxjSZªå¼±Ëº³­£™‘‹¥Š{wYyÀlƒ\Z\`DVC762A>$#!B! 8$$ Rœ‹šÿaÉ{tƒty€w‘}‚€z…™‚Ž”±¯±¢  ¬¨¨ªª«ªª¨ˆ§œ„‰€vm\S€­ã·­±¬¨¡š–‹§‹|ufUŸ¼{Z^^XBXG973@<&%# F&%: Mž›‹šÿÉzt‘€zy„y“‚xwrš‚‹‘˜­«¯ žŸ©¤¢¥¦€¥?¤™‚z  y…}vpedŒ¯é·¨¥ ™™Š¤‰wk[cå¼V_]YEXI:@4A<&&$D) 6 N›‹šÿaË{r€yys}usœŽ€‡’›¬§¬ž™œ¦ Ÿ ¡Ÿ¡¡ –†wož—|zuqhq¢Š¸è©– ŸŸ“‰¤‰€ƒtbR£êtNXXEYD=<0?<&)! F,!4$N›‹™ÿaÇwrŽ„rtrp{tq»¨uŒ”ª¢£˜—š¢›˜›œššœ›‘މ|pi“nooms²ž~ºä¡‘™™ˆ¥ˆ|xqcN\ÏÅONXB\?55.B;((%"D&%2 Mš‹™ÿaÈxrŒ}qsro’utn_k«°‚—±¯³¤œ—£œ˜–“””•˜ŒŒ†€vja‘”hkhtº±›}†ºâŸ‹”Š¡…yumaSJæ—MhP^O@7,:6#$4$H% !4 Mœš‹™ÿaÆxw†}vtut—€ƒ†‡›–žÂ¯™°«§––›¦¡žŸ ž˜•—Љ„~xnddŽžebs¾º«“…uÃ蚈‘§€€†–~t²ë…ebtc[^bncP?2,M24 Qœš‹™ÿaÆ…‰š›˜œ•§––“„‰ƒbt«¨•’œŽ‡ˆ˜Œ‘’”˜ŒŠ†ƒ|ro_ˆ•]kº¾¹©žqˆÐÞ˜šŸ·¡˜”ŠƒtfZfâ½B;S<378LRGGFE`G<>;7J.S›š‹™ŒÿbþÊ–Žš†zy|xˆnjjood]`”»™Œ„……—ˆ‰ˆ‡†‡Œ~~|zzvqvi]‚–vÃËÄÁ»q{ÊàŒw›}pjcdZ_a2ë‡1RA42198#!?#&)"A634\™š‹™ÿaÄmp†znpoqqlrqxˆlgd`…¶³|}ƒ•‹…„…†„„‰xzxtsqjtdVLs ¯²­´¶‰u_uÏÙ~Šy~Š”‘‡VP´ÞJJK;20<@$$ A 0 L›šˆ™šœœðð‹ÿaÄqq‡†smls‹okusz‹nljfqi ¸p†€€€€†tvssqoivfZRFy¾¨§¬¹”†p[}Ùד¯ÍßìñòïäÏ©œàŸKC349?E%"D"2 L›š†™šŸH±‰ÿ=Äojˆ}mkkmŠsktmqŽonnk|jb~³›„wxzyy{z‚qqnnkifse_[MRŸ·ž¥·“’~jW—ÕÕÜ…ÿóͱDŽ,13.<="! D"1 L›š…™œŸy6 O߇ÿ>Ãmn†slohi‰qjknv‰opliƒvnZa™´}hrtsuv~kljigffpb^\PV±¡²’’u¨àËÐÕäÿüñèäÚ»¥´s-+(<@%  @*7K›š„™ž“?… ̆ÿaÆuq„yoofj‰jeqxq…~}›¬—Šsfi“‰djlnqzfhofeean`WVR`•‹“»§‹‡ƒ½ôÿþÈÑÒñÿûçáéïïèÕ¸¦½|),:6# >" 3 L›šƒ™ ‹!ˆÉ…ÿ%Æol…xkb`i‰uw‡“Ÿ‹Œ‰yrdYXep««{syz}hdb€_aq]VTP_™”ƒ“·‰¿ò€ÿ%øÈâùðæêóôïéáÓÀ«¬ÚŒVKBJCS•{Ÿñ€ÿ*úéøóéâÜÖÓÏÎËÈÅÄ¿¸µ³²ºÉÝóº<0 K•—eÉÿÀg]wf_ZTQzjo{…šwfg_re]MIFf[WcgfbdcE>11ƒé©\B@B?N‘‰v¶ùÿÿþêôöîæßÙÖÒÎÍËÇÃÁ¼¹··¶ÈÚßñÏK5,#>. K—eËÿÀg_scdu–†xd]bsQSVSna[NFGeTGHIPSWq^VTD;yÔÓe3>;J‹†tÌýÿÿíìùñìåßÛØÓÎÍËÇÄÁ½º¹¸ÈÝêâòÖM$8961:+ZÃß”€wÞþøåøõñíêçãàÝÚÖÔÒÑÐÎÎÍÎÑÖßèïîÃ]24< ,L‘ —Ëÿ¿\NmbUZw‹©»Òê÷‚ÿOô¸q=(Q‡¶ÃÈÁ¸°¥—ƒraRB<90F4%7œéÁqVÏÿìèùôòðíêçäáÞÜÛÚÚÙØ×ØÙÜáéðó깃……sgM9 + Jž‘ — Ëÿ»\g‡“¦ÀÖçòþÿîÀ‰Y$ƒ%@j«·º´« •ŠyfXFQ9+.~×Ñp°ÿàî÷öôóðíéèå€ãââ€áââæêòõô᳊žª¥š”…q[EG%Iž‘ —ËÿÌ·ÐÝîú‚ÿéµ}K‰ @d†¢¬¯©¡™‘„ubP@0+i³×Ãóàð÷øø÷ôñí‚ë‚êëìïóøøóÛ–Lwž¬±­¦Ÿš’…xjScš‘ —Êÿùü‚ÿã«uB’>a‚œ§¤Ÿš•Œ}fZƒ‡¤Ðïåòøûüüùõó‡òóõ÷úüøëÙ^8Vr‘£§¢žœ™•› —ÌÿòÉIš Ts¤¡œ‘ŽÈ¹ž˜Ãéøùüÿÿüù‡ø ùùûüýýôèÝ,ƒ 4Zwœ¢¢žž‘ —ËïÀˆT#¡1Uu‘™§öàµ{`Úþýþÿÿýûû„ü‚ýþþýùÿ¤†/Liˆ›– —6¨3_ŠUuÿÿþþÿÿ‰þÿþÿê)Œ $:Ï Ôÿþýþ„ÿ€þ€ÿþöïfäFøÿýý‚üýþÿÿûìå…åRèÿý„úûûüý€þ÷âÔŽ ç4ÑÿÿûúûüûüðàÝé±€ÿ ýûúûûúùùûí̲eìGªíÿþþÿøØ±nð &d¬¹¼·q=öÿÿÿ£ÿÿÿÿÿÿÿÿÿÿóÿt8mk@L7 7uÇÊ}CLt Ñûݦq> 2mªÜûÿÿÿÿÿ뾈R 0c“ÅïÿýËÿÿÿÿýä¯zH .h¥ÙúÿÿÿÿÿÿÿÿÿÿÿÿÿóΗ`/ Dy©ÙùÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿ긆< V ÙùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùÚ¥f!IÀéÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿüÔj5 :u¯âÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòÄZ(K²ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûܧv> 5q­ßüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷Ó›g7 .`•ÊïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýã±}o¨ÜûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÞÜùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð  Ìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð  Îÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñ$  !&*+)/Óÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò9),+'#   *46-"&4AMW]^dÞÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöÑ¢u›Æóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõl^^YOD7( &6ET`ilsáÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõÛ¼Ÿiaegcg{œ¿Ýöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷zljbWG8( !1ARalrzäÿÿÿÿÿÿÿÿÿÿÿÿóØ» ‡xppuwyyyyyvrryˆ¦ÄàøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòÓâõÿÿÿÿÿÿÿÿÿÿÿÿÿ÷rmcUC4# '7JZgpzäÿÿÿÿÿÿÿÿðÓ·†ztvy{||||||||||||{zvv}ŒªÇâûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒ‡Š£»Óîÿÿÿÿÿÿÿÿÿ÷pi]M:+ -?Q_iuäÿÿÿÿ÷áÁuqsvwxxxxwwwvvwwwwwxxxyyyxvrsy»Ùóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþµvrqu€¿Úóÿÿÿÿÿø|jaTB/!  "2CP[iàô×·™ngfjkkkkjjjiihhhhhhhhhiijjkkkllllligmy—¸×ôÿÿÿÿúëàüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿã‘|pkkkkjgfmx’¬Éçüûp\SE5$#1=HRtgXQQTUVVUTTTSRQQQPOOONNNOOOPQQRRSTTUVVVWWWVSRZhв´•Òÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿü¤q_VSSTUUVVUURPT^sŠWH?4% !)177:<===<;;:99887655544333334456667899:;;;<==>???>:99;ETg‹ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀjQ?8889::;;<<=>=<9583+"  !$%%%$$##"""!  !!!"##$$%%&&'''''()1B[ŸýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐlJ0" !!""###$$%%%%%"   7UŸôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔiD(   4N‰éÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÇg?&5K|Øÿÿÿÿÿÿÿÿÿÿÿÿÿÿò°bB& .Ge™Ôúÿÿÿÿÿÿÿÿÿï¾}T?$% ?options? DESCRIPTION This class defines a widget for displaying the HDUs in the current FITS image. The user can select a FITS table or image extension to display by clicking on an entry the list or on one of the small images displayed in a table. ITK COMPONENTS buttons Button frame at bottom of window. image_table Frame (BLT table) used to display images in FITS extensions. table TableList(n) widget for displaying the list of HDUs. WIDGET OPTIONS -image Target RtdImage itcl class object. PUBLIC METHODS show_hdu_list {} Update the list of HDUs and the image displays, if needed. PROTECTED METHODS add_image_bindings {im hdu name} Add bindings to the given RtdImage itcl class object and set it to display the given HDU when clicked on. The image's extension name is also given. display_fits_table {name} Display the current FITS table. init {} This method is called after the options have been evaluated. make_buttons {} Add a row of buttons at bottom. make_image_table {} Make a subwindow for displaying miniature versions of image extensions. make_short_help {} Add a short help window. make_table {} Make the table component for displaying the HDU info. resize {im new_width new_height} This method is called when the image window is resized. The rtdImage widget and the new width and height are given. select_hdu {} Select an HDU to display. This makes it the current HDU. PROTECTED VARIABLES filename_ Name of image file. image_ Internal rtdimage object. imagetab_ Table displaying image extensions. table_ Table displaying the HDUs. COMMON CLASS VARIABLES astrocat_ C++ astrocat object use here to access catalog entries. SEE ALSO TopLevelWidget(n) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/skycat/man/SkySearch.man3000066400000000000000000000061141215713201500216640ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: SkySearch.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 27 Mar 98 Created NAME SkySearch - C++ class to extend the "astrocat" Tcl command PARENT CLASS TclAstroCat SYNOPSIS #include "SkySearch.h" class SkySearch : public TclAstroCat { ... public: SkySearch(Tcl_Interp* interp, const char* cmdname, const char* instname); static int astroCatCmd(ClientData, Tcl_Interp* interp, int argc, char* argv[]); virtual int imgplotCmd(int argc, char* argv[]); }; DESCRIPTION The SkySearch class extends the "astrocat" Tcl command (class TclAstroCat) with image plotting capabilities. The plot method was originally implemented as an Itcl method (see SkySearch(n)), but this turned out to be slow for large numbers of plot symbols. This class improves the plotting performace by making use of C++ symbol drawing methods defined in the Skycat class. This class adds a "plot" subcommand to the astrocat Tcl command. PUBLIC METHODS astroCatCmd(clientData, interp, argc, argv) This is the entry point from Tcl. This static method is called when the astrocat command is used. It creates a new Tcl command with the same name as its first argument, that can be used to access the astrocat and skysearch subcommands. the object can be deleted with the "delete" subcommand. imgplotCmd(argc, argv) This method implements the "plot" subcommand: usage: $instName imgplot $image ?$data? ?$equinox? ?$headings? This subcommand is used to plot catalog objects on the skycat image and was reimplemented here in C++ code to improve performance for large complicated catalogs. $image is the name of the image object ("rtdimage" object, implemented by the RtdImage C++ class and extended by the Skycat C++ class). If $data is specified, it should be a Tcl list of rows to be plotted, in the format returned by the query command. If $equinox is specified, it is the equinox of the ra and dec columns in the data (the first 3 columns are assumed to be id, ra and dec, unless otherwise defined in the catalog config entry or header). If $headings is given, it is used as a Tcl list of column headings. Otherwise the catalog headings are used, if there is a current catalog. Note: normally you will need to specify all the arguments, since the querries are done in the background (See AstroCat(n) (cat package) and Batch(n) (tclutil package)). The information for the previous query is lost when the background process exits. This might change if queries were done using threads or if the background/interrupt handling were done in the C++ code rather than in the Tcl code, as it is done now. SEE ALSO astrocat(n), AstroCat(n), SkyCat(n), SkySearch(n), RtdImage(3), TkImage(3), TclCommand(3), Batch(n) -------------------------------------------------------------------- skycat-3.1.2-starlink-1b/skycat/man/Skycat.man3000066400000000000000000000335531215713201500212350ustar00rootroot00000000000000# E.S.O. - VLT project # # "@(#) $Id: Skycat.man3,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 27 Mar 98 Created NAME Skycat - A C++ class that extends the rtdimage Tk image type PARENT CLASS RtdImage SYNOPSIS #include "Skycat.h" class Skycat : public RtdImage { ... public: Skycat(Tcl_Interp*, const char* instname, int argc, char** argv, Tk_ImageMaster master, const char* imageType, Tk_ConfigSpec* specs = (Tk_ConfigSpec*)NULL, RtdImageOptions* options = (RtdImageOptions*)NULL); virtual ~Skycat() {} virtual int call(const char* name, int len, int argc, char* argv[]); static int CreateImage(Tcl_Interp*, char *name, int argc, char **argv, Tk_ImageType*, Tk_ImageMaster, ClientData*); static Skycat* getInstance(char* name); int get_compass(double x, double y, const char* xy_units, double radius, const char* radius_units, double ratio, double angle, double& cx, double& cy, double& nx, double& ny, double& ex, double& ey); int rotate_point(double& x, double& y, double cx, double cy, double angle); int make_label(ostream& os, const char* label, double x, double y, const char* tags, const char* color, const char* font = "-*-courier-medium-r-*-*-*-120-*-*-*-*-*-*"); int draw_symbol(const char* shape, double x, double y, const char* xy_units, double radius, const char* radius_units, const char* bg, const char* fg, const char* symbol_tags, double ratio = 1., double angle = 0., const char* label = NULL, const char* label_tags = NULL); int draw_circle(double x, double y, const char* xy_units, double radius, const char* radius_units, const char* bg, const char* fg, const char* symbol_tags, double ratio = 1., double angle = 0., const char* label = NULL, const char* label_tags = NULL); int draw_square(double x, double y, const char* xy_units, double radius, const char* radius_units, const char* bg, const char* fg, const char* symbol_tags, double ratio = 1., double angle = 0., const char* label = NULL, const char* label_tags = NULL); int draw_plus(double x, double y, const char* xy_units, double radius, const char* radius_units, const char* bg, const char* fg, const char* symbol_tags, double ratio = 1., double angle = 0., const char* label = NULL, const char* label_tags = NULL); int draw_cross(double x, double y, const char* xy_units, double radius, const char* radius_units, const char* bg, const char* fg, const char* symbol_tags, double ratio = 1., double angle = 0., const char* label = NULL, const char* label_tags = NULL); int draw_triangle(double x, double y, const char* xy_units, double radius, const char* radius_units, const char* bg, const char* fg, const char* symbol_tags, double ratio = 1., double angle = 0., const char* label = NULL, const char* label_tags = NULL); int draw_diamond(double x, double y, const char* xy_units, double radius, const char* radius_units, const char* bg, const char* fg, const char* symbol_tags, double ratio = 1., double angle = 0., const char* label = NULL, const char* label_tags = NULL); int draw_ellipse(double x, double y, const char* xy_units, double radius, const char* radius_units, const char* bg, const char* fg, const char* symbol_tags, double ratio = 1., double angle = 0., const char* label = NULL, const char* label_tags = NULL); int draw_compass(double x, double y, const char* xy_units, double radius, const char* radius_units, const char* bg, const char* fg, const char* symbol_tags, double ratio = 1., double angle = 0., const char* label = NULL, const char* label_tags = NULL); int draw_line(double x, double y, const char* xy_units, double radius, const char* radius_units, const char* bg, const char* fg, const char* symbol_tags, double ratio = 1., double angle = 0., const char* label = NULL, const char* label_tags = NULL); int draw_arrow(double x, double y, const char* xy_units, double radius, const char* radius_units, const char* bg, const char* fg, const char* symbol_tags, double ratio = 1., double angle = 0., const char* label = NULL, const char* label_tags = NULL); int symbolCmd(int argc, char* argv[]); int hduCmd(int argc, char* argv[]); }; DESCRIPTION Class Skycat extends the RtdImage C++ class by adding methods for drawing symbols in an image based in world or image coordinates and by adding support for FITS tables and multiple FITS HDUs. Since the RtdImage class implements the rtdimage Tk image type, this class adds features to the rtdimage command as well. The symbol drawing methods defined here were originally implemented in Itcl and were later moved here to improve performance when plotting large numbers of symbols in an image. CONSTRUCTOR Skycat(interp, instname, argc, argv, master, imageType, specs, options) Create a new skycat extended rtdimage object with the given name and arguments. The optional arguments "specs" and "options" allow derived classes to add new configuration options. See RtdImage(3) for hints on how to add new subcommand and options. The imageType argument is normally "rtdimage", but could be set to a different name, if you do not want to redefine the rtdimage type, but add a new one instead. The "master" argument is a Tk struct that contains pointers to the image handling routines. METHODS call(name, len, argc, argv) This virtual method is defined at every level in the class hierarchy and is used to call a member function by specifying the name as a string. This is used to implement rtdimage subcommands by passing control from Tcl to C++. All of the methods that implement subcommands take the same arguments: argc and argv, the Tcl command line arguments. CreateImage(interp, name, argc, argv, type, master, clientData) This is the entry point from tcl to create a image. getInstance(name) Return a pointer to the Skycat class object for the given tcl rtdimage instance name, or NULL if the name is not an rtdimage. get_compass(x, y, xy_units, radius, radius_units, ratio, angle, cx, cy, nx, ny, ex, ey) Return the canvas coordinates of the 3 points: center, north and east, given the center point and radius in the given units, an optional rotation angle, and an x/y ellipticity ratio. If the image supports world coordinates, that is taken into account (the calculations are done in RA,DEC before converting to canvas coords). The conversion to canvas coords automatically takes the current zoom and rotate settings into account. The return arguments {cx cy nx ny ex ey} are for the 3 points center, north and east. rotate_point(x, y, cx, cy, angle) Rotate the point x,y around the center point cx,cy by the given angle in degrees. make_label(os, label, x, y, tags, color, font) Write a Tcl canvas command to the given stream to add a label to the image at the given canvas coordinates with the given label text, color and canvas tags. draw_symbol(shape, x, y, xy_units, radius, radius_units, bg, fg, symbol_tags, ratio, angle, label, label_tags) Draw a symbol on the image with the given shape at the given coordinates (in the given x,y units), with the given radius (in radius_units), bg and fg color, canvas tags list, x/y ratio and rotation angle. shape may be one of "circle", "square", "plus", "cross", "triangle", "diamond", "ellipse", "compass", "line", "arrow". x and y are the coordinates in "xy_units", which is one of the units accepted by the Rtd commands (canvas, image, screen, "wcs $equinox", "deg $equinox"). The radius value is interpreted in radius_units. bg and fg are X color names for the symbol (may be the same). symbol_tags should be a Tcl list of canvas tags for the symbol. ratio and angle are used to stretch/shrink and rotate the symbol. label is an optional text for a label to place near the symbol. label_tags should be a Tcl list of canvas tags for the label, or an empty or null string, if there is no label. Returns an error if the coordinates or part of the symbol are off the image. This method uses world coordinates, if available, for the rotation and orientation, for symbols that support it (i.e.: rotation is relative to WCS north). draw_square(x, y, xy_units, radius, radius_units, bg, fg, symbol_tags, ratio, angle, label, label_tags) draw_circle(...) draw_plus(...) draw_cross(...) draw_triangle(...) draw_diamond(...) draw_ellipse(...) draw_compass(...) draw_line(...) draw_arrow(...) These methods each draw one type of symbol. They are called by the draw_symbol method and have the same arguments (but no shape argument, of course). symbolCmd(argc, argv) This method implements a the Tcl symbol subcommand (a new rtdimage subcommand added in this subclass): Usage: $instName symbol $shape $x $y $xy_units $radius $radius_units \ $bg $fg $symbol_tags ?$ratio $angle $label $label_tags? Draw a symbol on the image with the given shape at the given coordinates (in the given x,y units), with the given radius (in radius_units), bg and fg color, canvas tags list, x/y ratio and rotation angle. shape may be one of "circle", "square", "plus", "cross", "triangle", "diamond", "ellipse", "compass", "line", "arrow". x and y are the coordinates in "xy_units", which is one of the units accepted by the Rtd commands (canvas, image, screen, "wcs $equinox", "deg $equinox"). The radius value is interpreted in radius_units. bg and fg are X color names for the symbol (may be the same). symbol_tags should be a Tcl list of canvas tags for the symbol. ratio and angle are optional and used to stretch/shrink and rotate the symbol. The default ratio is 1, default angle 0. label is an optional text for a label to place near the symbol. label_tags should be a Tcl list of canvas tags for the label, or an empty or null string, if there is no label. Returns an error if the coordinates or part of the symbol are off the image. Uses world coordinates, if available, for the rotation and orientation, for symbols that support it (i.e.: rotation is relative to WCS north). hduCmd(argc, argv) This method implements the "hdu" subcommand, to access different FITS HDUs (header data units). Each HDU may be of type "image", "binary" table or "ascii" table. Usage: hdu count or: hdu list or: hdu listheadings or: hdu type ?number? or: hdu headings ?$number? or: hdu get ?$number? ?$filename? ?$entry? or: hdu create $type $extname $headings $tform $data or: hdu delete $number or: hdu set $number or: hdu ?$number? If the "hdu count" subcommand is specified, it returns the number of HDUs in the current image. The "hdu type" subcommand returns the type of the current or given HDU as a string "ascii", "binary" or "image". If the "hdu list" subcommand is specified, it returns a Tcl list of FITS HDU information of the form: {{number type extname naxis naxis1 naxis2 naxis3 crpix1 crpix2} ...} Where: - number is the HDU number - type is the HDU type: one of "image", "binary table", "ascii table". - extname is the value of the EXTNAME keyword, if set - naxis, naxis1, naxis2, naxis3 match the FITS keyword values. The "hdu listheadings" subcommand returns a list of the column names returned by the "hdu list" subcommand. This can be used to set the title of a table listing of the HDUs in a FITS file. The "hdu headings" subcommand returns a list of the column names in the current or given FITS table. The "hdu get" subcommand with no arguments returns the contents of the current ASCII or binary table as a Tcl list (a list of rows, where each row is a list of column values). If the HDU number is given, the contents of the given HDU are returned. If a filename argument is given, the FITS table is written to the given file in the form of a local (tab separated) catalog. If optional "entry" argument is given, it specifies the catalog config entry as a list of {{keyword value} {keyword value} ...}, as defined in the catalog config file (~/.skycat/skycat.cfg). The entry is written to the header of the local catalog file and is used mainly to specify plot symbol information for the catalog. The "hdu create" command creates a new FITS table in the current image file. $type maye be "ascii" for an ASCII table or "binary" for a binary FITS table. The name of the table is given by extname. The table headings and data correspond to the catalog headings and data. The tform argument is a list of FITS storage formats, one for each column, of the form {16A 2D 12A ...} (similar to FORTRAN formats, see the FITS docs). The "hdu delete" command deletes the given HDU. The argument is the HDU number. The other HDUs in the file following the deleted one are moved to fill the gap. If the "hdu" subcommand is specified with no arguments, it returns the current HDU number. If a number argument is given, the current HDU is set to that number. The "hdu set" subcommand sets the current HDU to the given number. The keyword "set" is optional (see below). An optional numerical argument may be passed to the "hdu" subcommand, in which case the "current HDU" is set to the given number. SEE ALSO SkyCat(n), SkySearch(3), RtdImage(3), TkImage(3), FitsIO(3) -------------------------------------------------------------------- skycat-3.1.2-starlink-1b/skycat/man/skycat.man1000066400000000000000000000176221215713201500212720ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # $Id: skycat.man1,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is processed by the ESO/VLT docDoManPages command to # produce a man page in nroff, TeX and MIF formats. # See docDoManPages(1) for a description of the input format. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 5 Feb 96 Created # NAME skycat - A tool for displaying astronomical images and catalogs SYNOPSIS skycat ?filename? ?-option value ...? OPTIONS ?-file filename? Specify a FITS file to display. '-' means read the file from the standard input. The '-file' part is optional, so you can also simply specify a file name. Image compression and decompression is done automatically, based on the file name suffix: .gzfits or .gfits for GZIP compression, .hfits for H-compress, and .cfits for UNIX compression. -cat bool If bool is 1, include 'Data-Servers' menu in the menubar (This is the default). The 'Data-Servers' menu gives you access to the ESO Archive extensions for browsing astronomical catalogs, plotting objects in the image window and getting images over the network from the image servers, such as the Digitized Sky server. -rtd bool If bool is 1, include the Real-Time menu in the menubar (default is 0). The Real-Time menu gives you access to the VLT Real-Time Display features, such as camera control and rapid frames. To use these features, the rtdServer daemon must be running on the local host. A client application, linked with the Rtd image event library can then send images via shared memory to be displayed in rapid succession. -float_panel bool If the option value is 1, the skycat info panel is put in a separate popup window, leaving more space for the image window (The default is off). -panel_layout With this option you can change the order of the zoom and pan windows in the layout. The default layout is: zoom window on the left, info panel in the center and pan window right. If "-panel_layout saoimage" is specified, a layout similar to saoimage is used (info panel, pan window, zoom window). If "-panel_layout reverse" is specified, the order of the windows is the reverse of the default. -remote bool If "-remote 1" is specified and a skycat process is already running, the existing skycat process is sent a message and asked to open a new window and the new skycat process exits immediately. This has the advantage of sharing the image colormap and using fewer system resources, however it depends on being able to use the Tcl send mechanism. For security reasons, Tcl send will not work if you are using "xhost" based X security. You need to use X-auth security. See the "Tcl/Tk Tools" book from O'Reilly for more on this topic. -min_scale n -max_scale n Specify the min and max scale values for the Magnification menu. Negative values shrink the image, positive values zoom in closer. The default values are -10 and 20. -port portnum Specify a port number to use for the remote RTD socket interface. See the Rtd User's Guide for details on this socket based interface. By default, a port number is chosen automatically and written to the file ~/.rtd-remote. -disp_image_icon bool If bool is 1 (default), display a miniature version of the image in the tool's icon window. -default_cmap Specify the default colormap. This should be one of the names listed in the 'Colors' popup window (default is 'real'). -default_itt Specify the default intensity transfer table. This should be one of the names listed in the 'Colors' popup window (default is 'ramp'). -colorramp_height This option can be used to change the height of color bar (the widget at the bottom of the screen displaying the image colors). -with_colorramp bool If bool is true, display the color bar (default). -with_zoom_window bool If bool is true, display the zoom window (default). -with_pan_window bool If bool is true, display the pan window (default). -dozoom bool If bool is true, turn the zoom window on automatically (default). DESCRIPTION The ESO Skycat tool combines the image display capabilities of the RTD (Real-Time Display) with a set of classes for accessing astronomical catalogs locally and over the network using HTTP. The tool allows you to view FITS images from files or from the Digitized Sky Survey (DSS). MENU ITEMS: File menu Open... Open and display a (FITS) image file. Reopen... Reload the image display after the image has changed on disk. Save as... Save the current image to a file. Save region as... Save a section of the current image to a file. Print... Print the current image to a file or printer. Clear Clear the image display. New Window Display up a new main window. Close Close the main window and exit if there are no more windows. Exit Exit the application. View menu Colors... Display a window for manipulating the image colormap. Cut Levels... Display a window for manipulating the image cut levels. Cuts... Display a graph of pixel values along a line drawn interactively over the image. Pick Object... Select an object or star in the image and display statistics. Fits Header... Display the FITS header for the current image. Pixel Table... Display a table of pixel values surrounding the mouse cursor. Magnification Set the magnification factor of the image display. Hide Control Panel Toggle the visibility of the upper control panel Hide Popup Windows Toggle the visibility of the popup windows. Graphics menu Toolbox Display the line graphics toolbox. Mode => Select the drawing mode. Width => Set the line width for drawing. Arrow => Select the arrow mode for lines. ArrorShape => Select the arrow shape for lines. Fill => Select the fill color for drawing. Outline => Select the outline color for drawing. Stipple => Select the stipple pattern for filling objects. Font => Select the font to use for labels. Smooth => Set the smooth option for drawing polygons Clear => Delete graphic objects. Delete => Delete selected graphic objects. Hide Graphics Toggle the visibility of the image line graphics Data-Servers Catalogs => Select a catalog from the menu. Image Servers => Select an image server from the menu. Archives => Select an archive from the menu. Local Catalogs => Select a local catalog from the menu. Real-time menu (displayed when -rtd 1 is specified) Attach Camera Attach the real-time camera - start receiving images. Detach Camera Detach the real-time camera - stop receiving images. Set Camera... Set the real-time camera name. Rapid Frame Create a rapid frame by interactively drawing a rectangle on the image. Help menu About Skycat... Display a window with information about this Skycat version. Help... Display information about Skycat in netscape (if netscape is available). ENVIRONMENT VARIABLES $SKYCAT_CONFIG If set, this is used as the URL to access the skycat configuration file, which contains the list of available catalogs and how to query them. By default, the configuration file is also searched for in $HOME/.skycat/skycat.cfg, and if that is not found, in the ESO default URL: http://archive.eso.org/skycat/skycat2.0.cfg. $SKYCAT_PLUGIN If set, this variable should be a colon separated list of files or directories containing skycat plugins. A skycat plugin is a Tcl script that defines a Tcl proc to be called for each instance of the main window. The script is sourced before any windows are created and can also load shared libraries dynamically to add new features. See the Skycat User's Guide (ftp://ftp.archive.eso.org/pub/skycat/docs) for more information. FILES http://archive.eso.org/skycat/skycat2.0.cfg - default configuration file. SEE ALSO SkyCat(n), Skycat(3), rtd(1), RtdImage(3), AstroCat(n) ---------------------------------------------------------------------- skycat-3.1.2-starlink-1b/skycat/pkgIndex.tcl.in000066400000000000000000000002231215713201500213120ustar00rootroot00000000000000# Tcl package index file, version 1.0 package ifneeded Skycat @PACKAGE_VERSION@ [list load [file join [file dirname $dir] @PKG_LIB_FILE@] Skycat] skycat-3.1.2-starlink-1b/skycat/skycat-star.in000077500000000000000000000027301215713201500212350ustar00rootroot00000000000000#!/bin/sh # Start script for skycat # # "@(#) $Id$" # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 28 Jan 06 created # Determine skycat base dir, following any symbolic links, if needed. PRG="$0" while [ -h "$PRG" ]; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`/"$link" fi done DIR=`dirname "$PRG"`/.. SKYCAT_BASE=`(cd $DIR; pwd)` # If we're NOT ssh'd in if [ ! "${SSH_TTY}" ]; then # make sure X is running (on Mac OS X) if [ `uname` = "Darwin" ] ; then if [ "`ps -x | awk '{print $5}' | grep X11`" = "" ]; then for i in /Applications/Utilities $HOME/Desktop ; do if [ -e $i/X11.app ] ; then open $i/X11.app & break fi done fi fi # Make sure DISPLAY is set if [ x${DISPLAY} = x ]; then export DISPLAY=:0 fi fi # Make sure we can find the shared libs @LD_LIBRARY_PATH_VAR@="$SKYCAT_BASE/lib:@BLT_LIB_DIR@:${@LD_LIBRARY_PATH_VAR@}" export @LD_LIBRARY_PATH_VAR@ # and the Tcl packages TCLLIBPATH="$SKYCAT_BASE/lib" export TCLLIBPATH # Make sure we start the correct wish binary PATH=$SKYCAT_BASE/bin:$PATH export PATH test -d $HOME/.skycat || mkdir $HOME/.skycat echo "`date`: Starting skycat with: $0 ${1+"$@"}" > $HOME/.skycat/log exec wish8.5 $SKYCAT_BASE/lib/skycat@PACKAGE_VERSION@/main.tcl ${1+"$@"} | tee -a $HOME/.skycat/log 2>&1 skycat-3.1.2-starlink-1b/skycat/skycat.in000077500000000000000000000030141215713201500202620ustar00rootroot00000000000000#!/bin/sh # Start script for skycat # # "@(#) $Id: skycat.in,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 28 Jan 06 created # Determine skycat base dir, following any symbolic links, if needed. PRG="$0" while [ -h "$PRG" ]; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`/"$link" fi done DIR=`dirname "$PRG"`/.. SKYCAT_BASE=`(cd $DIR; pwd)` # If we're NOT ssh'd in if [ ! ${SSH_TTY} ]; then # make sure X is running (on Mac OS X) if [ `uname` = "Darwin" ] ; then if [ "`ps -x | awk '{print $5}' | grep X11`" = "" ]; then for i in /Applications/Utilities $HOME/Desktop ; do if [ -e $i/X11.app ] ; then open $i/X11.app & break fi done fi fi # Make sure DISPLAY is set if [ x${DISPLAY} = x ]; then export DISPLAY=:0 fi fi # Make sure we can find the shared libs @LD_LIBRARY_PATH_VAR@="$SKYCAT_BASE/lib:@BLT_LIB_DIR@:${@LD_LIBRARY_PATH_VAR@}" export @LD_LIBRARY_PATH_VAR@ # and the Tcl packages TCLLIBPATH="$SKYCAT_BASE/lib" export TCLLIBPATH # Make sure we start the correct wish binary PATH=$SKYCAT_BASE/bin:$PATH export PATH test -d $HOME/.skycat || mkdir $HOME/.skycat echo "`date`: Starting skycat with: $0 ${1+"$@"}" > $HOME/.skycat/log exec wish8.4 $SKYCAT_BASE/lib/skycat@PACKAGE_VERSION@/main.tcl ${1+"$@"} | tee -a $HOME/.skycat/log 2>&1 skycat-3.1.2-starlink-1b/skycat/skycatConfig.sh.in000066400000000000000000000032711215713201500220230ustar00rootroot00000000000000# E.S.O. - VLT project # $Id: skycatConfig.sh.in,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # skycatConfig.sh -- # # This shell script (for sh) is generated automatically by Skycat's # configure script. It will create shell variables for most of # the configuration options discovered by the configure script. # This script is intended to be included by the configure scripts # for Skycat extensions so that they don't have to figure this all # out for themselves. This file does not duplicate information # already provided by tclConfig.sh, so you may need to use that # file in addition to this one. # # The information in this file is specific to a single platform. # Skycat's version number. skycat_VERSION='@PACKAGE_VERSION@' # The name of the Skycat library: skycat_LIB_FILE=@skycat_LIB_FILE@ # String to pass to linker to pick up the Skycat library from its # build directory. skycat_BUILD_LIB_SPEC='@skycat_BUILD_LIB_SPEC@' # Skycat build directory. skycat_BUILD_DIR='@skycat_BUILD_DIR@' # String to pass to linker to pick up the Skycat library from its # installed directory. skycat_LIB_SPEC='@skycat_LIB_SPEC@' # Location of the top-level source directories from which Skycat # was built. This is the directory that contains generic, unix, etc. # If Skycat was compiled in a different place than the directory # containing the source files, this points to the location of the sources, # not the location where Skycat was compiled. skycat_SRC_DIR='@skycat_SRC_DIR@' # List of object files used to build the library (for merging packages). skycat_PKG_OBJECTS='@skycat_PKG_OBJECTS@' # List of header filesinstalled for this library (for merging packages). skycat_PKG_HEADERS='@skycat_PKG_HEADERS@' skycat-3.1.2-starlink-1b/skycat/skycat_version.tcl.in000066400000000000000000000001571215713201500226120ustar00rootroot00000000000000# This file is generated by configure: DO NOT EDIT BY HAND proc skycat_version {} { return @SKYCAT_VERSION@ } skycat-3.1.2-starlink-1b/tclconfig/000077500000000000000000000000001215713201500171055ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/tclconfig/ChangeLog000066400000000000000000000471721215713201500206720ustar00rootroot000000000000002005-12-05 Don Porter * tcl.m4 (TEA_PUBLIC_*_HEADERS): Better support for finding header files for uninstalled Tcl and Tk. 2005-12-02 Jeff Hobbs * tcl.m4: correctly bump TEA_VERSION var to 3.4 2005-12-01 Daniel Steffen * unix/tcl.m4 (Darwin): fixed error when MACOSX_DEPLOYMENT_TARGET unset 2005-11-29 Jeff Hobbs * tcl.m4: *** Bump to TEA version 3.4 *** Add Windows x64 build support. Remove TEA_PATH_NOSPACE and handle the problem with ""s where necessary - the macro relied on TCLSH_PROG which didn't work for cross-compiles. 2005-11-27 Daniel Steffen * tcl.m4 (Darwin): add 64bit support, add CFLAGS to SHLIB_LD to support passing -isysroot in env(CFLAGS) to configure (flag can't be present twice, so can't be in both CFLAGS and LDFLAGS during configure), don't use -prebind when deploying on 10.4. (TEA_ENABLE_LANGINFO, TEA_TIME_HANDLER): add/fix caching. 2005-10-30 Daniel Steffen * tcl.m4: fixed two tests for TEA_WINDOWINGSYSTEM = "aqua" that should have been for `uname -s` = "Darwin" instead; added some missing quoting. (TEA_PROG_TCLSH, TEA_PROG_WISH): fix incorrect assumption that install location of tclConfig.sh/tkConfig.sh allows to determine the tclsh/wish install dir via ../bin. Indeed tcl/tk can be configured with arbitrary --libdir and --bindir (independent of prefix) and such a configuration is in fact standard with Darwin framework builds. At least now also check ${TCL_PREFIX}/bin resp. ${TK_PREFIX}/bin for presence of tclsh resp. wish (if tcl/tk have been configured with arbitrary --bindir, this will still not find them, for a general solution *Config.sh would need to contain the values of bindir/libdir/includedir passed to configure). 2005-10-07 Jeff Hobbs * tcl.m4: Fix Solaris 5.10 check and Solaris AMD64 64-bit builds. 2005-10-04 Jeff Hobbs * tcl.m4 (TEA_PRIVATE_TCL_HEADERS): add / to finish sed macro (TEA_ENABLE_THREADS): don't check for pthread_attr_setstacksize func 2005-09-13 Jeff Hobbs * tcl.m4: *** Update to TEA version 3.3 *** define TEA_WINDOWINGSYSTEM in TEA_LOAD_TKCONFIG. Make --enable-threads the default (users can --disable-threads). Improve AIX ${CC}_r fix to better check existing ${CC} value. Do the appropriate evals to not require the *TOP_DIR_NATIVE vars be set for extensions that use private headers. Make aqua check for Xlib compat headers the same as win32. 2005-07-26 Mo DeJong * tcl.m4 (TEA_PROG_TCLSH, TEA_BUILD_TCLSH, TEA_PROG_WISH, TEA_BUILD_WISH): Remove TEA_BUILD_TCLSH and TEA_BUILD_WISH because of complaints that it broke the build when only an installed version of Tcl was available at extension build time. The TEA_PROG_TCLSH and TEA_PROG_WISH macros will no longer search the path at all. The build tclsh or installed tclsh shell will now be found by TEA_PROG_TCLSH. 2005-07-24 Mo DeJong * tcl.m4 (TEA_PROG_TCLSH, TEA_BUILD_TCLSH, TEA_PROG_WISH, TEA_BUILD_WISH): Split confused search for tclsh on PATH and build and install locations into two macros. TEA_PROG_TCLSH and TEA_PROG_WISH search the system PATH for an installed tclsh or wish. The TEA_BUILD_TCLSH and TEA_BUILD_WISH macros determine the name of tclsh or wish in the Tcl or Tk build directory even if tclsh or wish has not yet been built. [Tcl bug 1160114] [Tcl patch 1244153] 2005-06-23 Daniel Steffen * tcl.m4 (TEA_PRIVATE_TK_HEADERS): add ${TK_SRC_DIR}/macosx to TK_INCLUDES when building against TkAqua. * tcl.m4 (TEA_PATH_X): fixed missing comma in AC_DEFINE * tcl.m4: changes to better support framework builds of Tcl and Tk out of the box: search framework install locations for *Config.sh, and if in presence of a framework build, use the framework's Headers and PrivateHeaders directories for public and private includes. [FR 947735] 2005-06-18 Daniel Steffen * tcl.m4 (Darwin): add -headerpad_max_install_names to LDFLAGS to ensure we can always relocate binaries with install_name_tool. 2005-06-04 Daniel Steffen * tcl.m4 (TEA_PATH_X): for TEA_WINDOWINGSYSTEM == aqua, check if xlib compat headers are available in tkheaders location, otherwise add xlib sourcedir to TK_XINCLUDES. 2005-04-25 Daniel Steffen * tcl.m4: added AC_DEFINE* descriptions (from core tcl.m4) to allow use with autoheader. (Darwin): added configure checks for recently added linker flags -single_module and -search_paths_first to allow building with older tools (and on Mac OS X 10.1), use -single_module in SHLIB_LD. (TEA_MISSING_POSIX_HEADERS): added caching of dirent.h check. (TEA_BUGGY_STRTOD): added caching (sync with core tcl.m4). 2005-03-24 Jeff Hobbs * tcl.m4 (TEA_TCL_64BIT_FLAGS): use Tcl header defaults for wide int type only on Windows when __int64 is detected as valid. 2005-03-24 Don Porter * README.txt: Update reference to "SC_* macros" to "TEA_* macros". * tcl.m4: Incorporated recent improvements in SC_PATH_TCLCONFIG and SC_PATH_TKCONFIG into TEA_PATH_TCLCONFIG and TEA_PATH_TKCONFIG. Corrected search path in TEA_PATH_CONFIG and added AC_SUBST($1_BIN_DIR) to TEA_LOAD_CONFIG so that packages that load the configuration of another package can know where they loaded it from. 2005-03-18 Jeff Hobbs * tcl.m4 (TEA_CONFIG_CFLAGS): correct 2005-03-17 change to have variant LD_SEARCH_FLAGS for gcc and cc builds. * tcl.m4 (TEA_PROG_TCLSH, TEA_PROG_WISH): correct x-compile check. 2005-03-17 Jeff Hobbs * tcl.m4: Correct gcc build and HP-UX-11. 2005-02-08 Jeff Hobbs * tcl.m4 (TEA_ADD_LIBS): don't touch lib args starting with -. (TEA_CONFIG_CFLAGS): only define _DLL for CE in shared build. (TEA_MAKE_LIB): set RANLIB* to : on Windows (it's not needed). 2005-02-01 Jeff Hobbs * tcl.m4: redo of 2005-01-27 changes to correctly handle paths with spaces. Win/CE and Win/64 builds now require a prebuilt tclsh to handle conversion to short pathnames. This is done in the new TEA_PATH_NOSPACE macro. For Win/CE|64, make CC just the compiler and move the necessary includes to CFLAGS. (TEA_CONFIG_CFLAGS): Add Solaris 64-bit gcc build support. (TEA_PROG_TCLSH, TEA_PROG_WISH): Allow TCLSH_PROG and WISH_PROG to be set in the env and prevent resetting. (TEA_ADD_LIBS): On Windows using GCC (mingw), convert foo.lib args to -lfoo, for use with mingw. *** POTENTIAL INCOMPATABILITY *** (TEA_CONFIG_CFLAGS): Fix AIX gcc builds to work out-of-box. Bumped TEA to 3.2. 2005-01-27 Jeff Hobbs * tcl.m4: remove cygpath calls to support msys. Update base CE build assumption to "420,ARMV4,ARM,Pocket PC 2003". Make STLIB_LD use $LINKBIN -lib. 2005-01-25 Daniel Steffen * tcl.m4 (Darwin): fixed bug with static build linking to dynamic library in /usr/lib etc instead of linking to static library earlier in search path. [Tcl Bug 956908] Removed obsolete references to Rhapsody. 2004-12-29 Jeff Hobbs * tcl.m4: Updates for VC7 compatibility, fixing CFLAGS and LDFLAGS options, using better default -O levels. [Bug 1092952, 1091967] 2004-12-29 Joe English * tcl.m4: Do not use ${DBGX} suffix when building shared libraries [patch #1081595, TIP #34] 2004-09-07 Jeff Hobbs * tcl.m4 (TEA_CONFIG_CFLAGS): support eVC4 Win/CE builds 2004-08-10 Jeff Hobbs * tcl.m4 (TEA_INIT, TEA_PREFIX): update handling of exec_prefix to work around subdir configures since autoconf only propagates the prefix (not exec_prefix). 2004-07-23 Daniel Steffen * tcl.m4 (TEA_CONFIG_CFLAGS): Darwin section: brought inline with Tcl 8.5 HEAD config, removed core specific & obsolete settings. 2004-07-22 Jeff Hobbs * tcl.m4 (TEA_PATH_X): check in TK_DEFS for MAC_OSX_TK to see if we are compiling on Aqua. Add TEA_WINDOWINGSYSTEM var that reflects 'tk windowingsystem' value. 2004-07-16 Jeff Hobbs * tcl.m4 (TEA_ENABLE_THREADS): force a threaded build when building against a threaded core. (CFLAGS_WARNING): Remove -Wconversion for gcc builds (TEA_CONFIG_CFLAGS): Reorder configure.in for better 64-bit build configuration, replacing EXTRA_CFLAGS with CFLAGS. [Bug #874058] Update to latest Tcl 8.5 head config settings. Call this TEA version 3.1. 2004-04-29 Jeff Hobbs * tcl.m4 (TEA_TCL_64BIT_FLAGS): replace AC_TRY_RUN test with AC_TRY_COMPILE for the long vs. long long check. (kenny) 2004-04-26 Jeff Hobbs * tcl.m4 (TEA_TCL_64BIT_FLAGS): update against core tcl.m4 to define TCL_WIDE_INT_IS_LONG if 'using long'. 2004-03-19 Jeff Hobbs * tcl.m4: correct Windows builds getting LDFLAGS info in MAKE_LIB 2004-02-11 Jeff Hobbs * tcl.m4: correct TCL_INCLUDES for private headers on Windows - it doesn't need the eval. 2004-02-10 Jeff Hobbs * tcl.m4: don't require TK_INCLUDES and TCL_INCLUDES to have the DIR_NATIVE vars defined when using private headers on unix. Allow $... to TEA_ADD_SOURCES for constructs like TEA_ADD_SOURCES([\$(WIN_OBJECTS)]), that allow the developer to place more in the Makefile.in. tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and CHECK on limits.h 2003-12-10 Jeff Hobbs * Makefile.in: added TEA_ADD_LIBS, TEA_ADD_INCLUDES and * configure: TEA_ADD_CFLAGS to configurable parameters with * configure.in: PKG_* equivs in the Makefile. This allows the * tclconfig/tcl.m4: user to worry less about actual magic VAR names. Corrected Makefile.in to note that TEA_ADD_TCL_SOURCES requires exact file names. 2003-12-09 Jeff Hobbs * tcl.m4: updated OpenBSD support based on [Patch #775246] (cassoff) 2003-12-05 Jeff Hobbs * configure: * configure.in: * Makefile.in (VPATH): readd $(srcdir) to front of VPATH as the first part of VPATH can get chopped off. Change .c.$(OBJEXT) rule to .c.@OBJEXT@ to support more makes. * tclconfig/tcl.m4: add TEA_ADD_STUB_SOURCES to support libstub generation and TEA_ADD_TCL_SOURCES to replace RUNTIME_SOURCES as the way the user specifies library files. 2003-12-03 Jeff Hobbs * configure: Update of TEA spec to (hopefully) simplify * configure.in: some aspects of TEA by making use of more * Makefile.in: AC 2.5x features. Use PACKAGE_NAME (instead * generic/tclsample.c: of PACKAGE) and PACKAGE_VERSION (instead of * tclconfig/tcl.m4: VERSION) arguments to AC_INIT as the TEA package name and version. Provide a version argument to TEA_INIT - starting with 3.0. Drop all use of interior shell substs that older makefiles didn't like. Use PKG_* naming convention instead. Move specification of source files and public headers into configure.in with TEA_ADD_SOURCES and TEA_ADD_HEADERS. These will be munged during ./configure into the right obj file names (no $(SOURCES:.c=.obj) needed). There is almost nothing that should be touched in Makefile.in now for the developer. May want to add a TEA_ADD_TCL_SOURCES for the RUNTIME_SOURCES that remains. Use SHLID_LD_FLAGS (instead of SHLID_LDFLAGS) as Tcl does. Only specify the user requested LDFLAGS/CFLAGS in the Makefile, don't mention the _OPTIMIZE/_DEBUG variants. 2003-10-15 Jeff Hobbs * tcl.m4: create a TEA_SETUP_COMPILER_CC the precedes the TEA_SETUP_COMPILER macro. They are split so the check for CC occurs before any use of CC. Also add AC_PROG_CPP to the compiler checks. 2003-10-06 Jeff Hobbs * tcl.m4: Updated for autoconf 2.5x prereq. Where TCL_WIDE_INT_TYPE would be __int64, defer to the code checks in tcl.h, which also handles TCL_LL_MODIFIER* properly. 2003-04-22 Jeff Hobbs * tcl.m4: correct default setting of ARCH for WinCE builds. Correct \ escaping for CE sed macros. 2003-04-10 Jeff Hobbs * tcl.m4: replace $(syscal) construct with older `syscall` for systems where sh != bash. 2003-04-09 Jeff Hobbs * tcl.m4 (TEA_WITH_CELIB): add --enable-wince and --with-celib options for Windows/CE compilation support. Requires the Microsoft eMbedded SDK and Keuchel's celib emulation layer. 2003-02-18 Jeff Hobbs * tcl.m4 (TEA_ENABLE_THREADS): Make sure -lpthread gets passed on the link line when checking for the pthread_attr_setstacksize symbol. (dejong) * tcl.m4 (TEA_SETUP_COMPILER): added default calls to TEA_TCL_EARLY_FLAGS, TEA_TCL_64BIT_FLAGS, TEA_MISSING_POSIX_HEADERS and TEA_BUGGY_STRTOD. 2003-02-14 Jeff Hobbs * tcl.m4: correct HP-UX ia64 --enable-64bit build flags 2003-01-29 Jeff Hobbs * tcl.m4: check $prefix/lib as well as $exec_prefix/lib when looking for tcl|tkConfig.sh, as this check is done before we would set exec_prefix when the user does not define it. 2003-01-21 Mo DeJong * tcl.m4 (TEA_CONFIG_CFLAGS): Fix build support for mingw, the previous implementation would use VC++ when compiling with mingw gcc. Don't pass -fPIC since gcc always compiles pic code under win32. Change some hard coded cases of gcc to ${CC}. 2002-10-15 Jeff Hobbs * tcl.m4: move the CFLAGS definition from TEA_ENABLE_SHARED to TEA_MAKE_LIB because setting too early confuses other AC_* macros. Correct the HP-11 SHLIB_LD_LIBS setting. * tcl.m4: add the CFLAGS definition into TEA_ENABLE_SHARED and make it pick up the env CFLAGS at configure time. 2002-10-09 Jeff Hobbs * tcl.m4: add --enable-symbols=mem option to enable TCL_MEM_DEBUG. Improved AIX 64-bit build support, allow it on AIX-4 as well. Enable 64-bit HP-11 compilation with gcc. Enable 64-bit IRIX64-6 cc build support. Correct FreeBSD thread library linkage. Add OSF1 static build support. Improve SunOS-5 shared build SHLIB_LD macro. 2002-07-20 Zoran Vasiljevic * tcl.m4: Added MINGW32 to list of systems checked for Windows build. Also, fixes some indentation issues with "--with-XXX" options. 2002-04-23 Jeff Hobbs * tcl.m4 (TEA_ENABLE_THREADS): added USE_THREAD_ALLOC define to use new threaded allocatory by default on Unix for Tcl 8.4. (TEA_CONFIG_CFLAGS): corrected LD_SEARCH_FLAGS for FreeBSD-3+. 2002-04-22 Jeff Hobbs * tcl.m4 (TEA_SETUP_COMPILER): removed call to AC_CYGWIN so that we can use autoconf 2.5x as well as 2.13. This prevents us from being able to warn against the use of cygwin gcc at configure time, but allows autoconf 2.5x, which is what is shipped with most newer systems. 2002-04-11 Jeff Hobbs * tcl.m4: Enabled COFF as well as CV style debug info with --enable-symbols to allow Dr. Watson users to see function info. More info on debugging levels can be obtained at: http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp 2002-04-03 Jeff Hobbs * tcl.m4: change all SC_* macros to TEA_*. The SC_ was for Scriptics, which is no more. TEA represents a better, independent prefix that won't need changing. Added preliminary mingw gcc support. [Patch #538772] Added TEA_PREFIX macro that handles defaulting the prefix and exec_prefix vars to those used by Tcl if none were specified. Added TEA_SETUP_COMPILER macro that encompasses the AC_PROG_CC check and several other basic AC_PROG checks needed for making executables. This greatly simplifies user's configure.in files. Collapsed AIX-5 defines into AIX-* with extra checks for doing the ELF stuff on AIX-5-ia64. Updated TEA_ENABLE_THREADS to take an optional arg to allow switching it on by default (for Thread) and add sanity checking to warn the user if configuring threads incompatibly. 2002-03-29 Jeff Hobbs * tcl.m4: made sure that SHLIB_LDFLAGS was set to LDFLAGS_DEFAULT. Removed --enable-64bit support for AIX-4 because it wasn't correct. Added -MT or -MD Windows linker switches to properly support symbols-enabled builds. 2002-03-28 Jeff Hobbs * tcl.m4: called AC_MSG_ERROR when SC_TEA_INIT wasn't called first instead of calling it as that inlines it each time in shell code. Changed Windows CFLAGS_OPTIMIZE to use -O2 instead of -Oti. Noted TCL_LIB_VERSIONS_OK=nodots for Windows builds. A few changes to support itcl (and perhaps others): Added support for making your own stub libraries to SC_MAKE_LIB. New SC_PATH_CONFIG and SC_LOAD_CONFIG that take a package name arg and find that ${pkg}Config.sh file. itk uses this for itcl. 2002-03-27 Jeff Hobbs * tcl.m4: made SC_LOAD_TKCONFIG recognize when working with a Tk build dir setup. Added EXTRA_CFLAGS and SHLIB_LD_LIBS substs to SC_CONFIG_CFLAGS. Added XLIBSW onto LIBS when it is defined. Remove TCL_LIBS from MAKE_LIB and correctly use SHLIB_LD_LIBS instead to not rely as much on tclConfig.sh cached info. Add TK_BIN_DIR to paths to find wish in SC_PROG_WISH. These move towards making TEA much more independent of *Config.sh. 2002-03-19 Jeff Hobbs * tcl.m4: corrected forgotten (UN)SHARED_LIB_SUFFIX and SHLIB_SUFFIX defines for Win. (SC_PATH_X): made this only do the check on unix platforms. 2002-03-12 Jeff Hobbs * README.txt: updated to reflect fewer files 2002-03-06 Jeff Hobbs * config.guess (removed): * config.sub (removed): removed unnecessary files * installFile.tcl (removed): * mkinstalldirs (removed): these aren't really necessary for making TEA work * tcl.m4 (SC_PUBLIC_TCL_HEADERS, SC_PUBLIC_TK_HEADERS): don't check /usr(/local)/include for includes on Windows when not using gcc 2002-03-05 Jeff Hobbs * tcl.m4: added warnings on Windows, removed RELPATH define and added TCL_LIBS to MAKE_LIB macro. This import represents 2.0.0, or a new start at attempting to make TEA much easier for C extension developers. **** moved from tclpro project to core tcl project, **** **** renamed to 'tclconfig' **** 2001-03-15 Karl Lehenbauer * installFile.tcl: Added updating of the modification time of the target file whether we overwrote it or decided that it hadn't changed. This was necessary for us to be able to determine whether or not a module install touched the file. 2001-03-08 Karl Lehenbauer * installFile.tcl: Added support for converting new-style (1.1+) Cygnus drive paths to Tcl-style. 2001-01-15 * tcl.m4: Added FreeBSD clause. 2001-01-03 * tcl.m4: Fixed typo in SC_LIB_SPEC where it is checking for exec-prefix. 2000-12-01 * tcl.m4: Concatenated most of the Ajuba acsite.m4 file so we don't need to modify the autoconf installation. * config.guess: * config.sub: * installFile.tcl: Added files from the itcl config subdirectory, which should go away. 2000-7-29 * Fixed the use of TCL_SRC_DIR and TK_SRC_DIR within TCL_PRIVATE_INCLUDES and TK_PRIVATE_INCLUDES to match their recent change from $(srcdir) to $(srcdir)/.. skycat-3.1.2-starlink-1b/tclconfig/README.txt000066400000000000000000000014541215713201500206070ustar00rootroot00000000000000These files comprise the basic building blocks for a Tcl Extension Architecture (TEA) extension. For more information on TEA see: http://www.tcl.tk/doc/tea/ This package is part of the Tcl project at SourceForge, and latest sources should be available there: http://tcl.sourceforge.net/ This package is a freely available open source package. You can do virtually anything you like with it, such as modifying it, redistributing it, and selling it either in whole or in part. CONTENTS ======== The following is a short description of the files you will find in the sample extension. README.txt This file install-sh Program used for copying binaries and script files to their install locations. tcl.m4 Collection of Tcl autoconf macros. Included by a package's aclocal.m4 to define TEA_* macros. skycat-3.1.2-starlink-1b/tclconfig/install-sh000077500000000000000000000042121215713201500211100ustar00rootroot00000000000000#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5; it is not part of GNU. # # $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" instcmd="$mvprog" chmodcmd="" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; *) if [ x"$src" = x ] then src=$1 else dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` fi # Make a temp file name in the proper directory. dstdir=`dirname $dst` dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp # and set any options; do chmod last to preserve setuid bits if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi # Now rename the file to the real destination. $doit $rmcmd $dst $doit $mvcmd $dsttmp $dst exit 0 skycat-3.1.2-starlink-1b/tclconfig/tcl.m4000066400000000000000000003606731215713201500201500ustar00rootroot00000000000000# tcl.m4 -- # # This file provides a set of autoconf macros to help TEA-enable # a Tcl extension. # # Copyright (c) 1999-2000 Ajuba Solutions. # Copyright (c) 2002-2005 ActiveState Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: tcl.m4,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ AC_PREREQ(2.50) # Possible values for key variables defined: # # TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem') # TEA_PLATFORM - windows unix # #------------------------------------------------------------------------ # TEA_PATH_TCLCONFIG -- # # Locate the tclConfig.sh file and perform a sanity check on # the Tcl compile flags # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-tcl=... # # Defines the following vars: # TCL_BIN_DIR Full path to the directory containing # the tclConfig.sh file #------------------------------------------------------------------------ AC_DEFUN(TEA_PATH_TCLCONFIG, [ dnl Make sure we are initialized AC_REQUIRE([TEA_INIT]) # # Ok, lets find the tcl configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tcl # if test x"${no_tcl}" = x ; then # we reset no_tcl in case something fails here no_tcl=true AC_ARG_WITH(tcl, [ --with-tcl directory containing tcl configuration (tclConfig.sh)], with_tclconfig=${withval}) AC_MSG_CHECKING([for Tcl configuration]) AC_CACHE_VAL(ac_cv_c_tclconfig,[ # First check to see if --with-tcl was specified. if test x"${with_tclconfig}" != x ; then case ${with_tclconfig} in */tclConfig.sh ) if test -f ${with_tclconfig}; then AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself]) with_tclconfig=`echo ${with_tclconfig} | sed 's!/tclConfig\.sh$!!'` fi ;; esac if test -f "${with_tclconfig}/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` else AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh]) fi fi # check in a few common install locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d ${TCLTK_ROOT}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i; pwd)` break fi done fi # then check for a private Tcl installation if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ../tcl \ `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ ../../tcl \ `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ ../../../tcl \ `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ `ls -d /System/Library/Frameworks 2>/dev/null` \ ; do if test -f "$i/Tcl.framework/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi ]) if test x"${ac_cv_c_tclconfig}" = x ; then TCL_BIN_DIR="# no Tcl configs found" AC_MSG_WARN("Cannot find Tcl configuration definitions") exit 0 else no_tcl= TCL_BIN_DIR=${ac_cv_c_tclconfig} AC_MSG_RESULT([found $TCL_BIN_DIR/tclConfig.sh]) fi fi ]) #------------------------------------------------------------------------ # TEA_PATH_TKCONFIG -- # # Locate the tkConfig.sh file # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-tk=... # # Defines the following vars: # TK_BIN_DIR Full path to the directory containing # the tkConfig.sh file #------------------------------------------------------------------------ AC_DEFUN(TEA_PATH_TKCONFIG, [ # # Ok, lets find the tk configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tk # if test x"${no_tk}" = x ; then # we reset no_tk in case something fails here no_tk=true AC_ARG_WITH(tk, [ --with-tk directory containing tk configuration (tkConfig.sh)], with_tkconfig=${withval}) AC_MSG_CHECKING([for Tk configuration]) AC_CACHE_VAL(ac_cv_c_tkconfig,[ # First check to see if --with-tkconfig was specified. if test x"${with_tkconfig}" != x ; then case ${with_tkconfig} in */tkConfig.sh ) if test -f ${with_tkconfig}; then AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself]) with_tkconfig=`echo ${with_tkconfig} | sed 's!/tkConfig\.sh$!!'` fi ;; esac if test -f "${with_tkconfig}/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)` else AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh]) fi fi # check in a few common install locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d ${TCLTK_ROOT}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ ; do if test -f "$i/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i; pwd)` break fi done fi # then check for a private Tk library if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ../tk \ `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \ ../../tk \ `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \ ../../../tk \ `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/unix; pwd)` break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ `ls -d /System/Library/Frameworks 2>/dev/null` \ ; do if test -f "$i/Tk.framework/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/Tk.framework; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ${srcdir}/../tk \ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/unix; pwd)` break fi done fi ]) if test x"${ac_cv_c_tkconfig}" = x ; then TK_BIN_DIR="# no Tk configs found" AC_MSG_WARN("Cannot find Tk configuration definitions") exit 0 else no_tk= TK_BIN_DIR=${ac_cv_c_tkconfig} AC_MSG_RESULT([found $TK_BIN_DIR/tkConfig.sh]) fi fi ]) #------------------------------------------------------------------------ # TEA_LOAD_TCLCONFIG -- # # Load the tclConfig.sh file # # Arguments: # # Requires the following vars to be set: # TCL_BIN_DIR # # Results: # # Subst the following vars: # TCL_BIN_DIR # TCL_SRC_DIR # TCL_LIB_FILE # #------------------------------------------------------------------------ AC_DEFUN(TEA_LOAD_TCLCONFIG, [ AC_MSG_CHECKING([for existence of $TCL_BIN_DIR/tclConfig.sh]) if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then AC_MSG_RESULT([loading]) . $TCL_BIN_DIR/tclConfig.sh else AC_MSG_RESULT([file not found]) fi # # If the TCL_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TCL_LIB_SPEC will be set to the value # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC # instead of TCL_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. # if test -f $TCL_BIN_DIR/Makefile ; then TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC} TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC} TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH} fi # # eval is required to do the TCL_DBGX substitution # eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\"" eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\"" AC_SUBST(TCL_VERSION) AC_SUBST(TCL_BIN_DIR) AC_SUBST(TCL_SRC_DIR) AC_SUBST(TCL_LIB_FILE) AC_SUBST(TCL_LIB_FLAG) AC_SUBST(TCL_LIB_SPEC) AC_SUBST(TCL_STUB_LIB_FILE) AC_SUBST(TCL_STUB_LIB_FLAG) AC_SUBST(TCL_STUB_LIB_SPEC) AC_SUBST(TCL_LIBS) AC_SUBST(TCL_DEFS) AC_SUBST(TCL_EXTRA_CFLAGS) AC_SUBST(TCL_LD_FLAGS) AC_SUBST(TCL_SHLIB_LD_LIBS) #AC_SUBST(TCL_BUILD_LIB_SPEC) #AC_SUBST(TCL_BUILD_STUB_LIB_SPEC) ]) #------------------------------------------------------------------------ # TEA_LOAD_TKCONFIG -- # # Load the tkConfig.sh file # # Arguments: # # Requires the following vars to be set: # TK_BIN_DIR # # Results: # # Sets the following vars that should be in tkConfig.sh: # TK_BIN_DIR #------------------------------------------------------------------------ AC_DEFUN(TEA_LOAD_TKCONFIG, [ AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh]) if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then AC_MSG_RESULT([loading]) . $TK_BIN_DIR/tkConfig.sh else AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh]) fi # # If the TK_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TK_LIB_SPEC will be set to the value # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC # instead of TK_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. # if test -f $TK_BIN_DIR/Makefile ; then TK_LIB_SPEC=${TK_BUILD_LIB_SPEC} TK_STUB_LIB_SPEC=${TK_BUILD_STUB_LIB_SPEC} TK_STUB_LIB_PATH=${TK_BUILD_STUB_LIB_PATH} fi # Ensure windowingsystem is defined if test "${TEA_PLATFORM}" = "unix" ; then case ${TK_DEFS} in *MAC_OSX_TK*) AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?]) TEA_WINDOWINGSYSTEM="aqua" ;; *) TEA_WINDOWINGSYSTEM="x11" ;; esac elif test "${TEA_PLATFORM}" = "windows" ; then TEA_WINDOWINGSYSTEM="win32" fi # # eval is required to do the TK_DBGX substitution # eval "TK_LIB_FILE=\"${TK_LIB_FILE}\"" eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\"" eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\"" eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\"" eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\"" eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\"" AC_SUBST(TK_VERSION) AC_SUBST(TK_BIN_DIR) AC_SUBST(TK_SRC_DIR) AC_SUBST(TK_LIB_FILE) AC_SUBST(TK_LIB_FLAG) AC_SUBST(TK_LIB_SPEC) AC_SUBST(TK_STUB_LIB_FILE) AC_SUBST(TK_STUB_LIB_FLAG) AC_SUBST(TK_STUB_LIB_SPEC) AC_SUBST(TK_LIBS) AC_SUBST(TK_XINCLUDES) AC_SUBST(TK_SRC_DIR) ]) #------------------------------------------------------------------------ # TEA_ENABLE_SHARED -- # # Allows the building of shared libraries # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --enable-shared=yes|no # # Defines the following vars: # STATIC_BUILD Used for building import/export libraries # on Windows. # # Sets the following vars: # SHARED_BUILD Value of 1 or 0 #------------------------------------------------------------------------ AC_DEFUN(TEA_ENABLE_SHARED, [ AC_MSG_CHECKING([how to build libraries]) AC_ARG_ENABLE(shared, [ --enable-shared build and link with shared libraries [--enable-shared]], [tcl_ok=$enableval], [tcl_ok=yes]) if test "${enable_shared+set}" = set; then enableval="$enable_shared" tcl_ok=$enableval else tcl_ok=yes fi if test "$tcl_ok" = "yes" ; then AC_MSG_RESULT([shared]) SHARED_BUILD=1 else AC_MSG_RESULT([static]) SHARED_BUILD=0 AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?]) fi AC_SUBST(SHARED_BUILD) ]) #------------------------------------------------------------------------ # TEA_ENABLE_THREADS -- # # Specify if thread support should be enabled. If "yes" is specified # as an arg (optional), threads are enabled by default, "no" means # threads are disabled. "yes" is the default. # # TCL_THREADS is checked so that if you are compiling an extension # against a threaded core, your extension must be compiled threaded # as well. # # Note that it is legal to have a thread enabled extension run in a # threaded or non-threaded Tcl core, but a non-threaded extension may # only run in a non-threaded Tcl core. # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --enable-threads # # Sets the following vars: # THREADS_LIBS Thread library(s) # # Defines the following vars: # TCL_THREADS # _REENTRANT # #------------------------------------------------------------------------ AC_DEFUN(TEA_ENABLE_THREADS, [ AC_ARG_ENABLE(threads, [ --enable-threads build with threads], [tcl_ok=$enableval], [tcl_ok=yes]) if test "${enable_threads+set}" = set; then enableval="$enable_threads" tcl_ok=$enableval else tcl_ok=yes fi if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then TCL_THREADS=1 if test "${TEA_PLATFORM}" != "windows" ; then # We are always OK on Windows, so check what this platform wants. AC_DEFINE(USE_THREAD_ALLOC, 1, [Do we want to use the threaded memory allocator?]) AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?]) AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no) if test "$tcl_ok" = "no"; then # Check a little harder for __pthread_mutex_init in the # same library, as some systems hide it there until # pthread.h is defined. We could alternatively do an # AC_TRY_COMPILE with pthread.h, but that will work with # libpthread really doesn't exist, like AIX 4.2. # [Bug: 4359] AC_CHECK_LIB(pthread, __pthread_mutex_init, tcl_ok=yes, tcl_ok=no) fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthread" else AC_CHECK_LIB(pthreads, pthread_mutex_init, tcl_ok=yes, tcl_ok=no) if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthreads" else AC_CHECK_LIB(c, pthread_mutex_init, tcl_ok=yes, tcl_ok=no) if test "$tcl_ok" = "no"; then AC_CHECK_LIB(c_r, pthread_mutex_init, tcl_ok=yes, tcl_ok=no) if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -pthread" else TCL_THREADS=0 AC_MSG_WARN("Don t know how to find pthread lib on your system - thread support disabled") fi fi fi fi dnl # Not needed in TEA dnl # Does the pthread-implementation provide dnl # 'pthread_attr_setstacksize' ? dnl dnl ac_saved_libs=$LIBS dnl LIBS="$LIBS $THREADS_LIBS" dnl AC_CHECK_FUNCS(pthread_attr_setstacksize) dnl LIBS=$ac_saved_libs fi else TCL_THREADS=0 fi # Do checking message here to not mess up interleaved configure output AC_MSG_CHECKING([for building with threads]) if test "${TCL_THREADS}" = "1"; then AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?]) #LIBS="$LIBS $THREADS_LIBS" AC_MSG_RESULT([yes (default)]) else AC_MSG_RESULT([no]) fi # TCL_THREADS sanity checking. See if our request for building with # threads is the same as the way Tcl was built. If not, warn the user. case ${TCL_DEFS} in *THREADS=1*) if test "${TCL_THREADS}" = "0"; then AC_MSG_WARN([ Building ${PACKAGE_NAME} without threads enabled, but building against Tcl that IS thread-enabled. It is recommended to use --enable-threads.]) fi ;; *) if test "${TCL_THREADS}" = "1"; then AC_MSG_WARN([ --enable-threads requested, but building against a Tcl that is NOT thread-enabled. This is an OK configuration that will also run in a thread-enabled core.]) fi ;; esac AC_SUBST(TCL_THREADS) ]) #------------------------------------------------------------------------ # TEA_ENABLE_SYMBOLS -- # # Specify if debugging symbols should be used # Memory (TCL_MEM_DEBUG) debugging can also be enabled. # # Arguments: # none # # Requires the following vars to be set: # CFLAGS_DEBUG # CFLAGS_OPTIMIZE # LDFLAGS_DEBUG # LDFLAGS_OPTIMIZE # # Results: # # Adds the following arguments to configure: # --enable-symbols # # Defines the following vars: # CFLAGS_DEFAULT Sets to CFLAGS_DEBUG if true # Sets to CFLAGS_OPTIMIZE if false # LDFLAGS_DEFAULT Sets to LDFLAGS_DEBUG if true # Sets to LDFLAGS_OPTIMIZE if false # DBGX Formerly used as debug library extension; # always blank now. # #------------------------------------------------------------------------ AC_DEFUN(TEA_ENABLE_SYMBOLS, [ dnl Make sure we are initialized AC_REQUIRE([TEA_CONFIG_CFLAGS]) DBGX="" AC_MSG_CHECKING([for build with symbols]) AC_ARG_ENABLE(symbols, [ --enable-symbols build with debugging symbols [--disable-symbols]], [tcl_ok=$enableval], [tcl_ok=no]) if test "$tcl_ok" = "no"; then CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}" LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}" AC_MSG_RESULT([no]) else CFLAGS_DEFAULT="${CFLAGS_DEBUG}" LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}" if test "$tcl_ok" = "yes"; then AC_MSG_RESULT([yes (standard debugging)]) fi fi if test "${TEA_PLATFORM}" != "windows" ; then LDFLAGS_DEFAULT="${LDFLAGS}" fi AC_SUBST(TCL_DBGX) AC_SUBST(CFLAGS_DEFAULT) AC_SUBST(LDFLAGS_DEFAULT) if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?]) fi if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then if test "$tcl_ok" = "all"; then AC_MSG_RESULT([enabled symbols mem debugging]) else AC_MSG_RESULT([enabled $tcl_ok debugging]) fi fi ]) #------------------------------------------------------------------------ # TEA_ENABLE_LANGINFO -- # # Allows use of modern nl_langinfo check for better l10n. # This is only relevant for Unix. # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --enable-langinfo=yes|no (default is yes) # # Defines the following vars: # HAVE_LANGINFO Triggers use of nl_langinfo if defined. # #------------------------------------------------------------------------ AC_DEFUN(TEA_ENABLE_LANGINFO, [ AC_ARG_ENABLE(langinfo, [ --enable-langinfo use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic], [langinfo_ok=$enableval], [langinfo_ok=yes]) HAVE_LANGINFO=0 if test "$langinfo_ok" = "yes"; then AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no]) fi AC_MSG_CHECKING([whether to use nl_langinfo]) if test "$langinfo_ok" = "yes"; then AC_CACHE_VAL(tcl_cv_langinfo_h, AC_TRY_COMPILE([#include ], [nl_langinfo(CODESET);], [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])) AC_MSG_RESULT($tcl_cv_langinfo_h) if test $tcl_cv_langinfo_h = yes; then AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?]) fi else AC_MSG_RESULT([$langinfo_ok]) fi ]) #-------------------------------------------------------------------- # TEA_CONFIG_CFLAGS # # Try to determine the proper flags to pass to the compiler # for building shared libraries and other such nonsense. # # Arguments: # none # # Results: # # Defines the following vars: # # DL_OBJS - Name of the object file that implements dynamic # loading for Tcl on this system. # DL_LIBS - Library file(s) to include in tclsh and other base # applications in order for the "load" command to work. # LDFLAGS - Flags to pass to the compiler when linking object # files into an executable application binary such # as tclsh. # LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib", # that tell the run-time dynamic linker where to look # for shared libraries such as libtcl.so. Depends on # the variable LIB_RUNTIME_DIR in the Makefile. # SHLIB_CFLAGS - Flags to pass to cc when compiling the components # of a shared library (may request position-independent # code, among other things). # SHLIB_LD - Base command to use for combining object files # into a shared library. # SHLIB_LD_LIBS - Dependent libraries for the linker to scan when # creating shared libraries. This symbol typically # goes at the end of the "ld" commands that build # shared libraries. The value of the symbol is # "${LIBS}" if all of the dependent libraries should # be specified when creating a shared library. If # dependent libraries should not be specified (as on # SunOS 4.x, where they cause the link to fail, or in # general if Tcl and Tk aren't themselves shared # libraries), then this symbol has an empty string # as its value. # SHLIB_SUFFIX - Suffix to use for the names of dynamically loadable # extensions. An empty string means we don't know how # to use shared libraries on this platform. # TCL_LIB_FILE - Name of the file that contains the Tcl library, such # as libtcl7.8.so or libtcl7.8.a. # TCL_LIB_SUFFIX -Specifies everything that comes after the "libtcl" # in the shared library name, using the # ${PACKAGE_VERSION} variable to put the version in # the right place. This is used by platforms that # need non-standard library names. # Examples: ${PACKAGE_VERSION}.so.1.1 on NetBSD, # since it needs to have a version after the .so, and # ${PACKAGE_VERSION}.a on AIX, since the Tcl shared # library needs to have a .a extension whereas shared # objects for loadable extensions have a .so # extension. Defaults to # ${PACKAGE_VERSION}${SHLIB_SUFFIX}. # TCL_NEEDS_EXP_FILE - # 1 means that an export file is needed to link to a # shared library. # TCL_EXP_FILE - The name of the installed export / import file which # should be used to link to the Tcl shared library. # Empty if Tcl is unshared. # TCL_BUILD_EXP_FILE - # The name of the built export / import file which # should be used to link to the Tcl shared library. # Empty if Tcl is unshared. # CFLAGS_DEBUG - # Flags used when running the compiler in debug mode # CFLAGS_OPTIMIZE - # Flags used when running the compiler in optimize mode # CFLAGS - We add CFLAGS to pass to the compiler # # Subst's the following vars: # DL_LIBS # CFLAGS_DEBUG # CFLAGS_OPTIMIZE # CFLAGS_WARNING # # STLIB_LD # SHLIB_LD # SHLIB_CFLAGS # LDFLAGS_DEBUG # LDFLAGS_OPTIMIZE #-------------------------------------------------------------------- AC_DEFUN(TEA_CONFIG_CFLAGS, [ dnl Make sure we are initialized AC_REQUIRE([TEA_INIT]) # Step 0: Enable 64 bit support? AC_MSG_CHECKING([if 64bit support is enabled]) AC_ARG_ENABLE(64bit,[ --enable-64bit enable 64bit support (where applicable)], [do64bit=$enableval], [do64bit=no]) AC_MSG_RESULT([$do64bit]) # Step 0.b: Enable Solaris 64 bit VIS support? AC_MSG_CHECKING([if 64bit Sparc VIS support is requested]) AC_ARG_ENABLE(64bit-vis,[ --enable-64bit-vis enable 64bit Sparc VIS support], [do64bitVIS=$enableval], [do64bitVIS=no]) AC_MSG_RESULT([$do64bitVIS]) if test "$do64bitVIS" = "yes"; then # Force 64bit on with VIS do64bit=yes fi # Step 0.c: Cross-compiling options for Windows/CE builds? if test "${TEA_PLATFORM}" = "windows" ; then AC_MSG_CHECKING([if Windows/CE build is requested]) AC_ARG_ENABLE(wince,[ --enable-wince enable Win/CE support (where applicable)], [doWince=$enableval], [doWince=no]) AC_MSG_RESULT($doWince) fi # Step 1: set the variable "system" to hold the name and version number # for the system. This can usually be done via the "uname" command, but # there are a few systems, like Next, where this doesn't work. AC_MSG_CHECKING([system version (for dynamic loading)]) if test -f /usr/lib/NextStep/software_version; then system=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version` else system=`uname -s`-`uname -r` if test "$?" -ne 0 ; then AC_MSG_RESULT([unknown (can't find uname command)]) system=unknown else # Special check for weird MP-RAS system (uname returns weird # results, and the version is kept in special file). if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then system=MP-RAS-`awk '{print $3}' /etc/.relid` fi if test "`uname -s`" = "AIX" ; then system=AIX-`uname -v`.`uname -r` fi if test "${TEA_PLATFORM}" = "windows" ; then system=windows fi AC_MSG_RESULT([$system]) fi fi # Step 2: check for existence of -ldl library. This is needed because # Linux can use either -ldl or -ldld for dynamic loading. AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no) # Step 3: set configuration options based on system name and version. # This is similar to Tcl's unix/tcl.m4 except that we've added a # "windows" case and CC_SEARCH_FLAGS becomes LD_SEARCH_FLAGS for us # (and we have no CC_SEARCH_FLAGS). do64bit_ok=no LDFLAGS_ORIG="$LDFLAGS" TCL_EXPORT_FILE_SUFFIX="" UNSHARED_LIB_SUFFIX="" TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`' ECHO_VERSION='`echo ${PACKAGE_VERSION}`' TCL_LIB_VERSIONS_OK=ok CFLAGS_DEBUG=-g if test "$GCC" = "yes" ; then CFLAGS_OPTIMIZE=-O2 CFLAGS_WARNING="-Wall -Wno-implicit-int" else CFLAGS_OPTIMIZE=-O CFLAGS_WARNING="" fi TCL_NEEDS_EXP_FILE=0 TCL_BUILD_EXP_FILE="" TCL_EXP_FILE="" dnl FIXME: Replace AC_CHECK_PROG with AC_CHECK_TOOL once cross compiling is fixed. dnl AC_CHECK_TOOL(AR, ar, :) AC_CHECK_PROG(AR, ar, ar) STLIB_LD='${AR} cr' LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH" case $system in windows) # This is a 2-stage check to make sure we have the 64-bit SDK # We have to know where the SDK is installed. # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs # MACHINE is IX86 for LINK, but this is used by the manifest, # which requires x86|amd64|ia64. MACHINE="X86" if test "$do64bit" != "no" ; then if test "x${MSSDK}x" = "xx" ; then MSSDK="C:/Progra~1/Microsoft Platform SDK" fi MSSDK=`echo "$MSSDK" | sed -e 's!\\\!/!g'` PATH64="" case "$do64bit" in amd64|x64|yes) MACHINE="AMD64" ; # default to AMD64 64-bit build PATH64="${MSSDK}/Bin/Win64/x86/AMD64" ;; ia64) MACHINE="IA64" PATH64="${MSSDK}/Bin/Win64" ;; esac if test ! -d "${PATH64}" ; then AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode]) AC_MSG_WARN([Ensure latest Platform SDK is installed]) do64bit="no" else AC_MSG_RESULT([ Using 64-bit $MACHINE mode]) do64bit_ok="yes" fi fi if test "$doWince" != "no" ; then if test "$do64bit" != "no" ; then AC_MSG_ERROR([Windows/CE and 64-bit builds incompatible]) fi if test "$GCC" = "yes" ; then AC_MSG_ERROR([Windows/CE and GCC builds incompatible]) fi TEA_PATH_CELIB # Set defaults for common evc4/PPC2003 setup # Currently Tcl requires 300+, possibly 420+ for sockets CEVERSION=420; # could be 211 300 301 400 420 ... TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ... ARCH=ARM; # could be ARM MIPS X86EM ... PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002" if test "$doWince" != "yes"; then # If !yes then the user specified something # Reset ARCH to allow user to skip specifying it ARCH= eval `echo $doWince | awk -F, '{ \ if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \ if ([$]1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \ if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \ if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \ if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \ }'` if test "x${ARCH}" = "x" ; then ARCH=$TARGETCPU; fi fi OSVERSION=WCE$CEVERSION; if test "x${WCEROOT}" = "x" ; then WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0" if test ! -d "${WCEROOT}" ; then WCEROOT="C:/Program Files/Microsoft eMbedded Tools" fi fi if test "x${SDKROOT}" = "x" ; then SDKROOT="C:/Program Files/Windows CE Tools" if test ! -d "${SDKROOT}" ; then SDKROOT="C:/Windows CE Tools" fi fi WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'` SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'` if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \ -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]]) doWince="no" else # We could PATH_NOSPACE these, but that's not important, # as long as we quote them when used. CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include" if test -d "${CEINCLUDE}/${TARGETCPU}" ; then CEINCLUDE="${CEINCLUDE}/${TARGETCPU}" fi CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" fi fi if test "$GCC" != "yes" ; then if test "${SHARED_BUILD}" = "0" ; then runtime=-MT else runtime=-MD fi if test "$do64bit" != "no" ; then # All this magic is necessary for the Win64 SDK RC1 - hobbs CC="\"${PATH64}/cl.exe\"" CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\"" RC="\"${MSSDK}/bin/rc.exe\"" lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\"" LINKBIN="\"${PATH64}/link.exe\"" CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d" CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" # Avoid 'unresolved external symbol __security_cookie' # errors, c.f. http://support.microsoft.com/?id=894573 TEA_ADD_LIBS([bufferoverflowU.lib]) elif test "$doWince" != "no" ; then CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin" if test "${TARGETCPU}" = "X86"; then CC="\"${CEBINROOT}/cl.exe\"" else CC="\"${CEBINROOT}/cl${ARCH}.exe\"" fi CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\"" RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\"" arch=`echo ${ARCH} | awk '{print tolower([$]0)}'` defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS" if test "${SHARED_BUILD}" = "1" ; then # Static CE builds require static celib as well defs="${defs} _DLL" fi for i in $defs ; do AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i) done AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version]) AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version]) CFLAGS_DEBUG="-nologo -Zi -Od" CFLAGS_OPTIMIZE="-nologo -Ox" lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'` lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo" LINKBIN="\"${CEBINROOT}/link.exe\"" AC_SUBST(CELIB_DIR) else RC="rc" lflags="-nologo" LINKBIN="link" CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d" CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" fi fi if test "$GCC" = "yes"; then # mingw gcc mode RC="windres" CFLAGS_DEBUG="-g" CFLAGS_OPTIMIZE="-O2" SHLIB_LD="$CXX -shared" UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}" LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}" else SHLIB_LD="${LINKBIN} -dll ${lflags}" # link -lib only works when -lib is the first arg STLIB_LD="${LINKBIN} -lib ${lflags}" UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib' PATHTYPE=-w # For information on what debugtype is most useful, see: # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp # This essentially turns it all on. LDFLAGS_DEBUG="-debug:full -debugtype:both -warn:2" LDFLAGS_OPTIMIZE="-release" if test "$doWince" != "no" ; then LDFLAGS_CONSOLE="-link ${lflags}" LDFLAGS_WINDOW=${LDFLAGS_CONSOLE} else LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}" LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}" fi fi SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".dll" SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll' TCL_LIB_VERSIONS_OK=nodots # Bogus to avoid getting this turned off DL_OBJS="tclLoadNone.obj" ;; AIX-*) if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes" ; then # AIX requires the _r compiler when gcc isn't being used case "${CC}" in *_r) # ok ... ;; *) CC=${CC}_r ;; esac AC_MSG_RESULT([Using $CC for compiling with threads]) fi LIBS="$LIBS -lc" SHLIB_CFLAGS="" SHLIB_SUFFIX=".so" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadDl.o" LD_LIBRARY_PATH_VAR="LIBPATH" # AIX v<=4.1 has some different flags than 4.2+ if test "$system" = "AIX-4.1" -o "`uname -v`" -lt "4" ; then #LIBOBJS="$LIBOBJS tclLoadAix.o" AC_LIBOBJ([tclLoadAix]) DL_LIBS="-lld" fi # Check to enable 64-bit flags for compiler/linker on AIX 4+ if test "$do64bit" = "yes" -a "`uname -v`" -gt "3" ; then if test "$GCC" = "yes" ; then AC_MSG_WARN("64bit mode not supported with GCC on $system") else do64bit_ok=yes CFLAGS="$CFLAGS -q64" LDFLAGS="$LDFLAGS -q64" RANLIB="${RANLIB} -X64" AR="${AR} -X64" SHLIB_LD_FLAGS="-b64" fi fi if test "`uname -m`" = "ia64" ; then # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC SHLIB_LD="/usr/ccs/bin/ld -G -z text" # AIX-5 has dl* in libc.so DL_LIBS="" if test "$GCC" = "yes" ; then LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' else LD_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}' fi else if test "$GCC" = "yes" ; then SHLIB_LD="$CXX -shared" else SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry" fi SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}" DL_LIBS="-ldl" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' TCL_NEEDS_EXP_FILE=1 TCL_EXPORT_FILE_SUFFIX='${PACKAGE_VERSION}.exp' fi # On AIX <=v4 systems, libbsd.a has to be linked in to support # non-blocking file IO. This library has to be linked in after # the MATH_LIBS or it breaks the pow() function. The way to # insure proper sequencing, is to add it to the tail of MATH_LIBS. # This library also supplies gettimeofday. # # AIX does not have a timezone field in struct tm. When the AIX # bsd library is used, the timezone global and the gettimeofday # methods are to be avoided for timezone deduction instead, we # deduce the timezone by comparing the localtime result on a # known GMT value. AC_CHECK_LIB(bsd, gettimeofday, libbsd=yes, libbsd=no) if test $libbsd = yes; then MATH_LIBS="$MATH_LIBS -lbsd" AC_DEFINE(USE_DELTA_FOR_TZ, 1, [Do we need a special AIX hack for timezones?]) fi ;; BeOS*) SHLIB_CFLAGS="-fPIC" SHLIB_LD="${CXX} -nostart" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" ;; BSD/OS-2.1*|BSD/OS-3*) SHLIB_CFLAGS="" SHLIB_LD="shlicc -r" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS="" ;; BSD/OS-4.*) SHLIB_CFLAGS="-export-dynamic -fPIC" SHLIB_LD="$CXX -shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -export-dynamic" LD_SEARCH_FLAGS="" ;; dgux*) SHLIB_CFLAGS="-K PIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS="" ;; HP-UX-*.11.*) # Use updated header definitions where possible AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?]) SHLIB_SUFFIX=".sl" AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no) if test "$tcl_ok" = yes; then SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadShl.o" DL_LIBS="-ldld" LDFLAGS="$LDFLAGS -Wl,-E" LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.' LD_LIBRARY_PATH_VAR="SHLIB_PATH" fi if test "$GCC" = "yes" ; then SHLIB_LD="$CXX -shared -fPIC" SHLIB_LD_LIBS='${LIBS}' LD_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.' fi # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc #CFLAGS="$CFLAGS +DAportable" # Check to enable 64-bit flags for compiler/linker if test "$do64bit" = "yes" ; then if test "$GCC" = "yes" ; then hpux_arch=`${CC} -dumpmachine` case $hpux_arch in hppa64*) # 64-bit gcc in use. Fix flags for GNU ld. do64bit_ok=yes SHLIB_LD="${CXX} -shared -fPIC" SHLIB_LD_LIBS='${LIBS}' ;; *) AC_MSG_WARN("64bit mode not supported with GCC on $system") ;; esac else do64bit_ok=yes CFLAGS="$CFLAGS +DD64" LDFLAGS="$LDFLAGS +DD64" fi fi ;; HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*) SHLIB_SUFFIX=".sl" AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no) if test "$tcl_ok" = yes; then SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" SHLIB_LD_LIBS="" DL_OBJS="tclLoadShl.o" DL_LIBS="-ldld" LDFLAGS="$LDFLAGS -Wl,-E" LD_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.' fi LD_LIBRARY_PATH_VAR="SHLIB_PATH" ;; IRIX-4.*) SHLIB_CFLAGS="-G 0" SHLIB_SUFFIX=".a" SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadAout.o" DL_LIBS="" LDFLAGS="$LDFLAGS -Wl,-D,08000000" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' SHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a' ;; IRIX-5.*) SHLIB_CFLAGS="" SHLIB_LD="ld -shared -rdata_shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' ;; IRIX-6.*|IRIX64-6.5*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' if test "$GCC" = "yes" ; then CFLAGS="$CFLAGS -mabi=n32" LDFLAGS="$LDFLAGS -mabi=n32" else case $system in IRIX-6.3) # Use to build 6.2 compatible binaries on 6.3. CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS" ;; *) CFLAGS="$CFLAGS -n32" ;; esac LDFLAGS="$LDFLAGS -n32" fi ;; IRIX64-6.*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' # Check to enable 64-bit flags for compiler/linker if test "$do64bit" = "yes" ; then if test "$GCC" = "yes" ; then AC_MSG_WARN([64bit mode not supported by gcc]) else do64bit_ok=yes SHLIB_LD="ld -64 -shared -rdata_shared" CFLAGS="$CFLAGS -64" LDFLAGS="$LDFLAGS -64" fi fi ;; Linux*) SHLIB_CFLAGS="-fPIC" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" CFLAGS_OPTIMIZE="-O2" # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings # when you inline the string and math operations. Turn this off to # get rid of the warnings. #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES" if test "$have_dl" = yes; then SHLIB_LD="${CXX} -shared" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,--export-dynamic" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' else AC_CHECK_HEADER(dld.h, [ SHLIB_LD="ld -shared" DL_OBJS="tclLoadDld.o" DL_LIBS="-ldld" LD_SEARCH_FLAGS=""]) fi if test "`uname -m`" = "alpha" ; then CFLAGS="$CFLAGS -mieee" fi # The combo of gcc + glibc has a bug related # to inlining of functions like strtod(). The # -fno-builtin flag should address this problem # but it does not work. The -fno-inline flag # is kind of overkill but it works. # Disable inlining only when one of the # files in compat/*.c is being linked in. if test x"${USE_COMPAT}" != x ; then CFLAGS="$CFLAGS -fno-inline" fi ;; GNU*) SHLIB_CFLAGS="-fPIC" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" if test "$have_dl" = yes; then SHLIB_LD="${CXX} -shared" DL_OBJS="" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,--export-dynamic" LD_SEARCH_FLAGS="" else AC_CHECK_HEADER(dld.h, [ SHLIB_LD="ld -shared" DL_OBJS="" DL_LIBS="-ldld" LD_SEARCH_FLAGS=""]) fi if test "`uname -m`" = "alpha" ; then CFLAGS="$CFLAGS -mieee" fi ;; MP-RAS-02*) SHLIB_CFLAGS="-K PIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS="" ;; MP-RAS-*) SHLIB_CFLAGS="-K PIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,-Bexport" LD_SEARCH_FLAGS="" ;; NetBSD-*|FreeBSD-[[1-2]].*) # Not available on all versions: check for include file. AC_CHECK_HEADER(dlfcn.h, [ # NetBSD/SPARC needs -fPIC, -fpic will not do. SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' AC_MSG_CHECKING([for ELF]) AC_EGREP_CPP(yes, [ #ifdef __ELF__ yes #endif ], AC_MSG_RESULT([yes]) SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so', AC_MSG_RESULT([no]) SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' ) ], [ SHLIB_CFLAGS="" SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".a" DL_OBJS="tclLoadAout.o" DL_LIBS="" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' ]) # FreeBSD doesn't handle version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; OpenBSD-*) SHLIB_LD="${CXX} -shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS="" AC_MSG_CHECKING(for ELF) AC_EGREP_CPP(yes, [ #ifdef __ELF__ yes #endif ], [AC_MSG_RESULT(yes) SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'], [AC_MSG_RESULT(no) SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'] ) # OpenBSD doesn't do version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; FreeBSD-*) # FreeBSD 3.* and greater have ELF. SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LDFLAGS="$LDFLAGS -export-dynamic" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' if test "${TCL_THREADS}" = "1" ; then # The -pthread needs to go in the CFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` CFLAGS="$CFLAGS -pthread" LDFLAGS="$LDFLAGS -pthread" fi case $system in FreeBSD-3.*) # FreeBSD-3 doesn't handle version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so' TCL_LIB_VERSIONS_OK=nodots ;; esac ;; Darwin-*) CFLAGS_OPTIMIZE="-Os" SHLIB_CFLAGS="-fno-common" if test $do64bit = yes; then do64bit_ok=yes CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" fi SHLIB_LD='${CXX} -dynamiclib ${CFLAGS} ${LDFLAGS}' AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [ hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module" AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no) LDFLAGS=$hold_ldflags]) if test $tcl_cv_ld_single_module = yes; then SHLIB_LD="${SHLIB_LD} -Wl,-single_module" fi SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".dylib" DL_OBJS="tclLoadDyld.o" DL_LIBS="" # Don't use -prebind when building for Mac OS X 10.4 or later only: test -z "${MACOSX_DEPLOYMENT_TARGET}" || \ test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F. '{print [$]2}'`" -lt 4 && \ LDFLAGS="$LDFLAGS -prebind" LDFLAGS="$LDFLAGS -headerpad_max_install_names" AC_CACHE_CHECK([if ld accepts -search_paths_first flag], tcl_cv_ld_search_paths_first, [ hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-search_paths_first" AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes, tcl_cv_ld_search_paths_first=no) LDFLAGS=$hold_ldflags]) if test $tcl_cv_ld_search_paths_first = yes; then LDFLAGS="$LDFLAGS -Wl,-search_paths_first" fi LD_SEARCH_FLAGS="" LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH" ;; NEXTSTEP-*) SHLIB_CFLAGS="" SHLIB_LD="$CXX -nostdlib -r" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadNext.o" DL_LIBS="" LD_SEARCH_FLAGS="" ;; OS/390-*) CFLAGS_OPTIMIZE="" # Optimizer is buggy AC_DEFINE(_OE_SOCKETS, 1, # needed in sys/socket.h [Should OS/390 do the right thing with sockets?]) ;; OSF1-1.0|OSF1-1.1|OSF1-1.2) # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1 SHLIB_CFLAGS="" # Hack: make package name same as library name SHLIB_LD='ld -R -export $@:' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadOSF.o" DL_LIBS="" LD_SEARCH_FLAGS="" ;; OSF1-1.*) # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2 SHLIB_CFLAGS="-fPIC" if test "$SHARED_BUILD" = "1" ; then SHLIB_LD="ld -shared" else SHLIB_LD="ld -non_shared" fi SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS="" ;; OSF1-V*) # Digital OSF/1 SHLIB_CFLAGS="" if test "$SHARED_BUILD" = "1" ; then SHLIB_LD='ld -shared -expect_unresolved "*"' else SHLIB_LD='ld -non_shared -expect_unresolved "*"' fi SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' if test "$GCC" = "yes" ; then CFLAGS="$CFLAGS -mieee" else CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee" fi # see pthread_intro(3) for pthread support on osf1, k.furukawa if test "${TCL_THREADS}" = "1" ; then CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE" CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64" LIBS=`echo $LIBS | sed s/-lpthreads//` if test "$GCC" = "yes" ; then LIBS="$LIBS -lpthread -lmach -lexc" else CFLAGS="$CFLAGS -pthread" # PWD: don't need this. #LDFLAGS="$LDFLAGS -pthread" fi fi ;; QNX-6*) # QNX RTP # This may work for all QNX, but it was only reported for v6. SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" # dlopen is in -lc on QNX DL_LIBS="" LD_SEARCH_FLAGS="" ;; RISCos-*) SHLIB_CFLAGS="-G 0" SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".a" DL_OBJS="tclLoadAout.o" DL_LIBS="" LDFLAGS="$LDFLAGS -Wl,-D,08000000" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' ;; SCO_SV-3.2*) # Note, dlopen is available only on SCO 3.2.5 and greater. However, # this test works, since "uname -s" was non-standard in 3.2.4 and # below. if test "$GCC" = "yes" ; then SHLIB_CFLAGS="-fPIC -melf" LDFLAGS="$LDFLAGS -melf -Wl,-Bexport" else SHLIB_CFLAGS="-Kpic -belf" LDFLAGS="$LDFLAGS -belf -Wl,-Bexport" fi SHLIB_LD="ld -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS="" ;; SINIX*5.4*) SHLIB_CFLAGS="-K PIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS="" ;; SunOS-4*) SHLIB_CFLAGS="-PIC" SHLIB_LD="ld" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' # SunOS can't handle version numbers with dots in them in library # specs, like -ltcl7.5, so use -ltcl75 instead. Also, it # requires an extra version number at the end of .so file names. # So, the library has to have a name like libtcl75.so.1.0 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; SunOS-5.[[0-6]]) # Careful to not let 5.10+ fall into this case # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Do we really want to follow the standard? Yes we do!]) # Note: need the LIBS below, otherwise Tk won't find Tcl's # symbols when dynamically loaded into tclsh. SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" if test "$GCC" = "yes" ; then SHLIB_CFLAGS="-fPIC" SHLIB_LD="$CXX -shared" LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' else SHLIB_LD="$CXX -G -z text" LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' SHLIB_CFLAGS="-KPIC" fi ;; SunOS-5*) # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Do we really want to follow the standard? Yes we do!]) # Check to enable 64-bit flags for compiler/linker if test "$do64bit" = "yes" ; then arch=`isainfo` if test "$arch" = "sparcv9 sparc" ; then if test "$GCC" = "yes" ; then if test "`gcc -dumpversion` | awk -F. '{print $1}'" -lt "3" ; then AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system]) else do64bit_ok=yes CFLAGS="$CFLAGS -m64 -mcpu=v9" LDFLAGS="$LDFLAGS -m64 -mcpu=v9" fi else do64bit_ok=yes if test "$do64bitVIS" = "yes" ; then CFLAGS="$CFLAGS -xarch=v9a" LDFLAGS="$LDFLAGS -xarch=v9a" else CFLAGS="$CFLAGS -xarch=v9" LDFLAGS="$LDFLAGS -xarch=v9" fi # Solaris 64 uses this as well #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64" fi elif test "$arch" = "amd64 i386" ; then if test "$GCC" = "yes" ; then AC_MSG_WARN([64bit mode not supported with GCC on $system]) else do64bit_ok=yes CFLAGS="$CFLAGS -xarch=amd64" LDFLAGS="$LDFLAGS -xarch=amd64" fi else AC_MSG_WARN([64bit mode not supported for $arch]) fi fi # Note: need the LIBS below, otherwise Tk won't find Tcl's # symbols when dynamically loaded into tclsh. SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" if test "$GCC" = "yes" ; then SHLIB_CFLAGS="-fPIC" SHLIB_LD="$CXX -shared" LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' if test "$do64bit" = "yes" ; then # We need to specify -static-libgcc or we need to # add the path to the sparv9 libgcc. # JH: static-libgcc is necessary for core Tcl, but may # not be necessary for extensions. SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc" # for finding sparcv9 libgcc, get the regular libgcc # path, remove so name and append 'sparcv9' #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..." #LD_SEARCH_FLAGS="${LD_SEARCH_FLAGS},-R,$v9gcclibdir" fi else SHLIB_CFLAGS="-KPIC" SHLIB_LD="$CXX -G -z text" LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' fi ;; ULTRIX-4.*) SHLIB_CFLAGS="-G 0" SHLIB_SUFFIX=".a" SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadAout.o" DL_LIBS="" LDFLAGS="$LDFLAGS -Wl,-D,08000000" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' if test "$GCC" != "yes" ; then CFLAGS="$CFLAGS -DHAVE_TZSET -std1" fi ;; UNIX_SV* | UnixWare-5*) SHLIB_CFLAGS="-KPIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers # that don't grok the -Bexport option. Test that it does. hold_ldflags=$LDFLAGS AC_MSG_CHECKING(for ld accepts -Bexport flag) LDFLAGS="$LDFLAGS -Wl,-Bexport" AC_TRY_LINK(, [int i;], [found=yes], [LDFLAGS=$hold_ldflags found=no]) AC_MSG_RESULT([$found]) LD_SEARCH_FLAGS="" ;; esac if test "$do64bit" != "no" -a "$do64bit_ok" = "no" ; then AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform]) fi # Step 4: If pseudo-static linking is in use (see K. B. Kenny, "Dynamic # Loading for Tcl -- What Became of It?". Proc. 2nd Tcl/Tk Workshop, # New Orleans, LA, Computerized Processes Unlimited, 1994), then we need # to determine which of several header files defines the a.out file # format (a.out.h, sys/exec.h, or sys/exec_aout.h). At present, we # support only a file format that is more or less version-7-compatible. # In particular, # - a.out files must begin with `struct exec'. # - the N_TXTOFF on the `struct exec' must compute the seek address # of the text segment # - The `struct exec' must contain a_magic, a_text, a_data, a_bss # and a_entry fields. # The following compilation should succeed if and only if either sys/exec.h # or a.out.h is usable for the purpose. # # Note that the modified COFF format used on MIPS Ultrix 4.x is usable; the # `struct exec' includes a second header that contains information that # duplicates the v7 fields that are needed. if test "x$DL_OBJS" = "xtclLoadAout.o" ; then AC_MSG_CHECKING([sys/exec.h]) AC_TRY_COMPILE([#include ],[ struct exec foo; unsigned long seek; int flag; #if defined(__mips) || defined(mips) seek = N_TXTOFF (foo.ex_f, foo.ex_o); #else seek = N_TXTOFF (foo); #endif flag = (foo.a_magic == OMAGIC); return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry; ], tcl_ok=usable, tcl_ok=unusable) AC_MSG_RESULT([$tcl_ok]) if test $tcl_ok = usable; then AC_DEFINE(USE_SYS_EXEC_H, 1, [Should we use when doing dynamic loading?]) else AC_MSG_CHECKING([a.out.h]) AC_TRY_COMPILE([#include ],[ struct exec foo; unsigned long seek; int flag; #if defined(__mips) || defined(mips) seek = N_TXTOFF (foo.ex_f, foo.ex_o); #else seek = N_TXTOFF (foo); #endif flag = (foo.a_magic == OMAGIC); return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry; ], tcl_ok=usable, tcl_ok=unusable) AC_MSG_RESULT([$tcl_ok]) if test $tcl_ok = usable; then AC_DEFINE(USE_A_OUT_H, 1, [Should we use when doing dynamic loading?]) else AC_MSG_CHECKING([sys/exec_aout.h]) AC_TRY_COMPILE([#include ],[ struct exec foo; unsigned long seek; int flag; #if defined(__mips) || defined(mips) seek = N_TXTOFF (foo.ex_f, foo.ex_o); #else seek = N_TXTOFF (foo); #endif flag = (foo.a_midmag == OMAGIC); return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry; ], tcl_ok=usable, tcl_ok=unusable) AC_MSG_RESULT([$tcl_ok]) if test $tcl_ok = usable; then AC_DEFINE(USE_SYS_EXEC_AOUT_H, 1, [Should we use when doing dynamic loading?]) else DL_OBJS="" fi fi fi fi # Step 5: disable dynamic loading if requested via a command-line switch. AC_ARG_ENABLE(load, [ --disable-load disallow dynamic loading and "load" command], [tcl_ok=$enableval], [tcl_ok=yes]) if test "$tcl_ok" = "no"; then DL_OBJS="" fi if test "x$DL_OBJS" != "x" ; then BUILD_DLTEST="\$(DLTEST_TARGETS)" else echo "Can't figure out how to do dynamic loading or shared libraries" echo "on this system." SHLIB_CFLAGS="" SHLIB_LD="" SHLIB_SUFFIX="" DL_OBJS="tclLoadNone.o" DL_LIBS="" LDFLAGS="$LDFLAGS_ORIG" LD_SEARCH_FLAGS="" BUILD_DLTEST="" fi # If we're running gcc, then change the C flags for compiling shared # libraries to the right flags for gcc, instead of those for the # standard manufacturer compiler. if test "$DL_OBJS" != "tclLoadNone.o" ; then if test "$GCC" = "yes" ; then case $system in AIX-*) ;; BSD/OS*) ;; IRIX*) ;; NetBSD-*|FreeBSD-*) ;; Darwin-*) ;; RISCos-*) ;; SCO_SV-3.2*) ;; ULTRIX-4.*) ;; windows) ;; *) SHLIB_CFLAGS="-fPIC" ;; esac fi fi if test "$SHARED_LIB_SUFFIX" = "" ; then SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}' fi if test "$UNSHARED_LIB_SUFFIX" = "" ; then UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a' fi AC_SUBST(SHLIB_SUFFIX) AC_SUBST(DL_LIBS) AC_SUBST(CFLAGS_DEBUG) AC_SUBST(CFLAGS_OPTIMIZE) AC_SUBST(CFLAGS_WARNING) AC_SUBST(STLIB_LD) AC_SUBST(SHLIB_LD) AC_SUBST(SHLIB_CFLAGS) AC_SUBST(SHLIB_LD_LIBS) AC_SUBST(LDFLAGS_DEBUG) AC_SUBST(LDFLAGS_OPTIMIZE) AC_SUBST(LD_LIBRARY_PATH_VAR) # These must be called after we do the basic CFLAGS checks and # verify any possible 64-bit or similar switches are necessary TEA_TCL_EARLY_FLAGS TEA_TCL_64BIT_FLAGS ]) #-------------------------------------------------------------------- # TEA_SERIAL_PORT # # Determine which interface to use to talk to the serial port. # Note that #include lines must begin in leftmost column for # some compilers to recognize them as preprocessor directives, # and some build environments have stdin not pointing at a # pseudo-terminal (usually /dev/null instead.) # # Arguments: # none # # Results: # # Defines only one of the following vars: # HAVE_SYS_MODEM_H # USE_TERMIOS # USE_TERMIO # USE_SGTTY # #-------------------------------------------------------------------- AC_DEFUN(TEA_SERIAL_PORT, [ AC_CHECK_HEADERS(sys/modem.h) AC_MSG_CHECKING([termios vs. termio vs. sgtty]) AC_CACHE_VAL(tcl_cv_api_serial, [ AC_TRY_RUN([ #include int main() { struct termios t; if (tcgetattr(0, &t) == 0) { cfsetospeed(&t, 0); t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB; return 0; } return 1; }], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no) if test $tcl_cv_api_serial = no ; then AC_TRY_RUN([ #include int main() { struct termio t; if (ioctl(0, TCGETA, &t) == 0) { t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB; return 0; } return 1; }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no) fi if test $tcl_cv_api_serial = no ; then AC_TRY_RUN([ #include int main() { struct sgttyb t; if (ioctl(0, TIOCGETP, &t) == 0) { t.sg_ospeed = 0; t.sg_flags |= ODDP | EVENP | RAW; return 0; } return 1; }], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none) fi if test $tcl_cv_api_serial = no ; then AC_TRY_RUN([ #include #include int main() { struct termios t; if (tcgetattr(0, &t) == 0 || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { cfsetospeed(&t, 0); t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB; return 0; } return 1; }], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no) fi if test $tcl_cv_api_serial = no; then AC_TRY_RUN([ #include #include int main() { struct termio t; if (ioctl(0, TCGETA, &t) == 0 || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB; return 0; } return 1; }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no) fi if test $tcl_cv_api_serial = no; then AC_TRY_RUN([ #include #include int main() { struct sgttyb t; if (ioctl(0, TIOCGETP, &t) == 0 || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { t.sg_ospeed = 0; t.sg_flags |= ODDP | EVENP | RAW; return 0; } return 1; }], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none) fi]) case $tcl_cv_api_serial in termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);; termio) AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);; sgtty) AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);; esac AC_MSG_RESULT([$tcl_cv_api_serial]) ]) #-------------------------------------------------------------------- # TEA_MISSING_POSIX_HEADERS # # Supply substitutes for missing POSIX header files. Special # notes: # - stdlib.h doesn't define strtol, strtoul, or # strtod insome versions of SunOS # - some versions of string.h don't declare procedures such # as strstr # # Arguments: # none # # Results: # # Defines some of the following vars: # NO_DIRENT_H # NO_ERRNO_H # NO_VALUES_H # HAVE_LIMITS_H or NO_LIMITS_H # NO_STDLIB_H # NO_STRING_H # NO_SYS_WAIT_H # NO_DLFCN_H # HAVE_SYS_PARAM_H # # HAVE_STRING_H ? # # tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and # CHECK on limits.h #-------------------------------------------------------------------- AC_DEFUN(TEA_MISSING_POSIX_HEADERS, [ AC_MSG_CHECKING([dirent.h]) AC_CACHE_VAL(tcl_cv_dirent_h, AC_TRY_LINK([#include #include ], [ #ifndef _POSIX_SOURCE # ifdef __Lynx__ /* * Generate compilation error to make the test fail: Lynx headers * are only valid if really in the POSIX environment. */ missing_procedure(); # endif #endif DIR *d; struct dirent *entryPtr; char *p; d = opendir("foobar"); entryPtr = readdir(d); p = entryPtr->d_name; closedir(d); ], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)) if test $tcl_cv_dirent_h = no; then AC_DEFINE(NO_DIRENT_H, 1, [Do we have ?]) fi AC_MSG_RESULT([$tcl_ok]) AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have ?])]) AC_CHECK_HEADER(float.h, , [AC_DEFINE(NO_FLOAT_H, 1, [Do we have ?])]) AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have ?])]) AC_CHECK_HEADER(limits.h, [AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have ?])], [AC_DEFINE(NO_LIMITS_H, 1, [Do we have ?])]) AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0) AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0) AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0) AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0) if test $tcl_ok = 0; then AC_DEFINE(NO_STDLIB_H, 1, [Do we have ?]) fi AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0) AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0) AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0) # See also memmove check below for a place where NO_STRING_H can be # set and why. if test $tcl_ok = 0; then AC_DEFINE(NO_STRING_H, 1, [Do we have ?]) fi AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have ?])]) AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have ?])]) # OS/390 lacks sys/param.h (and doesn't need it, by chance). AC_HAVE_HEADERS(sys/param.h) ]) #-------------------------------------------------------------------- # TEA_PATH_X # # Locate the X11 header files and the X11 library archive. Try # the ac_path_x macro first, but if it doesn't find the X stuff # (e.g. because there's no xmkmf program) then check through # a list of possible directories. Under some conditions the # autoconf macro will return an include directory that contains # no include files, so double-check its result just to be safe. # # This should be called after TEA_CONFIG_CFLAGS as setting the # LIBS line can confuse some configure macro magic. # # Arguments: # none # # Results: # # Sets the following vars: # XINCLUDES # XLIBSW # LIBS (appends to) # TEA_WINDOWINGSYSTEM # #-------------------------------------------------------------------- AC_DEFUN(TEA_PATH_X, [ if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then TEA_PATH_UNIX_X fi ]) AC_DEFUN(TEA_PATH_UNIX_X, [ AC_PATH_X not_really_there="" if test "$no_x" = ""; then if test "$x_includes" = ""; then AC_TRY_CPP([#include ], , not_really_there="yes") else if test ! -r $x_includes/X11/Intrinsic.h; then not_really_there="yes" fi fi fi if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then AC_MSG_CHECKING([for X11 header files]) XINCLUDES="# no special path needed" AC_TRY_CPP([#include ], , XINCLUDES="nope") if test "$XINCLUDES" = nope; then dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include" for i in $dirs ; do if test -r $i/X11/Intrinsic.h; then AC_MSG_RESULT([$i]) XINCLUDES=" -I$i" break fi done fi else if test "$x_includes" != ""; then XINCLUDES=-I$x_includes else XINCLUDES="# no special path needed" fi fi if test "$XINCLUDES" = nope; then AC_MSG_RESULT([could not find any!]) XINCLUDES="# no include files found" fi if test "$no_x" = yes; then AC_MSG_CHECKING([for X11 libraries]) XLIBSW=nope dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib" for i in $dirs ; do if test -r $i/libX11.dylib -o -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl; then AC_MSG_RESULT([$i]) XLIBSW="-L$i -lX11" x_libraries="$i" break fi done else if test "$x_libraries" = ""; then XLIBSW=-lX11 else XLIBSW="-L$x_libraries -lX11" fi fi if test "$XLIBSW" = nope ; then AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow) fi if test "$XLIBSW" = nope ; then AC_MSG_RESULT([could not find any! Using -lX11.]) XLIBSW=-lX11 fi if test x"${XLIBSW}" != x ; then PKG_LIBS="${PKG_LIBS} ${XLIBSW}" fi ]) #-------------------------------------------------------------------- # TEA_BLOCKING_STYLE # # The statements below check for systems where POSIX-style # non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented. # On these systems (mostly older ones), use the old BSD-style # FIONBIO approach instead. # # Arguments: # none # # Results: # # Defines some of the following vars: # HAVE_SYS_IOCTL_H # HAVE_SYS_FILIO_H # USE_FIONBIO # O_NONBLOCK # #-------------------------------------------------------------------- AC_DEFUN(TEA_BLOCKING_STYLE, [ AC_CHECK_HEADERS(sys/ioctl.h) AC_CHECK_HEADERS(sys/filio.h) AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O]) if test -f /usr/lib/NextStep/software_version; then system=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version` else system=`uname -s`-`uname -r` if test "$?" -ne 0 ; then system=unknown else # Special check for weird MP-RAS system (uname returns weird # results, and the version is kept in special file). if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then system=MP-RAS-`awk '{print $3}' /etc/.relid'` fi if test "`uname -s`" = "AIX" ; then system=AIX-`uname -v`.`uname -r` fi fi fi case $system in # There used to be code here to use FIONBIO under AIX. However, it # was reported that FIONBIO doesn't work under AIX 3.2.5. Since # using O_NONBLOCK seems fine under AIX 4.*, I removed the FIONBIO # code (JO, 5/31/97). OSF*) AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?]) AC_MSG_RESULT([FIONBIO]) ;; SunOS-4*) AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?]) AC_MSG_RESULT([FIONBIO]) ;; ULTRIX-4.*) AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?]) AC_MSG_RESULT([FIONBIO]) ;; *) AC_MSG_RESULT([O_NONBLOCK]) ;; esac ]) #-------------------------------------------------------------------- # TEA_TIME_HANLDER # # Checks how the system deals with time.h, what time structures # are used on the system, and what fields the structures have. # # Arguments: # none # # Results: # # Defines some of the following vars: # USE_DELTA_FOR_TZ # HAVE_TM_GMTOFF # HAVE_TM_TZADJ # HAVE_TIMEZONE_VAR # #-------------------------------------------------------------------- AC_DEFUN(TEA_TIME_HANDLER, [ AC_CHECK_HEADERS(sys/time.h) AC_HEADER_TIME AC_STRUCT_TIMEZONE AC_CHECK_FUNCS(gmtime_r localtime_r) AC_MSG_CHECKING([tm_tzadj in struct tm]) AC_CACHE_VAL(tcl_cv_member_tm_tzadj, AC_TRY_COMPILE([#include ], [struct tm tm; tm.tm_tzadj;], tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)) AC_MSG_RESULT([$tcl_cv_member_tm_tzadj]) if test $tcl_cv_member_tm_tzadj = yes ; then AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?]) fi AC_MSG_CHECKING([tm_gmtoff in struct tm]) AC_CACHE_VAL(tcl_cv_member_tm_gmtoff, AC_TRY_COMPILE([#include ], [struct tm tm; tm.tm_gmtoff;], tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)) AC_MSG_RESULT([$tcl_cv_member_tm_gmtoff]) if test $tcl_cv_member_tm_gmtoff = yes ; then AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?]) fi # # Its important to include time.h in this check, as some systems # (like convex) have timezone functions, etc. # AC_MSG_CHECKING([long timezone variable]) AC_CACHE_VAL(tcl_cv_timezone_long, AC_TRY_COMPILE([#include ], [extern long timezone; timezone += 1; exit (0);], tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)) AC_MSG_RESULT([$tcl_cv_timezone_long]) if test $tcl_cv_timezone_long = yes ; then AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?]) else # # On some systems (eg IRIX 6.2), timezone is a time_t and not a long. # AC_MSG_CHECKING([time_t timezone variable]) AC_CACHE_VAL(tcl_cv_timezone_time, AC_TRY_COMPILE([#include ], [extern time_t timezone; timezone += 1; exit (0);], tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)) AC_MSG_RESULT([$tcl_cv_timezone_time]) if test $tcl_cv_timezone_time = yes ; then AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?]) fi fi ]) #-------------------------------------------------------------------- # TEA_BUGGY_STRTOD # # Under Solaris 2.4, strtod returns the wrong value for the # terminating character under some conditions. Check for this # and if the problem exists use a substitute procedure # "fixstrtod" (provided by Tcl) that corrects the error. # Also, on Compaq's Tru64 Unix 5.0, # strtod(" ") returns 0.0 instead of a failure to convert. # # Arguments: # none # # Results: # # Might defines some of the following vars: # strtod (=fixstrtod) # #-------------------------------------------------------------------- AC_DEFUN(TEA_BUGGY_STRTOD, [ AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0) if test "$tcl_strtod" = 1; then AC_MSG_CHECKING([for Solaris2.4/Tru64 strtod bugs]) AC_CACHE_VAL(tcl_cv_strtod_buggy,[ AC_TRY_RUN([ extern double strtod(); int main() { char *string = "NaN", *spaceString = " "; char *term; double value; value = strtod(string, &term); if ((term != string) && (term[-1] == 0)) { exit(1); } value = strtod(spaceString, &term); if (term == (spaceString+1)) { exit(1); } exit(0); }], tcl_cv_strtod_buggy=1, tcl_cv_strtod_buggy=0, tcl_cv_strtod_buggy=0)]) if test "$tcl_cv_strtod_buggy" = 1; then AC_MSG_RESULT([ok]) else AC_MSG_RESULT([buggy]) #LIBOBJS="$LIBOBJS fixstrtod.o" AC_LIBOBJ([fixstrtod]) USE_COMPAT=1 AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?]) fi fi ]) #-------------------------------------------------------------------- # TEA_TCL_LINK_LIBS # # Search for the libraries needed to link the Tcl shell. # Things like the math library (-lm) and socket stuff (-lsocket vs. # -lnsl) are dealt with here. # # Arguments: # Requires the following vars to be set in the Makefile: # DL_LIBS # LIBS # MATH_LIBS # # Results: # # Subst's the following var: # TCL_LIBS # MATH_LIBS # # Might append to the following vars: # LIBS # # Might define the following vars: # HAVE_NET_ERRNO_H # #-------------------------------------------------------------------- AC_DEFUN(TEA_TCL_LINK_LIBS, [ #-------------------------------------------------------------------- # On a few very rare systems, all of the libm.a stuff is # already in libc.a. Set compiler flags accordingly. # Also, Linux requires the "ieee" library for math to work # right (and it must appear before "-lm"). #-------------------------------------------------------------------- AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm") AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"]) #-------------------------------------------------------------------- # Interactive UNIX requires -linet instead of -lsocket, plus it # needs net/errno.h to define the socket-related error codes. #-------------------------------------------------------------------- AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"]) AC_CHECK_HEADER(net/errno.h, [ AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have ?])]) #-------------------------------------------------------------------- # Check for the existence of the -lsocket and -lnsl libraries. # The order here is important, so that they end up in the right # order in the command line generated by make. Here are some # special considerations: # 1. Use "connect" and "accept" to check for -lsocket, and # "gethostbyname" to check for -lnsl. # 2. Use each function name only once: can't redo a check because # autoconf caches the results of the last check and won't redo it. # 3. Use -lnsl and -lsocket only if they supply procedures that # aren't already present in the normal libraries. This is because # IRIX 5.2 has libraries, but they aren't needed and they're # bogus: they goof up name resolution if used. # 4. On some SVR4 systems, can't use -lsocket without -lnsl too. # To get around this problem, check for both libraries together # if -lsocket doesn't work by itself. #-------------------------------------------------------------------- tcl_checkBoth=0 AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1) if test "$tcl_checkSocket" = 1; then AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt, LIBS="$LIBS -lsocket", tcl_checkBoth=1)]) fi if test "$tcl_checkBoth" = 1; then tk_oldLibs=$LIBS LIBS="$LIBS -lsocket -lnsl" AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs]) fi AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname, [LIBS="$LIBS -lnsl"])]) # Don't perform the eval of the libraries here because DL_LIBS # won't be set until we call TEA_CONFIG_CFLAGS TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}' AC_SUBST(TCL_LIBS) AC_SUBST(MATH_LIBS) ]) #-------------------------------------------------------------------- # TEA_TCL_EARLY_FLAGS # # Check for what flags are needed to be passed so the correct OS # features are available. # # Arguments: # None # # Results: # # Might define the following vars: # _ISOC99_SOURCE # _LARGEFILE64_SOURCE # #-------------------------------------------------------------------- AC_DEFUN(TEA_TCL_EARLY_FLAG,[ AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]), AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no, AC_TRY_COMPILE([[#define ]$1[ 1 ]$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no))) if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then AC_DEFINE($1, 1, [Add the ]$1[ flag when building]) tcl_flags="$tcl_flags $1" fi ]) AC_DEFUN(TEA_TCL_EARLY_FLAGS,[ AC_MSG_CHECKING([for required early compiler flags]) tcl_flags="" TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include ], [char *p = (char *)strtoll; char *q = (char *)strtoull;]) TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include ], [struct stat64 buf; int i = stat64("/", &buf);]) if test "x${tcl_flags}" = "x" ; then AC_MSG_RESULT([none]) else AC_MSG_RESULT([${tcl_flags}]) fi ]) #-------------------------------------------------------------------- # TEA_TCL_64BIT_FLAGS # # Check for what is defined in the way of 64-bit features. # # Arguments: # None # # Results: # # Might define the following vars: # TCL_WIDE_INT_IS_LONG # TCL_WIDE_INT_TYPE # HAVE_STRUCT_DIRENT64 # HAVE_STRUCT_STAT64 # HAVE_TYPE_OFF64_T # #-------------------------------------------------------------------- AC_DEFUN(TEA_TCL_64BIT_FLAGS, [ AC_MSG_CHECKING([for 64-bit integer type]) AC_CACHE_VAL(tcl_cv_type_64bit,[ tcl_cv_type_64bit=none # See if the compiler knows natively about __int64 AC_TRY_COMPILE(,[__int64 value = (__int64) 0;], tcl_type_64bit=__int64, tcl_type_64bit="long long") # See if we should use long anyway Note that we substitute in the # type that is our current guess for a 64-bit type inside this check # program, so it should be modified only carefully... AC_TRY_COMPILE(,[switch (0) { case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ; }],tcl_cv_type_64bit=${tcl_type_64bit})]) if test "${tcl_cv_type_64bit}" = none ; then AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?]) AC_MSG_RESULT([using long]) elif test "${tcl_cv_type_64bit}" = "__int64" \ -a "${TEA_PLATFORM}" = "windows" ; then # We actually want to use the default tcl.h checks in this # case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER* AC_MSG_RESULT([using Tcl header defaults]) else AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit}, [What type should be used to define wide integers?]) AC_MSG_RESULT([${tcl_cv_type_64bit}]) # Now check for auxiliary declarations AC_MSG_CHECKING([for struct dirent64]) AC_CACHE_VAL(tcl_cv_struct_dirent64,[ AC_TRY_COMPILE([#include #include ],[struct dirent64 p;], tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)]) if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in ?]) fi AC_MSG_RESULT([${tcl_cv_struct_dirent64}]) AC_MSG_CHECKING([for struct stat64]) AC_CACHE_VAL(tcl_cv_struct_stat64,[ AC_TRY_COMPILE([#include ],[struct stat64 p; ], tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)]) if test "x${tcl_cv_struct_stat64}" = "xyes" ; then AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in ?]) fi AC_MSG_RESULT([${tcl_cv_struct_stat64}]) AC_MSG_CHECKING([for off64_t]) AC_CACHE_VAL(tcl_cv_type_off64_t,[ AC_TRY_COMPILE([#include ],[off64_t offset; ], tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)]) if test "x${tcl_cv_type_off64_t}" = "xyes" ; then AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in ?]) fi AC_MSG_RESULT([${tcl_cv_type_off64_t}]) fi ]) ## ## Here ends the standard Tcl configuration bits and starts the ## TEA specific functions ## #------------------------------------------------------------------------ # TEA_INIT -- # # Init various Tcl Extension Architecture (TEA) variables. # This should be the first called TEA_* macro. # # Arguments: # none # # Results: # # Defines and substs the following vars: # CYGPATH # EXEEXT # Defines only: # TEA_INITED # TEA_PLATFORM (windows or unix) # # "cygpath" is used on windows to generate native path names for include # files. These variables should only be used with the compiler and linker # since they generate native path names. # # EXEEXT # Select the executable extension based on the host type. This # is a lightweight replacement for AC_EXEEXT that doesn't require # a compiler. #------------------------------------------------------------------------ AC_DEFUN(TEA_INIT, [ # TEA extensions pass this us the version of TEA they think they # are compatible with. TEA_VERSION="3.4" AC_MSG_CHECKING([for correct TEA configuration]) if test x"${PACKAGE_NAME}" = x ; then AC_MSG_ERROR([ The PACKAGE_NAME variable must be defined by your TEA configure.in]) fi if test x"$1" = x ; then AC_MSG_ERROR([ TEA version not specified.]) elif test "$1" != "${TEA_VERSION}" ; then AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"]) else AC_MSG_RESULT([ok (TEA ${TEA_VERSION})]) fi case "`uname -s`" in *win32*|*WIN32*|*CYGWIN_NT*|*CYGWIN_9*|*CYGWIN_ME*|*MINGW32_*) AC_CHECK_PROG(CYGPATH, cygpath, cygpath -w, echo) EXEEXT=".exe" TEA_PLATFORM="windows" ;; *) CYGPATH=echo EXEEXT="" TEA_PLATFORM="unix" ;; esac # Check if exec_prefix is set. If not use fall back to prefix. # Note when adjusted, so that TEA_PREFIX can correct for this. # This is needed for recursive configures, since autoconf propagates # $prefix, but not $exec_prefix (doh!). if test x$exec_prefix = xNONE ; then exec_prefix_default=yes exec_prefix=$prefix fi AC_SUBST(EXEEXT) AC_SUBST(CYGPATH) # This package name must be replaced statically for AC_SUBST to work AC_SUBST(PKG_LIB_FILE) # Substitute STUB_LIB_FILE in case package creates a stub library too. AC_SUBST(PKG_STUB_LIB_FILE) # We AC_SUBST these here to ensure they are subst'ed, # in case the user doesn't call TEA_ADD_... AC_SUBST(PKG_STUB_SOURCES) AC_SUBST(PKG_STUB_OBJECTS) AC_SUBST(PKG_TCL_SOURCES) AC_SUBST(PKG_HEADERS) AC_SUBST(PKG_INCLUDES) AC_SUBST(PKG_LIBS) AC_SUBST(PKG_CFLAGS) ]) #------------------------------------------------------------------------ # TEA_ADD_SOURCES -- # # Specify one or more source files. Users should check for # the right platform before adding to their list. # It is not important to specify the directory, as long as it is # in the generic, win or unix subdirectory of $(srcdir). # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_SOURCES # PKG_OBJECTS #------------------------------------------------------------------------ AC_DEFUN(TEA_ADD_SOURCES, [ vars="$@" for i in $vars; do case $i in [\$]*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then AC_MSG_ERROR([could not find source file '$i']) fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done AC_SUBST(PKG_SOURCES) AC_SUBST(PKG_OBJECTS) ]) #------------------------------------------------------------------------ # TEA_ADD_STUB_SOURCES -- # # Specify one or more source files. Users should check for # the right platform before adding to their list. # It is not important to specify the directory, as long as it is # in the generic, win or unix subdirectory of $(srcdir). # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_STUB_SOURCES # PKG_STUB_OBJECTS #------------------------------------------------------------------------ AC_DEFUN(TEA_ADD_STUB_SOURCES, [ vars="$@" for i in $vars; do # check for existence - allows for generic/win/unix VPATH if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then AC_MSG_ERROR([could not find stub source file '$i']) fi PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}" fi PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j" done AC_SUBST(PKG_STUB_SOURCES) AC_SUBST(PKG_STUB_OBJECTS) ]) #------------------------------------------------------------------------ # TEA_ADD_TCL_SOURCES -- # # Specify one or more Tcl source files. These should be platform # independent runtime files. # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_TCL_SOURCES #------------------------------------------------------------------------ AC_DEFUN(TEA_ADD_TCL_SOURCES, [ vars="$@" for i in $vars; do # check for existence, be strict because it is installed if test ! -f "${srcdir}/$i" ; then AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i']) fi PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i" done AC_SUBST(PKG_TCL_SOURCES) ]) #------------------------------------------------------------------------ # TEA_ADD_HEADERS -- # # Specify one or more source headers. Users should check for # the right platform before adding to their list. # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_HEADERS #------------------------------------------------------------------------ AC_DEFUN(TEA_ADD_HEADERS, [ vars="$@" for i in $vars; do # check for existence, be strict because it is installed if test ! -f "${srcdir}/$i" ; then AC_MSG_ERROR([could not find header file '${srcdir}/$i']) fi PKG_HEADERS="$PKG_HEADERS $i" done AC_SUBST(PKG_HEADERS) ]) #------------------------------------------------------------------------ # TEA_ADD_INCLUDES -- # # Specify one or more include dirs. Users should check for # the right platform before adding to their list. # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_INCLUDES #------------------------------------------------------------------------ AC_DEFUN(TEA_ADD_INCLUDES, [ vars="$@" for i in $vars; do PKG_INCLUDES="$PKG_INCLUDES $i" done AC_SUBST(PKG_INCLUDES) ]) #------------------------------------------------------------------------ # TEA_ADD_LIBS -- # # Specify one or more libraries. Users should check for # the right platform before adding to their list. For Windows, # libraries provided in "foo.lib" format will be converted to # "-lfoo" when using GCC (mingw). # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_LIBS #------------------------------------------------------------------------ AC_DEFUN(TEA_ADD_LIBS, [ vars="$@" for i in $vars; do if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then # Convert foo.lib to -lfoo for GCC. No-op if not *.lib i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.lib[$]/-l\1/i'` fi PKG_LIBS="$PKG_LIBS $i" done AC_SUBST(PKG_LIBS) ]) #------------------------------------------------------------------------ # TEA_ADD_CFLAGS -- # # Specify one or more CFLAGS. Users should check for # the right platform before adding to their list. # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_CFLAGS #------------------------------------------------------------------------ AC_DEFUN(TEA_ADD_CFLAGS, [ PKG_CFLAGS="$PKG_CFLAGS $@" AC_SUBST(PKG_CFLAGS) ]) #------------------------------------------------------------------------ # TEA_PREFIX -- # # Handle the --prefix=... option by defaulting to what Tcl gave # # Arguments: # none # # Results: # # If --prefix or --exec-prefix was not specified, $prefix and # $exec_prefix will be set to the values given to Tcl when it was # configured. #------------------------------------------------------------------------ AC_DEFUN(TEA_PREFIX, [ if test "${prefix}" = "NONE"; then prefix_default=yes if test x"${TCL_PREFIX}" != x; then AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}]) prefix=${TCL_PREFIX} else AC_MSG_NOTICE([--prefix defaulting to /usr/local]) prefix=/usr/local fi fi if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \ -o x"${exec_prefix_default}" = x"yes" ; then #if test x"${TCL_EXEC_PREFIX}" != x; then #AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}]) #exec_prefix=${TCL_EXEC_PREFIX} #else AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}]) exec_prefix=$prefix #fi fi ]) #------------------------------------------------------------------------ # TEA_SETUP_COMPILER_CC -- # # Do compiler checks the way we want. This is just a replacement # for AC_PROG_CC in TEA configure.in files to make them cleaner. # # Arguments: # none # # Results: # # Sets up CC var and other standard bits we need to make executables. #------------------------------------------------------------------------ AC_DEFUN(TEA_SETUP_COMPILER_CC, [ # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE) # in this macro, they need to go into TEA_SETUP_COMPILER instead. # If the user did not set CFLAGS, set it now to keep # the AC_PROG_CC macro from adding "-g -O2". if test "${CFLAGS+set}" != "set" ; then CFLAGS="" fi AC_PROG_CC if test $ac_cv_prog_gcc = yes; then GCC=yes fi AC_PROG_CPP AC_PROG_CXX AC_PROG_INSTALL #-------------------------------------------------------------------- # Checks to see if the make program sets the $MAKE variable. #-------------------------------------------------------------------- AC_PROG_MAKE_SET #-------------------------------------------------------------------- # Find ranlib #-------------------------------------------------------------------- AC_PROG_RANLIB #-------------------------------------------------------------------- # Determines the correct binary file extension (.o, .obj, .exe etc.) #-------------------------------------------------------------------- AC_OBJEXT AC_EXEEXT ]) #------------------------------------------------------------------------ # TEA_SETUP_COMPILER -- # # Do compiler checks that use the compiler. This must go after # TEA_SETUP_COMPILER_CC, which does the actual compiler check. # # Arguments: # none # # Results: # # Sets up CC var and other standard bits we need to make executables. #------------------------------------------------------------------------ AC_DEFUN(TEA_SETUP_COMPILER, [ # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here. AC_REQUIRE([TEA_SETUP_COMPILER_CC]) #------------------------------------------------------------------------ # If we're using GCC, see if the compiler understands -pipe. If so, use it. # It makes compiling go faster. (This is only a performance feature.) #------------------------------------------------------------------------ if test -z "$no_pipe" -a -n "$GCC"; then AC_MSG_CHECKING([if the compiler understands -pipe]) OLDCC="$CC" CC="$CC -pipe" AC_TRY_COMPILE(,, AC_MSG_RESULT([yes]), CC="$OLDCC" AC_MSG_RESULT([no])) fi #-------------------------------------------------------------------- # Pick up flags from the environment (user). #-------------------------------------------------------------------- CC="${CC} $CFLAGS" CXX="${CXX} $CXXFLAGS $CFLAGS" #-------------------------------------------------------------------- # Common compiler flag setup #-------------------------------------------------------------------- AC_C_BIGENDIAN if test "${TEA_PLATFORM}" = "unix" ; then TEA_TCL_LINK_LIBS TEA_MISSING_POSIX_HEADERS # Let the user call this, because if it triggers, they will # need a compat/strtod.c that is correct. Users can also # use Tcl_GetDouble(FromObj) instead. #TEA_BUGGY_STRTOD fi ]) #------------------------------------------------------------------------ # TEA_MAKE_LIB -- # # Generate a line that can be used to build a shared/unshared library # in a platform independent manner. # # Arguments: # none # # Requires: # # Results: # # Defines the following vars: # CFLAGS - Done late here to note disturb other AC macros # MAKE_LIB - Command to execute to build the Tcl library; # differs depending on whether or not Tcl is being # compiled as a shared library. # MAKE_SHARED_LIB Makefile rule for building a shared library # MAKE_STATIC_LIB Makefile rule for building a static library # MAKE_STUB_LIB Makefile rule for building a stub library #------------------------------------------------------------------------ AC_DEFUN(TEA_MAKE_LIB, [ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)" MAKE_STUB_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_STUB_OBJECTS)" else MAKE_STATIC_LIB="\${STLIB_LD} \[$]@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} -o \[$]@ \$(PKG_OBJECTS) \${LDFLAGS_DEFAULT} \${SHLIB_LD_LIBS}" MAKE_STUB_LIB="\${STLIB_LD} \[$]@ \$(PKG_STUB_OBJECTS)" fi if test "${SHARED_BUILD}" = "1" ; then MAKE_LIB="${MAKE_SHARED_LIB} " else MAKE_LIB="${MAKE_STATIC_LIB} " fi #-------------------------------------------------------------------- # Shared libraries and static libraries have different names. # Use the double eval to make sure any variables in the suffix is # substituted. (@@@ Might not be necessary anymore) #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" ; then if test "${SHARED_BUILD}" = "1" ; then # We force the unresolved linking of symbols that are really in # the private libraries of Tcl and Tk. SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_LIB_FILE}`\"" if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_LIB_FILE}`\"" fi eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" else eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" fi # Some packages build there own stubs libraries eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" # These aren't needed on Windows (either MSVC or gcc) RANLIB=: RANLIB_STUB=: else RANLIB_STUB="${RANLIB}" if test "${SHARED_BUILD}" = "1" ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_LIB_SPEC}" if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_LIB_SPEC}" fi eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" RANLIB=: else eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" fi # Some packages build there own stubs libraries eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" fi # These are escaped so that only CFLAGS is picked up at configure time. # The other values will be substituted at make time. CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}" if test "${SHARED_BUILD}" = "1" ; then CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}" fi AC_SUBST(MAKE_LIB) AC_SUBST(MAKE_SHARED_LIB) AC_SUBST(MAKE_STATIC_LIB) AC_SUBST(MAKE_STUB_LIB) AC_SUBST(RANLIB_STUB) ]) #------------------------------------------------------------------------ # TEA_LIB_SPEC -- # # Compute the name of an existing object library located in libdir # from the given base name and produce the appropriate linker flags. # # Arguments: # basename The base name of the library without version # numbers, extensions, or "lib" prefixes. # extra_dir Extra directory in which to search for the # library. This location is used first, then # $prefix/$exec-prefix, then some defaults. # # Requires: # TEA_INIT and TEA_PREFIX must be called first. # # Results: # # Defines the following vars: # ${basename}_LIB_NAME The computed library name. # ${basename}_LIB_SPEC The computed linker flags. #------------------------------------------------------------------------ AC_DEFUN(TEA_LIB_SPEC, [ AC_MSG_CHECKING([for $1 library]) # Look in exec-prefix for the library (defined by TEA_PREFIX). tea_lib_name_dir="${exec_prefix}/lib" # Or in a user-specified location. if test x"$2" != x ; then tea_extra_lib_dir=$2 else tea_extra_lib_dir=NONE fi for i in \ `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \ `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \ `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \ `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do if test -f "$i" ; then tea_lib_name_dir=`dirname $i` $1_LIB_NAME=`basename $i` $1_LIB_PATH_NAME=$i break fi done if test "${TEA_PLATFORM}" = "windows"; then $1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\" else # Strip off the leading "lib" and trailing ".a" or ".so" tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'` $1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}" fi if test "x${$1_LIB_NAME}" = x ; then AC_MSG_ERROR([not found]) else AC_MSG_RESULT([${$1_LIB_SPEC}]) fi ]) #------------------------------------------------------------------------ # TEA_PRIVATE_TCL_HEADERS -- # # Locate the private Tcl include files # # Arguments: # # Requires: # TCL_SRC_DIR Assumes that TEA_LOAD_TCLCONFIG has # already been called. # # Results: # # Substs the following vars: # TCL_TOP_DIR_NATIVE # TCL_GENERIC_DIR_NATIVE # TCL_UNIX_DIR_NATIVE # TCL_WIN_DIR_NATIVE # TCL_BMAP_DIR_NATIVE # TCL_TOOL_DIR_NATIVE # TCL_PLATFORM_DIR_NATIVE # TCL_BIN_DIR_NATIVE # TCL_INCLUDES #------------------------------------------------------------------------ AC_DEFUN(TEA_PRIVATE_TCL_HEADERS, [ AC_MSG_CHECKING([for Tcl private include files]) TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}` TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\" TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\" TCL_UNIX_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\" TCL_WIN_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\" TCL_BMAP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/bitmaps\" TCL_TOOL_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/tools\" TCL_COMPAT_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/compat\" if test "${TEA_PLATFORM}" = "windows"; then TCL_PLATFORM_DIR_NATIVE=${TCL_WIN_DIR_NATIVE} else TCL_PLATFORM_DIR_NATIVE=${TCL_UNIX_DIR_NATIVE} fi # We want to ensure these are substituted so as not to require # any *_NATIVE vars be defined in the Makefile TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}" if test "`uname -s`" = "Darwin"; then # If Tcl was built as a framework, attempt to use # the framework's Headers and PrivateHeaders directories case ${TCL_DEFS} in *TCL_FRAMEWORK*) if test -d "${TCL_BIN_DIR}/Headers" -a -d "${TCL_BIN_DIR}/PrivateHeaders"; then TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"; else TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"; fi ;; esac fi AC_SUBST(TCL_TOP_DIR_NATIVE) AC_SUBST(TCL_GENERIC_DIR_NATIVE) AC_SUBST(TCL_UNIX_DIR_NATIVE) AC_SUBST(TCL_WIN_DIR_NATIVE) AC_SUBST(TCL_BMAP_DIR_NATIVE) AC_SUBST(TCL_TOOL_DIR_NATIVE) AC_SUBST(TCL_PLATFORM_DIR_NATIVE) AC_SUBST(TCL_INCLUDES) AC_MSG_RESULT([Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}]) ]) #------------------------------------------------------------------------ # TEA_PUBLIC_TCL_HEADERS -- # # Locate the installed public Tcl header files # # Arguments: # None. # # Requires: # CYGPATH must be set # # Results: # # Adds a --with-tclinclude switch to configure. # Result is cached. # # Substs the following vars: # TCL_INCLUDES #------------------------------------------------------------------------ AC_DEFUN(TEA_PUBLIC_TCL_HEADERS, [ AC_MSG_CHECKING([for Tcl public headers]) AC_ARG_WITH(tclinclude, [ --with-tclinclude directory containing the public Tcl header files], with_tclinclude=${withval}) AC_CACHE_VAL(ac_cv_c_tclh, [ # Use the value from --with-tclinclude, if it was given if test x"${with_tclinclude}" != x ; then if test -f "${with_tclinclude}/tcl.h" ; then ac_cv_c_tclh=${with_tclinclude} else AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h]) fi else # If Tcl was built as a framework, attempt to use # the framework's Headers directory case ${TCL_DEFS} in *TCL_FRAMEWORK*) list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`" ;; *) list="" ;; esac # Look in the source dir only if Tcl is not installed, # and in that situation, look there before installed locations. if test -f "$TCL_BIN_DIR/Makefile" ; then list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`" fi # Check order: pkg --prefix location, Tcl's --prefix location, # relative to directory of tclConfig.sh. eval "temp_includedir=${includedir}" list="$list \ `ls -d ${temp_includedir} 2>/dev/null` \ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then list="$list /usr/local/include /usr/include" if test x"${TCL_INCLUDE_SPEC}" != x ; then d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'` list="$list `ls -d ${d} 2>/dev/null`" fi fi for i in $list ; do if test -f "$i/tcl.h" ; then ac_cv_c_tclh=$i break fi done fi ]) # Print a message based on how we determined the include path if test x"${ac_cv_c_tclh}" = x ; then AC_MSG_ERROR([tcl.h not found. Please specify its location with --with-tclinclude]) else AC_MSG_RESULT([${ac_cv_c_tclh}]) fi # Convert to a native path and substitute into the output files. INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}` TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" AC_SUBST(TCL_INCLUDES) ]) #------------------------------------------------------------------------ # TEA_PRIVATE_TK_HEADERS -- # # Locate the private Tk include files # # Arguments: # # Requires: # TK_SRC_DIR Assumes that TEA_LOAD_TKCONFIG has # already been called. # # Results: # # Substs the following vars: # TK_INCLUDES #------------------------------------------------------------------------ AC_DEFUN(TEA_PRIVATE_TK_HEADERS, [ AC_MSG_CHECKING([for Tk private include files]) TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}` TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\" TK_UNIX_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\" TK_WIN_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\" TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\" TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\" if test "${TEA_PLATFORM}" = "windows"; then TK_PLATFORM_DIR_NATIVE=${TK_WIN_DIR_NATIVE} else TK_PLATFORM_DIR_NATIVE=${TK_UNIX_DIR_NATIVE} fi # We want to ensure these are substituted so as not to require # any *_NATIVE vars be defined in the Makefile TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}" if test "${TEA_WINDOWINGSYSTEM}" = "win32" \ -o "${TEA_WINDOWINGSYSTEM}" = "aqua"; then TK_INCLUDES="${TK_INCLUDES} -I${TK_XLIB_DIR_NATIVE}" fi if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then TK_INCLUDES="${TK_INCLUDES} -I${TK_SRC_DIR_NATIVE}/macosx" fi if test "`uname -s`" = "Darwin"; then # If Tk was built as a framework, attempt to use # the framework's Headers and PrivateHeaders directories case ${TK_DEFS} in *TK_FRAMEWORK*) if test -d "${TK_BIN_DIR}/Headers" -a -d "${TK_BIN_DIR}/PrivateHeaders"; then TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"; fi ;; esac fi AC_SUBST(TK_TOP_DIR_NATIVE) AC_SUBST(TK_UNIX_DIR_NATIVE) AC_SUBST(TK_WIN_DIR_NATIVE) AC_SUBST(TK_GENERIC_DIR_NATIVE) AC_SUBST(TK_XLIB_DIR_NATIVE) AC_SUBST(TK_PLATFORM_DIR_NATIVE) AC_SUBST(TK_INCLUDES) AC_MSG_RESULT([Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}]) ]) #------------------------------------------------------------------------ # TEA_PUBLIC_TK_HEADERS -- # # Locate the installed public Tk header files # # Arguments: # None. # # Requires: # CYGPATH must be set # # Results: # # Adds a --with-tkinclude switch to configure. # Result is cached. # # Substs the following vars: # TK_INCLUDES #------------------------------------------------------------------------ AC_DEFUN(TEA_PUBLIC_TK_HEADERS, [ AC_MSG_CHECKING([for Tk public headers]) AC_ARG_WITH(tkinclude, [ --with-tkinclude directory containing the public Tk header files.], with_tkinclude=${withval}) AC_CACHE_VAL(ac_cv_c_tkh, [ # Use the value from --with-tkinclude, if it was given if test x"${with_tkinclude}" != x ; then if test -f "${with_tkinclude}/tk.h" ; then ac_cv_c_tkh=${with_tkinclude} else AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h]) fi else # If Tk was built as a framework, attempt to use # the framework's Headers directory. case ${TK_DEFS} in *TK_FRAMEWORK*) list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`" ;; *) list="" ;; esac # Look in the source dir only if Tk is not installed, # and in that situation, look there before installed locations. if test -f "$TK_BIN_DIR/Makefile" ; then list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`" fi # Check order: pkg --prefix location, Tk's --prefix location, # relative to directory of tkConfig.sh, Tcl's --prefix location, # relative to directory of tclConfig.sh. eval "temp_includedir=${includedir}" list="$list \ `ls -d ${temp_includedir} 2>/dev/null` \ `ls -d ${TK_PREFIX}/include 2>/dev/null` \ `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then list="$list /usr/local/include /usr/include" fi for i in $list ; do if test -f "$i/tk.h" ; then ac_cv_c_tkh=$i break fi done fi ]) # Print a message based on how we determined the include path if test x"${ac_cv_c_tkh}" = x ; then AC_MSG_ERROR([tk.h not found. Please specify its location with --with-tkinclude]) else AC_MSG_RESULT([${ac_cv_c_tkh}]) fi # Convert to a native path and substitute into the output files. INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}` TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" AC_SUBST(TK_INCLUDES) if test "${TEA_WINDOWINGSYSTEM}" = "win32" \ -o "${TEA_WINDOWINGSYSTEM}" = "aqua"; then # On Windows and Aqua, we need the X compat headers AC_MSG_CHECKING([for X11 header files]) if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`" TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" AC_SUBST(TK_XINCLUDES) fi AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}]) fi ]) #------------------------------------------------------------------------ # TEA_PROG_TCLSH # Determine the fully qualified path name of the tclsh executable # in the Tcl build directory or the tclsh installed in a bin # directory. This macro will correctly determine the name # of the tclsh executable even if tclsh has not yet been # built in the build directory. The tclsh found is always # associated with a tclConfig.sh file. This tclsh should be used # only for running extension test cases. It should never be # or generation of files (like pkgIndex.tcl) at build time. # # Arguments # none # # Results # Subst's the following values: # TCLSH_PROG #------------------------------------------------------------------------ AC_DEFUN(TEA_PROG_TCLSH, [ AC_MSG_CHECKING([for tclsh]) if test -f "${TCL_BIN_DIR}/Makefile" ; then # tclConfig.sh is in Tcl build directory if test "${TEA_PLATFORM}" = "windows"; then TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" else TCLSH_PROG="${TCL_BIN_DIR}/tclsh" fi else # tclConfig.sh is in install location if test "${TEA_PLATFORM}" = "windows"; then TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" else TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}" fi list="`ls -d ${TCL_PREFIX}/bin 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null`" for i in $list ; do if test -f "$i/${TCLSH_PROG}" ; then REAL_TCL_BIN_DIR="`cd "$i"; pwd`" break fi done TCLSH_PROG="${REAL_TCL_BIN_DIR}/${TCLSH_PROG}" fi AC_MSG_RESULT(${TCLSH_PROG}) AC_SUBST(TCLSH_PROG) ]) #------------------------------------------------------------------------ # TEA_PROG_WISH # Determine the fully qualified path name of the wish executable # in the Tk build directory or the wish installed in a bin # directory. This macro will correctly determine the name # of the wish executable even if wish has not yet been # built in the build directory. The wish found is always # associated with a tkConfig.sh file. This wish should be used # only for running extension test cases. It should never be # or generation of files (like pkgIndex.tcl) at build time. # # Arguments # none # # Results # Subst's the following values: # WISH_PROG #------------------------------------------------------------------------ AC_DEFUN(TEA_PROG_WISH, [ AC_MSG_CHECKING([for wish]) if test -f "${TK_BIN_DIR}/Makefile" ; then # tkConfig.sh is in Tk build directory if test "${TEA_PLATFORM}" = "windows"; then WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" else WISH_PROG="${TK_BIN_DIR}/wish" fi else # tkConfig.sh is in install location if test "${TEA_PLATFORM}" = "windows"; then WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" else WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}" fi list="`ls -d ${TK_PREFIX}/bin 2>/dev/null` \ `ls -d ${TK_BIN_DIR}/../bin 2>/dev/null`" for i in $list ; do if test -f "$i/${WISH_PROG}" ; then REAL_TK_BIN_DIR="`cd "$i"; pwd`" break fi done WISH_PROG="${REAL_TK_BIN_DIR}/${WISH_PROG}" fi AC_MSG_RESULT(${WISH_PROG}) AC_SUBST(WISH_PROG) ]) #------------------------------------------------------------------------ # TEA_PATH_CONFIG -- # # Locate the ${1}Config.sh file and perform a sanity check on # the ${1} compile flags. These are used by packages like # [incr Tk] that load *Config.sh files from more than Tcl and Tk. # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-$1=... # # Defines the following vars: # $1_BIN_DIR Full path to the directory containing # the $1Config.sh file #------------------------------------------------------------------------ AC_DEFUN(TEA_PATH_CONFIG, [ # # Ok, lets find the $1 configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-$1 # if test x"${no_$1}" = x ; then # we reset no_$1 in case something fails here no_$1=true AC_ARG_WITH($1, [ --with-$1 directory containing $1 configuration ($1Config.sh)], with_$1config=${withval}) AC_MSG_CHECKING([for $1 configuration]) AC_CACHE_VAL(ac_cv_c_$1config,[ # First check to see if --with-$1 was specified. if test x"${with_$1config}" != x ; then case ${with_$1config} in */$1Config.sh ) if test -f ${with_$1config}; then AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself]) with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'` fi;; esac if test -f "${with_$1config}/$1Config.sh" ; then ac_cv_c_$1config=`(cd ${with_$1config}; pwd)` else AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh]) fi fi # then check for a private $1 installation if test x"${ac_cv_c_$1config}" = x ; then for i in \ ../$1 \ `ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ `ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ `ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ ../../$1 \ `ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ `ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ `ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ ../../../$1 \ `ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ `ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ `ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ ${srcdir}/../$1 \ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ ; do if test -f "$i/$1Config.sh" ; then ac_cv_c_$1config=`(cd $i; pwd)` break fi if test -f "$i/unix/$1Config.sh" ; then ac_cv_c_$1config=`(cd $i/unix; pwd)` break fi done fi # check in a few common install locations if test x"${ac_cv_c_$1config}" = x ; then for i in `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ ; do if test -f "$i/$1Config.sh" ; then ac_cv_c_$1config=`(cd $i; pwd)` break fi done fi ]) if test x"${ac_cv_c_$1config}" = x ; then $1_BIN_DIR="# no $1 configs found" AC_MSG_WARN("Cannot find $1 configuration definitions") exit 0 else no_$1= $1_BIN_DIR=${ac_cv_c_$1config} AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh]) fi fi ]) #------------------------------------------------------------------------ # TEA_LOAD_CONFIG -- # # Load the $1Config.sh file # # Arguments: # # Requires the following vars to be set: # $1_BIN_DIR # # Results: # # Subst the following vars: # $1_SRC_DIR # $1_LIB_FILE # $1_LIB_SPEC # #------------------------------------------------------------------------ AC_DEFUN(TEA_LOAD_CONFIG, [ AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh]) if test -f "${$1_BIN_DIR}/$1Config.sh" ; then AC_MSG_RESULT([loading]) . ${$1_BIN_DIR}/$1Config.sh else AC_MSG_RESULT([file not found]) fi # # If the $1_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable $1_LIB_SPEC will be set to the value # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC # instead of $1_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. # if test -f ${$1_BIN_DIR}/Makefile ; then AC_MSG_WARN([Found Makefile - using build library specs for $1]) $1_LIB_SPEC=${$1_BUILD_LIB_SPEC} $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC} $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH} fi AC_SUBST($1_VERSION) AC_SUBST($1_BIN_DIR) AC_SUBST($1_SRC_DIR) AC_SUBST($1_LIB_FILE) AC_SUBST($1_LIB_SPEC) AC_SUBST($1_STUB_LIB_FILE) AC_SUBST($1_STUB_LIB_SPEC) AC_SUBST($1_STUB_LIB_PATH) ]) #------------------------------------------------------------------------ # TEA_PATH_CELIB -- # # Locate Keuchel's celib emulation layer for targeting Win/CE # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-celib=... # # Defines the following vars: # CELIB_DIR Full path to the directory containing # the include and platform lib files #------------------------------------------------------------------------ AC_DEFUN(TEA_PATH_CELIB, [ # First, look for one uninstalled. # the alternative search directory is invoked by --with-celib if test x"${no_celib}" = x ; then # we reset no_celib in case something fails here no_celib=true AC_ARG_WITH(celib,[ --with-celib=DIR use Windows/CE support library from DIR], with_celibconfig=${withval}) AC_MSG_CHECKING([for Windows/CE celib directory]) AC_CACHE_VAL(ac_cv_c_celibconfig,[ # First check to see if --with-celibconfig was specified. if test x"${with_celibconfig}" != x ; then if test -d "${with_celibconfig}/inc" ; then ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)` else AC_MSG_ERROR([${with_celibconfig} directory doesn't contain inc directory]) fi fi # then check for a celib library if test x"${ac_cv_c_celibconfig}" = x ; then for i in \ ../celib-palm-3.0 \ ../celib \ ../../celib-palm-3.0 \ ../../celib \ `ls -dr ../celib-*3.[[0-9]]* 2>/dev/null` \ ${srcdir}/../celib-palm-3.0 \ ${srcdir}/../celib \ `ls -dr ${srcdir}/../celib-*3.[[0-9]]* 2>/dev/null` \ ; do if test -d "$i/inc" ; then ac_cv_c_celibconfig=`(cd $i; pwd)` break fi done fi ]) if test x"${ac_cv_c_celibconfig}" = x ; then AC_MSG_ERROR([Cannot find celib support library directory]) else no_celib= CELIB_DIR=${ac_cv_c_celibconfig} CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'` AC_MSG_RESULT([found $CELIB_DIR]) fi fi ]) skycat-3.1.2-starlink-1b/tcltags000077500000000000000000000065121215713201500165300ustar00rootroot00000000000000#!/usr/local/itcl/bin/tclsh7.4 # @(#) tcltags.tcl 1.1 21 Sep 1994 (C) SNI AG; MR STO SI 134, MR OI 2 # # Make Emacs-style TAGS file for Tcl source. # Tom Tromey Mon Feb 15 1993 # $Id: tcltags,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # tcltags is not part of GNU Emacs, but is distributed under the same # terms (IE the GNU Public License). tcltags is really only useful # with GNU Emacs anyway. # GNU Emacs is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY. No author or distributor # accepts responsibility to anyone for the consequences of using it # or for whether it serves any particular purpose or works at all, # unless he says so in writing. Refer to the GNU Emacs General Public # License for full details. # Everyone is granted permission to copy, modify and redistribute # GNU Emacs, but only under the conditions described in the # GNU Emacs General Public License. A copy of this license is # supposed to have been given to you along with GNU Emacs so you # can know your rights and responsibilities. It should be in a # file named COPYING. Among other things, the copyright notice # and this notice must be preserved on all copies. # KNOWN BUGS: # * Should support updating existing tags files, ctags format, etc. # * Should integrate with etags program somehow. # Configuration stuff: set verbose 1 # # "rexp" is an array of regular expressions. Each must have exactly one # parenthesized subexpression, which should match the tag exactly. # The array indices are unimportant. The regexp as a whole should # match the line containing the tag, up to the tag but not past it. # # Bogus quoting gyrations because Tcl regexps interpret \t as # "t" and not TAB. set rexp(proc) "^proc\[\ \t\]+(\[^\ \t\]+)" set rexp(method) "^\[\ \t\]+method\[\ \t\]+(\[^\ \t\]+)" set rexp(itcl_class) "^itcl_class\[\ \t\]+(\[^\ \t\]+)" set rexp(class) "^class\[\ \t\]+(\[^\ \t\]+)" # Next two are for local Tcl procs, for example purposes only. # I can't give out defvar and defoption, sorry. # set rexp(defvar) "^defvar\[\ \t\]+(\[^\ \t\]+)" # set rexp(defoption) "^defoption\[\ \t\]+(\[^\ \t\]+)" # # Figure out tags for one file. # proc tagify_file {file TAGS} { global rexp verbose if $verbose then { puts stderr "Doing $file..." nonewline } set f [open $file r] set where 0 set lineNo 0 while {[gets $f line] >= 0} { foreach try [array names rexp] { if [regexp $rexp($try) $line match tag] then { if [info exists fileTags($tag)] then { puts stderr "\n\tDuplicate tag $tag, ignoring" } else { set fileTags($tag) $match append fileTags($tag) \177 append fileTags($tag) $lineNo,$where append fileTags($tag) \n } break } } incr where [string length $line] incr lineNo } close $f # Now sort list by tag, and create entry, but only if a tag was # found. set entry {} if [string length [info locals fileTags]] then { foreach tag [lsort [array names fileTags]] { append entry $fileTags($tag) } } # Write file part and then entry to TAGS file. puts $TAGS \014 puts $TAGS $file,[string length $entry] puts $TAGS $entry nonewline if $verbose then { puts stderr done } } # Open output file set TAGS [open TAGS w] # Munge every file listed on the command line. foreach file $argv { tagify_file $file $TAGS } close $TAGS skycat-3.1.2-starlink-1b/tclutil/000077500000000000000000000000001215713201500166155ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/tclutil/CHANGES000066400000000000000000000376771215713201500176340ustar00rootroot00000000000000CHANGES to Tclutil ----------------- This file contains a list of changes to the Tclutil software. The latest changes are at the top. --------------- 20/10/08 released tclutil-2.1.0 ------------------- * Added support for data types double and long long int. * Added support for tiled-image compressed files. --------------- 03.02.06 released tclutil-2.0 ------------------- * Major update: see top level CHANGES file. --------------- 04.04.05 released tclutil-1.2.8 ----------------- * workaround bug in tcl 8.4.3 (SourceForge Request ID 835020) * Updated configure.in for APR2004 (tcl8.4, itcl3.3) * Generally 'using namespace std' instead of specifying ::std * Made the menu toolbar a bit smaller (it's planned to add an icon toolbar underneath the menu toolbar. --------------- 20.01.03 released tclutil-1.2.5 ----------------- * Ported to gcc-3.2.1 and Tcl-8.4.1 --------------- 27.08.01 released tclutil-1.2.4 ----------------- * Merged in minor changes from Peter Biereichel (added some #include files). --------------- 18.05.01 released tclutil-1.2.3 ----------------- * Ported to tcl8.3.3 (still compatible with earlier versions). --------------- 09.11.00 released tclutil-1.2.3 ----------------- * Fixed a bug that occurred when attempting to memory map a file that was a relative path to a relative symbolic link. (For example: Mem("../x.fits"), where x.fits is a link to y.fits). The util/Mem class previously tried to resolve symbolic links, but didn't get it right in this one case. The new version does not try to resolve the links (commented out the call to fileRealname()). --------------- 02.03.00 released tclutil-1.2.2 ----------------- * Added an optional argument to TopLevelWidget::start to specify the valid options for an application. This was as a workaround to what may be a bug in Tcl or Itcl that caused the application to crash when an unknown argument was given. --------------- 14.12.99 released tclutil-1.2.1 ------------------ * Merged in changes made by Peter Biereichel (see below): * Mem.C: use _exit() in the signal handler to avoid that the message queue of a possible parent process (see Batch.tcl) is closed. * Mem.C: attach to shm with SHM_RDONLY when owner=0 --------------- 25.10.99 released tclutil-1.2 -------------------- * Merged in changes made by Peter Biereichel --------------- 09.09.99 released tclutil-1.1.5 ------------------------ * Updated for egcs/gcc-2.95 (This compiler version is stricter for C++ code and even fails the solaris X11 header files, unless told to ignore the errors...). Added check in configure.in for solaris and gcc-2.95*, to include the -fpermissive flag with g++. --------------- 21.06.99 released tclutil-1.1.4 ------------------------ * FileSelect.tcl: changed listbox bindings from <1> to to avoid conflict with default bindings. --------------- 01.04.99 released tclutil-1.1.3 ------------------------ * Replaced sys_errlist[] with strerror() in error.C to get around porting problems. * changed tclsh$vers to itclsh$vers in tix/src/Makefile.in, since tclsh was often not found. * Added workaround in configure.in to tcl8.0.5 configure script bug dealing with HP-UX machines and the TCL_SHLIB_LD variable defined in tclConfig.sh (was set wrong for HP). --------------- 22.03.99 released tclutil-1.1.2 ------------------------ * Replaced itclsh2.2 with itclsh@ITCL_VERSION@ in Makefile.in. * EntryForm.tcl: added scrollbars to make it easier to view many entries. * Changed "quit" method in TopLevelWidget to use "delete object $this" instead of "destroy $w_". * Removed lib -lieee from configure.in, since it caused problems with shared libraries later on in the gaia plugin. * error.C: removed "#include errno.h" to avoid problems with new linux versions. * configure.in: removed -lieee library from configure script, since it caused linking problems on glibc linux versions. * updated local copies of tcl headers for the local tix package for tcl8.0.5. * Merged in changes from Peter W. Draper (Starlink) to support 16 and 24 bit color. * Added routine Tk_CanvasWindowCoordsNoClip() in tkCanvasImagePs.c to work around Tk's limit on canvas coordinates to short range. Now the canvas coordinates do not have to be clipped to short range. * bltGraph.tcl: Added patch for blt2.4g from Peter Draper. --------------- 28.12.98 released tclutil-1.1.1 ------------------------ * Minor change in udialog.tcl to avoid multiple error message problems. * Added an optional argument to Mem::remap() to allow increasing the size of an mmapped file. * Fixed mistaken "//" comments in Blt_GraphElement.c. * Rebuild tclIndex file whenever configure is run, since Tcl8 version is not compatible with tcl7 version (see makelinks script). * tkCanvasPsImage.c: changed "unsigned int" to "int" to avoid sunpro cc warning. --------------- 16.11.98 released tclutil-1.1 ------------------------ * Ported to tcl8.0.3 (still compatible with tcl7.6): - Changed the syntax used for the namespace and scope commands in tcl8. - Itcl member procs in the "util" namespace now need to be called with "util::" prefix. For example: "util::TopLevelWidget::start ..." - Updated the BLT related code to work with both BLT2.1 and 2.4f. - Updated the configure scripts to handle Tcl8.0 and Tcl7.6. --------------- 30.8.98 released tclutil-1.0.17 ----------------------- * Added a "wait" command in Batch.tcl to reap background processes and avoid zombies. --------------- 5.8.98 released tclutil-1.0.16 ----------------------- * Added authorization support to class HTTP. The class now recognizes the "Authorization Required" message returned from an HTTP server and provides a method "authorize(username, passwd)" for clients to set user and password information. The information is optionally saved in a file (by default: ~/.http_auth), indexed by server host name and realm and with the username and password encoded. * Added new public methods to class HTTP: content_encoding(), www_auth_realm(), authorizationRequired(), authorize(), authFile(), userAgent(), and changed html_error() from a "static" to nonstatic member. * Added new Itcl dialog class: PasswdDialog, and new proc that uses it: passwd_dialog. * Added the X11 library directory to shared lib path in startup script * Changed DialogWidget itcl class to use a label in place of a message and truncate lines from long messages. * Fixed minor bug in TopLevelWidget that prevented the code from remembering the locations of top level widgets. Now, if you place a window somewhere, it comes up there the next time the window is created in that session. --------------- 07.07.98 released tclutil-1.0.15 ----------------------- * class HTTP: added suport for HTTP POST: new methods: HTTP::post(url, data) and HTTP::post(url, data, ostream). --------------- 26.6.98 released tclutil-1.0.14 ----------------------- * Added support for HTTP proxy servers (thanks to Peter Draper for implementing this). The proxy server, if available, is defined by the "http_proxy" environment variable. This should have the format: http_proxy = "http://wwwcache.some.domain:port/" A list of domains that do not require to be proxied (i.e. local machines etc.) is defined by the variable "http_noproxy". This should be a list of comma separated names, i.e.: http_noproxy = "local.domain,national.domain" If the given host is in one of these domains no proxy will be set up. * Mem.C: added checks for file permissions to avoid problems with mmap and read-only files (or files with no read permission). --------------- 19.6.98 released tclutil-1.0.13 ----------------------- * HTTP.C: fixed a minor bug that cut off last char of an HTTP error message * Added new file: tclutil/src/tkCanvasPsImage.c, which implements Tk canvas postscript printing for images. The default Tk canvas postscript command does not support printing images and the available patch could not handle large, zoomed in images. This version does not require a patch to Tk. The extension is based on the patch, with fixes provided by Peter Draper of Starlink, and is activated optionally by calling the C routine TkCanvasPsImage_Init(). --------------- 28.5.98 released tclutil-1.0.12 ----------------------- * Added support for HTTP redirect "Location: ..." to HTTP class * HTTP.C: check for HTTP header info in URL command output. If a URL is a command (not "file:/..." or "http:/...") its output may have an optional HTTP type header containing lines such as "Content-type: ...", "Content-length: ...", etc. (at most 5 lines). If these lines are found, they are noted and skipped over before accessing the data. * Minor bug fix in TclCommand.C, for case when interp->result is appended to itself. --------------- 13.5.98 released tclutil-1.0.11 ----------------------- - * FileSelect.tcl: added missing method (set_filter_type) * EntryForm.tcl: destroy window on "Enter" as well as "Cancel" (previously, "Cancel" destroyed the window, but "Enter" only closed it). --------------- 4.5.98 released tclutil-1.0.10 ------------------------- * CanvasDraw.tcl: Changed protection on "create_done" to public --------------- 28.4.98 released tclutil-1.0.9 ------------------------- * Minor addition to TopLevelWidget error handling (in start_err_, allow --help option to print "usage" message). --------------- 15.4.98 released tclutil-1.0.8 ------------------------- * itcldoc.tcl (automatic man page generation from Itcl classes) - Added code to extract information from Itcl classes about the Itk components and component options. - Added code to document "public" and "protected" methods and variables. * (doc, *.tcl): For documenting the "public interface": Updated comments on all Itk component declarations and added "public", "private" and "protected" keywords in the source to help identify the public interface, which is documented in man pages generated from the source by the itcldoc utility in this package. * Minor changes in configure script and top level makefile for shared libraries * Fixed a last minute problem with calling plugin procs (needed to use "uplevel #0" due to Itcl scoping/namespace hell...). ----------------- 31.03.98 released tclutil-1.0.7 ---------------------- * Updated man pages and documentation ----------------- 25.03.98 released tclutil-1.0.6 ---------------------- * Minor change in class ShellCommand (kill child process on error). * added "more_error" method to TclCommand, to append an error message. * TkImage constructor: changed options arg from reference to pointer for consistency with usage. * TopLevelWidget.tcl: Added support for a simple help window to TopLevelWidget, and added two new widgets: HelpWin and ScrolledText (contributed by Peter Draper, Starlink). * CanvasDraw.tcl: * Make use of "init" method in CanvasDraw constructor (easier for subclassing). * Added -clipping option to control clipping of graphics (default is the same as before). * TopLevelWidget.tcl: Added "-underline" option to add_menubutton, to allow proper keyboard traversal. * Tix library: commented out global bindings (grep for "bind all" in tix/library dir), since they interfere with Tk keyboard traversal in menus, etc. * TopLevelWidget: fixed bug in method "list_windows" so that it lists all top level windows (previously not all windows were listed). * TopLevelWidget: added "-number" option to keep track of cloned windows. This is a number that can be put in the window title to identify which main window a popup window belongs to. By default the number is set automatically set from the widget path name by looking for a name, such as "....", for example: .app1, .app2, ... * LabelEntryScale.tcl: added fixes from Peter Fraper, Starlink, to support vertical and horizontal layout and keybindings and improve performance. ----------------- 05.03.98 released tclutil-1.0.5 ------------------------- * fixed minor problems setting and restoring the mouse cursor * (CanvasDraw). * For backward compatibility with existing applications: The Tclutil package now contains the sources for the Tix widget set. Tix support can be included in an application by calling Tixsam_Init(interp) and linking -ltclutil (or the necessary object files from this package). This has no effect on packages that do not use Tix. * Implemented rotation for canvas graphics. Since Tk doesn't support this directly, it is done now in Tcl code. Polygons are now used in place of rectangles, to make it posible to rotate a rectangle. (The appearance and funtionality is the same). You still can't rotate ovals, but you can rotate a smooth rectangle, which is similar (see below). * Added a "Smooth" option in the graphics window (CanvasDraw), so you can make smooth (rounded) rectangles, polygons or polylines. * Changed the selection mechanism, so that the graphics window always displays the options for the currently selected object. * Plugins: The _PLUGIN environment variable may now contain a colon separated list of plugin files or directories containing plugin files. This way you can have multiple plugins for a class. For a top level class Foo, for example, the environment variable FOO_PLUGIN may contain a colon separated list of plugin files or directories containing plugin files. The default file name, if only a directory name is given, is then Foo_plugin.tcl, which defines the Tcl proc Foo_plugin. ----------------- 13.2.98 released tclutil-1.0.4 ------------------------- * Added 2 methods to TopLevelWidget: list_windows and hide_windows to add support for toggling the visibility of all popup windows other than the main one. ----------------- 9.2.98 released tclutil-1.0.3 ------------------------- * Added "const" to "cmdname" arg in constructor for TclCommandand TkImage classes. * Added (void*) cast to MAP_FAILED constant in class Mem_Map * Fixed minor bugs in bltGraph.tcl (used for zooming in a graph) * added check for "gethostname" prototype to configure script. ----------------- 3.2.98 released tclutil-1.0.2 ------------------------- * In class CanvasDraw, added support for selecting a region of objects, and moving a group of objects. Added region icon to drawing mode frame. * Added methods "append_result", "append_element", "reset_result" in class TclCommand. --------------- 26.01.98 released tclutil-1.0.1 ------------------------- * Added plugin support to the TopLevelWidget class, so all classes derived from it can have Tcl plugins (see docs). * Added a script tclutil/demos/itcldoc that extracts man pages from Itcl class sources automatically, with no special syntax needed in the comments. The script simply assumes that comments precede declarations. Since Itcl sources have a simple Tcl list format, it is fairly easy to parse them. The only requirement is that each class, method and other important declarations are preceded by a "block" comment (a group of lines starting with "#"). To run the script, cd to the dir containing the tcl source files (here tclutil/library) and type: "make doc". * Updated comments in Itcl sources for automatic generation of man pages. * Renamed some source files to have the same name as the class (TList.tcl ==> TableList.tcl, Dialog.tcl ==> DialogWidget.tcl, ...) --------------- released tclutil-1.0 ------------------------------------ * Created new package Tclutil by gathering "generic" Tcl and C++ code from various applications into a single generic Tcl package. The Tclutil package contains a collection of handy Itcl and C++ utility classes and also provides a shell script (TclutilConfig.sh), created by configure, that makes it easier to write configure scripts for other packages. This package assumes the development environment includes C++, Itcl, TclX, BLT and optionally other packages that can be linked in statically or dynamically as needed. ----------- Nov 21, 1997: begin change log for Tclutil ----------------- skycat-3.1.2-starlink-1b/tclutil/Makefile.in000077500000000000000000000371531215713201500206760ustar00rootroot00000000000000# Makefile.in -- # # This file is a Makefile for Sample TEA Extension. If it has the name # "Makefile.in" then it is a template for a Makefile; to generate the # actual Makefile, run "./configure", which is a configuration script # generated by the "autoconf" program (constructs like "@foo@" will get # replaced in the actual Makefile). # # Copyright (c) 1999 Scriptics Corporation. # Copyright (c) 2002-2005 ActiveState Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: Makefile.in,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ #======================================================================== # Add additional lines to handle any additional AC_SUBST cases that # have been added in a customized configure script. #======================================================================== #SAMPLE_NEW_VAR = @SAMPLE_NEW_VAR@ TEST_APPS = tMem tHTTP #tShellCommand TEST_LIBS = @tclutil_LIB_SPEC@ @TCL_LIB_SPEC@ @TK_LIB_SPEC@ #======================================================================== # Nothing of the variables below this line should need to be changed. # Please check the TARGETS section below to make sure the make targets # are correct. #======================================================================== #======================================================================== # The names of the source files is defined in the configure script. # The object files are used for linking into the final library. # This will be used when a dist target is added to the Makefile. # It is not important to specify the directory, as long as it is the # $(srcdir) or in the generic, win or unix subdirectory. #======================================================================== PKG_SOURCES = @PKG_SOURCES@ PKG_OBJECTS = @PKG_OBJECTS@ PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ #======================================================================== # PKG_TCL_SOURCES identifies Tcl runtime files that are associated with # this package that need to be installed, if any. #======================================================================== PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ #======================================================================== # This is a list of public header files to be installed, if any. #======================================================================== PKG_HEADERS = @PKG_HEADERS@ #======================================================================== # "PKG_LIB_FILE" refers to the library (dynamic or static as per # configuration options) composed of the named objects. #======================================================================== PKG_LIB_FILE = @PKG_LIB_FILE@ PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ #PKG_BIN_FILE = tclutil.sh bin_BINARIES = $(PKG_BIN_FILE) lib_BINARIES = $(PKG_LIB_FILE) BINARIES = $(lib_BINARIES) $(bin_BINARIES) SHELL = @SHELL@ srcdir = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ libdir = @libdir@ datadir = @datadir@ mandir = @mandir@ includedir = @includedir@ DESTDIR = PKG_DIR = $(PACKAGE_NAME)$(PACKAGE_VERSION) pkgdatadir = $(datadir)/$(PKG_DIR) pkglibdir = $(libdir)/$(PKG_DIR) pkgincludedir = $(includedir)/$(PACKAGE_NAME) top_builddir = . INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ CC = @CC@ CXX = @CXX@ CFLAGS_DEFAULT = @CFLAGS_DEFAULT@ #CFLAGS_WARNING = @CFLAGS_WARNING@ CLEANFILES = @CLEANFILES@ $(TEST_APPS) *.result *.tmp *.o EXEEXT = @EXEEXT@ LDFLAGS_DEFAULT = @LDFLAGS_DEFAULT@ MAKE_LIB = @MAKE_LIB@ MAKE_SHARED_LIB = @MAKE_SHARED_LIB@ MAKE_STATIC_LIB = @MAKE_STATIC_LIB@ MAKE_STUB_LIB = @MAKE_STUB_LIB@ OBJEXT = @OBJEXT@ RANLIB = @RANLIB@ RANLIB_STUB = @RANLIB_STUB@ SHLIB_CFLAGS = @SHLIB_CFLAGS@ SHLIB_LD = @SHLIB_LD@ SHLIB_LD_LIBS = @PKG_LIBS@ @SHLIB_LD_LIBS@ @SHLIB_LD_CXX_LIBS@ STLIB_LD = @STLIB_LD@ #TCL_DEFS = @TCL_DEFS@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_SRC_DIR = @TCL_SRC_DIR@ #TK_BIN_DIR = @TK_BIN_DIR@ #TK_SRC_DIR = @TK_SRC_DIR@ # Not used, but retained for reference of what libs Tcl required #TCL_LIBS = @TCL_LIBS@ #======================================================================== # TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our # package without installing. The other environment variables allow us # to test against an uninstalled Tcl. Add special env vars that you # require for testing here (like TCLX_LIBRARY). #======================================================================== EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR) #EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR) TCLLIBPATH = $(top_builddir) TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \ @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \ PATH="$(EXTRA_PATH):$(PATH)" \ TCLLIBPATH="$(TCLLIBPATH)" # TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library` TCLSH_PROG = @TCLSH_PROG@ TCLSH = $(TCLSH_ENV) $(TCLSH_PROG) WISH_PROG = @WISH_PROG@ WISH = $(TCLSH_ENV) $(WISH_PROG) SHARED_BUILD = @SHARED_BUILD@ #INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@ PKG_CFLAGS = @PKG_CFLAGS@ # TCL_DEFS is not strictly need here, but if you remove it, then you # must make sure that configure.in checks for the necessary components # that your library may use. TCL_DEFS can actually be a problem if # you do not compile with a similar machine setup as the Tcl core was # compiled with. #DEFS = $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS) DEFS = @DEFS@ $(PKG_CFLAGS) CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl ${PACKAGE_NAME}Config.sh ${PACKAGE_NAME}.sh ${PACKAGE_NAME}_version.tcl CPPFLAGS = @CPPFLAGS@ LIBS = @PKG_LIBS@ @LIBS@ AR = @AR@ CFLAGS = @CFLAGS@ CXXFLAGS = @CXXFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(CXXFLAGS) #======================================================================== # Start of user-definable TARGETS section #======================================================================== #======================================================================== # TEA TARGETS. Please note that the "libraries:" target refers to platform # independent files, and the "binaries:" target inclues executable programs and # platform-dependent libraries. Modify these targets so that they install # the various pieces of your package. The make and install rules # for the BINARIES that you specified above have already been done. #======================================================================== all: binaries libraries doc tclIndex #======================================================================== # The binaries target builds executable programs, Windows .dll's, unix # shared/static libraries, and any other platform-dependent files. # The list of targets to build for "binaries:" is specified at the top # of the Makefile, in the "BINARIES" variable. #======================================================================== binaries: $(BINARIES) libraries: tclIndex: (cd $(srcdir)/library; $(TCLSH_PROG) mkIndex.tcl) #======================================================================== # Your doc target should differentiate from doc builds (by the developer) # and doc installs (see install-doc), which just install the docs on the # end user machine when building from source. #======================================================================== doc: # generate man pages for itcl classes gendoc: (cd $(srcdir)/library; $(TCLSH_PROG) itcldoc.tcl [A-Z]*.tcl) # remove generated man pages cleandoc: rm -f $(srcdir)/man/[A-Z]*.mann install: all install-binaries install-libraries install-doc install-binaries: binaries install-lib-binaries install-bin-binaries #======================================================================== # This rule installs platform-independent files, such as header files. # The list=...; for p in $$list handles the empty list case x-platform. #======================================================================== install-libraries: libraries @test -d $(DESTDIR)$(pkgincludedir) || mkdir -p $(DESTDIR)$(pkgincludedir) @echo "Installing header files in $(DESTDIR)$(pkgincludedir)" @list='$(PKG_HEADERS)'; for i in $$list; do \ echo "Installing $(srcdir)/$$i" ; \ $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(pkgincludedir) ; \ done; #======================================================================== # Install documentation. Unix manpages should go in the $(mandir) # directory. #======================================================================== install-doc: #install-doc: doc # @mkdir -p $(DESTDIR)$(mandir)/mann # @echo "Installing documentation in $(DESTDIR)$(mandir)" # @list='$(srcdir)/doc/*.n'; for i in $$list; do \ # echo "Installing $$i"; \ # rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \ # $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \ # done shell: binaries libraries @$(TCLSH) $(SCRIPT) gdb: $(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT) depend: #======================================================================== # $(PKG_LIB_FILE) should be listed as part of the BINARIES variable # mentioned above. That will ensure that this target is built when you # run "make binaries". # # The $(PKG_OBJECTS) objects are created and linked into the final # library. In most cases these object files will correspond to the # source files above. #======================================================================== $(PKG_LIB_FILE): $(PKG_OBJECTS) -rm -f $(PKG_LIB_FILE) ${MAKE_LIB} $(RANLIB) $(PKG_LIB_FILE) #$(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS) # -rm -f $(PKG_STUB_LIB_FILE) # ${MAKE_STUB_LIB} # $(RANLIB_STUB) $(PKG_STUB_LIB_FILE) #======================================================================== # We need to enumerate the list of .c to .o lines here. # # In the following lines, $(srcdir) refers to the toplevel directory # containing your extension. If your sources are in a subdirectory, # you will have to modify the paths to reflect this: # # sample.$(OBJEXT): $(srcdir)/generic/sample.c # $(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@ # # Setting the VPATH variable to a list of paths will cause the makefile # to look into these paths when resolving .c to .obj dependencies. # As necessary, add $(srcdir):$(srcdir)/compat:.... #======================================================================== VPATH = $(srcdir):$(srcdir)/generic .c.@OBJEXT@: $(COMPILE) -c `@CYGPATH@ $<` -o $@ .C.@OBJEXT@: $(CXXCOMPILE) -c `@CYGPATH@ $<` -o $@ #======================================================================== # End of user-definable section #======================================================================== #======================================================================== # Don't modify the file to clean here. Instead, set the "CLEANFILES" # variable in configure.in #======================================================================== clean: -test -z "$(BINARIES)" || rm -f $(BINARIES) -rm -f *.$(OBJEXT) core *.core -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean: clean -rm -f *.tab.c -rm -f $(CONFIG_CLEAN_FILES) -rm -rf config.cache config.log config.status autom4te.cache #======================================================================== # Install binary object libraries. On Windows this includes both .dll and # .lib files. Because the .lib files are not explicitly listed anywhere, # we need to deduce their existence from the .dll file of the same name. # Library files go into the lib directory. # In addition, this will generate the pkgIndex.tcl # file in the install location (assuming it can find a usable tclsh shell) # # You should not have to modify this target. #======================================================================== install-lib-binaries: binaries @test -d $(DESTDIR)$(pkglibdir) || mkdir -p $(DESTDIR)$(pkglibdir) @list='$(lib_BINARIES)'; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libdir)/$$p"; \ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libdir)/$$p; \ stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \ if test "x$$stub" = "xstub"; then \ echo " $(RANLIB_STUB) $(DESTDIR)$(libdir)/$$p"; \ $(RANLIB_STUB) $(DESTDIR)$(libdir)/$$p; \ else \ echo " $(RANLIB) $(DESTDIR)$(libdir)/$$p"; \ $(RANLIB) $(DESTDIR)$(libdir)/$$p; \ fi; \ ext=`echo $$p|sed -e "s/.*\.//"`; \ if test "x$$ext" = "xdll"; then \ lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \ if test -f $$lib; then \ echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(libdir)/$$lib"; \ $(INSTALL_DATA) $$lib $(DESTDIR)$(libdir)/$$lib; \ fi; \ fi; \ fi; \ done @echo " Install $(PACKAGE_NAME)Config.sh $(DESTDIR)$(libdir)" @$(INSTALL_DATA) $(PACKAGE_NAME)Config.sh $(DESTDIR)$(libdir); @list='$(PKG_TCL_SOURCES) library/tclIndex $(PACKAGE_NAME)_version.tcl'; \ for p in $$list; do \ if test -f $(srcdir)/$$p; then \ destp=`basename $$p`; \ echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \ fi; \ done @if test "x$(SHARED_BUILD)" = "x1"; then \ echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \ $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \ fi # (cd $(DESTDIR)$(pkglibdir); $(TCLSH_PROG) mkIndex.tcl) #======================================================================== # Install binary executables (e.g. .exe files and dependent .dll files) # This is for files that must go in the bin directory (located next to # wish and tclsh), like dependent .dll files on Windows. # # You should not have to modify this target, except to define bin_BINARIES # above if necessary. #======================================================================== install-bin-binaries: binaries @test -d $(DESTDIR)$(bindir) || mkdir -p $(DESTDIR)$(bindir) @list='$(bin_BINARIES)'; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \ fi; \ done .SUFFIXES: .c .$(OBJEXT) .C Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status uninstall-binaries: list='$(lib_BINARIES)'; for p in $$list; do \ rm -f $(DESTDIR)$(pkglibdir)/$$p; \ done list='$(PKG_TCL_SOURCES)'; for p in $$list; do \ p=`basename $$p`; \ rm -f $(DESTDIR)$(pkglibdir)/$$p; \ done list='$(bin_BINARIES)'; for p in $$list; do \ rm -f $(DESTDIR)$(bindir)/$$p; \ done .PHONY: all binaries clean depend distclean doc install libraries test # Tell versions (3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: #======================================================================== # Run C++ Test cases #======================================================================== test: binaries libraries $(TEST_APPS) $(TEST_APPS): FORCE $(CXXCOMPILE) -o $@ $(srcdir)/tests/$@.C $(TEST_LIBS) -@@LD_LIBRARY_PATH_VAR@=@exec_prefix@/lib; export @LD_LIBRARY_PATH_VAR@ ;\ $@ > $@.result 2>&1 ;\ if cmp $@.result $(srcdir)/tests/$@.ok ;\ then echo "$@: PASSED" ; \ else echo "*** $@: TEST FAILED: see $@.result" ; \ fi #======================================================================== # Run Tcl test cases #======================================================================== tcltest: binaries libraries (cd $(srcdir)/tests; sh all.tcl) FORCE: skycat-3.1.2-starlink-1b/tclutil/README000066400000000000000000000026521215713201500175020ustar00rootroot00000000000000 Tclutil, Generic Tcl/Tk and C++ Utilities and Classes ----------------------------------------------------- The Tclutil package was created by gathering generic Tcl, Itcl and C++ code from various applications into a single, general purpose, utility package, that can be loaded dynamically into a running Tcl application or linked in at compile time as a general purpose library. The package contains a collection of useful Itcl and C++ utility classes. It also provides a shell script (TclutilConfig.sh), which is created by the configure script and makes it easier to write configure scripts for other packages by providing configuration information, such as the locations and names of all the Tcl extensions and libraries. The development environment here includes C++, Itcl, TclX, BLT, Tkimg, and optionally other packages that can be linked in dynamically as needed. You can use this package by including the following line in a Tcl script: package require Tclutil For installation instructions, see the file INSTALL in the parent directory. See the CHANGES file in this directory for a list of recent changes. The following URLs may also be of interest: Skycat home page: http://archive.eso.org/skycat/ Sources and binaries: ftp://ftp.eso.org/pub/archive/skycat/README.html Postscript, PDF, and FrameMaker Documentation: ftp://ftp.eso.org/pub/archive/skycat/doc HTML Docs: http://archive.eso.org/skycat/docs/skycat-man.html skycat-3.1.2-starlink-1b/tclutil/VERSION000066400000000000000000000000161215713201500176620ustar00rootroot00000000000000tclutil-2.1.0 skycat-3.1.2-starlink-1b/tclutil/aclocal.m4000066400000000000000000000130401215713201500204530ustar00rootroot00000000000000builtin(include,../tclconfig/tcl.m4) AC_DEFUN(TCLUTIL_CONFIG, [ #------------------------------------------------------------------------ # TCLUTIL_PATH_BLT -- # # Locate the BLT library # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-blt=... # # Defines the following vars: # BLT_LIB_SPEC String to add to link the BLT lib (-L... -lBLT) # BLT_LIB_DIR Directory containing libBLT24.so #------------------------------------------------------------------------ AC_DEFUN(TCLUTIL_PATH_BLT, [ AC_MSG_CHECKING(for BLT library) AC_ARG_WITH(blt, [AC_HELP_STRING([--with-blt=DIR],[link with BLT library installed in DIR])], BLT_LIB_DIR=$withval) BLT_LIBNAME=libBLT25${SHLIB_SUFFIX} BLT_LIBFLAG="-lBLT25" if test -z "$BLT_LIB_DIR" ; then # If --with-blt=dir was not specified, try the Tcl lib dir and the exec-prefix/lib dir places="\ $TCL_BIN_DIR \ $TCL_BIN_DIR/blt2.4 \ $TCLTK_ROOT/lib \ $TCLTK_ROOT/lib/blt2.4 \ $exec_prefix/lib \ $exec_prefix/lib/blt2.4 \ $prefix/lib \ $prefix/lib/blt2.4 \ " for i in $places ; do if test -f $i/$BLT_LIBNAME then BLT_LIB_DIR=$i break fi done if test -z "$BLT_LIB_DIR" ; then echo AC_MSG_ERROR([could not find $BLT_LIBNAME: Please use the --with-blt=DIR option.]) fi else # Check if the BLT library is in the lib subdir of the given dir if test ! -f $BLT_LIB_DIR/$BLT_LIBNAME then if test ! -f $BLT_LIB_DIR/lib/$BLT_LIBNAME then echo AC_MSG_ERROR([could not find $BLT_LIBNAME in $BLT_LIB_DIR or in $BLT_LIB_DIR/lib: Please use the --with-blt=DIR option.]) else BLT_LIB_DIR=$BLT_LIB_DIR/lib fi fi fi BLT_LIB_SPEC="-L$BLT_LIB_DIR $BLT_LIBFLAG" AC_MSG_RESULT($BLT_LIB_DIR) AC_SUBST(BLT_LIB_DIR) AC_SUBST(BLT_LIB_SPEC) ]) # ----------------------------------------------------------------------- AC_DEFINE(USE_COMPAT_CONST, 1, [For compatibility between tcl8.4 and previous tcl releases]) # ----------------------------------------------------------------------- AC_MSG_CHECKING([sysv shared memory prototypes]) AC_EGREP_HEADER([int.*shmdt.*\(], [sys/shm.h], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no); AC_DEFINE(NEED_SHM_PROTO, 1, [Check if we need (or can use) shared memory (sysv/shm) prototypes])]) # ----------------------------------------------------------------------- AC_MSG_CHECKING([gethostname prototype]) AC_EGREP_HEADER([int.*gethostname.*\(], [unistd.h], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no); AC_DEFINE(NEED_GETHOSTNAME_PROTO, 1, [Check if we need a prototype for gethostname()])]) # ----------------------------------------------------------------------- AC_CHECK_SIZEOF(long, 4) # ------------------------------------------------------------------------- # there are some idiosyncrasies with semun defs (used in semxxx). Solaris # does not define it at all # ------------------------------------------------------------------------- AC_MSG_CHECKING("do we have union semun defined") AC_TRY_COMPILE( [#include #include #include #include ], [ union semun filler; ], [ AC_DEFINE(HAVE_UNION_SEMUN) AC_MSG_RESULT("yes") ], AC_MSG_RESULT("no") ) AC_DEFINE(HAVE_NET_SERVICES) # ----------------------------------------------------------------------- AC_MSG_CHECKING([mmap prototypes]) AC_EGREP_HEADER([int.*munmap.*\(], [sys/mman.h], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no); AC_DEFINE(NEED_MMAP_PROTO, 1, [Check if we need (or can use) mmap prototypes])]) # ----------------------------------------------------------------------- AC_CHECK_HEADERS(sys/filio.h) AC_CHECK_HEADERS(sys/statvfs.h) # ----------------------------------------------------------------------- # Check if we need (or can use) the socklen_t type. # ----------------------------------------------------------------------- AC_CHECK_TYPES([socklen_t],,,[#include ]) #------------------------------------------------------------------------ #AC_LANG(C++) AC_MSG_CHECKING([fd_set]) AC_TRY_COMPILE([ #include #include ], [fd_set readFds; select(32, &readFds, 0, 0, 0);], test_ok=yes, test_ok=no) if test $test_ok = yes; then AC_DEFINE(HAVE_SELECT_FD_SET, 1, [See if the select system call uses fd_set arguments]) fi AC_MSG_RESULT($test_ok) #------------------------------------------------------------------------ # Check if we require additional libraries to support C++ shareable # libraries. system=`uname -s`-`uname -r` SHLIB_LD_CXX_LIBS="" export SHLIB_LD_CXX_LIBS case $system in SunOS-5*) SHLIB_LD_CXX_LIBS="-lCrun -lCstd" ;; OSF*) SHLIB_LD_CXX_LIBS="-lcxx -lcxxstd" ;; esac AC_SUBST(SHLIB_LD_CXX_LIBS) #------------------------------------------------------------------------- # The cxx C++ compiler under Tru64 UNIX needs the special # CXXFLAGS "-std gnu -D__USE_STD_IOSTREAM=1". These allow the standard # library streams headers to work and to generate templates that do # not require special handling throughout skycat directories (normally # template object files are created in various cxx_repository subdirectories, # this way the object files are kept embedded the usual object files, see # the cxx man page for details). #------------------------------------------------------------------------- export CXXFLAGS case $system in OSF*) case "x$CXX" in xcxx*) CXXFLAGS="$CXXFLAGS -g3 -std gnu -D__USE_STD_IOSTREAM=1" ;; esac ;; esac ]) # End of macro skycat-3.1.2-starlink-1b/tclutil/bitmaps/000077500000000000000000000000001215713201500202545ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/tclutil/bitmaps/README000066400000000000000000000002211215713201500211270ustar00rootroot00000000000000Be sure to re-run make if you add or modify a bitmap in this directory. This will create ../src/bitmaps.c which defines the bitmaps in C code. skycat-3.1.2-starlink-1b/tclutil/bitmaps/abc.xbm000066400000000000000000000004201215713201500215050ustar00rootroot00000000000000#define abc_width 16 #define abc_height 16 static char abc_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x49, 0x30, 0xc8, 0x49, 0x4e, 0x0a, 0x49, 0x4a, 0xde, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/anyselect.xbm000066400000000000000000000004421215713201500227530ustar00rootroot00000000000000#define anyselect_width 16 #define anyselect_height 16 static char anyselect_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x01, 0x63, 0x03, 0x14, 0x07, 0x08, 0x0f, 0x08, 0x1f, 0x08, 0x3f, 0x08, 0x7f, 0x08, 0xff, 0x08, 0x1b, 0x08, 0x31, 0x08, 0x30, 0x08, 0x60, 0x14, 0x60, 0x63, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/ar10_13_3.xbm000066400000000000000000000004421215713201500222540ustar00rootroot00000000000000#define ar10_13_3_width 16 #define ar10_13_3_height 16 static char ar10_13_3_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x07, 0xe0, 0x03, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xe0, 0x03, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/ar12_11_3.xbm000066400000000000000000000004421215713201500222540ustar00rootroot00000000000000#define ar12_11_3_width 16 #define ar12_11_3_height 16 static char ar12_11_3_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x07, 0xf0, 0x0f, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xf0, 0x0f, 0x80, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/ar12_12_3.xbm000066400000000000000000000004421215713201500222550ustar00rootroot00000000000000#define ar12_12_3_width 16 #define ar12_12_3_height 16 static char ar12_12_3_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0f, 0xe0, 0x0f, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xe0, 0x0f, 0x00, 0x0f, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/ar6_6_4.xbm000066400000000000000000000004341215713201500221250ustar00rootroot00000000000000#define ar6_6_4_width 16 #define ar6_6_4_height 16 static char ar6_6_4_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x30, 0x00, 0x38, 0x00, 0x3c, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x3c, 0x00, 0x38, 0x00, 0x30, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/ar8_10_3.xbm000066400000000000000000000004371215713201500222040ustar00rootroot00000000000000#define ar8_10_3_width 16 #define ar8_10_3_height 16 static char ar8_10_3_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x18, 0x00, 0x1c, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x1c, 0x00, 0x18, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/ar8_12_9.xbm000066400000000000000000000004371215713201500222140ustar00rootroot00000000000000#define ar8_12_9_width 16 #define ar8_12_9_height 16 static char ar8_12_9_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x30, 0x00, 0x18, 0x00, 0x1c, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x1c, 0x00, 0x18, 0x00, 0x30, 0x00, 0x20, 0x00, 0x40, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/ar8_8_6.xbm000066400000000000000000000004341215713201500221330ustar00rootroot00000000000000#define ar8_8_6_width 16 #define ar8_8_6_height 16 static char ar8_8_6_bits[] = { 0x80, 0x00, 0xc0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf8, 0x00, 0xfc, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfc, 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xe0, 0x00, 0xc0, 0x00, 0x80, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/arc.xbm000066400000000000000000000004201215713201500215250ustar00rootroot00000000000000#define arc_width 16 #define arc_height 16 static char arc_bits[] = { 0x1f, 0x00, 0xe1, 0x00, 0x01, 0x03, 0x01, 0x04, 0x01, 0x08, 0x01, 0x10, 0x01, 0x20, 0x01, 0x20, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0xff, 0xff}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/arrowboth.xbm000066400000000000000000000011021215713201500227650ustar00rootroot00000000000000#define arrowboth_width 43 #define arrowboth_height 13 static char arrowboth_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x40, 0x00, 0x03, 0x00, 0x00, 0x06, 0x60, 0x80, 0x03, 0x00, 0x00, 0x0e, 0x70, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0xf8, 0x80, 0x03, 0x00, 0x00, 0x0e, 0x70, 0x00, 0x03, 0x00, 0x00, 0x06, 0x60, 0x00, 0x02, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/arrowfirst.xbm000066400000000000000000000011051215713201500231630ustar00rootroot00000000000000#define arrowfirst_width 43 #define arrowfirst_height 13 static char arrowfirst_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x00, 0x60, 0x80, 0x03, 0x00, 0x00, 0x00, 0x70, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0xf8, 0x80, 0x03, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, 0x00, 0x00, 0x00, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/arrowlast.xbm000066400000000000000000000011021215713201500227740ustar00rootroot00000000000000#define arrowlast_width 43 #define arrowlast_height 13 static char arrowlast_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x70, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x70, 0x00, 0x00, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/arrownone.xbm000066400000000000000000000011021215713201500227700ustar00rootroot00000000000000#define arrownone_width 43 #define arrownone_height 13 static char arrownone_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/b1.xbm000066400000000000000000000004151215713201500212660ustar00rootroot00000000000000#define b1_width 16 #define b1_height 16 static char b1_bits[] = { 0xf8, 0x1f, 0xfc, 0x3f, 0xcc, 0x36, 0xcc, 0x36, 0xcc, 0x36, 0xcc, 0x36, 0xcc, 0x36, 0xcc, 0x36, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x23, 0xfc, 0x3f, 0xf8, 0x1f}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/b2.xbm000066400000000000000000000004151215713201500212670ustar00rootroot00000000000000#define b2_width 16 #define b2_height 16 static char b2_bits[] = { 0xf8, 0x1f, 0xfc, 0x3f, 0x6c, 0x36, 0x6c, 0x36, 0x6c, 0x36, 0x6c, 0x36, 0x6c, 0x36, 0x6c, 0x36, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x23, 0xfc, 0x3f, 0xf8, 0x1f}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/b3.xbm000066400000000000000000000004151215713201500212700ustar00rootroot00000000000000#define b3_width 16 #define b3_height 16 static char b3_bits[] = { 0xf8, 0x1f, 0xfc, 0x3f, 0x6c, 0x33, 0x6c, 0x33, 0x6c, 0x33, 0x6c, 0x33, 0x6c, 0x33, 0x6c, 0x33, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x23, 0xfc, 0x3f, 0xf8, 0x1f}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/bitmaps.tcl000066400000000000000000000016501215713201500224210ustar00rootroot00000000000000#!../bin/rtdimage_wish # # E.S.O. - VLT project # # "@(#) $Id: bitmaps.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # script to generate C code declaring X bitmaps so that the (binary) application # doesn't have to be delivered with the bitmap files. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 21 Nov 95 Created puts { /* * E.S.O. - VLT project * "@(#) $Id: bitmaps.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * Bitmap definitions for Tk * * This file was generated by ../bitmaps/bitmaps.tcl - DO NO EDIT */ #include #include } puts "void defineTclutilBitmaps(Tcl_Interp *interp) {" foreach file [glob *.xbm] { set name [file rootname $file] puts " #include \"$file\"" puts " Tk_DefineBitmap(interp, Tk_GetUid(\"$name\"), (char*)${name}_bits, ${name}_width, ${name}_height);\n" } puts "}" exit 0 skycat-3.1.2-starlink-1b/tclutil/bitmaps/circle.xbm000066400000000000000000000004311215713201500222230ustar00rootroot00000000000000#define circle_width 16 #define circle_height 16 static char circle_bits[] = { 0xe0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x02, 0x40, 0x02, 0x40, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x02, 0x40, 0x02, 0x40, 0x04, 0x20, 0x18, 0x18, 0xe0, 0x07}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/decr.xbm000066400000000000000000000001431215713201500216770ustar00rootroot00000000000000#define decr_width 7 #define decr_height 4 static char decr_bits[] = { 0x7f, 0x3e, 0x1c, 0x08}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/dir.xbm000066400000000000000000000003541215713201500215440ustar00rootroot00000000000000#define dir_width 16 #define dir_height 13 static char dir_bits[] = { 0x00, 0x7e, 0x00, 0x81, 0xff, 0xff, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0xff, 0xff}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/down.xbm000066400000000000000000000004231215713201500217320ustar00rootroot00000000000000#define down_width 16 #define down_height 16 static char down_bits[] = { 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xf8, 0x1f, 0xf8, 0x1f, 0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/down_arrow.xbm000066400000000000000000000004451215713201500231500ustar00rootroot00000000000000#define down_arrow_width 16 #define down_arrow_height 16 static char down_arrow_bits[] = { 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xf8, 0x1f, 0xf8, 0x1f, 0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/dragb1.xbm000066400000000000000000000007421215713201500221270ustar00rootroot00000000000000#define dragb1_width 28 #define dragb1_height 16 static char dragb1_bits[] = { 0x00, 0x80, 0xff, 0x01, 0x00, 0xc0, 0xff, 0x03, 0x00, 0xc0, 0x6c, 0x03, 0x00, 0xc0, 0x6c, 0x03, 0x00, 0xc0, 0x6c, 0x03, 0x00, 0xc0, 0x6c, 0x03, 0x40, 0xc0, 0x6c, 0x03, 0xc0, 0xc8, 0x6c, 0x03, 0xfe, 0xdd, 0xff, 0x03, 0xc0, 0xc8, 0xff, 0x03, 0x40, 0xc0, 0xff, 0x03, 0x00, 0xc0, 0xff, 0x03, 0x00, 0xc0, 0xff, 0x03, 0x00, 0xc0, 0x3f, 0x02, 0x00, 0xc0, 0xff, 0x03, 0x00, 0x80, 0xff, 0x01}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/dragb2.xbm000066400000000000000000000007421215713201500221300ustar00rootroot00000000000000#define dragb2_width 28 #define dragb2_height 16 static char dragb2_bits[] = { 0x00, 0x80, 0xff, 0x01, 0x00, 0xc0, 0xff, 0x03, 0x00, 0xc0, 0x66, 0x03, 0x00, 0xc0, 0x66, 0x03, 0x00, 0xc0, 0x66, 0x03, 0x00, 0xc0, 0x66, 0x03, 0x40, 0xc0, 0x66, 0x03, 0xc0, 0xc8, 0x66, 0x03, 0xfe, 0xdd, 0xff, 0x03, 0xc0, 0xc8, 0xff, 0x03, 0x40, 0xc0, 0xff, 0x03, 0x00, 0xc0, 0xff, 0x03, 0x00, 0xc0, 0xff, 0x03, 0x00, 0xc0, 0x3f, 0x02, 0x00, 0xc0, 0xff, 0x03, 0x00, 0x80, 0xff, 0x01}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/dragb3.xbm000066400000000000000000000007421215713201500221310ustar00rootroot00000000000000#define dragb3_width 28 #define dragb3_height 16 static char dragb3_bits[] = { 0x00, 0x80, 0xff, 0x01, 0x00, 0xc0, 0xff, 0x03, 0x00, 0xc0, 0x36, 0x03, 0x00, 0xc0, 0x36, 0x03, 0x00, 0xc0, 0x36, 0x03, 0x00, 0xc0, 0x36, 0x03, 0x40, 0xc0, 0x36, 0x03, 0xc0, 0xc8, 0x36, 0x03, 0xfe, 0xdd, 0xff, 0x03, 0xc0, 0xc8, 0xff, 0x03, 0x40, 0xc0, 0xff, 0x03, 0x00, 0xc0, 0xff, 0x03, 0x00, 0xc0, 0xff, 0x03, 0x00, 0xc0, 0x3f, 0x02, 0x00, 0xc0, 0xff, 0x03, 0x00, 0x80, 0xff, 0x01}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/file.xbm000066400000000000000000000004231215713201500217020ustar00rootroot00000000000000#define file_width 16 #define file_height 16 static char file_bits[] = { 0xfe, 0x07, 0x02, 0x0c, 0x02, 0x14, 0x02, 0x24, 0x1a, 0x7c, 0x02, 0x40, 0xfa, 0x43, 0x02, 0x40, 0xfa, 0x47, 0x02, 0x40, 0xfa, 0x4f, 0x02, 0x40, 0xfa, 0x43, 0x02, 0x40, 0x02, 0x40, 0xfe, 0x7f}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/files.xbm000066400000000000000000000004261215713201500220700ustar00rootroot00000000000000#define files_width 16 #define files_height 16 static char files_bits[] = { 0x80, 0x1f, 0x80, 0x20, 0xe0, 0x40, 0xa0, 0x40, 0xb8, 0x40, 0xa8, 0x40, 0xae, 0x40, 0xaa, 0x40, 0xaa, 0x7f, 0x2a, 0x10, 0xea, 0x1f, 0x0a, 0x04, 0xfa, 0x07, 0x02, 0x01, 0xfe, 0x01, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/flipx.xbm000066400000000000000000000004261215713201500221100ustar00rootroot00000000000000#define flipx_width 16 #define flipx_height 16 static char flipx_bits[] = { 0x00, 0x08, 0x00, 0x18, 0xfc, 0x3f, 0xfc, 0x7f, 0xfc, 0x3f, 0x00, 0x18, 0x00, 0x08, 0x80, 0x01, 0x80, 0x01, 0x10, 0x00, 0x18, 0x00, 0xfc, 0x3f, 0xfe, 0x3f, 0xfc, 0x3f, 0x18, 0x00, 0x10, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/flipy.xbm000066400000000000000000000004261215713201500221110ustar00rootroot00000000000000#define flipy_width 16 #define flipy_height 16 static char flipy_bits[] = { 0x00, 0x00, 0x08, 0x00, 0x1c, 0x38, 0x3e, 0x38, 0x7f, 0x38, 0x1c, 0x38, 0x1c, 0x38, 0x9c, 0x39, 0x9c, 0x39, 0x1c, 0x38, 0x1c, 0x38, 0x1c, 0xfe, 0x1c, 0x7c, 0x1c, 0x38, 0x00, 0x10, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/freehand.xbm000066400000000000000000000004371215713201500225440ustar00rootroot00000000000000#define freehand_width 16 #define freehand_height 16 static char freehand_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x20, 0x01, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x11, 0x02, 0x22, 0x41, 0xcc, 0x20, 0xb0, 0x10, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/incr.xbm000066400000000000000000000001431215713201500217150ustar00rootroot00000000000000#define incr_width 7 #define incr_height 4 static char incr_bits[] = { 0x08, 0x1c, 0x3e, 0x7f}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/information.xbm000066400000000000000000000004501215713201500233100ustar00rootroot00000000000000#define information_width 16 #define information_height 16 static char information_bits[] = { 0xff, 0xff, 0xff, 0xff, 0x03, 0xc0, 0x83, 0xc1, 0x83, 0xc1, 0x03, 0xc0, 0xc3, 0xc1, 0x83, 0xc1, 0x83, 0xc1, 0x83, 0xc1, 0x83, 0xc1, 0xc3, 0xc3, 0x03, 0xc0, 0x03, 0xc0, 0xff, 0xff, 0xff, 0xff}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/label.xbm000066400000000000000000000004261215713201500220450ustar00rootroot00000000000000#define label_width 16 #define label_height 16 static char label_bits[] = { 0xff, 0xff, 0x01, 0x80, 0x01, 0x80, 0x81, 0x80, 0x81, 0x80, 0x41, 0x81, 0x41, 0x81, 0x21, 0x82, 0x21, 0x82, 0xe1, 0x83, 0x11, 0x84, 0x11, 0x84, 0x39, 0x8e, 0x01, 0x80, 0x01, 0x80, 0xff, 0xff}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/left.xbm000066400000000000000000000001651215713201500217200ustar00rootroot00000000000000#define left_width 4 #define left_height 7 static char left_bits[] = { 0x08, 0x0c, 0x0e, 0x0f, 0x0e, 0x0c, 0x08}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/left_arrow.xbm000066400000000000000000000004451215713201500231330ustar00rootroot00000000000000#define left_arrow_width 16 #define left_arrow_height 16 static char left_arrow_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf8, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xf8, 0x3f, 0xf0, 0x00, 0xe0, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/line.xbm000066400000000000000000000004231215713201500217120ustar00rootroot00000000000000#define line_width 16 #define line_height 16 static char line_bits[] = { 0x01, 0x00, 0x03, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x18, 0x00, 0x30, 0x00, 0x60, 0x00, 0xc0, 0x00, 0x80, 0x01, 0x00, 0x03, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x18, 0x00, 0x30, 0x00, 0x60, 0x00, 0xc0}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/link.xbm000066400000000000000000000003571215713201500217260ustar00rootroot00000000000000#define link_width 16 #define link_height 13 static char link_bits[] = { 0x00, 0x7e, 0x00, 0x81, 0xff, 0xff, 0x01, 0x80, 0x01, 0x84, 0x01, 0x8c, 0xfd, 0x97, 0x55, 0xad, 0xfd, 0x97, 0x01, 0x8c, 0x01, 0x84, 0x01, 0x80, 0xff, 0xff}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/magnify.xbm000066400000000000000000000004341215713201500224170ustar00rootroot00000000000000#define magnify_width 16 #define magnify_height 16 static char magnify_bits[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1c, 0x00, 0x0e, 0x00, 0x07, 0x80, 0x03, 0xc0, 0x01, 0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1c, 0x00, 0x0e, 0x00, 0xff, 0xff, 0xff, 0xff}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/objselect.xbm000066400000000000000000000004421215713201500227360ustar00rootroot00000000000000#define objselect_width 16 #define objselect_height 16 static char objselect_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x1c, 0x00, 0x3c, 0x00, 0x7c, 0x00, 0xfc, 0x00, 0xfc, 0x01, 0xfc, 0x03, 0x6c, 0x00, 0xc4, 0x00, 0xc0, 0x00, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/oval.xbm000066400000000000000000000004231215713201500217240ustar00rootroot00000000000000#define oval_width 16 #define oval_height 16 static char oval_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x0c, 0x30, 0x02, 0x40, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x02, 0x40, 0x0c, 0x30, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/pat0.xbm000066400000000000000000000004231215713201500216270ustar00rootroot00000000000000#define pat0_width 16 #define pat0_height 16 static char pat0_bits[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/pat1.xbm000066400000000000000000000004231215713201500216300ustar00rootroot00000000000000#define pat1_width 16 #define pat1_height 16 static char pat1_bits[] = { 0xee, 0xee, 0xff, 0xff, 0xbb, 0xbb, 0xff, 0xff, 0xee, 0xee, 0xff, 0xff, 0xbb, 0xbb, 0xff, 0xff, 0xee, 0xee, 0xff, 0xff, 0xbb, 0xbb, 0xff, 0xff, 0xee, 0xee, 0xff, 0xff, 0xbb, 0xbb, 0xff, 0xff}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/pat10.xbm000066400000000000000000000004261215713201500217130ustar00rootroot00000000000000#define pat10_width 16 #define pat10_height 16 static char pat10_bits[] = { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/pat11.xbm000066400000000000000000000004261215713201500217140ustar00rootroot00000000000000#define pat11_width 16 #define pat11_height 16 static char pat11_bits[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/pat12.xbm000066400000000000000000000004261215713201500217150ustar00rootroot00000000000000#define pat12_width 16 #define pat12_height 16 static char pat12_bits[] = { 0x81, 0x81, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18, 0x18, 0x18, 0x24, 0x24, 0x42, 0x42, 0x81, 0x81, 0x81, 0x81, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18, 0x18, 0x18, 0x24, 0x24, 0x42, 0x42, 0x81, 0x81}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/pat13.xbm000066400000000000000000000004261215713201500217160ustar00rootroot00000000000000#define pat13_width 16 #define pat13_height 16 static char pat13_bits[] = { 0x02, 0x81, 0x81, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x81, 0x81, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x81, 0x81, 0x40}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/pat14.xbm000066400000000000000000000004261215713201500217170ustar00rootroot00000000000000#define pat14_width 16 #define pat14_height 16 static char pat14_bits[] = { 0x81, 0x40, 0x02, 0x81, 0x04, 0x02, 0x08, 0x04, 0x10, 0x08, 0x20, 0x10, 0x40, 0x20, 0x81, 0x40, 0x02, 0x81, 0x04, 0x02, 0x08, 0x04, 0x10, 0x08, 0x20, 0x10, 0x40, 0x20, 0x81, 0x40, 0x02, 0x81}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/pat15.xbm000066400000000000000000000004261215713201500217200ustar00rootroot00000000000000#define pat15_width 16 #define pat15_height 16 static char pat15_bits[] = { 0x00, 0x00, 0x04, 0x20, 0x0c, 0x20, 0x14, 0x20, 0x24, 0x20, 0x44, 0x20, 0x84, 0x20, 0x04, 0x21, 0x04, 0x22, 0x04, 0x24, 0x04, 0x28, 0x04, 0x30, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/pat2.xbm000066400000000000000000000004231215713201500216310ustar00rootroot00000000000000#define pat2_width 16 #define pat2_height 16 static char pat2_bits[] = { 0xee, 0xee, 0xbb, 0xbb, 0xee, 0xee, 0xbb, 0xbb, 0xee, 0xee, 0xbb, 0xbb, 0xee, 0xee, 0xbb, 0xbb, 0xee, 0xee, 0xbb, 0xbb, 0xee, 0xee, 0xbb, 0xbb, 0xee, 0xee, 0xbb, 0xbb, 0xee, 0xee, 0xbb, 0xbb}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/pat3.xbm000066400000000000000000000004231215713201500216320ustar00rootroot00000000000000#define pat3_width 16 #define pat3_height 16 static char pat3_bits[] = { 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/pat4.xbm000066400000000000000000000004231215713201500216330ustar00rootroot00000000000000#define pat4_width 16 #define pat4_height 16 static char pat4_bits[] = { 0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/pat5.xbm000066400000000000000000000004231215713201500216340ustar00rootroot00000000000000#define pat5_width 16 #define pat5_height 16 static char pat5_bits[] = { 0x11, 0x11, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/pat6.xbm000066400000000000000000000004231215713201500216350ustar00rootroot00000000000000#define pat6_width 16 #define pat6_height 16 static char pat6_bits[] = { 0x08, 0x82, 0x00, 0x00, 0x41, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x00, 0x41, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x00, 0x41, 0x10, 0x00, 0x00, 0x08, 0x82, 0x00, 0x00, 0x41, 0x10, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/pat7.xbm000066400000000000000000000004231215713201500216360ustar00rootroot00000000000000#define pat7_width 16 #define pat7_height 16 static char pat7_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/pat8.xbm000066400000000000000000000004231215713201500216370ustar00rootroot00000000000000#define pat8_width 16 #define pat8_height 16 static char pat8_bits[] = { 0x1e, 0x1e, 0x0f, 0x0f, 0x87, 0x87, 0xc3, 0xc3, 0xe1, 0xe1, 0xf0, 0xf0, 0x78, 0x78, 0x3c, 0x3c, 0x1e, 0x1e, 0x0f, 0x0f, 0x87, 0x87, 0xc3, 0xc3, 0xe1, 0xe1, 0xf0, 0xf0, 0x78, 0x78, 0x3c, 0x3c}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/pat9.xbm000066400000000000000000000004231215713201500216400ustar00rootroot00000000000000#define pat9_width 16 #define pat9_height 16 static char pat9_bits[] = { 0x78, 0x78, 0xf0, 0xf0, 0xe1, 0xe1, 0xc3, 0xc3, 0x87, 0x87, 0x0f, 0x0f, 0x1e, 0x1e, 0x3c, 0x3c, 0x78, 0x78, 0xf0, 0xf0, 0xe1, 0xe1, 0xc3, 0xc3, 0x87, 0x87, 0x0f, 0x0f, 0x1e, 0x1e, 0x3c, 0x3c}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/polygon.xbm000066400000000000000000000004341215713201500224540ustar00rootroot00000000000000#define polygon_width 16 #define polygon_height 16 static char polygon_bits[] = { 0x01, 0x00, 0x03, 0x00, 0x05, 0xc0, 0x09, 0xb0, 0x11, 0x8c, 0x21, 0x43, 0xc1, 0x40, 0x01, 0x20, 0x01, 0x20, 0x01, 0x10, 0x03, 0x10, 0x0c, 0x08, 0x30, 0x08, 0xc0, 0x04, 0x00, 0x07, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/polyline.xbm000066400000000000000000000004371215713201500226230ustar00rootroot00000000000000#define polyline_width 16 #define polyline_height 16 static char polyline_bits[] = { 0x00, 0x00, 0x01, 0xc0, 0x03, 0xb0, 0x05, 0x4c, 0x09, 0x43, 0xd1, 0x20, 0x21, 0x20, 0x01, 0x10, 0x01, 0x10, 0x01, 0x08, 0x01, 0x08, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/rectangle.xbm000066400000000000000000000004421215713201500227300ustar00rootroot00000000000000#define rectangle_width 16 #define rectangle_height 16 static char rectangle_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/region.xbm000066400000000000000000000004311215713201500222450ustar00rootroot00000000000000#define region_width 16 #define region_height 16 static char region_bits[] = { 0xb7, 0xed, 0x01, 0x80, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0xb7, 0xed}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/right.xbm000066400000000000000000000001701215713201500220770ustar00rootroot00000000000000#define right_width 4 #define right_height 7 static char right_bits[] = { 0x01, 0x03, 0x07, 0x0f, 0x07, 0x03, 0x01}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/right_arrow.xbm000066400000000000000000000004501215713201500233120ustar00rootroot00000000000000#define right_arrow_width 16 #define right_arrow_height 16 static char right_arrow_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0f, 0xfc, 0x1f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x1f, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/rotate.xbm000066400000000000000000000004311215713201500222600ustar00rootroot00000000000000#define rotate_width 16 #define rotate_height 16 static char rotate_bits[] = { 0xe1, 0x07, 0xfb, 0x1f, 0x3f, 0x3c, 0x0f, 0x70, 0x1f, 0x60, 0x3f, 0xe0, 0x7f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0x07, 0xfc, 0x06, 0xf8, 0x0e, 0xf0, 0x3c, 0xfc, 0xf8, 0xdf, 0xe0, 0x87}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/shiftb1.xbm000066400000000000000000000007451215713201500223320ustar00rootroot00000000000000#define shiftb1_width 28 #define shiftb1_height 16 static char shiftb1_bits[] = { 0x00, 0x80, 0xff, 0x01, 0x00, 0xc0, 0xff, 0x03, 0x10, 0xc0, 0x6c, 0x03, 0x38, 0xc0, 0x6c, 0x03, 0x7c, 0xc0, 0x6c, 0x03, 0xfe, 0xc0, 0x6c, 0x03, 0x10, 0xc0, 0x6c, 0x03, 0x10, 0xc2, 0x6c, 0x03, 0x10, 0xc7, 0xff, 0x03, 0x10, 0xc2, 0xff, 0x03, 0x10, 0xc0, 0xff, 0x03, 0x10, 0xc0, 0xff, 0x03, 0x10, 0xc0, 0xff, 0x03, 0x10, 0xc0, 0x3f, 0x02, 0x10, 0xc0, 0xff, 0x03, 0x00, 0x80, 0xff, 0x01}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/shiftdragb1.xbm000066400000000000000000000007611215713201500231660ustar00rootroot00000000000000#define shiftdragb1_width 28 #define shiftdragb1_height 16 static char shiftdragb1_bits[] = { 0x00, 0x80, 0xff, 0x01, 0x40, 0xc0, 0xff, 0x03, 0xc0, 0xc0, 0x6c, 0x03, 0xfe, 0xc1, 0x6c, 0x03, 0xc0, 0xc0, 0x6c, 0x03, 0x40, 0xc0, 0x6c, 0x03, 0x00, 0xc8, 0x6c, 0x03, 0x20, 0xdc, 0x6c, 0x03, 0x70, 0xc8, 0xff, 0x03, 0xf8, 0xc0, 0xff, 0x03, 0x20, 0xc0, 0xff, 0x03, 0x20, 0xc0, 0xff, 0x03, 0x20, 0xc0, 0xff, 0x03, 0x20, 0xc0, 0x3f, 0x02, 0x20, 0xc0, 0xff, 0x03, 0x00, 0x80, 0xff, 0x01}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/shrink.xbm000066400000000000000000000004311215713201500222600ustar00rootroot00000000000000#define shrink_width 16 #define shrink_height 16 static char shrink_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0xf0, 0x3f, 0x00, 0x1c, 0x00, 0x0e, 0x00, 0x07, 0x80, 0x03, 0xc0, 0x01, 0xe0, 0x00, 0xf0, 0x3f, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/smooth.xbm000066400000000000000000000004421215713201500222750ustar00rootroot00000000000000#define smooth_width 16 #define smooth_height 16 static unsigned char smooth_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x3f, 0x02, 0x40, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x02, 0x40, 0xfc, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/square.xbm000066400000000000000000000004311215713201500222620ustar00rootroot00000000000000#define square_width 16 #define square_height 16 static char square_bits[] = { 0xff, 0xff, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0xff, 0xff}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/text.xbm000066400000000000000000000004231215713201500217470ustar00rootroot00000000000000#define text_width 16 #define text_height 16 static char text_bits[] = { 0x80, 0x03, 0x80, 0x03, 0x80, 0x06, 0x40, 0x06, 0x40, 0x0c, 0x60, 0x0c, 0x20, 0x0c, 0x20, 0x18, 0x30, 0x18, 0xf0, 0x1f, 0x10, 0x30, 0x18, 0x30, 0x08, 0x30, 0x08, 0x60, 0x0c, 0x60, 0x3f, 0xf8}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/up.xbm000066400000000000000000000004151215713201500214100ustar00rootroot00000000000000#define up_width 16 #define up_height 16 static char up_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf8, 0x1f, 0xf8, 0x1f, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/up_arrow.xbm000066400000000000000000000004371215713201500226260ustar00rootroot00000000000000#define up_arrow_width 16 #define up_arrow_height 16 static char up_arrow_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf8, 0x1f, 0xf8, 0x1f, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/width1.xbm000066400000000000000000000012501215713201500221620ustar00rootroot00000000000000#define width1_width 43 #define width1_height 16 static char width1_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/width2.xbm000066400000000000000000000012501215713201500221630ustar00rootroot00000000000000#define width2_width 43 #define width2_height 16 static char width2_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/width3.xbm000066400000000000000000000012501215713201500221640ustar00rootroot00000000000000#define width3_width 43 #define width3_height 16 static char width3_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/bitmaps/width4.xbm000066400000000000000000000012501215713201500221650ustar00rootroot00000000000000#define width4_width 43 #define width4_height 16 static char width4_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; skycat-3.1.2-starlink-1b/tclutil/configure000077500000000000000000014063231215713201500205350ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by Starlink Autoconf 2.59 for tclutil 2.1.0. # # Copyright (C) 2003 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` exec 6>&1 # # Initializations. # ac_default_prefix=/usr/local ac_config_libobj_dir=. cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. # This variable seems obsolete. It should probably be removed, and # only ac_max_sed_lines should be used. : ${ac_max_here_lines=38} # Identity of this package. PACKAGE_NAME='tclutil' PACKAGE_TARNAME='tclutil' PACKAGE_VERSION='2.1.0' PACKAGE_STRING='tclutil 2.1.0' PACKAGE_BUGREPORT='' # Factoring default headers for most tests. ac_includes_default="\ #include #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_STAT_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #if HAVE_INTTYPES_H # include #else # if HAVE_STDINT_H # include # endif #endif #if HAVE_UNISTD_H # include #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CYGPATH EXEEXT PKG_LIB_FILE PKG_STUB_LIB_FILE PKG_STUB_SOURCES PKG_STUB_OBJECTS PKG_TCL_SOURCES PKG_HEADERS PKG_INCLUDES PKG_LIBS PKG_CFLAGS TCL_VERSION TCL_BIN_DIR TCL_SRC_DIR TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_LIBS TCL_DEFS TCL_EXTRA_CFLAGS TCL_LD_FLAGS TCL_SHLIB_LD_LIBS TK_VERSION TK_BIN_DIR TK_SRC_DIR TK_LIB_FILE TK_LIB_FLAG TK_LIB_SPEC TK_STUB_LIB_FILE TK_STUB_LIB_FLAG TK_STUB_LIB_SPEC TK_LIBS TK_XINCLUDES CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT CPP CXX CXXFLAGS ac_ct_CXX INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA SET_MAKE RANLIB ac_ct_RANLIB EGREP MATH_LIBS SHLIB_LD_CXX_LIBS PKG_SOURCES PKG_OBJECTS CLEANFILES TCL_INCLUDES TK_INCLUDES TCL_THREADS SHARED_BUILD AR CELIB_DIR LIBOBJS SHLIB_SUFFIX DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING STLIB_LD SHLIB_LD SHLIB_CFLAGS SHLIB_LD_LIBS LDFLAGS_DEBUG LDFLAGS_OPTIMIZE LD_LIBRARY_PATH_VAR BLT_LIB_DIR BLT_LIB_SPEC TCL_DBGX CFLAGS_DEFAULT LDFLAGS_DEFAULT MAKE_LIB MAKE_SHARED_LIB MAKE_STATIC_LIB MAKE_STUB_LIB RANLIB_STUB TCLSH_PROG WISH_PROG tclutil_LIB_FILE tclutil_BUILD_DIR tclutil_BUILD_LIB_SPEC tclutil_LIB_SPEC tclutil_PKG_OBJECTS tclutil_SRC_DIR LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_option in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval "enable_$ac_feature=no" ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "enable_$ac_feature='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "with_$ac_package='$ac_optarg'" ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/-/_/g'` eval "with_$ac_package=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` eval "$ac_envvar='$ac_optarg'" export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute paths. for ac_var in exec_prefix prefix do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* | NONE | '' ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # Be sure to have absolute paths. for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ localstatedir libdir includedir oldincludedir infodir mandir do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_confdir=`(dirname "$0") 2>/dev/null || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 { (exit 1); exit 1; }; } else { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi fi (cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 { (exit 1); exit 1; }; } srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` ac_env_build_alias_set=${build_alias+set} ac_env_build_alias_value=$build_alias ac_cv_env_build_alias_set=${build_alias+set} ac_cv_env_build_alias_value=$build_alias ac_env_host_alias_set=${host_alias+set} ac_env_host_alias_value=$host_alias ac_cv_env_host_alias_set=${host_alias+set} ac_cv_env_host_alias_value=$host_alias ac_env_target_alias_set=${target_alias+set} ac_env_target_alias_value=$target_alias ac_cv_env_target_alias_set=${target_alias+set} ac_cv_env_target_alias_value=$target_alias ac_env_CC_set=${CC+set} ac_env_CC_value=$CC ac_cv_env_CC_set=${CC+set} ac_cv_env_CC_value=$CC ac_env_CFLAGS_set=${CFLAGS+set} ac_env_CFLAGS_value=$CFLAGS ac_cv_env_CFLAGS_set=${CFLAGS+set} ac_cv_env_CFLAGS_value=$CFLAGS ac_env_LDFLAGS_set=${LDFLAGS+set} ac_env_LDFLAGS_value=$LDFLAGS ac_cv_env_LDFLAGS_set=${LDFLAGS+set} ac_cv_env_LDFLAGS_value=$LDFLAGS ac_env_CPPFLAGS_set=${CPPFLAGS+set} ac_env_CPPFLAGS_value=$CPPFLAGS ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} ac_cv_env_CPPFLAGS_value=$CPPFLAGS ac_env_CPP_set=${CPP+set} ac_env_CPP_value=$CPP ac_cv_env_CPP_set=${CPP+set} ac_cv_env_CPP_value=$CPP ac_env_CXX_set=${CXX+set} ac_env_CXX_value=$CXX ac_cv_env_CXX_set=${CXX+set} ac_cv_env_CXX_value=$CXX ac_env_CXXFLAGS_set=${CXXFLAGS+set} ac_env_CXXFLAGS_value=$CXXFLAGS ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set} ac_cv_env_CXXFLAGS_value=$CXXFLAGS # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures tclutil 2.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] _ACEOF cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --infodir=DIR info documentation [PREFIX/info] --mandir=DIR man documentation [PREFIX/man] _ACEOF cat <<\_ACEOF X features: --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of tclutil 2.1.0:";; esac cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-threads build with threads --enable-shared build and link with shared libraries --enable-shared --enable-64bit enable 64bit support (where applicable) --enable-64bit-vis enable 64bit Sparc VIS support --enable-wince enable Win/CE support (where applicable) --disable-load disallow dynamic loading and "load" command --enable-symbols build with debugging symbols --disable-symbols Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-tcl directory containing tcl configuration (tclConfig.sh) --with-tk directory containing tk configuration (tkConfig.sh) --with-tclinclude directory containing the public Tcl header files --with-tkinclude directory containing the public Tk header files. --with-x use the X Window System --with-celib=DIR use Windows/CE support library from DIR --with-blt=DIR link with BLT library installed in DIR Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor CXX C++ compiler command CXXFLAGS C++ compiler flags Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d $ac_dir || continue ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_srcdir/configure.gnu; then echo $SHELL $ac_srcdir/configure.gnu --help=recursive elif test -f $ac_srcdir/configure; then echo $SHELL $ac_srcdir/configure --help=recursive elif test -f $ac_srcdir/configure.ac || test -f $ac_srcdir/configure.in; then echo $ac_configure --help else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi cd $ac_popdir done fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF tclutil configure 2.1.0 generated by Starlink Autoconf 2.59 Copyright (C) 2003 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit 0 fi exec 5>config.log cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by tclutil $as_me 2.1.0, which was generated by Starlink Autoconf 2.59. Invocation command line was $ $0 $@ _ACEOF { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` hostinfo = `(hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" # Get rid of the leading space. ac_sep=" " ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Be sure not to use single quotes in there, as some shells, # such as our DU 5.0 friend, will then `close' the trap. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, { (set) 2>&1 | case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in *ac_space=\ *) sed -n \ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" ;; *) sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------- ## ## Output files. ## ## ------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo sed "/^$/d" confdefs.h | sort echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core && rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo >confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . $cache_file;; *) . ./$cache_file;; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in `(set) 2>&1 | sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val="\$ac_cv_env_${ac_var}_value" eval ac_new_val="\$ac_env_${ac_var}_value" case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu #-------------------------------------------------------------------- # Call TEA_INIT as the first TEA_ macro to set up initial vars. # This will define a ${TEA_PLATFORM} variable == "unix" or "windows" # as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE. #-------------------------------------------------------------------- # TEA extensions pass this us the version of TEA they think they # are compatible with. TEA_VERSION="3.4" echo "$as_me:$LINENO: checking for correct TEA configuration" >&5 echo $ECHO_N "checking for correct TEA configuration... $ECHO_C" >&6 if test x"${PACKAGE_NAME}" = x ; then { { echo "$as_me:$LINENO: error: The PACKAGE_NAME variable must be defined by your TEA configure.in" >&5 echo "$as_me: error: The PACKAGE_NAME variable must be defined by your TEA configure.in" >&2;} { (exit 1); exit 1; }; } fi if test x"3.4" = x ; then { { echo "$as_me:$LINENO: error: TEA version not specified." >&5 echo "$as_me: error: TEA version not specified." >&2;} { (exit 1); exit 1; }; } elif test "3.4" != "${TEA_VERSION}" ; then echo "$as_me:$LINENO: result: warning: requested TEA version \"3.4\", have \"${TEA_VERSION}\"" >&5 echo "${ECHO_T}warning: requested TEA version \"3.4\", have \"${TEA_VERSION}\"" >&6 else echo "$as_me:$LINENO: result: ok (TEA ${TEA_VERSION})" >&5 echo "${ECHO_T}ok (TEA ${TEA_VERSION})" >&6 fi case "`uname -s`" in *win32*|*WIN32*|*CYGWIN_NT*|*CYGWIN_9*|*CYGWIN_ME*|*MINGW32_*) # Extract the first word of "cygpath", so it can be a program name with args. set dummy cygpath; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CYGPATH+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CYGPATH"; then ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CYGPATH="cygpath -w" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo" fi fi CYGPATH=$ac_cv_prog_CYGPATH if test -n "$CYGPATH"; then echo "$as_me:$LINENO: result: $CYGPATH" >&5 echo "${ECHO_T}$CYGPATH" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi EXEEXT=".exe" TEA_PLATFORM="windows" ;; *) CYGPATH=echo EXEEXT="" TEA_PLATFORM="unix" ;; esac # Check if exec_prefix is set. If not use fall back to prefix. # Note when adjusted, so that TEA_PREFIX can correct for this. # This is needed for recursive configures, since autoconf propagates # $prefix, but not $exec_prefix (doh!). if test x$exec_prefix = xNONE ; then exec_prefix_default=yes exec_prefix=$prefix fi # This package name must be replaced statically for AC_SUBST to work # Substitute STUB_LIB_FILE in case package creates a stub library too. # We AC_SUBST these here to ensure they are subst'ed, # in case the user doesn't call TEA_ADD_... #-------------------------------------------------------------------- # Load the tclConfig.sh file #-------------------------------------------------------------------- # # Ok, lets find the tcl configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tcl # if test x"${no_tcl}" = x ; then # we reset no_tcl in case something fails here no_tcl=true # Check whether --with-tcl or --without-tcl was given. if test "${with_tcl+set}" = set; then withval="$with_tcl" with_tclconfig=${withval} fi; echo "$as_me:$LINENO: checking for Tcl configuration" >&5 echo $ECHO_N "checking for Tcl configuration... $ECHO_C" >&6 if test "${ac_cv_c_tclconfig+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # First check to see if --with-tcl was specified. if test x"${with_tclconfig}" != x ; then case ${with_tclconfig} in */tclConfig.sh ) if test -f ${with_tclconfig}; then { echo "$as_me:$LINENO: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5 echo "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;} with_tclconfig=`echo ${with_tclconfig} | sed 's!/tclConfig\.sh$!!'` fi ;; esac if test -f "${with_tclconfig}/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` else { { echo "$as_me:$LINENO: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&5 echo "$as_me: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&2;} { (exit 1); exit 1; }; } fi fi # check in a few common install locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d ${TCLTK_ROOT}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i; pwd)` break fi done fi # then check for a private Tcl installation if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ../tcl \ `ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \ ../../tcl \ `ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \ ../../../tcl \ `ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ `ls -d /System/Library/Frameworks 2>/dev/null` \ ; do if test -f "$i/Tcl.framework/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi fi if test x"${ac_cv_c_tclconfig}" = x ; then TCL_BIN_DIR="# no Tcl configs found" { echo "$as_me:$LINENO: WARNING: \"Cannot find Tcl configuration definitions\"" >&5 echo "$as_me: WARNING: \"Cannot find Tcl configuration definitions\"" >&2;} exit 0 else no_tcl= TCL_BIN_DIR=${ac_cv_c_tclconfig} echo "$as_me:$LINENO: result: found $TCL_BIN_DIR/tclConfig.sh" >&5 echo "${ECHO_T}found $TCL_BIN_DIR/tclConfig.sh" >&6 fi fi echo "$as_me:$LINENO: checking for existence of $TCL_BIN_DIR/tclConfig.sh" >&5 echo $ECHO_N "checking for existence of $TCL_BIN_DIR/tclConfig.sh... $ECHO_C" >&6 if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then echo "$as_me:$LINENO: result: loading" >&5 echo "${ECHO_T}loading" >&6 . $TCL_BIN_DIR/tclConfig.sh else echo "$as_me:$LINENO: result: file not found" >&5 echo "${ECHO_T}file not found" >&6 fi # # If the TCL_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TCL_LIB_SPEC will be set to the value # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC # instead of TCL_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. # if test -f $TCL_BIN_DIR/Makefile ; then TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC} TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC} TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH} fi # # eval is required to do the TCL_DBGX substitution # eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\"" eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\"" #AC_SUBST(TCL_BUILD_LIB_SPEC) #AC_SUBST(TCL_BUILD_STUB_LIB_SPEC) #-------------------------------------------------------------------- # Load the tkConfig.sh file if necessary (Tk extension) #-------------------------------------------------------------------- # # Ok, lets find the tk configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tk # if test x"${no_tk}" = x ; then # we reset no_tk in case something fails here no_tk=true # Check whether --with-tk or --without-tk was given. if test "${with_tk+set}" = set; then withval="$with_tk" with_tkconfig=${withval} fi; echo "$as_me:$LINENO: checking for Tk configuration" >&5 echo $ECHO_N "checking for Tk configuration... $ECHO_C" >&6 if test "${ac_cv_c_tkconfig+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # First check to see if --with-tkconfig was specified. if test x"${with_tkconfig}" != x ; then case ${with_tkconfig} in */tkConfig.sh ) if test -f ${with_tkconfig}; then { echo "$as_me:$LINENO: WARNING: --with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself" >&5 echo "$as_me: WARNING: --with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself" >&2;} with_tkconfig=`echo ${with_tkconfig} | sed 's!/tkConfig\.sh$!!'` fi ;; esac if test -f "${with_tkconfig}/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)` else { { echo "$as_me:$LINENO: error: ${with_tkconfig} directory doesn't contain tkConfig.sh" >&5 echo "$as_me: error: ${with_tkconfig} directory doesn't contain tkConfig.sh" >&2;} { (exit 1); exit 1; }; } fi fi # check in a few common install locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d ${TCLTK_ROOT}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ ; do if test -f "$i/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i; pwd)` break fi done fi # then check for a private Tk library if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ../tk \ `ls -dr ../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../tk[8-9].[0-9] 2>/dev/null` \ `ls -dr ../tk[8-9].[0-9]* 2>/dev/null` \ ../../tk \ `ls -dr ../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../tk[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../tk[8-9].[0-9]* 2>/dev/null` \ ../../../tk \ `ls -dr ../../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../../tk[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../../tk[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/unix; pwd)` break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ `ls -d /System/Library/Frameworks 2>/dev/null` \ ; do if test -f "$i/Tk.framework/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/Tk.framework; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ${srcdir}/../tk \ `ls -dr ${srcdir}/../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ${srcdir}/../tk[8-9].[0-9] 2>/dev/null` \ `ls -dr ${srcdir}/../tk[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/unix; pwd)` break fi done fi fi if test x"${ac_cv_c_tkconfig}" = x ; then TK_BIN_DIR="# no Tk configs found" { echo "$as_me:$LINENO: WARNING: \"Cannot find Tk configuration definitions\"" >&5 echo "$as_me: WARNING: \"Cannot find Tk configuration definitions\"" >&2;} exit 0 else no_tk= TK_BIN_DIR=${ac_cv_c_tkconfig} echo "$as_me:$LINENO: result: found $TK_BIN_DIR/tkConfig.sh" >&5 echo "${ECHO_T}found $TK_BIN_DIR/tkConfig.sh" >&6 fi fi echo "$as_me:$LINENO: checking for existence of ${TK_BIN_DIR}/tkConfig.sh" >&5 echo $ECHO_N "checking for existence of ${TK_BIN_DIR}/tkConfig.sh... $ECHO_C" >&6 if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then echo "$as_me:$LINENO: result: loading" >&5 echo "${ECHO_T}loading" >&6 . $TK_BIN_DIR/tkConfig.sh else echo "$as_me:$LINENO: result: could not find ${TK_BIN_DIR}/tkConfig.sh" >&5 echo "${ECHO_T}could not find ${TK_BIN_DIR}/tkConfig.sh" >&6 fi # # If the TK_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TK_LIB_SPEC will be set to the value # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC # instead of TK_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. # if test -f $TK_BIN_DIR/Makefile ; then TK_LIB_SPEC=${TK_BUILD_LIB_SPEC} TK_STUB_LIB_SPEC=${TK_BUILD_STUB_LIB_SPEC} TK_STUB_LIB_PATH=${TK_BUILD_STUB_LIB_PATH} fi # Ensure windowingsystem is defined if test "${TEA_PLATFORM}" = "unix" ; then case ${TK_DEFS} in *MAC_OSX_TK*) cat >>confdefs.h <<\_ACEOF #define MAC_OSX_TK 1 _ACEOF TEA_WINDOWINGSYSTEM="aqua" ;; *) TEA_WINDOWINGSYSTEM="x11" ;; esac elif test "${TEA_PLATFORM}" = "windows" ; then TEA_WINDOWINGSYSTEM="win32" fi # # eval is required to do the TK_DBGX substitution # eval "TK_LIB_FILE=\"${TK_LIB_FILE}\"" eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\"" eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\"" eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\"" eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\"" eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\"" #----------------------------------------------------------------------- # Handle the --prefix=... option by defaulting to what Tcl gave. # Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER. #----------------------------------------------------------------------- if test "${prefix}" = "NONE"; then prefix_default=yes if test x"${TCL_PREFIX}" != x; then { echo "$as_me:$LINENO: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&5 echo "$as_me: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&6;} prefix=${TCL_PREFIX} else { echo "$as_me:$LINENO: --prefix defaulting to /usr/local" >&5 echo "$as_me: --prefix defaulting to /usr/local" >&6;} prefix=/usr/local fi fi if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \ -o x"${exec_prefix_default}" = x"yes" ; then #if test x"${TCL_EXEC_PREFIX}" != x; then #AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}]) #exec_prefix=${TCL_EXEC_PREFIX} #else { echo "$as_me:$LINENO: --exec-prefix defaulting to ${prefix}" >&5 echo "$as_me: --exec-prefix defaulting to ${prefix}" >&6;} exec_prefix=$prefix #fi fi #----------------------------------------------------------------------- # Standard compiler checks. # This sets up CC by using the CC env var, or looks for gcc otherwise. # This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create # the basic setup necessary to compile executables. #----------------------------------------------------------------------- ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f $ac_dir/shtool; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} { (exit 1); exit 1; }; } fi ac_config_guess="$SHELL $ac_aux_dir/config.guess" ac_config_sub="$SHELL $ac_aux_dir/config.sub" ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE) # in this macro, they need to go into TEA_SETUP_COMPILER instead. # If the user did not set CFLAGS, set it now to keep # the AC_PROG_CC macro from adding "-g -O2". if test "${CFLAGS+set}" != "set" ; then CFLAGS="" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CC" && break done CC=$ac_ct_CC fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 (eval $ac_link_default) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Find the output, starting from the most likely. This scheme is # not robust to junk in `.', hence go to wildcards (a.*) only as a last # resort. # Be careful to initialize this variable, since it used to be cached. # Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. ac_cv_exeext= # b.out is created by i960 compilers. for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; conftest.$ac_ext ) # This is the source file. ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` # FIXME: I believe we export ac_cv_exeext for Libtool, # but it would be cool to find out if it's true. Does anybody # maintain Libtool? --akim. export ac_cv_exeext break;; * ) break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6 # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6 echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` export ac_cv_exeext break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6 rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6 OBJEXT=$ac_cv_objext ac_objext=$OBJEXT echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS CFLAGS="-g" echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cc_g=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 if test "${ac_cv_prog_cc_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_stdc=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std1 is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std1. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX 10.20 and later -Ae # HP-UX older versions -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_stdc=$ac_arg break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext done rm -f conftest.$ac_ext conftest.$ac_objext CC=$ac_save_CC fi case "x$ac_cv_prog_cc_stdc" in x|xno) echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6 ;; *) echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 CC="$CC $ac_cv_prog_cc_stdc" ;; esac # Some people use a C++ compiler to compile C. Since we use `exit', # in C++ we need to declare it. In case someone uses the same compiler # for both compiling C and C++ we need to have the C++ compiler decide # the declaration of exit, since it's the most demanding environment. cat >conftest.$ac_ext <<_ACEOF #ifndef __cplusplus choke me #endif _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration #include int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_cv_c_compiler_gnu = yes; then GCC=yes fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6 ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=cc ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -n "$ac_tool_prefix"; then for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then echo "$as_me:$LINENO: result: $CXX" >&5 echo "${ECHO_T}$CXX" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 echo "${ECHO_T}$ac_ct_CXX" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CXX" && break done test -n "$ac_ct_CXX" || ac_ct_CXX="g++" CXX=$ac_ct_CXX fi # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C++ compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 if test "${ac_cv_cxx_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 GXX=`test $ac_compiler_gnu = yes && echo yes` ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS CXXFLAGS="-g" echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cxx_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cxx_g=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi for ac_declaration in \ '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration #include int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL=$ac_install_sh fi fi echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' #-------------------------------------------------------------------- # Checks to see if the make program sets the $MAKE variable. #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.make <<\_ACEOF all: @echo 'ac_maketemp="$(MAKE)"' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi rm -f conftest.make fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 SET_MAKE= else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 SET_MAKE="MAKE=${MAKE-make}" fi #-------------------------------------------------------------------- # Find ranlib #-------------------------------------------------------------------- if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then echo "$as_me:$LINENO: result: $RANLIB" >&5 echo "${ECHO_T}$RANLIB" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 echo "${ECHO_T}$ac_ct_RANLIB" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi RANLIB=$ac_ct_RANLIB else RANLIB="$ac_cv_prog_RANLIB" fi #-------------------------------------------------------------------- # Determines the correct binary file extension (.o, .obj, .exe etc.) #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6 if test "${ac_cv_prog_egrep+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | (grep -E '(a|b)') >/dev/null 2>&1 then ac_cv_prog_egrep='grep -E' else ac_cv_prog_egrep='egrep' fi fi echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 echo "${ECHO_T}$ac_cv_prog_egrep" >&6 EGREP=$ac_cv_prog_egrep echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6 if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here. #------------------------------------------------------------------------ # If we're using GCC, see if the compiler understands -pipe. If so, use it. # It makes compiling go faster. (This is only a performance feature.) #------------------------------------------------------------------------ if test -z "$no_pipe" -a -n "$GCC"; then echo "$as_me:$LINENO: checking if the compiler understands -pipe" >&5 echo $ECHO_N "checking if the compiler understands -pipe... $ECHO_C" >&6 OLDCC="$CC" CC="$CC -pipe" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CC="$OLDCC" echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi #-------------------------------------------------------------------- # Pick up flags from the environment (user). #-------------------------------------------------------------------- CC="${CC} $CFLAGS" CXX="${CXX} $CXXFLAGS $CFLAGS" #-------------------------------------------------------------------- # Common compiler flag setup #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6 if test "${ac_cv_c_bigendian+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # See if sys/param.h defines the BYTE_ORDER macro. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN bogus endian macros #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then # It does; now see whether it defined to BIG_ENDIAN or not. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_bigendian=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_bigendian=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # It does not; compile a test program. if test "$cross_compiling" = yes; then # try to guess the endianness by grepping values into an object file ac_cv_c_bigendian=unknown cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } int main () { _ascii (); _ebcdic (); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long l; char c[sizeof (long)]; } u; u.l = 1; exit (u.c[sizeof (long) - 1] == 1); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_bigendian=no else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_c_bigendian=yes fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 echo "${ECHO_T}$ac_cv_c_bigendian" >&6 case $ac_cv_c_bigendian in yes) cat >>confdefs.h <<\_ACEOF #define WORDS_BIGENDIAN 1 _ACEOF ;; no) ;; *) { { echo "$as_me:$LINENO: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&5 echo "$as_me: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} { (exit 1); exit 1; }; } ;; esac if test "${TEA_PLATFORM}" = "unix" ; then #-------------------------------------------------------------------- # On a few very rare systems, all of the libm.a stuff is # already in libc.a. Set compiler flags accordingly. # Also, Linux requires the "ieee" library for math to work # right (and it must appear before "-lm"). #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking for sin" >&5 echo $ECHO_N "checking for sin... $ECHO_C" >&6 if test "${ac_cv_func_sin+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define sin to an innocuous variant, in case declares sin. For example, HP-UX 11i declares gettimeofday. */ #define sin innocuous_sin /* System header to define __stub macros and hopefully few prototypes, which can conflict with char sin (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef sin /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char sin (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_sin) || defined (__stub___sin) choke me #else char (*f) () = sin; #endif #ifdef __cplusplus } #endif int main () { return f != sin; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_sin=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_sin=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_sin" >&5 echo "${ECHO_T}$ac_cv_func_sin" >&6 if test $ac_cv_func_sin = yes; then MATH_LIBS="" else MATH_LIBS="-lm" fi echo "$as_me:$LINENO: checking for main in -lieee" >&5 echo $ECHO_N "checking for main in -lieee... $ECHO_C" >&6 if test "${ac_cv_lib_ieee_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lieee $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_ieee_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ieee_main=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_ieee_main" >&5 echo "${ECHO_T}$ac_cv_lib_ieee_main" >&6 if test $ac_cv_lib_ieee_main = yes; then MATH_LIBS="-lieee $MATH_LIBS" fi #-------------------------------------------------------------------- # Interactive UNIX requires -linet instead of -lsocket, plus it # needs net/errno.h to define the socket-related error codes. #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking for main in -linet" >&5 echo $ECHO_N "checking for main in -linet... $ECHO_C" >&6 if test "${ac_cv_lib_inet_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-linet $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_inet_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_inet_main=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_inet_main" >&5 echo "${ECHO_T}$ac_cv_lib_inet_main" >&6 if test $ac_cv_lib_inet_main = yes; then LIBS="$LIBS -linet" fi if test "${ac_cv_header_net_errno_h+set}" = set; then echo "$as_me:$LINENO: checking for net/errno.h" >&5 echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6 if test "${ac_cv_header_net_errno_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5 echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking net/errno.h usability" >&5 echo $ECHO_N "checking net/errno.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking net/errno.h presence" >&5 echo $ECHO_N "checking net/errno.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: net/errno.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: net/errno.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: net/errno.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: net/errno.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: net/errno.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: net/errno.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: net/errno.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: net/errno.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ---------------------------------- ## ## Report this to the tclutil lists. ## ## ---------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for net/errno.h" >&5 echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6 if test "${ac_cv_header_net_errno_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_net_errno_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5 echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6 fi if test $ac_cv_header_net_errno_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_NET_ERRNO_H 1 _ACEOF fi #-------------------------------------------------------------------- # Check for the existence of the -lsocket and -lnsl libraries. # The order here is important, so that they end up in the right # order in the command line generated by make. Here are some # special considerations: # 1. Use "connect" and "accept" to check for -lsocket, and # "gethostbyname" to check for -lnsl. # 2. Use each function name only once: can't redo a check because # autoconf caches the results of the last check and won't redo it. # 3. Use -lnsl and -lsocket only if they supply procedures that # aren't already present in the normal libraries. This is because # IRIX 5.2 has libraries, but they aren't needed and they're # bogus: they goof up name resolution if used. # 4. On some SVR4 systems, can't use -lsocket without -lnsl too. # To get around this problem, check for both libraries together # if -lsocket doesn't work by itself. #-------------------------------------------------------------------- tcl_checkBoth=0 echo "$as_me:$LINENO: checking for connect" >&5 echo $ECHO_N "checking for connect... $ECHO_C" >&6 if test "${ac_cv_func_connect+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define connect to an innocuous variant, in case declares connect. For example, HP-UX 11i declares gettimeofday. */ #define connect innocuous_connect /* System header to define __stub macros and hopefully few prototypes, which can conflict with char connect (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef connect /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char connect (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_connect) || defined (__stub___connect) choke me #else char (*f) () = connect; #endif #ifdef __cplusplus } #endif int main () { return f != connect; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_connect=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_connect=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5 echo "${ECHO_T}$ac_cv_func_connect" >&6 if test $ac_cv_func_connect = yes; then tcl_checkSocket=0 else tcl_checkSocket=1 fi if test "$tcl_checkSocket" = 1; then echo "$as_me:$LINENO: checking for setsockopt" >&5 echo $ECHO_N "checking for setsockopt... $ECHO_C" >&6 if test "${ac_cv_func_setsockopt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define setsockopt to an innocuous variant, in case declares setsockopt. For example, HP-UX 11i declares gettimeofday. */ #define setsockopt innocuous_setsockopt /* System header to define __stub macros and hopefully few prototypes, which can conflict with char setsockopt (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef setsockopt /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char setsockopt (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_setsockopt) || defined (__stub___setsockopt) choke me #else char (*f) () = setsockopt; #endif #ifdef __cplusplus } #endif int main () { return f != setsockopt; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_setsockopt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_setsockopt=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_setsockopt" >&5 echo "${ECHO_T}$ac_cv_func_setsockopt" >&6 if test $ac_cv_func_setsockopt = yes; then : else echo "$as_me:$LINENO: checking for setsockopt in -lsocket" >&5 echo $ECHO_N "checking for setsockopt in -lsocket... $ECHO_C" >&6 if test "${ac_cv_lib_socket_setsockopt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char setsockopt (); int main () { setsockopt (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_socket_setsockopt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_socket_setsockopt=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_socket_setsockopt" >&5 echo "${ECHO_T}$ac_cv_lib_socket_setsockopt" >&6 if test $ac_cv_lib_socket_setsockopt = yes; then LIBS="$LIBS -lsocket" else tcl_checkBoth=1 fi fi fi if test "$tcl_checkBoth" = 1; then tk_oldLibs=$LIBS LIBS="$LIBS -lsocket -lnsl" echo "$as_me:$LINENO: checking for accept" >&5 echo $ECHO_N "checking for accept... $ECHO_C" >&6 if test "${ac_cv_func_accept+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define accept to an innocuous variant, in case declares accept. For example, HP-UX 11i declares gettimeofday. */ #define accept innocuous_accept /* System header to define __stub macros and hopefully few prototypes, which can conflict with char accept (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef accept /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char accept (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_accept) || defined (__stub___accept) choke me #else char (*f) () = accept; #endif #ifdef __cplusplus } #endif int main () { return f != accept; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_accept=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_accept=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_accept" >&5 echo "${ECHO_T}$ac_cv_func_accept" >&6 if test $ac_cv_func_accept = yes; then tcl_checkNsl=0 else LIBS=$tk_oldLibs fi fi echo "$as_me:$LINENO: checking for gethostbyname" >&5 echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6 if test "${ac_cv_func_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define gethostbyname to an innocuous variant, in case declares gethostbyname. For example, HP-UX 11i declares gettimeofday. */ #define gethostbyname innocuous_gethostbyname /* System header to define __stub macros and hopefully few prototypes, which can conflict with char gethostbyname (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef gethostbyname /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostbyname (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) choke me #else char (*f) () = gethostbyname; #endif #ifdef __cplusplus } #endif int main () { return f != gethostbyname; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_gethostbyname=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_gethostbyname=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6 if test $ac_cv_func_gethostbyname = yes; then : else echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5 echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6 if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostbyname (); int main () { gethostbyname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_nsl_gethostbyname=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_nsl_gethostbyname=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6 if test $ac_cv_lib_nsl_gethostbyname = yes; then LIBS="$LIBS -lnsl" fi fi # Don't perform the eval of the libraries here because DL_LIBS # won't be set until we call TEA_CONFIG_CFLAGS TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}' echo "$as_me:$LINENO: checking dirent.h" >&5 echo $ECHO_N "checking dirent.h... $ECHO_C" >&6 if test "${tcl_cv_dirent_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #ifndef _POSIX_SOURCE # ifdef __Lynx__ /* * Generate compilation error to make the test fail: Lynx headers * are only valid if really in the POSIX environment. */ missing_procedure(); # endif #endif DIR *d; struct dirent *entryPtr; char *p; d = opendir("foobar"); entryPtr = readdir(d); p = entryPtr->d_name; closedir(d); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_dirent_h=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_dirent_h=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi if test $tcl_cv_dirent_h = no; then cat >>confdefs.h <<\_ACEOF #define NO_DIRENT_H 1 _ACEOF fi echo "$as_me:$LINENO: result: $tcl_ok" >&5 echo "${ECHO_T}$tcl_ok" >&6 if test "${ac_cv_header_errno_h+set}" = set; then echo "$as_me:$LINENO: checking for errno.h" >&5 echo $ECHO_N "checking for errno.h... $ECHO_C" >&6 if test "${ac_cv_header_errno_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5 echo "${ECHO_T}$ac_cv_header_errno_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking errno.h usability" >&5 echo $ECHO_N "checking errno.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking errno.h presence" >&5 echo $ECHO_N "checking errno.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: errno.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: errno.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: errno.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: errno.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: errno.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: errno.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: errno.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: errno.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ---------------------------------- ## ## Report this to the tclutil lists. ## ## ---------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for errno.h" >&5 echo $ECHO_N "checking for errno.h... $ECHO_C" >&6 if test "${ac_cv_header_errno_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_errno_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5 echo "${ECHO_T}$ac_cv_header_errno_h" >&6 fi if test $ac_cv_header_errno_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_ERRNO_H 1 _ACEOF fi if test "${ac_cv_header_float_h+set}" = set; then echo "$as_me:$LINENO: checking for float.h" >&5 echo $ECHO_N "checking for float.h... $ECHO_C" >&6 if test "${ac_cv_header_float_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5 echo "${ECHO_T}$ac_cv_header_float_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking float.h usability" >&5 echo $ECHO_N "checking float.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking float.h presence" >&5 echo $ECHO_N "checking float.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: float.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: float.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: float.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: float.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: float.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: float.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: float.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: float.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ---------------------------------- ## ## Report this to the tclutil lists. ## ## ---------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for float.h" >&5 echo $ECHO_N "checking for float.h... $ECHO_C" >&6 if test "${ac_cv_header_float_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_float_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5 echo "${ECHO_T}$ac_cv_header_float_h" >&6 fi if test $ac_cv_header_float_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_FLOAT_H 1 _ACEOF fi if test "${ac_cv_header_values_h+set}" = set; then echo "$as_me:$LINENO: checking for values.h" >&5 echo $ECHO_N "checking for values.h... $ECHO_C" >&6 if test "${ac_cv_header_values_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5 echo "${ECHO_T}$ac_cv_header_values_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking values.h usability" >&5 echo $ECHO_N "checking values.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking values.h presence" >&5 echo $ECHO_N "checking values.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: values.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: values.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: values.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: values.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: values.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: values.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: values.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: values.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ---------------------------------- ## ## Report this to the tclutil lists. ## ## ---------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for values.h" >&5 echo $ECHO_N "checking for values.h... $ECHO_C" >&6 if test "${ac_cv_header_values_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_values_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5 echo "${ECHO_T}$ac_cv_header_values_h" >&6 fi if test $ac_cv_header_values_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_VALUES_H 1 _ACEOF fi if test "${ac_cv_header_limits_h+set}" = set; then echo "$as_me:$LINENO: checking for limits.h" >&5 echo $ECHO_N "checking for limits.h... $ECHO_C" >&6 if test "${ac_cv_header_limits_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5 echo "${ECHO_T}$ac_cv_header_limits_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking limits.h usability" >&5 echo $ECHO_N "checking limits.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking limits.h presence" >&5 echo $ECHO_N "checking limits.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: limits.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: limits.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: limits.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: limits.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: limits.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: limits.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: limits.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: limits.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ---------------------------------- ## ## Report this to the tclutil lists. ## ## ---------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for limits.h" >&5 echo $ECHO_N "checking for limits.h... $ECHO_C" >&6 if test "${ac_cv_header_limits_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_limits_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5 echo "${ECHO_T}$ac_cv_header_limits_h" >&6 fi if test $ac_cv_header_limits_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIMITS_H 1 _ACEOF else cat >>confdefs.h <<\_ACEOF #define NO_LIMITS_H 1 _ACEOF fi if test "${ac_cv_header_stdlib_h+set}" = set; then echo "$as_me:$LINENO: checking for stdlib.h" >&5 echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6 if test "${ac_cv_header_stdlib_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5 echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking stdlib.h usability" >&5 echo $ECHO_N "checking stdlib.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking stdlib.h presence" >&5 echo $ECHO_N "checking stdlib.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: stdlib.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: stdlib.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: stdlib.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: stdlib.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: stdlib.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: stdlib.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: stdlib.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: stdlib.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ---------------------------------- ## ## Report this to the tclutil lists. ## ## ---------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for stdlib.h" >&5 echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6 if test "${ac_cv_header_stdlib_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_stdlib_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5 echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6 fi if test $ac_cv_header_stdlib_h = yes; then tcl_ok=1 else tcl_ok=0 fi cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strtol" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strtoul" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strtod" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* if test $tcl_ok = 0; then cat >>confdefs.h <<\_ACEOF #define NO_STDLIB_H 1 _ACEOF fi if test "${ac_cv_header_string_h+set}" = set; then echo "$as_me:$LINENO: checking for string.h" >&5 echo $ECHO_N "checking for string.h... $ECHO_C" >&6 if test "${ac_cv_header_string_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5 echo "${ECHO_T}$ac_cv_header_string_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking string.h usability" >&5 echo $ECHO_N "checking string.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking string.h presence" >&5 echo $ECHO_N "checking string.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: string.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: string.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: string.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: string.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: string.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: string.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: string.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: string.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ---------------------------------- ## ## Report this to the tclutil lists. ## ## ---------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for string.h" >&5 echo $ECHO_N "checking for string.h... $ECHO_C" >&6 if test "${ac_cv_header_string_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_string_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5 echo "${ECHO_T}$ac_cv_header_string_h" >&6 fi if test $ac_cv_header_string_h = yes; then tcl_ok=1 else tcl_ok=0 fi cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strstr" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strerror" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* # See also memmove check below for a place where NO_STRING_H can be # set and why. if test $tcl_ok = 0; then cat >>confdefs.h <<\_ACEOF #define NO_STRING_H 1 _ACEOF fi if test "${ac_cv_header_sys_wait_h+set}" = set; then echo "$as_me:$LINENO: checking for sys/wait.h" >&5 echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6 if test "${ac_cv_header_sys_wait_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking sys/wait.h usability" >&5 echo $ECHO_N "checking sys/wait.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking sys/wait.h presence" >&5 echo $ECHO_N "checking sys/wait.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: sys/wait.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: sys/wait.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: sys/wait.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: sys/wait.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: sys/wait.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: sys/wait.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ---------------------------------- ## ## Report this to the tclutil lists. ## ## ---------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for sys/wait.h" >&5 echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6 if test "${ac_cv_header_sys_wait_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_sys_wait_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 fi if test $ac_cv_header_sys_wait_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_SYS_WAIT_H 1 _ACEOF fi if test "${ac_cv_header_dlfcn_h+set}" = set; then echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking dlfcn.h usability" >&5 echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking dlfcn.h presence" >&5 echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: dlfcn.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ---------------------------------- ## ## Report this to the tclutil lists. ## ## ---------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_dlfcn_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 fi if test $ac_cv_header_dlfcn_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_DLFCN_H 1 _ACEOF fi # OS/390 lacks sys/param.h (and doesn't need it, by chance). for ac_header in sys/param.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ---------------------------------- ## ## Report this to the tclutil lists. ## ## ---------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Let the user call this, because if it triggers, they will # need a compat/strtod.c that is correct. Users can also # use Tcl_GetDouble(FromObj) instead. #TEA_BUGGY_STRTOD fi #----------------------------------------------------------------------- # Do application specific checks (see aclocal.m4), after compiler setup. #----------------------------------------------------------------------- #------------------------------------------------------------------------ # TCLUTIL_PATH_BLT -- # # Locate the BLT library # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-blt=... # # Defines the following vars: # BLT_LIB_SPEC String to add to link the BLT lib (-L... -lBLT) # BLT_LIB_DIR Directory containing libBLT24.so #------------------------------------------------------------------------ # ----------------------------------------------------------------------- cat >>confdefs.h <<\_ACEOF #define USE_COMPAT_CONST 1 _ACEOF # ----------------------------------------------------------------------- echo "$as_me:$LINENO: checking sysv shared memory prototypes" >&5 echo $ECHO_N "checking sysv shared memory prototypes... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "int.*shmdt.*\(" >/dev/null 2>&1; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; cat >>confdefs.h <<\_ACEOF #define NEED_SHM_PROTO 1 _ACEOF fi rm -f conftest* # ----------------------------------------------------------------------- echo "$as_me:$LINENO: checking gethostname prototype" >&5 echo $ECHO_N "checking gethostname prototype... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "int.*gethostname.*\(" >/dev/null 2>&1; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; cat >>confdefs.h <<\_ACEOF #define NEED_GETHOSTNAME_PROTO 1 _ACEOF fi rm -f conftest* # ----------------------------------------------------------------------- echo "$as_me:$LINENO: checking for long" >&5 echo $ECHO_N "checking for long... $ECHO_C" >&6 if test "${ac_cv_type_long+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((long *) 0) return 0; if (sizeof (long)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_long=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_long=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5 echo "${ECHO_T}$ac_cv_type_long" >&6 echo "$as_me:$LINENO: checking size of long" >&5 echo $ECHO_N "checking size of long... $ECHO_C" >&6 if test "${ac_cv_sizeof_long+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$ac_cv_type_long" = yes; then # The cast to unsigned long works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(((long) (sizeof (long))) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_lo=0 ac_mid=0 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr $ac_mid + 1` if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid + 1` fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(((long) (sizeof (long))) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=-1 ac_mid=-1 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(((long) (sizeof (long))) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_lo=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_hi=`expr '(' $ac_mid ')' - 1` if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid` fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo= ac_hi= fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=$ac_mid else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr '(' $ac_mid ')' + 1` fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in ?*) ac_cv_sizeof_long=$ac_lo;; '') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77 See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (long), 77 See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } ;; esac else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling See \`config.log' for more details." >&5 echo "$as_me: error: cannot run test program while cross compiling See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default long longval () { return (long) (sizeof (long)); } unsigned long ulongval () { return (long) (sizeof (long)); } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) exit (1); if (((long) (sizeof (long))) < 0) { long i = longval (); if (i != ((long) (sizeof (long)))) exit (1); fprintf (f, "%ld\n", i); } else { unsigned long i = ulongval (); if (i != ((long) (sizeof (long)))) exit (1); fprintf (f, "%lu\n", i); } exit (ferror (f) || fclose (f) != 0); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_long=`cat conftest.val` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77 See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (long), 77 See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi rm -f conftest.val else ac_cv_sizeof_long=0 fi fi echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5 echo "${ECHO_T}$ac_cv_sizeof_long" >&6 cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG $ac_cv_sizeof_long _ACEOF # ------------------------------------------------------------------------- # there are some idiosyncrasies with semun defs (used in semxxx). Solaris # does not define it at all # ------------------------------------------------------------------------- echo "$as_me:$LINENO: checking \"do we have union semun defined\"" >&5 echo $ECHO_N "checking \"do we have union semun defined\"... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { union semun filler; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cat >>confdefs.h <<\_ACEOF #define HAVE_UNION_SEMUN 1 _ACEOF echo "$as_me:$LINENO: result: \"yes\"" >&5 echo "${ECHO_T}\"yes\"" >&6 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 echo "$as_me:$LINENO: result: \"no\"" >&5 echo "${ECHO_T}\"no\"" >&6 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >>confdefs.h <<\_ACEOF #define HAVE_NET_SERVICES 1 _ACEOF # ----------------------------------------------------------------------- echo "$as_me:$LINENO: checking mmap prototypes" >&5 echo $ECHO_N "checking mmap prototypes... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "int.*munmap.*\(" >/dev/null 2>&1; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; cat >>confdefs.h <<\_ACEOF #define NEED_MMAP_PROTO 1 _ACEOF fi rm -f conftest* # ----------------------------------------------------------------------- for ac_header in sys/filio.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ---------------------------------- ## ## Report this to the tclutil lists. ## ## ---------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in sys/statvfs.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ---------------------------------- ## ## Report this to the tclutil lists. ## ## ---------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # ----------------------------------------------------------------------- # Check if we need (or can use) the socklen_t type. # ----------------------------------------------------------------------- echo "$as_me:$LINENO: checking for socklen_t" >&5 echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6 if test "${ac_cv_type_socklen_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { if ((socklen_t *) 0) return 0; if (sizeof (socklen_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_socklen_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_socklen_t=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_socklen_t" >&5 echo "${ECHO_T}$ac_cv_type_socklen_t" >&6 if test $ac_cv_type_socklen_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_SOCKLEN_T 1 _ACEOF fi #------------------------------------------------------------------------ #AC_LANG(C++) echo "$as_me:$LINENO: checking fd_set" >&5 echo $ECHO_N "checking fd_set... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { fd_set readFds; select(32, &readFds, 0, 0, 0); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then test_ok=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 test_ok=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext if test $test_ok = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_SELECT_FD_SET 1 _ACEOF fi echo "$as_me:$LINENO: result: $test_ok" >&5 echo "${ECHO_T}$test_ok" >&6 #------------------------------------------------------------------------ # Check if we require additional libraries to support C++ shareable # libraries. system=`uname -s`-`uname -r` SHLIB_LD_CXX_LIBS="" export SHLIB_LD_CXX_LIBS case $system in SunOS-5*) SHLIB_LD_CXX_LIBS="-lCrun -lCstd" ;; OSF*) SHLIB_LD_CXX_LIBS="-lcxx -lcxxstd" ;; esac #------------------------------------------------------------------------- # The cxx C++ compiler under Tru64 UNIX needs the special # CXXFLAGS "-std gnu -D__USE_STD_IOSTREAM=1". These allow the standard # library streams headers to work and to generate templates that do # not require special handling throughout skycat directories (normally # template object files are created in various cxx_repository subdirectories, # this way the object files are kept embedded the usual object files, see # the cxx man page for details). #------------------------------------------------------------------------- export CXXFLAGS case $system in OSF*) case "x$CXX" in xcxx*) CXXFLAGS="$CXXFLAGS -g3 -std gnu -D__USE_STD_IOSTREAM=1" ;; esac ;; esac #----------------------------------------------------------------------- # __CHANGE__ # Specify the C source files to compile in TEA_ADD_SOURCES, # public headers that need to be installed in TEA_ADD_HEADERS, # stub library C source files to compile in TEA_ADD_STUB_SOURCES, # and runtime Tcl library files in TEA_ADD_TCL_SOURCES. # This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS # and PKG_TCL_SOURCES. #----------------------------------------------------------------------- csources=`cd $srcdir; echo generic/*.[Cc]` cheaders=`cd $srcdir; echo generic/*.h` cincludes="-I. -I$srcdir/bitmaps -I$srcdir/generic" tclsources=`cd $srcdir; echo library/*.tcl` vars="${csources}" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done vars="${cheaders}" for i in $vars; do # check for existence, be strict because it is installed if test ! -f "${srcdir}/$i" ; then { { echo "$as_me:$LINENO: error: could not find header file '${srcdir}/$i'" >&5 echo "$as_me: error: could not find header file '${srcdir}/$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_HEADERS="$PKG_HEADERS $i" done vars="$cincludes" for i in $vars; do PKG_INCLUDES="$PKG_INCLUDES $i" done PKG_CFLAGS="$PKG_CFLAGS " vars="" for i in $vars; do # check for existence - allows for generic/win/unix VPATH if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find stub source file '$i'" >&5 echo "$as_me: error: could not find stub source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j" done vars="${tclsources}" for i in $vars; do # check for existence, be strict because it is installed if test ! -f "${srcdir}/$i" ; then { { echo "$as_me:$LINENO: error: could not find tcl source file '${srcdir}/$i'" >&5 echo "$as_me: error: could not find tcl source file '${srcdir}/$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i" done #-------------------------------------------------------------------- # __CHANGE__ # A few miscellaneous platform-specific items: # # Define a special symbol for Windows (BUILD_sample in this case) so # that we create the export library with the dll. # # Windows creates a few extra files that need to be cleaned up. # You can add more files to clean if your extension creates any extra # files. # # TEA_ADD_* any platform specific compiler/build info here. #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" ; then cat >>confdefs.h <<\_ACEOF #define BUILD_tclutil 1 _ACEOF CLEANFILES="*.lib *.dll *.exp *.ilk *.pdb vc*.pch" #TEA_ADD_SOURCES([win/winFile.c]) #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"]) else CLEANFILES="" #TEA_ADD_SOURCES([unix/unixFile.c]) #TEA_ADD_LIBS([-lsuperfly]) fi #-------------------------------------------------------------------- # __CHANGE__ # Choose which headers you need. Extension authors should try very # hard to only rely on the Tcl public header files. Internal headers # contain private data structures and are subject to change without # notice. # This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking for Tcl public headers" >&5 echo $ECHO_N "checking for Tcl public headers... $ECHO_C" >&6 # Check whether --with-tclinclude or --without-tclinclude was given. if test "${with_tclinclude+set}" = set; then withval="$with_tclinclude" with_tclinclude=${withval} fi; if test "${ac_cv_c_tclh+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Use the value from --with-tclinclude, if it was given if test x"${with_tclinclude}" != x ; then if test -f "${with_tclinclude}/tcl.h" ; then ac_cv_c_tclh=${with_tclinclude} else { { echo "$as_me:$LINENO: error: ${with_tclinclude} directory does not contain tcl.h" >&5 echo "$as_me: error: ${with_tclinclude} directory does not contain tcl.h" >&2;} { (exit 1); exit 1; }; } fi else # If Tcl was built as a framework, attempt to use # the framework's Headers directory case ${TCL_DEFS} in *TCL_FRAMEWORK*) list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`" ;; *) list="" ;; esac # Look in the source dir only if Tcl is not installed, # and in that situation, look there before installed locations. if test -f "$TCL_BIN_DIR/Makefile" ; then list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`" fi # Check order: pkg --prefix location, Tcl's --prefix location, # relative to directory of tclConfig.sh. eval "temp_includedir=${includedir}" list="$list \ `ls -d ${temp_includedir} 2>/dev/null` \ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then list="$list /usr/local/include /usr/include" if test x"${TCL_INCLUDE_SPEC}" != x ; then d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'` list="$list `ls -d ${d} 2>/dev/null`" fi fi for i in $list ; do if test -f "$i/tcl.h" ; then ac_cv_c_tclh=$i break fi done fi fi # Print a message based on how we determined the include path if test x"${ac_cv_c_tclh}" = x ; then { { echo "$as_me:$LINENO: error: tcl.h not found. Please specify its location with --with-tclinclude" >&5 echo "$as_me: error: tcl.h not found. Please specify its location with --with-tclinclude" >&2;} { (exit 1); exit 1; }; } else echo "$as_me:$LINENO: result: ${ac_cv_c_tclh}" >&5 echo "${ECHO_T}${ac_cv_c_tclh}" >&6 fi # Convert to a native path and substitute into the output files. INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}` TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" #TEA_PRIVATE_TCL_HEADERS echo "$as_me:$LINENO: checking for Tk public headers" >&5 echo $ECHO_N "checking for Tk public headers... $ECHO_C" >&6 # Check whether --with-tkinclude or --without-tkinclude was given. if test "${with_tkinclude+set}" = set; then withval="$with_tkinclude" with_tkinclude=${withval} fi; if test "${ac_cv_c_tkh+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Use the value from --with-tkinclude, if it was given if test x"${with_tkinclude}" != x ; then if test -f "${with_tkinclude}/tk.h" ; then ac_cv_c_tkh=${with_tkinclude} else { { echo "$as_me:$LINENO: error: ${with_tkinclude} directory does not contain tk.h" >&5 echo "$as_me: error: ${with_tkinclude} directory does not contain tk.h" >&2;} { (exit 1); exit 1; }; } fi else # If Tk was built as a framework, attempt to use # the framework's Headers directory. case ${TK_DEFS} in *TK_FRAMEWORK*) list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`" ;; *) list="" ;; esac # Look in the source dir only if Tk is not installed, # and in that situation, look there before installed locations. if test -f "$TK_BIN_DIR/Makefile" ; then list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`" fi # Check order: pkg --prefix location, Tk's --prefix location, # relative to directory of tkConfig.sh, Tcl's --prefix location, # relative to directory of tclConfig.sh. eval "temp_includedir=${includedir}" list="$list \ `ls -d ${temp_includedir} 2>/dev/null` \ `ls -d ${TK_PREFIX}/include 2>/dev/null` \ `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then list="$list /usr/local/include /usr/include" fi for i in $list ; do if test -f "$i/tk.h" ; then ac_cv_c_tkh=$i break fi done fi fi # Print a message based on how we determined the include path if test x"${ac_cv_c_tkh}" = x ; then { { echo "$as_me:$LINENO: error: tk.h not found. Please specify its location with --with-tkinclude" >&5 echo "$as_me: error: tk.h not found. Please specify its location with --with-tkinclude" >&2;} { (exit 1); exit 1; }; } else echo "$as_me:$LINENO: result: ${ac_cv_c_tkh}" >&5 echo "${ECHO_T}${ac_cv_c_tkh}" >&6 fi # Convert to a native path and substitute into the output files. INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}` TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" if test "${TEA_WINDOWINGSYSTEM}" = "win32" \ -o "${TEA_WINDOWINGSYSTEM}" = "aqua"; then # On Windows and Aqua, we need the X compat headers echo "$as_me:$LINENO: checking for X11 header files" >&5 echo $ECHO_N "checking for X11 header files... $ECHO_C" >&6 if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`" TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" fi echo "$as_me:$LINENO: result: ${INCLUDE_DIR_NATIVE}" >&5 echo "${ECHO_T}${INCLUDE_DIR_NATIVE}" >&6 fi #TEA_PRIVATE_TK_HEADERS if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then echo "$as_me:$LINENO: checking for X" >&5 echo $ECHO_N "checking for X... $ECHO_C" >&6 # Check whether --with-x or --without-x was given. if test "${with_x+set}" = set; then withval="$with_x" fi; # $have_x is `yes', `no', `disabled', or empty when we do not yet know. if test "x$with_x" = xno; then # The user explicitly disabled X. have_x=disabled else if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then # Both variables are already set. have_x=yes else if test "${ac_cv_have_x+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # One or both of the vars are not set, and there is no cached value. ac_x_includes=no ac_x_libraries=no rm -fr conftest.dir if mkdir conftest.dir; then cd conftest.dir # Make sure to not put "make" in the Imakefile rules, since we grep it out. cat >Imakefile <<'_ACEOF' acfindx: @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"' _ACEOF if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} acfindx 2>/dev/null | grep -v make` # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. for ac_extension in a so sl dylib la dll; do if test ! -f $ac_im_usrlibdir/libX11.$ac_extension && test -f $ac_im_libdir/libX11.$ac_extension; then ac_im_usrlibdir=$ac_im_libdir; break fi done # Screen out bogus values from the imake configuration. They are # bogus both because they are the default anyway, and because # using them would break gcc on systems where it needs fixed includes. case $ac_im_incroot in /usr/include) ;; *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; esac case $ac_im_usrlibdir in /usr/lib | /lib) ;; *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; esac fi cd .. rm -fr conftest.dir fi # Standard set of common directories for X headers. # Check X11 before X11Rn because it is often a symlink to the current release. ac_x_header_dirs=' /usr/X11/include /usr/X11R6/include /usr/X11R5/include /usr/X11R4/include /usr/include/X11 /usr/include/X11R6 /usr/include/X11R5 /usr/include/X11R4 /usr/local/X11/include /usr/local/X11R6/include /usr/local/X11R5/include /usr/local/X11R4/include /usr/local/include/X11 /usr/local/include/X11R6 /usr/local/include/X11R5 /usr/local/include/X11R4 /usr/X386/include /usr/x386/include /usr/XFree86/include/X11 /usr/include /usr/local/include /usr/unsupported/include /usr/athena/include /usr/local/x11r5/include /usr/lpp/Xamples/include /usr/openwin/include /usr/openwin/share/include' if test "$ac_x_includes" = no; then # Guess where to find include files, by looking for Intrinsic.h. # First, try using that file with no special directory specified. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # We can compile using X headers with no special include directory. ac_x_includes= else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 for ac_dir in $ac_x_header_dirs; do if test -r "$ac_dir/X11/Intrinsic.h"; then ac_x_includes=$ac_dir break fi done fi rm -f conftest.err conftest.$ac_ext fi # $ac_x_includes = no if test "$ac_x_libraries" = no; then # Check for the libraries. # See if we find them without any special options. # Don't add to $LIBS permanently. ac_save_LIBS=$LIBS LIBS="-lXt $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { XtMalloc (0) ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then LIBS=$ac_save_LIBS # We can link X programs with no special library path. ac_x_libraries= else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 LIBS=$ac_save_LIBS for ac_dir in `echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` do # Don't even attempt the hair of trying to link an X program! for ac_extension in a so sl dylib la dll; do if test -r $ac_dir/libXt.$ac_extension; then ac_x_libraries=$ac_dir break 2 fi done done fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi # $ac_x_libraries = no if test "$ac_x_includes" = no || test "$ac_x_libraries" = no; then # Didn't find X anywhere. Cache the known absence of X. ac_cv_have_x="have_x=no" else # Record where we found X for the cache. ac_cv_have_x="have_x=yes \ ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries" fi fi fi eval "$ac_cv_have_x" fi # $with_x != no if test "$have_x" != yes; then echo "$as_me:$LINENO: result: $have_x" >&5 echo "${ECHO_T}$have_x" >&6 no_x=yes else # If each of the values was on the command line, it overrides each guess. test "x$x_includes" = xNONE && x_includes=$ac_x_includes test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries # Update the cache value to reflect the command line values. ac_cv_have_x="have_x=yes \ ac_x_includes=$x_includes ac_x_libraries=$x_libraries" echo "$as_me:$LINENO: result: libraries $x_libraries, headers $x_includes" >&5 echo "${ECHO_T}libraries $x_libraries, headers $x_includes" >&6 fi not_really_there="" if test "$no_x" = ""; then if test "$x_includes" = ""; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 not_really_there="yes" fi rm -f conftest.err conftest.$ac_ext else if test ! -r $x_includes/X11/Intrinsic.h; then not_really_there="yes" fi fi fi if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then echo "$as_me:$LINENO: checking for X11 header files" >&5 echo $ECHO_N "checking for X11 header files... $ECHO_C" >&6 XINCLUDES="# no special path needed" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 XINCLUDES="nope" fi rm -f conftest.err conftest.$ac_ext if test "$XINCLUDES" = nope; then dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include" for i in $dirs ; do if test -r $i/X11/Intrinsic.h; then echo "$as_me:$LINENO: result: $i" >&5 echo "${ECHO_T}$i" >&6 XINCLUDES=" -I$i" break fi done fi else if test "$x_includes" != ""; then XINCLUDES=-I$x_includes else XINCLUDES="# no special path needed" fi fi if test "$XINCLUDES" = nope; then echo "$as_me:$LINENO: result: could not find any!" >&5 echo "${ECHO_T}could not find any!" >&6 XINCLUDES="# no include files found" fi if test "$no_x" = yes; then echo "$as_me:$LINENO: checking for X11 libraries" >&5 echo $ECHO_N "checking for X11 libraries... $ECHO_C" >&6 XLIBSW=nope dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib" for i in $dirs ; do if test -r $i/libX11.dylib -o -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl; then echo "$as_me:$LINENO: result: $i" >&5 echo "${ECHO_T}$i" >&6 XLIBSW="-L$i -lX11" x_libraries="$i" break fi done else if test "$x_libraries" = ""; then XLIBSW=-lX11 else XLIBSW="-L$x_libraries -lX11" fi fi if test "$XLIBSW" = nope ; then echo "$as_me:$LINENO: checking for XCreateWindow in -lXwindow" >&5 echo $ECHO_N "checking for XCreateWindow in -lXwindow... $ECHO_C" >&6 if test "${ac_cv_lib_Xwindow_XCreateWindow+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXwindow $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char XCreateWindow (); int main () { XCreateWindow (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_Xwindow_XCreateWindow=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_Xwindow_XCreateWindow=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_Xwindow_XCreateWindow" >&5 echo "${ECHO_T}$ac_cv_lib_Xwindow_XCreateWindow" >&6 if test $ac_cv_lib_Xwindow_XCreateWindow = yes; then XLIBSW=-lXwindow fi fi if test "$XLIBSW" = nope ; then echo "$as_me:$LINENO: result: could not find any! Using -lX11." >&5 echo "${ECHO_T}could not find any! Using -lX11." >&6 XLIBSW=-lX11 fi if test x"${XLIBSW}" != x ; then PKG_LIBS="${PKG_LIBS} ${XLIBSW}" fi fi #-------------------------------------------------------------------- # Check whether --enable-threads or --disable-threads was given. # This auto-enables if Tcl was compiled threaded. #-------------------------------------------------------------------- # Check whether --enable-threads or --disable-threads was given. if test "${enable_threads+set}" = set; then enableval="$enable_threads" tcl_ok=$enableval else tcl_ok=yes fi; if test "${enable_threads+set}" = set; then enableval="$enable_threads" tcl_ok=$enableval else tcl_ok=yes fi if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then TCL_THREADS=1 if test "${TEA_PLATFORM}" != "windows" ; then # We are always OK on Windows, so check what this platform wants. cat >>confdefs.h <<\_ACEOF #define USE_THREAD_ALLOC 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _REENTRANT 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _THREAD_SAFE 1 _ACEOF echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthread" >&5 echo $ECHO_N "checking for pthread_mutex_init in -lpthread... $ECHO_C" >&6 if test "${ac_cv_lib_pthread_pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_pthread_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthread_pthread_mutex_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_pthread_pthread_mutex_init" >&6 if test $ac_cv_lib_pthread_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "no"; then # Check a little harder for __pthread_mutex_init in the # same library, as some systems hide it there until # pthread.h is defined. We could alternatively do an # AC_TRY_COMPILE with pthread.h, but that will work with # libpthread really doesn't exist, like AIX 4.2. # [Bug: 4359] echo "$as_me:$LINENO: checking for __pthread_mutex_init in -lpthread" >&5 echo $ECHO_N "checking for __pthread_mutex_init in -lpthread... $ECHO_C" >&6 if test "${ac_cv_lib_pthread___pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char __pthread_mutex_init (); int main () { __pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_pthread___pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthread___pthread_mutex_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_pthread___pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_pthread___pthread_mutex_init" >&6 if test $ac_cv_lib_pthread___pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthread" else echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthreads" >&5 echo $ECHO_N "checking for pthread_mutex_init in -lpthreads... $ECHO_C" >&6 if test "${ac_cv_lib_pthreads_pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthreads $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_pthreads_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthreads_pthread_mutex_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_pthreads_pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_pthreads_pthread_mutex_init" >&6 if test $ac_cv_lib_pthreads_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthreads" else echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc" >&5 echo $ECHO_N "checking for pthread_mutex_init in -lc... $ECHO_C" >&6 if test "${ac_cv_lib_c_pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_c_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_c_pthread_mutex_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_c_pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_c_pthread_mutex_init" >&6 if test $ac_cv_lib_c_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "no"; then echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc_r" >&5 echo $ECHO_N "checking for pthread_mutex_init in -lc_r... $ECHO_C" >&6 if test "${ac_cv_lib_c_r_pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc_r $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_c_r_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_c_r_pthread_mutex_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_c_r_pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_c_r_pthread_mutex_init" >&6 if test $ac_cv_lib_c_r_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -pthread" else TCL_THREADS=0 { echo "$as_me:$LINENO: WARNING: \"Don t know how to find pthread lib on your system - thread support disabled\"" >&5 echo "$as_me: WARNING: \"Don t know how to find pthread lib on your system - thread support disabled\"" >&2;} fi fi fi fi fi else TCL_THREADS=0 fi # Do checking message here to not mess up interleaved configure output echo "$as_me:$LINENO: checking for building with threads" >&5 echo $ECHO_N "checking for building with threads... $ECHO_C" >&6 if test "${TCL_THREADS}" = "1"; then cat >>confdefs.h <<\_ACEOF #define TCL_THREADS 1 _ACEOF #LIBS="$LIBS $THREADS_LIBS" echo "$as_me:$LINENO: result: yes (default)" >&5 echo "${ECHO_T}yes (default)" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi # TCL_THREADS sanity checking. See if our request for building with # threads is the same as the way Tcl was built. If not, warn the user. case ${TCL_DEFS} in *THREADS=1*) if test "${TCL_THREADS}" = "0"; then { echo "$as_me:$LINENO: WARNING: Building ${PACKAGE_NAME} without threads enabled, but building against Tcl that IS thread-enabled. It is recommended to use --enable-threads." >&5 echo "$as_me: WARNING: Building ${PACKAGE_NAME} without threads enabled, but building against Tcl that IS thread-enabled. It is recommended to use --enable-threads." >&2;} fi ;; *) if test "${TCL_THREADS}" = "1"; then { echo "$as_me:$LINENO: WARNING: --enable-threads requested, but building against a Tcl that is NOT thread-enabled. This is an OK configuration that will also run in a thread-enabled core." >&5 echo "$as_me: WARNING: --enable-threads requested, but building against a Tcl that is NOT thread-enabled. This is an OK configuration that will also run in a thread-enabled core." >&2;} fi ;; esac #-------------------------------------------------------------------- # The statement below defines a collection of symbols related to # building as a shared library instead of a static library. #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking how to build libraries" >&5 echo $ECHO_N "checking how to build libraries... $ECHO_C" >&6 # Check whether --enable-shared or --disable-shared was given. if test "${enable_shared+set}" = set; then enableval="$enable_shared" tcl_ok=$enableval else tcl_ok=yes fi; if test "${enable_shared+set}" = set; then enableval="$enable_shared" tcl_ok=$enableval else tcl_ok=yes fi if test "$tcl_ok" = "yes" ; then echo "$as_me:$LINENO: result: shared" >&5 echo "${ECHO_T}shared" >&6 SHARED_BUILD=1 else echo "$as_me:$LINENO: result: static" >&5 echo "${ECHO_T}static" >&6 SHARED_BUILD=0 cat >>confdefs.h <<\_ACEOF #define STATIC_BUILD 1 _ACEOF fi #-------------------------------------------------------------------- # This macro figures out what flags to use with the compiler/linker # when building shared/static debug/optimized objects. This information # can be taken from the tclConfig.sh file, but this figures it all out. #-------------------------------------------------------------------- # Step 0: Enable 64 bit support? echo "$as_me:$LINENO: checking if 64bit support is enabled" >&5 echo $ECHO_N "checking if 64bit support is enabled... $ECHO_C" >&6 # Check whether --enable-64bit or --disable-64bit was given. if test "${enable_64bit+set}" = set; then enableval="$enable_64bit" do64bit=$enableval else do64bit=no fi; echo "$as_me:$LINENO: result: $do64bit" >&5 echo "${ECHO_T}$do64bit" >&6 # Step 0.b: Enable Solaris 64 bit VIS support? echo "$as_me:$LINENO: checking if 64bit Sparc VIS support is requested" >&5 echo $ECHO_N "checking if 64bit Sparc VIS support is requested... $ECHO_C" >&6 # Check whether --enable-64bit-vis or --disable-64bit-vis was given. if test "${enable_64bit_vis+set}" = set; then enableval="$enable_64bit_vis" do64bitVIS=$enableval else do64bitVIS=no fi; echo "$as_me:$LINENO: result: $do64bitVIS" >&5 echo "${ECHO_T}$do64bitVIS" >&6 if test "$do64bitVIS" = "yes"; then # Force 64bit on with VIS do64bit=yes fi # Step 0.c: Cross-compiling options for Windows/CE builds? if test "${TEA_PLATFORM}" = "windows" ; then echo "$as_me:$LINENO: checking if Windows/CE build is requested" >&5 echo $ECHO_N "checking if Windows/CE build is requested... $ECHO_C" >&6 # Check whether --enable-wince or --disable-wince was given. if test "${enable_wince+set}" = set; then enableval="$enable_wince" doWince=$enableval else doWince=no fi; echo "$as_me:$LINENO: result: $doWince" >&5 echo "${ECHO_T}$doWince" >&6 fi # Step 1: set the variable "system" to hold the name and version number # for the system. This can usually be done via the "uname" command, but # there are a few systems, like Next, where this doesn't work. echo "$as_me:$LINENO: checking system version (for dynamic loading)" >&5 echo $ECHO_N "checking system version (for dynamic loading)... $ECHO_C" >&6 if test -f /usr/lib/NextStep/software_version; then system=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version` else system=`uname -s`-`uname -r` if test "$?" -ne 0 ; then echo "$as_me:$LINENO: result: unknown (can't find uname command)" >&5 echo "${ECHO_T}unknown (can't find uname command)" >&6 system=unknown else # Special check for weird MP-RAS system (uname returns weird # results, and the version is kept in special file). if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then system=MP-RAS-`awk '{print }' /etc/.relid` fi if test "`uname -s`" = "AIX" ; then system=AIX-`uname -v`.`uname -r` fi if test "${TEA_PLATFORM}" = "windows" ; then system=windows fi echo "$as_me:$LINENO: result: $system" >&5 echo "${ECHO_T}$system" >&6 fi fi # Step 2: check for existence of -ldl library. This is needed because # Linux can use either -ldl or -ldld for dynamic loading. echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 if test "${ac_cv_lib_dl_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char dlopen (); int main () { dlopen (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 if test $ac_cv_lib_dl_dlopen = yes; then have_dl=yes else have_dl=no fi # Step 3: set configuration options based on system name and version. # This is similar to Tcl's unix/tcl.m4 except that we've added a # "windows" case and CC_SEARCH_FLAGS becomes LD_SEARCH_FLAGS for us # (and we have no CC_SEARCH_FLAGS). do64bit_ok=no LDFLAGS_ORIG="$LDFLAGS" TCL_EXPORT_FILE_SUFFIX="" UNSHARED_LIB_SUFFIX="" TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`' ECHO_VERSION='`echo ${PACKAGE_VERSION}`' TCL_LIB_VERSIONS_OK=ok CFLAGS_DEBUG=-g if test "$GCC" = "yes" ; then CFLAGS_OPTIMIZE=-O2 CFLAGS_WARNING="-Wall -Wno-implicit-int" else CFLAGS_OPTIMIZE=-O CFLAGS_WARNING="" fi TCL_NEEDS_EXP_FILE=0 TCL_BUILD_EXP_FILE="" TCL_EXP_FILE="" # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_AR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="ar" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then echo "$as_me:$LINENO: result: $AR" >&5 echo "${ECHO_T}$AR" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi STLIB_LD='${AR} cr' LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH" case $system in windows) # This is a 2-stage check to make sure we have the 64-bit SDK # We have to know where the SDK is installed. # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs # MACHINE is IX86 for LINK, but this is used by the manifest, # which requires x86|amd64|ia64. MACHINE="X86" if test "$do64bit" != "no" ; then if test "x${MSSDK}x" = "xx" ; then MSSDK="C:/Progra~1/Microsoft Platform SDK" fi MSSDK=`echo "$MSSDK" | sed -e 's!\\\!/!g'` PATH64="" case "$do64bit" in amd64|x64|yes) MACHINE="AMD64" ; # default to AMD64 64-bit build PATH64="${MSSDK}/Bin/Win64/x86/AMD64" ;; ia64) MACHINE="IA64" PATH64="${MSSDK}/Bin/Win64" ;; esac if test ! -d "${PATH64}" ; then { echo "$as_me:$LINENO: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&5 echo "$as_me: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&2;} { echo "$as_me:$LINENO: WARNING: Ensure latest Platform SDK is installed" >&5 echo "$as_me: WARNING: Ensure latest Platform SDK is installed" >&2;} do64bit="no" else echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5 echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6 do64bit_ok="yes" fi fi if test "$doWince" != "no" ; then if test "$do64bit" != "no" ; then { { echo "$as_me:$LINENO: error: Windows/CE and 64-bit builds incompatible" >&5 echo "$as_me: error: Windows/CE and 64-bit builds incompatible" >&2;} { (exit 1); exit 1; }; } fi if test "$GCC" = "yes" ; then { { echo "$as_me:$LINENO: error: Windows/CE and GCC builds incompatible" >&5 echo "$as_me: error: Windows/CE and GCC builds incompatible" >&2;} { (exit 1); exit 1; }; } fi # First, look for one uninstalled. # the alternative search directory is invoked by --with-celib if test x"${no_celib}" = x ; then # we reset no_celib in case something fails here no_celib=true # Check whether --with-celib or --without-celib was given. if test "${with_celib+set}" = set; then withval="$with_celib" with_celibconfig=${withval} fi; echo "$as_me:$LINENO: checking for Windows/CE celib directory" >&5 echo $ECHO_N "checking for Windows/CE celib directory... $ECHO_C" >&6 if test "${ac_cv_c_celibconfig+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # First check to see if --with-celibconfig was specified. if test x"${with_celibconfig}" != x ; then if test -d "${with_celibconfig}/inc" ; then ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)` else { { echo "$as_me:$LINENO: error: ${with_celibconfig} directory doesn't contain inc directory" >&5 echo "$as_me: error: ${with_celibconfig} directory doesn't contain inc directory" >&2;} { (exit 1); exit 1; }; } fi fi # then check for a celib library if test x"${ac_cv_c_celibconfig}" = x ; then for i in \ ../celib-palm-3.0 \ ../celib \ ../../celib-palm-3.0 \ ../../celib \ `ls -dr ../celib-*3.[0-9]* 2>/dev/null` \ ${srcdir}/../celib-palm-3.0 \ ${srcdir}/../celib \ `ls -dr ${srcdir}/../celib-*3.[0-9]* 2>/dev/null` \ ; do if test -d "$i/inc" ; then ac_cv_c_celibconfig=`(cd $i; pwd)` break fi done fi fi if test x"${ac_cv_c_celibconfig}" = x ; then { { echo "$as_me:$LINENO: error: Cannot find celib support library directory" >&5 echo "$as_me: error: Cannot find celib support library directory" >&2;} { (exit 1); exit 1; }; } else no_celib= CELIB_DIR=${ac_cv_c_celibconfig} CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'` echo "$as_me:$LINENO: result: found $CELIB_DIR" >&5 echo "${ECHO_T}found $CELIB_DIR" >&6 fi fi # Set defaults for common evc4/PPC2003 setup # Currently Tcl requires 300+, possibly 420+ for sockets CEVERSION=420; # could be 211 300 301 400 420 ... TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ... ARCH=ARM; # could be ARM MIPS X86EM ... PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002" if test "$doWince" != "yes"; then # If !yes then the user specified something # Reset ARCH to allow user to skip specifying it ARCH= eval `echo $doWince | awk -F, '{ \ if (length($1)) { printf "CEVERSION=\"%s\"\n", $1; \ if ($1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \ if (length($2)) { printf "TARGETCPU=\"%s\"\n", toupper($2) }; \ if (length($3)) { printf "ARCH=\"%s\"\n", toupper($3) }; \ if (length($4)) { printf "PLATFORM=\"%s\"\n", $4 }; \ }'` if test "x${ARCH}" = "x" ; then ARCH=$TARGETCPU; fi fi OSVERSION=WCE$CEVERSION; if test "x${WCEROOT}" = "x" ; then WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0" if test ! -d "${WCEROOT}" ; then WCEROOT="C:/Program Files/Microsoft eMbedded Tools" fi fi if test "x${SDKROOT}" = "x" ; then SDKROOT="C:/Program Files/Windows CE Tools" if test ! -d "${SDKROOT}" ; then SDKROOT="C:/Windows CE Tools" fi fi WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'` SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'` if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \ -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then { { echo "$as_me:$LINENO: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&5 echo "$as_me: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&2;} { (exit 1); exit 1; }; } doWince="no" else # We could PATH_NOSPACE these, but that's not important, # as long as we quote them when used. CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include" if test -d "${CEINCLUDE}/${TARGETCPU}" ; then CEINCLUDE="${CEINCLUDE}/${TARGETCPU}" fi CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" fi fi if test "$GCC" != "yes" ; then if test "${SHARED_BUILD}" = "0" ; then runtime=-MT else runtime=-MD fi if test "$do64bit" != "no" ; then # All this magic is necessary for the Win64 SDK RC1 - hobbs CC="\"${PATH64}/cl.exe\"" CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\"" RC="\"${MSSDK}/bin/rc.exe\"" lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\"" LINKBIN="\"${PATH64}/link.exe\"" CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d" CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" # Avoid 'unresolved external symbol __security_cookie' # errors, c.f. http://support.microsoft.com/?id=894573 vars="bufferoverflowU.lib" for i in $vars; do if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then # Convert foo.lib to -lfoo for GCC. No-op if not *.lib i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'` fi PKG_LIBS="$PKG_LIBS $i" done elif test "$doWince" != "no" ; then CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin" if test "${TARGETCPU}" = "X86"; then CC="\"${CEBINROOT}/cl.exe\"" else CC="\"${CEBINROOT}/cl${ARCH}.exe\"" fi CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\"" RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\"" arch=`echo ${ARCH} | awk '{print tolower($0)}'` defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS" if test "${SHARED_BUILD}" = "1" ; then # Static CE builds require static celib as well defs="${defs} _DLL" fi for i in $defs ; do cat >>confdefs.h <<_ACEOF #define $i 1 _ACEOF done cat >>confdefs.h <<_ACEOF #define _WIN32_WCE $CEVERSION _ACEOF cat >>confdefs.h <<_ACEOF #define UNDER_CE $CEVERSION _ACEOF CFLAGS_DEBUG="-nologo -Zi -Od" CFLAGS_OPTIMIZE="-nologo -Ox" lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'` lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo" LINKBIN="\"${CEBINROOT}/link.exe\"" else RC="rc" lflags="-nologo" LINKBIN="link" CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d" CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" fi fi if test "$GCC" = "yes"; then # mingw gcc mode RC="windres" CFLAGS_DEBUG="-g" CFLAGS_OPTIMIZE="-O2" SHLIB_LD="$CXX -shared" UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}" LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}" else SHLIB_LD="${LINKBIN} -dll ${lflags}" # link -lib only works when -lib is the first arg STLIB_LD="${LINKBIN} -lib ${lflags}" UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib' PATHTYPE=-w # For information on what debugtype is most useful, see: # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp # This essentially turns it all on. LDFLAGS_DEBUG="-debug:full -debugtype:both -warn:2" LDFLAGS_OPTIMIZE="-release" if test "$doWince" != "no" ; then LDFLAGS_CONSOLE="-link ${lflags}" LDFLAGS_WINDOW=${LDFLAGS_CONSOLE} else LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}" LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}" fi fi SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".dll" SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll' TCL_LIB_VERSIONS_OK=nodots # Bogus to avoid getting this turned off DL_OBJS="tclLoadNone.obj" ;; AIX-*) if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes" ; then # AIX requires the _r compiler when gcc isn't being used case "${CC}" in *_r) # ok ... ;; *) CC=${CC}_r ;; esac echo "$as_me:$LINENO: result: Using $CC for compiling with threads" >&5 echo "${ECHO_T}Using $CC for compiling with threads" >&6 fi LIBS="$LIBS -lc" SHLIB_CFLAGS="" SHLIB_SUFFIX=".so" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadDl.o" LD_LIBRARY_PATH_VAR="LIBPATH" # AIX v<=4.1 has some different flags than 4.2+ if test "$system" = "AIX-4.1" -o "`uname -v`" -lt "4" ; then #LIBOBJS="$LIBOBJS tclLoadAix.o" case $LIBOBJS in "tclLoadAix.$ac_objext" | \ *" tclLoadAix.$ac_objext" | \ "tclLoadAix.$ac_objext "* | \ *" tclLoadAix.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS tclLoadAix.$ac_objext" ;; esac DL_LIBS="-lld" fi # Check to enable 64-bit flags for compiler/linker on AIX 4+ if test "$do64bit" = "yes" -a "`uname -v`" -gt "3" ; then if test "$GCC" = "yes" ; then { echo "$as_me:$LINENO: WARNING: \"64bit mode not supported with GCC on $system\"" >&5 echo "$as_me: WARNING: \"64bit mode not supported with GCC on $system\"" >&2;} else do64bit_ok=yes CFLAGS="$CFLAGS -q64" LDFLAGS="$LDFLAGS -q64" RANLIB="${RANLIB} -X64" AR="${AR} -X64" SHLIB_LD_FLAGS="-b64" fi fi if test "`uname -m`" = "ia64" ; then # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC SHLIB_LD="/usr/ccs/bin/ld -G -z text" # AIX-5 has dl* in libc.so DL_LIBS="" if test "$GCC" = "yes" ; then LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' else LD_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}' fi else if test "$GCC" = "yes" ; then SHLIB_LD="$CXX -shared" else SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry" fi SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}" DL_LIBS="-ldl" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' TCL_NEEDS_EXP_FILE=1 TCL_EXPORT_FILE_SUFFIX='${PACKAGE_VERSION}.exp' fi # On AIX <=v4 systems, libbsd.a has to be linked in to support # non-blocking file IO. This library has to be linked in after # the MATH_LIBS or it breaks the pow() function. The way to # insure proper sequencing, is to add it to the tail of MATH_LIBS. # This library also supplies gettimeofday. # # AIX does not have a timezone field in struct tm. When the AIX # bsd library is used, the timezone global and the gettimeofday # methods are to be avoided for timezone deduction instead, we # deduce the timezone by comparing the localtime result on a # known GMT value. echo "$as_me:$LINENO: checking for gettimeofday in -lbsd" >&5 echo $ECHO_N "checking for gettimeofday in -lbsd... $ECHO_C" >&6 if test "${ac_cv_lib_bsd_gettimeofday+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbsd $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gettimeofday (); int main () { gettimeofday (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_bsd_gettimeofday=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_bsd_gettimeofday=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_gettimeofday" >&5 echo "${ECHO_T}$ac_cv_lib_bsd_gettimeofday" >&6 if test $ac_cv_lib_bsd_gettimeofday = yes; then libbsd=yes else libbsd=no fi if test $libbsd = yes; then MATH_LIBS="$MATH_LIBS -lbsd" cat >>confdefs.h <<\_ACEOF #define USE_DELTA_FOR_TZ 1 _ACEOF fi ;; BeOS*) SHLIB_CFLAGS="-fPIC" SHLIB_LD="${CXX} -nostart" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" ;; BSD/OS-2.1*|BSD/OS-3*) SHLIB_CFLAGS="" SHLIB_LD="shlicc -r" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS="" ;; BSD/OS-4.*) SHLIB_CFLAGS="-export-dynamic -fPIC" SHLIB_LD="$CXX -shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -export-dynamic" LD_SEARCH_FLAGS="" ;; dgux*) SHLIB_CFLAGS="-K PIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS="" ;; HP-UX-*.11.*) # Use updated header definitions where possible cat >>confdefs.h <<\_ACEOF #define _XOPEN_SOURCE_EXTENDED 1 _ACEOF SHLIB_SUFFIX=".sl" echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 if test "${ac_cv_lib_dld_shl_load+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char shl_load (); int main () { shl_load (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dld_shl_load=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_shl_load=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 if test $ac_cv_lib_dld_shl_load = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = yes; then SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadShl.o" DL_LIBS="-ldld" LDFLAGS="$LDFLAGS -Wl,-E" LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.' LD_LIBRARY_PATH_VAR="SHLIB_PATH" fi if test "$GCC" = "yes" ; then SHLIB_LD="$CXX -shared -fPIC" SHLIB_LD_LIBS='${LIBS}' LD_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.' fi # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc #CFLAGS="$CFLAGS +DAportable" # Check to enable 64-bit flags for compiler/linker if test "$do64bit" = "yes" ; then if test "$GCC" = "yes" ; then hpux_arch=`${CC} -dumpmachine` case $hpux_arch in hppa64*) # 64-bit gcc in use. Fix flags for GNU ld. do64bit_ok=yes SHLIB_LD="${CXX} -shared -fPIC" SHLIB_LD_LIBS='${LIBS}' ;; *) { echo "$as_me:$LINENO: WARNING: \"64bit mode not supported with GCC on $system\"" >&5 echo "$as_me: WARNING: \"64bit mode not supported with GCC on $system\"" >&2;} ;; esac else do64bit_ok=yes CFLAGS="$CFLAGS +DD64" LDFLAGS="$LDFLAGS +DD64" fi fi ;; HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*) SHLIB_SUFFIX=".sl" echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 if test "${ac_cv_lib_dld_shl_load+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char shl_load (); int main () { shl_load (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dld_shl_load=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_shl_load=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 if test $ac_cv_lib_dld_shl_load = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = yes; then SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" SHLIB_LD_LIBS="" DL_OBJS="tclLoadShl.o" DL_LIBS="-ldld" LDFLAGS="$LDFLAGS -Wl,-E" LD_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.' fi LD_LIBRARY_PATH_VAR="SHLIB_PATH" ;; IRIX-4.*) SHLIB_CFLAGS="-G 0" SHLIB_SUFFIX=".a" SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadAout.o" DL_LIBS="" LDFLAGS="$LDFLAGS -Wl,-D,08000000" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' SHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a' ;; IRIX-5.*) SHLIB_CFLAGS="" SHLIB_LD="ld -shared -rdata_shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' ;; IRIX-6.*|IRIX64-6.5*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' if test "$GCC" = "yes" ; then CFLAGS="$CFLAGS -mabi=n32" LDFLAGS="$LDFLAGS -mabi=n32" else case $system in IRIX-6.3) # Use to build 6.2 compatible binaries on 6.3. CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS" ;; *) CFLAGS="$CFLAGS -n32" ;; esac LDFLAGS="$LDFLAGS -n32" fi ;; IRIX64-6.*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' # Check to enable 64-bit flags for compiler/linker if test "$do64bit" = "yes" ; then if test "$GCC" = "yes" ; then { echo "$as_me:$LINENO: WARNING: 64bit mode not supported by gcc" >&5 echo "$as_me: WARNING: 64bit mode not supported by gcc" >&2;} else do64bit_ok=yes SHLIB_LD="ld -64 -shared -rdata_shared" CFLAGS="$CFLAGS -64" LDFLAGS="$LDFLAGS -64" fi fi ;; Linux*) SHLIB_CFLAGS="-fPIC" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" CFLAGS_OPTIMIZE="-O2" # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings # when you inline the string and math operations. Turn this off to # get rid of the warnings. #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES" if test "$have_dl" = yes; then SHLIB_LD="${CXX} -shared" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,--export-dynamic" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' else if test "${ac_cv_header_dld_h+set}" = set; then echo "$as_me:$LINENO: checking for dld.h" >&5 echo $ECHO_N "checking for dld.h... $ECHO_C" >&6 if test "${ac_cv_header_dld_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_dld_h" >&5 echo "${ECHO_T}$ac_cv_header_dld_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking dld.h usability" >&5 echo $ECHO_N "checking dld.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking dld.h presence" >&5 echo $ECHO_N "checking dld.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: dld.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: dld.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: dld.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: dld.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: dld.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: dld.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: dld.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: dld.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: dld.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: dld.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ---------------------------------- ## ## Report this to the tclutil lists. ## ## ---------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for dld.h" >&5 echo $ECHO_N "checking for dld.h... $ECHO_C" >&6 if test "${ac_cv_header_dld_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_dld_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_dld_h" >&5 echo "${ECHO_T}$ac_cv_header_dld_h" >&6 fi if test $ac_cv_header_dld_h = yes; then SHLIB_LD="ld -shared" DL_OBJS="tclLoadDld.o" DL_LIBS="-ldld" LD_SEARCH_FLAGS="" fi fi if test "`uname -m`" = "alpha" ; then CFLAGS="$CFLAGS -mieee" fi # The combo of gcc + glibc has a bug related # to inlining of functions like strtod(). The # -fno-builtin flag should address this problem # but it does not work. The -fno-inline flag # is kind of overkill but it works. # Disable inlining only when one of the # files in compat/*.c is being linked in. if test x"${USE_COMPAT}" != x ; then CFLAGS="$CFLAGS -fno-inline" fi ;; GNU*) SHLIB_CFLAGS="-fPIC" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" if test "$have_dl" = yes; then SHLIB_LD="${CXX} -shared" DL_OBJS="" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,--export-dynamic" LD_SEARCH_FLAGS="" else if test "${ac_cv_header_dld_h+set}" = set; then echo "$as_me:$LINENO: checking for dld.h" >&5 echo $ECHO_N "checking for dld.h... $ECHO_C" >&6 if test "${ac_cv_header_dld_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_dld_h" >&5 echo "${ECHO_T}$ac_cv_header_dld_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking dld.h usability" >&5 echo $ECHO_N "checking dld.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking dld.h presence" >&5 echo $ECHO_N "checking dld.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: dld.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: dld.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: dld.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: dld.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: dld.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: dld.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: dld.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: dld.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: dld.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: dld.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: dld.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ---------------------------------- ## ## Report this to the tclutil lists. ## ## ---------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for dld.h" >&5 echo $ECHO_N "checking for dld.h... $ECHO_C" >&6 if test "${ac_cv_header_dld_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_dld_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_dld_h" >&5 echo "${ECHO_T}$ac_cv_header_dld_h" >&6 fi if test $ac_cv_header_dld_h = yes; then SHLIB_LD="ld -shared" DL_OBJS="" DL_LIBS="-ldld" LD_SEARCH_FLAGS="" fi fi if test "`uname -m`" = "alpha" ; then CFLAGS="$CFLAGS -mieee" fi ;; MP-RAS-02*) SHLIB_CFLAGS="-K PIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS="" ;; MP-RAS-*) SHLIB_CFLAGS="-K PIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,-Bexport" LD_SEARCH_FLAGS="" ;; NetBSD-*|FreeBSD-[1-2].*) # Not available on all versions: check for include file. if test "${ac_cv_header_dlfcn_h+set}" = set; then echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking dlfcn.h usability" >&5 echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking dlfcn.h presence" >&5 echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: dlfcn.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ---------------------------------- ## ## Report this to the tclutil lists. ## ## ---------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_dlfcn_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 fi if test $ac_cv_header_dlfcn_h = yes; then # NetBSD/SPARC needs -fPIC, -fpic will not do. SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' echo "$as_me:$LINENO: checking for ELF" >&5 echo $ECHO_N "checking for ELF... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __ELF__ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so' else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' fi rm -f conftest* else SHLIB_CFLAGS="" SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".a" DL_OBJS="tclLoadAout.o" DL_LIBS="" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' fi # FreeBSD doesn't handle version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; OpenBSD-*) SHLIB_LD="${CXX} -shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS="" echo "$as_me:$LINENO: checking for ELF" >&5 echo $ECHO_N "checking for ELF... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __ELF__ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' fi rm -f conftest* # OpenBSD doesn't do version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; FreeBSD-*) # FreeBSD 3.* and greater have ELF. SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LDFLAGS="$LDFLAGS -export-dynamic" LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' if test "${TCL_THREADS}" = "1" ; then # The -pthread needs to go in the CFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` CFLAGS="$CFLAGS -pthread" LDFLAGS="$LDFLAGS -pthread" fi case $system in FreeBSD-3.*) # FreeBSD-3 doesn't handle version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so' TCL_LIB_VERSIONS_OK=nodots ;; esac ;; Darwin-*) CFLAGS_OPTIMIZE="-Os" SHLIB_CFLAGS="-fno-common" if test $do64bit = yes; then do64bit_ok=yes CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" fi SHLIB_LD='${CXX} -dynamiclib ${CFLAGS} ${LDFLAGS}' echo "$as_me:$LINENO: checking if ld accepts -single_module flag" >&5 echo $ECHO_N "checking if ld accepts -single_module flag... $ECHO_C" >&6 if test "${tcl_cv_ld_single_module+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { int i; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_ld_single_module=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_ld_single_module=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$hold_ldflags fi echo "$as_me:$LINENO: result: $tcl_cv_ld_single_module" >&5 echo "${ECHO_T}$tcl_cv_ld_single_module" >&6 if test $tcl_cv_ld_single_module = yes; then SHLIB_LD="${SHLIB_LD} -Wl,-single_module" fi SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".dylib" DL_OBJS="tclLoadDyld.o" DL_LIBS="" # Don't use -prebind when building for Mac OS X 10.4 or later only: test -z "${MACOSX_DEPLOYMENT_TARGET}" || \ test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F. '{print $2}'`" -lt 4 && \ LDFLAGS="$LDFLAGS -prebind" LDFLAGS="$LDFLAGS -headerpad_max_install_names" echo "$as_me:$LINENO: checking if ld accepts -search_paths_first flag" >&5 echo $ECHO_N "checking if ld accepts -search_paths_first flag... $ECHO_C" >&6 if test "${tcl_cv_ld_search_paths_first+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-search_paths_first" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { int i; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_ld_search_paths_first=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_ld_search_paths_first=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$hold_ldflags fi echo "$as_me:$LINENO: result: $tcl_cv_ld_search_paths_first" >&5 echo "${ECHO_T}$tcl_cv_ld_search_paths_first" >&6 if test $tcl_cv_ld_search_paths_first = yes; then LDFLAGS="$LDFLAGS -Wl,-search_paths_first" fi LD_SEARCH_FLAGS="" LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH" ;; NEXTSTEP-*) SHLIB_CFLAGS="" SHLIB_LD="$CXX -nostdlib -r" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadNext.o" DL_LIBS="" LD_SEARCH_FLAGS="" ;; OS/390-*) CFLAGS_OPTIMIZE="" # Optimizer is buggy cat >>confdefs.h <<\_ACEOF #define _OE_SOCKETS 1 _ACEOF ;; OSF1-1.0|OSF1-1.1|OSF1-1.2) # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1 SHLIB_CFLAGS="" # Hack: make package name same as library name SHLIB_LD='ld -R -export :' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadOSF.o" DL_LIBS="" LD_SEARCH_FLAGS="" ;; OSF1-1.*) # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2 SHLIB_CFLAGS="-fPIC" if test "$SHARED_BUILD" = "1" ; then SHLIB_LD="ld -shared" else SHLIB_LD="ld -non_shared" fi SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS="" ;; OSF1-V*) # Digital OSF/1 SHLIB_CFLAGS="" if test "$SHARED_BUILD" = "1" ; then SHLIB_LD='ld -shared -expect_unresolved "*"' else SHLIB_LD='ld -non_shared -expect_unresolved "*"' fi SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' if test "$GCC" = "yes" ; then CFLAGS="$CFLAGS -mieee" else CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee" fi # see pthread_intro(3) for pthread support on osf1, k.furukawa if test "${TCL_THREADS}" = "1" ; then CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE" CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64" LIBS=`echo $LIBS | sed s/-lpthreads//` if test "$GCC" = "yes" ; then LIBS="$LIBS -lpthread -lmach -lexc" else CFLAGS="$CFLAGS -pthread" # PWD: don't need this. #LDFLAGS="$LDFLAGS -pthread" fi fi ;; QNX-6*) # QNX RTP # This may work for all QNX, but it was only reported for v6. SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" # dlopen is in -lc on QNX DL_LIBS="" LD_SEARCH_FLAGS="" ;; RISCos-*) SHLIB_CFLAGS="-G 0" SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".a" DL_OBJS="tclLoadAout.o" DL_LIBS="" LDFLAGS="$LDFLAGS -Wl,-D,08000000" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' ;; SCO_SV-3.2*) # Note, dlopen is available only on SCO 3.2.5 and greater. However, # this test works, since "uname -s" was non-standard in 3.2.4 and # below. if test "$GCC" = "yes" ; then SHLIB_CFLAGS="-fPIC -melf" LDFLAGS="$LDFLAGS -melf -Wl,-Bexport" else SHLIB_CFLAGS="-Kpic -belf" LDFLAGS="$LDFLAGS -belf -Wl,-Bexport" fi SHLIB_LD="ld -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LD_SEARCH_FLAGS="" ;; SINIX*5.4*) SHLIB_CFLAGS="-K PIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS="" ;; SunOS-4*) SHLIB_CFLAGS="-PIC" SHLIB_LD="ld" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' # SunOS can't handle version numbers with dots in them in library # specs, like -ltcl7.5, so use -ltcl75 instead. Also, it # requires an extra version number at the end of .so file names. # So, the library has to have a name like libtcl75.so.1.0 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; SunOS-5.[0-6]) # Careful to not let 5.10+ fall into this case # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. cat >>confdefs.h <<\_ACEOF #define _REENTRANT 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _POSIX_PTHREAD_SEMANTICS 1 _ACEOF # Note: need the LIBS below, otherwise Tk won't find Tcl's # symbols when dynamically loaded into tclsh. SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" if test "$GCC" = "yes" ; then SHLIB_CFLAGS="-fPIC" SHLIB_LD="$CXX -shared" LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' else SHLIB_LD="$CXX -G -z text" LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' SHLIB_CFLAGS="-KPIC" fi ;; SunOS-5*) # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. cat >>confdefs.h <<\_ACEOF #define _REENTRANT 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _POSIX_PTHREAD_SEMANTICS 1 _ACEOF # Check to enable 64-bit flags for compiler/linker if test "$do64bit" = "yes" ; then arch=`isainfo` if test "$arch" = "sparcv9 sparc" ; then if test "$GCC" = "yes" ; then if test "`gcc -dumpversion` | awk -F. '{print }'" -lt "3" ; then { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5 echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;} else do64bit_ok=yes CFLAGS="$CFLAGS -m64 -mcpu=v9" LDFLAGS="$LDFLAGS -m64 -mcpu=v9" fi else do64bit_ok=yes if test "$do64bitVIS" = "yes" ; then CFLAGS="$CFLAGS -xarch=v9a" LDFLAGS="$LDFLAGS -xarch=v9a" else CFLAGS="$CFLAGS -xarch=v9" LDFLAGS="$LDFLAGS -xarch=v9" fi # Solaris 64 uses this as well #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64" fi elif test "$arch" = "amd64 i386" ; then if test "$GCC" = "yes" ; then { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5 echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;} else do64bit_ok=yes CFLAGS="$CFLAGS -xarch=amd64" LDFLAGS="$LDFLAGS -xarch=amd64" fi else { echo "$as_me:$LINENO: WARNING: 64bit mode not supported for $arch" >&5 echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;} fi fi # Note: need the LIBS below, otherwise Tk won't find Tcl's # symbols when dynamically loaded into tclsh. SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" if test "$GCC" = "yes" ; then SHLIB_CFLAGS="-fPIC" SHLIB_LD="$CXX -shared" LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' if test "$do64bit" = "yes" ; then # We need to specify -static-libgcc or we need to # add the path to the sparv9 libgcc. # JH: static-libgcc is necessary for core Tcl, but may # not be necessary for extensions. SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc" # for finding sparcv9 libgcc, get the regular libgcc # path, remove so name and append 'sparcv9' #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..." #LD_SEARCH_FLAGS="${LD_SEARCH_FLAGS},-R,$v9gcclibdir" fi else SHLIB_CFLAGS="-KPIC" SHLIB_LD="$CXX -G -z text" LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' fi ;; ULTRIX-4.*) SHLIB_CFLAGS="-G 0" SHLIB_SUFFIX=".a" SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadAout.o" DL_LIBS="" LDFLAGS="$LDFLAGS -Wl,-D,08000000" LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' if test "$GCC" != "yes" ; then CFLAGS="$CFLAGS -DHAVE_TZSET -std1" fi ;; UNIX_SV* | UnixWare-5*) SHLIB_CFLAGS="-KPIC" SHLIB_LD="$CXX -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers # that don't grok the -Bexport option. Test that it does. hold_ldflags=$LDFLAGS echo "$as_me:$LINENO: checking for ld accepts -Bexport flag" >&5 echo $ECHO_N "checking for ld accepts -Bexport flag... $ECHO_C" >&6 LDFLAGS="$LDFLAGS -Wl,-Bexport" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { int i; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then found=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 LDFLAGS=$hold_ldflags found=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext echo "$as_me:$LINENO: result: $found" >&5 echo "${ECHO_T}$found" >&6 LD_SEARCH_FLAGS="" ;; esac if test "$do64bit" != "no" -a "$do64bit_ok" = "no" ; then { echo "$as_me:$LINENO: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5 echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;} fi # Step 4: If pseudo-static linking is in use (see K. B. Kenny, "Dynamic # Loading for Tcl -- What Became of It?". Proc. 2nd Tcl/Tk Workshop, # New Orleans, LA, Computerized Processes Unlimited, 1994), then we need # to determine which of several header files defines the a.out file # format (a.out.h, sys/exec.h, or sys/exec_aout.h). At present, we # support only a file format that is more or less version-7-compatible. # In particular, # - a.out files must begin with `struct exec'. # - the N_TXTOFF on the `struct exec' must compute the seek address # of the text segment # - The `struct exec' must contain a_magic, a_text, a_data, a_bss # and a_entry fields. # The following compilation should succeed if and only if either sys/exec.h # or a.out.h is usable for the purpose. # # Note that the modified COFF format used on MIPS Ultrix 4.x is usable; the # `struct exec' includes a second header that contains information that # duplicates the v7 fields that are needed. if test "x$DL_OBJS" = "xtclLoadAout.o" ; then echo "$as_me:$LINENO: checking sys/exec.h" >&5 echo $ECHO_N "checking sys/exec.h... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct exec foo; unsigned long seek; int flag; #if defined(__mips) || defined(mips) seek = N_TXTOFF (foo.ex_f, foo.ex_o); #else seek = N_TXTOFF (foo); #endif flag = (foo.a_magic == OMAGIC); return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_ok=usable else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_ok=unusable fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $tcl_ok" >&5 echo "${ECHO_T}$tcl_ok" >&6 if test $tcl_ok = usable; then cat >>confdefs.h <<\_ACEOF #define USE_SYS_EXEC_H 1 _ACEOF else echo "$as_me:$LINENO: checking a.out.h" >&5 echo $ECHO_N "checking a.out.h... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct exec foo; unsigned long seek; int flag; #if defined(__mips) || defined(mips) seek = N_TXTOFF (foo.ex_f, foo.ex_o); #else seek = N_TXTOFF (foo); #endif flag = (foo.a_magic == OMAGIC); return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_ok=usable else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_ok=unusable fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $tcl_ok" >&5 echo "${ECHO_T}$tcl_ok" >&6 if test $tcl_ok = usable; then cat >>confdefs.h <<\_ACEOF #define USE_A_OUT_H 1 _ACEOF else echo "$as_me:$LINENO: checking sys/exec_aout.h" >&5 echo $ECHO_N "checking sys/exec_aout.h... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct exec foo; unsigned long seek; int flag; #if defined(__mips) || defined(mips) seek = N_TXTOFF (foo.ex_f, foo.ex_o); #else seek = N_TXTOFF (foo); #endif flag = (foo.a_midmag == OMAGIC); return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_ok=usable else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_ok=unusable fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $tcl_ok" >&5 echo "${ECHO_T}$tcl_ok" >&6 if test $tcl_ok = usable; then cat >>confdefs.h <<\_ACEOF #define USE_SYS_EXEC_AOUT_H 1 _ACEOF else DL_OBJS="" fi fi fi fi # Step 5: disable dynamic loading if requested via a command-line switch. # Check whether --enable-load or --disable-load was given. if test "${enable_load+set}" = set; then enableval="$enable_load" tcl_ok=$enableval else tcl_ok=yes fi; if test "$tcl_ok" = "no"; then DL_OBJS="" fi if test "x$DL_OBJS" != "x" ; then BUILD_DLTEST="\$(DLTEST_TARGETS)" else echo "Can't figure out how to do dynamic loading or shared libraries" echo "on this system." SHLIB_CFLAGS="" SHLIB_LD="" SHLIB_SUFFIX="" DL_OBJS="tclLoadNone.o" DL_LIBS="" LDFLAGS="$LDFLAGS_ORIG" LD_SEARCH_FLAGS="" BUILD_DLTEST="" fi # If we're running gcc, then change the C flags for compiling shared # libraries to the right flags for gcc, instead of those for the # standard manufacturer compiler. if test "$DL_OBJS" != "tclLoadNone.o" ; then if test "$GCC" = "yes" ; then case $system in AIX-*) ;; BSD/OS*) ;; IRIX*) ;; NetBSD-*|FreeBSD-*) ;; Darwin-*) ;; RISCos-*) ;; SCO_SV-3.2*) ;; ULTRIX-4.*) ;; windows) ;; *) SHLIB_CFLAGS="-fPIC" ;; esac fi fi if test "$SHARED_LIB_SUFFIX" = "" ; then SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}' fi if test "$UNSHARED_LIB_SUFFIX" = "" ; then UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a' fi # These must be called after we do the basic CFLAGS checks and # verify any possible 64-bit or similar switches are necessary echo "$as_me:$LINENO: checking for required early compiler flags" >&5 echo $ECHO_N "checking for required early compiler flags... $ECHO_C" >&6 tcl_flags="" if test "${tcl_cv_flag__isoc99_source+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char *p = (char *)strtoll; char *q = (char *)strtoull; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_flag__isoc99_source=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _ISOC99_SOURCE 1 #include int main () { char *p = (char *)strtoll; char *q = (char *)strtoull; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_flag__isoc99_source=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_flag__isoc99_source=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_flag__isoc99_source}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define _ISOC99_SOURCE 1 _ACEOF tcl_flags="$tcl_flags _ISOC99_SOURCE" fi if test "${tcl_cv_flag__largefile64_source+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct stat64 buf; int i = stat64("/", &buf); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_flag__largefile64_source=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _LARGEFILE64_SOURCE 1 #include int main () { struct stat64 buf; int i = stat64("/", &buf); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_flag__largefile64_source=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_flag__largefile64_source=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_flag__largefile64_source}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define _LARGEFILE64_SOURCE 1 _ACEOF tcl_flags="$tcl_flags _LARGEFILE64_SOURCE" fi if test "x${tcl_flags}" = "x" ; then echo "$as_me:$LINENO: result: none" >&5 echo "${ECHO_T}none" >&6 else echo "$as_me:$LINENO: result: ${tcl_flags}" >&5 echo "${ECHO_T}${tcl_flags}" >&6 fi echo "$as_me:$LINENO: checking for 64-bit integer type" >&5 echo $ECHO_N "checking for 64-bit integer type... $ECHO_C" >&6 if test "${tcl_cv_type_64bit+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else tcl_cv_type_64bit=none # See if the compiler knows natively about __int64 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { __int64 value = (__int64) 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_type_64bit=__int64 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_type_64bit="long long" fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext # See if we should use long anyway Note that we substitute in the # type that is our current guess for a 64-bit type inside this check # program, so it should be modified only carefully... cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { switch (0) { case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ; } ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_type_64bit=${tcl_type_64bit} else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "${tcl_cv_type_64bit}" = none ; then cat >>confdefs.h <<\_ACEOF #define TCL_WIDE_INT_IS_LONG 1 _ACEOF echo "$as_me:$LINENO: result: using long" >&5 echo "${ECHO_T}using long" >&6 elif test "${tcl_cv_type_64bit}" = "__int64" \ -a "${TEA_PLATFORM}" = "windows" ; then # We actually want to use the default tcl.h checks in this # case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER* echo "$as_me:$LINENO: result: using Tcl header defaults" >&5 echo "${ECHO_T}using Tcl header defaults" >&6 else cat >>confdefs.h <<_ACEOF #define TCL_WIDE_INT_TYPE ${tcl_cv_type_64bit} _ACEOF echo "$as_me:$LINENO: result: ${tcl_cv_type_64bit}" >&5 echo "${ECHO_T}${tcl_cv_type_64bit}" >&6 # Now check for auxiliary declarations echo "$as_me:$LINENO: checking for struct dirent64" >&5 echo $ECHO_N "checking for struct dirent64... $ECHO_C" >&6 if test "${tcl_cv_struct_dirent64+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { struct dirent64 p; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_struct_dirent64=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_struct_dirent64=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRUCT_DIRENT64 1 _ACEOF fi echo "$as_me:$LINENO: result: ${tcl_cv_struct_dirent64}" >&5 echo "${ECHO_T}${tcl_cv_struct_dirent64}" >&6 echo "$as_me:$LINENO: checking for struct stat64" >&5 echo $ECHO_N "checking for struct stat64... $ECHO_C" >&6 if test "${tcl_cv_struct_stat64+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct stat64 p; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_struct_stat64=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_struct_stat64=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_struct_stat64}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRUCT_STAT64 1 _ACEOF fi echo "$as_me:$LINENO: result: ${tcl_cv_struct_stat64}" >&5 echo "${ECHO_T}${tcl_cv_struct_stat64}" >&6 echo "$as_me:$LINENO: checking for off64_t" >&5 echo $ECHO_N "checking for off64_t... $ECHO_C" >&6 if test "${tcl_cv_type_off64_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { off64_t offset; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then tcl_cv_type_off64_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_type_off64_t=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_type_off64_t}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_TYPE_OFF64_T 1 _ACEOF fi echo "$as_me:$LINENO: result: ${tcl_cv_type_off64_t}" >&5 echo "${ECHO_T}${tcl_cv_type_off64_t}" >&6 fi #----------------------------------------------------------------------- # Find -lBLT library (needs variable set indirectly by TEA_CONFIG_CFLAGS: SHLIB_SUFFIX) echo "$as_me:$LINENO: checking for BLT library" >&5 echo $ECHO_N "checking for BLT library... $ECHO_C" >&6 # Check whether --with-blt or --without-blt was given. if test "${with_blt+set}" = set; then withval="$with_blt" BLT_LIB_DIR=$withval fi; BLT_LIBNAME=libBLT25${SHLIB_SUFFIX} BLT_LIBFLAG="-lBLT25" if test -z "$BLT_LIB_DIR" ; then # If --with-blt=dir was not specified, try the Tcl lib dir and the exec-prefix/lib dir places="\ $TCL_BIN_DIR \ $TCL_BIN_DIR/blt2.4 \ $TCLTK_ROOT/lib \ $TCLTK_ROOT/lib/blt2.4 \ $exec_prefix/lib \ $exec_prefix/lib/blt2.4 \ $prefix/lib \ $prefix/lib/blt2.4 \ " for i in $places ; do if test -f $i/$BLT_LIBNAME then BLT_LIB_DIR=$i break fi done if test -z "$BLT_LIB_DIR" ; then echo { { echo "$as_me:$LINENO: error: could not find $BLT_LIBNAME: Please use the --with-blt=DIR option." >&5 echo "$as_me: error: could not find $BLT_LIBNAME: Please use the --with-blt=DIR option." >&2;} { (exit 1); exit 1; }; } fi else # Check if the BLT library is in the lib subdir of the given dir if test ! -f $BLT_LIB_DIR/$BLT_LIBNAME then if test ! -f $BLT_LIB_DIR/lib/$BLT_LIBNAME then echo { { echo "$as_me:$LINENO: error: could not find $BLT_LIBNAME in $BLT_LIB_DIR or in $BLT_LIB_DIR/lib: Please use the --with-blt=DIR option." >&5 echo "$as_me: error: could not find $BLT_LIBNAME in $BLT_LIB_DIR or in $BLT_LIB_DIR/lib: Please use the --with-blt=DIR option." >&2;} { (exit 1); exit 1; }; } else BLT_LIB_DIR=$BLT_LIB_DIR/lib fi fi fi BLT_LIB_SPEC="-L$BLT_LIB_DIR $BLT_LIBFLAG" echo "$as_me:$LINENO: result: $BLT_LIB_DIR" >&5 echo "${ECHO_T}$BLT_LIB_DIR" >&6 vars="${BLT_LIB_SPEC}" for i in $vars; do if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then # Convert foo.lib to -lfoo for GCC. No-op if not *.lib i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'` fi PKG_LIBS="$PKG_LIBS $i" done #----------------------------------------------------------------------- #-------------------------------------------------------------------- # Set the default compiler switches based on the --enable-symbols option. #-------------------------------------------------------------------- DBGX="" echo "$as_me:$LINENO: checking for build with symbols" >&5 echo $ECHO_N "checking for build with symbols... $ECHO_C" >&6 # Check whether --enable-symbols or --disable-symbols was given. if test "${enable_symbols+set}" = set; then enableval="$enable_symbols" tcl_ok=$enableval else tcl_ok=no fi; if test "$tcl_ok" = "no"; then CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}" LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}" echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 else CFLAGS_DEFAULT="${CFLAGS_DEBUG}" LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}" if test "$tcl_ok" = "yes"; then echo "$as_me:$LINENO: result: yes (standard debugging)" >&5 echo "${ECHO_T}yes (standard debugging)" >&6 fi fi if test "${TEA_PLATFORM}" != "windows" ; then LDFLAGS_DEFAULT="${LDFLAGS}" fi if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then cat >>confdefs.h <<\_ACEOF #define TCL_MEM_DEBUG 1 _ACEOF fi if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then if test "$tcl_ok" = "all"; then echo "$as_me:$LINENO: result: enabled symbols mem debugging" >&5 echo "${ECHO_T}enabled symbols mem debugging" >&6 else echo "$as_me:$LINENO: result: enabled $tcl_ok debugging" >&5 echo "${ECHO_T}enabled $tcl_ok debugging" >&6 fi fi #-------------------------------------------------------------------- # Everyone should be linking against the Tcl stub library. If you # can't for some reason, remove this definition. If you aren't using # stubs, you also need to modify the SHLIB_LD_LIBS setting below to # link against the non-stubbed Tcl library. Add Tk too if necessary. #-------------------------------------------------------------------- # allan: can't use stubs, due to BLT dependency #AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs]) #AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs]) #-------------------------------------------------------------------- # This macro generates a line to use when building a library. It # depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS, # and TEA_LOAD_TCLCONFIG macros above. #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then MAKE_STATIC_LIB="\${STLIB_LD} -out:\$@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\$@ \$(PKG_OBJECTS)" MAKE_STUB_LIB="\${STLIB_LD} -out:\$@ \$(PKG_STUB_OBJECTS)" else MAKE_STATIC_LIB="\${STLIB_LD} \$@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} -o \$@ \$(PKG_OBJECTS) \${LDFLAGS_DEFAULT} \${SHLIB_LD_LIBS}" MAKE_STUB_LIB="\${STLIB_LD} \$@ \$(PKG_STUB_OBJECTS)" fi if test "${SHARED_BUILD}" = "1" ; then MAKE_LIB="${MAKE_SHARED_LIB} " else MAKE_LIB="${MAKE_STATIC_LIB} " fi #-------------------------------------------------------------------- # Shared libraries and static libraries have different names. # Use the double eval to make sure any variables in the suffix is # substituted. (@@@ Might not be necessary anymore) #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" ; then if test "${SHARED_BUILD}" = "1" ; then # We force the unresolved linking of symbols that are really in # the private libraries of Tcl and Tk. SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_LIB_FILE}`\"" if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_LIB_FILE}`\"" fi eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" else eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" fi # Some packages build there own stubs libraries eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" # These aren't needed on Windows (either MSVC or gcc) RANLIB=: RANLIB_STUB=: else RANLIB_STUB="${RANLIB}" if test "${SHARED_BUILD}" = "1" ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_LIB_SPEC}" if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_LIB_SPEC}" fi eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" RANLIB=: else eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" fi # Some packages build there own stubs libraries eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" fi # These are escaped so that only CFLAGS is picked up at configure time. # The other values will be substituted at make time. CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}" if test "${SHARED_BUILD}" = "1" ; then CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}" fi #-------------------------------------------------------------------- # Determine the name of the tclsh and/or wish executables in the # Tcl and Tk build directories or the location they were installed # into. These paths are used to support running test cases only, # the Makefile should not be making use of these paths to generate # a pkgIndex.tcl file or anything else at extension build time. #-------------------------------------------------------------------- echo "$as_me:$LINENO: checking for tclsh" >&5 echo $ECHO_N "checking for tclsh... $ECHO_C" >&6 if test -f "${TCL_BIN_DIR}/Makefile" ; then # tclConfig.sh is in Tcl build directory if test "${TEA_PLATFORM}" = "windows"; then TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" else TCLSH_PROG="${TCL_BIN_DIR}/tclsh" fi else # tclConfig.sh is in install location if test "${TEA_PLATFORM}" = "windows"; then TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" else TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}" fi list="`ls -d ${TCL_PREFIX}/bin 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null`" for i in $list ; do if test -f "$i/${TCLSH_PROG}" ; then REAL_TCL_BIN_DIR="`cd "$i"; pwd`" break fi done TCLSH_PROG="${REAL_TCL_BIN_DIR}/${TCLSH_PROG}" fi echo "$as_me:$LINENO: result: ${TCLSH_PROG}" >&5 echo "${ECHO_T}${TCLSH_PROG}" >&6 echo "$as_me:$LINENO: checking for wish" >&5 echo $ECHO_N "checking for wish... $ECHO_C" >&6 if test -f "${TK_BIN_DIR}/Makefile" ; then # tkConfig.sh is in Tk build directory if test "${TEA_PLATFORM}" = "windows"; then WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" else WISH_PROG="${TK_BIN_DIR}/wish" fi else # tkConfig.sh is in install location if test "${TEA_PLATFORM}" = "windows"; then WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" else WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}" fi list="`ls -d ${TK_PREFIX}/bin 2>/dev/null` \ `ls -d ${TK_BIN_DIR}/../bin 2>/dev/null`" for i in $list ; do if test -f "$i/${WISH_PROG}" ; then REAL_TK_BIN_DIR="`cd "$i"; pwd`" break fi done WISH_PROG="${REAL_TK_BIN_DIR}/${WISH_PROG}" fi echo "$as_me:$LINENO: result: ${WISH_PROG}" >&5 echo "${ECHO_T}${WISH_PROG}" >&6 #-------------------------------------------------------------------- # These are for tclutilConfig.sh #-------------------------------------------------------------------- tclutil_LIB_FILE=${PKG_LIB_FILE} eval pkglibdir="${libdir}" if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then eval tclutil_LIB_FLAG="-ltclutil${PACKAGE_VERSION}" else eval tclutil_LIB_FLAG="-ltclutil`echo ${PACKAGE_VERSION} | tr -d .`" fi tclutil_BUILD_DIR="`pwd`" tclutil_BUILD_LIB_SPEC="-L`pwd` ${tclutil_LIB_FLAG}" tclutil_LIB_SPEC="-L${pkglibdir} ${tclutil_LIB_FLAG}" for i in ${PKG_OBJECTS} ; do tclutil_PKG_OBJECTS="$tclutil_PKG_OBJECTS ../tclutil/$i" done # tclutil_SRC_DIR must be a fully qualified path eval tclutil_SRC_DIR="$srcdir" tclutil_SRC_DIR=`cd "${tclutil_SRC_DIR}"; pwd` #-------------------------------------------------------------------- # Finally, substitute all of the various values into the Makefile. # You may alternatively have a special pkgIndex.tcl.in or other files # which require substituting th AC variables in. Include these here. #-------------------------------------------------------------------- ac_config_files="$ac_config_files Makefile pkgIndex.tcl tclutilConfig.sh tclutil.sh tclutil_version.tcl" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. { (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } | sed ' t clear : clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ : end' >>confcache if diff $cache_file confcache >/dev/null 2>&1; then :; else if test -w $cache_file; then test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" cat confcache >$cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/; s/:*\${srcdir}:*/:/; s/:*@srcdir@:*/:/; s/^\([^=]*=[ ]*\):*/\1/; s/:*$//; s/^[^=]*=[ ]*$//; }' fi # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then we branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. cat >confdef2opt.sed <<\_ACEOF t clear : clear s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g t quote s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g t quote d : quote s,[ `~#$^&*(){}\\|;'"<>?],\\&,g s,\[,\\&,g s,\],\\&,g s,\$,$$,g p _ACEOF # We use echo to avoid assuming a particular line-breaking character. # The extra dot is to prevent the shell from consuming trailing # line-breaks from the sub-command output. A line-break within # single-quotes doesn't work because, if this script is created in a # platform that uses two characters for line-breaks (e.g., DOS), tr # would break. ac_LF_and_DOT=`echo; echo .` DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` rm -f confdef2opt.sed ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_i=`echo "$ac_i" | sed 's/\$U\././;s/\.o$//;s/\.obj$//'` # 2. Add them. ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH exec 6>&1 # Open the log real soon, to keep \$[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. Logging --version etc. is OK. exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX } >&5 cat >&5 <<_CSEOF This file was extended by tclutil $as_me 2.1.0, which was generated by Starlink Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ _CSEOF echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 echo >&5 _ACEOF # Files that config.status was made for. if test -n "$ac_config_files"; then echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS fi if test -n "$ac_config_headers"; then echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS fi if test -n "$ac_config_links"; then echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS fi if test -n "$ac_config_commands"; then echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS fi cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ tclutil config.status 2.1.0 configured by $0, generated by Starlink Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2003 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." srcdir=$srcdir INSTALL="$INSTALL" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "x$1" : 'x\([^=]*\)='` ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` ac_shift=: ;; -*) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; *) # This is not an option, so the user has probably given explicit # arguments. ac_option=$1 ac_need_defaults=false;; esac case $ac_option in # Handling of the options. _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --vers* | -V ) echo "$ac_cs_version"; exit 0 ;; --he | --h) # Conflict between --help and --header { { echo "$as_me:$LINENO: error: ambiguous option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_config_target in $ac_config_targets do case "$ac_config_target" in # Handling of arguments. "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; "pkgIndex.tcl" ) CONFIG_FILES="$CONFIG_FILES pkgIndex.tcl" ;; "tclutilConfig.sh" ) CONFIG_FILES="$CONFIG_FILES tclutilConfig.sh" ;; "tclutil.sh" ) CONFIG_FILES="$CONFIG_FILES tclutil.sh" ;; "tclutil_version.tcl" ) CONFIG_FILES="$CONFIG_FILES tclutil_version.tcl" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason to put it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Create a temporary directory, and hook for its removal unless debugging. $debug || { trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./confstat$$-$RANDOM (umask 077 && mkdir $tmp) } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "\$CONFIG_FILES"; then # Protect against being on the right side of a sed subst in config.status. sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF s,@SHELL@,$SHELL,;t t s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t s,@exec_prefix@,$exec_prefix,;t t s,@prefix@,$prefix,;t t s,@program_transform_name@,$program_transform_name,;t t s,@bindir@,$bindir,;t t s,@sbindir@,$sbindir,;t t s,@libexecdir@,$libexecdir,;t t s,@datadir@,$datadir,;t t s,@sysconfdir@,$sysconfdir,;t t s,@sharedstatedir@,$sharedstatedir,;t t s,@localstatedir@,$localstatedir,;t t s,@libdir@,$libdir,;t t s,@includedir@,$includedir,;t t s,@oldincludedir@,$oldincludedir,;t t s,@infodir@,$infodir,;t t s,@mandir@,$mandir,;t t s,@build_alias@,$build_alias,;t t s,@host_alias@,$host_alias,;t t s,@target_alias@,$target_alias,;t t s,@DEFS@,$DEFS,;t t s,@ECHO_C@,$ECHO_C,;t t s,@ECHO_N@,$ECHO_N,;t t s,@ECHO_T@,$ECHO_T,;t t s,@LIBS@,$LIBS,;t t s,@CYGPATH@,$CYGPATH,;t t s,@EXEEXT@,$EXEEXT,;t t s,@PKG_LIB_FILE@,$PKG_LIB_FILE,;t t s,@PKG_STUB_LIB_FILE@,$PKG_STUB_LIB_FILE,;t t s,@PKG_STUB_SOURCES@,$PKG_STUB_SOURCES,;t t s,@PKG_STUB_OBJECTS@,$PKG_STUB_OBJECTS,;t t s,@PKG_TCL_SOURCES@,$PKG_TCL_SOURCES,;t t s,@PKG_HEADERS@,$PKG_HEADERS,;t t s,@PKG_INCLUDES@,$PKG_INCLUDES,;t t s,@PKG_LIBS@,$PKG_LIBS,;t t s,@PKG_CFLAGS@,$PKG_CFLAGS,;t t s,@TCL_VERSION@,$TCL_VERSION,;t t s,@TCL_BIN_DIR@,$TCL_BIN_DIR,;t t s,@TCL_SRC_DIR@,$TCL_SRC_DIR,;t t s,@TCL_LIB_FILE@,$TCL_LIB_FILE,;t t s,@TCL_LIB_FLAG@,$TCL_LIB_FLAG,;t t s,@TCL_LIB_SPEC@,$TCL_LIB_SPEC,;t t s,@TCL_STUB_LIB_FILE@,$TCL_STUB_LIB_FILE,;t t s,@TCL_STUB_LIB_FLAG@,$TCL_STUB_LIB_FLAG,;t t s,@TCL_STUB_LIB_SPEC@,$TCL_STUB_LIB_SPEC,;t t s,@TCL_LIBS@,$TCL_LIBS,;t t s,@TCL_DEFS@,$TCL_DEFS,;t t s,@TCL_EXTRA_CFLAGS@,$TCL_EXTRA_CFLAGS,;t t s,@TCL_LD_FLAGS@,$TCL_LD_FLAGS,;t t s,@TCL_SHLIB_LD_LIBS@,$TCL_SHLIB_LD_LIBS,;t t s,@TK_VERSION@,$TK_VERSION,;t t s,@TK_BIN_DIR@,$TK_BIN_DIR,;t t s,@TK_SRC_DIR@,$TK_SRC_DIR,;t t s,@TK_LIB_FILE@,$TK_LIB_FILE,;t t s,@TK_LIB_FLAG@,$TK_LIB_FLAG,;t t s,@TK_LIB_SPEC@,$TK_LIB_SPEC,;t t s,@TK_STUB_LIB_FILE@,$TK_STUB_LIB_FILE,;t t s,@TK_STUB_LIB_FLAG@,$TK_STUB_LIB_FLAG,;t t s,@TK_STUB_LIB_SPEC@,$TK_STUB_LIB_SPEC,;t t s,@TK_LIBS@,$TK_LIBS,;t t s,@TK_XINCLUDES@,$TK_XINCLUDES,;t t s,@CC@,$CC,;t t s,@CFLAGS@,$CFLAGS,;t t s,@LDFLAGS@,$LDFLAGS,;t t s,@CPPFLAGS@,$CPPFLAGS,;t t s,@ac_ct_CC@,$ac_ct_CC,;t t s,@OBJEXT@,$OBJEXT,;t t s,@CPP@,$CPP,;t t s,@CXX@,$CXX,;t t s,@CXXFLAGS@,$CXXFLAGS,;t t s,@ac_ct_CXX@,$ac_ct_CXX,;t t s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t s,@INSTALL_DATA@,$INSTALL_DATA,;t t s,@SET_MAKE@,$SET_MAKE,;t t s,@RANLIB@,$RANLIB,;t t s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t s,@EGREP@,$EGREP,;t t s,@MATH_LIBS@,$MATH_LIBS,;t t s,@SHLIB_LD_CXX_LIBS@,$SHLIB_LD_CXX_LIBS,;t t s,@PKG_SOURCES@,$PKG_SOURCES,;t t s,@PKG_OBJECTS@,$PKG_OBJECTS,;t t s,@CLEANFILES@,$CLEANFILES,;t t s,@TCL_INCLUDES@,$TCL_INCLUDES,;t t s,@TK_INCLUDES@,$TK_INCLUDES,;t t s,@TCL_THREADS@,$TCL_THREADS,;t t s,@SHARED_BUILD@,$SHARED_BUILD,;t t s,@AR@,$AR,;t t s,@CELIB_DIR@,$CELIB_DIR,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@SHLIB_SUFFIX@,$SHLIB_SUFFIX,;t t s,@DL_LIBS@,$DL_LIBS,;t t s,@CFLAGS_DEBUG@,$CFLAGS_DEBUG,;t t s,@CFLAGS_OPTIMIZE@,$CFLAGS_OPTIMIZE,;t t s,@CFLAGS_WARNING@,$CFLAGS_WARNING,;t t s,@STLIB_LD@,$STLIB_LD,;t t s,@SHLIB_LD@,$SHLIB_LD,;t t s,@SHLIB_CFLAGS@,$SHLIB_CFLAGS,;t t s,@SHLIB_LD_LIBS@,$SHLIB_LD_LIBS,;t t s,@LDFLAGS_DEBUG@,$LDFLAGS_DEBUG,;t t s,@LDFLAGS_OPTIMIZE@,$LDFLAGS_OPTIMIZE,;t t s,@LD_LIBRARY_PATH_VAR@,$LD_LIBRARY_PATH_VAR,;t t s,@BLT_LIB_DIR@,$BLT_LIB_DIR,;t t s,@BLT_LIB_SPEC@,$BLT_LIB_SPEC,;t t s,@TCL_DBGX@,$TCL_DBGX,;t t s,@CFLAGS_DEFAULT@,$CFLAGS_DEFAULT,;t t s,@LDFLAGS_DEFAULT@,$LDFLAGS_DEFAULT,;t t s,@MAKE_LIB@,$MAKE_LIB,;t t s,@MAKE_SHARED_LIB@,$MAKE_SHARED_LIB,;t t s,@MAKE_STATIC_LIB@,$MAKE_STATIC_LIB,;t t s,@MAKE_STUB_LIB@,$MAKE_STUB_LIB,;t t s,@RANLIB_STUB@,$RANLIB_STUB,;t t s,@TCLSH_PROG@,$TCLSH_PROG,;t t s,@WISH_PROG@,$WISH_PROG,;t t s,@tclutil_LIB_FILE@,$tclutil_LIB_FILE,;t t s,@tclutil_BUILD_DIR@,$tclutil_BUILD_DIR,;t t s,@tclutil_BUILD_LIB_SPEC@,$tclutil_BUILD_LIB_SPEC,;t t s,@tclutil_LIB_SPEC@,$tclutil_LIB_SPEC,;t t s,@tclutil_PKG_OBJECTS@,$tclutil_PKG_OBJECTS,;t t s,@tclutil_SRC_DIR@,$tclutil_SRC_DIR,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_lines=48 ac_sed_frag=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_lines # Line after last line for current file. ac_more_lines=: ac_sed_cmds= while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag else sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag fi if test ! -s $tmp/subs.frag; then ac_more_lines=false else # The purpose of the label and of the branching condition is to # speed up the sed processing (if there are no `@' at all, there # is no need to browse any of the substitutions). # These are the two extra sed commands mentioned above. (echo ':t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" else ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" fi ac_sed_frag=`expr $ac_sed_frag + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_lines` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi fi # test -n "$CONFIG_FILES" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_builddir$INSTALL ;; esac if test x"$ac_file" != x-; then { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} rm -f "$ac_file" fi # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then configure_input= else configure_input="$ac_file. " fi configure_input=$configure_input"Generated from `echo $ac_file_in | sed 's,.*/,,'` by configure." # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo "$f";; *) # Relative if test -f "$f"; then # Build tree echo "$f" elif test -f "$srcdir/$f"; then # Source tree echo "$srcdir/$f" else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s,@configure_input@,$configure_input,;t t s,@srcdir@,$ac_srcdir,;t t s,@abs_srcdir@,$ac_abs_srcdir,;t t s,@top_srcdir@,$ac_top_srcdir,;t t s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t s,@builddir@,$ac_builddir,;t t s,@abs_builddir@,$ac_abs_builddir,;t t s,@top_builddir@,$ac_top_builddir,;t t s,@abs_top_builddir@,$ac_abs_top_builddir,;t t s,@INSTALL@,$ac_INSTALL,;t t " $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out rm -f $tmp/stdin if test x"$ac_file" != x-; then mv $tmp/out $ac_file else cat $tmp/out rm -f $tmp/out fi done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi chmod ugo+x tclutil.sh skycat-3.1.2-starlink-1b/tclutil/configure.in000066400000000000000000000225501215713201500211320ustar00rootroot00000000000000# E.S.O. - VLT project # $Id: configure.in,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # This file is used with GNU autoconf to generate a configure script # # usage: % autoconf # only if configure.in changed # % configure # % make # % make install # # who when what # -------------- -------- --------------------------------------------- # Allan Brighton 15/12/05 Rewrote using TCL TEA standard # ----------------------------------------------------------------------- #----------------------------------------------------------------------- # Sample configure.in for Tcl Extensions. The only places you should # need to modify this file are marked by the string __CHANGE__ #----------------------------------------------------------------------- #----------------------------------------------------------------------- # __CHANGE__ # Set your package name and version numbers here. # # This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION # set as provided. These will also be added as -D defs in your Makefile # so you can encode the package version directly into the source files. #----------------------------------------------------------------------- AC_INIT([tclutil], [2.1.0]) #-------------------------------------------------------------------- # Call TEA_INIT as the first TEA_ macro to set up initial vars. # This will define a ${TEA_PLATFORM} variable == "unix" or "windows" # as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE. #-------------------------------------------------------------------- TEA_INIT([3.4]) #-------------------------------------------------------------------- # Load the tclConfig.sh file #-------------------------------------------------------------------- TEA_PATH_TCLCONFIG TEA_LOAD_TCLCONFIG #-------------------------------------------------------------------- # Load the tkConfig.sh file if necessary (Tk extension) #-------------------------------------------------------------------- TEA_PATH_TKCONFIG TEA_LOAD_TKCONFIG #----------------------------------------------------------------------- # Handle the --prefix=... option by defaulting to what Tcl gave. # Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER. #----------------------------------------------------------------------- TEA_PREFIX #----------------------------------------------------------------------- # Standard compiler checks. # This sets up CC by using the CC env var, or looks for gcc otherwise. # This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create # the basic setup necessary to compile executables. #----------------------------------------------------------------------- TEA_SETUP_COMPILER #----------------------------------------------------------------------- # Do application specific checks (see aclocal.m4), after compiler setup. #----------------------------------------------------------------------- TCLUTIL_CONFIG #----------------------------------------------------------------------- # __CHANGE__ # Specify the C source files to compile in TEA_ADD_SOURCES, # public headers that need to be installed in TEA_ADD_HEADERS, # stub library C source files to compile in TEA_ADD_STUB_SOURCES, # and runtime Tcl library files in TEA_ADD_TCL_SOURCES. # This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS # and PKG_TCL_SOURCES. #----------------------------------------------------------------------- changequote(<<, >>) csources=`cd $srcdir; echo generic/*.[Cc]` changequote([, ]) cheaders=`cd $srcdir; echo generic/*.h` cincludes="-I. -I$srcdir/bitmaps -I$srcdir/generic" tclsources=`cd $srcdir; echo library/*.tcl` TEA_ADD_SOURCES([${csources}]) TEA_ADD_HEADERS([${cheaders}]) TEA_ADD_INCLUDES([$cincludes]) dnl TEA_ADD_LIBS([${BLT_LIB_SPEC}]) TEA_ADD_CFLAGS([]) TEA_ADD_STUB_SOURCES([]) TEA_ADD_TCL_SOURCES([${tclsources}]) #-------------------------------------------------------------------- # __CHANGE__ # A few miscellaneous platform-specific items: # # Define a special symbol for Windows (BUILD_sample in this case) so # that we create the export library with the dll. # # Windows creates a few extra files that need to be cleaned up. # You can add more files to clean if your extension creates any extra # files. # # TEA_ADD_* any platform specific compiler/build info here. #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" ; then AC_DEFINE(BUILD_tclutil, 1, [Build windows export dll]) CLEANFILES="*.lib *.dll *.exp *.ilk *.pdb vc*.pch" #TEA_ADD_SOURCES([win/winFile.c]) #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"]) else CLEANFILES="" #TEA_ADD_SOURCES([unix/unixFile.c]) #TEA_ADD_LIBS([-lsuperfly]) fi AC_SUBST(CLEANFILES) #-------------------------------------------------------------------- # __CHANGE__ # Choose which headers you need. Extension authors should try very # hard to only rely on the Tcl public header files. Internal headers # contain private data structures and are subject to change without # notice. # This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG #-------------------------------------------------------------------- TEA_PUBLIC_TCL_HEADERS #TEA_PRIVATE_TCL_HEADERS TEA_PUBLIC_TK_HEADERS #TEA_PRIVATE_TK_HEADERS TEA_PATH_X #-------------------------------------------------------------------- # Check whether --enable-threads or --disable-threads was given. # This auto-enables if Tcl was compiled threaded. #-------------------------------------------------------------------- TEA_ENABLE_THREADS #-------------------------------------------------------------------- # The statement below defines a collection of symbols related to # building as a shared library instead of a static library. #-------------------------------------------------------------------- TEA_ENABLE_SHARED #-------------------------------------------------------------------- # This macro figures out what flags to use with the compiler/linker # when building shared/static debug/optimized objects. This information # can be taken from the tclConfig.sh file, but this figures it all out. #-------------------------------------------------------------------- TEA_CONFIG_CFLAGS #----------------------------------------------------------------------- # Find -lBLT library (needs variable set indirectly by TEA_CONFIG_CFLAGS: SHLIB_SUFFIX) TCLUTIL_PATH_BLT TEA_ADD_LIBS([${BLT_LIB_SPEC}]) #----------------------------------------------------------------------- #-------------------------------------------------------------------- # Set the default compiler switches based on the --enable-symbols option. #-------------------------------------------------------------------- TEA_ENABLE_SYMBOLS #-------------------------------------------------------------------- # Everyone should be linking against the Tcl stub library. If you # can't for some reason, remove this definition. If you aren't using # stubs, you also need to modify the SHLIB_LD_LIBS setting below to # link against the non-stubbed Tcl library. Add Tk too if necessary. #-------------------------------------------------------------------- # allan: can't use stubs, due to BLT dependency #AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs]) #AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs]) #-------------------------------------------------------------------- # This macro generates a line to use when building a library. It # depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS, # and TEA_LOAD_TCLCONFIG macros above. #-------------------------------------------------------------------- TEA_MAKE_LIB #-------------------------------------------------------------------- # Determine the name of the tclsh and/or wish executables in the # Tcl and Tk build directories or the location they were installed # into. These paths are used to support running test cases only, # the Makefile should not be making use of these paths to generate # a pkgIndex.tcl file or anything else at extension build time. #-------------------------------------------------------------------- TEA_PROG_TCLSH TEA_PROG_WISH #-------------------------------------------------------------------- # These are for tclutilConfig.sh #-------------------------------------------------------------------- tclutil_LIB_FILE=${PKG_LIB_FILE} eval pkglibdir="${libdir}" if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then eval tclutil_LIB_FLAG="-ltclutil${PACKAGE_VERSION}" else eval tclutil_LIB_FLAG="-ltclutil`echo ${PACKAGE_VERSION} | tr -d .`" fi tclutil_BUILD_DIR="`pwd`" tclutil_BUILD_LIB_SPEC="-L`pwd` ${tclutil_LIB_FLAG}" tclutil_LIB_SPEC="-L${pkglibdir} ${tclutil_LIB_FLAG}" for i in ${PKG_OBJECTS} ; do tclutil_PKG_OBJECTS="$tclutil_PKG_OBJECTS ../tclutil/$i" done AC_SUBST(tclutil_LIB_FILE) AC_SUBST(tclutil_BUILD_DIR) AC_SUBST(tclutil_BUILD_LIB_SPEC) AC_SUBST(tclutil_LIB_SPEC) AC_SUBST(tclutil_PKG_OBJECTS) # tclutil_SRC_DIR must be a fully qualified path eval tclutil_SRC_DIR="$srcdir" tclutil_SRC_DIR=`cd "${tclutil_SRC_DIR}"; pwd` AC_SUBST(tclutil_SRC_DIR) #-------------------------------------------------------------------- # Finally, substitute all of the various values into the Makefile. # You may alternatively have a special pkgIndex.tcl.in or other files # which require substituting th AC variables in. Include these here. #-------------------------------------------------------------------- AC_OUTPUT([Makefile pkgIndex.tcl tclutilConfig.sh tclutil.sh tclutil_version.tcl]) chmod ugo+x tclutil.sh skycat-3.1.2-starlink-1b/tclutil/generic/000077500000000000000000000000001215713201500202315ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/tclutil/generic/Blt_GraphElement.c000066400000000000000000000055501215713201500235560ustar00rootroot00000000000000/* * E.S.O. - VLT project / ESO Archive * * Blt_GraphElement.c - replacement for the cancelled blt convenience function * * who when what * -------------- -------- ---------------------------------------- * PBi 21/02/97 Created */ #include "tcl.h" /* * Hack: Rather than have to worry about finding out where blt.h is, * just include the required definitions here (I don't expect this * package to change much anymore). -- Allan: 03.01.06 */ #if 0 #include "blt.h" #else typedef struct { double *valueArr; /* Array of values (possibly malloc-ed) */ int numValues; /* Number of values in the array */ int arraySize; /* Size of the allocated space */ double min, max; /* Minimum and maximum values in the vector */ int dirty; /* Indicates if the vector has been updated */ int reserved; /* Reserved for future use */ } Blt_Vector; int Blt_GetVector _ANSI_ARGS_((Tcl_Interp *interp, char *vecName, Blt_Vector **vecPtrPtr)); int Blt_ResetVector _ANSI_ARGS_((Blt_Vector *vecPtr, double *dataArr, int nValues, int arraySize, Tcl_FreeProc *freeProc)); #endif /* Replacement for the cancelled blt convenience function */ int Blt_GraphElement( Tcl_Interp *interp, /* Interpreter of the graph widget */ char *pathName, /* Path name of the graph widget */ char *elemName, /* Name of the element to reset */ int numValues, /* Number of values in array */ double *valueArr, /* Array of x,y coordinate pairs */ char *xVecName, /* Name of x array */ char *yVecName) /* Name of y array */ { register int i; int num = numValues/2; int nbytes = sizeof(double) * num; /* Note: Blt_Vector::arraySize is the number of bytes bytes! */ Blt_Vector *xVecPtr, *yVecPtr; double *xArray, *yArray; if (Blt_GetVector(interp, xVecName, &xVecPtr) != 0 || Blt_GetVector(interp, yVecName, &yVecPtr) != 0) return TCL_ERROR; /* Allocate space for the new vectors, if needed */ if (xVecPtr->arraySize < nbytes) { xArray = (double *)Tcl_Alloc(nbytes); yArray = (double *)Tcl_Alloc(nbytes); if (xArray == NULL || yArray == NULL) { fprintf(stderr, "malloc: out of memory\n"); return TCL_ERROR; } } else { /* reuse existing arrays */ xArray = xVecPtr->valueArr; yArray = yVecPtr->valueArr; nbytes = xVecPtr->arraySize; } /* Write the data points into the vectors */ for (i = 0; i < num; i++) { xArray[i] = *valueArr++; yArray[i] = *valueArr++; } if ((Blt_ResetVector(xVecPtr, xArray, num, nbytes, TCL_DYNAMIC) != TCL_OK) || (Blt_ResetVector(yVecPtr, yArray, num, nbytes, TCL_DYNAMIC) != TCL_OK)) { return TCL_ERROR; } return TCL_OK; } skycat-3.1.2-starlink-1b/tclutil/generic/ErrorHandler.C000066400000000000000000000033131215713201500227240ustar00rootroot00000000000000/* * E.S.O. - VLT project * "@(#) $Id: ErrorHandler.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * ErrorHandler.C - class definitions for catching X errors in Tk * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * pbiereic 17/02/03 Added 'using namespace std'. Removed ::std specs. */ static const char* const rcsId="@(#) $Id: ErrorHandler.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include #include #include #include "error.h" #include "ErrorHandler.h" using namespace std; /* * install an X error handler */ int ErrorHandler::install() { xErrorFlag_ = 0; errHandle_ = Tk_CreateErrorHandler(display_, -1, -1, -1, errorProc, (ClientData)this); return 0; } /* * de-install the X error handler */ int ErrorHandler::remove() { if (errHandle_) { Tk_DeleteErrorHandler(errHandle_); errHandle_ = NULL; } return 0; } /* * this static method is called for X protocal errors */ int ErrorHandler::errorProc(ClientData clientData, XErrorEvent *errEventPtr) { ErrorHandler* thisPtr = (ErrorHandler*)clientData; return thisPtr->error(errEventPtr); } /* * this virtual method is called to handle X protocal errors. * It should not do anything directly with X, but should only * note the error for later. */ int ErrorHandler::error(XErrorEvent *errEventPtr) { xErrorFlag_++; if (verbose_) { char msg[80]; XGetErrorText(display_, errEventPtr->error_code, msg, sizeof(msg)); cout << "X Error: " << msg << endl; ::error("X Error: ", msg); } return TCL_OK; } skycat-3.1.2-starlink-1b/tclutil/generic/ErrorHandler.h000066400000000000000000000040021215713201500227650ustar00rootroot00000000000000// -*-c++-*- #ifndef _ErrorHandler_H_ #define _ErrorHandler_H_ /* * E.S.O. - VLT project * "@(#) $Id: ErrorHandler.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * ErrorHandler.h - class for managing Tk Error Handler for catching * X errors * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created */ #include /* * This class is used to install and remove Tk X error handlers * in order to catch X errors and deal with them. * * Usage:ErrorHandler errorHandler(display, verbose_flag); * ... (something that might produce X errors) * if (errorHandler.errors()) {// errors occurred ... } */ class ErrorHandler { protected: Display* display_; // X Display pointer Tk_ErrorHandler errHandle_; // error handler handle returned from Tk int xErrorFlag_; // flag: true if an X protocol error occurred // and an error handler is installed int verbose_; // flag: if true, print diagnostic messages // -- member functions -- // called for X protocal errors when errorHandler is installed virtual int error(XErrorEvent*); public: // constructor ErrorHandler(Display* display, int verbose = 1) : display_(display), errHandle_(NULL), xErrorFlag_(0), verbose_(verbose) {install();} // destructor // the call to XSync flushes any pending errors virtual ~ErrorHandler() {XSync(display_, False); remove();} // static version of error handler, called from Tk static int errorProc(ClientData clientData, XErrorEvent *errEventPtr); // install/remove an X error handler int install(); int remove(); // return 1 if errors occurred // the call to XSync is necessary to avoid delays due to X buffering int errors() {XSync(display_, False); return xErrorFlag_;} // reset the error flag int reset() {xErrorFlag_ = 0; return 0;} }; #endif /* _ErrorHandler_H_ */ skycat-3.1.2-starlink-1b/tclutil/generic/HTTP.C000066400000000000000000000743571215713201500211340ustar00rootroot00000000000000 /* * E.S.O. - VLT project/ESO Archive * $Id: HTTP.C,v 1.2 2010/07/21 19:42:46 cguirao Exp $ * * HTTP.C - method definitions for class HTTP * (based on code from DSS:HTTP.c by Miguell Albrecht) * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 95 Created * Peter W. Draper 16 Jun 98 Added support for web proxy servers. * 06 Aug 01 Added "Host:" header for interception * proxy support. * 21 Jan 03 Changed to work with UNIX permissions * after gcc3 looses a non-standard * ofstream constructor. * pbiereic 17/02/03 Added 'using namespace std'. Removed ::std specs. * Peter W. Draper 06 Apr 09 Increase size of host buffers to 64 from 32. */ static const char* const rcsId="@(#) $Id: HTTP.C,v 1.2 2010/07/21 19:42:46 cguirao Exp $"; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "error.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "util.h" #include "base64.h" #include "HTTP.h" using namespace std; #ifdef NEED_SOCKET_PROTO // some protos missing in SunOS /* extern "C" { int socket(int, int, int); int connect(int, const void*, int); int strncasecmp(char*, char*, int); } */ #endif /* NEED_SOCKET_PROTO */ // this flag is made static to make it easy to turn on and off. // If true, allow a URL to be a command to exec int HTTP::allowUrlExec_ = 0; // HTTP authorization info, set with authorize(user, passwd, ...) char* HTTP::auth_info_ = NULL; // base64 encoded "username:passwd" // Using "User-Agent: SkyCat/1.0" is historical - this source used to be // part of skycat. Changing this might cause problems with existing catalog // or image servers (HST previews, in particular). char* HTTP::user_agent_ = NULL; const char* default_user_agent_ = "SkyCat/1.0"; // This sets the default name for the file used to store authorization info // (host, realm, encoded(user:passwd)) used to access restricted HTTP sites. // The information is stored in this file after an HTTP GET returns an // "Authorization Required" result and the user supplies the username and // password. The "~" will be replaced with getenv(HOME). char* HTTP::auth_file_ = NULL; const char* default_auth_file_ = "~/.http_auth"; /* * constructor - open a connection to the httpd server on the * given host/port */ HTTP::HTTP() : status_(0), port_(-1), proxyport_(-1), fd_(-1), feedback_(NULL), content_type_(NULL), content_encoding_(NULL), content_length_(0), location_(NULL), www_auth_realm_(NULL), resultBuf_(NULL), resultGC_(NULL), resultPtr_(NULL) { strcpy(hostname_, "localhost"); proxyname_[0] = '\0'; } /* * destructor - close the connection */ HTTP::~HTTP() { if (fd_ >= 0) close(fd_); if (resultGC_) { free( resultGC_ ); resultGC_ = NULL; } reset(); } /* * take an error message in HTML format from the given stream and pass it * on to error(), stripped of HTML syntax (<...>) */ int HTTP::html_error(istream& is) { char buf[1024*2]; is.read(buf, sizeof(buf)); int n = is.gcount(); if (n > 0) { buf[n-1] = '\0'; return html_error(buf); } return 0; } /* * Take an error message in HTML format and pass it on to error(), * stripped of HTML syntax (<...>). */ int HTTP::html_error(char* s) { // other HTML error message, filter out HTML syntax char* p = s; char* q = s; while (*p) { if (*p == '<') { while (*p && *p != '>') p++; } else if (*p == '>') { p++; } else if (*p == '\r') { p++; } else *q++ = *p++; } *q = '\0'; return error("HTTP error: ", s); } /* * set the file ptr to use for feedback during http transfers */ void HTTP::feedback(FILE* f) { feedback_ = f; } /* * open the connection to the given host and port and set the member * variable fd_ to the open socket descriptor. * * Returns 0 on success, 1 for error. */ int HTTP::open(const char* hostname, int port) { // close previous connection if (fd_ >= 0) close(fd_); // see if its the same host/port as last time... if (port != port_ || strcmp(hostname, hostname_) != 0) { strncpy(hostname_, hostname, sizeof(hostname_)-1); port_ = port; // reset authorization info for new server if (auth_info_) { free(auth_info_); auth_info_ = NULL; } if (feedback_) { fprintf(feedback_, "opening connection to %s:%d...\n", hostname, port); fflush(feedback_); } // Fill in the structure "servAddr_" with the address of the // server that we want to connect with. memset((char *)&servAddr_, '\0', sizeof(servAddr_)); // get host entry from hostname or IP address if (isdigit(hostname_[0])) { servAddr_.sin_addr.s_addr = inet_addr(hostname_); if ((int)servAddr_.sin_addr.s_addr == -1) return sys_error("malformed IP address: ", hostname); } else { hostent *host = gethostbyname(hostname); if (!host) return error("Can't find host IP address for: ", hostname); if (feedback_) { fprintf(feedback_, "connecting to %s:%d...\n", host->h_name, port); fflush(feedback_); } memcpy(&servAddr_.sin_addr, host->h_addr_list[0], host->h_length); } servAddr_.sin_family = AF_INET; servAddr_.sin_port = htons(port); } // Open a TCP socket (an Internet stream socket). if ((fd_ = socket(AF_INET, SOCK_STREAM, 0)) < 0) return sys_error("Can't open stream socket"); // Connect to the server. if (connect(fd_, (sockaddr *)&servAddr_, sizeof(servAddr_)) < 0) return sys_error("Can't connect to HTTP server ", hostname_); return 0; } /* * replace blanks or tabs in url with %20 and write the output in * new_url[size] */ static void replace_blanks(const char* url, char* new_url, int size) { int i = 0; for (const char* p = url; *p && i < size; p++, i++) { if (isspace(*p)) { strcpy(new_url, "%20"); new_url += 3; } else { *new_url++ = *p; } } *new_url = '\0'; } /* * Open the given local file and return the status. * Sets fd_ to the file desc. */ int HTTP::openFile(const char* filename) { if (fd_ >= 0) close(fd_); fd_ = ::open(filename, O_RDONLY); if (fd_ < 0) return sys_error("can't open file: ", filename); return 0; } /* * Run the given command and set fd_ to be positioned at the beginning of * the output. Return the status of the command (0 if ok). * * We run the command and put the output in a temp file, then open the * temp file so we can read it in the same way as the other URLS. We * could read it from a pipe, but that makes error handling more * complicated (system() returns the exit status of the command). */ int HTTP::openCommand(const char* command) { char cmd[2048]; char tmpfile[80]; strcpy(tmpfile, "/tmp/httpXXXXXX"); mkstemp(tmpfile); sprintf(cmd, "%s > %s", command, tmpfile); if (system(cmd) != 0) { error("error executing command: ", command); unlink(tmpfile); return 1; } // The command may or may not output an HTTP type header, // so we just peek at the first few lines to see if there // is one there and save the values. The return value is // the number of lines in the header, or 0 if there was // none. int nHeaderLines = checkCommandOutput(tmpfile); // open the file descriptor as for the HTTP GET socket... int status = openFile(tmpfile); unlink(tmpfile); // remove on close // skip over header lines, if any char buf[80]; for(int i = 0; i < nHeaderLines; i++) { readline(buf, sizeof(buf)); } return status; } /* * Scan the first few lines of the given file for HTTP header * info: Content-type, etc., and set the corresponding member * vars. * The return value is the number of lines in the header, * or 0 if there was none. * Note that we are not sure in this case whether the file contains * any header lines or not. */ int HTTP::checkCommandOutput(const char* filename) { ifstream is(filename); if (! is) return 0; char buf[80]; int nHeaderLines = 0; for(int i = 0; i < 5; i++) { if (is.getline(buf, sizeof(buf))) { if (strlen(buf) <= 2) { if (nHeaderLines > 0) nHeaderLines++; break; } if (strncasecmp(buf, "Content-Length:", 15) == 0) { nHeaderLines++; if (sscanf(buf+15, "%d", &content_length_) == 1) { if (feedback_) { fprintf(feedback_, "total length: %d bytes\n", content_length_); fflush(feedback_); } } } else if (strncasecmp(buf, "Content-type:", 13) == 0) { nHeaderLines++; // save the content-type for later reference content_type_ = strdup(stripWhiteSpace(buf+13)); } else if (strncasecmp(buf, "Content-Encoding:", 17) == 0) { nHeaderLines++; // save the content-type for later reference content_encoding_ = strdup(stripWhiteSpace(buf+17)); } else if (nHeaderLines == 0) { // ignore unknown header lines only if we have a header... break; } } } return nHeaderLines; } /* * Scan the given HTTP header line for any keywords that we are interested * in and save the values in member variables. */ void HTTP::scanHeaderLine(char* buf) { if (strncasecmp(buf, "Content-Length:", 15) == 0) { if (sscanf(buf+15, "%d", &content_length_) == 1) { if (feedback_) { fprintf(feedback_, "total length: %d bytes\n", content_length_); fflush(feedback_); } } } else if (strncasecmp(buf, "Content-type:", 13) == 0) { // save the content-type for later reference content_type_ = strdup(stripWhiteSpace(buf+13)); } else if (strncasecmp(buf, "Content-Encoding:", 17) == 0) { // save the content-type for later reference content_encoding_ = strdup(stripWhiteSpace(buf+17)); } else if (strncasecmp(buf, "Location:", 9) == 0) { // Redirect to a new URL location location_ = strdup(stripWhiteSpace(buf+9)); } else if (strncasecmp(buf, "WWW-Authenticate: Basic realm=\"", 31) == 0) { // Save the "realm" value (passwd domain) for later reference. // This also is an indication to the caller that a passwd is required. www_auth_realm_ = strdup(stripWhiteSpace(buf+31)); int n = strlen(www_auth_realm_)-1; if (n > 0) www_auth_realm_[n] = '\0'; // remove closing quote } } /* * reset any previous member values before a GET or POST */ void HTTP::reset() { if (content_type_) { free(content_type_); content_type_ = NULL; } if (content_encoding_) { free(content_encoding_); content_encoding_ = NULL; } if (www_auth_realm_) { free(www_auth_realm_); www_auth_realm_ = NULL; } if (location_) { free(location_); location_ = NULL; } content_length_ = 0; } /* * Set the username and password to use for authorization and, if realm * and server are given, save an entry in the auth_file for later * reference. * * This is normally called after an HTTP GET returned "401 Authorization * Required" and the user interface asked the user to type in a username * and password, but could also be called at other times, if the * necessary information is available. * * The server name can be obtained via the hostname() method after * calling get(). The realm string is returned by the method * www_auth_realm() after a get(). These values are also included in the * error message generated when the "401 Authorization Required" HTTP * result is received. */ void HTTP::authorize(const char* username, const char* passwd, const char* realm, const char* server) { // encode the username and passwd if (auth_info_) { free(auth_info_); auth_info_ = NULL; } char auth_info[1024]; sprintf(auth_info, "%s:%s", username, passwd); auth_info_ = encode_base64(auth_info); // encoded result is allocated // if realm and server are specified, save an entry to the auth_file_ if (realm && server) addAuthFileEntry(server, realm); } /* * Set the name of the file to use to store and look for HTTP * authorization info. '~' is translated into $HOME in the pathname. */ void HTTP::authFile(const char* s) { if (auth_file_) { free(auth_file_); auth_file_ = NULL; } // replace '~' in auth_file_ if needed char filename[1024]; if (s[0] == '~') { char* home = getenv("HOME"); if (home) strcpy(filename, home); strcat(filename, s+1); auth_file_ = strdup(filename); } else auth_file_ = strdup(s); } /* * Set the value of the HTTP User-Agent to use with requests */ void HTTP::userAgent(const char* s) { if (user_agent_) free(user_agent_); user_agent_ = strdup(s); } /* * Add an entry to the auth_file_ for the given server and realm and the * the current value of auth_info_. The file has the format: * * server:realm:auth_info * * Where: server is the HTTP server hostname * realm is a string returned from the server (in the auth request) * auth_info is the base64 encoded "username:passwd" */ int HTTP::addAuthFileEntry(const char* server, const char* realm) { if (!auth_file_) authFile(default_auth_file_); ifstream is(auth_file_); ostringstream os; char newentry[1024]; sprintf(newentry, "%s:%s:%s", server, realm, auth_info_); char buf[1024]; int n = strlen(server) + strlen(realm) + 1; while(is.getline(buf, sizeof(buf))) { if (strncmp(buf, newentry, n) != 0) os << buf << endl; } is.close(); os << newentry << endl; // create the auth file with -rw------- perms //ofstream f(auth_file_, ios::out, 0600); ofstream f(auth_file_, ios::out); chmod(auth_file_, 0600); if (f) f << os.str(); f.close(); return 0; } /* * Search the auth_file_, if it exists, for an entry with the given server * and realm and set auth_info_ to the value found there. * Returns 0 if found, otherwise 1. */ int HTTP::findAuthFileEntry(const char* server, const char* realm) { if (!auth_file_) authFile(default_auth_file_); ifstream is(auth_file_); char entry[1024]; sprintf(entry, "%s:%s:", server, realm); int n = strlen(entry); char buf[1024]; while(is.getline(buf, sizeof(buf))) { if (strncmp(buf, entry, n) == 0) { char* new_auth_info = buf+n; if (auth_info_) { // if we find the same user/passwd information twice, it // probably means that the server rejected it and asked // for the password again. We have to return an error to // avoid an endless loop... if (strcmp(auth_info_, new_auth_info) == 0) return 1; free(auth_info_); } auth_info_ = strdup(new_auth_info); return 0; // found } } return 1; // not found } /* * This method is called when we receive a HTTP server request for * authorization (401). If we know the username and password, retry the * request with the encoded authorization info, otherwise, return a * special error message: "Authorization Required for at " * so that the user interface can pop up a password dialog and then * eventually call HTTP::authorize() with the username and password. */ int HTTP::getAuthorization(const char* url) { if (findAuthFileEntry(hostname_, www_auth_realm_) == 0) // found return get(url); return fmt_error("Authorization Required for %s at %s", www_auth_realm_, hostname_); } /* * Get the value of the given URL and position the read fd after the * http header. * * This method accepts 3 types of URL: * * - http://host/path - URL: do an HTTP get * * - file:/path - get the file * * - /path - command: exec the command and read the stdout * (must be turned on explicitly with HTTP::allowUrlExec(int)) * * Note that for http we have to open the connection once for each GET, * since HTTP automatically closes the connection after each GET. * * If an error occurs, 1 is returned, otherwise 0. Use readline() to * fetch the results. */ int HTTP::get(const char* url) { // reset any previous values reset(); // look for local file URL: "file:/..." if (strncmp(url, "file:", 5) == 0) { char filename[1024]; if (sscanf(url, "file:%1023s", filename) == 1) { if (openFile(filename) != 0) return 1; return 0; } return error("can't parse URL: %s", url); } // If its not a HTTP URL, it should be a local command to exec if (strncmp(url, "http:", 5) != 0) { if (allowUrlExec_) { return openCommand(url); } return error("invalid HTTP URL: ", url); } // look for URL: "http://host:port/args" or "http://host/args" char host[64]; // http host name int port = 80; // http server port on host char args[1024]; // part of URL after host:port char req[2048]; // request sent to http // replace blanks or tabs in request with %20 char new_url[1024]; replace_blanks(url, new_url, sizeof(new_url)); if (feedback_) { fprintf(feedback_, "url: %s\n", new_url); // mainly for debugging info fflush(feedback_); } if (sscanf(new_url, "http://%63[^:/]:%d%1000s", host, &port, args) != 3 && sscanf(new_url, "http://%63[^/]%1000s", host, args) != 2) { return error("bad URL format: ", new_url); } // open a connection to the http server on the given host/port, // make this the proxy server if necessary. Note we check the // proxy everytime so that it can be reconfigured on the fly (by // setting the http_proxy environment variable). This call also // checks if the host is in a domain that we do not want to proxy. checkProxy( host ); if ( proxyport_ == -1 ) { if (open(host, port) != 0) return 1; // error } else { if (open(proxyname_, proxyport_) != 0) return 1; // error // Request to proxy needs the fully qualified URL. strncpy( args, new_url, 1024 ); // The apparent hostname and port are now wrong. Change these // to values that make sense in the feedback messages. strncpy( hostname_, host, 64 ); port_ = port; } if (feedback_) { fprintf(feedback_, "sending request to %s...\n", hostname_); fflush(feedback_); } // generate the request ostringstream os; os << "GET " << args << " HTTP/1.0" << endl; // PWD: add the Host: header, this is required by some // interception proxy servers (these are transparent servers that // sniff port 80 traffic and don't require any client // configuration, this is a HTTP/1.1 standard header that does no // harm for 1.0). os << "Host: " << hostname_ << endl; // add the user-agent if (! user_agent_) userAgent(default_user_agent_); os << "User-Agent: " << user_agent_ << endl; // If we have authorization info (encoded username:passwd), include it // in the request if (auth_info_ != NULL) os << "Authorization: Basic " << auth_info_ << endl; // add newline after request and null terminate os << endl; strncpy(req, os.str().c_str(), sizeof(req)); // send the request int n = strlen(req); if (writen(req, n) != n) { char buf[255]; sprintf(buf, "could not contact http server on %s:%d\n", hostname_, port_); if (feedback_) { fprintf(feedback_, "%s", buf); fflush(feedback_); } close(fd_); fd_ = -1; return sys_error(buf);; } if (feedback_) { fprintf(feedback_, "waiting for result from %s...\n", hostname_); fflush(feedback_); } // Read the result and position after the HTTP header, which ends with a blank line char buf[1024]; while (readline(buf, sizeof(buf)) > 2) { scanHeaderLine(buf); } if (location_) { // Redirect to a new URL location char* newurl = location_; location_ = NULL; // don't want to overwrite url in reset() int status = get(newurl); free(newurl); return status; } if (authorizationRequired()) { // Server requested a username and password return getAuthorization(url); } return 0; } /* * do an HTTP get on the given URL and return a pointer to the result * of NULL if an error occurred. * * nlines is set to the number of lines in the result (not counting the * http header) or -1 for errors. * * If freeFlag is true, the return buffer is only valid until the next * call to this method or when this object is deleted, at which time the * memory for it is freed. */ char* HTTP::get(const char* url, int& nlines, int freeFlag) { if (resultGC_) { free( resultGC_ ); resultGC_ = resultBuf_ = resultPtr_ = NULL; } if (get(url) != 0) { nlines = -1; return NULL; // error } // read the data into a buffer ostringstream os; char buf[8*1024]; nlines = 0; int n; if (feedback_) { int tot = 0; while ((n = read(fd_, buf, sizeof(buf))) > 0) { fprintf(feedback_, "read %d bytes from %s\n", tot += n, hostname_); fflush(feedback_); os.write(buf, n); } } else { while ((n = read(fd_, buf, sizeof(buf))) > 0) { os.write(buf, n); } } resultPtr_ = resultBuf_ = strdup(os.str().c_str()); // count the lines // and remove "end of data" marker char* p = resultBuf_; char* q = p; int errs = 0; for (p = resultBuf_; *p; p++) { if (*p == '\n') { if (strncmp(q, "[EOD]", 5) == 0) { *q = '\0'; break; } if (strncmp(q, "***", 3) == 0) { *p = '\0'; error(q); if (feedback_) { fprintf(feedback_, "%s\n", q); fflush(feedback_); } errs++; break; } nlines++; q = p+1; } } close(fd_); fd_ = -1; if (freeFlag) resultGC_ = resultBuf_; if (errs) { nlines = -1; return NULL; } if (feedback_) { fprintf(feedback_, "done: read %d lines from %s\n", nlines, hostname_); fflush(feedback_); } return resultBuf_; } /* * do an HTTP GET on the given URL and write the results to the * given stream. * * Returns 0 if successful, otherwise 1 */ int HTTP::get(const char* url, ostream& os) { if (get(url) != 0) { return 1; // error } return copy(os); } /* * Do an HTTP POST using the given URL and data and position the read fd * after the http header of the result. * * This method accepts only standard http://... type URLs. * * If an error occurs, 1 is returned, otherwise 0. Use readline() to * fetch the results. * * Note: authorization is not implemented for POST yet, but could be added * easily. I'm not sure if we need it yet... */ int HTTP::post(const char* url, const char* data) { // reset any previous values reset(); // For now, only support http://... URLs if (strncmp(url, "http:", 5) != 0) { return error("Invalid URL for HTTP POST method"); } // look for URL: "http://host:port/args" or "http://host/args" char host[64]; // http host name int port = 80; // http server port on host char args[1024]; // part of URL after host:port char req[1024]; // request sent to http if (sscanf(url, "http://%63[^:/]:%d%1000s", host, &port, args) != 3 && sscanf(url, "http://%63[^/]%1000s", host, args) != 2) { return error("bad URL format: ", url); } // open a connection to the http server on the given host/port, // make this the proxy server if necessary. Note we check the // proxy everytime so that it can be reconfigured on the fly (by // setting the http_proxy environment variable). This call also // checks if the host is in a domain that we do not want to proxy. checkProxy(host); if (proxyport_ == -1) { if (open(host, port) != 0) return 1; // error } else { if (open(proxyname_, proxyport_) != 0) return 1; // error // Request to proxy needs the fully qualified URL. strncpy(args, url, 1024); // The apparent hostname and port are now wrong. Change these // to values that make sense in the feedback messages. strncpy(hostname_, host, 64); port_ = port; } if (feedback_) { fprintf(feedback_, "sending request to %s...\n", hostname_); fflush(feedback_); } // generate the HTTP POST command sprintf(req, "POST %s HTTP/1.0\nContent-type: text/plain\nContent-length: %d\n\n%s", args, (int) strlen(data), data); int n = strlen(req); if (writen(req, n) != n) { char buf[255]; sprintf(buf, "could not contact http server on %s:%d\n", hostname_, port_); if (feedback_) { fprintf(feedback_, "%s", buf); fflush(feedback_); } close(fd_); fd_ = -1; return sys_error(buf);; } if (feedback_) { fprintf(feedback_, "waiting for result from %s...\n", hostname_); fflush(feedback_); } // skip the HTTP header: ends with a blank line char buf[1024]; while (readline(buf, sizeof(buf)) > 2) { scanHeaderLine(buf); } if (location_) { // Redirect to a new URL location char* newurl = location_; location_ = NULL; // don't want to overwrite url in reset() int status = post(newurl, data); free(newurl); return status; } return 0; } /* * do an HTTP POST using the given URL and data and write the * results to the given stream. * * Returns 0 if successful, otherwise 1 */ int HTTP::post(const char* url, const char* data, ostream& os) { if (post(url, data) != 0) { return 1; // error } return copy(os); } /* * copy the results of a previous get(url) to the given stream. * * Assumes that the connection is open and the header has been read, * i.e., get(url) was called. * * Returns 0 if successful, otherwise 1 */ int HTTP::copy(ostream& os) { char buf[8*1024]; int n; if (feedback_) { int tot = 0; while((n = read(fd_, buf, sizeof(buf))) > 0) { os.write(buf, n); fprintf(feedback_, "read %d bytes from %s\n", tot += n, hostname_); fflush(feedback_); } } else { while((n = read(fd_, buf, sizeof(buf))) > 0) { os.write(buf, n); } } return 0; } /* * Return a pointer to the next line in the results of the previous call * to get(url, nlines). A null char is inserted in place of the newline * so that the line can be treated as a single string. * * A NULL is returned when there are no more lines in the results. */ char* HTTP::getNext() { if (resultPtr_) { char* q = resultPtr_; char* p = strchr(q, '\n'); if (p) { *p++ = '\0'; resultPtr_ = p; return q; } } return NULL; } /* * Read the line one byte at a time, looking for the newline. We store * the newline in the buffer, then follow it with a null (the same as * fgets(3)). Not very efficient but usefull for sockets. * * Returns the number of characters up to, but not including, the null * (the same as strlen(3)) or < 0 upon errors. * * Taken from Stevens (readline()), "Unix Network Programming" */ int HTTP::readline(char* ptr, int maxlen) { int n, rc; char c; for (n = 1; n < maxlen; n++) { if ( (rc = read(fd_, &c, 1)) == 1) { *ptr++ = c; if (c == '\n') break; } else if (rc == 0) { if (n == 1) return(0); // EOF, no data read else break; // EOF, some data was read } else return(-1); // error } *ptr = 0; return(n); } /* * Write "n" bytes to a descriptor. Use in place of write() when fd is a * stream socket. * * Returns the number of characters written or <0 upon error. * * Taken from Stevens, "Unix Network Programming". */ int HTTP::writen(char* ptr, int nbytes) { int nleft, nwritten; nleft = nbytes; while (nleft > 0) { nwritten = write(fd_, ptr, nleft); if (nwritten <= 0) return(nwritten); // error nleft -= nwritten; ptr += nwritten; } return(nbytes - nleft); } /* * Check if a proxy server is available and required to access the * given host machine. * * The proxy server, if available, is defined by the "http_proxy" * environment variable. This should have the format: * * http_proxy = "http://wwwcache.some.domain:port/" * * A list of domains that do not require to be proxied (i.e. local * machines etc.) is defined by the variable "http_noproxy". This * should be a list of comma separated names, i.e.: * * http_noproxy = "local.domain,national.domain" * * If the given host is in one of these domains no proxy will be set * up otherwise the member variables "proxyname_" and "proxyport_" * will be defined (specifically proxyport_ will be set to -1 for no * proxy). * */ void HTTP::checkProxy( const char *host ) { // Check if a proxy is available. proxyport_ = -1; char *proxy = getenv( "http_proxy" ); if ( proxy != NULL ) { // Parse the string into a hostname and port number. This // should be in the form : // "http://host:port/" or "http://host/" if ( sscanf( proxy, "http://%63[^:/]:%d", proxyname_, &proxyport_ ) == 2 || sscanf( proxy, "http://%63[^/]", proxyname_ ) == 1 ) { // Succeeded. Make sure port is valid. if ( proxyport_ == -1 ) { proxyport_ = 80; } // Now see if we really need to use this for the given // host. Note need a copy of variable as strtok modifies it. char *ptr = getenv( "http_noproxy" ); if ( ptr != NULL ) { const char *hostdomain = strchr(host, '.'); if (hostdomain != NULL) { hostdomain++; // make a copy of the http_noproxy string for strtok char buf[1024]; strncpy(buf, ptr, sizeof(buf)-1); ptr = NULL; char* noproxy = buf; while ((ptr = strtok(noproxy, ", ")) != NULL) { noproxy = NULL; if (strcmp(hostdomain, ptr) == 0) { proxyname_[0] = '\0'; proxyport_ = -1; break; } } } } } else { // Scan failed to find valid proxy type address. proxyname_[0] = '\0'; proxyport_ = -1; } } else { // No http_proxy variable. So nothing to do. proxyname_[0] = '\0'; proxyport_ = -1; } // Feedback for proxy if found/needed. if (feedback_) { if ( proxyport_ != -1 ) { fprintf(feedback_, "using proxy server %s:%d\n", proxyname_, proxyport_); fflush(feedback_); } } } skycat-3.1.2-starlink-1b/tclutil/generic/HTTP.h000066400000000000000000000162071215713201500211670ustar00rootroot00000000000000// -*-c++-*- #ifndef _HTTP_h_ #define _HTTP_h_ /* * E.S.O. - VLT project * $Id: HTTP.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * HTTP.h - utility class for communicating with the HTTP daemon * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 26 Sep 95 Created * Peter W. Draper 16 Jun 98 Added support for proxy servers * pbiereic 17/02/03 Added 'using namespace std'. * Peter W. Draper 06 Apr 09 Increase size of host buffers to 64 from 32. */ using namespace std; #include #include #include #include #include #include #include #include /* * Class HTTP * */ class HTTP { private: int status_; // status after constructor sockaddr_in servAddr_; // server address char hostname_[64]; // http server hostname char proxyname_[64]; // http proxy server hostname int port_; // port number for http server int proxyport_; // port number for http proxy server int fd_; // file desc from last call to get(url) FILE* feedback_; // optional file ptr for feedback info char* content_type_; // "Content-type" field read from HTTP server or NULL char* content_encoding_; // "Content-Encoding" field read from HTTP server or NULL int content_length_; // "Content-length" field read from HTTP server or NULL char* location_; // URL for redirect (Location keyword in HTTP header) char* www_auth_realm_; // "WWW-Authenticate:" value of string after "Basic realm=" // pointers for stepping through http results char* resultBuf_; // pointer to result buffer char* resultGC_; // if not null, pointer to resultBuf_ to be freed char* resultPtr_; // pointer to current line in resultBuf_ static int allowUrlExec_; // flag: if true, allow a URL to be a command to exec. // (default: false) // authorization info, set with authorize(user, passwd, ...) static char* auth_info_; // base64 encoded "username:passwd" info, if needed // these variables have default values that should not normally need to be // changed static char* user_agent_; // value of User-Agent string to send with requests static char* auth_file_; // filename for saving HTTP authorization info private: // I/O utility int writen(char* ptr, int nbytes); // open a socket to the http server on host/port int open(const char* hostname, int port = 80); // Open the given local file and return the status. int openFile(const char* filename); // run command and position fd_ at start of output int openCommand(const char* command); // Scan the first few lines of the given file for HTTP header int checkCommandOutput(const char* filename); // check proxy server configuration void checkProxy( const char *host ); // reset any previous member values before a GET or POST void reset(); // Scan the given HTTP header line for any keywords that we are interested in void scanHeaderLine(char* buf); // Add an entry to the auth_file_ for the given server and realm and // current value of auth_info_ static int addAuthFileEntry(const char* server, const char* realm); // Search the auth_file_, if it exists, for an entry with the given server // and realm and set auth_info_ to the value found there. static int findAuthFileEntry(const char* server, const char* realm); // redo the GET on the URL with username/passwd, if known, or return special // error message so that user interface can do it. int getAuthorization(const char* url); // copy constructor - not defined HTTP(const HTTP&); public: // constructor HTTP(); // destructor ~HTTP(); // return status after constructor int status() const {return status_;} // do an HTTP GET with the given URL and position the read fd after // the result HTTP header. Returns 0 if OK. Use readNext() to read // the result lines. int get(const char* url); // do an HTTP get on the given URL and return the result as a buffer. // nlines is set to the number of result lines (use getNext() to // fetch the result lines from the buffer) char* get(const char* url, int& nlines, int freeFlag = 1); // do an HTTP get on the given URL and write the results to the // given stream int get(const char* url, ostream&); // do an HTTP POST using the given URL and data and position the read // fd after the result HTTP header. int post(const char* url, const char* data); // do an HTTP post using the given URL and data and write the results // to the given stream int post(const char* url, const char* data, ostream&); // copy the results of a previous get(url) to the given stream int copy(ostream& os); // read a line of the results after a call to get(url, nlines) int readline(char* ptr, int maxlen); // return the next result line after a call to get(url) // or NULL if there are no more lines. char* getNext(); // return a pointer to the result buffer from http const char* result() {return resultBuf_;} // set/get the file ptr to use for feedback during http transfers void feedback(FILE* f); FILE* feedback() const {return feedback_;} // return the hostname of the http server const char* hostname() const {return hostname_;} // return file desc from last call to get(url) int fd() const {return fd_;} // return http header values from last GET char* content_type() const {return content_type_;} char* content_encoding() const {return content_encoding_;} int content_length() const {return content_length_;} // if we see: WWW-Authenticate: Basic realm="somedomain" // in the HTTP header, we assume a username and password are required // and www_auth_realm_ is set to the "somedomain" value. const char* www_auth_realm() const {return www_auth_realm_;} // return true if a username/passwd is needed for the previous GET int authorizationRequired() {return www_auth_realm_ != NULL;} // set the username and password to use for authorization, // and, if realm and server are given, save an entry in the auth_file static void authorize(const char* user, const char* passwd, const char* realm = NULL, const char* server = NULL); // take an error message in HTML format and pass it // on to error(), stripped of HTML syntax (<...>) int html_error(istream& is); int html_error(char* s); // get/set flag value to allow URL to be a local command static int allowUrlExec() {return allowUrlExec_;} static void allowUrlExec(int i) {allowUrlExec_ = i;} // get/set the value of the HTTP User-Agent to use with requests static const char* userAgent() {return user_agent_;} static void userAgent(const char* s); // get/set the value of the file used to remember authorization info static const char* authFile() {return auth_file_;} static void authFile(const char* s); }; #endif /* _HTTP_h_ */ skycat-3.1.2-starlink-1b/tclutil/generic/Mem.C000066400000000000000000000427231215713201500210630ustar00rootroot00000000000000/* * E.S.O. - VLT project / ESO Archive * * "@(#) $Id: Mem.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * Mem.C - method definitions for class Mem, for managing memory * areas with or without shared memory. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 07/03/96 Created * D.Hopkinson 21/01/97 Added constructor to use when multi-buffering shared memory. * pbiereic 22/10/99 Attach to shm with SHM_RDONLY when owner=0 * pbiereic 10/11/99 Use _exit() in signal handler, so that the * Peter W. Draper 23/01/00 Added constructor to accept "malloc'd" * memory. This is may or may not be "owned" * (I added this to accept memory mapped * from the NDF library, so as to avoid the * need for a memory copy). * message queue of a possible parent process is not closed * pbiereic 17/02/03 Added 'using namespace std'. * Peter W. Draper 03/09/04 New addr arguments for Mem and Mem_Rep * constructors. * 04/04/06 Added "refcnt" member so that owner can control * when to release memory. */ static const char* const rcsId="@(#) $Id: Mem.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include #include #include #include #include #include #include #include #include #include "error.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" #include "util.h" #include "Mem.h" #include "Mem_Map.h" using namespace std; /* * NOTE: on Solaris2.5, the default limit is 8 shared memory areas per process: * this can be changed by editing /etc/system and adding the following line: * * set shmsys:shminfo_shmseg=200 */ // Some in-file data static int const MEM_MMAP_DEFAULT_FLAGS = O_RDONLY; static int const MEM_MMAP_DEFAULT_PROT = PROT_READ; static int const MEM_MMAP_DEFAULT_SHARING = MAP_SHARED; #ifdef NEED_SHM_PROTO // missing prototypes (on SunOS at least) extern "C" { // should be in sys/shm.h void *shmat(int shmid, const void* shmaddr, int shmflg); int shmdt(const void* shmaddr); int shmget(key_t, size_t, int); int shmctl(int shmid, int cmd, shmid_ds *buf); } #endif // The following is used to keep track of shared memory Mem objects. // On some systems (hp), a shmat will fail if the shared memory // is alread attached (also: mmap fails if the file is already mapped). // That is why we need the following. It is also handy for cleaning up when // a program is killed. enum {MAX_SHM_ = 255}; // max number of shared memory Mem objects allowed static MemRep* shmObjs_[MAX_SHM_]; // array of existing shared memory Mem objects static int shmCount_ = 0; // count of objects in above array /* * default constructor */ MemRep::MemRep() : size(0), owner(0), refcnt(1), ptr(NULL), newmem(0), shmId(-1), shmNum(0), semId(-1), options(0), status(0), verbose(0), m_map(NULL), linkName(NULL) { } /* * constructor - attach to existing sysV shared memory with given id */ MemRep::MemRep(size_t sz, int own, int id, int verb) : size(sz), owner(own), refcnt(1), ptr(NULL), newmem(0), shmId(id), shmNum(0), semId(-1), options(0), status(0), verbose(verb), m_map(NULL), linkName(NULL) { if (shmCount_ >= MAX_SHM_) { status = error("too many shared memory segments"); return; } // check the size shmid_ds shmInfo; if (shmctl(shmId, IPC_STAT, &shmInfo) != 0) { status = sys_error("bad shared memory Id specified"); return; } if (shmInfo.shm_segsz < size) { status = error("specified shared memory area is too small"); return; } // attach new shared memory segment if (owner) ptr = shmat(shmId, NULL, 0); else ptr = shmat(shmId, NULL, SHM_RDONLY); if (ptr == NULL || ptr == (void *)-1) { ptr = NULL; shmId = -1; status = sys_error("Invalid shared memory id specified"); return; } #ifdef DEBUG if (verbose) log_message("attach to new shared memory with Id: %d", shmId); #endif // enter new object table for later reference shmObjs_[shmCount_++] = this; } /* * constructor - create a new MemRep object with the given size. If * "useShm" is non-zero, shared memory is allocated, otherwise "operator * new" is used. */ MemRep::MemRep(size_t sz, int useShm, int verb) : size(sz), owner(1), refcnt(1), ptr(NULL), newmem(0), shmId(-1), shmNum(0), semId(-1), options(0), status(0), verbose(verb), m_map(NULL), linkName(NULL) { if (size <= 0) return; // null shared mem if (! useShm) { ptr = new char[size]; newmem = 1; if (!ptr) status = error("out of memory"); return; } if (shmCount_ >= MAX_SHM_) { status = error("too many shared memory segments"); return; } shmId = shmget(IPC_PRIVATE, size, 0666); ptr = (void *)shmat(shmId, NULL, 0); if (ptr == NULL || ptr == (void *)-1) { ptr = NULL; status = sys_error("error creating shared memory"); return; } #ifdef DEBUG if (verbose) log_message("Shared Memory area created, Id: %d, size: %d", shmId, size); #endif // enter new object in table for later reference shmObjs_[shmCount_++] = this; } /* * constructor - accept pointer to malloc'd memory. * * If owner is non-zero the memory is freed when this object is * deleted. */ MemRep::MemRep(void *inptr, size_t sz, int own) : size(sz), owner(own), refcnt(1), ptr(inptr), newmem(0), shmId(-1), shmNum(0), semId(-1), options(0), status(0), verbose(0), m_map(NULL), linkName(NULL) { } /* * constructor - mmap the given file using the given options and flags. * * If owner is non-zero, the file is deleted when this object is deleted. */ MemRep::MemRep(const char *filename, int flags, int prot, int share, size_t nbytes, int own, int verb, void *addr) : size(0), owner(own), refcnt(1), ptr(NULL), newmem(0), shmId(-1), shmNum(0), semId(-1), options(0), status(0), verbose(verb), m_map(NULL), linkName(NULL) { if (! filename) { status = error("no file name specified for mmap"); return; } if ((flags & O_CREAT) == 0) { // using existing file, not creating a new one? // can't map a file that doesn't exist if (access(filename, F_OK) != 0) { status = error("file does not exist: ", filename); return; } // can't map a file without read permission if (access(filename, R_OK) != 0) { status = error("file has no read permission: ", filename); return; } // check the file permissions and the mmap flags, since on solaris at least, // mmap(read-write) seems to succede, even if file is read-only if ((flags & O_RDWR) && access(filename, W_OK) != 0) { status = error("can't mmap read-only file for writing: ", filename); return; } } // get the name of the real file (if a link) //char realname[1024]; //const char* fname = fileRealname(filename, realname, sizeof(realname)); //if (fname == realname) //linkName = strdup(filename); // remember the name of the link const char* fname = filename; // allan: 9.11.00: had problems with relative links // map the file m_map = new Mem_Map(fname, nbytes, // length flags, // Read/Write, etc. MMAP_DEFAULT_PERMS, // mode prot, // protection, share, // share map on write addr); // address to map file at if (!m_map || m_map->status() != 0) { // status = error("mapping of file failed"); status = 1; return; } size = m_map->size(); ptr = m_map->addr(); // enter new object table for later reference shmObjs_[shmCount_++] = this; } /* * internal destructor - Detach and/or delete shared memory, if needed. */ MemRep::~MemRep() { if (shmId >= 0 || m_map) { // remove this obejct from the table, and shift others left // (there won't normally be very many entries in the table...) for (int i = 0; i < shmCount_; i++) { if (shmObjs_[i] == this) { shmCount_--; while (i < shmCount_) { shmObjs_[i] = shmObjs_[i+1]; i++; } shmObjs_[shmCount_] = NULL; break; } } } // If there is a semaphore associated with this shared memory, set // it to zero . if (shmId >= 0) { // if we are responsible for deleting this memory, do it now if (owner) { struct sembuf semDec[1] = { 0, 0, IPC_NOWAIT }; // Perform the reset #ifdef HAVE_UNION_SEMUN union semun s; // allan: 11.9.97 - type needed for linux s.val = 0; #else void* s = NULL; #endif semDec[0].sem_num = (unsigned short)shmNum; semDec[0].sem_op = (short)(0 - semctl(semId, shmNum, GETVAL, s)); semop(semId, &semDec[0], 1); #ifdef DEBUG if (verbose) log_message("removing (IPC_RMID) shared memory area: %d", shmId); #endif shmctl(shmId, IPC_RMID, NULL); } // detach and delete, since there are no more references if (ptr) { #ifdef DEBUG if (verbose) log_message("detaching shared memory area: %d", shmId); #endif shmdt((char*)ptr); } } else if (m_map != 0) { // mmap file if (owner && m_map->filename()) unlink(m_map->filename()); // if we are the owner, rm the file now if(m_map) delete m_map; } else if (ptr) { // must be using plain memory if (newmem && owner) { delete[] (char *)ptr; } else if (owner) { free( ptr ); } } ptr = NULL; newmem = 0; m_map = NULL; shmId = -1; size = 0; status = -1; if (linkName) { free(linkName); linkName = NULL; } } /* * return name of mmap file or NULL if mmap not being used. * If flag is 1 and the original file was a link, return the link name, * otherwise return the real name. */ const char* MemRep::filename(int flag) const { if (m_map) { if (flag && linkName) return linkName; return m_map->filename(); } return NULL; } /* * Temporarily unmap the shared memory. This is needed if you want to save lots * of these objects without running out of shared memory resources. * (Note: only for use with read-only mmapped memory.) */ void MemRep::unmap() { if (refcnt > 1) return; // can't unmap, more than one ref if (m_map) { m_map->close(); ptr = NULL; } // not impl for sysV shared mem } /* * remap the shared memory after a call to unmap() * (may be used to unmap and remap with different options, see MemFileOptions) * If the optional newsize arg is given and is not 0, it indicates a new * file size. This can be used to extend the file size. */ int MemRep::remap(int opts, size_t newsize) { if (!m_map || !m_map->filename()) return error("can't remap memory, not mapped"); int flags = 0; int prot = 0; int sharing = 0; if (opts == Mem::FILE_DEFAULTS) { flags = MEM_MMAP_DEFAULT_FLAGS; prot = MEM_MMAP_DEFAULT_PROT; sharing = MEM_MMAP_DEFAULT_SHARING; } else { // There are client specified options flags |= (opts & Mem::FILE_RDWR ) ? O_RDWR : O_RDONLY; prot = (opts & Mem::FILE_RDWR) ? PROT_RDWR : PROT_READ; sharing = (opts & Mem::FILE_PRIVATE) ? MAP_PRIVATE: MAP_SHARED; } // first unmap (very important...) m_map->close(); // now remap if (m_map->map(m_map->filename(), newsize, flags, MMAP_DEFAULT_PERMS, prot, sharing, NULL, 0) < 0) { return sys_error("mmap failed for file: ", m_map->filename()); } size = m_map->size(); ptr = m_map->addr(); options = opts; // not impl for sysV shared mem return 0; } /* * search for an existing MemRep object for the given shmId and return it * or NULL if not found */ static MemRep* findMemRep(int shmId) { if (shmId >= 0) { for (int i = 0; i < shmCount_; i++) if (shmObjs_[i]->shmId == shmId) return shmObjs_[i]; } return NULL; } /* * search for an existing MemRep object for the given filename and return it * or NULL if not found */ static MemRep* findMemRep(const char* filename) { MemRep* rep; if (filename) { // get the name of the real file //char realname[1024]; //const char* pfile = fileRealname(filename, realname, sizeof(realname)); const char* pfile = filename; // allan: 9.11.00: had problems with relative links for (int i = 0; i < shmCount_; i++) { if (shmObjs_[i]->m_map && strcmp(shmObjs_[i]->m_map->filename(), pfile) == 0) { rep = shmObjs_[i]; // Note: memory may have been temporarily unmapped (see unmap()) // If so, remap it here. if (rep->ptr == NULL && rep->remap() != 0) return NULL; return rep; } } } return NULL; // not found } // --------------------- Below is Mem - Above MemRep ------------------------- /* * constructor - attach (if needed) to existing shm area */ Mem::Mem(size_t size, int shmId, int owner, int verbose) : offset_(0), length_(0) { // see if we have this Id already if (rep_ = findMemRep(shmId)) { rep_->refcnt++; return; } // make a new one rep_ = new MemRep(size, owner, shmId, verbose); } /* * Constructor to use when multi-buffering shared memory. The fifth argument * is the number of the buffer in the sequence of use of shared memory * buffers. This is only required to lock the memory when using semaphores. * The final argument is the ID of the semaphore used to lock this * particular area of shared memory. */ Mem::Mem(size_t size, int shmId, int owner, int verbose, int shmNum, int semId) : offset_(0), length_(0) { // see if we have this Id already if (rep_ = findMemRep(shmId)) { rep_->refcnt++; return; } // make a new one rep_ = new MemRep(size, owner, shmId, verbose); rep_->shmNum = shmNum; rep_->semId = semId; } /* * constructor - use Mem_Map to open file and get pointer */ Mem::Mem(const char *filename, int verbose) : offset_(0), length_(0) { // see if we have mapped this file already if (rep_ = findMemRep(filename)) { rep_->refcnt++; return; } rep_ = new MemRep(filename, MEM_MMAP_DEFAULT_FLAGS, MEM_MMAP_DEFAULT_PROT, MEM_MMAP_DEFAULT_SHARING, 0, 0, verbose); } /* * Constructor uses mmap to map a file and adds file options */ Mem::Mem(const char *filename, int options, int verbose, void *addr) : offset_(0), length_(0) { int flags = 0; int prot = 0; int sharing = 0; if (options == FILE_DEFAULTS) { flags = MEM_MMAP_DEFAULT_FLAGS; prot = MEM_MMAP_DEFAULT_PROT; sharing = MEM_MMAP_DEFAULT_SHARING; } else { // There are client specified options flags |= (options & FILE_RDWR ) ? O_RDWR : O_RDONLY; prot = (options & FILE_RDWR) ? PROT_RDWR : PROT_READ; sharing = (options & FILE_PRIVATE) ? MAP_PRIVATE: MAP_SHARED; } // see if we have mapped this file already if (rep_ = findMemRep(filename)) { rep_->refcnt++; return; } rep_ = new MemRep(filename, flags, prot, sharing, 0, 0, verbose, addr); rep_->options = options; } /* * Constructor: create a file of the given size and use mmap to map the * file read/write (Note: we have to use O_RDWR for mmap). * * If owner if non-zero, the file is deleted when there are no more * references. */ Mem::Mem(size_t size, const char *filename, int owner, int verbose) : offset_(0), length_(0) { // see if we have mapped this file already if (rep_ = findMemRep(filename)) { rep_->refcnt++; fmt_error("warning: file %s already exists and is already mmapped!", filename); return; } unlink(filename); // remove any existing file by this name... (is this needed?) rep_ = new MemRep(filename, O_RDWR|O_CREAT, PROT_RDWR, MAP_SHARED, size, owner, verbose); } /* * Constructor: accept a pointer to memory, do not modify this * reference (assume user looks after it). */ Mem::Mem(void *ptr, size_t size, int owner) : offset_(0), length_(0) { rep_ = new MemRep(ptr, size, owner); } /* * destructor, detach and/or delete memory if needed */ Mem::~Mem() { if (rep_ && --rep_->refcnt <= 0) delete rep_; } /* * assignment operator */ Mem& Mem::operator=(const Mem& m) { if (m.rep_) m.rep_->refcnt++; // protect against "shm = shm" if (rep_ && --rep_->refcnt <= 0) delete rep_; offset_ = m.offset_; length_ = m.length_; rep_ = m.rep_; return *this; } /* * return the current reference count. */ int Mem::refcnt() { if ( rep_ ) { return rep_->refcnt; } return 0; } /* * force the memory to be shared (1) or not shared (0) */ int Mem::shared(int share) { if (share == shared()) return 0; Mem m(length(), share, verbose()); if (m.status() != 0) return m.status(); memcpy(m.ptr(), ptr(), length()); *this = m; return 0; } /* * remove all "owned" shared memory areas (should be called before exit) */ void Mem::cleanup() { for (int i = 0; i < shmCount_; i++) { if (shmObjs_[i]->owner && shmObjs_[i]->status == 0) { if (shmObjs_[i]->m_map && shmObjs_[i]->m_map->filename()) unlink(shmObjs_[i]->m_map->filename()); else if (shmObjs_[i]->shmId > -1) shmctl(shmObjs_[i]->shmId, IPC_RMID, NULL); shmObjs_[i]->owner = 0; } } } /* * external version, for use as a signal handler */ void Mem_cleanup(int) { Mem::cleanup(); _exit(0); } skycat-3.1.2-starlink-1b/tclutil/generic/Mem.h000066400000000000000000000173431215713201500211300ustar00rootroot00000000000000// -*-c++-*- #ifndef _Mem_h_ #define _Mem_h_ /* * E.S.O. - VLT project / ESO Archive * * "@(#) $Id: Mem.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * Mem.h - declarations for class Mem, a class for managing memory areas, * which may or may not be shared memory. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 07 Mar 96 Created * 03 Dec 96 added filename() method to return mmap filename * or NULL if mmap is not being used. * D.Hopkinson 21/01/97 Added constructor to use when * multi-buffering shared memory. * Peter W. Draper 23/01/00 Added constructor and methods for * accepting a piece of malloc'd memory. * 03/09/04 Added addr parameter to Mem and Mem_Rep * constructors. Starlink fortran 64 bit * interoperability requires that addresses may be * changed. * 04/04/06 Added "refcnt" member so that owner can control * when to release memory. * 05/12/07 Change length function to return off_t instead * of int. */ #include #include class Mem_Map; // internal struct used for reference counting struct MemRep { size_t size; // size in bytes int owner; // true if we should delete the shm when no longer needed int refcnt; // count of the number of reference to this memory area void* ptr; // pointer to memory area int newmem; // memory allocated using "new" int shmId; // shared memory id, or 0 if not shared int shmNum; // shm buffer number, if multi-buffering int semId; // Semaphore ID for locking shm int options; // mmap options for read/write access int status; // status after constructor int verbose; // if true, print diagnostic messages Mem_Map *m_map; // Used when mapping a file char* linkName; // If a file name specified for mmap was a link, it is // replaced with the real name and the name of the link // is recorded here. // default constructor: empty memory MemRep(); // attach to sysV shared memory MemRep(size_t size, int owner, int shmId, int verbose); // create memory (sysV shared, if useShm is 1) with given size MemRep(size_t size, int useShm, int verbose); // mmap the given file, create/extend if nbytes > 0 MemRep(const char *filename, int flags, int prot, int share, size_t nbytes, int owner, int verbose, void *addr = NULL); // accept pointer to malloc'd memory. MemRep(void *inptr, size_t size, int owner); // destructor ~MemRep(); // return name of mmap file or NULL if mmap not being used const char* filename(int flag = 0) const; // temporarily unmap the shared memory void unmap(); // remap the shared memory after a call to unmap(), optionally specifying // new mapping options and a new file size. int remap(int options = 0, size_t newsize = 0); }; /* * This class uses reference counting to help manage memory areas. The * class keeps track of who owns the (shared) memory, who is responsible * for deleting it when no longer needed and how many references there * are to the memory area. When there are no more references, we * can safely detach a shared memory area and if we are the "owner", * delete it. */ class Mem { private: MemRep* rep_; // internal representation, reference counting long offset_; // optional offset in memory area long length_; // optional different length of memory area used public: // default constructor Mem() : rep_(new MemRep), offset_(0), length_(0) { } // constructor: attach (if needed) to existing shared memory area Mem(size_t size, int shmId, int owner, int verbose); // constructor: create new memory area, shared if useShm is true Mem(size_t size, int useShm, int verbose = 0) : rep_(new MemRep(size, useShm, verbose)), offset_(0), length_(0) { } // mmap options enum MemFileOptions { FILE_DEFAULTS = 0, // File RDONLY, MAP_SHARED FILE_RDWR = 1, // Make mapped file writable FILE_PRIVATE = 2, // Make written segments private FILE_FIXED = 4 // Fixed address, not in use }; // Constructor uses mmap to map a file Mem(const char *filename, int verbose = 0); // Constructor uses mmap to map a file and adds file options // PWD: Use the addr argument if you need to suggest an address to map // the file. Starlink Fortran interoperability sometimes needs this. Mem(const char *filename, int options, int verbose, void *addr = NULL); // Constructor: creates a file of the given size and uses mmap // to map the file read/write. Mem(size_t size, const char *filename, int owner, int verbose = 0 ); // Constructor to use when multi-buffering shared memory. Mem(size_t size, int shmId, int owner, int verbose, int shmNum, int semId); // Accept pointer to malloc'd memory Mem(void *ptr, size_t size, int owner); // copy constructor, just copy ptr and increment ref count Mem(const Mem& m) : rep_(m.rep_), offset_(m.offset_), length_(m.length_) { rep_->refcnt++; } // destructor, detach and/or delete memory if needed ~Mem(); // assignment Mem& operator=(const Mem&); int operator==(const Mem& m) const { return m.rep_ == rep_ && m.offset_ == offset_ && m.length_ == length_; } int operator!=(const Mem& m) const { return m.rep_ != rep_ || m.offset_ != offset_ || m.length_ != length_; } // reference counts of memory int refcnt(); // return true if the memory is shared int shared() const {return shmId() >= 0;} // force the memory to be shared (1) or not shared (0) int shared(int share); // temporarily unmap the shared memory void unmap() {rep_->unmap();} // remap the shared memory after a call to unmap(), optionally specifying // new mapping options and a new file size int remap(int options = 0, size_t newsize = 0) { return rep_->remap(options, newsize); } // remove all "owned" shared memory areas (should be called before exit) static void cleanup(); // return the working length of the memory off_t length() const {return off_t(length_ ? length_ : (rep_->size - offset_));} // set optional length void length(long newLength) {length_ = newLength;} // member access size_t size() const {return rep_->size;} void* ptr() const {return rep_->ptr ? ((void *)((char *)rep_->ptr + offset_)) : NULL;} int shmId() const {return rep_->shmId;} int shmNum() const {return rep_->shmNum;} int semId() const {return rep_->semId;} int options() const {return rep_->options;} int status() const {return rep_->status;} int verbose() const {return rep_->verbose;} Mem_Map* m_map() const {return rep_->m_map;} // return a pointer to the internal representation // (This should only be used, if needed, in special cases) const MemRep* rep() const {return rep_;} // set/get the owner flag: if non-zero, memory will be deleted when there // are no more references void owner(int b) {rep_->owner = b;} int owner() {return rep_->owner;} // return name of mmap file or NULL if mmap not being used const char* filename(int flag = 0) const {return rep_->filename(flag);} // set/get offset void offset(long newOffset) {offset_ = newOffset;} long offset() const {return offset_;} }; /* cleanup shared mem and exit: for use as a signal handler */ void Mem_cleanup(int); #endif /* _Mem_h_ */ skycat-3.1.2-starlink-1b/tclutil/generic/Mem_Map.C000066400000000000000000000162411215713201500216540ustar00rootroot00000000000000 /* * E.S.O. - VLT project/ESO Archive * $Id: Mem_Map.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * Mem_Map.C - method definitions for class Mem_Map * Author: Doug Schmidt - ripped from ACE_wrappers by K. Gillies. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 3 Aug 96 Created, added call to "sys_error()", set status_ * Peter W. Draper 23 Jan 97 Added cast to MAP_FAILED comparison (OSF/1). * 23 Oct 00 Expanded error messages to be a little * more informative to an end user. */ static const char* const rcsId="@(#) $Id: Mem_Map.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include #include #include #include #include #include "error.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "Mem_Map.h" #include #ifdef HAVE_SYS_STATVFS_H #include #endif //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void Mem_Map::dump (void) const { } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // This function rounds the request to a multiple of the page size. size_t round_to_pagesize (off_t len) { return (len + (MMAP_PAGE_SIZE - 1)) & ~(MMAP_PAGE_SIZE - 1); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- int Mem_Map::close (void) { if (this->base_addr_ != (void*)MAP_FAILED) // allan: 30.7.97 added check this->unmap(); if (this->close_handle_) { return ::close(this->handle_); } return 0; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- Mem_Map::~Mem_Map (void) { this->close(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // This function does the dirty work of actually calling mmap // to map the file into memory. int Mem_Map::map_it(int handle, size_t len_request, int prot, int share, void *addr, off_t pos) { this->base_addr_ = addr; this->handle_ = handle; // Inquire file to access and get length in bytes. struct stat sb; int status = ::fstat(this->handle_, &sb); if (status == -1) { sys_error("get file status (fstat) failed for: ", filename_); // allan: added error report return -1; } // Set initial length to all of file. off_t file_len = sb.st_size; this->length_ = file_len; // If file is zero sized or too small. if ((this->length_ == 0 && len_request > 0) || (this->length_ < len_request)) { // Length is that requested. this->length_ = len_request; #ifdef HAVE_SYS_STATVFS_H // allan: make sure there is enough space on the filesystem struct statvfs vfs; if (fstatvfs(handle, &vfs) != 0) { sys_error("get file system information (fstatvfs) failed for: ", filename_); return -1; } if (vfs.f_frsize > 0) { // NOTE: must calculate in blocks to avoid 32bit overflow unsigned long need = (len_request - file_len + vfs.f_frsize)/vfs.f_frsize; unsigned long have = vfs.f_bavail; if (have < need) { error("DISK FULL: cannot create a sufficiently large map file: ", filename_); return -1; } } #endif // Extend the backing store. if (::lseek (this->handle_, len_request > 0 ? len_request - 1 : 0, SEEK_SET) == -1 || ::write (this->handle_, "", 1) != 1 || ::lseek (this->handle_, 0, SEEK_SET) == -1) { sys_error("write or seek failed for: ", filename_); // allan: added error report return -1; } } if (this->length_ <= 0) { error("cannot map zero length file: ", filename_); return -1; } this->base_addr_ = ::mmap ((caddr_t)this->base_addr_, this->length_, prot, share, this->handle_, off_t (round_to_pagesize (pos))); if (this->base_addr_ == (void*)MAP_FAILED) { // allan: added error report sys_error("failed to map file (insufficient VM?): ", filename_); return -1; } return 0; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- int Mem_Map::open(const char file_name[], int flags, int mode) { ::strncpy (this->filename_, file_name, MAXPATHLEN); this->handle_ = ::open(file_name, flags, mode); if (this->handle_ == MMAP_INVALID_HANDLE) { sys_error("open failed for: ", filename_); // allan: added error report return -1; } else { this->close_handle_ = 1; return 0; } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- int Mem_Map::map(const char file_name[], size_t len, int flags, int mode, int prot, int share, void *addr, off_t pos) { if (this->open(file_name, flags, mode) == -1) { return -1; } return this->map_it(this->handle(), len, prot, share, addr, pos); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- Mem_Map::Mem_Map(void) : length_ (0), base_addr_ (0), handle_ (MMAP_INVALID_HANDLE), close_handle_ (0), status_ (0) { ::memset (this->filename_, 0, sizeof this->filename_); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Map a file specified by FILE_NAME. Mem_Map::Mem_Map (const char file_name[], size_t len, int flags, int mode, int prot, int share, void *addr, off_t pos) : base_addr_ (0), close_handle_ (0), status_ (0) { if (this->map (file_name, len, flags, mode, prot, share, addr, pos) < 0) { status_ = 1; } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Map a file from an open file descriptor HANDLE. This function will // lookup the length of the file if it is not given. Mem_Map::Mem_Map (int handle, size_t len, int prot, int share, void *addr, off_t pos) : close_handle_ (0), status_ (0) { memset (this->filename_, 0, sizeof this->filename_); if (this->map (handle, len, prot, share, addr, pos) < 0) status_ = 1; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Close down and remove the file from the file system. int Mem_Map::remove (void) { ::ftruncate(this->handle_, 0); this->close(); if (this->filename_[0] != '\0') { return ::unlink (this->filename_); } // Else return 0; } skycat-3.1.2-starlink-1b/tclutil/generic/Mem_Map.h000066400000000000000000000251541215713201500217240ustar00rootroot00000000000000// -*-c++-*- #ifndef MEM_MAP_H #define MEM_MAP_H /* * E.S.O. - VLT project * $Id: Mem_Map.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * Mem_Map.h - utility class wrapper for mmap(2), Author: Doug Schmidt * (ripped from ACE C++ library for use in OCS by K. Gillies, * "...Doug says it's okay...." * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 02 Aug 96 Created, added status() method, removed TRACE * 06 Aug 96 Changed ssize_t to int, since it is not defined on sunos * define MAP_FAILED to (void*)-1, not def on HP,sunos * 03 Dec 96 Added filename() method to return filename mapped. * Reformatted .h file and put comments above declarations * for readability. * Peter W. Draper 27 Sep 05 All lengths are now size_t, which usually means * an unsigned long, consequently all use of * -1 as a special length has been changed to 0. */ #include #include // the wrapper is needed on some HPs extern "C" { #include } #include /* allan: 6.8.96: add defs missing on HP and/or sunos */ #ifndef MAP_FAILED #define MAP_FAILED NULL #endif #ifndef MS_SYNC #define MS_SYNC 0 #endif /* #ifdef NEED_MMAP_PROTO extern "C" { extern caddr_t mmap(caddr_t, size_t, int, int, int, off_t); extern int munmap(caddr_t, size_t); } #endif */ // MMAP additional flags #define PROT_RDWR (PROT_READ|PROT_WRITE) // Default file permissions. #define MMAP_DEFAULT_PERMS 0666 #define MMAP_INVALID_HANDLE 0 // Default size of mapped page on SunOS, HP and Solaris. #define MMAP_PAGE_SIZE 4096 // External used to round request. size_t round_to_pagesize (off_t len); // C++ interface to the mmap(2) UNIX system call. class Mem_Map { public: // Default constructor. Mem_Map (void); // Map a file from an open file descriptor . This function // will lookup the length of the file if it is not given. Mem_Map (int handle, size_t length = 0, int prot = PROT_READ, int share = MAP_SHARED, void *addr = 0, off_t pos = 0); // Map a file specified by . Mem_Map (const char file_name[], size_t len = 0, int flags = O_RDWR, int mode = MMAP_DEFAULT_PERMS, int prot = PROT_READ, int share = MAP_SHARED, void *addr = 0, off_t pos = 0); // Map a file from an open file descriptor . This function // will lookup the length of the file if it is not given. int map (int handle, size_t length = 0, int prot = PROT_READ, int share = MAP_SHARED, void *addr = 0, off_t pos = 0); // Remap the file associated with . int map (size_t length = 0, int prot = PROT_READ, int share = MAP_SHARED, void *addr = 0, off_t pos = 0); // Map a file specified by . int map (const char file_name[], size_t len = 0, int flags = O_RDWR, int mode = MMAP_DEFAULT_PERMS, int prot = PROT_READ, int share = MAP_SHARED, void *addr = 0, off_t pos = 0); // Destructor. ~Mem_Map (void); const char* filename() {return filename_;} // Open the file without mapping it. int open (const char file_name[], int flags = O_RDWR, int mode = MMAP_DEFAULT_PERMS); // Close down the if necessary. int close (void); // This operator passes back the starting address of the mapped file. int operator () (void *&addr); // Return the base address. void *addr (void) const; // This function returns the number of bytes currently mapped in the // file. size_t size (void) const; // Unmap the region starting at . int unmap (size_t len = 0); // Unmap the region starting at . int unmap (void *addr, size_t len); // Sync bytes of the memory region to the backing store // starting at . If == 0 then sync the whole // region. int sync (size_t len = 0, int flags = MS_SYNC); // Sync bytes of the memory region to the backing store // starting at . int sync (void *addr, size_t len, int flags = MS_SYNC); // Change the protection of the pages of the mapped region to // starting at up to bytes. If == 0 then // change protection of all pages in the mapped region. int protect (size_t len = 0, int prot = PROT_READ); // Change the protection of the pages of the mapped region to // starting at up to bytes. int protect (void *addr, size_t len, int prot = PROT_READ); // Close down and remove the file from the file system. int remove (void); #if 0 // Hook into the underlying VM system. int advise (int behavior, size_t len = 0); #endif // Return the underlying . int handle (void) const; // Dump the state of an object. void dump (void) const; // Return the status after the constructor int status() {return status_;} private: // Base address of the memory-mapped file. void *base_addr_; // Name of the file that is mapped. char filename_[MAXPATHLEN + 1]; // Length of the mapping. size_t length_; // HANDLE for the open file. int handle_; // status after constructor (allan) int status_; // Keeps track of whether we need to close the handle. This is set // if we opened the file. int close_handle_; // This method does the dirty work of actually calling ::mmap to map // the file into memory. int map_it (int handle, size_t len = 0, int prot = PROT_READ, int share = MAP_SHARED, void *addr = 0, off_t pos = 0); Mem_Map (const Mem_Map &) {} void operator = (const Mem_Map &) {} }; // inlines //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- inline int Mem_Map::handle (void) const { return this->handle_; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- inline int Mem_Map::map (int handle, size_t len, int prot, int share, void *addr, off_t pos) { return this->map_it (handle, len, prot, share, addr, pos); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Remap the file associated with handle_>. inline int Mem_Map::map (size_t len, int prot, int share, void *addr, off_t pos) { return this->map_it (this->handle(), len, prot, share, addr, pos); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // This operator passes back the starting address of the mapped file. inline int Mem_Map::operator () (void *&addr) { if (this->base_addr_ == (void*)MAP_FAILED) { /* allan: not defined on HP */ return -1; } else { addr = this->base_addr_; return 0; } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Return the base address. inline void * Mem_Map::addr (void) const { return this->base_addr_; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // This function returns the number of bytes currently mapped in the // file. inline size_t Mem_Map::size (void) const { return this->length_; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Unmap the region starting at base_addr_>. inline int Mem_Map::unmap (size_t len) { return ::munmap ((caddr_t)this->base_addr_, len == 0 ? this->length_ : len); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Unmap the region starting at . inline int Mem_Map::unmap (void *addr, size_t len) { return ::munmap ((caddr_t)addr, len == 0 ? this->length_ : len); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Sync bytes of the memory region to the backing store starting // at base_addr_>. If == 0 then sync the whole mapped // region. inline int Mem_Map::sync (size_t len, int flags) { return ::msync ((caddr_t)this->base_addr_, len == 0 ? this->length_ : len, flags); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Sync bytes of the memory region to the backing store starting // at . inline int Mem_Map::sync (void *addr, size_t len, int flags) { return ::msync((caddr_t)addr, len, flags); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Change the protection of the pages of the mapped region to // starting at base_addr_> up to bytes. If == 0 // then change protection of all pages in the mapped region. inline int Mem_Map::protect (size_t len, int prot) { if (len == 0) { len = this->length_; } return ::mprotect((caddr_t)this->base_addr_, len, prot); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Change the protection of the pages of the mapped region to // starting at up to bytes. inline int Mem_Map::protect(void *addr, size_t len, int prot) { return ::mprotect((caddr_t)addr, len, prot); } #if 0 //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Hook into the underlying VM system. inline int Mem_Map::advise (int behavior, size_t len) { if (len == 0) { len = this->length_; } return ::madvise ((caddr_t)this->base_addr_, len, behavior); } #endif #endif /* ACE_MEM_MAP_H */ skycat-3.1.2-starlink-1b/tclutil/generic/ShellCommand.C000066400000000000000000000054011215713201500227030ustar00rootroot00000000000000/* * E.S.O. - VLT project / ESO Archive * * "@(#) $Id: ShellCommand.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * ShellCommand.C - methods for class ShellCommand, util class for * running a shell command and getting the output. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 12 Jun 96 Created * pbiereic 17/02/03 Added 'using namespace std'. */ static const char* const rcsId="@(#) $Id: ShellCommand.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include #include #include #include #include #include #include #include #include #include #include #include "error.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" #include "ShellCommand.h" using namespace std; /* * local util to read a file desc into memory and return an * allocated buffer for it. */ static char* read_pipe(int fd) { struct stat stat_buf; if (fstat(fd, &stat_buf) != 0) { sys_error("stat"); return NULL; } char* buf = new char[stat_buf.st_size+1]; buf[0] = '\0'; if (read(fd, buf, stat_buf.st_size) != stat_buf.st_size) { sys_error("read failed"); return NULL; } buf[stat_buf.st_size] = '\0'; return buf; } /* * constructor: runs the command and saves the results */ ShellCommand::ShellCommand(const char* cmd) : status_(0), stdOut_(NULL), stdErr_(NULL) { pid_t pid; int stdout_fds[2], stderr_fds[2]; // stdout and stderr pipes if (pipe(stdout_fds) || pipe(stderr_fds)) { status_ = sys_error("coudn't create pipe"); } pid = fork (); if (pid < 0) { status_ = sys_error("could not fork process"); return; } if (pid == 0) { // child process. dup2(stdout_fds[1], 1); dup2(stderr_fds[1], 2); close(stdout_fds[0]); close(stderr_fds[0]); execl ("/bin/sh", "sh", "-c", cmd, NULL); _exit (256); } // parent process. if (waitpid (pid, &status_, 0) == -1) { status_ = sys_error("error waiting for process"); kill(pid, SIGTERM); // allan: 6.3.98: by request kill(pid, SIGKILL); // in case first kill didn't work return; } int status = status_; // workaround for bug in egcs-1.0.3? status_ = WEXITSTATUS(status); stdOut_ = read_pipe(stdout_fds[0]); stdErr_ = read_pipe(stderr_fds[0]); close(stdout_fds[0]); close(stderr_fds[0]); close(stdout_fds[1]); close(stderr_fds[1]); if (status_ != 0 && stdErr_) { error(stdErr_); } } /* * destructor - free the command results */ ShellCommand::~ShellCommand() { if (stdOut_) delete stdOut_; if (stdErr_) delete stdErr_; } skycat-3.1.2-starlink-1b/tclutil/generic/ShellCommand.h000066400000000000000000000017741215713201500227610ustar00rootroot00000000000000// -*-c++-*- #ifndef _ShellCommand_h_ #define _ShellCommand_h_ /* * E.S.O. - VLT project / ESO Archive * * "@(#) $Id: ShellCommand.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * ShellCommand.h - class to exec a shell command and save the status, * stdout and stderr * * who when what * -------------- --------- ---------------------------------------- * Allan Brighton 12 Jun 96 Created */ class ShellCommand { private: int status_; // command exit status char* stdOut_; // command output char* stdErr_; // error output public: // constructor: runs the command and saves the results. ShellCommand(const char* cmd); // destructor ~ShellCommand(); int status() {return status_;} // return ptr to the stdout or stderr of the command // Note: these will be deleted automatically with this object const char* stdOut() {return stdOut_;} const char* stdErr() {return stdErr_;} }; #endif /* _ShellCommand_h_ */ skycat-3.1.2-starlink-1b/tclutil/generic/TclCommand.C000066400000000000000000000174521215713201500223670ustar00rootroot00000000000000/* * TclCommand.C - base class definitions for tcl command classes * "@(#) $Id: TclCommand.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * pbiereic 17/02/03 Added 'using namespace std'. Removed ::std specs. * */ static const char* const rcsId="@(#) $Id: TclCommand.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "error.h" #include "TclCommand.h" using namespace std; // static member: used to generate unique names int TclCommand::seq_ = 0; // static member: interp used for error reporting Tcl_Interp* TclCommand::maininterp_ = NULL; /* * Constructor - install the named tcl command in the interpreter * and initialize a hash table of tcl subcommands for this command. */ TclCommand::TclCommand(Tcl_Interp* interp, const char* cmdname, const char* instname) : interp_(interp), status_(TCL_OK) { // set the error routine to use for error reporting (see error.C) maininterp_ = interp; set_error_handler(tcl_error); // save the command name cmdname_ = strdup(cmdname); // generate a name if necessary if (strcmp(instname, "#auto") == 0) { instname_ = new char[strlen(cmdname_)+16]; sprintf(instname_, "%s%d", cmdname_, seq_++); } else { instname_ = new char[strlen(instname)+1]; strcpy(instname_, instname); } // create the basic tcl command and return its name Tcl_CreateCommand(interp, instname_, (Tcl_CmdProc*)TclCommand::tclCmdProc, (ClientData)this, TclCommand::tclDeleteProc); // The result of the comamnd is its name // Note: if you access the tcl interpreter in a subclass constructor, // you will have to reset the result again before returning. Tcl_SetResult(interp, instname_, TCL_STATIC); } /* * Dxestructor - called when tcl command is deleted */ TclCommand::~TclCommand() { free((char*)cmdname_); delete[] instname_; instname_ = NULL; } /* * check the arg count for a subcommand and return an error in * Tcl if it is out of range */ int TclCommand::check_args(const char* name, int argc, int min_args, int max_args) { if (argc >= min_args && argc <= max_args) return TCL_OK; Tcl_AppendResult(interp_, "wrong number of args, should be \"", instname_, " ", name, " ?args?\"", NULL); return TCL_ERROR; } /* * Call the given method in this class with the given arguments * (in this case there is only one method defined: "delete" */ int TclCommand::call(const char* name, int len, int argc, char* argv[]) { if (strncmp(name, "delete", len) == 0) { return deleteCmd(argc, argv); } Tcl_AppendResult(interp_, "unknown ", cmdname_, " subcommand: \"", name, "\"", NULL); return TCL_ERROR; } /* * This method is called for operations on the tcl objects created above * - just call a member function to be defined in the subclass */ int TclCommand::tclCmdProc(ClientData thisPtr, Tcl_Interp* interp, int argc, char* argv[]) { // saved this ptr for command TclCommand* tclcmd = (TclCommand*)thisPtr; // must be at least "cmd subcmd" if (argc >= 2) { Tcl_ResetResult(tclcmd->interp_); int len = strlen(argv[1]); if (len) return tclcmd->call(argv[1], len, argc-2, argv+2); } // error: arg count wrong Tcl_AppendResult(interp, "wrong number of args, should be \"", argv[0], " command ?args?\"", NULL); return TCL_ERROR; } /* * This static method is called by Tk when a tcl object is deleted. * Delete the C++ object passed as client data. */ void TclCommand::tclDeleteProc(ClientData thisPtr) { // pointer to current object TclCommand* tclcmd = (TclCommand*)thisPtr; delete tclcmd; } /* * delete subcommand - Remove the Tcl command from the interpreter * (the C++ object is deleted when the tclDeleteProc is called) */ int TclCommand::deleteCmd(int, char**) { return Tcl_DeleteCommand(interp_, instname_); } /* * return an integer value in tcl */ int TclCommand::set_result(int i) { char buf[32]; sprintf(buf, "%d", i); Tcl_SetResult(interp_, buf, TCL_VOLATILE); return TCL_OK; } /* * return 2 integer values in tcl */ int TclCommand::set_result(int i, int j) { char buf[64]; sprintf(buf, "%d %d", i, j); Tcl_SetResult(interp_, buf, TCL_VOLATILE); return TCL_OK; } /* * return 2 double values in tcl */ int TclCommand::set_result(double i, double j) { // PWD: use Tcl_PrintDouble to get tcl_precision encoded doubles. char buf[TCL_DOUBLE_SPACE + 1]; Tcl_ResetResult(interp_); Tcl_PrintDouble(interp_, i, buf ); Tcl_AppendResult(interp_, buf, (char *)NULL); buf[0] = ' '; Tcl_PrintDouble(interp_, j, buf + 1 ); Tcl_AppendResult(interp_, buf, (char *)NULL); return TCL_OK; } /* * return a double value in tcl */ int TclCommand::set_result(double d) { // PWD: use Tcl_PrintDouble to get tcl_precision encoded doubles. char buf[TCL_DOUBLE_SPACE]; Tcl_PrintDouble(interp_, d, buf ); Tcl_SetResult(interp_, buf, TCL_VOLATILE); return TCL_OK; } /* * return a string value in tcl */ int TclCommand::set_result(const char* s) { Tcl_SetResult(interp_, (char*)s, TCL_VOLATILE); return TCL_OK; } /* * Reset the Tcl result to empty */ int TclCommand::reset_result() { Tcl_ResetResult(interp_); return TCL_OK; } /* * append a string value to the tcl result */ int TclCommand::append_result(const char* s) { Tcl_AppendResult(interp_, (char*)s, NULL); return TCL_OK; } /* * append an integer value to the tcl result list */ int TclCommand::append_element(int i) { char buf[32]; sprintf(buf, "%d", i); Tcl_AppendElement(interp_, buf); return TCL_OK; } /* * append 2 integer values to the tcl result list */ int TclCommand::append_element(int i, int j) { char buf[64]; sprintf(buf, "%d %d", i, j); Tcl_AppendElement(interp_, buf); return TCL_OK; } /* * append 2 double values to the tcl result list */ int TclCommand::append_element(double i, double j) { // PWD: use Tcl_PrintDouble to get tcl_precision encoded doubles. char buf[TCL_DOUBLE_SPACE + 1]; Tcl_PrintDouble(interp_, i, buf ); Tcl_AppendElement(interp_, buf); buf[0] = ' '; Tcl_PrintDouble(interp_, j, buf + 1 ); Tcl_AppendElement(interp_, buf); return TCL_OK; } /* * append a double value to the tcl result list */ int TclCommand::append_element(double d) { // PWD: use Tcl_PrintDouble to get tcl_precision encoded doubles. char buf[TCL_DOUBLE_SPACE + 1]; Tcl_PrintDouble(interp_, d, buf ); Tcl_AppendElement(interp_, buf); return TCL_OK; } /* * append a string value to the tcl result list */ int TclCommand::append_element(const char* s) { Tcl_AppendElement(interp_, (char*)s); return TCL_OK; } /* * report an error messageto the tcl result list */ int TclCommand::error(const char* msg1, const char* msg2) { // msg1 or msg2 might be the same as interp_->result... ostringstream os; os << msg1 << msg2; Tcl_ResetResult(interp_); Tcl_SetResult(interp_, (char*)os.str().c_str(), TCL_VOLATILE); return TCL_ERROR; } /* * report an error message, keeping existing messages. */ int TclCommand::more_error(const char* msg1, const char* msg2) { // msg1 or msg2 might be the same as interp_->result... ostringstream os; os << msg1 << msg2; Tcl_AppendResult(interp_, os.str().c_str(), (char *)NULL); return TCL_ERROR; } /* * static error message reporter, called from error.C to report error */ void TclCommand::tcl_error(const char* msg) { Tcl_ResetResult(maininterp_); Tcl_SetResult(maininterp_, (char*)msg, TCL_VOLATILE); } skycat-3.1.2-starlink-1b/tclutil/generic/TclCommand.h000066400000000000000000000060711215713201500224270ustar00rootroot00000000000000// -*-c++-*- #ifndef _TclCommand_H_ #define _TclCommand_H_ /* * TclCommand.h - base class for tcl commands implemented in C++. * * This base class assumes that each derived class has a virtual "call" * member function that will call a method by name to implement a Tcl * subcommand. The search for a member function starts at the bottom * and ends at the top of the class hierarchy - in this class. * * The tcl command is assumed to have an [incr Tcl] like syntax: * * cmdName instName ?args? * or: cmdName #auto ?args? * and then: instName subCmd ?args? * * See the man page for a complete description. * ----------------------------------------------------------------------------- * "@(#) $Id: TclCommand.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" */ #include /* * This is the base class for classes defining tcl commands from * C++ classes */ class TclCommand { protected: // tcl interpreter Tcl_Interp* interp_; static Tcl_Interp* maininterp_; // status after constructor int status_; // class of tcl command (same as prefix for instname_) const char* cmdname_; // name of tcl command created for this object char* instname_; // used to generate unique tcl command name if name is specified as '#auto' static int seq_; protected: // tcl command proc, called by tcl, calls the correct member function static int tclCmdProc(ClientData, Tcl_Interp* interp, int argc, char* argv[]); // tcl delete proc, called when tcl object is deleted static void tclDeleteProc(ClientData); // check the arg count for a subcommand int check_args(const char* name, int argc, int min_args, int max_args); // call a member function by name virtual int call(const char* name, int len, int argc, char* argv[]); // return a value (or a pair of values) in tcl int set_result(int); int set_result(int, int); int set_result(double); int set_result(double, double); int set_result(const char*); // append a string to the tcl result int append_result(const char*); // append a value (or a pair of values) to the tcl result list int append_element(int); int append_element(int, int); int append_element(double); int append_element(double, double); int append_element(const char*); // Reset the Tcl result to empty int reset_result(); // evaluate Tcl code int eval(const char* cmd) {return Tcl_Eval(interp_, (char*)cmd);} // report an error in tcl int error(const char* msg1, const char* msg2=""); int more_error(const char* msg1, const char* msg2=""); static void tcl_error(const char* msg); public: // constructor TclCommand(Tcl_Interp*, const char* cmdname, const char* instname); // destructor virtual ~TclCommand(); // tcl delete sub command (always the same) virtual int deleteCmd(int argc, char** argv); // member access Tcl_Interp* interp() {return interp_;} int status() const { return status_; } char* instname() {return instname_;} }; #endif /* _TclCommand_H_ */ skycat-3.1.2-starlink-1b/tclutil/generic/Tclutil.C000066400000000000000000000055721215713201500217660ustar00rootroot00000000000000/* * E.S.O. - VLT project * "@(#) $Id: Tclutil.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * Tclutil.C - Initialize Tclutil package * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 21 Nov 97 Created * pbiereic 26/08/99 Changed Tclutil_Init() * pbiereic 17/02/03 Added 'using namespace std'. * Allan Brighton 28/12/05 Replaced init script */ static const char* const rcsId="@(#) $Id: Tclutil.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; using namespace std; #include #include #include #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" #include "tcl.h" #include "tk.h" #include "error.h" // Since we have to link the BLT library anyway (because we're using the BLT C interface) // call the init routine directly extern "C" int Blt_Init(Tcl_Interp *interp); // generated code for bitmaps used in tcl scripts void defineTclutilBitmaps(Tcl_Interp*); // Tcl procedure to search for an init for Tclutil startup file. static char initScript[] = "if {[info proc ::util::Init]==\"\"} {\n\ namespace eval ::util {}\n\ proc ::util::Init {} {\n" #ifdef MAC_TCL " source -rsrc TclutilInit.tcl\n" #else " global tclutil_library\n\ tcl_findLibrary tclutil " PACKAGE_VERSION " " PACKAGE_VERSION " TclutilInit.tcl TCLUTIL_LIBRARY tclutil_library\n" #endif " }\n\ }\n\ ::util::Init"; // dummy Tcl command implementation static int tclutil_cmd(ClientData, Tcl_Interp* interp, int argc, char** argv) { return TCL_OK; } /* * A call to this function is made from the tkAppInit file at startup * to initialize this package */ extern "C" int Tclutil_Init(Tcl_Interp* interp) { char buf[1024]; static int initialized = 0; if (initialized++) return TCL_OK; // initialize the required BLT package if (Blt_Init(interp) == TCL_ERROR) { return TCL_ERROR; } // set up Tcl package if (Tcl_PkgProvide(interp, "Tclutil", PACKAGE_VERSION) != TCL_OK) { return TCL_ERROR; } // define bitmaps used by Tcl library defineTclutilBitmaps(interp); // add a dummy tcl command (this command doesn't do anything currently) Tcl_CreateCommand(interp, "tclutil", (Tcl_CmdProc*)tclutil_cmd, NULL, NULL); // Set the global Tcl variable tclutil_version Tcl_SetVar(interp, "tclutil_version", PACKAGE_VERSION, TCL_GLOBAL_ONLY); // Hack to work around problem in older tcl-8.4.x versions: see ./tcl_findLibrary.h #if ((TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 4 && TCL_RELEASE_SERIAL < 11) || TCL_MAJOR_VERSION < 8 || TCL_MINOR_VERSION < 4) #include "tcl_findLibrary.h" if (Tcl_Eval(interp, tcl_findLibrary) != TCL_OK) return TCL_ERROR; #endif return Tcl_Eval(interp, initScript); } skycat-3.1.2-starlink-1b/tclutil/generic/TkImage.C000066400000000000000000000240011215713201500216530ustar00rootroot00000000000000/* * E.S.O. - VLT project * "@(#) $Id: TkImage.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * TkImage.C - base class definitions for Tk images implemented in C++ * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * Peter W. Draper 13/10/97 Added makeGC call to constructor. * Allan Brighton 10/03/98 Pass config options to constructor as pointer * instead of reference. * Peter W. Draper 12/06/98 Removed explicit depth and visual, these * are now left at window defaults. * pbiereic 17/02/03 Added 'using namespace std'. Removed ::std specs. */ static const char* const rcsId="@(#) $Id: TkImage.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; using namespace std; #include #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" #include "error.h" #include "ErrorHandler.h" #include "TkImage.h" /* * Constructor - create the image and install the tcl command of the * same name. * * interp - is the Tk interpreter * * cmdname - is the name of the tcl command that created this image * * instname - is the name of this image (and tcl command) * * specs - is a pointer to the image's config struct, which defines * the config options for the image * * options - is a derived struct that holds the values defined in specs. * * master - is passed from the Tk imaging routines * * pclass - if specified, makes sure that the image window has the given * Tk class */ TkImage::TkImage(Tcl_Interp* interp, const char* cmdname, const char* instname, Tk_ConfigSpec* specs, TkImageOptions* options, Tk_ImageMaster master, char* pclass) : TclCommand(interp, cmdname, instname), optionsPtr_(options), configSpecsPtr_(specs), master_(master), tkwin_(Tk_MainWindow(interp)), display_(Tk_Display(tkwin_)), visual_(Tk_Visual(tkwin_)), screen_(Tk_Screen(tkwin_)), gc_(None), pm_(None), width_(1), height_(1), pixw_(1), pixh_(1), depth_(Tk_Depth(tkwin_)), refCount_(0), pclass_(pclass), initialized_(0), update_pending_(0) { // Allan: Modification by P.W. Draper (advised by Dave Terrett). makeGC(); } /* * Dxestructor - called when tcl command is deleted */ TkImage::~TkImage() { if (gc_ != None) { Tk_FreeGC(display_, gc_); } if (pm_ != None) { XFreePixmap (display_, pm_); } Tk_FreeOptions(configSpecsPtr_, (char *) optionsPtr_, display_, 0); } /* * create the X graphics context for copying the image to the screen */ void TkImage::makeGC() { XColor* white = Tk_GetColor(interp_, tkwin_, "white"); XColor* black = Tk_GetColor(interp_, tkwin_, "black"); XGCValues gcValues; gcValues.foreground = (white != NULL)? white->pixel: WhitePixelOfScreen(screen_); gcValues.background = (black != NULL)? black->pixel: BlackPixelOfScreen(screen_); gcValues.graphics_exposures = False; gc_ = Tk_GetGC(tkwin_, GCForeground|GCBackground|GCGraphicsExposures, &gcValues); } /* * set the image dimensions to the given width and height and * if use_pixmap is 1, create or update a pixmap to have the same * dimensions */ int TkImage::setImageSize(int width, int height, int use_pixmap, int pixw, int pixh) { width_ = width; height_ = height; if (use_pixmap) { if (pm_ == None || pixw_ != pixw || pixh_ != pixh) { // delete previous pixmap if (pm_ != None) { XFreePixmap(display_, pm_); pm_ = None; } // catch errors when image is too large ErrorHandler errorHandler(display_); pm_ = XCreatePixmap(display_, RootWindowOfScreen(screen_), pixw_ = pixw, pixh_ = pixh, depth_); // check for errors if (pm_ == None || errorHandler.errors()) { if (pm_ != None) { XFreePixmap(display_, pm_); pm_ = None; } error("Can't create pixmap large enough to hold image"); Tk_BackgroundError(interp_); return TCL_ERROR; } } } else { if (pm_ != None) { XFreePixmap(display_, pm_); pm_ = None; } } return TCL_OK; } /* * This static method is called by the Tk image handling routines * for each use of the image in a widget. */ ClientData TkImage::GetImage(Tk_Window tkwin, ClientData clientData) { TkImage* thisPtr = (TkImage*)clientData; return (ClientData)thisPtr->getImage(tkwin); } /* * This virtual method is called indirectly by the Tk image handling routines * for each use of the image in a widget. */ TkImage* TkImage::getImage(Tk_Window tkwin) { // only allow one instance (use views instead of instances, since // all instances must be the same size, which is not what we need here) if (refCount_) { error("Only one instance of this image type is allowed"); Tk_BackgroundError(interp_); return NULL; } // if pclass was specified, check that the parent window has that class if (pclass_ != NULL) { if (strcmp(Tk_Class(tkwin), pclass_) != 0) { error("This image type should only be used in a ", pclass_); Tk_BackgroundError(interp_); return NULL; } } refCount_++; // Make a new instance of the image. tkwin_ = tkwin; display_ = Tk_Display(tkwin_); // PWD: leave these at defaults. // visual_ = Tk_Visual(tkwin_); // depth_ = 8; // make the graphics context now that we have the window Tk_MakeWindowExist(tkwin_); // allan: 14.2.96: fix problem reported by // David Terret, when window is not mapped yet makeGC(); Tk_ImageChanged(master_, 0, 0, 0, 0, width_, height_); return this; } /* * This static method is invoked by the Tk image handling routines * to draw a the image. */ void TkImage::DisplayImage( ClientData clientData, // pointer to class instance Display *display, // Display on which to draw image. Drawable drawable, // Pixmap or window in which to draw image. int imageX, int imageY, // Upper-left corner of region within image to draw. int width, int height, // Dimensions of region within image to draw. int drawableX, int drawableY) // Coordinates within drawable that { TkImage* thisPtr = (TkImage*)clientData; thisPtr->displayImage(drawable, imageX, imageY, width, height, drawableX, drawableY); } /* * This static method is called by the Tk image handling routines * when a widget ceases to use a particular instance of an image. * We don't actually get rid of the instance until later because we * may be about to get this instance again. */ void TkImage::FreeImage(ClientData clientData, Display *display) { // TkImage* thisPtr = (TkImage*)clientData; // XXX add a do-when-idle call to delete "thisPtr" ? } /* * This method should be called when the image has changed and should be * redrawn eventually */ void TkImage::imageChanged() { Tk_ImageChanged(master_, 0, 0, width_, height_, width_, height_); update_pending_++; } /* * This static method is invoked by Tk_EventuallyFree to clean up * the internal structure of the image at a safe time */ void TkImage::DeleteImage(ClientData clientData) { TkImage *thisPtr = (TkImage *)clientData; // deleting the tcl command will result in the virtual // destructors being called, which should do the cleanup Tcl_DeleteCommand(thisPtr->interp_, thisPtr->instname_); } /* * This procedure needs to be called from the derived class constructor * to complete the image initialization. This can't be done in the * constructor here since the options_ struct wouldn't be initialized yet. */ int TkImage::initImage(int argc, char* argv[]) { // handle the config options if ((status_ = configureImage(argc, argv, 0)) != TCL_OK) { // XXX add some clean up code here ... return TCL_ERROR; } // return the name of the image as a tcl result Tcl_SetResult(interp_, instname_, TCL_STATIC); initialized_ = 1; return TCL_OK; } /* * utility method: equivalent of Tk "update idletasks" command, * process all pending display events. */ void TkImage::updateIdleTasks() { while (1) { while (Tk_DoOneEvent(TK_IDLE_EVENTS) != 0) { /* Empty loop body */ } XSync(display_, False); if (Tk_DoOneEvent(TK_IDLE_EVENTS) == 0) { break; } } } /* * This procedure is called to process an argv/argc list, plus * the Tk option database, in order to configure (or reconfigure) * a image. */ int TkImage::configureImage(int argc, char* argv[], int flags) { if (Tk_ConfigureWidget(interp_, tkwin_, configSpecsPtr_, argc, argv, (char*)optionsPtr_, flags) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* * this is called for the configure image command */ int TkImage::configureCmd(int argc, char* argv[]) { if (argc == 0) { return Tk_ConfigureInfo(interp_, tkwin_, configSpecsPtr_, (char*)optionsPtr_, NULL, 0); } else if (argc == 1) { return Tk_ConfigureInfo(interp_, tkwin_, configSpecsPtr_, (char*)optionsPtr_, argv[0], 0); } else { return configureImage(argc, argv, TK_CONFIG_ARGV_ONLY); } } /* * this is called for the tcget image command */ int TkImage::cgetCmd(int argc, char* argv[]) { if (argc != 1) { return error("wrong # args: should be: \"$image cget option\""); } return Tk_ConfigureValue(interp_, tkwin_, configSpecsPtr_, (char*)optionsPtr_, argv[0], TK_CONFIG_ARGV_ONLY); } /* * Call the given method in this class with the given arguments */ int TkImage::call(const char* name, int len, int argc, char* argv[]) { if (strncmp(name, "configure", len) == 0) { return configureCmd(argc, argv); } else if (strncmp(name, "cget", len) == 0) { return cgetCmd(argc, argv); } return TclCommand::call(name, len, argc, argv); } /* * delete subcommand - * (should probably redefine to use "image delete $image") */ int TkImage::deleteCmd(int, char**) { return error("use \"image delete $image\" to delete the image."); } skycat-3.1.2-starlink-1b/tclutil/generic/TkImage.h000066400000000000000000000106111215713201500217220ustar00rootroot00000000000000// -*-c++-*- #ifndef _TkImage_H_ #define _TkImage_H_ /* * E.S.O. - VLT project * "@(#) $Id: TkImage.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * TkImage.h - base class for Tk images implemented in C++. * * This class adds some features to the TclCommand class for * implementing Tk image types. * * See the man page for a complete description. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * 10/03/98 Pass config options to constructor as pointer * instead of reference. */ #include #include "TclCommand.h" /* * This class or a class derived from it is used to hold the values * modified by the configure image command */ class TkImageOptions { public: }; /* * This is the base class for classes defining tk images from * C++ classes. * In this class, only one instance of an image may be displayed, * in a window, however multiple views of the image with varying * sizes may be displayed (I didn't see any need for exact copies * of the same image in the same size...) */ class TkImage : public TclCommand { protected: Tk_ImageMaster master_; // passed from the Tk imaging routines TkImageOptions* optionsPtr_; // ptr to class or struct holding option values Tk_ConfigSpec* configSpecsPtr_; // ptr to configSpecs array for Tk options int refCount_; // Number of instances that share this // image (may only be one here). Tk_Window tkwin_; // Window in which the image will be displayed. Display *display_; // X token for the window's display Visual *visual_; // X visual for window Screen *screen_; // X screen for window GC gc_; // Graphics context for copying to screen Pixmap pm_; // Pixmap for storing the image int width_; // total width of image int height_; // total height of image int pixw_; // width of X pixmap, if used int pixh_; // height of X pixmap, if used int depth_; // depth of screen char* pclass_; // if specified, restrict images to only be displayed // in widgets of that class int update_pending_; // flag: true if image needs to be updated int initialized_; // flag: true after image has been initialized // (configured, after constructor is done) // -- member functions -- // do first time image configuration virtual int initImage(int argc, char* argv[]); // configure the image with cmd line options. virtual int configureImage(int argc, char* argv[], int flags = 0); // these are called indirectly by the Tk imaging routines virtual TkImage* getImage(Tk_Window); virtual void displayImage(Drawable, int imageX, int imageY, int width, int height, int drawableX, int drawableY) = 0; // update the image display eventually virtual void imageChanged(); // make the X graphics context void makeGC(); // set the image size and create/update a pixmap, if use_pixmap is 1 int setImageSize(int width, int height, int use_pixmap, int pixw, int pixh); // utility method: equivalent of Tk "update idletasks" command void updateIdleTasks(); // call a member function by name virtual int call(const char* name, int len, int argc, char* argv[]); public: // constructor TkImage(Tcl_Interp* interp, const char* cmdname, const char* instname, Tk_ConfigSpec* specs, TkImageOptions* options, Tk_ImageMaster master, char* pclass = NULL); // destructor virtual ~TkImage(); // the following static methods are called by the Tk image handling routines static ClientData GetImage(Tk_Window, ClientData); static void DisplayImage(ClientData, Display*, Drawable, int imageX, int imageY, int width, int height, int drawableX, int drawableY); static void FreeImage(ClientData, Display*); static void DeleteImage(ClientData); // implement the configure Tk command virtual int configureCmd(int argc, char* argv[]); // called for the cget image command virtual int cgetCmd(int argc, char* argv[]); // delete tcl subcommand // (should probably redefine to use "image delete $image") virtual int deleteCmd(int argc, char* argv[]); // set options pointer void setOptionsPtr(char * ptr) {optionsPtr_ = (TkImageOptions *)ptr;} }; #endif /* _TkImage_H_ */ skycat-3.1.2-starlink-1b/tclutil/generic/TkWidget.C000066400000000000000000000152131215713201500220610ustar00rootroot00000000000000/* * TkWidget.C - base class definitions for Tk widgets implemented in C++ * * "@(#) $Id: TkWidget.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * See the man page for a complete description. * * * who when what * -------------- -------- ---------------------------------------- * pbiereic 17/02/03 Added 'using namespace std'. Removed ::std specs. */ static const char* const rcsId="@(#) $Id: TkWidget.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; using namespace std; #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "TkWidget.h" /* * Constructor - create the widget and install the tcl command of the * same name. * * pclass - if non null, is the expected class of the parent widget * (Canvas, Frame, ...) * * specs - is a pointer to the widget's config struct, which defines * the config options for the widget * * options - is a derived struct that holds the values defined in specs. * * argc, argv - are passed from the widget command (argv[0] is the widget command) */ TkWidget::TkWidget(Tcl_Interp* interp, const char* pclass, Tk_ConfigSpec* specs, TkWidgetOptions& options, int /* argc */, char* argv[]) : TclCommand(interp, argv[0], argv[1]), tkwin_(NULL), pname_(strdup(instname_)), wclass_(strdup(cmdname_)), configSpecsPtr_(specs), optionsPtr_(&options), redraw_pending_(0) { // if pclass was specified, check that the parent window has that class if (pclass != NULL) { // get the name of the parent window from the widgets's path char* p = strrchr(pname_, '.'); if (p != NULL) *p = '\0'; if (p == NULL || strcmp(Tk_Class(Tk_NameToWindow(interp, pname_, Tk_MainWindow(interp))), pclass) != 0) { status_ = TCL_ERROR; Tcl_ResetResult(interp_); Tcl_AppendResult(interp, "bad path name for ", cmdname_, ": \"", instname_, "\" parent of ", cmdname_, " should be a ", pclass, " widget", 0); return; } } // create the widget window tkwin_ = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), instname_, NULL); if (tkwin_ == NULL) { status_ = TCL_ERROR; return; } display_ = Tk_Display(tkwin_); // set the class to the widget type with the first letter capitalized *wclass_ = toupper(*wclass_); Tk_SetClass(tkwin_, wclass_); // add event handler to catch destroy event Tk_CreateEventHandler(tkwin_, StructureNotifyMask, structureNotify, (ClientData)this); } /* * Dxestructor - called when tcl command is deleted */ TkWidget::~TkWidget() { free(pname_); free(wclass_); /* free config options */ Tk_FreeOptions(configSpecsPtr_, (char *) optionsPtr_, display_, 0); } /* * This static method is called for StructureNotify events in the widget */ void TkWidget::structureNotify(ClientData clientData, XEvent *eventPtr) { TkWidget* thisPtr = (TkWidget*)clientData; if (eventPtr->type == DestroyNotify) thisPtr->destroyNotify(eventPtr); else if (eventPtr->type == ConfigureNotify) thisPtr->configureNotify(eventPtr); } /* * method called for DestroyNotify events in the widget */ void TkWidget::destroyNotify(XEvent *eventPtr) { Tk_CancelIdleCall(redrawWidget, (ClientData)this); tkwin_ = NULL; Tk_EventuallyFree((ClientData) this, destroyProc); } /* * method called for ConfigureNotify events in the widget * (when the window is resized) */ void TkWidget::configureNotify(XEvent *eventPtr) { } /* * This static method is invoked by Tk_EventuallyFree to clean up * the internal structure of the widget at a safe time */ void TkWidget::destroyProc(char *clientData) { TkWidget *thisPtr = (TkWidget *)clientData; // deleting the tcl command will result in the virtual // destructors being called, which should do the cleanup Tcl_DeleteCommand(thisPtr->interp_, thisPtr->instname_); } /* * This procedure needs to be called from the derived class constructor * to complete the widget initialization. This can't be done in the * constructor here since the options_ struct wouldn't be initialized yet. */ int TkWidget::initWidget(int argc, char* argv[]) { // handle the config options if ((status_ = configureWidget(argc-2, argv+2, 0)) != TCL_OK) { Tk_DestroyWindow(tkwin_); tkwin_ = NULL; return TCL_ERROR; } // return the name of the widget as a tcl result Tcl_SetResult(interp_, instname_, TCL_STATIC); return TCL_OK; } /* * This procedure is called to process an argv/argc list, plus * the Tk option database, in order to configure (or reconfigure) * a widget. */ int TkWidget::configureWidget(int argc, char* argv[], int flags) { if (Tk_ConfigureWidget(interp_, tkwin_, configSpecsPtr_, argc, argv, (char*)optionsPtr_, flags) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* * this is called for the configure widget command */ int TkWidget::configureCmd(int argc, char* argv[]) { if (argc == 0) { return Tk_ConfigureInfo(interp_, tkwin_, configSpecsPtr_, (char*)optionsPtr_, NULL, 0); } else if (argc == 1) { return Tk_ConfigureInfo(interp_, tkwin_, configSpecsPtr_, (char*)optionsPtr_, argv[0], 0); } else { eventually_redraw(); return configureWidget(argc, argv, TK_CONFIG_ARGV_ONLY); } } /* * If not already scheduled, schedule the widget to be redrawn */ int TkWidget::eventually_redraw() { if (!redraw_pending_) { Tk_DoWhenIdle(redrawWidget, (ClientData) this); redraw_pending_ = 1; } return TCL_OK; } /* * Redraw the widget by calling the virtual redraw_ method * which may be defined in a derived class. */ void TkWidget::redrawWidget(ClientData clientData) { TkWidget* thisPtr = (TkWidget*)clientData; thisPtr->redraw(); thisPtr->redraw_pending_ = 0; } /* * this method may be redefined in a derived class to redraw * the widget. */ void TkWidget::redraw() { } /* * this is called for the tcget widget command */ int TkWidget::cgetCmd(int argc, char* argv[]) { if (argc != 1) return error("wrong # args: should be: \"$widget cget option\""); return Tk_ConfigureValue(interp_, tkwin_, configSpecsPtr_, (char*)optionsPtr_, argv[0], TK_CONFIG_ARGV_ONLY); } /* * Call the given method in this class with the given arguments * (In this case there is only one command defined: "configure" */ int TkWidget::call(const char* name, int len, int argc, char* argv[]) { if (strncmp(name, "configure", len) == 0) { return configureCmd(argc, argv); } else if (strncmp(name, "cget", len) == 0) { return cgetCmd(argc, argv); } return TclCommand::call(name, len, argc, argv); } skycat-3.1.2-starlink-1b/tclutil/generic/TkWidget.h000066400000000000000000000055461215713201500221360ustar00rootroot00000000000000// -*-c++-*- #ifndef _TkWidget_H_ #define _TkWidget_H_ /* * TkWidget.h - base class for Tk widgets implemented in C++. * * This class adds some features to the TclCommand class for * implementing Tk widgets. * * See the man page for a complete description. * * ----------------------------------------------------------------------------- * "@(#) $Id: TkWidget.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" */ #include #include "TclCommand.h" /* * A struct derived from this one is used to hold the values * modified by the configure widget command */ class TkWidgetOptions {}; /* * This is the base class for classes defining tk widgets from * C++ classes */ class TkWidget : public TclCommand { protected: Tk_Window tkwin_; // widget's Tk window Display *display_; // X token for the window's display char* pname_; // name of parent window char* wclass_; // this widget's class Tk_ConfigSpec* configSpecsPtr_; // ptr to widget's config struct TkWidgetOptions* optionsPtr_; // ptr to struct holding option values int redraw_pending_; // flag: true if widget needs to be redrawn // do first time widget configuration virtual int initWidget(int argc, char* argv[]); // configure the widget with cmd line options. virtual int configureWidget(int argc, char* argv[], int flags = 0); // If not already scheduled, schedule the widget to be redrawn virtual int eventually_redraw(); // this method may be redefined in a derived class to redraw // the widget. virtual void redraw(); // called for DestroyNotify events in the widget virtual void destroyNotify(XEvent *eventPtr); // called for ConfigureNotify events (resize) virtual void configureNotify(XEvent *eventPtr); public: // constructor: pclass is the expected parent window class type, // the specs and options args are used to process the command line // args and for the configure widget command. TkWidget(Tcl_Interp*, const char* pclass, Tk_ConfigSpec* specs, TkWidgetOptions& options, int argc, char* argv[]); // destructor virtual ~TkWidget(); // call a member function by name virtual int call(const char* name, int len, int argc, char* argv[]); virtual int configureCmd(int argc, char* argv[]); // called for the cget widget command virtual int cgetCmd(int argc, char* argv[]); // Redraw the widget by calling the virtual redraw_ method // which may be defined in a derived class. static void redrawWidget(ClientData); // called for StructureNotify events in the widget static void structureNotify(ClientData clientData, XEvent *eventPtr); // invoked by Tk_EventuallyFree to clean up widget static void destroyProc(char *clientData); }; #endif /* _TkWidget_H_ */ skycat-3.1.2-starlink-1b/tclutil/generic/base64.C000066400000000000000000000067351215713201500214340ustar00rootroot00000000000000 /* * E.S.O. - VLT project/ESO Archive * $Id: base64.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * base64.C - utility routines for base64 encoding and decoding * (needed for some HTTP protocols, such as password * encoding). * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton Jul 15 Created, based on modified versions of * mozilla routines in libi18n/mime2fun.c * See http://www.mozilla.org/NPL/. */ static const char* const rcsId="@(#) $Id: base64.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include #include #include #include #include "base64.h" static char basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static int encode_base64_ (const char *in, char *out) { unsigned char c1, c2, c3; c1 = in[0]; c2 = in[1]; c3 = in[2]; *out++ = basis_64[c1>>2]; *out++ = basis_64[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)]; *out++ = basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)]; *out++ = basis_64[c3 & 0x3F]; return 1; } char *encode_base64(char *input) { char *output = 0; char *pSrc, *pDest ; int i ; size_t size = strlen(input); output = (char *)malloc(size * 4 / 3 + 4); if (output == NULL) return NULL; pSrc = input; pDest = output ; for (i = size; i >= 3; i -= 3) { if (encode_base64_(pSrc, pDest) == 0) { /* error */ pSrc += 3; pDest += 3; } else { pSrc += 3; pDest += 4; } } /* in case (i % 3 ) == 1 or 2 */ if(i > 0) { char in[3]; int j; in[0] = in[1] = in[2] ='\0'; for(j=0;j= 'A' && in[j] <= 'Z') c = in[j] - 'A'; else if (in[j] >= 'a' && in[j] <= 'z') c = in[j] - ('a' - 26); else if (in[j] >= '0' && in[j] <= '9') c = in[j] - ('0' - 52); else if (in[j] == '+') c = 62; else if (in[j] == '/') c = 63; else if (in[j] == '=') c = 0; else { /* abort (); */ strcpy(out, in); /* I hate abort */ return 0; } num = (num << 6) | c; } *out++ = (unsigned char) (num >> 16); *out++ = (unsigned char) ((num >> 8) & 0xFF); *out++ = (unsigned char) (num & 0xFF); return 1; } char *decode_base64(char *input) { char *output = strdup(input);; char *pSrc = input, *pDest = output; int i ; for (i = strlen(input); i > 3; i -= 4) { if (decode_base64_(pSrc, pDest) == 0) { pSrc += 4; pDest += 4; } else { pSrc += 4; pDest += 3; } } *pDest = '\0'; return output; } #if TEST_BASE64 /* for testing */ main() { char* input = "Aladdin:open sesame"; char* base64 = "QWxhZGRpbjpvcGVuIHNlc2FtZQ=="; char* s = encode_base64(input); char* output = decode_base64(s); printf("base64 encoded value of %s is %s (should be %s)\n", input, s, base64); printf("decoded value of input %s is %s\n", s, output); printf("decoded value of target %s is %s\n", base64, decode_base64(base64)); if (strcmp(input, output) == 0) printf("TEST PASSED\n"); else printf("TEST FAILED\n"); exit(0); } #endif skycat-3.1.2-starlink-1b/tclutil/generic/base64.h000066400000000000000000000006401215713201500214660ustar00rootroot00000000000000 /* * E.S.O. - VLT project/ESO Archive * $Id: base64.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * base64.h - declarations for base64 encoding and decoding * utility routines. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton Jul 15 Created */ char *encode_base64(char *input); char *decode_base64(char *input); skycat-3.1.2-starlink-1b/tclutil/generic/define.h000066400000000000000000000063341215713201500216420ustar00rootroot00000000000000// -*-c++-*- #ifndef _define_h_ #define _define_h_ /* * * E.S.O. - VLT project * * $Id: define.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ * * define.h - common definitions * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * pbiereic 17/02/03 Added defines for byte swap and SOCKLEN_T * Peter W. Draper 16/12/05 Redo SOCKLEN_T logic. Only set when socklen_t * is not defined. Use a typedef. * pbiereic 12/08/07 added support for data types double and long long int */ #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif // Byte swap defines. On little Endian machines we use the network-to-host // routines since they are faster (implemented in assembler code). #ifdef WORDS_BIGENDIAN # define BIGENDIAN 1 // from /usr/include/bits/byteswap.h: # define SWAP16(x) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)) # define SWAP32(x) ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) #else # define BIGENDIAN 0 # define SWAP16(x) (ntohs((unsigned short)x)) # define SWAP32(x) (ntohl((unsigned int)x)) #endif /* ifdef WORDS_BIGENDIAN */ #define SWAP64(x) ( \ (((x) & 0xff00000000000000ull) >> 56) \ | (((x) & 0x00ff000000000000ull) >> 40) \ | (((x) & 0x0000ff0000000000ull) >> 24) \ | (((x) & 0x000000ff00000000ull) >> 8) \ | (((x) & 0x00000000ff000000ull) << 8) \ | (((x) & 0x0000000000ff0000ull) << 24) \ | (((x) & 0x000000000000ff00ull) << 40) \ | (((x) & 0x00000000000000ffull) << 56)) // Float data: Prevent auto conversions. // No speed hits if this is compiled with gcc -O. inline float SWAP_FLOAT(float x) { union {float f; unsigned int i;} u; u.f = x; u.i = SWAP32(u.i); return u.f; } inline double SWAP_DOUBLE(double x) { union {double d; unsigned long long l;} u; u.d = x; u.l = SWAP64(u.l); return u.d; } /* Make sure we always have a socklen_t type */ #if ! HAVE_SOCKLEN_T # if defined(linux) typedef unsigned int socklen_t; # elif defined(_XPG4_2) typedef size_t socklen_t; # else typedef int socklen_t; # endif #endif // min/max inline int min(int x, int y) {return xy ? x : y;} inline double min(double x, double y) {return xy ? x : y;} // swap values inline void swap(int& x, int& y) {int tmp = x; x = y; y = tmp;} inline void swap(double& x, double& y) {double tmp = x; x = y; y = tmp;} // inline int roundup(int nbytes, int pad) {return ((nbytes + (pad - 1)) / pad) * pad;} /* * time a function call * usage: TIMECALL("name", function(args,...)); */ #ifndef DEBUG #define TIMECALL(name,func) func #else #include #include #include extern "C" int ftime(timeb *tp); #define TIMECALL(name,func) {\ timeb tp1,tp2; \ ftime(&tp1); \ func; \ ftime(&tp2); \ fprintf(stderr, "time %s: %d\n", name, (tp2.time-tp1.time)*1000+(tp2.millitm-tp1.millitm)); \ } #endif #endif /* _define_h_ */ skycat-3.1.2-starlink-1b/tclutil/generic/error.C000066400000000000000000000121311215713201500214640ustar00rootroot00000000000000/* * E.S.O. - VLT project * "@(#) $Id: error.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * error.C - error reporting routines * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created * Peter W. Draper 08/05/98 ifdef'd errno.h include for * linux. Something horrible happens here * under RH5 and glibc. * 08/12/98 Changed for egcs compiler * 21/01/03 Changed for gcc3, now only uses syserror * rather than errno and sys_errlist. * 30/04/03 Removed ifdef for errno.h. Needed back * for RH7.3. * Allan Brighton 01/04/99 Replaced sys_errlist[] with strerror() * to get around porting problems * 20/01/03 Updated for gcc-3.2.1 * pbiereic 17/02/03 Added 'using namespace std'. Removed ::std specs. */ static const char* const rcsId="@(#) $Id: error.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include #include #include #include #include #include #include #include "error.h" using namespace std; // static variable holding text of last error messages static char errmsg_[5*1024]; // error code (see defines in for values) static int errno_ = 0; // optional error handler, to be called with error messages static void (*errhandler_)(const char*) = NULL; // optional message handler, to be called with log messages static void (*msghandler_)(const char*) = NULL; /* * global error reporting routine */ int error(const char* msg1, const char* msg2, int code) { ostringstream os; os << msg1 << msg2; if (errhandler_) (*errhandler_)(os.str().c_str()); else print_error(os.str().c_str()); #ifdef XXXDEBUG cerr << "debug: " << os.str().c_str() << endl; #endif errno_ = code; strncpy(errmsg_, os.str().c_str(), sizeof(errmsg_)-1); return ERROR; } /* * report the error, including system error code */ int sys_error(const char* msg1, const char* msg2) { char* s = strerror(errno); if (s == NULL || errno < 0 ) { return error(msg1, msg2); } ostringstream os; os << msg1 << msg2 << ": " << s; if (errhandler_) (*errhandler_)(os.str().c_str()); else print_error(os.str().c_str()); #ifdef XXXDEBUG cerr << "debug: " << os.str().c_str() << endl; #endif errno_ = errno; strncpy(errmsg_, os.str().c_str(), sizeof(errmsg_)-1); return ERROR; } /* * This routine has an interface like printf and reports an error in the * same way as error() above. */ int fmt_error(const char* fmt, ...) { char buf[1024]; va_list ap; va_start(ap, fmt); vsprintf(buf, fmt, ap); va_end(ap); return error(buf); } /* * This routine has an interface like printf and reports a system error * in the same way as sys_error() above. */ int fmt_sys_error(const char* fmt, ...) { char buf[1024]; va_list ap; va_start(ap, fmt); vsprintf(buf, fmt, ap); va_end(ap); return sys_error(buf); } /* * return the text of the previous error message */ char* last_error() { return errmsg_; } /* * return the error code for the previous error */ int last_error_code() { return errno_; } /* * reset the last_error buf to empty */ void clear_error() { errmsg_[0] = '\0'; } /* * set a routine to be called with the text of error messages * when they occur. The argument is a pointer to an error * handler: * * void errhandler(const char* msg); * * The return value is a pointer to the previous error handler, or NULL, * if none was defined. */ void (*set_error_handler(void (*errhandler)(const char*)))(const char*) { void (*old_handler)(const char*) = errhandler_; errhandler_ = errhandler; return old_handler; } /* * print the given message on stderr (may be used as an error * handler) */ void print_error(const char* msg) { fprintf(stderr, "%s\n", msg); fflush(stderr); } /* ---- The routines below are for log messages that are not errors --- */ /* * This routine logs a message and has an interface like printf. */ void log_message(const char* fmt, ...) { char buf[1024]; va_list ap; va_start(ap, fmt); vsprintf(buf, fmt, ap); va_end(ap); if (msghandler_) (*msghandler_)(buf); else print_log_message(buf); } /* * set a routine to be called with the text of log messages * when they are made. The argument is a pointer to a log message * handler: * * void msghandler(const char* msg); * * The return value is a pointer to the previous message handler, or NULL, * if none was defined. */ void (*set_log_message_handler(void (*msghandler)(const char*)))(const char*) { void (*old_handler)(const char*) = msghandler_; msghandler_ = msghandler; return old_handler; } /* * print the given message on stdout (may be used as a message * handler) */ void print_log_message(const char* msg) { printf("%s\n", msg); fflush(stdout); } skycat-3.1.2-starlink-1b/tclutil/generic/error.h000066400000000000000000000031111215713201500215270ustar00rootroot00000000000000#ifndef _error_h_ #define _error_h_ /* * E.S.O. - VLT project * "@(#) $Id: error.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * error.h - declarations for global error reporting * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 05/10/95 Created */ /* error status */ #undef OK #undef ERROR enum {OK, ERROR}; /* report the error */ int error(const char* msg1, const char* msg2="", int code = 0); /* report the error with the system error code, like perror */ int sys_error(const char* msg1, const char* msg2=""); /* report error with a printf style interface */ int fmt_error(const char* fmt, ...); /* report a system error with a printf style interface */ int fmt_sys_error(const char* fmt, ...); /* return the text of the previous error message */ char* last_error(); /* return the error code for the previous error */ int last_error_code(); /* reset the last_error buf to empty */ void clear_error(); /* set a routine to be called when errors occur and return ptr to previous handler */ void (*set_error_handler(void (*error_handler)(const char*)))(const char*); /* simple error handler: print the message */ void print_error(const char* msg); /* print a message (like printf) */ void log_message(const char* fmt, ...); /* set a routine to be called for log messages and return ptr to previous handler */ void (*set_log_message_handler(void (*message_handler)(const char*)))(const char*); /* simple message handler: print the message */ void print_log_message(const char* msg); #endif /* _error_h_ */ skycat-3.1.2-starlink-1b/tclutil/generic/tcl_findLibrary.h000066400000000000000000000055621215713201500235210ustar00rootroot00000000000000/* * E.S.O. - VLT project * "@(#) $Id: tcl_findLibrary.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * Replacement for Tcl's tcl_findLibrary script (This version is taken * from tcl-8.4.11/auto.tcl). * In earlier Tcl versions, this script did not look in the auto_path * for extensions. * * who when what * -------------- -------- ---------------------------------------- * Allan Brighton 11/01/06 created */ static const char* const rcsId="@(#) $Id: tcl_findLibrary.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; char* tcl_findLibrary = "proc tcl_findLibrary {basename version patch initScript enVarName varName} {\n" " upvar #0 $varName the_library\n" " global env errorInfo\n" " set dirs {}\n" " set errors {}\n" " set variableSet [info exists the_library]\n" " if {$variableSet && $the_library != \"\"} {\n" " lappend dirs $the_library\n" " } else {\n" " if {[info exists env($enVarName)]} {\n" " lappend dirs $env($enVarName)\n" " }\n" " foreach d $::auto_path {\n" " lappend dirs [file join $d $basename$version]\n" " if {$::tcl_platform(platform) == \"unix\"\n" " && $::tcl_platform(os) ==\"Darwin\"} {\n" " lappend dirs [file join $d $basename$version Resources Scripts]\n" " }\n" " }\n" " set parentDir [file dirname [file dirname [info nameofexecutable]]]\n" " set grandParentDir [file dirname $parentDir]\n" " lappend dirs [file join $parentDir lib $basename$version]\n" " lappend dirs [file join $grandParentDir lib $basename$version]\n" " lappend dirs [file join $parentDir library]\n" " if {1} {\n" " lappend dirs [file join $grandParentDir library]\n" " lappend dirs [file join $grandParentDir $basename$patch library]\n" " lappend dirs [file join [file dirname $grandParentDir] \\n" " $basename$patch library]\n" " }\n" " }\n" " array set seen {}\n" " foreach i $dirs {\n" " if {1 || [interp issafe]} {\n" " set norm $i\n" " } else {\n" " set norm [file normalize $i]\n" " }\n" " if {[info exists seen($norm)]} { continue }\n" " set seen($norm) \"\"\n" " lappend uniqdirs $i\n" " }\n" " set dirs $uniqdirs\n" " foreach i $dirs {\n" " set the_library $i\n" " set file [file join $i $initScript]\n" " if {[interp issafe] || [file exists $file]} {\n" " if {![catch {uplevel #0 [list source $file]} msg]} {\n" " return\n" " } else {\n" " append errors \"$file: $msg\n$errorInfo\n\"\n" " }\n" " }\n" " }\n" " if {!$variableSet} {\n" " unset the_library\n" " }\n" " set msg \"Can't find a usable $initScript in the following directories: \n\"\n" " append msg \" $dirs\n\n\"\n" " append msg \"$errors\n\n\"\n" " append msg \"This probably means that $basename wasn't installed properly.\n\"\n" " error $msg\n" "}\n"; skycat-3.1.2-starlink-1b/tclutil/generic/tclutil_bitmaps.C000066400000000000000000000227731215713201500235470ustar00rootroot00000000000000 /* * E.S.O. - VLT project * "@(#) $Id: tclutil_bitmaps.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * Bitmap definitions for Tk * * This file was generated by ../bitmaps/bitmaps.tcl - DO NO EDIT */ #include #include void defineTclutilBitmaps(Tcl_Interp *interp) { #include "ar6_6_4.xbm" Tk_DefineBitmap(interp, Tk_GetUid("ar6_6_4"), (char*)ar6_6_4_bits, ar6_6_4_width, ar6_6_4_height); #include "arrowboth.xbm" Tk_DefineBitmap(interp, Tk_GetUid("arrowboth"), (char*)arrowboth_bits, arrowboth_width, arrowboth_height); #include "files.xbm" Tk_DefineBitmap(interp, Tk_GetUid("files"), (char*)files_bits, files_width, files_height); #include "width1.xbm" Tk_DefineBitmap(interp, Tk_GetUid("width1"), (char*)width1_bits, width1_width, width1_height); #include "width2.xbm" Tk_DefineBitmap(interp, Tk_GetUid("width2"), (char*)width2_bits, width2_width, width2_height); #include "width3.xbm" Tk_DefineBitmap(interp, Tk_GetUid("width3"), (char*)width3_bits, width3_width, width3_height); #include "width4.xbm" Tk_DefineBitmap(interp, Tk_GetUid("width4"), (char*)width4_bits, width4_width, width4_height); #include "arrownone.xbm" Tk_DefineBitmap(interp, Tk_GetUid("arrownone"), (char*)arrownone_bits, arrownone_width, arrownone_height); #include "circle.xbm" Tk_DefineBitmap(interp, Tk_GetUid("circle"), (char*)circle_bits, circle_width, circle_height); #include "dir.xbm" Tk_DefineBitmap(interp, Tk_GetUid("dir"), (char*)dir_bits, dir_width, dir_height); #include "shiftb1.xbm" Tk_DefineBitmap(interp, Tk_GetUid("shiftb1"), (char*)shiftb1_bits, shiftb1_width, shiftb1_height); #include "down.xbm" Tk_DefineBitmap(interp, Tk_GetUid("down"), (char*)down_bits, down_width, down_height); #include "label.xbm" Tk_DefineBitmap(interp, Tk_GetUid("label"), (char*)label_bits, label_width, label_height); #include "polygon.xbm" Tk_DefineBitmap(interp, Tk_GetUid("polygon"), (char*)polygon_bits, polygon_width, polygon_height); #include "ar10_13_3.xbm" Tk_DefineBitmap(interp, Tk_GetUid("ar10_13_3"), (char*)ar10_13_3_bits, ar10_13_3_width, ar10_13_3_height); #include "right.xbm" Tk_DefineBitmap(interp, Tk_GetUid("right"), (char*)right_bits, right_width, right_height); #include "ar8_10_3.xbm" Tk_DefineBitmap(interp, Tk_GetUid("ar8_10_3"), (char*)ar8_10_3_bits, ar8_10_3_width, ar8_10_3_height); #include "left.xbm" Tk_DefineBitmap(interp, Tk_GetUid("left"), (char*)left_bits, left_width, left_height); #include "pat0.xbm" Tk_DefineBitmap(interp, Tk_GetUid("pat0"), (char*)pat0_bits, pat0_width, pat0_height); #include "pat1.xbm" Tk_DefineBitmap(interp, Tk_GetUid("pat1"), (char*)pat1_bits, pat1_width, pat1_height); #include "pat2.xbm" Tk_DefineBitmap(interp, Tk_GetUid("pat2"), (char*)pat2_bits, pat2_width, pat2_height); #include "pat3.xbm" Tk_DefineBitmap(interp, Tk_GetUid("pat3"), (char*)pat3_bits, pat3_width, pat3_height); #include "pat4.xbm" Tk_DefineBitmap(interp, Tk_GetUid("pat4"), (char*)pat4_bits, pat4_width, pat4_height); #include "pat5.xbm" Tk_DefineBitmap(interp, Tk_GetUid("pat5"), (char*)pat5_bits, pat5_width, pat5_height); #include "pat6.xbm" Tk_DefineBitmap(interp, Tk_GetUid("pat6"), (char*)pat6_bits, pat6_width, pat6_height); #include "pat7.xbm" Tk_DefineBitmap(interp, Tk_GetUid("pat7"), (char*)pat7_bits, pat7_width, pat7_height); #include "pat8.xbm" Tk_DefineBitmap(interp, Tk_GetUid("pat8"), (char*)pat8_bits, pat8_width, pat8_height); #include "pat9.xbm" Tk_DefineBitmap(interp, Tk_GetUid("pat9"), (char*)pat9_bits, pat9_width, pat9_height); #include "rotate.xbm" Tk_DefineBitmap(interp, Tk_GetUid("rotate"), (char*)rotate_bits, rotate_width, rotate_height); #include "anyselect.xbm" Tk_DefineBitmap(interp, Tk_GetUid("anyselect"), (char*)anyselect_bits, anyselect_width, anyselect_height); #include "freehand.xbm" Tk_DefineBitmap(interp, Tk_GetUid("freehand"), (char*)freehand_bits, freehand_width, freehand_height); #include "magnify.xbm" Tk_DefineBitmap(interp, Tk_GetUid("magnify"), (char*)magnify_bits, magnify_width, magnify_height); #include "file.xbm" Tk_DefineBitmap(interp, Tk_GetUid("file"), (char*)file_bits, file_width, file_height); #include "b1.xbm" Tk_DefineBitmap(interp, Tk_GetUid("b1"), (char*)b1_bits, b1_width, b1_height); #include "b2.xbm" Tk_DefineBitmap(interp, Tk_GetUid("b2"), (char*)b2_bits, b2_width, b2_height); #include "b3.xbm" Tk_DefineBitmap(interp, Tk_GetUid("b3"), (char*)b3_bits, b3_width, b3_height); #include "square.xbm" Tk_DefineBitmap(interp, Tk_GetUid("square"), (char*)square_bits, square_width, square_height); #include "smooth.xbm" Tk_DefineBitmap(interp, Tk_GetUid("smooth"), (char*)smooth_bits, smooth_width, smooth_height); #include "text.xbm" Tk_DefineBitmap(interp, Tk_GetUid("text"), (char*)text_bits, text_width, text_height); #include "ar8_8_6.xbm" Tk_DefineBitmap(interp, Tk_GetUid("ar8_8_6"), (char*)ar8_8_6_bits, ar8_8_6_width, ar8_8_6_height); #include "pat10.xbm" Tk_DefineBitmap(interp, Tk_GetUid("pat10"), (char*)pat10_bits, pat10_width, pat10_height); #include "pat11.xbm" Tk_DefineBitmap(interp, Tk_GetUid("pat11"), (char*)pat11_bits, pat11_width, pat11_height); #include "pat12.xbm" Tk_DefineBitmap(interp, Tk_GetUid("pat12"), (char*)pat12_bits, pat12_width, pat12_height); #include "pat13.xbm" Tk_DefineBitmap(interp, Tk_GetUid("pat13"), (char*)pat13_bits, pat13_width, pat13_height); #include "pat14.xbm" Tk_DefineBitmap(interp, Tk_GetUid("pat14"), (char*)pat14_bits, pat14_width, pat14_height); #include "pat15.xbm" Tk_DefineBitmap(interp, Tk_GetUid("pat15"), (char*)pat15_bits, pat15_width, pat15_height); #include "abc.xbm" Tk_DefineBitmap(interp, Tk_GetUid("abc"), (char*)abc_bits, abc_width, abc_height); #include "decr.xbm" Tk_DefineBitmap(interp, Tk_GetUid("decr"), (char*)decr_bits, decr_width, decr_height); #include "ar12_11_3.xbm" Tk_DefineBitmap(interp, Tk_GetUid("ar12_11_3"), (char*)ar12_11_3_bits, ar12_11_3_width, ar12_11_3_height); #include "shrink.xbm" Tk_DefineBitmap(interp, Tk_GetUid("shrink"), (char*)shrink_bits, shrink_width, shrink_height); #include "oval.xbm" Tk_DefineBitmap(interp, Tk_GetUid("oval"), (char*)oval_bits, oval_width, oval_height); #include "objselect.xbm" Tk_DefineBitmap(interp, Tk_GetUid("objselect"), (char*)objselect_bits, objselect_width, objselect_height); #include "flipx.xbm" Tk_DefineBitmap(interp, Tk_GetUid("flipx"), (char*)flipx_bits, flipx_width, flipx_height); #include "flipy.xbm" Tk_DefineBitmap(interp, Tk_GetUid("flipy"), (char*)flipy_bits, flipy_width, flipy_height); #include "ar8_12_9.xbm" Tk_DefineBitmap(interp, Tk_GetUid("ar8_12_9"), (char*)ar8_12_9_bits, ar8_12_9_width, ar8_12_9_height); #include "polyline.xbm" Tk_DefineBitmap(interp, Tk_GetUid("polyline"), (char*)polyline_bits, polyline_width, polyline_height); #include "ar12_12_3.xbm" Tk_DefineBitmap(interp, Tk_GetUid("ar12_12_3"), (char*)ar12_12_3_bits, ar12_12_3_width, ar12_12_3_height); #include "down_arrow.xbm" Tk_DefineBitmap(interp, Tk_GetUid("down_arrow"), (char*)down_arrow_bits, down_arrow_width, down_arrow_height); #include "shiftdragb1.xbm" Tk_DefineBitmap(interp, Tk_GetUid("shiftdragb1"), (char*)shiftdragb1_bits, shiftdragb1_width, shiftdragb1_height); #include "up.xbm" Tk_DefineBitmap(interp, Tk_GetUid("up"), (char*)up_bits, up_width, up_height); #include "dragb1.xbm" Tk_DefineBitmap(interp, Tk_GetUid("dragb1"), (char*)dragb1_bits, dragb1_width, dragb1_height); #include "dragb2.xbm" Tk_DefineBitmap(interp, Tk_GetUid("dragb2"), (char*)dragb2_bits, dragb2_width, dragb2_height); #include "dragb3.xbm" Tk_DefineBitmap(interp, Tk_GetUid("dragb3"), (char*)dragb3_bits, dragb3_width, dragb3_height); #include "arrowfirst.xbm" Tk_DefineBitmap(interp, Tk_GetUid("arrowfirst"), (char*)arrowfirst_bits, arrowfirst_width, arrowfirst_height); #include "up_arrow.xbm" Tk_DefineBitmap(interp, Tk_GetUid("up_arrow"), (char*)up_arrow_bits, up_arrow_width, up_arrow_height); #include "arc.xbm" Tk_DefineBitmap(interp, Tk_GetUid("arc"), (char*)arc_bits, arc_width, arc_height); #include "incr.xbm" Tk_DefineBitmap(interp, Tk_GetUid("incr"), (char*)incr_bits, incr_width, incr_height); #include "region.xbm" Tk_DefineBitmap(interp, Tk_GetUid("region"), (char*)region_bits, region_width, region_height); #include "rectangle.xbm" Tk_DefineBitmap(interp, Tk_GetUid("rectangle"), (char*)rectangle_bits, rectangle_width, rectangle_height); #include "arrowlast.xbm" Tk_DefineBitmap(interp, Tk_GetUid("arrowlast"), (char*)arrowlast_bits, arrowlast_width, arrowlast_height); #include "left_arrow.xbm" Tk_DefineBitmap(interp, Tk_GetUid("left_arrow"), (char*)left_arrow_bits, left_arrow_width, left_arrow_height); #include "line.xbm" Tk_DefineBitmap(interp, Tk_GetUid("line"), (char*)line_bits, line_width, line_height); #include "right_arrow.xbm" Tk_DefineBitmap(interp, Tk_GetUid("right_arrow"), (char*)right_arrow_bits, right_arrow_width, right_arrow_height); #include "link.xbm" Tk_DefineBitmap(interp, Tk_GetUid("link"), (char*)link_bits, link_width, link_height); #include "information.xbm" Tk_DefineBitmap(interp, Tk_GetUid("information"), (char*)information_bits, information_width, information_height); } skycat-3.1.2-starlink-1b/tclutil/generic/util.C000066400000000000000000000203031215713201500213100ustar00rootroot00000000000000/* * E.S.O. - VLT project / ESO Archive * * "@(#) $Id: util.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * util.C - utility routines * * who when what * -------------- --------- ---------------------------------------- * Allan Brighton 06.Jul.96 Created * Peter W. Draper 24.Nov.97 Fixed up suffix to return characters * after first '.' after last '/' or from * the beginning of string if no '/' * available, rather than just last '.'. * pbiereic 17/02/03 Added 'using namespace std'. */ static const char* const rcsId="@(#) $Id: util.C,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $"; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "error.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" using namespace std; /* * util: make a copy of the given string array in a single buffer */ char** copyArray(int len, char** ar) { int i, n = len * sizeof(char*), m = n; char* p; for (i = 0; i < len; i++) n += strlen(ar[i])+1; char** ret = new char*[(n/sizeof(char*))+1]; p = ((char*)ret) + m; for (i = 0; i < len; i++) { ret[i] = p; strcpy(p, ar[i]); p += strlen(ar[i])+1; } return ret; } /* * strip white space from string by returning offset * in string and setting trailing white space to '\0' */ char* stripWhiteSpace(char* p) { while(isspace(*p)) p++; char* q = p + strlen(p) - 1; while (isspace(*q)) *q-- = '\0'; return p; } /* * return the suffix of the filename, /xx/xx/xx.xxx or xx.xxx. */ const char* fileSuffix(const char* name) { char *c = (char *) name; c = strrchr( c, '/' ); if ( !c ) { c = (char *) name; c--; } c = strchr( ++c, '.' ); if ( c ) { return c + 1; } else { return ""; } } /* * return the basename of the file (part following last "/", if any) */ const char* fileBasename(const char* name) { const char* p = strrchr(name, '/'); if (p) return p+1; return name; } /* * return the size of the file in bytes or -1 on error */ size_t fileSize(const char* filename) { struct stat buf; if (stat(filename, &buf) != 0) return -sys_error("can't stat ", filename); return buf.st_size; } /* * Get the real name of the given file, which may be the name of a * symbolic link. If the file exists, the resolved name is written to the * given buffer and returned, otherwise a pointer to the original * filename is returned. No error message is generated here. */ const char* fileRealname(const char* filename, char* buf, size_t buflen) { // NOTE: readlink() does NOT null terminate filename !!! int n = readlink(filename, buf, buflen); if (n == -1) return filename; buf[n] = '\0'; // null terminate filename return buf; } /* * If filename is not an absolute path (starting with '/'), write * an absolute path for it to "path". "flag" is set to 1 if path * was written to. */ int fileAbsPath(const char* filename, char* path, int pathlen, int& flag) { // make sure we use an absolute path flag = 0; if (filename[0] != '/') { if (getcwd(path, pathlen) == NULL) return sys_error("getcwd"); strcat(path, "/"); strcat(path, filename); flag = 1; } return 0; } /* * Read "n" bytes from a file descriptor. * Use in place of read() when fd is a stream socket. */ ssize_t readUnbufferedBytes(int fd, char* ptr, size_t nbytes) { ssize_t nleft, nread; nleft = nbytes; while (nleft > 0) { nread = read(fd, ptr, nleft); if (nread < 0 && errno != EINTR && errno != EAGAIN) return(nread); /* error, return < 0 */ else if (nread == 0) break; /* EOF */ nleft -= nread; ptr += nread; } return(nbytes - nleft); /* return >= 0 */ } /* * Read the line one byte at a time, looking for the newline. We store * the newline in the buffer, then follow it with a null (the same as * fgets(3)). Not very efficient but usefull for sockets. * * Returns the number of characters up to, but not including, the null * (the same as strlen(3)) or < 0 upon errors. * * Taken from Stevens (readline()), "Unix Network Programming" */ int readUnbufferedLine(int fd, char* ptr, int maxlen) { int n; ssize_t rc; char c; for (n = 1; n < maxlen; n++) { if ( (rc = read(fd, &c, 1)) == 1) { *ptr++ = c; if (c == '\n') break; } else if (rc == 0) { if (n == 1) return(0); // EOF, no data read else break; // EOF, some data was read } else if (errno != EINTR && errno != EAGAIN) return(-1); // error } *ptr = 0; return(n); } /* * Write "n" bytes to a descriptor. Use in place of write() when fd is a * stream socket. * * Returns the number of characters written or <0 upon error. * * Taken from Stevens, "Unix Network Programming". */ ssize_t writeUnbufferedBytes(int fd, char* ptr, size_t nbytes) { ssize_t nleft, nwritten; nleft = nbytes; while (nleft > 0) { nwritten = write(fd, ptr, nleft); if (nwritten < 0 && errno != EINTR && errno != EAGAIN) return(nwritten); // error else if (nwritten == 0) break; nleft -= nwritten; ptr += nwritten; } return(nbytes - nleft); } /* * write the given buffer to the given fd followed by a newline */ ssize_t writeUnbufferedLine(int fd, char* ptr) { return writeUnbufferedBytes(fd, ptr, strlen(ptr)) + writeUnbufferedBytes(fd, (char *)"\n", 1); } /* * Open a socket connection on port on this same host. * *socket on connection is returned or set to -1 on failure * The return value is the status (0 is OK). */ int localSockConnect(int& sock, int port) { hostent *hp; // pointer to host info sockaddr_in addr; // for peer socket address sock = -1; // initial value // get local hostname struct utsname unameInfo; if (uname(&unameInfo) < 0) return sys_error("uname failed on localhost?"); /* clear out address */ memset ((char *)&addr, 0, sizeof(struct sockaddr_in)); /* Set up the peer address to which we will connect. */ addr.sin_family = AF_INET; /* Get the host information for the local host */ hp = gethostbyname(unameInfo.nodename); if (hp == NULL) return sys_error("failed gethostbyname on localhost?"); addr.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr; addr.sin_port = htons(port); /* Create the socket */ sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == -1) return sys_error("failed socket on localhost?"); /* Try to connect to the port */ if (connect(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) == -1) { fmt_sys_error("connect failed on port %d", port); close(sock); // free the socket fd sock = -1; return 1; } return 0; } /* * Start listening for a socket connection on the given port, * or choose a port if port is 0. * The value of sock is set to the socket fd, or -1 on error. * The value of port is set to the port used (may be different if 0). * The return value is the status (0 is OK). */ int localSockListen(int& sock, int& port) { // clear out address structures sockaddr_in addr; // for local socket address size_t addrSize = sizeof(addr); memset((char *)&addr, '\0', addrSize); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = port; // Create the listen socket. sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == -1) return sys_error("socket"); // Bind the listen address to the socket. if (bind(sock, (struct sockaddr *)&addr, addrSize) == -1) return sys_error("bind"); // note the port number (in case it was 0 and is generated) port = addr.sin_port; // Initiate the listen on the socket so remote users // can connect. The listen backlog is set to 5. 20 // is the currently supported maximum. if (listen(sock, 5) == -1) return sys_error("listen"); return 0; } skycat-3.1.2-starlink-1b/tclutil/generic/util.h000066400000000000000000000036131215713201500213620ustar00rootroot00000000000000// -*-c++-*- #ifndef _util_h_ #define _util_h_ /* * E.S.O. - VLT project / ESO Archive * * "@(#) $Id: util.h,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" * * util.h - utility routines * * who when what * -------------- --------- ---------------------------------------- * Allan Brighton 06.Jul.96 Created */ // util: make a copy of the given string array in a single buffer char** copyArray(int len, char** ar); // strip white space from string by returning offset // in string and setting trailing white space to '\0' char* stripWhiteSpace(char* p); // return the suffix of the string (part following ".", if any) const char* fileSuffix(const char* p); // return the basename of the file (part following last "/", if any) const char* fileBasename(const char* p); // get the real name of a file, which may be a link const char* fileRealname(const char* filename, char* buf, size_t buflen); // return the size of the file in bytes or -1 on error int fileSize(const char* filename); // If filename is not an absolute path (starting with '/'), write // an absolute path for it to "path". Sets flag to 1 if path was changed. int fileAbsPath(const char* filename, char* path, int pathlen, int& flag); // Read the line one byte at a time (for sockets and pipes, stdin, ...) int readUnbufferedLine(int fd, char* ptr, int maxlen); // Read "n" bytes from a file descriptor. int readUnbufferedBytes(int fd, char* ptr, int nbytes); // write the given buffer to the given fd followed by a newline int writeUnbufferedLine(int fd, char* ptr); // Write "n" bytes to a descriptor fd (for sockets and pipes, stdin,...) int writeUnbufferedBytes(int fd, char* ptr, int nbytes); // Open a socket connection on port on this same host. int localSockConnect(int& sock, int port); // start listening on the given port (or choose port, if 0) int localSockListen(int& sock, int& port); #endif /* _util_h_ */ skycat-3.1.2-starlink-1b/tclutil/install.sh000077500000000000000000000042121215713201500206210ustar00rootroot00000000000000#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5; it is not part of GNU. # # $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" instcmd="$mvprog" chmodcmd="" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; *) if [ x"$src" = x ] then src=$1 else dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` fi # Make a temp file name in the proper directory. dstdir=`dirname $dst` dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp # and set any options; do chmod last to preserve setuid bits if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi # Now rename the file to the real destination. $doit $rmcmd $dst $doit $mvcmd $dsttmp $dst exit 0 skycat-3.1.2-starlink-1b/tclutil/library/000077500000000000000000000000001215713201500202615ustar00rootroot00000000000000skycat-3.1.2-starlink-1b/tclutil/library/Batch.tcl000066400000000000000000000117401215713201500220110ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # @(#) $Id: Batch.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $ # # Batch.tcl - Class to evaluate Tcl commands in a separate process. # # usage: Batch $w_.batch -command $command # $w_.batch bg_eval $cmd # # where: $command is evaluated with 2 args: $cmd's status and the result # (or a filename containing the result, see the options...) # # See man page for a complete description. # # Copyright: # Copyright (C) 2000-2005 Central Laboratory of the Research Councils. # Copyright (C) 2006 Particle Physics & Astronomy Research Council. # All Rights Reserved. # # Licence: # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place,Suite 330, Boston, MA # 02111-1307, USA # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 20 Dec 95 created # P.W.Draper 10 Feb 98 Changed to use kill SIGKILL to make forked # process exit without executing any exit # handlers. This was causing problems with # Starlink infrastructure s/w (HDS). # 02 Mar 99 Merged skycat 2.3.2 changes itk::usual Batch {} # This class is used to evaluate a set of Tcl commands in a separate # process, so that it can be interrupted. No exec is done, so the # process is just a copy of the current one and has a copy of the # memory and open files. itcl::class util::Batch { # dummy inherit, just to catch Destroy event for clean up... inherit util::FrameWidget # constructor constructor {args} { eval itk_initialize $args if {"$itk_option(-tmpfile)" == ""} { set itk_option(-tmpfile) /tmp/batch[pid].[incr count_] } } # destructor destructor { interrupt } # evaluate the given tcl commands in the background, so that they # can be interrupted. The option $command is evaluated # when the results when done. public method bg_eval {cmd} { if {$itk_option(-debug)} { fg_eval $cmd return } flush stdout flush stderr pipe rfd wfd set pid [fork] if {$pid == 0} { # child set status [catch $cmd result] set fd [open $itk_option(-tmpfile) w] puts -nonewline $fd $result # Flush all pending output and kill the process using a # signal that avoids any exit handlers (otherwise these # are executed in the parent process, this process should # use _exit form to exit, obviously it doesn't). flush $fd close $fd puts $wfd $status flush $wfd close $wfd # The kill command is in Tclx and BLT, only BLT puts # it into a namespace we can use. blt::kill [pid] SIGKILL } else { set bg_pid_ $pid fileevent $rfd readable [code $this read_pipe $rfd $wfd] } } # evaluate the given command in the foreground (useful for debugging) # The option $command is evaluated when the results when done. public method fg_eval {cmd} { set status [catch $cmd result] eval $itk_option(-command) $status [list $result] } # read the pipe from the child process protected method read_pipe {rfd wfd} { set status [read $rfd 1] close $rfd close $wfd if {[file exists $itk_option(-tmpfile)]} { set fd [open $itk_option(-tmpfile)] set info [read $fd] close $fd file delete $itk_option(-tmpfile) } else { # may have been interrupted - ignore return } eval $itk_option(-command) $status [list $info] catch {wait -nohang $bg_pid_} } # interrupt the current search public method interrupt {} { catch {exec kill $bg_pid_} catch {file delete $itk_option(-tmpfile)} catch {wait -nohang $bg_pid_} } # -- options -- # command to evaluate when process is done. Called with 2 args: # status and result (or error message) itk_option define -command command Command {} # temp file for results itk_option define -tmpfile tmpfile Tmpfile {} # flag: if true run commands in the foreground for better debugging itk_option define -debug debug Debug 0 # -- protected members -- # process id of background process protected variable bg_pid_ # -- common variables (shared by all instances) -- # count used for filename generation common count_ 0 } skycat-3.1.2-starlink-1b/tclutil/library/ButtonFrame.tcl000066400000000000000000000041201215713201500232100ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id: ButtonFrame.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # ButtonFrame.tcl - Widget displaying a frame with some standard buttons. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 94 Created itk::usual ButtonFrame {} # This class is an itcl widget for displaying a frame with the standard # buttons like "OK Cancel", with options for configuring other labels and # actions itcl::class util::ButtonFrame { inherit util::FrameWidget # create a ButtonFrame constructor {args} { itk_option add hull.borderwidth hull.relief eval itk_initialize $args } # add a button to the row or configure an existing button public method buttonconfig {label args} { if {[info exists but_($label)]} { eval "[list $but_($label) config -text $label] $args" } else { pack \ [set but_($label) [eval "[list button $w_.but$seq_ -text $label] $args"]] \ -side left -fill none -expand 1 -padx 3m -pady 2m incr seq_ } } # add a button public method append {label cmd} { buttonconfig $label -text $label -command $cmd } # -- options -- # labels and commands for the standard buttons itk_option define -ok_label ok_label Ok_label {OK} { buttonconfig $itk_option(-ok_label) -text $itk_option(-ok_label) } itk_option define -ok_cmd ok_cmd Ok_cmd {} { buttonconfig $itk_option(-ok_label) -command $itk_option(-ok_cmd) } itk_option define -cancel_label cancel_label Cancel_label {Cancel} { buttonconfig $itk_option(-cancel_label) -text $itk_option(-cancel_label) } itk_option define -cancel_cmd cancel_cmd Cancel_cmd {} { if {"$itk_option(-cancel_cmd)" == ""} { config -cancel_cmd "destroy [winfo toplevel $w_]" } else { buttonconfig $itk_option(-cancel_label) -command $itk_option(-cancel_cmd) } } # -- protected variable vars -- # counter for button names protected variable seq_ {0} # array mapping label name to button name protected variable but_ } skycat-3.1.2-starlink-1b/tclutil/library/CanvasDraw.tcl000066400000000000000000001621601215713201500230240ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id: CanvasDraw.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # CanvasDraw.tcl - Add interactive drawing capabilities to a Tk canvas. # # usage: CanvasDraw .draw -canvas $canvas ?options...? # # See the man page CanvasDraw(n) for a complete description. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 95 Created # 23 Jun 96 constrain (clip) interactive drawing with -bbox option # 20 Mar 98 Use init method (easier to subclass) # Added -clipping option to control clipping of graphics # (default is the same as before). itk::usual CanvasDraw {} # CanvasDraw is an [incrTcl] widget class that an application # can use to add interactive drawing capabilities to any Tk # canvas. Since it is a subclass of TopLevelWidget, it creates # its own toplevel window containing a drawing mode selection # section and an option section for setting colors, fonts, line # thickness, arrow types, etc. The window can be hidden on # startup by specifying the "-withdraw 1" option inherited from # TopLevelWidget. itcl::class util::CanvasDraw { inherit util::TopLevelWidget # create an instance of this class constructor {args} { eval itk_initialize $args } # This method is called after the constructor have completed. protected method init {} { if {!$itk_option(-withtoolbox)} { return } wm title $w_ "Line Graphics ($itk_option(-number))" wm iconname $w_ Graphics # make the toolbox make_drawmode_frame make_options_frame # create the canvas item menu make_object_menu $canvas_ config -cursor [set prev_cursor_ $itk_option(-defaultcursor)] # add button frame and buttons # Button frame at bottom of window itk_component add bot { frame $w_.bot -borderwidth 2 -relief groove } pack $itk_component(bot) -side bottom -fill x # Close button itk_component add close { button $itk_component(bot).close -text Close \ -command "wm withdraw $w_" } # Clear button itk_component add clear { button $itk_component(bot).clear -text Clear \ -command [code $this clear] } # Delete button itk_component add delete { button $itk_component(bot).delete -text Delete \ -command [code $this delete_selected_objects] } pack $itk_component(close) $itk_component(clear) $itk_component(delete) \ -side left -padx 2m -pady 2m -expand 1 add_short_help $itk_component(close) "Close this window" add_short_help $itk_component(clear) "Clear all line graphics" add_short_help $itk_component(delete) "Delete selected line graphic objects" # short help for selection grips if {$itk_option(-withrotate)} { set msg "Selection grips: {bitmap dragb1} = resize object, \ Control {bitmap dragb3} = rotate object " } else { set msg "Selection grips: {bitmap dragb1} = resize object" } $canvas_ bind grip "+[code $short_help_win_ short_help $msg]" $canvas_ bind grip "+[code $short_help_win_ short_help {} ]" } # destructor: clean up destructor { catch {clear} catch {destroy $object_menu_} } # create the canvas item menu. protected method make_object_menu {} { # create menu in global namespace to avoid problems with tk menu utils set cmd [list menu $canvas_.objmenu -tearoff 0] set m [set object_menu_ [uplevel "#0" $cmd]] $m add command -label "Delete Selected Items" \ -command [code $this delete_selected_objects] } # post the object menu at the mouse cursor position. # If an item is selected, post the menu with the items enabled. protected method post_object_menu {x y} { # disable items if no selection... if {! [lempty [selected_items]]} { tk_popup $object_menu_ $x $y } } # delete the selected canvas items public method delete_selected_objects {} { foreach id [selected_items] { delete_object $id } } # delete the given canvas item public method delete_object {id} { deselect_object $id $canvas_ delete $id if {[info exists notify_($id)]} { set cmd $notify_($id) unset notify_($id) eval "$cmd delete" } if {[info exists notify_update_($id)]} { unset notify_update_($id) } } # delete all canvas items public method clear {} { deselect_objects $canvas_ delete $w_.objects $canvas_ delete objects } # create the menu items in the given menu public method add_menuitems {m} { # save menu name for enable/disable set menu_ $m # add the menus foreach i {Mode Width Arrow ArrowShape Fill Outline Stipple Font Smooth} { $m add cascade -label $i -menu [menu $m.[string tolower $i]] } # drawing mode menu foreach i $drawing_modes_ { $m.mode add radiobutton \ -variable $w_.mode -value $i \ -bitmap $i \ -command [code $this set_drawing_mode $i] } after idle [code $this set_drawing_mode anyselect] # line width menu foreach i {1 2 3 4} { $m.width add radiobutton \ -variable $w_.width \ -value $i \ -bitmap width$i \ -command [code $this set_linewidth $i] } # arrow menu foreach i {none first both last} { $m.arrow add radiobutton \ -variable $w_.arrow \ -bitmap arrow$i \ -value $i \ -command [code $this set_arrowtype $i] } # arrow shape menu (bitmap names corr. to arrow shape lists) foreach i $arrowshapes_ { $m.arrowshape add radiobutton \ -variable $w_.arrowshape \ -value $i \ -bitmap ar[join $i _] \ -command [list $this set_arrowshape $i] } # fill menu $m.fill add radiobutton \ -variable $w_.fill -value "" \ -label None \ -command [code $this set_fillcolor {} ] foreach i $itk_option(-colors) { $m.fill add radiobutton \ -variable $w_.fill -value $i \ -command [code $this set_fillcolor $i] \ -background $i } # outline menu foreach i $itk_option(-colors) { $m.outline add radiobutton \ -variable $w_.outline -value $i \ -command [code $this set_outlinecolor $i] \ -background $i } $m.outline add radiobutton \ -variable $w_.outline -value "" \ -label None \ -command [code $this set_outlinecolor {} ] # Stipple menu for {set i 0} {$i < 16} {incr i} { set bitmap pat$i $m.stipple add radiobutton \ -variable $w_.stipple -value pat$i \ -bitmap $bitmap \ -command [code $this set_stipplepattern $i] } # Font menu foreach i $itk_option(-fonts) { if {[catch { $m.font add radiobutton \ -variable $w_.font -value $i \ -label {abc} \ -command [code $this set_textfont $i] \ -font $i } msg]} { puts "warning: $msg" } } # Smooth menu set bool 0 foreach i {rectangle smooth} { $m.smooth add radiobutton \ -bitmap $i \ -value $bool \ -variable $w_.smooth \ -command [code $this set_smooth $bool] incr bool } set $w_.smooth 0 # add items for deleting objects $m add separator $m add command -label "Clear" -command [code $this clear] $m add command -label "Delete" -command [code $this delete_selected_objects] # add short help texts for menu items set w $short_help_win_ $w add_menu_short_help $m Mode {Select the drawing mode} $w add_menu_short_help $m Width {Set the line width for drawing} $w add_menu_short_help $m Arrow {Select the arrow mode for lines} $w add_menu_short_help $m ArrowShape {Select the arrow shape for lines} $w add_menu_short_help $m Fill {Select the fill color for drawing} $w add_menu_short_help $m Outline {Select the outline color for drawing} $w add_menu_short_help $m Stipple {Select the stipple pattern for filling objects} $w add_menu_short_help $m Font {Select the font to use for labels} $w add_menu_short_help $m Clear {Delete graphic objects} $w add_menu_short_help $m Delete {Delete selected graphic objects} $w add_menu_short_help $m Smooth {Set the smooth option for drawing polygons} } # enable or disable the drawing items in the menu # (enable is state is "normal", disable if "disabled". public method set_menu_state {state} { if {"$menu_" != ""} { for {set i 0} {$i < 16} {incr i} { catch {$menu_ entryconfigure $i -state $state} } } } # create the frame for selecting draw types (line, oval, ...) # in the given frame protected method make_drawmode_frame {} { # Frame containing drawing mode buttons. itk_component add drawmodes { frame $w_.drawmodes -borderwidth 6 } pack $itk_component(drawmodes) -side top -fill both set row 0 set col 0 set maxcol 3 foreach drawing_mode $drawing_modes_ { # Drawing mode buttons # (anyselect, region, line, rectangle, oval, polyline, polygon, text) itk_component add $drawing_mode { set b [button $itk_component(drawmodes).$drawing_mode \ -bitmap $drawing_mode \ -borderwidth 3 \ -command [code $this set_drawing_mode $drawing_mode]] } add_short_help $b "set the drawing mode to $drawing_mode" blt::blttable $itk_component(drawmodes) $b $row,$col \ -fill x -ipadx 1m -ipady 1m if {$col < $maxcol} { incr col } else { set col 0 incr row } } set_drawing_mode anyselect } # create the draw options frame (line width, color, etc...) protected method make_options_frame {} { global ::$w_.width ::$w_.arrow ::$w_.arrowshape ::$w_.fill ::$w_.outline \ ::$w_.stipple ::$w_.font ::$w_.smooth # Frame containing option menubuttons for graphic items itk_component add options { set f [frame $w_.options -borderwidth 6] } pack $itk_component(options) -side top -fill both foreach i {Width Arrow ArrowShape Fill Outline Stipple Font Smooth} { set menu [string tolower $i] # LabelMenu(n) items for changing options on graphic objects. # (Width Arrow ArrowShape Fill Outline Stipple Font Smooth) itk_component add $menu { util::LabelMenu $f.$menu \ -text "$i:" \ -relief raised \ -variable $w_.$menu \ -labelwidth 15 } pack $itk_component($menu) -side top -fill both -expand 1 -ipadx 1m -ipady 1m } # line width menu foreach i {1 2 3 4} { $f.width add \ -bitmap width$i \ -value $i \ -command [code $this set_linewidth $i] } set $w_.width 1 add_short_help $f.width "set the line width for drawing" # arrow menu foreach i {none first both last} { $f.arrow add \ -bitmap arrow$i \ -value $i \ -command [code $this set_arrowtype $i] } set $w_.arrow none add_short_help $f.arrow "set the arrow type for drawing lines" # arrow shape menu foreach i $arrowshapes_ { $f.arrowshape add \ -bitmap ar[join $i _] \ -value $i \ -command [list $this set_arrowshape $i] } set $w_.arrowshape [lindex $arrowshapes_ 0] add_short_help $f.arrowshape \ "set the arrow shape for drawing (must also select type above)" # fill menu $f.fill add \ -label None \ -command [code $this set_fillcolor {} ] \ -background [. cget -background] foreach i $itk_option(-colors) { $f.fill add \ -command [code $this set_fillcolor $i] \ -label { } \ -value $i \ -background $i } set $w_.fill None add_short_help $f.fill "set the fill color for drawing" # outline menu foreach i $itk_option(-colors) { $f.outline add \ -command [code $this set_outlinecolor $i] \ -label { } \ -value $i \ -background $i } $f.outline add \ -label None \ -command [code $this set_outlinecolor {} ] \ -background [. cget -background] set $w_.outline white add_short_help $f.outline "set the outline color for drawing" # Stipple menu for {set i 0} {$i < 16} {incr i} { set bitmap pat$i $f.stipple add \ -bitmap $bitmap \ -command [code $this set_stipplepattern $i] } set $w_.stipple pat0 add_short_help $f.stipple "set the stipple pattern for drawing" # Font menu foreach i $itk_option(-fonts) { if {[catch { $f.font add \ -label {abc} \ -value $i \ -command [code $this set_textfont $i] \ -font $i } msg]} { puts "warning: $msg" } } set $w_.font abc add_short_help $f.font "set the font used for text items" # Smooth menu set bool 0 foreach i {rectangle smooth} { $f.smooth add \ -bitmap $i \ -value $bool \ -command [code $this set_smooth $bool] incr bool } set $w_.smooth 0 add_short_help $f.smooth "set the smooth option for drawing" } # update the display to show the options for the given canvas item protected method update_display_from_object {id} { global ::$w_.width ::$w_.arrow ::$w_.arrowshape ::$w_.fill ::$w_.outline \ ::$w_.stipple ::$w_.font ::$w_.smooth foreach i [$canvas_ itemconfig $id] { lassign $i opt {} {} {} value set var "$w_.[string range $opt 1 end]" set $var $value } } # apply the given option to the selected canvas items public method config_selected {option value} { foreach i [selected_items] { if {[info exists option_map_($i,$option)]} { set option $option_map_($i,$option) } catch {$canvas_ itemconfig $i $option $value} } } # set the line width default and for any selected objects public method set_linewidth {w} { global ::$w_.width set $w_.width $w config -linewidth $w config_selected -width $w } # set the arrow type default and for any selected objects public method set_arrowtype {t} { global ::$w_.arrow config -arrowtype $t set $w_.arrow $t config_selected -arrow $t } # set the arrow shape default and for any selected objects public method set_arrowshape {list} { global ::$w_.arrowshape config -arrowshape $list set $w_.arrowshape $list config_selected -arrowshape $list } # set the fill color default and for any selected objects # note: if the stipple is invisible (see through), make it solid to # make sure fill is visible public method set_fillcolor {c} { global ::$w_.fill if {$stipple_index_ == 8} { set_stipplepattern 0 } elseif {"$c" == ""} { set_stipplepattern 8 } config -fillcolor [set $w_.fill $c] config_selected -fill $c } # set the outline color default and for any selected objects public method set_outlinecolor {c} { global ::$w_.outline config -outlinecolor [set $w_.outline $c] config_selected -outline $c } # set the stipple pattern default and for any selected objects # index is the pattern number (corresponding to pat$index.xbm) public method set_stipplepattern {index} { global ::$w_.stipple config -stipplepattern [set $w_.stipple pat$index] set stipple_index_ $index # make sure newly created lines are visible (pat8 is invisible) if {$index == 8} { config -linestipple pat0 } else { config -linestipple $itk_option(-stipplepattern) } config_selected -stipple $itk_option(-stipplepattern) } # set the text font default and for any selected objects public method set_textfont {f} { global ::$w_.font config -textfont $f set $w_.font $f config_selected -font $f } # set the smooth option for drawing public method set_smooth {bool} { global ::$w_.smooth config -smooth $bool set $w_.smooth $bool config_selected -smooth $bool } # set the type of object to draw (line, oval, ...) # If create_cmd is specified, it is called with the coordinates # of the new object when its creation is completed public method set_drawing_mode {type {create_cmd ""}} { if {"$type" == "region" && $drawing_} { # already drawing... return } # reset selection foreach i $drawing_modes_ { $itk_component($i) config -relief raised } if {[info exists itk_component($type)]} { $itk_component($type) config -relief sunken } # from menu's -variable option global ::$w_.mode set drawing_mode_ [set $w_.mode $type] set create_cmd_ $create_cmd set drawing_ [expr {"$type" != "objselect" && "$type" != "anyselect"} ] if {$drawing_} { deselect_objects $canvas_ config -cursor $itk_option(-drawcursor) } else { reset_cursor } # reset canvas bindings based on drawing_mode bind $canvas_ {} switch -exact $drawing_mode_ { anyselect - objselect { bind $canvas_ <1> [code $this check_deselect] bind $canvas_ {} bind $canvas_ {} bind $canvas_ {} bind $canvas_ {} } region { $canvas_ config -cursor $itk_option(-regioncursor) bind $canvas_ <1> \ [code eval $this create_object $canvasX_ $canvasY_] bind $canvas_ \ [code eval $this check_done $canvasX_ $canvasY_ update_region] bind $canvas_ \ [code eval $this update_region $canvasX_ $canvasY_ 0] bind $canvas_ \ [code eval $this update_region $canvasX_ $canvasY_ 1] bind $canvas_ \ [code eval $this create_done $canvasX_ $canvasY_] } line { bind $canvas_ <1> \ [code eval $this create_object $canvasX_ $canvasY_] bind $canvas_ \ [code eval $this check_done $canvasX_ $canvasY_] bind $canvas_ \ [code eval $this update_line $canvasX_ $canvasY_] bind $canvas_ \ [code eval $this update_line $canvasX_ $canvasY_ 1] bind $canvas_ \ [code eval $this create_done $canvasX_ $canvasY_] } oval - arc { bind $canvas_ <1> \ [code eval $this create_object $canvasX_ $canvasY_] bind $canvas_ \ [code eval $this check_done $canvasX_ $canvasY_] bind $canvas_ \ [code eval $this update_object $canvasX_ $canvasY_] bind $canvas_ \ [code eval $this update_object $canvasX_ $canvasY_ 1] bind $canvas_ \ [code eval $this create_done $canvasX_ $canvasY_] } rectangle { bind $canvas_ <1> \ [code eval $this create_object $canvasX_ $canvasY_] bind $canvas_ \ [code eval $this check_done $canvasX_ $canvasY_ update_rectangle] bind $canvas_ \ [code eval $this update_rectangle $canvasX_ $canvasY_] bind $canvas_ \ [code eval $this update_rectangle $canvasX_ $canvasY_ 1] bind $canvas_ \ [code eval $this create_done $canvasX_ $canvasY_] } polyline - polygon { bind $canvas_ <1> \ [code eval $this create_object $canvasX_ $canvasY_] bind $canvas_ \ [code eval $this add_poly_point $canvasX_ $canvasY_] bind $canvas_ \ [code eval $this update_poly_object $canvasX_ $canvasY_] bind $canvas_ \ [code eval $this update_poly_object $canvasX_ $canvasY_] bind $canvas_ \ [code eval $this create_done $canvasX_ $canvasY_] } freehand { bind $canvas_ <1> \ [code eval $this create_object $canvasX_ $canvasY_] bind $canvas_ \ [code eval $this check_done $canvasX_ $canvasY_ update_freehand] bind $canvas_ \ [code eval $this update_freehand $canvasX_ $canvasY_] bind $canvas_ \ [code eval $this update_freehand $canvasX_ $canvasY_] bind $canvas_ \ [code eval $this create_done $canvasX_ $canvasY_] } text - label { $canvas_ config -cursor $itk_option(-textcursor) bind $canvas_ <1> \ [code eval $this create_object $canvasX_ $canvasY_] bind $canvas_ \ [code eval $this create_text_done $canvasX_ $canvasY_] bind $canvas_ {} bind $canvas_ {} bind $canvas_ {} } } } # clip the given point to keep it over the drawing area public method clip {px py} { if {$itk_option(-clipping)} { upvar $px x upvar $py y if {$x < $x0_} { set x $x0_ } elseif {$x > $x1_} { set x $x1_ } if {$y < $y0_} { set y $y0_ } elseif {$y > $y1_} { set y $y1_ } } } # mark (remember) the current position protected method mark {x y} { clip x y set startx_ $x set starty_ $y set xoffset_ 0 set yoffset_ 0 } # set up the canvas object bindings. target_id defaults to id. # If target_id is specified, it will receive the events instead of id. public method add_object_bindings {id {target_id ""}} { if {"$target_id" == ""} { set target_id $id } # mark pos $canvas_ bind $id <1> "+[code eval $this mark $canvasX_ $canvasY_]" $canvas_ bind $id "+[code eval $this mark $canvasX_ $canvasY_]" $canvas_ bind $id "+[code eval $this mark $canvasX_ $canvasY_]" # select $canvas_ bind $id \ "+[code eval $this select_only_object $target_id $canvasX_ $canvasY_]" $canvas_ bind $id \ "+[code eval $this toggle_select_object $target_id $canvasX_ $canvasY_]" $canvas_ bind $id \ "+[code eval $this toggle_select_object $target_id $canvasX_ $canvasY_]" # move $canvas_ bind $id \ "+[code eval $this move_object $target_id $canvasX_ $canvasY_]" $canvas_ bind $id \ "+[code eval $this move_object $target_id $canvasX_ $canvasY_]" $canvas_ bind $id \ "+[code eval $this move_object $target_id $canvasX_ $canvasY_]" $canvas_ bind $id "+[code $this end_move $target_id]" $canvas_ bind $id "+[code $this end_move $target_id]" $canvas_ bind $id "+[code $this end_move $target_id]" # cursor $canvas_ bind $id "+[code $this set_cursor tcross]" $canvas_ bind $id "+[code $this reset_cursor]" # menu if {$itk_option(-show_object_menu)} { $canvas_ bind $id <3> "+[code $this post_object_menu %X %Y]" } } # Finish creation of the current object and call the "create" command, if one # was specified, otherwise, for region items, call the region command, if # defined. public method create_done {x y} { set resizing_ 0 reset_cursor add_object_bindings $obj_id_ if {"$create_cmd_" != ""} { eval "$create_cmd_ $obj_id_ [$canvas_ bbox $obj_id_]" set create_cmd_ "" } elseif {"$drawing_mode_" == "region"} { set_drawing_mode anyselect eval select_region [$canvas_ bbox $obj_id_] delete_object $obj_id_ return } set_drawing_mode anyselect select_object $obj_id_ update_display_from_object $obj_id_ mark $x $y } # Finish creation of the current text object protected method create_text_done {x y} { set_drawing_mode anyselect reset_cursor add_object_bindings $obj_id_ } # check if object creation is done: if the button has moved # since it was pressed, we are done, otherwise dragging continues # without the button pressed. # # update_method is the method to call to update the object, if needed protected method check_done {x y {update_method "update_object"}} { clip x y if {$x == $startx_ && $y == $starty_} { bind $canvas_ [code eval $this $update_method $canvasX_ $canvasY_] bind $canvas_ <1> [code eval $this create_done $canvasX_ $canvasY_] } else { create_done $x $y } } # This method is called when a region object has been created to select # a region of the canvas. # All objects in the region are selected and if a region command option # was specified, the command is evaluated with the bounding box of the region. public method select_region {x0 y0 x1 y1} { foreach id [$canvas_ find enclosed $x0 $y0 $x1 $y1] { # make sure its is one of our objects if {[item_has_tag $id $w_.objects]} { select_object $id } } if {"$itk_option(-regioncommand)" != ""} { eval "$itk_option(-regioncommand) $x0 $y0 $x1 $y1" } } # add a point to the curent polygon/polyline protected method add_poly_point {x y} { clip x y lappend obj_coords_ $x $y update_poly_object $x $y bind $canvas_ <1> {} bind $canvas_ [code eval $this update_poly_object $canvasX_ $canvasY_] } # If the mouse is not over an object, deselect all objects public method check_deselect {} { if {[llength [$canvas_ gettags current]] == 0} { deselect_objects } } # if the object is selected, deselect it, otherwise select it protected method toggle_select_object {id x y} { # only if not moving mouse... if {$startx_ == $x && $starty_ == $y} { if {[item_is_selected $id]} { deselect_object $id } else { select_object $id mark $x $y } } } # select only the given object public method select_only_object {id x y} { # only if not moving mouse... if {$startx_ == $x && $starty_ == $y} { deselect_objects select_object $id 1 update_display_from_object $id } if {$drawing_} { return } mark $x $y } # select the given object by drawing 8 little grips on it, or for text objects, # if any==1 and the selection type is "anyselect", select the text in the object. # The grips have the tag "grip" and the object gets the tag "$w_.selected" public method select_object {id {any 0}} { if {$drawing_} { return } # decide whether to select object or only text set type [$canvas_ type $id] if {$any && "$type" == "text" && "$drawing_mode_" == "anyselect"} { $canvas_ focus $id $canvas_ icursor $id end } elseif {$itk_option(-show_selection_grips)} { draw_selection_grips $id $type } $canvas_ addtag $w_.selected withtag $id } # Draw the selection grips for a simple line. # Lines get one grip at each end. protected method draw_line_selection_grips {id} { foreach side {e w} { set sel_id [$canvas_ create rectangle 0 0 \ $itk_option(-gripwidth) $itk_option(-gripwidth) \ -tags [list grip grip.$id grip.$id.$side] \ -fill $itk_option(-gripfill) -outline $itk_option(-gripoutline)] $canvas_ bind $sel_id \ [list $canvas_ config -cursor $itk_option(-linecursor)] $canvas_ bind $sel_id [code $this reset_cursor] $canvas_ bind $sel_id <1> \ [code eval $this mark $canvasX_ $canvasY_] $canvas_ bind $sel_id \ [code eval $this mark $canvasX_ $canvasY_] $canvas_ bind $sel_id \ [code $this end_resize_line $id] $canvas_ bind $sel_id \ [code $this end_resize_line $id] $canvas_ bind $sel_id \ [code eval $this resize_line $id $canvasX_ $canvasY_ $side 0] $canvas_ bind $sel_id \ [code eval $this resize_line $id $canvasX_ $canvasY_ $side 1] if {$itk_option(-withrotate)} { $canvas_ bind $sel_id \ [list $canvas_ config -cursor $rotate_cursor_] $canvas_ bind $sel_id \ [code eval $this start_rotate $id $canvasX_ $canvasY_] $canvas_ bind $sel_id \ [code eval $this update_rotate $id $canvasX_ $canvasY_] $canvas_ bind $sel_id \ [code $this end_rotate $id] } } adjust_line_selection $id } # set the cursor for the canvas window and save the previous cursor # for later restoration public method set_cursor {cursor} { if {! $resizing_} { set prev_cursor_ [$canvas_ cget -cursor] $canvas_ config -cursor $cursor } } # set the cursor for the canvas window back to the previous one, unless # we are in the middle of a resize operation public method reset_cursor {} { if {! $resizing_} { $canvas_ config -cursor $prev_cursor_ set prev_cursor_ $itk_option(-defaultcursor) } } # Draw the object selection grips (small boxes similar to those # used by FrameMaker and used to move and resize the object). # Lines (see above) get one at each end, # other objects (here) get one at each corner and side of the object's # bounding box. If type is "polygon" or "line", rotation bindings are # also enabled (with ). protected method draw_selection_grips {id {type ""}} { # make sure we are using the canvas id set id [lindex [$canvas_ find withtag $id] 0] if {"$type" == "line" && [llength [$canvas_ coords $id]] == 4} { draw_line_selection_grips $id return } foreach side {n e s w ne nw se sw} { set sel_id [$canvas_ create rectangle 0 0 \ $itk_option(-gripwidth) $itk_option(-gripwidth) \ -tags [list grip grip.$id grip.$id.$side] \ -fill $itk_option(-gripfill) -outline $itk_option(-gripoutline)] $canvas_ bind $sel_id \ [list $canvas_ config \ -cursor "$cursors_($side) white black" ] $canvas_ bind $sel_id [code $this reset_cursor] $canvas_ bind $sel_id <1> \ [code eval $this start_resize $id $canvasX_ $canvasY_ $side] $canvas_ bind $sel_id \ [code eval $this start_resize $id $canvasX_ $canvasY_ $side] $canvas_ bind $sel_id \ [code $this end_resize $id] $canvas_ bind $sel_id \ [code $this end_resize $id] $canvas_ bind $sel_id \ [code eval $this update_resize $id $canvasX_ $canvasY_ $side 0] $canvas_ bind $sel_id \ [code eval $this update_resize $id $canvasX_ $canvasY_ $side 1] # Add support for rotation for polygons and lines. # Tk doesn't support it directly, but we can do it manually for # polygons and (poly)lines. We don't want to allow rotation for # "region" items, for now. Note that we could do the selection # a lot better if the rotation angle was a Tk canvas item option # (i.e.: the coords would stay the same, and the angle would change). if {$itk_option(-withrotate) \ && ("$type" == "polygon" || "$type" == "line") \ && ![info exists regions_($id)]} { $canvas_ bind $sel_id \ [list $canvas_ config -cursor $rotate_cursor_] $canvas_ bind $sel_id \ [code eval $this start_rotate $id $canvasX_ $canvasY_] $canvas_ bind $sel_id \ [code eval $this update_rotate $id $canvasX_ $canvasY_] $canvas_ bind $sel_id \ [code $this end_rotate $id] } } adjust_object_selection $id } # deselect the given object public method deselect_object {id} { $canvas_ delete grip.$id $canvas_ dtag $id $w_.selected $canvas_ focus {} } # deselect all canvas objects public method deselect_objects {} { $canvas_ delete grip $canvas_ dtag all $w_.selected $canvas_ focus {} } # adjust the selection handles for the given object to fit the new size/pos. public method adjust_object_selection {id} { if {"[$canvas_ type $id]" == "line" && [llength [$canvas_ coords $id]] == 4} { adjust_line_selection $id return } lassign [$canvas_ bbox $id] x0 y0 x1 y1 if {"$x0" == ""} { deselect_object $id return } set xm [expr {$x0+($x1-$x0)/2}] set ym [expr {$y0+($y1-$y0)/2}] set w [expr {$itk_option(-gripwidth)/2}] foreach i [list \ "nw $x0 $y0" \ "n $xm $y0" \ "ne $x1 $y0" \ "e $x1 $ym" \ "se $x1 $y1" \ "s $xm $y1" \ "sw $x0 $y1" \ "w $x0 $ym" ] { lassign $i side x y $canvas_ coords grip.$id.$side \ [expr {$x-$w}] [expr {$y-$w}] \ [expr {$x+$w}] [expr {$y+$w}] } } # adjust the selection handles for the given simple line public method adjust_line_selection {id} { lassign [$canvas_ coords $id] x0 y0 x1 y1 set xm [expr {$x0+($x1-$x0)/2}] set ym [expr {$y0+($y1-$y0)/2}] set w [expr {$itk_option(-gripwidth)/2}] foreach i [list \ "e $x0 $y0" \ "w $x1 $y1" ] { lassign $i side x y $canvas_ coords grip.$id.$side \ [expr {$x-$w}] [expr {$y-$w}] \ [expr {$x+$w}] [expr {$y+$w}] } } # resize the given line protected method resize_line {id x y side constrain} { clip x y set resizing_ 1 lassign [$canvas_ coords $id] x0 y0 x1 y1 if {$constrain} { if {abs($x1-$x0) abs($starty_-$y)} { set x [expr {$startx_+($y-$starty_)}] } else { set y [expr {$starty_+($x-$startx_)}] } } if {$dragx_} { set d [expr {$endx_-$startx_}] if {$d != 0} { set dx [expr {($x-$startx_)/$d}] } } if {$dragy_} { set d [expr {$endy_-$starty_}] if {$d != 0} { set dy [expr {($y-$starty_)/$d}] } } if {$dx < 0 || $dy < 0} { return } if {$dx != 0 && $dy != 0} { $canvas_ scale $id $startx_ $starty_ $dx $dy } # move back to exact position (bbox only returns integer coords) # set exact end position to avoid cummulative errors set pos [$canvas_ bbox $id] if {$posx_ == -1} { set dx 0 set endx_ $x } else { set dx [expr {$startx_ - [lindex $pos $posx_]}] set endx_ [lindex $pos $posx2_] } if {$posy_ == -1} { set dy 0 set endy_ $y } else { set dy [expr {$starty_ - [lindex $pos $posy_]}] set endy_ [lindex $pos $posy2_] } $canvas_ move $id $dx $dy if {[info exists notify_update_($id)]} { eval "$notify_update_($id) resize" } } # create a new object in the canvas public method create_object {x y} { mark $x $y set obj_coords_ "$x $y" set obj_id_ [create_$drawing_mode_ $x $y] if {"$drawing_mode_" != "region"} { $canvas_ addtag objects withtag $obj_id_ $canvas_ addtag $w_.objects withtag $obj_id_ } set resizing_ 1 } # return 1 if the given item has the given tag public method item_has_tag {item tag} { return [expr {[lsearch -exact [$canvas_ gettags $item] $tag] != -1}] } # return 1 if the given item is currently selected public method item_is_selected {item} { return [item_has_tag $item $w_.selected] } # return a list of all of the currently selected items public method selected_items {} { return [$canvas_ find withtag $w_.selected] } # move the given object protected method move_object {id x y} { if {$drawing_} { return } if {![item_is_selected $id]} { deselect_objects select_object $id mark $x $y } set dx [expr {$x-($startx_+$xoffset_)}] set dy [expr {$y-($starty_+$yoffset_)}] set xoffset_ [expr {$x-$startx_}] set yoffset_ [expr {$y-$starty_}] if {$itk_option(-clipping)} { # don't allow a move outside of drawing area lassign [$canvas_ bbox $w_.selected] x0 y0 x1 y1 set dx0 [expr {$x0_-$x0}] set dy0 [expr {$y0_-$y0}] set dx1 [expr {$x1_-$x1}] set dy1 [expr {$y1_-$y1}] if {$dx < $dx0} { set dx $dx0 } elseif {$dx > $dx1} { set dx $dx1 } if {$dy < $dy0} { set dy $dy0 } elseif {$dy > $dy1} { set dy $dy1 } } if {$dx || $dy} { foreach i "$w_.selected grip" { $canvas_ move $i $dx $dy } foreach i [selected_items] { set moved_($i) 1 if {[info exists notify_update_($i)]} { eval "$notify_update_($i) move" } } update idletasks } } # this method is called when a move operation is done protected method end_move {id} { foreach i [selected_items] { if {[info exists moved_($i)]} { if {[info exists notify_($i)]} { eval "$notify_($i) move" } unset moved_($i) } } } # create and return a new rectangle object (actually create a # polygon object in the shape of a rectangle, since it is more # flexible and can be rotated). protected method create_rectangle {x y} { clip x y if {$itk_option(-withrotate)} { return [$canvas_ create polygon $x $y $x $y $x $y $x $y \ -width $itk_option(-linewidth) \ -fill $itk_option(-fillcolor) \ -outline $itk_option(-outlinecolor) \ -smooth $itk_option(-smooth) \ -stipple $itk_option(-stipplepattern)] } else { return [$canvas_ create rect $x $y $x $y \ -width $itk_option(-linewidth) \ -fill $itk_option(-fillcolor) \ -outline $itk_option(-outlinecolor) \ -stipple $itk_option(-stipplepattern)] } } # create and return a new region (dashed rectangle marking a region # of the canvas) protected method create_region {x y} { clip x y set id [$canvas_ create line $x $y $x $y $x $y $x $y \ -width 2 \ -fill $itk_option(-outlinecolor) \ -stipple pat8] set regions_($id) 1 return $id } # create and return a new oval object protected method create_oval {x y} { clip x y return [$canvas_ create oval $x $y $x $y \ -width $itk_option(-linewidth) \ -fill $itk_option(-fillcolor) \ -outline $itk_option(-outlinecolor) \ -stipple $itk_option(-stipplepattern)] } # create and return a new arc object protected method create_arc {x y} { clip x y return [$canvas_ create arc $x $y $x $y \ -width $itk_option(-linewidth) \ -fill $itk_option(-fillcolor) \ -outline $itk_option(-outlinecolor) \ -stipple $itk_option(-stipplepattern)] } # return a color for a line that will be visible protected method get_line_color {} { if {"$itk_option(-fillcolor)" == ""} { return $itk_option(-outlinecolor) } else { return $itk_option(-fillcolor) } } # create and return a new line object protected method create_line {x y} { clip x y return [$canvas_ create line $x $y $x $y \ -width $itk_option(-linewidth) \ -fill [get_line_color] \ -stipple $itk_option(-linestipple) \ -arrow $itk_option(-arrowtype) \ -smooth $itk_option(-smooth) \ -arrowshape $itk_option(-arrowshape)] } # create and return a new freehand object protected method create_freehand {x y} { clip x y return [$canvas_ create line $x $y $x $y \ -width $itk_option(-linewidth) \ -fill [get_line_color] \ -arrow $itk_option(-arrowtype) \ -stipple $itk_option(-linestipple) \ -arrowshape $itk_option(-arrowshape)] } # create and return a new polyline object protected method create_polyline {x y} { clip x y return [create_line $x $y] } # create and return a new polygon object protected method create_polygon {x y} { clip x y set obj_coords_ "$x $y $x $y $x $y" return [$canvas_ create polygon $x $y $x $y $x $y \ -fill $itk_option(-fillcolor) \ -outline $itk_option(-outlinecolor) \ -width $itk_option(-linewidth) \ -smooth $itk_option(-smooth) \ -stipple $itk_option(-stipplepattern)] } # create and return a new text object protected method create_text {x y} { clip x y set id [$canvas_ create text $x $y \ -fill [get_line_color] \ -font $itk_option(-textfont) \ -anchor w \ -stipple $itk_option(-linestipple)] # set up text bindings ct_add_bindings $canvas_ $id focus $canvas_ $canvas_ focus $id $canvas_ icursor $id 0 $canvas_ addtag $w_.selected withtag $id return $id } # create and return a new label (entry) object protected method create_label {x y} { clip x y set entry [entry $canvas_.lab[incr tag_count_] \ -font $itk_option(-textfont) \ -borderwidth 0 -relief flat \ -width 0] set id [$canvas_ create window $x $y \ -window $entry \ -anchor w] focus $entry bind $entry "+focus $canvas_; $this select_only_object $id $canvasX_ $canvasY_" bind $entry <1> "+focus $entry" $canvas_ addtag $w_.selected withtag $id return $id } # resize the rectangle for a label to fit the text protected method resize_label {text rect tag} { eval "$canvas_ coords $rect [$canvas_ bbox $text]" } # update the current object in the canvas with the new x, y end points protected method update_object {x y {constrain 0}} { clip x y if {$constrain} { if {abs($startx_-$x)>abs($starty_-$y)} { set x [expr {$startx_+($y-$starty_)}] } else { set y [expr {$starty_+($x-$startx_)}] } } $canvas_ coords $obj_id_ $startx_ $starty_ $x $y } # update the current line object in the canvas with the new x, y end points protected method update_line {x y {constrain 0}} { clip x y if {$constrain} { if {abs($startx_-$x)abs($starty_-$y)} { set x [expr {$startx_+($y-$starty_)}] } else { set y [expr {$starty_+($x-$startx_)}] } } if {$itk_option(-withrotate)} { $canvas_ coords $obj_id_ $startx_ $starty_ $x $starty_ $x $y $startx_ $y } else { $canvas_ coords $obj_id_ $startx_ $starty_ $x $y } } # update the current region object (dashed rectangle used for marking # a region on the canvas) protected method update_region {x y {constrain 0}} { clip x y if {$constrain} { if {abs($startx_-$x)>abs($starty_-$y)} { set x [expr {$startx_+($y-$starty_)}] } else { set y [expr {$starty_+($x-$startx_)}] } } $canvas_ coords $obj_id_ \ $startx_ $starty_ \ $x $starty_ \ $x $y \ $startx_ $y \ $startx_ $starty_ } # update the current freehand object in the canvas with the new x, y end points protected method update_freehand {x y} { clip x y lappend obj_coords_ $x $y eval $canvas_ coords $obj_id_ $obj_coords_ $x $y } # arrange to have cmd evaluated whenever the given object is moved # or resized. id is the canvas id of the object, If update_flag # is 1, $cmd is also evaluated while the item is being moved or # resized, otherwise only when the operation is done. public method add_notify_cmd {id cmd {update_flag 0}} { set notify_($id) $cmd if {$update_flag} { set notify_update_($id) $cmd } } # remove the notify command for the given canvas id public method remove_notify_cmd {id} { if {[info exists notify_($id)]} { unset notify_($id) } if {[info exists notify_update_($id)]} { unset notify_update_($id) } } # Exchange the X and Y coords for the given item (not really rotate...) public method rotate {item} { set ids [$canvas_ find withtag $item] foreach id $ids { catch { set coords [$canvas_ coords $id] set n [llength $coords] set ncoords {} for {set i 0} {$i < $n} {incr i 2} { lappend ncoords [lindex $coords [expr {$i+1}]] [lindex $coords $i] } eval $canvas_ coords $id $ncoords } } } # flip the named item(s) on the X axis by subtracting the x # coordinates from $maxx public method flipx {item maxx} { set ids [$canvas_ find withtag $item] foreach id $ids { catch { set coords [$canvas_ coords $id] set n [llength $coords] set ncoords {} for {set i 0} {$i < $n} {incr i 2} { lappend ncoords [expr {$maxx-[lindex $coords $i]}] \ [lindex $coords [expr {$i+1}]] } eval $canvas_ coords $id $ncoords } } } # flip the named item(s) on the Y axis by subtracting the y # coordinates from $maxy public method flipy {item maxy} { set ids [$canvas_ find withtag $item] foreach id $ids { catch { set coords [$canvas_ coords $id] set n [llength $coords] set ncoords {} for {set i 0} {$i < $n} {incr i 2} { lappend ncoords [lindex $coords $i] [expr {$maxy-[lindex $coords [expr {$i+1}]]}] } eval $canvas_ coords $id $ncoords } } } # start rotating the selected object protected method start_rotate {id x y} { mark $x $y set rotate_angle_ "" # get center of object lassign [$canvas_ bbox $w_.selected] x0 y0 x1 y1 set rotate_cx_ [expr {($x1+$x0)/2.}] set rotate_cy_ [expr {($y1+$y0)/2.}] } # rotate the given point about the given center point by the given angle # (in radians) and return a list {x y} as the result. public method rotate_point {x y cx cy angle} { set x [expr {$x-$cx}] set y [expr {$y-$cy}] set tmp $x set cosa [expr {cos($angle)}] set sina [expr {sin($angle)}] set x [expr {$x*$cosa+$y*$sina+$cx}] set y [expr {-$tmp*$sina+$y*$cosa+$cy}] return "$x $y" } # update the rotating of the selected object protected method update_rotate {id x y} { clip x y set dx [expr {$rotate_cx_-double($x+0.5)}] set dy [expr {$rotate_cy_-double($y+0.5)}] set a [expr {atan2($dx,$dy)}] if {"$rotate_angle_" == ""} { set rotate_angle_ $a return } set angle [expr {$a-$rotate_angle_}] set rotate_angle_ $a set coords [$canvas_ coords $id] set cmd [list $canvas_ coords $id] set n [llength $coords] for {set i 0} {$i<$n} {incr i 2} { set x [lindex $coords $i] set y [lindex $coords [expr {$i+1}]] append cmd " [rotate_point $x $y $rotate_cx_ $rotate_cy_ $angle]" } eval $cmd } # stop rotating the selected object protected method end_rotate {id} { if {[info exists notify_($id)]} { eval "$notify_($id) rotate" } adjust_object_selection $id reset_cursor } # -- options -- # if true (default) create the GUI interface (toolbox), otherwise don't itk_option define -withtoolbox withToolbox WithToolbox {1} # if true (default) use polygons for rectangles to support rotation in Tcl # (Tk doesn't support rotating, but polygons can be rotated in Tcl code). # Subclasses that define rotation by adding new canvas objects can set this # option to 0. itk_option define -withrotate withRotate WithRotate {1} # canvas window itk_option define -canvas canvas Canvas {} { set canvas_ $itk_option(-canvas) # string used in bindings to translate %x and %y to canvas coords set canvasX_ "\[$canvas_ canvasx %x\]" set canvasY_ "\[$canvas_ canvasy %y\]" } # specify bounding box of interactive drawing area as a list {x0 y0 x1 y1} itk_option define -bbox bbox Bbox {} { if {[llength $itk_option(-bbox)] == 4} { lassign $itk_option(-bbox) x0_ y0_ x1_ y1_ # leave room for the selection grips, line width, etc set w $itk_option(-gripwidth) set x0_ [expr {$x0_-$w}] set y0_ [expr {$y0_-$w}] set x1_ [expr {$x1_+$w}] set y1_ [expr {$y1_+$w}] } } # flag: if true, keep graphics within the specified bounding box (-bbox option) itk_option define -clipping clipping Clipping 1 # list of colors for menu itk_option define -colors colors Colors { white grey90 grey80 grey70 grey60 grey50 grey40 grey30 grey20 grey10 black red green blue cyan magenta yellow } # default color for outlines itk_option define -outlinecolor outlineColor OutlineColor {grey90} # default text item font itk_option define -textfont textFont TextFont TkFixedFont # default list of fonts for font menu itk_option define -fonts fonts Fonts { -*-courier-medium-r-*-*-*-120-*-*-*-*-*-* -*-courier-medium-o-*-*-*-120-*-*-*-*-*-* -*-courier-bold-r-*-*-*-120-*-*-*-*-*-* -*-courier-medium-r-*-*-*-140-*-*-*-*-*-* -*-courier-medium-o-*-*-*-140-*-*-*-*-*-* -*-courier-bold-r-*-*-*-140-*-*-*-*-*-* -*-courier-medium-r-*-*-*-180-*-*-*-*-*-* -*-courier-medium-o-*-*-*-180-*-*-*-*-*-* -*-courier-bold-r-*-*-*-180-*-*-*-*-*-* -*-courier-medium-r-*-*-*-240-*-*-*-*-*-* -*-courier-medium-o-*-*-*-240-*-*-*-*-*-* -*-courier-bold-r-*-*-*-240-*-*-*-*-*-* } # default value for smooth option itk_option define -smooth smooth Smooth 0 # default line width for drawing itk_option define -linewidth lineWidth LineWidth 1 # default arrow type for lines itk_option define -arrowtype arrowType ArrowType none # default arrow shape for lines itk_option define -arrowshape arrowShape ArrowShape {8 10 3} # default fill color for drawing itk_option define -fillcolor fillColor FillColor {white} # default stipple pattern for drawing itk_option define -stipplepattern stipplePattern StipplePattern "pat7" # default stipple for lines itk_option define -linestipple lineStipple LineStipple "pat0" # -- standard cursor names taken from X11/cursorfont.h -- # default cursor when not drawing itk_option define -defaultcursor defaultCursor DefaultCursor {} # cursor when drawing graphics itk_option define -drawcursor drawCursor DrawCursor {tcross white black} # cursor when creating region items (dashed box marking a region) itk_option define -regioncursor regionCursor RegionCursor {leftbutton white black} # Tcl command to evaluate whenever a "region" object is created, if no # specific "create" command was specified. itk_option define -regioncommand regionCommand RegionCommand {} # cursor when creating text items itk_option define -textcursor textCursor TextCursor {left_side} # cursor displayed over simple lines for resizing itk_option define -linecursor lineCursor LineCursor {draft_small white black} # size of selection grips itk_option define -gripwidth gripWidth GripWidth 5 # fill color of selection grips itk_option define -gripfill gripFill GripFill white # outline color of selection grips itk_option define -gripoutline gripOutline GripOutline black # flag: if true, display selection grips when an item is selected itk_option define -show_selection_grips show_selection_grips Show_selection_grips 1 # flag: if true, display menus over graphic objects when selected with <3> itk_option define -show_object_menu show_object_menu Show_object_menu 1 # -- protected member variables -- # list of drawing types protected variable drawing_modes_ { anyselect region line rectangle oval polyline polygon text } # available arrow shapes for canvas lines # (corresponds to bitmaps named ar$1_$2_$3) protected variable arrowshapes_ { {8 10 3} {10 13 3} {12 11 3} {12 12 3} {6 6 4} {8 12 9} {8 8 6} } # current draw type protected variable drawing_mode_ {anyselect} # starting x coord of object being drawn protected variable startx_ 0 # starting y coord of object being drawn protected variable starty_ 0 # ending x coord of object being drawn protected variable endx_ 0 # ending y coord of object being drawn protected variable endy_ 0 # x offset for move operations protected variable xoffset_ 0 # y offsets for move operations protected variable yoffset_ 0 # flag: true if resizing on X axis protected variable dragx_ 0 # flag: true if resizing on Y axis protected variable dragy_ 0 # flag, true if drawing currently protected variable drawing_ 0 # list of coords for current object being created protected variable obj_coords_ {} # canvas id of the current canvas item protected variable obj_id_ # strings used in bindings to translate %x to canvas coords protected variable canvasX_ # strings used in bindings to translate %y to canvas coords protected variable canvasY_ # counter used for compound objects to generate canvas tags protected variable tag_count_ 0 # array(canvasID,option) of option to use instead for that id protected variable option_map_ # command to evaluate when the current item has been created protected variable create_cmd_ # array(id) of tcl command to evaluate when object given by canvas id # is moved or scaled protected variable notify_ # same as notify_ above, but indicates command should be evaluated # while item is being moved or resized protected variable notify_update_ # array(id) of flag: set if object with id was moved protected variable moved_ # flag: true if currently resizing an item protected variable resizing_ 0 # popup menu for canvas items protected variable object_menu_ # saved menu (optional, from caller's menubar) with drawing commands # for setting the state of the menu items. protected variable menu_ {} # saved previous cursor for canvas protected variable prev_cursor_ {} # cursor to use in rotate mode protected variable rotate_cursor_ {exchange} # index of stipple bitmap (0 .. 15, 7 is see through, see -stipplepattern) protected variable stipple_index_ 7 # canvas widget protected variable canvas_ # x0 of bounding box of interactive drawing area protected variable x0_ 0 # y0 of bounding box of interactive drawing area protected variable y0_ 0 # x1 of bounding box of interactive drawing area protected variable x1_ 1000 # y1 of bounding box of interactive drawing area protected variable y1_ 1000 # x pos for resize operations protected variable posx_ 0 # y pos for resize operations protected variable posy_ 0 # x2 pos for resize operations protected variable posx2_ 0 # y2 pos for resize operations protected variable posy2_ 0 # center X coordinate of object being rotated protected variable rotate_cx_ 0 # center Y coordinate of object being rotated protected variable rotate_cy_ 0 # current rotation angle of object protected variable rotate_angle_ 0 # array(canvasId) of region ids, used to keep these from rotating protected variable regions_ # -- common variables -- # array(direction={n,w,e,s,nw,ne,sw,se}) of cursor names for selection handles protected common cursors_ set cursors_(n) top_side set cursors_(w) left_side set cursors_(s) bottom_side set cursors_(e) right_side set cursors_(nw) top_left_corner set cursors_(ne) top_right_corner set cursors_(sw) bottom_left_corner set cursors_(se) bottom_right_corner # const PI protected common pi_ 3.14159265358979323846 # const PI/180. protected common rad_ [expr {$pi_/180.}] } skycat-3.1.2-starlink-1b/tclutil/library/CanvasPrint.tcl000066400000000000000000000154611215713201500232240ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id: CanvasPrint.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # CanvasPrint.tcl - Popup dialog for printing the contents of a Tk canvas # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 94 Created # Peter W. Draper 20 Jul 09 Removed mono widget, BLT no longer offers this. itk::usual CanvasPrint {} # This class extends the PrintDialog class to be able to # print the contents of a canvas as postscript. # Note: this class does not support printing images embedded # in the canvas. itcl::class util::CanvasPrint { inherit util::PrintDialog # constructor constructor {args} { eval itk_initialize $args } # this method is called after all options have been evaluated protected method init {} { util::PrintDialog::init global ::$w_.color ::$w_.rotate ::$w_.fit_to_page pack [frame $w_.options -borderwidth 3 -relief groove] \ -side top -fill x -expand 1 -in $w_.config pack [label $w_.options.title -text "Postscript Options"] \ -side top # color options pack [frame $w_.color -borderwidth 5] \ -side top -fill x -expand 1 -in $w_.options pack [radiobutton $w_.color.color -text "Color" \ -variable $w_.color \ -value color] \ [radiobutton $w_.color.gray -text "Gray-Scale" \ -variable $w_.color \ -value gray] \ -side left -fill x -expand 1 ::set $w_.color color # rotate options pack [frame $w_.rotate -borderwidth 5] \ -side top -fill x -expand 1 -in $w_.options pack [radiobutton $w_.rotate.yes -text "Landscape" \ -variable $w_.rotate \ -value yes] \ [radiobutton $w_.rotate.no -text "Portrait" \ -variable $w_.rotate \ -value no] \ -side left -fill x -expand 1 ::set $w_.rotate no # page size options pack [frame $w_.pagesize -borderwidth 5] \ -side top -fill x -expand 1 -in $w_.options pack [checkbutton $w_.pagesize.fit -text "Fit on page" \ -variable $w_.fit_to_page \ -command [code $this toggle_fit_pagesize]] \ -side top -anchor w pack \ [LabelEntry $w_.pagesize.width \ -text "Page width " \ -value $itk_option(-pagewidth) \ -valuewidth 6] \ [LabelEntry $w_.pagesize.height \ -text "Page height" \ -value $itk_option(-pageheight) \ -valuewidth 6] \ -side left -expand 1 ::set $w_.fit_to_page $itk_option(-fit_to_page) } # called when the "Fit on page" button is pressed protected method toggle_fit_pagesize {} { global ::$w_.fit_to_page if {[set $w_.fit_to_page]} { $w_.pagesize.width config -state normal $w_.pagesize.height config -state normal } else { $w_.pagesize.width config -state disabled $w_.pagesize.height config -state disabled } } # print the contents of the canvas to the open filedescriptor protected method print {fd} { global ::$w_.color ::$w_.rotate ::$w_.colormap ::$w_.fit_to_page set cmd [list $itk_option(-canvas) postscript \ -colormode [set $w_.color] \ -rotate [set $w_.rotate]] if {"$x0" == ""} { lassign [$itk_option(-canvas) bbox all] x0 y0 x1 y1 } if {$itk_option(-show_headers)} { add_headers } lappend cmd \ -width [expr {$x1-$x0}] \ -height [expr {$y1-$y0}] \ -x $x0 \ -y $y0 if {[set $w_.fit_to_page]} { lappend cmd \ -pagewidth [$w_.pagesize.width get] \ -pageheight [$w_.pagesize.height get] } if {"[set $w_.color]" == "mono"} { # you can add to this array, see canvas(n) man page set $w_.colormap(grey) "0.0 0.0 0.0 setrgbcolor" lappend cmd -colormap $w_.colormap } # puts $cmd puts $fd [eval $cmd] if {$itk_option(-show_headers)} { rm_headers } } # add header and footer labels above/below draw area by temporarily inserting # the text protected method add_headers {} { set hy0 [expr {$y0-25}] set hy1 [expr {$y1+25}] # white background for labels $itk_option(-canvas) create rect $x0 $hy0 $x1 $y0 \ -outline white \ -fill white \ -tags print $itk_option(-canvas) create rect $x0 $y1 $x1 $hy1 \ -outline white \ -fill white \ -tags print set y0 [expr {$y0-5}] set y1 [expr {$y1+5}] if {"$itk_option(-top_left)" != ""} { $itk_option(-canvas) create text $x0 $y0 \ -text $itk_option(-top_left) \ -font $itk_option(-header_font) \ -anchor sw \ -tags print } if {"$itk_option(-top_right)" != ""} { $itk_option(-canvas) create text $x1 $y0 \ -text $itk_option(-top_right) \ -font $itk_option(-header_font) \ -anchor se \ -tags print } if {"$itk_option(-bot_left)" != ""} { $itk_option(-canvas) create text $x0 $y1 \ -text $itk_option(-bot_left) \ -font $itk_option(-header_font) \ -anchor nw \ -tags print } if {"$itk_option(-bot_right)" != ""} { $itk_option(-canvas) create text $x1 $y1 \ -text $itk_option(-bot_right) \ -font $itk_option(-header_font) \ -anchor ne \ -tags print } set y0 $hy0 set y1 $hy1 } # remove the headers, if any and restore the original state protected method rm_headers {} { $itk_option(-canvas) delete print } # -- options -- # canvas widget itk_option define -canvas canvas Canvas {} # flag, if true, scale output to fit on page itk_option define -fit_to_page fit_to_page Fit_to_page 1 # page width, used when fit_to_page is 1 itk_option define -pagewidth pageWidth Pagewidth 8.268i # page height, used when fit_to_page is 1 itk_option define -pageheight pageHeight Pageheight 11.693i # flag, if true, insert headers before printing itk_option define -show_headers show_headers Show_headers 0 # header text to appear at top left itk_option define -top_left top_left Top_left {} # header text to appear at top right itk_option define -top_right top_right Top_right {} # header text to appear at bottom left itk_option define -bot_left bot_left Bot_left {} # header text to appear at bottom right itk_option define -bot_right bot_right Bot_right {} # header/footer fonts itk_option define -header_font header_font Header_font TkDefaultFont # x0 coordinate of area of canvas to print itk_option define -x0 x0 X0 {} {set x0 $itk_option(-x0)} # y0 coordinate of area of canvas to print itk_option define -y0 y0 Y0 {} {set y0 $itk_option(-y0)} # x1 coordinate of area of canvas to print itk_option define -x1 x1 X1 {} {set x1 $itk_option(-x1)} # y1 coordinate of area of canvas to print itk_option define -y1 y1 Y1 {} {set y1 $itk_option(-y1)} # -- protected variables -- # saved -x0 option value protected variable x0 # saved -y0 option value protected variable y0 # saved -x1 option value protected variable x1 # saved -y1 option value protected variable y1 } skycat-3.1.2-starlink-1b/tclutil/library/CanvasWidget.tcl000066400000000000000000000031311215713201500233420ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id: CanvasWidget.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # CanvasWidget.tcl - Itcl class based on the Tk canvas widget # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 94 Created itk::usual CanvasWidget {} # This is an itcl class based on the Tk canvas widget. It combines # a canvas window in a frame with optional scrollbars. itcl::class util::CanvasWidget { inherit util::FrameWidget # create the canvas and scrollbars constructor {args} { # Canvas widget itk_component add canvas { canvas $w_.canvas -scrollregion {0 0 0 0} } { keep -width -height -borderwidth -relief usual rename -background -canvasbackground canvasBackground CanvasBackground } # Vertical scrollbar. itk_component add vscroll { scrollbar $w_.vscroll \ -relief sunken \ -command "$w_.canvas yview" } # Horrizontal scrollbar itk_component add hscroll { scrollbar $w_.hscroll \ -orient horiz \ -relief sunken \ -command "$itk_component(canvas) xview" } $itk_component(canvas) config \ -xscrollcommand "$itk_component(hscroll) set" \ -yscrollcommand "$itk_component(vscroll) set" bind $itk_component(canvas) "$itk_component(canvas) scan mark %x %y" bind $itk_component(canvas) "$itk_component(canvas) scan dragto %x %y" pack $itk_component(hscroll) -side bottom -fill x pack $itk_component(vscroll) -side right -fill y pack $itk_component(canvas) -fill both -expand 1 eval itk_initialize $args } } skycat-3.1.2-starlink-1b/tclutil/library/CheckEntry.tcl000066400000000000000000000052261215713201500230310ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id: CheckEntry.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # CheckEntry.tcl - Itcl widget combining a checkbutton and an entry # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 94 Created itk::usual CheckEntry {} # This class defines an Itk widget combining a checkbutton and an entry. itcl::class util::CheckEntry { inherit util::FrameWidget # constructor: create new CheckEntry constructor {args} { set variable_ $w_.var global ::$variable_ # Tk checkbutton widget itk_component add check { checkbutton $w_.check -variable $variable_ } { keep -text -background -foreground -anchor rename -font -labelfont labelFont LabelFont rename -width -labelwidth labelWidth LabelWidth } pack $itk_component(check) \ -side left -fill x -expand 1 -ipadx 1m # Tk entry widget itk_component add entry { entry $w_.entry -relief sunken } { keep -relief -borderwidth -textvariable -show rename -font -valuefont valueFont ValueFont rename -width -valuewidth valueWidth ValueWidth } pack $itk_component(entry) \ -side left -expand 1 -fill x -padx 1m -ipadx 1m bind $itk_component(entry) <1> "[bind Entry <1>]; $itk_component(check) select" eval itk_initialize $args } # Get the value in the entry public method get {} { global ::$variable_ if {[set $variable_]} { return [$itk_component(entry) get] } return {} } # called for Return in the entry protected method _command_proc {} { if {"$itk_option(-command)" != ""} { set a $itk_option(-command) lappend a [$this get] eval $a } } # -- options -- # set the value in the entry itk_option define -value value Value {} { global ::$variable_ if {"$itk_option(-value)" == ""} { set $variable_ 0 } else { if {[winfo exists $itk_component(entry)]} { set $variable_ 1 $itk_component(entry) delete 0 end $itk_component(entry) insert 0 [cget -value] $itk_component(entry) icursor end $itk_component(entry) xview moveto 1 } } } # the command for in the entry itk_option define -command command Command {} { bind $itk_component(entry) [code $this _command_proc] } # optionally specify the trace variable to use itk_option define -variable variable Variable {} { if {"$itk_option(-variable)" != ""} { $itk_component(check) configure -variable [set variable_ $itk_option(-variable)] } } # -- protected variables -- # trace var for checkbutton protected variable variable_ } skycat-3.1.2-starlink-1b/tclutil/library/CheckEntryNumber.tcl000066400000000000000000000035711215713201500242030ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id: CheckEntryNumber.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # CheckEntry.tcl - Itcl widget combining a checkbutton and an number entry # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 94 Created itk::usual CheckEntryNumber {} # This class defines an Itk widget combining a checkbutton and a number entry. itcl::class util::CheckEntryNumber { inherit util::CheckEntry # constructor: create a new LabelNumber constructor {args} { # button frame itk_component add bframe { frame $w_.f } { keep -background } # button to increment number. itk_component add incr { button $w_.f.incr \ -bitmap incr \ -command [code $this increment 1] } { keep -state -background -foreground } # button to decrement number. itk_component add decr { button $w_.f.decr \ -bitmap decr \ -command [code $this increment -1] } { keep -state -background -foreground } pack $itk_component(incr) $itk_component(decr) \ -side top pack $itk_component(bframe) -side left eval itk_initialize $args if {"itk_option(-value)" == ""} { config -value $itk_option(-min) } } # increment (1) or decrement (-1) the value by the current increment protected method increment {sign} { set v [expr [get]+($sign*$itk_option(-increment))] if {$v >= $itk_option(-min) && $v <= $itk_option(-max)} { config -value [format "%g" $v] if {"$itk_option(-command)" != ""} { set cmd $itk_option(-command) lappend cmd $v eval $cmd } } } # -- options -- # maximum value itk_option define -max max Max {100} # minimum value itk_option define -min min Min {0} # amount to add or subtract for each button push itk_option define -increment increment Increment {1} } skycat-3.1.2-starlink-1b/tclutil/library/ChoiceDialog.tcl000066400000000000000000000023701215713201500233010ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id: ChoiceDialog.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # ChoiceDialog.tcl - Dialog to display a message and get choice from the user # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 94 Created itk::usual ChoiceDialog {} # A ChoiceDialog is a dialog widget used to display a message and # get a choice from the user. itcl::class util::ChoiceDialog { inherit util::DialogWidget # create the dialog constructor {args} { # LabelChoice(n) Itk widget itk_component add choice { util::LabelChoice $itk_component(ext).choice \ -command [code $this set_choice] } { keep -choice -value -rows -cols } pack $itk_component(choice) -side left -fill x -expand 1 \ -padx 2m -pady 2m -ipady 1m eval itk_initialize $args } # called when a choice is made public method set_choice {choice} { global ::$variable_ set $variable_ $choice } # this method is redefined here to change the value # that is returned from activate to be the contents of the choice widget protected method set_result {} { global ::$variable_ return [$itk_component(choice) get] } } skycat-3.1.2-starlink-1b/tclutil/library/Chooser.tcl000066400000000000000000000045721215713201500223770ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # "@(#) $Id: Chooser.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # Chooser.tcl - A simple widget for selecting items based on filenames # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 94 Created itk::usual Chooser {} # Chooser is a simple itcl widget for selecting items based on files # with a given suffix in a given directory. itcl::class util::Chooser { inherit util::FrameWidget # create a new Chooser widget constructor {args} { itk_option add hull.borderwidth hull.relief # ListboxWidget(n) for displaying choice itk_component add list { util::ListboxWidget $w_.list \ -exportselection 0 \ -borderwidth 2 \ -relief sunken } { keep -title -vscroll -hscroll -width \ -background -foreground -font -height } pack $itk_component(list) -fill both -expand 1 set listbox_ [$itk_component(list) component listbox] bind $listbox_ "+[code $this choose]" eval itk_initialize $args } # set new values protected method choose {} { if {"$itk_option(-command)" != ""} { set sel [lindex [$itk_component(list) get_selected] 0] eval "$itk_option(-command) $itk_option(-dir)/$sel.$itk_option(-suffix)" } } # change the selection to the given file public method set_choice {file} { set n 0 foreach i $itk_option(-files) { set name [file rootname [file tail $i]] if {"$name" == "$file"} { $itk_component(list) select_row $n break } incr n } choose } # -- options -- # tcl command to evaluate with selected file name itk_option define -command command Command {} # directory for files itk_option define -dir dir Dir {.} # suffix for files itk_option define -suffix suffix Suffix {} # list of files (complete pathnames, usually output of [glob $dir/*.$suffix] itk_option define -files files Files {} { set n 0 foreach i $itk_option(-files) { set name [file rootname [file tail $i]] $itk_component(list) append $name if {"$name" == "$itk_option(-default)"} { $itk_component(list) select_row $n } incr n } } # default selection itk_option define -default default Default {} # -- protected vars -- # internal listbox widget protected variable listbox_ } skycat-3.1.2-starlink-1b/tclutil/library/DialogWidget.tcl000066400000000000000000000152421215713201500233340ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id: DialogWidget.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # DialogWidget.tcl - Base class of dialog widget classes # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 94 Created # Peter W. Draper 03 Jul 06 Stop . being used as a parent, that is usually # in a withdrawn state. Why hasn't this been a # problem before? # 21 Mar 07 Raise the window on activation. Keeps hiding. # 13 Apr 07 And wait for update # 17 May 07 Make truncation lines an option. itk::usual DialogWidget {} # A DialogWidget is an itk widget for creating dialog windows. # A dialog window here is a window with a message at top and a row # of buttons at bottom. Through inheritance, you can add widgets # inbetween. itcl::class util::DialogWidget { inherit util::TopLevelWidget # create the dialog constructor {args} { set variable_ $w_.choice global ::$variable_ wm iconname $w_ DialogWidget if {[winfo parent $w_] != "." } { wm transient $w_ [winfo parent $w_] } # The top frame has one frame for the message and bitmap # and another for extensions defined in derived classes. itk_component add top { frame $w_.top -relief raised -borderwidth 2 } # default frame (for image, bitmap, message...) itk_component add def { frame $itk_component(top).def -borderwidth 2 } # extension frame (for subclasses) itk_component add ext { frame $itk_component(top).ext -borderwidth 2 } pack $itk_component(top) $itk_component(def) $itk_component(ext) \ -side top -fill both -expand 1 # optional image frame itk_component add imagef { frame $itk_component(def).imagef } # optional image label itk_component add image { label $itk_component(imagef).image } # optional message text itk_component add text { label $itk_component(def).text } { keep -justify -background rename -font -messagefont messageFont MessageFont rename -wraplength -messagewidth messageWidth MessageWidth } # optional bitmap frame itk_component add bitmapf { frame $itk_component(def).bitmapf } # optional bitmap label itk_component add bitmap { label $itk_component(bitmapf).bitmap } pack $itk_component(imagef) -side top pack $itk_component(text) -side right -expand 1 -fill both -padx 5m -pady 5m pack $itk_component(bitmapf) -side left eval itk_initialize $args } # this method is called after the options have been evaluated protected method init {} { # truncate long (many lines) error mesages set err [split $itk_option(-text) \n] if {[llength $err] > $itk_option(-max_lines) } { set err [lrange $err 0 $itk_option(-max_lines)] lappend err "..." } set err [join $err \n] $itk_component(text) config -text $err # add optional buttons add_buttons } # Create a row of buttons at the bottom of the dialog. protected method add_buttons {} { # Button frame at bottom. itk_component add bot { frame $w_.bot -relief raised -borderwidth 2 } pack $itk_component(bot) -side bottom -fill x set i 0 foreach but $itk_option(-buttons) { # Components for buttons specified with the -buttons option. # For example "buttonOK" for the OK button. itk_component add button$i { button $itk_component(bot).button$i -text $but -command "set $variable_ $i" } { } if {$i == $itk_option(-default)} { # Frame surrounding the default dialog button. itk_component add default { frame $itk_component(bot).default -relief sunken -borderwidth 1 } raise $itk_component(button$i) $itk_component(default) pack $itk_component(default) -side left -expand 1 -padx 3m -pady 2m pack $itk_component(button$i) -in $itk_component(default) -padx 2m -pady 2m \ -ipadx 2m -ipady 1m bind $w_ "$itk_component(button$i) flash; $itk_component(button$i) invoke" } else { pack $itk_component(button$i) -side left -expand 1 \ -padx 3m -pady 3m -ipadx 2m -ipady 1m } incr i } } # Display the window and return the user's selection public method activate {} { global ::$variable_ # Set a grab and claim the focus. set oldFocus [focus] if {$itk_option(-modal)} { catch {grab $w_} } catch {::raise $w_} update idletasks tkwait visibility $w_ if {$itk_option(-default) >= 0} { focus $itk_component(button$itk_option(-default)) } else { focus $w_ } # If the window is closed by the window manager we need to # get that request as well. wm protocol $w_ WM_DELETE_WINDOW "set ::$variable_ 0" # Wait for the user to respond, then restore the focus and # return the index of the selected button. tkwait variable $variable_ set result [set_result] catch {unset $variable_} catch {destroy $w_} catch {focus $oldFocus} return $result } # this method may be redefined in a derived class to change the value # that is returned from activate (default is the number of the button selected) protected method set_result {} { global ::$variable_ if {[info exists $variable_]} { return [set $variable_] } return 0 } # -- itk_option define -variables variables variables -- # Title to display in dialog's decorative frame. itk_option define -title title Title {dialog} { wm title $w_ $itk_option(-title) } # Index of button that is to display the default ring (-1 means none). itk_option define -default default Default {0} # text of message (truncated if too long) itk_option define -text text Text {} # One or more strings to display in buttons across the # bottom of the dialog box. itk_option define -buttons buttons Buttons {OK} # optional image to display above the message itk_option define -image image Image {} { if {"$itk_option(-image)" != ""} { $itk_component(image) config -image $itk_option(-image) pack $itk_component(image) -padx 5m -pady 5m } else { pack forget $itk_component(image) } } # optional bitmap to display to left of message itk_option define -bitmap bitmap Bitmap {info} { if {"$itk_option(-bitmap)" != ""} { $itk_component(bitmap) config -bitmap $itk_option(-bitmap) pack $itk_component(bitmap) -padx 5m -pady 5m } else { pack forget $itk_component(bitmap) } } # flag: if true, grab the screen itk_option define -modal modal Modal 1 # number of lines before truncation. itk_option define -max_lines max_lines Max_Lines 20 # -- protected vars -- # trace variable name protected variable variable_ } skycat-3.1.2-starlink-1b/tclutil/library/DoubleList.tcl000066400000000000000000000055731215713201500230450ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id: DoubleList.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # DoubleList.tcl - Widget displaying two lists with arrows between them # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 94 Created itk::usual DoubleList { } # A DoubleList is an itcl widget for displaying two lists with arrows between # them for moving items back and forth. itcl::class util::DoubleList { inherit util::FrameWidget # create a new object of this class constructor {args} { # left list component (see ListboxWidget(n)) itk_component add left { util::ListboxWidget $w_.left } { rename -title -lefttitle leftTitle LeftTitle keep -hscroll -vscroll -exportselection -selectmode -width -height } pack $itk_component(left) -side left -fill both -expand 1 # arrows pack [frame $w_.arrows -bd 1m] \ -side left -fill y -ipadx 0.5m pack [label $w_.arrows.fill -text " " ] \ -side top -fill x pack [button $w_.arrows.right \ -bitmap right_arrow \ -command [code $this move_right]] \ -side top -fill y -expand 1 pack [button $w_.arrows.left \ -bitmap left_arrow \ -command [code $this move_left]] \ -side top -fill y -expand 1 -pady 1m # right list component (see ListboxWidget(n)) itk_component add right { util::ListboxWidget $w_.right } { rename -title -righttitle rightTitle RightTitle keep -hscroll -vscroll -exportselection -selectmode -width -height } pack $itk_component(right) -side right -fill both -expand 1 eval itk_initialize $args } # move the selected elements from the left to the right list public method move_right {} { $itk_component(right) append_list [$itk_component(left) remove_selected] } # move the selected elements from the right to the left list public method move_left {} { $itk_component(left) append_list [$itk_component(right) remove_selected] } # move the selected elements from the right to the left list public method move_up {} { $itk_component(left) move_up } # move the selected elements from the right to the left list public method move_down {} { $itk_component(left) move_down } # make the lists empty public method clear {} { $itk_component(left) clear $itk_component(right) clear } # -- options -- # flag: if true, also display up and down buttons for moving # list items vertically itk_option define -updown upDown UpDown 0 { if {$itk_option(-updown)} { pack [button $w_.arrows.up \ -bitmap up_arrow \ -command [code $this move_up]] \ -side top -fill y -expand 1 pack [button $w_.arrows.down \ -bitmap down_arrow \ -command [code $this move_down]] \ -side top -fill y -expand 1 -pady 1m } else { catch {destroy $w_.arrows.up} catch {destroy $w_.arrows.down} } } } skycat-3.1.2-starlink-1b/tclutil/library/DoubleTableList.tcl000066400000000000000000000065031215713201500240070ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id" # # DoubleTableList.tcl - Widget displaying two TableLists with arrows between them. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 94 Created itk::usual DoubleTableList { } # A DoubleTableList is an itcl widget for displaying two TableLists # with arrows between them for moving items back and forth. You can # access the left and right TableLists as itk components "left" and # "right". itcl::class util::DoubleTableList { inherit util::FrameWidget # create a new object of this class constructor {args} { # left table component (TableList(n)). itk_component add left { util::TableList $w_.left } { rename -title -lefttitle leftTitle LeftTitle rename -info -leftinfo leftInfo LeftInfo keep -headings -hscroll -vscroll -exportselection -selectmode -headinglines } pack $itk_component(left) -side left -fill both -expand 1 # arrows pack [frame $w_.arrows -bd 1m] \ -side left -fill y -ipadx 0.5m pack [label $w_.arrows.fill -text " " ] \ -side top -fill x pack [button $w_.arrows.right \ -bitmap right_arrow \ -command [code $this move_right]] \ -side top -fill y -expand 1 pack [button $w_.arrows.left \ -bitmap left_arrow \ -command [code $this move_left]] \ -side top -fill y -expand 1 -pady 1m # right table (see TableList(n)) itk_component add right { TableList $w_.right } { rename -title -righttitle rightTitle RightTitle rename -info -rightinfo rightInfo RightInfo keep -headings -hscroll -vscroll -exportselection -selectmode -headinglines } pack $itk_component(right) -side right -fill both -expand 1 # disable table configure here bind $itk_component(left).headbox <1> { } bind $itk_component(right).headbox <1> { } eval itk_initialize $args } # move the selected elements from the left to the right TableList public method move_right {} { $itk_component(right) append_rows [$itk_component(left) remove_selected] eval $command } # move the selected elements from the right to the left TableList public method move_left {} { $itk_component(left) append_rows [$itk_component(right) remove_selected] eval $command } # move the selected elements from the right to the left TableList public method move_up {} { $itk_component(left) move_up eval $command } # move the selected elements from the right to the left TableList public method move_down {} { $itk_component(left) move_down eval $command } # make the TableLists empty public method clear {} { $itk_component(left) clear $itk_component(right) clear eval $command } # -- options -- # command to evaluate when the list contents change public variable command {} # flag: if true, also display up and down buttons for moving # table items vertically itk_option define -updown upDown UpDown 0 { if {$itk_option(-updown)} { pack [button $w_.arrows.up \ -bitmap up_arrow \ -command [code $this move_up]] \ -side top -fill y -expand 1 pack [button $w_.arrows.down \ -bitmap down_arrow \ -command [code $this move_down]] \ -side top -fill y -expand 1 } else { catch {destroy $w_.arrows.up} catch {destroy $w_.arrows.down} } } } skycat-3.1.2-starlink-1b/tclutil/library/EntryForm.tcl000066400000000000000000000135111215713201500227130ustar00rootroot00000000000000# E.S.O. - VLT project/ESO Archive # "@(#) $Id: EntryForm.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # EntryForm.tcl - Form dialog for entering data at given labels # # who when what # -------- --------- ---------------------------------------------- # A.Brighton 26 Jun 96 created # P.Biereichel 04/08/99 Added option -scroll # P.W.Draper 03/12/08 Scroll for width as well as height. Some # reorganisations to make it work. itk::usual EntryForm {} # An EntryForm widget is a dialog for entering data at given labels. itcl::class util::EntryForm { inherit util::TopLevelWidget # constructor constructor {args} { eval itk_initialize $args } # called after options have been evaluated protected method init {} { # Title for window. itk_component add title { label $w_.title -text $itk_option(-title) } pack $itk_component(title) -side top -fill x -pady 2m -padx 2m # Frame containing dialog buttons. itk_component add buttons { util::ButtonFrame $w_.buttons \ -borderwidth 2 \ -relief raised \ -ok_label Enter \ -ok_cmd [code $this enter_data] \ -cancel_label Close \ -cancel_cmd [code $this cancel] } $itk_component(buttons) append Reset [code $this reset] foreach i $itk_option(-buttons) { lassign $i label cmd $itk_component(buttons) append $label [code $this eval_cmd $cmd] } pack $itk_component(buttons) -side bottom -fill x if {$itk_option(-scroll)} { # Canvas used to add a scrollbar itk_component add canvas { CanvasWidget $w_.canvas } set canvas [$w_.canvas component canvas] pack $w_.canvas -side top -fill both -expand 1 \ -padx 1m -pady 1m -ipadx 1m -ipady 1m # Frame containing entries. itk_component add entries { set f [frame $canvas.entries -bd 3 -relief groove] } $canvas create window 0 0 -window $f -anchor nw -tags frame $canvas configure -background [$f cget -background] after idle [code $this add_bindings_ $canvas $f] } else { itk_component add entries { set f [frame $w_.entries -bd 3 -relief groove] } pack $f -side top -fill both -expand 1 \ -padx 1m -pady 1m -ipadx 1m -ipady 1m } blt::blttable $f set row 0 foreach label $itk_option(-labels) { blt::blttable $f \ [label $f.label$row -text $label] \ $row,0 -anchor e \ [set entries_($label) [entry $f.entry$row -relief sunken]] \ $row,1 -fill x -anchor w $f.entry$row insert end [lindex $itk_option(-values) $row] bind $f.entry$row [code $this enter_data] incr row } blt::blttable configure $f c1 -resize expand blt::blttable configure $f c0 -resize none blt::blttable configure $f r* -resize none wm title $w_ {Entry Form} set initialized_ 1 } # Add bindings to the canvas. Deferred until after window is realised. protected method add_bindings_ {canvas f} { bind $canvas [code $this resize $f $canvas %w %h] } # Called when the window is resized. the arguments are the # entries frame (in the canvas), the canvas and the canvas # width and hight. public method resize {frame canvas cw ch} { # Don't resize when already resizing. if { $resizing_ } return set fh [max $ch [winfo height $frame]] set fw [max $cw [winfo width $frame]] set resizing_ 1 $canvas configure -width $fw $canvas configure -height $fh $canvas itemconfigure frame -width $fw -height $fh $canvas configure -scrollregion "0 0 $fw $fh" # Make sure we're completed before releasing the lock. update set resizing_ 0 } # reset to the original values public method reset {} { set row 0 foreach i $itk_option(-values) { set w [component entries].entry$row $w delete 0 end $w insert end $i incr row } } # called for the Cancel button public method cancel {} { destroy $w_ } # set (reset) the value for the given entry public method set_entry {label value} { if {[info exists entries_($label)]} { $entries_($label) delete 0 end $entries_($label) insert end $value } } # this method is called to enter the data when the Enter button is # pressed. Call the command specified by the -command option with # a list of values, one for each label. protected method enter_data {} { eval_cmd $itk_option(-command) #destroy $w_ } # add the contents of this window as a list argument to the given # command and then evaluate it protected method eval_cmd {cmd} { if {"$cmd" != ""} { set n 0 set list {} set row 0 set f $itk_component(entries) foreach label $itk_option(-labels) { set s [$f.entry$row get] lappend list $s incr row incr n [string length $s] } if {$n == 0} { error_dialog "No data was entered" return } lappend cmd $list eval $cmd } } # -- options -- # title for dialog itk_option define -title title Title {} # list of labels, one for each entry to be displayed itk_option define -labels labels Labels {} # optional list of values, one for each entry to be displayed itk_option define -values values Values {} { if {$initialized_} { reset } } # called with list of values when Enter button is pushed itk_option define -command command Command {} # list {{label cmd} {label cmd}} of additional buttons to display itk_option define -buttons buttons Buttons {} # use scrollbar option itk_option define -scroll scroll Scroll {1} # -- protected vars -- # array(label) of entry widget for given label protected variable entries_ # flag: set to 1 after init protected variable initialized_ 0 # resizing during configure, so don't update protected variable resizing_ 0 } skycat-3.1.2-starlink-1b/tclutil/library/FileSelect.tcl000066400000000000000000000633041215713201500230120ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id: FileSelect.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # FileSelect.tcl - OSF/Motif standard file selection dialog # # ---------------------------------------------------------------------- # Implements a version of the OSF/Motif standard file selection dialog # box using primitive widgets as the building blocks. # # # PUBLIC ATTRIBUTES: # # -filterlabel ... label for filter entry, default "Filter" # -dirlabel ...... label for directory list, default "Directories" # -filelabel ..... label for file list, default "Files" # -selectlabel ... label for selection entry, default "Selection" # -dispfilter .... display filter, yes or no, default yes # -dispdir ....... display directory list, yes or no, default yes # -dispfile ...... display file list, yes or no, default yes # -dispselect .... display selection, yes or no, default yes # -filter ........ file list filter, defaults to "*" # -dir ........... initial directory, default to [pwd] # -title ......... window title text, default "Select File" # -full .......... display full file names, yes or no, default no # # -width ......... width of filter/selection entry widgets in chars # -height ........ height of displayed list in lines # # -button_1 ...... Name of the first button, default ok # -button_2 ...... Name of the second button, default filter # -button_3 ...... Name of the third button, default cancel # -button_4 ...... Name of the fourth button default "", i.e none. # # -cmd_4 ......... Command to execute when fourth button is pressed. # Note assumes that this window should be closed # (as if pressing OK, but returns 0 for the activate # status, and this action should take control, by # accessing the selected file). # # METHODS: # # config ......... used to change public attributes # get ............ return the selection # activate ....... perform a grab, upon selection of ok(1) or cancel(0), # return result. # # USAGE: # # FileSelect .fs -title "Test File Select" -full 0 # # if {[.fs activate]} { # puts stdout "OK >>==> [.fs get]" # } else { # puts stdout "Cancel" # } # # .fs destroy # # X11 OPTION DATABASE ATTRIBUTES # # ...and the rest of the usual widget attributes # # ---------------------------------------------------------------------- # AUTHOR: Mark L. Ulferts Phone: (214) 519-3947 # DSC Communications Corp E-mail: mulferts@spd.dsccc.com # ---------------------------------------------------------------------- # # Contributions: Shawn Ellis E-mail: ellis@sctc.com # o Simple Emacs key bindings for entry widgets # o Can now paste a filename or directory into entry # widgets # o Directories are checked on whether they exist before # they are cd'd into. # o Filenames displayed in alphabetical order # o Multiple FileSelect widgets can be used. # o Get method returns _selection only if the file # exists (XXX allan: no, not good when specifying a new file) # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 20 May 96 added quick hack to get this to work in itk2.0. # (New version in iwidgets2.0.1 was too slow) # # Peter W. Draper 27 Jan 97 added -filter_types option to allow caller # to see a list of "known" file extensions. # 30 Mar 00 added changes to add a file filter # when user just types in a directory # (which doesn't then show any files). # 05 Jun 00 added catch to directory list expansion, # this blows up if a file like "~noname" is # found (a failed attempt to seek # $env(HOME)/noname is made). # 16 Oct 00 Also now skips $filename and # ~$filename. These cannot be handled by # NDF (user can still enter these names by hand) # 26 Mar 01 Added panedwindow to control how the # space is divided between the directory # and files views. # 07 Jul 03 Added horizontal scrollbars. # 22 Nov 05 Removed panedwindow as this seems to be stopping # the delivery of double clicks. # 12 Jan 08 Allow extra space to be taken by the file list # by default. Add a panedwindow to control dir # and file list share of space. itk::usual FileSelect {} # This class implements a version of the OSF/Motif standard file selection # dialog box using primitive widgets as the building blocks. # This is a modified version of an old widget written by Mark Ulferts # that is still used because of poor performance in the iwidgets2.x version. # This should probably be replaced when we move to tcl8.x. itcl::class util::FileSelect { inherit util::TopLevelWidget # create new scrolled text constructor {args} { eval itk_initialize $args # # Set the minimum size to 0,0 to allow both shrinkage and expansion. # Also, set the title if one has been given. # wm minsize $w_ 250 250 wm title $w_ "$itk_option(-title)" # # Create an overall frame and separate frames for the filter, # lists, selection, and buttons. # set f [frame $w_.fs] set fs(filterf) [frame $f.filterf] set fs(listf) [panedwindow $f.listf -width 4i -orient horizontal] set fs(self) [frame $f.self] set fs(btnf) [frame $f.btnf -height 30] # # Create the label and entry widgets for the filter. Turn off # the selection capability, at least from the visual aspect. # label $fs(filterf).label -text "$itk_option(-filterlabel)" set fs(filter) [entry $fs(filterf).entry -relief sunken] #$fs(filter) configure -selectbackground \ # [lindex [$fs(filter) configure -background] 4] -selectborderwidth 0 pack $fs(filterf).label -side top -anchor w # PWD: modification here, pack to top not bottom. pack $fs(filterf).entry -side top -fill x -expand yes -ipady 1m # # Create directory list, scrollbar, and label for the directory # frame. Make the list single select. # set fs(dirf) [frame $fs(listf).dirf] label $fs(dirf).label -text "$itk_option(-dirlabel)" set fs(dirs) [listbox $fs(dirf).list -relief sunken \ -yscrollcommand "$fs(dirf).vscroll set" \ -xscrollcommand "$fs(dirf).hscroll set" \ -selectmode single \ -exportselection no] scrollbar $fs(dirf).vscroll -orient vertical -relief sunken \ -command "$fs(dirf).list yview" scrollbar $fs(dirf).hscroll -orient horizontal -relief sunken \ -command "$fs(dirf).list xview" pack $fs(dirf).label -side top -anchor w pack $fs(dirf).vscroll -side right -fill y pack $fs(dirf).hscroll -side bottom -fill x pack $fs(dirf).list -side left -expand yes -fill both # # Create file list, scrollbar, and label for the file frame. # Again, make the list single select. # set fs(filef) [frame $fs(listf).filef] label $fs(filef).label -text "$itk_option(-filelabel)" set fs(files) [listbox $fs(filef).list -relief sunken \ -yscrollcommand "$fs(filef).vscroll set" \ -xscrollcommand "$fs(filef).hscroll set" \ -selectmode single \ -exportselection no] scrollbar $fs(filef).vscroll -orient vertical -relief sunken \ -command "$fs(filef).list yview" scrollbar $fs(filef).hscroll -orient horizontal -relief sunken \ -command "$fs(filef).list xview" pack $fs(filef).label -side top -anchor w pack $fs(filef).vscroll -side right -fill y pack $fs(filef).hscroll -side bottom -fill x pack $fs(filef).list -side left -expand yes -fill both # # Add the directory and file lists based on the attributes # for displaying each list. Uses a split pane with extra space # to the file list. # frame $fs(listf).buf -width $_margin -borderwidth 0 if {$itk_option(-dispdir)} { $fs(listf) add $fs(dirf) } if {$itk_option(-dispfile)} { $fs(listf) add $fs(filef) } # # Create the label and entry widgets for the selection frame. Turn # off the selection capability, at least from the visual aspect # label $fs(self).label -text "$itk_option(-selectlabel)" set fs(select) [entry $fs(self).entry -relief sunken] set _selection "$itk_option(-dir)/" pack $fs(self).label -side top -anchor w pack $fs(self).entry -side bottom -fill x -expand yes -ipady 1m # # Add the separator and create the buttons in the button frame. # Each button is within a frame used to display as default. # The placer is used to locate the three buttons at relative # locations. # frame $f.line -height 2 -width 2 -borderwidth 1 -relief sunken frame $fs(btnf).okf -borderwidth 1 set fs(okbtn) [button $fs(btnf).okf.ok -text $itk_option(-button_1) -width 8] pack $fs(btnf).okf.ok -padx 2 -pady 2 raise $fs(btnf).okf.ok # If have a label and command for button 4, enable it. if { $itk_option(-button_4) != {} && $itk_option(-cmd_4) != {} } { frame $fs(btnf).extraf -borderwidth 1 set fs(extrabtn) [button $fs(btnf).extraf.extra \ -text $itk_option(-button_4) \ -width 8 \ -command [code $this _extracmd]] pack $fs(btnf).extraf.extra -padx 2 -pady 2 raise $fs(btnf).extraf.extra } frame $fs(btnf).ff -borderwidth 1 set fs(filterbtn) [button $fs(btnf).ff.f -text $itk_option(-button_2) -width 8 \ -command [code $this _filtercmd]] pack $fs(btnf).ff.f -padx 2 -pady 2 raise $fs(btnf).ff.f frame $fs(btnf).cf -borderwidth 1 set fs(cancelbtn) [button $fs(btnf).cf.c -text $itk_option(-button_3) -width 8] pack $fs(btnf).cf.c -padx 2 -pady 2 raise $fs(btnf).cf.c if { $itk_option(-button_4) != {} && $itk_option(-cmd_4) != {} } { place $fs(btnf).okf -relx 0.125 -rely 0.5 -anchor center place $fs(btnf).extraf -relx 0.375 -rely 0.5 -anchor center place $fs(btnf).ff -relx 0.625 -rely 0.5 -anchor center place $fs(btnf).cf -relx 0.875 -rely 0.5 -anchor center } else { place $fs(btnf).okf -relx 0 -rely 0.5 -anchor w place $fs(btnf).ff -relx 0.5 -rely 0.5 -anchor center place $fs(btnf).cf -relx 1 -rely 0.5 -anchor e } # # Pack all the components of the file selection box. The filter # and selection frames are packed based on the display attributes. # if {$itk_option(-dispfilter)} {pack $fs(filterf) -fill x -padx $_margin -pady 5} pack $fs(listf) -fill both -padx $_margin -pady 5 -expand yes if {$itk_option(-dispselect)} {pack $fs(self) -fill x -padx $_margin -pady 5} pack $f.line -fill x -pady 5 pack $fs(btnf) -fill x -padx $_margin -pady 5 pack $f -fill both -expand yes # # Set up the bindings for the list widgets. Single click in either # list executes a select method. Double click for the both lists # selects the entry and then invokes the button callback. Focus # events for the filter and select entry widgets control the default # button display, and return is mapped to the default button as well. # bind $fs(dirs) <1> [code $this _selectdir %y] bind $fs(files) <1> [code $this _selectfile %y] bind $fs(dirs) [code $this _dclickdir %y] bind $fs(files) [code $this _dclickfile %y] bind $fs(filter) [code $this _defaultbtn filter] bind $fs(select) [code $this _defaultbtn ok] bind $fs(filter) "$fs(filterbtn) invoke" bind $fs(select) "$fs(okbtn) invoke" # # Explicitly handle configs that may have been ignored earlier. # Also, check to see if the user has specified, width, or height. # If not, use the default and config. # set _initialized 1 eval itk_initialize $args # # Construction is complete. Now set up the initial text for the # filter, selection, and both lists. Finally, set the focus for # either the filter or select widget based on the display attribute. # _setfilter $itk_option(-dir) $itk_option(-filter) _setselection _filldirlist _fillfilelist if {$itk_option(-dispselect)} { focus $fs(select) } elseif {$itk_option(-dispfilter)} { focus $fs(filter) } } # Perform a grab operation, install the button # callbacks, and wait for the result. Make sure # to reset the working directory back to the # original before returning the result. public method activate {} { global ::result set curwd "[pwd]" wm deiconify $w_ if {$itk_option(-modal)} { grab $w_ } $fs(okbtn) configure -command [code $this _okcmd] $fs(cancelbtn) configure -command [code $this _cancelcmd] set seldir [file dirname [$fs(filter) get]] cd $seldir configure -dir "[pwd]" configure -filter "[file tail [$fs(filter) get]]" set _selection "$itk_option(-dir)/" _filldirlist _fillfilelist tkwait variable result($this) wm withdraw $w_ cd $curwd return $result($this) } # Return the selection. public method get {} { return $_selection } # called for double click on a filename protected method _dclickfile {y} { _selectfile $y update idletasks $fs(okbtn) invoke } # called for double click on a dir name protected method _dclickdir {y} { _selectdir $y update idletasks $fs(filterbtn) invoke } # Select the directory, set the filter to # the new directory. Set the selection to the # new directory if the file list is not # displayed. Mark the filter button as the # default. protected method _selectdir {y} { $fs(dirs) selection clear 0 end $fs(dirs) selection set [$fs(dirs) nearest $y] set curwd "[pwd]" set seldir [$fs(dirs) get [$fs(dirs) curselection]] if {$seldir == "."} { cd . } elseif {$seldir == ".."} { cd .. } else { cd $seldir } _setfilter "[pwd]" if {! $itk_option(-dispfile)} { _setselection "[pwd]" } cd $curwd _defaultbtn filter } # Select the file, set the selection to # the new file. Mark the ok button as the # default. protected method _selectfile {y} { $fs(files) selection clear 0 end $fs(files) selection set [$fs(files) nearest $y] set sel [$fs(files) curselection] if {[llength $sel]} { set _selection $itk_option(-dir)/[$fs(files) get $sel] if {[file exists $_selection]} { _setselection _defaultbtn ok } } } # Update the filter based on the parameters. # If the directory 'd' parameter is null, use # the 'dir' attribute. If the file 'f' # parameter is null use the tail of the filter # entry text. protected method _setfilter {{d ""} {f ""}} { if { $d == "" } { set filt [$fs(filter) get] if { [file isdirectory $filt] } { set d $filt } else { set d [file dirname $filt] } } if {$f == ""} { set filt [$fs(filter) get] if { [file isdirectory $filt] } { set f $last_filter_type_ } else { set f [file tail $filt] } } $fs(filter) delete 0 end $fs(filter) insert 0 "$d/$f" set last_filter_type_ $f } # Update the selection based on the # parameter. If the file 'f' parameter is # null, use the 'selection' attribute. protected method _setselection {{f ""}} { if {$f == ""} {set f $_selection} $fs(select) delete 0 end $fs(select) insert end "$f" } # Ok button callback. Set the default button to # OK, and set the selection attribute to the # current entry widget text. Undo the callbacks # for both the ok and cancel buttons. Release # the grab and set the global ::result, which frees # the wait. protected method _okcmd {} { global ::result set _selection [$fs(select) get] if {[file isdirectory $_selection]} { warning_dialog "Please select a file" $w_ return 0 } _defaultbtn ok $fs(okbtn) configure -command {} $fs(cancelbtn) configure -command {} if {$itk_option(-modal)} { grab release $w_ } set result($this) 1 return 1 } # Filter button callback. Change directories # as needed, and set the dir, filter, and # selection attributes. Change the filter and # selection text along with the list contents. # Mark the default button as filter. protected method _filtercmd {} { set filt [$fs(filter) get] if { [file isdirectory $filt] } { set seldir $filt } else { set seldir [file dirname $filt] } if {![file exists $seldir]} { return } cd $seldir set seldir [pwd] _setfilter $seldir configure -dir $seldir configure -filter "[file tail [$fs(filter) get]]" set _selection "$itk_option(-dir)/" _setselection _filldirlist _fillfilelist _defaultbtn filter } # ------------------------------------------------------------------ # METHOD: _cancelcmd - Cancel button callback. Set the default # button to cancel, undo the callbacks, and # release the grab and wait via the global # result variable. # ------------------------------------------------------------------ protected method _cancelcmd {} { global ::result _defaultbtn cancel $fs(okbtn) configure -command {} $fs(cancelbtn) configure -command {} if {$itk_option(-modal)} { grab release $w_ } set result($this) 0 } # Execute the extra command button. Assumes that this window should be # closed so prepares the selection and checks that something existent # has been selected (equivalent to pressing OK first then extra button # but activate returns 0). protected method _extracmd {} { if { $itk_option(-cmd_4) != {} } { global ::result set _selection [$fs(select) get] if {[file isdirectory $_selection]} { warning_dialog "Please select a file" $w_ return } _defaultbtn ok $fs(okbtn) configure -command {} $fs(cancelbtn) configure -command {} if {$itk_option(-modal)} { grab release $w_ } set result($this) 0 eval $itk_option(-cmd_4) } } # Clear the directory list filling with the # results of an 'ls'. Use the full attribute # to determine full file name insertion. # Select the first element if it exists. protected method _filldirlist {} { $fs(dirs) delete 0 end foreach i [exec /bin/ls -a $itk_option(-dir)] { catch { if {[file isdirectory $i]} { if {$itk_option(-full)} { $fs(dirs) insert end "$itk_option(-dir)/$i" } else { $fs(dirs) insert end [file tail $i] } } } } if {[$fs(dirs) size]} { $fs(dirs) selection clear 0 end $fs(dirs) selection set 0 } } # Clear the file list filling with the results of an 'glob'. # Use the full attribute to determine full file name insertion. # Select the first element if it exists. PWD: modification. NDF's # cannot start with "$" or "~$", so leave these files alone. protected method _fillfilelist {} { $fs(files) delete 0 end set file_temp [glob -nocomplain $itk_option(-dir)/$itk_option(-filter)] set filefiller [lsort $file_temp] foreach i $filefiller { set tail [file tail $i] if { [string match {$*} $tail] || [string match {./~$*} $tail] } { continue } if {[file isfile $i] } { if {$itk_option(-full)} { $fs(files) insert end $i } else { $fs(files) insert end $tail } } } } # Sets the default button, either ok, filter # or cancel. The focus is also adjusted. protected method _defaultbtn {btn} { if {$btn == "ok"} { $fs(btnf).okf configure -relief sunken $fs(btnf).ff configure -relief flat $fs(btnf).cf configure -relief flat focus $fs(select) } elseif {$btn == "filter"} { $fs(btnf).okf configure -relief flat $fs(btnf).ff configure -relief sunken $fs(btnf).cf configure -relief flat focus $fs(filter) } elseif {$btn == "cancel"} { $fs(btnf).okf configure -relief flat $fs(btnf).ff configure -relief flat $fs(btnf).cf configure -relief sunken } } # Method: Get the selection from an xterm and display it if # it in one of the entry widgets. A catch has to be used # because Tk will issue an error that the selection doesn't # exist. If it doesn't exist, this will still insert it # into the entry widget. I don't know of a workaround protected method get_selection {entry_widget} { set cmd "selection get" catch $cmd string $entry_widget insert insert $string } # Method: Get the position of the cursor and move it one way or another protected method entry_adjust_pos {entry_widget offset} { set pos [$entry_widget index insert] incr pos $offset if {$pos < 0} { set pos 0 } $entry_widget icursor $pos } # # Method: Set the filter type to a known value. # method set_filter_type {type} { if { $type == "" } { set type "*" } set dirname [file dirname [$fs(filter) get]] $fs(filter) delete 0 end $fs(filter) insert 0 $dirname/$type set last_filter_type_ $type update _filtercmd } # Set the window title. itk_option define -title title Title "Select File" { if {$_initialized} { wm title $w_ $itk_option(-title) } } # The label string above the filter widget. itk_option define -filterlabel filterLabel FilterLabel "Filter" { if {$_initialized} { $fs(filterf).label configure -text $itk_option(-filterlabel) } } # File list filter, defaults to "*". itk_option define -filter filter Filter "*" { if {$_initialized} { _setfilter $itk_option(-dir) $itk_option(-filter) } } # Initial directory, default to [pwd]. itk_option define -dir dir Dir "." { cd $itk_option(-dir) } # Label for directory list, default "Directories" itk_option define -dirlabel dirLabel DirLabel "Directories" { if {$_initialized} { $fs(dirf).label configure -text $itk_option(-dirlabel) } } # Label for file list, default "Files". itk_option define -filelabel fileLabel FileLabel "Files" { if {$_initialized} { $fs(filef).label configure -text $itk_option(-filelabel) } } # Label for selection entry, default # "Selection". itk_option define -selectlabel selectLabel SelectLabel "Selection" { if {$_initialized} { $fs(self).label configure -text $itk_option(-selectlabel) } } # Display full file names, yes/no, default no. itk_option define -full full Full 0 {} # Display filter, yes or no, default yes itk_option define -dispfilter dispFilter DispFilter 1 {} # Display directory list, yes or no, default yes itk_option define -dispdir dispDir DispDir 1 {} # Display file list, yes or no, default yes itk_option define -dispfile dispFile DispFile 1 {} # Display selection, yes or no, default yes itk_option define -dispselect dispSelect DispSelect 1 {} # Set the width of the selection and filter entry # widgets. itk_option define -width width Width 50 { if {$_initialized} { $fs(filter) configure -width $itk_option(-width) $fs(select) configure -width $itk_option(-width) } } # Set the height of the directory and file lists. itk_option define -height height Height 10 { if {$_initialized} { $fs(dirs) configure -height $itk_option(-height) $fs(files) configure -height $itk_option(-height) } } # The button label for button 1 itk_option define -button_1 button_1 Button_1 "OK" {} # The button label for button 2 itk_option define -button_2 button_2 Button_2 "Filter" {} # The button label for button 3 itk_option define -button_3 button_3 Button_3 "Cancel" {} # The button label for button 4 itk_option define -button_4 button_4 Button_4 {} {} # Command to execute for a button 4 press. itk_option define -cmd_4 cmd_4 Cmd_4 {} # Add an optional menu of file suffixes (preset file filters). itk_option define -filter_types filter_types Filter_Types {} { if {$_initialized} { if { [info exists fs(filter_types)] } { catch {destroy $fs(filter_types)} } if { $itk_option(-filter_types) != {} } { set fs(filter_types) [LabelMenu $fs(filterf).types \ -text {Type Filter:}] foreach pair "$itk_option(-filter_types)" { set name [lindex $pair 0] set type [lindex $pair 1] $fs(filter_types) add -label $name \ -command [code $this set_filter_type $type] } pack $fs(filterf).types -side bottom -ipady 1m -anchor w } } } # flag: if true, grab the screen itk_option define -modal modal Modal 0 # Margin distance used in construction protected variable _margin 10 # Current selection. protected variable _selection "./" protected variable fs protected variable _initialized 0 # Last filter type. protected variable last_filter_type_ "*.*" } skycat-3.1.2-starlink-1b/tclutil/library/FrameWidget.tcl000066400000000000000000000054161215713201500231710ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id: FrameWidget.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # FrameWidget.tcl - Itk base class for widgets with their own frame # # who when what # -------------- -------- ---------------------------------------- # Allan Brighton 01 Jun 94 Created # # Peter W. Draper 20 Jan 98 Fixed busy focus -lastfor so # that it does restore the focus, # not just get the window name. # 23 Jan 08 Make focus control is busy method optional. itk::usual FrameWidget {} # The FrameWidget itcl class is a subclass of itk::Widget and thus # inherits all of the features described in Widget(n). In addition, a # number of useful methods are defined, for use by the derived classes. itcl::class util::FrameWidget { inherit itk::Widget # Create a frame with the same name as this object constructor {args} { set class_ [utilNamespaceTail [$this info class]] set w_ $itk_component(hull) eval itk_initialize $args after idle [code $this init] } # derived classes can re-define the "init" method to run code after all # options have been evaluated protected method init {} { } # run the given tcl command while displaying the busy cursor # in the frame's parent top level window, if defocus is false don't handle # focussing. public method busy {cmd {defocus 1}} { global ::errorInfo ::errorCode if {[incr busy_count_] == 1} { if { $defocus } { catch {focus .} } blt::busy hold $w_ update idletasks } # save any errors and report them later if {[set code [catch [list uplevel $cmd] msg]]} { set info $errorInfo } if {[incr busy_count_ -1] == 0} { blt::busy release $w_ if { $defocus } { catch {focus [focus -lastfor $w_]} } } if {$code} { uplevel [list error $msg $info $code] } } # set the text of short help message to be displayed whenever # the mouse enters the widget w (assumes you are using class # ToplevelWidget) public method add_short_help {w text} { if {[catch {[winfo toplevel $w_] add_short_help $w $text} msg]} { # puts "$msg" } } # set the text of the short help message (display now, assumes you # are using class ToplevelWidget) public method short_help {text} { #catch {[winfo command [winfo toplevel $w_]] short_help $text} catch {[winfo toplevel $w_] short_help $text} } # -- options -- # -- class variables -- # name of this (derived) class protected variable class_ # shorter name for $itk_component(hull) protected variable w_ # count used for busy cursor private variable busy_count_ {0} } skycat-3.1.2-starlink-1b/tclutil/library/GraphPrint.tcl000066400000000000000000000035071215713201500230500ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id: GraphPrint.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # GraphPrint.tcl - Print dialog box for printing the contents of a graph # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 94 Created # Peter W. Draper 11 Jul 00 Changed to use "fit" variable, previous # form wasn't working as fit to page option. # 20 Jul 09 Removed mono mode, no longer supported. itk::usual GraphPrint {} # This widget defines a print dialog box for printing the contents of a graph. itcl::class util::GraphPrint { # similar to canvas... inherit util::CanvasPrint # create a new instance of this class constructor {args} { eval itk_initialize $args } # print the contents of the graph as postscript to the given file descriptor public method print {fd} { global ::$w_.color ::$w_.rotate ::$w_.colormap ::$w_.fit_to_page if { [set $w_.fit_to_page] } { set fit yes } else { set fit no } # try to fit on a page set width [lindex [$itk_option(-graph) config -width] 4] set height [lindex [$itk_option(-graph) config -height] 4] $itk_option(-graph) postscript configure \ -colormode [set $w_.color] \ -paperwidth [$w_.pagesize.width get] \ -paperheight [$w_.pagesize.height get] \ -landscape [set $w_.rotate] \ -padx 0 \ -pady 0 \ -center 1 \ -maxpec $fit set cmd [list $itk_option(-graph) postscript output] puts $fd [eval $cmd] } # use PrintDialog::ok to get the fd (CanvasPrint::ok returns filename) public method ok {args} { PrintDialog::ok $args } # Public data # graph to print itk_option define -graph graph Graph {} } skycat-3.1.2-starlink-1b/tclutil/library/HelpWin.tcl000066400000000000000000000075111215713201500223370ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id: HelpWin.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # HelpWin.tcl - Itcl class for displaying a text window with a help text. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 18 Mar 98 Copied from GAIA (Peter Draper, Starlink) # and renamed to util::HelpWin. # Modified comment format a little for use # with the itcldoc script to generate # man pages. # This is a simple class that displays the contents of a named # file in a text widget. The file should be set as a configuration # option when an instance is created. This class shares a text # window amongst all its instances, this means that it overwrites # any previous contents. itcl::class util::HelpWin { # Constructor: Note that all HelpWin objects share a single toplevel window. constructor {args} { # Evaluate any options. eval configure $args # We have an interest in health of widget. incr reference_ } # Destructor: deletes shared window if there are no more references. destructor { incr reference_ -1 if { $reference_ == 0 } { destroy_help } } # This method causes the object to take control of the text # widget and display the help text. public method display {} { if { [file readable $file] } { if { ![winfo exists $Top_] } { create_ } else { wm deiconify $Top_ raise $Top_ } $ScrollText_ clear all set fd [open $file r] $ScrollText_ insert 0.0 [read $fd] } } # Remove the help window. public method remove_help {} { if { [winfo exists $Top_] } { wm withdraw $Top_ } } # Create the help window. private method create_ {} { if { ![winfo exists $Top_] } { set Top_ [TopLevelWidget .\#auto] # Set the top-level window title. wm title $Top_ {Help} # Add the font control menu. $Top_ add_menubar set m [$Top_ add_menubutton Font] foreach font $fonts_ { $m add command -label abc -font $font \ -command [code $this set_font_ "$font"] } # Add the text widget. set ScrollText_ [ScrollText $Top_.text] set_font_ "[lindex $fonts_ 0]" # Create the control button. set Button [button $Top_.dismiss \ -text {Dismiss} \ -command [code $this remove_help]] pack $ScrollText_ -side top -fill both -expand true pack $Button -side bottom } } # Set the font of the help text. private method set_font_ {font} { if { [winfo exists $ScrollText_] } { $ScrollText_ configure -font "$font" } } # Configuration options: (public variables) # ---------------------- # The name of the file whose contents are to be displayed # in the help text widget. public variable file {name} {} # Protected variables: (available to instance) # -------------------- # Names of available fonts. protected variable fonts_ { -*-courier-medium-r-*-*-*-120-*-*-*-*-*-* -*-courier-medium-r-*-*-*-140-*-*-*-*-*-* -*-courier-medium-r-*-*-*-180-*-*-*-*-*-* } # Common variables: (shared by all instances) # ----------------- # Name of the text widget used to display the help. private common ScrollText_ {} # Name of the top-level widget the contains the help and control # buttons . private common Top_ {} # Reference count of help objects that have an interest in the # help widget. private common reference_ 0 # End of class definition. } skycat-3.1.2-starlink-1b/tclutil/library/InputDialog.tcl000066400000000000000000000025771215713201500232170ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id: InputDialog.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # InputDialog.tcl - Dialog to display a message and get input from the user # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 94 Created itk::usual InputDialog {} # An InputDialog is a dialog to display a message and get input from # the user. itcl::class util::InputDialog { inherit util::DialogWidget # create the dialog constructor {args} { # add an entry widget below the message global ::$variable_ # Tk entry widget for input. itk_component add entry { entry $itk_component(ext).entry -relief sunken } pack $itk_component(entry) -side left -fill x -expand 1 \ -padx 2m -pady 2m -ipady 1m eval itk_initialize $args } # called after options have been evaluated protected method init {} { DialogWidget::init bind $itk_component(entry) \ "$itk_component(button$itk_option(-default)) flash; set $variable_ $itk_option(-default)" } # this method is redefined here to change the value # that is returned from activate to be the contents of the entry widget protected method set_result {} { global ::$variable_ if {"[set $variable_]" == "$itk_option(-default)"} { return [$itk_component(entry) get] } return {} } } skycat-3.1.2-starlink-1b/tclutil/library/LabelCheck.tcl000066400000000000000000000106231215713201500227440ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id: LabelCheck.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # LabelCheck.tcl - Itcl megawidget for choosing options. # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 94 Created itk::usual LabelCheck {} # LabelCheck is an itcl megawidget for choosing options using a # label and radiobuttons (uses blt_table to arrange the buttons in # rows and columns). itcl::class util::LabelCheck { inherit util::LabelWidget constructor {args} { set variable_ $w_.choice # Tk frame containing checkbuttons. itk_component add table { frame $w_.table } { keep -background -relief -borderwidth } blt::blttable $itk_component(table) eval itk_initialize $args } # clear the choice display public method clear {} { if {[info exists but_]} { foreach i [array names but_] { destroy $but_($i) } unset but_ } } # layout the choices according to the options protected method do_layout {} { global ::$variable_ clear set rows $itk_option(-rows) set cols $itk_option(-cols) set choice $itk_option(-choice) set n [llength $choice] set row 0 set col 0 set i 0 # determine how many rows and columns if {$rows != 0} { set cols [expr {$n/$rows+1}] } elseif {$cols != 0} { set rows [expr {$n/$cols+1}] } elseif {"$itk_option(-orient)" == "horizontal"} { set rows 1 set cols $n } else { set rows $n set cols 1 } for {set row 0} {$row < $rows} {incr row} { for {set col 0} {$col < $cols} {incr col} { set name [lindex $choice $i] set ${variable_}($name) 0 # One Tk component is created for each item in the list # given by the -choice argument. itk_component add $name { set but_($name) \ [checkbutton $itk_component(table).choice$i \ -text $name \ -variable ${variable_}($name) \ -command [code $this command_proc_]] } { keep -state -anchor -background -foreground rename -font -valuefont valueFont Font rename -width -valuewidth valueWidth Width } blt::blttable $itk_component(table) $but_($name) $row,$col -fill x if {[incr i] == $n} { break } } if {$i == $n} { break } } } # return the current value of this option public method get {} { global ::$variable_ set value {} foreach i $itk_option(-choice) { if {[set ${variable_}($i)]} { lappend value $i } } return $value } # configure the individual buttons by name public method itemconfig {name args} { eval "$but_($name) config $args" } # call the command with the selected item private method command_proc_ {} { set cmd $itk_option(-command) if {"$cmd" != ""} { lappend cmd [$this get] } eval $cmd } # -- options -- # name of global variable to set (defaults to $w_.choice) itk_option define -variable variable Variable {} { if {"$itk_option(-variable)" != ""} { set variable_ $itk_option(-variable) global ::$variable_ if {[info exists but_]} { foreach i [array names but_] { $but_($i) config -variable ${variable_}($i) } } } } # list of choices to display as ON, all others are then OFF itk_option define -value value Value {} { global ::$variable_ if {[info exists $variable_]} { foreach i [array names $variable_] { set ${variable_}($i) 0 } } foreach i $itk_option(-value) { set ${variable_}($i) 1 } } # list of choices itk_option define -choice choice Choice {} { do_layout } # command to run when value is changed (new value is appended) itk_option define -command command Command {} # widget orientation: horizontal or vertical itk_option define -orient orient Orient {horizontal} { pack $itk_component(table) \ -side $side_ -padx 1m -pady 1m -fill both -expand 1 } # max number of rows to display (0 for unlimited) # note: specify either -rows OR -cols, but not both itk_option define -rows rows Rows {0} # max number of columns to display (0 for unlimited) # note: specify either -rows OR -cols, but not both itk_option define -cols cols Cols {0} # -- protected members -- # array(name) of button widgets protected variable but_ # name of text variable array for tracing protected variable variable_ } skycat-3.1.2-starlink-1b/tclutil/library/LabelChoice.tcl000066400000000000000000000105501215713201500231200ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id: LabelChoice.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # LabelChoice.tcl - Widget for choosing options using a label and radiobuttons # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 94 Created itk::usual LabelChoice {} # LabelChoice is an itcl megawidget for choosing options using a # label and radiobuttons (uses blt_table to arrange the buttons in # rows and columns). itcl::class util::LabelChoice { inherit util::LabelWidget constructor {args} { itk_option add hull.borderwidth hull.relief set variable_ $w_.choice # Tk frame containing radiobuttons. itk_component add table { frame $w_.table } { keep -background -relief -borderwidth } blt::blttable $itk_component(table) eval itk_initialize $args } # clear the choice display public method clear {} { if {[info exists but_]} { foreach i [array names but_] { destroy $but_($i) } unset but_ } } # layout the choices according to the options protected method do_layout {} { global ::$variable_ clear set rows $itk_option(-rows) set cols $itk_option(-cols) set choice $itk_option(-choice) set n [llength $choice] set row 0 set col 0 set i 0 # determine how many rows and columns if {$rows != 0} { set cols [expr {$n/$rows+1}] } elseif {$cols != 0} { set rows [expr {$n/$cols+1}] } elseif {"$itk_option(-orient)" == "horizontal"} { set rows 1 set cols $n } else { set rows $n set cols 1 } for {set row 0} {$row < $rows} {incr row} { for {set col 0} {$col < $cols} {incr col} { set name [lindex $choice $i] # One Tk component is created for each item in the list # given by the -choice argument. The component names are # choice0, choice1, ... itk_component add choice$i { set but_($name) \ [radiobutton $itk_component(table).choice$i \ -text $name \ -value $name \ -variable $variable_ \ -command [code $this command_proc_]] } { keep -state -anchor -background -foreground rename -font -valuefont valueFont Font rename -width -valuewidth valueWidth Width } blt::blttable $itk_component(table) $but_($name) $row,$col -fill x if {[incr i] == $n} { break } } if {$i == $n} { break } } # set default value if {"$itk_option(-value)" == ""} { set $variable_ [lindex $choice 0] } } # return the current value of this option public method get {} { global ::$variable_ return [set $variable_] } # configure the individual buttons by name public method itemconfig {name args} { eval "$but_($name) config $args" } # call the command with the selected item private method command_proc_ {} { set cmd $itk_option(-command) if {"$cmd" != ""} { lappend cmd [$this get] } eval $cmd } # -- options -- # name of global variable to set (defaults to $w_.choice) itk_option define -variable variable Variable {} { if {"$itk_option(-variable)" != ""} { set variable_ $itk_option(-variable) global ::$variable_ if {[info exists but_]} { foreach i [array names but_] { $but_($i) config -variable $variable_ } } } } # value to display itk_option define -value value Value {} { if {[info exists variable_]} { global ::$variable_ set $variable_ $itk_option(-value) } } # list of choices itk_option define -choice choice Choice {} { do_layout } # command to run when value is changed (new value is appended) itk_option define -command command Command {} # widget orientation: horizontal or vertical itk_option define -orient orient Orient {horizontal} { pack $itk_component(table) \ -side $side_ -padx 1m -pady 1m -fill both -expand 1 } # max number of rows to display (0 for unlimited) # note: specify either -rows OR -cols, but not both itk_option define -rows rows Rows {0} # max number of columns to display (0 for unlimited) # note: specify either -rows OR -cols, but not both itk_option define -cols cols Cols {0} # -- protected members -- # array(name) of button widgets protected variable but_ # name of text variable for tracing protected variable variable_ } skycat-3.1.2-starlink-1b/tclutil/library/LabelEntry.tcl000066400000000000000000000205331215713201500230310ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id: LabelEntry.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # LabelEntry.tcl - Itk widget for displaying a labeled entry # # Copyright: # Copyright (C) 1998-2005 Central Laboratory of the Research Councils. # Copyright (C) 2006 Particle Physics & Astronomy Research Council. # All Rights Reserved. # # Licence: # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place,Suite 330, Boston, MA # 02111-1307, USA # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 94 Created # Peter W. Draper 11 Aug 98 Expanded real definition to allow 1.0e6 # type values. # 26 Feb 99 Merged tcl8 changes from real tclutil version. itk::usual LabelEntry {} # This widget displays a label and an entry and implements convenient # methods for accessing and modifying the label and the value. itcl::class util::LabelEntry { inherit util::LabelWidget # constructor: create a new LabelEntry widget constructor {args} { # Tk entry widget. itk_component add entry { entry $w_.entry } { keep -textvariable -relief -borderwidth -show rename -font -valuefont valueFont ValueFont } eval itk_initialize $args } # Get the value in the entry public method get {} { return [$itk_component(entry) get] } # select the contents of the entry public method select {} { $itk_component(entry) select range 0 end } # called for traces on textvariable private method trace_ {args} { if {!$notrace_} { command_proc_ $itk_option(-changecmd) } } # called for return or keypress in entry, calls command proc with new value protected method command_proc_ {cmd} { lappend cmd [$itk_component(entry) get] eval $cmd } # The peek procedure returns the value of the entry with the # char inserted at the insert position. (ripped from iwidgets::entryfield) private method peek_ {char} { set str [get] set insertPos [$itk_component(entry) index insert] set firstPart [string range $str 0 [expr $insertPos - 1]] set lastPart [string range $str $insertPos end] append rtnVal $firstPart $char $lastPart return $rtnVal } # called for keypress events when validation is on (based on code from iwidgets) private method validate_ {char sym} { set cmd $validate_cmd_ if {"$cmd" == "" || "$itk_option(-validate)" == ""} { return } # pass these on to other bindings... if {$sym == "Return" || $sym == "Tab" || $sym == "BackSpace" || $sym == "Delete" || $sym == "Escape" || $sym == "space" || $char == ""} { return } regsub -all "%W" $cmd $itk_component(hull) cmd regsub -all "%P" $cmd [peek_ $char] cmd regsub -all "%S" $cmd [get] cmd if {$char == "\\"} { regsub -all "%c" $cmd {\\\\} cmd } elseif {$char == "&"} { regsub -all "%c" $cmd {\&} cmd } else { regsub "\"|\\\[|\\\]|{|}| " $char {\\\0} char regsub -all "%c" $cmd $char cmd } set valid [eval LabelEntry::$cmd] if {($valid == "") || (! $valid)} { eval $itk_option(-invalid) return -code break } } # validation methods used for -validate option (from iwidgets::entryfield class) protected proc numeric {char} { return [regexp {[0-9]} $char] } protected proc integer {string} { return [regexp {^[-+]?[0-9]*$} $string] } protected proc alphanumeric {char} { return [regexp -nocase {[0-9a-z]} $char] } protected proc alphabetic {char} { return [regexp -nocase {[a-z]} $char] } protected proc hexidecimal {string} { return [regexp {^(0x)?[0-9a-fA-F]*$} $string] } protected proc real {string} { # return [regexp {^\-?[0-9]*\.?[0-9]*$} $string] return [regexp -nocase {^[-+]?[0-9]*\.?[0-9]*([0-9]\.?e[-+]?[0-9]*)?$} $string] } # -- options -- # set the value displayed in the entry itk_option define -value value Value {} { set prev_state [$itk_component(entry) cget -state] $itk_component(entry) config -state normal set notrace_ 1 $itk_component(entry) delete 0 end $itk_component(entry) insert 0 $itk_option(-value) if {"$itk_option(-justify)" == "right"} { $itk_component(entry) icursor end $itk_component(entry) xview moveto 1 } $itk_component(entry) config -state $prev_state set notrace_ 0 } # set the width of the value displayed itk_option define -valuewidth valueWidth ValueWidth {15} { $itk_component(entry) config -width $itk_option(-valuewidth) } # set the state to normal or disabled (greyed out) itk_option define -state state State normal { $itk_component(entry) config -state $itk_option(-state) if {"$itk_option(-state)" == "normal"} { $itk_component(entry) config -foreground $itk_option(-foreground) } else { $itk_component(entry) config -foreground $itk_option(-disabledforeground) } } # the command for in the entry, called with the new value itk_option define -command command Command {} { if {"$itk_option(-command)" != ""} { bind $itk_component(entry) [code $this command_proc_ $itk_option(-command)] } } # alternative name for use when -command is already used by a derived class itk_option define -entrycommand entryCommand EntryCommand {} { if {"$itk_option(-entrycommand)" != ""} { bind $itk_component(entry) \ [code $this LabelEntry::command_proc_ $itk_option(-entrycommand)] } } # set to "right" to make sure the end of the entry is visible itk_option define -justify justify Justify {left} # commands to evaluate whenever the entry value changes itk_option define -changecmd changecmd Changecmd {} { if {"$itk_option(-changecmd)" != ""} { if {"$itk_option(-textvariable)" == ""} { config -textvariable $w_ } set var $itk_option(-textvariable) global ::$var trace variable $var w [code $this trace_] } } # widget orientation: horizontal or vertical itk_option define -orient orient Orient {horizontal} { if {"$itk_option(-valuewidth)" == "" || $itk_option(-valuewidth) == 0} { set expand 0 } else { set expand 1 } pack $itk_component(entry) \ -side $side_ -expand $expand -fill x -padx 1m -ipadx 1m } # valiadation of entry fields (based on iwidgets entryfield class) # numeric, alphabetic, integer, hexidecimal, real, and alphanumeric itk_option define -validate validate Validate {""} { if {"$itk_option(-validate)" != ""} { set validate_cmd_ "" switch $itk_option(-validate) { numeric { set validate_cmd_ "numeric %c" } integer { set validate_cmd_ "integer %P" } hexidecimal { set validate_cmd_ "hexidecimal %P" } real { set validate_cmd_ "real %P" } alphabetic { set validate_cmd_ "alphabetic %c" } alphanumeric { set validate_cmd_ "alphanumeric %c" } } if {"$validate_cmd_" != ""} { bind $itk_component(entry) [code $this validate_ %A %K] } } } # select the contents of the entry whenever it gets the focus itk_option define -autoselect autoSelect AutoSelect {0} { if {$itk_option(-autoselect)} { #bind autoSelect FocusIn "$itk_component(entry) select range 0 end" #bindtags $itk_component(entry) autoSelect } else { #bind autoSelect FocusIn { } } } # for compat with iwidgets entryfield: action for invalid char with -validate itk_option define -invalid invalid Command {bell} # -- protected vars -- # this flag is set to 1 to avoid tracing when changing the entry's value protected variable notrace_ 0 # command to validate entry contents protected variable validate_cmd_ "" } skycat-3.1.2-starlink-1b/tclutil/library/LabelEntryScale.tcl000066400000000000000000000242331215713201500240020ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id: LabelEntryScale.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # LabelEntryScale.tcl - Widget combining a labeled entry with a scale widget # # Copyright: # Copyright (C) 1999-2005 Central Laboratory of the Research Councils. # Copyright (C) 2006 Particle Physics & Astronomy Research Council. # All Rights Reserved. # # Licence: # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place,Suite 330, Boston, MA # 02111-1307, USA # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 94 Created # # 23 Mar 98 Added changes from P.W. Draper, Starlink. # Sorted out alignment when packing # vertically, added -resolution to keep # list for scale, added bindings for auto # increment and decrement when pressing # left and right arrows, added state # configuration option, added check that # value has changed in scaleCmd (The scale # widget has a binding that means # this is called repeatably which means # that any -commands are also called for no # reason). # Peter W. Draper 26 Feb 99 More changes: added option to hide the # scale and just keep the arrows. Also # added option to constrain the upper and # lower value limits. # 31 Mar 06 Added bindscale method. itk::usual LabelEntryScale {} # LabelEntryScale is an Itcl widget combining a labeled entry with a # scale widget to make a scale with an editable entry field. itcl::class util::LabelEntryScale { inherit util::LabelEntry # constructor: create a new instance of this widget constructor {args} { # Remove value from configuration options as we may need to # update the range of the scale. itk_option remove util::LabelEntry::value # Tk frame containing scale widget. itk_component add scaleframe { frame $w_.scaleframe } # Tk scale widget. itk_component add scale { scale $itk_component(scaleframe).scale \ -showvalue 0 \ -orient horizontal \ -command [code $this scaleCmd] } { keep -background -foreground -length -resolution -digits rename -width -scaleWidth scaleWidth ScaleWidth } # Left arrow button. itk_component add left { button $itk_component(scaleframe).left } { keep -background -foreground } bind $itk_component(left) [code $this start_increment -1] bind $itk_component(left) [code $this stop_increment] # Right arrow button. itk_component add right { button $itk_component(scaleframe).right } { keep -background -foreground } bind $itk_component(right) [code $this start_increment 1] bind $itk_component(right) [code $this stop_increment] eval itk_initialize $args } # Start incrementing if not already doing so. protected method start_increment {sign} { if { $afterId_ == {} && $itk_option(-state) == "normal" } { increment $sign } } # Stop incrementing. protected method stop_increment {} { if { $afterId_ != {} } { after cancel $afterId_ set afterId_ {} } } # Increment (1) or decrement (-1) the value by the current increment protected method increment {sign} { set v [expr [get]+($sign*$itk_option(-increment))] if {$v >= $itk_option(-from) && $v <= $itk_option(-to)} { config -value $v if {"$itk_option(-command)" != ""} { set cmd $itk_option(-command) lappend cmd $v eval $cmd } } set afterId_ [after $itk_option(-delay) [code $this increment $sign]] } # This method is called for changes in the scale widget. It does # nothing unless the value has changed, since the Scale has a # motion event that is constantly being invoked. protected method scaleCmd {newValue} { if { $itk_option(-value) != $newValue } { config -value $newValue if {"$itk_option(-command)" != ""} { eval "$itk_option(-command) $newValue" } } } # Redefined from parent class to update scale when entry is # changed private method command_proc_ {cmd} { set v [$itk_component(entry) get] if { $itk_option(-fix_range) } { if {$v < $from_} { set v $from_ } if {$v > $to_} { set v $to_ } scaleCmd $v configure -value $v } else { set from $from_ set to $to_ if {$v < $from} { set from $v } if {$v > $to} { set to $v } $itk_component(scale) config -from $from -to $to scaleCmd $v } } # Add a binding to all widgets related to scale. If a binding exists # already this one will be appended to it. public method bindscale {sequence script} { bind $itk_component(scale) $sequence +"$script" bind $itk_component(left) $sequence +"$script" bind $itk_component(right) $sequence +"$script" } # Add a binding to all widgets related to entry field. If a binding # exists already this one will be appended to it. public method bindentry {sequence script} { bind $itk_component(entry) $sequence +"$script" } # -- options -- # Widget orientation: horizontal or vertical itk_option define -orient orient Orient {horizontal} { if { $itk_option(-show_scale) } { set arrowside left set bitmap1 left set bitmap2 right } else { set arrowside bottom set bitmap1 decr set bitmap2 incr } pack $itk_component(scaleframe) -fill x -side $side_ if {$itk_option(-show_arrows)} { pack $itk_component(left) -side $arrowside $itk_component(left) configure -bitmap $bitmap1 } if { $itk_option(-show_scale) } { pack $itk_component(scale) \ -side left -expand 1 -fill x -padx 1m -ipadx 1m } if {$itk_option(-show_arrows)} { pack $itk_component(right) -side $arrowside $itk_component(right) configure -bitmap $bitmap2 } } # Scale range -from. itk_option define -from from From {} { set v $itk_option(-from) if {"$v" != ""} { $itk_component(scale) config -from $v set from_ $v } } # Scale range -to. itk_option define -to to To {} { set v $itk_option(-to) if {"$v" != ""} { $itk_component(scale) config -to $itk_option(-to) set to_ $v } } # Set the value for scale and entry field. itk_option define -value value Value {} { set v $itk_option(-value) if {"$v" != ""} { set notrace_ 1 # Update range to reflect this, if possible. Assumes -to # -from already set. set from $itk_option(-from) set to $itk_option(-to) if { ! $itk_option(-fix_range) } { # Expand range, if needed. if { $v < $from} { set from $v } if { $v > $to } { set to $v } if { $from != {} && $to != {} } { config -from $from -to $to } } else { # Clip to range. if { $v < $from} { set v $from } if { $v > $to } { set v $to } set itk_option(-value) $v } # Now update values. set prev_state [$itk_component(entry) cget -state] $itk_component(entry) config -state normal $itk_component(entry) delete 0 end $itk_component(entry) insert 0 $v $itk_component(scale) set $v if {"$itk_option(-justify)" == "right"} { $itk_component(entry) icursor end $itk_component(entry) xview moveto 1 } $itk_component(entry) config -state $prev_state set notrace_ 0 } } # Flag: if true, display left and right arrows for incrementing the value itk_option define -show_arrows show_arrows Show_arrows {0} # Amount to add or subtract for each button push itk_option define -increment increment Increment 1 # Command to execute when the value changes itk_option define -command command Command {} # Set the state to normal or disabled (greyed out) itk_option define -state state State normal { $itk_component(scale) config -state $itk_option(-state) if {"$itk_option(-state)" == "normal"} { $itk_component(scale) config -foreground $itk_option(-foreground) } else { $itk_component(scale) config -foreground $itk_option(-disabledforeground) } } # Whether to/from range is also fixed in entry field. itk_option define -fix_range fix_range Fix_Range 0 {} # Whether to show the scale widget. itk_option define -show_scale show_scale Show_Scale 1 {} # The pause in milliseconds for the animation delay. itk_option define -delay delay Delay 150 # State of increment command. protected variable afterId_ {} # Original -from and -to values protected variable from_ {} protected variable to_ {} } skycat-3.1.2-starlink-1b/tclutil/library/LabelMenu.tcl000066400000000000000000000146041215713201500226360ustar00rootroot00000000000000# E.S.O. - VLT project/ ESO Archive # "@(#) $Id: LabelMenu.tcl,v 1.1.1.1 2009/03/31 14:11:52 cguirao Exp $" # # LabelMenu.tcl - Itcl widget for displaying a label and a menubutton # # Copyright: # Copyright (C) 1999-2005 Central Laboratory of the Research Councils. # Copyright (C) 2006 Particle Physics & Astronomy Research Council. # All Rights Reserved. # # Licence: # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place,Suite 330, Boston, MA # 02111-1307, USA # # who when what # -------------- --------- ---------------------------------------- # Allan Brighton 01 Jun 94 Created # Peter W. Draper 26 Mar 99 Removed global statements for $variable_ # itcl3 scoping breaks this # 02 Apr 01 Added delete and invoke methods for a single item. itk::usual LabelMenu {} # This widget displays a label and a menubutton with a selector and a # menu of radiobuttons. This can be used for choosing items from a list # and displaying the current choice. The widget supports adding of items # to the radiobutton menu and keeps track of which items are selected. itcl::class util::LabelMenu { inherit util::LabelWidget # create a LabelMenu constructor {args} { set menu $w_.mb.m # Menubutton containing the menu. itk_component add mb { menubutton $w_.mb -menu $menu } { keep -indicatoron -relief -borderwidth -state rename -width -valuewidth valueWidth Width rename -font -valuefont valueFont Font rename -anchor -valueanchor valueAnchor ValueAnchor ignore -disabledforeground } # Component for the menu. itk_component add menu { menu $menu } { ignore -disabledforeground } set default_bg_ [$itk_component(mb) cget -background] # trace this radiobutton var to change menubutton label global ::$w_.var set $w_.var "" trace variable $w_.var w [code $this update_menubutton] eval itk_initialize $args } # destructor destructor { global ::$w_.var catch {unset $w_.var} } # remove all of the items in the menu public method clear {} { $itk_component(menu) delete 0 end } # remove a single entry public method delete {index} { $itk_component(menu) delete $index } # invoke an item. public method invoke {index} { $itk_component(menu) invoke $index } # return the current value public method get {} { global ::$w_.var set v [set $w_.var] foreach i [array names values_] { if {"$values_($i)" == "$v"} { return $i } } } # add a separator item to the menu public method add_separator {} { $itk_component(menu) add separator } # add an item to the menu. # The args may be the options: # -label